From 3c55eccece2c9c9263f4c3d7f4ebfb6f38234317 Mon Sep 17 00:00:00 2001 From: Flashphoner Date: Thu, 10 Apr 2014 14:13:33 +1000 Subject: [PATCH 01/20] [INIT] Init new branch. --- .gitignore | 7 - README | 4 - build.sh | 7 - builder/builder.sh | 29 - builder/functions.lib | 104 - client/api/.actionScriptProperties | 20 - client/api/.flexLibProperties | 37 - client/api/.project | 25 - .../org.eclipse.core.resources.prefs | 3 - .../.settings/org.eclipse.wst.html.core.prefs | 36 - client/api/build.properties | 3 - client/api/build.xml | 56 - client/api/src/com/flashphoner/Logger.as | 161 - client/api/src/com/flashphoner/api/Call.as | 253 - .../src/com/flashphoner/api/CallCommand.as | 92 - .../api/src/com/flashphoner/api/CallEvent.as | 41 - .../com/flashphoner/api/CallServerProxy.as | 149 - .../api/src/com/flashphoner/api/Flash_API.as | 709 - .../src/com/flashphoner/api/InstantMessage.as | 44 - .../src/com/flashphoner/api/MainCommand.as | 75 - .../api/src/com/flashphoner/api/MainEvent.as | 41 - .../src/com/flashphoner/api/MessageCommand.as | 50 - .../src/com/flashphoner/api/MessageEvent.as | 39 - .../src/com/flashphoner/api/PhoneCallback.as | 251 - .../com/flashphoner/api/PhoneController.as | 50 - .../api/src/com/flashphoner/api/PhoneModel.as | 265 - .../com/flashphoner/api/PhoneServerProxy.as | 251 - .../src/com/flashphoner/api/PhoneSpeaker.as | 185 - .../src/com/flashphoner/api/SoundControl.as | 313 - .../com/flashphoner/api/data/ErrorCodes.as | 83 - .../com/flashphoner/api/data/ModelLocator.as | 48 - .../com/flashphoner/api/data/PhoneConfig.as | 134 - .../src/com/flashphoner/api/interfaces/API.as | 38 - .../flashphoner/api/interfaces/APINotify.as | 39 - .../src/com/flashphoner/api/js/APINotifyJS.as | 95 - .../api/management/VideoControl.as | 135 - client/api/src/sounds/BUSY.mp3 | Bin 6567 -> 0 bytes client/api/src/sounds/CALL_IN.mp3 | Bin 37130 -> 0 bytes client/api/src/sounds/CALL_OUT.mp3 | Bin 6456 -> 0 bytes client/api/src/sounds/HANGUP.mp3 | Bin 4483 -> 0 bytes client/api/src/sounds/REGISTER.mp3 | Bin 4224 -> 0 bytes client/client/.actionScriptProperties | 23 - client/client/.flexProperties | 6 - client/client/.project | 25 - .../com.adobe.flexbuilder.project.prefs | 5 - .../org.eclipse.core.resources.prefs | 3 - .../org.eclipse.ltk.core.refactoring.prefs | 3 - client/client/build.properties | 4 - client/client/build.xml | 120 - client/client/src/Click2callJS.html | 154 - client/client/src/Phone.html | 73 - client/client/src/PhoneJS.html | 238 - client/client/src/assets/background_phone.png | Bin 368 -> 0 bytes client/client/src/assets/c2c_camera.png | Bin 1303 -> 0 bytes client/client/src/assets/c2c_dialpad.png | Bin 1899 -> 0 bytes client/client/src/assets/c2c_hangup.png | Bin 4754 -> 0 bytes client/client/src/assets/c2c_mic.png | Bin 1534 -> 0 bytes client/client/src/assets/c2c_pause.png | Bin 6039 -> 0 bytes client/client/src/assets/c2c_play.png | Bin 9288 -> 0 bytes client/client/src/assets/c2c_sound.png | Bin 2907 -> 0 bytes client/client/src/assets/camera.png | Bin 1206 -> 0 bytes client/client/src/assets/close.png | Bin 3309 -> 0 bytes client/client/src/assets/hold.png | Bin 598 -> 0 bytes client/client/src/assets/hold_big.png | Bin 221 -> 0 bytes client/client/src/assets/mic.png | Bin 1343 -> 0 bytes client/client/src/assets/mic_crossed.png | Bin 255 -> 0 bytes client/client/src/assets/mic_settings.png | Bin 512 -> 0 bytes .../src/assets/mic_settings_background.png | Bin 535 -> 0 bytes client/client/src/assets/pie/PIE.htc | 96 - client/client/src/assets/pie/PIE.js | 88 - client/client/src/assets/pie/PIE.php | 19 - .../src/assets/pie/PIE_uncompressed.htc | 4505 ------ .../client/src/assets/pie/PIE_uncompressed.js | 4474 ------ client/client/src/assets/sound_crossed.png | Bin 238 -> 0 bytes client/client/src/assets/speaker.png | Bin 1395 -> 0 bytes client/client/src/assets/transfer.png | Bin 607 -> 0 bytes client/client/src/assets/unhold.png | Bin 592 -> 0 bytes .../com/flashphoner/phone/APINotifyPhone.as | 154 - .../src/com/flashphoner/phone/DataPhone.as | 100 - .../flashphoner/phone/ViewControllerPhone.as | 163 - .../flashphoner/phone/views/AccessView.mxml | 26 - .../com/flashphoner/phone/views/CallView.mxml | 71 - .../phone/views/ConnectingView.mxml | 25 - .../com/flashphoner/phone/views/DragPanel.as | 47 - .../flashphoner/phone/views/IncomingView.mxml | 99 - .../com/flashphoner/phone/views/InfoView.mxml | 31 - .../phone/views/InstantMessageChatView.mxml | 78 - .../com/flashphoner/phone/views/MainView.mxml | 88 - .../phone/views/MicrophoneSettingsView.mxml | 98 - .../flashphoner/phone/views/PhoneButton.mxml | 138 - .../phone/views/SipAccountView.mxml | 105 - .../flashphoner/phone/views/TabChatView.mxml | 112 - .../flashphoner/phone/views/TransferView.mxml | 52 - .../flashphoner/phone/views/VideoView.mxml | 76 - .../src/com/flashphoner/util/HashMap.as | 158 - .../client/src/com/flashphoner/util/IMap.as | 49 - client/client/src/flashphoner.xml | 32 - client/client/src/flashphoner_js_api.mxml | 122 - client/client/src/js/Click2Call.js | 718 - client/client/src/js/FlashphonerLoader.js | 370 - client/client/src/js/Phone.js | 1315 -- client/client/src/js/StaticData.js | 102 - client/client/src/js/UnitTests.js | 11 - client/client/src/js/imgtrackbar/b_bg_all.gif | Bin 52 -> 0 bytes client/client/src/js/imgtrackbar/b_bg_off.gif | Bin 52 -> 0 bytes client/client/src/js/imgtrackbar/b_bg_on.gif | Bin 52 -> 0 bytes client/client/src/js/imgtrackbar/b_l.gif | Bin 182 -> 0 bytes client/client/src/js/imgtrackbar/b_r.gif | Bin 183 -> 0 bytes client/client/src/js/jquery/jquery-ui.js | 11737 ---------------- client/client/src/js/jquery/jquery.js | 8981 ------------ client/client/src/js/jquery/jquery.json.js | 199 - .../client/src/js/jquery/jquery.websocket.js | 54 - .../client/src/js/listener/DefaultListener.js | 46 - .../src/js/listener/LoadToolListener.js | 66 - client/client/src/js/rtc/Adapter.js | 82 - .../client/src/js/rtc/WebRtcMediaManager.js | 362 - client/client/src/js/swf/AC_OETags.js | 292 - client/client/src/js/swf/expressInstall.swf | Bin 727 -> 0 bytes client/client/src/js/swf/history/history.css | 12 - client/client/src/js/swf/history/history.js | 674 - .../src/js/swf/history/historyFrame.html | 29 - .../src/js/swf/playerProductInstall.swf | Bin 657 -> 0 bytes client/client/src/js/swf/swfobject.js | 4 - client/client/src/js/trackbar.js | 405 - client/client/src/js/ui/UIManagerFlash.js | 87 - client/client/src/js/ui/UIManagerWebRtc.js | 66 - client/client/src/js/ws/Messenger.js | 136 - client/client/src/js/ws/SoundControl.js | 79 - client/client/src/js/ws/WebSocketManager.js | 465 - client/client/src/phone.mxml | 175 - client/client/src/sounds/BUSY.ogg | Bin 6741 -> 0 bytes client/client/src/sounds/CALL_IN.ogg | Bin 28376 -> 0 bytes client/client/src/sounds/CALL_OUT.ogg | Bin 7646 -> 0 bytes client/client/src/sounds/HANGUP.ogg | Bin 5199 -> 0 bytes client/client/src/sounds/REGISTER.ogg | Bin 3619 -> 0 bytes client/client/src/styles/arial.ttf | Bin 774476 -> 0 bytes client/client/src/styles/style.css | 171 - client/client/src/styles/style_html.css | 961 -- client/client/src/styles/style_html_c2c.css | 665 - .../src/styles/style_jquery_ui_1.8.15.css | 565 - client/client/src/styles/trackbar.css | 100 - client/client/src/styles/verdana.ttf | Bin 189144 -> 0 bytes client/libs/Cairngorm.swc | Bin 11256 -> 0 bytes client/load_tool/.actionScriptProperties | 22 - client/load_tool/.flexProperties | 2 - client/load_tool/.project | 25 - .../org.eclipse.core.resources.prefs | 3 - client/load_tool/build.properties | 3 - client/load_tool/build.xml | 59 - client/load_tool/html-template/AC_OETags.js | 292 - .../load_tool/html-template/flashphoner.xml | 6 - client/load_tool/html-template/general.xml | 105 - .../html-template/history/history.css | 6 - .../html-template/history/history.js | 669 - .../html-template/history/historyFrame.html | 29 - client/load_tool/html-template/swfobject.js | 4 - client/load_tool/src/APINotifyImpl.as | 117 - client/load_tool/src/Account.as | 219 - client/load_tool/src/Accounts.as | 283 - client/load_tool/src/TestStabApplication.html | 41 - client/load_tool/src/TestStabApplication.mxml | 267 - client/wcs_media_client/.idea/.name | 1 + client/wcs_media_client/.idea/encodings.xml | 5 + client/wcs_media_client/.idea/misc.xml | 5 + client/wcs_media_client/.idea/modules.xml | 9 + .../.idea/scopes/scope_settings.xml | 5 + client/wcs_media_client/.idea/vcs.xml | 7 + .../.idea/wcs_media_client.iml | 9 + client/wcs_media_client/.idea/workspace.xml | 217 + client/wcs_media_client/index.html | 11 + client/wcs_media_client/js/main.js | 4 + 171 files changed, 273 insertions(+), 46613 deletions(-) delete mode 100644 .gitignore delete mode 100644 README delete mode 100644 build.sh delete mode 100644 builder/builder.sh delete mode 100644 builder/functions.lib delete mode 100644 client/api/.actionScriptProperties delete mode 100644 client/api/.flexLibProperties delete mode 100644 client/api/.project delete mode 100644 client/api/.settings/org.eclipse.core.resources.prefs delete mode 100644 client/api/.settings/org.eclipse.wst.html.core.prefs delete mode 100644 client/api/build.properties delete mode 100644 client/api/build.xml delete mode 100644 client/api/src/com/flashphoner/Logger.as delete mode 100644 client/api/src/com/flashphoner/api/Call.as delete mode 100644 client/api/src/com/flashphoner/api/CallCommand.as delete mode 100644 client/api/src/com/flashphoner/api/CallEvent.as delete mode 100644 client/api/src/com/flashphoner/api/CallServerProxy.as delete mode 100644 client/api/src/com/flashphoner/api/Flash_API.as delete mode 100644 client/api/src/com/flashphoner/api/InstantMessage.as delete mode 100644 client/api/src/com/flashphoner/api/MainCommand.as delete mode 100644 client/api/src/com/flashphoner/api/MainEvent.as delete mode 100644 client/api/src/com/flashphoner/api/MessageCommand.as delete mode 100644 client/api/src/com/flashphoner/api/MessageEvent.as delete mode 100644 client/api/src/com/flashphoner/api/PhoneCallback.as delete mode 100644 client/api/src/com/flashphoner/api/PhoneController.as delete mode 100644 client/api/src/com/flashphoner/api/PhoneModel.as delete mode 100644 client/api/src/com/flashphoner/api/PhoneServerProxy.as delete mode 100644 client/api/src/com/flashphoner/api/PhoneSpeaker.as delete mode 100644 client/api/src/com/flashphoner/api/SoundControl.as delete mode 100644 client/api/src/com/flashphoner/api/data/ErrorCodes.as delete mode 100644 client/api/src/com/flashphoner/api/data/ModelLocator.as delete mode 100644 client/api/src/com/flashphoner/api/data/PhoneConfig.as delete mode 100644 client/api/src/com/flashphoner/api/interfaces/API.as delete mode 100644 client/api/src/com/flashphoner/api/interfaces/APINotify.as delete mode 100644 client/api/src/com/flashphoner/api/js/APINotifyJS.as delete mode 100644 client/api/src/com/flashphoner/api/management/VideoControl.as delete mode 100644 client/api/src/sounds/BUSY.mp3 delete mode 100644 client/api/src/sounds/CALL_IN.mp3 delete mode 100644 client/api/src/sounds/CALL_OUT.mp3 delete mode 100644 client/api/src/sounds/HANGUP.mp3 delete mode 100644 client/api/src/sounds/REGISTER.mp3 delete mode 100644 client/client/.actionScriptProperties delete mode 100644 client/client/.flexProperties delete mode 100644 client/client/.project delete mode 100644 client/client/.settings/com.adobe.flexbuilder.project.prefs delete mode 100644 client/client/.settings/org.eclipse.core.resources.prefs delete mode 100644 client/client/.settings/org.eclipse.ltk.core.refactoring.prefs delete mode 100644 client/client/build.properties delete mode 100644 client/client/build.xml delete mode 100644 client/client/src/Click2callJS.html delete mode 100644 client/client/src/Phone.html delete mode 100644 client/client/src/PhoneJS.html delete mode 100644 client/client/src/assets/background_phone.png delete mode 100644 client/client/src/assets/c2c_camera.png delete mode 100644 client/client/src/assets/c2c_dialpad.png delete mode 100644 client/client/src/assets/c2c_hangup.png delete mode 100644 client/client/src/assets/c2c_mic.png delete mode 100644 client/client/src/assets/c2c_pause.png delete mode 100644 client/client/src/assets/c2c_play.png delete mode 100644 client/client/src/assets/c2c_sound.png delete mode 100644 client/client/src/assets/camera.png delete mode 100644 client/client/src/assets/close.png delete mode 100644 client/client/src/assets/hold.png delete mode 100644 client/client/src/assets/hold_big.png delete mode 100644 client/client/src/assets/mic.png delete mode 100644 client/client/src/assets/mic_crossed.png delete mode 100644 client/client/src/assets/mic_settings.png delete mode 100644 client/client/src/assets/mic_settings_background.png delete mode 100644 client/client/src/assets/pie/PIE.htc delete mode 100644 client/client/src/assets/pie/PIE.js delete mode 100644 client/client/src/assets/pie/PIE.php delete mode 100644 client/client/src/assets/pie/PIE_uncompressed.htc delete mode 100644 client/client/src/assets/pie/PIE_uncompressed.js delete mode 100644 client/client/src/assets/sound_crossed.png delete mode 100644 client/client/src/assets/speaker.png delete mode 100644 client/client/src/assets/transfer.png delete mode 100644 client/client/src/assets/unhold.png delete mode 100644 client/client/src/com/flashphoner/phone/APINotifyPhone.as delete mode 100644 client/client/src/com/flashphoner/phone/DataPhone.as delete mode 100644 client/client/src/com/flashphoner/phone/ViewControllerPhone.as delete mode 100644 client/client/src/com/flashphoner/phone/views/AccessView.mxml delete mode 100644 client/client/src/com/flashphoner/phone/views/CallView.mxml delete mode 100644 client/client/src/com/flashphoner/phone/views/ConnectingView.mxml delete mode 100644 client/client/src/com/flashphoner/phone/views/DragPanel.as delete mode 100644 client/client/src/com/flashphoner/phone/views/IncomingView.mxml delete mode 100644 client/client/src/com/flashphoner/phone/views/InfoView.mxml delete mode 100644 client/client/src/com/flashphoner/phone/views/InstantMessageChatView.mxml delete mode 100644 client/client/src/com/flashphoner/phone/views/MainView.mxml delete mode 100644 client/client/src/com/flashphoner/phone/views/MicrophoneSettingsView.mxml delete mode 100644 client/client/src/com/flashphoner/phone/views/PhoneButton.mxml delete mode 100644 client/client/src/com/flashphoner/phone/views/SipAccountView.mxml delete mode 100644 client/client/src/com/flashphoner/phone/views/TabChatView.mxml delete mode 100644 client/client/src/com/flashphoner/phone/views/TransferView.mxml delete mode 100644 client/client/src/com/flashphoner/phone/views/VideoView.mxml delete mode 100644 client/client/src/com/flashphoner/util/HashMap.as delete mode 100644 client/client/src/com/flashphoner/util/IMap.as delete mode 100644 client/client/src/flashphoner.xml delete mode 100644 client/client/src/flashphoner_js_api.mxml delete mode 100644 client/client/src/js/Click2Call.js delete mode 100644 client/client/src/js/FlashphonerLoader.js delete mode 100644 client/client/src/js/Phone.js delete mode 100644 client/client/src/js/StaticData.js delete mode 100644 client/client/src/js/UnitTests.js delete mode 100644 client/client/src/js/imgtrackbar/b_bg_all.gif delete mode 100644 client/client/src/js/imgtrackbar/b_bg_off.gif delete mode 100644 client/client/src/js/imgtrackbar/b_bg_on.gif delete mode 100644 client/client/src/js/imgtrackbar/b_l.gif delete mode 100644 client/client/src/js/imgtrackbar/b_r.gif delete mode 100644 client/client/src/js/jquery/jquery-ui.js delete mode 100644 client/client/src/js/jquery/jquery.js delete mode 100644 client/client/src/js/jquery/jquery.json.js delete mode 100644 client/client/src/js/jquery/jquery.websocket.js delete mode 100644 client/client/src/js/listener/DefaultListener.js delete mode 100644 client/client/src/js/listener/LoadToolListener.js delete mode 100644 client/client/src/js/rtc/Adapter.js delete mode 100644 client/client/src/js/rtc/WebRtcMediaManager.js delete mode 100644 client/client/src/js/swf/AC_OETags.js delete mode 100644 client/client/src/js/swf/expressInstall.swf delete mode 100644 client/client/src/js/swf/history/history.css delete mode 100644 client/client/src/js/swf/history/history.js delete mode 100644 client/client/src/js/swf/history/historyFrame.html delete mode 100644 client/client/src/js/swf/playerProductInstall.swf delete mode 100644 client/client/src/js/swf/swfobject.js delete mode 100644 client/client/src/js/trackbar.js delete mode 100644 client/client/src/js/ui/UIManagerFlash.js delete mode 100644 client/client/src/js/ui/UIManagerWebRtc.js delete mode 100644 client/client/src/js/ws/Messenger.js delete mode 100644 client/client/src/js/ws/SoundControl.js delete mode 100644 client/client/src/js/ws/WebSocketManager.js delete mode 100644 client/client/src/phone.mxml delete mode 100644 client/client/src/sounds/BUSY.ogg delete mode 100644 client/client/src/sounds/CALL_IN.ogg delete mode 100644 client/client/src/sounds/CALL_OUT.ogg delete mode 100644 client/client/src/sounds/HANGUP.ogg delete mode 100644 client/client/src/sounds/REGISTER.ogg delete mode 100644 client/client/src/styles/arial.ttf delete mode 100644 client/client/src/styles/style.css delete mode 100644 client/client/src/styles/style_html.css delete mode 100644 client/client/src/styles/style_html_c2c.css delete mode 100644 client/client/src/styles/style_jquery_ui_1.8.15.css delete mode 100644 client/client/src/styles/trackbar.css delete mode 100644 client/client/src/styles/verdana.ttf delete mode 100644 client/libs/Cairngorm.swc delete mode 100644 client/load_tool/.actionScriptProperties delete mode 100644 client/load_tool/.flexProperties delete mode 100644 client/load_tool/.project delete mode 100644 client/load_tool/.settings/org.eclipse.core.resources.prefs delete mode 100644 client/load_tool/build.properties delete mode 100644 client/load_tool/build.xml delete mode 100644 client/load_tool/html-template/AC_OETags.js delete mode 100644 client/load_tool/html-template/flashphoner.xml delete mode 100644 client/load_tool/html-template/general.xml delete mode 100644 client/load_tool/html-template/history/history.css delete mode 100644 client/load_tool/html-template/history/history.js delete mode 100644 client/load_tool/html-template/history/historyFrame.html delete mode 100644 client/load_tool/html-template/swfobject.js delete mode 100644 client/load_tool/src/APINotifyImpl.as delete mode 100644 client/load_tool/src/Account.as delete mode 100644 client/load_tool/src/Accounts.as delete mode 100644 client/load_tool/src/TestStabApplication.html delete mode 100644 client/load_tool/src/TestStabApplication.mxml create mode 100644 client/wcs_media_client/.idea/.name create mode 100644 client/wcs_media_client/.idea/encodings.xml create mode 100644 client/wcs_media_client/.idea/misc.xml create mode 100644 client/wcs_media_client/.idea/modules.xml create mode 100644 client/wcs_media_client/.idea/scopes/scope_settings.xml create mode 100644 client/wcs_media_client/.idea/vcs.xml create mode 100644 client/wcs_media_client/.idea/wcs_media_client.iml create mode 100644 client/wcs_media_client/.idea/workspace.xml create mode 100644 client/wcs_media_client/index.html create mode 100644 client/wcs_media_client/js/main.js diff --git a/.gitignore b/.gitignore deleted file mode 100644 index 389d9e8f..00000000 --- a/.gitignore +++ /dev/null @@ -1,7 +0,0 @@ - -/client/output -/client/libs/api.swc -/release -/server/.idea -/server/build -/client/.metadata diff --git a/README b/README deleted file mode 100644 index e03064b2..00000000 --- a/README +++ /dev/null @@ -1,4 +0,0 @@ -Flashphoner-client is an open-source part of Flashphoner product. -You can use it for customization. - -Builds: http://flashphoner.com/downloads/builds/flashphoner_client/ \ No newline at end of file diff --git a/build.sh b/build.sh deleted file mode 100644 index e4b7e762..00000000 --- a/build.sh +++ /dev/null @@ -1,7 +0,0 @@ -#!/bin/sh -FULL_PATH=$0 -CURRENT_DIR=`dirname $FULL_PATH` -cd $CURRENT_DIR -cd builder -chmod +x builder.sh -./builder.sh \ No newline at end of file diff --git a/builder/builder.sh b/builder/builder.sh deleted file mode 100644 index 776daed9..00000000 --- a/builder/builder.sh +++ /dev/null @@ -1,29 +0,0 @@ -#!/bin/sh -. ./functions.lib - -cd $CURRENT_DIR - -echo "" > log -# check_root_access -# detect_java -# detect_ant - -echo "Start clients build..." -build_client "$CURRENT_DIR/../" -echo "Build clients complete" -echo "" -# echo "Start server build..." -# cd "$CURRENT_DIR/../$BUILD_XML_DIR" -# ant -# -# echo "Build server complete" -# echo "" - -cd "$CURRENT_DIR/../release" - -FOLDER_NAME=$(ls) - -echo "Creating archive of the build" -tar -cvf $FOLDER_NAME.tar.gz $FOLDER_NAME >& /dev/null -echo "FINISH" - diff --git a/builder/functions.lib b/builder/functions.lib deleted file mode 100644 index 4860491a..00000000 --- a/builder/functions.lib +++ /dev/null @@ -1,104 +0,0 @@ -#!/bin/sh -CURRENT_DIR=`pwd` -FLASHPHONER_API_DIR="client/api" -FLASHPHONER_CLIENT_DIR="client/client" -BUILD_XML_DIR="server/phone_app" - -check_root_access(){ - USERID=`id | sed -e 's/).*//; s/^.*(//;'` - if [ "X$USERID" != "Xroot" ]; then - echo "" - echo "ERROR: You must be logged in as the root user to install the Flashphoner." - echo "" - exit - fi -} - -detect_java(){ - echo "DETECTING java command..." - - JAVA_SYMLINK_BIN=`which java 2>/dev/null` - if ! test -f "$JAVA_SYMLINK_BIN" ; then - echo "" - echo "ERROR: The Java command (java) could not be found." - echo "Search path: $PATH" - echo "In most cases this problem can be fixed by adding a symbolic " - echo "link to the Java command in the /usr/bin directory. " - echo "To do this first execute the command \"which java\" to identify " - echo "the full path to the Java executable. Next, create a symbolic " - echo "link to this file with the command" - echo "\"ln -sf [path-to-java] /usr/bin/java\" where [path-to-java] is " - echo "the path returned by the \"which\" command." - echo "" - exit 0 - else - echo "- Java command found successfully." - fi - echo "" - - echo "DETECTING JVM architecture..." - java -version 2> tmp.jdk-version 1> /dev/null - JDK_VERSION=`cat tmp.jdk-version` - rm tmp.jdk-version - JVM_ARCH=`echo $JDK_VERSION | sed 's/.*\(...bit\).*/\1/i'` - JVM_ARCH_DIGIT=`echo $JVM_ARCH | sed 's/\([0-9]*\).*/\1/'` - echo "- $JVM_ARCH architecture detected successfully." - echo "" - - echo "DETECTING JDK home..." - JAVA_SYMLINK=`ls -l $JAVA_SYMLINK_BIN` - JDK_BIN=`echo $JAVA_SYMLINK | sed 's/.*->//'` - JDK_HOME=`echo $JDK_BIN | sed 's/\/bin.*//'` - if [ ! -f $JDK_HOME/include/jni.h ]; then - echo "- Can not find jni.h in JDK_HOME/include dir." - get_jdk_home () { - echo "- Please specify JDK_HOME path manually. File JDK_HOME/include/jni.h must exist." - read in - if [ ! -z "$in" ]; then - if [ ! -f $in/include/jni.h ]; then - echo "- Can not find jni.h in JDK_HOME/include dir." - get_jdk_home - fi - JDK_HOME=$in - echo "- JDK home detected successfully: $JDK_HOME" - else - echo "- Please do not enter a blank JDK home." - get_jdk_home - fi - } - get_jdk_home - else - echo "- JDK home detected successfully: $JDK_HOME." - fi - echo "" -} - -detect_ant(){ - echo "DETECTING ANT..." - - ANT_RESPONSE=$(ant 2>&1 | grep Buildfile) - if [ ! -n "$ANT_RESPONSE" ]; then - echo "- Error: ANT is not found" - exit - fi - echo "- ANT detected successfully." - echo "" -} - -build_client(){ - cd "$1$FLASHPHONER_API_DIR" - BUILD_RESPONSE=$(ant 2>&1 |tee -a $CURRENT_DIR"/log" 2>&1 | grep -i FAILED) - if [ -n "$BUILD_RESPONSE" ]; then - echo "Error. Build api was not created" - exit 0 - else - cd "$1$FLASHPHONER_CLIENT_DIR" - BUILD_RESPONSE=$(ant 2>&1|tee -a $CURRENT_DIR"/log" 2>&1 | grep -i FAILED) - if [ -n "$BUILD_RESPONSE" ]; then - echo "Error. Build client was not created" - exit 0 - else - echo "Build client has been created" - fi - fi -} diff --git a/client/api/.actionScriptProperties b/client/api/.actionScriptProperties deleted file mode 100644 index 4e4f3186..00000000 --- a/client/api/.actionScriptProperties +++ /dev/null @@ -1,20 +0,0 @@ - - - - - - - - - - - - - - - - - - - - diff --git a/client/api/.flexLibProperties b/client/api/.flexLibProperties deleted file mode 100644 index f38e47d4..00000000 --- a/client/api/.flexLibProperties +++ /dev/null @@ -1,37 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/client/api/.project b/client/api/.project deleted file mode 100644 index 5ff1b301..00000000 --- a/client/api/.project +++ /dev/null @@ -1,25 +0,0 @@ - - - api - - - - - - com.adobe.flexbuilder.project.flexbuilder - - - - - - com.adobe.flexbuilder.project.flexlibnature - com.adobe.flexbuilder.project.actionscriptnature - - - - bin-debug - 2 - DOCUMENTS/libs - - - diff --git a/client/api/.settings/org.eclipse.core.resources.prefs b/client/api/.settings/org.eclipse.core.resources.prefs deleted file mode 100644 index 93de40f2..00000000 --- a/client/api/.settings/org.eclipse.core.resources.prefs +++ /dev/null @@ -1,3 +0,0 @@ -#Wed Aug 18 17:12:19 NOVST 2010 -eclipse.preferences.version=1 -encoding/=UTF-8 diff --git a/client/api/.settings/org.eclipse.wst.html.core.prefs b/client/api/.settings/org.eclipse.wst.html.core.prefs deleted file mode 100644 index ba47ee12..00000000 --- a/client/api/.settings/org.eclipse.wst.html.core.prefs +++ /dev/null @@ -1,36 +0,0 @@ -#Wed Aug 18 17:18:46 NOVST 2010 -attrDuplicate=2 -attrInvalidName=2 -attrInvalidValue=2 -attrNameMismatch=2 -attrUndefName=2 -attrUndefValue=2 -attrValueMismatch=1 -attrValueUnclosed=2 -cdataInvalidContent=2 -cdataUnclosed=1 -commentInvalidContent=2 -commentUnclosed=1 -docDoctypeUnclosed=1 -docDuplicateTag=1 -docInvalidChar=2 -docInvalidContent=2 -eclipse.preferences.version=1 -elemCoexistence=2 -elemDuplicate=2 -elemEndInvalidCase=1 -elemInvalidContent=2 -elemInvalidDirective=1 -elemInvalidEmptyTag=2 -elemInvalidName=1 -elemMissingEnd=2 -elemMissingStart=1 -elemStartInvalidCase=2 -elemUnclosedEndTag=1 -elemUnclosedStartTag=1 -elemUnknownName=2 -elemUnnecessaryEnd=2 -piInvalidContent=2 -piUnclosed=1 -piUndefined=2 -refInvalidContent=2 diff --git a/client/api/build.properties b/client/api/build.properties deleted file mode 100644 index 92a259c7..00000000 --- a/client/api/build.properties +++ /dev/null @@ -1,3 +0,0 @@ -FLEX_HOME_WINDOWS=C:/Program Files/Adobe/Adobe Flash Builder 4/sdks/3.4 -FLEX_HOME_LINUX=/opt/flex -PLAYER_VERSION=11.0 \ No newline at end of file diff --git a/client/api/build.xml b/client/api/build.xml deleted file mode 100644 index 245ede45..00000000 --- a/client/api/build.xml +++ /dev/null @@ -1,56 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/client/api/src/com/flashphoner/Logger.as b/client/api/src/com/flashphoner/Logger.as deleted file mode 100644 index fea6b72c..00000000 --- a/client/api/src/com/flashphoner/Logger.as +++ /dev/null @@ -1,161 +0,0 @@ -/* -Copyright (c) 2011 Flashphoner -All rights reserved. This Code and the accompanying materials -are made available under the terms of the GNU Public License v2.0 -which accompanies this distribution, and is available at -http://www.gnu.org/licenses/old-licenses/gpl-2.0.html - -Contributors: - Flashphoner - initial API and implementation - -This code and accompanying materials also available under LGPL and MPL license for Flashphoner buyers. Other license versions by negatiation. Write us support@flashphoner.com with any questions. -*/ -package com.flashphoner -{ - - import com.flashphoner.api.data.PhoneConfig; - - import flash.system.Capabilities; - - public class Logger - { - [Bindable] - /** - * String which contain full logs. - **/ - public static var log:String = new String(); - - public static var SEVERITY:Object = new Object(); - - public static var SEVERITY_VALUE:int = 30; - - /** - * Default constructor - **/ - public static function init():void - { - SEVERITY["ERROR"]=10; - SEVERITY["WARN"]=20; - SEVERITY["INFO"]=30; - SEVERITY["DEBUG"]=40; - SEVERITY["TRACE"]=50; - SEVERITY_VALUE = SEVERITY[PhoneConfig.LOG_SEVERITY]; - trace("Init logger, SEVERITY: "+PhoneConfig.LOG_SEVERITY+" "+SEVERITY_VALUE); - } - - private static function getTime() : String - { - var dt : Date = new Date(); - var str : String = 'UTC ' + dt.getUTCMonth() + '.' + dt.getUTCDate() + ' ' + dt.getUTCHours() + ':' + dt.getUTCMinutes() + ':' + dt.getUTCSeconds() + '.' + dt.getUTCMilliseconds() + ': '; - return str; - } - - /** - * Add info message to log and output to trace - **/ - public static function info(str : String) : void - { - _log(str,"INFO"); - } - - /** - * Add debug message to log and output to trace - **/ - public static function debug(str : String) : void - { - _log(str,"DEBUG"); - } - - /** - * Add error message to log and output to trace - **/ - public static function error(str : String) : void - { - _log(str,"ERROR"); - } - - public static function warn(str : String) : void - { - _log(str,"WARN"); - - } - - public static function _trace(str : String) : void - { - _log(str,"TRACE"); - - } - - private static function _log(str:String,severity:String):void{ - if (SEVERITY[severity] <= SEVERITY_VALUE ){ - str = severity+': ' + getTime() + str + "\n"; - trace(str); - log += str + ''; - } - } - - public static function clear():void { - log = new String(); - } - - //merge two logs together based on time - public static function merge(logsJS:String):String { - //split logs to Arrays of Strings - var logsJSArray:Array = logsJS.split("\n"); - var logArray:Array = log.split("\n"); - - //create time pattern - var timePattern:RegExp = /[0-9]*:[0-9]*:[0-9]*\.[0-9]*/; - - //create new array and fill it with data - var resultingArray:Array = new Array(); - - var result:Array = new Array(); - var s:String; - - for each (s in logsJSArray) { - result = s.match(timePattern); - if (result != null) { - resultingArray.push([logTimeToInt(result[0]) , "[JS]\t" + s]); - } - } - - for each (s in logArray) { - result = s.match(timePattern); - if (result != null) { - resultingArray.push([logTimeToInt(result[0]), "[FLASH]\t" + s]); - } - } - - //sort array based on time - resultingArray.sortOn("0"); - - var resultingLogs:String = new String(); - var i:Array; - for each (i in resultingArray) { - resultingLogs += i[1] + "\n"; - } - - return resultingLogs; - } - - private static function logTimeToInt(s:String):int { - s = s.replace(/:/g, ""); - - var ms:String = s.substr(s.indexOf(".")); - var replaceStr:String = new String(""); - if(ms.length == 2) { - replaceStr = "00"; - } else if (ms.length == 3) { - replaceStr = "0"; - } - - s = s.replace(/\./, replaceStr); - var result:int = int(s); - return result; - } - - - - } -} diff --git a/client/api/src/com/flashphoner/api/Call.as b/client/api/src/com/flashphoner/api/Call.as deleted file mode 100644 index eddfd534..00000000 --- a/client/api/src/com/flashphoner/api/Call.as +++ /dev/null @@ -1,253 +0,0 @@ -/* -Copyright (c) 2011 Flashphoner -All rights reserved. This Code and the accompanying materials -are made available under the terms of the GNU Public License v2.0 -which accompanies this distribution, and is available at -http://www.gnu.org/licenses/old-licenses/gpl-2.0.html - -Contributors: - Flashphoner - initial API and implementation - -This code and accompanying materials also available under LGPL and MPL license for Flashphoner buyers. Other license versions by negatiation. Write us support@flashphoner.com with any questions. -*/ -package com.flashphoner.api -{ - import com.flashphoner.api.data.ModelLocator; - import com.flashphoner.api.data.PhoneConfig; - - import flash.events.TimerEvent; - import flash.utils.Timer; - - /** - * Class which contain data of call anf method for hangup,trasfer,hold. - **/ - [Bindable] - public class Call - { - - public static const STATE_RING:String = "RING"; - public static const STATE_HOLD:String = "HOLD"; - public static const STATE_TALK:String = "TALK"; - public static const STATE_FINISH:String = "FINISH"; - public static const STATE_BUSY:String = "BUSY"; - public static const STATE_SESSION_PROGRESS:String = "SESSION_PROGRESS"; - - - /** - * Video state of the call (sendrecv / recvonly etc.) - **/ - public var state_video:String; - - /** - * Identifier of call - **/ - public var id:String; - /** - * State of call (RING,HOLD,TALK,FINISH,BUSY,SESSION_PROGRESS) - **/ - public var state:String; - /** - * Flag on execute hold operation - * true - if user execute call.hold(true) - * false - if user execute call.hold(false) - **/ - public var iHolded:Boolean = false; - - /** - * Sip state of call - **/ - public var sip_state:String; - /** - * Not initiator of the call - **/ - public var callee:String; - /** - * Initiator of the call - **/ - public var caller:String; - /** - * Not initiators visible name of the call - **/ - public var visibleNameCallee:String; - /** - * Initiators visible name of the call - **/ - public var visibleNameCaller:String; - /** - * Player video format (CIF,QCIF) - **/ - public var playerVideoHeight:int; - - public var playerVideoWidth:int; - /** - * Streamer video format (CIF,QCIF) - **/ - public var streamerVideoHeight:int; - - public var streamerVideoWidth:int; - /** - * Time of call - **/ - public var timeOfCall:int = 0; - private var timer:Timer; - /** - * Another side logged user of call - **/ - public var anotherSideUser:String; - - /** - * Flag on incomming call - **/ - public var incoming:Boolean = false; - /** - * Flag on video call - **/ - public var isVideoCall:Boolean = false; - - public var isVideoSended:Boolean = false; - - private var callServerProxy:CallServerProxy; - - internal var flash_API:Flash_API; - - /** - * @param flash_API Api to be used for this call - **/ - public function Call(flash_API:Flash_API) - { - this.flash_API = flash_API; - callServerProxy = new CallServerProxy(this,flash_API.phoneServerProxy.nc); - } - /** - * Hangup this call - **/ - public function hangup():void{ - callServerProxy.unpublish(); - callServerProxy.hangup(); - SoundControl.stopRingSound(); - } - /** - * Change state of call (HOLD/TALK) - */ - public function setStatusHold(isHold:Boolean):void{ - if (state == Call.STATE_TALK || state == Call.STATE_HOLD){ - callServerProxy.hold(isHold); - } - } - - /** - * Transfer call to another user - * @param callee Target transfer call - **/ - public function transfer(callee:String):int{ - var modelLocator:ModelLocator = flash_API.modelLocator; - if (PhoneConfig.CHECK_VALIDATION_CALLEE){ - var reg:RegExp = /[a-zа-яё]/i; - if (callee != null && callee != ""){ - if ((callee.indexOf("sip:") == 0)){ - if (callee.indexOf("@") == -1 || callee.indexOf("@") == callee.length-1){ - return 1; - } - }else{ - if (callee.search(reg) != -1){ - if (callee.indexOf("@") != -1){ - return 1; - } - if (callee.indexOf(":") != -1){ - return 1; - } - callee = "sip:"+callee+"@"+modelLocator.domain+":"+modelLocator.port; - } - } - }else{ - return 1; - } - } - for each (var tempCall:Call in flash_API.calls){ - if (tempCall.state == Call.STATE_TALK && tempCall.id != id){ - tempCall.setStatusHold(true); - } - } - callServerProxy.transfer(callee); - SoundControl.stopRingSound(); - return 0; - } - - /** - * Answer on incoming call - * @param isVideoCall true - if answer with video (default - false). - **/ - public function answer(isVideoCall:Boolean = false):void{ - SoundControl.stopRingSound(); - for each (var tempCall:Call in flash_API.calls){ - if (tempCall.state == Call.STATE_TALK && tempCall.id != id){ - tempCall.setStatusHold(true); - } - } - callServerProxy.answer(isVideoCall); - } - /** - * Start/stop sending video to the server - * @param flag true - if start send video. - **/ - public function setSendVideo(flag:Boolean):void{ - callServerProxy.setSendVideo(flag); - } - - /** - * Send dtmf command to the sip provider - * @param dtmf DTMF command - **/ - public function sendDTMF(dtmf:String):void{ - callServerProxy.sendDtmf(dtmf); - } - - /** - * @private - * Publish video and audio streams - **/ - internal function publish():void{ - callServerProxy.publish(flash_API.modelLocator.login); - } - /** - * @private - * Unpublish video and audio streams - **/ - internal function unpublish():void{ - callServerProxy.unpublish(); - } - /** - * @private - * Start timer of call - **/ - internal function startTimer():void{ - if (timer!=null){ - timer.removeEventListener(TimerEvent.TIMER,timerHandler); - timer.stop(); - timer = null; - } - timeOfCall = 0; - timer = new Timer(999); - timer.addEventListener(TimerEvent.TIMER,timerHandler); - timer.start(); - } - - /** - * @private - * Stop timer of call - **/ - internal function stopTimer():void{ - timeOfCall = 0; - if (timer != null){ - timer.removeEventListener(TimerEvent.TIMER,timerHandler); - timer.stop(); - timer = null; - } - } - - private function timerHandler(timeEvent:TimerEvent):void{ - timeOfCall++; - } - - } -} diff --git a/client/api/src/com/flashphoner/api/CallCommand.as b/client/api/src/com/flashphoner/api/CallCommand.as deleted file mode 100644 index 3b5d2961..00000000 --- a/client/api/src/com/flashphoner/api/CallCommand.as +++ /dev/null @@ -1,92 +0,0 @@ -/* -Copyright (c) 2011 Flashphoner -All rights reserved. This Code and the accompanying materials -are made available under the terms of the GNU Public License v2.0 -which accompanies this distribution, and is available at -http://www.gnu.org/licenses/old-licenses/gpl-2.0.html - -Contributors: - Flashphoner - initial API and implementation - -This code and accompanying materials also available under LGPL and MPL license for Flashphoner buyers. Other license versions by negatiation. Write us support@flashphoner.com with any questions. -*/ -package com.flashphoner.api -{ - - import com.adobe.cairngorm.commands.ICommand; - import com.adobe.cairngorm.control.CairngormEvent; - import com.flashphoner.Logger; - import com.flashphoner.api.data.ModelLocator; - import com.flashphoner.api.data.PhoneConfig; - import com.flashphoner.api.management.VideoControl; - - import flash.events.*; - import flash.utils.*; - - internal class CallCommand implements ICommand - { - private var hangupTimer:Timer; - - public function CallCommand() - { - } - - private function getStreamName(modelLocator:ModelLocator, call:Call) : String - { - return "INCOMING_"+modelLocator.login+"_"+call.id; - } - - public function execute( event : CairngormEvent ) : void - { - Logger.info("PhoneCommand.execute() event.type "+event.type); - - var call:Call = (event as CallEvent).call; - var flashAPI:Flash_API = call.flash_API; - var modelLocator:ModelLocator = flashAPI.modelLocator; - - if (event.type==CallEvent.TALK){ - Logger.info("MainEvent.TALK "+call.id); - SoundControl.stopRingSound(); - - call.startTimer(); - call.publish(); - flashAPI.phoneServerProxy.phoneSpeaker.play(getStreamName(modelLocator, call), true); - } - - if (event.type==CallEvent.HOLD){ - call.unpublish(); - } - - if (event.type == CallEvent.SESSION_PROGRESS){ - Logger.info("MainEvent.SESSION_PROGRESS"); - SoundControl.stopRingSound(); - flashAPI.phoneServerProxy.phoneSpeaker.play(getStreamName(modelLocator, call), true); - } - - if (event.type==CallEvent.IN){ - SoundControl.playRingSound(); - flashAPI.phoneServerProxy.phoneSpeaker.play(getStreamName(modelLocator, call), false); - } - - if (event.type ==CallEvent.OUT){ - SoundControl.playRingSound(); - flashAPI.phoneServerProxy.phoneSpeaker.play(getStreamName(modelLocator, call), false); - } - - if (event.type == CallEvent.BUSY){ - SoundControl.playBusySound(); - SoundControl.stopRingSound(); - } - if (event.type == CallEvent.FINISH){ - SoundControl.playFinishSound(); - SoundControl.stopRingSound(); - - call.stopTimer(); - call.unpublish(); - flashAPI.removeCall(call.id); - flashAPI.phoneServerProxy.phoneSpeaker.stop(call.id); - } - - } - } -} diff --git a/client/api/src/com/flashphoner/api/CallEvent.as b/client/api/src/com/flashphoner/api/CallEvent.as deleted file mode 100644 index da6fcda9..00000000 --- a/client/api/src/com/flashphoner/api/CallEvent.as +++ /dev/null @@ -1,41 +0,0 @@ -/* -Copyright (c) 2011 Flashphoner -All rights reserved. This Code and the accompanying materials -are made available under the terms of the GNU Public License v2.0 -which accompanies this distribution, and is available at -http://www.gnu.org/licenses/old-licenses/gpl-2.0.html - -Contributors: - Flashphoner - initial API and implementation - -This code and accompanying materials also available under LGPL and MPL license for Flashphoner buyers. Other license versions by negatiation. Write us support@flashphoner.com with any questions. -*/ -package com.flashphoner.api -{ - import com.adobe.cairngorm.control.CairngormEvent; - - import flash.events.Event; - - /** - * Phone event - describe all phone events - * **/ - internal class CallEvent extends CairngormEvent - { - public static const IN:String = "IN"; - public static const OUT:String = "OUT"; - public static const TALK:String = "TALK"; - public static const HOLD:String = "HOLD"; - public static const BUSY:String = "BUSY"; - public static const FINISH:String = "FINISH"; - public static const SESSION_PROGRESS:String = "SESSION_PROGRESS"; - - public var call:Call; - - public function CallEvent(type:String,call:Call):void - { - super(type,bubbles,cancelable); - this.call = call; - } - - } -} diff --git a/client/api/src/com/flashphoner/api/CallServerProxy.as b/client/api/src/com/flashphoner/api/CallServerProxy.as deleted file mode 100644 index cb4d0e14..00000000 --- a/client/api/src/com/flashphoner/api/CallServerProxy.as +++ /dev/null @@ -1,149 +0,0 @@ -/* -Copyright (c) 2011 Flashphoner -All rights reserved. This Code and the accompanying materials -are made available under the terms of the GNU Public License v2.0 -which accompanies this distribution, and is available at -http://www.gnu.org/licenses/old-licenses/gpl-2.0.html - -Contributors: - Flashphoner - initial API and implementation - -This code and accompanying materials also available under LGPL and MPL license for Flashphoner buyers. Other license versions by negatiation. Write us support@flashphoner.com with any questions. -*/ -package com.flashphoner.api -{ - import com.flashphoner.Logger; - import com.flashphoner.api.data.PhoneConfig; - import com.flashphoner.api.management.VideoControl; - - import flash.events.AsyncErrorEvent; - import flash.events.NetStatusEvent; - import flash.media.Camera; - import flash.media.H264Profile; - import flash.media.H264VideoStreamSettings; - import flash.net.NetConnection; - import flash.net.NetStream; - import flash.net.Responder; - - internal class CallServerProxy - { - private var outStream:NetStream; - - private var nc:NetConnection; - private var flashCall:Call; - - private var sendVideo:Boolean = false; - - public function CallServerProxy(call:Call,nc:NetConnection) - { - this.nc = nc; - this.flashCall = call; - } - - public function sendDtmf(dtmf:String):void{ - Logger.info("CallServerProxy.sendDtmf() "+dtmf); - var dtmfObject:Object = new Object(); - dtmfObject.callId = flashCall.id; - dtmfObject.dtmf = dtmf; - nc.call("sendDtmf", null, dtmfObject); - } - - public function hangup():void{ - Logger.info("CallServerProxy.hangup() call.id: "+ flashCall.id); - nc.call("hangup", null, flashCall.id); - } - - public function transfer(callee:String):void{ - Logger.info("CallServerProxy.transfer() call.id: "+flashCall.id+";callee: "+callee); - var transferObject:Object = new Object(); - transferObject.callId = flashCall.id; - transferObject.callee = callee; - nc.call("transfer", null, transferObject); - } - - public function hold(isHold:Boolean):void{ - Logger.info("CallServerProxy.setStatusHold() call.id: "+flashCall.id+";isHold: "+isHold); - var holdObject:Object = new Object(); - holdObject.callId = flashCall.id; - holdObject.isHold = isHold; - nc.call("hold",null,holdObject); - } - - public function answer(isVideoCall:Boolean):void{ - Logger.info("CallServerProxy.answer() call.id: "+flashCall.id); - var answerObject:Object = new Object(); - answerObject.callId = flashCall.id; - answerObject.hasVideo = isVideoCall; - nc.call("answer",null,answerObject); - } - - public function publish(login:String):void{ - Logger.info("CallServerProxy.publish() login: "+login+";call.id: "+flashCall.id); - if (outStream == null){ - outStream = new NetStream(nc); - outStream.addEventListener(AsyncErrorEvent.ASYNC_ERROR,asyncErrorHandler); - outStream.addEventListener(NetStatusEvent.NET_STATUS,onNetStatus); - outStream.attachAudio(flashCall.flash_API.soundControl.getMicrophone()); - outStream.audioReliable = PhoneConfig.AUDIO_RELIABLE; - outStream.videoReliable = PhoneConfig.VIDEO_RELIABLE; - - if (PhoneConfig.VIDEO_ENABLED && sendVideo){ - setVideoCompressionSettings(outStream); - } - /* outStream.publish(login+"_"+flashCall.id); - WSP-1703 - Removed "login_" from stream name. No need now. - */ - outStream.publish((flashCall.incoming ? "0":"1") + "_" + flashCall.id); - } - } - - private function setVideoCompressionSettings(outStream:NetStream):void{ - if (PhoneConfig.MAJOR_PLAYER_VERSION >= 11 && PhoneConfig.AVOID_FLV2H264_TRANSCODING){ - Logger.info("Player 11. Using h.264 compresstion settings...") - var settings:flash.media.H264VideoStreamSettings= new flash.media.H264VideoStreamSettings(); - settings.setProfileLevel(H264Profile.BASELINE, flash.media.H264Level.LEVEL_3); - outStream.videoStreamSettings = settings; - } - var cam:Camera = flashCall.flash_API.videoControl.getCam(); - outStream.attachCamera(cam); - Logger.info("attach video stream: "+cam.width+"x"+cam.height); - } - - public function unpublish():void{ - Logger.info("CallServerProxy.unpublish() call.id: "+flashCall.id); - if (outStream != null){ - outStream.removeEventListener(AsyncErrorEvent.ASYNC_ERROR,asyncErrorHandler); - outStream.removeEventListener(NetStatusEvent.NET_STATUS,onNetStatus); - outStream.close(); - outStream=null; - } - } - public function setSendVideo(flag:Boolean):void{ - sendVideo = flag; - - if (outStream == null){ - return; - } - - if (PhoneConfig.VIDEO_ENABLED && sendVideo && flashCall != null){ - - if (flashCall.state_video != "sendrecv") { - nc.call("updateCallToVideo",null,flashCall.id); - } - - flashCall.isVideoSended = true; - setVideoCompressionSettings(outStream); - } - - if (!sendVideo){ - outStream.attachCamera(null); - } - } - - private function asyncErrorHandler(event: AsyncErrorEvent):void { - } - - private function onNetStatus(event : NetStatusEvent) : void{ - } - } -} diff --git a/client/api/src/com/flashphoner/api/Flash_API.as b/client/api/src/com/flashphoner/api/Flash_API.as deleted file mode 100644 index 52b32ecf..00000000 --- a/client/api/src/com/flashphoner/api/Flash_API.as +++ /dev/null @@ -1,709 +0,0 @@ -/* -Copyright (c) 2011 Flashphoner -All rights reserved. This Code and the accompanying materials -are made available under the terms of the GNU Public License v2.0 -which accompanies this distribution, and is available at -http://www.gnu.org/licenses/old-licenses/gpl-2.0.html - -Contributors: - Flashphoner - initial API and implementation - -This code and accompanying materials also available under LGPL and MPL license for Flashphoner buyers. Other license versions by negatiation. Write us support@flashphoner.com with any questions. -*/ - -package com.flashphoner.api -{ - import com.flashphoner.Logger; - import com.flashphoner.api.data.ErrorCodes; - import com.flashphoner.api.data.ModelLocator; - import com.flashphoner.api.data.PhoneConfig; - import com.flashphoner.api.interfaces.API; - import com.flashphoner.api.interfaces.APINotify; - import com.flashphoner.api.js.APINotifyJS; - import com.flashphoner.api.management.VideoControl; - - import flash.events.TimerEvent; - import flash.external.ExternalInterface; - import flash.media.Camera; - import flash.media.Microphone; - import flash.net.Responder; - import flash.net.SharedObject; - import flash.system.Security; - import flash.utils.Timer; - - import mx.collections.ArrayCollection; - - [Bindable] - public class Flash_API - { - private var registeredTimer:Timer; - /** - * @private - **/ - internal var phoneServerProxy:PhoneServerProxy; - /** - * List of calls - **/ - public var calls:ArrayCollection; - /** - * @private - * Notifier added by addNotify() - **/ - public static var apiNotifys:ArrayCollection; - /** - * Data about logged user - **/ - public var modelLocator:ModelLocator; - - /** - * management sounds and microphone - **/ - public var soundControl:SoundControl; - - /** - * Control of video - **/ - public var videoControl:VideoControl; - - /** - * - * Initialize parameters from 'flashphoner.xml' and another - **/ - public static function initLibrary():void{ - PhoneModel.getInstance(); - } - /** - * Default contructor. - * Initialize calls,modelLocato and initialize library - */ - public function Flash_API(apiNotify:APINotify){ - Security.allowDomain("*"); - Logger.init(); - apiNotifys = new ArrayCollection(); - addAPINotify(apiNotify); - PhoneModel.getInstance(); - ExternalInterface.addCallback("getParameters",getParameters); - ExternalInterface.addCallback("login",login); - ExternalInterface.addCallback("loginByToken",loginByToken); - ExternalInterface.addCallback("logoff",logoff); - ExternalInterface.addCallback("getInfoAboutMe",getInfoAboutMe); - ExternalInterface.addCallback("sendMessage",sendMessage); - ExternalInterface.addCallback("notificationResult",notificationResult); - ExternalInterface.addCallback("call",call); - ExternalInterface.addCallback("callByToken",callByToken); - ExternalInterface.addCallback("msrpCall",msrpCall); - ExternalInterface.addCallback("hangup",hangup); - ExternalInterface.addCallback("answer",answer); - ExternalInterface.addCallback("subscribe",subscribe); - ExternalInterface.addCallback("sendDTMF",sendDTMF); - ExternalInterface.addCallback("setStatusHold",setStatusHold); - ExternalInterface.addCallback("transfer",transfer); - ExternalInterface.addCallback("setSendVideo",setSendVideo); - ExternalInterface.addCallback("getMicVolume",getMicVolume); - ExternalInterface.addCallback("setMicVolume",setMicVolume); - ExternalInterface.addCallback("getVolume",getVolume); - ExternalInterface.addCallback("setVolume",setVolume); - ExternalInterface.addCallback("hasAccessToAudio",hasAccessToAudio); - ExternalInterface.addCallback("hasAccessToVideo",hasAccessToVideo); - ExternalInterface.addCallback("getMicropones",getMicropones); - ExternalInterface.addCallback("setMicrophone",setMicrophone); - ExternalInterface.addCallback("getCameras",getCameras); - ExternalInterface.addCallback("setCamera",setCamera); - ExternalInterface.addCallback("getCurrentCall",getCurrentCall); - ExternalInterface.addCallback("setCookie",setCookie); - ExternalInterface.addCallback("getCookie",getCookie); - ExternalInterface.addCallback("getVersion",getVersion); - ExternalInterface.addCallback("sendInfo",sendInfo); - ExternalInterface.addCallback("setSpeexQuality",setSpeexQuality); - ExternalInterface.addCallback("playSound",playSound); - ExternalInterface.addCallback("stopSound", stopSound); - ExternalInterface.addCallback("pushLogs", pushLogs); - ExternalInterface.addCallback("sendXcapRequest", sendXcapRequest); - ExternalInterface.addCallback("openSettingsPanel",openSettingsPanel); - ExternalInterface.addCallback("submitBugReport",submitBugReport); - ExternalInterface.addCallback("setLTState",setLTState); - calls = new ArrayCollection(); - modelLocator = new ModelLocator(); - phoneServerProxy = new PhoneServerProxy(new Responder(result),this); - - } - - public function initMedia():void{ - Logger.info("Init media..."); - soundControl = new SoundControl(this); - videoControl = new VideoControl(); - } - - /** - * Hangup call by id - * @param callId Identifier of call - **/ - public function hangup(callId:String):void{ - var call:Call = getCallById(callId); - if (call != null){ - call.hangup(); - } - } - - /** - * Answer call by id - * @param callId Identifier of call - * @param isVideoCall video call?(true/false) - **/ - public function answer(callId:String, isVideoCall:Boolean = false):void{ - var call:Call = getCallById(callId); - if (call != null){ - call.answer(isVideoCall); - } - } - - /** - * Send dtmf to voip server - * @param callId Identifier of call - * @param dtmf command for dtmf - **/ - public function sendDTMF(callId:String,dtmf:String):void{ - var call:Call = getCallById(callId); - if (call != null){ - call.sendDTMF(dtmf); - } - } - - /** - * Hold/Unhold call - * @param callId Identifier of call - * @param isHold true, if set state hold - **/ - public function setStatusHold(callId:String,isHold:Boolean = true):void{ - Logger.info("setStatusHold; callId - " + callId + "; isHold - " + isHold); - var call:Call = getCallById(callId); - if (call != null){ - call.setStatusHold(isHold); - } - } - - /** - * Transfer call - * @param callId Identifier of call - * @param target target for transfer call - **/ - public function transfer(callId:String,target:String):void{ - var call:Call = getCallById(callId); - if (call != null){ - call.transfer(target); - } - } - - /** - * Start/stop video stream - * @param isSend true, if start(true/false) - **/ - public function setSendVideo(callId:String, isSend:Boolean):void{ - var call:Call = getCallById(callId); - if (call != null){ - call.setSendVideo(isSend); - } - } - - /** - * Get current call in TALK-state - **/ - public function getCurrentCall():Call{ - for each(var obj:* in calls){ - if (obj.state == Call.STATE_TALK){ - return Call(obj); - } - } - return null; - } - - /** - * Get call by indetifier - * @param callId Identifier of call - **/ - public function getCallById(callId:String):Call{ - for each(var obj:* in calls){ - if (obj.id == callId){ - return Call(obj); - } - } - return null; - } - - /** - * Get call by index - * @param index Index in calls collection - **/ - public function getCallByIndex(index:Number):Call{ - var obj:* = calls.getItemAt(index); - if (obj != null){ - return Call(obj); - } - return null; - } - - /** - * Get index by call identifier - * @param callId Identifier of call - * @return -1 - if call not found - **/ - public function getIndexByCallId(callId:String):Number{ - for (var index:* in calls){ - var obj:* = calls.getItemAt(index); - if (obj.id == callId){ - return index; - } - } - return -1; - } - - /** - * @private - * Add call to calls collection - **/ - internal function addCall(call:Call):void{ - for (var index:* in calls){ - var obj:* = calls.getItemAt(index); - if (obj.id == call.id){ - return; - } - } - calls.addItem(call); - for each (var apiNotify:APINotify in apiNotifys){ - apiNotify.notifyAddCall(call); - } - } - /** - * @private - * Remove call from calls collection - * @param callId Identifier of call - **/ - internal function removeCall(callId:String):void{ - var hasTalkState:Boolean = false; - for (var index:* in calls){ - var obj:* = calls.getItemAt(index); - if (obj.id == callId){ - for each (var apiNotify:APINotify in apiNotifys){ - apiNotify.notifyRemoveCall(Call(obj)); - } - calls.removeItemAt(index); - } else if (obj.state == Call.STATE_TALK){ - hasTalkState = true; - } - } - if (!hasTalkState){ - for each (var call:Call in calls){ - if (call.state == Call.STATE_HOLD){ - if (call.iHolded){ - call.setStatusHold(false); - } - } - - } - } - } - - /** - * Get controller of speaker - **/ - public function getPhoneSpeaker():PhoneSpeaker{ - return this.phoneServerProxy.phoneSpeaker; - } - - /** - * Add notifier to api - * @param apiNotify Object will be implemented APINotify - **/ - public function addAPINotify(apiNotify:APINotify):void{ - Flash_API.apiNotifys.addItem(apiNotify); - } - /** - * Get parameters from file 'flashphoner.xml' - **/ - public function getParameters():Object{ - var object:Object = PhoneModel.getInstance().parameters; - if (object == null){ - return ErrorCodes.PARAMETERS_IS_NOT_INITIALIZED; - }else{ - return PhoneModel.getInstance().parameters; - } - } - - /** - * Get full version of server - **/ - public function getVersion():String{ - return PhoneConfig.getFullVersion(); - } - - /** - * Authentication on sip provider server on "flashphoner" mode - * @param username sip format username (example: sip:...) - * @param password Password for user - **/ - public function login(loginObject:Object, WCSUrl:String):int{ - videoControl.init(); - return phoneServerProxy.login(loginObject, WCSUrl); - } - - /** - * Authentication on sip provider server on "flashphoner" mode with token - * @param token Token for auth server - * @param password Password for user - **/ - public function loginByToken(WCSUrl:String, token:String = null, pageUrl:String = null):void{ - - /** - * pageUrl need here by that reason = WSP-1855 "Problem with pageUrl in Firefox" - * if client broswer is Firefox, default pageUrl not works, and we send from js special pageUrl - */ - Logger.info("loginByToken: " + token + ", pageUrl: " + pageUrl); - var obj:Object = {}; - obj.token = token; - obj.pageUrl = pageUrl; - - videoControl.init(); - phoneServerProxy.login(obj, WCSUrl); - } - - /** - * Create new call - * @param callee login of user - target call - * @param visibleName name of logged user wich target user see - * @param isVideoCall video call?(true/false) - **/ - public function call(callObject:Object):int{ - if (PhoneConfig.CHECK_VALIDATION_CALLEE){ - var reg:RegExp = /[a-zа-яё]/i; - var callee = callObject.callee; - if (callee != null && callee != ""){ - if ((callee.indexOf("sip:") == 0)){ - if (callee.indexOf("@") == -1 || callee.indexOf("@") == callee.length-1){ - return 1; - } - }else if (callee.indexOf("tel:") == 0){ - if (callee.substring(4).search(reg) != -1){ - return 1; - } - }else{ - if (callee.search(reg) != -1){ - if (callee.indexOf("@") != -1){ - return 1; - } - if (callee.indexOf(":") != -1){ - return 1; - } - callObject.callee = "sip:"+callee+"@"+modelLocator.domain+":"+modelLocator.port; - } - } - }else{ - return 1; - } - } - if (callObject.visibleName != null){ - callObject.visibleName.replace("\"",""); - callObject.visibleName.replace("'",""); - } - for each (var tempCall:Call in calls){ - if (tempCall.state == Call.STATE_TALK){ - tempCall.setStatusHold(true); - } - } - phoneServerProxy.call(callObject); - return 0; - } - - /** - * Create new call by URL - * @param isVideoCall video call?(true/false) - **/ - public function callByToken(callObject:Object):int{ - phoneServerProxy.callByToken(callObject); - return 0; - } - - /** - * Create new msrp call - * @param call object - **/ - public function msrpCall(callObject:Object):int{ - phoneServerProxy.msrpCall(callObject); - return 0; - } - - /** - * Get information about logged user - **/ - public function getInfoAboutMe():ModelLocator{ - return modelLocator; - } - - /** - * Get state of flash_api - * @return boolean of initialized state - **/ - public function isInitialized():Boolean{ - return PhoneModel.getInstance().initialized; - } - - /** - * Get volume of current microphone - * @return volume interval 1-100 - **/ - public function getMicVolume():int{ - var mic:Microphone = soundControl.getMicrophone(); - if (mic == null){ - return 0; - }else{ - return mic.gain; - } - - } - - /** - * Set volume for current microphone - * @param volume interval 1-100 - **/ - public function setMicVolume(volume:int):void{ - var mic:Microphone = soundControl.getMicrophone(); - if (mic != null){ - mic.gain = volume; - } - } - - /** - * Get volume of speakers - * @return volume interval 1-100 - **/ - public function getVolume():int{ - return phoneServerProxy.phoneSpeaker.getVolume(); - } - - /** - * Set volume for speakers - * @param volume interval 1-100 - **/ - public function setVolume(volume:int):void{ - phoneServerProxy.phoneSpeaker.setVolume(volume); - } - - /** - * Get list of microphones - **/ - public function getMicropones():Array{ - return Microphone.names; - } - - /** - * Set current microphone - * @param name name of microphone - **/ - public function setMicrophone(name:String):void{ - var i:int = 0; - for each (var nameMic:String in Microphone.names){ - if (nameMic == name){ - soundControl.changeMicrophone(i,false); - return; - } - i++; - } - } - - /** - * Check access to the devices (mic,camera) - **/ - public function hasAccessToAudio():Boolean{ - return soundControl.isMuted() == -1; - } - - /** - * Check access to the devices (mic,camera) - **/ - public function hasAccessToVideo():Boolean{ - return videoControl.isMuted() == -1; - } - - - /** - * Get list of cameras - **/ - public function getCameras():Array{ - return Camera.names; - } - - /** - * Set current camera - * @param name name of camera - **/ - public function setCamera(name:String):void{ - videoControl.changeCamera(Camera.getCamera(name)); - } - - /** - * Log off from the server and close connection - **/ - public function logoff():void{ - phoneServerProxy.disconnect(); - } - - /** - * Get cookie from flash - * @param key Key of the parameter - **/ - public function getCookie(key:String):String{ - var localSharedObject:SharedObject = SharedObject.getLocal("Flashphoner"); - if (localSharedObject!=null){ - return localSharedObject.data[key]; - } - return null; - } - - /** - * Set cookie to flash - * @param key Key of the parameter - * @param value Value of the parameter - **/ - public function setCookie(key:String,value:String):void{ - var localSharedObject:SharedObject = SharedObject.getLocal("Flashphoner"); - if (localSharedObject!=null){ - localSharedObject.setProperty(key,value); - } - } - - /** - * @private - **/ - internal function startRegisterTimer():void{ - registeredTimer.start(); - } - - - /** - * @private - * Start timer for REGISTER_EXPIRE error - **/ - internal function upRegisteredTimer():void{ - if (registeredTimer!=null){ - registeredTimer.stop(); - } else { - registeredTimer = new Timer(15000); - registeredTimer.addEventListener(TimerEvent.TIMER,registeredExpire); - } - } - - /** - * @private - * Stop timer for REGISTER_EXPIRE error - **/ - internal function dropRegisteredTimer():void{ - if (registeredTimer!=null){ - registeredTimer.stop(); - registeredTimer.removeEventListener(TimerEvent.TIMER,registeredExpire); - registeredTimer=null; - } - } - - /** - * Handler on registerTimer - **/ - private function registeredExpire(event:TimerEvent):void{ - for each (var apiNotify:APINotify in apiNotifys){ - apiNotify.notifyError(ErrorCodes.REGISTER_EXPIRE); - } - dropRegisteredTimer(); - } - /** - * Impementation for Responder - **/ - private function result(_call : Object) : void - { - var call:Call = new Call(this); - call.id = _call.id; - call.state = _call.state; - call.incoming=false; - call.callee = _call.callee; - call.anotherSideUser = _call.callee; - addCall(call); - } - - /** - * Send instance message to the user - * @param to target of the message - * @param body content of the message - * @param contentType type of content - **/ - public function sendMessage(msg:Object):void{ - this.phoneServerProxy.sendInstantMessage(msg); - } - - /** - * Send instance message to the user - * @param instantMessage - **/ - public function sendInstantMessage(instantMessage:InstantMessage):void{ - this.phoneServerProxy.sendInstantMessage(instantMessage); - } - - public function notificationResult(notificationResult:Object):void{ - Logger.info("notificationResult "+notificationResult); - this.phoneServerProxy.notificationResult(notificationResult); - } - - public function sendInfo(infoObj:Object):void { - this.phoneServerProxy.sendInfo(infoObj); - } - - public function setSpeexQuality(quality:int):void{ - soundControl.setSpeexQuality(quality); - } - - /** - * Added for compatibility with WebRTC implementation - **/ - public function playSound(sound:String):void{ - Logger.info("Received request to play sound " + sound); - } - - public function stopSound(sound:String):void{ - Logger.info("Received request to stop sound " + sound); - } - - public function pushLogs(logs:String):Boolean { - //check if push_log enabled - if (PhoneConfig.PUSH_LOG) { - var pushResult:Boolean = phoneServerProxy.pushLogs(logs); - return pushResult; - } else { - return false; - } - } - - - public function subscribe(subscribeObj:Object):void{ - this.phoneServerProxy.subscribe(subscribeObj); - } - - public function sendXcapRequest(xcapUrl:String):void{ - this.phoneServerProxy.sendXcapRequest(xcapUrl); - } - - public function openSettingsPanel():void{ - Security.showSettings(); - } - - public function submitBugReport(reportObj:Object):Boolean { - phoneServerProxy.submitBugReport(reportObj); - return true; - } - - public function pong():void { - phoneServerProxy.pong(); - } - - public function setLTState(state:String):void{ - var obj:Object = new Object(); - obj.state = state; - this.phoneServerProxy.setLTState(obj); - } - } -} diff --git a/client/api/src/com/flashphoner/api/InstantMessage.as b/client/api/src/com/flashphoner/api/InstantMessage.as deleted file mode 100644 index 0f355ab6..00000000 --- a/client/api/src/com/flashphoner/api/InstantMessage.as +++ /dev/null @@ -1,44 +0,0 @@ -/* -Copyright (c) 2011 Flashphoner -All rights reserved. This Code and the accompanying materials -are made available under the terms of the GNU Public License v2.0 -which accompanies this distribution, and is available at -http://www.gnu.org/licenses/old-licenses/gpl-2.0.html - -Contributors: - Flashphoner - initial API and implementation - -This code and accompanying materials also available under LGPL and MPL license for Flashphoner buyers. Other license versions by negatiation. Write us support@flashphoner.com with any questions. -*/ -package com.flashphoner.api -{ - public class InstantMessage - { - - public function InstantMessage() - { - } - - public var from:String; - - - /** - * Target of the message - **/ - public var to:String; - - /** - * Content of the message - **/ - public var body:String; - - /** - * Type of content - **/ - public var contentType:String; - - public var recipients:String; - - public var deliveryNotification:String; - } -} diff --git a/client/api/src/com/flashphoner/api/MainCommand.as b/client/api/src/com/flashphoner/api/MainCommand.as deleted file mode 100644 index 7db734d9..00000000 --- a/client/api/src/com/flashphoner/api/MainCommand.as +++ /dev/null @@ -1,75 +0,0 @@ -/* -Copyright (c) 2011 Flashphoner -All rights reserved. This Code and the accompanying materials -are made available under the terms of the GNU Public License v2.0 -which accompanies this distribution, and is available at -http://www.gnu.org/licenses/old-licenses/gpl-2.0.html - -Contributors: - Flashphoner - initial API and implementation - -This code and accompanying materials also available under LGPL and MPL license for Flashphoner buyers. Other license versions by negatiation. Write us support@flashphoner.com with any questions. -*/ -package com.flashphoner.api -{ - - import com.adobe.cairngorm.commands.ICommand; - import com.adobe.cairngorm.control.CairngormEvent; - import com.flashphoner.Logger; - import com.flashphoner.api.data.ModelLocator; - import com.flashphoner.api.data.PhoneConfig; - - import flash.events.*; - import flash.utils.*; - - import mx.collections.ArrayCollection; - - internal class MainCommand implements ICommand - { - private var hangupTimer:Timer; - - public function MainCommand() - { - } - - public function execute( event : CairngormEvent ) : void - { - Logger.info("PhoneCommand.execute() event.type "+event.type); - - var flashAPI:Flash_API = (event as MainEvent).flashAPI; - var modelLocator:ModelLocator = flashAPI.modelLocator; - - if (event.type == MainEvent.CONNECTED){ - if (!PhoneConfig.REGISTER_REQUIRED){ - modelLocator.logged = true; - SoundControl.playRegisterSound(); - } - } - if (event.type == MainEvent.REGISTERED){ - modelLocator.logged = true; - flashAPI.dropRegisteredTimer(); - SoundControl.playRegisterSound(); - } - - if (event.type == MainEvent.DISCONNECT){ - SoundControl.stopRingSound(); - modelLocator.logged = false; - modelLocator.login = null; - modelLocator.pwd = null; - flashAPI.calls = new ArrayCollection(); - } - - if (event.type == MainEvent.AUDIO_CODEC_CHANGED_EVENT){ - var codec:Object = (event as MainEvent).obj; - flashAPI.soundControl.changeAudioCodec(codec); - } - - if (event.type == MainEvent.VIDEO_FORMAT_CHANGED){ - var mediaFormat:Object = (event as MainEvent).obj; - flashAPI.videoControl.changeFormat(mediaFormat.streamerVideoWidth,mediaFormat.streamerVideoHeight); - //flashAPI.phoneServerProxy.phoneSpeaker.changeFormat(call.playerVideoWidth,call.playerVideoHeight); - } - - } - } -} diff --git a/client/api/src/com/flashphoner/api/MainEvent.as b/client/api/src/com/flashphoner/api/MainEvent.as deleted file mode 100644 index 2d82f8f4..00000000 --- a/client/api/src/com/flashphoner/api/MainEvent.as +++ /dev/null @@ -1,41 +0,0 @@ -/* -Copyright (c) 2011 Flashphoner -All rights reserved. This Code and the accompanying materials -are made available under the terms of the GNU Public License v2.0 -which accompanies this distribution, and is available at -http://www.gnu.org/licenses/old-licenses/gpl-2.0.html - -Contributors: - Flashphoner - initial API and implementation - -This code and accompanying materials also available under LGPL and MPL license for Flashphoner buyers. Other license versions by negatiation. Write us support@flashphoner.com with any questions. -*/ -package com.flashphoner.api -{ - import com.adobe.cairngorm.control.CairngormEvent; - - import flash.events.Event; - - /** - * Phone event - describe all phone events - * **/ - internal class MainEvent extends CairngormEvent - { - public static const CONNECTED:String = "CONNECTED"; - public static const REGISTERED:String = "REGISTERED"; - public static const DISCONNECT:String = "DISCONNECT"; - public static const MESSAGE_ACCEPTED:String = "MESSAGE_ACCEPTED"; - public static const VIDEO_FORMAT_CHANGED:String = "VIDEO_FORMAT_CHANGED"; - public static const AUDIO_CODEC_CHANGED_EVENT:String = "AUDIO_CODEC_CHANGED_EVENT"; - - public var flashAPI:Flash_API; - public var obj:Object; - - public function MainEvent(type:String, flashAPI:Flash_API):void - { - super(type); - this.flashAPI = flashAPI; - } - - } -} diff --git a/client/api/src/com/flashphoner/api/MessageCommand.as b/client/api/src/com/flashphoner/api/MessageCommand.as deleted file mode 100644 index 6ae795ec..00000000 --- a/client/api/src/com/flashphoner/api/MessageCommand.as +++ /dev/null @@ -1,50 +0,0 @@ -/* -Copyright (c) 2011 Flashphoner -All rights reserved. This Code and the accompanying materials -are made available under the terms of the GNU Public License v2.0 -which accompanies this distribution, and is available at -http://www.gnu.org/licenses/old-licenses/gpl-2.0.html - -Contributors: - Flashphoner - initial API and implementation - -This code and accompanying materials also available under LGPL and MPL license for Flashphoner buyers. Other license versions by negatiation. Write us support@flashphoner.com with any questions. -*/ -package com.flashphoner.api -{ - - import com.adobe.cairngorm.commands.ICommand; - import com.adobe.cairngorm.control.CairngormEvent; - import com.flashphoner.Logger; - import com.flashphoner.api.data.ModelLocator; - import com.flashphoner.api.data.PhoneConfig; - import com.flashphoner.api.interfaces.APINotify; - - import flash.events.*; - import flash.utils.*; - - import mx.collections.ArrayCollection; - - internal class MessageCommand implements ICommand - { - - public function MessageCommand() - { - } - - public function execute( event : CairngormEvent ) : void - { - Logger.info("MessageCommand.execute() event.type "+event.type); - - var messageEvent:MessageEvent = event as MessageEvent; - var flashAPI:Flash_API = messageEvent.flashAPI; - if (event.type == MessageEvent.MESSAGE_EVENT){ - for each (var apiNotify:APINotify in Flash_API.apiNotifys){ - apiNotify.notifyMessage(messageEvent.messageObj,messageEvent.notificationResult,messageEvent.sipObject); - } - } - - - } - } -} diff --git a/client/api/src/com/flashphoner/api/MessageEvent.as b/client/api/src/com/flashphoner/api/MessageEvent.as deleted file mode 100644 index 7333e949..00000000 --- a/client/api/src/com/flashphoner/api/MessageEvent.as +++ /dev/null @@ -1,39 +0,0 @@ -/* -Copyright (c) 2011 Flashphoner -All rights reserved. This Code and the accompanying materials -are made available under the terms of the GNU Public License v2.0 -which accompanies this distribution, and is available at -http://www.gnu.org/licenses/old-licenses/gpl-2.0.html - -Contributors: - Flashphoner - initial API and implementation - -This code and accompanying materials also available under LGPL and MPL license for Flashphoner buyers. Other license versions by negatiation. Write us support@flashphoner.com with any questions. -*/ -package com.flashphoner.api -{ - import com.adobe.cairngorm.control.CairngormEvent; - - import flash.events.Event; - - /** - * Message event - describe all phone events - * **/ - internal class MessageEvent extends CairngormEvent - { - public static const MESSAGE_EVENT:String = "MESSAGE_EVENT"; - - public var flashAPI:Flash_API; - public var messageObj:Object; - public var notificationResult:Object; - public var sipObject:Object; - - public function MessageEvent(type:String,messageObj:Object, flashAPI:Flash_API ):void - { - super(type,bubbles,cancelable); - this.messageObj = messageObj; - this.flashAPI = flashAPI; - } - - } -} diff --git a/client/api/src/com/flashphoner/api/PhoneCallback.as b/client/api/src/com/flashphoner/api/PhoneCallback.as deleted file mode 100644 index 5fb2b3ec..00000000 --- a/client/api/src/com/flashphoner/api/PhoneCallback.as +++ /dev/null @@ -1,251 +0,0 @@ -/* -Copyright (c) 2011 Flashphoner -All rights reserved. This Code and the accompanying materials -are made available under the terms of the GNU Public License v2.0 -which accompanies this distribution, and is available at -http://www.gnu.org/licenses/old-licenses/gpl-2.0.html - -Contributors: - Flashphoner - initial API and implementation - -This code and accompanying materials also available under LGPL and MPL license for Flashphoner buyers. Other license versions by negatiation. Write us support@flashphoner.com with any questions. -*/ -package com.flashphoner.api -{ - - import com.adobe.cairngorm.control.CairngormEventDispatcher; - import com.flashphoner.Logger; - import com.flashphoner.api.data.ErrorCodes; - import com.flashphoner.api.data.ModelLocator; - import com.flashphoner.api.data.PhoneConfig; - import com.flashphoner.api.interfaces.APINotify; - - import flash.external.ExternalInterface; - import flash.net.NetConnection; - import flash.net.NetStream; - - public class PhoneCallback - { - private var flash_API:Flash_API; - public function PhoneCallback(flashAPI:Flash_API) - { - this.flash_API = flashAPI; - } - - public function ping():void{ - this.flash_API.pong(); - } - - public function notifyBalance(balance:Number,_sipObject:Object):void{ - for each (var apiNotify:APINotify in Flash_API.apiNotifys){ - apiNotify.notifyBalance(balance,_sipObject); - } - } - - public function notifyBugReport(filename:String):void{ - for each (var apiNotify:APINotify in Flash_API.apiNotifys){ - apiNotify.notifyBugReport(filename); - } - } - - public function getVersion(version:String):void{ - PhoneConfig.VERSION_OF_SERVER = version; - for each (var apiNotify:APINotify in Flash_API.apiNotifys){ - apiNotify.notifyVersion(PhoneConfig.getFullVersion()); - } - } - - public function getUserData(resObj:Object):void{ - var modelLocator:ModelLocator = flash_API.modelLocator; - modelLocator.login = resObj.login; - modelLocator.pwd = resObj.password; - modelLocator.outboundProxy = resObj.outboundProxy; - modelLocator.domain = resObj.domain; - modelLocator.port = resObj.port; - - PhoneConfig.REGISTER_REQUIRED = resObj.regRequired; - ExternalInterface.call("notifyRegisterRequired",PhoneConfig.REGISTER_REQUIRED); - if (PhoneConfig.REGISTER_REQUIRED){ - flash_API.upRegisteredTimer(); - flash_API.startRegisterTimer(); - } - } - - public function fail(errorCode:String,_sipObject:Object):void{ - Logger.info("PhoneCallback.fail() "+errorCode); - if (errorCode == ErrorCodes.AUTHENTICATION_FAIL || errorCode == ErrorCodes.SIP_PORTS_BUSY){ - flash_API.dropRegisteredTimer(); - } - for each (var apiNotify:APINotify in Flash_API.apiNotifys){ - apiNotify.notifyError(errorCode,_sipObject); - } - } - - public function close():void{ - } - - public function registered(_sipObject:Object):void{ - for each (var apiNotify:APINotify in Flash_API.apiNotifys){ - apiNotify.notifyRegistered(_sipObject); - } - CairngormEventDispatcher.getInstance().dispatchEvent(new MainEvent(MainEvent.REGISTERED,flash_API)); - } - - public function ring(_call:Object,_sipObject:Object):void{ - var call:Call = process(_call); - for each (var apiNotify:APINotify in Flash_API.apiNotifys){ - apiNotify.notify(call,_sipObject); - } - if (!call.incoming){ - CairngormEventDispatcher.getInstance().dispatchEvent(new CallEvent(CallEvent.OUT,call)); - } else { - CairngormEventDispatcher.getInstance().dispatchEvent(new CallEvent(CallEvent.IN,call)); - } - } - - public function sessionProgress(_call:Object,_sipObject:Object):void{ - var call:Call = process(_call); - CairngormEventDispatcher.getInstance().dispatchEvent(new CallEvent(CallEvent.SESSION_PROGRESS,call)); - } - - public function talk(_call:Object,_sipObject:Object):void{ - var call:Call = process(_call); - for each (var apiNotify:APINotify in Flash_API.apiNotifys){ - apiNotify.notify(call,_sipObject); - } - CairngormEventDispatcher.getInstance().dispatchEvent(new CallEvent(CallEvent.TALK,call)); - } - - public function hold(_call:Object, _sipObject:Object):void{ - var call:Call = process(_call); - for each (var apiNotify:APINotify in Flash_API.apiNotifys){ - apiNotify.notify(call,_sipObject); - } - CairngormEventDispatcher.getInstance().dispatchEvent(new CallEvent(CallEvent.HOLD,call)); - } - - // Notify about CIF 352x288 or QCIF 176x144 video format - public function notifyVideoFormat(videoFormat:Object):void{ - for each (var apiNotify:APINotify in Flash_API.apiNotifys){ - apiNotify.notifyVideoFormat(videoFormat); - } - var event:MainEvent = new MainEvent(MainEvent.VIDEO_FORMAT_CHANGED, flash_API); - event.obj = videoFormat; - CairngormEventDispatcher.getInstance().dispatchEvent(event); - } - - public function onVideoPlay(_call:Object, play:Boolean):void{ - var call:Call = process(_call); - for each (var apiNotify:APINotify in Flash_API.apiNotifys){ - apiNotify.notifyOpenVideoView(play); - } - } - - public function callbackHold(callId:String, isHold:Boolean):void{ - var call:Call = flash_API.getCallById(callId); - call.iHolded = isHold; - if (!isHold){ - for each (var tempCall:Call in flash_API.calls){ - if (tempCall.state == Call.STATE_TALK && tempCall.id != call.id){ - tempCall.setStatusHold(true); - } - } - } - for each (var apiNotify:APINotify in Flash_API.apiNotifys){ - apiNotify.notifyCallbackHold(call,isHold); - } - } - - public function busy(_call:Object,_sipObject:Object):void{ - var call:Call = process(_call); - for each (var apiNotify:APINotify in Flash_API.apiNotifys){ - apiNotify.notify(call,_sipObject); - } - CairngormEventDispatcher.getInstance().dispatchEvent(new CallEvent(CallEvent.BUSY,call)); - } - - public function finish(_call:Object,_sipObject:Object):void{ - var call:Call = process(_call); - for each (var apiNotify:APINotify in Flash_API.apiNotifys){ - apiNotify.notify(call,_sipObject); - } - CairngormEventDispatcher.getInstance().dispatchEvent(new CallEvent(CallEvent.FINISH,call)); - } - - public function process(_call:Object):Call{ - Logger.info("PhoneCallback.process() id="+_call.id+" state="+_call.state+" callee="+_call.callee); - var call:Call = flash_API.getCallById(_call.id); - if (call==null){ - call = new Call(flash_API); - call.id = _call.id; - } - - call.incoming = _call.incoming; - call.isVideoCall = _call.isVideoCall; - call.callee = _call.callee; - call.caller = _call.caller; - if (call.incoming){ - call.anotherSideUser = _call.caller; - }else{ - call.anotherSideUser = _call.callee; - } - call.visibleNameCallee = _call.visibleNameCallee; - if (call.visibleNameCallee != null){ - call.visibleNameCallee = call.visibleNameCallee.replace("<",""); - call.visibleNameCallee = call.visibleNameCallee.replace(">",""); - } - call.visibleNameCaller = _call.visibleNameCaller; - if (call.visibleNameCaller != null){ - call.visibleNameCaller = call.visibleNameCaller.replace("<",""); - call.visibleNameCaller = call.visibleNameCaller.replace(">",""); - } - call.state = _call.state; - call.state_video = _call.state_video; - call.sip_state = _call.sip_state; - call.playerVideoHeight = _call.playerVideoHeight; - call.playerVideoWidth = _call.playerVideoWidth; - call.streamerVideoWidth = _call.streamerVideoWidth; - call.streamerVideoHeight = _call.streamerVideoHeight; - - flash_API.addCall(call); - Logger.info("PhoneCallback.process() complete id="+call.id+" state="+call.state+" callee="+call.callee); - return call; - } - - public function notifyMessage(messageObj:Object, notificationResult:Object, sipObject:Object):void { - Logger.info("Message has been accepted by other participant"); - var messageEvent:MessageEvent = new MessageEvent(MessageEvent.MESSAGE_EVENT,messageObj,flash_API); - messageEvent.notificationResult = notificationResult; - messageEvent.sipObject = sipObject; - CairngormEventDispatcher.getInstance().dispatchEvent(messageEvent); - } - - public function notifyAudioCodec(codec:Object):void { - Logger.info("notifyAudioCodec: "+codec); - var event:MainEvent = new MainEvent(MainEvent.AUDIO_CODEC_CHANGED_EVENT,flash_API); - event.obj = codec; - CairngormEventDispatcher.getInstance().dispatchEvent(event); - } - - public function notifyOptions(sipObj:Object):int { - Logger.info("notifyOptions "+sipObj); - return 200; - } - - public function notifySubscription(subscribtionObj:Object, sipObj:Object):void { - for each (var apiNotify:APINotify in Flash_API.apiNotifys){ - apiNotify.notifySubscription(subscribtionObj,sipObj); - } - } - - public function notifyXcapResponse(xcapResponse:String):void{ - Logger.info("notifyXcapResponse:\n"+xcapResponse); - for each (var apiNotify:APINotify in Flash_API.apiNotifys){ - apiNotify.notifyXcapResponse(xcapResponse); - } - } - - - - } -} diff --git a/client/api/src/com/flashphoner/api/PhoneController.as b/client/api/src/com/flashphoner/api/PhoneController.as deleted file mode 100644 index f43b899a..00000000 --- a/client/api/src/com/flashphoner/api/PhoneController.as +++ /dev/null @@ -1,50 +0,0 @@ -/* -Copyright (c) 2011 Flashphoner -All rights reserved. This Code and the accompanying materials -are made available under the terms of the GNU Public License v2.0 -which accompanies this distribution, and is available at -http://www.gnu.org/licenses/old-licenses/gpl-2.0.html - -Contributors: - Flashphoner - initial API and implementation - -This code and accompanying materials also available under LGPL and MPL license for Flashphoner buyers. Other license versions by negatiation. Write us support@flashphoner.com with any questions. -*/ -package com.flashphoner.api -{ - import com.adobe.cairngorm.control.FrontController; - - /** - * Dispatcher for all application events - * **/ - internal class PhoneController extends FrontController - { - private static var UUID : String = "33de0550-44d6-4550-b133-43344716776a"; - - public function PhoneController() - { - init(); - } - - private function init(): void - { - addCommand(CallEvent.TALK , CallCommand ); - addCommand(CallEvent.HOLD , CallCommand ); - addCommand(CallEvent.OUT , CallCommand); - addCommand(CallEvent.IN , CallCommand); - addCommand(CallEvent.BUSY, CallCommand); - addCommand(CallEvent.FINISH,CallCommand); - addCommand(CallEvent.SESSION_PROGRESS,CallCommand); - - addCommand(MainEvent.CONNECTED,MainCommand); - addCommand(MainEvent.REGISTERED,MainCommand); - addCommand(MainEvent.DISCONNECT,MainCommand); - addCommand(MainEvent.AUDIO_CODEC_CHANGED_EVENT,MainCommand); - addCommand(MainEvent.VIDEO_FORMAT_CHANGED,MainCommand); - - addCommand(MessageEvent.MESSAGE_EVENT,MessageCommand); - - - } - } -} diff --git a/client/api/src/com/flashphoner/api/PhoneModel.as b/client/api/src/com/flashphoner/api/PhoneModel.as deleted file mode 100644 index d11f8608..00000000 --- a/client/api/src/com/flashphoner/api/PhoneModel.as +++ /dev/null @@ -1,265 +0,0 @@ -/* -Copyright (c) 2011 Flashphoner -All rights reserved. This Code and the accompanying materials -are made available under the terms of the GNU Public License v2.0 -which accompanies this distribution, and is available at -http://www.gnu.org/licenses/old-licenses/gpl-2.0.html - -Contributors: - Flashphoner - initial API and implementation - -This code and accompanying materials also available under LGPL and MPL license for Flashphoner buyers. Other license versions by negatiation. Write us support@flashphoner.com with any questions. -*/ -package com.flashphoner.api -{ - import com.adobe.cairngorm.model.IModelLocator; - import com.flashphoner.Logger; - import com.flashphoner.api.data.ErrorCodes; - import com.flashphoner.api.data.PhoneConfig; - import com.flashphoner.api.interfaces.APINotify; - import com.flashphoner.api.js.APINotifyJS; - - import flash.display.DisplayObjectContainer; - import flash.events.*; - import flash.external.ExternalInterface; - import flash.media.*; - import flash.net.*; - import flash.system.Capabilities; - import flash.utils.Timer; - - import mx.collections.ArrayCollection; - import mx.core.Application; - - /** - * Model object - * **/ - [Bindable] - public class PhoneModel implements IModelLocator - { - private static var phoneModel:PhoneModel; - - public var initialized:Boolean = false; - - private var xml:XML; - - public var app : DisplayObjectContainer; - private var phoneController:PhoneController; - public var parameters:Object = null; - - private static var initTimer:Timer; - - public static function getInstance():PhoneModel { - if (phoneModel == null){ - phoneModel = new PhoneModel(); - } - return phoneModel; - } - - - - public function PhoneModel() - { - super(); - startInitTimer(); - init(); - phoneController = new PhoneController(); - - } - - - private function init(event:TimerEvent = null):void{ - if (Application.application == null || Application.application.parameters == null){ - return; - }else{ - dropInitTimer(); - } - var loader:URLLoader = new URLLoader(); - var qwe:Object = Application.application.parameters; - var config:String = "flashphoner.xml"; - try{ - if (Application.application.parameters != null && Application.application.parameters.config!=null){ - config = Application.application.parameters.config; - } - } catch (e:Error){ - config = "flashphoner.xml"; - } - - var request:URLRequest = new URLRequest(config); - loader.load(request); - loader.addEventListener(Event.COMPLETE, onComplete); - loader.addEventListener(SecurityErrorEvent.SECURITY_ERROR,seurityErrorHandler); - loader.addEventListener(IOErrorEvent.IO_ERROR,ioErrorHandler); - - setFlashPlayerMajorVersion(); - - } - - private function setFlashPlayerMajorVersion():void { - Logger.info("setFlashPlayerMajorVersion"); - var flashPlayerVersion:String = Capabilities.version; - var osArray:Array = flashPlayerVersion.split(' '); - var osType:String = osArray[0]; - var versionArray:Array = osArray[1].split(','); - PhoneConfig.MAJOR_PLAYER_VERSION = parseInt(versionArray[0]); - Logger.info("majorVersion "+PhoneConfig.MAJOR_PLAYER_VERSION); - } - - private function seurityErrorHandler(event:SecurityErrorEvent):void{ - throw new Error(event.toString()); - } - - private function ioErrorHandler(event:IOErrorEvent):void{ - throw new Error(event.toString()); - } - - private function onComplete(event:Event):void - { - var loader:URLLoader = event.target as URLLoader; - if (loader != null) - { - xml = new XML(loader.data); - var count:Number = xml.children().length(); - parameters = new Object(); - for (var i:Number = 0; i < count; i++) - { - var node:String = xml.children()[i].localName().toString(); - parameters[node] = String(xml[node]); - } - - var wcs_server:String = xml.wcs_server; - if (wcs_server!=null && wcs_server.length!=0){ - PhoneConfig.WCS_SERVER = wcs_server; - } - Logger.info("WCS_SERVER: "+PhoneConfig.WCS_SERVER); - - var rtmfp_port:String = xml.rtmfp_port; - if (rtmfp_port!=null && rtmfp_port.length!=0){ - PhoneConfig.RTMFP_PORT = int(rtmfp_port); - } - Logger.info("RTMFP_PORT: "+PhoneConfig.RTMFP_PORT); - - var use_enhanced_mic:String = xml.use_enhanced_mic; - - if (use_enhanced_mic!=null && use_enhanced_mic.length!=0){ - PhoneConfig.USE_ENHANCED_MIC = (use_enhanced_mic == "true"); - } - Logger.info("USE_ENHANCED_MIC: "+PhoneConfig.USE_ENHANCED_MIC); - - var forceEnhancedMic:String = xml.force_enhanced_mic; - if (forceEnhancedMic!=null && forceEnhancedMic.length!=0){ - PhoneConfig.FORCE_ENHANCED_MIC= (forceEnhancedMic=="true"); - } - Logger.info("FORCE_ENHANCED_MIC: "+PhoneConfig.FORCE_ENHANCED_MIC); - - var regRequired:String = xml.register_required; - PhoneConfig.REGISTER_REQUIRED = (regRequired == "true"); - - if (xml.video_width != null && xml.video_width.toString() != ""){ - PhoneConfig.VIDEO_WIDTH = int(xml.video_width); - } - if (xml.video_height != null && xml.video_height.toString() != ""){ - PhoneConfig.VIDEO_HEIGHT = int(xml.video_height); - } - - if (xml.keep_alive == "true"){ - PhoneConfig.KEEP_ALIVE=true; - } - Logger.info("KEEP_ALIVE: "+PhoneConfig.KEEP_ALIVE); - - if (xml.keep_alive_interval !=null && xml.keep_alive_interval.toString() !=""){ - PhoneConfig.KEEP_ALIVE_INTERVAL = int(xml.keep_alive_interval); - } - Logger.info("KEEP_ALIVE_INTERVAL: "+PhoneConfig.KEEP_ALIVE_INTERVAL); - - if (xml.keep_alive_timeout !=null && xml.keep_alive_timeout.toString() !=""){ - PhoneConfig.KEEP_ALIVE_TIMEOUT = int(xml.keep_alive_timeout); - } - Logger.info("KEEP_ALIVE_TIMEOUT: "+PhoneConfig.KEEP_ALIVE_TIMEOUT); - - if (xml.push_log != null && xml.push_log.toString() != ""){ - PhoneConfig.PUSH_LOG = (xml.push_log == "true"); - } - Logger.info("PUSH_LOG: "+PhoneConfig.PUSH_LOG); - - if (xml.audio_codec != null && xml.audio_codec.toString() != ""){ - PhoneConfig.AUDIO_CODEC = xml.audio_codec; - } - Logger.info("AUDIO_CODEC: "+PhoneConfig.AUDIO_CODEC); - - if (xml.g711_frames_per_packet != null && xml.g711_frames_per_packet.toString() != ""){ - PhoneConfig.G711_FRAMES_PER_PACKET = xml.g711_frames_per_packet; - } - Logger.info("G711_FRAMES_PER_PACKET: "+PhoneConfig.G711_FRAMES_PER_PACKET); - - if (xml.avoid_flv2h264_transcoding != null && xml.avoid_flv2h264_transcoding.toString() != ""){ - PhoneConfig.AVOID_FLV2H264_TRANSCODING = (xml.avoid_flv2h264_transcoding == "true"); - } - Logger.info("AVOID_H264_TRANSCODING: "+PhoneConfig.AVOID_FLV2H264_TRANSCODING); - - if (xml.audio_reliable != null && xml.audio_reliable.toString() != ""){ - PhoneConfig.AUDIO_RELIABLE = (xml.audio_reliable == "true"); - } - Logger.info("AUDIO_RELIABLE: "+PhoneConfig.AUDIO_RELIABLE); - - if (xml.video_reliable != null && xml.video_reliable.toString() != ""){ - PhoneConfig.VIDEO_RELIABLE = (xml.video_reliable == "true"); - } - Logger.info("VIDEO_RELIABLE: "+PhoneConfig.VIDEO_RELIABLE); - - if (xml.buffer_time != null && xml.buffer_time.toString() != ""){ - PhoneConfig.BUFFER_TIME = Number(xml.buffer_time); - } - Logger.info("BUFFER_TIME: "+PhoneConfig.BUFFER_TIME); - - if (xml.ring_sound != null && xml.ring_sound.toString() != ""){ - SoundControl.RING_SOUND = xml.ring_sound; - } - if (xml.busy_sound != null && xml.busy_sound.toString() != ""){ - SoundControl.BUSY_SOUND = xml.busy_sound; - } - if (xml.register_sound != null && xml.register_sound.toString() != ""){ - SoundControl.REGISTER_SOUND = xml.register_sound; - } - if (xml.finish_sound != null && xml.finish_sound.toString() != ""){ - SoundControl.FINISH_SOUND = xml.finish_sound; - } - - if (xml.load_balancer_url != null && xml.load_balancer_url.toString() !=""){ - PhoneConfig.LOAD_BALANCER_URL = xml.load_balancer_url; - } - - SoundControl.updateSounds(); - } - else - { - Logger.info("Can not load xml settings. Default settings will be used."); - } - initialized = true; - - } - - - public function dropInitTimer():void{ - if (initTimer!=null){ - initTimer.stop(); - initTimer.removeEventListener(TimerEvent.TIMER,init); - initTimer=null; - } - } - - public function startInitTimer():void{ - if (initTimer!=null){ - initTimer.stop(); - - } else { - initTimer = new Timer(1000); - initTimer.addEventListener(TimerEvent.TIMER,init); - } - initTimer.start(); - } - - - } - - -} diff --git a/client/api/src/com/flashphoner/api/PhoneServerProxy.as b/client/api/src/com/flashphoner/api/PhoneServerProxy.as deleted file mode 100644 index b2e2b210..00000000 --- a/client/api/src/com/flashphoner/api/PhoneServerProxy.as +++ /dev/null @@ -1,251 +0,0 @@ -/* -Copyright (c) 2011 Flashphoner -All rights reserved. This Code and the accompanying materials -are made available under the terms of the GNU Public License v2.0 -which accompanies this distribution, and is available at -http://www.gnu.org/licenses/old-licenses/gpl-2.0.html - -Contributors: - Flashphoner - initial API and implementation - -This code and accompanying materials also available under LGPL and MPL license for Flashphoner buyers. Other license versions by negatiation. Write us support@flashphoner.com with any questions. -*/ -package com.flashphoner.api -{ - import com.adobe.cairngorm.control.CairngormEventDispatcher; - import com.flashphoner.Logger; - import com.flashphoner.api.data.ErrorCodes; - import com.flashphoner.api.data.ModelLocator; - import com.flashphoner.api.data.PhoneConfig; - import com.flashphoner.api.interfaces.APINotify; - import com.flashphoner.api.management.VideoControl; - - import flash.events.*; - import flash.net.*; - import flash.system.Security; - import flash.system.SecurityPanel; - import flash.utils.Timer; - import flash.utils.setTimeout; - - import mx.controls.Alert; - - /** - * Media server outgoing communication class - * **/ - internal class PhoneServerProxy - { - //output voice stream - private static var outStream:NetStream; - - private var responder:Responder; - internal var nc:NetConnection; - - public var hasDisconnectAttempt:Boolean; - - public static var sendVideo:Boolean = false; - - public var phoneSpeaker:PhoneSpeaker; - - private var flash_API:Flash_API; - - private var keepAliveTimer:Timer; - - private var keepAliveTimeoutTimer:Timer; - - private var isConnected:Boolean; - - public function PhoneServerProxy(responder:Responder,flash_API:Flash_API) - { - this.flash_API = flash_API; - this.responder = responder; - nc = new NetConnection(); - nc.client = new PhoneCallback(flash_API); - phoneSpeaker = new PhoneSpeaker(nc,flash_API); - isConnected = false; - - } - - public function login(loginObject:Object, WCSUrl:String):int{ - - var modelLocator:ModelLocator = flash_API.modelLocator; - loginObject.registerRequired = PhoneConfig.REGISTER_REQUIRED; - - loginObject.width = PhoneConfig.VIDEO_WIDTH; - loginObject.height = PhoneConfig.VIDEO_HEIGHT; - loginObject.supportedResolutions = PhoneConfig.SUPPORTED_RESOLUTIONS; - - if (loginObject.token == null) { - if (loginObject.authenticationName == null || loginObject.authenticationName == ""){ - loginObject.authenticationName = loginObject.login; - } - loginObject.visibleName = modelLocator.visibleName; - } - createConnection(loginObject, WCSUrl); - return 0; - } - - private function createConnection(obj:Object, WCSUrl:String):void { - Logger.info("createConnection serverUrl: "+WCSUrl); - nc.addEventListener(NetStatusEvent.NET_STATUS,netStatusHandler); - nc.connect(WCSUrl,obj); - } - - public function subscribe(subscribeObj:Object):void{ - Logger.info("subscribe "+subscribeObj); - nc.call("subscribe",null,subscribeObj); - } - - /* - public function loginByTokenWithPageUrl(token:String = null, pageUrl:String):void{ - var modelLocator:ModelLocator = flash_API.modelLocator; - var obj:Object = new Object(); - obj.registerRequired = PhoneConfig.REGISTER_REQUIRED; - obj.token = token; - obj.width = PhoneConfig.VIDEO_WIDTH; - obj.height = PhoneConfig.VIDEO_HEIGHT; - obj.pageUrl = pageUrl; - nc.addEventListener(NetStatusEvent.NET_STATUS,netStatusHandler); - nc.connect(PhoneConfig.SERVER_URL+"/"+PhoneConfig.APP_NAME,obj); - } - */ - - public function call(callObject:Object):void{ - Logger.info("PhoneServerProxy.call()"); - nc.call("call", responder, callObject); - } - - public function callByToken(callObject:Object):void{ - Logger.info("PhoneServerProxy.callByToken()"); - nc.call("call", responder, callObject); - } - - public function msrpCall(callObject:Object):void{ - Logger.info("PhoneServerProxy.msrpCall()"); - nc.call("msrpCall", responder, callObject); - } - public function disconnect():void { - hasDisconnectAttempt = true; - nc.close(); - } - - public function initKeepAlive():void{ - Logger.info("initKeepAlive"); - keepAliveTimer = new Timer(PhoneConfig.KEEP_ALIVE_INTERVAL,1); - keepAliveTimer.addEventListener(TimerEvent.TIMER_COMPLETE,fireKeepAlive); - - keepAliveTimeoutTimer = new Timer(PhoneConfig.KEEP_ALIVE_TIMEOUT,1); - keepAliveTimeoutTimer.addEventListener(TimerEvent.TIMER_COMPLETE,fireKeepAliveTimeout); - Logger.info("keepAliveTimeoutTimer: "+PhoneConfig.KEEP_ALIVE_INTERVAL+" keepAliveTimeoutTimer: "+PhoneConfig.KEEP_ALIVE_TIMEOUT); - } - - public function startKeepAlive():void{ - Logger.debug("startKeepAlive "+new Date()); - keepAliveTimer.start(); - } - - public function fireKeepAlive(event:TimerEvent):void{ - Logger.debug("fireKeepAlive "+new Date()); - nc.call("keepAlive",new Responder(keepAliveResponse)); - keepAliveTimeoutTimer.start(); - } - - public function keepAliveResponse(result:int):void{ - Logger.debug("keepAliveResponse: "+result); - keepAliveTimeoutTimer.stop(); - startKeepAlive(); - } - - public function fireKeepAliveTimeout(event:TimerEvent):void{ - Logger.info("fireKeepAliveTimeout. Close connection by keep alive timeout: "+PhoneConfig.KEEP_ALIVE_TIMEOUT); - nc.close(); - } - - public function netStatusHandler(event : NetStatusEvent) : void - { - var modelLocator:ModelLocator = flash_API.modelLocator; - if(event.info.code == "NetConnection.Connect.Success") - { - Logger.info("NetConnection.Connect.Success"); - for each (var apiNotify:APINotify in Flash_API.apiNotifys){ - apiNotify.notifyConnected(); - } - CairngormEventDispatcher.getInstance().dispatchEvent(new MainEvent(MainEvent.CONNECTED,flash_API)); - if (PhoneConfig.KEEP_ALIVE){ - initKeepAlive(); - startKeepAlive(); - } - - isConnected = true; - - } else if(event.info.code == "NetConnection.Connect.Failed") - { - Logger.info("NetConnection.Connect.Failed"); - flash_API.dropRegisteredTimer(); - for each (var apiNotify:APINotify in Flash_API.apiNotifys){ - apiNotify.notifyError(ErrorCodes.CONNECTION_ERROR); - } - hasDisconnectAttempt = false; - } else if (event.info.code == 'NetConnection.Connect.Rejected') - { - Logger.info("NetConnection.Connect.Rejected"); - Alert.show("Connect rejected,\n permission to server denied."); - hasDisconnectAttempt = false; - } else if (event.info.code == 'NetConnection.Connect.Closed') - { - Logger.info("NetConnection.Connect.Closed"); - for each (var apiNotify:APINotify in Flash_API.apiNotifys){ - apiNotify.notifyCloseConnection(); - } - CairngormEventDispatcher.getInstance().dispatchEvent(new MainEvent(MainEvent.DISCONNECT,flash_API)); - hasDisconnectAttempt = false; - isConnected = false; - } - } - - public function sendInstantMessage(msg:Object):void{ - nc.call("sendInstantMessage",null,msg); - } - - public function notificationResult(notificationResult:Object):void{ - nc.call("notificationResult", null, notificationResult); - } - - public function sendInfo(infoObject:Object):void{ - nc.call("sendInfo", null, infoObject); - } - - public function pushLogs(logs:String):Boolean { - if(isConnected) { - //merge JS and FLASH logs - var logsToServer:String = Logger.merge(logs); - - //clear FLASH logs - Logger.clear(); - - nc.call("pushLogs", null, logsToServer); - return true; - } else { - return false; - } - } - - public function submitBugReport(reportObj:Object){ - if (isConnected){ - nc.call("submitBugReport",null,reportObj); - } - } - - public function pong(){ - nc.call("pong",null); - } - - public function setLTState(stateObj:Object):void{ - nc.call("setLTState", null, stateObj); - } - - public function sendXcapRequest(xcapUrl:String):void{ - nc.call("sendXcapRequest", null, xcapUrl); - } - - } -} diff --git a/client/api/src/com/flashphoner/api/PhoneSpeaker.as b/client/api/src/com/flashphoner/api/PhoneSpeaker.as deleted file mode 100644 index 67634b99..00000000 --- a/client/api/src/com/flashphoner/api/PhoneSpeaker.as +++ /dev/null @@ -1,185 +0,0 @@ -/* -Copyright (c) 2011 Flashphoner -All rights reserved. This Code and the accompanying materials -are made available under the terms of the GNU Public License v2.0 -which accompanies this distribution, and is available at -http://www.gnu.org/licenses/old-licenses/gpl-2.0.html - -Contributors: - Flashphoner - initial API and implementation - -This code and accompanying materials also available under LGPL and MPL license for Flashphoner buyers. Other license versions by negatiation. Write us support@flashphoner.com with any questions. -*/ -package com.flashphoner.api -{ - - import com.flashphoner.Logger; - import com.flashphoner.api.data.PhoneConfig; - import com.flashphoner.api.interfaces.APINotify; - - import flash.events.*; - import flash.media.*; - import flash.net.NetConnection; - import flash.net.NetStream; - - import mx.core.UIComponent; - - /** - * Phone speaker and video window implementation - * **/ - public class PhoneSpeaker extends UIComponent - { - private var videoContainer:UIComponent; - private var video:Video; - private var incomingStream:NetStream; - private var incomingVideoStream:NetStream; - private var netConnection:NetConnection; - /** - * Playing flag - **/ - public var playing:Boolean; - - private var currentVolume:int = 100; - private var streamName:String; - private var rePlay:Boolean = false; - - private var flashAPI:Flash_API; - - /** - * Construstor to create video object - * @param netConnection connection for playing audio and video - **/ - public function PhoneSpeaker(netConnection:NetConnection, flashAPI:Flash_API):void - { - this.flashAPI = flashAPI; - this.netConnection = netConnection; - video = new Video(); - addChild(video); - video.width = 215; - video.height = 138; - video.clear(); - } - - private function nsOnStatus(infoObject:NetStatusEvent):void - { - Logger.info("PhoneSpeaker.nsOnStatus() "+infoObject.info.code); - - if (incomingStream==null){ - return; - } - - if (infoObject.info.code == "NetStream.Play.Start"){ - playing = true; - } - - if (infoObject.info.code == "NetStream.Play.PublishNotify"){ - SoundControl.stopRingSound(); - } - - else if (infoObject.info.code == "NetStream.Play.StreamNotFound" || infoObject.info.code == "NetStream.Play.Failed"||infoObject.info.code == "NetStream.Play.Stop"){ - Logger.info("incomingStream.onStatus() "+infoObject.info.description); - playing = false; - } - - } - - - /** - * Stop playing audio stream for call - * @param callId identifier for call - **/ - public function stop(callId:String):void{ - Logger.info("PhoneSpeaker.stopAudio() - "+callId +"; current stream name - "+streamName); - if (incomingStream!=null && streamName.indexOf(callId) != -1){ - incomingStream.removeEventListener(NetStatusEvent.NET_STATUS,nsOnStatus); - try{ - incomingStream.play(false); - incomingStream.close(); - }catch (e:Error){ - Logger.error(e.message); - } - incomingStream.close(); - incomingStream = null; - playing = false; - video.clear(); - video.attachNetStream(null); - } - } - - /** - * Play audio stream - * @param streamName name of audio stream - **/ - public function play(streamName:String, rePlay:Boolean):void{ - Logger.info("PhoneSpeaker play streamName="+streamName +"; currentStremName="+this.streamName); - //If we have a new stream, we stop old and start new - //This is mandatory for reInvite and update to video session - var needReplay:Boolean = this.rePlay; - this.rePlay = rePlay; - if (incomingStream != null){ - if (this.streamName == streamName && !needReplay){ - return; - } - stop(this.streamName); - } - incomingStream = startNewIncomingStream(streamName,nsOnStatus); - this.streamName = streamName; - } - - private function startNewIncomingStream(streamName:String, listener:Function):NetStream{ - Logger.info("PhoneSpeaker startNewIncomingStream streamName="+streamName); - - var stream:NetStream = new NetStream(netConnection); - - stream.addEventListener(NetStatusEvent.NET_STATUS, listener); - - var streamClientObj:Object = new Object(); - stream.client = streamClientObj; - stream.bufferTime = PhoneConfig.BUFFER_TIME; - - Logger.info("bufferTime "+stream.bufferTime); - - var soundTransform:SoundTransform = new SoundTransform(); - soundTransform.volume=currentVolume/100; - - stream.soundTransform = soundTransform; - stream.play(streamName); - - video.attachNetStream(stream); - - return stream; - } - - /** - * Get current volume for speakers (1-100) - **/ - public function getVolume():int{ - return currentVolume; - } - - /** - * Set current volume for speakers - * @param volume (1-100) - **/ - public function setVolume(volume:int):void{ - currentVolume = volume; - if (incomingStream != null){ - var soundTransform:SoundTransform = new SoundTransform; - soundTransform.volume = currentVolume/100; - incomingStream.soundTransform = soundTransform; - } - - } - - /** - * Change format of a video - * @param format (CIF/QCIF) - **/ - public function changeFormat(width:int, height:int):void{ - this.video.width=width; - this.video.height=height; - this.video.clear(); - } - - } -} diff --git a/client/api/src/com/flashphoner/api/SoundControl.as b/client/api/src/com/flashphoner/api/SoundControl.as deleted file mode 100644 index a42b02df..00000000 --- a/client/api/src/com/flashphoner/api/SoundControl.as +++ /dev/null @@ -1,313 +0,0 @@ -/* -Copyright (c) 2011 Flashphoner -All rights reserved. This Code and the accompanying materials -are made available under the terms of the GNU Public License v2.0 -which accompanies this distribution, and is available at -http://www.gnu.org/licenses/old-licenses/gpl-2.0.html - -Contributors: - Flashphoner - initial API and implementation - -This code and accompanying materials also available under LGPL and MPL license for Flashphoner buyers. Other license versions by negatiation. Write us support@flashphoner.com with any questions. -*/ -package com.flashphoner.api -{ - import com.flashphoner.Logger; - import com.flashphoner.api.data.PhoneConfig; - import com.flashphoner.api.interfaces.APINotify; - - import flash.events.Event; - import flash.events.IOErrorEvent; - import flash.events.ProgressEvent; - import flash.media.Microphone; - import flash.media.Sound; - import flash.media.SoundChannel; - import flash.media.SoundCodec; - import flash.media.SoundTransform; - import flash.net.URLRequest; - import flash.system.Capabilities; - - import flashx.textLayout.events.UpdateCompleteEvent; - - public class SoundControl - { - - [Embed(source="/sounds/CALL_OUT.mp3")] - private static var ringClass:Class; - [Embed(source="/sounds/BUSY.mp3")] - private static var busyClass:Class; - [Embed(source="/sounds/REGISTER.mp3")] - private static var registerClass:Class; - [Embed(source="/sounds/HANGUP.mp3")] - private static var finishClass:Class; - - private static var ringSound:Sound; - private static var busySound:Sound; - private static var registerSound:Sound; - private static var finishSound:Sound; - private static var ringSoundChannel:SoundChannel; - - /** - * Path to sound for ring - **/ - public static var RING_SOUND:String = null; - /** - * Path to sound for busy - **/ - public static var BUSY_SOUND:String = null; - /** - * Path to sound for register event on voip server - **/ - public static var REGISTER_SOUND:String = null; - /** - * Path to sound for finish call - **/ - public static var FINISH_SOUND:String = null; - - private static var soundControl:SoundControl; - - private var mic:Microphone; - - private var flash_API:Flash_API; - - private var majorPlayerVersion:Number=11; - - /** - * Control class (singelton) for microphone and sounds. - **/ - - public function SoundControl(flash_API:Flash_API) - { - this.flash_API = flash_API; - Logger.info("Use enchenced mic: "+PhoneConfig.USE_ENHANCED_MIC); - mic = defineMicrophone(); - - if (mic != null){ - initMic(mic,50,false); - } - } - - - private function defineMicrophone(index:int=-1):Microphone { - Logger.info("getMicrophone "+index); - if (PhoneConfig.USE_ENHANCED_MIC){ - if (PhoneConfig.MAJOR_PLAYER_VERSION >= 11 || Capabilities.language.indexOf("en") >= 0 || PhoneConfig.FORCE_ENHANCED_MIC){ - Logger.info("return EnhancedMicrophone"); - Logger.info("majorVersion: "+PhoneConfig.MAJOR_PLAYER_VERSION); - Logger.info("Capabilities.language: "+Capabilities.language); - Logger.info("FORCE_ENHANCED_MIC: "+PhoneConfig.FORCE_ENHANCED_MIC); - return Microphone.getEnhancedMicrophone(index); - }else{ - for each (var apiNotify:APINotify in Flash_API.apiNotifys){ - apiNotify.addLogMessage("WARNING!!! Echo cancellation is turned off on your side (because your OS has no-english localization). Please use a headset to avoid echo for your interlocutor."); - } - Logger.info("return Microphone"); - return Microphone.getMicrophone(index); - } - }else{ - Logger.info("return Microphone"); - return Microphone.getMicrophone(index); - } - } - - /** - * Update all sounds from pathes - **/ - public static function updateSounds():void{ - ringSound = Sound(new ringClass()); - busySound = Sound(new busyClass()); - registerSound = Sound(new registerClass()); - finishSound = Sound(new finishClass()); - - // Create new sounds. We will not check if links != 0, because we plus "" there. - // So it will not create error. Just will empty sounds. - - if (SoundControl.RING_SOUND!=null && SoundControl.RING_SOUND.length!=0){ - updateSound(new Sound(new URLRequest(SoundControl.RING_SOUND))); - } - - if (SoundControl.BUSY_SOUND!=null && SoundControl.BUSY_SOUND.length!=0){ - updateSound(new Sound(new URLRequest(SoundControl.BUSY_SOUND))); - } - - if (SoundControl.REGISTER_SOUND!=null && SoundControl.REGISTER_SOUND.length!=0){ - updateSound(new Sound(new URLRequest(SoundControl.REGISTER_SOUND))); - } - - if (SoundControl.FINISH_SOUND!=null && SoundControl.FINISH_SOUND.length!=0){ - updateSound(new Sound(new URLRequest(SoundControl.FINISH_SOUND))); - } - - } - - private static function updateSound(sound:Sound):void{ - sound.addEventListener(Event.COMPLETE, onUpdateSoundComplete); - sound.addEventListener(IOErrorEvent.IO_ERROR,onUpdateSoundError); - Logger.info("updateSound: "+sound.url); - } - - public static function onUpdateSoundError(event:IOErrorEvent):void{ - Logger.info("Error: "+event.text); - } - - // We are waiting for "complete" event. That mean if link broken and there is - // no sound on that url, complete event will never appear. - // On complete event we are invoking assign function. - // It assign old sounds to new ones. - - public static function onUpdateSoundComplete(event:Event):void{ - - var localSound:Sound = event.target as Sound; - - // For every event we check by what sounds complete event was invoked. - // we check sound url and compare it with all our urls. - // When we found coincidence - we making assignment - - if (localSound.url.indexOf(SoundControl.RING_SOUND) >= 0){ - ringSound = localSound; - } - - if (localSound.url.indexOf(SoundControl.BUSY_SOUND) >= 0) { - busySound = localSound; - } - - if (localSound.url.indexOf(SoundControl.REGISTER_SOUND) >= 0) { - registerSound = localSound; - } - - if (localSound.url.indexOf(SoundControl.FINISH_SOUND) >= 0) { - finishSound = localSound; - } - - Logger.info("onUpdateSoundComplete :"+localSound.url); - } - - /** - * Play busy sound - **/ - public static function playBusySound():void{ - busySound.play(0,1); - } - - /** - * Play finish sound - **/ - public static function playFinishSound():void{ - finishSound.play(0,1); - } - - /** - * Play register sound - **/ - public static function playRegisterSound():void{ - Logger.info("playRegisterSound "+registerSound.url); - registerSound.play(0,1); - } - - /** - * Stop ring sound - **/ - public static function stopRingSound():void{ - if (ringSoundChannel!=null){ - ringSoundChannel.stop(); - ringSoundChannel = null; - } - } - - /** - * Play register sound - **/ - public static function playRingSound():void{ - if (ringSoundChannel == null){ - ringSoundChannel = ringSound.play(0,999); - } - } - - public function isMuted():int{ - if (mic == null){ - return 0; - }else{ - if (mic.muted){ - return 1; - }else{ - return -1; - } - - } - } - - /** - * Change current microphone - * @param index of array - * @param isLoopBack playback voice on speakers - * @param gain volume of microphone(-1 - if not change volume) - **/ - public function changeMicrophone(index:int,isLoopback:Boolean,gain:Number = -1):void{ - Logger.info("changeMicrophone: index "+index+" isLoopback "+isLoopback+" gain: "+gain); - var microphone:Microphone = defineMicrophone(index); - if (microphone != null){ - this.mic = microphone; - if (this.mic != null){ - initMic(mic,gain,isLoopback); - } - } - } - - /** - * Get cuurent microphone - **/ - public function getMicrophone():Microphone{ - return mic; - } - - private function initMic(mic:Microphone, gain:int=50, loopback:Boolean=false):void{ - var logMsg:String = "Init mic: codec: "+PhoneConfig.AUDIO_CODEC+" gain: "+50+" loopback: "+loopback; - Logger.info(logMsg); - for each (var apiNotify:APINotify in Flash_API.apiNotifys){ - apiNotify.addLogMessage(logMsg); - } - - changeCodec(PhoneConfig.AUDIO_CODEC); - - if (gain != -1){ - mic.gain = gain; - } - - mic.soundTransform = new SoundTransform(1,0); - mic.setLoopBack(loopback); - mic.setSilenceLevel(0,3600000); - mic.setUseEchoSuppression(true); - } - - public function changeAudioCodec(codec:Object):void{ - var codecName:String = codec.name; - Logger.info("changeAudioCodec: "+codecName); - changeCodec(codecName); - } - - private function changeCodec(name:String):void{ - Logger.info("changeCodec: "+name); - if (name=="speex"){ - mic.codec = SoundCodec.SPEEX; - mic.framesPerPacket = 1; - mic.rate = 16; - mic.encodeQuality = 6; - }else if (name=="ulaw" || name=="pcmu" ){ - mic.codec = SoundCodec.PCMU; - mic.framesPerPacket = PhoneConfig.G711_FRAMES_PER_PACKET; - mic.rate = 8; - }else if (name=="alaw" || name=="pcma" ){ - mic.codec = SoundCodec.PCMA; - mic.framesPerPacket = PhoneConfig.G711_FRAMES_PER_PACKET; - mic.rate = 8; - } - } - - public function setSpeexQuality(quality:int){ - Logger.info("setSpeexQuality: "+quality); - mic.encodeQuality=quality; - } - - - } -} diff --git a/client/api/src/com/flashphoner/api/data/ErrorCodes.as b/client/api/src/com/flashphoner/api/data/ErrorCodes.as deleted file mode 100644 index 032a6f01..00000000 --- a/client/api/src/com/flashphoner/api/data/ErrorCodes.as +++ /dev/null @@ -1,83 +0,0 @@ -/* -Copyright (c) 2011 Flashphoner -All rights reserved. This Code and the accompanying materials -are made available under the terms of the GNU Public License v2.0 -which accompanies this distribution, and is available at -http://www.gnu.org/licenses/old-licenses/gpl-2.0.html - -Contributors: - Flashphoner - initial API and implementation - -This code and accompanying materials also available under LGPL and MPL license for Flashphoner buyers. Other license versions by negatiation. Write us support@flashphoner.com with any questions. -*/ -package com.flashphoner.api.data -{ - - /** - * Error codes from server and client side - * **/ - public class ErrorCodes - { - /** - * Authentication on sip server is fail - **/ - public static const AUTHENTICATION_FAIL:String = "AUTHENTICATION_FAIL"; - /** - * User not available on sip server - **/ - public static const USER_NOT_AVAILABLE:String = "USER_NOT_AVAILABLE"; - /** - * Many registration attempts - **/ - public static const TOO_MANY_REGISTER_ATTEMPTS:String = "TOO_MANY_REGISTER_ATTEMPTS"; - /** - * Your license of Flashphoner is trial - **/ - public static const LICENSE_RESTRICTION:String = "LICENSE_RESTRICTION"; - /** - * Your license of Flashphoner not found - **/ - public static const LICENSE_NOT_FOUND:String = "LICENSE_NOT_FOUND"; - /** - * Unknown error on server by sip protocol - **/ - public static const INTERNAL_SIP_ERROR:String = "INTERNAL_SIP_ERROR"; - /** - * Connection with flashphoner-server is not available - **/ - public static const CONNECTION_ERROR:String = "CONNECTION_ERROR"; - /** - * It is client error, throw if answer on registration do not receive from server within 15 seconds - **/ - public static const REGISTER_EXPIRE:String = "REGISTER_EXPIRE"; - /** - * Parameters from file 'flashphoner.xml' is not readed. - * throw when excecute Flash_API.getParameters() - **/ - public static const PARAMETERS_IS_NOT_INITIALIZED:String = "PARAMETERS_IS_NOT_INITIALIZED"; - /** - * All sip ports on flashphoner-server is busy - **/ - public static const SIP_PORTS_BUSY:String = "SIP_PORTS_BUSY"; - /** - * All sip ports on flashphoner-server is busy - **/ - public static const MEDIA_PORTS_BUSY:String = "MEDIA_PORTS_BUSY"; - /** - * flashphoner server can not connect with sip provider server. - **/ - public static const WRONG_SIPPROVIDER_ADDRESS:String = "WRONG_SIPPROVIDER_ADDRESS"; - /** - * Application can`t load flashphoner.xml properly - **/ - public static const WRONG_FLASHPHONER_XML:String = "WRONG_FLASHPHONER_XML"; - /** - * Callee name is null. - **/ - public static const CALLEE_NAME_IS_NULL:String = "CALLEE_NAME_IS_NULL"; - /** - * Payments required from user. SIP 402 Payment Required - **/ - public static const PAYMENT_REQUIRED:String = "PAYMENT_REQUIRED"; - } -} diff --git a/client/api/src/com/flashphoner/api/data/ModelLocator.as b/client/api/src/com/flashphoner/api/data/ModelLocator.as deleted file mode 100644 index f27fd1bd..00000000 --- a/client/api/src/com/flashphoner/api/data/ModelLocator.as +++ /dev/null @@ -1,48 +0,0 @@ -/* -Copyright (c) 2011 Flashphoner -All rights reserved. This Code and the accompanying materials -are made available under the terms of the GNU Public License v2.0 -which accompanies this distribution, and is available at -http://www.gnu.org/licenses/old-licenses/gpl-2.0.html - -Contributors: - Flashphoner - initial API and implementation - -This code and accompanying materials also available under LGPL and MPL license for Flashphoner buyers. Other license versions by negatiation. Write us support@flashphoner.com with any questions. -*/ -package com.flashphoner.api.data -{ - [Bindable] - /** - * Class used to store information about connected user - **/ - public class ModelLocator - { - /** - * Login of user - */ - public var login:String = ''; - /** - * Password of user - **/ - public var pwd:String = null; - /** - * Host of sip provider (example: sipnet.ru) - */ - public var outboundProxy:String; - - public var domain:String; - /** - * Port of sip provider (default - 5060) - **/ - public var port:String; - /** - * Visible name of user - **/ - public var visibleName:String = ""; - /** - * Logged user on sip provider or no - */ - public var logged:Boolean = false; - } -} diff --git a/client/api/src/com/flashphoner/api/data/PhoneConfig.as b/client/api/src/com/flashphoner/api/data/PhoneConfig.as deleted file mode 100644 index 13e3d37d..00000000 --- a/client/api/src/com/flashphoner/api/data/PhoneConfig.as +++ /dev/null @@ -1,134 +0,0 @@ -/* -Copyright (c) 2011 Flashphoner -All rights reserved. This Code and the accompanying materials -are made available under the terms of the GNU Public License v2.0 -which accompanies this distribution, and is available at -http://www.gnu.org/licenses/old-licenses/gpl-2.0.html - -Contributors: - Flashphoner - initial API and implementation - -This code and accompanying materials also available under LGPL and MPL license for Flashphoner buyers. Other license versions by negatiation. Write us support@flashphoner.com with any questions. -*/ -package com.flashphoner.api.data -{ - import flash.events.*; - import flash.net.*; - [Bindable] - /** - * Confiruration parameters from file flashphoner.xml - **/ - public class PhoneConfig - { - /** - * Width of outgoing video - **/ - public static var VIDEO_WIDTH:int = 176; - - /** - * Height of outgoing video - **/ - public static var VIDEO_HEIGHT:int = 144; - - /** - * Size of buffer in incomming video - **/ - public static var BUFFER_TIME:Number = 0; - - /** - * Is User Agent on VoIP server required (true/false) - **/ - public static var REGISTER_REQUIRED:Boolean = true; - - /** - * Is videocalls support enabled (true/false) - **/ - public static var VIDEO_ENABLED:Boolean = true; - - /** - * Is callee validation enabled (true/false) - **/ - public static var CHECK_VALIDATION_CALLEE:Boolean = true; - - /** - * Is use enhansed mic for echo supression (true/false) - **/ - public static var USE_ENHANCED_MIC:Boolean = true; - - /** - * Always use enhanced mic, regardless of Player version or locale - **/ - public static var FORCE_ENHANCED_MIC:Boolean = false; - - /** - * Current version of Flashphoner client - **/ - public static var VERSION_OF_CLIENT:String = "1.0.X"; - - /** - * Current version of Flashphoner server - **/ - public static var VERSION_OF_SERVER:String = "1.0.5.X"; - - public static var AUDIO_CODEC:String = "speex"; - - public static var KEEP_ALIVE:Boolean = false; - - public static var KEEP_ALIVE_INTERVAL:int = 1000; - - public static var KEEP_ALIVE_TIMEOUT:int = 5000; - - public static var PUSH_LOG:Boolean = false; - - public static var LOG_SEVERITY:String = "INFO"; - - public static var MAJOR_PLAYER_VERSION:int = 11; - - public static var AVOID_FLV2H264_TRANSCODING:Boolean = true; - - public static var VIDEO_RELIABLE = false; - - public static var AUDIO_RELIABLE = false; - - public static var LOAD_BALANCER_URL = null; - - public static var WCS_SERVER:String = "192.168.1.5"; - - public static var RTMFP_PORT:int = 1935; - - /** - * 1 - 10 ms - * 2 - 20 ms by default - * The setting may be required if you need to change ptime interval for G.711. - **/ - public static var G711_FRAMES_PER_PACKET:int = 2; - - /** - * Current version of Flashphoner product - **/ - public static function getFullVersion():String{ - var client:String = "X"; - var indexClient:int = VERSION_OF_CLIENT.lastIndexOf("."); - if (indexClient > -1){ - client = VERSION_OF_CLIENT.substring(indexClient+1); - } - - var indexServer:int = VERSION_OF_SERVER.lastIndexOf(".") - var server:String = "X"; - if (indexServer > -1){ - server = VERSION_OF_SERVER.substring(indexServer+1); - } - return client+"-"+server; - } - - public static function getRandomInt(from:int, to:int):int{ - return int(Math.floor( from + ( Math.random() * ( to - from + 1)))); - } - - /** - * Resolutions which supported camera - **/ - public static var SUPPORTED_RESOLUTIONS:String =""; - - } -} diff --git a/client/api/src/com/flashphoner/api/interfaces/API.as b/client/api/src/com/flashphoner/api/interfaces/API.as deleted file mode 100644 index c331d814..00000000 --- a/client/api/src/com/flashphoner/api/interfaces/API.as +++ /dev/null @@ -1,38 +0,0 @@ -/* -Copyright (c) 2011 Flashphoner -All rights reserved. This Code and the accompanying materials -are made available under the terms of the GNU Public License v2.0 -which accompanies this distribution, and is available at -http://www.gnu.org/licenses/old-licenses/gpl-2.0.html - -Contributors: - Flashphoner - initial API and implementation - -This code and accompanying materials also available under LGPL and MPL license for Flashphoner buyers. Other license versions by negatiation. Write us support@flashphoner.com with any questions. -*/ -package com.flashphoner.api.interfaces -{ - public interface API - { - function addAPINotify(apiNotify:APINotify):void; - function getAPINotify():APINotify; - function getParameters():Object; - function login(username:String,password:String):int; - function call(callee:String, visibleName:String, isVideoCall:Boolean = false):int; - function hangup():void; - function setStatusHold(isHold:Boolean):void; - function transfer(callee:String):void; - function answer(isVideoCall:Boolean = false):void; - function isSendVideo(flag:Boolean):void; - function sendDTMF(dtmf:String):void; - function getMicVolume():int; - function setMicVolume(volume:int):void; - function getMicropones():Array; - function setMicrophone(name:String):void; - function getCameras():Array; - function setCamera(name:String):void; - function getVolume():int; - function setVolume(volume:int):void; - function logoff():void; - } -} diff --git a/client/api/src/com/flashphoner/api/interfaces/APINotify.as b/client/api/src/com/flashphoner/api/interfaces/APINotify.as deleted file mode 100644 index f72a66f5..00000000 --- a/client/api/src/com/flashphoner/api/interfaces/APINotify.as +++ /dev/null @@ -1,39 +0,0 @@ -/* -Copyright (c) 2011 Flashphoner -All rights reserved. This Code and the accompanying materials -are made available under the terms of the GNU Public License v2.0 -which accompanies this distribution, and is available at -http://www.gnu.org/licenses/old-licenses/gpl-2.0.html - -Contributors: - Flashphoner - initial API and implementation - -This code and accompanying materials also available under LGPL and MPL license for Flashphoner buyers. Other license versions by negatiation. Write us support@flashphoner.com with any questions. -*/ -package com.flashphoner.api.interfaces -{ - import com.flashphoner.api.Call; - - public interface APINotify - { - function notifyCloseConnection():void; - function notifyConnected():void; - function notifyRegistered(_sipObject:Object):void; - function notifyCallbackHold(call:Call,isHold:Boolean):void; - function notify(call:Call,_sipObject:Object):void; - function notifyCost(call:Call,cost:Number):void; - function notifyBalance(balance:Number,_sipObject:Object):void; - function notifyBugReport(filename:String):void; - function notifyError(error:String,_sipObject:Object = null):void; - function notifyVideoFormat(videoFormat:Object,_sipObject:Object = null):void; - function notifyOpenVideoView(isViewed:Boolean):void; - function notifyMessage(messageObject:Object, notifyMessageResult:Object, sipObject:Object):void; - function notifyAddCall(call:Call):void; - function notifyRemoveCall(call:Call):void; - function notifySubscription(subscribtionObj:Object, sipObj:Object):void; - - function addLogMessage(message:String):void; - function notifyVersion(version:String):void; - function notifyXcapResponse(xcapResponse:String):void; - } -} diff --git a/client/api/src/com/flashphoner/api/js/APINotifyJS.as b/client/api/src/com/flashphoner/api/js/APINotifyJS.as deleted file mode 100644 index 2512ce44..00000000 --- a/client/api/src/com/flashphoner/api/js/APINotifyJS.as +++ /dev/null @@ -1,95 +0,0 @@ -/* -Copyright (c) 2011 Flashphoner -All rights reserved. This Code and the accompanying materials -are made available under the terms of the GNU Public License v2.0 -which accompanies this distribution, and is available at -http://www.gnu.org/licenses/old-licenses/gpl-2.0.html - -Contributors: - Flashphoner - initial API and implementation - -This code and accompanying materials also available under LGPL and MPL license for Flashphoner buyers. Other license versions by negatiation. Write us support@flashphoner.com with any questions. -*/ -package com.flashphoner.api.js -{ - import com.flashphoner.api.Call; - import com.flashphoner.api.interfaces.APINotify; - - import flash.external.ExternalInterface; - - /** - * Implementaion interface for js-phones - **/ - public class APINotifyJS implements APINotify - { - public function APINotifyJS() - { - } - public function notifyCloseConnection():void{ - ExternalInterface.call("notifyCloseConnection"); - } - public function notifyConnected():void{ - ExternalInterface.call("notifyConnected"); - } - public function notifyRegistered(_sipObject:Object):void{ - ExternalInterface.call("notifyRegistered", _sipObject); - } - public function notifyBalance(balance:Number,_sipObject:Object):void{ - ExternalInterface.call("notifyBalance",String(balance)); - } - public function notifyBugReport(filename:String):void{ - ExternalInterface.call("notifyBugReport",filename); - } - public function notify(call:Call,_sipObject:Object):void{ - ExternalInterface.call("notify",call, _sipObject); - } - public function notifyCallbackHold(call:Call,isHold:Boolean):void{ - ExternalInterface.call("notifyCallbackHold",call,isHold); - } - - public function notifyCost(call:Call,cost:Number):void{ - ExternalInterface.call("notifyCost",call.id,String(cost)); - } - - public function notifyError(error:String,_sipObject:Object = null):void{ - ExternalInterface.call("notifyError",error); - } - - public function notifyVideoFormat(videoFormat:Object,_sipObject:Object = null):void{ - ExternalInterface.call("notifyVideoFormat",videoFormat); - } - - public function notifyOpenVideoView(isViewed:Boolean):void{ - ExternalInterface.call("notifyOpenVideoView",isViewed); - } - - public function notifyMessage(messageObject:Object, notifyMessageResult:Object, sipObject:Object):void{ - ExternalInterface.call("notifyMessage",messageObject, notifyMessageResult, sipObject); - } - - public function notifyAddCall(call:Call):void{ - ExternalInterface.call("notifyAddCall",call); - } - - public function notifyRemoveCall(call:Call):void{ - ExternalInterface.call("notifyRemoveCall",call); - } - - public function notifySubscription(subscribtionObj:Object, sipObj:Object):void { - ExternalInterface.call("notifySubscription", subscribtionObj, sipObj); - } - - public function addLogMessage(message:String):void{ - ExternalInterface.call("addLogMessage", message); - } - - public function notifyVersion(version:String):void{ - ExternalInterface.call("notifyVersion", version); - } - - public function notifyXcapResponse(xcapResponse:String):void{ - ExternalInterface.call("notifyXcapResponse", xcapResponse); - } - - } -} diff --git a/client/api/src/com/flashphoner/api/management/VideoControl.as b/client/api/src/com/flashphoner/api/management/VideoControl.as deleted file mode 100644 index 7fc25eb7..00000000 --- a/client/api/src/com/flashphoner/api/management/VideoControl.as +++ /dev/null @@ -1,135 +0,0 @@ -/* -Copyright (c) 2011 Flashphoner -All rights reserved. This Code and the accompanying materials -are made available under the terms of the GNU Public License v2.0 -which accompanies this distribution, and is available at -http://www.gnu.org/licenses/old-licenses/gpl-2.0.html - -Contributors: - Flashphoner - initial API and implementation - -This code and accompanying materials also available under LGPL and MPL license for Flashphoner buyers. Other license versions by negatiation. Write us support@flashphoner.com with any questions. -*/ -package com.flashphoner.api.management -{ - import com.flashphoner.Logger; - import com.flashphoner.api.data.PhoneConfig; - - import flash.media.Camera; - - import flashx.textLayout.debug.assert; - - import mx.controls.Alert; - import mx.core.Application; - - /** - * Control class (singelton) for cameras - **/ - public class VideoControl - { - private static var videoControl:VideoControl; - private var cam:Camera; - private const FPS:int = 15; - private const KEEP_RATIO:Boolean = true; - private const KEY_INT:int = 48; - private const QUALITY:int = 80; - - public function VideoControl() - { - cam = Camera.getCamera(); - - } - - /** - * Init width,height,fps and another parameters - **/ - public function init():void{ - if (cam != null){ - supportedResolutions("1280x720,720x576,720x480,640x480,352x576,352x480,352x288,320x240,176x144,160x120,128x96,80x60"); - cam.setMode(PhoneConfig.VIDEO_WIDTH,PhoneConfig.VIDEO_HEIGHT,FPS,KEEP_RATIO); - cam.setKeyFrameInterval(KEY_INT); - cam.setQuality(0,QUALITY); - cam.setMotionLevel(0,2000); - PhoneConfig.VIDEO_WIDTH = cam.width; - PhoneConfig.VIDEO_HEIGHT = cam.height; - } - - } - - /** - * Add new supported resolutions - **/ - public function supportedResolutions(resolutions:String):void { - var supportedResolutions:String = ""; - var resolutionsSplit:Array = resolutions.split(","); - var flag:Boolean = true; - for (var i:int=0;i0)&&(height>0)){ - cam.setMode(width,height,FPS,KEEP_RATIO); - } - } - - public function isMuted():int{ - if (cam == null){ - return 0; - }else{ - if (cam.muted){ - return 1; - }else{ - return -1; - } - - } - } - - /** - * change current camera to used Flashphoner - **/ - public function changeCamera(camera:Camera):void{ - Logger.info("changeCamera"); - if (PhoneConfig.VIDEO_ENABLED){ - camera.setMode(320,240,FPS,KEEP_RATIO); - camera.setKeyFrameInterval(KEY_INT); - camera.setQuality(0,QUALITY); - camera.setMotionLevel(0,2000); - this.cam = camera; - } - } - } -} diff --git a/client/api/src/sounds/BUSY.mp3 b/client/api/src/sounds/BUSY.mp3 deleted file mode 100644 index d34b898c3f170e93df46ed7a4c110d83d419d0bd..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6567 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 diff --git a/client/api/src/sounds/CALL_OUT.mp3 b/client/api/src/sounds/CALL_OUT.mp3 deleted file mode 100644 index 99db3ee6403e921586d8a2d051e9afdedee0b81f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6456 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 diff --git a/client/api/src/sounds/HANGUP.mp3 b/client/api/src/sounds/HANGUP.mp3 deleted file mode 100644 index 6ff02d87bc759e2ef7dd0077ab6c7f99c4a9120e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4483 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 RKVPfAsQLH*2=7m0_!m4RAzuIh diff --git a/client/client/.actionScriptProperties b/client/client/.actionScriptProperties deleted file mode 100644 index 968a490f..00000000 --- a/client/client/.actionScriptProperties +++ /dev/null @@ -1,23 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - diff --git a/client/client/.flexProperties b/client/client/.flexProperties deleted file mode 100644 index a230c4a2..00000000 --- a/client/client/.flexProperties +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - diff --git a/client/client/.project b/client/client/.project deleted file mode 100644 index 82625292..00000000 --- a/client/client/.project +++ /dev/null @@ -1,25 +0,0 @@ - - - client - - - - - - com.adobe.flexbuilder.project.flexbuilder - - - - - - com.adobe.flexbuilder.project.flexnature - com.adobe.flexbuilder.project.actionscriptnature - - - - bin-debug - 2 - DOCUMENTS/output - - - diff --git a/client/client/.settings/com.adobe.flexbuilder.project.prefs b/client/client/.settings/com.adobe.flexbuilder.project.prefs deleted file mode 100644 index 438ebc79..00000000 --- a/client/client/.settings/com.adobe.flexbuilder.project.prefs +++ /dev/null @@ -1,5 +0,0 @@ -#Tue Jun 05 12:04:51 NOVST 2012 -eclipse.preferences.version=1 -instance/org.eclipse.core.net/org.eclipse.core.net.hasMigrated=true -upgradeSDK/fb4= -useFlex3CompatibilityMode/fb4=true diff --git a/client/client/.settings/org.eclipse.core.resources.prefs b/client/client/.settings/org.eclipse.core.resources.prefs deleted file mode 100644 index 8540fbb9..00000000 --- a/client/client/.settings/org.eclipse.core.resources.prefs +++ /dev/null @@ -1,3 +0,0 @@ -#Fri Jul 30 11:09:30 NOVST 2010 -eclipse.preferences.version=1 -encoding/=UTF-8 diff --git a/client/client/.settings/org.eclipse.ltk.core.refactoring.prefs b/client/client/.settings/org.eclipse.ltk.core.refactoring.prefs deleted file mode 100644 index ef3d5c3d..00000000 --- a/client/client/.settings/org.eclipse.ltk.core.refactoring.prefs +++ /dev/null @@ -1,3 +0,0 @@ -#Wed Aug 18 17:17:59 NOVST 2010 -eclipse.preferences.version=1 -org.eclipse.ltk.core.refactoring.enable.project.refactoring.history=false diff --git a/client/client/build.properties b/client/client/build.properties deleted file mode 100644 index febf7d07..00000000 --- a/client/client/build.properties +++ /dev/null @@ -1,4 +0,0 @@ -FLEX_HOME_WINDOWS=C:/Program Files/Adobe/Adobe Flash Builder 4/sdks/3.4 -FLEX_HOME_LINUX=/opt/flex -PLAYER_VERSION=11.0 -SWF_VERSION=13 \ No newline at end of file diff --git a/client/client/build.xml b/client/client/build.xml deleted file mode 100644 index 2a9453c7..00000000 --- a/client/client/build.xml +++ /dev/null @@ -1,120 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/client/client/src/Click2callJS.html b/client/client/src/Click2callJS.html deleted file mode 100644 index bc85c172..00000000 --- a/client/client/src/Click2callJS.html +++ /dev/null @@ -1,154 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Click2Call - - - -
- -
- -
- -
Support
-
- - -
- - -
-
-
Hangup
-
-
-
- - -
-
-
-
1
-
2
-
3
-
-
-
4
-
5
-
6
-
-
-
7
-
8
-
9
-
-
-
*
-
0
-
#
-
-
- - -
-
-
-
- -
- - -
-
- Click "Allow" to continue -
- - - -
-
-
- - -
-
-
- - - -
- -
- - -
- - -
Mic / Cam settings
- -
- - - - - - - - -
Ok
-
- - - - - diff --git a/client/client/src/Phone.html b/client/client/src/Phone.html deleted file mode 100644 index 51564766..00000000 --- a/client/client/src/Phone.html +++ /dev/null @@ -1,73 +0,0 @@ - - - - -Flash phone - - - - - - -
- - Get Adobe Flash player - -
- - - - diff --git a/client/client/src/PhoneJS.html b/client/client/src/PhoneJS.html deleted file mode 100644 index 8b91be95..00000000 --- a/client/client/src/PhoneJS.html +++ /dev/null @@ -1,238 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Phone - - - - -
- - -
- -
-
-
-
-
-
- -
-
-
-
-
-
-
- -
- - - -
Log in
-
-
Log out
- -
- - - - -
- -
Video Call
-
- - - - - -
-
Chat
-
Call
-
- -
-
1
-
2
-
3
-
- -
-
4
-
5
-
6
-
- -
-
7
-
8
-
9
-
- -
-
*
-
0
-
#
-
- -
-
- - - -
-
  Login
- - - - - - - - - - - - - - - - - - - -
Log in
-
Cancel
-
-
- - - - -
-
  Incoming call
-
Caller
- is calling you -
Answer
-
Hangup
-
-
- - - -
-
Connecting...
-
- -
-
-
- - - -
-
  Security panel
-
Please allow access to devices
-
- -
-
- - -
-
- - - -
- - - -
-
  Transfer
- Transfer this call to - - -
Ok
-
Cancel
-
-
- - - -
-
  Chat
-
    -
  • -
-
-
-
- - - -
-
-
-
-
-
- - - -
-
- - - -
-
Submit Bug Report
-
- - - -
Test -
- - - - diff --git a/client/client/src/assets/background_phone.png b/client/client/src/assets/background_phone.png deleted file mode 100644 index 8c17d215a887e805ada51b2efb612a4909d7cdbb..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 368 zcmeAS@N?(olHy`uVBq!ia0vp^cNiEL**KViEXy!%KOiMp;u=vBoS#-wo>-L1;Fyx1 zl&avFo0y&&l$w}QS$Hzl2B?TFz$e7@_3PJPzkZ$2dq5Lt27{-IV@SoVH|Gs`85nq& v7hK!_@@9q@AIk)@zgk7Z8&vxNgOH)UeZ~E$Z$C}|h7N{tPRqvYWRs?xL(AHik7d7d2k!gC?GXJ(3b6ZeE@y za7hdj8E+iKwJ^*}ZG$>Y4YsF+!9F1%63vJ4rXq_3WN7kuQSMg^wiqPVby+mGwn+kC zhnRgqV#BFyJb{N*9pYX$a0$Q%a3AHS7?0oYKZMhO0wkbGigr)sqTWA#|@}{Y=Bv~jF+y%z1>OCYC2m~w*nsy zDe^gWzzh<|(~S^hEgs(zR*cO=p_GwDULz?tAZ6K#YaMNvN%)T&+oFwhNrPk(8tQ;9 zpn7!ISI8)L_cmk!kvHrST|!0S`#Dt@kfCD6xFCT}+@d71z~}Q)ey$ZnXb_<&D&X-_ z0UynIJWQCPJ%NhGc3j2}ysd!t(4du}s0bDE(2e27#&9_5k8+XF7B{9CCa(yvVpl?T zH@VC`xolX6ys7GGRqd~IKq9Z2s*zVUJe>048A%bZ**dXP1?> zu@3zI74-&J{685Zku#*#8vkmQ$`}1-=+S=OchK7dvrSqA|6PbzUI{&!4th%GoXzrGJ z-=Zrq+;|*+(&_9auKjd<@|A^8U(VFfcNV6Pt-SroFx;K*a8QYp0aB4C)wqbt9R z-$vS(&y>qMUY#D=8~UzD*=(nFpT3PP{@4=ytYx+K^z#pm6-FI<4jgzVfj@fkkewL2 zdVg1cSsZTp9vg8~56*zsd#`@;Zu9=bM^~<3w$zk8CkVo&;;)OpKb3m_t@$ZeDU7Y6m6UvfBdXZ{?oB{3Hx&XP4b1+53?7CM#pA$)#VlC z=QXF(X`h>$J9~WMWa-XtFx1=YWNiEPUEkBu(UIxOi3gt;E4wc(FMe**9`4L$FI0Ve is|uU~%mWL#8vF{@JvV%w>Kh)nepRtZJ2%nVHS{-}FTQvH diff --git a/client/client/src/assets/c2c_dialpad.png b/client/client/src/assets/c2c_dialpad.png deleted file mode 100644 index a7baf33e06f3e540a4a87d2348dce2f519bfa819..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1899 zcmbVNc~BE~6pp1FiXxq=py;?=XcaZt-E0mM2$BmE1FJNA9w_ul)xH@hS* zcKWa(V}>vojA2TJEP)=xx0<@UHXcd9IjYmMhs272A zxG`{yO^T%(6%GPRbi}H34wFux2d6~<;dUWSV8JL2V7Hj9q|hz`U-Js-xqBM|f!8LK zNd&%eN*xmiNO1xKxGb2dgLyE(Ls$sP;q&=Z05*)k5X^=UHWT3sQMM3O(%uNaB#iW-Xv{KPmubPQlu{-F=`Sq3Q7?p19v9)u zB(R(f%Mk<-aJYzo$Chz8s1#vy1OpuJ!-{2yTpT6fuwe-el_O#~50#;80Z+i;OpTJF z16ZY%q%>9?HlS;yb>Cvq4`PK<0@F}9p~7+VKn295;}lM&<2FE=$OYyYt$I9*bRW)} zSY;StoR8_F2;2g^&aTk-9(5^%FTEM`e2TUf@UG_mW5|RrYqJxTrLeoH`OC2mbTtV9OCPni8*S-GXFk%xK^tL5ia-faHMcTetv#)TU$bo z!!ehyfH@9|D!F^>){K@epzDS|uhY!)RD^8UR!~ro=$9{5sZzfuZawM}!`%@=|VTbah$=})S z>yEu>SXU>R&##-Swzg;7DD`{_<`jHfy69wOH$$nva^`s%duRM6_N}kYI38wiFF`UD z+m_}8?3%P2MbQqIYsN;716vnaA?a{N0)=@Qt5(_#h6(37J176v-k#Xl*eLWbI&tgb z#fx#Bot-1AC1n*A6}hoRxk1UB9fz&}37;Lm_E$r5bMs`cY)7caC>Ot*wn%2y?5}%;H4m-ma{y9KZF?`_F$Ng&VJi-oAOW!)&pP<5zeU zP8g(6V5PgfXx-_Nl06;3^Rqy_syQey+v%5Mj;M>C1+KEMq%M2!F6(gx?9cbEPeqqM z4L-GJcQLUtSCeWo&BX8T+qcg*%}~mWX`8rA2F6}#{r+4>bD&@S4lnFN&%|WKrXRN# zjqu;RrliD);_@{;zbAb@e0$2LNU!NpcVB-tPZN@Y_;lyAG7zo*TCP`n-O!G4^S>(h zv*e5m3M$6dbOh&2to!ErM-NZ>wouC-&pci6p!WE}Jt=u+ul^u)OJ2O|Nzj-vBW@n) dZ|x60%3!Dm)kkk%(Cz;HDdn-Uos!gre*?!G>q!6r diff --git a/client/client/src/assets/c2c_hangup.png b/client/client/src/assets/c2c_hangup.png deleted file mode 100644 index 26d5067451e9edc01c147198a79fbce8e1730520..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4754 zcmV;D5^e2?P)KLZ*U+IBfRsybQWXdwQbLP>6pAqfylh#{fb6;Z(vMMVS~$e@S=j*ftg6;Uhf59&ghTmgWD0l;*T zI709Y^p6lP1rIRMx#05C~cW=H_Aw*bJ-5DT&Z2n+x)QHX^p z00esgV8|mQcmRZ%02D^@S3L16t`O%c004NIvOKvYIYoh62rY33S640`D9%Y2D-rV&neh&#Q1i z007~1e$oCcFS8neI|hJl{-P!B1ZZ9hpmq0)X0i`JwE&>$+E?>%_LC6RbVIkUx0b+_+BaR3cnT7Zv!AJxW zizFb)h!jyGOOZ85F;a?DAXP{m@;!0_IfqH8(HlgRxt7s3}k3K`kFu>>-2Q$QMFfPW!La{h336o>X zu_CMttHv6zR;&ZNiS=X8v3CR#fknUxHUxJ0uoBa_M6WNWeqIg~6QE69c9o#eyhGvpiOA@W-aonk<7r1(?fC{oI5N*U!4 zfg=2N-7=cNnjjOr{yriy6mMFgG#l znCF=fnQv8CDz++o6_Lscl}eQ+l^ZHARH>?_s@|##Rr6KLRFA1%Q+=*RRWnoLsR`7U zt5vFIcfW3@?wFpwUVxrVZ>QdQz32KIeJ}k~{cZZE^+ya? z2D1z#2HOnI7(B%_ac?{wFUQ;QQA1tBKtrWrm0_3Rgps+?Jfqb{jYbcQX~taRB;#$y zZN{S}1|}gUOHJxc?wV3fxuz+mJ4`!F$IZ;mqRrNsHJd##*D~ju=bP7?-?v~|cv>vB zsJ6IeNwVZxrdjT`yl#bBIa#GxRa#xMMy;K#CDyyGyQdMSxlWT#tDe?p!?5wT$+oGt z8L;Kp2HUQ-ZMJ=3XJQv;x5ci*?vuTfeY$;({XGW_huIFR9a(?@3)XSs8O^N5RyOM=TTmp(3=8^+zpz2r)C z^>JO{deZfso3oq3?Wo(Y?l$ge?uXo;%ru`Vo>?<<(8I_>;8Eq#KMS9gFl*neeosSB zfoHYnBQIkwkyowPu(zdms`p{<7e4kra-ZWq<2*OsGTvEV%s0Td$hXT+!*8Bnh2KMe zBmZRodjHV?r+_5^X9J0WL4jKW`}lf%A-|44I@@LTvf1rHjG(ze6+w@Jt%Bvjts!X0 z?2xS?_ve_-kiKB_KiJlZ$9G`c^=E@oNG)mWWaNo-3TIW8)$Hg0Ub-~8?KhvJ>$ z3*&nim@mj(aCxE5!t{lw7O5^0EIO7zOo&c6l<+|iDySBWCGrz@C5{St!X3hAA}`T4 z(TLbXTq+(;@<=L8dXnssyft|w#WSTW<++3>sgS%(4NTpeI-VAqb|7ssJvzNHgOZVu zaYCvgO_R1~>SyL=cFU|~g|hy|Zi}}s9+d~lYqOB71z9Z$wnC=pR9Yz4DhIM>Wmjgu z&56o6maCpC&F##y%G;1PobR9i?GnNg;gYtchD%p19a!eQtZF&3JaKv33gZ<8D~47E ztUS1iwkmDaPpj=$m#%)jCVEY4fnLGNg2A-`YwHVD3gv};>)hAvT~AmqS>Lr``i7kw zJ{5_It`yrBmlc25DBO7E8;5VoznR>Ww5hAaxn$2~(q`%A-YuS64wkBy=9dm`4cXeX z4c}I@?e+FW+b@^RDBHV(wnMq2zdX3SWv9u`%{xC-q*U}&`cyXV(%rRT*Z6MH?i+i& z_B8C(+grT%{XWUQ+f@NoP1R=AW&26{v-dx)iK^-Nmiuj8txj!m?Z*Ss1N{dh4z}01 z)YTo*JycSU)+_5r4#yw9{+;i4Ee$peRgIj+;v;ZGdF1K$3E%e~4LaI(jC-u%2h$&R z9cLXcYC@Xwnns&bn)_Q~Te?roKGD|d-g^8;+aC{{G(1^(O7m37Y1-+6)01cN&y1aw zoqc{T`P^XJqPBbIW6s}d4{z_f5Om?vMgNQEJG?v2T=KYd^0M3I6IZxbny)%vZR&LD zJpPl@Psh8QyPB@KTx+@RdcC!KX7}kEo;S|j^u2lU7XQ}Oo;f|;z4Ll+_r>@1-xl3| zawq-H%e&ckC+@AhPrP6BKT#_XdT7&;F71j}Joy zkC~6lh7E@6o;W@^IpRNZ{ptLtL(gQ-CY~4mqW;US7Zxvm_|@yz&e53Bp_lTPlfP|z zrTyx_>lv@x#=^!PzR7qqF<$gm`|ZJZ+;<)Cqu&ot2z=0000WV@Og>004R=004l4008;_004mL004C`008P>0026e000+nl3&F} z000NQNklKqR1!+kgmDtbV|&J)_vX#an~yi| z>)tLPfqX)ORQlW8)w$>V&bjB@-;wI(7B*{}aNPmYnG8mUhv9S`)T&hkeuSivM1Eod zZoiLAHiNaw8XU(#6o#nPYA6+pD9z4dwNijzIp8U#tyuH>J$zgJcuw1@%rnp z!*LwU&(Gui_uj*S0|zjk&!gAtp;D>9_dNXP!Ua&=BRJ>aoI{c%5JEDNEE_@yRnxSo z$wFbjrfY^w2n)kt2O$KSre#Z|(r`MR<^y-oY_(e(tyZf(IyP4I2Hv@Py>2RsVll={ z09FtL@O&Rp6x~x?cO@c(0O$PLIV6Ng>AF4_hQW77Mn;P>Gc&V#EM_RG8lRk;Gzx`+ zdb7Q%X;@rbyd@b?6d?>l-*KF<(P+5UYPHpFw?C@a>*q_w;)QrT{;#dAEvM7zIIin< zg%I~nLid319-G*VzYpPnJgnWxqI#nnX@&L%)$V-w00N2l(Ag;p+?TVGyYJ~bE&UhDOG=Yk-xIOn(ADP8N4UayaI zI*m*w^G!m@4+Q6nnx-F!#bVhz1@ymy=Xu!L+UlM?dv>j|x_Y#3S+82Ad3JMi6M^r4 z)+3yA#N+Wj>2&(1hLLgS58+)#yktw6uu zN3+#xMPb+u!_bSxVgqmBsayyxo6Uql5O6;TXcUIYR4Qd85()ZMs+341@buG9{p!S< zC$3ORkI^6q7Bx+O{C=NLyWK7yJ$m$S$BrF4^T5uXE7OI7X*cabu~>AgwN2Ic{MeyG z2SeMod2Mr(2EL#1eLpunJ^jeS!oqWgVZ`s3%<#xa=E#vFKdaShC#a&b$0SKo@8_cR z_4SjNFJFH4oqxWwa^j6QFf~1mn69JOSHT#Aq9~9cfe->pDHKHkCFJtet1GD0YOi&> zy>}mf{QED*Fr!Dhr>@if#d%;j=^B? zg~qPy!uJEr&CNp7b(G8H-&&@{hDU}c48xdG6eS1XOIJuy6wJ@>-$5ZTbhn@fgF(ah zylSIqUsRa#t`NfYecug&AlYm-Js||f$0zXo^UuQ%0t8`rXQzw-@i_7m6X^ANa2y9t zyB!djod3A|@!x|mfMKMx@on4Ex*pq|NW`aex!eS$bQ=J6N7)obB`T9o`h#;m7z_rE z<2dD5EcVvGb=Sf$+;Tb{N!N9m%4A&Cw0%S--_GT<5k*l(7-P?J&dWjw9Dd?32qh?& z%dqVRJ})VR5O6vUoK6QuGKukR+W-Jj6yd>LyM9+7Ftv+9=S zT3SM}Sj7JMc|Zbg)_p<c+1jaO!pr8DqG3@gnN=Iv8WPoqCO;2z&SL{nO0M z%+rQpB<^Qw`Mw{WK7INrs;TPLJB`UGih?MLmZLDNbbGx^mSrs~igL#DypMzst&=BD zUf)e_r*K`@MYGw2EX#LP%2%#j`NhJ*!b>9~BM%yeu|Jhg&n1V3W_4Z9d>JBy$o}!; z$8EY*uYZ`&=Yuee{2=f*`~CiEzu#YOG^|VQPUrk=Y4&Vf*PFI&4>mS7Ff~-;?+qchUv)Mdj$~2`k zP6)X{+B7WtgYxpF4{58_dR0}`s%e^LqhYT^Jg`QFM|r2yy}r_3+aD;UpLFyWetY*0 z#uyl5poBEL{cf|@?_abm>#wV;6--Y}B@>B6adL99V4CJ`Ldb#X>1jjPb*a&8{_&Y- ze$=J_nw;}DIOl^XiZ~bIdfc-mj#PnPRIHZt82`Ti~3Uk?B!Ylp0*+7m{3+ootz+WN)WnQ(*-(AUCxn zQK2F?C$HG5!d3}vt`(3C64qBz04piUwpD^SD#ABF!8yMuRl!uxKsVXI%s|1+P|wiV z#N6CmN5ROz&_Lh7NZ-&%*U;R`*vQJjKmiJrfVLH-q*(>IxIyg#@@$ndN=gc>^!3Zj z%k|2Q_413-^$jg8EkR}&8R-I5=oVMzl_XZ^<`pZ$OmImpPA){ffi_eM3D1{oGuTzrd=COM+4n&cLd=IHa;5RX-@T zIKQ+g85kdF$}r8qu)}W=NFmTQR{lkqz(`5Vami0E%}vcK@pQ3O0?O#6WTsdd7@C4@78ktza%)qAC(cIA4$jI2l$iUIf(9qS;!r92h z#l*$g($dky)XBsIrq?sCxFj(zITdDaCeU7}USqs^t(=Qe6HD@oLh|!-U@0IVBfliS zI3vG6!8zDeAv`lLCBM8F6gd#Tx}+9mmZhe+73JqDfJ4_R6N~Kzri6SA(VId}i0K0z zqYp|NNJ#}I1WbP*COqK-IqEaktajPYGf47vQ$h^M~ z*T)`y*|;Ro#<6z^*F=+L8w8SsEfib-H)cAiD2C1wX*AiX7M8hg=eZz9R>cX2jHYI? z=w4Z%(b>MAFFf{cP5xuK>Ur*RHqXw^p83A^^I2)b`R9#|d@tW9+L_XPu%S@K{quE? z`j*un%s+77dj7R)rUJ(=IU_$2SKAwT+jT^^Hu|VJ7fSpS&eZ;$EQrbo_fv{d;P1b7lT|#w`z_zh zwxTV9rK3uqVU?*=Z~OxF-+%w5w>m8h)0@6EY2%KyVXN;?sBWD8AbRb!{Lf!ms=S+@ zWtd1cSE)($+8txewVHdXYuGyY=>4 z>e3*~ZWpEgpp{pCt~2KU&Zzsq%l%}^r%D^S{YE@eLX`AOhYK=-*a_6Q; zNpIfv>K-k5kJ+)R=3grN4@=oy4rkhNQMrxnn0LbG+8$P)rM6}D26LDa()JySXJlj0 X$l#FOY18WlDv>>1{an^LB{Ts5mk=>d diff --git a/client/client/src/assets/c2c_pause.png b/client/client/src/assets/c2c_pause.png deleted file mode 100644 index b3518ce467f074489ee6f4242f2275f5a9223e1c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6039 zcmbtWWmuG3*M5+03_1?TkOBkJ-6dTT(gH)b%+Mi?f-p*hpduZDG)Q*|NS82#0|Jsm z^NyZ#zVp`ge)VI=z4nUxS!?ZUKQY>x%ESaT1ONaKtEwpI0sw~j&w+=7o*TH7pP>)% z-Bpae0D$oJ&w&A?XHo$GftG{3ytcNzo41>ny_-9us=Pd-yQiC-gR?CFz-F`bAo_Yp z3Q5%Bp`2QD$V)XhU2;4|UAefBJBh5EO!#CEqM34M$aUIoDk@^p_U1%m#>a;|BiG>~ ziY1uFU1fR`|MYEiZ2$SP|68ZYCe-@SRrQqAM#(`|)d+4Y9#OIizm8xCQK1~e&96^; zI=h!wd1OKfK<)q;UX=}#*CjIsa1taTaqn&`?k4~PHcp5Kv}$Cu^3p|JlWxkTnPP;5 zW3+lFim2g*+yP|#;^p20GD;XBS*fggKn@mQIq=vT0cdjrmTbZ6<3LE(Nt!S^=;Z2TDdB#wr3vyuckhwN6oBnj7F%HMCO!Dr$k&VKTx>0FMaZ)rpSa z0I>W4%U)(?7!aNY+)>&$l-RphMz+C;&Qw~ZL_J7UG4v50w+F7FArAxluqx%fJ3>}B ztkPw8+I`cg?}rMIemxijfSg2f^w%C-!iGu8hKGgXYe+1(H(PM7?^;_UuGU71-DLn^ z**j?TiVIvt6C#ci;&SzdWe3aNoG|AJD$cHwRHhopLCzW;xc|(JV(yFjnVGfK)#(SF za*wR~4Fj(r?G~+um(Hg_5*MhWub);xq4&)~m9b8~whtbv=h2NM;fGt#uO}#9)Dm7_ z(2w8kRJE=*;=F^}xg?G*ma%J_l_jooOsOS7pu$lK!#|O`!0a*R zu^Jnhk$39~3IO&S-P*pe<6(x_KV2SyUhhg@D(A2OA$F=s9sppj0OHZ_uafS;0|14b zP|gZj+QT*~u2vknHthK}!V62Ga5+$CyBwJuflUaVrzJ;8m>hfLPz61wCHRXBy+Esu zeI(qSgs0u0jzrR(^vnt`yN$gm6dy~r7w@(e(`+<`b*vF{JRW6Q#0gWI3f8SS5My8T z9i6*siGnJ8y0Q9<1}gOXlAbq2qfC_=62*Ig`(YQ6P0D;PLo0P8zYtZ+*B1!Wge$!v z{A}aRm!3e8lkwT}BaP%Uq1=tn#rCAL2~zSsysh7;aQQo(d3m}!<2Y0V5qq;N~p8Fg|9uPCMIO zc!AnS)`pv>omAHM`J#+exR@tzCENy+`A5rl3WILN$lqtHe{ni*OC9dd8F2;Mk5vy6N9jpASw5v?}j|j4?Wjx-U=&i8p_B%eHUL#u* zSi`YRy)SFN^fxlUBUZGk80qC-z9RMqlI-@F>9v8S|0Ih23% zZn(Mdia|5wv*FkPQu$lTH_SsQ5pg8>)1GJuJ9P#XE)|3tN>!e!{+@a~j=D#mSD0@r zbt8>5&CS4wvxYN(Jh7kP)q_{8uV^{J`h`XBix!Ir4Gs(j^b-or^#aS34EXgBh4^2R ziw%mhw72wV^&o}f1yMzi0yll>cR|LNF*wE@>K$70?{soLSRk6Z83`X#SHZZLoQR7f zpM(l_vVItv3Gm@;OueLUjFT)X%oUaAf52~8rF-zwP8t`H>T#0kt%<+Eo}Y3M6uWq5 zmt%#4_Pv05J)f0u}-n_R^~x$`IXtm`RO0P~(sL!!XAa$_2oS=h z+ok(0D-J6YtD459#!kAfM*Vw^_u}f}>ODh)LvMyA(*!dl`KIn~WNc(iWh~WNn!rrB zY6@!VY*i~)P2L;t)HJz9n1~wZ85x+ERVkHbm9k7WmNw?!%&*skYZhluLOLq;YWivl zYpE;Nrg7%VYFugptsvHvklL=YjvaV2Jg_0~`K2T-anuY+F}(?Wkk?1gJ7N#T7So3_ zcccTm4wI2!h|vhy$TUBq=Jo(br$d%r#<((s5>oH=^dLGeMlEcBCq;@UgSLC2w|Vt} z_mPL$vftQIRz_7u`*y)x`Hs+z!%o!v>p_9n9NEVFUY|R9<-h8zjY<=~e#PswR1%~m zuN4ZZ-e3kl1}7SpPF2+AL5omUyOdJLQl767QV0p*#ruoK7K6gAwY{|iS{-iL77j)xZi-?LajFgUdk2aziKD@&D?!+huaS$@+k^=ZgGhv%cw_dioEg9dZ{u zDl{5BEpN)npt-NYso|IOJ+Vp97u3a{$F)`;&Q|!MNu5}IAww*iBHf44<-Vj?GvCvs z#1|fNMNAs-8ptMO-OgvA#5SVxs>?O57R>Mpx6i5SMG3YsH$jcu`)~Rt>{Fb$l@MD) zyOyDte$nLO?0ZAogH`==FN8C9Ute$EYQMFdRFfB}X2?x%wBB6eC|W7u;X6lwAjiHJ z`4Fc>qAs?E(`7=dc-t_gEU1~)Ps1tHysba1ts28=i_m~zEh2DhernrH%Lr_|RBd$@ znMEr_9ur%3XO1$3Jb0RY9=1js<<{SlHvjTtVR2`@&4}HY9ddnAN-`uQX4M-5toQlpcbi+&f%bH9;h3P>3HJ~+_tbC^Yjjl&`P zBhRv4Wd#QDoX%U$y{Ylvcs#u1Nb0uRK<2$Xrg$BJfDY`S0PyWQ$5JG#~i6p}J5< zOB4%1o@|%H1C29Kww=-@ttN{@nQhq_`Gu$n=|@-d)4TJ*j;+v~gVA|q6i&p`k*ma` z1X6kIgtUZ#NaDz?Y!N9@(G_XWOXNkq{D{p6Yc}Q8o2!8`N(yk$$;8&w@M!92ZpwZN zyu~FT?{c$si@JQSySBmg|&1%ORU01!(B07|zci!LPq zAZk}tkkyCHexLY&-yuU3v24-ZOxZ7#z7>gY&Q8nzoH$ef*FkgD5SqV^V1nrwc&F1d z@?)5{ey9)xYPLRzQRGOqDZ}GLg#Cuz(o(gBVH0K-tXtSU+dG09Tz*-ElW`eUSpF1K zpf_KyF_aAw(`?&+Vc2_NS9fo9k&um|zQx>67yxj6{e7;DIE0Z*VbqwmHLS!={7ndV zw^1TJjF(EX7;oKcMZsL?Hi>%0VuPI*s?yE)(*qjjm1u>n$C|U}?!-ySnqw~rU@Htb zL{z+AMU~DkK>+4YY}p!uf!@?Hh-_S(q^<8PG}$YM-^52tugRR%PqLnzb~+Mk z`AN+Qp%aKEGCztRCPUY{96SmPFOzIr^NVN`BjiGNk8|W^6s@~$16q`I!V?f=yWaCS z$zpqSHx2AHQ=&y!7+A8+TcITs1{ydB9zo?+vvOAgB9vOMKM4afK!~Ps<06jUb5Wvt zf^!0W%WaL7%%Sw`Q=W_-jCb{B#-%C! zbbkKDUm%%30np16uR^U3kM{0d`yokEt<2BOjlfF@hnQ@m`&-C`Aps+yDaUiB?TLht@`*J(EX`MSZ zB@Y@FcP!00Bg-$GvX^RH4g=jhojz_fkI)giFB9;X)`byLmVIrHxL5Z(#QXYpmVf8y zr;h(cL)qMRHTQ%2_3_yM5{8gcHgG=tjlF|dy&&s&$w={$a6MTHJz zetP}e3CG#k=fBr=fzNf;lCFE1k|T`caaFBuC-sZ;x4gdl*dkbsT^J${I6ZKZ{j{dI zU^!-tiX0&F+!!)tN^(g1Y9~!I6+w<~*cFrVdcJo0fJB7G~U9n5%Mck@f zOa@JE+8qAQIGAh`qj@Lc3ie(Y>?Syx@(;<$cF{=ig|pBAOhW4XkQQ%4!YI#Wl+q-5$zm0WrT1~qfr89`A+MSe#>n|yQN4c3J<{8S^M5Ola- z_WwlSY8>YF>?ui|D8+692x=!Ex3Ddykz^|AzxOCf_EsaOeMZ|-nJ=zt*-#usofO56 zldy9_<5L_}*P$0sZ~xDWh(5KwAWT;8A@HBIcA~`vBA2y5MlFo+MnZu*4Om3fH$qo9 z9=&Je&FqE|oG8OI!c*vo`E2^fc>3<>;-xw(rb#%c=6trWd|FCWpM1<|T=~5ddgA*~ z4RVgCu7iiOn41h7G<}>L0&Sf3P@~`yYMuk$rf*u3h~O7BgU<&lC8n5n;{pQDz8fy@ z6VDgTravq->v!m|d(s*jc&dqG;FUocgGvFFyY!L!nhC;oVA7zO%HIr~iyb|Xu-Bk^ z7h#$epNZ9W*c4o%l9KqK!0})ZCOs1qdFK7F3Hn{WV5`sC+uJ7A#SGV`$TsP%g_P#H>QL_>Ut0yR84}xqm1-S`y*5x&Gv` zOIS$gJ{8f}wvS=M_2{V1F$(47?q0D!Qc+a}H!rWYZ?oTd(&%k zzy34owK^+D?8 zL|kUB7G~L}=BMqMbe0%S*T4flQWEbePuL{K2&)E_ytZg1&q7=Y?8ZTwYnNS60^_%yIBL^R@S;-9iCJB-@j@-vysW0z zDU)Y6et#iboM@qRJC zPP_Nr2aLqRNFF8Pmo}W?u>O?`Y>qyC-kaD@exz9Iik>YW%#>wAMo9-wPUxBfq?Q6- zQRdji;aYq&DMefuPr(CTta>IDuQgYL2z@ZM4^Bg~_AeZgC{?d|`L3Lb=e8Lb7Gq0T zPR06qRFk(Ke|>2z;{F4A^kU?@?R8C*8;L^0eS=Ik@z<;7Ny4g;s@W{3>fWLJ&h_5k zjghk%WAz7Y^ov8FU^ZWaZ19X>>-861Capd@0%|&yStj+c7qj z)^RS<=i-Hx+P^(EQrK~>mN|f(I#E3~8q?93X0tF4#M?+lnfe_2z*67=PUgU?6CP$) zR)6s(i%xn7U|`H?76^f5Spx-=XLUcy(r?P-J?x1-wUmg8_Z2y7L|JczN2owt4sU099Gk2UodXMd*v?hd(&M&>i==lpga59^^-9;`? zip3K&H25;r4GXRvH^Hs=xBd?)|Fc|w)$Z%F2o#tZqu|Sy$8w;n67b58kEiL89hP>X z1-j-@ApdnN?HJjl-JS?2xX;iITRR4L6|0 zl1R1u27WO1DXa3Z%Fk9XPU`mXK@iK_-_X{fOZM0Vtw0ou%j hxtL$R|Mu&Z#{}s8SKECDqs7n=P*v1aD3h}c`x~d4O_~4z diff --git a/client/client/src/assets/c2c_play.png b/client/client/src/assets/c2c_play.png deleted file mode 100644 index 47ba131b79ec0ee8211dd17946eddfacb0a1c4b8..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 9288 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 F{{v7>56=Jq diff --git a/client/client/src/assets/c2c_sound.png b/client/client/src/assets/c2c_sound.png deleted file mode 100644 index d18fa88bacf0c7b91d6b13685e914b78bf4a6c45..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2907 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 FV1kl6VxRy3 diff --git a/client/client/src/assets/camera.png b/client/client/src/assets/camera.png deleted file mode 100644 index 685d99890bbee11fee49abca56c7c40ccfe6ab96..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1206 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 diff --git a/client/client/src/assets/hold.png b/client/client/src/assets/hold.png deleted file mode 100644 index 2d9ce9c4ec4b787b77e2407809c8887b6252dc6e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 598 zcmV-c0;&CpP)U3VE{tZoOXQ3gborPd)C!*bfsFfgUA%b`K z{k54{z0H}ACRrHvW^d-rdyicUV+{VYtX~gCqfs0|(-=vN2o1PiuPW{>+#Atov}dlj zm>FQRf_YAoB-!b7g57TC=llI0*6TIQX0twmlwz@1Su_y<#c()O27`fy#f%p1x~?-# z)7Wme<7b=AhIKj}t=(=bMjvNzr~MuZg=Ct#TCD`Id5F*FgY9+;-ENndyrfd8-V+sI zk|x?lbD>axN~J2Ai^W%{R^I>_0Z9u6gEF#73lqsO`axO|3~qzj{hRS`0}LC%>-AD? zlFkeU5t@ED93Che0EA(j5rE6(g7f(t5ddbb)O7oPG}&BpJRae6I)RyiO6J&XwmSe5 z5OEZ?Ln>~)xgN-MK!Jnpfz<8>_RWW{9kg+(HWc9OO0c-` ze)6;rj(aoS?OoonBPigGwXf14W%WhR-npH6wj=Ys<(drB(vLe9UA>a}z}^3CU~g7@ zLX+CspOfo(Bn%P`G%zx=@mNS)Gu*Z#+5Vnib=c$Fdy$FvBwl=eU$)%6fsrBMnjzEj T6J|0%r!aWB`njxgN@xNA2t-xj diff --git a/client/client/src/assets/mic.png b/client/client/src/assets/mic.png deleted file mode 100644 index c162e7d66c0bac3d92b6eef2ea9698baec3a8f5d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1343 zcmbVMZA=?w9KTHmj)0DYED=$T1GgD$@1E-$J?XIRwbEe`+bX#Dfur{nZl!nS?rKY& z(=f(_ZP_FtTZ~J@7-5=WFit@RZV^y}gAc~Vy=0D&NFu>$NCZO^p96}1Ap77YchB4J z_xry-*IrfmOjbs228Ll-o^sZQ#)q``fi(1e>T1_MG(4=jYE-`zQsbNqF*`5SLEIDJ z>Y)#Ed~?&cuoT1Y;$xC^oPS_xnCuQhQRtAE}aL~#VWqa|`1cL-3Q04GMq)}9ugpF9$WzbyPCJB5M zqK0k6no~92D%>f_5I5;5U63+UxEbhy!Dz8qp2TSiP$Wf@fYt#EW1ty|!q*=HS(Et? z<73_Hw$RE(G^lEnA<1|=u8$k^l3Y&$tJSJ$(6kOAbV{?RatWQN6s8nds03vpstS^b zYl>W*6jN;k@^mePNYv}y5Ehm7M4^c1YgZA zBWz~fU^kh7%V2k}MQty!SXoyIpiO2#nJp;lH7@^uGDae2NUb&g(<-Sg)PLG^qw&#V zW-4_{M4Dz?J2@KoP_@AjH5m{|Y7@Z;%cTi)&O-r3)C?l1DD<4Q&Pp_iwIXJ4Njp54<0 zJ!L!F3Qo8SeK|)4i)*)+Vr5>xoOd+ytECfnePi$KA*L3}zyCCA;PW@2HEpgbZ~2S9 zV`FD4j|N_VUGc$F*NT3eT)24}4(3+IKJM(9j^AiGaA)7opJZ1XCs#tO-{|Qa*+2T- zuJM`vR+D%>@BYh=-g?cKb^DL@_j^k6Gm7h9G9QB-+bp9`oEg6oYL$LnT$auZwNHgl zEzGx`j6CRH+R>q#$gL~-Xo=r`^-^~2-$bWAGwpEk^o8gD+&V$m+6xj}(rX`kXJ&RV z`$c_6ODvh+*fhN>ac8bza$=>8{M|C5WX~PCv^Z9G@pNa=waWvOw?90%{8sFdSxqIlBFs1#{Jg!Q%&r#d*4>Ka+ AGynhq diff --git a/client/client/src/assets/mic_crossed.png b/client/client/src/assets/mic_crossed.png deleted file mode 100644 index 712a4f83d8c85b65c0b724f5c624c840a4fb6108..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 255 zcmeAS@N?(olHy`uVBq!ia0vp^A|TAc1|)ksWqE;=WQl7;NpOBzNqJ&XDuZK6ep0G} zXKrG8YEWuoN@d~6R2!h8g`O^sAr-gQT)oZPpuoc#;B}+Xab~mQ%tcBQSw4oHS}cET z!m}G;0ZD1aMt5pE4c}QUT_wP@GjQ4We^;HnIt9WGpG!zsyLY+bip*uyZ$LwH8;Z8 zcx9=1R`AC{0qrOIg%|Kv3ppF#ImA`)OT2*7fPrnUyGGAx7eAn589ZJ6T-G@yGywo} CKw#nk diff --git a/client/client/src/assets/mic_settings.png b/client/client/src/assets/mic_settings.png deleted file mode 100644 index 67de2c6ccbeac17742f56cf7391e72b2bf5033ba..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 512 zcmV+b0{{JqP)CQDsH?WF>AIFt zQuJ}i;w2$ZUU#3SZ6RY0Gw;kZ&ol1~2ky^QZ(fom$=jNJZt!z7w_pH~wdQ;R)Gh%BbQFCx+Nm!4SuS-vkr`vhhrX zM*>w%e+v~?m@q~ImPAgtLkR_3U<2F8LP3W5=LJ*ZN|S5p#sf4YFr$p~Q~Z*0Ngxf2 zjk#J#<7EAlhzlrV53~GF&pIzcCN_lz9@05UeoUXiK%N z#x+4o*i_c|6_Uu1+&TIho?3@y4k-#b8Y_o94zW*B3a1ne2-Y5s0uke$$|@=}OP-i= zNYZQA=>PrZu0MfSL=b8UhD_={W4IY1{b{)U)*gc45xtL%IYLY&hF;d`@GzI&7H&D# zh;z_BX$#hqh@q?AY3sJTod2%*Yd)_>YM0#q&ixGuh+PQsneK)F0000|6H_V+Po~;1Ffi`)ba4!+xb^0aW7i=E0f)e;DKm4PRn_j9V{kL|GP7P= zqLScI&+wPk+O94hcD`Ga=4Y=}Kk@jHkV51H9S^aSO(~9>Jj7JEC%J9{iA-VzicADb zsB{A*6e58VtS6NaN-;&inxE#Dp5L20YuWtcOGU0vys-Ms`?&4?2NM{8rV1F|oV)R= zi}#L{_iihrc-TIKU;p-adg{#QH*-&9OSBcrELM;9s=VsY`FfX^+17pU`Tf4dWY?BV zyKA=Vvyh4Rw|8vb>sxNuy>(d`uC#8G`Sj?GLgiCIt~5N|6pGwX^uA;|=r<11Ll}UNR%`$22roKl? z_Y)RGeLA~omFoR(-dk0?!?wztG%TulqJVWxFs2zi MUHx3vIVCg!032-LZU6uP diff --git a/client/client/src/assets/pie/PIE.htc b/client/client/src/assets/pie/PIE.htc deleted file mode 100644 index ca3b5470..00000000 --- a/client/client/src/assets/pie/PIE.htc +++ /dev/null @@ -1,96 +0,0 @@ - - - - - - - - - diff --git a/client/client/src/assets/pie/PIE.js b/client/client/src/assets/pie/PIE.js deleted file mode 100644 index d36448a9..00000000 --- a/client/client/src/assets/pie/PIE.js +++ /dev/null @@ -1,88 +0,0 @@ -/* -PIE: CSS3 rendering for IE -Version 1.0.0 -http://css3pie.com -Dual-licensed for use under the Apache License Version 2.0 or the General Public License (GPL) Version 2. -*/ -(function(){ -var doc = document;var f=window.PIE; -if(!f){f=window.PIE={F:"-pie-",nb:"Pie",La:"pie_",Ac:{TD:1,TH:1},cc:{TABLE:1,THEAD:1,TBODY:1,TFOOT:1,TR:1,INPUT:1,TEXTAREA:1,SELECT:1,OPTION:1,IMG:1,HR:1},fc:{A:1,INPUT:1,TEXTAREA:1,SELECT:1,BUTTON:1},Gd:{submit:1,button:1,reset:1},aa:function(){}};try{doc.execCommand("BackgroundImageCache",false,true)}catch(aa){}for(var ba=4,Z=doc.createElement("div"),ca=Z.getElementsByTagName("i"),ga;Z.innerHTML=" - - - - - - - - diff --git a/client/client/src/assets/pie/PIE_uncompressed.js b/client/client/src/assets/pie/PIE_uncompressed.js deleted file mode 100644 index 85f6785e..00000000 --- a/client/client/src/assets/pie/PIE_uncompressed.js +++ /dev/null @@ -1,4474 +0,0 @@ -/* -PIE: CSS3 rendering for IE -Version 1.0.0 -http://css3pie.com -Dual-licensed for use under the Apache License Version 2.0 or the General Public License (GPL) Version 2. -*/ -(function(){ -var doc = document;var PIE = window['PIE']; - -if( !PIE ) { - PIE = window['PIE'] = { - CSS_PREFIX: '-pie-', - STYLE_PREFIX: 'Pie', - CLASS_PREFIX: 'pie_', - tableCellTags: { - 'TD': 1, - 'TH': 1 - }, - - /** - * Lookup table of elements which cannot take custom children. - */ - childlessElements: { - 'TABLE':1, - 'THEAD':1, - 'TBODY':1, - 'TFOOT':1, - 'TR':1, - 'INPUT':1, - 'TEXTAREA':1, - 'SELECT':1, - 'OPTION':1, - 'IMG':1, - 'HR':1 - }, - - /** - * Elements that can receive user focus - */ - focusableElements: { - 'A':1, - 'INPUT':1, - 'TEXTAREA':1, - 'SELECT':1, - 'BUTTON':1 - }, - - /** - * Values of the type attribute for input elements displayed as buttons - */ - inputButtonTypes: { - 'submit':1, - 'button':1, - 'reset':1 - }, - - emptyFn: function() {} - }; - - // Force the background cache to be used. No reason it shouldn't be. - try { - doc.execCommand( 'BackgroundImageCache', false, true ); - } catch(e) {} - - (function() { - /* - * IE version detection approach by James Padolsey, with modifications -- from - * http://james.padolsey.com/javascript/detect-ie-in-js-using-conditional-comments/ - */ - var ieVersion = 4, - div = doc.createElement('div'), - all = div.getElementsByTagName('i'), - shape; - while ( - div.innerHTML = '', - all[0] - ) {} - PIE.ieVersion = ieVersion; - - // Detect IE6 - if( ieVersion === 6 ) { - // IE6 can't access properties with leading dash, but can without it. - PIE.CSS_PREFIX = PIE.CSS_PREFIX.replace( /^-/, '' ); - } - - PIE.ieDocMode = doc.documentMode || PIE.ieVersion; - - // Detect VML support (a small number of IE installs don't have a working VML engine) - div.innerHTML = ''; - shape = div.firstChild; - shape.style['behavior'] = 'url(#default#VML)'; - PIE.supportsVML = (typeof shape['adj'] === "object"); - }()); -/** - * Utility functions - */ -(function() { - var vmlCreatorDoc, - idNum = 0, - imageSizes = {}; - - - PIE.Util = { - - /** - * To create a VML element, it must be created by a Document which has the VML - * namespace set. Unfortunately, if you try to add the namespace programatically - * into the main document, you will get an "Unspecified error" when trying to - * access document.namespaces before the document is finished loading. To get - * around this, we create a DocumentFragment, which in IE land is apparently a - * full-fledged Document. It allows adding namespaces immediately, so we add the - * namespace there and then have it create the VML element. - * @param {string} tag The tag name for the VML element - * @return {Element} The new VML element - */ - createVmlElement: function( tag ) { - var vmlPrefix = 'css3vml'; - if( !vmlCreatorDoc ) { - vmlCreatorDoc = doc.createDocumentFragment(); - vmlCreatorDoc.namespaces.add( vmlPrefix, 'urn:schemas-microsoft-com:vml' ); - } - return vmlCreatorDoc.createElement( vmlPrefix + ':' + tag ); - }, - - - /** - * Generate and return a unique ID for a given object. The generated ID is stored - * as a property of the object for future reuse. - * @param {Object} obj - */ - getUID: function( obj ) { - return obj && obj[ '_pieId' ] || ( obj[ '_pieId' ] = '_' + ++idNum ); - }, - - - /** - * Simple utility for merging objects - * @param {Object} obj1 The main object into which all others will be merged - * @param {...Object} var_args Other objects which will be merged into the first, in order - */ - merge: function( obj1 ) { - var i, len, p, objN, args = arguments; - for( i = 1, len = args.length; i < len; i++ ) { - objN = args[i]; - for( p in objN ) { - if( objN.hasOwnProperty( p ) ) { - obj1[ p ] = objN[ p ]; - } - } - } - return obj1; - }, - - - /** - * Execute a callback function, passing it the dimensions of a given image once - * they are known. - * @param {string} src The source URL of the image - * @param {function({w:number, h:number})} func The callback function to be called once the image dimensions are known - * @param {Object} ctx A context object which will be used as the 'this' value within the executed callback function - */ - withImageSize: function( src, func, ctx ) { - var size = imageSizes[ src ], img, queue; - if( size ) { - // If we have a queue, add to it - if( Object.prototype.toString.call( size ) === '[object Array]' ) { - size.push( [ func, ctx ] ); - } - // Already have the size cached, call func right away - else { - func.call( ctx, size ); - } - } else { - queue = imageSizes[ src ] = [ [ func, ctx ] ]; //create queue - img = new Image(); - img.onload = function() { - size = imageSizes[ src ] = { w: img.width, h: img.height }; - for( var i = 0, len = queue.length; i < len; i++ ) { - queue[ i ][ 0 ].call( queue[ i ][ 1 ], size ); - } - img.onload = null; - }; - img.src = src; - } - } - }; -})();/** - * Utility functions for handling gradients - */ -PIE.GradientUtil = { - - getGradientMetrics: function( el, width, height, gradientInfo ) { - var angle = gradientInfo.angle, - startPos = gradientInfo.gradientStart, - startX, startY, - endX, endY, - startCornerX, startCornerY, - endCornerX, endCornerY, - deltaX, deltaY, - p, UNDEF; - - // Find the "start" and "end" corners; these are the corners furthest along the gradient line. - // This is used below to find the start/end positions of the CSS3 gradient-line, and also in finding - // the total length of the VML rendered gradient-line corner to corner. - function findCorners() { - startCornerX = ( angle >= 90 && angle < 270 ) ? width : 0; - startCornerY = angle < 180 ? height : 0; - endCornerX = width - startCornerX; - endCornerY = height - startCornerY; - } - - // Normalize the angle to a value between [0, 360) - function normalizeAngle() { - while( angle < 0 ) { - angle += 360; - } - angle = angle % 360; - } - - // Find the start and end points of the gradient - if( startPos ) { - startPos = startPos.coords( el, width, height ); - startX = startPos.x; - startY = startPos.y; - } - if( angle ) { - angle = angle.degrees(); - - normalizeAngle(); - findCorners(); - - // If no start position was specified, then choose a corner as the starting point. - if( !startPos ) { - startX = startCornerX; - startY = startCornerY; - } - - // Find the end position by extending a perpendicular line from the gradient-line which - // intersects the corner opposite from the starting corner. - p = PIE.GradientUtil.perpendicularIntersect( startX, startY, angle, endCornerX, endCornerY ); - endX = p[0]; - endY = p[1]; - } - else if( startPos ) { - // Start position but no angle specified: find the end point by rotating 180deg around the center - endX = width - startX; - endY = height - startY; - } - else { - // Neither position nor angle specified; create vertical gradient from top to bottom - startX = startY = endX = 0; - endY = height; - } - deltaX = endX - startX; - deltaY = endY - startY; - - if( angle === UNDEF ) { - // Get the angle based on the change in x/y from start to end point. Checks first for horizontal - // or vertical angles so they get exact whole numbers rather than what atan2 gives. - angle = ( !deltaX ? ( deltaY < 0 ? 90 : 270 ) : - ( !deltaY ? ( deltaX < 0 ? 180 : 0 ) : - -Math.atan2( deltaY, deltaX ) / Math.PI * 180 - ) - ); - normalizeAngle(); - findCorners(); - } - - return { - angle: angle, - startX: startX, - startY: startY, - endX: endX, - endY: endY, - startCornerX: startCornerX, - startCornerY: startCornerY, - endCornerX: endCornerX, - endCornerY: endCornerY, - deltaX: deltaX, - deltaY: deltaY, - lineLength: PIE.GradientUtil.distance( startX, startY, endX, endY ) - } - }, - - /** - * Find the point along a given line (defined by a starting point and an angle), at which - * that line is intersected by a perpendicular line extending through another point. - * @param x1 - x coord of the starting point - * @param y1 - y coord of the starting point - * @param angle - angle of the line extending from the starting point (in degrees) - * @param x2 - x coord of point along the perpendicular line - * @param y2 - y coord of point along the perpendicular line - * @return [ x, y ] - */ - perpendicularIntersect: function( x1, y1, angle, x2, y2 ) { - // Handle straight vertical and horizontal angles, for performance and to avoid - // divide-by-zero errors. - if( angle === 0 || angle === 180 ) { - return [ x2, y1 ]; - } - else if( angle === 90 || angle === 270 ) { - return [ x1, y2 ]; - } - else { - // General approach: determine the Ax+By=C formula for each line (the slope of the second - // line is the negative inverse of the first) and then solve for where both formulas have - // the same x/y values. - var a1 = Math.tan( -angle * Math.PI / 180 ), - c1 = a1 * x1 - y1, - a2 = -1 / a1, - c2 = a2 * x2 - y2, - d = a2 - a1, - endX = ( c2 - c1 ) / d, - endY = ( a1 * c2 - a2 * c1 ) / d; - return [ endX, endY ]; - } - }, - - /** - * Find the distance between two points - * @param {Number} p1x - * @param {Number} p1y - * @param {Number} p2x - * @param {Number} p2y - * @return {Number} the distance - */ - distance: function( p1x, p1y, p2x, p2y ) { - var dx = p2x - p1x, - dy = p2y - p1y; - return Math.abs( - dx === 0 ? dy : - dy === 0 ? dx : - Math.sqrt( dx * dx + dy * dy ) - ); - } - -};/** - * - */ -PIE.Observable = function() { - /** - * List of registered observer functions - */ - this.observers = []; - - /** - * Hash of function ids to their position in the observers list, for fast lookup - */ - this.indexes = {}; -}; -PIE.Observable.prototype = { - - observe: function( fn ) { - var id = PIE.Util.getUID( fn ), - indexes = this.indexes, - observers = this.observers; - if( !( id in indexes ) ) { - indexes[ id ] = observers.length; - observers.push( fn ); - } - }, - - unobserve: function( fn ) { - var id = PIE.Util.getUID( fn ), - indexes = this.indexes; - if( id && id in indexes ) { - delete this.observers[ indexes[ id ] ]; - delete indexes[ id ]; - } - }, - - fire: function() { - var o = this.observers, - i = o.length; - while( i-- ) { - o[ i ] && o[ i ](); - } - } - -};/* - * Simple heartbeat timer - this is a brute-force workaround for syncing issues caused by IE not - * always firing the onmove and onresize events when elements are moved or resized. We check a few - * times every second to make sure the elements have the correct position and size. See Element.js - * which adds heartbeat listeners based on the custom -pie-poll flag, which defaults to true in IE8-9 - * and false elsewhere. - */ - -PIE.Heartbeat = new PIE.Observable(); -PIE.Heartbeat.run = function() { - var me = this, - interval; - if( !me.running ) { - interval = doc.documentElement.currentStyle.getAttribute( PIE.CSS_PREFIX + 'poll-interval' ) || 250; - (function beat() { - me.fire(); - setTimeout(beat, interval); - })(); - me.running = 1; - } -}; -/** - * Create an observable listener for the onunload event - */ -(function() { - PIE.OnUnload = new PIE.Observable(); - - function handleUnload() { - PIE.OnUnload.fire(); - window.detachEvent( 'onunload', handleUnload ); - window[ 'PIE' ] = null; - } - - window.attachEvent( 'onunload', handleUnload ); - - /** - * Attach an event which automatically gets detached onunload - */ - PIE.OnUnload.attachManagedEvent = function( target, name, handler ) { - target.attachEvent( name, handler ); - this.observe( function() { - target.detachEvent( name, handler ); - } ); - }; -})()/** - * Create a single observable listener for window resize events. - */ -PIE.OnResize = new PIE.Observable(); - -PIE.OnUnload.attachManagedEvent( window, 'onresize', function() { PIE.OnResize.fire(); } ); -/** - * Create a single observable listener for scroll events. Used for lazy loading based - * on the viewport, and for fixed position backgrounds. - */ -(function() { - PIE.OnScroll = new PIE.Observable(); - - function scrolled() { - PIE.OnScroll.fire(); - } - - PIE.OnUnload.attachManagedEvent( window, 'onscroll', scrolled ); - - PIE.OnResize.observe( scrolled ); -})(); -/** - * Listen for printing events, destroy all active PIE instances when printing, and - * restore them afterward. - */ -(function() { - - var elements; - - function beforePrint() { - elements = PIE.Element.destroyAll(); - } - - function afterPrint() { - if( elements ) { - for( var i = 0, len = elements.length; i < len; i++ ) { - PIE[ 'attach' ]( elements[i] ); - } - elements = 0; - } - } - - if( PIE.ieDocMode < 9 ) { - PIE.OnUnload.attachManagedEvent( window, 'onbeforeprint', beforePrint ); - PIE.OnUnload.attachManagedEvent( window, 'onafterprint', afterPrint ); - } - -})();/** - * Create a single observable listener for document mouseup events. - */ -PIE.OnMouseup = new PIE.Observable(); - -PIE.OnUnload.attachManagedEvent( doc, 'onmouseup', function() { PIE.OnMouseup.fire(); } ); -/** - * Wrapper for length and percentage style values. The value is immutable. A singleton instance per unique - * value is returned from PIE.getLength() - always use that instead of instantiating directly. - * @constructor - * @param {string} val The CSS string representing the length. It is assumed that this will already have - * been validated as a valid length or percentage syntax. - */ -PIE.Length = (function() { - var lengthCalcEl = doc.createElement( 'length-calc' ), - parent = doc.body || doc.documentElement, - s = lengthCalcEl.style, - conversions = {}, - units = [ 'mm', 'cm', 'in', 'pt', 'pc' ], - i = units.length, - instances = {}; - - s.position = 'absolute'; - s.top = s.left = '-9999px'; - - parent.appendChild( lengthCalcEl ); - while( i-- ) { - s.width = '100' + units[i]; - conversions[ units[i] ] = lengthCalcEl.offsetWidth / 100; - } - parent.removeChild( lengthCalcEl ); - - // All calcs from here on will use 1em - s.width = '1em'; - - - function Length( val ) { - this.val = val; - } - Length.prototype = { - /** - * Regular expression for matching the length unit - * @private - */ - unitRE: /(px|em|ex|mm|cm|in|pt|pc|%)$/, - - /** - * Get the numeric value of the length - * @return {number} The value - */ - getNumber: function() { - var num = this.num, - UNDEF; - if( num === UNDEF ) { - num = this.num = parseFloat( this.val ); - } - return num; - }, - - /** - * Get the unit of the length - * @return {string} The unit - */ - getUnit: function() { - var unit = this.unit, - m; - if( !unit ) { - m = this.val.match( this.unitRE ); - unit = this.unit = ( m && m[0] ) || 'px'; - } - return unit; - }, - - /** - * Determine whether this is a percentage length value - * @return {boolean} - */ - isPercentage: function() { - return this.getUnit() === '%'; - }, - - /** - * Resolve this length into a number of pixels. - * @param {Element} el - the context element, used to resolve font-relative values - * @param {(function():number|number)=} pct100 - the number of pixels that equal a 100% percentage. This can be either a number or a - * function which will be called to return the number. - */ - pixels: function( el, pct100 ) { - var num = this.getNumber(), - unit = this.getUnit(); - switch( unit ) { - case "px": - return num; - case "%": - return num * ( typeof pct100 === 'function' ? pct100() : pct100 ) / 100; - case "em": - return num * this.getEmPixels( el ); - case "ex": - return num * this.getEmPixels( el ) / 2; - default: - return num * conversions[ unit ]; - } - }, - - /** - * The em and ex units are relative to the font-size of the current element, - * however if the font-size is set using non-pixel units then we get that value - * rather than a pixel conversion. To get around this, we keep a floating element - * with width:1em which we insert into the target element and then read its offsetWidth. - * For elements that won't accept a child we insert into the parent node and perform - * additional calculation. If the font-size *is* specified in pixels, then we use that - * directly to avoid the expensive DOM manipulation. - * @param {Element} el - * @return {number} - */ - getEmPixels: function( el ) { - var fs = el.currentStyle.fontSize, - px, parent, me; - - if( fs.indexOf( 'px' ) > 0 ) { - return parseFloat( fs ); - } - else if( el.tagName in PIE.childlessElements ) { - me = this; - parent = el.parentNode; - return PIE.getLength( fs ).pixels( parent, function() { - return me.getEmPixels( parent ); - } ); - } - else { - el.appendChild( lengthCalcEl ); - px = lengthCalcEl.offsetWidth; - if( lengthCalcEl.parentNode === el ) { //not sure how this could be false but it sometimes is - el.removeChild( lengthCalcEl ); - } - return px; - } - } - }; - - - /** - * Retrieve a PIE.Length instance for the given value. A shared singleton instance is returned for each unique value. - * @param {string} val The CSS string representing the length. It is assumed that this will already have - * been validated as a valid length or percentage syntax. - */ - PIE.getLength = function( val ) { - return instances[ val ] || ( instances[ val ] = new Length( val ) ); - }; - - return Length; -})(); -/** - * Wrapper for a CSS3 bg-position value. Takes up to 2 position keywords and 2 lengths/percentages. - * @constructor - * @param {Array.} tokens The tokens making up the background position value. - */ -PIE.BgPosition = (function() { - - var length_fifty = PIE.getLength( '50%' ), - vert_idents = { 'top': 1, 'center': 1, 'bottom': 1 }, - horiz_idents = { 'left': 1, 'center': 1, 'right': 1 }; - - - function BgPosition( tokens ) { - this.tokens = tokens; - } - BgPosition.prototype = { - /** - * Normalize the values into the form: - * [ xOffsetSide, xOffsetLength, yOffsetSide, yOffsetLength ] - * where: xOffsetSide is either 'left' or 'right', - * yOffsetSide is either 'top' or 'bottom', - * and x/yOffsetLength are both PIE.Length objects. - * @return {Array} - */ - getValues: function() { - if( !this._values ) { - var tokens = this.tokens, - len = tokens.length, - Tokenizer = PIE.Tokenizer, - identType = Tokenizer.Type, - length_zero = PIE.getLength( '0' ), - type_ident = identType.IDENT, - type_length = identType.LENGTH, - type_percent = identType.PERCENT, - type, value, - vals = [ 'left', length_zero, 'top', length_zero ]; - - // If only one value, the second is assumed to be 'center' - if( len === 1 ) { - tokens.push( new Tokenizer.Token( type_ident, 'center' ) ); - len++; - } - - // Two values - CSS2 - if( len === 2 ) { - // If both idents, they can appear in either order, so switch them if needed - if( type_ident & ( tokens[0].tokenType | tokens[1].tokenType ) && - tokens[0].tokenValue in vert_idents && tokens[1].tokenValue in horiz_idents ) { - tokens.push( tokens.shift() ); - } - if( tokens[0].tokenType & type_ident ) { - if( tokens[0].tokenValue === 'center' ) { - vals[1] = length_fifty; - } else { - vals[0] = tokens[0].tokenValue; - } - } - else if( tokens[0].isLengthOrPercent() ) { - vals[1] = PIE.getLength( tokens[0].tokenValue ); - } - if( tokens[1].tokenType & type_ident ) { - if( tokens[1].tokenValue === 'center' ) { - vals[3] = length_fifty; - } else { - vals[2] = tokens[1].tokenValue; - } - } - else if( tokens[1].isLengthOrPercent() ) { - vals[3] = PIE.getLength( tokens[1].tokenValue ); - } - } - - // Three or four values - CSS3 - else { - // TODO - } - - this._values = vals; - } - return this._values; - }, - - /** - * Find the coordinates of the background image from the upper-left corner of the background area. - * Note that these coordinate values are not rounded. - * @param {Element} el - * @param {number} width - the width for percentages (background area width minus image width) - * @param {number} height - the height for percentages (background area height minus image height) - * @return {Object} { x: Number, y: Number } - */ - coords: function( el, width, height ) { - var vals = this.getValues(), - pxX = vals[1].pixels( el, width ), - pxY = vals[3].pixels( el, height ); - - return { - x: vals[0] === 'right' ? width - pxX : pxX, - y: vals[2] === 'bottom' ? height - pxY : pxY - }; - } - }; - - return BgPosition; -})(); -/** - * Wrapper for a CSS3 background-size value. - * @constructor - * @param {String|PIE.Length} w The width parameter - * @param {String|PIE.Length} h The height parameter, if any - */ -PIE.BgSize = (function() { - - var CONTAIN = 'contain', - COVER = 'cover', - AUTO = 'auto'; - - - function BgSize( w, h ) { - this.w = w; - this.h = h; - } - BgSize.prototype = { - - pixels: function( el, areaW, areaH, imgW, imgH ) { - var me = this, - w = me.w, - h = me.h, - areaRatio = areaW / areaH, - imgRatio = imgW / imgH; - - if ( w === CONTAIN ) { - w = imgRatio > areaRatio ? areaW : areaH * imgRatio; - h = imgRatio > areaRatio ? areaW / imgRatio : areaH; - } - else if ( w === COVER ) { - w = imgRatio < areaRatio ? areaW : areaH * imgRatio; - h = imgRatio < areaRatio ? areaW / imgRatio : areaH; - } - else if ( w === AUTO ) { - h = ( h === AUTO ? imgH : h.pixels( el, areaH ) ); - w = h * imgRatio; - } - else { - w = w.pixels( el, areaW ); - h = ( h === AUTO ? w / imgRatio : h.pixels( el, areaH ) ); - } - - return { w: w, h: h }; - } - - }; - - BgSize.DEFAULT = new BgSize( AUTO, AUTO ); - - return BgSize; -})(); -/** - * Wrapper for angle values; handles conversion to degrees from all allowed angle units - * @constructor - * @param {string} val The raw CSS value for the angle. It is assumed it has been pre-validated. - */ -PIE.Angle = (function() { - function Angle( val ) { - this.val = val; - } - Angle.prototype = { - unitRE: /[a-z]+$/i, - - /** - * @return {string} The unit of the angle value - */ - getUnit: function() { - return this._unit || ( this._unit = this.val.match( this.unitRE )[0].toLowerCase() ); - }, - - /** - * Get the numeric value of the angle in degrees. - * @return {number} The degrees value - */ - degrees: function() { - var deg = this._deg, u, n; - if( deg === undefined ) { - u = this.getUnit(); - n = parseFloat( this.val, 10 ); - deg = this._deg = ( u === 'deg' ? n : u === 'rad' ? n / Math.PI * 180 : u === 'grad' ? n / 400 * 360 : u === 'turn' ? n * 360 : 0 ); - } - return deg; - } - }; - - return Angle; -})();/** - * Abstraction for colors values. Allows detection of rgba values. A singleton instance per unique - * value is returned from PIE.getColor() - always use that instead of instantiating directly. - * @constructor - * @param {string} val The raw CSS string value for the color - */ -PIE.Color = (function() { - var instances = {}; - - function Color( val ) { - this.val = val; - } - - /** - * Regular expression for matching rgba colors and extracting their components - * @type {RegExp} - */ - Color.rgbaRE = /\s*rgba\(\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d+|\d*\.\d+)\s*\)\s*/; - - Color.names = { - "aliceblue":"F0F8FF", "antiquewhite":"FAEBD7", "aqua":"0FF", - "aquamarine":"7FFFD4", "azure":"F0FFFF", "beige":"F5F5DC", - "bisque":"FFE4C4", "black":"000", "blanchedalmond":"FFEBCD", - "blue":"00F", "blueviolet":"8A2BE2", "brown":"A52A2A", - "burlywood":"DEB887", "cadetblue":"5F9EA0", "chartreuse":"7FFF00", - "chocolate":"D2691E", "coral":"FF7F50", "cornflowerblue":"6495ED", - "cornsilk":"FFF8DC", "crimson":"DC143C", "cyan":"0FF", - "darkblue":"00008B", "darkcyan":"008B8B", "darkgoldenrod":"B8860B", - "darkgray":"A9A9A9", "darkgreen":"006400", "darkkhaki":"BDB76B", - "darkmagenta":"8B008B", "darkolivegreen":"556B2F", "darkorange":"FF8C00", - "darkorchid":"9932CC", "darkred":"8B0000", "darksalmon":"E9967A", - "darkseagreen":"8FBC8F", "darkslateblue":"483D8B", "darkslategray":"2F4F4F", - "darkturquoise":"00CED1", "darkviolet":"9400D3", "deeppink":"FF1493", - "deepskyblue":"00BFFF", "dimgray":"696969", "dodgerblue":"1E90FF", - "firebrick":"B22222", "floralwhite":"FFFAF0", "forestgreen":"228B22", - "fuchsia":"F0F", "gainsboro":"DCDCDC", "ghostwhite":"F8F8FF", - "gold":"FFD700", "goldenrod":"DAA520", "gray":"808080", - "green":"008000", "greenyellow":"ADFF2F", "honeydew":"F0FFF0", - "hotpink":"FF69B4", "indianred":"CD5C5C", "indigo":"4B0082", - "ivory":"FFFFF0", "khaki":"F0E68C", "lavender":"E6E6FA", - "lavenderblush":"FFF0F5", "lawngreen":"7CFC00", "lemonchiffon":"FFFACD", - "lightblue":"ADD8E6", "lightcoral":"F08080", "lightcyan":"E0FFFF", - "lightgoldenrodyellow":"FAFAD2", "lightgreen":"90EE90", "lightgrey":"D3D3D3", - "lightpink":"FFB6C1", "lightsalmon":"FFA07A", "lightseagreen":"20B2AA", - "lightskyblue":"87CEFA", "lightslategray":"789", "lightsteelblue":"B0C4DE", - "lightyellow":"FFFFE0", "lime":"0F0", "limegreen":"32CD32", - "linen":"FAF0E6", "magenta":"F0F", "maroon":"800000", - "mediumauqamarine":"66CDAA", "mediumblue":"0000CD", "mediumorchid":"BA55D3", - "mediumpurple":"9370D8", "mediumseagreen":"3CB371", "mediumslateblue":"7B68EE", - "mediumspringgreen":"00FA9A", "mediumturquoise":"48D1CC", "mediumvioletred":"C71585", - "midnightblue":"191970", "mintcream":"F5FFFA", "mistyrose":"FFE4E1", - "moccasin":"FFE4B5", "navajowhite":"FFDEAD", "navy":"000080", - "oldlace":"FDF5E6", "olive":"808000", "olivedrab":"688E23", - "orange":"FFA500", "orangered":"FF4500", "orchid":"DA70D6", - "palegoldenrod":"EEE8AA", "palegreen":"98FB98", "paleturquoise":"AFEEEE", - "palevioletred":"D87093", "papayawhip":"FFEFD5", "peachpuff":"FFDAB9", - "peru":"CD853F", "pink":"FFC0CB", "plum":"DDA0DD", - "powderblue":"B0E0E6", "purple":"800080", "red":"F00", - "rosybrown":"BC8F8F", "royalblue":"4169E1", "saddlebrown":"8B4513", - "salmon":"FA8072", "sandybrown":"F4A460", "seagreen":"2E8B57", - "seashell":"FFF5EE", "sienna":"A0522D", "silver":"C0C0C0", - "skyblue":"87CEEB", "slateblue":"6A5ACD", "slategray":"708090", - "snow":"FFFAFA", "springgreen":"00FF7F", "steelblue":"4682B4", - "tan":"D2B48C", "teal":"008080", "thistle":"D8BFD8", - "tomato":"FF6347", "turquoise":"40E0D0", "violet":"EE82EE", - "wheat":"F5DEB3", "white":"FFF", "whitesmoke":"F5F5F5", - "yellow":"FF0", "yellowgreen":"9ACD32" - }; - - Color.prototype = { - /** - * @private - */ - parse: function() { - if( !this._color ) { - var me = this, - v = me.val, - vLower, - m = v.match( Color.rgbaRE ); - if( m ) { - me._color = 'rgb(' + m[1] + ',' + m[2] + ',' + m[3] + ')'; - me._alpha = parseFloat( m[4] ); - } - else { - if( ( vLower = v.toLowerCase() ) in Color.names ) { - v = '#' + Color.names[vLower]; - } - me._color = v; - me._alpha = ( v === 'transparent' ? 0 : 1 ); - } - } - }, - - /** - * Retrieve the value of the color in a format usable by IE natively. This will be the same as - * the raw input value, except for rgba values which will be converted to an rgb value. - * @param {Element} el The context element, used to get 'currentColor' keyword value. - * @return {string} Color value - */ - colorValue: function( el ) { - this.parse(); - return this._color === 'currentColor' ? el.currentStyle.color : this._color; - }, - - /** - * Retrieve the alpha value of the color. Will be 1 for all values except for rgba values - * with an alpha component. - * @return {number} The alpha value, from 0 to 1. - */ - alpha: function() { - this.parse(); - return this._alpha; - } - }; - - - /** - * Retrieve a PIE.Color instance for the given value. A shared singleton instance is returned for each unique value. - * @param {string} val The CSS string representing the color. It is assumed that this will already have - * been validated as a valid color syntax. - */ - PIE.getColor = function(val) { - return instances[ val ] || ( instances[ val ] = new Color( val ) ); - }; - - return Color; -})();/** - * A tokenizer for CSS value strings. - * @constructor - * @param {string} css The CSS value string - */ -PIE.Tokenizer = (function() { - function Tokenizer( css ) { - this.css = css; - this.ch = 0; - this.tokens = []; - this.tokenIndex = 0; - } - - /** - * Enumeration of token type constants. - * @enum {number} - */ - var Type = Tokenizer.Type = { - ANGLE: 1, - CHARACTER: 2, - COLOR: 4, - DIMEN: 8, - FUNCTION: 16, - IDENT: 32, - LENGTH: 64, - NUMBER: 128, - OPERATOR: 256, - PERCENT: 512, - STRING: 1024, - URL: 2048 - }; - - /** - * A single token - * @constructor - * @param {number} type The type of the token - see PIE.Tokenizer.Type - * @param {string} value The value of the token - */ - Tokenizer.Token = function( type, value ) { - this.tokenType = type; - this.tokenValue = value; - }; - Tokenizer.Token.prototype = { - isLength: function() { - return this.tokenType & Type.LENGTH || ( this.tokenType & Type.NUMBER && this.tokenValue === '0' ); - }, - isLengthOrPercent: function() { - return this.isLength() || this.tokenType & Type.PERCENT; - } - }; - - Tokenizer.prototype = { - whitespace: /\s/, - number: /^[\+\-]?(\d*\.)?\d+/, - url: /^url\(\s*("([^"]*)"|'([^']*)'|([!#$%&*-~]*))\s*\)/i, - ident: /^\-?[_a-z][\w-]*/i, - string: /^("([^"]*)"|'([^']*)')/, - operator: /^[\/,]/, - hash: /^#[\w]+/, - hashColor: /^#([\da-f]{6}|[\da-f]{3})/i, - - unitTypes: { - 'px': Type.LENGTH, 'em': Type.LENGTH, 'ex': Type.LENGTH, - 'mm': Type.LENGTH, 'cm': Type.LENGTH, 'in': Type.LENGTH, - 'pt': Type.LENGTH, 'pc': Type.LENGTH, - 'deg': Type.ANGLE, 'rad': Type.ANGLE, 'grad': Type.ANGLE - }, - - colorFunctions: { - 'rgb': 1, 'rgba': 1, 'hsl': 1, 'hsla': 1 - }, - - - /** - * Advance to and return the next token in the CSS string. If the end of the CSS string has - * been reached, null will be returned. - * @param {boolean} forget - if true, the token will not be stored for the purposes of backtracking with prev(). - * @return {PIE.Tokenizer.Token} - */ - next: function( forget ) { - var css, ch, firstChar, match, val, - me = this; - - function newToken( type, value ) { - var tok = new Tokenizer.Token( type, value ); - if( !forget ) { - me.tokens.push( tok ); - me.tokenIndex++; - } - return tok; - } - function failure() { - me.tokenIndex++; - return null; - } - - // In case we previously backed up, return the stored token in the next slot - if( this.tokenIndex < this.tokens.length ) { - return this.tokens[ this.tokenIndex++ ]; - } - - // Move past leading whitespace characters - while( this.whitespace.test( this.css.charAt( this.ch ) ) ) { - this.ch++; - } - if( this.ch >= this.css.length ) { - return failure(); - } - - ch = this.ch; - css = this.css.substring( this.ch ); - firstChar = css.charAt( 0 ); - switch( firstChar ) { - case '#': - if( match = css.match( this.hashColor ) ) { - this.ch += match[0].length; - return newToken( Type.COLOR, match[0] ); - } - break; - - case '"': - case "'": - if( match = css.match( this.string ) ) { - this.ch += match[0].length; - return newToken( Type.STRING, match[2] || match[3] || '' ); - } - break; - - case "/": - case ",": - this.ch++; - return newToken( Type.OPERATOR, firstChar ); - - case 'u': - if( match = css.match( this.url ) ) { - this.ch += match[0].length; - return newToken( Type.URL, match[2] || match[3] || match[4] || '' ); - } - } - - // Numbers and values starting with numbers - if( match = css.match( this.number ) ) { - val = match[0]; - this.ch += val.length; - - // Check if it is followed by a unit - if( css.charAt( val.length ) === '%' ) { - this.ch++; - return newToken( Type.PERCENT, val + '%' ); - } - if( match = css.substring( val.length ).match( this.ident ) ) { - val += match[0]; - this.ch += match[0].length; - return newToken( this.unitTypes[ match[0].toLowerCase() ] || Type.DIMEN, val ); - } - - // Plain ol' number - return newToken( Type.NUMBER, val ); - } - - // Identifiers - if( match = css.match( this.ident ) ) { - val = match[0]; - this.ch += val.length; - - // Named colors - if( val.toLowerCase() in PIE.Color.names || val === 'currentColor' || val === 'transparent' ) { - return newToken( Type.COLOR, val ); - } - - // Functions - if( css.charAt( val.length ) === '(' ) { - this.ch++; - - // Color values in function format: rgb, rgba, hsl, hsla - if( val.toLowerCase() in this.colorFunctions ) { - function isNum( tok ) { - return tok && tok.tokenType & Type.NUMBER; - } - function isNumOrPct( tok ) { - return tok && ( tok.tokenType & ( Type.NUMBER | Type.PERCENT ) ); - } - function isValue( tok, val ) { - return tok && tok.tokenValue === val; - } - function next() { - return me.next( 1 ); - } - - if( ( val.charAt(0) === 'r' ? isNumOrPct( next() ) : isNum( next() ) ) && - isValue( next(), ',' ) && - isNumOrPct( next() ) && - isValue( next(), ',' ) && - isNumOrPct( next() ) && - ( val === 'rgb' || val === 'hsa' || ( - isValue( next(), ',' ) && - isNum( next() ) - ) ) && - isValue( next(), ')' ) ) { - return newToken( Type.COLOR, this.css.substring( ch, this.ch ) ); - } - return failure(); - } - - return newToken( Type.FUNCTION, val ); - } - - // Other identifier - return newToken( Type.IDENT, val ); - } - - // Standalone character - this.ch++; - return newToken( Type.CHARACTER, firstChar ); - }, - - /** - * Determine whether there is another token - * @return {boolean} - */ - hasNext: function() { - var next = this.next(); - this.prev(); - return !!next; - }, - - /** - * Back up and return the previous token - * @return {PIE.Tokenizer.Token} - */ - prev: function() { - return this.tokens[ this.tokenIndex-- - 2 ]; - }, - - /** - * Retrieve all the tokens in the CSS string - * @return {Array.} - */ - all: function() { - while( this.next() ) {} - return this.tokens; - }, - - /** - * Return a list of tokens from the current position until the given function returns - * true. The final token will not be included in the list. - * @param {function():boolean} func - test function - * @param {boolean} require - if true, then if the end of the CSS string is reached - * before the test function returns true, null will be returned instead of the - * tokens that have been found so far. - * @return {Array.} - */ - until: function( func, require ) { - var list = [], t, hit; - while( t = this.next() ) { - if( func( t ) ) { - hit = true; - this.prev(); - break; - } - list.push( t ); - } - return require && !hit ? null : list; - } - }; - - return Tokenizer; -})();/** - * Handles calculating, caching, and detecting changes to size and position of the element. - * @constructor - * @param {Element} el the target element - */ -PIE.BoundsInfo = function( el ) { - this.targetElement = el; -}; -PIE.BoundsInfo.prototype = { - - _locked: 0, - - positionChanged: function() { - var last = this._lastBounds, - bounds; - return !last || ( ( bounds = this.getBounds() ) && ( last.x !== bounds.x || last.y !== bounds.y ) ); - }, - - sizeChanged: function() { - var last = this._lastBounds, - bounds; - return !last || ( ( bounds = this.getBounds() ) && ( last.w !== bounds.w || last.h !== bounds.h ) ); - }, - - getLiveBounds: function() { - var el = this.targetElement, - rect = el.getBoundingClientRect(), - isIE9 = PIE.ieDocMode === 9, - isIE7 = PIE.ieVersion === 7, - width = rect.right - rect.left; - return { - x: rect.left, - y: rect.top, - // In some cases scrolling the page will cause IE9 to report incorrect dimensions - // in the rect returned by getBoundingClientRect, so we must query offsetWidth/Height - // instead. Also IE7 is inconsistent in using logical vs. device pixels in measurements - // so we must calculate the ratio and use it in certain places as a position adjustment. - w: isIE9 || isIE7 ? el.offsetWidth : width, - h: isIE9 || isIE7 ? el.offsetHeight : rect.bottom - rect.top, - logicalZoomRatio: ( isIE7 && width ) ? el.offsetWidth / width : 1 - }; - }, - - getBounds: function() { - return this._locked ? - ( this._lockedBounds || ( this._lockedBounds = this.getLiveBounds() ) ) : - this.getLiveBounds(); - }, - - hasBeenQueried: function() { - return !!this._lastBounds; - }, - - lock: function() { - ++this._locked; - }, - - unlock: function() { - if( !--this._locked ) { - if( this._lockedBounds ) this._lastBounds = this._lockedBounds; - this._lockedBounds = null; - } - } - -}; -(function() { - -function cacheWhenLocked( fn ) { - var uid = PIE.Util.getUID( fn ); - return function() { - if( this._locked ) { - var cache = this._lockedValues || ( this._lockedValues = {} ); - return ( uid in cache ) ? cache[ uid ] : ( cache[ uid ] = fn.call( this ) ); - } else { - return fn.call( this ); - } - } -} - - -PIE.StyleInfoBase = { - - _locked: 0, - - /** - * Create a new StyleInfo class, with the standard constructor, and augmented by - * the StyleInfoBase's members. - * @param proto - */ - newStyleInfo: function( proto ) { - function StyleInfo( el ) { - this.targetElement = el; - this._lastCss = this.getCss(); - } - PIE.Util.merge( StyleInfo.prototype, PIE.StyleInfoBase, proto ); - StyleInfo._propsCache = {}; - return StyleInfo; - }, - - /** - * Get an object representation of the target CSS style, caching it for each unique - * CSS value string. - * @return {Object} - */ - getProps: function() { - var css = this.getCss(), - cache = this.constructor._propsCache; - return css ? ( css in cache ? cache[ css ] : ( cache[ css ] = this.parseCss( css ) ) ) : null; - }, - - /** - * Get the raw CSS value for the target style - * @return {string} - */ - getCss: cacheWhenLocked( function() { - var el = this.targetElement, - ctor = this.constructor, - s = el.style, - cs = el.currentStyle, - cssProp = this.cssProperty, - styleProp = this.styleProperty, - prefixedCssProp = ctor._prefixedCssProp || ( ctor._prefixedCssProp = PIE.CSS_PREFIX + cssProp ), - prefixedStyleProp = ctor._prefixedStyleProp || ( ctor._prefixedStyleProp = PIE.STYLE_PREFIX + styleProp.charAt(0).toUpperCase() + styleProp.substring(1) ); - return s[ prefixedStyleProp ] || cs.getAttribute( prefixedCssProp ) || s[ styleProp ] || cs.getAttribute( cssProp ); - } ), - - /** - * Determine whether the target CSS style is active. - * @return {boolean} - */ - isActive: cacheWhenLocked( function() { - return !!this.getProps(); - } ), - - /** - * Determine whether the target CSS style has changed since the last time it was used. - * @return {boolean} - */ - changed: cacheWhenLocked( function() { - var currentCss = this.getCss(), - changed = currentCss !== this._lastCss; - this._lastCss = currentCss; - return changed; - } ), - - cacheWhenLocked: cacheWhenLocked, - - lock: function() { - ++this._locked; - }, - - unlock: function() { - if( !--this._locked ) { - delete this._lockedValues; - } - } -}; - -})();/** - * Handles parsing, caching, and detecting changes to background (and -pie-background) CSS - * @constructor - * @param {Element} el the target element - */ -PIE.BackgroundStyleInfo = PIE.StyleInfoBase.newStyleInfo( { - - cssProperty: PIE.CSS_PREFIX + 'background', - styleProperty: PIE.STYLE_PREFIX + 'Background', - - attachIdents: { 'scroll':1, 'fixed':1, 'local':1 }, - repeatIdents: { 'repeat-x':1, 'repeat-y':1, 'repeat':1, 'no-repeat':1 }, - originAndClipIdents: { 'padding-box':1, 'border-box':1, 'content-box':1 }, - positionIdents: { 'top':1, 'right':1, 'bottom':1, 'left':1, 'center':1 }, - sizeIdents: { 'contain':1, 'cover':1 }, - propertyNames: { - CLIP: 'backgroundClip', - COLOR: 'backgroundColor', - IMAGE: 'backgroundImage', - ORIGIN: 'backgroundOrigin', - POSITION: 'backgroundPosition', - REPEAT: 'backgroundRepeat', - SIZE: 'backgroundSize' - }, - - /** - * For background styles, we support the -pie-background property but fall back to the standard - * backround* properties. The reason we have to use the prefixed version is that IE natively - * parses the standard properties and if it sees something it doesn't know how to parse, for example - * multiple values or gradient definitions, it will throw that away and not make it available through - * currentStyle. - * - * Format of return object: - * { - * color: , - * bgImages: [ - * { - * imgType: 'image', - * imgUrl: 'image.png', - * imgRepeat: <'no-repeat' | 'repeat-x' | 'repeat-y' | 'repeat'>, - * bgPosition: , - * bgAttachment: <'scroll' | 'fixed' | 'local'>, - * bgOrigin: <'border-box' | 'padding-box' | 'content-box'>, - * bgClip: <'border-box' | 'padding-box'>, - * bgSize: , - * origString: 'url(img.png) no-repeat top left' - * }, - * { - * imgType: 'linear-gradient', - * gradientStart: , - * angle: , - * stops: [ - * { color: , offset: }, - * { color: , offset: }, ... - * ] - * } - * ] - * } - * @param {String} css - * @override - */ - parseCss: function( css ) { - var el = this.targetElement, - cs = el.currentStyle, - tokenizer, token, image, - tok_type = PIE.Tokenizer.Type, - type_operator = tok_type.OPERATOR, - type_ident = tok_type.IDENT, - type_color = tok_type.COLOR, - tokType, tokVal, - beginCharIndex = 0, - positionIdents = this.positionIdents, - gradient, stop, width, height, - props = { bgImages: [] }; - - function isBgPosToken( token ) { - return token && token.isLengthOrPercent() || ( token.tokenType & type_ident && token.tokenValue in positionIdents ); - } - - function sizeToken( token ) { - return token && ( ( token.isLengthOrPercent() && PIE.getLength( token.tokenValue ) ) || ( token.tokenValue === 'auto' && 'auto' ) ); - } - - // If the CSS3-specific -pie-background property is present, parse it - if( this.getCss3() ) { - tokenizer = new PIE.Tokenizer( css ); - image = {}; - - while( token = tokenizer.next() ) { - tokType = token.tokenType; - tokVal = token.tokenValue; - - if( !image.imgType && tokType & tok_type.FUNCTION && tokVal === 'linear-gradient' ) { - gradient = { stops: [], imgType: tokVal }; - stop = {}; - while( token = tokenizer.next() ) { - tokType = token.tokenType; - tokVal = token.tokenValue; - - // If we reached the end of the function and had at least 2 stops, flush the info - if( tokType & tok_type.CHARACTER && tokVal === ')' ) { - if( stop.color ) { - gradient.stops.push( stop ); - } - if( gradient.stops.length > 1 ) { - PIE.Util.merge( image, gradient ); - } - break; - } - - // Color stop - must start with color - if( tokType & type_color ) { - // if we already have an angle/position, make sure that the previous token was a comma - if( gradient.angle || gradient.gradientStart ) { - token = tokenizer.prev(); - if( token.tokenType !== type_operator ) { - break; //fail - } - tokenizer.next(); - } - - stop = { - color: PIE.getColor( tokVal ) - }; - // check for offset following color - token = tokenizer.next(); - if( token.isLengthOrPercent() ) { - stop.offset = PIE.getLength( token.tokenValue ); - } else { - tokenizer.prev(); - } - } - // Angle - can only appear in first spot - else if( tokType & tok_type.ANGLE && !gradient.angle && !stop.color && !gradient.stops.length ) { - gradient.angle = new PIE.Angle( token.tokenValue ); - } - else if( isBgPosToken( token ) && !gradient.gradientStart && !stop.color && !gradient.stops.length ) { - tokenizer.prev(); - gradient.gradientStart = new PIE.BgPosition( - tokenizer.until( function( t ) { - return !isBgPosToken( t ); - }, false ) - ); - } - else if( tokType & type_operator && tokVal === ',' ) { - if( stop.color ) { - gradient.stops.push( stop ); - stop = {}; - } - } - else { - // Found something we didn't recognize; fail without adding image - break; - } - } - } - else if( !image.imgType && tokType & tok_type.URL ) { - image.imgUrl = tokVal; - image.imgType = 'image'; - } - else if( isBgPosToken( token ) && !image.bgPosition ) { - tokenizer.prev(); - image.bgPosition = new PIE.BgPosition( - tokenizer.until( function( t ) { - return !isBgPosToken( t ); - }, false ) - ); - } - else if( tokType & type_ident ) { - if( tokVal in this.repeatIdents && !image.imgRepeat ) { - image.imgRepeat = tokVal; - } - else if( tokVal in this.originAndClipIdents && !image.bgOrigin ) { - image.bgOrigin = tokVal; - if( ( token = tokenizer.next() ) && ( token.tokenType & type_ident ) && - token.tokenValue in this.originAndClipIdents ) { - image.bgClip = token.tokenValue; - } else { - image.bgClip = tokVal; - tokenizer.prev(); - } - } - else if( tokVal in this.attachIdents && !image.bgAttachment ) { - image.bgAttachment = tokVal; - } - else { - return null; - } - } - else if( tokType & type_color && !props.color ) { - props.color = PIE.getColor( tokVal ); - } - else if( tokType & type_operator && tokVal === '/' && !image.bgSize && image.bgPosition ) { - // background size - token = tokenizer.next(); - if( token.tokenType & type_ident && token.tokenValue in this.sizeIdents ) { - image.bgSize = new PIE.BgSize( token.tokenValue ); - } - else if( width = sizeToken( token ) ) { - height = sizeToken( tokenizer.next() ); - if ( !height ) { - height = width; - tokenizer.prev(); - } - image.bgSize = new PIE.BgSize( width, height ); - } - else { - return null; - } - } - // new layer - else if( tokType & type_operator && tokVal === ',' && image.imgType ) { - image.origString = css.substring( beginCharIndex, tokenizer.ch - 1 ); - beginCharIndex = tokenizer.ch; - props.bgImages.push( image ); - image = {}; - } - else { - // Found something unrecognized; chuck everything - return null; - } - } - - // leftovers - if( image.imgType ) { - image.origString = css.substring( beginCharIndex ); - props.bgImages.push( image ); - } - } - - // Otherwise, use the standard background properties; let IE give us the values rather than parsing them - else { - this.withActualBg( PIE.ieDocMode < 9 ? - function() { - var propNames = this.propertyNames, - posX = cs[propNames.POSITION + 'X'], - posY = cs[propNames.POSITION + 'Y'], - img = cs[propNames.IMAGE], - color = cs[propNames.COLOR]; - - if( color !== 'transparent' ) { - props.color = PIE.getColor( color ) - } - if( img !== 'none' ) { - props.bgImages = [ { - imgType: 'image', - imgUrl: new PIE.Tokenizer( img ).next().tokenValue, - imgRepeat: cs[propNames.REPEAT], - bgPosition: new PIE.BgPosition( new PIE.Tokenizer( posX + ' ' + posY ).all() ) - } ]; - } - } : - function() { - var propNames = this.propertyNames, - splitter = /\s*,\s*/, - images = cs[propNames.IMAGE].split( splitter ), - color = cs[propNames.COLOR], - repeats, positions, origins, clips, sizes, i, len, image, sizeParts; - - if( color !== 'transparent' ) { - props.color = PIE.getColor( color ) - } - - len = images.length; - if( len && images[0] !== 'none' ) { - repeats = cs[propNames.REPEAT].split( splitter ); - positions = cs[propNames.POSITION].split( splitter ); - origins = cs[propNames.ORIGIN].split( splitter ); - clips = cs[propNames.CLIP].split( splitter ); - sizes = cs[propNames.SIZE].split( splitter ); - - props.bgImages = []; - for( i = 0; i < len; i++ ) { - image = images[ i ]; - if( image && image !== 'none' ) { - sizeParts = sizes[i].split( ' ' ); - props.bgImages.push( { - origString: image + ' ' + repeats[ i ] + ' ' + positions[ i ] + ' / ' + sizes[ i ] + ' ' + - origins[ i ] + ' ' + clips[ i ], - imgType: 'image', - imgUrl: new PIE.Tokenizer( image ).next().tokenValue, - imgRepeat: repeats[ i ], - bgPosition: new PIE.BgPosition( new PIE.Tokenizer( positions[ i ] ).all() ), - bgOrigin: origins[ i ], - bgClip: clips[ i ], - bgSize: new PIE.BgSize( sizeParts[ 0 ], sizeParts[ 1 ] ) - } ); - } - } - } - } - ); - } - - return ( props.color || props.bgImages[0] ) ? props : null; - }, - - /** - * Execute a function with the actual background styles (not overridden with runtimeStyle - * properties set by the renderers) available via currentStyle. - * @param fn - */ - withActualBg: function( fn ) { - var isIE9 = PIE.ieDocMode > 8, - propNames = this.propertyNames, - rs = this.targetElement.runtimeStyle, - rsImage = rs[propNames.IMAGE], - rsColor = rs[propNames.COLOR], - rsRepeat = rs[propNames.REPEAT], - rsClip, rsOrigin, rsSize, rsPosition, ret; - - if( rsImage ) rs[propNames.IMAGE] = ''; - if( rsColor ) rs[propNames.COLOR] = ''; - if( rsRepeat ) rs[propNames.REPEAT] = ''; - if( isIE9 ) { - rsClip = rs[propNames.CLIP]; - rsOrigin = rs[propNames.ORIGIN]; - rsPosition = rs[propNames.POSITION]; - rsSize = rs[propNames.SIZE]; - if( rsClip ) rs[propNames.CLIP] = ''; - if( rsOrigin ) rs[propNames.ORIGIN] = ''; - if( rsPosition ) rs[propNames.POSITION] = ''; - if( rsSize ) rs[propNames.SIZE] = ''; - } - - ret = fn.call( this ); - - if( rsImage ) rs[propNames.IMAGE] = rsImage; - if( rsColor ) rs[propNames.COLOR] = rsColor; - if( rsRepeat ) rs[propNames.REPEAT] = rsRepeat; - if( isIE9 ) { - if( rsClip ) rs[propNames.CLIP] = rsClip; - if( rsOrigin ) rs[propNames.ORIGIN] = rsOrigin; - if( rsPosition ) rs[propNames.POSITION] = rsPosition; - if( rsSize ) rs[propNames.SIZE] = rsSize; - } - - return ret; - }, - - getCss: PIE.StyleInfoBase.cacheWhenLocked( function() { - return this.getCss3() || - this.withActualBg( function() { - var cs = this.targetElement.currentStyle, - propNames = this.propertyNames; - return cs[propNames.COLOR] + ' ' + cs[propNames.IMAGE] + ' ' + cs[propNames.REPEAT] + ' ' + - cs[propNames.POSITION + 'X'] + ' ' + cs[propNames.POSITION + 'Y']; - } ); - } ), - - getCss3: PIE.StyleInfoBase.cacheWhenLocked( function() { - var el = this.targetElement; - return el.style[ this.styleProperty ] || el.currentStyle.getAttribute( this.cssProperty ); - } ), - - /** - * Tests if style.PiePngFix or the -pie-png-fix property is set to true in IE6. - */ - isPngFix: function() { - var val = 0, el; - if( PIE.ieVersion < 7 ) { - el = this.targetElement; - val = ( '' + ( el.style[ PIE.STYLE_PREFIX + 'PngFix' ] || el.currentStyle.getAttribute( PIE.CSS_PREFIX + 'png-fix' ) ) === 'true' ); - } - return val; - }, - - /** - * The isActive logic is slightly different, because getProps() always returns an object - * even if it is just falling back to the native background properties. But we only want - * to report is as being "active" if either the -pie-background override property is present - * and parses successfully or '-pie-png-fix' is set to true in IE6. - */ - isActive: PIE.StyleInfoBase.cacheWhenLocked( function() { - return (this.getCss3() || this.isPngFix()) && !!this.getProps(); - } ) - -} );/** - * Handles parsing, caching, and detecting changes to border CSS - * @constructor - * @param {Element} el the target element - */ -PIE.BorderStyleInfo = PIE.StyleInfoBase.newStyleInfo( { - - sides: [ 'Top', 'Right', 'Bottom', 'Left' ], - namedWidths: { - 'thin': '1px', - 'medium': '3px', - 'thick': '5px' - }, - - parseCss: function( css ) { - var w = {}, - s = {}, - c = {}, - active = false, - colorsSame = true, - stylesSame = true, - widthsSame = true; - - this.withActualBorder( function() { - var el = this.targetElement, - cs = el.currentStyle, - i = 0, - style, color, width, lastStyle, lastColor, lastWidth, side, ltr; - for( ; i < 4; i++ ) { - side = this.sides[ i ]; - - ltr = side.charAt(0).toLowerCase(); - style = s[ ltr ] = cs[ 'border' + side + 'Style' ]; - color = cs[ 'border' + side + 'Color' ]; - width = cs[ 'border' + side + 'Width' ]; - - if( i > 0 ) { - if( style !== lastStyle ) { stylesSame = false; } - if( color !== lastColor ) { colorsSame = false; } - if( width !== lastWidth ) { widthsSame = false; } - } - lastStyle = style; - lastColor = color; - lastWidth = width; - - c[ ltr ] = PIE.getColor( color ); - - width = w[ ltr ] = PIE.getLength( s[ ltr ] === 'none' ? '0' : ( this.namedWidths[ width ] || width ) ); - if( width.pixels( this.targetElement ) > 0 ) { - active = true; - } - } - } ); - - return active ? { - widths: w, - styles: s, - colors: c, - widthsSame: widthsSame, - colorsSame: colorsSame, - stylesSame: stylesSame - } : null; - }, - - getCss: PIE.StyleInfoBase.cacheWhenLocked( function() { - var el = this.targetElement, - cs = el.currentStyle, - css; - - // Don't redraw or hide borders for cells in border-collapse:collapse tables - if( !( el.tagName in PIE.tableCellTags && el.offsetParent.currentStyle.borderCollapse === 'collapse' ) ) { - this.withActualBorder( function() { - css = cs.borderWidth + '|' + cs.borderStyle + '|' + cs.borderColor; - } ); - } - return css; - } ), - - /** - * Execute a function with the actual border styles (not overridden with runtimeStyle - * properties set by the renderers) available via currentStyle. - * @param fn - */ - withActualBorder: function( fn ) { - var rs = this.targetElement.runtimeStyle, - rsWidth = rs.borderWidth, - rsColor = rs.borderColor, - ret; - - if( rsWidth ) rs.borderWidth = ''; - if( rsColor ) rs.borderColor = ''; - - ret = fn.call( this ); - - if( rsWidth ) rs.borderWidth = rsWidth; - if( rsColor ) rs.borderColor = rsColor; - - return ret; - } - -} ); -/** - * Handles parsing, caching, and detecting changes to border-radius CSS - * @constructor - * @param {Element} el the target element - */ -(function() { - -PIE.BorderRadiusStyleInfo = PIE.StyleInfoBase.newStyleInfo( { - - cssProperty: 'border-radius', - styleProperty: 'borderRadius', - - parseCss: function( css ) { - var p = null, x, y, - tokenizer, token, length, - hasNonZero = false; - - if( css ) { - tokenizer = new PIE.Tokenizer( css ); - - function collectLengths() { - var arr = [], num; - while( ( token = tokenizer.next() ) && token.isLengthOrPercent() ) { - length = PIE.getLength( token.tokenValue ); - num = length.getNumber(); - if( num < 0 ) { - return null; - } - if( num > 0 ) { - hasNonZero = true; - } - arr.push( length ); - } - return arr.length > 0 && arr.length < 5 ? { - 'tl': arr[0], - 'tr': arr[1] || arr[0], - 'br': arr[2] || arr[0], - 'bl': arr[3] || arr[1] || arr[0] - } : null; - } - - // Grab the initial sequence of lengths - if( x = collectLengths() ) { - // See if there is a slash followed by more lengths, for the y-axis radii - if( token ) { - if( token.tokenType & PIE.Tokenizer.Type.OPERATOR && token.tokenValue === '/' ) { - y = collectLengths(); - } - } else { - y = x; - } - - // Treat all-zero values the same as no value - if( hasNonZero && x && y ) { - p = { x: x, y : y }; - } - } - } - - return p; - } -} ); - -var zero = PIE.getLength( '0' ), - zeros = { 'tl': zero, 'tr': zero, 'br': zero, 'bl': zero }; -PIE.BorderRadiusStyleInfo.ALL_ZERO = { x: zeros, y: zeros }; - -})();/** - * Handles parsing, caching, and detecting changes to border-image CSS - * @constructor - * @param {Element} el the target element - */ -PIE.BorderImageStyleInfo = PIE.StyleInfoBase.newStyleInfo( { - - cssProperty: 'border-image', - styleProperty: 'borderImage', - - repeatIdents: { 'stretch':1, 'round':1, 'repeat':1, 'space':1 }, - - parseCss: function( css ) { - var p = null, tokenizer, token, type, value, - slices, widths, outsets, - slashCount = 0, - Type = PIE.Tokenizer.Type, - IDENT = Type.IDENT, - NUMBER = Type.NUMBER, - PERCENT = Type.PERCENT; - - if( css ) { - tokenizer = new PIE.Tokenizer( css ); - p = {}; - - function isSlash( token ) { - return token && ( token.tokenType & Type.OPERATOR ) && ( token.tokenValue === '/' ); - } - - function isFillIdent( token ) { - return token && ( token.tokenType & IDENT ) && ( token.tokenValue === 'fill' ); - } - - function collectSlicesEtc() { - slices = tokenizer.until( function( tok ) { - return !( tok.tokenType & ( NUMBER | PERCENT ) ); - } ); - - if( isFillIdent( tokenizer.next() ) && !p.fill ) { - p.fill = true; - } else { - tokenizer.prev(); - } - - if( isSlash( tokenizer.next() ) ) { - slashCount++; - widths = tokenizer.until( function( token ) { - return !token.isLengthOrPercent() && !( ( token.tokenType & IDENT ) && token.tokenValue === 'auto' ); - } ); - - if( isSlash( tokenizer.next() ) ) { - slashCount++; - outsets = tokenizer.until( function( token ) { - return !token.isLength(); - } ); - } - } else { - tokenizer.prev(); - } - } - - while( token = tokenizer.next() ) { - type = token.tokenType; - value = token.tokenValue; - - // Numbers and/or 'fill' keyword: slice values. May be followed optionally by width values, followed optionally by outset values - if( type & ( NUMBER | PERCENT ) && !slices ) { - tokenizer.prev(); - collectSlicesEtc(); - } - else if( isFillIdent( token ) && !p.fill ) { - p.fill = true; - collectSlicesEtc(); - } - - // Idents: one or values for 'repeat' - else if( ( type & IDENT ) && this.repeatIdents[value] && !p.repeat ) { - p.repeat = { h: value }; - if( token = tokenizer.next() ) { - if( ( token.tokenType & IDENT ) && this.repeatIdents[token.tokenValue] ) { - p.repeat.v = token.tokenValue; - } else { - tokenizer.prev(); - } - } - } - - // URL of the image - else if( ( type & Type.URL ) && !p.src ) { - p.src = value; - } - - // Found something unrecognized; exit. - else { - return null; - } - } - - // Validate what we collected - if( !p.src || !slices || slices.length < 1 || slices.length > 4 || - ( widths && widths.length > 4 ) || ( slashCount === 1 && widths.length < 1 ) || - ( outsets && outsets.length > 4 ) || ( slashCount === 2 && outsets.length < 1 ) ) { - return null; - } - - // Fill in missing values - if( !p.repeat ) { - p.repeat = { h: 'stretch' }; - } - if( !p.repeat.v ) { - p.repeat.v = p.repeat.h; - } - - function distributeSides( tokens, convertFn ) { - return { - 't': convertFn( tokens[0] ), - 'r': convertFn( tokens[1] || tokens[0] ), - 'b': convertFn( tokens[2] || tokens[0] ), - 'l': convertFn( tokens[3] || tokens[1] || tokens[0] ) - }; - } - - p.slice = distributeSides( slices, function( tok ) { - return PIE.getLength( ( tok.tokenType & NUMBER ) ? tok.tokenValue + 'px' : tok.tokenValue ); - } ); - - if( widths && widths[0] ) { - p.widths = distributeSides( widths, function( tok ) { - return tok.isLengthOrPercent() ? PIE.getLength( tok.tokenValue ) : tok.tokenValue; - } ); - } - - if( outsets && outsets[0] ) { - p.outset = distributeSides( outsets, function( tok ) { - return tok.isLength() ? PIE.getLength( tok.tokenValue ) : tok.tokenValue; - } ); - } - } - - return p; - } - -} );/** - * Handles parsing, caching, and detecting changes to box-shadow CSS - * @constructor - * @param {Element} el the target element - */ -PIE.BoxShadowStyleInfo = PIE.StyleInfoBase.newStyleInfo( { - - cssProperty: 'box-shadow', - styleProperty: 'boxShadow', - - parseCss: function( css ) { - var props, - getLength = PIE.getLength, - Type = PIE.Tokenizer.Type, - tokenizer; - - if( css ) { - tokenizer = new PIE.Tokenizer( css ); - props = { outset: [], inset: [] }; - - function parseItem() { - var token, type, value, color, lengths, inset, len; - - while( token = tokenizer.next() ) { - value = token.tokenValue; - type = token.tokenType; - - if( type & Type.OPERATOR && value === ',' ) { - break; - } - else if( token.isLength() && !lengths ) { - tokenizer.prev(); - lengths = tokenizer.until( function( token ) { - return !token.isLength(); - } ); - } - else if( type & Type.COLOR && !color ) { - color = value; - } - else if( type & Type.IDENT && value === 'inset' && !inset ) { - inset = true; - } - else { //encountered an unrecognized token; fail. - return false; - } - } - - len = lengths && lengths.length; - if( len > 1 && len < 5 ) { - ( inset ? props.inset : props.outset ).push( { - xOffset: getLength( lengths[0].tokenValue ), - yOffset: getLength( lengths[1].tokenValue ), - blur: getLength( lengths[2] ? lengths[2].tokenValue : '0' ), - spread: getLength( lengths[3] ? lengths[3].tokenValue : '0' ), - color: PIE.getColor( color || 'currentColor' ) - } ); - return true; - } - return false; - } - - while( parseItem() ) {} - } - - return props && ( props.inset.length || props.outset.length ) ? props : null; - } -} ); -/** - * Retrieves the state of the element's visibility and display - * @constructor - * @param {Element} el the target element - */ -PIE.VisibilityStyleInfo = PIE.StyleInfoBase.newStyleInfo( { - - getCss: PIE.StyleInfoBase.cacheWhenLocked( function() { - var cs = this.targetElement.currentStyle; - return cs.visibility + '|' + cs.display; - } ), - - parseCss: function() { - var el = this.targetElement, - rs = el.runtimeStyle, - cs = el.currentStyle, - rsVis = rs.visibility, - csVis; - - rs.visibility = ''; - csVis = cs.visibility; - rs.visibility = rsVis; - - return { - visible: csVis !== 'hidden', - displayed: cs.display !== 'none' - } - }, - - /** - * Always return false for isActive, since this property alone will not trigger - * a renderer to do anything. - */ - isActive: function() { - return false; - } - -} ); -PIE.RendererBase = { - - /** - * Create a new Renderer class, with the standard constructor, and augmented by - * the RendererBase's members. - * @param proto - */ - newRenderer: function( proto ) { - function Renderer( el, boundsInfo, styleInfos, parent ) { - this.targetElement = el; - this.boundsInfo = boundsInfo; - this.styleInfos = styleInfos; - this.parent = parent; - } - PIE.Util.merge( Renderer.prototype, PIE.RendererBase, proto ); - return Renderer; - }, - - /** - * Flag indicating the element has already been positioned at least once. - * @type {boolean} - */ - isPositioned: false, - - /** - * Determine if the renderer needs to be updated - * @return {boolean} - */ - needsUpdate: function() { - return false; - }, - - /** - * Run any preparation logic that would affect the main update logic of this - * renderer or any of the other renderers, e.g. things that might affect the - * element's size or style properties. - */ - prepareUpdate: PIE.emptyFn, - - /** - * Tell the renderer to update based on modified properties - */ - updateProps: function() { - this.destroy(); - if( this.isActive() ) { - this.draw(); - } - }, - - /** - * Tell the renderer to update based on modified element position - */ - updatePos: function() { - this.isPositioned = true; - }, - - /** - * Tell the renderer to update based on modified element dimensions - */ - updateSize: function() { - if( this.isActive() ) { - this.draw(); - } else { - this.destroy(); - } - }, - - - /** - * Add a layer element, with the given z-order index, to the renderer's main box element. We can't use - * z-index because that breaks when the root rendering box's z-index is 'auto' in IE8+ standards mode. - * So instead we make sure they are inserted into the DOM in the correct order. - * @param {number} index - * @param {Element} el - */ - addLayer: function( index, el ) { - this.removeLayer( index ); - for( var layers = this._layers || ( this._layers = [] ), i = index + 1, len = layers.length, layer; i < len; i++ ) { - layer = layers[i]; - if( layer ) { - break; - } - } - layers[index] = el; - this.getBox().insertBefore( el, layer || null ); - }, - - /** - * Retrieve a layer element by its index, or null if not present - * @param {number} index - * @return {Element} - */ - getLayer: function( index ) { - var layers = this._layers; - return layers && layers[index] || null; - }, - - /** - * Remove a layer element by its index - * @param {number} index - */ - removeLayer: function( index ) { - var layer = this.getLayer( index ), - box = this._box; - if( layer && box ) { - box.removeChild( layer ); - this._layers[index] = null; - } - }, - - - /** - * Get a VML shape by name, creating it if necessary. - * @param {string} name A name identifying the element - * @param {string=} subElName If specified a subelement of the shape will be created with this tag name - * @param {Element} parent The parent element for the shape; will be ignored if 'group' is specified - * @param {number=} group If specified, an ordinal group for the shape. 1 or greater. Groups are rendered - * using container elements in the correct order, to get correct z stacking without z-index. - */ - getShape: function( name, subElName, parent, group ) { - var shapes = this._shapes || ( this._shapes = {} ), - shape = shapes[ name ], - s; - - if( !shape ) { - shape = shapes[ name ] = PIE.Util.createVmlElement( 'shape' ); - if( subElName ) { - shape.appendChild( shape[ subElName ] = PIE.Util.createVmlElement( subElName ) ); - } - - if( group ) { - parent = this.getLayer( group ); - if( !parent ) { - this.addLayer( group, doc.createElement( 'group' + group ) ); - parent = this.getLayer( group ); - } - } - - parent.appendChild( shape ); - - s = shape.style; - s.position = 'absolute'; - s.left = s.top = 0; - s['behavior'] = 'url(#default#VML)'; - } - return shape; - }, - - /** - * Delete a named shape which was created by getShape(). Returns true if a shape with the - * given name was found and deleted, or false if there was no shape of that name. - * @param {string} name - * @return {boolean} - */ - deleteShape: function( name ) { - var shapes = this._shapes, - shape = shapes && shapes[ name ]; - if( shape ) { - shape.parentNode.removeChild( shape ); - delete shapes[ name ]; - } - return !!shape; - }, - - - /** - * For a given set of border radius length/percentage values, convert them to concrete pixel - * values based on the current size of the target element. - * @param {Object} radii - * @return {Object} - */ - getRadiiPixels: function( radii ) { - var el = this.targetElement, - bounds = this.boundsInfo.getBounds(), - w = bounds.w, - h = bounds.h, - tlX, tlY, trX, trY, brX, brY, blX, blY, f; - - tlX = radii.x['tl'].pixels( el, w ); - tlY = radii.y['tl'].pixels( el, h ); - trX = radii.x['tr'].pixels( el, w ); - trY = radii.y['tr'].pixels( el, h ); - brX = radii.x['br'].pixels( el, w ); - brY = radii.y['br'].pixels( el, h ); - blX = radii.x['bl'].pixels( el, w ); - blY = radii.y['bl'].pixels( el, h ); - - // If any corner ellipses overlap, reduce them all by the appropriate factor. This formula - // is taken straight from the CSS3 Backgrounds and Borders spec. - f = Math.min( - w / ( tlX + trX ), - h / ( trY + brY ), - w / ( blX + brX ), - h / ( tlY + blY ) - ); - if( f < 1 ) { - tlX *= f; - tlY *= f; - trX *= f; - trY *= f; - brX *= f; - brY *= f; - blX *= f; - blY *= f; - } - - return { - x: { - 'tl': tlX, - 'tr': trX, - 'br': brX, - 'bl': blX - }, - y: { - 'tl': tlY, - 'tr': trY, - 'br': brY, - 'bl': blY - } - } - }, - - /** - * Return the VML path string for the element's background box, with corners rounded. - * @param {Object.<{t:number, r:number, b:number, l:number}>} shrink - if present, specifies number of - * pixels to shrink the box path inward from the element's four sides. - * @param {number=} mult If specified, all coordinates will be multiplied by this number - * @param {Object=} radii If specified, this will be used for the corner radii instead of the properties - * from this renderer's borderRadiusInfo object. - * @return {string} the VML path - */ - getBoxPath: function( shrink, mult, radii ) { - mult = mult || 1; - - var r, str, - bounds = this.boundsInfo.getBounds(), - w = bounds.w * mult, - h = bounds.h * mult, - radInfo = this.styleInfos.borderRadiusInfo, - floor = Math.floor, ceil = Math.ceil, - shrinkT = shrink ? shrink.t * mult : 0, - shrinkR = shrink ? shrink.r * mult : 0, - shrinkB = shrink ? shrink.b * mult : 0, - shrinkL = shrink ? shrink.l * mult : 0, - tlX, tlY, trX, trY, brX, brY, blX, blY; - - if( radii || radInfo.isActive() ) { - r = this.getRadiiPixels( radii || radInfo.getProps() ); - - tlX = r.x['tl'] * mult; - tlY = r.y['tl'] * mult; - trX = r.x['tr'] * mult; - trY = r.y['tr'] * mult; - brX = r.x['br'] * mult; - brY = r.y['br'] * mult; - blX = r.x['bl'] * mult; - blY = r.y['bl'] * mult; - - str = 'm' + floor( shrinkL ) + ',' + floor( tlY ) + - 'qy' + floor( tlX ) + ',' + floor( shrinkT ) + - 'l' + ceil( w - trX ) + ',' + floor( shrinkT ) + - 'qx' + ceil( w - shrinkR ) + ',' + floor( trY ) + - 'l' + ceil( w - shrinkR ) + ',' + ceil( h - brY ) + - 'qy' + ceil( w - brX ) + ',' + ceil( h - shrinkB ) + - 'l' + floor( blX ) + ',' + ceil( h - shrinkB ) + - 'qx' + floor( shrinkL ) + ',' + ceil( h - blY ) + ' x e'; - } else { - // simplified path for non-rounded box - str = 'm' + floor( shrinkL ) + ',' + floor( shrinkT ) + - 'l' + ceil( w - shrinkR ) + ',' + floor( shrinkT ) + - 'l' + ceil( w - shrinkR ) + ',' + ceil( h - shrinkB ) + - 'l' + floor( shrinkL ) + ',' + ceil( h - shrinkB ) + - 'xe'; - } - return str; - }, - - - /** - * Get the container element for the shapes, creating it if necessary. - */ - getBox: function() { - var box = this.parent.getLayer( this.boxZIndex ), s; - - if( !box ) { - box = doc.createElement( this.boxName ); - s = box.style; - s.position = 'absolute'; - s.top = s.left = 0; - this.parent.addLayer( this.boxZIndex, box ); - } - - return box; - }, - - - /** - * Hide the actual border of the element. In IE7 and up we can just set its color to transparent; - * however IE6 does not support transparent borders so we have to get tricky with it. Also, some elements - * like form buttons require removing the border width altogether, so for those we increase the padding - * by the border size. - */ - hideBorder: function() { - var el = this.targetElement, - cs = el.currentStyle, - rs = el.runtimeStyle, - tag = el.tagName, - isIE6 = PIE.ieVersion === 6, - sides, side, i; - - if( ( isIE6 && ( tag in PIE.childlessElements || tag === 'FIELDSET' ) ) || - tag === 'BUTTON' || ( tag === 'INPUT' && el.type in PIE.inputButtonTypes ) ) { - rs.borderWidth = ''; - sides = this.styleInfos.borderInfo.sides; - for( i = sides.length; i--; ) { - side = sides[ i ]; - rs[ 'padding' + side ] = ''; - rs[ 'padding' + side ] = ( PIE.getLength( cs[ 'padding' + side ] ) ).pixels( el ) + - ( PIE.getLength( cs[ 'border' + side + 'Width' ] ) ).pixels( el ) + - ( PIE.ieVersion !== 8 && i % 2 ? 1 : 0 ); //needs an extra horizontal pixel to counteract the extra "inner border" going away - } - rs.borderWidth = 0; - } - else if( isIE6 ) { - // Wrap all the element's children in a custom element, set the element to visiblity:hidden, - // and set the wrapper element to visiblity:visible. This hides the outer element's decorations - // (background and border) but displays all the contents. - // TODO find a better way to do this that doesn't mess up the DOM parent-child relationship, - // as this can interfere with other author scripts which add/modify/delete children. Also, this - // won't work for elements which cannot take children, e.g. input/button/textarea/img/etc. Look into - // using a compositor filter or some other filter which masks the border. - if( el.childNodes.length !== 1 || el.firstChild.tagName !== 'ie6-mask' ) { - var cont = doc.createElement( 'ie6-mask' ), - s = cont.style, child; - s.visibility = 'visible'; - s.zoom = 1; - while( child = el.firstChild ) { - cont.appendChild( child ); - } - el.appendChild( cont ); - rs.visibility = 'hidden'; - } - } - else { - rs.borderColor = 'transparent'; - } - }, - - unhideBorder: function() { - - }, - - - /** - * Destroy the rendered objects. This is a base implementation which handles common renderer - * structures, but individual renderers may override as necessary. - */ - destroy: function() { - this.parent.removeLayer( this.boxZIndex ); - delete this._shapes; - delete this._layers; - } -}; -/** - * Root renderer; creates the outermost container element and handles keeping it aligned - * with the target element's size and position. - * @param {Element} el The target element - * @param {Object} styleInfos The StyleInfo objects - */ -PIE.RootRenderer = PIE.RendererBase.newRenderer( { - - isActive: function() { - var children = this.childRenderers; - for( var i in children ) { - if( children.hasOwnProperty( i ) && children[ i ].isActive() ) { - return true; - } - } - return false; - }, - - needsUpdate: function() { - return this.styleInfos.visibilityInfo.changed(); - }, - - updatePos: function() { - if( this.isActive() ) { - var el = this.getPositioningElement(), - par = el, - docEl, - parRect, - tgtCS = el.currentStyle, - tgtPos = tgtCS.position, - boxPos, - s = this.getBox().style, cs, - x = 0, y = 0, - elBounds = this.boundsInfo.getBounds(), - logicalZoomRatio = elBounds.logicalZoomRatio; - - if( tgtPos === 'fixed' && PIE.ieVersion > 6 ) { - x = elBounds.x * logicalZoomRatio; - y = elBounds.y * logicalZoomRatio; - boxPos = tgtPos; - } else { - // Get the element's offsets from its nearest positioned ancestor. Uses - // getBoundingClientRect for accuracy and speed. - do { - par = par.offsetParent; - } while( par && ( par.currentStyle.position === 'static' ) ); - if( par ) { - parRect = par.getBoundingClientRect(); - cs = par.currentStyle; - x = ( elBounds.x - parRect.left ) * logicalZoomRatio - ( parseFloat(cs.borderLeftWidth) || 0 ); - y = ( elBounds.y - parRect.top ) * logicalZoomRatio - ( parseFloat(cs.borderTopWidth) || 0 ); - } else { - docEl = doc.documentElement; - x = ( elBounds.x + docEl.scrollLeft - docEl.clientLeft ) * logicalZoomRatio; - y = ( elBounds.y + docEl.scrollTop - docEl.clientTop ) * logicalZoomRatio; - } - boxPos = 'absolute'; - } - - s.position = boxPos; - s.left = x; - s.top = y; - s.zIndex = tgtPos === 'static' ? -1 : tgtCS.zIndex; - this.isPositioned = true; - } - }, - - updateSize: PIE.emptyFn, - - updateVisibility: function() { - var vis = this.styleInfos.visibilityInfo.getProps(); - this.getBox().style.display = ( vis.visible && vis.displayed ) ? '' : 'none'; - }, - - updateProps: function() { - if( this.isActive() ) { - this.updateVisibility(); - } else { - this.destroy(); - } - }, - - getPositioningElement: function() { - var el = this.targetElement; - return el.tagName in PIE.tableCellTags ? el.offsetParent : el; - }, - - getBox: function() { - var box = this._box, el; - if( !box ) { - el = this.getPositioningElement(); - box = this._box = doc.createElement( 'css3-container' ); - box.style['direction'] = 'ltr'; //fix positioning bug in rtl environments - - this.updateVisibility(); - - el.parentNode.insertBefore( box, el ); - } - return box; - }, - - finishUpdate: PIE.emptyFn, - - destroy: function() { - var box = this._box, par; - if( box && ( par = box.parentNode ) ) { - par.removeChild( box ); - } - delete this._box; - delete this._layers; - } - -} ); -/** - * Renderer for element backgrounds. - * @constructor - * @param {Element} el The target element - * @param {Object} styleInfos The StyleInfo objects - * @param {PIE.RootRenderer} parent - */ -PIE.BackgroundRenderer = PIE.RendererBase.newRenderer( { - - boxZIndex: 2, - boxName: 'background', - - needsUpdate: function() { - var si = this.styleInfos; - return si.backgroundInfo.changed() || si.borderRadiusInfo.changed(); - }, - - isActive: function() { - var si = this.styleInfos; - return si.borderImageInfo.isActive() || - si.borderRadiusInfo.isActive() || - si.backgroundInfo.isActive() || - ( si.boxShadowInfo.isActive() && si.boxShadowInfo.getProps().inset ); - }, - - /** - * Draw the shapes - */ - draw: function() { - var bounds = this.boundsInfo.getBounds(); - if( bounds.w && bounds.h ) { - this.drawBgColor(); - this.drawBgImages(); - } - }, - - /** - * Draw the background color shape - */ - drawBgColor: function() { - var props = this.styleInfos.backgroundInfo.getProps(), - bounds = this.boundsInfo.getBounds(), - el = this.targetElement, - color = props && props.color, - shape, w, h, s, alpha; - - if( color && color.alpha() > 0 ) { - this.hideBackground(); - - shape = this.getShape( 'bgColor', 'fill', this.getBox(), 1 ); - w = bounds.w; - h = bounds.h; - shape.stroked = false; - shape.coordsize = w * 2 + ',' + h * 2; - shape.coordorigin = '1,1'; - shape.path = this.getBoxPath( null, 2 ); - s = shape.style; - s.width = w; - s.height = h; - shape.fill.color = color.colorValue( el ); - - alpha = color.alpha(); - if( alpha < 1 ) { - shape.fill.opacity = alpha; - } - } else { - this.deleteShape( 'bgColor' ); - } - }, - - /** - * Draw all the background image layers - */ - drawBgImages: function() { - var props = this.styleInfos.backgroundInfo.getProps(), - bounds = this.boundsInfo.getBounds(), - images = props && props.bgImages, - img, shape, w, h, s, i; - - if( images ) { - this.hideBackground(); - - w = bounds.w; - h = bounds.h; - - i = images.length; - while( i-- ) { - img = images[i]; - shape = this.getShape( 'bgImage' + i, 'fill', this.getBox(), 2 ); - - shape.stroked = false; - shape.fill.type = 'tile'; - shape.fillcolor = 'none'; - shape.coordsize = w * 2 + ',' + h * 2; - shape.coordorigin = '1,1'; - shape.path = this.getBoxPath( 0, 2 ); - s = shape.style; - s.width = w; - s.height = h; - - if( img.imgType === 'linear-gradient' ) { - this.addLinearGradient( shape, img ); - } - else { - shape.fill.src = img.imgUrl; - this.positionBgImage( shape, i ); - } - } - } - - // Delete any bgImage shapes previously created which weren't used above - i = images ? images.length : 0; - while( this.deleteShape( 'bgImage' + i++ ) ) {} - }, - - - /** - * Set the position and clipping of the background image for a layer - * @param {Element} shape - * @param {number} index - */ - positionBgImage: function( shape, index ) { - var me = this; - PIE.Util.withImageSize( shape.fill.src, function( size ) { - var el = me.targetElement, - bounds = me.boundsInfo.getBounds(), - elW = bounds.w, - elH = bounds.h; - - // It's possible that the element dimensions are zero now but weren't when the original - // update executed, make sure that's not the case to avoid divide-by-zero error - if( elW && elH ) { - var fill = shape.fill, - si = me.styleInfos, - border = si.borderInfo.getProps(), - bw = border && border.widths, - bwT = bw ? bw['t'].pixels( el ) : 0, - bwR = bw ? bw['r'].pixels( el ) : 0, - bwB = bw ? bw['b'].pixels( el ) : 0, - bwL = bw ? bw['l'].pixels( el ) : 0, - bg = si.backgroundInfo.getProps().bgImages[ index ], - bgPos = bg.bgPosition ? bg.bgPosition.coords( el, elW - size.w - bwL - bwR, elH - size.h - bwT - bwB ) : { x:0, y:0 }, - repeat = bg.imgRepeat, - pxX, pxY, - clipT = 0, clipL = 0, - clipR = elW + 1, clipB = elH + 1, //make sure the default clip region is not inside the box (by a subpixel) - clipAdjust = PIE.ieVersion === 8 ? 0 : 1; //prior to IE8 requires 1 extra pixel in the image clip region - - // Positioning - find the pixel offset from the top/left and convert to a ratio - // The position is shifted by half a pixel, to adjust for the half-pixel coordorigin shift which is - // needed to fix antialiasing but makes the bg image fuzzy. - pxX = Math.round( bgPos.x ) + bwL + 0.5; - pxY = Math.round( bgPos.y ) + bwT + 0.5; - fill.position = ( pxX / elW ) + ',' + ( pxY / elH ); - - // Set the size of the image. We have to actually set it to px values otherwise it will not honor - // the user's browser zoom level and always display at its natural screen size. - fill['size']['x'] = 1; //Can be any value, just has to be set to "prime" it so the next line works. Weird! - fill['size'] = size.w + 'px,' + size.h + 'px'; - - // Repeating - clip the image shape - if( repeat && repeat !== 'repeat' ) { - if( repeat === 'repeat-x' || repeat === 'no-repeat' ) { - clipT = pxY + 1; - clipB = pxY + size.h + clipAdjust; - } - if( repeat === 'repeat-y' || repeat === 'no-repeat' ) { - clipL = pxX + 1; - clipR = pxX + size.w + clipAdjust; - } - shape.style.clip = 'rect(' + clipT + 'px,' + clipR + 'px,' + clipB + 'px,' + clipL + 'px)'; - } - } - } ); - }, - - - /** - * Draw the linear gradient for a gradient layer - * @param {Element} shape - * @param {Object} info The object holding the information about the gradient - */ - addLinearGradient: function( shape, info ) { - var el = this.targetElement, - bounds = this.boundsInfo.getBounds(), - w = bounds.w, - h = bounds.h, - fill = shape.fill, - stops = info.stops, - stopCount = stops.length, - PI = Math.PI, - GradientUtil = PIE.GradientUtil, - perpendicularIntersect = GradientUtil.perpendicularIntersect, - distance = GradientUtil.distance, - metrics = GradientUtil.getGradientMetrics( el, w, h, info ), - angle = metrics.angle, - startX = metrics.startX, - startY = metrics.startY, - startCornerX = metrics.startCornerX, - startCornerY = metrics.startCornerY, - endCornerX = metrics.endCornerX, - endCornerY = metrics.endCornerY, - deltaX = metrics.deltaX, - deltaY = metrics.deltaY, - lineLength = metrics.lineLength, - vmlAngle, vmlGradientLength, vmlColors, - stopPx, vmlOffsetPct, - p, i, j, before, after; - - // In VML land, the angle of the rendered gradient depends on the aspect ratio of the shape's - // bounding box; for example specifying a 45 deg angle actually results in a gradient - // drawn diagonally from one corner to its opposite corner, which will only appear to the - // viewer as 45 degrees if the shape is equilateral. We adjust for this by taking the x/y deltas - // between the start and end points, multiply one of them by the shape's aspect ratio, - // and get their arctangent, resulting in an appropriate VML angle. If the angle is perfectly - // horizontal or vertical then we don't need to do this conversion. - vmlAngle = ( angle % 90 ) ? Math.atan2( deltaX * w / h, deltaY ) / PI * 180 : ( angle + 90 ); - - // VML angles are 180 degrees offset from CSS angles - vmlAngle += 180; - vmlAngle = vmlAngle % 360; - - // Add all the stops to the VML 'colors' list, including the first and last stops. - // For each, we find its pixel offset along the gradient-line; if the offset of a stop is less - // than that of its predecessor we increase it to be equal. We then map that pixel offset to a - // percentage along the VML gradient-line, which runs from shape corner to corner. - p = perpendicularIntersect( startCornerX, startCornerY, angle, endCornerX, endCornerY ); - vmlGradientLength = distance( startCornerX, startCornerY, p[0], p[1] ); - vmlColors = []; - p = perpendicularIntersect( startX, startY, angle, startCornerX, startCornerY ); - vmlOffsetPct = distance( startX, startY, p[0], p[1] ) / vmlGradientLength * 100; - - // Find the pixel offsets along the CSS3 gradient-line for each stop. - stopPx = []; - for( i = 0; i < stopCount; i++ ) { - stopPx.push( stops[i].offset ? stops[i].offset.pixels( el, lineLength ) : - i === 0 ? 0 : i === stopCount - 1 ? lineLength : null ); - } - // Fill in gaps with evenly-spaced offsets - for( i = 1; i < stopCount; i++ ) { - if( stopPx[ i ] === null ) { - before = stopPx[ i - 1 ]; - j = i; - do { - after = stopPx[ ++j ]; - } while( after === null ); - stopPx[ i ] = before + ( after - before ) / ( j - i + 1 ); - } - // Make sure each stop's offset is no less than the one before it - stopPx[ i ] = Math.max( stopPx[ i ], stopPx[ i - 1 ] ); - } - - // Convert to percentage along the VML gradient line and add to the VML 'colors' value - for( i = 0; i < stopCount; i++ ) { - vmlColors.push( - ( vmlOffsetPct + ( stopPx[ i ] / vmlGradientLength * 100 ) ) + '% ' + stops[i].color.colorValue( el ) - ); - } - - // Now, finally, we're ready to render the gradient fill. Set the start and end colors to - // the first and last stop colors; this just sets outer bounds for the gradient. - fill['angle'] = vmlAngle; - fill['type'] = 'gradient'; - fill['method'] = 'sigma'; - fill['color'] = stops[0].color.colorValue( el ); - fill['color2'] = stops[stopCount - 1].color.colorValue( el ); - if( fill['colors'] ) { //sometimes the colors object isn't initialized so we have to assign it directly (?) - fill['colors'].value = vmlColors.join( ',' ); - } else { - fill['colors'] = vmlColors.join( ',' ); - } - }, - - - /** - * Hide the actual background image and color of the element. - */ - hideBackground: function() { - var rs = this.targetElement.runtimeStyle; - rs.backgroundImage = 'url(about:blank)'; //ensures the background area reacts to mouse events - rs.backgroundColor = 'transparent'; - }, - - destroy: function() { - PIE.RendererBase.destroy.call( this ); - var rs = this.targetElement.runtimeStyle; - rs.backgroundImage = rs.backgroundColor = ''; - } - -} ); -/** - * Renderer for element borders. - * @constructor - * @param {Element} el The target element - * @param {Object} styleInfos The StyleInfo objects - * @param {PIE.RootRenderer} parent - */ -PIE.BorderRenderer = PIE.RendererBase.newRenderer( { - - boxZIndex: 4, - boxName: 'border', - - needsUpdate: function() { - var si = this.styleInfos; - return si.borderInfo.changed() || si.borderRadiusInfo.changed(); - }, - - isActive: function() { - var si = this.styleInfos; - return si.borderRadiusInfo.isActive() && - !si.borderImageInfo.isActive() && - si.borderInfo.isActive(); //check BorderStyleInfo last because it's the most expensive - }, - - /** - * Draw the border shape(s) - */ - draw: function() { - var el = this.targetElement, - props = this.styleInfos.borderInfo.getProps(), - bounds = this.boundsInfo.getBounds(), - w = bounds.w, - h = bounds.h, - shape, stroke, s, - segments, seg, i, len; - - if( props ) { - this.hideBorder(); - - segments = this.getBorderSegments( 2 ); - for( i = 0, len = segments.length; i < len; i++) { - seg = segments[i]; - shape = this.getShape( 'borderPiece' + i, seg.stroke ? 'stroke' : 'fill', this.getBox() ); - shape.coordsize = w * 2 + ',' + h * 2; - shape.coordorigin = '1,1'; - shape.path = seg.path; - s = shape.style; - s.width = w; - s.height = h; - - shape.filled = !!seg.fill; - shape.stroked = !!seg.stroke; - if( seg.stroke ) { - stroke = shape.stroke; - stroke['weight'] = seg.weight + 'px'; - stroke.color = seg.color.colorValue( el ); - stroke['dashstyle'] = seg.stroke === 'dashed' ? '2 2' : seg.stroke === 'dotted' ? '1 1' : 'solid'; - stroke['linestyle'] = seg.stroke === 'double' && seg.weight > 2 ? 'ThinThin' : 'Single'; - } else { - shape.fill.color = seg.fill.colorValue( el ); - } - } - - // remove any previously-created border shapes which didn't get used above - while( this.deleteShape( 'borderPiece' + i++ ) ) {} - } - }, - - - /** - * Get the VML path definitions for the border segment(s). - * @param {number=} mult If specified, all coordinates will be multiplied by this number - * @return {Array.} - */ - getBorderSegments: function( mult ) { - var el = this.targetElement, - bounds, elW, elH, - borderInfo = this.styleInfos.borderInfo, - segments = [], - floor, ceil, wT, wR, wB, wL, - round = Math.round, - borderProps, radiusInfo, radii, widths, styles, colors; - - if( borderInfo.isActive() ) { - borderProps = borderInfo.getProps(); - - widths = borderProps.widths; - styles = borderProps.styles; - colors = borderProps.colors; - - if( borderProps.widthsSame && borderProps.stylesSame && borderProps.colorsSame ) { - if( colors['t'].alpha() > 0 ) { - // shortcut for identical border on all sides - only need 1 stroked shape - wT = widths['t'].pixels( el ); //thickness - wR = wT / 2; //shrink - segments.push( { - path: this.getBoxPath( { t: wR, r: wR, b: wR, l: wR }, mult ), - stroke: styles['t'], - color: colors['t'], - weight: wT - } ); - } - } - else { - mult = mult || 1; - bounds = this.boundsInfo.getBounds(); - elW = bounds.w; - elH = bounds.h; - - wT = round( widths['t'].pixels( el ) ); - wR = round( widths['r'].pixels( el ) ); - wB = round( widths['b'].pixels( el ) ); - wL = round( widths['l'].pixels( el ) ); - var pxWidths = { - 't': wT, - 'r': wR, - 'b': wB, - 'l': wL - }; - - radiusInfo = this.styleInfos.borderRadiusInfo; - if( radiusInfo.isActive() ) { - radii = this.getRadiiPixels( radiusInfo.getProps() ); - } - - floor = Math.floor; - ceil = Math.ceil; - - function radius( xy, corner ) { - return radii ? radii[ xy ][ corner ] : 0; - } - - function curve( corner, shrinkX, shrinkY, startAngle, ccw, doMove ) { - var rx = radius( 'x', corner), - ry = radius( 'y', corner), - deg = 65535, - isRight = corner.charAt( 1 ) === 'r', - isBottom = corner.charAt( 0 ) === 'b'; - return ( rx > 0 && ry > 0 ) ? - ( doMove ? 'al' : 'ae' ) + - ( isRight ? ceil( elW - rx ) : floor( rx ) ) * mult + ',' + // center x - ( isBottom ? ceil( elH - ry ) : floor( ry ) ) * mult + ',' + // center y - ( floor( rx ) - shrinkX ) * mult + ',' + // width - ( floor( ry ) - shrinkY ) * mult + ',' + // height - ( startAngle * deg ) + ',' + // start angle - ( 45 * deg * ( ccw ? 1 : -1 ) // angle change - ) : ( - ( doMove ? 'm' : 'l' ) + - ( isRight ? elW - shrinkX : shrinkX ) * mult + ',' + - ( isBottom ? elH - shrinkY : shrinkY ) * mult - ); - } - - function line( side, shrink, ccw, doMove ) { - var - start = ( - side === 't' ? - floor( radius( 'x', 'tl') ) * mult + ',' + ceil( shrink ) * mult : - side === 'r' ? - ceil( elW - shrink ) * mult + ',' + floor( radius( 'y', 'tr') ) * mult : - side === 'b' ? - ceil( elW - radius( 'x', 'br') ) * mult + ',' + floor( elH - shrink ) * mult : - // side === 'l' ? - floor( shrink ) * mult + ',' + ceil( elH - radius( 'y', 'bl') ) * mult - ), - end = ( - side === 't' ? - ceil( elW - radius( 'x', 'tr') ) * mult + ',' + ceil( shrink ) * mult : - side === 'r' ? - ceil( elW - shrink ) * mult + ',' + ceil( elH - radius( 'y', 'br') ) * mult : - side === 'b' ? - floor( radius( 'x', 'bl') ) * mult + ',' + floor( elH - shrink ) * mult : - // side === 'l' ? - floor( shrink ) * mult + ',' + floor( radius( 'y', 'tl') ) * mult - ); - return ccw ? ( doMove ? 'm' + end : '' ) + 'l' + start : - ( doMove ? 'm' + start : '' ) + 'l' + end; - } - - - function addSide( side, sideBefore, sideAfter, cornerBefore, cornerAfter, baseAngle ) { - var vert = side === 'l' || side === 'r', - sideW = pxWidths[ side ], - beforeX, beforeY, afterX, afterY; - - if( sideW > 0 && styles[ side ] !== 'none' && colors[ side ].alpha() > 0 ) { - beforeX = pxWidths[ vert ? side : sideBefore ]; - beforeY = pxWidths[ vert ? sideBefore : side ]; - afterX = pxWidths[ vert ? side : sideAfter ]; - afterY = pxWidths[ vert ? sideAfter : side ]; - - if( styles[ side ] === 'dashed' || styles[ side ] === 'dotted' ) { - segments.push( { - path: curve( cornerBefore, beforeX, beforeY, baseAngle + 45, 0, 1 ) + - curve( cornerBefore, 0, 0, baseAngle, 1, 0 ), - fill: colors[ side ] - } ); - segments.push( { - path: line( side, sideW / 2, 0, 1 ), - stroke: styles[ side ], - weight: sideW, - color: colors[ side ] - } ); - segments.push( { - path: curve( cornerAfter, afterX, afterY, baseAngle, 0, 1 ) + - curve( cornerAfter, 0, 0, baseAngle - 45, 1, 0 ), - fill: colors[ side ] - } ); - } - else { - segments.push( { - path: curve( cornerBefore, beforeX, beforeY, baseAngle + 45, 0, 1 ) + - line( side, sideW, 0, 0 ) + - curve( cornerAfter, afterX, afterY, baseAngle, 0, 0 ) + - - ( styles[ side ] === 'double' && sideW > 2 ? - curve( cornerAfter, afterX - floor( afterX / 3 ), afterY - floor( afterY / 3 ), baseAngle - 45, 1, 0 ) + - line( side, ceil( sideW / 3 * 2 ), 1, 0 ) + - curve( cornerBefore, beforeX - floor( beforeX / 3 ), beforeY - floor( beforeY / 3 ), baseAngle, 1, 0 ) + - 'x ' + - curve( cornerBefore, floor( beforeX / 3 ), floor( beforeY / 3 ), baseAngle + 45, 0, 1 ) + - line( side, floor( sideW / 3 ), 1, 0 ) + - curve( cornerAfter, floor( afterX / 3 ), floor( afterY / 3 ), baseAngle, 0, 0 ) - : '' ) + - - curve( cornerAfter, 0, 0, baseAngle - 45, 1, 0 ) + - line( side, 0, 1, 0 ) + - curve( cornerBefore, 0, 0, baseAngle, 1, 0 ), - fill: colors[ side ] - } ); - } - } - } - - addSide( 't', 'l', 'r', 'tl', 'tr', 90 ); - addSide( 'r', 't', 'b', 'tr', 'br', 0 ); - addSide( 'b', 'r', 'l', 'br', 'bl', -90 ); - addSide( 'l', 'b', 't', 'bl', 'tl', -180 ); - } - } - - return segments; - }, - - destroy: function() { - var me = this; - if (me.finalized || !me.styleInfos.borderImageInfo.isActive()) { - me.targetElement.runtimeStyle.borderColor = ''; - } - PIE.RendererBase.destroy.call( me ); - } - - -} ); -/** - * Renderer for border-image - * @constructor - * @param {Element} el The target element - * @param {Object} styleInfos The StyleInfo objects - * @param {PIE.RootRenderer} parent - */ -PIE.BorderImageRenderer = PIE.RendererBase.newRenderer( { - - boxZIndex: 5, - pieceNames: [ 't', 'tr', 'r', 'br', 'b', 'bl', 'l', 'tl', 'c' ], - - needsUpdate: function() { - return this.styleInfos.borderImageInfo.changed(); - }, - - isActive: function() { - return this.styleInfos.borderImageInfo.isActive(); - }, - - draw: function() { - this.getBox(); //make sure pieces are created - - var props = this.styleInfos.borderImageInfo.getProps(), - borderProps = this.styleInfos.borderInfo.getProps(), - bounds = this.boundsInfo.getBounds(), - el = this.targetElement, - pieces = this.pieces; - - PIE.Util.withImageSize( props.src, function( imgSize ) { - var elW = bounds.w, - elH = bounds.h, - zero = PIE.getLength( '0' ), - widths = props.widths || ( borderProps ? borderProps.widths : { 't': zero, 'r': zero, 'b': zero, 'l': zero } ), - widthT = widths['t'].pixels( el ), - widthR = widths['r'].pixels( el ), - widthB = widths['b'].pixels( el ), - widthL = widths['l'].pixels( el ), - slices = props.slice, - sliceT = slices['t'].pixels( el ), - sliceR = slices['r'].pixels( el ), - sliceB = slices['b'].pixels( el ), - sliceL = slices['l'].pixels( el ); - - // Piece positions and sizes - function setSizeAndPos( piece, w, h, x, y ) { - var s = pieces[piece].style, - max = Math.max; - s.width = max(w, 0); - s.height = max(h, 0); - s.left = x; - s.top = y; - } - setSizeAndPos( 'tl', widthL, widthT, 0, 0 ); - setSizeAndPos( 't', elW - widthL - widthR, widthT, widthL, 0 ); - setSizeAndPos( 'tr', widthR, widthT, elW - widthR, 0 ); - setSizeAndPos( 'r', widthR, elH - widthT - widthB, elW - widthR, widthT ); - setSizeAndPos( 'br', widthR, widthB, elW - widthR, elH - widthB ); - setSizeAndPos( 'b', elW - widthL - widthR, widthB, widthL, elH - widthB ); - setSizeAndPos( 'bl', widthL, widthB, 0, elH - widthB ); - setSizeAndPos( 'l', widthL, elH - widthT - widthB, 0, widthT ); - setSizeAndPos( 'c', elW - widthL - widthR, elH - widthT - widthB, widthL, widthT ); - - - // image croppings - function setCrops( sides, crop, val ) { - for( var i=0, len=sides.length; i < len; i++ ) { - pieces[ sides[i] ]['imagedata'][ crop ] = val; - } - } - - // corners - setCrops( [ 'tl', 't', 'tr' ], 'cropBottom', ( imgSize.h - sliceT ) / imgSize.h ); - setCrops( [ 'tl', 'l', 'bl' ], 'cropRight', ( imgSize.w - sliceL ) / imgSize.w ); - setCrops( [ 'bl', 'b', 'br' ], 'cropTop', ( imgSize.h - sliceB ) / imgSize.h ); - setCrops( [ 'tr', 'r', 'br' ], 'cropLeft', ( imgSize.w - sliceR ) / imgSize.w ); - - // edges and center - // TODO right now this treats everything like 'stretch', need to support other schemes - //if( props.repeat.v === 'stretch' ) { - setCrops( [ 'l', 'r', 'c' ], 'cropTop', sliceT / imgSize.h ); - setCrops( [ 'l', 'r', 'c' ], 'cropBottom', sliceB / imgSize.h ); - //} - //if( props.repeat.h === 'stretch' ) { - setCrops( [ 't', 'b', 'c' ], 'cropLeft', sliceL / imgSize.w ); - setCrops( [ 't', 'b', 'c' ], 'cropRight', sliceR / imgSize.w ); - //} - - // center fill - pieces['c'].style.display = props.fill ? '' : 'none'; - }, this ); - }, - - getBox: function() { - var box = this.parent.getLayer( this.boxZIndex ), - s, piece, i, - pieceNames = this.pieceNames, - len = pieceNames.length; - - if( !box ) { - box = doc.createElement( 'border-image' ); - s = box.style; - s.position = 'absolute'; - - this.pieces = {}; - - for( i = 0; i < len; i++ ) { - piece = this.pieces[ pieceNames[i] ] = PIE.Util.createVmlElement( 'rect' ); - piece.appendChild( PIE.Util.createVmlElement( 'imagedata' ) ); - s = piece.style; - s['behavior'] = 'url(#default#VML)'; - s.position = "absolute"; - s.top = s.left = 0; - piece['imagedata'].src = this.styleInfos.borderImageInfo.getProps().src; - piece.stroked = false; - piece.filled = false; - box.appendChild( piece ); - } - - this.parent.addLayer( this.boxZIndex, box ); - } - - return box; - }, - - prepareUpdate: function() { - if (this.isActive()) { - var me = this, - el = me.targetElement, - rs = el.runtimeStyle, - widths = me.styleInfos.borderImageInfo.getProps().widths; - - // Force border-style to solid so it doesn't collapse - rs.borderStyle = 'solid'; - - // If widths specified in border-image shorthand, override border-width - // NOTE px units needed here as this gets used by the IE9 renderer too - if ( widths ) { - rs.borderTopWidth = widths['t'].pixels( el ) + 'px'; - rs.borderRightWidth = widths['r'].pixels( el ) + 'px'; - rs.borderBottomWidth = widths['b'].pixels( el ) + 'px'; - rs.borderLeftWidth = widths['l'].pixels( el ) + 'px'; - } - - // Make the border transparent - me.hideBorder(); - } - }, - - destroy: function() { - var me = this, - rs = me.targetElement.runtimeStyle; - rs.borderStyle = ''; - if (me.finalized || !me.styleInfos.borderInfo.isActive()) { - rs.borderColor = rs.borderWidth = ''; - } - PIE.RendererBase.destroy.call( this ); - } - -} ); -/** - * Renderer for outset box-shadows - * @constructor - * @param {Element} el The target element - * @param {Object} styleInfos The StyleInfo objects - * @param {PIE.RootRenderer} parent - */ -PIE.BoxShadowOutsetRenderer = PIE.RendererBase.newRenderer( { - - boxZIndex: 1, - boxName: 'outset-box-shadow', - - needsUpdate: function() { - var si = this.styleInfos; - return si.boxShadowInfo.changed() || si.borderRadiusInfo.changed(); - }, - - isActive: function() { - var boxShadowInfo = this.styleInfos.boxShadowInfo; - return boxShadowInfo.isActive() && boxShadowInfo.getProps().outset[0]; - }, - - draw: function() { - var me = this, - el = this.targetElement, - box = this.getBox(), - styleInfos = this.styleInfos, - shadowInfos = styleInfos.boxShadowInfo.getProps().outset, - radii = styleInfos.borderRadiusInfo.getProps(), - len = shadowInfos.length, - i = len, j, - bounds = this.boundsInfo.getBounds(), - w = bounds.w, - h = bounds.h, - clipAdjust = PIE.ieVersion === 8 ? 1 : 0, //workaround for IE8 bug where VML leaks out top/left of clip region by 1px - corners = [ 'tl', 'tr', 'br', 'bl' ], corner, - shadowInfo, shape, fill, ss, xOff, yOff, spread, blur, shrink, color, alpha, path, - totalW, totalH, focusX, focusY, isBottom, isRight; - - - function getShadowShape( index, corner, xOff, yOff, color, blur, path ) { - var shape = me.getShape( 'shadow' + index + corner, 'fill', box, len - index ), - fill = shape.fill; - - // Position and size - shape['coordsize'] = w * 2 + ',' + h * 2; - shape['coordorigin'] = '1,1'; - - // Color and opacity - shape['stroked'] = false; - shape['filled'] = true; - fill.color = color.colorValue( el ); - if( blur ) { - fill['type'] = 'gradienttitle'; //makes the VML gradient follow the shape's outline - hooray for undocumented features?!?! - fill['color2'] = fill.color; - fill['opacity'] = 0; - } - - // Path - shape.path = path; - - // This needs to go last for some reason, to prevent rendering at incorrect size - ss = shape.style; - ss.left = xOff; - ss.top = yOff; - ss.width = w; - ss.height = h; - - return shape; - } - - - while( i-- ) { - shadowInfo = shadowInfos[ i ]; - xOff = shadowInfo.xOffset.pixels( el ); - yOff = shadowInfo.yOffset.pixels( el ); - spread = shadowInfo.spread.pixels( el ); - blur = shadowInfo.blur.pixels( el ); - color = shadowInfo.color; - // Shape path - shrink = -spread - blur; - if( !radii && blur ) { - // If blurring, use a non-null border radius info object so that getBoxPath will - // round the corners of the expanded shadow shape rather than squaring them off. - radii = PIE.BorderRadiusStyleInfo.ALL_ZERO; - } - path = this.getBoxPath( { t: shrink, r: shrink, b: shrink, l: shrink }, 2, radii ); - - if( blur ) { - totalW = ( spread + blur ) * 2 + w; - totalH = ( spread + blur ) * 2 + h; - focusX = totalW ? blur * 2 / totalW : 0; - focusY = totalH ? blur * 2 / totalH : 0; - if( blur - spread > w / 2 || blur - spread > h / 2 ) { - // If the blur is larger than half the element's narrowest dimension, we cannot do - // this with a single shape gradient, because its focussize would have to be less than - // zero which results in ugly artifacts. Instead we create four shapes, each with its - // gradient focus past center, and then clip them so each only shows the quadrant - // opposite the focus. - for( j = 4; j--; ) { - corner = corners[j]; - isBottom = corner.charAt( 0 ) === 'b'; - isRight = corner.charAt( 1 ) === 'r'; - shape = getShadowShape( i, corner, xOff, yOff, color, blur, path ); - fill = shape.fill; - fill['focusposition'] = ( isRight ? 1 - focusX : focusX ) + ',' + - ( isBottom ? 1 - focusY : focusY ); - fill['focussize'] = '0,0'; - - // Clip to show only the appropriate quadrant. Add 1px to the top/left clip values - // in IE8 to prevent a bug where IE8 displays one pixel outside the clip region. - shape.style.clip = 'rect(' + ( ( isBottom ? totalH / 2 : 0 ) + clipAdjust ) + 'px,' + - ( isRight ? totalW : totalW / 2 ) + 'px,' + - ( isBottom ? totalH : totalH / 2 ) + 'px,' + - ( ( isRight ? totalW / 2 : 0 ) + clipAdjust ) + 'px)'; - } - } else { - // TODO delete old quadrant shapes if resizing expands past the barrier - shape = getShadowShape( i, '', xOff, yOff, color, blur, path ); - fill = shape.fill; - fill['focusposition'] = focusX + ',' + focusY; - fill['focussize'] = ( 1 - focusX * 2 ) + ',' + ( 1 - focusY * 2 ); - } - } else { - shape = getShadowShape( i, '', xOff, yOff, color, blur, path ); - alpha = color.alpha(); - if( alpha < 1 ) { - // shape.style.filter = 'alpha(opacity=' + ( alpha * 100 ) + ')'; - // ss.filter = 'progid:DXImageTransform.Microsoft.BasicImage(opacity=' + ( alpha ) + ')'; - shape.fill.opacity = alpha; - } - } - } - } - -} ); -/** - * Renderer for re-rendering img elements using VML. Kicks in if the img has - * a border-radius applied, or if the -pie-png-fix flag is set. - * @constructor - * @param {Element} el The target element - * @param {Object} styleInfos The StyleInfo objects - * @param {PIE.RootRenderer} parent - */ -PIE.ImgRenderer = PIE.RendererBase.newRenderer( { - - boxZIndex: 6, - boxName: 'imgEl', - - needsUpdate: function() { - var si = this.styleInfos; - return this.targetElement.src !== this._lastSrc || si.borderRadiusInfo.changed(); - }, - - isActive: function() { - var si = this.styleInfos; - return si.borderRadiusInfo.isActive() || si.backgroundInfo.isPngFix(); - }, - - draw: function() { - this._lastSrc = src; - this.hideActualImg(); - - var shape = this.getShape( 'img', 'fill', this.getBox() ), - fill = shape.fill, - bounds = this.boundsInfo.getBounds(), - w = bounds.w, - h = bounds.h, - borderProps = this.styleInfos.borderInfo.getProps(), - borderWidths = borderProps && borderProps.widths, - el = this.targetElement, - src = el.src, - round = Math.round, - cs = el.currentStyle, - getLength = PIE.getLength, - s, zero; - - // In IE6, the BorderRenderer will have hidden the border by moving the border-width to - // the padding; therefore we want to pretend the borders have no width so they aren't doubled - // when adding in the current padding value below. - if( !borderWidths || PIE.ieVersion < 7 ) { - zero = PIE.getLength( '0' ); - borderWidths = { 't': zero, 'r': zero, 'b': zero, 'l': zero }; - } - - shape.stroked = false; - fill.type = 'frame'; - fill.src = src; - fill.position = (w ? 0.5 / w : 0) + ',' + (h ? 0.5 / h : 0); - shape.coordsize = w * 2 + ',' + h * 2; - shape.coordorigin = '1,1'; - shape.path = this.getBoxPath( { - t: round( borderWidths['t'].pixels( el ) + getLength( cs.paddingTop ).pixels( el ) ), - r: round( borderWidths['r'].pixels( el ) + getLength( cs.paddingRight ).pixels( el ) ), - b: round( borderWidths['b'].pixels( el ) + getLength( cs.paddingBottom ).pixels( el ) ), - l: round( borderWidths['l'].pixels( el ) + getLength( cs.paddingLeft ).pixels( el ) ) - }, 2 ); - s = shape.style; - s.width = w; - s.height = h; - }, - - hideActualImg: function() { - this.targetElement.runtimeStyle.filter = 'alpha(opacity=0)'; - }, - - destroy: function() { - PIE.RendererBase.destroy.call( this ); - this.targetElement.runtimeStyle.filter = ''; - } - -} ); -/** - * Root renderer for IE9; manages the rendering layers in the element's background - * @param {Element} el The target element - * @param {Object} styleInfos The StyleInfo objects - */ -PIE.IE9RootRenderer = PIE.RendererBase.newRenderer( { - - updatePos: PIE.emptyFn, - updateSize: PIE.emptyFn, - updateVisibility: PIE.emptyFn, - updateProps: PIE.emptyFn, - - outerCommasRE: /^,+|,+$/g, - innerCommasRE: /,+/g, - - setBackgroundLayer: function(zIndex, bg) { - var me = this, - bgLayers = me._bgLayers || ( me._bgLayers = [] ), - undef; - bgLayers[zIndex] = bg || undef; - }, - - finishUpdate: function() { - var me = this, - bgLayers = me._bgLayers, - bg; - if( bgLayers && ( bg = bgLayers.join( ',' ).replace( me.outerCommasRE, '' ).replace( me.innerCommasRE, ',' ) ) !== me._lastBg ) { - me._lastBg = me.targetElement.runtimeStyle.background = bg; - } - }, - - destroy: function() { - this.targetElement.runtimeStyle.background = ''; - delete this._bgLayers; - } - -} ); -/** - * Renderer for element backgrounds, specific for IE9. Only handles translating CSS3 gradients - * to an equivalent SVG data URI. - * @constructor - * @param {Element} el The target element - * @param {Object} styleInfos The StyleInfo objects - */ -PIE.IE9BackgroundRenderer = PIE.RendererBase.newRenderer( { - - bgLayerZIndex: 1, - - needsUpdate: function() { - var si = this.styleInfos; - return si.backgroundInfo.changed(); - }, - - isActive: function() { - var si = this.styleInfos; - return si.backgroundInfo.isActive() || si.borderImageInfo.isActive(); - }, - - draw: function() { - var me = this, - props = me.styleInfos.backgroundInfo.getProps(), - bg, images, i = 0, img, bgAreaSize, bgSize; - - if ( props ) { - bg = []; - - images = props.bgImages; - if ( images ) { - while( img = images[ i++ ] ) { - if (img.imgType === 'linear-gradient' ) { - bgAreaSize = me.getBgAreaSize( img.bgOrigin ); - bgSize = ( img.bgSize || PIE.BgSize.DEFAULT ).pixels( - me.targetElement, bgAreaSize.w, bgAreaSize.h, bgAreaSize.w, bgAreaSize.h - ), - bg.push( - 'url(data:image/svg+xml,' + escape( me.getGradientSvg( img, bgSize.w, bgSize.h ) ) + ') ' + - me.bgPositionToString( img.bgPosition ) + ' / ' + bgSize.w + 'px ' + bgSize.h + 'px ' + - ( img.bgAttachment || '' ) + ' ' + ( img.bgOrigin || '' ) + ' ' + ( img.bgClip || '' ) - ); - } else { - bg.push( img.origString ); - } - } - } - - if ( props.color ) { - bg.push( props.color.val ); - } - - me.parent.setBackgroundLayer(me.bgLayerZIndex, bg.join(',')); - } - }, - - bgPositionToString: function( bgPosition ) { - return bgPosition ? bgPosition.tokens.map(function(token) { - return token.tokenValue; - }).join(' ') : '0 0'; - }, - - getBgAreaSize: function( bgOrigin ) { - var me = this, - el = me.targetElement, - bounds = me.boundsInfo.getBounds(), - elW = bounds.w, - elH = bounds.h, - w = elW, - h = elH, - borders, getLength, cs; - - if( bgOrigin !== 'border-box' ) { - borders = me.styleInfos.borderInfo.getProps(); - if( borders && ( borders = borders.widths ) ) { - w -= borders[ 'l' ].pixels( el ) + borders[ 'l' ].pixels( el ); - h -= borders[ 't' ].pixels( el ) + borders[ 'b' ].pixels( el ); - } - } - - if ( bgOrigin === 'content-box' ) { - getLength = PIE.getLength; - cs = el.currentStyle; - w -= getLength( cs.paddingLeft ).pixels( el ) + getLength( cs.paddingRight ).pixels( el ); - h -= getLength( cs.paddingTop ).pixels( el ) + getLength( cs.paddingBottom ).pixels( el ); - } - - return { w: w, h: h }; - }, - - getGradientSvg: function( info, bgWidth, bgHeight ) { - var el = this.targetElement, - stopsInfo = info.stops, - stopCount = stopsInfo.length, - metrics = PIE.GradientUtil.getGradientMetrics( el, bgWidth, bgHeight, info ), - startX = metrics.startX, - startY = metrics.startY, - endX = metrics.endX, - endY = metrics.endY, - lineLength = metrics.lineLength, - stopPx, - i, j, before, after, - svg; - - // Find the pixel offsets along the CSS3 gradient-line for each stop. - stopPx = []; - for( i = 0; i < stopCount; i++ ) { - stopPx.push( stopsInfo[i].offset ? stopsInfo[i].offset.pixels( el, lineLength ) : - i === 0 ? 0 : i === stopCount - 1 ? lineLength : null ); - } - // Fill in gaps with evenly-spaced offsets - for( i = 1; i < stopCount; i++ ) { - if( stopPx[ i ] === null ) { - before = stopPx[ i - 1 ]; - j = i; - do { - after = stopPx[ ++j ]; - } while( after === null ); - stopPx[ i ] = before + ( after - before ) / ( j - i + 1 ); - } - } - - svg = [ - '' + - '' + - '' - ]; - - // Convert to percentage along the SVG gradient line and add to the stops list - for( i = 0; i < stopCount; i++ ) { - svg.push( - '' - ); - } - - svg.push( - '' + - '' + - '' + - '' - ); - - return svg.join( '' ); - }, - - destroy: function() { - this.parent.setBackgroundLayer( this.bgLayerZIndex ); - } - -} ); -/** - * Renderer for border-image - * @constructor - * @param {Element} el The target element - * @param {Object} styleInfos The StyleInfo objects - * @param {PIE.RootRenderer} parent - */ -PIE.IE9BorderImageRenderer = PIE.RendererBase.newRenderer( { - - REPEAT: 'repeat', - STRETCH: 'stretch', - ROUND: 'round', - - bgLayerZIndex: 0, - - needsUpdate: function() { - return this.styleInfos.borderImageInfo.changed(); - }, - - isActive: function() { - return this.styleInfos.borderImageInfo.isActive(); - }, - - draw: function() { - var me = this, - props = me.styleInfos.borderImageInfo.getProps(), - borderProps = me.styleInfos.borderInfo.getProps(), - bounds = me.boundsInfo.getBounds(), - repeat = props.repeat, - repeatH = repeat.h, - repeatV = repeat.v, - el = me.targetElement, - isAsync = 0; - - PIE.Util.withImageSize( props.src, function( imgSize ) { - var elW = bounds.w, - elH = bounds.h, - imgW = imgSize.w, - imgH = imgSize.h, - - // The image cannot be referenced as a URL directly in the SVG because IE9 throws a strange - // security exception (perhaps due to cross-origin policy within data URIs?) Therefore we - // work around this by converting the image data into a data URI itself using a transient - // canvas. This unfortunately requires the border-image src to be within the same domain, - // which isn't a limitation in true border-image, so we need to try and find a better fix. - imgSrc = me.imageToDataURI( props.src, imgW, imgH ), - - REPEAT = me.REPEAT, - STRETCH = me.STRETCH, - ROUND = me.ROUND, - ceil = Math.ceil, - - zero = PIE.getLength( '0' ), - widths = props.widths || ( borderProps ? borderProps.widths : { 't': zero, 'r': zero, 'b': zero, 'l': zero } ), - widthT = widths['t'].pixels( el ), - widthR = widths['r'].pixels( el ), - widthB = widths['b'].pixels( el ), - widthL = widths['l'].pixels( el ), - slices = props.slice, - sliceT = slices['t'].pixels( el ), - sliceR = slices['r'].pixels( el ), - sliceB = slices['b'].pixels( el ), - sliceL = slices['l'].pixels( el ), - centerW = elW - widthL - widthR, - middleH = elH - widthT - widthB, - imgCenterW = imgW - sliceL - sliceR, - imgMiddleH = imgH - sliceT - sliceB, - - // Determine the size of each tile - 'round' is handled below - tileSizeT = repeatH === STRETCH ? centerW : imgCenterW * widthT / sliceT, - tileSizeR = repeatV === STRETCH ? middleH : imgMiddleH * widthR / sliceR, - tileSizeB = repeatH === STRETCH ? centerW : imgCenterW * widthB / sliceB, - tileSizeL = repeatV === STRETCH ? middleH : imgMiddleH * widthL / sliceL, - - svg, - patterns = [], - rects = [], - i = 0; - - // For 'round', subtract from each tile's size enough so that they fill the space a whole number of times - if (repeatH === ROUND) { - tileSizeT -= (tileSizeT - (centerW % tileSizeT || tileSizeT)) / ceil(centerW / tileSizeT); - tileSizeB -= (tileSizeB - (centerW % tileSizeB || tileSizeB)) / ceil(centerW / tileSizeB); - } - if (repeatV === ROUND) { - tileSizeR -= (tileSizeR - (middleH % tileSizeR || tileSizeR)) / ceil(middleH / tileSizeR); - tileSizeL -= (tileSizeL - (middleH % tileSizeL || tileSizeL)) / ceil(middleH / tileSizeL); - } - - - // Build the SVG for the border-image rendering. Add each piece as a pattern, which is then stretched - // or repeated as the fill of a rect of appropriate size. - svg = [ - '' - ]; - - function addImage( x, y, w, h, cropX, cropY, cropW, cropH, tileW, tileH ) { - patterns.push( - '' + - '' + - '' + - '' + - '' - ); - rects.push( - '' - ); - i++; - } - addImage( 0, 0, widthL, widthT, 0, 0, sliceL, sliceT, widthL, widthT ); // top left - addImage( widthL, 0, centerW, widthT, sliceL, 0, imgCenterW, sliceT, tileSizeT, widthT ); // top center - addImage( elW - widthR, 0, widthR, widthT, imgW - sliceR, 0, sliceR, sliceT, widthR, widthT ); // top right - addImage( 0, widthT, widthL, middleH, 0, sliceT, sliceL, imgMiddleH, widthL, tileSizeL ); // middle left - if ( props.fill ) { // center fill - addImage( widthL, widthT, centerW, middleH, sliceL, sliceT, imgCenterW, imgMiddleH, - tileSizeT || tileSizeB || imgCenterW, tileSizeL || tileSizeR || imgMiddleH ); - } - addImage( elW - widthR, widthT, widthR, middleH, imgW - sliceR, sliceT, sliceR, imgMiddleH, widthR, tileSizeR ); // middle right - addImage( 0, elH - widthB, widthL, widthB, 0, imgH - sliceB, sliceL, sliceB, widthL, widthB ); // bottom left - addImage( widthL, elH - widthB, centerW, widthB, sliceL, imgH - sliceB, imgCenterW, sliceB, tileSizeB, widthB ); // bottom center - addImage( elW - widthR, elH - widthB, widthR, widthB, imgW - sliceR, imgH - sliceB, sliceR, sliceB, widthR, widthB ); // bottom right - - svg.push( - '' + - patterns.join('\n') + - '' + - rects.join('\n') + - '' - ); - - me.parent.setBackgroundLayer( me.bgLayerZIndex, 'url(data:image/svg+xml,' + escape( svg.join( '' ) ) + ') no-repeat border-box border-box' ); - - // If the border-image's src wasn't immediately available, the SVG for its background layer - // will have been created asynchronously after the main element's update has finished; we'll - // therefore need to force the root renderer to sync to the final background once finished. - if( isAsync ) { - me.parent.finishUpdate(); - } - }, me ); - - isAsync = 1; - }, - - /** - * Convert a given image to a data URI - */ - imageToDataURI: (function() { - var uris = {}; - return function( src, width, height ) { - var uri = uris[ src ], - image, canvas; - if ( !uri ) { - image = new Image(); - canvas = doc.createElement( 'canvas' ); - image.src = src; - canvas.width = width; - canvas.height = height; - canvas.getContext( '2d' ).drawImage( image, 0, 0 ); - uri = uris[ src ] = canvas.toDataURL(); - } - return uri; - } - })(), - - prepareUpdate: PIE.BorderImageRenderer.prototype.prepareUpdate, - - destroy: function() { - var me = this, - rs = me.targetElement.runtimeStyle; - me.parent.setBackgroundLayer( me.bgLayerZIndex ); - rs.borderColor = rs.borderStyle = rs.borderWidth = ''; - } - -} ); - -PIE.Element = (function() { - - var wrappers = {}, - lazyInitCssProp = PIE.CSS_PREFIX + 'lazy-init', - pollCssProp = PIE.CSS_PREFIX + 'poll', - trackActiveCssProp = PIE.CSS_PREFIX + 'track-active', - trackHoverCssProp = PIE.CSS_PREFIX + 'track-hover', - hoverClass = PIE.CLASS_PREFIX + 'hover', - activeClass = PIE.CLASS_PREFIX + 'active', - focusClass = PIE.CLASS_PREFIX + 'focus', - firstChildClass = PIE.CLASS_PREFIX + 'first-child', - ignorePropertyNames = { 'background':1, 'bgColor':1, 'display': 1 }, - classNameRegExes = {}, - dummyArray = []; - - - function addClass( el, className ) { - el.className += ' ' + className; - } - - function removeClass( el, className ) { - var re = classNameRegExes[ className ] || - ( classNameRegExes[ className ] = new RegExp( '\\b' + className + '\\b', 'g' ) ); - el.className = el.className.replace( re, '' ); - } - - function delayAddClass( el, className /*, className2*/ ) { - var classes = dummyArray.slice.call( arguments, 1 ), - i = classes.length; - setTimeout( function() { - if( el ) { - while( i-- ) { - addClass( el, classes[ i ] ); - } - } - }, 0 ); - } - - function delayRemoveClass( el, className /*, className2*/ ) { - var classes = dummyArray.slice.call( arguments, 1 ), - i = classes.length; - setTimeout( function() { - if( el ) { - while( i-- ) { - removeClass( el, classes[ i ] ); - } - } - }, 0 ); - } - - - - function Element( el ) { - var renderers, - rootRenderer, - boundsInfo = new PIE.BoundsInfo( el ), - styleInfos, - styleInfosArr, - initializing, - initialized, - eventsAttached, - eventListeners = [], - delayed, - destroyed, - poll; - - /** - * Initialize PIE for this element. - */ - function init() { - if( !initialized ) { - var docEl, - bounds, - ieDocMode = PIE.ieDocMode, - cs = el.currentStyle, - lazy = cs.getAttribute( lazyInitCssProp ) === 'true', - trackActive = cs.getAttribute( trackActiveCssProp ) !== 'false', - trackHover = cs.getAttribute( trackHoverCssProp ) !== 'false', - childRenderers; - - // Polling for size/position changes: default to on in IE8, off otherwise, overridable by -pie-poll - poll = cs.getAttribute( pollCssProp ); - poll = ieDocMode > 7 ? poll !== 'false' : poll === 'true'; - - // Force layout so move/resize events will fire. Set this as soon as possible to avoid layout changes - // after load, but make sure it only gets called the first time through to avoid recursive calls to init(). - if( !initializing ) { - initializing = 1; - el.runtimeStyle.zoom = 1; - initFirstChildPseudoClass(); - } - - boundsInfo.lock(); - - // If the -pie-lazy-init:true flag is set, check if the element is outside the viewport and if so, delay initialization - if( lazy && ( bounds = boundsInfo.getBounds() ) && ( docEl = doc.documentElement || doc.body ) && - ( bounds.y > docEl.clientHeight || bounds.x > docEl.clientWidth || bounds.y + bounds.h < 0 || bounds.x + bounds.w < 0 ) ) { - if( !delayed ) { - delayed = 1; - PIE.OnScroll.observe( init ); - } - } else { - initialized = 1; - delayed = initializing = 0; - PIE.OnScroll.unobserve( init ); - - // Create the style infos and renderers - if ( ieDocMode === 9 ) { - styleInfos = { - backgroundInfo: new PIE.BackgroundStyleInfo( el ), - borderImageInfo: new PIE.BorderImageStyleInfo( el ), - borderInfo: new PIE.BorderStyleInfo( el ) - }; - styleInfosArr = [ - styleInfos.backgroundInfo, - styleInfos.borderImageInfo - ]; - rootRenderer = new PIE.IE9RootRenderer( el, boundsInfo, styleInfos ); - childRenderers = [ - new PIE.IE9BackgroundRenderer( el, boundsInfo, styleInfos, rootRenderer ), - new PIE.IE9BorderImageRenderer( el, boundsInfo, styleInfos, rootRenderer ) - ]; - } else { - - styleInfos = { - backgroundInfo: new PIE.BackgroundStyleInfo( el ), - borderInfo: new PIE.BorderStyleInfo( el ), - borderImageInfo: new PIE.BorderImageStyleInfo( el ), - borderRadiusInfo: new PIE.BorderRadiusStyleInfo( el ), - boxShadowInfo: new PIE.BoxShadowStyleInfo( el ), - visibilityInfo: new PIE.VisibilityStyleInfo( el ) - }; - styleInfosArr = [ - styleInfos.backgroundInfo, - styleInfos.borderInfo, - styleInfos.borderImageInfo, - styleInfos.borderRadiusInfo, - styleInfos.boxShadowInfo, - styleInfos.visibilityInfo - ]; - rootRenderer = new PIE.RootRenderer( el, boundsInfo, styleInfos ); - childRenderers = [ - new PIE.BoxShadowOutsetRenderer( el, boundsInfo, styleInfos, rootRenderer ), - new PIE.BackgroundRenderer( el, boundsInfo, styleInfos, rootRenderer ), - //new PIE.BoxShadowInsetRenderer( el, boundsInfo, styleInfos, rootRenderer ), - new PIE.BorderRenderer( el, boundsInfo, styleInfos, rootRenderer ), - new PIE.BorderImageRenderer( el, boundsInfo, styleInfos, rootRenderer ) - ]; - if( el.tagName === 'IMG' ) { - childRenderers.push( new PIE.ImgRenderer( el, boundsInfo, styleInfos, rootRenderer ) ); - } - rootRenderer.childRenderers = childRenderers; // circular reference, can't pass in constructor; TODO is there a cleaner way? - } - renderers = [ rootRenderer ].concat( childRenderers ); - - // Add property change listeners to ancestors if requested - initAncestorEventListeners(); - - // Add to list of polled elements in IE8 - if( poll ) { - PIE.Heartbeat.observe( update ); - PIE.Heartbeat.run(); - } - - // Trigger rendering - update( 1 ); - } - - if( !eventsAttached ) { - eventsAttached = 1; - if( ieDocMode < 9 ) { - addListener( el, 'onmove', handleMoveOrResize ); - } - addListener( el, 'onresize', handleMoveOrResize ); - addListener( el, 'onpropertychange', propChanged ); - if( trackHover ) { - addListener( el, 'onmouseenter', mouseEntered ); - } - if( trackHover || trackActive ) { - addListener( el, 'onmouseleave', mouseLeft ); - } - if( trackActive ) { - addListener( el, 'onmousedown', mousePressed ); - } - if( el.tagName in PIE.focusableElements ) { - addListener( el, 'onfocus', focused ); - addListener( el, 'onblur', blurred ); - } - PIE.OnResize.observe( handleMoveOrResize ); - - PIE.OnUnload.observe( removeEventListeners ); - } - - boundsInfo.unlock(); - } - } - - - - - /** - * Event handler for onmove and onresize events. Invokes update() only if the element's - * bounds have previously been calculated, to prevent multiple runs during page load when - * the element has no initial CSS3 properties. - */ - function handleMoveOrResize() { - if( boundsInfo && boundsInfo.hasBeenQueried() ) { - update(); - } - } - - - /** - * Update position and/or size as necessary. Both move and resize events call - * this rather than the updatePos/Size functions because sometimes, particularly - * during page load, one will fire but the other won't. - */ - function update( force ) { - if( !destroyed ) { - if( initialized ) { - var i, len = renderers.length; - - lockAll(); - for( i = 0; i < len; i++ ) { - renderers[i].prepareUpdate(); - } - if( force || boundsInfo.positionChanged() ) { - /* TODO just using getBoundingClientRect (used internally by BoundsInfo) for detecting - position changes may not always be accurate; it's possible that - an element will actually move relative to its positioning parent, but its position - relative to the viewport will stay the same. Need to come up with a better way to - track movement. The most accurate would be the same logic used in RootRenderer.updatePos() - but that is a more expensive operation since it does some DOM walking, and we want this - check to be as fast as possible. */ - for( i = 0; i < len; i++ ) { - renderers[i].updatePos(); - } - } - if( force || boundsInfo.sizeChanged() ) { - for( i = 0; i < len; i++ ) { - renderers[i].updateSize(); - } - } - rootRenderer.finishUpdate(); - unlockAll(); - } - else if( !initializing ) { - init(); - } - } - } - - /** - * Handle property changes to trigger update when appropriate. - */ - function propChanged() { - var i, len = renderers.length, - renderer, - e = event; - - // Some elements like fire onpropertychange events for old-school background properties - // ('background', 'bgColor') when runtimeStyle background properties are changed, which - // results in an infinite loop; therefore we filter out those property names. Also, 'display' - // is ignored because size calculations don't work correctly immediately when its onpropertychange - // event fires, and because it will trigger an onresize event anyway. - if( !destroyed && !( e && e.propertyName in ignorePropertyNames ) ) { - if( initialized ) { - lockAll(); - for( i = 0; i < len; i++ ) { - renderers[i].prepareUpdate(); - } - for( i = 0; i < len; i++ ) { - renderer = renderers[i]; - // Make sure position is synced if the element hasn't already been rendered. - // TODO this feels sloppy - look into merging propChanged and update functions - if( !renderer.isPositioned ) { - renderer.updatePos(); - } - if( renderer.needsUpdate() ) { - renderer.updateProps(); - } - } - rootRenderer.finishUpdate(); - unlockAll(); - } - else if( !initializing ) { - init(); - } - } - } - - - /** - * Handle mouseenter events. Adds a custom class to the element to allow IE6 to add - * hover styles to non-link elements, and to trigger a propertychange update. - */ - function mouseEntered() { - //must delay this because the mouseenter event fires before the :hover styles are added. - delayAddClass( el, hoverClass ); - } - - /** - * Handle mouseleave events - */ - function mouseLeft() { - //must delay this because the mouseleave event fires before the :hover styles are removed. - delayRemoveClass( el, hoverClass, activeClass ); - } - - /** - * Handle mousedown events. Adds a custom class to the element to allow IE6 to add - * active styles to non-link elements, and to trigger a propertychange update. - */ - function mousePressed() { - //must delay this because the mousedown event fires before the :active styles are added. - delayAddClass( el, activeClass ); - - // listen for mouseups on the document; can't just be on the element because the user might - // have dragged out of the element while the mouse button was held down - PIE.OnMouseup.observe( mouseReleased ); - } - - /** - * Handle mouseup events - */ - function mouseReleased() { - //must delay this because the mouseup event fires before the :active styles are removed. - delayRemoveClass( el, activeClass ); - - PIE.OnMouseup.unobserve( mouseReleased ); - } - - /** - * Handle focus events. Adds a custom class to the element to trigger a propertychange update. - */ - function focused() { - //must delay this because the focus event fires before the :focus styles are added. - delayAddClass( el, focusClass ); - } - - /** - * Handle blur events - */ - function blurred() { - //must delay this because the blur event fires before the :focus styles are removed. - delayRemoveClass( el, focusClass ); - } - - - /** - * Handle property changes on ancestors of the element; see initAncestorEventListeners() - * which adds these listeners as requested with the -pie-watch-ancestors CSS property. - */ - function ancestorPropChanged() { - var name = event.propertyName; - if( name === 'className' || name === 'id' ) { - propChanged(); - } - } - - function lockAll() { - boundsInfo.lock(); - for( var i = styleInfosArr.length; i--; ) { - styleInfosArr[i].lock(); - } - } - - function unlockAll() { - for( var i = styleInfosArr.length; i--; ) { - styleInfosArr[i].unlock(); - } - boundsInfo.unlock(); - } - - - function addListener( targetEl, type, handler ) { - targetEl.attachEvent( type, handler ); - eventListeners.push( [ targetEl, type, handler ] ); - } - - /** - * Remove all event listeners from the element and any monitored ancestors. - */ - function removeEventListeners() { - if (eventsAttached) { - var i = eventListeners.length, - listener; - - while( i-- ) { - listener = eventListeners[ i ]; - listener[ 0 ].detachEvent( listener[ 1 ], listener[ 2 ] ); - } - - PIE.OnUnload.unobserve( removeEventListeners ); - eventsAttached = 0; - eventListeners = []; - } - } - - - /** - * Clean everything up when the behavior is removed from the element, or the element - * is manually destroyed. - */ - function destroy() { - if( !destroyed ) { - var i, len; - - removeEventListeners(); - - destroyed = 1; - - // destroy any active renderers - if( renderers ) { - for( i = 0, len = renderers.length; i < len; i++ ) { - renderers[i].finalized = 1; - renderers[i].destroy(); - } - } - - // Remove from list of polled elements in IE8 - if( poll ) { - PIE.Heartbeat.unobserve( update ); - } - // Stop onresize listening - PIE.OnResize.unobserve( update ); - - // Kill references - renderers = boundsInfo = styleInfos = styleInfosArr = el = null; - } - } - - - /** - * If requested via the custom -pie-watch-ancestors CSS property, add onpropertychange and - * other event listeners to ancestor(s) of the element so we can pick up style changes - * based on CSS rules using descendant selectors. - */ - function initAncestorEventListeners() { - var watch = el.currentStyle.getAttribute( PIE.CSS_PREFIX + 'watch-ancestors' ), - i, a; - if( watch ) { - watch = parseInt( watch, 10 ); - i = 0; - a = el.parentNode; - while( a && ( watch === 'NaN' || i++ < watch ) ) { - addListener( a, 'onpropertychange', ancestorPropChanged ); - addListener( a, 'onmouseenter', mouseEntered ); - addListener( a, 'onmouseleave', mouseLeft ); - addListener( a, 'onmousedown', mousePressed ); - if( a.tagName in PIE.focusableElements ) { - addListener( a, 'onfocus', focused ); - addListener( a, 'onblur', blurred ); - } - a = a.parentNode; - } - } - } - - - /** - * If the target element is a first child, add a pie_first-child class to it. This allows using - * the added class as a workaround for the fact that PIE's rendering element breaks the :first-child - * pseudo-class selector. - */ - function initFirstChildPseudoClass() { - var tmpEl = el, - isFirst = 1; - while( tmpEl = tmpEl.previousSibling ) { - if( tmpEl.nodeType === 1 ) { - isFirst = 0; - break; - } - } - if( isFirst ) { - addClass( el, firstChildClass ); - } - } - - - // These methods are all already bound to this instance so there's no need to wrap them - // in a closure to maintain the 'this' scope object when calling them. - this.init = init; - this.update = update; - this.destroy = destroy; - this.el = el; - } - - Element.getInstance = function( el ) { - var id = PIE.Util.getUID( el ); - return wrappers[ id ] || ( wrappers[ id ] = new Element( el ) ); - }; - - Element.destroy = function( el ) { - var id = PIE.Util.getUID( el ), - wrapper = wrappers[ id ]; - if( wrapper ) { - wrapper.destroy(); - delete wrappers[ id ]; - } - }; - - Element.destroyAll = function() { - var els = [], wrapper; - if( wrappers ) { - for( var w in wrappers ) { - if( wrappers.hasOwnProperty( w ) ) { - wrapper = wrappers[ w ]; - els.push( wrapper.el ); - wrapper.destroy(); - } - } - wrappers = {}; - } - return els; - }; - - return Element; -})(); - -/* - * This file exposes the public API for invoking PIE. - */ - - -/** - * @property supportsVML - * True if the current IE browser environment has a functioning VML engine. Should be true - * in most IEs, but in rare cases may be false. If false, PIE will exit immediately when - * attached to an element; this property may be used for debugging or by external scripts - * to perform some special action when VML support is absent. - * @type {boolean} - */ -PIE[ 'supportsVML' ] = PIE.supportsVML; - - -/** - * Programatically attach PIE to a single element. - * @param {Element} el - */ -PIE[ 'attach' ] = function( el ) { - if (PIE.ieDocMode < 10 && PIE.supportsVML) { - PIE.Element.getInstance( el ).init(); - } -}; - - -/** - * Programatically detach PIE from a single element. - * @param {Element} el - */ -PIE[ 'detach' ] = function( el ) { - PIE.Element.destroy( el ); -}; - - -} // if( !PIE ) -})(); \ No newline at end of file diff --git a/client/client/src/assets/sound_crossed.png b/client/client/src/assets/sound_crossed.png deleted file mode 100644 index 65d3c45fa39185ee0c38f0e2b5d2528010591aef..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 238 zcmeAS@N?(olHy`uVBq!ia0vp^A|TAc1|)ksWqE;=WQl7;NpOBzNqJ&XDuZK6ep0G} zXKrG8YEWuoN@d~6R2!h837#&FAr-gQT)oK4Ajre^VD%loX`5Rua}q6szdU-lL_Mg! zdRB$v-z|;;#_{UP6~ftT7f%Y}`u>nD-Dlmzt*M<`uN|v7H}j0>I|Jd41cQzw+dSP$ zzRsf(|6`?DnjJ-&9k{o#uARYEwLx`8(4xCn4H`e??u)p8gms-kr}$iDW?BensRTwF4u~onf(nYlB1PA;3S7h1al8e&JvfBG z9AiPMa2M(l?W~_GZI;-|=5jCHTu&1WQd9^Rgw3izfK@0s9BANWbJ&6`>zdVhVq1s6 z%MhjBf~+{@bGc!=Ah9s6MKv^PL}4S)0=>axGUdS-3Q!%2=>VnyCbJ$hqbR)kAgVQq zsWp4Zl2u#k%7XY6MKtSlp-@O0(rX2&P6r5rNN8Y~Mn!1k2(M6K4KMFbDv+#9OPr{1 z0uLt?sTv`uSP<3Il@J1=%e5xV%d3e}Q>F`3q7G(1Hy=r27}%XFawd)SdWX7b|X%h44B5RwzcS&5ZoC9a8ON+clw zFK5@xtz(_QtT+xFdTYr_)Yg0xK|1mQh8qEDG^tUqaGC#;F`ep+F3}qQX_e%b+JA}Z zTH~vWwX4JO>V1*ai*YXH#1aIhyz3;b-thFrQbHa+gwqqUT}LnPb7M-uBMP{A~yK=H%U&e53CRQ{1*UR`b&A z+}rWEERD4YpB@?7Ujq2NhombzpWNO-p6r{u_ub*GpNAjQTt!Bilm4y}@-z4Q-qOOJ zJ<;OfK_Md^{oNg%C_i^9quo{)yBSYCGIZ1RUiXfrpEW*c*X7C&H$VN(Xk+{}uB#`u zg?#RZXGhScmcpKU=;AQeku%)(_?-<#@Z!hbeK`}q1RWO-T&N#7xX{{kXC!(<8xS{* zMUQXppIKOJymILIIY-6i4OaN5`&Kma=)7|D!bI2H{ob9|vkq+{#^wSuolwi4n#Q)j z5Z_Oc?w3a>`|*;qAG}_g+t!qx(>}HRH2u+aZ$3+p=X^7@WnZj-5G$nq6PDeS}Z#&%j58p8J AD*ylh diff --git a/client/client/src/assets/transfer.png b/client/client/src/assets/transfer.png deleted file mode 100644 index 31f7fd3adf22f2ae4e1162d1e438be7c5d9c5292..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 607 zcmV-l0-*hgP)VN9{w9DwJzd%Gm5%l6k(Srw1f=C@i5k%a|<)Grew%RTzD&|xaqcXf< z9*@@$bXSuRnUR_GMnrG_gFk+>+ij)QYU#~plQkL*gL7`wYBg4^R`qhZto$k<$f_Xo z<#I{K-n-q7Ow**(=_LO_v`{FR`Fvje zCh%1@e~?F`5v|v2G7LjvFc=W3dWbN_cqWrko&v(J{s`D?He|Qk1!*YBtJR9ERvYzt zJ(|zwGN#k%P%@d+p8}#;49X}KB%94HV55G&Pm9Gu2v{Y$-LC8hs*A_t>?u&M*9|ml zyWL6wWCWZ}Ck=-~vRJGF7W(*b$n)iLp-3cRJO#v!q9QpfKQN-6~U9qk7R5;6} zlgp~&KoEw{L*wq6jM9+RMU)_iNO6K~b@$|K=nj zb2!5=4Mjq_zrU*f>U2#vSVnMZ9ja4cY`AdOM*t}k^goWqfa3Iq(>2kSH;P81hAqIyBm_{t1>+!KRdtb~{1AK7>C~ zD-Nov`UX!X6ET_La7f{B_|*cRuZGR%^C`gjd@jmW6h*+;8;{2{8ja|Fzf-YTq+l@k zGLg?!DijI~9$+CG0 - - - - - - - - diff --git a/client/client/src/com/flashphoner/phone/views/CallView.mxml b/client/client/src/com/flashphoner/phone/views/CallView.mxml deleted file mode 100644 index 9c2c623d..00000000 --- a/client/client/src/com/flashphoner/phone/views/CallView.mxml +++ /dev/null @@ -1,71 +0,0 @@ - - - - - - - - - - - - - diff --git a/client/client/src/com/flashphoner/phone/views/ConnectingView.mxml b/client/client/src/com/flashphoner/phone/views/ConnectingView.mxml deleted file mode 100644 index aa611d83..00000000 --- a/client/client/src/com/flashphoner/phone/views/ConnectingView.mxml +++ /dev/null @@ -1,25 +0,0 @@ - - - - - - - - diff --git a/client/client/src/com/flashphoner/phone/views/DragPanel.as b/client/client/src/com/flashphoner/phone/views/DragPanel.as deleted file mode 100644 index a1dc308e..00000000 --- a/client/client/src/com/flashphoner/phone/views/DragPanel.as +++ /dev/null @@ -1,47 +0,0 @@ -/* -Copyright (c) 2011 Flashphoner -All rights reserved. This Code and the accompanying materials -are made available under the terms of the GNU Public License v2.0 -which accompanies this distribution, and is available at -http://www.gnu.org/licenses/old-licenses/gpl-2.0.html - -Contributors: - Flashphoner - initial API and implementation - -This code and accompanying materials also available under LGPL and MPL license for Flashphoner buyers. Other license versions by negatiation. Write us support@flashphoner.com with any questions. -*/ -package com.flashphoner.phone.views -{ - import flash.events.Event; - import flash.events.MouseEvent; - - import mx.containers.Panel; - import mx.controls.LinkButton; - - public class DragPanel extends Panel{ - - public function DragPanel(){ - super(); - } - - override protected function createChildren():void{ - super.createChildren(); - this.addEventListener(MouseEvent.MOUSE_DOWN,handleDown); - this.addEventListener(MouseEvent.MOUSE_UP,handleUp); - } - override protected function updateDisplayList(unscaledWidth:Number, unscaledHeight:Number):void{ - super.updateDisplayList(unscaledWidth,unscaledHeight); - } - - private function handleDown(e:Event):void{ - this.startDrag(); - } - private function handleUp(e:Event):void{ - this.stopDrag(); - } - - private function closeMe(e:MouseEvent):void{ - this.visible = false; - } - } -} diff --git a/client/client/src/com/flashphoner/phone/views/IncomingView.mxml b/client/client/src/com/flashphoner/phone/views/IncomingView.mxml deleted file mode 100644 index 030ea0e3..00000000 --- a/client/client/src/com/flashphoner/phone/views/IncomingView.mxml +++ /dev/null @@ -1,99 +0,0 @@ - - - - - - - - - - - - diff --git a/client/client/src/com/flashphoner/phone/views/InfoView.mxml b/client/client/src/com/flashphoner/phone/views/InfoView.mxml deleted file mode 100644 index 80152fda..00000000 --- a/client/client/src/com/flashphoner/phone/views/InfoView.mxml +++ /dev/null @@ -1,31 +0,0 @@ - - - - - - - - - - diff --git a/client/client/src/com/flashphoner/phone/views/InstantMessageChatView.mxml b/client/client/src/com/flashphoner/phone/views/InstantMessageChatView.mxml deleted file mode 100644 index 3317b20e..00000000 --- a/client/client/src/com/flashphoner/phone/views/InstantMessageChatView.mxml +++ /dev/null @@ -1,78 +0,0 @@ - - - - - - - - - - - - diff --git a/client/client/src/com/flashphoner/phone/views/MainView.mxml b/client/client/src/com/flashphoner/phone/views/MainView.mxml deleted file mode 100644 index a23cb296..00000000 --- a/client/client/src/com/flashphoner/phone/views/MainView.mxml +++ /dev/null @@ -1,88 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/client/client/src/com/flashphoner/phone/views/MicrophoneSettingsView.mxml b/client/client/src/com/flashphoner/phone/views/MicrophoneSettingsView.mxml deleted file mode 100644 index 8b918d2f..00000000 --- a/client/client/src/com/flashphoner/phone/views/MicrophoneSettingsView.mxml +++ /dev/null @@ -1,98 +0,0 @@ - - - - - - - - - - - - diff --git a/client/client/src/com/flashphoner/phone/views/PhoneButton.mxml b/client/client/src/com/flashphoner/phone/views/PhoneButton.mxml deleted file mode 100644 index 0608b657..00000000 --- a/client/client/src/com/flashphoner/phone/views/PhoneButton.mxml +++ /dev/null @@ -1,138 +0,0 @@ - - - - - - - - diff --git a/client/client/src/com/flashphoner/phone/views/SipAccountView.mxml b/client/client/src/com/flashphoner/phone/views/SipAccountView.mxml deleted file mode 100644 index a9751f84..00000000 --- a/client/client/src/com/flashphoner/phone/views/SipAccountView.mxml +++ /dev/null @@ -1,105 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/client/client/src/com/flashphoner/phone/views/TabChatView.mxml b/client/client/src/com/flashphoner/phone/views/TabChatView.mxml deleted file mode 100644 index 46c6f9cd..00000000 --- a/client/client/src/com/flashphoner/phone/views/TabChatView.mxml +++ /dev/null @@ -1,112 +0,0 @@ - - - - - - 0){ - numChild --; - tn.removeChildAt(numChild); - } - } - - public function close():void{ - PopUpManager.removePopUp(this); - } - - private function sendInstantMessage():void{ - (InstantMessageChatView(tn.selectedChild)).sendInstantMessage(); - } - - public function pushMessage(messageObject:Object){ - var userNameFrom:String = messageObject["from"].toLowerCase(); - var userNameTo:String = messageObject["to"].toLowerCase(); - var imcv:InstantMessageChatView; - if (tabsMap.containsKey(userNameTo)){ - imcv = tabsMap.getValue(userNameTo); - } else if (tabsMap.containsKey(userNameFrom)){ - imcv = tabsMap.getValue(userNameFrom); - }else{ - imcv = addTab(userNameFrom); - } - imcv.pushMessage(messageObject); - - tn.selectedChild = imcv; - } - ]]> - - - - - - - - diff --git a/client/client/src/com/flashphoner/phone/views/TransferView.mxml b/client/client/src/com/flashphoner/phone/views/TransferView.mxml deleted file mode 100644 index cdd6ed82..00000000 --- a/client/client/src/com/flashphoner/phone/views/TransferView.mxml +++ /dev/null @@ -1,52 +0,0 @@ - - - - - - - - - - - - diff --git a/client/client/src/com/flashphoner/phone/views/VideoView.mxml b/client/client/src/com/flashphoner/phone/views/VideoView.mxml deleted file mode 100644 index 20c09acb..00000000 --- a/client/client/src/com/flashphoner/phone/views/VideoView.mxml +++ /dev/null @@ -1,76 +0,0 @@ - - - - - - - - - - - diff --git a/client/client/src/com/flashphoner/util/HashMap.as b/client/client/src/com/flashphoner/util/HashMap.as deleted file mode 100644 index 96f24d63..00000000 --- a/client/client/src/com/flashphoner/util/HashMap.as +++ /dev/null @@ -1,158 +0,0 @@ -/* -Copyright (c) 2011 Flashphoner -All rights reserved. This Code and the accompanying materials -are made available under the terms of the GNU Public License v2.0 -which accompanies this distribution, and is available at -http://www.gnu.org/licenses/old-licenses/gpl-2.0.html - -Contributors: - Flashphoner - initial API and implementation - -This code and accompanying materials also available under LGPL and MPL license for Flashphoner buyers. Other license versions by negatiation. Write us support@flashphoner.com with any questions. -*/ -package com.flashphoner.util -{ - import flash.utils.Dictionary; - - public class HashMap implements IMap - { - protected var map:Dictionary = null; - - public function HashMap(useWeakReferences:Boolean = true) - { - map = new Dictionary( useWeakReferences ); - } - - public function put(key:*, value:*) : void - { - map[key] = value; - } - - public function putAll(table:Dictionary) : void - { - for ( var prop:* in table ) - { - put( prop, table[prop] ); - } - } - - public function remove(key:*) : void - { - map[ key ] = undefined; - delete map[ key ]; - } - - public function containsKey(key:*) : Boolean - { - return map.hasOwnProperty( key ); - } - - public function containsValue(value:*) : Boolean - { - for ( var key:* in map ) - { - if ( map[ key ] == value ) - { - return true; - } - } - return false; - } - - public function getKey(value:*) : * - { - var identifier:* = undefined; - - for ( var key:* in map ) - { - if ( map[ key ] == value ) - { - identifier = key; - break; - } - } - return identifier; - } - - public function getKeys() : Array - { - var keys:Array = []; - - for ( var key:* in map ) - { - keys.push( key ); - } - return keys; - } - - public function getValue(key:*) : * - { - return map[key]; - } - - public function getValues() : Array - { - var values:Array = []; - - for (var key:* in map) - { - values.push( map[key] ); - } - return values; - } - - public function size() : int - { - var length:int = 0; - - for ( var key:* in map ) - { - length++; - } - return length; - } - - public function isEmpty() : Boolean - { - return size() <= 0; - } - - public function reset() : void - { - for ( var key:* in map ) - { - map[ key ] = undefined; - } - } - - public function resetAllExcept(keyId:*) : void - { - for ( var key:* in map ) - { - if ( key != keyId ) - { - map[ key ] = undefined; - } - } - } - - public function clear() : void - { - for ( var key:* in map ) - { - remove( key ); - } - } - - public function clearAllExcept(keyId:*) : void - { - for ( var key:* in map ) - { - if ( key != keyId ) - { - remove( key ); - } - } - } - } -} diff --git a/client/client/src/com/flashphoner/util/IMap.as b/client/client/src/com/flashphoner/util/IMap.as deleted file mode 100644 index dd9b6b27..00000000 --- a/client/client/src/com/flashphoner/util/IMap.as +++ /dev/null @@ -1,49 +0,0 @@ -/* -Copyright (c) 2011 Flashphoner -All rights reserved. This Code and the accompanying materials -are made available under the terms of the GNU Public License v2.0 -which accompanies this distribution, and is available at -http://www.gnu.org/licenses/old-licenses/gpl-2.0.html - -Contributors: - Flashphoner - initial API and implementation - -This code and accompanying materials also available under LGPL and MPL license for Flashphoner buyers. Other license versions by negatiation. Write us support@flashphoner.com with any questions. -*/ -package com.flashphoner.util -{ - import flash.utils.Dictionary; - - public interface IMap - { - function put(key:*, value:*) : void; - - function putAll(table:Dictionary) : void; - - function remove(key:*) : void; - - function containsKey(key:*) : Boolean; - - function containsValue(value:*) : Boolean; - - function getKey(value:*) : *; - - function getValue(key:*) : *; - - function getKeys() : Array; - - function getValues() : Array; - - function size() : int; - - function isEmpty() : Boolean; - - function reset() : void; - - function resetAllExcept(key:*) : void; - - function clear() : void; - - function clearAllExcept(key:*) : void; - } -} diff --git a/client/client/src/flashphoner.xml b/client/client/src/flashphoner.xml deleted file mode 100644 index 5aa46aae..00000000 --- a/client/client/src/flashphoner.xml +++ /dev/null @@ -1,32 +0,0 @@ - - - - 87.226.225.59 - 8080 - 8443 - false - 1935 - true - true - - phone_app - 176 - 144 - true - true - - - - - diff --git a/client/client/src/flashphoner_js_api.mxml b/client/client/src/flashphoner_js_api.mxml deleted file mode 100644 index d77252b3..00000000 --- a/client/client/src/flashphoner_js_api.mxml +++ /dev/null @@ -1,122 +0,0 @@ - - - - - - - - - - - - diff --git a/client/client/src/js/Click2Call.js b/client/client/src/js/Click2Call.js deleted file mode 100644 index d5047103..00000000 --- a/client/client/src/js/Click2Call.js +++ /dev/null @@ -1,718 +0,0 @@ -/* - Copyright (c) 2011 Flashphoner - All rights reserved. This Code and the accompanying materials - are made available under the terms of the GNU Public License v2.0 - which accompanies this distribution, and is available at - http://www.gnu.org/licenses/old-licenses/gpl-2.0.html - - Contributors: - Flashphoner - initial API and implementation - - This code and accompanying materials also available under LGPL and MPL license for Flashphoner buyers. - Other license versions by negatiation. Write us support@flashphoner.com with any questions. - */ -var flashphoner; -var flashphoner_UI; -var flashphonerLoader; -var flashphonerListener; - -// One call become two calls during TRANSFER case -// there is why we need at least two kinds of calls here -var currentCall = null; -var callee = ''; -var callerLogin = ''; -var registerRequired; -var isLogged = false; - -var micVolume = 100; -var speakerVolume = 100; -var traceEnabled = true; -var intervalId = -1; -var proportion = 0; -var proportionStreamer = 0; -var callToken = "testcalltoken"; - -var timerHours = 0; -var timerMinutes = 0; -var timerSeconds = 0; -var timerTimeout; - -var testInviteParameter = new Object; -testInviteParameter['param1'] = "value1"; -testInviteParameter['param2'] = "value2"; - -var logs=""; - -function timer() { - - if (timerHours < 10) { - mTimerHours = "0" + timerHours - } else { - mTimerHours = timerHours - } - if (timerMinutes < 10) { - mTimerMinutes = "0" + timerMinutes - } else { - mTimerMinutes = timerMinutes - } - if (timerSeconds < 10) { - mTimerSeconds = "0" + timerSeconds - } else { - mTimerSeconds = timerSeconds - } - - $("#timer").html(mTimerHours + ":" + mTimerMinutes + ":" + mTimerSeconds); - - timerSeconds = timerSeconds + 1; - - if (timerSeconds == 60) { - timerMinutes = timerMinutes + 1; - timerSeconds = 0; - } - - if (timerMinutes == 60) { - timerHours = timerHours + 1; - timerMinutes = 0; - } - - timerTimeout = setTimeout("timer()", 1000); -} - -$(document).ready(function () { - changeCallStateInfo("...Loading..."); - flashphonerLoader = new FlashphonerLoader(); -}); - - -function loginByToken(token) { - trace("Click2Call - loginByToken url: "+ document.URL+" token: "+ token); - changeCallStateInfo("...Registering..."); - - var pageUrl = document.URL; - var result = flashphoner.loginByToken(flashphonerLoader.urlServer, token, pageUrl); -} - -function getInfoAboutMe() { - trace("Click2Call - getInfoAboutMe"); - return flashphoner.getInfoAboutMe(); -} - -function logoff() { - trace("Click2Call - logoff"); - flashphoner.logoff(); -} - -function callByToken(token) { - trace("Click2Call - callByToken "+ token); - if (isLogged) { - if (!hasAccessToAudio()) { - intervalId = setInterval('if (hasAccessToAudio()){flashphoner_UI.closeRequestUnmuteC2C(); clearInterval(intervalId);callByToken(callToken);}', 500); - flashphoner_UI.requestUnmuteC2C(); - } else if (hasAccessToAudio()) { - var callRequest = {}; - callRequest.token = token; - callRequest.inviteParameters = testInviteParameter; - callRequest.isMsrp = false; - callRequest.hasVideo = false; - var result = flashphoner.callByToken(callRequest); - if (result == 0) { - changeCallStateInfo("...Calling..."); - toHangupState(); - flashphonerListener.onCall(); - } - } else { - openInfoView("Microphone is not plugged in", 3000); - } - } else { - if (flashphonerLoader.getToken()) { - loginByToken(flashphonerLoader.getToken()); - } else { - console.log("Please, specify token in flashphoner.xml!"); - } - } -} - -function hangup(callId) { - trace("Click2Call - hangup "+ callId); - flashphoner.hangup(callId); - flashphonerListener.onHangup(); -} - -function sendDTMF(callId, dtmf) { - trace("Click2Call - sendDTMF callId: "+ callId+" dtmf: "+ dtmf); - flashphoner.sendDTMF(callId, dtmf); -} - -// TODO change img to background -function sendVideoChangeState() { - trace("Click2Call - sendVideoChangeState"); - var sendVideoButton = $('.sendVideoButton'); - var sendVideoButtonImage = $('#sendVideoButtonImage'); - - if (sendVideoButton.hasClass('on')) { - sendVideoButton.toggleClass('on'); - sendVideoButtonImage.attr('src', 'assets/c2c_play.png') - flashphoner.setSendVideo(false); - } else { - sendVideoButton.toggleClass('on'); - sendVideoButtonImage.attr('src', 'assets/c2c_pause.png') - flashphoner.setSendVideo(true); - } -} - -function initSendVideoButton() { - var sendVideoButton = $('.sendVideoButton'); - var sendVideoButtonImage = $('#sendVideoButtonImage'); - if (sendVideoButton.hasClass('on')) { - sendVideoButton.toggleClass('on'); - sendVideoButtonImage.attr('src', 'assets/c2c_play.png'); - flashphoner.setSendVideo(false); - } -} - -function changeRelationMyVideo(relation) { - trace("Click2Call - changeRelationMyVideo "+ relation); - flashphoner.changeRelationMyVideo(relation); -} - -function getMicVolume() { - var ret = flashphoner.getMicVolume(); - trace("Click2Call - getMicVolume "+ret); - return ret; -} -function getVolume() { - var ret = flashphoner.getVolume(); - trace("Click2Call - getVolume "+ret); - return ret; -} - -function getVersion() { - var ret = flashphoner.getVersion(); - trace("Click2Call - getVersion "+ret); - return ret; -} - -function hasAccessToAudioAndVideo() { - return hasAccessToAudio() && hasAccessToVideo(); -} - -function hasAccessToAudio() { - return flashphoner.hasAccessToAudio(); -} - -function hasAccessToVideo() { - return flashphoner.hasAccessToVideo(); -} -/* ------------------ Notify functions ----------------- */ - -function addLogMessage(message) { - trace('Click2Call - addLogMessage '+ message); -} - -function notifyConfigLoaded() { - trace("Click2Call - notifyConfigLoaded"); - flashphoner = flashphonerLoader.getFlashphoner(); - flashphoner_UI = flashphonerLoader.getFlashphonerUI(); - flashphonerListener = flashphonerLoader.getFlashphonerListener(); - if (flashphonerLoader.useWebRTC) { - $('#cameraButton').css('visibility', 'hidden'); - $('#micButton').css('visibility', 'hidden'); - } else { - $("#micSlider").slider("option", "value", getMicVolume()); - } - - if (flashphonerLoader.getToken()) { - loginByToken(flashphonerLoader.getToken()); - } else { - console.log("Please, specify token in flashphoner.xml!"); - } - $("#speakerSlider").slider("option", "value", getVolume()); -} - -function notifyRegisterRequired(registerR) { - registerRequired = registerR; -} - -function notifyCloseConnection() { - trace("Click2Call - notifyCloseConnection"); - currentCall = null; - toCallState(); - isLogged = false; - closeVideoView(); - initSendVideoButton(); - changeCallStateInfo("Finished"); -} - -function notifyConnected() { - trace("Click2Call - notifyConnected"); - if (!registerRequired) { - isLogged = true; - callByToken(callToken); - } -} - -function notifyRegistered() { - trace("Click2Call - notifyRegistered"); - if (registerRequired) { - changeCallStateInfo("Registered"); - isLogged = true; - flashphonerListener.onRegistered(); - callByToken(callToken); - } -} - -function notifyBalance(balance) { -} - -// This functions invoked every time when call state changed -function notify(call) { - trace('Click2Call - notify call_id: '+ call.id +' call.anotherSideUser: '+ call.anotherSideUser); - if (call.incoming) { - //do nothing because we already hangup this call in notifyAddCall() - return; - } - if (currentCall.id == call.id) { - currentCall = call; - if (currentCall.visibleNameCallee != null) { - if (currentCall.visibleNameCallee.length > 11) { - $('#caller').css('font-size', 20); - $('#caller').css('top', 95); - } - $('#caller').html(currentCall.visibleNameCallee.replace(/^<|>$/g, "")); - } else { - $('#caller').html(currentCall.callee); - } - // if we finish the call - if (call.state == STATE_FINISH) { - proportion = 0; - closeVideoView(); - initSendVideoButton(); - changeCallStateInfo("Finished"); - toCallState(); - flashphoner.stopSound("RING"); - flashphoner.playSound("FINISH"); - - timerMinutes = 0; - timerHours = 0; - timerSeconds = 0; - $("#timer").hide(); - clearTimeout(timerTimeout); - // if call is holded - } else if (call.state == STATE_HOLD) { - changeCallStateInfo("...Holded..."); - // or if call is started talk - } else if (call.state == STATE_TALK) { - changeCallStateInfo("...Talking..."); - flashphoner.stopSound("RING"); - timer(); - $("#timer").show(); - // or if we just ringing - } else if (call.state == STATE_RING) { - changeCallStateInfo("...Ringing..."); - flashphoner.playSound("RING"); - } else if (call.state == STATE_BUSY) { - flashphoner.playSound("BUSY"); - changeCallStateInfo("Busy"); - } - } -} - -function notifyCallbackHold(call, isHold) { -} - -function notifyCost(cost) { -} - -function notifyBugReport(filename) { - trace("Created bug report; filename - " + filename); -} - -function notifyError(error) { - - trace("Click2Call - notifyError "+ error); - - if (error == CONNECTION_ERROR || error == TOO_MANY_REGISTER_ATTEMPTS || - error == LICENSE_RESTRICTION || error == LICENSE_NOT_FOUND || - error == REGISTER_EXPIRE || error == MEDIA_PORTS_BUSY) { - openInfoView("Connection error, try later", 3000); - } else if (error == AUTHENTICATION_FAIL || error == SIP_PORTS_BUSY || - error == WRONG_SIPPROVIDER_ADDRESS) { - openInfoView("Connection error, try later", 3000); - window.setTimeout("logoff();", 3000); - } else if (error == USER_NOT_AVAILABLE) { - openInfoView("Support is offline", 3000); - } else if (error == INTERNAL_SIP_ERROR) { - openInfoView("Unknown error", 3000); - } - toCallState(); - flashphonerListener.onError(); -} - -function notifyVideoFormat(call) { - trace("Click2Call - notifyVideoFormat "+ call.id); - - // proportionStreamer allow us change proportion of small video window (myself preview video) - if (call.streamerVideoWidth != 0) { - proportionStreamer = call.streamerVideoHeight / call.streamerVideoWidth; - if (proportionStreamer != 0) { - /** Here we change size of small myself preview video window in the swf from the js code. - * To be precise we cnahge only height, width is fixed and equal to 20% of big video. - */ - changeRelationMyVideo(proportionStreamer); - } - } - - if (!call.playerVideoHeight == 0) { //that mean other side really send us video - proportion = call.playerVideoHeight / call.playerVideoWidth; //set proportion of video picture, else it will be = 0 - var newHeight = 320 * proportion; - $('.video').height(newHeight); - $('#video').height(newHeight).width(320); - //$('#c2c').height(newHeight+40); - } -} - -function notifyOpenVideoView(isViewed) { - trace("Click2Call - notifyOpenVideoView: isViewed: " + isViewed); - if (isViewed) { - openVideoView('big'); - } else { - closeVideoView(); - } -} - -function notifyMessage(messageObject) { - trace('Click2Call - notifyMessage from: '+ messageObject.from+' body: '+ messageObject.body); -} - -function notifyAddCall(call) { - trace("Click2Call - notifyAddCall call.id: "+ call.id +" call.anotherSideUser: "+ call.anotherSideUser); - if (call.incoming == true) { - hangup(call.id); - } else { - currentCall = call; - $('#caller').html(currentCall.anotherSideUser); - } -} - -function notifyRemoveCall(call) { - trace("Click2Call - notifyRemoveCall "+ call.id); - if (currentCall != null && currentCall.id == call.id) { - currentCall = null; - flashphonerListener.onRemoveCall(); - } -} - -function notifyVersion(version) { - getElement('versionOfProduct').innerHTML = version; -} -/* ----------------------------------------------------------------------- */ - -function openInfoView(str, timeout) { - if (timeout != 0) { - window.setTimeout("closeInfoView();", timeout); - } - getElement('infoDiv').style.visibility = "visible"; - getElement('infoDiv').innerHTML = str; -} - -function changeCallStateInfo(str) { - $('#callState').html(str); -} - -function closeInfoView(timeout) { - trace("Click2Call - closeInfoView "+timeout); - if (timeout != 0) { - window.setTimeout("getElement('infoDiv').style.visibility = 'hidden';", timeout); - } else { - getElement('infoDiv').style.visibility = "hidden"; - } -} - -function openSettingsView() { - trace("Click2Call - openSettingsView"); - getElement('settingsDiv').style.visibility = "visible"; -} -function closeSettingsView() { - trace("Click2Call - closeSettingsView"); - getElement('settingsDiv').style.visibility = "hidden"; -} - -function getElement(str) { - return document.getElementById(str); -} - -function toHangupState() { - trace("Click2Call - toHangupState"); - $('#callButton').html('Hangup').addClass('hangup').removeClass('call'); - disableCallButton(); -} - -function toCallState() { - trace("Click2Call - toCallState"); - $('#callButton').html('Call').addClass('call').removeClass('hangup'); - disableCallButton(); -} - -function disableCallButton() { - trace("Click2Call - disableCallButton"); - var button = $('#callButton'); - - $('#callButton').addClass('disabled'); - window.setTimeout(enableCallButton, 3000); - - function enableCallButton() { - $('#callButton').removeClass('disabled'); - } -} - -/* ----- VIDEO ----- */ - -function openVideoView(size) { - trace("Click2Call - openVideoView "+ size); - flashphoner_UI.openVideoView(); - $('#cameraButton').addClass('pressed'); - // if we already give access to devices when trying to open video view - if (hasAccessToVideo()) { - - // show send my video button - $('.sendVideoButton').show(); - - // if we need show only myself video (when other side dont send us video) - // or if we need show both videos - ourselves and partner`s - if ((size == 'big') && (proportion != 0)) { // sometimes voip servers send video with null sizes. Here we defend from such cases - $('#flash').removeClass('init').addClass('video'); - var newHeight = 320 * proportion; - $('.video').height(newHeight); - $('#video').height(newHeight).width(320); - $('#c2c').height(newHeight + 40); - } else if (size == 'small') { - $('#flash').removeClass('init').addClass('video'); - $('#video').height(240).width(320); - } else { - $('#flash').removeClass('init').addClass('video'); - $('#video').height(240).width(320); - - } - - // or if we did not access the devices yet - } else { - flashphoner_UI.requestUnmuteC2C(); - intervalId = setInterval('if (hasAccessToVideo()){flashphoner_UI.closeRequestUnmuteC2C(); clearInterval(intervalId); openVideoView("small");}', 500); - } -} - -function closeVideoView() { - trace("Click2Call - closeVideoView"); - // turn flash div back to init size - $('#flash').removeClass().removeAttr('style').addClass('init'); - // turn c2c div back to init size - $('#c2c').height(240); - // hide send video button - $('.sendVideoButton').hide(); - // unpressed camerabutton - $('#cameraButton').removeClass('pressed'); -} - -// functions closeView is simplifying of many close....View functions -function close(element) { - element.css('visibility', 'hidden'); -} - -/* TODO make good auto trace - function getFnName(fn) { - return fn.toString().match(/function ([^(]*)\(/)[1]; - } - */ - - -/* --------------------- On document load we do... ------------------ */ -$(function () { - - // load c2c interface in frame c2c-test for showing in popup - // $('#c2c-test').load('Click2callJS.html', alert('done')); - - // All buttons except .call and .hangup stay in press state until double click - $(".button:not(.dialButton, .call, .hangup, .disabled)").click(function () { - $(this).toggleClass('pressed'); - }); - - // All dial buttons and call/hangup go unpressed after mouseup. Except if it disabled mode. - $('.dialButton, .call, .hangup').mousedown(function () { - if (!$(this).hasClass('disabled')) { - $(this).addClass('pressed'); - } - }).mouseup(function () { - $(this).removeClass('pressed'); - }).mouseover(function () { - $(this).removeClass('pressed'); - }); - - // dialpad button opens dialpad - $("#dialpadButton").click(function () { - if ($(this).hasClass('pressed')) { - $('#dialPad').show(); - } else { - $('#dialPad').hide(); - } - }); - - // dialButtons sends DTMF signals - $(".dialButton").click(function () { - if (currentCall != null && currentCall.state == STATE_TALK) { - sendDTMF(currentCall.id, $(this).html()); - var dialScreenText = $('.dialScreen').html(); - if (dialScreenText.length > 10) { - $('.dialScreen').html(dialScreenText.substr(1) + $(this).html()); - } else { - $('.dialScreen').append($(this).html()); - } - } - }); - - // mic button opens mic slider - $("#micButton").click(function () { - if ($(this).hasClass('pressed')) { - $('#micSlider').show(); - $('#micBack').show(); - } else { - $('#micSlider').hide(); - $('#micBack').hide(); - } - }); - - // sound button opens sound slider - $("#soundButton").click(function () { - if ($(this).hasClass('pressed')) { - $('#speakerSlider').show(); - $('#speakerBack').show(); - } else { - $('#speakerSlider').hide(); - $('#speakerBack').hide(); - } - }); - - // call button makes call or hangup - $("#callButton:not(.disabled)").click(function () { - if (!$(this).hasClass('disabled')) { - if ($(this).html() == 'Call') { - callByToken(callToken); - } else { - hangup(currentCall.id); - } - } - }); - - - // call me button opens new window with click2call - $("#callMeButton1:not(.disabled)").click(function () { - window.open('click2call-test-1.html', '_blank', 'width=340,height=260,resizable=no,toolbar=no,menubar=no,location=no,status=no,scrollbar=no') - }); - - $("#callMeButton2:not(.disabled)").click(function () { - window.open('click2call-test-2.html', '_blank', 'width=340,height=260,resizable=no,toolbar=no,menubar=no,location=no,status=no,scrollbar=no') - }); - - $("#callMeButton3:not(.disabled)").click(function () { - window.open('click2call-test-3.html', '_blank', 'width=340,height=260,resizable=no,toolbar=no,menubar=no,location=no,status=no,scrollbar=no') - }); - - // Mic slider set mic volume when you slide it - $("#micSlider").slider({ - orientation: "vertical", - range: "min", - min: 0, - max: 100, - value: 60, - slide: function (event, ui) { - flashphoner.setMicVolume(ui.value); - } - }); - - // Speaker slider set speaker volume when you slide it - $("#speakerSlider").slider({ - orientation: "vertical", - range: "min", - min: 0, - max: 100, - value: 60, - slide: function (event, ui) { - flashphoner.setVolume(ui.value); - } - }); - - // Camera button opens video window. - // Depends on situation it can be both video or just my video - $("#cameraButton").click(function () { - if ($(this).hasClass('pressed')) { - $('.sendVideoButton').show(); - if (proportion != 0) { - openVideoView('big'); - } else { - openVideoView('small'); - } - } else { - $('.sendVideoButton').hide(); - closeVideoView(); - } - }); - - // bind effects to click on send video button - // and toggle video on/off by clicking - $('.sendVideoButton').mousedown(function () { - $(this).addClass('sendVideoButtonPressed'); - }).mouseup(function () { - $(this).removeClass('sendVideoButtonPressed'); - }).mouseover(function () { - $(this).removeClass('sendVideoButtonPressed'); - }).click(function () { - sendVideoChangeState(); - }); - - // Settings button button opens settings view - $("#settingsButton").click(function () { - if ($(this).hasClass('pressed')) { - - $("#settingsView").show(); - - var micList = flashphoner.getMicropones(); - var camList = flashphoner.getCameras(); - - //clear it each time, else we append it more and more... - $("#micSelector").html(""); - $("#camSelector").html(""); - - for (var i = 0; i < micList.length; i++) { - $("#micSelector").append(''); - } - - // we use here index instead of name because AS getcamera can only use indexes - for (var i = 0; i < camList.length; i++) { - $("#camSelector").append(''); - } - - } else { - $("#settingsView").hide(); - } - }); - - - $("#micSelector").change(function () { - flashphoner.setMicrophone($(this).val()); - trace('Click2Call - Microphone was changed to '+ $(this).val()); - }); - - $("#camSelector").change(function () { - flashphoner.setCamera($(this).val()); - trace('Click2Call - Camera was changed to '+ $(this).val()); - }); - - $("#settingsOkButton").click(function () { - $("#settingsView").hide(); - $("#settingsButton").removeClass("pressed"); - }); - -}); - - - - \ No newline at end of file diff --git a/client/client/src/js/FlashphonerLoader.js b/client/client/src/js/FlashphonerLoader.js deleted file mode 100644 index 8e09ffa6..00000000 --- a/client/client/src/js/FlashphonerLoader.js +++ /dev/null @@ -1,370 +0,0 @@ -/* - Copyright (c) 2011 Flashphoner - All rights reserved. This Code and the accompanying materials - are made available under the terms of the GNU Public License v2.0 - which accompanies this distribution, and is available at - http://www.gnu.org/licenses/old-licenses/gpl-2.0.html - - Contributors: - Flashphoner - initial API and implementation - - This code and accompanying materials also available under LGPL and MPL license for Flashphoner buyers. Other license versions by negatiation. Write us support@flashphoner.com with any questions. - */ -FlashphonerLoader = function (config) { - this.flashphoner = null; - this.flashphoner_UI = null; - this.flashphonerListener = new DefaultListener(); - this.useWebRTC = false; - this.urlServer = null; - this.wcsIP = null; - this.wsPort = "8080"; - this.flashPort = "1935"; - this.appName = "phone_app"; - this.loadBalancerUrl = null; - this.jsonpSuccess = false; - this.token = null; - this.registerRequired = true; - this.useDTLS = true; - this.videoWidth = 320; - this.videoHeight = 240; - this.pushLogEnabled = false; - this.ringSound = "sounds/CALL_OUT.ogg"; - this.busySound = "sounds/BUSY.ogg"; - this.registerSound = "sounds/REGISTER.ogg"; - this.finishSound = "sounds/HANGUP.ogg"; - this.xcapUrl = null; - this.msrpCallee = null; - this.subscribeEvent = null; - this.contactParams = null; - this.imdnEnabled = false; - this.msgContentType = "text/plain"; - this.stripCodecs = new Array(); - this.stunServer = ""; - this.disableLocalRing = false; - this.modeLT = false; - this.hangupLT = 0; - this.answerLT = 0; - this.callLT = 0; - - $.ajax({ - type: "GET", - url: "flashphoner.xml", - dataType: "xml", - success: this.parseFlashphonerXml, - context: this - }); -}; - -FlashphonerLoader.prototype = { - - parseFlashphonerXml: function (xml) { - var me = this; - var wcsIP = $(xml).find("wcs_server"); - if (wcsIP.length > 0) { - this.wcsIP = wcsIP[0].textContent; - } else { - openConnectingView("Can not find 'wcs_server' in flashphoner.xml", 0); - return; - } - var wsPort = $(xml).find("ws_port"); - if (wsPort.length > 0) { - this.wsPort = wsPort[0].textContent; - } - var wssPort = $(xml).find("wss_port"); - if (wssPort.length > 0) { - this.wssPort = wssPort[0].textContent; - } - var useWss= $(xml).find("use_wss"); - if (useWss.length > 0) { - this.useWss = "true" == useWss[0].textContent; - } - - var flashPort = $(xml).find("flash_port"); - if (flashPort.length > 0) { - this.flashPort = flashPort[0].textContent; - } - var appName = $(xml).find("application"); - if (appName.length > 0) { - this.appName = appName[0].textContent; - } - var loadBalancerUrl = $(xml).find("load_balancer_url"); - if (loadBalancerUrl.length > 0) { - this.loadBalancerUrl = loadBalancerUrl[0].textContent; - } - var token = $(xml).find("token"); - if (token.length > 0) { - this.token = token[0].textContent; - } - var registerRequired = $(xml).find("register_required"); - if (registerRequired.length > 0) { - this.registerRequired = (registerRequired[0].textContent === "true"); - } - - var useDTLS = $(xml).find("use_dtls"); - if (useDTLS.length > 0) { - this.useDTLS = (useDTLS[0].textContent === "true"); - } - - var videoWidth = $(xml).find("video_width"); - if (videoWidth.length > 0) { - this.videoWidth = videoWidth[0].textContent; - } - var videoHeight = $(xml).find("video_height"); - if (videoHeight.length > 0) { - this.videoHeight = videoHeight[0].textContent; - } - - var pushLogEnabled = $(xml).find("push_log"); - if (pushLogEnabled.length) { - this.pushLogEnabled = pushLogEnabled.text(); - } - - //Sounds for WebRTC implementation - var ringSound = $(xml).find("ring_sound"); - if (ringSound.length > 0) { - if (ringSound[0].textContent.length) { - this.ringSound = ringSound[0].textContent; - } - } - var busySound = $(xml).find("busy_sound"); - if (busySound.length > 0) { - if (busySound[0].textContent.length) { - this.busySound = busySound[0].textContent; - } - } - var registerSound = $(xml).find("register_sound"); - if (registerSound.length > 0) { - if (registerSound[0].textContent.length) { - this.registerSound = registerSound[0].textContent; - } - } - var finishSound = $(xml).find("finish_sound"); - if (finishSound.length > 0) { - if (finishSound[0].textContent.length) { - this.finishSound = finishSound[0].textContent; - } - } - - var xcapUrl = $(xml).find("xcap_url"); - if (xcapUrl.length > 0) { - if (xcapUrl[0].textContent.length) { - this.xcapUrl = xcapUrl[0].textContent; - } - } - - var msrpCallee = $(xml).find("msrp_callee"); - if (msrpCallee.length > 0) { - if (msrpCallee[0].textContent.length) { - this.msrpCallee = msrpCallee[0].textContent; - } - } - - var subscribeEvent = $(xml).find("subscribe_event"); - if (subscribeEvent.length > 0) { - if (subscribeEvent[0].textContent.length) { - this.subscribeEvent = subscribeEvent[0].textContent; - } - } - - var contactParams = $(xml).find("contact_params"); - if (contactParams.length > 0) { - if (contactParams[0].textContent.length) { - this.contactParams = contactParams[0].textContent; - } - } - - var imdnEnabled = $(xml).find("imdn_enabled"); - if (imdnEnabled.length > 0) { - if (imdnEnabled[0].textContent.length) { - this.imdnEnabled = Boolean(imdnEnabled[0].textContent); - } - } - - var disableLocalRing = $(xml).find("disable_local_ring"); - if (disableLocalRing.length > 0) { - if (disableLocalRing[0].textContent.length) { - this.disableLocalRing = Boolean(disableLocalRing[0].textContent); - } - } - console.log("disableLocalRing: "+this.disableLocalRing); - - //Message content type by default "text/plain", can be "message/cpim" - var msgContentType = $(xml).find("msg_content_type"); - if (msgContentType.length > 0) { - this.msgContentType = msgContentType.text(); - console.log("Message content type: " + this.msgContentType); - } - - var stripCodecs = $(xml).find("strip_codecs"); - if (stripCodecs.length > 0) { - var tempCodecs = stripCodecs[0].textContent.split(","); - for (i = 0; i < tempCodecs.length; i++) { - if (tempCodecs[i].length) this.stripCodecs[i] = tempCodecs[i]; - console.log("Codec " + tempCodecs[i] + " will be removed from SDP!"); - } - } - - //stun server address - var stunServer = $(xml).find("stun_server"); - if (stunServer.length > 0) { - this.stunServer = stunServer.text(); - console.log("Stun server: " + this.stunServer); - } - - //variable participating in api load, can bee null, webrtc, flash - var streamingType = $(xml).find("streaming"); - if (streamingType.length > 0) { - if (streamingType.text() == "webrtc") { - console.log("Force WebRTC usage!"); - isWebRTCAvailable = true; - } else if (streamingType.text() == "flash") { - console.log("Force Flash usage!"); - isWebRTCAvailable = false; - } else { - console.log("Bad streaming property " + streamingType.text() + - ", can be webrtc or flash. Using default behaviour!") - } - } - - //Load Tool mode on/off - var modeLT = $(xml).find("modeLT"); - if (modeLT.length > 0) { - if (modeLT[0].textContent.length) { - this.modeLT = Boolean(modeLT[0].textContent); - } - } - - //call duration in seconds when Load Tool is enabled, callee will hangup after this timeout. - // Hangup will not occur in case of 0 timeout. - var hangupLT = $(xml).find("hangupLT"); - if (hangupLT.length > 0) { - this.hangupLT = hangupLT[0].textContent; - } - - //Answer timeout when Load Tool is enabled, if greater than 0 callee answer the call after specified amount of seconds - var answerLT = $(xml).find("answerLT"); - if (answerLT.length > 0) { - this.answerLT = answerLT[0].textContent; - } - - //Recall timeout when Load Tool is enabled, specifies how long caller must wait after hangup to place another call. - var callLT = $(xml).find("callLT"); - if (callLT.length > 0) { - this.callLT = callLT[0].textContent; - } - - //get load balancer url if load balancing enabled - if (me.loadBalancerUrl != null) { - trace("FlashphonerLoader - Retrieve server url from load balancer"); - - /* - * this timeout is a workaround to catch errors from ajax request - * Unfortunately jQuery do not support error callback in case of JSONP - */ - setTimeout(function () { - //check status of ajax request - if (!me.jsonpSuccess) { - trace("FlashphonerLoader - Error occurred while retrieving load balancer data, please check your load balancer url " + - me.loadBalancerUrl); - me.loadAPI(); - } - }, 10000) - var loadBalancerData = null; - $.ajax({ - type: "GET", - url: me.loadBalancerUrl, - dataType: "jsonp", - data: loadBalancerData, - success: function (loadBalancerData) { - me.wcsIP = loadBalancerData.server; - me.wsPort = loadBalancerData.ws; - me.wssPort = loadBalancerData.wss; - me.flashPort = loadBalancerData.flash; - me.jsonpSuccess = true; - trace("FlashphonerLoader - Connection data from load balancer: " - + "wcsIP " + loadBalancerData.server - + ", wsPort " + loadBalancerData.ws - + ", wssPort " + loadBalancerData.wss - + ", flashPort " + loadBalancerData.flash); - me.loadAPI(); - } - }); - } else { - me.loadAPI(); - } - }, - - loadAPI: function () { - var me = this; - if (isWebRTCAvailable) { - me.useWebRTC = true; - var protocol = "ws://"; - var port = this.wsPort; - if (this.useWss){ - protocol = "wss://"; - port = this.wssPort; - } - me.urlServer = protocol + this.wcsIP + ":" + port; - me.flashphoner = new WebSocketManager(getElement('localVideoPreview'), getElement('remoteVideo')); - if (me.stripCodecs.length) me.flashphoner.setStripCodecs(me.stripCodecs); - if (me.stunServer != "") me.flashphoner.setStunServer(me.stunServer); - me.flashphoner_UI = new UIManagerWebRtc(); - if (me.modeLT) me.flashphonerListener = new LoadToolListener(); - notifyConfigLoaded(); - } else { - me.useWebRTC = false; - me.urlServer = "rtmfp://" + this.wcsIP + ":" + this.flashPort + "/" + this.appName; - var params = {}; - params.menu = "true"; - params.swliveconnect = "true"; - params.allowfullscreen = "true"; - params.allowscriptaccess = "always"; - //in case of Safari wmode should be "window" - if((navigator.userAgent.indexOf("Safari") > -1) && !(navigator.userAgent.indexOf("Chrome") > -1)) { - params.wmode = "window"; - //workaround for safari browser, FPNR-403 - swfobject.switchOffAutoHideShow(); - } else { - params.wmode = "transparent"; - } - var attributes = {}; - var flashvars = {}; - flashvars.config = "flashphoner.xml"; - - if (this.hasFlash()) { - swfobject.embedSWF("flashphoner_js_api.swf", "videoDiv", "100%", "100%", "11.2.202", "expressInstall.swf", flashvars, params, attributes, function (e) { - me.flashphoner = e.ref; - me.flashphoner_UI = new UIManagerFlash(); - if (me.modeLT) me.flashphonerListener = new LoadToolListener(); - }); - } else { - notifyFlashNotFound(); - } - - } - - }, - - hasFlash: function () { - return swfobject.hasFlashPlayerVersion("11.2"); - }, - - getFlashphoner: function () { - return this.flashphoner; - }, - - getFlashphonerUI: function () { - return this.flashphoner_UI; - }, - - getFlashphonerListener: function () { - return this.flashphonerListener; - }, - - getToken: function () { - return this.token; - } -}; - - - diff --git a/client/client/src/js/Phone.js b/client/client/src/js/Phone.js deleted file mode 100644 index 32371d45..00000000 --- a/client/client/src/js/Phone.js +++ /dev/null @@ -1,1315 +0,0 @@ -/* - Copyright (c) 2011 Flashphoner - All rights reserved. This Code and the accompanying materials - are made available under the terms of the GNU Public License v2.0 - which accompanies this distribution, and is available at - http://www.gnu.org/licenses/old-licenses/gpl-2.0.html - - Contributors: - Flashphoner - initial API and implementation - - This code and accompanying materials also available under LGPL and MPL license for Flashphoner buyers. Other license versions by negatiation. Write us support@flashphoner.com with any questions. - */ - -var flashphoner; -var flashphoner_UI; -var flashphonerLoader; -var flashphonerListener; - -// One call become two calls during TRANSFER case -// there is why we need at least two kinds of calls here -var holdedCall = null; -var currentCall = null; -// not sure if "callee" is reserved word so I will use callee /Pavel -var callee = ''; -var callerLogin = ''; -var registerRequired; -var isLogged = false; - -var needOpenTransferView = false; -var connectingViewBeClosed = false; -var traceEnabled = true; -var intervalId = -1; -var proportion = 0; - -var testInviteParameter = {}; -testInviteParameter['param1'] = "value1"; -testInviteParameter['param2'] = "value2"; - -var messenger; - -var logs=""; - -$(document).ready(function () { - toLogOffState(); - openConnectingView("Loading...", 0); - flashphonerLoader = new FlashphonerLoader(); -}); - - -function login() { - trace("Phone - login"); - connectingViewBeClosed = false; - - if ($("#outbound_proxy").val() == "") { - $("#outbound_proxy").val($("#domain").val()); - } - - var loginObject = {}; - loginObject.login = $('#username').val(); - loginObject.password = $('#password').val(); - loginObject.authenticationName = $('#authname').val(); - loginObject.domain = $('#domain').val(); - loginObject.outboundProxy = $('#outbound_proxy').val(); - loginObject.port = $('#port').val(); - loginObject.useProxy = $('#checkboxUseProxy').attr("checked") ? true : false; - loginObject.registerRequired = flashphonerLoader.registerRequired; - loginObject.useDTLS = flashphonerLoader.useDTLS; - if (flashphonerLoader.contactParams != null && flashphonerLoader.contactParams.length != 0) { - loginObject.contactParams = flashphonerLoader.contactParams; - } - - trace("Phone - loginObject login: "+loginObject.login+" authenticationName: "+loginObject.authenticationName+" registerRequired: "+registerRequired+" useDTLS: "+loginObject.useDTLS); - - var result = flashphoner.login(loginObject, flashphonerLoader.urlServer); - closeLoginView(); - if (result == 0) { - openConnectingView("Connecting...", 0); - setCookie("login", $('#username').val()); - setCookie("authName", $('#authname').val()); - setCookie("pwd", $('#password').val()); - setCookie("domain", $('#domain').val()); - setCookie("outbound_proxy", $('#outbound_proxy').val()); - setCookie("port", $('#port').val()); - } -} - -function loginByToken(token) { - trace("Phone - loginByToken "+ token); - connectingViewBeClosed = false; - var result = flashphoner.loginByToken(flashphonerLoader.urlServer, token, document.URL); - - closeLoginView(); - openConnectingView("Connecting...", 0); -} - -function getInfoAboutMe() { - trace("Phone - getInfoAboutMe"); - return flashphoner.getInfoAboutMe(); -} - -function logoff() { - trace("Phone - logoff"); - flashphoner.logoff(); -} - -function msrpCall(callee) { - trace("Phone - msrpCall "+callee); - flashphoner.msrpCall({callee: callee, visibleName: 'Caller', hasVideo: false, inviteParameters: testInviteParameter, isMsrp: true}); -} - -function call() { - trace("Phone - call "+callee); - if (isLogged) { - var hasAccess; - if (isVideoCall()){ - hasAccess = hasAccessToAudioAndVideo; - } else { - hasAccess = hasAccessToAudio; - } - if (!hasAccess()) { - if (intervalId == -1) { - intervalId = setInterval('if (isVideoCall() ? hasAccessToAudioAndVideo() : hasAccessToAudio()){flashphoner_UI.closeRequestUnmute(); clearInterval(intervalId); intervalId = -1; call();}', 500); - } - if (isVideoCall()){ - flashphoner_UI.getAccessToAudioAndVideo(); - } else { - flashphoner_UI.getAccessToAudio(); - } - } else if (hasAccess()) { - var result = flashphoner.call({callee: callee, visibleName: 'Caller', hasVideo: isVideoCall(), inviteParameters: testInviteParameter, isMsrp: false}); - if (result == 0) { - toHangupState(); - flashphonerListener.onCall(); - } else { - openConnectingView("Callee number is wrong", 3000); - } - } else { - openConnectingView("Microphone is not plugged in", 3000); - } - } else { - openLoginView(); - } -} - -function notifyMessage(message, notificationResult, sipObject) { - messenger.notifyMessage(message, notificationResult, sipObject); -} - -function sendMessage(to, body, contentType) { - trace("Phone - sendMessage "+ to+" body: "+ body+" contentType: "+ contentType); - var message = new Object(); - message.from = callerLogin; - message.to = to; - message.body = body; - message.contentType = contentType; - message.deliveryNotification = flashphonerLoader.imdnEnabled; - messenger.sendMessage(message); -} - - -function answer(callId) { - trace("Phone - answer "+ callId); - var hasAccess; - if (isVideoCall()){ - hasAccess = hasAccessToAudioAndVideo; - } else { - hasAccess = hasAccessToAudio; - } - if (!hasAccess()) { - if (intervalId == -1) { - intervalId = setInterval('if (isVideoCall() ? hasAccessToAudioAndVideo() : hasAccessToAudio()){flashphoner_UI.closeRequestUnmute(); clearInterval(intervalId); intervalId = -1; answer(currentCall.id);}', 500); - } - if (isVideoCall()){ - flashphoner_UI.getAccessToAudioAndVideo(); - } else { - flashphoner_UI.getAccessToAudio(); - } - } else if (hasAccess()) { - flashphoner.answer(callId, isVideoCall()); - flashphonerListener.onAnswer(callId); - } else { - openConnectingView("Microphone is not plugged in", 3000); - } -} - -function hangup(callId) { - trace("Phone - hangup "+ callId); - flashphoner.hangup(callId); - flashphonerListener.onHangup(); -} - -function sendDTMF(callId, dtmf) { - trace("Phone - sendDTMF callId: "+ callId +" dtmf: "+ dtmf); - flashphoner.sendDTMF(callId, dtmf); -} - -function setStatusHold(callId, isHold) { - trace("Phone - setStatusHold callId: "+ callId+" isHold: "+ isHold); - flashphoner.setStatusHold(callId, isHold); - disableHoldButton(); -} - -function transfer(callId, target) { - trace("Phone - transfer callId: "+ callId+" target: "+ target); - flashphoner.transfer(callId, target); -} - -function hasAccessToAudioAndVideo() { - return hasAccessToAudio() && hasAccessToVideo(); -} - -function hasAccessToAudio() { - return flashphoner.hasAccessToAudio(); -} - -function hasAccessToVideo() { - return flashphoner.hasAccessToVideo(); -} - - -function sendVideoChangeState() { - trace("Phone - sendVideoChangeState currentCall: "+currentCall.id); - var sendVideoButton = getElement('sendVideo'); - if (sendVideoButton.value == 'Send video') { - sendVideoButton.value = "Stop video"; - flashphoner.setSendVideo(currentCall.id, true); - } else { - sendVideoButton.value = "Send video"; - flashphoner.setSendVideo(currentCall.id, false); - } -} - -function changeRelationMyVideo(relation) { - trace("Phone - changeRelationMyVideo "+ relation); - flashphoner.changeRelationMyVideo(relation); -} - -function getMicVolume() { - var ret = flashphoner.getMicVolume(); - trace("Phone - getMicVolume "+ret); - return ret; -} -function getVolume() { - var ret = flashphoner.getVolume(); - trace("Phone - getVolume "+ret); - return ret; -} - -function setCookie(key, value) { - trace("Phone - setCookie key: "+ key+" value: "+ value); - flashphoner.setCookie(key, value); -} - -function getCookie(key) { - trace("Phone - getCookie "+ key); - return flashphoner.getCookie(key); -} - -function getVersion() { - var ret = flashphoner.getVersion(); - trace("Phone - getVersion "+ret); - return ret; -} -/* ------------------ Notify functions ----------------- */ - -function addLogMessage(message) { - trace("Phone - addLogMessage: "+message); -} - -function notifyFlashNotFound() { - closeConnectingView(); - getElement('phoneScreen2').innerHTML = "Get Adobe Flash player"; -} - -function notifyConfigLoaded() { - notifyReady(); - flashphoner = flashphonerLoader.getFlashphoner(); - flashphoner_UI = flashphonerLoader.getFlashphonerUI(); - flashphonerListener = flashphonerLoader.getFlashphonerListener(); - messenger = new Messenger(flashphoner); - if (flashphonerLoader.useWebRTC) { - $('#micButton').css('visibility', 'hidden'); - $('#sendVideo').css('visibility', 'hidden'); - } else { - $('#micButton').css('visibility', 'visible'); - $('#sendVideo').css('visibility', 'visible'); - } - //todo refactoring - //$('#versionOfProduct').html(getVersion()); - if (flashphonerLoader.getToken()) { - loginByToken(flashphonerLoader.getToken()); - } else { - closeConnectingView(); - } -} - -function notifyRequestUnmuteResult(accessGranted) { - console.log("Access to microphone granted: " + accessGranted); -} - - -function notifyRegisterRequired(registerR) { - registerRequired = registerR; -} - -function notifyCloseConnection() { - trace("Phone - notifyCloseConnection"); - currentCall = null; - toLogOffState(); - toCallState(); - isLogged = false; - closeIncomingView(); - closeVideoView(); - closeCallView(); - getElement('sendVideo').value = "Send video"; -} - -function notifyConnected() { - trace("Phone - notifyConnected"); - if (registerRequired) { - if (!connectingViewBeClosed) { - openConnectingView("Waiting for registering...", 0); - } - } else { - toLogState(); - callerLogin = getInfoAboutMe().login; - getElement("callerLogin").innerHTML = callerLogin; - isLogged = true; - closeConnectingView(); - } - //You can set speex quality here - //flashphoner.setSpeexQuality(10); -} - -function notifyRegistered(sipObject) { - trace("Phone - notifyRegistered "+sipObject.message.raw); - if (registerRequired) { - toLogState(); - callerLogin = getInfoAboutMe().login; - getElement("callerLogin").innerHTML = callerLogin; - isLogged = true; - connectingViewBeClosed = true; - closeConnectingView(); - flashphoner.playSound("REGISTER"); - flashphonerListener.onRegistered(); - } - - if (flashphonerLoader.subscribeEvent != null && flashphonerLoader.subscribeEvent.length != 0) { - subscribeReg(); - } - - sendXcapRequest(); -} - -function notifySubscription(subscriptionObject, sipObject) { - trace("Phone - notify subscription event: " + subscriptionObject.event + " expires: " + subscriptionObject.expires + " status: " + subscriptionObject.status+" terminate: "+subscriptionObject.terminate); - trace("Phone - notify subscription body: " + subscriptionObject.requestBody); - if (subscriptionObject.event == "reg") { - if (subscriptionObject.terminate){ - terminate(); - } - } -} - -function terminate() { - trace("Phone - terminate and logoff"); - logoff(); -} - -function sendXcapRequest() { - if (flashphonerLoader.xcapUrl != null && flashphonerLoader.xcapUrl.length != 0) { - flashphoner.sendXcapRequest(flashphonerLoader.xcapUrl); - } - -} - -function notifyXcapResponse(xcapResponse) { - trace("Phone - notifyXcapResponse " + xcapResponse); - var xml = $.parseXML(xcapResponse); - var history = $(xml).find("history-list").find("history"); - if (history != null && history.length != 0) { - if (flashphonerLoader.msrpCallee != null && flashphonerLoader.msrpCallee.length != 0) { - msrpCall(flashphonerLoader.msrpCallee); - } - } -} - - -function subscribeReg() { - var subscribeObj = new Object(); - subscribeObj.event = flashphonerLoader.subscribeEvent; - subscribeObj.expires = 3600; - flashphoner.subscribe(subscribeObj); -} - -function notifyBalance(balance) { -} - -function onCallFinished(){ - trace("Phone - onCallFinished"); - // if that hangup during transfer procedure? - if (holdedCall != null) { - trace("Phone - Existing holdedCall detected: "+holdedCall.id+" currentCall: "+currentCall.id); - currentCall = holdedCall; //holded call become current - holdedCall = null; //make variable null - createCallView(currentCall); - } else { - trace("Phone - no existing holdedCall. Just close call states.") - closeIncomingView(); - closeVideoView(); - toCallState(); - flashphoner.stopSound("RING"); - flashphoner.playSound("FINISH"); - } - getElement('sendVideo').value = "Send video"; - // or this just usual hangup during the call -} - -function onCurrentCallNotify(call){ - trace("Phone - onCurrentCallNotify: "+currentCall.id+" state: "+call.state); - currentCall = call; - if (call.state == STATE_FINISH) { - onCallFinished(); - } else if (call.state == STATE_HOLD) { - $('#callState').html('...Call on hold...'); - enableHoldButton(); - } else if (call.state == STATE_TALK) { - $('#callState').html('...Talking...'); - enableHoldButton(); - flashphoner.stopSound("RING"); - var sendVideoButton = getElement('sendVideo'); - if (isVideoCall() && call.state_video == "sendrecv" && sendVideoButton.value == 'Send video'){ - sendVideoChangeState(); - } - } else if (call.state == STATE_RING) { - $('#callState').html('...Ringing...'); - flashphoner.playSound("RING"); - } else if (call.state == STATE_RING_MEDIA){ - $('#callState').html('...Ringing...'); - flashphoner.stopSound("RING"); - } else if (call.state == STATE_BUSY) { - flashphoner.playSound("BUSY"); - } else if (call.state == STATE_SESSION_PROGRESS){ - $('#callState').html('...Call in Progress...'); - flashphoner.stopSound("RING"); - } -} - -function onNotCurrentCallNotify(call){ - trace("Phone - onNotCurrentCallNotify call.id: "+call.id+" holdedCall: "+holdedCall.id+" call.state: "+call.state); - if (holdedCall.id == call.id) { - if (call.state == STATE_FINISH) { - trace("It seems we received FINISH state on holdedCall. Just do null the holdedCall."); - /* that mean if - - user1 call user2 - - user2 transfer to user3 - - user3 just thinking (not answer, not hangup) - - user2 hangup during him thinking - then we delete old holded call from user1 memory - */ - holdedCall = null; - getElement('sendVideo').value = "Send video"; - } - enableHoldButton(); - } -} - -function notify(call,sipObject) { - trace("Phone - notify call id: "+ call.id+" state: "+call.state+" callee: "+call.callee+" caller: "+call.caller+" incoming: "+call.incoming+" isVideoCall: "+call.isVideoCall); - trace("Phone - currentCall.id: "+currentCall.id); - trace("Phone - sipObject: "+sipObject); - if (currentCall.id == call.id) { - onCurrentCallNotify(call); - } else { - onNotCurrentCallNotify(call); - } -} - -function notifyCallbackHold(call, isHold) { - trace("Phone - notifyCallbackHold call: "+ call +" isHold: "+ isHold); - if (currentCall != null && currentCall.id == call.id) { - currentCall = call; - if (needOpenTransferView) { - getElement('transfer').style.visibility = "visible"; - } - if (isHold) { - getElement('holdButton').style.background = "url(assets/unhold.png)"; - $('#holdButton').unbind('click'); - $('#holdButton').click(function () { - setStatusHold(call.id, false); - }); - - } else { - getElement('holdButton').style.background = "url(assets/hold.png)"; - $('#holdButton').unbind('click'); - $('#holdButton').click(function () { - setStatusHold(call.id, true); - }); - } - } -} - -function notifyCost(cost) { -} - -function notifyBugReport(filename) { - trace("Created bug report; filename - " + filename); -} - -function notifyError(error) { - - trace("Phone - notifyError "+ error); - - if (error == CONNECTION_ERROR) { - openInfoView("Can`t connect to server.", 3000, 30); - - } else if (error == AUTHENTICATION_FAIL) { - openInfoView("Register fail, please check your SIP account details.", 3000, 30); - window.setTimeout("logoff();", 3000); - - } else if (error == USER_NOT_AVAILABLE) { - openInfoView("User not available.", 3000, 30); - - /* Deprecated error - - else if (error == TOO_MANY_REGISTER_ATTEMPTS) { - openInfoView("Connection error", 3000, 30); - toLoggedOffState(); - */ - - } else if (error == LICENSE_RESTRICTION) { - openInfoView("You trying to connect too many users, or license is expired", 3000, 90); - - } else if (error == LICENSE_NOT_FOUND) { - openInfoView("Please get a valid license or contact Flashphoner support", 5000, 90); - - } else if (error == INTERNAL_SIP_ERROR) { - openInfoView("Unknown error. Please contact support.", 3000, 60); - - } else if (error == REGISTER_EXPIRE) { - openInfoView("No response from VOIP server during 15 seconds.", 3000, 60); - - } else if (error == SIP_PORTS_BUSY) { - openInfoView("SIP ports are busy. Please open SIP ports range (30000-31000 by default).", 3000, 90); - connectingViewBeClosed = true; - window.setTimeout("logoff();", 3000); - - } else if (error == MEDIA_PORTS_BUSY) { - openInfoView("Media ports are busy. Please open media ports range (31001-32000 by default).", 3000, 90); - - } else if (error == WRONG_SIPPROVIDER_ADDRESS) { - openInfoView("Wrong domain.", 3000, 30); - connectingViewBeClosed = true; - window.setTimeout("logoff();", 3000); - - } else if (error == CALLEE_NAME_IS_NULL) { - openInfoView("Callee name is empty.", 3000, 30); - - } else if (error == WRONG_FLASHPHONER_XML) { - openInfoView("Flashphoner.xml has errors. Please check it.", 3000, 60); - } else if (error == PAYMENT_REQUIRED) { - openInfoView("Payment required, please check your balance.", 3000, 60); - } - - flashphonerListener.onError(); - closeConnectingView(); - toCallState(); -} - -function notifyVideoFormat(call) { - trace("Phone - notifyVideoFormat "+ call); - - if (call.streamerVideoWidth != 0) { - proportionStreamer = call.streamerVideoHeight / call.streamerVideoWidth; - if (proportionStreamer != 0) { - changeRelationMyVideo(proportionStreamer); - } - } - - if (!call.playerVideoHeight == 0) { //that mean if user really send me video - proportion = call.playerVideoHeight / call.playerVideoWidth; //set proportion of video picture, else it will be = 0 - } - - if ($('div').is('.videoDiv') && proportion != 0) { //if video window opened and other side send video - var newHeight = $('.videoDiv').width() * proportion + 40; - $('.videoDiv').height(newHeight); //we resize video window for new proportion - $('#video').height(newHeight - 40); //and resize flash for new video window - } -} - -function notifyOpenVideoView(isViewed) { - trace("Phone - notifyOpenVideoView "+ isViewed); - if (isViewed) { - openVideoView(); - } else { - closeVideoView(); - } -} - -function notifyMessageReceived(messageObject) { - //ignore application/im-iscomposing+xml RFC3994 - if (messageObject.contentType == "application/im-iscomposing+xml") { - return; - } - openChatView(); - trace("Phone - notifyMessageReceived "+ messageObject); - var from = messageObject.from.toLowerCase(); - createChat(from); - var chatDiv = $('#chat' + removeNonDigitOrLetter(from) + ' .chatTextarea'); //set current textarea - var body = convertMessageBody(messageObject.body, messageObject.contentType); - addMessageToChat(chatDiv, from, body, "yourNick", messageObject.id); -} - -function convertMessageBody(messageBody, contentType) { - trace("Phone - convertMessageBody " + contentType); - if (contentType == "application/fsservice+xml") { - var missedCallNotification; - var xml = $.parseXML(messageBody); - var fsService = $(xml).find("fs-services").find("fs-service"); - var action = fsService.attr("action"); - if (action == "servicenoti-indicate") { - var caw = parseMsn(fsService,"caw"); - if (!!caw){ - missedCallNotification = caw; - }else{ - missedCallNotification = parseMsn(fsService,"mcn"); - } - } else if (action == "serviceinfo-confirm") { - //service status confirmation - missedCallNotification = "Service status: " + $(fsService.find("mcn").find("mcn-data")).attr("status"); - } - if(missedCallNotification !== undefined) return missedCallNotification; - } - - return messageBody; - -} - -function parseMsn(fsService,mcn){ - trace("Phone - parseMcn: "+mcn); - var caw = fsService.find(mcn); - var ret = null; - if (!!caw){ - var cawData = caw.find(mcn+"-data"); - if (!!cawData) { - var sender = $(cawData).attr("sender"); - if (!!sender){ - trace("Phone - Missed call: " + sender); - ret = "Missed call from " + sender; - } - } - } - return ret; -} - -function addMessageToChat(chatDiv, from, body, className, messageId) { - trace("Phone - addMessageToChat: messageId: "+messageId+" from: "+from); - var idAttr = (messageId != null) ? "id='" + messageId + "'" : ""; - var isScrolled = (chatDiv[0].scrollHeight - chatDiv.height() + 1) / (chatDiv[0].scrollTop + 1); // is chat scrolled down? or may be you are reading previous messages. - var messageDiv = "
" + from + " " + body + "
"; - chatDiv.append(messageDiv); //add message to chat - if (isScrolled == 1) { - chatDiv[0].scrollTop = chatDiv[0].scrollHeight; //autoscroll if you are not reading previous messages - } -} - -function notifyMessageSent(messageObject) { - trace("Phone - notifyMessageSent "+ messageObject); - createChat(messageObject.to.toLowerCase()); - var chatDiv = $('#chat' + removeNonDigitOrLetter(messageObject.to.toLowerCase()) + ' .chatTextarea'); //set current textarea for - addMessageToChat(chatDiv, messageObject.from, messageObject.body, "myNick", messageObject.id); -} - -function notifyMessageAccepted(message) { - trace("Phone - notifyMessageAccepted "+ message); - var messageDiv = $('#' + message.id); - messageDiv.addClass("myNick message_accepted"); -} - -function notifyMessageDelivered(message) { - trace("Phone - notifyMessageDelivered "+ message); - var messageDiv = $('#' + message.id); - messageDiv.addClass("myNick message_delivered"); -} - -function notifyMessageDeliveryFailed(message) { - trace("Phone - notifyMessageDeliveryFailed "+ message); - var messageDiv = $('#' + message.id); - messageDiv.addClass("myNick message_delivery_failed"); - messageDiv.innerHTML = messageDiv.innerHTML + "- Delivery failed to " + message.recipients; -} - -function notifyMessageFailed(message) { - trace("Phone - notifyMessageFailed "+ message); - var messageDiv = $('#' + message.id); - messageDiv.addClass("myNick message_failed"); -} - -function notifyAddCall(call) { - trace("Phone - notifyAddCall "+ call.id+" call.incoming: "+call.incoming+" call.state: "+call.state); - if (currentCall!=null && !call.incoming){ - holdedCall = currentCall; - currentCall = call; - createCallView(currentCall); - trace("Phone - It seems like a hold: holdedCall: "+holdedCall.id+" currentCall: "+currentCall.id); - } else { - currentCall = call; - createCallView(currentCall); - if (call.incoming == true) { - openIncomingView(call); - toHangupState(); - flashphonerListener.onIncomingCall(call.id); - } - trace("Phone - It seems like a new call currentCall: "+currentCall.id +" state: "+currentCall.state); - } -} - -function createCallView(call) { - trace("createCallView call: "+call.id+" state: "+call.state); - openCallView(); - $('#caller').html(call.anotherSideUser); - - if (call.state == STATE_HOLD) { - $('#callState').html('...Call on hold...'); - enableHoldButton(); - } else if (call.state == STATE_TALK) { - $('#callState').html('...Talking...'); - enableHoldButton(); - } else if (call.state == STATE_RING) { - $('#callState').html('...Ringing...'); - } - - $('#holdButton').unbind('click'); - $('#holdButton').click(function () { - setStatusHold(call.id, true); - }); - - $('#transferButton').unbind('click'); - $('#transferButton').click(function () { - openTransferView(); - }); -} - -function removeCallView(call) { - closeCallView(); - $('#caller').html(''); - $('#callState').html(''); - $('#holdButton').css('background', 'url(assets/hold.png)'); -} - -function isCurrentCall(call) { - return currentCall != null && currentCall.id == call.id; -} - -function notifyRemoveCall(call) { - trace("Phone - notifyRemoveCall "+ call.id+" currentCall: "+currentCall.id); - if (isCurrentCall(call)) { - currentCall = null; - removeCallView(call) - flashphonerListener.onRemoveCall(); - } -} - -function notifyVersion(version) { - getElement('versionOfProduct').innerHTML = version; -} -/* ----------------------------------------------------------------------- */ - -/* --------------- Additional functions ------------------- */ - -function toLogState() { - trace("Phone - toLogState"); - $("#callerLogin").show().html(callerLogin); - $("#loginMainButton").hide(); -} - -function toLogOffState() { - trace("Phone - toLogOffState"); - $("#loginMainButton").show(); - $('#callerLogin').hide().html(''); -} - -function toHangupState() { - trace("Phone - toHangupState"); - $('#callButton').html("Hangup"); - /*$('#callButton').css('background', '#C00');*/ - $('#callButton').removeClass('call').addClass('hangup'); - disableCallButton(); -} - -function toCallState() { - trace("Phone - toCallState"); - $('#callButton').html("Call"); - /*$('#callButton').css('background', '#090');*/ - $('#callButton').removeClass('hangup').addClass('call'); - disableCallButton(); -} - -function disableCallButton() { - trace("Phone - disableCallButton"); - $('#callButton').addClass('disabled'); - window.setTimeout(enableCallButton, 3000); - - function enableCallButton() { - $('#callButton').removeClass('disabled'); - } -} - - -function enableHoldButton() { - trace("Phone - enableHoldButton"); - var button = $('#holdButton'); - button.css('visibility', 'inherit'); -} - -function disableHoldButton() { - trace("Phone - disableHoldButton"); - var button = $('#holdButton'); - button.css('visibility', 'hidden'); -} - - -function openLoginView() { - if (flashphonerLoader.getToken()) { - loginByToken(flashphonerLoader.getToken()); - } else { - trace("Phone - openLoginView"); - $('#loginDiv').css('visibility', 'visible'); - $('#username').val(getCookie('login')); - $('#authname').val(getCookie('authName')); - $('#password').val(getCookie('pwd')); - $('#domain').val(getCookie('domain')); - $('#outbound_proxy').val(getCookie('outbound_proxy')); - $('#port').val(getCookie('port')); - } - -} - -function closeLoginView() { - $('#loginDiv').css('visibility', 'hidden'); -} - -function openConnectingView(str, timeout) { - trace("Phone - openConnectingView: message - " + str + "; timeout - " + timeout); - if (timeout != 0) { - window.setTimeout("closeConnectingView();", timeout); - } - getElement('connectingDiv').style.visibility = "visible"; - getElement('connectingText').innerHTML = str; -} - -function closeConnectingView() { - trace("Phone - closeConnectingView"); - getElement('connectingDiv').style.visibility = "hidden"; -} - -function openInfoView(str, timeout, height) { - trace("Phone - openInfoView str: "+ str+" timeout: "+ timeout); - if (timeout != 0) { - window.setTimeout("closeInfoView();", timeout); - } - getElement('infoDiv').style.visibility = "visible"; - getElement('infoDiv').style.height = height + "px"; - getElement('infoText').innerHTML = str; -} - -function closeInfoView(timeout) { - trace("Phone - closeInfoView "+timeout); - if (timeout) { - window.setTimeout("getElement('infoDiv').style.visibility = 'hidden';", timeout); - } else { - getElement('infoDiv').style.visibility = "hidden"; - } -} - -function openIncomingView(call) { - trace("Phone - openIncomingView "+ call)// call.caller, call.visibleNameCaller - - //form Caller-ID information displayed to user - var displayedCaller = ""; - if (call.caller !== undefined) displayedCaller += call.caller; - if (call.visibleNameCaller !== undefined) displayedCaller += " '" + call.visibleNameCaller + "'"; - - $('#incomingDiv').show(); - $('#callerField').html(displayedCaller); - - $('#answerButton').unbind('click'); - $('#answerButton').click(function () { - answer(call.id); - closeIncomingView(); - }); - $('#hangupButton').unbind('click'); - $('#hangupButton').click(function () { - trace("Phone - openIncomingView hangup "+call.id); - hangup(call.id); - closeIncomingView(); - }); -} - -function closeIncomingView() { - trace("Phone - closeIncomingView"); - $('#incomingDiv').hide(); -} - -function openSettingsView() { - trace("Phone - openSettingsView"); - getElement('settingsDiv').style.visibility = "visible"; -} -function closeSettingsView() { - trace("Phone - closeSettingsView"); - getElement('settingsDiv').style.visibility = "hidden"; -} - -function getElement(str) { - return document.getElementById(str); -} - -/* ----- VIDEO ----- */ - -function openVideoView() { - flashphoner_UI.openVideoView(); -} - -function closeVideoView() { - trace("Phone - closeVideoView"); - $('#video_requestUnmuteDiv').removeClass().addClass('closed'); -} - -/* ----- CHAT ----- */ - -function openChatView() { - trace("Phone - openChatView"); - $('#chatDiv').css('visibility', 'visible'); -} -function closeChatView() { - trace("Phone - closeChatView"); - $('#chatDiv').css('visibility', 'hidden'); -} -/*-----------------*/ - -/* ----- CALL ----- */ -function openCallView() { - trace("Phone - openCallView"); - $('#callDiv').css('visibility', 'visible'); -} -function closeCallView() { - trace("Phone - closeCallView"); - $('#callDiv').css('visibility', 'hidden'); -} -/*-----------------*/ -/* ----- TRANSFER ----- */ -function openTransferView() { - trace("Phone - openTransferView"); - $('#transferOk').unbind('click'); - $('#transferOk').click(function () { - if (currentCall.state == STATE_HOLD) { - transfer(currentCall.id, $('#transferInput').val()); - closeTransferView(); - } else { - needOpenTransferView = true; - setStatusHold(currentCall.id, true); - } - }); - - if (call.state != STATE_HOLD) { - needOpenTransferView = true; - setStatusHold(currentCall.id, true); - } else { - getElement('transfer').style.visibility = "visible"; - } -} - -function closeTransferView() { - trace("Phone - closeTransferView"); - needOpenTransferView = false; - getElement('transfer').style.visibility = "hidden"; -} - -function submitBugReport(){ - var bugReportText = getElement('bugReportText').value; - trace("submitBugReport "+bugReportText); - if (flashphoner){ - flashphoner.submitBugReport({text:bugReportText, type: "no_media"}); - } -} - -/*-----------------*/ - -/* ------------- Additional interface functions --------- */ -function isVideoCall(){ - return $('#checkboxVideoCall').attr("checked") ? true : false; -} -// Functions createChat creates chat with the callee. -// It contains all chat window functionality including send message function - -function createChat(calleeName) { - - //var closetab = '×'; - //$("#tabul").append('
  • ' + calleeName + ' ' + closetab + '
  • '); //add tab with the close button - var shortCalleeName = calleeName; - var fullCalleeName = shortCalleeName; - var calleeNameId = removeNonDigitOrLetter(fullCalleeName); - if (!$('li').is('#tab' + calleeNameId)) { - var closetab = '×'; - - // We will cut too long calleeNames to place it within chat tab - if (shortCalleeName.length > 21) { - shortCalleeName = shortCalleeName.substr(0, 21) + '...'; - } - - - $("#tabul").append('
  • ' + shortCalleeName + ' ' + closetab + '
  • '); //add tab with the close button - - - $('#tabcontent').append('
    '); //add chatBox - $('#chat' + calleeNameId).append('
    ')//add text area for chat messages - .append('')//add input field - .append(''); //add send button - - $("#tabul li").removeClass("ctab"); //remove select from all tabs - $("#tab" + calleeNameId).addClass("ctab"); //select new tab - $(".chatBox").hide(); //hide all chatBoxes - $("#chat" + calleeNameId).show(); //show new chatBox - - // Bind send message on click Enter in message inout field - - $('#chat' + calleeNameId + ' .messageInput').keydown(function (event) { - if (event.keyCode == '13') { - $(this).next().click(); // click on sendMessage button - } else if (event.keyCode == '27') { - $(this).val(''); - } - }); - - // Bind send message function - $('#chat' + calleeNameId + ' .messageSend').click(function () { - var fullCalleeName = $(this).parent().attr('fullCalleeName'); //parse id of current chatBox, take away chat word from the beginning - var messageText = $(this).prev().val(); //parse text from input - sendMessage(calleeName, messageText, flashphonerLoader.msgContentType); //send message - $(this).prev().val(''); //clear message input - }); - - // Bind selecting tab - $("#tab" + calleeNameId).bind("click", function () { - $("#tabul li").removeClass("ctab"); //hide all tabs - $("#tab" + calleeNameId).addClass("ctab"); //select clicked tab - $(".chatBox").hide(); //chide all chatBoxes - $("#chat" + calleeNameId).show(); //show new chatBox - }); - - // Bind closing tab on click - $("#close" + calleeNameId).click(function () { - //close this tab - $(this).parent().hide(); - $("#chat" + calleeNameId).hide(); - - var prevVisibleTab = $(this).parent().prevAll().filter(':visible').filter(':first'); //set prev visible tab - var nextVisibleTab = $(this).parent().nextAll().filter(':visible').filter(':first'); //set next visible tab - - if ($(this).parent().is('.ctab')) { //but what if this tab was selected? - $(this).parent().removeClass("ctab"); //we will unselect this - if (prevVisibleTab.is('.ntabs')) { //and if there is prev tab - prevVisibleTab.addClass('ctab'); //then select prev tab - $('#chat' + prevVisibleTab.attr('id').substr(3)).show(); //and show accoring chat - - } else if (nextVisibleTab.is('.ntabs')) { //or if there is next tab - nextVisibleTab.addClass('ctab'); //then select next tab - $('#chat' + nextVisibleTab.attr('id').substr(3)).show(); //and show accoring chat - - } else { - $('#chatDiv').css('visibility', 'hidden'); //else simply close all chat - } - } - ; - return false; // i don`t know why it need - }); - } else { - $("#tabul li").removeClass("ctab"); //remove select from all tabs - $("#tab" + calleeNameId).show(); //show our tab - $("#tab" + calleeNameId).addClass("ctab"); //select our tab - $(".chatBox").hide(); //hide all chatboxes - $("#chat" + calleeNameId).show(); //show our chatBox - - } - -} - -function removeNonDigitOrLetter(calleeName) { - return calleeName.replace(/\W/g, '') -} - -/* ---------------------------------------------------- */ - -// functions closeView is simplifying of many close....View functions -function close(element) { - element.css('visibility', 'hidden'); -} - - -/* --------------------- On document load we do... ------------------ */ -function notifyReady() { - - // open login view - $("#loginMainButton").click(function () { - openLoginView(); - }); - - // logout - $("#logoutButton").click(function () { - logoff(); - $(this).hide(); - }); - - // login - $("#loginButton").click(function () { - login(); - }); - - // click on caller login show logout button - $("#callerLogin").click(function () { - $('#logoutButton').toggle() - }); - - // every time when we change callee field - we set parameter callee - // that parameter used around the code - $("#calleeText").keyup(function () { - callee = $(this).val(); - }); - - //Bind click on different buttons - $("#callButton").click(function () { - if ($("#callButton").html() == 'Call') { - call(); - } else { - if (currentCall) { - trace("Phone - Hangup current call by click: "+currentCall.id); - hangup(currentCall.id); - } else { - trace("Phone - Hangup call by click"); - hangup(); - } - } - }); - - $("#cameraButtonInCallee").click(function () { - openVideoView(); - }); - - $("#canselLoginDiv").click(function () { - closeLoginView(); - }); - - $("#sendVideo").click(function () { - sendVideoChangeState(); - }); - - $("#transferCansel").click(function () { - closeTransferView(); - }); - - $(".iconButton").click(function () { - $(this).toggleClass('iconPressed'); - }); - - //micButton opens mic slider - $("#micButton").click(function () { - if ($(this).hasClass('iconPressed')) { - $('#micSlider').show(); - $('#micBack').show(); - } else { - $('#micSlider').hide(); - $('#micBack').hide(); - } - }); - - //micButton opens mic slider - $("#soundButton").click(function () { - if ($(this).hasClass('iconPressed')) { - $('#speakerSlider').show(); - $('#speakerBack').show(); - } else { - $('#speakerSlider').hide(); - $('#speakerBack').hide(); - } - }); - - $("#cameraButton").click(function () { - openVideoView(); - }); - - $("#closeButton_video_requestUnmuteDiv").click(function () { - closeVideoView(); - }); - - $(".closeButton").click(function () { - close($(this).parent()); - }); - - //enable drag and resize objects - $("#loginDiv").draggable({handle: '.bar', stack: "#loginDiv"}); - $("#incomingDiv").draggable({handle: '.bar', stack: "#incomingDiv"}); - $("#settingsDiv").draggable({handle: '.bar', stack: "#settingsDiv"}); - $("#transfer").draggable({handle: '.bar', stack: "#transfer"}); - $("#chatDiv").draggable({handle: '.bar', stack: "#chatDiv"}); - $("#video_requestUnmuteDiv").draggable({handle: '.bar', stack: "#video_requestUnmuteDiv"}); - $("#video_requestUnmuteDiv").resizable({ minWidth: 215, minHeight: 180, aspectRatio: true}); - - var all_videos = $('#localVideoPreview, #remoteVideo'); - all_videos.each(function () { - var el = $(this); - el.attr('data-aspectRatio', el.height() / el.width()); - var width = $("#video_requestUnmuteDiv").width(); - el.attr('data-windowRatio', el.width() / (width == 1 ? 640 : width)); - }); - - $("#video_requestUnmuteDiv").resize(function () { - var width = $("#video_requestUnmuteDiv").width(); - var height = $("#video_requestUnmuteDiv").height(); - var newWidth = width == 1 ? 640 : width; - $('#video').height((height == 1 ? 520 : height) - 40); - $('#video').width(width == 1 ? 640 : width); - $('#remoteVideo').height((height == 1 ? 520 : height) - 40); - var localVideo = $('#localVideoPreview'); - localVideo.height(newWidth * localVideo.attr('data-windowRatio') * localVideo.attr('data-aspectRatio')); - all_videos.each(function () { - var el = $(this); - el.width(newWidth * el.attr('data-windowRatio')); - }); - }).resize(); - - //Bind click on number buttons - $(".numberButton").click(function () { - if (currentCall != null && currentCall.state == STATE_TALK) { - sendDTMF(currentCall.id, $(this).html()); - } else if (currentCall == null) { - $("#calleeText").val($("#calleeText").val() + $(this).html()); - callee = callee + $(this).html(); - } - }); - - $(".testButton").click(function () { - startUnitTests(); - }); - - $(".bugReportButton").click(function () { - submitBugReport(); - }); - - // this function set changing in button styles when you press any button - $(".button").mousedown(function () { - $(this).addClass('pressed'); - }).mouseup(function () { - $(this).removeClass('pressed'); - }).mouseout(function () { - $(this).removeClass('pressed'); - }); - - // Bind click on chatButton - $("#chatButton").click(function () { - if (isLogged) { - if (callee != '') { - openChatView(); - createChat(callee.toLowerCase()); - } else { - openConnectingView("Callee number is wrong", 3000); - } - } else { - openLoginView(); - } - }); - - /* Autofill Aut. name field when you fill Login field */ - $('#username').keyup(function () { - $('#authname').val($(this).val()); - }); - - /* Autofill Outb. proxy field when you fill "domain" field */ - $('#domain').keyup(function () { - $('#outbound_proxy').val($(this).val()); - }); - - // Mic slider set mic volume when you slide it - $("#micSlider").slider({ - orientation: "vertical", - range: "min", - min: 0, - max: 100, - value: 60, - slide: function (event, ui) { - flashphoner.setMicVolume(ui.value); - } - }); - - // Speaker slider set speaker volume when you slide it - $("#speakerSlider").slider({ - orientation: "vertical", - range: "min", - min: 0, - max: 100, - value: 60, - slide: function (event, ui) { - flashphoner.setVolume(ui.value); - } - }); - - $("#checkboxUseProxy").change(function () { - if ($(this).attr("checked")) { - flashphoner.setUseProxy(true); - } else { - flashphoner.setUseProxy(false); - } - }); - - -}; diff --git a/client/client/src/js/StaticData.js b/client/client/src/js/StaticData.js deleted file mode 100644 index d5a309b4..00000000 --- a/client/client/src/js/StaticData.js +++ /dev/null @@ -1,102 +0,0 @@ -/* -Copyright (c) 2011 Flashphoner -All rights reserved. This Code and the accompanying materials -are made available under the terms of the GNU Public License v2.0 -which accompanies this distribution, and is available at -http://www.gnu.org/licenses/old-licenses/gpl-2.0.html - -Contributors: - Flashphoner - initial API and implementation - -This code and accompanying materials also available under LGPL and MPL license for Flashphoner buyers. Other license versions by negatiation. Write us support@flashphoner.com with any questions. -*/ -var STATE_RING = "RING"; -var STATE_RING_MEDIA = "RING_MEDIA"; -var STATE_HOLD = "HOLD"; -var STATE_TALK = "TALK"; -var STATE_FINISH = "FINISH"; -var STATE_BUSY = "BUSY"; -var STATE_SESSION_PROGRESS = "SESSION_PROGRESS"; - -var AUTHENTICATION_FAIL = "AUTHENTICATION_FAIL"; -var USER_NOT_AVAILABLE = "USER_NOT_AVAILABLE"; -var TOO_MANY_REGISTER_ATTEMPTS = "TOO_MANY_REGISTER_ATTEMPTS"; -var LICENSE_RESTRICTION = "LICENSE_RESTRICTION"; -var LICENSE_NOT_FOUND = "LICENSE_NOT_FOUND"; -var INTERNAL_SIP_ERROR = "INTERNAL_SIP_ERROR"; -var CONNECTION_ERROR = "CONNECTION_ERROR"; -var REGISTER_EXPIRE = "REGISTER_EXPIRE"; -var SIP_PORTS_BUSY = "SIP_PORTS_BUSY"; -var MEDIA_PORTS_BUSY = "MEDIA_PORTS_BUSY"; -var WRONG_SIPPROVIDER_ADDRESS = "WRONG_SIPPROVIDER_ADDRESS"; -var CALLEE_NAME_IS_NULL = "CALLEE_NAME_IS_NULL"; -var WRONG_FLASHPHONER_XML = "WRONG_FLASHPHONER_XML"; -var PAYMENT_REQUIRED = "PAYMENT_REQUIRED"; - -function extend(Child, Parent) { - var F = function() { } - F.prototype = Parent.prototype - Child.prototype = new F() - Child.prototype.constructor = Child - Child.superclass = Parent.prototype -} - -function trace(logMessage) { - - var today = new Date(); - // get hours, minutes and seconds - var hh = today.getUTCHours().toString(); - var mm = today.getUTCMinutes().toString(); - var ss = today.getUTCSeconds().toString(); - var ms = today.getUTCMilliseconds().toString(); - - // Add leading '0' to see 14:08:06.001 instead of 14:8:6.1 - hh = hh.length == 1 ? "0" + hh : hh; - mm = mm.length == 1 ? "0" + mm : mm; - ss = ss.length == 1 ? "0" + ss : ss; - ms = ms.length == 1 ? "00" + ms : ms.length == 2 ? "0" + ms : ms; - - // set time - var time = "UTC " + hh + ':' + mm + ':' + ss + '.' + ms; - - var console = $("#console"); - - // Check if console is scrolled down? Or may be you are reading previous messages. - var isScrolled = (console[0].scrollHeight - console.height() + 1) / (console[0].scrollTop + 1 + 37); - - var logMessage = time + ' - ' + logMessage; - - // Print message to console and push it to server - if (traceEnabled) { - //check if API already loaded - if (flashphoner !== undefined) { - //check if push_log enabled - if (flashphonerLoader.pushLogEnabled) { - var result = flashphoner.pushLogs(logs + logMessage+'\n'); - if (!result) { - logs += logMessage+'\n'; - } else { - logs = ""; - } - } else { - logs = ""; - } - - } else { - logs += logMessage+'\n'; - } - - console.append(logMessage+'
    '); - try { - window.console.debug(logMessage); - } catch(err) { - //Not supported. For example IE - } - - } - - //Autoscroll cosole if you are not reading previous messages - if (isScrolled < 1) { - console[0].scrollTop = console[0].scrollHeight; - } -} \ No newline at end of file diff --git a/client/client/src/js/UnitTests.js b/client/client/src/js/UnitTests.js deleted file mode 100644 index a4476bd0..00000000 --- a/client/client/src/js/UnitTests.js +++ /dev/null @@ -1,11 +0,0 @@ -function startUnitTests() { - testConvertMessageBody(); -} - -function testConvertMessageBody(){ - //var messageBody=""; - var messageBody="" - var contentType="application/fsservice+xml"; - var res = convertMessageBody(messageBody,contentType); - trace("Phone - testConvertMessageBody "+res); -} \ No newline at end of file diff --git a/client/client/src/js/imgtrackbar/b_bg_all.gif b/client/client/src/js/imgtrackbar/b_bg_all.gif deleted file mode 100644 index 20751aa74d8ed84ee305d4444f272732381d1e49..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 52 zcmZ?wbhEHbWMmLzn8?hqdiCma7jCAdrTzc^U-2gkBLf37gAM}_faDpNSm)R?HHI@- F0|2+F4ov_6 diff --git a/client/client/src/js/imgtrackbar/b_bg_off.gif b/client/client/src/js/imgtrackbar/b_bg_off.gif deleted file mode 100644 index 9087f866cdd440a3f67a8a4aa872772af2742cc5..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 52 zcmZ?wbhEHbWMmLzn8?7ediCma7jCAdrTzc^U-2gk0|@AV2#`Dj6YCs%rp9mvYXG*_ B4n_a~ diff --git a/client/client/src/js/imgtrackbar/b_bg_on.gif b/client/client/src/js/imgtrackbar/b_bg_on.gif deleted file mode 100644 index 002497abf90acbcdb0355f5bdf0ff83235439d8e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 52 zcmZ?wbhEHbWMmLzn8?7e_uPvW+t1eZExz^Yzv5381`yBz5g>U6Ce}IjLJi>z)&Ry$ B4!-~Z diff --git a/client/client/src/js/imgtrackbar/b_l.gif b/client/client/src/js/imgtrackbar/b_l.gif deleted file mode 100644 index bcbe5f43185d97ace94878c215d25e56aa41bc5a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 182 zcmZ?wbhEHbWMvR!IKs=YdiCo6|NrmVv*-8k-|N?}|N8aovuDq?ZrytI>eYMq?wvVv z=H0t@M~)m}AQve9WMO1r;APMO833}Afz>!c+3WxZ%cIU!jJNqdFo={e>il4m*u$uD hfQ7-)g+auFwc%h214{to0|#3MjtC~s1H6n3)&Td`GdchO diff --git a/client/client/src/js/imgtrackbar/b_r.gif b/client/client/src/js/imgtrackbar/b_r.gif deleted file mode 100644 index 7867a92a21ccd76c532b9a838b1d77ac0c428bc6..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 183 zcmZ?wbhEHbWMvR!IKs=YdiCo6|NrmVv*-8k-|N?}|N8aovuDq?ZrytI>eYMq?wvVv z=H0t@M~)m}AQve9WMO1r;APMO833}Afz?FeLXWRPUt{O8q*Ht!7(_}Kb$&2O>|s
    - value = parseInt( elem.css( "zIndex" ), 10 ); - if ( !isNaN( value ) && value !== 0 ) { - return value; - } - } - elem = elem.parent(); - } - } - - return 0; - }, - - disableSelection: function() { - return this.bind( ( $.support.selectstart ? "selectstart" : "mousedown" ) + - ".ui-disableSelection", function( event ) { - event.preventDefault(); - }); - }, - - enableSelection: function() { - return this.unbind( ".ui-disableSelection" ); - } -}); - -$.each( [ "Width", "Height" ], function( i, name ) { - var side = name === "Width" ? [ "Left", "Right" ] : [ "Top", "Bottom" ], - type = name.toLowerCase(), - orig = { - innerWidth: $.fn.innerWidth, - innerHeight: $.fn.innerHeight, - outerWidth: $.fn.outerWidth, - outerHeight: $.fn.outerHeight - }; - - function reduce( elem, size, border, margin ) { - $.each( side, function() { - size -= parseFloat( $.curCSS( elem, "padding" + this, true) ) || 0; - if ( border ) { - size -= parseFloat( $.curCSS( elem, "border" + this + "Width", true) ) || 0; - } - if ( margin ) { - size -= parseFloat( $.curCSS( elem, "margin" + this, true) ) || 0; - } - }); - return size; - } - - $.fn[ "inner" + name ] = function( size ) { - if ( size === undefined ) { - return orig[ "inner" + name ].call( this ); - } - - return this.each(function() { - $( this ).css( type, reduce( this, size ) + "px" ); - }); - }; - - $.fn[ "outer" + name] = function( size, margin ) { - if ( typeof size !== "number" ) { - return orig[ "outer" + name ].call( this, size ); - } - - return this.each(function() { - $( this).css( type, reduce( this, size, true, margin ) + "px" ); - }); - }; -}); - -// selectors -function focusable( element, isTabIndexNotNaN ) { - var nodeName = element.nodeName.toLowerCase(); - if ( "area" === nodeName ) { - var map = element.parentNode, - mapName = map.name, - img; - if ( !element.href || !mapName || map.nodeName.toLowerCase() !== "map" ) { - return false; - } - img = $( "img[usemap=#" + mapName + "]" )[0]; - return !!img && visible( img ); - } - return ( /input|select|textarea|button|object/.test( nodeName ) - ? !element.disabled - : "a" == nodeName - ? element.href || isTabIndexNotNaN - : isTabIndexNotNaN) - // the element and all of its ancestors must be visible - && visible( element ); -} - -function visible( element ) { - return !$( element ).parents().andSelf().filter(function() { - return $.curCSS( this, "visibility" ) === "hidden" || - $.expr.filters.hidden( this ); - }).length; -} - -$.extend( $.expr[ ":" ], { - data: function( elem, i, match ) { - return !!$.data( elem, match[ 3 ] ); - }, - - focusable: function( element ) { - return focusable( element, !isNaN( $.attr( element, "tabindex" ) ) ); - }, - - tabbable: function( element ) { - var tabIndex = $.attr( element, "tabindex" ), - isTabIndexNaN = isNaN( tabIndex ); - return ( isTabIndexNaN || tabIndex >= 0 ) && focusable( element, !isTabIndexNaN ); - } -}); - -// support -$(function() { - var body = document.body, - div = body.appendChild( div = document.createElement( "div" ) ); - - $.extend( div.style, { - minHeight: "100px", - height: "auto", - padding: 0, - borderWidth: 0 - }); - - $.support.minHeight = div.offsetHeight === 100; - $.support.selectstart = "onselectstart" in div; - - // set display to none to avoid a layout bug in IE - // http://dev.jquery.com/ticket/4014 - body.removeChild( div ).style.display = "none"; -}); - - - - - -// deprecated -$.extend( $.ui, { - // $.ui.plugin is deprecated. Use the proxy pattern instead. - plugin: { - add: function( module, option, set ) { - var proto = $.ui[ module ].prototype; - for ( var i in set ) { - proto.plugins[ i ] = proto.plugins[ i ] || []; - proto.plugins[ i ].push( [ option, set[ i ] ] ); - } - }, - call: function( instance, name, args ) { - var set = instance.plugins[ name ]; - if ( !set || !instance.element[ 0 ].parentNode ) { - return; - } - - for ( var i = 0; i < set.length; i++ ) { - if ( instance.options[ set[ i ][ 0 ] ] ) { - set[ i ][ 1 ].apply( instance.element, args ); - } - } - } - }, - - // will be deprecated when we switch to jQuery 1.4 - use jQuery.contains() - contains: function( a, b ) { - return document.compareDocumentPosition ? - a.compareDocumentPosition( b ) & 16 : - a !== b && a.contains( b ); - }, - - // only used by resizable - hasScroll: function( el, a ) { - - //If overflow is hidden, the element might have extra content, but the user wants to hide it - if ( $( el ).css( "overflow" ) === "hidden") { - return false; - } - - var scroll = ( a && a === "left" ) ? "scrollLeft" : "scrollTop", - has = false; - - if ( el[ scroll ] > 0 ) { - return true; - } - - // TODO: determine which cases actually cause this to happen - // if the element doesn't have the scroll set, see if it's possible to - // set the scroll - el[ scroll ] = 1; - has = ( el[ scroll ] > 0 ); - el[ scroll ] = 0; - return has; - }, - - // these are odd functions, fix the API or move into individual plugins - isOverAxis: function( x, reference, size ) { - //Determines when x coordinate is over "b" element axis - return ( x > reference ) && ( x < ( reference + size ) ); - }, - isOver: function( y, x, top, left, height, width ) { - //Determines when x, y coordinates is over "b" element - return $.ui.isOverAxis( y, top, height ) && $.ui.isOverAxis( x, left, width ); - } -}); - -})( jQuery ); -/*! - * jQuery UI Widget 1.8.15 - * - * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) - * Dual licensed under the MIT or GPL Version 2 licenses. - * http://jquery.org/license - * - * http://docs.jquery.com/UI/Widget - */ -(function( $, undefined ) { - -// jQuery 1.4+ -if ( $.cleanData ) { - var _cleanData = $.cleanData; - $.cleanData = function( elems ) { - for ( var i = 0, elem; (elem = elems[i]) != null; i++ ) { - $( elem ).triggerHandler( "remove" ); - } - _cleanData( elems ); - }; -} else { - var _remove = $.fn.remove; - $.fn.remove = function( selector, keepData ) { - return this.each(function() { - if ( !keepData ) { - if ( !selector || $.filter( selector, [ this ] ).length ) { - $( "*", this ).add( [ this ] ).each(function() { - $( this ).triggerHandler( "remove" ); - }); - } - } - return _remove.call( $(this), selector, keepData ); - }); - }; -} - -$.widget = function( name, base, prototype ) { - var namespace = name.split( "." )[ 0 ], - fullName; - name = name.split( "." )[ 1 ]; - fullName = namespace + "-" + name; - - if ( !prototype ) { - prototype = base; - base = $.Widget; - } - - // create selector for plugin - $.expr[ ":" ][ fullName ] = function( elem ) { - return !!$.data( elem, name ); - }; - - $[ namespace ] = $[ namespace ] || {}; - $[ namespace ][ name ] = function( options, element ) { - // allow instantiation without initializing for simple inheritance - if ( arguments.length ) { - this._createWidget( options, element ); - } - }; - - var basePrototype = new base(); - // we need to make the options hash a property directly on the new instance - // otherwise we'll modify the options hash on the prototype that we're - // inheriting from -// $.each( basePrototype, function( key, val ) { -// if ( $.isPlainObject(val) ) { -// basePrototype[ key ] = $.extend( {}, val ); -// } -// }); - basePrototype.options = $.extend( true, {}, basePrototype.options ); - $[ namespace ][ name ].prototype = $.extend( true, basePrototype, { - namespace: namespace, - widgetName: name, - widgetEventPrefix: $[ namespace ][ name ].prototype.widgetEventPrefix || name, - widgetBaseClass: fullName - }, prototype ); - - $.widget.bridge( name, $[ namespace ][ name ] ); -}; - -$.widget.bridge = function( name, object ) { - $.fn[ name ] = function( options ) { - var isMethodCall = typeof options === "string", - args = Array.prototype.slice.call( arguments, 1 ), - returnValue = this; - - // allow multiple hashes to be passed on init - options = !isMethodCall && args.length ? - $.extend.apply( null, [ true, options ].concat(args) ) : - options; - - // prevent calls to internal methods - if ( isMethodCall && options.charAt( 0 ) === "_" ) { - return returnValue; - } - - if ( isMethodCall ) { - this.each(function() { - var instance = $.data( this, name ), - methodValue = instance && $.isFunction( instance[options] ) ? - instance[ options ].apply( instance, args ) : - instance; - // TODO: add this back in 1.9 and use $.error() (see #5972) -// if ( !instance ) { -// throw "cannot call methods on " + name + " prior to initialization; " + -// "attempted to call method '" + options + "'"; -// } -// if ( !$.isFunction( instance[options] ) ) { -// throw "no such method '" + options + "' for " + name + " widget instance"; -// } -// var methodValue = instance[ options ].apply( instance, args ); - if ( methodValue !== instance && methodValue !== undefined ) { - returnValue = methodValue; - return false; - } - }); - } else { - this.each(function() { - var instance = $.data( this, name ); - if ( instance ) { - instance.option( options || {} )._init(); - } else { - $.data( this, name, new object( options, this ) ); - } - }); - } - - return returnValue; - }; -}; - -$.Widget = function( options, element ) { - // allow instantiation without initializing for simple inheritance - if ( arguments.length ) { - this._createWidget( options, element ); - } -}; - -$.Widget.prototype = { - widgetName: "widget", - widgetEventPrefix: "", - options: { - disabled: false - }, - _createWidget: function( options, element ) { - // $.widget.bridge stores the plugin instance, but we do it anyway - // so that it's stored even before the _create function runs - $.data( element, this.widgetName, this ); - this.element = $( element ); - this.options = $.extend( true, {}, - this.options, - this._getCreateOptions(), - options ); - - var self = this; - this.element.bind( "remove." + this.widgetName, function() { - self.destroy(); - }); - - this._create(); - this._trigger( "create" ); - this._init(); - }, - _getCreateOptions: function() { - return $.metadata && $.metadata.get( this.element[0] )[ this.widgetName ]; - }, - _create: function() {}, - _init: function() {}, - - destroy: function() { - this.element - .unbind( "." + this.widgetName ) - .removeData( this.widgetName ); - this.widget() - .unbind( "." + this.widgetName ) - .removeAttr( "aria-disabled" ) - .removeClass( - this.widgetBaseClass + "-disabled " + - "ui-state-disabled" ); - }, - - widget: function() { - return this.element; - }, - - option: function( key, value ) { - var options = key; - - if ( arguments.length === 0 ) { - // don't return a reference to the internal hash - return $.extend( {}, this.options ); - } - - if (typeof key === "string" ) { - if ( value === undefined ) { - return this.options[ key ]; - } - options = {}; - options[ key ] = value; - } - - this._setOptions( options ); - - return this; - }, - _setOptions: function( options ) { - var self = this; - $.each( options, function( key, value ) { - self._setOption( key, value ); - }); - - return this; - }, - _setOption: function( key, value ) { - this.options[ key ] = value; - - if ( key === "disabled" ) { - this.widget() - [ value ? "addClass" : "removeClass"]( - this.widgetBaseClass + "-disabled" + " " + - "ui-state-disabled" ) - .attr( "aria-disabled", value ); - } - - return this; - }, - - enable: function() { - return this._setOption( "disabled", false ); - }, - disable: function() { - return this._setOption( "disabled", true ); - }, - - _trigger: function( type, event, data ) { - var callback = this.options[ type ]; - - event = $.Event( event ); - event.type = ( type === this.widgetEventPrefix ? - type : - this.widgetEventPrefix + type ).toLowerCase(); - data = data || {}; - - // copy original event properties over to the new event - // this would happen if we could call $.event.fix instead of $.Event - // but we don't have a way to force an event to be fixed multiple times - if ( event.originalEvent ) { - for ( var i = $.event.props.length, prop; i; ) { - prop = $.event.props[ --i ]; - event[ prop ] = event.originalEvent[ prop ]; - } - } - - this.element.trigger( event, data ); - - return !( $.isFunction(callback) && - callback.call( this.element[0], event, data ) === false || - event.isDefaultPrevented() ); - } -}; - -})( jQuery ); -/*! - * jQuery UI Mouse 1.8.15 - * - * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) - * Dual licensed under the MIT or GPL Version 2 licenses. - * http://jquery.org/license - * - * http://docs.jquery.com/UI/Mouse - * - * Depends: - * jquery.ui.widget.js - */ -(function( $, undefined ) { - -$.widget("ui.mouse", { - options: { - cancel: ':input,option', - distance: 1, - delay: 0 - }, - _mouseInit: function() { - var self = this; - - this.element - .bind('mousedown.'+this.widgetName, function(event) { - return self._mouseDown(event); - }) - .bind('click.'+this.widgetName, function(event) { - if (true === $.data(event.target, self.widgetName + '.preventClickEvent')) { - $.removeData(event.target, self.widgetName + '.preventClickEvent'); - event.stopImmediatePropagation(); - return false; - } - }); - - this.started = false; - }, - - // TODO: make sure destroying one instance of mouse doesn't mess with - // other instances of mouse - _mouseDestroy: function() { - this.element.unbind('.'+this.widgetName); - }, - - _mouseDown: function(event) { - // don't let more than one widget handle mouseStart - // TODO: figure out why we have to use originalEvent - event.originalEvent = event.originalEvent || {}; - if (event.originalEvent.mouseHandled) { return; } - - // we may have missed mouseup (out of window) - (this._mouseStarted && this._mouseUp(event)); - - this._mouseDownEvent = event; - - var self = this, - btnIsLeft = (event.which == 1), - elIsCancel = (typeof this.options.cancel == "string" ? $(event.target).closest(this.options.cancel).length : false); - if (!btnIsLeft || elIsCancel || !this._mouseCapture(event)) { - return true; - } - - this.mouseDelayMet = !this.options.delay; - if (!this.mouseDelayMet) { - this._mouseDelayTimer = setTimeout(function() { - self.mouseDelayMet = true; - }, this.options.delay); - } - - if (this._mouseDistanceMet(event) && this._mouseDelayMet(event)) { - this._mouseStarted = (this._mouseStart(event) !== false); - if (!this._mouseStarted) { - event.preventDefault(); - return true; - } - } - - // Click event may never have fired (Gecko & Opera) - if (true === $.data(event.target, this.widgetName + '.preventClickEvent')) { - $.removeData(event.target, this.widgetName + '.preventClickEvent'); - } - - // these delegates are required to keep context - this._mouseMoveDelegate = function(event) { - return self._mouseMove(event); - }; - this._mouseUpDelegate = function(event) { - return self._mouseUp(event); - }; - $(document) - .bind('mousemove.'+this.widgetName, this._mouseMoveDelegate) - .bind('mouseup.'+this.widgetName, this._mouseUpDelegate); - - event.preventDefault(); - event.originalEvent.mouseHandled = true; - return true; - }, - - _mouseMove: function(event) { - // IE mouseup check - mouseup happened when mouse was out of window - if ($.browser.msie && !(document.documentMode >= 9) && !event.button) { - return this._mouseUp(event); - } - - if (this._mouseStarted) { - this._mouseDrag(event); - return event.preventDefault(); - } - - if (this._mouseDistanceMet(event) && this._mouseDelayMet(event)) { - this._mouseStarted = - (this._mouseStart(this._mouseDownEvent, event) !== false); - (this._mouseStarted ? this._mouseDrag(event) : this._mouseUp(event)); - } - - return !this._mouseStarted; - }, - - _mouseUp: function(event) { - $(document) - .unbind('mousemove.'+this.widgetName, this._mouseMoveDelegate) - .unbind('mouseup.'+this.widgetName, this._mouseUpDelegate); - - if (this._mouseStarted) { - this._mouseStarted = false; - - if (event.target == this._mouseDownEvent.target) { - $.data(event.target, this.widgetName + '.preventClickEvent', true); - } - - this._mouseStop(event); - } - - return false; - }, - - _mouseDistanceMet: function(event) { - return (Math.max( - Math.abs(this._mouseDownEvent.pageX - event.pageX), - Math.abs(this._mouseDownEvent.pageY - event.pageY) - ) >= this.options.distance - ); - }, - - _mouseDelayMet: function(event) { - return this.mouseDelayMet; - }, - - // These are placeholder methods, to be overriden by extending plugin - _mouseStart: function(event) {}, - _mouseDrag: function(event) {}, - _mouseStop: function(event) {}, - _mouseCapture: function(event) { return true; } -}); - -})(jQuery); -/* - * jQuery UI Draggable 1.8.15 - * - * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) - * Dual licensed under the MIT or GPL Version 2 licenses. - * http://jquery.org/license - * - * http://docs.jquery.com/UI/Draggables - * - * Depends: - * jquery.ui.core.js - * jquery.ui.mouse.js - * jquery.ui.widget.js - */ -(function( $, undefined ) { - -$.widget("ui.draggable", $.ui.mouse, { - widgetEventPrefix: "drag", - options: { - addClasses: true, - appendTo: "parent", - axis: false, - connectToSortable: false, - containment: false, - cursor: "auto", - cursorAt: false, - grid: false, - handle: false, - helper: "original", - iframeFix: false, - opacity: false, - refreshPositions: false, - revert: false, - revertDuration: 500, - scope: "default", - scroll: true, - scrollSensitivity: 20, - scrollSpeed: 20, - snap: false, - snapMode: "both", - snapTolerance: 20, - stack: false, - zIndex: false - }, - _create: function() { - - if (this.options.helper == 'original' && !(/^(?:r|a|f)/).test(this.element.css("position"))) - this.element[0].style.position = 'relative'; - - (this.options.addClasses && this.element.addClass("ui-draggable")); - (this.options.disabled && this.element.addClass("ui-draggable-disabled")); - - this._mouseInit(); - - }, - - destroy: function() { - if(!this.element.data('draggable')) return; - this.element - .removeData("draggable") - .unbind(".draggable") - .removeClass("ui-draggable" - + " ui-draggable-dragging" - + " ui-draggable-disabled"); - this._mouseDestroy(); - - return this; - }, - - _mouseCapture: function(event) { - - var o = this.options; - - // among others, prevent a drag on a resizable-handle - if (this.helper || o.disabled || $(event.target).is('.ui-resizable-handle')) - return false; - - //Quit if we're not on a valid handle - this.handle = this._getHandle(event); - if (!this.handle) - return false; - - $(o.iframeFix === true ? "iframe" : o.iframeFix).each(function() { - $('
    ') - .css({ - width: this.offsetWidth+"px", height: this.offsetHeight+"px", - position: "absolute", opacity: "0.001", zIndex: 1000 - }) - .css($(this).offset()) - .appendTo("body"); - }); - - return true; - - }, - - _mouseStart: function(event) { - - var o = this.options; - - //Create and append the visible helper - this.helper = this._createHelper(event); - - //Cache the helper size - this._cacheHelperProportions(); - - //If ddmanager is used for droppables, set the global draggable - if($.ui.ddmanager) - $.ui.ddmanager.current = this; - - /* - * - Position generation - - * This block generates everything position related - it's the core of draggables. - */ - - //Cache the margins of the original element - this._cacheMargins(); - - //Store the helper's css position - this.cssPosition = this.helper.css("position"); - this.scrollParent = this.helper.scrollParent(); - - //The element's absolute position on the page minus margins - this.offset = this.positionAbs = this.element.offset(); - this.offset = { - top: this.offset.top - this.margins.top, - left: this.offset.left - this.margins.left - }; - - $.extend(this.offset, { - click: { //Where the click happened, relative to the element - left: event.pageX - this.offset.left, - top: event.pageY - this.offset.top - }, - parent: this._getParentOffset(), - relative: this._getRelativeOffset() //This is a relative to absolute position minus the actual position calculation - only used for relative positioned helper - }); - - //Generate the original position - this.originalPosition = this.position = this._generatePosition(event); - this.originalPageX = event.pageX; - this.originalPageY = event.pageY; - - //Adjust the mouse offset relative to the helper if 'cursorAt' is supplied - (o.cursorAt && this._adjustOffsetFromHelper(o.cursorAt)); - - //Set a containment if given in the options - if(o.containment) - this._setContainment(); - - //Trigger event + callbacks - if(this._trigger("start", event) === false) { - this._clear(); - return false; - } - - //Recache the helper size - this._cacheHelperProportions(); - - //Prepare the droppable offsets - if ($.ui.ddmanager && !o.dropBehaviour) - $.ui.ddmanager.prepareOffsets(this, event); - - this.helper.addClass("ui-draggable-dragging"); - this._mouseDrag(event, true); //Execute the drag once - this causes the helper not to be visible before getting its correct position - - //If the ddmanager is used for droppables, inform the manager that dragging has started (see #5003) - if ( $.ui.ddmanager ) $.ui.ddmanager.dragStart(this, event); - - return true; - }, - - _mouseDrag: function(event, noPropagation) { - - //Compute the helpers position - this.position = this._generatePosition(event); - this.positionAbs = this._convertPositionTo("absolute"); - - //Call plugins and callbacks and use the resulting position if something is returned - if (!noPropagation) { - var ui = this._uiHash(); - if(this._trigger('drag', event, ui) === false) { - this._mouseUp({}); - return false; - } - this.position = ui.position; - } - - if(!this.options.axis || this.options.axis != "y") this.helper[0].style.left = this.position.left+'px'; - if(!this.options.axis || this.options.axis != "x") this.helper[0].style.top = this.position.top+'px'; - if($.ui.ddmanager) $.ui.ddmanager.drag(this, event); - - return false; - }, - - _mouseStop: function(event) { - - //If we are using droppables, inform the manager about the drop - var dropped = false; - if ($.ui.ddmanager && !this.options.dropBehaviour) - dropped = $.ui.ddmanager.drop(this, event); - - //if a drop comes from outside (a sortable) - if(this.dropped) { - dropped = this.dropped; - this.dropped = false; - } - - //if the original element is removed, don't bother to continue if helper is set to "original" - if((!this.element[0] || !this.element[0].parentNode) && this.options.helper == "original") - return false; - - if((this.options.revert == "invalid" && !dropped) || (this.options.revert == "valid" && dropped) || this.options.revert === true || ($.isFunction(this.options.revert) && this.options.revert.call(this.element, dropped))) { - var self = this; - $(this.helper).animate(this.originalPosition, parseInt(this.options.revertDuration, 10), function() { - if(self._trigger("stop", event) !== false) { - self._clear(); - } - }); - } else { - if(this._trigger("stop", event) !== false) { - this._clear(); - } - } - - return false; - }, - - _mouseUp: function(event) { - if (this.options.iframeFix === true) { - $("div.ui-draggable-iframeFix").each(function() { - this.parentNode.removeChild(this); - }); //Remove frame helpers - } - - //If the ddmanager is used for droppables, inform the manager that dragging has stopped (see #5003) - if( $.ui.ddmanager ) $.ui.ddmanager.dragStop(this, event); - - return $.ui.mouse.prototype._mouseUp.call(this, event); - }, - - cancel: function() { - - if(this.helper.is(".ui-draggable-dragging")) { - this._mouseUp({}); - } else { - this._clear(); - } - - return this; - - }, - - _getHandle: function(event) { - - var handle = !this.options.handle || !$(this.options.handle, this.element).length ? true : false; - $(this.options.handle, this.element) - .find("*") - .andSelf() - .each(function() { - if(this == event.target) handle = true; - }); - - return handle; - - }, - - _createHelper: function(event) { - - var o = this.options; - var helper = $.isFunction(o.helper) ? $(o.helper.apply(this.element[0], [event])) : (o.helper == 'clone' ? this.element.clone().removeAttr('id') : this.element); - - if(!helper.parents('body').length) - helper.appendTo((o.appendTo == 'parent' ? this.element[0].parentNode : o.appendTo)); - - if(helper[0] != this.element[0] && !(/(fixed|absolute)/).test(helper.css("position"))) - helper.css("position", "absolute"); - - return helper; - - }, - - _adjustOffsetFromHelper: function(obj) { - if (typeof obj == 'string') { - obj = obj.split(' '); - } - if ($.isArray(obj)) { - obj = {left: +obj[0], top: +obj[1] || 0}; - } - if ('left' in obj) { - this.offset.click.left = obj.left + this.margins.left; - } - if ('right' in obj) { - this.offset.click.left = this.helperProportions.width - obj.right + this.margins.left; - } - if ('top' in obj) { - this.offset.click.top = obj.top + this.margins.top; - } - if ('bottom' in obj) { - this.offset.click.top = this.helperProportions.height - obj.bottom + this.margins.top; - } - }, - - _getParentOffset: function() { - - //Get the offsetParent and cache its position - this.offsetParent = this.helper.offsetParent(); - var po = this.offsetParent.offset(); - - // This is a special case where we need to modify a offset calculated on start, since the following happened: - // 1. The position of the helper is absolute, so it's position is calculated based on the next positioned parent - // 2. The actual offset parent is a child of the scroll parent, and the scroll parent isn't the document, which means that - // the scroll is included in the initial calculation of the offset of the parent, and never recalculated upon drag - if(this.cssPosition == 'absolute' && this.scrollParent[0] != document && $.ui.contains(this.scrollParent[0], this.offsetParent[0])) { - po.left += this.scrollParent.scrollLeft(); - po.top += this.scrollParent.scrollTop(); - } - - if((this.offsetParent[0] == document.body) //This needs to be actually done for all browsers, since pageX/pageY includes this information - || (this.offsetParent[0].tagName && this.offsetParent[0].tagName.toLowerCase() == 'html' && $.browser.msie)) //Ugly IE fix - po = { top: 0, left: 0 }; - - return { - top: po.top + (parseInt(this.offsetParent.css("borderTopWidth"),10) || 0), - left: po.left + (parseInt(this.offsetParent.css("borderLeftWidth"),10) || 0) - }; - - }, - - _getRelativeOffset: function() { - - if(this.cssPosition == "relative") { - var p = this.element.position(); - return { - top: p.top - (parseInt(this.helper.css("top"),10) || 0) + this.scrollParent.scrollTop(), - left: p.left - (parseInt(this.helper.css("left"),10) || 0) + this.scrollParent.scrollLeft() - }; - } else { - return { top: 0, left: 0 }; - } - - }, - - _cacheMargins: function() { - this.margins = { - left: (parseInt(this.element.css("marginLeft"),10) || 0), - top: (parseInt(this.element.css("marginTop"),10) || 0), - right: (parseInt(this.element.css("marginRight"),10) || 0), - bottom: (parseInt(this.element.css("marginBottom"),10) || 0) - }; - }, - - _cacheHelperProportions: function() { - this.helperProportions = { - width: this.helper.outerWidth(), - height: this.helper.outerHeight() - }; - }, - - _setContainment: function() { - - var o = this.options; - if(o.containment == 'parent') o.containment = this.helper[0].parentNode; - if(o.containment == 'document' || o.containment == 'window') this.containment = [ - o.containment == 'document' ? 0 : $(window).scrollLeft() - this.offset.relative.left - this.offset.parent.left, - o.containment == 'document' ? 0 : $(window).scrollTop() - this.offset.relative.top - this.offset.parent.top, - (o.containment == 'document' ? 0 : $(window).scrollLeft()) + $(o.containment == 'document' ? document : window).width() - this.helperProportions.width - this.margins.left, - (o.containment == 'document' ? 0 : $(window).scrollTop()) + ($(o.containment == 'document' ? document : window).height() || document.body.parentNode.scrollHeight) - this.helperProportions.height - this.margins.top - ]; - - if(!(/^(document|window|parent)$/).test(o.containment) && o.containment.constructor != Array) { - var c = $(o.containment); - var ce = c[0]; if(!ce) return; - var co = c.offset(); - var over = ($(ce).css("overflow") != 'hidden'); - - this.containment = [ - (parseInt($(ce).css("borderLeftWidth"),10) || 0) + (parseInt($(ce).css("paddingLeft"),10) || 0), - (parseInt($(ce).css("borderTopWidth"),10) || 0) + (parseInt($(ce).css("paddingTop"),10) || 0), - (over ? Math.max(ce.scrollWidth,ce.offsetWidth) : ce.offsetWidth) - (parseInt($(ce).css("borderLeftWidth"),10) || 0) - (parseInt($(ce).css("paddingRight"),10) || 0) - this.helperProportions.width - this.margins.left - this.margins.right, - (over ? Math.max(ce.scrollHeight,ce.offsetHeight) : ce.offsetHeight) - (parseInt($(ce).css("borderTopWidth"),10) || 0) - (parseInt($(ce).css("paddingBottom"),10) || 0) - this.helperProportions.height - this.margins.top - this.margins.bottom - ]; - this.relative_container = c; - - } else if(o.containment.constructor == Array) { - this.containment = o.containment; - } - - }, - - _convertPositionTo: function(d, pos) { - - if(!pos) pos = this.position; - var mod = d == "absolute" ? 1 : -1; - var o = this.options, scroll = this.cssPosition == 'absolute' && !(this.scrollParent[0] != document && $.ui.contains(this.scrollParent[0], this.offsetParent[0])) ? this.offsetParent : this.scrollParent, scrollIsRootNode = (/(html|body)/i).test(scroll[0].tagName); - - return { - top: ( - pos.top // The absolute mouse position - + this.offset.relative.top * mod // Only for relative positioned nodes: Relative offset from element to offset parent - + this.offset.parent.top * mod // The offsetParent's offset without borders (offset + border) - - ($.browser.safari && $.browser.version < 526 && this.cssPosition == 'fixed' ? 0 : ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollTop() : ( scrollIsRootNode ? 0 : scroll.scrollTop() ) ) * mod) - ), - left: ( - pos.left // The absolute mouse position - + this.offset.relative.left * mod // Only for relative positioned nodes: Relative offset from element to offset parent - + this.offset.parent.left * mod // The offsetParent's offset without borders (offset + border) - - ($.browser.safari && $.browser.version < 526 && this.cssPosition == 'fixed' ? 0 : ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : scroll.scrollLeft() ) * mod) - ) - }; - - }, - - _generatePosition: function(event) { - - var o = this.options, scroll = this.cssPosition == 'absolute' && !(this.scrollParent[0] != document && $.ui.contains(this.scrollParent[0], this.offsetParent[0])) ? this.offsetParent : this.scrollParent, scrollIsRootNode = (/(html|body)/i).test(scroll[0].tagName); - var pageX = event.pageX; - var pageY = event.pageY; - - /* - * - Position constraining - - * Constrain the position to a mix of grid, containment. - */ - - if(this.originalPosition) { //If we are not dragging yet, we won't check for options - var containment; - if(this.containment) { - if (this.relative_container){ - var co = this.relative_container.offset(); - containment = [ this.containment[0] + co.left, - this.containment[1] + co.top, - this.containment[2] + co.left, - this.containment[3] + co.top ]; - } - else { - containment = this.containment; - } - - if(event.pageX - this.offset.click.left < containment[0]) pageX = containment[0] + this.offset.click.left; - if(event.pageY - this.offset.click.top < containment[1]) pageY = containment[1] + this.offset.click.top; - if(event.pageX - this.offset.click.left > containment[2]) pageX = containment[2] + this.offset.click.left; - if(event.pageY - this.offset.click.top > containment[3]) pageY = containment[3] + this.offset.click.top; - } - - if(o.grid) { - //Check for grid elements set to 0 to prevent divide by 0 error causing invalid argument errors in IE (see ticket #6950) - var top = o.grid[1] ? this.originalPageY + Math.round((pageY - this.originalPageY) / o.grid[1]) * o.grid[1] : this.originalPageY; - pageY = containment ? (!(top - this.offset.click.top < containment[1] || top - this.offset.click.top > containment[3]) ? top : (!(top - this.offset.click.top < containment[1]) ? top - o.grid[1] : top + o.grid[1])) : top; - - var left = o.grid[0] ? this.originalPageX + Math.round((pageX - this.originalPageX) / o.grid[0]) * o.grid[0] : this.originalPageX; - pageX = containment ? (!(left - this.offset.click.left < containment[0] || left - this.offset.click.left > containment[2]) ? left : (!(left - this.offset.click.left < containment[0]) ? left - o.grid[0] : left + o.grid[0])) : left; - } - - } - - return { - top: ( - pageY // The absolute mouse position - - this.offset.click.top // Click offset (relative to the element) - - this.offset.relative.top // Only for relative positioned nodes: Relative offset from element to offset parent - - this.offset.parent.top // The offsetParent's offset without borders (offset + border) - + ($.browser.safari && $.browser.version < 526 && this.cssPosition == 'fixed' ? 0 : ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollTop() : ( scrollIsRootNode ? 0 : scroll.scrollTop() ) )) - ), - left: ( - pageX // The absolute mouse position - - this.offset.click.left // Click offset (relative to the element) - - this.offset.relative.left // Only for relative positioned nodes: Relative offset from element to offset parent - - this.offset.parent.left // The offsetParent's offset without borders (offset + border) - + ($.browser.safari && $.browser.version < 526 && this.cssPosition == 'fixed' ? 0 : ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : scroll.scrollLeft() )) - ) - }; - - }, - - _clear: function() { - this.helper.removeClass("ui-draggable-dragging"); - if(this.helper[0] != this.element[0] && !this.cancelHelperRemoval) this.helper.remove(); - //if($.ui.ddmanager) $.ui.ddmanager.current = null; - this.helper = null; - this.cancelHelperRemoval = false; - }, - - // From now on bulk stuff - mainly helpers - - _trigger: function(type, event, ui) { - ui = ui || this._uiHash(); - $.ui.plugin.call(this, type, [event, ui]); - if(type == "drag") this.positionAbs = this._convertPositionTo("absolute"); //The absolute position has to be recalculated after plugins - return $.Widget.prototype._trigger.call(this, type, event, ui); - }, - - plugins: {}, - - _uiHash: function(event) { - return { - helper: this.helper, - position: this.position, - originalPosition: this.originalPosition, - offset: this.positionAbs - }; - } - -}); - -$.extend($.ui.draggable, { - version: "1.8.15" -}); - -$.ui.plugin.add("draggable", "connectToSortable", { - start: function(event, ui) { - - var inst = $(this).data("draggable"), o = inst.options, - uiSortable = $.extend({}, ui, { item: inst.element }); - inst.sortables = []; - $(o.connectToSortable).each(function() { - var sortable = $.data(this, 'sortable'); - if (sortable && !sortable.options.disabled) { - inst.sortables.push({ - instance: sortable, - shouldRevert: sortable.options.revert - }); - sortable.refreshPositions(); // Call the sortable's refreshPositions at drag start to refresh the containerCache since the sortable container cache is used in drag and needs to be up to date (this will ensure it's initialised as well as being kept in step with any changes that might have happened on the page). - sortable._trigger("activate", event, uiSortable); - } - }); - - }, - stop: function(event, ui) { - - //If we are still over the sortable, we fake the stop event of the sortable, but also remove helper - var inst = $(this).data("draggable"), - uiSortable = $.extend({}, ui, { item: inst.element }); - - $.each(inst.sortables, function() { - if(this.instance.isOver) { - - this.instance.isOver = 0; - - inst.cancelHelperRemoval = true; //Don't remove the helper in the draggable instance - this.instance.cancelHelperRemoval = false; //Remove it in the sortable instance (so sortable plugins like revert still work) - - //The sortable revert is supported, and we have to set a temporary dropped variable on the draggable to support revert: 'valid/invalid' - if(this.shouldRevert) this.instance.options.revert = true; - - //Trigger the stop of the sortable - this.instance._mouseStop(event); - - this.instance.options.helper = this.instance.options._helper; - - //If the helper has been the original item, restore properties in the sortable - if(inst.options.helper == 'original') - this.instance.currentItem.css({ top: 'auto', left: 'auto' }); - - } else { - this.instance.cancelHelperRemoval = false; //Remove the helper in the sortable instance - this.instance._trigger("deactivate", event, uiSortable); - } - - }); - - }, - drag: function(event, ui) { - - var inst = $(this).data("draggable"), self = this; - - var checkPos = function(o) { - var dyClick = this.offset.click.top, dxClick = this.offset.click.left; - var helperTop = this.positionAbs.top, helperLeft = this.positionAbs.left; - var itemHeight = o.height, itemWidth = o.width; - var itemTop = o.top, itemLeft = o.left; - - return $.ui.isOver(helperTop + dyClick, helperLeft + dxClick, itemTop, itemLeft, itemHeight, itemWidth); - }; - - $.each(inst.sortables, function(i) { - - //Copy over some variables to allow calling the sortable's native _intersectsWith - this.instance.positionAbs = inst.positionAbs; - this.instance.helperProportions = inst.helperProportions; - this.instance.offset.click = inst.offset.click; - - if(this.instance._intersectsWith(this.instance.containerCache)) { - - //If it intersects, we use a little isOver variable and set it once, so our move-in stuff gets fired only once - if(!this.instance.isOver) { - - this.instance.isOver = 1; - //Now we fake the start of dragging for the sortable instance, - //by cloning the list group item, appending it to the sortable and using it as inst.currentItem - //We can then fire the start event of the sortable with our passed browser event, and our own helper (so it doesn't create a new one) - this.instance.currentItem = $(self).clone().removeAttr('id').appendTo(this.instance.element).data("sortable-item", true); - this.instance.options._helper = this.instance.options.helper; //Store helper option to later restore it - this.instance.options.helper = function() { return ui.helper[0]; }; - - event.target = this.instance.currentItem[0]; - this.instance._mouseCapture(event, true); - this.instance._mouseStart(event, true, true); - - //Because the browser event is way off the new appended portlet, we modify a couple of variables to reflect the changes - this.instance.offset.click.top = inst.offset.click.top; - this.instance.offset.click.left = inst.offset.click.left; - this.instance.offset.parent.left -= inst.offset.parent.left - this.instance.offset.parent.left; - this.instance.offset.parent.top -= inst.offset.parent.top - this.instance.offset.parent.top; - - inst._trigger("toSortable", event); - inst.dropped = this.instance.element; //draggable revert needs that - //hack so receive/update callbacks work (mostly) - inst.currentItem = inst.element; - this.instance.fromOutside = inst; - - } - - //Provided we did all the previous steps, we can fire the drag event of the sortable on every draggable drag, when it intersects with the sortable - if(this.instance.currentItem) this.instance._mouseDrag(event); - - } else { - - //If it doesn't intersect with the sortable, and it intersected before, - //we fake the drag stop of the sortable, but make sure it doesn't remove the helper by using cancelHelperRemoval - if(this.instance.isOver) { - - this.instance.isOver = 0; - this.instance.cancelHelperRemoval = true; - - //Prevent reverting on this forced stop - this.instance.options.revert = false; - - // The out event needs to be triggered independently - this.instance._trigger('out', event, this.instance._uiHash(this.instance)); - - this.instance._mouseStop(event, true); - this.instance.options.helper = this.instance.options._helper; - - //Now we remove our currentItem, the list group clone again, and the placeholder, and animate the helper back to it's original size - this.instance.currentItem.remove(); - if(this.instance.placeholder) this.instance.placeholder.remove(); - - inst._trigger("fromSortable", event); - inst.dropped = false; //draggable revert needs that - } - - }; - - }); - - } -}); - -$.ui.plugin.add("draggable", "cursor", { - start: function(event, ui) { - var t = $('body'), o = $(this).data('draggable').options; - if (t.css("cursor")) o._cursor = t.css("cursor"); - t.css("cursor", o.cursor); - }, - stop: function(event, ui) { - var o = $(this).data('draggable').options; - if (o._cursor) $('body').css("cursor", o._cursor); - } -}); - -$.ui.plugin.add("draggable", "opacity", { - start: function(event, ui) { - var t = $(ui.helper), o = $(this).data('draggable').options; - if(t.css("opacity")) o._opacity = t.css("opacity"); - t.css('opacity', o.opacity); - }, - stop: function(event, ui) { - var o = $(this).data('draggable').options; - if(o._opacity) $(ui.helper).css('opacity', o._opacity); - } -}); - -$.ui.plugin.add("draggable", "scroll", { - start: function(event, ui) { - var i = $(this).data("draggable"); - if(i.scrollParent[0] != document && i.scrollParent[0].tagName != 'HTML') i.overflowOffset = i.scrollParent.offset(); - }, - drag: function(event, ui) { - - var i = $(this).data("draggable"), o = i.options, scrolled = false; - - if(i.scrollParent[0] != document && i.scrollParent[0].tagName != 'HTML') { - - if(!o.axis || o.axis != 'x') { - if((i.overflowOffset.top + i.scrollParent[0].offsetHeight) - event.pageY < o.scrollSensitivity) - i.scrollParent[0].scrollTop = scrolled = i.scrollParent[0].scrollTop + o.scrollSpeed; - else if(event.pageY - i.overflowOffset.top < o.scrollSensitivity) - i.scrollParent[0].scrollTop = scrolled = i.scrollParent[0].scrollTop - o.scrollSpeed; - } - - if(!o.axis || o.axis != 'y') { - if((i.overflowOffset.left + i.scrollParent[0].offsetWidth) - event.pageX < o.scrollSensitivity) - i.scrollParent[0].scrollLeft = scrolled = i.scrollParent[0].scrollLeft + o.scrollSpeed; - else if(event.pageX - i.overflowOffset.left < o.scrollSensitivity) - i.scrollParent[0].scrollLeft = scrolled = i.scrollParent[0].scrollLeft - o.scrollSpeed; - } - - } else { - - if(!o.axis || o.axis != 'x') { - if(event.pageY - $(document).scrollTop() < o.scrollSensitivity) - scrolled = $(document).scrollTop($(document).scrollTop() - o.scrollSpeed); - else if($(window).height() - (event.pageY - $(document).scrollTop()) < o.scrollSensitivity) - scrolled = $(document).scrollTop($(document).scrollTop() + o.scrollSpeed); - } - - if(!o.axis || o.axis != 'y') { - if(event.pageX - $(document).scrollLeft() < o.scrollSensitivity) - scrolled = $(document).scrollLeft($(document).scrollLeft() - o.scrollSpeed); - else if($(window).width() - (event.pageX - $(document).scrollLeft()) < o.scrollSensitivity) - scrolled = $(document).scrollLeft($(document).scrollLeft() + o.scrollSpeed); - } - - } - - if(scrolled !== false && $.ui.ddmanager && !o.dropBehaviour) - $.ui.ddmanager.prepareOffsets(i, event); - - } -}); - -$.ui.plugin.add("draggable", "snap", { - start: function(event, ui) { - - var i = $(this).data("draggable"), o = i.options; - i.snapElements = []; - - $(o.snap.constructor != String ? ( o.snap.items || ':data(draggable)' ) : o.snap).each(function() { - var $t = $(this); var $o = $t.offset(); - if(this != i.element[0]) i.snapElements.push({ - item: this, - width: $t.outerWidth(), height: $t.outerHeight(), - top: $o.top, left: $o.left - }); - }); - - }, - drag: function(event, ui) { - - var inst = $(this).data("draggable"), o = inst.options; - var d = o.snapTolerance; - - var x1 = ui.offset.left, x2 = x1 + inst.helperProportions.width, - y1 = ui.offset.top, y2 = y1 + inst.helperProportions.height; - - for (var i = inst.snapElements.length - 1; i >= 0; i--){ - - var l = inst.snapElements[i].left, r = l + inst.snapElements[i].width, - t = inst.snapElements[i].top, b = t + inst.snapElements[i].height; - - //Yes, I know, this is insane ;) - if(!((l-d < x1 && x1 < r+d && t-d < y1 && y1 < b+d) || (l-d < x1 && x1 < r+d && t-d < y2 && y2 < b+d) || (l-d < x2 && x2 < r+d && t-d < y1 && y1 < b+d) || (l-d < x2 && x2 < r+d && t-d < y2 && y2 < b+d))) { - if(inst.snapElements[i].snapping) (inst.options.snap.release && inst.options.snap.release.call(inst.element, event, $.extend(inst._uiHash(), { snapItem: inst.snapElements[i].item }))); - inst.snapElements[i].snapping = false; - continue; - } - - if(o.snapMode != 'inner') { - var ts = Math.abs(t - y2) <= d; - var bs = Math.abs(b - y1) <= d; - var ls = Math.abs(l - x2) <= d; - var rs = Math.abs(r - x1) <= d; - if(ts) ui.position.top = inst._convertPositionTo("relative", { top: t - inst.helperProportions.height, left: 0 }).top - inst.margins.top; - if(bs) ui.position.top = inst._convertPositionTo("relative", { top: b, left: 0 }).top - inst.margins.top; - if(ls) ui.position.left = inst._convertPositionTo("relative", { top: 0, left: l - inst.helperProportions.width }).left - inst.margins.left; - if(rs) ui.position.left = inst._convertPositionTo("relative", { top: 0, left: r }).left - inst.margins.left; - } - - var first = (ts || bs || ls || rs); - - if(o.snapMode != 'outer') { - var ts = Math.abs(t - y1) <= d; - var bs = Math.abs(b - y2) <= d; - var ls = Math.abs(l - x1) <= d; - var rs = Math.abs(r - x2) <= d; - if(ts) ui.position.top = inst._convertPositionTo("relative", { top: t, left: 0 }).top - inst.margins.top; - if(bs) ui.position.top = inst._convertPositionTo("relative", { top: b - inst.helperProportions.height, left: 0 }).top - inst.margins.top; - if(ls) ui.position.left = inst._convertPositionTo("relative", { top: 0, left: l }).left - inst.margins.left; - if(rs) ui.position.left = inst._convertPositionTo("relative", { top: 0, left: r - inst.helperProportions.width }).left - inst.margins.left; - } - - if(!inst.snapElements[i].snapping && (ts || bs || ls || rs || first)) - (inst.options.snap.snap && inst.options.snap.snap.call(inst.element, event, $.extend(inst._uiHash(), { snapItem: inst.snapElements[i].item }))); - inst.snapElements[i].snapping = (ts || bs || ls || rs || first); - - }; - - } -}); - -$.ui.plugin.add("draggable", "stack", { - start: function(event, ui) { - - var o = $(this).data("draggable").options; - - var group = $.makeArray($(o.stack)).sort(function(a,b) { - return (parseInt($(a).css("zIndex"),10) || 0) - (parseInt($(b).css("zIndex"),10) || 0); - }); - if (!group.length) { return; } - - var min = parseInt(group[0].style.zIndex) || 0; - $(group).each(function(i) { - this.style.zIndex = min + i; - }); - - this[0].style.zIndex = min + group.length; - - } -}); - -$.ui.plugin.add("draggable", "zIndex", { - start: function(event, ui) { - var t = $(ui.helper), o = $(this).data("draggable").options; - if(t.css("zIndex")) o._zIndex = t.css("zIndex"); - t.css('zIndex', o.zIndex); - }, - stop: function(event, ui) { - var o = $(this).data("draggable").options; - if(o._zIndex) $(ui.helper).css('zIndex', o._zIndex); - } -}); - -})(jQuery); -/* - * jQuery UI Droppable 1.8.15 - * - * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) - * Dual licensed under the MIT or GPL Version 2 licenses. - * http://jquery.org/license - * - * http://docs.jquery.com/UI/Droppables - * - * Depends: - * jquery.ui.core.js - * jquery.ui.widget.js - * jquery.ui.mouse.js - * jquery.ui.draggable.js - */ -(function( $, undefined ) { - -$.widget("ui.droppable", { - widgetEventPrefix: "drop", - options: { - accept: '*', - activeClass: false, - addClasses: true, - greedy: false, - hoverClass: false, - scope: 'default', - tolerance: 'intersect' - }, - _create: function() { - - var o = this.options, accept = o.accept; - this.isover = 0; this.isout = 1; - - this.accept = $.isFunction(accept) ? accept : function(d) { - return d.is(accept); - }; - - //Store the droppable's proportions - this.proportions = { width: this.element[0].offsetWidth, height: this.element[0].offsetHeight }; - - // Add the reference and positions to the manager - $.ui.ddmanager.droppables[o.scope] = $.ui.ddmanager.droppables[o.scope] || []; - $.ui.ddmanager.droppables[o.scope].push(this); - - (o.addClasses && this.element.addClass("ui-droppable")); - - }, - - destroy: function() { - var drop = $.ui.ddmanager.droppables[this.options.scope]; - for ( var i = 0; i < drop.length; i++ ) - if ( drop[i] == this ) - drop.splice(i, 1); - - this.element - .removeClass("ui-droppable ui-droppable-disabled") - .removeData("droppable") - .unbind(".droppable"); - - return this; - }, - - _setOption: function(key, value) { - - if(key == 'accept') { - this.accept = $.isFunction(value) ? value : function(d) { - return d.is(value); - }; - } - $.Widget.prototype._setOption.apply(this, arguments); - }, - - _activate: function(event) { - var draggable = $.ui.ddmanager.current; - if(this.options.activeClass) this.element.addClass(this.options.activeClass); - (draggable && this._trigger('activate', event, this.ui(draggable))); - }, - - _deactivate: function(event) { - var draggable = $.ui.ddmanager.current; - if(this.options.activeClass) this.element.removeClass(this.options.activeClass); - (draggable && this._trigger('deactivate', event, this.ui(draggable))); - }, - - _over: function(event) { - - var draggable = $.ui.ddmanager.current; - if (!draggable || (draggable.currentItem || draggable.element)[0] == this.element[0]) return; // Bail if draggable and droppable are same element - - if (this.accept.call(this.element[0],(draggable.currentItem || draggable.element))) { - if(this.options.hoverClass) this.element.addClass(this.options.hoverClass); - this._trigger('over', event, this.ui(draggable)); - } - - }, - - _out: function(event) { - - var draggable = $.ui.ddmanager.current; - if (!draggable || (draggable.currentItem || draggable.element)[0] == this.element[0]) return; // Bail if draggable and droppable are same element - - if (this.accept.call(this.element[0],(draggable.currentItem || draggable.element))) { - if(this.options.hoverClass) this.element.removeClass(this.options.hoverClass); - this._trigger('out', event, this.ui(draggable)); - } - - }, - - _drop: function(event,custom) { - - var draggable = custom || $.ui.ddmanager.current; - if (!draggable || (draggable.currentItem || draggable.element)[0] == this.element[0]) return false; // Bail if draggable and droppable are same element - - var childrenIntersection = false; - this.element.find(":data(droppable)").not(".ui-draggable-dragging").each(function() { - var inst = $.data(this, 'droppable'); - if( - inst.options.greedy - && !inst.options.disabled - && inst.options.scope == draggable.options.scope - && inst.accept.call(inst.element[0], (draggable.currentItem || draggable.element)) - && $.ui.intersect(draggable, $.extend(inst, { offset: inst.element.offset() }), inst.options.tolerance) - ) { childrenIntersection = true; return false; } - }); - if(childrenIntersection) return false; - - if(this.accept.call(this.element[0],(draggable.currentItem || draggable.element))) { - if(this.options.activeClass) this.element.removeClass(this.options.activeClass); - if(this.options.hoverClass) this.element.removeClass(this.options.hoverClass); - this._trigger('drop', event, this.ui(draggable)); - return this.element; - } - - return false; - - }, - - ui: function(c) { - return { - draggable: (c.currentItem || c.element), - helper: c.helper, - position: c.position, - offset: c.positionAbs - }; - } - -}); - -$.extend($.ui.droppable, { - version: "1.8.15" -}); - -$.ui.intersect = function(draggable, droppable, toleranceMode) { - - if (!droppable.offset) return false; - - var x1 = (draggable.positionAbs || draggable.position.absolute).left, x2 = x1 + draggable.helperProportions.width, - y1 = (draggable.positionAbs || draggable.position.absolute).top, y2 = y1 + draggable.helperProportions.height; - var l = droppable.offset.left, r = l + droppable.proportions.width, - t = droppable.offset.top, b = t + droppable.proportions.height; - - switch (toleranceMode) { - case 'fit': - return (l <= x1 && x2 <= r - && t <= y1 && y2 <= b); - break; - case 'intersect': - return (l < x1 + (draggable.helperProportions.width / 2) // Right Half - && x2 - (draggable.helperProportions.width / 2) < r // Left Half - && t < y1 + (draggable.helperProportions.height / 2) // Bottom Half - && y2 - (draggable.helperProportions.height / 2) < b ); // Top Half - break; - case 'pointer': - var draggableLeft = ((draggable.positionAbs || draggable.position.absolute).left + (draggable.clickOffset || draggable.offset.click).left), - draggableTop = ((draggable.positionAbs || draggable.position.absolute).top + (draggable.clickOffset || draggable.offset.click).top), - isOver = $.ui.isOver(draggableTop, draggableLeft, t, l, droppable.proportions.height, droppable.proportions.width); - return isOver; - break; - case 'touch': - return ( - (y1 >= t && y1 <= b) || // Top edge touching - (y2 >= t && y2 <= b) || // Bottom edge touching - (y1 < t && y2 > b) // Surrounded vertically - ) && ( - (x1 >= l && x1 <= r) || // Left edge touching - (x2 >= l && x2 <= r) || // Right edge touching - (x1 < l && x2 > r) // Surrounded horizontally - ); - break; - default: - return false; - break; - } - -}; - -/* - This manager tracks offsets of draggables and droppables -*/ -$.ui.ddmanager = { - current: null, - droppables: { 'default': [] }, - prepareOffsets: function(t, event) { - - var m = $.ui.ddmanager.droppables[t.options.scope] || []; - var type = event ? event.type : null; // workaround for #2317 - var list = (t.currentItem || t.element).find(":data(droppable)").andSelf(); - - droppablesLoop: for (var i = 0; i < m.length; i++) { - - if(m[i].options.disabled || (t && !m[i].accept.call(m[i].element[0],(t.currentItem || t.element)))) continue; //No disabled and non-accepted - for (var j=0; j < list.length; j++) { if(list[j] == m[i].element[0]) { m[i].proportions.height = 0; continue droppablesLoop; } }; //Filter out elements in the current dragged item - m[i].visible = m[i].element.css("display") != "none"; if(!m[i].visible) continue; //If the element is not visible, continue - - if(type == "mousedown") m[i]._activate.call(m[i], event); //Activate the droppable if used directly from draggables - - m[i].offset = m[i].element.offset(); - m[i].proportions = { width: m[i].element[0].offsetWidth, height: m[i].element[0].offsetHeight }; - - } - - }, - drop: function(draggable, event) { - - var dropped = false; - $.each($.ui.ddmanager.droppables[draggable.options.scope] || [], function() { - - if(!this.options) return; - if (!this.options.disabled && this.visible && $.ui.intersect(draggable, this, this.options.tolerance)) - dropped = dropped || this._drop.call(this, event); - - if (!this.options.disabled && this.visible && this.accept.call(this.element[0],(draggable.currentItem || draggable.element))) { - this.isout = 1; this.isover = 0; - this._deactivate.call(this, event); - } - - }); - return dropped; - - }, - dragStart: function( draggable, event ) { - //Listen for scrolling so that if the dragging causes scrolling the position of the droppables can be recalculated (see #5003) - draggable.element.parentsUntil( "body" ).bind( "scroll.droppable", function() { - if( !draggable.options.refreshPositions ) $.ui.ddmanager.prepareOffsets( draggable, event ); - }); - }, - drag: function(draggable, event) { - - //If you have a highly dynamic page, you might try this option. It renders positions every time you move the mouse. - if(draggable.options.refreshPositions) $.ui.ddmanager.prepareOffsets(draggable, event); - - //Run through all droppables and check their positions based on specific tolerance options - $.each($.ui.ddmanager.droppables[draggable.options.scope] || [], function() { - - if(this.options.disabled || this.greedyChild || !this.visible) return; - var intersects = $.ui.intersect(draggable, this, this.options.tolerance); - - var c = !intersects && this.isover == 1 ? 'isout' : (intersects && this.isover == 0 ? 'isover' : null); - if(!c) return; - - var parentInstance; - if (this.options.greedy) { - var parent = this.element.parents(':data(droppable):eq(0)'); - if (parent.length) { - parentInstance = $.data(parent[0], 'droppable'); - parentInstance.greedyChild = (c == 'isover' ? 1 : 0); - } - } - - // we just moved into a greedy child - if (parentInstance && c == 'isover') { - parentInstance['isover'] = 0; - parentInstance['isout'] = 1; - parentInstance._out.call(parentInstance, event); - } - - this[c] = 1; this[c == 'isout' ? 'isover' : 'isout'] = 0; - this[c == "isover" ? "_over" : "_out"].call(this, event); - - // we just moved out of a greedy child - if (parentInstance && c == 'isout') { - parentInstance['isout'] = 0; - parentInstance['isover'] = 1; - parentInstance._over.call(parentInstance, event); - } - }); - - }, - dragStop: function( draggable, event ) { - draggable.element.parentsUntil( "body" ).unbind( "scroll.droppable" ); - //Call prepareOffsets one final time since IE does not fire return scroll events when overflow was caused by drag (see #5003) - if( !draggable.options.refreshPositions ) $.ui.ddmanager.prepareOffsets( draggable, event ); - } -}; - -})(jQuery); -/* - * jQuery UI Resizable 1.8.15 - * - * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) - * Dual licensed under the MIT or GPL Version 2 licenses. - * http://jquery.org/license - * - * http://docs.jquery.com/UI/Resizables - * - * Depends: - * jquery.ui.core.js - * jquery.ui.mouse.js - * jquery.ui.widget.js - */ -(function( $, undefined ) { - -$.widget("ui.resizable", $.ui.mouse, { - widgetEventPrefix: "resize", - options: { - alsoResize: false, - animate: false, - animateDuration: "slow", - animateEasing: "swing", - aspectRatio: false, - autoHide: false, - containment: false, - ghost: false, - grid: false, - handles: "e,s,se", - helper: false, - maxHeight: null, - maxWidth: null, - minHeight: 10, - minWidth: 10, - zIndex: 1000 - }, - _create: function() { - - var self = this, o = this.options; - this.element.addClass("ui-resizable"); - - $.extend(this, { - _aspectRatio: !!(o.aspectRatio), - aspectRatio: o.aspectRatio, - originalElement: this.element, - _proportionallyResizeElements: [], - _helper: o.helper || o.ghost || o.animate ? o.helper || 'ui-resizable-helper' : null - }); - - //Wrap the element if it cannot hold child nodes - if(this.element[0].nodeName.match(/canvas|textarea|input|select|button|img/i)) { - - //Opera fix for relative positioning - if (/relative/.test(this.element.css('position')) && $.browser.opera) - this.element.css({ position: 'relative', top: 'auto', left: 'auto' }); - - //Create a wrapper element and set the wrapper to the new current internal element - this.element.wrap( - $('
    ').css({ - position: this.element.css('position'), - width: this.element.outerWidth(), - height: this.element.outerHeight(), - top: this.element.css('top'), - left: this.element.css('left') - }) - ); - - //Overwrite the original this.element - this.element = this.element.parent().data( - "resizable", this.element.data('resizable') - ); - - this.elementIsWrapper = true; - - //Move margins to the wrapper - this.element.css({ marginLeft: this.originalElement.css("marginLeft"), marginTop: this.originalElement.css("marginTop"), marginRight: this.originalElement.css("marginRight"), marginBottom: this.originalElement.css("marginBottom") }); - this.originalElement.css({ marginLeft: 0, marginTop: 0, marginRight: 0, marginBottom: 0}); - - //Prevent Safari textarea resize - this.originalResizeStyle = this.originalElement.css('resize'); - this.originalElement.css('resize', 'none'); - - //Push the actual element to our proportionallyResize internal array - this._proportionallyResizeElements.push(this.originalElement.css({ position: 'static', zoom: 1, display: 'block' })); - - // avoid IE jump (hard set the margin) - this.originalElement.css({ margin: this.originalElement.css('margin') }); - - // fix handlers offset - this._proportionallyResize(); - - } - - this.handles = o.handles || (!$('.ui-resizable-handle', this.element).length ? "e,s,se" : { n: '.ui-resizable-n', e: '.ui-resizable-e', s: '.ui-resizable-s', w: '.ui-resizable-w', se: '.ui-resizable-se', sw: '.ui-resizable-sw', ne: '.ui-resizable-ne', nw: '.ui-resizable-nw' }); - if(this.handles.constructor == String) { - - if(this.handles == 'all') this.handles = 'n,e,s,w,se,sw,ne,nw'; - var n = this.handles.split(","); this.handles = {}; - - for(var i = 0; i < n.length; i++) { - - var handle = $.trim(n[i]), hname = 'ui-resizable-'+handle; - var axis = $('
    '); - - // increase zIndex of sw, se, ne, nw axis - //TODO : this modifies original option - if(/sw|se|ne|nw/.test(handle)) axis.css({ zIndex: ++o.zIndex }); - - //TODO : What's going on here? - if ('se' == handle) { - axis.addClass('ui-icon ui-icon-gripsmall-diagonal-se'); - }; - - //Insert into internal handles object and append to element - this.handles[handle] = '.ui-resizable-'+handle; - this.element.append(axis); - } - - } - - this._renderAxis = function(target) { - - target = target || this.element; - - for(var i in this.handles) { - - if(this.handles[i].constructor == String) - this.handles[i] = $(this.handles[i], this.element).show(); - - //Apply pad to wrapper element, needed to fix axis position (textarea, inputs, scrolls) - if (this.elementIsWrapper && this.originalElement[0].nodeName.match(/textarea|input|select|button/i)) { - - var axis = $(this.handles[i], this.element), padWrapper = 0; - - //Checking the correct pad and border - padWrapper = /sw|ne|nw|se|n|s/.test(i) ? axis.outerHeight() : axis.outerWidth(); - - //The padding type i have to apply... - var padPos = [ 'padding', - /ne|nw|n/.test(i) ? 'Top' : - /se|sw|s/.test(i) ? 'Bottom' : - /^e$/.test(i) ? 'Right' : 'Left' ].join(""); - - target.css(padPos, padWrapper); - - this._proportionallyResize(); - - } - - //TODO: What's that good for? There's not anything to be executed left - if(!$(this.handles[i]).length) - continue; - - } - }; - - //TODO: make renderAxis a prototype function - this._renderAxis(this.element); - - this._handles = $('.ui-resizable-handle', this.element) - .disableSelection(); - - //Matching axis name - this._handles.mouseover(function() { - if (!self.resizing) { - if (this.className) - var axis = this.className.match(/ui-resizable-(se|sw|ne|nw|n|e|s|w)/i); - //Axis, default = se - self.axis = axis && axis[1] ? axis[1] : 'se'; - } - }); - - //If we want to auto hide the elements - if (o.autoHide) { - this._handles.hide(); - $(this.element) - .addClass("ui-resizable-autohide") - .hover(function() { - if (o.disabled) return; - $(this).removeClass("ui-resizable-autohide"); - self._handles.show(); - }, - function(){ - if (o.disabled) return; - if (!self.resizing) { - $(this).addClass("ui-resizable-autohide"); - self._handles.hide(); - } - }); - } - - //Initialize the mouse interaction - this._mouseInit(); - - }, - - destroy: function() { - - this._mouseDestroy(); - - var _destroy = function(exp) { - $(exp).removeClass("ui-resizable ui-resizable-disabled ui-resizable-resizing") - .removeData("resizable").unbind(".resizable").find('.ui-resizable-handle').remove(); - }; - - //TODO: Unwrap at same DOM position - if (this.elementIsWrapper) { - _destroy(this.element); - var wrapper = this.element; - wrapper.after( - this.originalElement.css({ - position: wrapper.css('position'), - width: wrapper.outerWidth(), - height: wrapper.outerHeight(), - top: wrapper.css('top'), - left: wrapper.css('left') - }) - ).remove(); - } - - this.originalElement.css('resize', this.originalResizeStyle); - _destroy(this.originalElement); - - return this; - }, - - _mouseCapture: function(event) { - var handle = false; - for (var i in this.handles) { - if ($(this.handles[i])[0] == event.target) { - handle = true; - } - } - - return !this.options.disabled && handle; - }, - - _mouseStart: function(event) { - - var o = this.options, iniPos = this.element.position(), el = this.element; - - this.resizing = true; - this.documentScroll = { top: $(document).scrollTop(), left: $(document).scrollLeft() }; - - // bugfix for http://dev.jquery.com/ticket/1749 - if (el.is('.ui-draggable') || (/absolute/).test(el.css('position'))) { - el.css({ position: 'absolute', top: iniPos.top, left: iniPos.left }); - } - - //Opera fixing relative position - if ($.browser.opera && (/relative/).test(el.css('position'))) - el.css({ position: 'relative', top: 'auto', left: 'auto' }); - - this._renderProxy(); - - var curleft = num(this.helper.css('left')), curtop = num(this.helper.css('top')); - - if (o.containment) { - curleft += $(o.containment).scrollLeft() || 0; - curtop += $(o.containment).scrollTop() || 0; - } - - //Store needed variables - this.offset = this.helper.offset(); - this.position = { left: curleft, top: curtop }; - this.size = this._helper ? { width: el.outerWidth(), height: el.outerHeight() } : { width: el.width(), height: el.height() }; - this.originalSize = this._helper ? { width: el.outerWidth(), height: el.outerHeight() } : { width: el.width(), height: el.height() }; - this.originalPosition = { left: curleft, top: curtop }; - this.sizeDiff = { width: el.outerWidth() - el.width(), height: el.outerHeight() - el.height() }; - this.originalMousePosition = { left: event.pageX, top: event.pageY }; - - //Aspect Ratio - this.aspectRatio = (typeof o.aspectRatio == 'number') ? o.aspectRatio : ((this.originalSize.width / this.originalSize.height) || 1); - - var cursor = $('.ui-resizable-' + this.axis).css('cursor'); - $('body').css('cursor', cursor == 'auto' ? this.axis + '-resize' : cursor); - - el.addClass("ui-resizable-resizing"); - this._propagate("start", event); - return true; - }, - - _mouseDrag: function(event) { - - //Increase performance, avoid regex - var el = this.helper, o = this.options, props = {}, - self = this, smp = this.originalMousePosition, a = this.axis; - - var dx = (event.pageX-smp.left)||0, dy = (event.pageY-smp.top)||0; - var trigger = this._change[a]; - if (!trigger) return false; - - // Calculate the attrs that will be change - var data = trigger.apply(this, [event, dx, dy]), ie6 = $.browser.msie && $.browser.version < 7, csdif = this.sizeDiff; - - // Put this in the mouseDrag handler since the user can start pressing shift while resizing - this._updateVirtualBoundaries(event.shiftKey); - if (this._aspectRatio || event.shiftKey) - data = this._updateRatio(data, event); - - data = this._respectSize(data, event); - - // plugins callbacks need to be called first - this._propagate("resize", event); - - el.css({ - top: this.position.top + "px", left: this.position.left + "px", - width: this.size.width + "px", height: this.size.height + "px" - }); - - if (!this._helper && this._proportionallyResizeElements.length) - this._proportionallyResize(); - - this._updateCache(data); - - // calling the user callback at the end - this._trigger('resize', event, this.ui()); - - return false; - }, - - _mouseStop: function(event) { - - this.resizing = false; - var o = this.options, self = this; - - if(this._helper) { - var pr = this._proportionallyResizeElements, ista = pr.length && (/textarea/i).test(pr[0].nodeName), - soffseth = ista && $.ui.hasScroll(pr[0], 'left') /* TODO - jump height */ ? 0 : self.sizeDiff.height, - soffsetw = ista ? 0 : self.sizeDiff.width; - - var s = { width: (self.helper.width() - soffsetw), height: (self.helper.height() - soffseth) }, - left = (parseInt(self.element.css('left'), 10) + (self.position.left - self.originalPosition.left)) || null, - top = (parseInt(self.element.css('top'), 10) + (self.position.top - self.originalPosition.top)) || null; - - if (!o.animate) - this.element.css($.extend(s, { top: top, left: left })); - - self.helper.height(self.size.height); - self.helper.width(self.size.width); - - if (this._helper && !o.animate) this._proportionallyResize(); - } - - $('body').css('cursor', 'auto'); - - this.element.removeClass("ui-resizable-resizing"); - - this._propagate("stop", event); - - if (this._helper) this.helper.remove(); - return false; - - }, - - _updateVirtualBoundaries: function(forceAspectRatio) { - var o = this.options, pMinWidth, pMaxWidth, pMinHeight, pMaxHeight, b; - - b = { - minWidth: isNumber(o.minWidth) ? o.minWidth : 0, - maxWidth: isNumber(o.maxWidth) ? o.maxWidth : Infinity, - minHeight: isNumber(o.minHeight) ? o.minHeight : 0, - maxHeight: isNumber(o.maxHeight) ? o.maxHeight : Infinity - }; - - if(this._aspectRatio || forceAspectRatio) { - // We want to create an enclosing box whose aspect ration is the requested one - // First, compute the "projected" size for each dimension based on the aspect ratio and other dimension - pMinWidth = b.minHeight * this.aspectRatio; - pMinHeight = b.minWidth / this.aspectRatio; - pMaxWidth = b.maxHeight * this.aspectRatio; - pMaxHeight = b.maxWidth / this.aspectRatio; - - if(pMinWidth > b.minWidth) b.minWidth = pMinWidth; - if(pMinHeight > b.minHeight) b.minHeight = pMinHeight; - if(pMaxWidth < b.maxWidth) b.maxWidth = pMaxWidth; - if(pMaxHeight < b.maxHeight) b.maxHeight = pMaxHeight; - } - this._vBoundaries = b; - }, - - _updateCache: function(data) { - var o = this.options; - this.offset = this.helper.offset(); - if (isNumber(data.left)) this.position.left = data.left; - if (isNumber(data.top)) this.position.top = data.top; - if (isNumber(data.height)) this.size.height = data.height; - if (isNumber(data.width)) this.size.width = data.width; - }, - - _updateRatio: function(data, event) { - - var o = this.options, cpos = this.position, csize = this.size, a = this.axis; - - if (isNumber(data.height)) data.width = (data.height * this.aspectRatio); - else if (isNumber(data.width)) data.height = (data.width / this.aspectRatio); - - if (a == 'sw') { - data.left = cpos.left + (csize.width - data.width); - data.top = null; - } - if (a == 'nw') { - data.top = cpos.top + (csize.height - data.height); - data.left = cpos.left + (csize.width - data.width); - } - - return data; - }, - - _respectSize: function(data, event) { - - var el = this.helper, o = this._vBoundaries, pRatio = this._aspectRatio || event.shiftKey, a = this.axis, - ismaxw = isNumber(data.width) && o.maxWidth && (o.maxWidth < data.width), ismaxh = isNumber(data.height) && o.maxHeight && (o.maxHeight < data.height), - isminw = isNumber(data.width) && o.minWidth && (o.minWidth > data.width), isminh = isNumber(data.height) && o.minHeight && (o.minHeight > data.height); - - if (isminw) data.width = o.minWidth; - if (isminh) data.height = o.minHeight; - if (ismaxw) data.width = o.maxWidth; - if (ismaxh) data.height = o.maxHeight; - - var dw = this.originalPosition.left + this.originalSize.width, dh = this.position.top + this.size.height; - var cw = /sw|nw|w/.test(a), ch = /nw|ne|n/.test(a); - - if (isminw && cw) data.left = dw - o.minWidth; - if (ismaxw && cw) data.left = dw - o.maxWidth; - if (isminh && ch) data.top = dh - o.minHeight; - if (ismaxh && ch) data.top = dh - o.maxHeight; - - // fixing jump error on top/left - bug #2330 - var isNotwh = !data.width && !data.height; - if (isNotwh && !data.left && data.top) data.top = null; - else if (isNotwh && !data.top && data.left) data.left = null; - - return data; - }, - - _proportionallyResize: function() { - - var o = this.options; - if (!this._proportionallyResizeElements.length) return; - var element = this.helper || this.element; - - for (var i=0; i < this._proportionallyResizeElements.length; i++) { - - var prel = this._proportionallyResizeElements[i]; - - if (!this.borderDif) { - var b = [prel.css('borderTopWidth'), prel.css('borderRightWidth'), prel.css('borderBottomWidth'), prel.css('borderLeftWidth')], - p = [prel.css('paddingTop'), prel.css('paddingRight'), prel.css('paddingBottom'), prel.css('paddingLeft')]; - - this.borderDif = $.map(b, function(v, i) { - var border = parseInt(v,10)||0, padding = parseInt(p[i],10)||0; - return border + padding; - }); - } - - if ($.browser.msie && !(!($(element).is(':hidden') || $(element).parents(':hidden').length))) - continue; - - prel.css({ - height: (element.height() - this.borderDif[0] - this.borderDif[2]) || 0, - width: (element.width() - this.borderDif[1] - this.borderDif[3]) || 0 - }); - - }; - - }, - - _renderProxy: function() { - - var el = this.element, o = this.options; - this.elementOffset = el.offset(); - - if(this._helper) { - - this.helper = this.helper || $('
    '); - - // fix ie6 offset TODO: This seems broken - var ie6 = $.browser.msie && $.browser.version < 7, ie6offset = (ie6 ? 1 : 0), - pxyoffset = ( ie6 ? 2 : -1 ); - - this.helper.addClass(this._helper).css({ - width: this.element.outerWidth() + pxyoffset, - height: this.element.outerHeight() + pxyoffset, - position: 'absolute', - left: this.elementOffset.left - ie6offset +'px', - top: this.elementOffset.top - ie6offset +'px', - zIndex: ++o.zIndex //TODO: Don't modify option - }); - - this.helper - .appendTo("body") - .disableSelection(); - - } else { - this.helper = this.element; - } - - }, - - _change: { - e: function(event, dx, dy) { - return { width: this.originalSize.width + dx }; - }, - w: function(event, dx, dy) { - var o = this.options, cs = this.originalSize, sp = this.originalPosition; - return { left: sp.left + dx, width: cs.width - dx }; - }, - n: function(event, dx, dy) { - var o = this.options, cs = this.originalSize, sp = this.originalPosition; - return { top: sp.top + dy, height: cs.height - dy }; - }, - s: function(event, dx, dy) { - return { height: this.originalSize.height + dy }; - }, - se: function(event, dx, dy) { - return $.extend(this._change.s.apply(this, arguments), this._change.e.apply(this, [event, dx, dy])); - }, - sw: function(event, dx, dy) { - return $.extend(this._change.s.apply(this, arguments), this._change.w.apply(this, [event, dx, dy])); - }, - ne: function(event, dx, dy) { - return $.extend(this._change.n.apply(this, arguments), this._change.e.apply(this, [event, dx, dy])); - }, - nw: function(event, dx, dy) { - return $.extend(this._change.n.apply(this, arguments), this._change.w.apply(this, [event, dx, dy])); - } - }, - - _propagate: function(n, event) { - $.ui.plugin.call(this, n, [event, this.ui()]); - (n != "resize" && this._trigger(n, event, this.ui())); - }, - - plugins: {}, - - ui: function() { - return { - originalElement: this.originalElement, - element: this.element, - helper: this.helper, - position: this.position, - size: this.size, - originalSize: this.originalSize, - originalPosition: this.originalPosition - }; - } - -}); - -$.extend($.ui.resizable, { - version: "1.8.15" -}); - -/* - * Resizable Extensions - */ - -$.ui.plugin.add("resizable", "alsoResize", { - - start: function (event, ui) { - var self = $(this).data("resizable"), o = self.options; - - var _store = function (exp) { - $(exp).each(function() { - var el = $(this); - el.data("resizable-alsoresize", { - width: parseInt(el.width(), 10), height: parseInt(el.height(), 10), - left: parseInt(el.css('left'), 10), top: parseInt(el.css('top'), 10), - position: el.css('position') // to reset Opera on stop() - }); - }); - }; - - if (typeof(o.alsoResize) == 'object' && !o.alsoResize.parentNode) { - if (o.alsoResize.length) { o.alsoResize = o.alsoResize[0]; _store(o.alsoResize); } - else { $.each(o.alsoResize, function (exp) { _store(exp); }); } - }else{ - _store(o.alsoResize); - } - }, - - resize: function (event, ui) { - var self = $(this).data("resizable"), o = self.options, os = self.originalSize, op = self.originalPosition; - - var delta = { - height: (self.size.height - os.height) || 0, width: (self.size.width - os.width) || 0, - top: (self.position.top - op.top) || 0, left: (self.position.left - op.left) || 0 - }, - - _alsoResize = function (exp, c) { - $(exp).each(function() { - var el = $(this), start = $(this).data("resizable-alsoresize"), style = {}, - css = c && c.length ? c : el.parents(ui.originalElement[0]).length ? ['width', 'height'] : ['width', 'height', 'top', 'left']; - - $.each(css, function (i, prop) { - var sum = (start[prop]||0) + (delta[prop]||0); - if (sum && sum >= 0) - style[prop] = sum || null; - }); - - // Opera fixing relative position - if ($.browser.opera && /relative/.test(el.css('position'))) { - self._revertToRelativePosition = true; - el.css({ position: 'absolute', top: 'auto', left: 'auto' }); - } - - el.css(style); - }); - }; - - if (typeof(o.alsoResize) == 'object' && !o.alsoResize.nodeType) { - $.each(o.alsoResize, function (exp, c) { _alsoResize(exp, c); }); - }else{ - _alsoResize(o.alsoResize); - } - }, - - stop: function (event, ui) { - var self = $(this).data("resizable"), o = self.options; - - var _reset = function (exp) { - $(exp).each(function() { - var el = $(this); - // reset position for Opera - no need to verify it was changed - el.css({ position: el.data("resizable-alsoresize").position }); - }); - }; - - if (self._revertToRelativePosition) { - self._revertToRelativePosition = false; - if (typeof(o.alsoResize) == 'object' && !o.alsoResize.nodeType) { - $.each(o.alsoResize, function (exp) { _reset(exp); }); - }else{ - _reset(o.alsoResize); - } - } - - $(this).removeData("resizable-alsoresize"); - } -}); - -$.ui.plugin.add("resizable", "animate", { - - stop: function(event, ui) { - var self = $(this).data("resizable"), o = self.options; - - var pr = self._proportionallyResizeElements, ista = pr.length && (/textarea/i).test(pr[0].nodeName), - soffseth = ista && $.ui.hasScroll(pr[0], 'left') /* TODO - jump height */ ? 0 : self.sizeDiff.height, - soffsetw = ista ? 0 : self.sizeDiff.width; - - var style = { width: (self.size.width - soffsetw), height: (self.size.height - soffseth) }, - left = (parseInt(self.element.css('left'), 10) + (self.position.left - self.originalPosition.left)) || null, - top = (parseInt(self.element.css('top'), 10) + (self.position.top - self.originalPosition.top)) || null; - - self.element.animate( - $.extend(style, top && left ? { top: top, left: left } : {}), { - duration: o.animateDuration, - easing: o.animateEasing, - step: function() { - - var data = { - width: parseInt(self.element.css('width'), 10), - height: parseInt(self.element.css('height'), 10), - top: parseInt(self.element.css('top'), 10), - left: parseInt(self.element.css('left'), 10) - }; - - if (pr && pr.length) $(pr[0]).css({ width: data.width, height: data.height }); - - // propagating resize, and updating values for each animation step - self._updateCache(data); - self._propagate("resize", event); - - } - } - ); - } - -}); - -$.ui.plugin.add("resizable", "containment", { - - start: function(event, ui) { - var self = $(this).data("resizable"), o = self.options, el = self.element; - var oc = o.containment, ce = (oc instanceof $) ? oc.get(0) : (/parent/.test(oc)) ? el.parent().get(0) : oc; - if (!ce) return; - - self.containerElement = $(ce); - - if (/document/.test(oc) || oc == document) { - self.containerOffset = { left: 0, top: 0 }; - self.containerPosition = { left: 0, top: 0 }; - - self.parentData = { - element: $(document), left: 0, top: 0, - width: $(document).width(), height: $(document).height() || document.body.parentNode.scrollHeight - }; - } - - // i'm a node, so compute top, left, right, bottom - else { - var element = $(ce), p = []; - $([ "Top", "Right", "Left", "Bottom" ]).each(function(i, name) { p[i] = num(element.css("padding" + name)); }); - - self.containerOffset = element.offset(); - self.containerPosition = element.position(); - self.containerSize = { height: (element.innerHeight() - p[3]), width: (element.innerWidth() - p[1]) }; - - var co = self.containerOffset, ch = self.containerSize.height, cw = self.containerSize.width, - width = ($.ui.hasScroll(ce, "left") ? ce.scrollWidth : cw ), height = ($.ui.hasScroll(ce) ? ce.scrollHeight : ch); - - self.parentData = { - element: ce, left: co.left, top: co.top, width: width, height: height - }; - } - }, - - resize: function(event, ui) { - var self = $(this).data("resizable"), o = self.options, - ps = self.containerSize, co = self.containerOffset, cs = self.size, cp = self.position, - pRatio = self._aspectRatio || event.shiftKey, cop = { top:0, left:0 }, ce = self.containerElement; - - if (ce[0] != document && (/static/).test(ce.css('position'))) cop = co; - - if (cp.left < (self._helper ? co.left : 0)) { - self.size.width = self.size.width + (self._helper ? (self.position.left - co.left) : (self.position.left - cop.left)); - if (pRatio) self.size.height = self.size.width / o.aspectRatio; - self.position.left = o.helper ? co.left : 0; - } - - if (cp.top < (self._helper ? co.top : 0)) { - self.size.height = self.size.height + (self._helper ? (self.position.top - co.top) : self.position.top); - if (pRatio) self.size.width = self.size.height * o.aspectRatio; - self.position.top = self._helper ? co.top : 0; - } - - self.offset.left = self.parentData.left+self.position.left; - self.offset.top = self.parentData.top+self.position.top; - - var woset = Math.abs( (self._helper ? self.offset.left - cop.left : (self.offset.left - cop.left)) + self.sizeDiff.width ), - hoset = Math.abs( (self._helper ? self.offset.top - cop.top : (self.offset.top - co.top)) + self.sizeDiff.height ); - - var isParent = self.containerElement.get(0) == self.element.parent().get(0), - isOffsetRelative = /relative|absolute/.test(self.containerElement.css('position')); - - if(isParent && isOffsetRelative) woset -= self.parentData.left; - - if (woset + self.size.width >= self.parentData.width) { - self.size.width = self.parentData.width - woset; - if (pRatio) self.size.height = self.size.width / self.aspectRatio; - } - - if (hoset + self.size.height >= self.parentData.height) { - self.size.height = self.parentData.height - hoset; - if (pRatio) self.size.width = self.size.height * self.aspectRatio; - } - }, - - stop: function(event, ui){ - var self = $(this).data("resizable"), o = self.options, cp = self.position, - co = self.containerOffset, cop = self.containerPosition, ce = self.containerElement; - - var helper = $(self.helper), ho = helper.offset(), w = helper.outerWidth() - self.sizeDiff.width, h = helper.outerHeight() - self.sizeDiff.height; - - if (self._helper && !o.animate && (/relative/).test(ce.css('position'))) - $(this).css({ left: ho.left - cop.left - co.left, width: w, height: h }); - - if (self._helper && !o.animate && (/static/).test(ce.css('position'))) - $(this).css({ left: ho.left - cop.left - co.left, width: w, height: h }); - - } -}); - -$.ui.plugin.add("resizable", "ghost", { - - start: function(event, ui) { - - var self = $(this).data("resizable"), o = self.options, cs = self.size; - - self.ghost = self.originalElement.clone(); - self.ghost - .css({ opacity: .25, display: 'block', position: 'relative', height: cs.height, width: cs.width, margin: 0, left: 0, top: 0 }) - .addClass('ui-resizable-ghost') - .addClass(typeof o.ghost == 'string' ? o.ghost : ''); - - self.ghost.appendTo(self.helper); - - }, - - resize: function(event, ui){ - var self = $(this).data("resizable"), o = self.options; - if (self.ghost) self.ghost.css({ position: 'relative', height: self.size.height, width: self.size.width }); - }, - - stop: function(event, ui){ - var self = $(this).data("resizable"), o = self.options; - if (self.ghost && self.helper) self.helper.get(0).removeChild(self.ghost.get(0)); - } - -}); - -$.ui.plugin.add("resizable", "grid", { - - resize: function(event, ui) { - var self = $(this).data("resizable"), o = self.options, cs = self.size, os = self.originalSize, op = self.originalPosition, a = self.axis, ratio = o._aspectRatio || event.shiftKey; - o.grid = typeof o.grid == "number" ? [o.grid, o.grid] : o.grid; - var ox = Math.round((cs.width - os.width) / (o.grid[0]||1)) * (o.grid[0]||1), oy = Math.round((cs.height - os.height) / (o.grid[1]||1)) * (o.grid[1]||1); - - if (/^(se|s|e)$/.test(a)) { - self.size.width = os.width + ox; - self.size.height = os.height + oy; - } - else if (/^(ne)$/.test(a)) { - self.size.width = os.width + ox; - self.size.height = os.height + oy; - self.position.top = op.top - oy; - } - else if (/^(sw)$/.test(a)) { - self.size.width = os.width + ox; - self.size.height = os.height + oy; - self.position.left = op.left - ox; - } - else { - self.size.width = os.width + ox; - self.size.height = os.height + oy; - self.position.top = op.top - oy; - self.position.left = op.left - ox; - } - } - -}); - -var num = function(v) { - return parseInt(v, 10) || 0; -}; - -var isNumber = function(value) { - return !isNaN(parseInt(value, 10)); -}; - -})(jQuery); -/* - * jQuery UI Selectable 1.8.15 - * - * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) - * Dual licensed under the MIT or GPL Version 2 licenses. - * http://jquery.org/license - * - * http://docs.jquery.com/UI/Selectables - * - * Depends: - * jquery.ui.core.js - * jquery.ui.mouse.js - * jquery.ui.widget.js - */ -(function( $, undefined ) { - -$.widget("ui.selectable", $.ui.mouse, { - options: { - appendTo: 'body', - autoRefresh: true, - distance: 0, - filter: '*', - tolerance: 'touch' - }, - _create: function() { - var self = this; - - this.element.addClass("ui-selectable"); - - this.dragged = false; - - // cache selectee children based on filter - var selectees; - this.refresh = function() { - selectees = $(self.options.filter, self.element[0]); - selectees.each(function() { - var $this = $(this); - var pos = $this.offset(); - $.data(this, "selectable-item", { - element: this, - $element: $this, - left: pos.left, - top: pos.top, - right: pos.left + $this.outerWidth(), - bottom: pos.top + $this.outerHeight(), - startselected: false, - selected: $this.hasClass('ui-selected'), - selecting: $this.hasClass('ui-selecting'), - unselecting: $this.hasClass('ui-unselecting') - }); - }); - }; - this.refresh(); - - this.selectees = selectees.addClass("ui-selectee"); - - this._mouseInit(); - - this.helper = $("
    "); - }, - - destroy: function() { - this.selectees - .removeClass("ui-selectee") - .removeData("selectable-item"); - this.element - .removeClass("ui-selectable ui-selectable-disabled") - .removeData("selectable") - .unbind(".selectable"); - this._mouseDestroy(); - - return this; - }, - - _mouseStart: function(event) { - var self = this; - - this.opos = [event.pageX, event.pageY]; - - if (this.options.disabled) - return; - - var options = this.options; - - this.selectees = $(options.filter, this.element[0]); - - this._trigger("start", event); - - $(options.appendTo).append(this.helper); - // position helper (lasso) - this.helper.css({ - "left": event.clientX, - "top": event.clientY, - "width": 0, - "height": 0 - }); - - if (options.autoRefresh) { - this.refresh(); - } - - this.selectees.filter('.ui-selected').each(function() { - var selectee = $.data(this, "selectable-item"); - selectee.startselected = true; - if (!event.metaKey) { - selectee.$element.removeClass('ui-selected'); - selectee.selected = false; - selectee.$element.addClass('ui-unselecting'); - selectee.unselecting = true; - // selectable UNSELECTING callback - self._trigger("unselecting", event, { - unselecting: selectee.element - }); - } - }); - - $(event.target).parents().andSelf().each(function() { - var selectee = $.data(this, "selectable-item"); - if (selectee) { - var doSelect = !event.metaKey || !selectee.$element.hasClass('ui-selected'); - selectee.$element - .removeClass(doSelect ? "ui-unselecting" : "ui-selected") - .addClass(doSelect ? "ui-selecting" : "ui-unselecting"); - selectee.unselecting = !doSelect; - selectee.selecting = doSelect; - selectee.selected = doSelect; - // selectable (UN)SELECTING callback - if (doSelect) { - self._trigger("selecting", event, { - selecting: selectee.element - }); - } else { - self._trigger("unselecting", event, { - unselecting: selectee.element - }); - } - return false; - } - }); - - }, - - _mouseDrag: function(event) { - var self = this; - this.dragged = true; - - if (this.options.disabled) - return; - - var options = this.options; - - var x1 = this.opos[0], y1 = this.opos[1], x2 = event.pageX, y2 = event.pageY; - if (x1 > x2) { var tmp = x2; x2 = x1; x1 = tmp; } - if (y1 > y2) { var tmp = y2; y2 = y1; y1 = tmp; } - this.helper.css({left: x1, top: y1, width: x2-x1, height: y2-y1}); - - this.selectees.each(function() { - var selectee = $.data(this, "selectable-item"); - //prevent helper from being selected if appendTo: selectable - if (!selectee || selectee.element == self.element[0]) - return; - var hit = false; - if (options.tolerance == 'touch') { - hit = ( !(selectee.left > x2 || selectee.right < x1 || selectee.top > y2 || selectee.bottom < y1) ); - } else if (options.tolerance == 'fit') { - hit = (selectee.left > x1 && selectee.right < x2 && selectee.top > y1 && selectee.bottom < y2); - } - - if (hit) { - // SELECT - if (selectee.selected) { - selectee.$element.removeClass('ui-selected'); - selectee.selected = false; - } - if (selectee.unselecting) { - selectee.$element.removeClass('ui-unselecting'); - selectee.unselecting = false; - } - if (!selectee.selecting) { - selectee.$element.addClass('ui-selecting'); - selectee.selecting = true; - // selectable SELECTING callback - self._trigger("selecting", event, { - selecting: selectee.element - }); - } - } else { - // UNSELECT - if (selectee.selecting) { - if (event.metaKey && selectee.startselected) { - selectee.$element.removeClass('ui-selecting'); - selectee.selecting = false; - selectee.$element.addClass('ui-selected'); - selectee.selected = true; - } else { - selectee.$element.removeClass('ui-selecting'); - selectee.selecting = false; - if (selectee.startselected) { - selectee.$element.addClass('ui-unselecting'); - selectee.unselecting = true; - } - // selectable UNSELECTING callback - self._trigger("unselecting", event, { - unselecting: selectee.element - }); - } - } - if (selectee.selected) { - if (!event.metaKey && !selectee.startselected) { - selectee.$element.removeClass('ui-selected'); - selectee.selected = false; - - selectee.$element.addClass('ui-unselecting'); - selectee.unselecting = true; - // selectable UNSELECTING callback - self._trigger("unselecting", event, { - unselecting: selectee.element - }); - } - } - } - }); - - return false; - }, - - _mouseStop: function(event) { - var self = this; - - this.dragged = false; - - var options = this.options; - - $('.ui-unselecting', this.element[0]).each(function() { - var selectee = $.data(this, "selectable-item"); - selectee.$element.removeClass('ui-unselecting'); - selectee.unselecting = false; - selectee.startselected = false; - self._trigger("unselected", event, { - unselected: selectee.element - }); - }); - $('.ui-selecting', this.element[0]).each(function() { - var selectee = $.data(this, "selectable-item"); - selectee.$element.removeClass('ui-selecting').addClass('ui-selected'); - selectee.selecting = false; - selectee.selected = true; - selectee.startselected = true; - self._trigger("selected", event, { - selected: selectee.element - }); - }); - this._trigger("stop", event); - - this.helper.remove(); - - return false; - } - -}); - -$.extend($.ui.selectable, { - version: "1.8.15" -}); - -})(jQuery); -/* - * jQuery UI Sortable 1.8.15 - * - * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) - * Dual licensed under the MIT or GPL Version 2 licenses. - * http://jquery.org/license - * - * http://docs.jquery.com/UI/Sortables - * - * Depends: - * jquery.ui.core.js - * jquery.ui.mouse.js - * jquery.ui.widget.js - */ -(function( $, undefined ) { - -$.widget("ui.sortable", $.ui.mouse, { - widgetEventPrefix: "sort", - options: { - appendTo: "parent", - axis: false, - connectWith: false, - containment: false, - cursor: 'auto', - cursorAt: false, - dropOnEmpty: true, - forcePlaceholderSize: false, - forceHelperSize: false, - grid: false, - handle: false, - helper: "original", - items: '> *', - opacity: false, - placeholder: false, - revert: false, - scroll: true, - scrollSensitivity: 20, - scrollSpeed: 20, - scope: "default", - tolerance: "intersect", - zIndex: 1000 - }, - _create: function() { - - var o = this.options; - this.containerCache = {}; - this.element.addClass("ui-sortable"); - - //Get the items - this.refresh(); - - //Let's determine if the items are being displayed horizontally - this.floating = this.items.length ? o.axis === 'x' || (/left|right/).test(this.items[0].item.css('float')) || (/inline|table-cell/).test(this.items[0].item.css('display')) : false; - - //Let's determine the parent's offset - this.offset = this.element.offset(); - - //Initialize mouse events for interaction - this._mouseInit(); - - }, - - destroy: function() { - this.element - .removeClass("ui-sortable ui-sortable-disabled") - .removeData("sortable") - .unbind(".sortable"); - this._mouseDestroy(); - - for ( var i = this.items.length - 1; i >= 0; i-- ) - this.items[i].item.removeData("sortable-item"); - - return this; - }, - - _setOption: function(key, value){ - if ( key === "disabled" ) { - this.options[ key ] = value; - - this.widget() - [ value ? "addClass" : "removeClass"]( "ui-sortable-disabled" ); - } else { - // Don't call widget base _setOption for disable as it adds ui-state-disabled class - $.Widget.prototype._setOption.apply(this, arguments); - } - }, - - _mouseCapture: function(event, overrideHandle) { - - if (this.reverting) { - return false; - } - - if(this.options.disabled || this.options.type == 'static') return false; - - //We have to refresh the items data once first - this._refreshItems(event); - - //Find out if the clicked node (or one of its parents) is a actual item in this.items - var currentItem = null, self = this, nodes = $(event.target).parents().each(function() { - if($.data(this, 'sortable-item') == self) { - currentItem = $(this); - return false; - } - }); - if($.data(event.target, 'sortable-item') == self) currentItem = $(event.target); - - if(!currentItem) return false; - if(this.options.handle && !overrideHandle) { - var validHandle = false; - - $(this.options.handle, currentItem).find("*").andSelf().each(function() { if(this == event.target) validHandle = true; }); - if(!validHandle) return false; - } - - this.currentItem = currentItem; - this._removeCurrentsFromItems(); - return true; - - }, - - _mouseStart: function(event, overrideHandle, noActivation) { - - var o = this.options, self = this; - this.currentContainer = this; - - //We only need to call refreshPositions, because the refreshItems call has been moved to mouseCapture - this.refreshPositions(); - - //Create and append the visible helper - this.helper = this._createHelper(event); - - //Cache the helper size - this._cacheHelperProportions(); - - /* - * - Position generation - - * This block generates everything position related - it's the core of draggables. - */ - - //Cache the margins of the original element - this._cacheMargins(); - - //Get the next scrolling parent - this.scrollParent = this.helper.scrollParent(); - - //The element's absolute position on the page minus margins - this.offset = this.currentItem.offset(); - this.offset = { - top: this.offset.top - this.margins.top, - left: this.offset.left - this.margins.left - }; - - // Only after we got the offset, we can change the helper's position to absolute - // TODO: Still need to figure out a way to make relative sorting possible - this.helper.css("position", "absolute"); - this.cssPosition = this.helper.css("position"); - - $.extend(this.offset, { - click: { //Where the click happened, relative to the element - left: event.pageX - this.offset.left, - top: event.pageY - this.offset.top - }, - parent: this._getParentOffset(), - relative: this._getRelativeOffset() //This is a relative to absolute position minus the actual position calculation - only used for relative positioned helper - }); - - //Generate the original position - this.originalPosition = this._generatePosition(event); - this.originalPageX = event.pageX; - this.originalPageY = event.pageY; - - //Adjust the mouse offset relative to the helper if 'cursorAt' is supplied - (o.cursorAt && this._adjustOffsetFromHelper(o.cursorAt)); - - //Cache the former DOM position - this.domPosition = { prev: this.currentItem.prev()[0], parent: this.currentItem.parent()[0] }; - - //If the helper is not the original, hide the original so it's not playing any role during the drag, won't cause anything bad this way - if(this.helper[0] != this.currentItem[0]) { - this.currentItem.hide(); - } - - //Create the placeholder - this._createPlaceholder(); - - //Set a containment if given in the options - if(o.containment) - this._setContainment(); - - if(o.cursor) { // cursor option - if ($('body').css("cursor")) this._storedCursor = $('body').css("cursor"); - $('body').css("cursor", o.cursor); - } - - if(o.opacity) { // opacity option - if (this.helper.css("opacity")) this._storedOpacity = this.helper.css("opacity"); - this.helper.css("opacity", o.opacity); - } - - if(o.zIndex) { // zIndex option - if (this.helper.css("zIndex")) this._storedZIndex = this.helper.css("zIndex"); - this.helper.css("zIndex", o.zIndex); - } - - //Prepare scrolling - if(this.scrollParent[0] != document && this.scrollParent[0].tagName != 'HTML') - this.overflowOffset = this.scrollParent.offset(); - - //Call callbacks - this._trigger("start", event, this._uiHash()); - - //Recache the helper size - if(!this._preserveHelperProportions) - this._cacheHelperProportions(); - - - //Post 'activate' events to possible containers - if(!noActivation) { - for (var i = this.containers.length - 1; i >= 0; i--) { this.containers[i]._trigger("activate", event, self._uiHash(this)); } - } - - //Prepare possible droppables - if($.ui.ddmanager) - $.ui.ddmanager.current = this; - - if ($.ui.ddmanager && !o.dropBehaviour) - $.ui.ddmanager.prepareOffsets(this, event); - - this.dragging = true; - - this.helper.addClass("ui-sortable-helper"); - this._mouseDrag(event); //Execute the drag once - this causes the helper not to be visible before getting its correct position - return true; - - }, - - _mouseDrag: function(event) { - - //Compute the helpers position - this.position = this._generatePosition(event); - this.positionAbs = this._convertPositionTo("absolute"); - - if (!this.lastPositionAbs) { - this.lastPositionAbs = this.positionAbs; - } - - //Do scrolling - if(this.options.scroll) { - var o = this.options, scrolled = false; - if(this.scrollParent[0] != document && this.scrollParent[0].tagName != 'HTML') { - - if((this.overflowOffset.top + this.scrollParent[0].offsetHeight) - event.pageY < o.scrollSensitivity) - this.scrollParent[0].scrollTop = scrolled = this.scrollParent[0].scrollTop + o.scrollSpeed; - else if(event.pageY - this.overflowOffset.top < o.scrollSensitivity) - this.scrollParent[0].scrollTop = scrolled = this.scrollParent[0].scrollTop - o.scrollSpeed; - - if((this.overflowOffset.left + this.scrollParent[0].offsetWidth) - event.pageX < o.scrollSensitivity) - this.scrollParent[0].scrollLeft = scrolled = this.scrollParent[0].scrollLeft + o.scrollSpeed; - else if(event.pageX - this.overflowOffset.left < o.scrollSensitivity) - this.scrollParent[0].scrollLeft = scrolled = this.scrollParent[0].scrollLeft - o.scrollSpeed; - - } else { - - if(event.pageY - $(document).scrollTop() < o.scrollSensitivity) - scrolled = $(document).scrollTop($(document).scrollTop() - o.scrollSpeed); - else if($(window).height() - (event.pageY - $(document).scrollTop()) < o.scrollSensitivity) - scrolled = $(document).scrollTop($(document).scrollTop() + o.scrollSpeed); - - if(event.pageX - $(document).scrollLeft() < o.scrollSensitivity) - scrolled = $(document).scrollLeft($(document).scrollLeft() - o.scrollSpeed); - else if($(window).width() - (event.pageX - $(document).scrollLeft()) < o.scrollSensitivity) - scrolled = $(document).scrollLeft($(document).scrollLeft() + o.scrollSpeed); - - } - - if(scrolled !== false && $.ui.ddmanager && !o.dropBehaviour) - $.ui.ddmanager.prepareOffsets(this, event); - } - - //Regenerate the absolute position used for position checks - this.positionAbs = this._convertPositionTo("absolute"); - - //Set the helper position - if(!this.options.axis || this.options.axis != "y") this.helper[0].style.left = this.position.left+'px'; - if(!this.options.axis || this.options.axis != "x") this.helper[0].style.top = this.position.top+'px'; - - //Rearrange - for (var i = this.items.length - 1; i >= 0; i--) { - - //Cache variables and intersection, continue if no intersection - var item = this.items[i], itemElement = item.item[0], intersection = this._intersectsWithPointer(item); - if (!intersection) continue; - - if(itemElement != this.currentItem[0] //cannot intersect with itself - && this.placeholder[intersection == 1 ? "next" : "prev"]()[0] != itemElement //no useless actions that have been done before - && !$.ui.contains(this.placeholder[0], itemElement) //no action if the item moved is the parent of the item checked - && (this.options.type == 'semi-dynamic' ? !$.ui.contains(this.element[0], itemElement) : true) - //&& itemElement.parentNode == this.placeholder[0].parentNode // only rearrange items within the same container - ) { - - this.direction = intersection == 1 ? "down" : "up"; - - if (this.options.tolerance == "pointer" || this._intersectsWithSides(item)) { - this._rearrange(event, item); - } else { - break; - } - - this._trigger("change", event, this._uiHash()); - break; - } - } - - //Post events to containers - this._contactContainers(event); - - //Interconnect with droppables - if($.ui.ddmanager) $.ui.ddmanager.drag(this, event); - - //Call callbacks - this._trigger('sort', event, this._uiHash()); - - this.lastPositionAbs = this.positionAbs; - return false; - - }, - - _mouseStop: function(event, noPropagation) { - - if(!event) return; - - //If we are using droppables, inform the manager about the drop - if ($.ui.ddmanager && !this.options.dropBehaviour) - $.ui.ddmanager.drop(this, event); - - if(this.options.revert) { - var self = this; - var cur = self.placeholder.offset(); - - self.reverting = true; - - $(this.helper).animate({ - left: cur.left - this.offset.parent.left - self.margins.left + (this.offsetParent[0] == document.body ? 0 : this.offsetParent[0].scrollLeft), - top: cur.top - this.offset.parent.top - self.margins.top + (this.offsetParent[0] == document.body ? 0 : this.offsetParent[0].scrollTop) - }, parseInt(this.options.revert, 10) || 500, function() { - self._clear(event); - }); - } else { - this._clear(event, noPropagation); - } - - return false; - - }, - - cancel: function() { - - var self = this; - - if(this.dragging) { - - this._mouseUp({ target: null }); - - if(this.options.helper == "original") - this.currentItem.css(this._storedCSS).removeClass("ui-sortable-helper"); - else - this.currentItem.show(); - - //Post deactivating events to containers - for (var i = this.containers.length - 1; i >= 0; i--){ - this.containers[i]._trigger("deactivate", null, self._uiHash(this)); - if(this.containers[i].containerCache.over) { - this.containers[i]._trigger("out", null, self._uiHash(this)); - this.containers[i].containerCache.over = 0; - } - } - - } - - if (this.placeholder) { - //$(this.placeholder[0]).remove(); would have been the jQuery way - unfortunately, it unbinds ALL events from the original node! - if(this.placeholder[0].parentNode) this.placeholder[0].parentNode.removeChild(this.placeholder[0]); - if(this.options.helper != "original" && this.helper && this.helper[0].parentNode) this.helper.remove(); - - $.extend(this, { - helper: null, - dragging: false, - reverting: false, - _noFinalSort: null - }); - - if(this.domPosition.prev) { - $(this.domPosition.prev).after(this.currentItem); - } else { - $(this.domPosition.parent).prepend(this.currentItem); - } - } - - return this; - - }, - - serialize: function(o) { - - var items = this._getItemsAsjQuery(o && o.connected); - var str = []; o = o || {}; - - $(items).each(function() { - var res = ($(o.item || this).attr(o.attribute || 'id') || '').match(o.expression || (/(.+)[-=_](.+)/)); - if(res) str.push((o.key || res[1]+'[]')+'='+(o.key && o.expression ? res[1] : res[2])); - }); - - if(!str.length && o.key) { - str.push(o.key + '='); - } - - return str.join('&'); - - }, - - toArray: function(o) { - - var items = this._getItemsAsjQuery(o && o.connected); - var ret = []; o = o || {}; - - items.each(function() { ret.push($(o.item || this).attr(o.attribute || 'id') || ''); }); - return ret; - - }, - - /* Be careful with the following core functions */ - _intersectsWith: function(item) { - - var x1 = this.positionAbs.left, - x2 = x1 + this.helperProportions.width, - y1 = this.positionAbs.top, - y2 = y1 + this.helperProportions.height; - - var l = item.left, - r = l + item.width, - t = item.top, - b = t + item.height; - - var dyClick = this.offset.click.top, - dxClick = this.offset.click.left; - - var isOverElement = (y1 + dyClick) > t && (y1 + dyClick) < b && (x1 + dxClick) > l && (x1 + dxClick) < r; - - if( this.options.tolerance == "pointer" - || this.options.forcePointerForContainers - || (this.options.tolerance != "pointer" && this.helperProportions[this.floating ? 'width' : 'height'] > item[this.floating ? 'width' : 'height']) - ) { - return isOverElement; - } else { - - return (l < x1 + (this.helperProportions.width / 2) // Right Half - && x2 - (this.helperProportions.width / 2) < r // Left Half - && t < y1 + (this.helperProportions.height / 2) // Bottom Half - && y2 - (this.helperProportions.height / 2) < b ); // Top Half - - } - }, - - _intersectsWithPointer: function(item) { - - var isOverElementHeight = $.ui.isOverAxis(this.positionAbs.top + this.offset.click.top, item.top, item.height), - isOverElementWidth = $.ui.isOverAxis(this.positionAbs.left + this.offset.click.left, item.left, item.width), - isOverElement = isOverElementHeight && isOverElementWidth, - verticalDirection = this._getDragVerticalDirection(), - horizontalDirection = this._getDragHorizontalDirection(); - - if (!isOverElement) - return false; - - return this.floating ? - ( ((horizontalDirection && horizontalDirection == "right") || verticalDirection == "down") ? 2 : 1 ) - : ( verticalDirection && (verticalDirection == "down" ? 2 : 1) ); - - }, - - _intersectsWithSides: function(item) { - - var isOverBottomHalf = $.ui.isOverAxis(this.positionAbs.top + this.offset.click.top, item.top + (item.height/2), item.height), - isOverRightHalf = $.ui.isOverAxis(this.positionAbs.left + this.offset.click.left, item.left + (item.width/2), item.width), - verticalDirection = this._getDragVerticalDirection(), - horizontalDirection = this._getDragHorizontalDirection(); - - if (this.floating && horizontalDirection) { - return ((horizontalDirection == "right" && isOverRightHalf) || (horizontalDirection == "left" && !isOverRightHalf)); - } else { - return verticalDirection && ((verticalDirection == "down" && isOverBottomHalf) || (verticalDirection == "up" && !isOverBottomHalf)); - } - - }, - - _getDragVerticalDirection: function() { - var delta = this.positionAbs.top - this.lastPositionAbs.top; - return delta != 0 && (delta > 0 ? "down" : "up"); - }, - - _getDragHorizontalDirection: function() { - var delta = this.positionAbs.left - this.lastPositionAbs.left; - return delta != 0 && (delta > 0 ? "right" : "left"); - }, - - refresh: function(event) { - this._refreshItems(event); - this.refreshPositions(); - return this; - }, - - _connectWith: function() { - var options = this.options; - return options.connectWith.constructor == String - ? [options.connectWith] - : options.connectWith; - }, - - _getItemsAsjQuery: function(connected) { - - var self = this; - var items = []; - var queries = []; - var connectWith = this._connectWith(); - - if(connectWith && connected) { - for (var i = connectWith.length - 1; i >= 0; i--){ - var cur = $(connectWith[i]); - for (var j = cur.length - 1; j >= 0; j--){ - var inst = $.data(cur[j], 'sortable'); - if(inst && inst != this && !inst.options.disabled) { - queries.push([$.isFunction(inst.options.items) ? inst.options.items.call(inst.element) : $(inst.options.items, inst.element).not(".ui-sortable-helper").not('.ui-sortable-placeholder'), inst]); - } - }; - }; - } - - queries.push([$.isFunction(this.options.items) ? this.options.items.call(this.element, null, { options: this.options, item: this.currentItem }) : $(this.options.items, this.element).not(".ui-sortable-helper").not('.ui-sortable-placeholder'), this]); - - for (var i = queries.length - 1; i >= 0; i--){ - queries[i][0].each(function() { - items.push(this); - }); - }; - - return $(items); - - }, - - _removeCurrentsFromItems: function() { - - var list = this.currentItem.find(":data(sortable-item)"); - - for (var i=0; i < this.items.length; i++) { - - for (var j=0; j < list.length; j++) { - if(list[j] == this.items[i].item[0]) - this.items.splice(i,1); - }; - - }; - - }, - - _refreshItems: function(event) { - - this.items = []; - this.containers = [this]; - var items = this.items; - var self = this; - var queries = [[$.isFunction(this.options.items) ? this.options.items.call(this.element[0], event, { item: this.currentItem }) : $(this.options.items, this.element), this]]; - var connectWith = this._connectWith(); - - if(connectWith) { - for (var i = connectWith.length - 1; i >= 0; i--){ - var cur = $(connectWith[i]); - for (var j = cur.length - 1; j >= 0; j--){ - var inst = $.data(cur[j], 'sortable'); - if(inst && inst != this && !inst.options.disabled) { - queries.push([$.isFunction(inst.options.items) ? inst.options.items.call(inst.element[0], event, { item: this.currentItem }) : $(inst.options.items, inst.element), inst]); - this.containers.push(inst); - } - }; - }; - } - - for (var i = queries.length - 1; i >= 0; i--) { - var targetData = queries[i][1]; - var _queries = queries[i][0]; - - for (var j=0, queriesLength = _queries.length; j < queriesLength; j++) { - var item = $(_queries[j]); - - item.data('sortable-item', targetData); // Data for target checking (mouse manager) - - items.push({ - item: item, - instance: targetData, - width: 0, height: 0, - left: 0, top: 0 - }); - }; - }; - - }, - - refreshPositions: function(fast) { - - //This has to be redone because due to the item being moved out/into the offsetParent, the offsetParent's position will change - if(this.offsetParent && this.helper) { - this.offset.parent = this._getParentOffset(); - } - - for (var i = this.items.length - 1; i >= 0; i--){ - var item = this.items[i]; - - //We ignore calculating positions of all connected containers when we're not over them - if(item.instance != this.currentContainer && this.currentContainer && item.item[0] != this.currentItem[0]) - continue; - - var t = this.options.toleranceElement ? $(this.options.toleranceElement, item.item) : item.item; - - if (!fast) { - item.width = t.outerWidth(); - item.height = t.outerHeight(); - } - - var p = t.offset(); - item.left = p.left; - item.top = p.top; - }; - - if(this.options.custom && this.options.custom.refreshContainers) { - this.options.custom.refreshContainers.call(this); - } else { - for (var i = this.containers.length - 1; i >= 0; i--){ - var p = this.containers[i].element.offset(); - this.containers[i].containerCache.left = p.left; - this.containers[i].containerCache.top = p.top; - this.containers[i].containerCache.width = this.containers[i].element.outerWidth(); - this.containers[i].containerCache.height = this.containers[i].element.outerHeight(); - }; - } - - return this; - }, - - _createPlaceholder: function(that) { - - var self = that || this, o = self.options; - - if(!o.placeholder || o.placeholder.constructor == String) { - var className = o.placeholder; - o.placeholder = { - element: function() { - - var el = $(document.createElement(self.currentItem[0].nodeName)) - .addClass(className || self.currentItem[0].className+" ui-sortable-placeholder") - .removeClass("ui-sortable-helper")[0]; - - if(!className) - el.style.visibility = "hidden"; - - return el; - }, - update: function(container, p) { - - // 1. If a className is set as 'placeholder option, we don't force sizes - the class is responsible for that - // 2. The option 'forcePlaceholderSize can be enabled to force it even if a class name is specified - if(className && !o.forcePlaceholderSize) return; - - //If the element doesn't have a actual height by itself (without styles coming from a stylesheet), it receives the inline height from the dragged item - if(!p.height()) { p.height(self.currentItem.innerHeight() - parseInt(self.currentItem.css('paddingTop')||0, 10) - parseInt(self.currentItem.css('paddingBottom')||0, 10)); }; - if(!p.width()) { p.width(self.currentItem.innerWidth() - parseInt(self.currentItem.css('paddingLeft')||0, 10) - parseInt(self.currentItem.css('paddingRight')||0, 10)); }; - } - }; - } - - //Create the placeholder - self.placeholder = $(o.placeholder.element.call(self.element, self.currentItem)); - - //Append it after the actual current item - self.currentItem.after(self.placeholder); - - //Update the size of the placeholder (TODO: Logic to fuzzy, see line 316/317) - o.placeholder.update(self, self.placeholder); - - }, - - _contactContainers: function(event) { - - // get innermost container that intersects with item - var innermostContainer = null, innermostIndex = null; - - - for (var i = this.containers.length - 1; i >= 0; i--){ - - // never consider a container that's located within the item itself - if($.ui.contains(this.currentItem[0], this.containers[i].element[0])) - continue; - - if(this._intersectsWith(this.containers[i].containerCache)) { - - // if we've already found a container and it's more "inner" than this, then continue - if(innermostContainer && $.ui.contains(this.containers[i].element[0], innermostContainer.element[0])) - continue; - - innermostContainer = this.containers[i]; - innermostIndex = i; - - } else { - // container doesn't intersect. trigger "out" event if necessary - if(this.containers[i].containerCache.over) { - this.containers[i]._trigger("out", event, this._uiHash(this)); - this.containers[i].containerCache.over = 0; - } - } - - } - - // if no intersecting containers found, return - if(!innermostContainer) return; - - // move the item into the container if it's not there already - if(this.containers.length === 1) { - this.containers[innermostIndex]._trigger("over", event, this._uiHash(this)); - this.containers[innermostIndex].containerCache.over = 1; - } else if(this.currentContainer != this.containers[innermostIndex]) { - - //When entering a new container, we will find the item with the least distance and append our item near it - var dist = 10000; var itemWithLeastDistance = null; var base = this.positionAbs[this.containers[innermostIndex].floating ? 'left' : 'top']; - for (var j = this.items.length - 1; j >= 0; j--) { - if(!$.ui.contains(this.containers[innermostIndex].element[0], this.items[j].item[0])) continue; - var cur = this.items[j][this.containers[innermostIndex].floating ? 'left' : 'top']; - if(Math.abs(cur - base) < dist) { - dist = Math.abs(cur - base); itemWithLeastDistance = this.items[j]; - } - } - - if(!itemWithLeastDistance && !this.options.dropOnEmpty) //Check if dropOnEmpty is enabled - return; - - this.currentContainer = this.containers[innermostIndex]; - itemWithLeastDistance ? this._rearrange(event, itemWithLeastDistance, null, true) : this._rearrange(event, null, this.containers[innermostIndex].element, true); - this._trigger("change", event, this._uiHash()); - this.containers[innermostIndex]._trigger("change", event, this._uiHash(this)); - - //Update the placeholder - this.options.placeholder.update(this.currentContainer, this.placeholder); - - this.containers[innermostIndex]._trigger("over", event, this._uiHash(this)); - this.containers[innermostIndex].containerCache.over = 1; - } - - - }, - - _createHelper: function(event) { - - var o = this.options; - var helper = $.isFunction(o.helper) ? $(o.helper.apply(this.element[0], [event, this.currentItem])) : (o.helper == 'clone' ? this.currentItem.clone() : this.currentItem); - - if(!helper.parents('body').length) //Add the helper to the DOM if that didn't happen already - $(o.appendTo != 'parent' ? o.appendTo : this.currentItem[0].parentNode)[0].appendChild(helper[0]); - - if(helper[0] == this.currentItem[0]) - this._storedCSS = { width: this.currentItem[0].style.width, height: this.currentItem[0].style.height, position: this.currentItem.css("position"), top: this.currentItem.css("top"), left: this.currentItem.css("left") }; - - if(helper[0].style.width == '' || o.forceHelperSize) helper.width(this.currentItem.width()); - if(helper[0].style.height == '' || o.forceHelperSize) helper.height(this.currentItem.height()); - - return helper; - - }, - - _adjustOffsetFromHelper: function(obj) { - if (typeof obj == 'string') { - obj = obj.split(' '); - } - if ($.isArray(obj)) { - obj = {left: +obj[0], top: +obj[1] || 0}; - } - if ('left' in obj) { - this.offset.click.left = obj.left + this.margins.left; - } - if ('right' in obj) { - this.offset.click.left = this.helperProportions.width - obj.right + this.margins.left; - } - if ('top' in obj) { - this.offset.click.top = obj.top + this.margins.top; - } - if ('bottom' in obj) { - this.offset.click.top = this.helperProportions.height - obj.bottom + this.margins.top; - } - }, - - _getParentOffset: function() { - - - //Get the offsetParent and cache its position - this.offsetParent = this.helper.offsetParent(); - var po = this.offsetParent.offset(); - - // This is a special case where we need to modify a offset calculated on start, since the following happened: - // 1. The position of the helper is absolute, so it's position is calculated based on the next positioned parent - // 2. The actual offset parent is a child of the scroll parent, and the scroll parent isn't the document, which means that - // the scroll is included in the initial calculation of the offset of the parent, and never recalculated upon drag - if(this.cssPosition == 'absolute' && this.scrollParent[0] != document && $.ui.contains(this.scrollParent[0], this.offsetParent[0])) { - po.left += this.scrollParent.scrollLeft(); - po.top += this.scrollParent.scrollTop(); - } - - if((this.offsetParent[0] == document.body) //This needs to be actually done for all browsers, since pageX/pageY includes this information - || (this.offsetParent[0].tagName && this.offsetParent[0].tagName.toLowerCase() == 'html' && $.browser.msie)) //Ugly IE fix - po = { top: 0, left: 0 }; - - return { - top: po.top + (parseInt(this.offsetParent.css("borderTopWidth"),10) || 0), - left: po.left + (parseInt(this.offsetParent.css("borderLeftWidth"),10) || 0) - }; - - }, - - _getRelativeOffset: function() { - - if(this.cssPosition == "relative") { - var p = this.currentItem.position(); - return { - top: p.top - (parseInt(this.helper.css("top"),10) || 0) + this.scrollParent.scrollTop(), - left: p.left - (parseInt(this.helper.css("left"),10) || 0) + this.scrollParent.scrollLeft() - }; - } else { - return { top: 0, left: 0 }; - } - - }, - - _cacheMargins: function() { - this.margins = { - left: (parseInt(this.currentItem.css("marginLeft"),10) || 0), - top: (parseInt(this.currentItem.css("marginTop"),10) || 0) - }; - }, - - _cacheHelperProportions: function() { - this.helperProportions = { - width: this.helper.outerWidth(), - height: this.helper.outerHeight() - }; - }, - - _setContainment: function() { - - var o = this.options; - if(o.containment == 'parent') o.containment = this.helper[0].parentNode; - if(o.containment == 'document' || o.containment == 'window') this.containment = [ - 0 - this.offset.relative.left - this.offset.parent.left, - 0 - this.offset.relative.top - this.offset.parent.top, - $(o.containment == 'document' ? document : window).width() - this.helperProportions.width - this.margins.left, - ($(o.containment == 'document' ? document : window).height() || document.body.parentNode.scrollHeight) - this.helperProportions.height - this.margins.top - ]; - - if(!(/^(document|window|parent)$/).test(o.containment)) { - var ce = $(o.containment)[0]; - var co = $(o.containment).offset(); - var over = ($(ce).css("overflow") != 'hidden'); - - this.containment = [ - co.left + (parseInt($(ce).css("borderLeftWidth"),10) || 0) + (parseInt($(ce).css("paddingLeft"),10) || 0) - this.margins.left, - co.top + (parseInt($(ce).css("borderTopWidth"),10) || 0) + (parseInt($(ce).css("paddingTop"),10) || 0) - this.margins.top, - co.left+(over ? Math.max(ce.scrollWidth,ce.offsetWidth) : ce.offsetWidth) - (parseInt($(ce).css("borderLeftWidth"),10) || 0) - (parseInt($(ce).css("paddingRight"),10) || 0) - this.helperProportions.width - this.margins.left, - co.top+(over ? Math.max(ce.scrollHeight,ce.offsetHeight) : ce.offsetHeight) - (parseInt($(ce).css("borderTopWidth"),10) || 0) - (parseInt($(ce).css("paddingBottom"),10) || 0) - this.helperProportions.height - this.margins.top - ]; - } - - }, - - _convertPositionTo: function(d, pos) { - - if(!pos) pos = this.position; - var mod = d == "absolute" ? 1 : -1; - var o = this.options, scroll = this.cssPosition == 'absolute' && !(this.scrollParent[0] != document && $.ui.contains(this.scrollParent[0], this.offsetParent[0])) ? this.offsetParent : this.scrollParent, scrollIsRootNode = (/(html|body)/i).test(scroll[0].tagName); - - return { - top: ( - pos.top // The absolute mouse position - + this.offset.relative.top * mod // Only for relative positioned nodes: Relative offset from element to offset parent - + this.offset.parent.top * mod // The offsetParent's offset without borders (offset + border) - - ($.browser.safari && this.cssPosition == 'fixed' ? 0 : ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollTop() : ( scrollIsRootNode ? 0 : scroll.scrollTop() ) ) * mod) - ), - left: ( - pos.left // The absolute mouse position - + this.offset.relative.left * mod // Only for relative positioned nodes: Relative offset from element to offset parent - + this.offset.parent.left * mod // The offsetParent's offset without borders (offset + border) - - ($.browser.safari && this.cssPosition == 'fixed' ? 0 : ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : scroll.scrollLeft() ) * mod) - ) - }; - - }, - - _generatePosition: function(event) { - - var o = this.options, scroll = this.cssPosition == 'absolute' && !(this.scrollParent[0] != document && $.ui.contains(this.scrollParent[0], this.offsetParent[0])) ? this.offsetParent : this.scrollParent, scrollIsRootNode = (/(html|body)/i).test(scroll[0].tagName); - - // This is another very weird special case that only happens for relative elements: - // 1. If the css position is relative - // 2. and the scroll parent is the document or similar to the offset parent - // we have to refresh the relative offset during the scroll so there are no jumps - if(this.cssPosition == 'relative' && !(this.scrollParent[0] != document && this.scrollParent[0] != this.offsetParent[0])) { - this.offset.relative = this._getRelativeOffset(); - } - - var pageX = event.pageX; - var pageY = event.pageY; - - /* - * - Position constraining - - * Constrain the position to a mix of grid, containment. - */ - - if(this.originalPosition) { //If we are not dragging yet, we won't check for options - - if(this.containment) { - if(event.pageX - this.offset.click.left < this.containment[0]) pageX = this.containment[0] + this.offset.click.left; - if(event.pageY - this.offset.click.top < this.containment[1]) pageY = this.containment[1] + this.offset.click.top; - if(event.pageX - this.offset.click.left > this.containment[2]) pageX = this.containment[2] + this.offset.click.left; - if(event.pageY - this.offset.click.top > this.containment[3]) pageY = this.containment[3] + this.offset.click.top; - } - - if(o.grid) { - var top = this.originalPageY + Math.round((pageY - this.originalPageY) / o.grid[1]) * o.grid[1]; - pageY = this.containment ? (!(top - this.offset.click.top < this.containment[1] || top - this.offset.click.top > this.containment[3]) ? top : (!(top - this.offset.click.top < this.containment[1]) ? top - o.grid[1] : top + o.grid[1])) : top; - - var left = this.originalPageX + Math.round((pageX - this.originalPageX) / o.grid[0]) * o.grid[0]; - pageX = this.containment ? (!(left - this.offset.click.left < this.containment[0] || left - this.offset.click.left > this.containment[2]) ? left : (!(left - this.offset.click.left < this.containment[0]) ? left - o.grid[0] : left + o.grid[0])) : left; - } - - } - - return { - top: ( - pageY // The absolute mouse position - - this.offset.click.top // Click offset (relative to the element) - - this.offset.relative.top // Only for relative positioned nodes: Relative offset from element to offset parent - - this.offset.parent.top // The offsetParent's offset without borders (offset + border) - + ($.browser.safari && this.cssPosition == 'fixed' ? 0 : ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollTop() : ( scrollIsRootNode ? 0 : scroll.scrollTop() ) )) - ), - left: ( - pageX // The absolute mouse position - - this.offset.click.left // Click offset (relative to the element) - - this.offset.relative.left // Only for relative positioned nodes: Relative offset from element to offset parent - - this.offset.parent.left // The offsetParent's offset without borders (offset + border) - + ($.browser.safari && this.cssPosition == 'fixed' ? 0 : ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : scroll.scrollLeft() )) - ) - }; - - }, - - _rearrange: function(event, i, a, hardRefresh) { - - a ? a[0].appendChild(this.placeholder[0]) : i.item[0].parentNode.insertBefore(this.placeholder[0], (this.direction == 'down' ? i.item[0] : i.item[0].nextSibling)); - - //Various things done here to improve the performance: - // 1. we create a setTimeout, that calls refreshPositions - // 2. on the instance, we have a counter variable, that get's higher after every append - // 3. on the local scope, we copy the counter variable, and check in the timeout, if it's still the same - // 4. this lets only the last addition to the timeout stack through - this.counter = this.counter ? ++this.counter : 1; - var self = this, counter = this.counter; - - window.setTimeout(function() { - if(counter == self.counter) self.refreshPositions(!hardRefresh); //Precompute after each DOM insertion, NOT on mousemove - },0); - - }, - - _clear: function(event, noPropagation) { - - this.reverting = false; - // We delay all events that have to be triggered to after the point where the placeholder has been removed and - // everything else normalized again - var delayedTriggers = [], self = this; - - // We first have to update the dom position of the actual currentItem - // Note: don't do it if the current item is already removed (by a user), or it gets reappended (see #4088) - if(!this._noFinalSort && this.currentItem.parent().length) this.placeholder.before(this.currentItem); - this._noFinalSort = null; - - if(this.helper[0] == this.currentItem[0]) { - for(var i in this._storedCSS) { - if(this._storedCSS[i] == 'auto' || this._storedCSS[i] == 'static') this._storedCSS[i] = ''; - } - this.currentItem.css(this._storedCSS).removeClass("ui-sortable-helper"); - } else { - this.currentItem.show(); - } - - if(this.fromOutside && !noPropagation) delayedTriggers.push(function(event) { this._trigger("receive", event, this._uiHash(this.fromOutside)); }); - if((this.fromOutside || this.domPosition.prev != this.currentItem.prev().not(".ui-sortable-helper")[0] || this.domPosition.parent != this.currentItem.parent()[0]) && !noPropagation) delayedTriggers.push(function(event) { this._trigger("update", event, this._uiHash()); }); //Trigger update callback if the DOM position has changed - if(!$.ui.contains(this.element[0], this.currentItem[0])) { //Node was moved out of the current element - if(!noPropagation) delayedTriggers.push(function(event) { this._trigger("remove", event, this._uiHash()); }); - for (var i = this.containers.length - 1; i >= 0; i--){ - if($.ui.contains(this.containers[i].element[0], this.currentItem[0]) && !noPropagation) { - delayedTriggers.push((function(c) { return function(event) { c._trigger("receive", event, this._uiHash(this)); }; }).call(this, this.containers[i])); - delayedTriggers.push((function(c) { return function(event) { c._trigger("update", event, this._uiHash(this)); }; }).call(this, this.containers[i])); - } - }; - }; - - //Post events to containers - for (var i = this.containers.length - 1; i >= 0; i--){ - if(!noPropagation) delayedTriggers.push((function(c) { return function(event) { c._trigger("deactivate", event, this._uiHash(this)); }; }).call(this, this.containers[i])); - if(this.containers[i].containerCache.over) { - delayedTriggers.push((function(c) { return function(event) { c._trigger("out", event, this._uiHash(this)); }; }).call(this, this.containers[i])); - this.containers[i].containerCache.over = 0; - } - } - - //Do what was originally in plugins - if(this._storedCursor) $('body').css("cursor", this._storedCursor); //Reset cursor - if(this._storedOpacity) this.helper.css("opacity", this._storedOpacity); //Reset opacity - if(this._storedZIndex) this.helper.css("zIndex", this._storedZIndex == 'auto' ? '' : this._storedZIndex); //Reset z-index - - this.dragging = false; - if(this.cancelHelperRemoval) { - if(!noPropagation) { - this._trigger("beforeStop", event, this._uiHash()); - for (var i=0; i < delayedTriggers.length; i++) { delayedTriggers[i].call(this, event); }; //Trigger all delayed events - this._trigger("stop", event, this._uiHash()); - } - return false; - } - - if(!noPropagation) this._trigger("beforeStop", event, this._uiHash()); - - //$(this.placeholder[0]).remove(); would have been the jQuery way - unfortunately, it unbinds ALL events from the original node! - this.placeholder[0].parentNode.removeChild(this.placeholder[0]); - - if(this.helper[0] != this.currentItem[0]) this.helper.remove(); this.helper = null; - - if(!noPropagation) { - for (var i=0; i < delayedTriggers.length; i++) { delayedTriggers[i].call(this, event); }; //Trigger all delayed events - this._trigger("stop", event, this._uiHash()); - } - - this.fromOutside = false; - return true; - - }, - - _trigger: function() { - if ($.Widget.prototype._trigger.apply(this, arguments) === false) { - this.cancel(); - } - }, - - _uiHash: function(inst) { - var self = inst || this; - return { - helper: self.helper, - placeholder: self.placeholder || $([]), - position: self.position, - originalPosition: self.originalPosition, - offset: self.positionAbs, - item: self.currentItem, - sender: inst ? inst.element : null - }; - } - -}); - -$.extend($.ui.sortable, { - version: "1.8.15" -}); - -})(jQuery); -/* - * jQuery UI Effects 1.8.15 - * - * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) - * Dual licensed under the MIT or GPL Version 2 licenses. - * http://jquery.org/license - * - * http://docs.jquery.com/UI/Effects/ - */ -;jQuery.effects || (function($, undefined) { - -$.effects = {}; - - - -/******************************************************************************/ -/****************************** COLOR ANIMATIONS ******************************/ -/******************************************************************************/ - -// override the animation for color styles -$.each(['backgroundColor', 'borderBottomColor', 'borderLeftColor', - 'borderRightColor', 'borderTopColor', 'borderColor', 'color', 'outlineColor'], -function(i, attr) { - $.fx.step[attr] = function(fx) { - if (!fx.colorInit) { - fx.start = getColor(fx.elem, attr); - fx.end = getRGB(fx.end); - fx.colorInit = true; - } - - fx.elem.style[attr] = 'rgb(' + - Math.max(Math.min(parseInt((fx.pos * (fx.end[0] - fx.start[0])) + fx.start[0], 10), 255), 0) + ',' + - Math.max(Math.min(parseInt((fx.pos * (fx.end[1] - fx.start[1])) + fx.start[1], 10), 255), 0) + ',' + - Math.max(Math.min(parseInt((fx.pos * (fx.end[2] - fx.start[2])) + fx.start[2], 10), 255), 0) + ')'; - }; -}); - -// Color Conversion functions from highlightFade -// By Blair Mitchelmore -// http://jquery.offput.ca/highlightFade/ - -// Parse strings looking for color tuples [255,255,255] -function getRGB(color) { - var result; - - // Check if we're already dealing with an array of colors - if ( color && color.constructor == Array && color.length == 3 ) - return color; - - // Look for rgb(num,num,num) - if (result = /rgb\(\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*\)/.exec(color)) - return [parseInt(result[1],10), parseInt(result[2],10), parseInt(result[3],10)]; - - // Look for rgb(num%,num%,num%) - if (result = /rgb\(\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*\)/.exec(color)) - return [parseFloat(result[1])*2.55, parseFloat(result[2])*2.55, parseFloat(result[3])*2.55]; - - // Look for #a0b1c2 - if (result = /#([a-fA-F0-9]{2})([a-fA-F0-9]{2})([a-fA-F0-9]{2})/.exec(color)) - return [parseInt(result[1],16), parseInt(result[2],16), parseInt(result[3],16)]; - - // Look for #fff - if (result = /#([a-fA-F0-9])([a-fA-F0-9])([a-fA-F0-9])/.exec(color)) - return [parseInt(result[1]+result[1],16), parseInt(result[2]+result[2],16), parseInt(result[3]+result[3],16)]; - - // Look for rgba(0, 0, 0, 0) == transparent in Safari 3 - if (result = /rgba\(0, 0, 0, 0\)/.exec(color)) - return colors['transparent']; - - // Otherwise, we're most likely dealing with a named color - return colors[$.trim(color).toLowerCase()]; -} - -function getColor(elem, attr) { - var color; - - do { - color = $.curCSS(elem, attr); - - // Keep going until we find an element that has color, or we hit the body - if ( color != '' && color != 'transparent' || $.nodeName(elem, "body") ) - break; - - attr = "backgroundColor"; - } while ( elem = elem.parentNode ); - - return getRGB(color); -}; - -// Some named colors to work with -// From Interface by Stefan Petre -// http://interface.eyecon.ro/ - -var colors = { - aqua:[0,255,255], - azure:[240,255,255], - beige:[245,245,220], - black:[0,0,0], - blue:[0,0,255], - brown:[165,42,42], - cyan:[0,255,255], - darkblue:[0,0,139], - darkcyan:[0,139,139], - darkgrey:[169,169,169], - darkgreen:[0,100,0], - darkkhaki:[189,183,107], - darkmagenta:[139,0,139], - darkolivegreen:[85,107,47], - darkorange:[255,140,0], - darkorchid:[153,50,204], - darkred:[139,0,0], - darksalmon:[233,150,122], - darkviolet:[148,0,211], - fuchsia:[255,0,255], - gold:[255,215,0], - green:[0,128,0], - indigo:[75,0,130], - khaki:[240,230,140], - lightblue:[173,216,230], - lightcyan:[224,255,255], - lightgreen:[144,238,144], - lightgrey:[211,211,211], - lightpink:[255,182,193], - lightyellow:[255,255,224], - lime:[0,255,0], - magenta:[255,0,255], - maroon:[128,0,0], - navy:[0,0,128], - olive:[128,128,0], - orange:[255,165,0], - pink:[255,192,203], - purple:[128,0,128], - violet:[128,0,128], - red:[255,0,0], - silver:[192,192,192], - white:[255,255,255], - yellow:[255,255,0], - transparent: [255,255,255] -}; - - - -/******************************************************************************/ -/****************************** CLASS ANIMATIONS ******************************/ -/******************************************************************************/ - -var classAnimationActions = ['add', 'remove', 'toggle'], - shorthandStyles = { - border: 1, - borderBottom: 1, - borderColor: 1, - borderLeft: 1, - borderRight: 1, - borderTop: 1, - borderWidth: 1, - margin: 1, - padding: 1 - }; - -function getElementStyles() { - var style = document.defaultView - ? document.defaultView.getComputedStyle(this, null) - : this.currentStyle, - newStyle = {}, - key, - camelCase; - - // webkit enumerates style porperties - if (style && style.length && style[0] && style[style[0]]) { - var len = style.length; - while (len--) { - key = style[len]; - if (typeof style[key] == 'string') { - camelCase = key.replace(/\-(\w)/g, function(all, letter){ - return letter.toUpperCase(); - }); - newStyle[camelCase] = style[key]; - } - } - } else { - for (key in style) { - if (typeof style[key] === 'string') { - newStyle[key] = style[key]; - } - } - } - - return newStyle; -} - -function filterStyles(styles) { - var name, value; - for (name in styles) { - value = styles[name]; - if ( - // ignore null and undefined values - value == null || - // ignore functions (when does this occur?) - $.isFunction(value) || - // shorthand styles that need to be expanded - name in shorthandStyles || - // ignore scrollbars (break in IE) - (/scrollbar/).test(name) || - - // only colors or values that can be converted to numbers - (!(/color/i).test(name) && isNaN(parseFloat(value))) - ) { - delete styles[name]; - } - } - - return styles; -} - -function styleDifference(oldStyle, newStyle) { - var diff = { _: 0 }, // http://dev.jquery.com/ticket/5459 - name; - - for (name in newStyle) { - if (oldStyle[name] != newStyle[name]) { - diff[name] = newStyle[name]; - } - } - - return diff; -} - -$.effects.animateClass = function(value, duration, easing, callback) { - if ($.isFunction(easing)) { - callback = easing; - easing = null; - } - - return this.queue(function() { - var that = $(this), - originalStyleAttr = that.attr('style') || ' ', - originalStyle = filterStyles(getElementStyles.call(this)), - newStyle, - className = that.attr('class'); - - $.each(classAnimationActions, function(i, action) { - if (value[action]) { - that[action + 'Class'](value[action]); - } - }); - newStyle = filterStyles(getElementStyles.call(this)); - that.attr('class', className); - - that.animate(styleDifference(originalStyle, newStyle), { - queue: false, - duration: duration, - easing: easing, - complete: function() { - $.each(classAnimationActions, function(i, action) { - if (value[action]) { that[action + 'Class'](value[action]); } - }); - // work around bug in IE by clearing the cssText before setting it - if (typeof that.attr('style') == 'object') { - that.attr('style').cssText = ''; - that.attr('style').cssText = originalStyleAttr; - } else { - that.attr('style', originalStyleAttr); - } - if (callback) { callback.apply(this, arguments); } - $.dequeue( this ); - } - }); - }); -}; - -$.fn.extend({ - _addClass: $.fn.addClass, - addClass: function(classNames, speed, easing, callback) { - return speed ? $.effects.animateClass.apply(this, [{ add: classNames },speed,easing,callback]) : this._addClass(classNames); - }, - - _removeClass: $.fn.removeClass, - removeClass: function(classNames,speed,easing,callback) { - return speed ? $.effects.animateClass.apply(this, [{ remove: classNames },speed,easing,callback]) : this._removeClass(classNames); - }, - - _toggleClass: $.fn.toggleClass, - toggleClass: function(classNames, force, speed, easing, callback) { - if ( typeof force == "boolean" || force === undefined ) { - if ( !speed ) { - // without speed parameter; - return this._toggleClass(classNames, force); - } else { - return $.effects.animateClass.apply(this, [(force?{add:classNames}:{remove:classNames}),speed,easing,callback]); - } - } else { - // without switch parameter; - return $.effects.animateClass.apply(this, [{ toggle: classNames },force,speed,easing]); - } - }, - - switchClass: function(remove,add,speed,easing,callback) { - return $.effects.animateClass.apply(this, [{ add: add, remove: remove },speed,easing,callback]); - } -}); - - - -/******************************************************************************/ -/*********************************** EFFECTS **********************************/ -/******************************************************************************/ - -$.extend($.effects, { - version: "1.8.15", - - // Saves a set of properties in a data storage - save: function(element, set) { - for(var i=0; i < set.length; i++) { - if(set[i] !== null) element.data("ec.storage."+set[i], element[0].style[set[i]]); - } - }, - - // Restores a set of previously saved properties from a data storage - restore: function(element, set) { - for(var i=0; i < set.length; i++) { - if(set[i] !== null) element.css(set[i], element.data("ec.storage."+set[i])); - } - }, - - setMode: function(el, mode) { - if (mode == 'toggle') mode = el.is(':hidden') ? 'show' : 'hide'; // Set for toggle - return mode; - }, - - getBaseline: function(origin, original) { // Translates a [top,left] array into a baseline value - // this should be a little more flexible in the future to handle a string & hash - var y, x; - switch (origin[0]) { - case 'top': y = 0; break; - case 'middle': y = 0.5; break; - case 'bottom': y = 1; break; - default: y = origin[0] / original.height; - }; - switch (origin[1]) { - case 'left': x = 0; break; - case 'center': x = 0.5; break; - case 'right': x = 1; break; - default: x = origin[1] / original.width; - }; - return {x: x, y: y}; - }, - - // Wraps the element around a wrapper that copies position properties - createWrapper: function(element) { - - // if the element is already wrapped, return it - if (element.parent().is('.ui-effects-wrapper')) { - return element.parent(); - } - - // wrap the element - var props = { - width: element.outerWidth(true), - height: element.outerHeight(true), - 'float': element.css('float') - }, - wrapper = $('
    ') - .addClass('ui-effects-wrapper') - .css({ - fontSize: '100%', - background: 'transparent', - border: 'none', - margin: 0, - padding: 0 - }); - - element.wrap(wrapper); - wrapper = element.parent(); //Hotfix for jQuery 1.4 since some change in wrap() seems to actually loose the reference to the wrapped element - - // transfer positioning properties to the wrapper - if (element.css('position') == 'static') { - wrapper.css({ position: 'relative' }); - element.css({ position: 'relative' }); - } else { - $.extend(props, { - position: element.css('position'), - zIndex: element.css('z-index') - }); - $.each(['top', 'left', 'bottom', 'right'], function(i, pos) { - props[pos] = element.css(pos); - if (isNaN(parseInt(props[pos], 10))) { - props[pos] = 'auto'; - } - }); - element.css({position: 'relative', top: 0, left: 0, right: 'auto', bottom: 'auto' }); - } - - return wrapper.css(props).show(); - }, - - removeWrapper: function(element) { - if (element.parent().is('.ui-effects-wrapper')) - return element.parent().replaceWith(element); - return element; - }, - - setTransition: function(element, list, factor, value) { - value = value || {}; - $.each(list, function(i, x){ - unit = element.cssUnit(x); - if (unit[0] > 0) value[x] = unit[0] * factor + unit[1]; - }); - return value; - } -}); - - -function _normalizeArguments(effect, options, speed, callback) { - // shift params for method overloading - if (typeof effect == 'object') { - callback = options; - speed = null; - options = effect; - effect = options.effect; - } - if ($.isFunction(options)) { - callback = options; - speed = null; - options = {}; - } - if (typeof options == 'number' || $.fx.speeds[options]) { - callback = speed; - speed = options; - options = {}; - } - if ($.isFunction(speed)) { - callback = speed; - speed = null; - } - - options = options || {}; - - speed = speed || options.duration; - speed = $.fx.off ? 0 : typeof speed == 'number' - ? speed : speed in $.fx.speeds ? $.fx.speeds[speed] : $.fx.speeds._default; - - callback = callback || options.complete; - - return [effect, options, speed, callback]; -} - -function standardSpeed( speed ) { - // valid standard speeds - if ( !speed || typeof speed === "number" || $.fx.speeds[ speed ] ) { - return true; - } - - // invalid strings - treat as "normal" speed - if ( typeof speed === "string" && !$.effects[ speed ] ) { - return true; - } - - return false; -} - -$.fn.extend({ - effect: function(effect, options, speed, callback) { - var args = _normalizeArguments.apply(this, arguments), - // TODO: make effects take actual parameters instead of a hash - args2 = { - options: args[1], - duration: args[2], - callback: args[3] - }, - mode = args2.options.mode, - effectMethod = $.effects[effect]; - - if ( $.fx.off || !effectMethod ) { - // delegate to the original method (e.g., .show()) if possible - if ( mode ) { - return this[ mode ]( args2.duration, args2.callback ); - } else { - return this.each(function() { - if ( args2.callback ) { - args2.callback.call( this ); - } - }); - } - } - - return effectMethod.call(this, args2); - }, - - _show: $.fn.show, - show: function(speed) { - if ( standardSpeed( speed ) ) { - return this._show.apply(this, arguments); - } else { - var args = _normalizeArguments.apply(this, arguments); - args[1].mode = 'show'; - return this.effect.apply(this, args); - } - }, - - _hide: $.fn.hide, - hide: function(speed) { - if ( standardSpeed( speed ) ) { - return this._hide.apply(this, arguments); - } else { - var args = _normalizeArguments.apply(this, arguments); - args[1].mode = 'hide'; - return this.effect.apply(this, args); - } - }, - - // jQuery core overloads toggle and creates _toggle - __toggle: $.fn.toggle, - toggle: function(speed) { - if ( standardSpeed( speed ) || typeof speed === "boolean" || $.isFunction( speed ) ) { - return this.__toggle.apply(this, arguments); - } else { - var args = _normalizeArguments.apply(this, arguments); - args[1].mode = 'toggle'; - return this.effect.apply(this, args); - } - }, - - // helper functions - cssUnit: function(key) { - var style = this.css(key), val = []; - $.each( ['em','px','%','pt'], function(i, unit){ - if(style.indexOf(unit) > 0) - val = [parseFloat(style), unit]; - }); - return val; - } -}); - - - -/******************************************************************************/ -/*********************************** EASING ***********************************/ -/******************************************************************************/ - -/* - * jQuery Easing v1.3 - http://gsgd.co.uk/sandbox/jquery/easing/ - * - * Uses the built in easing capabilities added In jQuery 1.1 - * to offer multiple easing options - * - * TERMS OF USE - jQuery Easing - * - * Open source under the BSD License. - * - * Copyright 2008 George McGinley Smith - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * Redistributions of source code must retain the above copyright notice, this list of - * conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright notice, this list - * of conditions and the following disclaimer in the documentation and/or other materials - * provided with the distribution. - * - * Neither the name of the author nor the names of contributors may be used to endorse - * or promote products derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE - * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED - * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * -*/ - -// t: current time, b: begInnIng value, c: change In value, d: duration -$.easing.jswing = $.easing.swing; - -$.extend($.easing, -{ - def: 'easeOutQuad', - swing: function (x, t, b, c, d) { - //alert($.easing.default); - return $.easing[$.easing.def](x, t, b, c, d); - }, - easeInQuad: function (x, t, b, c, d) { - return c*(t/=d)*t + b; - }, - easeOutQuad: function (x, t, b, c, d) { - return -c *(t/=d)*(t-2) + b; - }, - easeInOutQuad: function (x, t, b, c, d) { - if ((t/=d/2) < 1) return c/2*t*t + b; - return -c/2 * ((--t)*(t-2) - 1) + b; - }, - easeInCubic: function (x, t, b, c, d) { - return c*(t/=d)*t*t + b; - }, - easeOutCubic: function (x, t, b, c, d) { - return c*((t=t/d-1)*t*t + 1) + b; - }, - easeInOutCubic: function (x, t, b, c, d) { - if ((t/=d/2) < 1) return c/2*t*t*t + b; - return c/2*((t-=2)*t*t + 2) + b; - }, - easeInQuart: function (x, t, b, c, d) { - return c*(t/=d)*t*t*t + b; - }, - easeOutQuart: function (x, t, b, c, d) { - return -c * ((t=t/d-1)*t*t*t - 1) + b; - }, - easeInOutQuart: function (x, t, b, c, d) { - if ((t/=d/2) < 1) return c/2*t*t*t*t + b; - return -c/2 * ((t-=2)*t*t*t - 2) + b; - }, - easeInQuint: function (x, t, b, c, d) { - return c*(t/=d)*t*t*t*t + b; - }, - easeOutQuint: function (x, t, b, c, d) { - return c*((t=t/d-1)*t*t*t*t + 1) + b; - }, - easeInOutQuint: function (x, t, b, c, d) { - if ((t/=d/2) < 1) return c/2*t*t*t*t*t + b; - return c/2*((t-=2)*t*t*t*t + 2) + b; - }, - easeInSine: function (x, t, b, c, d) { - return -c * Math.cos(t/d * (Math.PI/2)) + c + b; - }, - easeOutSine: function (x, t, b, c, d) { - return c * Math.sin(t/d * (Math.PI/2)) + b; - }, - easeInOutSine: function (x, t, b, c, d) { - return -c/2 * (Math.cos(Math.PI*t/d) - 1) + b; - }, - easeInExpo: function (x, t, b, c, d) { - return (t==0) ? b : c * Math.pow(2, 10 * (t/d - 1)) + b; - }, - easeOutExpo: function (x, t, b, c, d) { - return (t==d) ? b+c : c * (-Math.pow(2, -10 * t/d) + 1) + b; - }, - easeInOutExpo: function (x, t, b, c, d) { - if (t==0) return b; - if (t==d) return b+c; - if ((t/=d/2) < 1) return c/2 * Math.pow(2, 10 * (t - 1)) + b; - return c/2 * (-Math.pow(2, -10 * --t) + 2) + b; - }, - easeInCirc: function (x, t, b, c, d) { - return -c * (Math.sqrt(1 - (t/=d)*t) - 1) + b; - }, - easeOutCirc: function (x, t, b, c, d) { - return c * Math.sqrt(1 - (t=t/d-1)*t) + b; - }, - easeInOutCirc: function (x, t, b, c, d) { - if ((t/=d/2) < 1) return -c/2 * (Math.sqrt(1 - t*t) - 1) + b; - return c/2 * (Math.sqrt(1 - (t-=2)*t) + 1) + b; - }, - easeInElastic: function (x, t, b, c, d) { - var s=1.70158;var p=0;var a=c; - if (t==0) return b; if ((t/=d)==1) return b+c; if (!p) p=d*.3; - if (a < Math.abs(c)) { a=c; var s=p/4; } - else var s = p/(2*Math.PI) * Math.asin (c/a); - return -(a*Math.pow(2,10*(t-=1)) * Math.sin( (t*d-s)*(2*Math.PI)/p )) + b; - }, - easeOutElastic: function (x, t, b, c, d) { - var s=1.70158;var p=0;var a=c; - if (t==0) return b; if ((t/=d)==1) return b+c; if (!p) p=d*.3; - if (a < Math.abs(c)) { a=c; var s=p/4; } - else var s = p/(2*Math.PI) * Math.asin (c/a); - return a*Math.pow(2,-10*t) * Math.sin( (t*d-s)*(2*Math.PI)/p ) + c + b; - }, - easeInOutElastic: function (x, t, b, c, d) { - var s=1.70158;var p=0;var a=c; - if (t==0) return b; if ((t/=d/2)==2) return b+c; if (!p) p=d*(.3*1.5); - if (a < Math.abs(c)) { a=c; var s=p/4; } - else var s = p/(2*Math.PI) * Math.asin (c/a); - if (t < 1) return -.5*(a*Math.pow(2,10*(t-=1)) * Math.sin( (t*d-s)*(2*Math.PI)/p )) + b; - return a*Math.pow(2,-10*(t-=1)) * Math.sin( (t*d-s)*(2*Math.PI)/p )*.5 + c + b; - }, - easeInBack: function (x, t, b, c, d, s) { - if (s == undefined) s = 1.70158; - return c*(t/=d)*t*((s+1)*t - s) + b; - }, - easeOutBack: function (x, t, b, c, d, s) { - if (s == undefined) s = 1.70158; - return c*((t=t/d-1)*t*((s+1)*t + s) + 1) + b; - }, - easeInOutBack: function (x, t, b, c, d, s) { - if (s == undefined) s = 1.70158; - if ((t/=d/2) < 1) return c/2*(t*t*(((s*=(1.525))+1)*t - s)) + b; - return c/2*((t-=2)*t*(((s*=(1.525))+1)*t + s) + 2) + b; - }, - easeInBounce: function (x, t, b, c, d) { - return c - $.easing.easeOutBounce (x, d-t, 0, c, d) + b; - }, - easeOutBounce: function (x, t, b, c, d) { - if ((t/=d) < (1/2.75)) { - return c*(7.5625*t*t) + b; - } else if (t < (2/2.75)) { - return c*(7.5625*(t-=(1.5/2.75))*t + .75) + b; - } else if (t < (2.5/2.75)) { - return c*(7.5625*(t-=(2.25/2.75))*t + .9375) + b; - } else { - return c*(7.5625*(t-=(2.625/2.75))*t + .984375) + b; - } - }, - easeInOutBounce: function (x, t, b, c, d) { - if (t < d/2) return $.easing.easeInBounce (x, t*2, 0, c, d) * .5 + b; - return $.easing.easeOutBounce (x, t*2-d, 0, c, d) * .5 + c*.5 + b; - } -}); - -/* - * - * TERMS OF USE - EASING EQUATIONS - * - * Open source under the BSD License. - * - * Copyright 2001 Robert Penner - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * Redistributions of source code must retain the above copyright notice, this list of - * conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright notice, this list - * of conditions and the following disclaimer in the documentation and/or other materials - * provided with the distribution. - * - * Neither the name of the author nor the names of contributors may be used to endorse - * or promote products derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE - * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED - * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * - */ - -})(jQuery); -/* - * jQuery UI Effects Blind 1.8.15 - * - * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) - * Dual licensed under the MIT or GPL Version 2 licenses. - * http://jquery.org/license - * - * http://docs.jquery.com/UI/Effects/Blind - * - * Depends: - * jquery.effects.core.js - */ -(function( $, undefined ) { - -$.effects.blind = function(o) { - - return this.queue(function() { - - // Create element - var el = $(this), props = ['position','top','bottom','left','right']; - - // Set options - var mode = $.effects.setMode(el, o.options.mode || 'hide'); // Set Mode - var direction = o.options.direction || 'vertical'; // Default direction - - // Adjust - $.effects.save(el, props); el.show(); // Save & Show - var wrapper = $.effects.createWrapper(el).css({overflow:'hidden'}); // Create Wrapper - var ref = (direction == 'vertical') ? 'height' : 'width'; - var distance = (direction == 'vertical') ? wrapper.height() : wrapper.width(); - if(mode == 'show') wrapper.css(ref, 0); // Shift - - // Animation - var animation = {}; - animation[ref] = mode == 'show' ? distance : 0; - - // Animate - wrapper.animate(animation, o.duration, o.options.easing, function() { - if(mode == 'hide') el.hide(); // Hide - $.effects.restore(el, props); $.effects.removeWrapper(el); // Restore - if(o.callback) o.callback.apply(el[0], arguments); // Callback - el.dequeue(); - }); - - }); - -}; - -})(jQuery); -/* - * jQuery UI Effects Bounce 1.8.15 - * - * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) - * Dual licensed under the MIT or GPL Version 2 licenses. - * http://jquery.org/license - * - * http://docs.jquery.com/UI/Effects/Bounce - * - * Depends: - * jquery.effects.core.js - */ -(function( $, undefined ) { - -$.effects.bounce = function(o) { - - return this.queue(function() { - - // Create element - var el = $(this), props = ['position','top','bottom','left','right']; - - // Set options - var mode = $.effects.setMode(el, o.options.mode || 'effect'); // Set Mode - var direction = o.options.direction || 'up'; // Default direction - var distance = o.options.distance || 20; // Default distance - var times = o.options.times || 5; // Default # of times - var speed = o.duration || 250; // Default speed per bounce - if (/show|hide/.test(mode)) props.push('opacity'); // Avoid touching opacity to prevent clearType and PNG issues in IE - - // Adjust - $.effects.save(el, props); el.show(); // Save & Show - $.effects.createWrapper(el); // Create Wrapper - var ref = (direction == 'up' || direction == 'down') ? 'top' : 'left'; - var motion = (direction == 'up' || direction == 'left') ? 'pos' : 'neg'; - var distance = o.options.distance || (ref == 'top' ? el.outerHeight({margin:true}) / 3 : el.outerWidth({margin:true}) / 3); - if (mode == 'show') el.css('opacity', 0).css(ref, motion == 'pos' ? -distance : distance); // Shift - if (mode == 'hide') distance = distance / (times * 2); - if (mode != 'hide') times--; - - // Animate - if (mode == 'show') { // Show Bounce - var animation = {opacity: 1}; - animation[ref] = (motion == 'pos' ? '+=' : '-=') + distance; - el.animate(animation, speed / 2, o.options.easing); - distance = distance / 2; - times--; - }; - for (var i = 0; i < times; i++) { // Bounces - var animation1 = {}, animation2 = {}; - animation1[ref] = (motion == 'pos' ? '-=' : '+=') + distance; - animation2[ref] = (motion == 'pos' ? '+=' : '-=') + distance; - el.animate(animation1, speed / 2, o.options.easing).animate(animation2, speed / 2, o.options.easing); - distance = (mode == 'hide') ? distance * 2 : distance / 2; - }; - if (mode == 'hide') { // Last Bounce - var animation = {opacity: 0}; - animation[ref] = (motion == 'pos' ? '-=' : '+=') + distance; - el.animate(animation, speed / 2, o.options.easing, function(){ - el.hide(); // Hide - $.effects.restore(el, props); $.effects.removeWrapper(el); // Restore - if(o.callback) o.callback.apply(this, arguments); // Callback - }); - } else { - var animation1 = {}, animation2 = {}; - animation1[ref] = (motion == 'pos' ? '-=' : '+=') + distance; - animation2[ref] = (motion == 'pos' ? '+=' : '-=') + distance; - el.animate(animation1, speed / 2, o.options.easing).animate(animation2, speed / 2, o.options.easing, function(){ - $.effects.restore(el, props); $.effects.removeWrapper(el); // Restore - if(o.callback) o.callback.apply(this, arguments); // Callback - }); - }; - el.queue('fx', function() { el.dequeue(); }); - el.dequeue(); - }); - -}; - -})(jQuery); -/* - * jQuery UI Effects Clip 1.8.15 - * - * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) - * Dual licensed under the MIT or GPL Version 2 licenses. - * http://jquery.org/license - * - * http://docs.jquery.com/UI/Effects/Clip - * - * Depends: - * jquery.effects.core.js - */ -(function( $, undefined ) { - -$.effects.clip = function(o) { - - return this.queue(function() { - - // Create element - var el = $(this), props = ['position','top','bottom','left','right','height','width']; - - // Set options - var mode = $.effects.setMode(el, o.options.mode || 'hide'); // Set Mode - var direction = o.options.direction || 'vertical'; // Default direction - - // Adjust - $.effects.save(el, props); el.show(); // Save & Show - var wrapper = $.effects.createWrapper(el).css({overflow:'hidden'}); // Create Wrapper - var animate = el[0].tagName == 'IMG' ? wrapper : el; - var ref = { - size: (direction == 'vertical') ? 'height' : 'width', - position: (direction == 'vertical') ? 'top' : 'left' - }; - var distance = (direction == 'vertical') ? animate.height() : animate.width(); - if(mode == 'show') { animate.css(ref.size, 0); animate.css(ref.position, distance / 2); } // Shift - - // Animation - var animation = {}; - animation[ref.size] = mode == 'show' ? distance : 0; - animation[ref.position] = mode == 'show' ? 0 : distance / 2; - - // Animate - animate.animate(animation, { queue: false, duration: o.duration, easing: o.options.easing, complete: function() { - if(mode == 'hide') el.hide(); // Hide - $.effects.restore(el, props); $.effects.removeWrapper(el); // Restore - if(o.callback) o.callback.apply(el[0], arguments); // Callback - el.dequeue(); - }}); - - }); - -}; - -})(jQuery); -/* - * jQuery UI Effects Drop 1.8.15 - * - * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) - * Dual licensed under the MIT or GPL Version 2 licenses. - * http://jquery.org/license - * - * http://docs.jquery.com/UI/Effects/Drop - * - * Depends: - * jquery.effects.core.js - */ -(function( $, undefined ) { - -$.effects.drop = function(o) { - - return this.queue(function() { - - // Create element - var el = $(this), props = ['position','top','bottom','left','right','opacity']; - - // Set options - var mode = $.effects.setMode(el, o.options.mode || 'hide'); // Set Mode - var direction = o.options.direction || 'left'; // Default Direction - - // Adjust - $.effects.save(el, props); el.show(); // Save & Show - $.effects.createWrapper(el); // Create Wrapper - var ref = (direction == 'up' || direction == 'down') ? 'top' : 'left'; - var motion = (direction == 'up' || direction == 'left') ? 'pos' : 'neg'; - var distance = o.options.distance || (ref == 'top' ? el.outerHeight({margin:true}) / 2 : el.outerWidth({margin:true}) / 2); - if (mode == 'show') el.css('opacity', 0).css(ref, motion == 'pos' ? -distance : distance); // Shift - - // Animation - var animation = {opacity: mode == 'show' ? 1 : 0}; - animation[ref] = (mode == 'show' ? (motion == 'pos' ? '+=' : '-=') : (motion == 'pos' ? '-=' : '+=')) + distance; - - // Animate - el.animate(animation, { queue: false, duration: o.duration, easing: o.options.easing, complete: function() { - if(mode == 'hide') el.hide(); // Hide - $.effects.restore(el, props); $.effects.removeWrapper(el); // Restore - if(o.callback) o.callback.apply(this, arguments); // Callback - el.dequeue(); - }}); - - }); - -}; - -})(jQuery); -/* - * jQuery UI Effects Explode 1.8.15 - * - * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) - * Dual licensed under the MIT or GPL Version 2 licenses. - * http://jquery.org/license - * - * http://docs.jquery.com/UI/Effects/Explode - * - * Depends: - * jquery.effects.core.js - */ -(function( $, undefined ) { - -$.effects.explode = function(o) { - - return this.queue(function() { - - var rows = o.options.pieces ? Math.round(Math.sqrt(o.options.pieces)) : 3; - var cells = o.options.pieces ? Math.round(Math.sqrt(o.options.pieces)) : 3; - - o.options.mode = o.options.mode == 'toggle' ? ($(this).is(':visible') ? 'hide' : 'show') : o.options.mode; - var el = $(this).show().css('visibility', 'hidden'); - var offset = el.offset(); - - //Substract the margins - not fixing the problem yet. - offset.top -= parseInt(el.css("marginTop"),10) || 0; - offset.left -= parseInt(el.css("marginLeft"),10) || 0; - - var width = el.outerWidth(true); - var height = el.outerHeight(true); - - for(var i=0;i') - .css({ - position: 'absolute', - visibility: 'visible', - left: -j*(width/cells), - top: -i*(height/rows) - }) - .parent() - .addClass('ui-effects-explode') - .css({ - position: 'absolute', - overflow: 'hidden', - width: width/cells, - height: height/rows, - left: offset.left + j*(width/cells) + (o.options.mode == 'show' ? (j-Math.floor(cells/2))*(width/cells) : 0), - top: offset.top + i*(height/rows) + (o.options.mode == 'show' ? (i-Math.floor(rows/2))*(height/rows) : 0), - opacity: o.options.mode == 'show' ? 0 : 1 - }).animate({ - left: offset.left + j*(width/cells) + (o.options.mode == 'show' ? 0 : (j-Math.floor(cells/2))*(width/cells)), - top: offset.top + i*(height/rows) + (o.options.mode == 'show' ? 0 : (i-Math.floor(rows/2))*(height/rows)), - opacity: o.options.mode == 'show' ? 1 : 0 - }, o.duration || 500); - } - } - - // Set a timeout, to call the callback approx. when the other animations have finished - setTimeout(function() { - - o.options.mode == 'show' ? el.css({ visibility: 'visible' }) : el.css({ visibility: 'visible' }).hide(); - if(o.callback) o.callback.apply(el[0]); // Callback - el.dequeue(); - - $('div.ui-effects-explode').remove(); - - }, o.duration || 500); - - - }); - -}; - -})(jQuery); -/* - * jQuery UI Effects Fade 1.8.15 - * - * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) - * Dual licensed under the MIT or GPL Version 2 licenses. - * http://jquery.org/license - * - * http://docs.jquery.com/UI/Effects/Fade - * - * Depends: - * jquery.effects.core.js - */ -(function( $, undefined ) { - -$.effects.fade = function(o) { - return this.queue(function() { - var elem = $(this), - mode = $.effects.setMode(elem, o.options.mode || 'hide'); - - elem.animate({ opacity: mode }, { - queue: false, - duration: o.duration, - easing: o.options.easing, - complete: function() { - (o.callback && o.callback.apply(this, arguments)); - elem.dequeue(); - } - }); - }); -}; - -})(jQuery); -/* - * jQuery UI Effects Fold 1.8.15 - * - * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) - * Dual licensed under the MIT or GPL Version 2 licenses. - * http://jquery.org/license - * - * http://docs.jquery.com/UI/Effects/Fold - * - * Depends: - * jquery.effects.core.js - */ -(function( $, undefined ) { - -$.effects.fold = function(o) { - - return this.queue(function() { - - // Create element - var el = $(this), props = ['position','top','bottom','left','right']; - - // Set options - var mode = $.effects.setMode(el, o.options.mode || 'hide'); // Set Mode - var size = o.options.size || 15; // Default fold size - var horizFirst = !(!o.options.horizFirst); // Ensure a boolean value - var duration = o.duration ? o.duration / 2 : $.fx.speeds._default / 2; - - // Adjust - $.effects.save(el, props); el.show(); // Save & Show - var wrapper = $.effects.createWrapper(el).css({overflow:'hidden'}); // Create Wrapper - var widthFirst = ((mode == 'show') != horizFirst); - var ref = widthFirst ? ['width', 'height'] : ['height', 'width']; - var distance = widthFirst ? [wrapper.width(), wrapper.height()] : [wrapper.height(), wrapper.width()]; - var percent = /([0-9]+)%/.exec(size); - if(percent) size = parseInt(percent[1],10) / 100 * distance[mode == 'hide' ? 0 : 1]; - if(mode == 'show') wrapper.css(horizFirst ? {height: 0, width: size} : {height: size, width: 0}); // Shift - - // Animation - var animation1 = {}, animation2 = {}; - animation1[ref[0]] = mode == 'show' ? distance[0] : size; - animation2[ref[1]] = mode == 'show' ? distance[1] : 0; - - // Animate - wrapper.animate(animation1, duration, o.options.easing) - .animate(animation2, duration, o.options.easing, function() { - if(mode == 'hide') el.hide(); // Hide - $.effects.restore(el, props); $.effects.removeWrapper(el); // Restore - if(o.callback) o.callback.apply(el[0], arguments); // Callback - el.dequeue(); - }); - - }); - -}; - -})(jQuery); -/* - * jQuery UI Effects Highlight 1.8.15 - * - * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) - * Dual licensed under the MIT or GPL Version 2 licenses. - * http://jquery.org/license - * - * http://docs.jquery.com/UI/Effects/Highlight - * - * Depends: - * jquery.effects.core.js - */ -(function( $, undefined ) { - -$.effects.highlight = function(o) { - return this.queue(function() { - var elem = $(this), - props = ['backgroundImage', 'backgroundColor', 'opacity'], - mode = $.effects.setMode(elem, o.options.mode || 'show'), - animation = { - backgroundColor: elem.css('backgroundColor') - }; - - if (mode == 'hide') { - animation.opacity = 0; - } - - $.effects.save(elem, props); - elem - .show() - .css({ - backgroundImage: 'none', - backgroundColor: o.options.color || '#ffff99' - }) - .animate(animation, { - queue: false, - duration: o.duration, - easing: o.options.easing, - complete: function() { - (mode == 'hide' && elem.hide()); - $.effects.restore(elem, props); - (mode == 'show' && !$.support.opacity && this.style.removeAttribute('filter')); - (o.callback && o.callback.apply(this, arguments)); - elem.dequeue(); - } - }); - }); -}; - -})(jQuery); -/* - * jQuery UI Effects Pulsate 1.8.15 - * - * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) - * Dual licensed under the MIT or GPL Version 2 licenses. - * http://jquery.org/license - * - * http://docs.jquery.com/UI/Effects/Pulsate - * - * Depends: - * jquery.effects.core.js - */ -(function( $, undefined ) { - -$.effects.pulsate = function(o) { - return this.queue(function() { - var elem = $(this), - mode = $.effects.setMode(elem, o.options.mode || 'show'); - times = ((o.options.times || 5) * 2) - 1; - duration = o.duration ? o.duration / 2 : $.fx.speeds._default / 2, - isVisible = elem.is(':visible'), - animateTo = 0; - - if (!isVisible) { - elem.css('opacity', 0).show(); - animateTo = 1; - } - - if ((mode == 'hide' && isVisible) || (mode == 'show' && !isVisible)) { - times--; - } - - for (var i = 0; i < times; i++) { - elem.animate({ opacity: animateTo }, duration, o.options.easing); - animateTo = (animateTo + 1) % 2; - } - - elem.animate({ opacity: animateTo }, duration, o.options.easing, function() { - if (animateTo == 0) { - elem.hide(); - } - (o.callback && o.callback.apply(this, arguments)); - }); - - elem - .queue('fx', function() { elem.dequeue(); }) - .dequeue(); - }); -}; - -})(jQuery); -/* - * jQuery UI Effects Scale 1.8.15 - * - * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) - * Dual licensed under the MIT or GPL Version 2 licenses. - * http://jquery.org/license - * - * http://docs.jquery.com/UI/Effects/Scale - * - * Depends: - * jquery.effects.core.js - */ -(function( $, undefined ) { - -$.effects.puff = function(o) { - return this.queue(function() { - var elem = $(this), - mode = $.effects.setMode(elem, o.options.mode || 'hide'), - percent = parseInt(o.options.percent, 10) || 150, - factor = percent / 100, - original = { height: elem.height(), width: elem.width() }; - - $.extend(o.options, { - fade: true, - mode: mode, - percent: mode == 'hide' ? percent : 100, - from: mode == 'hide' - ? original - : { - height: original.height * factor, - width: original.width * factor - } - }); - - elem.effect('scale', o.options, o.duration, o.callback); - elem.dequeue(); - }); -}; - -$.effects.scale = function(o) { - - return this.queue(function() { - - // Create element - var el = $(this); - - // Set options - var options = $.extend(true, {}, o.options); - var mode = $.effects.setMode(el, o.options.mode || 'effect'); // Set Mode - var percent = parseInt(o.options.percent,10) || (parseInt(o.options.percent,10) == 0 ? 0 : (mode == 'hide' ? 0 : 100)); // Set default scaling percent - var direction = o.options.direction || 'both'; // Set default axis - var origin = o.options.origin; // The origin of the scaling - if (mode != 'effect') { // Set default origin and restore for show/hide - options.origin = origin || ['middle','center']; - options.restore = true; - } - var original = {height: el.height(), width: el.width()}; // Save original - el.from = o.options.from || (mode == 'show' ? {height: 0, width: 0} : original); // Default from state - - // Adjust - var factor = { // Set scaling factor - y: direction != 'horizontal' ? (percent / 100) : 1, - x: direction != 'vertical' ? (percent / 100) : 1 - }; - el.to = {height: original.height * factor.y, width: original.width * factor.x}; // Set to state - - if (o.options.fade) { // Fade option to support puff - if (mode == 'show') {el.from.opacity = 0; el.to.opacity = 1;}; - if (mode == 'hide') {el.from.opacity = 1; el.to.opacity = 0;}; - }; - - // Animation - options.from = el.from; options.to = el.to; options.mode = mode; - - // Animate - el.effect('size', options, o.duration, o.callback); - el.dequeue(); - }); - -}; - -$.effects.size = function(o) { - - return this.queue(function() { - - // Create element - var el = $(this), props = ['position','top','bottom','left','right','width','height','overflow','opacity']; - var props1 = ['position','top','bottom','left','right','overflow','opacity']; // Always restore - var props2 = ['width','height','overflow']; // Copy for children - var cProps = ['fontSize']; - var vProps = ['borderTopWidth', 'borderBottomWidth', 'paddingTop', 'paddingBottom']; - var hProps = ['borderLeftWidth', 'borderRightWidth', 'paddingLeft', 'paddingRight']; - - // Set options - var mode = $.effects.setMode(el, o.options.mode || 'effect'); // Set Mode - var restore = o.options.restore || false; // Default restore - var scale = o.options.scale || 'both'; // Default scale mode - var origin = o.options.origin; // The origin of the sizing - var original = {height: el.height(), width: el.width()}; // Save original - el.from = o.options.from || original; // Default from state - el.to = o.options.to || original; // Default to state - // Adjust - if (origin) { // Calculate baseline shifts - var baseline = $.effects.getBaseline(origin, original); - el.from.top = (original.height - el.from.height) * baseline.y; - el.from.left = (original.width - el.from.width) * baseline.x; - el.to.top = (original.height - el.to.height) * baseline.y; - el.to.left = (original.width - el.to.width) * baseline.x; - }; - var factor = { // Set scaling factor - from: {y: el.from.height / original.height, x: el.from.width / original.width}, - to: {y: el.to.height / original.height, x: el.to.width / original.width} - }; - if (scale == 'box' || scale == 'both') { // Scale the css box - if (factor.from.y != factor.to.y) { // Vertical props scaling - props = props.concat(vProps); - el.from = $.effects.setTransition(el, vProps, factor.from.y, el.from); - el.to = $.effects.setTransition(el, vProps, factor.to.y, el.to); - }; - if (factor.from.x != factor.to.x) { // Horizontal props scaling - props = props.concat(hProps); - el.from = $.effects.setTransition(el, hProps, factor.from.x, el.from); - el.to = $.effects.setTransition(el, hProps, factor.to.x, el.to); - }; - }; - if (scale == 'content' || scale == 'both') { // Scale the content - if (factor.from.y != factor.to.y) { // Vertical props scaling - props = props.concat(cProps); - el.from = $.effects.setTransition(el, cProps, factor.from.y, el.from); - el.to = $.effects.setTransition(el, cProps, factor.to.y, el.to); - }; - }; - $.effects.save(el, restore ? props : props1); el.show(); // Save & Show - $.effects.createWrapper(el); // Create Wrapper - el.css('overflow','hidden').css(el.from); // Shift - - // Animate - if (scale == 'content' || scale == 'both') { // Scale the children - vProps = vProps.concat(['marginTop','marginBottom']).concat(cProps); // Add margins/font-size - hProps = hProps.concat(['marginLeft','marginRight']); // Add margins - props2 = props.concat(vProps).concat(hProps); // Concat - el.find("*[width]").each(function(){ - child = $(this); - if (restore) $.effects.save(child, props2); - var c_original = {height: child.height(), width: child.width()}; // Save original - child.from = {height: c_original.height * factor.from.y, width: c_original.width * factor.from.x}; - child.to = {height: c_original.height * factor.to.y, width: c_original.width * factor.to.x}; - if (factor.from.y != factor.to.y) { // Vertical props scaling - child.from = $.effects.setTransition(child, vProps, factor.from.y, child.from); - child.to = $.effects.setTransition(child, vProps, factor.to.y, child.to); - }; - if (factor.from.x != factor.to.x) { // Horizontal props scaling - child.from = $.effects.setTransition(child, hProps, factor.from.x, child.from); - child.to = $.effects.setTransition(child, hProps, factor.to.x, child.to); - }; - child.css(child.from); // Shift children - child.animate(child.to, o.duration, o.options.easing, function(){ - if (restore) $.effects.restore(child, props2); // Restore children - }); // Animate children - }); - }; - - // Animate - el.animate(el.to, { queue: false, duration: o.duration, easing: o.options.easing, complete: function() { - if (el.to.opacity === 0) { - el.css('opacity', el.from.opacity); - } - if(mode == 'hide') el.hide(); // Hide - $.effects.restore(el, restore ? props : props1); $.effects.removeWrapper(el); // Restore - if(o.callback) o.callback.apply(this, arguments); // Callback - el.dequeue(); - }}); - - }); - -}; - -})(jQuery); -/* - * jQuery UI Effects Shake 1.8.15 - * - * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) - * Dual licensed under the MIT or GPL Version 2 licenses. - * http://jquery.org/license - * - * http://docs.jquery.com/UI/Effects/Shake - * - * Depends: - * jquery.effects.core.js - */ -(function( $, undefined ) { - -$.effects.shake = function(o) { - - return this.queue(function() { - - // Create element - var el = $(this), props = ['position','top','bottom','left','right']; - - // Set options - var mode = $.effects.setMode(el, o.options.mode || 'effect'); // Set Mode - var direction = o.options.direction || 'left'; // Default direction - var distance = o.options.distance || 20; // Default distance - var times = o.options.times || 3; // Default # of times - var speed = o.duration || o.options.duration || 140; // Default speed per shake - - // Adjust - $.effects.save(el, props); el.show(); // Save & Show - $.effects.createWrapper(el); // Create Wrapper - var ref = (direction == 'up' || direction == 'down') ? 'top' : 'left'; - var motion = (direction == 'up' || direction == 'left') ? 'pos' : 'neg'; - - // Animation - var animation = {}, animation1 = {}, animation2 = {}; - animation[ref] = (motion == 'pos' ? '-=' : '+=') + distance; - animation1[ref] = (motion == 'pos' ? '+=' : '-=') + distance * 2; - animation2[ref] = (motion == 'pos' ? '-=' : '+=') + distance * 2; - - // Animate - el.animate(animation, speed, o.options.easing); - for (var i = 1; i < times; i++) { // Shakes - el.animate(animation1, speed, o.options.easing).animate(animation2, speed, o.options.easing); - }; - el.animate(animation1, speed, o.options.easing). - animate(animation, speed / 2, o.options.easing, function(){ // Last shake - $.effects.restore(el, props); $.effects.removeWrapper(el); // Restore - if(o.callback) o.callback.apply(this, arguments); // Callback - }); - el.queue('fx', function() { el.dequeue(); }); - el.dequeue(); - }); - -}; - -})(jQuery); -/* - * jQuery UI Effects Slide 1.8.15 - * - * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) - * Dual licensed under the MIT or GPL Version 2 licenses. - * http://jquery.org/license - * - * http://docs.jquery.com/UI/Effects/Slide - * - * Depends: - * jquery.effects.core.js - */ -(function( $, undefined ) { - -$.effects.slide = function(o) { - - return this.queue(function() { - - // Create element - var el = $(this), props = ['position','top','bottom','left','right']; - - // Set options - var mode = $.effects.setMode(el, o.options.mode || 'show'); // Set Mode - var direction = o.options.direction || 'left'; // Default Direction - - // Adjust - $.effects.save(el, props); el.show(); // Save & Show - $.effects.createWrapper(el).css({overflow:'hidden'}); // Create Wrapper - var ref = (direction == 'up' || direction == 'down') ? 'top' : 'left'; - var motion = (direction == 'up' || direction == 'left') ? 'pos' : 'neg'; - var distance = o.options.distance || (ref == 'top' ? el.outerHeight({margin:true}) : el.outerWidth({margin:true})); - if (mode == 'show') el.css(ref, motion == 'pos' ? (isNaN(distance) ? "-" + distance : -distance) : distance); // Shift - - // Animation - var animation = {}; - animation[ref] = (mode == 'show' ? (motion == 'pos' ? '+=' : '-=') : (motion == 'pos' ? '-=' : '+=')) + distance; - - // Animate - el.animate(animation, { queue: false, duration: o.duration, easing: o.options.easing, complete: function() { - if(mode == 'hide') el.hide(); // Hide - $.effects.restore(el, props); $.effects.removeWrapper(el); // Restore - if(o.callback) o.callback.apply(this, arguments); // Callback - el.dequeue(); - }}); - - }); - -}; - -})(jQuery); -/* - * jQuery UI Effects Transfer 1.8.15 - * - * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) - * Dual licensed under the MIT or GPL Version 2 licenses. - * http://jquery.org/license - * - * http://docs.jquery.com/UI/Effects/Transfer - * - * Depends: - * jquery.effects.core.js - */ -(function( $, undefined ) { - -$.effects.transfer = function(o) { - return this.queue(function() { - var elem = $(this), - target = $(o.options.to), - endPosition = target.offset(), - animation = { - top: endPosition.top, - left: endPosition.left, - height: target.innerHeight(), - width: target.innerWidth() - }, - startPosition = elem.offset(), - transfer = $('
    ') - .appendTo(document.body) - .addClass(o.options.className) - .css({ - top: startPosition.top, - left: startPosition.left, - height: elem.innerHeight(), - width: elem.innerWidth(), - position: 'absolute' - }) - .animate(animation, o.duration, o.options.easing, function() { - transfer.remove(); - (o.callback && o.callback.apply(elem[0], arguments)); - elem.dequeue(); - }); - }); -}; - -})(jQuery); -/* - * jQuery UI Accordion 1.8.15 - * - * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) - * Dual licensed under the MIT or GPL Version 2 licenses. - * http://jquery.org/license - * - * http://docs.jquery.com/UI/Accordion - * - * Depends: - * jquery.ui.core.js - * jquery.ui.widget.js - */ -(function( $, undefined ) { - -$.widget( "ui.accordion", { - options: { - active: 0, - animated: "slide", - autoHeight: true, - clearStyle: false, - collapsible: false, - event: "click", - fillSpace: false, - header: "> li > :first-child,> :not(li):even", - icons: { - header: "ui-icon-triangle-1-e", - headerSelected: "ui-icon-triangle-1-s" - }, - navigation: false, - navigationFilter: function() { - return this.href.toLowerCase() === location.href.toLowerCase(); - } - }, - - _create: function() { - var self = this, - options = self.options; - - self.running = 0; - - self.element - .addClass( "ui-accordion ui-widget ui-helper-reset" ) - // in lack of child-selectors in CSS - // we need to mark top-LIs in a UL-accordion for some IE-fix - .children( "li" ) - .addClass( "ui-accordion-li-fix" ); - - self.headers = self.element.find( options.header ) - .addClass( "ui-accordion-header ui-helper-reset ui-state-default ui-corner-all" ) - .bind( "mouseenter.accordion", function() { - if ( options.disabled ) { - return; - } - $( this ).addClass( "ui-state-hover" ); - }) - .bind( "mouseleave.accordion", function() { - if ( options.disabled ) { - return; - } - $( this ).removeClass( "ui-state-hover" ); - }) - .bind( "focus.accordion", function() { - if ( options.disabled ) { - return; - } - $( this ).addClass( "ui-state-focus" ); - }) - .bind( "blur.accordion", function() { - if ( options.disabled ) { - return; - } - $( this ).removeClass( "ui-state-focus" ); - }); - - self.headers.next() - .addClass( "ui-accordion-content ui-helper-reset ui-widget-content ui-corner-bottom" ); - - if ( options.navigation ) { - var current = self.element.find( "a" ).filter( options.navigationFilter ).eq( 0 ); - if ( current.length ) { - var header = current.closest( ".ui-accordion-header" ); - if ( header.length ) { - // anchor within header - self.active = header; - } else { - // anchor within content - self.active = current.closest( ".ui-accordion-content" ).prev(); - } - } - } - - self.active = self._findActive( self.active || options.active ) - .addClass( "ui-state-default ui-state-active" ) - .toggleClass( "ui-corner-all" ) - .toggleClass( "ui-corner-top" ); - self.active.next().addClass( "ui-accordion-content-active" ); - - self._createIcons(); - self.resize(); - - // ARIA - self.element.attr( "role", "tablist" ); - - self.headers - .attr( "role", "tab" ) - .bind( "keydown.accordion", function( event ) { - return self._keydown( event ); - }) - .next() - .attr( "role", "tabpanel" ); - - self.headers - .not( self.active || "" ) - .attr({ - "aria-expanded": "false", - "aria-selected": "false", - tabIndex: -1 - }) - .next() - .hide(); - - // make sure at least one header is in the tab order - if ( !self.active.length ) { - self.headers.eq( 0 ).attr( "tabIndex", 0 ); - } else { - self.active - .attr({ - "aria-expanded": "true", - "aria-selected": "true", - tabIndex: 0 - }); - } - - // only need links in tab order for Safari - if ( !$.browser.safari ) { - self.headers.find( "a" ).attr( "tabIndex", -1 ); - } - - if ( options.event ) { - self.headers.bind( options.event.split(" ").join(".accordion ") + ".accordion", function(event) { - self._clickHandler.call( self, event, this ); - event.preventDefault(); - }); - } - }, - - _createIcons: function() { - var options = this.options; - if ( options.icons ) { - $( "" ) - .addClass( "ui-icon " + options.icons.header ) - .prependTo( this.headers ); - this.active.children( ".ui-icon" ) - .toggleClass(options.icons.header) - .toggleClass(options.icons.headerSelected); - this.element.addClass( "ui-accordion-icons" ); - } - }, - - _destroyIcons: function() { - this.headers.children( ".ui-icon" ).remove(); - this.element.removeClass( "ui-accordion-icons" ); - }, - - destroy: function() { - var options = this.options; - - this.element - .removeClass( "ui-accordion ui-widget ui-helper-reset" ) - .removeAttr( "role" ); - - this.headers - .unbind( ".accordion" ) - .removeClass( "ui-accordion-header ui-accordion-disabled ui-helper-reset ui-state-default ui-corner-all ui-state-active ui-state-disabled ui-corner-top" ) - .removeAttr( "role" ) - .removeAttr( "aria-expanded" ) - .removeAttr( "aria-selected" ) - .removeAttr( "tabIndex" ); - - this.headers.find( "a" ).removeAttr( "tabIndex" ); - this._destroyIcons(); - var contents = this.headers.next() - .css( "display", "" ) - .removeAttr( "role" ) - .removeClass( "ui-helper-reset ui-widget-content ui-corner-bottom ui-accordion-content ui-accordion-content-active ui-accordion-disabled ui-state-disabled" ); - if ( options.autoHeight || options.fillHeight ) { - contents.css( "height", "" ); - } - - return $.Widget.prototype.destroy.call( this ); - }, - - _setOption: function( key, value ) { - $.Widget.prototype._setOption.apply( this, arguments ); - - if ( key == "active" ) { - this.activate( value ); - } - if ( key == "icons" ) { - this._destroyIcons(); - if ( value ) { - this._createIcons(); - } - } - // #5332 - opacity doesn't cascade to positioned elements in IE - // so we need to add the disabled class to the headers and panels - if ( key == "disabled" ) { - this.headers.add(this.headers.next()) - [ value ? "addClass" : "removeClass" ]( - "ui-accordion-disabled ui-state-disabled" ); - } - }, - - _keydown: function( event ) { - if ( this.options.disabled || event.altKey || event.ctrlKey ) { - return; - } - - var keyCode = $.ui.keyCode, - length = this.headers.length, - currentIndex = this.headers.index( event.target ), - toFocus = false; - - switch ( event.keyCode ) { - case keyCode.RIGHT: - case keyCode.DOWN: - toFocus = this.headers[ ( currentIndex + 1 ) % length ]; - break; - case keyCode.LEFT: - case keyCode.UP: - toFocus = this.headers[ ( currentIndex - 1 + length ) % length ]; - break; - case keyCode.SPACE: - case keyCode.ENTER: - this._clickHandler( { target: event.target }, event.target ); - event.preventDefault(); - } - - if ( toFocus ) { - $( event.target ).attr( "tabIndex", -1 ); - $( toFocus ).attr( "tabIndex", 0 ); - toFocus.focus(); - return false; - } - - return true; - }, - - resize: function() { - var options = this.options, - maxHeight; - - if ( options.fillSpace ) { - if ( $.browser.msie ) { - var defOverflow = this.element.parent().css( "overflow" ); - this.element.parent().css( "overflow", "hidden"); - } - maxHeight = this.element.parent().height(); - if ($.browser.msie) { - this.element.parent().css( "overflow", defOverflow ); - } - - this.headers.each(function() { - maxHeight -= $( this ).outerHeight( true ); - }); - - this.headers.next() - .each(function() { - $( this ).height( Math.max( 0, maxHeight - - $( this ).innerHeight() + $( this ).height() ) ); - }) - .css( "overflow", "auto" ); - } else if ( options.autoHeight ) { - maxHeight = 0; - this.headers.next() - .each(function() { - maxHeight = Math.max( maxHeight, $( this ).height( "" ).height() ); - }) - .height( maxHeight ); - } - - return this; - }, - - activate: function( index ) { - // TODO this gets called on init, changing the option without an explicit call for that - this.options.active = index; - // call clickHandler with custom event - var active = this._findActive( index )[ 0 ]; - this._clickHandler( { target: active }, active ); - - return this; - }, - - _findActive: function( selector ) { - return selector - ? typeof selector === "number" - ? this.headers.filter( ":eq(" + selector + ")" ) - : this.headers.not( this.headers.not( selector ) ) - : selector === false - ? $( [] ) - : this.headers.filter( ":eq(0)" ); - }, - - // TODO isn't event.target enough? why the separate target argument? - _clickHandler: function( event, target ) { - var options = this.options; - if ( options.disabled ) { - return; - } - - // called only when using activate(false) to close all parts programmatically - if ( !event.target ) { - if ( !options.collapsible ) { - return; - } - this.active - .removeClass( "ui-state-active ui-corner-top" ) - .addClass( "ui-state-default ui-corner-all" ) - .children( ".ui-icon" ) - .removeClass( options.icons.headerSelected ) - .addClass( options.icons.header ); - this.active.next().addClass( "ui-accordion-content-active" ); - var toHide = this.active.next(), - data = { - options: options, - newHeader: $( [] ), - oldHeader: options.active, - newContent: $( [] ), - oldContent: toHide - }, - toShow = ( this.active = $( [] ) ); - this._toggle( toShow, toHide, data ); - return; - } - - // get the click target - var clicked = $( event.currentTarget || target ), - clickedIsActive = clicked[0] === this.active[0]; - - // TODO the option is changed, is that correct? - // TODO if it is correct, shouldn't that happen after determining that the click is valid? - options.active = options.collapsible && clickedIsActive ? - false : - this.headers.index( clicked ); - - // if animations are still active, or the active header is the target, ignore click - if ( this.running || ( !options.collapsible && clickedIsActive ) ) { - return; - } - - // find elements to show and hide - var active = this.active, - toShow = clicked.next(), - toHide = this.active.next(), - data = { - options: options, - newHeader: clickedIsActive && options.collapsible ? $([]) : clicked, - oldHeader: this.active, - newContent: clickedIsActive && options.collapsible ? $([]) : toShow, - oldContent: toHide - }, - down = this.headers.index( this.active[0] ) > this.headers.index( clicked[0] ); - - // when the call to ._toggle() comes after the class changes - // it causes a very odd bug in IE 8 (see #6720) - this.active = clickedIsActive ? $([]) : clicked; - this._toggle( toShow, toHide, data, clickedIsActive, down ); - - // switch classes - active - .removeClass( "ui-state-active ui-corner-top" ) - .addClass( "ui-state-default ui-corner-all" ) - .children( ".ui-icon" ) - .removeClass( options.icons.headerSelected ) - .addClass( options.icons.header ); - if ( !clickedIsActive ) { - clicked - .removeClass( "ui-state-default ui-corner-all" ) - .addClass( "ui-state-active ui-corner-top" ) - .children( ".ui-icon" ) - .removeClass( options.icons.header ) - .addClass( options.icons.headerSelected ); - clicked - .next() - .addClass( "ui-accordion-content-active" ); - } - - return; - }, - - _toggle: function( toShow, toHide, data, clickedIsActive, down ) { - var self = this, - options = self.options; - - self.toShow = toShow; - self.toHide = toHide; - self.data = data; - - var complete = function() { - if ( !self ) { - return; - } - return self._completed.apply( self, arguments ); - }; - - // trigger changestart event - self._trigger( "changestart", null, self.data ); - - // count elements to animate - self.running = toHide.size() === 0 ? toShow.size() : toHide.size(); - - if ( options.animated ) { - var animOptions = {}; - - if ( options.collapsible && clickedIsActive ) { - animOptions = { - toShow: $( [] ), - toHide: toHide, - complete: complete, - down: down, - autoHeight: options.autoHeight || options.fillSpace - }; - } else { - animOptions = { - toShow: toShow, - toHide: toHide, - complete: complete, - down: down, - autoHeight: options.autoHeight || options.fillSpace - }; - } - - if ( !options.proxied ) { - options.proxied = options.animated; - } - - if ( !options.proxiedDuration ) { - options.proxiedDuration = options.duration; - } - - options.animated = $.isFunction( options.proxied ) ? - options.proxied( animOptions ) : - options.proxied; - - options.duration = $.isFunction( options.proxiedDuration ) ? - options.proxiedDuration( animOptions ) : - options.proxiedDuration; - - var animations = $.ui.accordion.animations, - duration = options.duration, - easing = options.animated; - - if ( easing && !animations[ easing ] && !$.easing[ easing ] ) { - easing = "slide"; - } - if ( !animations[ easing ] ) { - animations[ easing ] = function( options ) { - this.slide( options, { - easing: easing, - duration: duration || 700 - }); - }; - } - - animations[ easing ]( animOptions ); - } else { - if ( options.collapsible && clickedIsActive ) { - toShow.toggle(); - } else { - toHide.hide(); - toShow.show(); - } - - complete( true ); - } - - // TODO assert that the blur and focus triggers are really necessary, remove otherwise - toHide.prev() - .attr({ - "aria-expanded": "false", - "aria-selected": "false", - tabIndex: -1 - }) - .blur(); - toShow.prev() - .attr({ - "aria-expanded": "true", - "aria-selected": "true", - tabIndex: 0 - }) - .focus(); - }, - - _completed: function( cancel ) { - this.running = cancel ? 0 : --this.running; - if ( this.running ) { - return; - } - - if ( this.options.clearStyle ) { - this.toShow.add( this.toHide ).css({ - height: "", - overflow: "" - }); - } - - // other classes are removed before the animation; this one needs to stay until completed - this.toHide.removeClass( "ui-accordion-content-active" ); - // Work around for rendering bug in IE (#5421) - if ( this.toHide.length ) { - this.toHide.parent()[0].className = this.toHide.parent()[0].className; - } - - this._trigger( "change", null, this.data ); - } -}); - -$.extend( $.ui.accordion, { - version: "1.8.15", - animations: { - slide: function( options, additions ) { - options = $.extend({ - easing: "swing", - duration: 300 - }, options, additions ); - if ( !options.toHide.size() ) { - options.toShow.animate({ - height: "show", - paddingTop: "show", - paddingBottom: "show" - }, options ); - return; - } - if ( !options.toShow.size() ) { - options.toHide.animate({ - height: "hide", - paddingTop: "hide", - paddingBottom: "hide" - }, options ); - return; - } - var overflow = options.toShow.css( "overflow" ), - percentDone = 0, - showProps = {}, - hideProps = {}, - fxAttrs = [ "height", "paddingTop", "paddingBottom" ], - originalWidth; - // fix width before calculating height of hidden element - var s = options.toShow; - originalWidth = s[0].style.width; - s.width( parseInt( s.parent().width(), 10 ) - - parseInt( s.css( "paddingLeft" ), 10 ) - - parseInt( s.css( "paddingRight" ), 10 ) - - ( parseInt( s.css( "borderLeftWidth" ), 10 ) || 0 ) - - ( parseInt( s.css( "borderRightWidth" ), 10) || 0 ) ); - - $.each( fxAttrs, function( i, prop ) { - hideProps[ prop ] = "hide"; - - var parts = ( "" + $.css( options.toShow[0], prop ) ).match( /^([\d+-.]+)(.*)$/ ); - showProps[ prop ] = { - value: parts[ 1 ], - unit: parts[ 2 ] || "px" - }; - }); - options.toShow.css({ height: 0, overflow: "hidden" }).show(); - options.toHide - .filter( ":hidden" ) - .each( options.complete ) - .end() - .filter( ":visible" ) - .animate( hideProps, { - step: function( now, settings ) { - // only calculate the percent when animating height - // IE gets very inconsistent results when animating elements - // with small values, which is common for padding - if ( settings.prop == "height" ) { - percentDone = ( settings.end - settings.start === 0 ) ? 0 : - ( settings.now - settings.start ) / ( settings.end - settings.start ); - } - - options.toShow[ 0 ].style[ settings.prop ] = - ( percentDone * showProps[ settings.prop ].value ) - + showProps[ settings.prop ].unit; - }, - duration: options.duration, - easing: options.easing, - complete: function() { - if ( !options.autoHeight ) { - options.toShow.css( "height", "" ); - } - options.toShow.css({ - width: originalWidth, - overflow: overflow - }); - options.complete(); - } - }); - }, - bounceslide: function( options ) { - this.slide( options, { - easing: options.down ? "easeOutBounce" : "swing", - duration: options.down ? 1000 : 200 - }); - } - } -}); - -})( jQuery ); -/* - * jQuery UI Autocomplete 1.8.15 - * - * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) - * Dual licensed under the MIT or GPL Version 2 licenses. - * http://jquery.org/license - * - * http://docs.jquery.com/UI/Autocomplete - * - * Depends: - * jquery.ui.core.js - * jquery.ui.widget.js - * jquery.ui.position.js - */ -(function( $, undefined ) { - -// used to prevent race conditions with remote data sources -var requestIndex = 0; - -$.widget( "ui.autocomplete", { - options: { - appendTo: "body", - autoFocus: false, - delay: 300, - minLength: 1, - position: { - my: "left top", - at: "left bottom", - collision: "none" - }, - source: null - }, - - pending: 0, - - _create: function() { - var self = this, - doc = this.element[ 0 ].ownerDocument, - suppressKeyPress; - - this.element - .addClass( "ui-autocomplete-input" ) - .attr( "autocomplete", "off" ) - // TODO verify these actually work as intended - .attr({ - role: "textbox", - "aria-autocomplete": "list", - "aria-haspopup": "true" - }) - .bind( "keydown.autocomplete", function( event ) { - if ( self.options.disabled || self.element.propAttr( "readOnly" ) ) { - return; - } - - suppressKeyPress = false; - var keyCode = $.ui.keyCode; - switch( event.keyCode ) { - case keyCode.PAGE_UP: - self._move( "previousPage", event ); - break; - case keyCode.PAGE_DOWN: - self._move( "nextPage", event ); - break; - case keyCode.UP: - self._move( "previous", event ); - // prevent moving cursor to beginning of text field in some browsers - event.preventDefault(); - break; - case keyCode.DOWN: - self._move( "next", event ); - // prevent moving cursor to end of text field in some browsers - event.preventDefault(); - break; - case keyCode.ENTER: - case keyCode.NUMPAD_ENTER: - // when menu is open and has focus - if ( self.menu.active ) { - // #6055 - Opera still allows the keypress to occur - // which causes forms to submit - suppressKeyPress = true; - event.preventDefault(); - } - //passthrough - ENTER and TAB both select the current element - case keyCode.TAB: - if ( !self.menu.active ) { - return; - } - self.menu.select( event ); - break; - case keyCode.ESCAPE: - self.element.val( self.term ); - self.close( event ); - break; - default: - // keypress is triggered before the input value is changed - clearTimeout( self.searching ); - self.searching = setTimeout(function() { - // only search if the value has changed - if ( self.term != self.element.val() ) { - self.selectedItem = null; - self.search( null, event ); - } - }, self.options.delay ); - break; - } - }) - .bind( "keypress.autocomplete", function( event ) { - if ( suppressKeyPress ) { - suppressKeyPress = false; - event.preventDefault(); - } - }) - .bind( "focus.autocomplete", function() { - if ( self.options.disabled ) { - return; - } - - self.selectedItem = null; - self.previous = self.element.val(); - }) - .bind( "blur.autocomplete", function( event ) { - if ( self.options.disabled ) { - return; - } - - clearTimeout( self.searching ); - // clicks on the menu (or a button to trigger a search) will cause a blur event - self.closing = setTimeout(function() { - self.close( event ); - self._change( event ); - }, 150 ); - }); - this._initSource(); - this.response = function() { - return self._response.apply( self, arguments ); - }; - this.menu = $( "
      " ) - .addClass( "ui-autocomplete" ) - .appendTo( $( this.options.appendTo || "body", doc )[0] ) - // prevent the close-on-blur in case of a "slow" click on the menu (long mousedown) - .mousedown(function( event ) { - // clicking on the scrollbar causes focus to shift to the body - // but we can't detect a mouseup or a click immediately afterward - // so we have to track the next mousedown and close the menu if - // the user clicks somewhere outside of the autocomplete - var menuElement = self.menu.element[ 0 ]; - if ( !$( event.target ).closest( ".ui-menu-item" ).length ) { - setTimeout(function() { - $( document ).one( 'mousedown', function( event ) { - if ( event.target !== self.element[ 0 ] && - event.target !== menuElement && - !$.ui.contains( menuElement, event.target ) ) { - self.close(); - } - }); - }, 1 ); - } - - // use another timeout to make sure the blur-event-handler on the input was already triggered - setTimeout(function() { - clearTimeout( self.closing ); - }, 13); - }) - .menu({ - focus: function( event, ui ) { - var item = ui.item.data( "item.autocomplete" ); - if ( false !== self._trigger( "focus", event, { item: item } ) ) { - // use value to match what will end up in the input, if it was a key event - if ( /^key/.test(event.originalEvent.type) ) { - self.element.val( item.value ); - } - } - }, - selected: function( event, ui ) { - var item = ui.item.data( "item.autocomplete" ), - previous = self.previous; - - // only trigger when focus was lost (click on menu) - if ( self.element[0] !== doc.activeElement ) { - self.element.focus(); - self.previous = previous; - // #6109 - IE triggers two focus events and the second - // is asynchronous, so we need to reset the previous - // term synchronously and asynchronously :-( - setTimeout(function() { - self.previous = previous; - self.selectedItem = item; - }, 1); - } - - if ( false !== self._trigger( "select", event, { item: item } ) ) { - self.element.val( item.value ); - } - // reset the term after the select event - // this allows custom select handling to work properly - self.term = self.element.val(); - - self.close( event ); - self.selectedItem = item; - }, - blur: function( event, ui ) { - // don't set the value of the text field if it's already correct - // this prevents moving the cursor unnecessarily - if ( self.menu.element.is(":visible") && - ( self.element.val() !== self.term ) ) { - self.element.val( self.term ); - } - } - }) - .zIndex( this.element.zIndex() + 1 ) - // workaround for jQuery bug #5781 http://dev.jquery.com/ticket/5781 - .css({ top: 0, left: 0 }) - .hide() - .data( "menu" ); - if ( $.fn.bgiframe ) { - this.menu.element.bgiframe(); - } - }, - - destroy: function() { - this.element - .removeClass( "ui-autocomplete-input" ) - .removeAttr( "autocomplete" ) - .removeAttr( "role" ) - .removeAttr( "aria-autocomplete" ) - .removeAttr( "aria-haspopup" ); - this.menu.element.remove(); - $.Widget.prototype.destroy.call( this ); - }, - - _setOption: function( key, value ) { - $.Widget.prototype._setOption.apply( this, arguments ); - if ( key === "source" ) { - this._initSource(); - } - if ( key === "appendTo" ) { - this.menu.element.appendTo( $( value || "body", this.element[0].ownerDocument )[0] ) - } - if ( key === "disabled" && value && this.xhr ) { - this.xhr.abort(); - } - }, - - _initSource: function() { - var self = this, - array, - url; - if ( $.isArray(this.options.source) ) { - array = this.options.source; - this.source = function( request, response ) { - response( $.ui.autocomplete.filter(array, request.term) ); - }; - } else if ( typeof this.options.source === "string" ) { - url = this.options.source; - this.source = function( request, response ) { - if ( self.xhr ) { - self.xhr.abort(); - } - self.xhr = $.ajax({ - url: url, - data: request, - dataType: "json", - autocompleteRequest: ++requestIndex, - success: function( data, status ) { - if ( this.autocompleteRequest === requestIndex ) { - response( data ); - } - }, - error: function() { - if ( this.autocompleteRequest === requestIndex ) { - response( [] ); - } - } - }); - }; - } else { - this.source = this.options.source; - } - }, - - search: function( value, event ) { - value = value != null ? value : this.element.val(); - - // always save the actual value, not the one passed as an argument - this.term = this.element.val(); - - if ( value.length < this.options.minLength ) { - return this.close( event ); - } - - clearTimeout( this.closing ); - if ( this._trigger( "search", event ) === false ) { - return; - } - - return this._search( value ); - }, - - _search: function( value ) { - this.pending++; - this.element.addClass( "ui-autocomplete-loading" ); - - this.source( { term: value }, this.response ); - }, - - _response: function( content ) { - if ( !this.options.disabled && content && content.length ) { - content = this._normalize( content ); - this._suggest( content ); - this._trigger( "open" ); - } else { - this.close(); - } - this.pending--; - if ( !this.pending ) { - this.element.removeClass( "ui-autocomplete-loading" ); - } - }, - - close: function( event ) { - clearTimeout( this.closing ); - if ( this.menu.element.is(":visible") ) { - this.menu.element.hide(); - this.menu.deactivate(); - this._trigger( "close", event ); - } - }, - - _change: function( event ) { - if ( this.previous !== this.element.val() ) { - this._trigger( "change", event, { item: this.selectedItem } ); - } - }, - - _normalize: function( items ) { - // assume all items have the right format when the first item is complete - if ( items.length && items[0].label && items[0].value ) { - return items; - } - return $.map( items, function(item) { - if ( typeof item === "string" ) { - return { - label: item, - value: item - }; - } - return $.extend({ - label: item.label || item.value, - value: item.value || item.label - }, item ); - }); - }, - - _suggest: function( items ) { - var ul = this.menu.element - .empty() - .zIndex( this.element.zIndex() + 1 ); - this._renderMenu( ul, items ); - // TODO refresh should check if the active item is still in the dom, removing the need for a manual deactivate - this.menu.deactivate(); - this.menu.refresh(); - - // size and position menu - ul.show(); - this._resizeMenu(); - ul.position( $.extend({ - of: this.element - }, this.options.position )); - - if ( this.options.autoFocus ) { - this.menu.next( new $.Event("mouseover") ); - } - }, - - _resizeMenu: function() { - var ul = this.menu.element; - ul.outerWidth( Math.max( - ul.width( "" ).outerWidth(), - this.element.outerWidth() - ) ); - }, - - _renderMenu: function( ul, items ) { - var self = this; - $.each( items, function( index, item ) { - self._renderItem( ul, item ); - }); - }, - - _renderItem: function( ul, item) { - return $( "
    • " ) - .data( "item.autocomplete", item ) - .append( $( "" ).text( item.label ) ) - .appendTo( ul ); - }, - - _move: function( direction, event ) { - if ( !this.menu.element.is(":visible") ) { - this.search( null, event ); - return; - } - if ( this.menu.first() && /^previous/.test(direction) || - this.menu.last() && /^next/.test(direction) ) { - this.element.val( this.term ); - this.menu.deactivate(); - return; - } - this.menu[ direction ]( event ); - }, - - widget: function() { - return this.menu.element; - } -}); - -$.extend( $.ui.autocomplete, { - escapeRegex: function( value ) { - return value.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, "\\$&"); - }, - filter: function(array, term) { - var matcher = new RegExp( $.ui.autocomplete.escapeRegex(term), "i" ); - return $.grep( array, function(value) { - return matcher.test( value.label || value.value || value ); - }); - } -}); - -}( jQuery )); - -/* - * jQuery UI Menu (not officially released) - * - * This widget isn't yet finished and the API is subject to change. We plan to finish - * it for the next release. You're welcome to give it a try anyway and give us feedback, - * as long as you're okay with migrating your code later on. We can help with that, too. - * - * Copyright 2010, AUTHORS.txt (http://jqueryui.com/about) - * Dual licensed under the MIT or GPL Version 2 licenses. - * http://jquery.org/license - * - * http://docs.jquery.com/UI/Menu - * - * Depends: - * jquery.ui.core.js - * jquery.ui.widget.js - */ -(function($) { - -$.widget("ui.menu", { - _create: function() { - var self = this; - this.element - .addClass("ui-menu ui-widget ui-widget-content ui-corner-all") - .attr({ - role: "listbox", - "aria-activedescendant": "ui-active-menuitem" - }) - .click(function( event ) { - if ( !$( event.target ).closest( ".ui-menu-item a" ).length ) { - return; - } - // temporary - event.preventDefault(); - self.select( event ); - }); - this.refresh(); - }, - - refresh: function() { - var self = this; - - // don't refresh list items that are already adapted - var items = this.element.children("li:not(.ui-menu-item):has(a)") - .addClass("ui-menu-item") - .attr("role", "menuitem"); - - items.children("a") - .addClass("ui-corner-all") - .attr("tabindex", -1) - // mouseenter doesn't work with event delegation - .mouseenter(function( event ) { - self.activate( event, $(this).parent() ); - }) - .mouseleave(function() { - self.deactivate(); - }); - }, - - activate: function( event, item ) { - this.deactivate(); - if (this.hasScroll()) { - var offset = item.offset().top - this.element.offset().top, - scroll = this.element.scrollTop(), - elementHeight = this.element.height(); - if (offset < 0) { - this.element.scrollTop( scroll + offset); - } else if (offset >= elementHeight) { - this.element.scrollTop( scroll + offset - elementHeight + item.height()); - } - } - this.active = item.eq(0) - .children("a") - .addClass("ui-state-hover") - .attr("id", "ui-active-menuitem") - .end(); - this._trigger("focus", event, { item: item }); - }, - - deactivate: function() { - if (!this.active) { return; } - - this.active.children("a") - .removeClass("ui-state-hover") - .removeAttr("id"); - this._trigger("blur"); - this.active = null; - }, - - next: function(event) { - this.move("next", ".ui-menu-item:first", event); - }, - - previous: function(event) { - this.move("prev", ".ui-menu-item:last", event); - }, - - first: function() { - return this.active && !this.active.prevAll(".ui-menu-item").length; - }, - - last: function() { - return this.active && !this.active.nextAll(".ui-menu-item").length; - }, - - move: function(direction, edge, event) { - if (!this.active) { - this.activate(event, this.element.children(edge)); - return; - } - var next = this.active[direction + "All"](".ui-menu-item").eq(0); - if (next.length) { - this.activate(event, next); - } else { - this.activate(event, this.element.children(edge)); - } - }, - - // TODO merge with previousPage - nextPage: function(event) { - if (this.hasScroll()) { - // TODO merge with no-scroll-else - if (!this.active || this.last()) { - this.activate(event, this.element.children(".ui-menu-item:first")); - return; - } - var base = this.active.offset().top, - height = this.element.height(), - result = this.element.children(".ui-menu-item").filter(function() { - var close = $(this).offset().top - base - height + $(this).height(); - // TODO improve approximation - return close < 10 && close > -10; - }); - - // TODO try to catch this earlier when scrollTop indicates the last page anyway - if (!result.length) { - result = this.element.children(".ui-menu-item:last"); - } - this.activate(event, result); - } else { - this.activate(event, this.element.children(".ui-menu-item") - .filter(!this.active || this.last() ? ":first" : ":last")); - } - }, - - // TODO merge with nextPage - previousPage: function(event) { - if (this.hasScroll()) { - // TODO merge with no-scroll-else - if (!this.active || this.first()) { - this.activate(event, this.element.children(".ui-menu-item:last")); - return; - } - - var base = this.active.offset().top, - height = this.element.height(); - result = this.element.children(".ui-menu-item").filter(function() { - var close = $(this).offset().top - base + height - $(this).height(); - // TODO improve approximation - return close < 10 && close > -10; - }); - - // TODO try to catch this earlier when scrollTop indicates the last page anyway - if (!result.length) { - result = this.element.children(".ui-menu-item:first"); - } - this.activate(event, result); - } else { - this.activate(event, this.element.children(".ui-menu-item") - .filter(!this.active || this.first() ? ":last" : ":first")); - } - }, - - hasScroll: function() { - return this.element.height() < this.element[ $.fn.prop ? "prop" : "attr" ]("scrollHeight"); - }, - - select: function( event ) { - this._trigger("selected", event, { item: this.active }); - } -}); - -}(jQuery)); -/* - * jQuery UI Button 1.8.15 - * - * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) - * Dual licensed under the MIT or GPL Version 2 licenses. - * http://jquery.org/license - * - * http://docs.jquery.com/UI/Button - * - * Depends: - * jquery.ui.core.js - * jquery.ui.widget.js - */ -(function( $, undefined ) { - -var lastActive, startXPos, startYPos, clickDragged, - baseClasses = "ui-button ui-widget ui-state-default ui-corner-all", - stateClasses = "ui-state-hover ui-state-active ", - typeClasses = "ui-button-icons-only ui-button-icon-only ui-button-text-icons ui-button-text-icon-primary ui-button-text-icon-secondary ui-button-text-only", - formResetHandler = function() { - var buttons = $( this ).find( ":ui-button" ); - setTimeout(function() { - buttons.button( "refresh" ); - }, 1 ); - }, - radioGroup = function( radio ) { - var name = radio.name, - form = radio.form, - radios = $( [] ); - if ( name ) { - if ( form ) { - radios = $( form ).find( "[name='" + name + "']" ); - } else { - radios = $( "[name='" + name + "']", radio.ownerDocument ) - .filter(function() { - return !this.form; - }); - } - } - return radios; - }; - -$.widget( "ui.button", { - options: { - disabled: null, - text: true, - label: null, - icons: { - primary: null, - secondary: null - } - }, - _create: function() { - this.element.closest( "form" ) - .unbind( "reset.button" ) - .bind( "reset.button", formResetHandler ); - - if ( typeof this.options.disabled !== "boolean" ) { - this.options.disabled = this.element.propAttr( "disabled" ); - } - - this._determineButtonType(); - this.hasTitle = !!this.buttonElement.attr( "title" ); - - var self = this, - options = this.options, - toggleButton = this.type === "checkbox" || this.type === "radio", - hoverClass = "ui-state-hover" + ( !toggleButton ? " ui-state-active" : "" ), - focusClass = "ui-state-focus"; - - if ( options.label === null ) { - options.label = this.buttonElement.html(); - } - - if ( this.element.is( ":disabled" ) ) { - options.disabled = true; - } - - this.buttonElement - .addClass( baseClasses ) - .attr( "role", "button" ) - .bind( "mouseenter.button", function() { - if ( options.disabled ) { - return; - } - $( this ).addClass( "ui-state-hover" ); - if ( this === lastActive ) { - $( this ).addClass( "ui-state-active" ); - } - }) - .bind( "mouseleave.button", function() { - if ( options.disabled ) { - return; - } - $( this ).removeClass( hoverClass ); - }) - .bind( "click.button", function( event ) { - if ( options.disabled ) { - event.preventDefault(); - event.stopImmediatePropagation(); - } - }); - - this.element - .bind( "focus.button", function() { - // no need to check disabled, focus won't be triggered anyway - self.buttonElement.addClass( focusClass ); - }) - .bind( "blur.button", function() { - self.buttonElement.removeClass( focusClass ); - }); - - if ( toggleButton ) { - this.element.bind( "change.button", function() { - if ( clickDragged ) { - return; - } - self.refresh(); - }); - // if mouse moves between mousedown and mouseup (drag) set clickDragged flag - // prevents issue where button state changes but checkbox/radio checked state - // does not in Firefox (see ticket #6970) - this.buttonElement - .bind( "mousedown.button", function( event ) { - if ( options.disabled ) { - return; - } - clickDragged = false; - startXPos = event.pageX; - startYPos = event.pageY; - }) - .bind( "mouseup.button", function( event ) { - if ( options.disabled ) { - return; - } - if ( startXPos !== event.pageX || startYPos !== event.pageY ) { - clickDragged = true; - } - }); - } - - if ( this.type === "checkbox" ) { - this.buttonElement.bind( "click.button", function() { - if ( options.disabled || clickDragged ) { - return false; - } - $( this ).toggleClass( "ui-state-active" ); - self.buttonElement.attr( "aria-pressed", self.element[0].checked ); - }); - } else if ( this.type === "radio" ) { - this.buttonElement.bind( "click.button", function() { - if ( options.disabled || clickDragged ) { - return false; - } - $( this ).addClass( "ui-state-active" ); - self.buttonElement.attr( "aria-pressed", "true" ); - - var radio = self.element[ 0 ]; - radioGroup( radio ) - .not( radio ) - .map(function() { - return $( this ).button( "widget" )[ 0 ]; - }) - .removeClass( "ui-state-active" ) - .attr( "aria-pressed", "false" ); - }); - } else { - this.buttonElement - .bind( "mousedown.button", function() { - if ( options.disabled ) { - return false; - } - $( this ).addClass( "ui-state-active" ); - lastActive = this; - $( document ).one( "mouseup", function() { - lastActive = null; - }); - }) - .bind( "mouseup.button", function() { - if ( options.disabled ) { - return false; - } - $( this ).removeClass( "ui-state-active" ); - }) - .bind( "keydown.button", function(event) { - if ( options.disabled ) { - return false; - } - if ( event.keyCode == $.ui.keyCode.SPACE || event.keyCode == $.ui.keyCode.ENTER ) { - $( this ).addClass( "ui-state-active" ); - } - }) - .bind( "keyup.button", function() { - $( this ).removeClass( "ui-state-active" ); - }); - - if ( this.buttonElement.is("a") ) { - this.buttonElement.keyup(function(event) { - if ( event.keyCode === $.ui.keyCode.SPACE ) { - // TODO pass through original event correctly (just as 2nd argument doesn't work) - $( this ).click(); - } - }); - } - } - - // TODO: pull out $.Widget's handling for the disabled option into - // $.Widget.prototype._setOptionDisabled so it's easy to proxy and can - // be overridden by individual plugins - this._setOption( "disabled", options.disabled ); - this._resetButton(); - }, - - _determineButtonType: function() { - - if ( this.element.is(":checkbox") ) { - this.type = "checkbox"; - } else if ( this.element.is(":radio") ) { - this.type = "radio"; - } else if ( this.element.is("input") ) { - this.type = "input"; - } else { - this.type = "button"; - } - - if ( this.type === "checkbox" || this.type === "radio" ) { - // we don't search against the document in case the element - // is disconnected from the DOM - var ancestor = this.element.parents().filter(":last"), - labelSelector = "label[for=" + this.element.attr("id") + "]"; - this.buttonElement = ancestor.find( labelSelector ); - if ( !this.buttonElement.length ) { - ancestor = ancestor.length ? ancestor.siblings() : this.element.siblings(); - this.buttonElement = ancestor.filter( labelSelector ); - if ( !this.buttonElement.length ) { - this.buttonElement = ancestor.find( labelSelector ); - } - } - this.element.addClass( "ui-helper-hidden-accessible" ); - - var checked = this.element.is( ":checked" ); - if ( checked ) { - this.buttonElement.addClass( "ui-state-active" ); - } - this.buttonElement.attr( "aria-pressed", checked ); - } else { - this.buttonElement = this.element; - } - }, - - widget: function() { - return this.buttonElement; - }, - - destroy: function() { - this.element - .removeClass( "ui-helper-hidden-accessible" ); - this.buttonElement - .removeClass( baseClasses + " " + stateClasses + " " + typeClasses ) - .removeAttr( "role" ) - .removeAttr( "aria-pressed" ) - .html( this.buttonElement.find(".ui-button-text").html() ); - - if ( !this.hasTitle ) { - this.buttonElement.removeAttr( "title" ); - } - - $.Widget.prototype.destroy.call( this ); - }, - - _setOption: function( key, value ) { - $.Widget.prototype._setOption.apply( this, arguments ); - if ( key === "disabled" ) { - if ( value ) { - this.element.propAttr( "disabled", true ); - } else { - this.element.propAttr( "disabled", false ); - } - return; - } - this._resetButton(); - }, - - refresh: function() { - var isDisabled = this.element.is( ":disabled" ); - if ( isDisabled !== this.options.disabled ) { - this._setOption( "disabled", isDisabled ); - } - if ( this.type === "radio" ) { - radioGroup( this.element[0] ).each(function() { - if ( $( this ).is( ":checked" ) ) { - $( this ).button( "widget" ) - .addClass( "ui-state-active" ) - .attr( "aria-pressed", "true" ); - } else { - $( this ).button( "widget" ) - .removeClass( "ui-state-active" ) - .attr( "aria-pressed", "false" ); - } - }); - } else if ( this.type === "checkbox" ) { - if ( this.element.is( ":checked" ) ) { - this.buttonElement - .addClass( "ui-state-active" ) - .attr( "aria-pressed", "true" ); - } else { - this.buttonElement - .removeClass( "ui-state-active" ) - .attr( "aria-pressed", "false" ); - } - } - }, - - _resetButton: function() { - if ( this.type === "input" ) { - if ( this.options.label ) { - this.element.val( this.options.label ); - } - return; - } - var buttonElement = this.buttonElement.removeClass( typeClasses ), - buttonText = $( "" ) - .addClass( "ui-button-text" ) - .html( this.options.label ) - .appendTo( buttonElement.empty() ) - .text(), - icons = this.options.icons, - multipleIcons = icons.primary && icons.secondary, - buttonClasses = []; - - if ( icons.primary || icons.secondary ) { - if ( this.options.text ) { - buttonClasses.push( "ui-button-text-icon" + ( multipleIcons ? "s" : ( icons.primary ? "-primary" : "-secondary" ) ) ); - } - - if ( icons.primary ) { - buttonElement.prepend( "" ); - } - - if ( icons.secondary ) { - buttonElement.append( "" ); - } - - if ( !this.options.text ) { - buttonClasses.push( multipleIcons ? "ui-button-icons-only" : "ui-button-icon-only" ); - - if ( !this.hasTitle ) { - buttonElement.attr( "title", buttonText ); - } - } - } else { - buttonClasses.push( "ui-button-text-only" ); - } - buttonElement.addClass( buttonClasses.join( " " ) ); - } -}); - -$.widget( "ui.buttonset", { - options: { - items: ":button, :submit, :reset, :checkbox, :radio, a, :data(button)" - }, - - _create: function() { - this.element.addClass( "ui-buttonset" ); - }, - - _init: function() { - this.refresh(); - }, - - _setOption: function( key, value ) { - if ( key === "disabled" ) { - this.buttons.button( "option", key, value ); - } - - $.Widget.prototype._setOption.apply( this, arguments ); - }, - - refresh: function() { - var ltr = this.element.css( "direction" ) === "ltr"; - - this.buttons = this.element.find( this.options.items ) - .filter( ":ui-button" ) - .button( "refresh" ) - .end() - .not( ":ui-button" ) - .button() - .end() - .map(function() { - return $( this ).button( "widget" )[ 0 ]; - }) - .removeClass( "ui-corner-all ui-corner-left ui-corner-right" ) - .filter( ":first" ) - .addClass( ltr ? "ui-corner-left" : "ui-corner-right" ) - .end() - .filter( ":last" ) - .addClass( ltr ? "ui-corner-right" : "ui-corner-left" ) - .end() - .end(); - }, - - destroy: function() { - this.element.removeClass( "ui-buttonset" ); - this.buttons - .map(function() { - return $( this ).button( "widget" )[ 0 ]; - }) - .removeClass( "ui-corner-left ui-corner-right" ) - .end() - .button( "destroy" ); - - $.Widget.prototype.destroy.call( this ); - } -}); - -}( jQuery ) ); -/* - * jQuery UI Datepicker 1.8.15 - * - * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) - * Dual licensed under the MIT or GPL Version 2 licenses. - * http://jquery.org/license - * - * http://docs.jquery.com/UI/Datepicker - * - * Depends: - * jquery.ui.core.js - */ -(function( $, undefined ) { - -$.extend($.ui, { datepicker: { version: "1.8.15" } }); - -var PROP_NAME = 'datepicker'; -var dpuuid = new Date().getTime(); -var instActive; - -/* Date picker manager. - Use the singleton instance of this class, $.datepicker, to interact with the date picker. - Settings for (groups of) date pickers are maintained in an instance object, - allowing multiple different settings on the same page. */ - -function Datepicker() { - this.debug = false; // Change this to true to start debugging - this._curInst = null; // The current instance in use - this._keyEvent = false; // If the last event was a key event - this._disabledInputs = []; // List of date picker inputs that have been disabled - this._datepickerShowing = false; // True if the popup picker is showing , false if not - this._inDialog = false; // True if showing within a "dialog", false if not - this._mainDivId = 'ui-datepicker-div'; // The ID of the main datepicker division - this._inlineClass = 'ui-datepicker-inline'; // The name of the inline marker class - this._appendClass = 'ui-datepicker-append'; // The name of the append marker class - this._triggerClass = 'ui-datepicker-trigger'; // The name of the trigger marker class - this._dialogClass = 'ui-datepicker-dialog'; // The name of the dialog marker class - this._disableClass = 'ui-datepicker-disabled'; // The name of the disabled covering marker class - this._unselectableClass = 'ui-datepicker-unselectable'; // The name of the unselectable cell marker class - this._currentClass = 'ui-datepicker-current-day'; // The name of the current day marker class - this._dayOverClass = 'ui-datepicker-days-cell-over'; // The name of the day hover marker class - this.regional = []; // Available regional settings, indexed by language code - this.regional[''] = { // Default regional settings - closeText: 'Done', // Display text for close link - prevText: 'Prev', // Display text for previous month link - nextText: 'Next', // Display text for next month link - currentText: 'Today', // Display text for current month link - monthNames: ['January','February','March','April','May','June', - 'July','August','September','October','November','December'], // Names of months for drop-down and formatting - monthNamesShort: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'], // For formatting - dayNames: ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'], // For formatting - dayNamesShort: ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'], // For formatting - dayNamesMin: ['Su','Mo','Tu','We','Th','Fr','Sa'], // Column headings for days starting at Sunday - weekHeader: 'Wk', // Column header for week of the year - dateFormat: 'mm/dd/yy', // See format options on parseDate - firstDay: 0, // The first day of the week, Sun = 0, Mon = 1, ... - isRTL: false, // True if right-to-left language, false if left-to-right - showMonthAfterYear: false, // True if the year select precedes month, false for month then year - yearSuffix: '' // Additional text to append to the year in the month headers - }; - this._defaults = { // Global defaults for all the date picker instances - showOn: 'focus', // 'focus' for popup on focus, - // 'button' for trigger button, or 'both' for either - showAnim: 'fadeIn', // Name of jQuery animation for popup - showOptions: {}, // Options for enhanced animations - defaultDate: null, // Used when field is blank: actual date, - // +/-number for offset from today, null for today - appendText: '', // Display text following the input box, e.g. showing the format - buttonText: '...', // Text for trigger button - buttonImage: '', // URL for trigger button image - buttonImageOnly: false, // True if the image appears alone, false if it appears on a button - hideIfNoPrevNext: false, // True to hide next/previous month links - // if not applicable, false to just disable them - navigationAsDateFormat: false, // True if date formatting applied to prev/today/next links - gotoCurrent: false, // True if today link goes back to current selection instead - changeMonth: false, // True if month can be selected directly, false if only prev/next - changeYear: false, // True if year can be selected directly, false if only prev/next - yearRange: 'c-10:c+10', // Range of years to display in drop-down, - // either relative to today's year (-nn:+nn), relative to currently displayed year - // (c-nn:c+nn), absolute (nnnn:nnnn), or a combination of the above (nnnn:-n) - showOtherMonths: false, // True to show dates in other months, false to leave blank - selectOtherMonths: false, // True to allow selection of dates in other months, false for unselectable - showWeek: false, // True to show week of the year, false to not show it - calculateWeek: this.iso8601Week, // How to calculate the week of the year, - // takes a Date and returns the number of the week for it - shortYearCutoff: '+10', // Short year values < this are in the current century, - // > this are in the previous century, - // string value starting with '+' for current year + value - minDate: null, // The earliest selectable date, or null for no limit - maxDate: null, // The latest selectable date, or null for no limit - duration: 'fast', // Duration of display/closure - beforeShowDay: null, // Function that takes a date and returns an array with - // [0] = true if selectable, false if not, [1] = custom CSS class name(s) or '', - // [2] = cell title (optional), e.g. $.datepicker.noWeekends - beforeShow: null, // Function that takes an input field and - // returns a set of custom settings for the date picker - onSelect: null, // Define a callback function when a date is selected - onChangeMonthYear: null, // Define a callback function when the month or year is changed - onClose: null, // Define a callback function when the datepicker is closed - numberOfMonths: 1, // Number of months to show at a time - showCurrentAtPos: 0, // The position in multipe months at which to show the current month (starting at 0) - stepMonths: 1, // Number of months to step back/forward - stepBigMonths: 12, // Number of months to step back/forward for the big links - altField: '', // Selector for an alternate field to store selected dates into - altFormat: '', // The date format to use for the alternate field - constrainInput: true, // The input is constrained by the current date format - showButtonPanel: false, // True to show button panel, false to not show it - autoSize: false, // True to size the input for the date format, false to leave as is - disabled: false // The initial disabled state - }; - $.extend(this._defaults, this.regional['']); - this.dpDiv = bindHover($('
      ')); -} - -$.extend(Datepicker.prototype, { - /* Class name added to elements to indicate already configured with a date picker. */ - markerClassName: 'hasDatepicker', - - //Keep track of the maximum number of rows displayed (see #7043) - maxRows: 4, - - /* Debug logging (if enabled). */ - log: function () { - if (this.debug) - console.log.apply('', arguments); - }, - - // TODO rename to "widget" when switching to widget factory - _widgetDatepicker: function() { - return this.dpDiv; - }, - - /* Override the default settings for all instances of the date picker. - @param settings object - the new settings to use as defaults (anonymous object) - @return the manager object */ - setDefaults: function(settings) { - extendRemove(this._defaults, settings || {}); - return this; - }, - - /* Attach the date picker to a jQuery selection. - @param target element - the target input field or division or span - @param settings object - the new settings to use for this date picker instance (anonymous) */ - _attachDatepicker: function(target, settings) { - // check for settings on the control itself - in namespace 'date:' - var inlineSettings = null; - for (var attrName in this._defaults) { - var attrValue = target.getAttribute('date:' + attrName); - if (attrValue) { - inlineSettings = inlineSettings || {}; - try { - inlineSettings[attrName] = eval(attrValue); - } catch (err) { - inlineSettings[attrName] = attrValue; - } - } - } - var nodeName = target.nodeName.toLowerCase(); - var inline = (nodeName == 'div' || nodeName == 'span'); - if (!target.id) { - this.uuid += 1; - target.id = 'dp' + this.uuid; - } - var inst = this._newInst($(target), inline); - inst.settings = $.extend({}, settings || {}, inlineSettings || {}); - if (nodeName == 'input') { - this._connectDatepicker(target, inst); - } else if (inline) { - this._inlineDatepicker(target, inst); - } - }, - - /* Create a new instance object. */ - _newInst: function(target, inline) { - var id = target[0].id.replace(/([^A-Za-z0-9_-])/g, '\\\\$1'); // escape jQuery meta chars - return {id: id, input: target, // associated target - selectedDay: 0, selectedMonth: 0, selectedYear: 0, // current selection - drawMonth: 0, drawYear: 0, // month being drawn - inline: inline, // is datepicker inline or not - dpDiv: (!inline ? this.dpDiv : // presentation div - bindHover($('
      ')))}; - }, - - /* Attach the date picker to an input field. */ - _connectDatepicker: function(target, inst) { - var input = $(target); - inst.append = $([]); - inst.trigger = $([]); - if (input.hasClass(this.markerClassName)) - return; - this._attachments(input, inst); - input.addClass(this.markerClassName).keydown(this._doKeyDown). - keypress(this._doKeyPress).keyup(this._doKeyUp). - bind("setData.datepicker", function(event, key, value) { - inst.settings[key] = value; - }).bind("getData.datepicker", function(event, key) { - return this._get(inst, key); - }); - this._autoSize(inst); - $.data(target, PROP_NAME, inst); - //If disabled option is true, disable the datepicker once it has been attached to the input (see ticket #5665) - if( inst.settings.disabled ) { - this._disableDatepicker( target ); - } - }, - - /* Make attachments based on settings. */ - _attachments: function(input, inst) { - var appendText = this._get(inst, 'appendText'); - var isRTL = this._get(inst, 'isRTL'); - if (inst.append) - inst.append.remove(); - if (appendText) { - inst.append = $('' + appendText + ''); - input[isRTL ? 'before' : 'after'](inst.append); - } - input.unbind('focus', this._showDatepicker); - if (inst.trigger) - inst.trigger.remove(); - var showOn = this._get(inst, 'showOn'); - if (showOn == 'focus' || showOn == 'both') // pop-up date picker when in the marked field - input.focus(this._showDatepicker); - if (showOn == 'button' || showOn == 'both') { // pop-up date picker when button clicked - var buttonText = this._get(inst, 'buttonText'); - var buttonImage = this._get(inst, 'buttonImage'); - inst.trigger = $(this._get(inst, 'buttonImageOnly') ? - $('').addClass(this._triggerClass). - attr({ src: buttonImage, alt: buttonText, title: buttonText }) : - $('').addClass(this._triggerClass). - html(buttonImage == '' ? buttonText : $('').attr( - { src:buttonImage, alt:buttonText, title:buttonText }))); - input[isRTL ? 'before' : 'after'](inst.trigger); - inst.trigger.click(function() { - if ($.datepicker._datepickerShowing && $.datepicker._lastInput == input[0]) - $.datepicker._hideDatepicker(); - else - $.datepicker._showDatepicker(input[0]); - return false; - }); - } - }, - - /* Apply the maximum length for the date format. */ - _autoSize: function(inst) { - if (this._get(inst, 'autoSize') && !inst.inline) { - var date = new Date(2009, 12 - 1, 20); // Ensure double digits - var dateFormat = this._get(inst, 'dateFormat'); - if (dateFormat.match(/[DM]/)) { - var findMax = function(names) { - var max = 0; - var maxI = 0; - for (var i = 0; i < names.length; i++) { - if (names[i].length > max) { - max = names[i].length; - maxI = i; - } - } - return maxI; - }; - date.setMonth(findMax(this._get(inst, (dateFormat.match(/MM/) ? - 'monthNames' : 'monthNamesShort')))); - date.setDate(findMax(this._get(inst, (dateFormat.match(/DD/) ? - 'dayNames' : 'dayNamesShort'))) + 20 - date.getDay()); - } - inst.input.attr('size', this._formatDate(inst, date).length); - } - }, - - /* Attach an inline date picker to a div. */ - _inlineDatepicker: function(target, inst) { - var divSpan = $(target); - if (divSpan.hasClass(this.markerClassName)) - return; - divSpan.addClass(this.markerClassName).append(inst.dpDiv). - bind("setData.datepicker", function(event, key, value){ - inst.settings[key] = value; - }).bind("getData.datepicker", function(event, key){ - return this._get(inst, key); - }); - $.data(target, PROP_NAME, inst); - this._setDate(inst, this._getDefaultDate(inst), true); - this._updateDatepicker(inst); - this._updateAlternate(inst); - //If disabled option is true, disable the datepicker before showing it (see ticket #5665) - if( inst.settings.disabled ) { - this._disableDatepicker( target ); - } - // Set display:block in place of inst.dpDiv.show() which won't work on disconnected elements - // http://bugs.jqueryui.com/ticket/7552 - A Datepicker created on a detached div has zero height - inst.dpDiv.css( "display", "block" ); - }, - - /* Pop-up the date picker in a "dialog" box. - @param input element - ignored - @param date string or Date - the initial date to display - @param onSelect function - the function to call when a date is selected - @param settings object - update the dialog date picker instance's settings (anonymous object) - @param pos int[2] - coordinates for the dialog's position within the screen or - event - with x/y coordinates or - leave empty for default (screen centre) - @return the manager object */ - _dialogDatepicker: function(input, date, onSelect, settings, pos) { - var inst = this._dialogInst; // internal instance - if (!inst) { - this.uuid += 1; - var id = 'dp' + this.uuid; - this._dialogInput = $(''); - this._dialogInput.keydown(this._doKeyDown); - $('body').append(this._dialogInput); - inst = this._dialogInst = this._newInst(this._dialogInput, false); - inst.settings = {}; - $.data(this._dialogInput[0], PROP_NAME, inst); - } - extendRemove(inst.settings, settings || {}); - date = (date && date.constructor == Date ? this._formatDate(inst, date) : date); - this._dialogInput.val(date); - - this._pos = (pos ? (pos.length ? pos : [pos.pageX, pos.pageY]) : null); - if (!this._pos) { - var browserWidth = document.documentElement.clientWidth; - var browserHeight = document.documentElement.clientHeight; - var scrollX = document.documentElement.scrollLeft || document.body.scrollLeft; - var scrollY = document.documentElement.scrollTop || document.body.scrollTop; - this._pos = // should use actual width/height below - [(browserWidth / 2) - 100 + scrollX, (browserHeight / 2) - 150 + scrollY]; - } - - // move input on screen for focus, but hidden behind dialog - this._dialogInput.css('left', (this._pos[0] + 20) + 'px').css('top', this._pos[1] + 'px'); - inst.settings.onSelect = onSelect; - this._inDialog = true; - this.dpDiv.addClass(this._dialogClass); - this._showDatepicker(this._dialogInput[0]); - if ($.blockUI) - $.blockUI(this.dpDiv); - $.data(this._dialogInput[0], PROP_NAME, inst); - return this; - }, - - /* Detach a datepicker from its control. - @param target element - the target input field or division or span */ - _destroyDatepicker: function(target) { - var $target = $(target); - var inst = $.data(target, PROP_NAME); - if (!$target.hasClass(this.markerClassName)) { - return; - } - var nodeName = target.nodeName.toLowerCase(); - $.removeData(target, PROP_NAME); - if (nodeName == 'input') { - inst.append.remove(); - inst.trigger.remove(); - $target.removeClass(this.markerClassName). - unbind('focus', this._showDatepicker). - unbind('keydown', this._doKeyDown). - unbind('keypress', this._doKeyPress). - unbind('keyup', this._doKeyUp); - } else if (nodeName == 'div' || nodeName == 'span') - $target.removeClass(this.markerClassName).empty(); - }, - - /* Enable the date picker to a jQuery selection. - @param target element - the target input field or division or span */ - _enableDatepicker: function(target) { - var $target = $(target); - var inst = $.data(target, PROP_NAME); - if (!$target.hasClass(this.markerClassName)) { - return; - } - var nodeName = target.nodeName.toLowerCase(); - if (nodeName == 'input') { - target.disabled = false; - inst.trigger.filter('button'). - each(function() { this.disabled = false; }).end(). - filter('img').css({opacity: '1.0', cursor: ''}); - } - else if (nodeName == 'div' || nodeName == 'span') { - var inline = $target.children('.' + this._inlineClass); - inline.children().removeClass('ui-state-disabled'); - inline.find("select.ui-datepicker-month, select.ui-datepicker-year"). - removeAttr("disabled"); - } - this._disabledInputs = $.map(this._disabledInputs, - function(value) { return (value == target ? null : value); }); // delete entry - }, - - /* Disable the date picker to a jQuery selection. - @param target element - the target input field or division or span */ - _disableDatepicker: function(target) { - var $target = $(target); - var inst = $.data(target, PROP_NAME); - if (!$target.hasClass(this.markerClassName)) { - return; - } - var nodeName = target.nodeName.toLowerCase(); - if (nodeName == 'input') { - target.disabled = true; - inst.trigger.filter('button'). - each(function() { this.disabled = true; }).end(). - filter('img').css({opacity: '0.5', cursor: 'default'}); - } - else if (nodeName == 'div' || nodeName == 'span') { - var inline = $target.children('.' + this._inlineClass); - inline.children().addClass('ui-state-disabled'); - inline.find("select.ui-datepicker-month, select.ui-datepicker-year"). - attr("disabled", "disabled"); - } - this._disabledInputs = $.map(this._disabledInputs, - function(value) { return (value == target ? null : value); }); // delete entry - this._disabledInputs[this._disabledInputs.length] = target; - }, - - /* Is the first field in a jQuery collection disabled as a datepicker? - @param target element - the target input field or division or span - @return boolean - true if disabled, false if enabled */ - _isDisabledDatepicker: function(target) { - if (!target) { - return false; - } - for (var i = 0; i < this._disabledInputs.length; i++) { - if (this._disabledInputs[i] == target) - return true; - } - return false; - }, - - /* Retrieve the instance data for the target control. - @param target element - the target input field or division or span - @return object - the associated instance data - @throws error if a jQuery problem getting data */ - _getInst: function(target) { - try { - return $.data(target, PROP_NAME); - } - catch (err) { - throw 'Missing instance data for this datepicker'; - } - }, - - /* Update or retrieve the settings for a date picker attached to an input field or division. - @param target element - the target input field or division or span - @param name object - the new settings to update or - string - the name of the setting to change or retrieve, - when retrieving also 'all' for all instance settings or - 'defaults' for all global defaults - @param value any - the new value for the setting - (omit if above is an object or to retrieve a value) */ - _optionDatepicker: function(target, name, value) { - var inst = this._getInst(target); - if (arguments.length == 2 && typeof name == 'string') { - return (name == 'defaults' ? $.extend({}, $.datepicker._defaults) : - (inst ? (name == 'all' ? $.extend({}, inst.settings) : - this._get(inst, name)) : null)); - } - var settings = name || {}; - if (typeof name == 'string') { - settings = {}; - settings[name] = value; - } - if (inst) { - if (this._curInst == inst) { - this._hideDatepicker(); - } - var date = this._getDateDatepicker(target, true); - var minDate = this._getMinMaxDate(inst, 'min'); - var maxDate = this._getMinMaxDate(inst, 'max'); - extendRemove(inst.settings, settings); - // reformat the old minDate/maxDate values if dateFormat changes and a new minDate/maxDate isn't provided - if (minDate !== null && settings['dateFormat'] !== undefined && settings['minDate'] === undefined) - inst.settings.minDate = this._formatDate(inst, minDate); - if (maxDate !== null && settings['dateFormat'] !== undefined && settings['maxDate'] === undefined) - inst.settings.maxDate = this._formatDate(inst, maxDate); - this._attachments($(target), inst); - this._autoSize(inst); - this._setDate(inst, date); - this._updateAlternate(inst); - this._updateDatepicker(inst); - } - }, - - // change method deprecated - _changeDatepicker: function(target, name, value) { - this._optionDatepicker(target, name, value); - }, - - /* Redraw the date picker attached to an input field or division. - @param target element - the target input field or division or span */ - _refreshDatepicker: function(target) { - var inst = this._getInst(target); - if (inst) { - this._updateDatepicker(inst); - } - }, - - /* Set the dates for a jQuery selection. - @param target element - the target input field or division or span - @param date Date - the new date */ - _setDateDatepicker: function(target, date) { - var inst = this._getInst(target); - if (inst) { - this._setDate(inst, date); - this._updateDatepicker(inst); - this._updateAlternate(inst); - } - }, - - /* Get the date(s) for the first entry in a jQuery selection. - @param target element - the target input field or division or span - @param noDefault boolean - true if no default date is to be used - @return Date - the current date */ - _getDateDatepicker: function(target, noDefault) { - var inst = this._getInst(target); - if (inst && !inst.inline) - this._setDateFromField(inst, noDefault); - return (inst ? this._getDate(inst) : null); - }, - - /* Handle keystrokes. */ - _doKeyDown: function(event) { - var inst = $.datepicker._getInst(event.target); - var handled = true; - var isRTL = inst.dpDiv.is('.ui-datepicker-rtl'); - inst._keyEvent = true; - if ($.datepicker._datepickerShowing) - switch (event.keyCode) { - case 9: $.datepicker._hideDatepicker(); - handled = false; - break; // hide on tab out - case 13: var sel = $('td.' + $.datepicker._dayOverClass + ':not(.' + - $.datepicker._currentClass + ')', inst.dpDiv); - if (sel[0]) - $.datepicker._selectDay(event.target, inst.selectedMonth, inst.selectedYear, sel[0]); - var onSelect = $.datepicker._get(inst, 'onSelect'); - if (onSelect) { - var dateStr = $.datepicker._formatDate(inst); - - // trigger custom callback - onSelect.apply((inst.input ? inst.input[0] : null), [dateStr, inst]); - } - else - $.datepicker._hideDatepicker(); - return false; // don't submit the form - break; // select the value on enter - case 27: $.datepicker._hideDatepicker(); - break; // hide on escape - case 33: $.datepicker._adjustDate(event.target, (event.ctrlKey ? - -$.datepicker._get(inst, 'stepBigMonths') : - -$.datepicker._get(inst, 'stepMonths')), 'M'); - break; // previous month/year on page up/+ ctrl - case 34: $.datepicker._adjustDate(event.target, (event.ctrlKey ? - +$.datepicker._get(inst, 'stepBigMonths') : - +$.datepicker._get(inst, 'stepMonths')), 'M'); - break; // next month/year on page down/+ ctrl - case 35: if (event.ctrlKey || event.metaKey) $.datepicker._clearDate(event.target); - handled = event.ctrlKey || event.metaKey; - break; // clear on ctrl or command +end - case 36: if (event.ctrlKey || event.metaKey) $.datepicker._gotoToday(event.target); - handled = event.ctrlKey || event.metaKey; - break; // current on ctrl or command +home - case 37: if (event.ctrlKey || event.metaKey) $.datepicker._adjustDate(event.target, (isRTL ? +1 : -1), 'D'); - handled = event.ctrlKey || event.metaKey; - // -1 day on ctrl or command +left - if (event.originalEvent.altKey) $.datepicker._adjustDate(event.target, (event.ctrlKey ? - -$.datepicker._get(inst, 'stepBigMonths') : - -$.datepicker._get(inst, 'stepMonths')), 'M'); - // next month/year on alt +left on Mac - break; - case 38: if (event.ctrlKey || event.metaKey) $.datepicker._adjustDate(event.target, -7, 'D'); - handled = event.ctrlKey || event.metaKey; - break; // -1 week on ctrl or command +up - case 39: if (event.ctrlKey || event.metaKey) $.datepicker._adjustDate(event.target, (isRTL ? -1 : +1), 'D'); - handled = event.ctrlKey || event.metaKey; - // +1 day on ctrl or command +right - if (event.originalEvent.altKey) $.datepicker._adjustDate(event.target, (event.ctrlKey ? - +$.datepicker._get(inst, 'stepBigMonths') : - +$.datepicker._get(inst, 'stepMonths')), 'M'); - // next month/year on alt +right - break; - case 40: if (event.ctrlKey || event.metaKey) $.datepicker._adjustDate(event.target, +7, 'D'); - handled = event.ctrlKey || event.metaKey; - break; // +1 week on ctrl or command +down - default: handled = false; - } - else if (event.keyCode == 36 && event.ctrlKey) // display the date picker on ctrl+home - $.datepicker._showDatepicker(this); - else { - handled = false; - } - if (handled) { - event.preventDefault(); - event.stopPropagation(); - } - }, - - /* Filter entered characters - based on date format. */ - _doKeyPress: function(event) { - var inst = $.datepicker._getInst(event.target); - if ($.datepicker._get(inst, 'constrainInput')) { - var chars = $.datepicker._possibleChars($.datepicker._get(inst, 'dateFormat')); - var chr = String.fromCharCode(event.charCode == undefined ? event.keyCode : event.charCode); - return event.ctrlKey || event.metaKey || (chr < ' ' || !chars || chars.indexOf(chr) > -1); - } - }, - - /* Synchronise manual entry and field/alternate field. */ - _doKeyUp: function(event) { - var inst = $.datepicker._getInst(event.target); - if (inst.input.val() != inst.lastVal) { - try { - var date = $.datepicker.parseDate($.datepicker._get(inst, 'dateFormat'), - (inst.input ? inst.input.val() : null), - $.datepicker._getFormatConfig(inst)); - if (date) { // only if valid - $.datepicker._setDateFromField(inst); - $.datepicker._updateAlternate(inst); - $.datepicker._updateDatepicker(inst); - } - } - catch (event) { - $.datepicker.log(event); - } - } - return true; - }, - - /* Pop-up the date picker for a given input field. - @param input element - the input field attached to the date picker or - event - if triggered by focus */ - _showDatepicker: function(input) { - input = input.target || input; - if (input.nodeName.toLowerCase() != 'input') // find from button/image trigger - input = $('input', input.parentNode)[0]; - if ($.datepicker._isDisabledDatepicker(input) || $.datepicker._lastInput == input) // already here - return; - var inst = $.datepicker._getInst(input); - if ($.datepicker._curInst && $.datepicker._curInst != inst) { - if ( $.datepicker._datepickerShowing ) { - $.datepicker._triggerOnClose($.datepicker._curInst); - } - $.datepicker._curInst.dpDiv.stop(true, true); - } - var beforeShow = $.datepicker._get(inst, 'beforeShow'); - extendRemove(inst.settings, (beforeShow ? beforeShow.apply(input, [input, inst]) : {})); - inst.lastVal = null; - $.datepicker._lastInput = input; - $.datepicker._setDateFromField(inst); - if ($.datepicker._inDialog) // hide cursor - input.value = ''; - if (!$.datepicker._pos) { // position below input - $.datepicker._pos = $.datepicker._findPos(input); - $.datepicker._pos[1] += input.offsetHeight; // add the height - } - var isFixed = false; - $(input).parents().each(function() { - isFixed |= $(this).css('position') == 'fixed'; - return !isFixed; - }); - if (isFixed && $.browser.opera) { // correction for Opera when fixed and scrolled - $.datepicker._pos[0] -= document.documentElement.scrollLeft; - $.datepicker._pos[1] -= document.documentElement.scrollTop; - } - var offset = {left: $.datepicker._pos[0], top: $.datepicker._pos[1]}; - $.datepicker._pos = null; - //to avoid flashes on Firefox - inst.dpDiv.empty(); - // determine sizing offscreen - inst.dpDiv.css({position: 'absolute', display: 'block', top: '-1000px'}); - $.datepicker._updateDatepicker(inst); - // fix width for dynamic number of date pickers - // and adjust position before showing - offset = $.datepicker._checkOffset(inst, offset, isFixed); - inst.dpDiv.css({position: ($.datepicker._inDialog && $.blockUI ? - 'static' : (isFixed ? 'fixed' : 'absolute')), display: 'none', - left: offset.left + 'px', top: offset.top + 'px'}); - if (!inst.inline) { - var showAnim = $.datepicker._get(inst, 'showAnim'); - var duration = $.datepicker._get(inst, 'duration'); - var postProcess = function() { - var cover = inst.dpDiv.find('iframe.ui-datepicker-cover'); // IE6- only - if( !! cover.length ){ - var borders = $.datepicker._getBorders(inst.dpDiv); - cover.css({left: -borders[0], top: -borders[1], - width: inst.dpDiv.outerWidth(), height: inst.dpDiv.outerHeight()}); - } - }; - inst.dpDiv.zIndex($(input).zIndex()+1); - $.datepicker._datepickerShowing = true; - if ($.effects && $.effects[showAnim]) - inst.dpDiv.show(showAnim, $.datepicker._get(inst, 'showOptions'), duration, postProcess); - else - inst.dpDiv[showAnim || 'show']((showAnim ? duration : null), postProcess); - if (!showAnim || !duration) - postProcess(); - if (inst.input.is(':visible') && !inst.input.is(':disabled')) - inst.input.focus(); - $.datepicker._curInst = inst; - } - }, - - /* Generate the date picker content. */ - _updateDatepicker: function(inst) { - var self = this; - self.maxRows = 4; //Reset the max number of rows being displayed (see #7043) - var borders = $.datepicker._getBorders(inst.dpDiv); - instActive = inst; // for delegate hover events - inst.dpDiv.empty().append(this._generateHTML(inst)); - var cover = inst.dpDiv.find('iframe.ui-datepicker-cover'); // IE6- only - if( !!cover.length ){ //avoid call to outerXXXX() when not in IE6 - cover.css({left: -borders[0], top: -borders[1], width: inst.dpDiv.outerWidth(), height: inst.dpDiv.outerHeight()}) - } - inst.dpDiv.find('.' + this._dayOverClass + ' a').mouseover(); - var numMonths = this._getNumberOfMonths(inst); - var cols = numMonths[1]; - var width = 17; - inst.dpDiv.removeClass('ui-datepicker-multi-2 ui-datepicker-multi-3 ui-datepicker-multi-4').width(''); - if (cols > 1) - inst.dpDiv.addClass('ui-datepicker-multi-' + cols).css('width', (width * cols) + 'em'); - inst.dpDiv[(numMonths[0] != 1 || numMonths[1] != 1 ? 'add' : 'remove') + - 'Class']('ui-datepicker-multi'); - inst.dpDiv[(this._get(inst, 'isRTL') ? 'add' : 'remove') + - 'Class']('ui-datepicker-rtl'); - if (inst == $.datepicker._curInst && $.datepicker._datepickerShowing && inst.input && - // #6694 - don't focus the input if it's already focused - // this breaks the change event in IE - inst.input.is(':visible') && !inst.input.is(':disabled') && inst.input[0] != document.activeElement) - inst.input.focus(); - // deffered render of the years select (to avoid flashes on Firefox) - if( inst.yearshtml ){ - var origyearshtml = inst.yearshtml; - setTimeout(function(){ - //assure that inst.yearshtml didn't change. - if( origyearshtml === inst.yearshtml && inst.yearshtml ){ - inst.dpDiv.find('select.ui-datepicker-year:first').replaceWith(inst.yearshtml); - } - origyearshtml = inst.yearshtml = null; - }, 0); - } - }, - - /* Retrieve the size of left and top borders for an element. - @param elem (jQuery object) the element of interest - @return (number[2]) the left and top borders */ - _getBorders: function(elem) { - var convert = function(value) { - return {thin: 1, medium: 2, thick: 3}[value] || value; - }; - return [parseFloat(convert(elem.css('border-left-width'))), - parseFloat(convert(elem.css('border-top-width')))]; - }, - - /* Check positioning to remain on screen. */ - _checkOffset: function(inst, offset, isFixed) { - var dpWidth = inst.dpDiv.outerWidth(); - var dpHeight = inst.dpDiv.outerHeight(); - var inputWidth = inst.input ? inst.input.outerWidth() : 0; - var inputHeight = inst.input ? inst.input.outerHeight() : 0; - var viewWidth = document.documentElement.clientWidth + $(document).scrollLeft(); - var viewHeight = document.documentElement.clientHeight + $(document).scrollTop(); - - offset.left -= (this._get(inst, 'isRTL') ? (dpWidth - inputWidth) : 0); - offset.left -= (isFixed && offset.left == inst.input.offset().left) ? $(document).scrollLeft() : 0; - offset.top -= (isFixed && offset.top == (inst.input.offset().top + inputHeight)) ? $(document).scrollTop() : 0; - - // now check if datepicker is showing outside window viewport - move to a better place if so. - offset.left -= Math.min(offset.left, (offset.left + dpWidth > viewWidth && viewWidth > dpWidth) ? - Math.abs(offset.left + dpWidth - viewWidth) : 0); - offset.top -= Math.min(offset.top, (offset.top + dpHeight > viewHeight && viewHeight > dpHeight) ? - Math.abs(dpHeight + inputHeight) : 0); - - return offset; - }, - - /* Find an object's position on the screen. */ - _findPos: function(obj) { - var inst = this._getInst(obj); - var isRTL = this._get(inst, 'isRTL'); - while (obj && (obj.type == 'hidden' || obj.nodeType != 1 || $.expr.filters.hidden(obj))) { - obj = obj[isRTL ? 'previousSibling' : 'nextSibling']; - } - var position = $(obj).offset(); - return [position.left, position.top]; - }, - - /* Trigger custom callback of onClose. */ - _triggerOnClose: function(inst) { - var onClose = this._get(inst, 'onClose'); - if (onClose) - onClose.apply((inst.input ? inst.input[0] : null), - [(inst.input ? inst.input.val() : ''), inst]); - }, - - /* Hide the date picker from view. - @param input element - the input field attached to the date picker */ - _hideDatepicker: function(input) { - var inst = this._curInst; - if (!inst || (input && inst != $.data(input, PROP_NAME))) - return; - if (this._datepickerShowing) { - var showAnim = this._get(inst, 'showAnim'); - var duration = this._get(inst, 'duration'); - var postProcess = function() { - $.datepicker._tidyDialog(inst); - this._curInst = null; - }; - if ($.effects && $.effects[showAnim]) - inst.dpDiv.hide(showAnim, $.datepicker._get(inst, 'showOptions'), duration, postProcess); - else - inst.dpDiv[(showAnim == 'slideDown' ? 'slideUp' : - (showAnim == 'fadeIn' ? 'fadeOut' : 'hide'))]((showAnim ? duration : null), postProcess); - if (!showAnim) - postProcess(); - $.datepicker._triggerOnClose(inst); - this._datepickerShowing = false; - this._lastInput = null; - if (this._inDialog) { - this._dialogInput.css({ position: 'absolute', left: '0', top: '-100px' }); - if ($.blockUI) { - $.unblockUI(); - $('body').append(this.dpDiv); - } - } - this._inDialog = false; - } - }, - - /* Tidy up after a dialog display. */ - _tidyDialog: function(inst) { - inst.dpDiv.removeClass(this._dialogClass).unbind('.ui-datepicker-calendar'); - }, - - /* Close date picker if clicked elsewhere. */ - _checkExternalClick: function(event) { - if (!$.datepicker._curInst) - return; - var $target = $(event.target); - if ($target[0].id != $.datepicker._mainDivId && - $target.parents('#' + $.datepicker._mainDivId).length == 0 && - !$target.hasClass($.datepicker.markerClassName) && - !$target.hasClass($.datepicker._triggerClass) && - $.datepicker._datepickerShowing && !($.datepicker._inDialog && $.blockUI)) - $.datepicker._hideDatepicker(); - }, - - /* Adjust one of the date sub-fields. */ - _adjustDate: function(id, offset, period) { - var target = $(id); - var inst = this._getInst(target[0]); - if (this._isDisabledDatepicker(target[0])) { - return; - } - this._adjustInstDate(inst, offset + - (period == 'M' ? this._get(inst, 'showCurrentAtPos') : 0), // undo positioning - period); - this._updateDatepicker(inst); - }, - - /* Action for current link. */ - _gotoToday: function(id) { - var target = $(id); - var inst = this._getInst(target[0]); - if (this._get(inst, 'gotoCurrent') && inst.currentDay) { - inst.selectedDay = inst.currentDay; - inst.drawMonth = inst.selectedMonth = inst.currentMonth; - inst.drawYear = inst.selectedYear = inst.currentYear; - } - else { - var date = new Date(); - inst.selectedDay = date.getDate(); - inst.drawMonth = inst.selectedMonth = date.getMonth(); - inst.drawYear = inst.selectedYear = date.getFullYear(); - } - this._notifyChange(inst); - this._adjustDate(target); - }, - - /* Action for selecting a new month/year. */ - _selectMonthYear: function(id, select, period) { - var target = $(id); - var inst = this._getInst(target[0]); - inst['selected' + (period == 'M' ? 'Month' : 'Year')] = - inst['draw' + (period == 'M' ? 'Month' : 'Year')] = - parseInt(select.options[select.selectedIndex].value,10); - this._notifyChange(inst); - this._adjustDate(target); - }, - - /* Action for selecting a day. */ - _selectDay: function(id, month, year, td) { - var target = $(id); - if ($(td).hasClass(this._unselectableClass) || this._isDisabledDatepicker(target[0])) { - return; - } - var inst = this._getInst(target[0]); - inst.selectedDay = inst.currentDay = $('a', td).html(); - inst.selectedMonth = inst.currentMonth = month; - inst.selectedYear = inst.currentYear = year; - this._selectDate(id, this._formatDate(inst, - inst.currentDay, inst.currentMonth, inst.currentYear)); - }, - - /* Erase the input field and hide the date picker. */ - _clearDate: function(id) { - var target = $(id); - var inst = this._getInst(target[0]); - this._selectDate(target, ''); - }, - - /* Update the input field with the selected date. */ - _selectDate: function(id, dateStr) { - var target = $(id); - var inst = this._getInst(target[0]); - dateStr = (dateStr != null ? dateStr : this._formatDate(inst)); - if (inst.input) - inst.input.val(dateStr); - this._updateAlternate(inst); - var onSelect = this._get(inst, 'onSelect'); - if (onSelect) - onSelect.apply((inst.input ? inst.input[0] : null), [dateStr, inst]); // trigger custom callback - else if (inst.input) - inst.input.trigger('change'); // fire the change event - if (inst.inline) - this._updateDatepicker(inst); - else { - this._hideDatepicker(); - this._lastInput = inst.input[0]; - inst.input.focus(); // restore focus - this._lastInput = null; - } - }, - - /* Update any alternate field to synchronise with the main field. */ - _updateAlternate: function(inst) { - var altField = this._get(inst, 'altField'); - if (altField) { // update alternate field too - var altFormat = this._get(inst, 'altFormat') || this._get(inst, 'dateFormat'); - var date = this._getDate(inst); - var dateStr = this.formatDate(altFormat, date, this._getFormatConfig(inst)); - $(altField).each(function() { $(this).val(dateStr); }); - } - }, - - /* Set as beforeShowDay function to prevent selection of weekends. - @param date Date - the date to customise - @return [boolean, string] - is this date selectable?, what is its CSS class? */ - noWeekends: function(date) { - var day = date.getDay(); - return [(day > 0 && day < 6), '']; - }, - - /* Set as calculateWeek to determine the week of the year based on the ISO 8601 definition. - @param date Date - the date to get the week for - @return number - the number of the week within the year that contains this date */ - iso8601Week: function(date) { - var checkDate = new Date(date.getTime()); - // Find Thursday of this week starting on Monday - checkDate.setDate(checkDate.getDate() + 4 - (checkDate.getDay() || 7)); - var time = checkDate.getTime(); - checkDate.setMonth(0); // Compare with Jan 1 - checkDate.setDate(1); - return Math.floor(Math.round((time - checkDate) / 86400000) / 7) + 1; - }, - - /* Parse a string value into a date object. - See formatDate below for the possible formats. - - @param format string - the expected format of the date - @param value string - the date in the above format - @param settings Object - attributes include: - shortYearCutoff number - the cutoff year for determining the century (optional) - dayNamesShort string[7] - abbreviated names of the days from Sunday (optional) - dayNames string[7] - names of the days from Sunday (optional) - monthNamesShort string[12] - abbreviated names of the months (optional) - monthNames string[12] - names of the months (optional) - @return Date - the extracted date value or null if value is blank */ - parseDate: function (format, value, settings) { - if (format == null || value == null) - throw 'Invalid arguments'; - value = (typeof value == 'object' ? value.toString() : value + ''); - if (value == '') - return null; - var shortYearCutoff = (settings ? settings.shortYearCutoff : null) || this._defaults.shortYearCutoff; - shortYearCutoff = (typeof shortYearCutoff != 'string' ? shortYearCutoff : - new Date().getFullYear() % 100 + parseInt(shortYearCutoff, 10)); - var dayNamesShort = (settings ? settings.dayNamesShort : null) || this._defaults.dayNamesShort; - var dayNames = (settings ? settings.dayNames : null) || this._defaults.dayNames; - var monthNamesShort = (settings ? settings.monthNamesShort : null) || this._defaults.monthNamesShort; - var monthNames = (settings ? settings.monthNames : null) || this._defaults.monthNames; - var year = -1; - var month = -1; - var day = -1; - var doy = -1; - var literal = false; - // Check whether a format character is doubled - var lookAhead = function(match) { - var matches = (iFormat + 1 < format.length && format.charAt(iFormat + 1) == match); - if (matches) - iFormat++; - return matches; - }; - // Extract a number from the string value - var getNumber = function(match) { - var isDoubled = lookAhead(match); - var size = (match == '@' ? 14 : (match == '!' ? 20 : - (match == 'y' && isDoubled ? 4 : (match == 'o' ? 3 : 2)))); - var digits = new RegExp('^\\d{1,' + size + '}'); - var num = value.substring(iValue).match(digits); - if (!num) - throw 'Missing number at position ' + iValue; - iValue += num[0].length; - return parseInt(num[0], 10); - }; - // Extract a name from the string value and convert to an index - var getName = function(match, shortNames, longNames) { - var names = $.map(lookAhead(match) ? longNames : shortNames, function (v, k) { - return [ [k, v] ]; - }).sort(function (a, b) { - return -(a[1].length - b[1].length); - }); - var index = -1; - $.each(names, function (i, pair) { - var name = pair[1]; - if (value.substr(iValue, name.length).toLowerCase() == name.toLowerCase()) { - index = pair[0]; - iValue += name.length; - return false; - } - }); - if (index != -1) - return index + 1; - else - throw 'Unknown name at position ' + iValue; - }; - // Confirm that a literal character matches the string value - var checkLiteral = function() { - if (value.charAt(iValue) != format.charAt(iFormat)) - throw 'Unexpected literal at position ' + iValue; - iValue++; - }; - var iValue = 0; - for (var iFormat = 0; iFormat < format.length; iFormat++) { - if (literal) - if (format.charAt(iFormat) == "'" && !lookAhead("'")) - literal = false; - else - checkLiteral(); - else - switch (format.charAt(iFormat)) { - case 'd': - day = getNumber('d'); - break; - case 'D': - getName('D', dayNamesShort, dayNames); - break; - case 'o': - doy = getNumber('o'); - break; - case 'm': - month = getNumber('m'); - break; - case 'M': - month = getName('M', monthNamesShort, monthNames); - break; - case 'y': - year = getNumber('y'); - break; - case '@': - var date = new Date(getNumber('@')); - year = date.getFullYear(); - month = date.getMonth() + 1; - day = date.getDate(); - break; - case '!': - var date = new Date((getNumber('!') - this._ticksTo1970) / 10000); - year = date.getFullYear(); - month = date.getMonth() + 1; - day = date.getDate(); - break; - case "'": - if (lookAhead("'")) - checkLiteral(); - else - literal = true; - break; - default: - checkLiteral(); - } - } - if (iValue < value.length){ - throw "Extra/unparsed characters found in date: " + value.substring(iValue); - } - if (year == -1) - year = new Date().getFullYear(); - else if (year < 100) - year += new Date().getFullYear() - new Date().getFullYear() % 100 + - (year <= shortYearCutoff ? 0 : -100); - if (doy > -1) { - month = 1; - day = doy; - do { - var dim = this._getDaysInMonth(year, month - 1); - if (day <= dim) - break; - month++; - day -= dim; - } while (true); - } - var date = this._daylightSavingAdjust(new Date(year, month - 1, day)); - if (date.getFullYear() != year || date.getMonth() + 1 != month || date.getDate() != day) - throw 'Invalid date'; // E.g. 31/02/00 - return date; - }, - - /* Standard date formats. */ - ATOM: 'yy-mm-dd', // RFC 3339 (ISO 8601) - COOKIE: 'D, dd M yy', - ISO_8601: 'yy-mm-dd', - RFC_822: 'D, d M y', - RFC_850: 'DD, dd-M-y', - RFC_1036: 'D, d M y', - RFC_1123: 'D, d M yy', - RFC_2822: 'D, d M yy', - RSS: 'D, d M y', // RFC 822 - TICKS: '!', - TIMESTAMP: '@', - W3C: 'yy-mm-dd', // ISO 8601 - - _ticksTo1970: (((1970 - 1) * 365 + Math.floor(1970 / 4) - Math.floor(1970 / 100) + - Math.floor(1970 / 400)) * 24 * 60 * 60 * 10000000), - - /* Format a date object into a string value. - The format can be combinations of the following: - d - day of month (no leading zero) - dd - day of month (two digit) - o - day of year (no leading zeros) - oo - day of year (three digit) - D - day name short - DD - day name long - m - month of year (no leading zero) - mm - month of year (two digit) - M - month name short - MM - month name long - y - year (two digit) - yy - year (four digit) - @ - Unix timestamp (ms since 01/01/1970) - ! - Windows ticks (100ns since 01/01/0001) - '...' - literal text - '' - single quote - - @param format string - the desired format of the date - @param date Date - the date value to format - @param settings Object - attributes include: - dayNamesShort string[7] - abbreviated names of the days from Sunday (optional) - dayNames string[7] - names of the days from Sunday (optional) - monthNamesShort string[12] - abbreviated names of the months (optional) - monthNames string[12] - names of the months (optional) - @return string - the date in the above format */ - formatDate: function (format, date, settings) { - if (!date) - return ''; - var dayNamesShort = (settings ? settings.dayNamesShort : null) || this._defaults.dayNamesShort; - var dayNames = (settings ? settings.dayNames : null) || this._defaults.dayNames; - var monthNamesShort = (settings ? settings.monthNamesShort : null) || this._defaults.monthNamesShort; - var monthNames = (settings ? settings.monthNames : null) || this._defaults.monthNames; - // Check whether a format character is doubled - var lookAhead = function(match) { - var matches = (iFormat + 1 < format.length && format.charAt(iFormat + 1) == match); - if (matches) - iFormat++; - return matches; - }; - // Format a number, with leading zero if necessary - var formatNumber = function(match, value, len) { - var num = '' + value; - if (lookAhead(match)) - while (num.length < len) - num = '0' + num; - return num; - }; - // Format a name, short or long as requested - var formatName = function(match, value, shortNames, longNames) { - return (lookAhead(match) ? longNames[value] : shortNames[value]); - }; - var output = ''; - var literal = false; - if (date) - for (var iFormat = 0; iFormat < format.length; iFormat++) { - if (literal) - if (format.charAt(iFormat) == "'" && !lookAhead("'")) - literal = false; - else - output += format.charAt(iFormat); - else - switch (format.charAt(iFormat)) { - case 'd': - output += formatNumber('d', date.getDate(), 2); - break; - case 'D': - output += formatName('D', date.getDay(), dayNamesShort, dayNames); - break; - case 'o': - output += formatNumber('o', - Math.round((new Date(date.getFullYear(), date.getMonth(), date.getDate()).getTime() - new Date(date.getFullYear(), 0, 0).getTime()) / 86400000), 3); - break; - case 'm': - output += formatNumber('m', date.getMonth() + 1, 2); - break; - case 'M': - output += formatName('M', date.getMonth(), monthNamesShort, monthNames); - break; - case 'y': - output += (lookAhead('y') ? date.getFullYear() : - (date.getYear() % 100 < 10 ? '0' : '') + date.getYear() % 100); - break; - case '@': - output += date.getTime(); - break; - case '!': - output += date.getTime() * 10000 + this._ticksTo1970; - break; - case "'": - if (lookAhead("'")) - output += "'"; - else - literal = true; - break; - default: - output += format.charAt(iFormat); - } - } - return output; - }, - - /* Extract all possible characters from the date format. */ - _possibleChars: function (format) { - var chars = ''; - var literal = false; - // Check whether a format character is doubled - var lookAhead = function(match) { - var matches = (iFormat + 1 < format.length && format.charAt(iFormat + 1) == match); - if (matches) - iFormat++; - return matches; - }; - for (var iFormat = 0; iFormat < format.length; iFormat++) - if (literal) - if (format.charAt(iFormat) == "'" && !lookAhead("'")) - literal = false; - else - chars += format.charAt(iFormat); - else - switch (format.charAt(iFormat)) { - case 'd': case 'm': case 'y': case '@': - chars += '0123456789'; - break; - case 'D': case 'M': - return null; // Accept anything - case "'": - if (lookAhead("'")) - chars += "'"; - else - literal = true; - break; - default: - chars += format.charAt(iFormat); - } - return chars; - }, - - /* Get a setting value, defaulting if necessary. */ - _get: function(inst, name) { - return inst.settings[name] !== undefined ? - inst.settings[name] : this._defaults[name]; - }, - - /* Parse existing date and initialise date picker. */ - _setDateFromField: function(inst, noDefault) { - if (inst.input.val() == inst.lastVal) { - return; - } - var dateFormat = this._get(inst, 'dateFormat'); - var dates = inst.lastVal = inst.input ? inst.input.val() : null; - var date, defaultDate; - date = defaultDate = this._getDefaultDate(inst); - var settings = this._getFormatConfig(inst); - try { - date = this.parseDate(dateFormat, dates, settings) || defaultDate; - } catch (event) { - this.log(event); - dates = (noDefault ? '' : dates); - } - inst.selectedDay = date.getDate(); - inst.drawMonth = inst.selectedMonth = date.getMonth(); - inst.drawYear = inst.selectedYear = date.getFullYear(); - inst.currentDay = (dates ? date.getDate() : 0); - inst.currentMonth = (dates ? date.getMonth() : 0); - inst.currentYear = (dates ? date.getFullYear() : 0); - this._adjustInstDate(inst); - }, - - /* Retrieve the default date shown on opening. */ - _getDefaultDate: function(inst) { - return this._restrictMinMax(inst, - this._determineDate(inst, this._get(inst, 'defaultDate'), new Date())); - }, - - /* A date may be specified as an exact value or a relative one. */ - _determineDate: function(inst, date, defaultDate) { - var offsetNumeric = function(offset) { - var date = new Date(); - date.setDate(date.getDate() + offset); - return date; - }; - var offsetString = function(offset) { - try { - return $.datepicker.parseDate($.datepicker._get(inst, 'dateFormat'), - offset, $.datepicker._getFormatConfig(inst)); - } - catch (e) { - // Ignore - } - var date = (offset.toLowerCase().match(/^c/) ? - $.datepicker._getDate(inst) : null) || new Date(); - var year = date.getFullYear(); - var month = date.getMonth(); - var day = date.getDate(); - var pattern = /([+-]?[0-9]+)\s*(d|D|w|W|m|M|y|Y)?/g; - var matches = pattern.exec(offset); - while (matches) { - switch (matches[2] || 'd') { - case 'd' : case 'D' : - day += parseInt(matches[1],10); break; - case 'w' : case 'W' : - day += parseInt(matches[1],10) * 7; break; - case 'm' : case 'M' : - month += parseInt(matches[1],10); - day = Math.min(day, $.datepicker._getDaysInMonth(year, month)); - break; - case 'y': case 'Y' : - year += parseInt(matches[1],10); - day = Math.min(day, $.datepicker._getDaysInMonth(year, month)); - break; - } - matches = pattern.exec(offset); - } - return new Date(year, month, day); - }; - var newDate = (date == null || date === '' ? defaultDate : (typeof date == 'string' ? offsetString(date) : - (typeof date == 'number' ? (isNaN(date) ? defaultDate : offsetNumeric(date)) : new Date(date.getTime())))); - newDate = (newDate && newDate.toString() == 'Invalid Date' ? defaultDate : newDate); - if (newDate) { - newDate.setHours(0); - newDate.setMinutes(0); - newDate.setSeconds(0); - newDate.setMilliseconds(0); - } - return this._daylightSavingAdjust(newDate); - }, - - /* Handle switch to/from daylight saving. - Hours may be non-zero on daylight saving cut-over: - > 12 when midnight changeover, but then cannot generate - midnight datetime, so jump to 1AM, otherwise reset. - @param date (Date) the date to check - @return (Date) the corrected date */ - _daylightSavingAdjust: function(date) { - if (!date) return null; - date.setHours(date.getHours() > 12 ? date.getHours() + 2 : 0); - return date; - }, - - /* Set the date(s) directly. */ - _setDate: function(inst, date, noChange) { - var clear = !date; - var origMonth = inst.selectedMonth; - var origYear = inst.selectedYear; - var newDate = this._restrictMinMax(inst, this._determineDate(inst, date, new Date())); - inst.selectedDay = inst.currentDay = newDate.getDate(); - inst.drawMonth = inst.selectedMonth = inst.currentMonth = newDate.getMonth(); - inst.drawYear = inst.selectedYear = inst.currentYear = newDate.getFullYear(); - if ((origMonth != inst.selectedMonth || origYear != inst.selectedYear) && !noChange) - this._notifyChange(inst); - this._adjustInstDate(inst); - if (inst.input) { - inst.input.val(clear ? '' : this._formatDate(inst)); - } - - var onSelect = this._get(inst, 'onSelect'); - if (onSelect) { - var dateStr = this._formatDate(inst); - - // trigger custom callback - onSelect.apply((inst.input ? inst.input[0] : null), [dateStr, inst]); - } - }, - - /* Retrieve the date(s) directly. */ - _getDate: function(inst) { - var startDate = (!inst.currentYear || (inst.input && inst.input.val() == '') ? null : - this._daylightSavingAdjust(new Date( - inst.currentYear, inst.currentMonth, inst.currentDay))); - return startDate; - }, - - /* Generate the HTML for the current state of the date picker. */ - _generateHTML: function(inst) { - var today = new Date(); - today = this._daylightSavingAdjust( - new Date(today.getFullYear(), today.getMonth(), today.getDate())); // clear time - var isRTL = this._get(inst, 'isRTL'); - var showButtonPanel = this._get(inst, 'showButtonPanel'); - var hideIfNoPrevNext = this._get(inst, 'hideIfNoPrevNext'); - var navigationAsDateFormat = this._get(inst, 'navigationAsDateFormat'); - var numMonths = this._getNumberOfMonths(inst); - var showCurrentAtPos = this._get(inst, 'showCurrentAtPos'); - var stepMonths = this._get(inst, 'stepMonths'); - var isMultiMonth = (numMonths[0] != 1 || numMonths[1] != 1); - var currentDate = this._daylightSavingAdjust((!inst.currentDay ? new Date(9999, 9, 9) : - new Date(inst.currentYear, inst.currentMonth, inst.currentDay))); - var minDate = this._getMinMaxDate(inst, 'min'); - var maxDate = this._getMinMaxDate(inst, 'max'); - var drawMonth = inst.drawMonth - showCurrentAtPos; - var drawYear = inst.drawYear; - if (drawMonth < 0) { - drawMonth += 12; - drawYear--; - } - if (maxDate) { - var maxDraw = this._daylightSavingAdjust(new Date(maxDate.getFullYear(), - maxDate.getMonth() - (numMonths[0] * numMonths[1]) + 1, maxDate.getDate())); - maxDraw = (minDate && maxDraw < minDate ? minDate : maxDraw); - while (this._daylightSavingAdjust(new Date(drawYear, drawMonth, 1)) > maxDraw) { - drawMonth--; - if (drawMonth < 0) { - drawMonth = 11; - drawYear--; - } - } - } - inst.drawMonth = drawMonth; - inst.drawYear = drawYear; - var prevText = this._get(inst, 'prevText'); - prevText = (!navigationAsDateFormat ? prevText : this.formatDate(prevText, - this._daylightSavingAdjust(new Date(drawYear, drawMonth - stepMonths, 1)), - this._getFormatConfig(inst))); - var prev = (this._canAdjustMonth(inst, -1, drawYear, drawMonth) ? - '' + prevText + '' : - (hideIfNoPrevNext ? '' : '' + prevText + '')); - var nextText = this._get(inst, 'nextText'); - nextText = (!navigationAsDateFormat ? nextText : this.formatDate(nextText, - this._daylightSavingAdjust(new Date(drawYear, drawMonth + stepMonths, 1)), - this._getFormatConfig(inst))); - var next = (this._canAdjustMonth(inst, +1, drawYear, drawMonth) ? - '' + nextText + '' : - (hideIfNoPrevNext ? '' : '' + nextText + '')); - var currentText = this._get(inst, 'currentText'); - var gotoDate = (this._get(inst, 'gotoCurrent') && inst.currentDay ? currentDate : today); - currentText = (!navigationAsDateFormat ? currentText : - this.formatDate(currentText, gotoDate, this._getFormatConfig(inst))); - var controls = (!inst.inline ? '' : ''); - var buttonPanel = (showButtonPanel) ? '
      ' + (isRTL ? controls : '') + - (this._isInRange(inst, gotoDate) ? '' : '') + (isRTL ? '' : controls) + '
      ' : ''; - var firstDay = parseInt(this._get(inst, 'firstDay'),10); - firstDay = (isNaN(firstDay) ? 0 : firstDay); - var showWeek = this._get(inst, 'showWeek'); - var dayNames = this._get(inst, 'dayNames'); - var dayNamesShort = this._get(inst, 'dayNamesShort'); - var dayNamesMin = this._get(inst, 'dayNamesMin'); - var monthNames = this._get(inst, 'monthNames'); - var monthNamesShort = this._get(inst, 'monthNamesShort'); - var beforeShowDay = this._get(inst, 'beforeShowDay'); - var showOtherMonths = this._get(inst, 'showOtherMonths'); - var selectOtherMonths = this._get(inst, 'selectOtherMonths'); - var calculateWeek = this._get(inst, 'calculateWeek') || this.iso8601Week; - var defaultDate = this._getDefaultDate(inst); - var html = ''; - for (var row = 0; row < numMonths[0]; row++) { - var group = ''; - this.maxRows = 4; - for (var col = 0; col < numMonths[1]; col++) { - var selectedDate = this._daylightSavingAdjust(new Date(drawYear, drawMonth, inst.selectedDay)); - var cornerClass = ' ui-corner-all'; - var calender = ''; - if (isMultiMonth) { - calender += '
      '; - } - calender += '
      ' + - (/all|left/.test(cornerClass) && row == 0 ? (isRTL ? next : prev) : '') + - (/all|right/.test(cornerClass) && row == 0 ? (isRTL ? prev : next) : '') + - this._generateMonthYearHeader(inst, drawMonth, drawYear, minDate, maxDate, - row > 0 || col > 0, monthNames, monthNamesShort) + // draw month headers - '
      ' + - ''; - var thead = (showWeek ? '' : ''); - for (var dow = 0; dow < 7; dow++) { // days of the week - var day = (dow + firstDay) % 7; - thead += '= 5 ? ' class="ui-datepicker-week-end"' : '') + '>' + - '' + dayNamesMin[day] + ''; - } - calender += thead + ''; - var daysInMonth = this._getDaysInMonth(drawYear, drawMonth); - if (drawYear == inst.selectedYear && drawMonth == inst.selectedMonth) - inst.selectedDay = Math.min(inst.selectedDay, daysInMonth); - var leadDays = (this._getFirstDayOfMonth(drawYear, drawMonth) - firstDay + 7) % 7; - var curRows = Math.ceil((leadDays + daysInMonth) / 7); // calculate the number of rows to generate - var numRows = (isMultiMonth ? this.maxRows > curRows ? this.maxRows : curRows : curRows); //If multiple months, use the higher number of rows (see #7043) - this.maxRows = numRows; - var printDate = this._daylightSavingAdjust(new Date(drawYear, drawMonth, 1 - leadDays)); - for (var dRow = 0; dRow < numRows; dRow++) { // create date picker rows - calender += ''; - var tbody = (!showWeek ? '' : ''); - for (var dow = 0; dow < 7; dow++) { // create date picker days - var daySettings = (beforeShowDay ? - beforeShowDay.apply((inst.input ? inst.input[0] : null), [printDate]) : [true, '']); - var otherMonth = (printDate.getMonth() != drawMonth); - var unselectable = (otherMonth && !selectOtherMonths) || !daySettings[0] || - (minDate && printDate < minDate) || (maxDate && printDate > maxDate); - tbody += ''; // display selectable date - printDate.setDate(printDate.getDate() + 1); - printDate = this._daylightSavingAdjust(printDate); - } - calender += tbody + ''; - } - drawMonth++; - if (drawMonth > 11) { - drawMonth = 0; - drawYear++; - } - calender += '
      ' + this._get(inst, 'weekHeader') + '
      ' + - this._get(inst, 'calculateWeek')(printDate) + '' + // actions - (otherMonth && !showOtherMonths ? ' ' : // display for other months - (unselectable ? '' + printDate.getDate() + '' : '' + printDate.getDate() + '')) + '
      ' + (isMultiMonth ? '' + - ((numMonths[0] > 0 && col == numMonths[1]-1) ? '
      ' : '') : ''); - group += calender; - } - html += group; - } - html += buttonPanel + ($.browser.msie && parseInt($.browser.version,10) < 7 && !inst.inline ? - '' : ''); - inst._keyEvent = false; - return html; - }, - - /* Generate the month and year header. */ - _generateMonthYearHeader: function(inst, drawMonth, drawYear, minDate, maxDate, - secondary, monthNames, monthNamesShort) { - var changeMonth = this._get(inst, 'changeMonth'); - var changeYear = this._get(inst, 'changeYear'); - var showMonthAfterYear = this._get(inst, 'showMonthAfterYear'); - var html = '
      '; - var monthHtml = ''; - // month selection - if (secondary || !changeMonth) - monthHtml += '' + monthNames[drawMonth] + ''; - else { - var inMinYear = (minDate && minDate.getFullYear() == drawYear); - var inMaxYear = (maxDate && maxDate.getFullYear() == drawYear); - monthHtml += ''; - } - if (!showMonthAfterYear) - html += monthHtml + (secondary || !(changeMonth && changeYear) ? ' ' : ''); - // year selection - if ( !inst.yearshtml ) { - inst.yearshtml = ''; - if (secondary || !changeYear) - html += '' + drawYear + ''; - else { - // determine range of years to display - var years = this._get(inst, 'yearRange').split(':'); - var thisYear = new Date().getFullYear(); - var determineYear = function(value) { - var year = (value.match(/c[+-].*/) ? drawYear + parseInt(value.substring(1), 10) : - (value.match(/[+-].*/) ? thisYear + parseInt(value, 10) : - parseInt(value, 10))); - return (isNaN(year) ? thisYear : year); - }; - var year = determineYear(years[0]); - var endYear = Math.max(year, determineYear(years[1] || '')); - year = (minDate ? Math.max(year, minDate.getFullYear()) : year); - endYear = (maxDate ? Math.min(endYear, maxDate.getFullYear()) : endYear); - inst.yearshtml += ''; - - html += inst.yearshtml; - inst.yearshtml = null; - } - } - html += this._get(inst, 'yearSuffix'); - if (showMonthAfterYear) - html += (secondary || !(changeMonth && changeYear) ? ' ' : '') + monthHtml; - html += '
      '; // Close datepicker_header - return html; - }, - - /* Adjust one of the date sub-fields. */ - _adjustInstDate: function(inst, offset, period) { - var year = inst.drawYear + (period == 'Y' ? offset : 0); - var month = inst.drawMonth + (period == 'M' ? offset : 0); - var day = Math.min(inst.selectedDay, this._getDaysInMonth(year, month)) + - (period == 'D' ? offset : 0); - var date = this._restrictMinMax(inst, - this._daylightSavingAdjust(new Date(year, month, day))); - inst.selectedDay = date.getDate(); - inst.drawMonth = inst.selectedMonth = date.getMonth(); - inst.drawYear = inst.selectedYear = date.getFullYear(); - if (period == 'M' || period == 'Y') - this._notifyChange(inst); - }, - - /* Ensure a date is within any min/max bounds. */ - _restrictMinMax: function(inst, date) { - var minDate = this._getMinMaxDate(inst, 'min'); - var maxDate = this._getMinMaxDate(inst, 'max'); - var newDate = (minDate && date < minDate ? minDate : date); - newDate = (maxDate && newDate > maxDate ? maxDate : newDate); - return newDate; - }, - - /* Notify change of month/year. */ - _notifyChange: function(inst) { - var onChange = this._get(inst, 'onChangeMonthYear'); - if (onChange) - onChange.apply((inst.input ? inst.input[0] : null), - [inst.selectedYear, inst.selectedMonth + 1, inst]); - }, - - /* Determine the number of months to show. */ - _getNumberOfMonths: function(inst) { - var numMonths = this._get(inst, 'numberOfMonths'); - return (numMonths == null ? [1, 1] : (typeof numMonths == 'number' ? [1, numMonths] : numMonths)); - }, - - /* Determine the current maximum date - ensure no time components are set. */ - _getMinMaxDate: function(inst, minMax) { - return this._determineDate(inst, this._get(inst, minMax + 'Date'), null); - }, - - /* Find the number of days in a given month. */ - _getDaysInMonth: function(year, month) { - return 32 - this._daylightSavingAdjust(new Date(year, month, 32)).getDate(); - }, - - /* Find the day of the week of the first of a month. */ - _getFirstDayOfMonth: function(year, month) { - return new Date(year, month, 1).getDay(); - }, - - /* Determines if we should allow a "next/prev" month display change. */ - _canAdjustMonth: function(inst, offset, curYear, curMonth) { - var numMonths = this._getNumberOfMonths(inst); - var date = this._daylightSavingAdjust(new Date(curYear, - curMonth + (offset < 0 ? offset : numMonths[0] * numMonths[1]), 1)); - if (offset < 0) - date.setDate(this._getDaysInMonth(date.getFullYear(), date.getMonth())); - return this._isInRange(inst, date); - }, - - /* Is the given date in the accepted range? */ - _isInRange: function(inst, date) { - var minDate = this._getMinMaxDate(inst, 'min'); - var maxDate = this._getMinMaxDate(inst, 'max'); - return ((!minDate || date.getTime() >= minDate.getTime()) && - (!maxDate || date.getTime() <= maxDate.getTime())); - }, - - /* Provide the configuration settings for formatting/parsing. */ - _getFormatConfig: function(inst) { - var shortYearCutoff = this._get(inst, 'shortYearCutoff'); - shortYearCutoff = (typeof shortYearCutoff != 'string' ? shortYearCutoff : - new Date().getFullYear() % 100 + parseInt(shortYearCutoff, 10)); - return {shortYearCutoff: shortYearCutoff, - dayNamesShort: this._get(inst, 'dayNamesShort'), dayNames: this._get(inst, 'dayNames'), - monthNamesShort: this._get(inst, 'monthNamesShort'), monthNames: this._get(inst, 'monthNames')}; - }, - - /* Format the given date for display. */ - _formatDate: function(inst, day, month, year) { - if (!day) { - inst.currentDay = inst.selectedDay; - inst.currentMonth = inst.selectedMonth; - inst.currentYear = inst.selectedYear; - } - var date = (day ? (typeof day == 'object' ? day : - this._daylightSavingAdjust(new Date(year, month, day))) : - this._daylightSavingAdjust(new Date(inst.currentYear, inst.currentMonth, inst.currentDay))); - return this.formatDate(this._get(inst, 'dateFormat'), date, this._getFormatConfig(inst)); - } -}); - -/* - * Bind hover events for datepicker elements. - * Done via delegate so the binding only occurs once in the lifetime of the parent div. - * Global instActive, set by _updateDatepicker allows the handlers to find their way back to the active picker. - */ -function bindHover(dpDiv) { - var selector = 'button, .ui-datepicker-prev, .ui-datepicker-next, .ui-datepicker-calendar td a'; - return dpDiv.bind('mouseout', function(event) { - var elem = $( event.target ).closest( selector ); - if ( !elem.length ) { - return; - } - elem.removeClass( "ui-state-hover ui-datepicker-prev-hover ui-datepicker-next-hover" ); - }) - .bind('mouseover', function(event) { - var elem = $( event.target ).closest( selector ); - if ($.datepicker._isDisabledDatepicker( instActive.inline ? dpDiv.parent()[0] : instActive.input[0]) || - !elem.length ) { - return; - } - elem.parents('.ui-datepicker-calendar').find('a').removeClass('ui-state-hover'); - elem.addClass('ui-state-hover'); - if (elem.hasClass('ui-datepicker-prev')) elem.addClass('ui-datepicker-prev-hover'); - if (elem.hasClass('ui-datepicker-next')) elem.addClass('ui-datepicker-next-hover'); - }); -} - -/* jQuery extend now ignores nulls! */ -function extendRemove(target, props) { - $.extend(target, props); - for (var name in props) - if (props[name] == null || props[name] == undefined) - target[name] = props[name]; - return target; -}; - -/* Determine whether an object is an array. */ -function isArray(a) { - return (a && (($.browser.safari && typeof a == 'object' && a.length) || - (a.constructor && a.constructor.toString().match(/\Array\(\)/)))); -}; - -/* Invoke the datepicker functionality. - @param options string - a command, optionally followed by additional parameters or - Object - settings for attaching new datepicker functionality - @return jQuery object */ -$.fn.datepicker = function(options){ - - /* Verify an empty collection wasn't passed - Fixes #6976 */ - if ( !this.length ) { - return this; - } - - /* Initialise the date picker. */ - if (!$.datepicker.initialized) { - $(document).mousedown($.datepicker._checkExternalClick). - find('body').append($.datepicker.dpDiv); - $.datepicker.initialized = true; - } - - var otherArgs = Array.prototype.slice.call(arguments, 1); - if (typeof options == 'string' && (options == 'isDisabled' || options == 'getDate' || options == 'widget')) - return $.datepicker['_' + options + 'Datepicker']. - apply($.datepicker, [this[0]].concat(otherArgs)); - if (options == 'option' && arguments.length == 2 && typeof arguments[1] == 'string') - return $.datepicker['_' + options + 'Datepicker']. - apply($.datepicker, [this[0]].concat(otherArgs)); - return this.each(function() { - typeof options == 'string' ? - $.datepicker['_' + options + 'Datepicker']. - apply($.datepicker, [this].concat(otherArgs)) : - $.datepicker._attachDatepicker(this, options); - }); -}; - -$.datepicker = new Datepicker(); // singleton instance -$.datepicker.initialized = false; -$.datepicker.uuid = new Date().getTime(); -$.datepicker.version = "1.8.15"; - -// Workaround for #4055 -// Add another global to avoid noConflict issues with inline event handlers -window['DP_jQuery_' + dpuuid] = $; - -})(jQuery); -/* - * jQuery UI Dialog 1.8.15 - * - * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) - * Dual licensed under the MIT or GPL Version 2 licenses. - * http://jquery.org/license - * - * http://docs.jquery.com/UI/Dialog - * - * Depends: - * jquery.ui.core.js - * jquery.ui.widget.js - * jquery.ui.button.js - * jquery.ui.draggable.js - * jquery.ui.mouse.js - * jquery.ui.position.js - * jquery.ui.resizable.js - */ -(function( $, undefined ) { - -var uiDialogClasses = - 'ui-dialog ' + - 'ui-widget ' + - 'ui-widget-content ' + - 'ui-corner-all ', - sizeRelatedOptions = { - buttons: true, - height: true, - maxHeight: true, - maxWidth: true, - minHeight: true, - minWidth: true, - width: true - }, - resizableRelatedOptions = { - maxHeight: true, - maxWidth: true, - minHeight: true, - minWidth: true - }, - // support for jQuery 1.3.2 - handle common attrFn methods for dialog - attrFn = $.attrFn || { - val: true, - css: true, - html: true, - text: true, - data: true, - width: true, - height: true, - offset: true, - click: true - }; - -$.widget("ui.dialog", { - options: { - autoOpen: true, - buttons: {}, - closeOnEscape: true, - closeText: 'close', - dialogClass: '', - draggable: true, - hide: null, - height: 'auto', - maxHeight: false, - maxWidth: false, - minHeight: 150, - minWidth: 150, - modal: false, - position: { - my: 'center', - at: 'center', - collision: 'fit', - // ensure that the titlebar is never outside the document - using: function(pos) { - var topOffset = $(this).css(pos).offset().top; - if (topOffset < 0) { - $(this).css('top', pos.top - topOffset); - } - } - }, - resizable: true, - show: null, - stack: true, - title: '', - width: 300, - zIndex: 1000 - }, - - _create: function() { - this.originalTitle = this.element.attr('title'); - // #5742 - .attr() might return a DOMElement - if ( typeof this.originalTitle !== "string" ) { - this.originalTitle = ""; - } - - this.options.title = this.options.title || this.originalTitle; - var self = this, - options = self.options, - - title = options.title || ' ', - titleId = $.ui.dialog.getTitleId(self.element), - - uiDialog = (self.uiDialog = $('
      ')) - .appendTo(document.body) - .hide() - .addClass(uiDialogClasses + options.dialogClass) - .css({ - zIndex: options.zIndex - }) - // setting tabIndex makes the div focusable - // setting outline to 0 prevents a border on focus in Mozilla - .attr('tabIndex', -1).css('outline', 0).keydown(function(event) { - if (options.closeOnEscape && event.keyCode && - event.keyCode === $.ui.keyCode.ESCAPE) { - - self.close(event); - event.preventDefault(); - } - }) - .attr({ - role: 'dialog', - 'aria-labelledby': titleId - }) - .mousedown(function(event) { - self.moveToTop(false, event); - }), - - uiDialogContent = self.element - .show() - .removeAttr('title') - .addClass( - 'ui-dialog-content ' + - 'ui-widget-content') - .appendTo(uiDialog), - - uiDialogTitlebar = (self.uiDialogTitlebar = $('
      ')) - .addClass( - 'ui-dialog-titlebar ' + - 'ui-widget-header ' + - 'ui-corner-all ' + - 'ui-helper-clearfix' - ) - .prependTo(uiDialog), - - uiDialogTitlebarClose = $('') - .addClass( - 'ui-dialog-titlebar-close ' + - 'ui-corner-all' - ) - .attr('role', 'button') - .hover( - function() { - uiDialogTitlebarClose.addClass('ui-state-hover'); - }, - function() { - uiDialogTitlebarClose.removeClass('ui-state-hover'); - } - ) - .focus(function() { - uiDialogTitlebarClose.addClass('ui-state-focus'); - }) - .blur(function() { - uiDialogTitlebarClose.removeClass('ui-state-focus'); - }) - .click(function(event) { - self.close(event); - return false; - }) - .appendTo(uiDialogTitlebar), - - uiDialogTitlebarCloseText = (self.uiDialogTitlebarCloseText = $('')) - .addClass( - 'ui-icon ' + - 'ui-icon-closethick' - ) - .text(options.closeText) - .appendTo(uiDialogTitlebarClose), - - uiDialogTitle = $('') - .addClass('ui-dialog-title') - .attr('id', titleId) - .html(title) - .prependTo(uiDialogTitlebar); - - //handling of deprecated beforeclose (vs beforeClose) option - //Ticket #4669 http://dev.jqueryui.com/ticket/4669 - //TODO: remove in 1.9pre - if ($.isFunction(options.beforeclose) && !$.isFunction(options.beforeClose)) { - options.beforeClose = options.beforeclose; - } - - uiDialogTitlebar.find("*").add(uiDialogTitlebar).disableSelection(); - - if (options.draggable && $.fn.draggable) { - self._makeDraggable(); - } - if (options.resizable && $.fn.resizable) { - self._makeResizable(); - } - - self._createButtons(options.buttons); - self._isOpen = false; - - if ($.fn.bgiframe) { - uiDialog.bgiframe(); - } - }, - - _init: function() { - if ( this.options.autoOpen ) { - this.open(); - } - }, - - destroy: function() { - var self = this; - - if (self.overlay) { - self.overlay.destroy(); - } - self.uiDialog.hide(); - self.element - .unbind('.dialog') - .removeData('dialog') - .removeClass('ui-dialog-content ui-widget-content') - .hide().appendTo('body'); - self.uiDialog.remove(); - - if (self.originalTitle) { - self.element.attr('title', self.originalTitle); - } - - return self; - }, - - widget: function() { - return this.uiDialog; - }, - - close: function(event) { - var self = this, - maxZ, thisZ; - - if (false === self._trigger('beforeClose', event)) { - return; - } - - if (self.overlay) { - self.overlay.destroy(); - } - self.uiDialog.unbind('keypress.ui-dialog'); - - self._isOpen = false; - - if (self.options.hide) { - self.uiDialog.hide(self.options.hide, function() { - self._trigger('close', event); - }); - } else { - self.uiDialog.hide(); - self._trigger('close', event); - } - - $.ui.dialog.overlay.resize(); - - // adjust the maxZ to allow other modal dialogs to continue to work (see #4309) - if (self.options.modal) { - maxZ = 0; - $('.ui-dialog').each(function() { - if (this !== self.uiDialog[0]) { - thisZ = $(this).css('z-index'); - if(!isNaN(thisZ)) { - maxZ = Math.max(maxZ, thisZ); - } - } - }); - $.ui.dialog.maxZ = maxZ; - } - - return self; - }, - - isOpen: function() { - return this._isOpen; - }, - - // the force parameter allows us to move modal dialogs to their correct - // position on open - moveToTop: function(force, event) { - var self = this, - options = self.options, - saveScroll; - - if ((options.modal && !force) || - (!options.stack && !options.modal)) { - return self._trigger('focus', event); - } - - if (options.zIndex > $.ui.dialog.maxZ) { - $.ui.dialog.maxZ = options.zIndex; - } - if (self.overlay) { - $.ui.dialog.maxZ += 1; - self.overlay.$el.css('z-index', $.ui.dialog.overlay.maxZ = $.ui.dialog.maxZ); - } - - //Save and then restore scroll since Opera 9.5+ resets when parent z-Index is changed. - // http://ui.jquery.com/bugs/ticket/3193 - saveScroll = { scrollTop: self.element.scrollTop(), scrollLeft: self.element.scrollLeft() }; - $.ui.dialog.maxZ += 1; - self.uiDialog.css('z-index', $.ui.dialog.maxZ); - self.element.attr(saveScroll); - self._trigger('focus', event); - - return self; - }, - - open: function() { - if (this._isOpen) { return; } - - var self = this, - options = self.options, - uiDialog = self.uiDialog; - - self.overlay = options.modal ? new $.ui.dialog.overlay(self) : null; - self._size(); - self._position(options.position); - uiDialog.show(options.show); - self.moveToTop(true); - - // prevent tabbing out of modal dialogs - if (options.modal) { - uiDialog.bind('keypress.ui-dialog', function(event) { - if (event.keyCode !== $.ui.keyCode.TAB) { - return; - } - - var tabbables = $(':tabbable', this), - first = tabbables.filter(':first'), - last = tabbables.filter(':last'); - - if (event.target === last[0] && !event.shiftKey) { - first.focus(1); - return false; - } else if (event.target === first[0] && event.shiftKey) { - last.focus(1); - return false; - } - }); - } - - // set focus to the first tabbable element in the content area or the first button - // if there are no tabbable elements, set focus on the dialog itself - $(self.element.find(':tabbable').get().concat( - uiDialog.find('.ui-dialog-buttonpane :tabbable').get().concat( - uiDialog.get()))).eq(0).focus(); - - self._isOpen = true; - self._trigger('open'); - - return self; - }, - - _createButtons: function(buttons) { - var self = this, - hasButtons = false, - uiDialogButtonPane = $('
      ') - .addClass( - 'ui-dialog-buttonpane ' + - 'ui-widget-content ' + - 'ui-helper-clearfix' - ), - uiButtonSet = $( "
      " ) - .addClass( "ui-dialog-buttonset" ) - .appendTo( uiDialogButtonPane ); - - // if we already have a button pane, remove it - self.uiDialog.find('.ui-dialog-buttonpane').remove(); - - if (typeof buttons === 'object' && buttons !== null) { - $.each(buttons, function() { - return !(hasButtons = true); - }); - } - if (hasButtons) { - $.each(buttons, function(name, props) { - props = $.isFunction( props ) ? - { click: props, text: name } : - props; - var button = $('') - .click(function() { - props.click.apply(self.element[0], arguments); - }) - .appendTo(uiButtonSet); - // can't use .attr( props, true ) with jQuery 1.3.2. - $.each( props, function( key, value ) { - if ( key === "click" ) { - return; - } - if ( key in attrFn ) { - button[ key ]( value ); - } else { - button.attr( key, value ); - } - }); - if ($.fn.button) { - button.button(); - } - }); - uiDialogButtonPane.appendTo(self.uiDialog); - } - }, - - _makeDraggable: function() { - var self = this, - options = self.options, - doc = $(document), - heightBeforeDrag; - - function filteredUi(ui) { - return { - position: ui.position, - offset: ui.offset - }; - } - - self.uiDialog.draggable({ - cancel: '.ui-dialog-content, .ui-dialog-titlebar-close', - handle: '.ui-dialog-titlebar', - containment: 'document', - start: function(event, ui) { - heightBeforeDrag = options.height === "auto" ? "auto" : $(this).height(); - $(this).height($(this).height()).addClass("ui-dialog-dragging"); - self._trigger('dragStart', event, filteredUi(ui)); - }, - drag: function(event, ui) { - self._trigger('drag', event, filteredUi(ui)); - }, - stop: function(event, ui) { - options.position = [ui.position.left - doc.scrollLeft(), - ui.position.top - doc.scrollTop()]; - $(this).removeClass("ui-dialog-dragging").height(heightBeforeDrag); - self._trigger('dragStop', event, filteredUi(ui)); - $.ui.dialog.overlay.resize(); - } - }); - }, - - _makeResizable: function(handles) { - handles = (handles === undefined ? this.options.resizable : handles); - var self = this, - options = self.options, - // .ui-resizable has position: relative defined in the stylesheet - // but dialogs have to use absolute or fixed positioning - position = self.uiDialog.css('position'), - resizeHandles = (typeof handles === 'string' ? - handles : - 'n,e,s,w,se,sw,ne,nw' - ); - - function filteredUi(ui) { - return { - originalPosition: ui.originalPosition, - originalSize: ui.originalSize, - position: ui.position, - size: ui.size - }; - } - - self.uiDialog.resizable({ - cancel: '.ui-dialog-content', - containment: 'document', - alsoResize: self.element, - maxWidth: options.maxWidth, - maxHeight: options.maxHeight, - minWidth: options.minWidth, - minHeight: self._minHeight(), - handles: resizeHandles, - start: function(event, ui) { - $(this).addClass("ui-dialog-resizing"); - self._trigger('resizeStart', event, filteredUi(ui)); - }, - resize: function(event, ui) { - self._trigger('resize', event, filteredUi(ui)); - }, - stop: function(event, ui) { - $(this).removeClass("ui-dialog-resizing"); - options.height = $(this).height(); - options.width = $(this).width(); - self._trigger('resizeStop', event, filteredUi(ui)); - $.ui.dialog.overlay.resize(); - } - }) - .css('position', position) - .find('.ui-resizable-se').addClass('ui-icon ui-icon-grip-diagonal-se'); - }, - - _minHeight: function() { - var options = this.options; - - if (options.height === 'auto') { - return options.minHeight; - } else { - return Math.min(options.minHeight, options.height); - } - }, - - _position: function(position) { - var myAt = [], - offset = [0, 0], - isVisible; - - if (position) { - // deep extending converts arrays to objects in jQuery <= 1.3.2 :-( - // if (typeof position == 'string' || $.isArray(position)) { - // myAt = $.isArray(position) ? position : position.split(' '); - - if (typeof position === 'string' || (typeof position === 'object' && '0' in position)) { - myAt = position.split ? position.split(' ') : [position[0], position[1]]; - if (myAt.length === 1) { - myAt[1] = myAt[0]; - } - - $.each(['left', 'top'], function(i, offsetPosition) { - if (+myAt[i] === myAt[i]) { - offset[i] = myAt[i]; - myAt[i] = offsetPosition; - } - }); - - position = { - my: myAt.join(" "), - at: myAt.join(" "), - offset: offset.join(" ") - }; - } - - position = $.extend({}, $.ui.dialog.prototype.options.position, position); - } else { - position = $.ui.dialog.prototype.options.position; - } - - // need to show the dialog to get the actual offset in the position plugin - isVisible = this.uiDialog.is(':visible'); - if (!isVisible) { - this.uiDialog.show(); - } - this.uiDialog - // workaround for jQuery bug #5781 http://dev.jquery.com/ticket/5781 - .css({ top: 0, left: 0 }) - .position($.extend({ of: window }, position)); - if (!isVisible) { - this.uiDialog.hide(); - } - }, - - _setOptions: function( options ) { - var self = this, - resizableOptions = {}, - resize = false; - - $.each( options, function( key, value ) { - self._setOption( key, value ); - - if ( key in sizeRelatedOptions ) { - resize = true; - } - if ( key in resizableRelatedOptions ) { - resizableOptions[ key ] = value; - } - }); - - if ( resize ) { - this._size(); - } - if ( this.uiDialog.is( ":data(resizable)" ) ) { - this.uiDialog.resizable( "option", resizableOptions ); - } - }, - - _setOption: function(key, value){ - var self = this, - uiDialog = self.uiDialog; - - switch (key) { - //handling of deprecated beforeclose (vs beforeClose) option - //Ticket #4669 http://dev.jqueryui.com/ticket/4669 - //TODO: remove in 1.9pre - case "beforeclose": - key = "beforeClose"; - break; - case "buttons": - self._createButtons(value); - break; - case "closeText": - // ensure that we always pass a string - self.uiDialogTitlebarCloseText.text("" + value); - break; - case "dialogClass": - uiDialog - .removeClass(self.options.dialogClass) - .addClass(uiDialogClasses + value); - break; - case "disabled": - if (value) { - uiDialog.addClass('ui-dialog-disabled'); - } else { - uiDialog.removeClass('ui-dialog-disabled'); - } - break; - case "draggable": - var isDraggable = uiDialog.is( ":data(draggable)" ); - if ( isDraggable && !value ) { - uiDialog.draggable( "destroy" ); - } - - if ( !isDraggable && value ) { - self._makeDraggable(); - } - break; - case "position": - self._position(value); - break; - case "resizable": - // currently resizable, becoming non-resizable - var isResizable = uiDialog.is( ":data(resizable)" ); - if (isResizable && !value) { - uiDialog.resizable('destroy'); - } - - // currently resizable, changing handles - if (isResizable && typeof value === 'string') { - uiDialog.resizable('option', 'handles', value); - } - - // currently non-resizable, becoming resizable - if (!isResizable && value !== false) { - self._makeResizable(value); - } - break; - case "title": - // convert whatever was passed in o a string, for html() to not throw up - $(".ui-dialog-title", self.uiDialogTitlebar).html("" + (value || ' ')); - break; - } - - $.Widget.prototype._setOption.apply(self, arguments); - }, - - _size: function() { - /* If the user has resized the dialog, the .ui-dialog and .ui-dialog-content - * divs will both have width and height set, so we need to reset them - */ - var options = this.options, - nonContentHeight, - minContentHeight, - isVisible = this.uiDialog.is( ":visible" ); - - // reset content sizing - this.element.show().css({ - width: 'auto', - minHeight: 0, - height: 0 - }); - - if (options.minWidth > options.width) { - options.width = options.minWidth; - } - - // reset wrapper sizing - // determine the height of all the non-content elements - nonContentHeight = this.uiDialog.css({ - height: 'auto', - width: options.width - }) - .height(); - minContentHeight = Math.max( 0, options.minHeight - nonContentHeight ); - - if ( options.height === "auto" ) { - // only needed for IE6 support - if ( $.support.minHeight ) { - this.element.css({ - minHeight: minContentHeight, - height: "auto" - }); - } else { - this.uiDialog.show(); - var autoHeight = this.element.css( "height", "auto" ).height(); - if ( !isVisible ) { - this.uiDialog.hide(); - } - this.element.height( Math.max( autoHeight, minContentHeight ) ); - } - } else { - this.element.height( Math.max( options.height - nonContentHeight, 0 ) ); - } - - if (this.uiDialog.is(':data(resizable)')) { - this.uiDialog.resizable('option', 'minHeight', this._minHeight()); - } - } -}); - -$.extend($.ui.dialog, { - version: "1.8.15", - - uuid: 0, - maxZ: 0, - - getTitleId: function($el) { - var id = $el.attr('id'); - if (!id) { - this.uuid += 1; - id = this.uuid; - } - return 'ui-dialog-title-' + id; - }, - - overlay: function(dialog) { - this.$el = $.ui.dialog.overlay.create(dialog); - } -}); - -$.extend($.ui.dialog.overlay, { - instances: [], - // reuse old instances due to IE memory leak with alpha transparency (see #5185) - oldInstances: [], - maxZ: 0, - events: $.map('focus,mousedown,mouseup,keydown,keypress,click'.split(','), - function(event) { return event + '.dialog-overlay'; }).join(' '), - create: function(dialog) { - if (this.instances.length === 0) { - // prevent use of anchors and inputs - // we use a setTimeout in case the overlay is created from an - // event that we're going to be cancelling (see #2804) - setTimeout(function() { - // handle $(el).dialog().dialog('close') (see #4065) - if ($.ui.dialog.overlay.instances.length) { - $(document).bind($.ui.dialog.overlay.events, function(event) { - // stop events if the z-index of the target is < the z-index of the overlay - // we cannot return true when we don't want to cancel the event (#3523) - if ($(event.target).zIndex() < $.ui.dialog.overlay.maxZ) { - return false; - } - }); - } - }, 1); - - // allow closing by pressing the escape key - $(document).bind('keydown.dialog-overlay', function(event) { - if (dialog.options.closeOnEscape && event.keyCode && - event.keyCode === $.ui.keyCode.ESCAPE) { - - dialog.close(event); - event.preventDefault(); - } - }); - - // handle window resize - $(window).bind('resize.dialog-overlay', $.ui.dialog.overlay.resize); - } - - var $el = (this.oldInstances.pop() || $('
      ').addClass('ui-widget-overlay')) - .appendTo(document.body) - .css({ - width: this.width(), - height: this.height() - }); - - if ($.fn.bgiframe) { - $el.bgiframe(); - } - - this.instances.push($el); - return $el; - }, - - destroy: function($el) { - var indexOf = $.inArray($el, this.instances); - if (indexOf != -1){ - this.oldInstances.push(this.instances.splice(indexOf, 1)[0]); - } - - if (this.instances.length === 0) { - $([document, window]).unbind('.dialog-overlay'); - } - - $el.remove(); - - // adjust the maxZ to allow other modal dialogs to continue to work (see #4309) - var maxZ = 0; - $.each(this.instances, function() { - maxZ = Math.max(maxZ, this.css('z-index')); - }); - this.maxZ = maxZ; - }, - - height: function() { - var scrollHeight, - offsetHeight; - // handle IE 6 - if ($.browser.msie && $.browser.version < 7) { - scrollHeight = Math.max( - document.documentElement.scrollHeight, - document.body.scrollHeight - ); - offsetHeight = Math.max( - document.documentElement.offsetHeight, - document.body.offsetHeight - ); - - if (scrollHeight < offsetHeight) { - return $(window).height() + 'px'; - } else { - return scrollHeight + 'px'; - } - // handle "good" browsers - } else { - return $(document).height() + 'px'; - } - }, - - width: function() { - var scrollWidth, - offsetWidth; - // handle IE - if ( $.browser.msie ) { - scrollWidth = Math.max( - document.documentElement.scrollWidth, - document.body.scrollWidth - ); - offsetWidth = Math.max( - document.documentElement.offsetWidth, - document.body.offsetWidth - ); - - if (scrollWidth < offsetWidth) { - return $(window).width() + 'px'; - } else { - return scrollWidth + 'px'; - } - // handle "good" browsers - } else { - return $(document).width() + 'px'; - } - }, - - resize: function() { - /* If the dialog is draggable and the user drags it past the - * right edge of the window, the document becomes wider so we - * need to stretch the overlay. If the user then drags the - * dialog back to the left, the document will become narrower, - * so we need to shrink the overlay to the appropriate size. - * This is handled by shrinking the overlay before setting it - * to the full document size. - */ - var $overlays = $([]); - $.each($.ui.dialog.overlay.instances, function() { - $overlays = $overlays.add(this); - }); - - $overlays.css({ - width: 0, - height: 0 - }).css({ - width: $.ui.dialog.overlay.width(), - height: $.ui.dialog.overlay.height() - }); - } -}); - -$.extend($.ui.dialog.overlay.prototype, { - destroy: function() { - $.ui.dialog.overlay.destroy(this.$el); - } -}); - -}(jQuery)); -/* - * jQuery UI Position 1.8.15 - * - * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) - * Dual licensed under the MIT or GPL Version 2 licenses. - * http://jquery.org/license - * - * http://docs.jquery.com/UI/Position - */ -(function( $, undefined ) { - -$.ui = $.ui || {}; - -var horizontalPositions = /left|center|right/, - verticalPositions = /top|center|bottom/, - center = "center", - _position = $.fn.position, - _offset = $.fn.offset; - -$.fn.position = function( options ) { - if ( !options || !options.of ) { - return _position.apply( this, arguments ); - } - - // make a copy, we don't want to modify arguments - options = $.extend( {}, options ); - - var target = $( options.of ), - targetElem = target[0], - collision = ( options.collision || "flip" ).split( " " ), - offset = options.offset ? options.offset.split( " " ) : [ 0, 0 ], - targetWidth, - targetHeight, - basePosition; - - if ( targetElem.nodeType === 9 ) { - targetWidth = target.width(); - targetHeight = target.height(); - basePosition = { top: 0, left: 0 }; - // TODO: use $.isWindow() in 1.9 - } else if ( targetElem.setTimeout ) { - targetWidth = target.width(); - targetHeight = target.height(); - basePosition = { top: target.scrollTop(), left: target.scrollLeft() }; - } else if ( targetElem.preventDefault ) { - // force left top to allow flipping - options.at = "left top"; - targetWidth = targetHeight = 0; - basePosition = { top: options.of.pageY, left: options.of.pageX }; - } else { - targetWidth = target.outerWidth(); - targetHeight = target.outerHeight(); - basePosition = target.offset(); - } - - // force my and at to have valid horizontal and veritcal positions - // if a value is missing or invalid, it will be converted to center - $.each( [ "my", "at" ], function() { - var pos = ( options[this] || "" ).split( " " ); - if ( pos.length === 1) { - pos = horizontalPositions.test( pos[0] ) ? - pos.concat( [center] ) : - verticalPositions.test( pos[0] ) ? - [ center ].concat( pos ) : - [ center, center ]; - } - pos[ 0 ] = horizontalPositions.test( pos[0] ) ? pos[ 0 ] : center; - pos[ 1 ] = verticalPositions.test( pos[1] ) ? pos[ 1 ] : center; - options[ this ] = pos; - }); - - // normalize collision option - if ( collision.length === 1 ) { - collision[ 1 ] = collision[ 0 ]; - } - - // normalize offset option - offset[ 0 ] = parseInt( offset[0], 10 ) || 0; - if ( offset.length === 1 ) { - offset[ 1 ] = offset[ 0 ]; - } - offset[ 1 ] = parseInt( offset[1], 10 ) || 0; - - if ( options.at[0] === "right" ) { - basePosition.left += targetWidth; - } else if ( options.at[0] === center ) { - basePosition.left += targetWidth / 2; - } - - if ( options.at[1] === "bottom" ) { - basePosition.top += targetHeight; - } else if ( options.at[1] === center ) { - basePosition.top += targetHeight / 2; - } - - basePosition.left += offset[ 0 ]; - basePosition.top += offset[ 1 ]; - - return this.each(function() { - var elem = $( this ), - elemWidth = elem.outerWidth(), - elemHeight = elem.outerHeight(), - marginLeft = parseInt( $.curCSS( this, "marginLeft", true ) ) || 0, - marginTop = parseInt( $.curCSS( this, "marginTop", true ) ) || 0, - collisionWidth = elemWidth + marginLeft + - ( parseInt( $.curCSS( this, "marginRight", true ) ) || 0 ), - collisionHeight = elemHeight + marginTop + - ( parseInt( $.curCSS( this, "marginBottom", true ) ) || 0 ), - position = $.extend( {}, basePosition ), - collisionPosition; - - if ( options.my[0] === "right" ) { - position.left -= elemWidth; - } else if ( options.my[0] === center ) { - position.left -= elemWidth / 2; - } - - if ( options.my[1] === "bottom" ) { - position.top -= elemHeight; - } else if ( options.my[1] === center ) { - position.top -= elemHeight / 2; - } - - // prevent fractions (see #5280) - position.left = Math.round( position.left ); - position.top = Math.round( position.top ); - - collisionPosition = { - left: position.left - marginLeft, - top: position.top - marginTop - }; - - $.each( [ "left", "top" ], function( i, dir ) { - if ( $.ui.position[ collision[i] ] ) { - $.ui.position[ collision[i] ][ dir ]( position, { - targetWidth: targetWidth, - targetHeight: targetHeight, - elemWidth: elemWidth, - elemHeight: elemHeight, - collisionPosition: collisionPosition, - collisionWidth: collisionWidth, - collisionHeight: collisionHeight, - offset: offset, - my: options.my, - at: options.at - }); - } - }); - - if ( $.fn.bgiframe ) { - elem.bgiframe(); - } - elem.offset( $.extend( position, { using: options.using } ) ); - }); -}; - -$.ui.position = { - fit: { - left: function( position, data ) { - var win = $( window ), - over = data.collisionPosition.left + data.collisionWidth - win.width() - win.scrollLeft(); - position.left = over > 0 ? position.left - over : Math.max( position.left - data.collisionPosition.left, position.left ); - }, - top: function( position, data ) { - var win = $( window ), - over = data.collisionPosition.top + data.collisionHeight - win.height() - win.scrollTop(); - position.top = over > 0 ? position.top - over : Math.max( position.top - data.collisionPosition.top, position.top ); - } - }, - - flip: { - left: function( position, data ) { - if ( data.at[0] === center ) { - return; - } - var win = $( window ), - over = data.collisionPosition.left + data.collisionWidth - win.width() - win.scrollLeft(), - myOffset = data.my[ 0 ] === "left" ? - -data.elemWidth : - data.my[ 0 ] === "right" ? - data.elemWidth : - 0, - atOffset = data.at[ 0 ] === "left" ? - data.targetWidth : - -data.targetWidth, - offset = -2 * data.offset[ 0 ]; - position.left += data.collisionPosition.left < 0 ? - myOffset + atOffset + offset : - over > 0 ? - myOffset + atOffset + offset : - 0; - }, - top: function( position, data ) { - if ( data.at[1] === center ) { - return; - } - var win = $( window ), - over = data.collisionPosition.top + data.collisionHeight - win.height() - win.scrollTop(), - myOffset = data.my[ 1 ] === "top" ? - -data.elemHeight : - data.my[ 1 ] === "bottom" ? - data.elemHeight : - 0, - atOffset = data.at[ 1 ] === "top" ? - data.targetHeight : - -data.targetHeight, - offset = -2 * data.offset[ 1 ]; - position.top += data.collisionPosition.top < 0 ? - myOffset + atOffset + offset : - over > 0 ? - myOffset + atOffset + offset : - 0; - } - } -}; - -// offset setter from jQuery 1.4 -if ( !$.offset.setOffset ) { - $.offset.setOffset = function( elem, options ) { - // set position first, in-case top/left are set even on static elem - if ( /static/.test( $.curCSS( elem, "position" ) ) ) { - elem.style.position = "relative"; - } - var curElem = $( elem ), - curOffset = curElem.offset(), - curTop = parseInt( $.curCSS( elem, "top", true ), 10 ) || 0, - curLeft = parseInt( $.curCSS( elem, "left", true ), 10) || 0, - props = { - top: (options.top - curOffset.top) + curTop, - left: (options.left - curOffset.left) + curLeft - }; - - if ( 'using' in options ) { - options.using.call( elem, props ); - } else { - curElem.css( props ); - } - }; - - $.fn.offset = function( options ) { - var elem = this[ 0 ]; - if ( !elem || !elem.ownerDocument ) { return null; } - if ( options ) { - return this.each(function() { - $.offset.setOffset( this, options ); - }); - } - return _offset.call( this ); - }; -} - -}( jQuery )); -/* - * jQuery UI Progressbar 1.8.15 - * - * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) - * Dual licensed under the MIT or GPL Version 2 licenses. - * http://jquery.org/license - * - * http://docs.jquery.com/UI/Progressbar - * - * Depends: - * jquery.ui.core.js - * jquery.ui.widget.js - */ -(function( $, undefined ) { - -$.widget( "ui.progressbar", { - options: { - value: 0, - max: 100 - }, - - min: 0, - - _create: function() { - this.element - .addClass( "ui-progressbar ui-widget ui-widget-content ui-corner-all" ) - .attr({ - role: "progressbar", - "aria-valuemin": this.min, - "aria-valuemax": this.options.max, - "aria-valuenow": this._value() - }); - - this.valueDiv = $( "
      " ) - .appendTo( this.element ); - - this.oldValue = this._value(); - this._refreshValue(); - }, - - destroy: function() { - this.element - .removeClass( "ui-progressbar ui-widget ui-widget-content ui-corner-all" ) - .removeAttr( "role" ) - .removeAttr( "aria-valuemin" ) - .removeAttr( "aria-valuemax" ) - .removeAttr( "aria-valuenow" ); - - this.valueDiv.remove(); - - $.Widget.prototype.destroy.apply( this, arguments ); - }, - - value: function( newValue ) { - if ( newValue === undefined ) { - return this._value(); - } - - this._setOption( "value", newValue ); - return this; - }, - - _setOption: function( key, value ) { - if ( key === "value" ) { - this.options.value = value; - this._refreshValue(); - if ( this._value() === this.options.max ) { - this._trigger( "complete" ); - } - } - - $.Widget.prototype._setOption.apply( this, arguments ); - }, - - _value: function() { - var val = this.options.value; - // normalize invalid value - if ( typeof val !== "number" ) { - val = 0; - } - return Math.min( this.options.max, Math.max( this.min, val ) ); - }, - - _percentage: function() { - return 100 * this._value() / this.options.max; - }, - - _refreshValue: function() { - var value = this.value(); - var percentage = this._percentage(); - - if ( this.oldValue !== value ) { - this.oldValue = value; - this._trigger( "change" ); - } - - this.valueDiv - .toggle( value > this.min ) - .toggleClass( "ui-corner-right", value === this.options.max ) - .width( percentage.toFixed(0) + "%" ); - this.element.attr( "aria-valuenow", value ); - } -}); - -$.extend( $.ui.progressbar, { - version: "1.8.15" -}); - -})( jQuery ); -/* - * jQuery UI Slider 1.8.15 - * - * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) - * Dual licensed under the MIT or GPL Version 2 licenses. - * http://jquery.org/license - * - * http://docs.jquery.com/UI/Slider - * - * Depends: - * jquery.ui.core.js - * jquery.ui.mouse.js - * jquery.ui.widget.js - */ -(function( $, undefined ) { - -// number of pages in a slider -// (how many times can you page up/down to go through the whole range) -var numPages = 5; - -$.widget( "ui.slider", $.ui.mouse, { - - widgetEventPrefix: "slide", - - options: { - animate: false, - distance: 0, - max: 100, - min: 0, - orientation: "horizontal", - range: false, - step: 1, - value: 0, - values: null - }, - - _create: function() { - var self = this, - o = this.options, - existingHandles = this.element.find( ".ui-slider-handle" ).addClass( "ui-state-default ui-corner-all" ), - handle = "", - handleCount = ( o.values && o.values.length ) || 1, - handles = []; - - this._keySliding = false; - this._mouseSliding = false; - this._animateOff = true; - this._handleIndex = null; - this._detectOrientation(); - this._mouseInit(); - - this.element - .addClass( "ui-slider" + - " ui-slider-" + this.orientation + - " ui-widget" + - " ui-widget-content" + - " ui-corner-all" + - ( o.disabled ? " ui-slider-disabled ui-disabled" : "" ) ); - - this.range = $([]); - - if ( o.range ) { - if ( o.range === true ) { - if ( !o.values ) { - o.values = [ this._valueMin(), this._valueMin() ]; - } - if ( o.values.length && o.values.length !== 2 ) { - o.values = [ o.values[0], o.values[0] ]; - } - } - - this.range = $( "
      " ) - .appendTo( this.element ) - .addClass( "ui-slider-range" + - // note: this isn't the most fittingly semantic framework class for this element, - // but worked best visually with a variety of themes - " ui-widget-header" + - ( ( o.range === "min" || o.range === "max" ) ? " ui-slider-range-" + o.range : "" ) ); - } - - for ( var i = existingHandles.length; i < handleCount; i += 1 ) { - handles.push( handle ); - } - - this.handles = existingHandles.add( $( handles.join( "" ) ).appendTo( self.element ) ); - - this.handle = this.handles.eq( 0 ); - - this.handles.add( this.range ).filter( "a" ) - .click(function( event ) { - event.preventDefault(); - }) - .hover(function() { - if ( !o.disabled ) { - $( this ).addClass( "ui-state-hover" ); - } - }, function() { - $( this ).removeClass( "ui-state-hover" ); - }) - .focus(function() { - if ( !o.disabled ) { - $( ".ui-slider .ui-state-focus" ).removeClass( "ui-state-focus" ); - $( this ).addClass( "ui-state-focus" ); - } else { - $( this ).blur(); - } - }) - .blur(function() { - $( this ).removeClass( "ui-state-focus" ); - }); - - this.handles.each(function( i ) { - $( this ).data( "index.ui-slider-handle", i ); - }); - - this.handles - .keydown(function( event ) { - var ret = true, - index = $( this ).data( "index.ui-slider-handle" ), - allowed, - curVal, - newVal, - step; - - if ( self.options.disabled ) { - return; - } - - switch ( event.keyCode ) { - case $.ui.keyCode.HOME: - case $.ui.keyCode.END: - case $.ui.keyCode.PAGE_UP: - case $.ui.keyCode.PAGE_DOWN: - case $.ui.keyCode.UP: - case $.ui.keyCode.RIGHT: - case $.ui.keyCode.DOWN: - case $.ui.keyCode.LEFT: - ret = false; - if ( !self._keySliding ) { - self._keySliding = true; - $( this ).addClass( "ui-state-active" ); - allowed = self._start( event, index ); - if ( allowed === false ) { - return; - } - } - break; - } - - step = self.options.step; - if ( self.options.values && self.options.values.length ) { - curVal = newVal = self.values( index ); - } else { - curVal = newVal = self.value(); - } - - switch ( event.keyCode ) { - case $.ui.keyCode.HOME: - newVal = self._valueMin(); - break; - case $.ui.keyCode.END: - newVal = self._valueMax(); - break; - case $.ui.keyCode.PAGE_UP: - newVal = self._trimAlignValue( curVal + ( (self._valueMax() - self._valueMin()) / numPages ) ); - break; - case $.ui.keyCode.PAGE_DOWN: - newVal = self._trimAlignValue( curVal - ( (self._valueMax() - self._valueMin()) / numPages ) ); - break; - case $.ui.keyCode.UP: - case $.ui.keyCode.RIGHT: - if ( curVal === self._valueMax() ) { - return; - } - newVal = self._trimAlignValue( curVal + step ); - break; - case $.ui.keyCode.DOWN: - case $.ui.keyCode.LEFT: - if ( curVal === self._valueMin() ) { - return; - } - newVal = self._trimAlignValue( curVal - step ); - break; - } - - self._slide( event, index, newVal ); - - return ret; - - }) - .keyup(function( event ) { - var index = $( this ).data( "index.ui-slider-handle" ); - - if ( self._keySliding ) { - self._keySliding = false; - self._stop( event, index ); - self._change( event, index ); - $( this ).removeClass( "ui-state-active" ); - } - - }); - - this._refreshValue(); - - this._animateOff = false; - }, - - destroy: function() { - this.handles.remove(); - this.range.remove(); - - this.element - .removeClass( "ui-slider" + - " ui-slider-horizontal" + - " ui-slider-vertical" + - " ui-slider-disabled" + - " ui-widget" + - " ui-widget-content" + - " ui-corner-all" ) - .removeData( "slider" ) - .unbind( ".slider" ); - - this._mouseDestroy(); - - return this; - }, - - _mouseCapture: function( event ) { - var o = this.options, - position, - normValue, - distance, - closestHandle, - self, - index, - allowed, - offset, - mouseOverHandle; - - if ( o.disabled ) { - return false; - } - - this.elementSize = { - width: this.element.outerWidth(), - height: this.element.outerHeight() - }; - this.elementOffset = this.element.offset(); - - position = { x: event.pageX, y: event.pageY }; - normValue = this._normValueFromMouse( position ); - distance = this._valueMax() - this._valueMin() + 1; - self = this; - this.handles.each(function( i ) { - var thisDistance = Math.abs( normValue - self.values(i) ); - if ( distance > thisDistance ) { - distance = thisDistance; - closestHandle = $( this ); - index = i; - } - }); - - // workaround for bug #3736 (if both handles of a range are at 0, - // the first is always used as the one with least distance, - // and moving it is obviously prevented by preventing negative ranges) - if( o.range === true && this.values(1) === o.min ) { - index += 1; - closestHandle = $( this.handles[index] ); - } - - allowed = this._start( event, index ); - if ( allowed === false ) { - return false; - } - this._mouseSliding = true; - - self._handleIndex = index; - - closestHandle - .addClass( "ui-state-active" ) - .focus(); - - offset = closestHandle.offset(); - mouseOverHandle = !$( event.target ).parents().andSelf().is( ".ui-slider-handle" ); - this._clickOffset = mouseOverHandle ? { left: 0, top: 0 } : { - left: event.pageX - offset.left - ( closestHandle.width() / 2 ), - top: event.pageY - offset.top - - ( closestHandle.height() / 2 ) - - ( parseInt( closestHandle.css("borderTopWidth"), 10 ) || 0 ) - - ( parseInt( closestHandle.css("borderBottomWidth"), 10 ) || 0) + - ( parseInt( closestHandle.css("marginTop"), 10 ) || 0) - }; - - if ( !this.handles.hasClass( "ui-state-hover" ) ) { - this._slide( event, index, normValue ); - } - this._animateOff = true; - return true; - }, - - _mouseStart: function( event ) { - return true; - }, - - _mouseDrag: function( event ) { - var position = { x: event.pageX, y: event.pageY }, - normValue = this._normValueFromMouse( position ); - - this._slide( event, this._handleIndex, normValue ); - - return false; - }, - - _mouseStop: function( event ) { - this.handles.removeClass( "ui-state-active" ); - this._mouseSliding = false; - - this._stop( event, this._handleIndex ); - this._change( event, this._handleIndex ); - - this._handleIndex = null; - this._clickOffset = null; - this._animateOff = false; - - return false; - }, - - _detectOrientation: function() { - this.orientation = ( this.options.orientation === "vertical" ) ? "vertical" : "horizontal"; - }, - - _normValueFromMouse: function( position ) { - var pixelTotal, - pixelMouse, - percentMouse, - valueTotal, - valueMouse; - - if ( this.orientation === "horizontal" ) { - pixelTotal = this.elementSize.width; - pixelMouse = position.x - this.elementOffset.left - ( this._clickOffset ? this._clickOffset.left : 0 ); - } else { - pixelTotal = this.elementSize.height; - pixelMouse = position.y - this.elementOffset.top - ( this._clickOffset ? this._clickOffset.top : 0 ); - } - - percentMouse = ( pixelMouse / pixelTotal ); - if ( percentMouse > 1 ) { - percentMouse = 1; - } - if ( percentMouse < 0 ) { - percentMouse = 0; - } - if ( this.orientation === "vertical" ) { - percentMouse = 1 - percentMouse; - } - - valueTotal = this._valueMax() - this._valueMin(); - valueMouse = this._valueMin() + percentMouse * valueTotal; - - return this._trimAlignValue( valueMouse ); - }, - - _start: function( event, index ) { - var uiHash = { - handle: this.handles[ index ], - value: this.value() - }; - if ( this.options.values && this.options.values.length ) { - uiHash.value = this.values( index ); - uiHash.values = this.values(); - } - return this._trigger( "start", event, uiHash ); - }, - - _slide: function( event, index, newVal ) { - var otherVal, - newValues, - allowed; - - if ( this.options.values && this.options.values.length ) { - otherVal = this.values( index ? 0 : 1 ); - - if ( ( this.options.values.length === 2 && this.options.range === true ) && - ( ( index === 0 && newVal > otherVal) || ( index === 1 && newVal < otherVal ) ) - ) { - newVal = otherVal; - } - - if ( newVal !== this.values( index ) ) { - newValues = this.values(); - newValues[ index ] = newVal; - // A slide can be canceled by returning false from the slide callback - allowed = this._trigger( "slide", event, { - handle: this.handles[ index ], - value: newVal, - values: newValues - } ); - otherVal = this.values( index ? 0 : 1 ); - if ( allowed !== false ) { - this.values( index, newVal, true ); - } - } - } else { - if ( newVal !== this.value() ) { - // A slide can be canceled by returning false from the slide callback - allowed = this._trigger( "slide", event, { - handle: this.handles[ index ], - value: newVal - } ); - if ( allowed !== false ) { - this.value( newVal ); - } - } - } - }, - - _stop: function( event, index ) { - var uiHash = { - handle: this.handles[ index ], - value: this.value() - }; - if ( this.options.values && this.options.values.length ) { - uiHash.value = this.values( index ); - uiHash.values = this.values(); - } - - this._trigger( "stop", event, uiHash ); - }, - - _change: function( event, index ) { - if ( !this._keySliding && !this._mouseSliding ) { - var uiHash = { - handle: this.handles[ index ], - value: this.value() - }; - if ( this.options.values && this.options.values.length ) { - uiHash.value = this.values( index ); - uiHash.values = this.values(); - } - - this._trigger( "change", event, uiHash ); - } - }, - - value: function( newValue ) { - if ( arguments.length ) { - this.options.value = this._trimAlignValue( newValue ); - this._refreshValue(); - this._change( null, 0 ); - return; - } - - return this._value(); - }, - - values: function( index, newValue ) { - var vals, - newValues, - i; - - if ( arguments.length > 1 ) { - this.options.values[ index ] = this._trimAlignValue( newValue ); - this._refreshValue(); - this._change( null, index ); - return; - } - - if ( arguments.length ) { - if ( $.isArray( arguments[ 0 ] ) ) { - vals = this.options.values; - newValues = arguments[ 0 ]; - for ( i = 0; i < vals.length; i += 1 ) { - vals[ i ] = this._trimAlignValue( newValues[ i ] ); - this._change( null, i ); - } - this._refreshValue(); - } else { - if ( this.options.values && this.options.values.length ) { - return this._values( index ); - } else { - return this.value(); - } - } - } else { - return this._values(); - } - }, - - _setOption: function( key, value ) { - var i, - valsLength = 0; - - if ( $.isArray( this.options.values ) ) { - valsLength = this.options.values.length; - } - - $.Widget.prototype._setOption.apply( this, arguments ); - - switch ( key ) { - case "disabled": - if ( value ) { - this.handles.filter( ".ui-state-focus" ).blur(); - this.handles.removeClass( "ui-state-hover" ); - this.handles.propAttr( "disabled", true ); - this.element.addClass( "ui-disabled" ); - } else { - this.handles.propAttr( "disabled", false ); - this.element.removeClass( "ui-disabled" ); - } - break; - case "orientation": - this._detectOrientation(); - this.element - .removeClass( "ui-slider-horizontal ui-slider-vertical" ) - .addClass( "ui-slider-" + this.orientation ); - this._refreshValue(); - break; - case "value": - this._animateOff = true; - this._refreshValue(); - this._change( null, 0 ); - this._animateOff = false; - break; - case "values": - this._animateOff = true; - this._refreshValue(); - for ( i = 0; i < valsLength; i += 1 ) { - this._change( null, i ); - } - this._animateOff = false; - break; - } - }, - - //internal value getter - // _value() returns value trimmed by min and max, aligned by step - _value: function() { - var val = this.options.value; - val = this._trimAlignValue( val ); - - return val; - }, - - //internal values getter - // _values() returns array of values trimmed by min and max, aligned by step - // _values( index ) returns single value trimmed by min and max, aligned by step - _values: function( index ) { - var val, - vals, - i; - - if ( arguments.length ) { - val = this.options.values[ index ]; - val = this._trimAlignValue( val ); - - return val; - } else { - // .slice() creates a copy of the array - // this copy gets trimmed by min and max and then returned - vals = this.options.values.slice(); - for ( i = 0; i < vals.length; i+= 1) { - vals[ i ] = this._trimAlignValue( vals[ i ] ); - } - - return vals; - } - }, - - // returns the step-aligned value that val is closest to, between (inclusive) min and max - _trimAlignValue: function( val ) { - if ( val <= this._valueMin() ) { - return this._valueMin(); - } - if ( val >= this._valueMax() ) { - return this._valueMax(); - } - var step = ( this.options.step > 0 ) ? this.options.step : 1, - valModStep = (val - this._valueMin()) % step, - alignValue = val - valModStep; - - if ( Math.abs(valModStep) * 2 >= step ) { - alignValue += ( valModStep > 0 ) ? step : ( -step ); - } - - // Since JavaScript has problems with large floats, round - // the final value to 5 digits after the decimal point (see #4124) - return parseFloat( alignValue.toFixed(5) ); - }, - - _valueMin: function() { - return this.options.min; - }, - - _valueMax: function() { - return this.options.max; - }, - - _refreshValue: function() { - var oRange = this.options.range, - o = this.options, - self = this, - animate = ( !this._animateOff ) ? o.animate : false, - valPercent, - _set = {}, - lastValPercent, - value, - valueMin, - valueMax; - - if ( this.options.values && this.options.values.length ) { - this.handles.each(function( i, j ) { - valPercent = ( self.values(i) - self._valueMin() ) / ( self._valueMax() - self._valueMin() ) * 100; - _set[ self.orientation === "horizontal" ? "left" : "bottom" ] = valPercent + "%"; - $( this ).stop( 1, 1 )[ animate ? "animate" : "css" ]( _set, o.animate ); - if ( self.options.range === true ) { - if ( self.orientation === "horizontal" ) { - if ( i === 0 ) { - self.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { left: valPercent + "%" }, o.animate ); - } - if ( i === 1 ) { - self.range[ animate ? "animate" : "css" ]( { width: ( valPercent - lastValPercent ) + "%" }, { queue: false, duration: o.animate } ); - } - } else { - if ( i === 0 ) { - self.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { bottom: ( valPercent ) + "%" }, o.animate ); - } - if ( i === 1 ) { - self.range[ animate ? "animate" : "css" ]( { height: ( valPercent - lastValPercent ) + "%" }, { queue: false, duration: o.animate } ); - } - } - } - lastValPercent = valPercent; - }); - } else { - value = this.value(); - valueMin = this._valueMin(); - valueMax = this._valueMax(); - valPercent = ( valueMax !== valueMin ) ? - ( value - valueMin ) / ( valueMax - valueMin ) * 100 : - 0; - _set[ self.orientation === "horizontal" ? "left" : "bottom" ] = valPercent + "%"; - this.handle.stop( 1, 1 )[ animate ? "animate" : "css" ]( _set, o.animate ); - - if ( oRange === "min" && this.orientation === "horizontal" ) { - this.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { width: valPercent + "%" }, o.animate ); - } - if ( oRange === "max" && this.orientation === "horizontal" ) { - this.range[ animate ? "animate" : "css" ]( { width: ( 100 - valPercent ) + "%" }, { queue: false, duration: o.animate } ); - } - if ( oRange === "min" && this.orientation === "vertical" ) { - this.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { height: valPercent + "%" }, o.animate ); - } - if ( oRange === "max" && this.orientation === "vertical" ) { - this.range[ animate ? "animate" : "css" ]( { height: ( 100 - valPercent ) + "%" }, { queue: false, duration: o.animate } ); - } - } - } - -}); - -$.extend( $.ui.slider, { - version: "1.8.15" -}); - -}(jQuery)); -/* - * jQuery UI Tabs 1.8.15 - * - * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) - * Dual licensed under the MIT or GPL Version 2 licenses. - * http://jquery.org/license - * - * http://docs.jquery.com/UI/Tabs - * - * Depends: - * jquery.ui.core.js - * jquery.ui.widget.js - */ -(function( $, undefined ) { - -var tabId = 0, - listId = 0; - -function getNextTabId() { - return ++tabId; -} - -function getNextListId() { - return ++listId; -} - -$.widget( "ui.tabs", { - options: { - add: null, - ajaxOptions: null, - cache: false, - cookie: null, // e.g. { expires: 7, path: '/', domain: 'jquery.com', secure: true } - collapsible: false, - disable: null, - disabled: [], - enable: null, - event: "click", - fx: null, // e.g. { height: 'toggle', opacity: 'toggle', duration: 200 } - idPrefix: "ui-tabs-", - load: null, - panelTemplate: "
      ", - remove: null, - select: null, - show: null, - spinner: "Loading…", - tabTemplate: "
    • #{label}
    • " - }, - - _create: function() { - this._tabify( true ); - }, - - _setOption: function( key, value ) { - if ( key == "selected" ) { - if (this.options.collapsible && value == this.options.selected ) { - return; - } - this.select( value ); - } else { - this.options[ key ] = value; - this._tabify(); - } - }, - - _tabId: function( a ) { - return a.title && a.title.replace( /\s/g, "_" ).replace( /[^\w\u00c0-\uFFFF-]/g, "" ) || - this.options.idPrefix + getNextTabId(); - }, - - _sanitizeSelector: function( hash ) { - // we need this because an id may contain a ":" - return hash.replace( /:/g, "\\:" ); - }, - - _cookie: function() { - var cookie = this.cookie || - ( this.cookie = this.options.cookie.name || "ui-tabs-" + getNextListId() ); - return $.cookie.apply( null, [ cookie ].concat( $.makeArray( arguments ) ) ); - }, - - _ui: function( tab, panel ) { - return { - tab: tab, - panel: panel, - index: this.anchors.index( tab ) - }; - }, - - _cleanup: function() { - // restore all former loading tabs labels - this.lis.filter( ".ui-state-processing" ) - .removeClass( "ui-state-processing" ) - .find( "span:data(label.tabs)" ) - .each(function() { - var el = $( this ); - el.html( el.data( "label.tabs" ) ).removeData( "label.tabs" ); - }); - }, - - _tabify: function( init ) { - var self = this, - o = this.options, - fragmentId = /^#.+/; // Safari 2 reports '#' for an empty hash - - this.list = this.element.find( "ol,ul" ).eq( 0 ); - this.lis = $( " > li:has(a[href])", this.list ); - this.anchors = this.lis.map(function() { - return $( "a", this )[ 0 ]; - }); - this.panels = $( [] ); - - this.anchors.each(function( i, a ) { - var href = $( a ).attr( "href" ); - // For dynamically created HTML that contains a hash as href IE < 8 expands - // such href to the full page url with hash and then misinterprets tab as ajax. - // Same consideration applies for an added tab with a fragment identifier - // since a[href=#fragment-identifier] does unexpectedly not match. - // Thus normalize href attribute... - var hrefBase = href.split( "#" )[ 0 ], - baseEl; - if ( hrefBase && ( hrefBase === location.toString().split( "#" )[ 0 ] || - ( baseEl = $( "base" )[ 0 ]) && hrefBase === baseEl.href ) ) { - href = a.hash; - a.href = href; - } - - // inline tab - if ( fragmentId.test( href ) ) { - self.panels = self.panels.add( self.element.find( self._sanitizeSelector( href ) ) ); - // remote tab - // prevent loading the page itself if href is just "#" - } else if ( href && href !== "#" ) { - // required for restore on destroy - $.data( a, "href.tabs", href ); - - // TODO until #3808 is fixed strip fragment identifier from url - // (IE fails to load from such url) - $.data( a, "load.tabs", href.replace( /#.*$/, "" ) ); - - var id = self._tabId( a ); - a.href = "#" + id; - var $panel = self.element.find( "#" + id ); - if ( !$panel.length ) { - $panel = $( o.panelTemplate ) - .attr( "id", id ) - .addClass( "ui-tabs-panel ui-widget-content ui-corner-bottom" ) - .insertAfter( self.panels[ i - 1 ] || self.list ); - $panel.data( "destroy.tabs", true ); - } - self.panels = self.panels.add( $panel ); - // invalid tab href - } else { - o.disabled.push( i ); - } - }); - - // initialization from scratch - if ( init ) { - // attach necessary classes for styling - this.element.addClass( "ui-tabs ui-widget ui-widget-content ui-corner-all" ); - this.list.addClass( "ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all" ); - this.lis.addClass( "ui-state-default ui-corner-top" ); - this.panels.addClass( "ui-tabs-panel ui-widget-content ui-corner-bottom" ); - - // Selected tab - // use "selected" option or try to retrieve: - // 1. from fragment identifier in url - // 2. from cookie - // 3. from selected class attribute on
    • - if ( o.selected === undefined ) { - if ( location.hash ) { - this.anchors.each(function( i, a ) { - if ( a.hash == location.hash ) { - o.selected = i; - return false; - } - }); - } - if ( typeof o.selected !== "number" && o.cookie ) { - o.selected = parseInt( self._cookie(), 10 ); - } - if ( typeof o.selected !== "number" && this.lis.filter( ".ui-tabs-selected" ).length ) { - o.selected = this.lis.index( this.lis.filter( ".ui-tabs-selected" ) ); - } - o.selected = o.selected || ( this.lis.length ? 0 : -1 ); - } else if ( o.selected === null ) { // usage of null is deprecated, TODO remove in next release - o.selected = -1; - } - - // sanity check - default to first tab... - o.selected = ( ( o.selected >= 0 && this.anchors[ o.selected ] ) || o.selected < 0 ) - ? o.selected - : 0; - - // Take disabling tabs via class attribute from HTML - // into account and update option properly. - // A selected tab cannot become disabled. - o.disabled = $.unique( o.disabled.concat( - $.map( this.lis.filter( ".ui-state-disabled" ), function( n, i ) { - return self.lis.index( n ); - }) - ) ).sort(); - - if ( $.inArray( o.selected, o.disabled ) != -1 ) { - o.disabled.splice( $.inArray( o.selected, o.disabled ), 1 ); - } - - // highlight selected tab - this.panels.addClass( "ui-tabs-hide" ); - this.lis.removeClass( "ui-tabs-selected ui-state-active" ); - // check for length avoids error when initializing empty list - if ( o.selected >= 0 && this.anchors.length ) { - self.element.find( self._sanitizeSelector( self.anchors[ o.selected ].hash ) ).removeClass( "ui-tabs-hide" ); - this.lis.eq( o.selected ).addClass( "ui-tabs-selected ui-state-active" ); - - // seems to be expected behavior that the show callback is fired - self.element.queue( "tabs", function() { - self._trigger( "show", null, - self._ui( self.anchors[ o.selected ], self.element.find( self._sanitizeSelector( self.anchors[ o.selected ].hash ) )[ 0 ] ) ); - }); - - this.load( o.selected ); - } - - // clean up to avoid memory leaks in certain versions of IE 6 - // TODO: namespace this event - $( window ).bind( "unload", function() { - self.lis.add( self.anchors ).unbind( ".tabs" ); - self.lis = self.anchors = self.panels = null; - }); - // update selected after add/remove - } else { - o.selected = this.lis.index( this.lis.filter( ".ui-tabs-selected" ) ); - } - - // update collapsible - // TODO: use .toggleClass() - this.element[ o.collapsible ? "addClass" : "removeClass" ]( "ui-tabs-collapsible" ); - - // set or update cookie after init and add/remove respectively - if ( o.cookie ) { - this._cookie( o.selected, o.cookie ); - } - - // disable tabs - for ( var i = 0, li; ( li = this.lis[ i ] ); i++ ) { - $( li )[ $.inArray( i, o.disabled ) != -1 && - // TODO: use .toggleClass() - !$( li ).hasClass( "ui-tabs-selected" ) ? "addClass" : "removeClass" ]( "ui-state-disabled" ); - } - - // reset cache if switching from cached to not cached - if ( o.cache === false ) { - this.anchors.removeData( "cache.tabs" ); - } - - // remove all handlers before, tabify may run on existing tabs after add or option change - this.lis.add( this.anchors ).unbind( ".tabs" ); - - if ( o.event !== "mouseover" ) { - var addState = function( state, el ) { - if ( el.is( ":not(.ui-state-disabled)" ) ) { - el.addClass( "ui-state-" + state ); - } - }; - var removeState = function( state, el ) { - el.removeClass( "ui-state-" + state ); - }; - this.lis.bind( "mouseover.tabs" , function() { - addState( "hover", $( this ) ); - }); - this.lis.bind( "mouseout.tabs", function() { - removeState( "hover", $( this ) ); - }); - this.anchors.bind( "focus.tabs", function() { - addState( "focus", $( this ).closest( "li" ) ); - }); - this.anchors.bind( "blur.tabs", function() { - removeState( "focus", $( this ).closest( "li" ) ); - }); - } - - // set up animations - var hideFx, showFx; - if ( o.fx ) { - if ( $.isArray( o.fx ) ) { - hideFx = o.fx[ 0 ]; - showFx = o.fx[ 1 ]; - } else { - hideFx = showFx = o.fx; - } - } - - // Reset certain styles left over from animation - // and prevent IE's ClearType bug... - function resetStyle( $el, fx ) { - $el.css( "display", "" ); - if ( !$.support.opacity && fx.opacity ) { - $el[ 0 ].style.removeAttribute( "filter" ); - } - } - - // Show a tab... - var showTab = showFx - ? function( clicked, $show ) { - $( clicked ).closest( "li" ).addClass( "ui-tabs-selected ui-state-active" ); - $show.hide().removeClass( "ui-tabs-hide" ) // avoid flicker that way - .animate( showFx, showFx.duration || "normal", function() { - resetStyle( $show, showFx ); - self._trigger( "show", null, self._ui( clicked, $show[ 0 ] ) ); - }); - } - : function( clicked, $show ) { - $( clicked ).closest( "li" ).addClass( "ui-tabs-selected ui-state-active" ); - $show.removeClass( "ui-tabs-hide" ); - self._trigger( "show", null, self._ui( clicked, $show[ 0 ] ) ); - }; - - // Hide a tab, $show is optional... - var hideTab = hideFx - ? function( clicked, $hide ) { - $hide.animate( hideFx, hideFx.duration || "normal", function() { - self.lis.removeClass( "ui-tabs-selected ui-state-active" ); - $hide.addClass( "ui-tabs-hide" ); - resetStyle( $hide, hideFx ); - self.element.dequeue( "tabs" ); - }); - } - : function( clicked, $hide, $show ) { - self.lis.removeClass( "ui-tabs-selected ui-state-active" ); - $hide.addClass( "ui-tabs-hide" ); - self.element.dequeue( "tabs" ); - }; - - // attach tab event handler, unbind to avoid duplicates from former tabifying... - this.anchors.bind( o.event + ".tabs", function() { - var el = this, - $li = $(el).closest( "li" ), - $hide = self.panels.filter( ":not(.ui-tabs-hide)" ), - $show = self.element.find( self._sanitizeSelector( el.hash ) ); - - // If tab is already selected and not collapsible or tab disabled or - // or is already loading or click callback returns false stop here. - // Check if click handler returns false last so that it is not executed - // for a disabled or loading tab! - if ( ( $li.hasClass( "ui-tabs-selected" ) && !o.collapsible) || - $li.hasClass( "ui-state-disabled" ) || - $li.hasClass( "ui-state-processing" ) || - self.panels.filter( ":animated" ).length || - self._trigger( "select", null, self._ui( this, $show[ 0 ] ) ) === false ) { - this.blur(); - return false; - } - - o.selected = self.anchors.index( this ); - - self.abort(); - - // if tab may be closed - if ( o.collapsible ) { - if ( $li.hasClass( "ui-tabs-selected" ) ) { - o.selected = -1; - - if ( o.cookie ) { - self._cookie( o.selected, o.cookie ); - } - - self.element.queue( "tabs", function() { - hideTab( el, $hide ); - }).dequeue( "tabs" ); - - this.blur(); - return false; - } else if ( !$hide.length ) { - if ( o.cookie ) { - self._cookie( o.selected, o.cookie ); - } - - self.element.queue( "tabs", function() { - showTab( el, $show ); - }); - - // TODO make passing in node possible, see also http://dev.jqueryui.com/ticket/3171 - self.load( self.anchors.index( this ) ); - - this.blur(); - return false; - } - } - - if ( o.cookie ) { - self._cookie( o.selected, o.cookie ); - } - - // show new tab - if ( $show.length ) { - if ( $hide.length ) { - self.element.queue( "tabs", function() { - hideTab( el, $hide ); - }); - } - self.element.queue( "tabs", function() { - showTab( el, $show ); - }); - - self.load( self.anchors.index( this ) ); - } else { - throw "jQuery UI Tabs: Mismatching fragment identifier."; - } - - // Prevent IE from keeping other link focussed when using the back button - // and remove dotted border from clicked link. This is controlled via CSS - // in modern browsers; blur() removes focus from address bar in Firefox - // which can become a usability and annoying problem with tabs('rotate'). - if ( $.browser.msie ) { - this.blur(); - } - }); - - // disable click in any case - this.anchors.bind( "click.tabs", function(){ - return false; - }); - }, - - _getIndex: function( index ) { - // meta-function to give users option to provide a href string instead of a numerical index. - // also sanitizes numerical indexes to valid values. - if ( typeof index == "string" ) { - index = this.anchors.index( this.anchors.filter( "[href$=" + index + "]" ) ); - } - - return index; - }, - - destroy: function() { - var o = this.options; - - this.abort(); - - this.element - .unbind( ".tabs" ) - .removeClass( "ui-tabs ui-widget ui-widget-content ui-corner-all ui-tabs-collapsible" ) - .removeData( "tabs" ); - - this.list.removeClass( "ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all" ); - - this.anchors.each(function() { - var href = $.data( this, "href.tabs" ); - if ( href ) { - this.href = href; - } - var $this = $( this ).unbind( ".tabs" ); - $.each( [ "href", "load", "cache" ], function( i, prefix ) { - $this.removeData( prefix + ".tabs" ); - }); - }); - - this.lis.unbind( ".tabs" ).add( this.panels ).each(function() { - if ( $.data( this, "destroy.tabs" ) ) { - $( this ).remove(); - } else { - $( this ).removeClass([ - "ui-state-default", - "ui-corner-top", - "ui-tabs-selected", - "ui-state-active", - "ui-state-hover", - "ui-state-focus", - "ui-state-disabled", - "ui-tabs-panel", - "ui-widget-content", - "ui-corner-bottom", - "ui-tabs-hide" - ].join( " " ) ); - } - }); - - if ( o.cookie ) { - this._cookie( null, o.cookie ); - } - - return this; - }, - - add: function( url, label, index ) { - if ( index === undefined ) { - index = this.anchors.length; - } - - var self = this, - o = this.options, - $li = $( o.tabTemplate.replace( /#\{href\}/g, url ).replace( /#\{label\}/g, label ) ), - id = !url.indexOf( "#" ) ? url.replace( "#", "" ) : this._tabId( $( "a", $li )[ 0 ] ); - - $li.addClass( "ui-state-default ui-corner-top" ).data( "destroy.tabs", true ); - - // try to find an existing element before creating a new one - var $panel = self.element.find( "#" + id ); - if ( !$panel.length ) { - $panel = $( o.panelTemplate ) - .attr( "id", id ) - .data( "destroy.tabs", true ); - } - $panel.addClass( "ui-tabs-panel ui-widget-content ui-corner-bottom ui-tabs-hide" ); - - if ( index >= this.lis.length ) { - $li.appendTo( this.list ); - $panel.appendTo( this.list[ 0 ].parentNode ); - } else { - $li.insertBefore( this.lis[ index ] ); - $panel.insertBefore( this.panels[ index ] ); - } - - o.disabled = $.map( o.disabled, function( n, i ) { - return n >= index ? ++n : n; - }); - - this._tabify(); - - if ( this.anchors.length == 1 ) { - o.selected = 0; - $li.addClass( "ui-tabs-selected ui-state-active" ); - $panel.removeClass( "ui-tabs-hide" ); - this.element.queue( "tabs", function() { - self._trigger( "show", null, self._ui( self.anchors[ 0 ], self.panels[ 0 ] ) ); - }); - - this.load( 0 ); - } - - this._trigger( "add", null, this._ui( this.anchors[ index ], this.panels[ index ] ) ); - return this; - }, - - remove: function( index ) { - index = this._getIndex( index ); - var o = this.options, - $li = this.lis.eq( index ).remove(), - $panel = this.panels.eq( index ).remove(); - - // If selected tab was removed focus tab to the right or - // in case the last tab was removed the tab to the left. - if ( $li.hasClass( "ui-tabs-selected" ) && this.anchors.length > 1) { - this.select( index + ( index + 1 < this.anchors.length ? 1 : -1 ) ); - } - - o.disabled = $.map( - $.grep( o.disabled, function(n, i) { - return n != index; - }), - function( n, i ) { - return n >= index ? --n : n; - }); - - this._tabify(); - - this._trigger( "remove", null, this._ui( $li.find( "a" )[ 0 ], $panel[ 0 ] ) ); - return this; - }, - - enable: function( index ) { - index = this._getIndex( index ); - var o = this.options; - if ( $.inArray( index, o.disabled ) == -1 ) { - return; - } - - this.lis.eq( index ).removeClass( "ui-state-disabled" ); - o.disabled = $.grep( o.disabled, function( n, i ) { - return n != index; - }); - - this._trigger( "enable", null, this._ui( this.anchors[ index ], this.panels[ index ] ) ); - return this; - }, - - disable: function( index ) { - index = this._getIndex( index ); - var self = this, o = this.options; - // cannot disable already selected tab - if ( index != o.selected ) { - this.lis.eq( index ).addClass( "ui-state-disabled" ); - - o.disabled.push( index ); - o.disabled.sort(); - - this._trigger( "disable", null, this._ui( this.anchors[ index ], this.panels[ index ] ) ); - } - - return this; - }, - - select: function( index ) { - index = this._getIndex( index ); - if ( index == -1 ) { - if ( this.options.collapsible && this.options.selected != -1 ) { - index = this.options.selected; - } else { - return this; - } - } - this.anchors.eq( index ).trigger( this.options.event + ".tabs" ); - return this; - }, - - load: function( index ) { - index = this._getIndex( index ); - var self = this, - o = this.options, - a = this.anchors.eq( index )[ 0 ], - url = $.data( a, "load.tabs" ); - - this.abort(); - - // not remote or from cache - if ( !url || this.element.queue( "tabs" ).length !== 0 && $.data( a, "cache.tabs" ) ) { - this.element.dequeue( "tabs" ); - return; - } - - // load remote from here on - this.lis.eq( index ).addClass( "ui-state-processing" ); - - if ( o.spinner ) { - var span = $( "span", a ); - span.data( "label.tabs", span.html() ).html( o.spinner ); - } - - this.xhr = $.ajax( $.extend( {}, o.ajaxOptions, { - url: url, - success: function( r, s ) { - self.element.find( self._sanitizeSelector( a.hash ) ).html( r ); - - // take care of tab labels - self._cleanup(); - - if ( o.cache ) { - $.data( a, "cache.tabs", true ); - } - - self._trigger( "load", null, self._ui( self.anchors[ index ], self.panels[ index ] ) ); - try { - o.ajaxOptions.success( r, s ); - } - catch ( e ) {} - }, - error: function( xhr, s, e ) { - // take care of tab labels - self._cleanup(); - - self._trigger( "load", null, self._ui( self.anchors[ index ], self.panels[ index ] ) ); - try { - // Passing index avoid a race condition when this method is - // called after the user has selected another tab. - // Pass the anchor that initiated this request allows - // loadError to manipulate the tab content panel via $(a.hash) - o.ajaxOptions.error( xhr, s, index, a ); - } - catch ( e ) {} - } - } ) ); - - // last, so that load event is fired before show... - self.element.dequeue( "tabs" ); - - return this; - }, - - abort: function() { - // stop possibly running animations - this.element.queue( [] ); - this.panels.stop( false, true ); - - // "tabs" queue must not contain more than two elements, - // which are the callbacks for the latest clicked tab... - this.element.queue( "tabs", this.element.queue( "tabs" ).splice( -2, 2 ) ); - - // terminate pending requests from other tabs - if ( this.xhr ) { - this.xhr.abort(); - delete this.xhr; - } - - // take care of tab labels - this._cleanup(); - return this; - }, - - url: function( index, url ) { - this.anchors.eq( index ).removeData( "cache.tabs" ).data( "load.tabs", url ); - return this; - }, - - length: function() { - return this.anchors.length; - } -}); - -$.extend( $.ui.tabs, { - version: "1.8.15" -}); - -/* - * Tabs Extensions - */ - -/* - * Rotate - */ -$.extend( $.ui.tabs.prototype, { - rotation: null, - rotate: function( ms, continuing ) { - var self = this, - o = this.options; - - var rotate = self._rotate || ( self._rotate = function( e ) { - clearTimeout( self.rotation ); - self.rotation = setTimeout(function() { - var t = o.selected; - self.select( ++t < self.anchors.length ? t : 0 ); - }, ms ); - - if ( e ) { - e.stopPropagation(); - } - }); - - var stop = self._unrotate || ( self._unrotate = !continuing - ? function(e) { - if (e.clientX) { // in case of a true click - self.rotate(null); - } - } - : function( e ) { - t = o.selected; - rotate(); - }); - - // start rotation - if ( ms ) { - this.element.bind( "tabsshow", rotate ); - this.anchors.bind( o.event + ".tabs", stop ); - rotate(); - // stop rotation - } else { - clearTimeout( self.rotation ); - this.element.unbind( "tabsshow", rotate ); - this.anchors.unbind( o.event + ".tabs", stop ); - delete this._rotate; - delete this._unrotate; - } - - return this; - } -}); - -})( jQuery ); diff --git a/client/client/src/js/jquery/jquery.js b/client/client/src/js/jquery/jquery.js deleted file mode 100644 index f3201aac..00000000 --- a/client/client/src/js/jquery/jquery.js +++ /dev/null @@ -1,8981 +0,0 @@ -/*! - * jQuery JavaScript Library v1.6.2 - * http://jquery.com/ - * - * Copyright 2011, John Resig - * Dual licensed under the MIT or GPL Version 2 licenses. - * http://jquery.org/license - * - * Includes Sizzle.js - * http://sizzlejs.com/ - * Copyright 2011, The Dojo Foundation - * Released under the MIT, BSD, and GPL Licenses. - * - * Date: Thu Jun 30 14:16:56 2011 -0400 - */ -(function( window, undefined ) { - -// Use the correct document accordingly with window argument (sandbox) -var document = window.document, - navigator = window.navigator, - location = window.location; -var jQuery = (function() { - -// Define a local copy of jQuery -var jQuery = function( selector, context ) { - // The jQuery object is actually just the init constructor 'enhanced' - return new jQuery.fn.init( selector, context, rootjQuery ); - }, - - // Map over jQuery in case of overwrite - _jQuery = window.jQuery, - - // Map over the $ in case of overwrite - _$ = window.$, - - // A central reference to the root jQuery(document) - rootjQuery, - - // A simple way to check for HTML strings or ID strings - // (both of which we optimize for) - quickExpr = /^(?:[^<]*(<[\w\W]+>)[^>]*$|#([\w\-]*)$)/, - - // Check if a string has a non-whitespace character in it - rnotwhite = /\S/, - - // Used for trimming whitespace - trimLeft = /^\s+/, - trimRight = /\s+$/, - - // Check for digits - rdigit = /\d/, - - // Match a standalone tag - rsingleTag = /^<(\w+)\s*\/?>(?:<\/\1>)?$/, - - // JSON RegExp - rvalidchars = /^[\],:{}\s]*$/, - rvalidescape = /\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g, - rvalidtokens = /"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g, - rvalidbraces = /(?:^|:|,)(?:\s*\[)+/g, - - // Useragent RegExp - rwebkit = /(webkit)[ \/]([\w.]+)/, - ropera = /(opera)(?:.*version)?[ \/]([\w.]+)/, - rmsie = /(msie) ([\w.]+)/, - rmozilla = /(mozilla)(?:.*? rv:([\w.]+))?/, - - // Matches dashed string for camelizing - rdashAlpha = /-([a-z])/ig, - - // Used by jQuery.camelCase as callback to replace() - fcamelCase = function( all, letter ) { - return letter.toUpperCase(); - }, - - // Keep a UserAgent string for use with jQuery.browser - userAgent = navigator.userAgent, - - // For matching the engine and version of the browser - browserMatch, - - // The deferred used on DOM ready - readyList, - - // The ready event handler - DOMContentLoaded, - - // Save a reference to some core methods - toString = Object.prototype.toString, - hasOwn = Object.prototype.hasOwnProperty, - push = Array.prototype.push, - slice = Array.prototype.slice, - trim = String.prototype.trim, - indexOf = Array.prototype.indexOf, - - // [[Class]] -> type pairs - class2type = {}; - -jQuery.fn = jQuery.prototype = { - constructor: jQuery, - init: function( selector, context, rootjQuery ) { - var match, elem, ret, doc; - - // Handle $(""), $(null), or $(undefined) - if ( !selector ) { - return this; - } - - // Handle $(DOMElement) - if ( selector.nodeType ) { - this.context = this[0] = selector; - this.length = 1; - return this; - } - - // The body element only exists once, optimize finding it - if ( selector === "body" && !context && document.body ) { - this.context = document; - this[0] = document.body; - this.selector = selector; - this.length = 1; - return this; - } - - // Handle HTML strings - if ( typeof selector === "string" ) { - // Are we dealing with HTML string or an ID? - if ( selector.charAt(0) === "<" && selector.charAt( selector.length - 1 ) === ">" && selector.length >= 3 ) { - // Assume that strings that start and end with <> are HTML and skip the regex check - match = [ null, selector, null ]; - - } else { - match = quickExpr.exec( selector ); - } - - // Verify a match, and that no context was specified for #id - if ( match && (match[1] || !context) ) { - - // HANDLE: $(html) -> $(array) - if ( match[1] ) { - context = context instanceof jQuery ? context[0] : context; - doc = (context ? context.ownerDocument || context : document); - - // If a single string is passed in and it's a single tag - // just do a createElement and skip the rest - ret = rsingleTag.exec( selector ); - - if ( ret ) { - if ( jQuery.isPlainObject( context ) ) { - selector = [ document.createElement( ret[1] ) ]; - jQuery.fn.attr.call( selector, context, true ); - - } else { - selector = [ doc.createElement( ret[1] ) ]; - } - - } else { - ret = jQuery.buildFragment( [ match[1] ], [ doc ] ); - selector = (ret.cacheable ? jQuery.clone(ret.fragment) : ret.fragment).childNodes; - } - - return jQuery.merge( this, selector ); - - // HANDLE: $("#id") - } else { - elem = document.getElementById( match[2] ); - - // Check parentNode to catch when Blackberry 4.6 returns - // nodes that are no longer in the document #6963 - if ( elem && elem.parentNode ) { - // Handle the case where IE and Opera return items - // by name instead of ID - if ( elem.id !== match[2] ) { - return rootjQuery.find( selector ); - } - - // Otherwise, we inject the element directly into the jQuery object - this.length = 1; - this[0] = elem; - } - - this.context = document; - this.selector = selector; - return this; - } - - // HANDLE: $(expr, $(...)) - } else if ( !context || context.jquery ) { - return (context || rootjQuery).find( selector ); - - // HANDLE: $(expr, context) - // (which is just equivalent to: $(context).find(expr) - } else { - return this.constructor( context ).find( selector ); - } - - // HANDLE: $(function) - // Shortcut for document ready - } else if ( jQuery.isFunction( selector ) ) { - return rootjQuery.ready( selector ); - } - - if (selector.selector !== undefined) { - this.selector = selector.selector; - this.context = selector.context; - } - - return jQuery.makeArray( selector, this ); - }, - - // Start with an empty selector - selector: "", - - // The current version of jQuery being used - jquery: "1.6.2", - - // The default length of a jQuery object is 0 - length: 0, - - // The number of elements contained in the matched element set - size: function() { - return this.length; - }, - - toArray: function() { - return slice.call( this, 0 ); - }, - - // Get the Nth element in the matched element set OR - // Get the whole matched element set as a clean array - get: function( num ) { - return num == null ? - - // Return a 'clean' array - this.toArray() : - - // Return just the object - ( num < 0 ? this[ this.length + num ] : this[ num ] ); - }, - - // Take an array of elements and push it onto the stack - // (returning the new matched element set) - pushStack: function( elems, name, selector ) { - // Build a new jQuery matched element set - var ret = this.constructor(); - - if ( jQuery.isArray( elems ) ) { - push.apply( ret, elems ); - - } else { - jQuery.merge( ret, elems ); - } - - // Add the old object onto the stack (as a reference) - ret.prevObject = this; - - ret.context = this.context; - - if ( name === "find" ) { - ret.selector = this.selector + (this.selector ? " " : "") + selector; - } else if ( name ) { - ret.selector = this.selector + "." + name + "(" + selector + ")"; - } - - // Return the newly-formed element set - return ret; - }, - - // Execute a callback for every element in the matched set. - // (You can seed the arguments with an array of args, but this is - // only used internally.) - each: function( callback, args ) { - return jQuery.each( this, callback, args ); - }, - - ready: function( fn ) { - // Attach the listeners - jQuery.bindReady(); - - // Add the callback - readyList.done( fn ); - - return this; - }, - - eq: function( i ) { - return i === -1 ? - this.slice( i ) : - this.slice( i, +i + 1 ); - }, - - first: function() { - return this.eq( 0 ); - }, - - last: function() { - return this.eq( -1 ); - }, - - slice: function() { - return this.pushStack( slice.apply( this, arguments ), - "slice", slice.call(arguments).join(",") ); - }, - - map: function( callback ) { - return this.pushStack( jQuery.map(this, function( elem, i ) { - return callback.call( elem, i, elem ); - })); - }, - - end: function() { - return this.prevObject || this.constructor(null); - }, - - // For internal use only. - // Behaves like an Array's method, not like a jQuery method. - push: push, - sort: [].sort, - splice: [].splice -}; - -// Give the init function the jQuery prototype for later instantiation -jQuery.fn.init.prototype = jQuery.fn; - -jQuery.extend = jQuery.fn.extend = function() { - var options, name, src, copy, copyIsArray, clone, - target = arguments[0] || {}, - i = 1, - length = arguments.length, - deep = false; - - // Handle a deep copy situation - if ( typeof target === "boolean" ) { - deep = target; - target = arguments[1] || {}; - // skip the boolean and the target - i = 2; - } - - // Handle case when target is a string or something (possible in deep copy) - if ( typeof target !== "object" && !jQuery.isFunction(target) ) { - target = {}; - } - - // extend jQuery itself if only one argument is passed - if ( length === i ) { - target = this; - --i; - } - - for ( ; i < length; i++ ) { - // Only deal with non-null/undefined values - if ( (options = arguments[ i ]) != null ) { - // Extend the base object - for ( name in options ) { - src = target[ name ]; - copy = options[ name ]; - - // Prevent never-ending loop - if ( target === copy ) { - continue; - } - - // Recurse if we're merging plain objects or arrays - if ( deep && copy && ( jQuery.isPlainObject(copy) || (copyIsArray = jQuery.isArray(copy)) ) ) { - if ( copyIsArray ) { - copyIsArray = false; - clone = src && jQuery.isArray(src) ? src : []; - - } else { - clone = src && jQuery.isPlainObject(src) ? src : {}; - } - - // Never move original objects, clone them - target[ name ] = jQuery.extend( deep, clone, copy ); - - // Don't bring in undefined values - } else if ( copy !== undefined ) { - target[ name ] = copy; - } - } - } - } - - // Return the modified object - return target; -}; - -jQuery.extend({ - noConflict: function( deep ) { - if ( window.$ === jQuery ) { - window.$ = _$; - } - - if ( deep && window.jQuery === jQuery ) { - window.jQuery = _jQuery; - } - - return jQuery; - }, - - // Is the DOM ready to be used? Set to true once it occurs. - isReady: false, - - // A counter to track how many items to wait for before - // the ready event fires. See #6781 - readyWait: 1, - - // Hold (or release) the ready event - holdReady: function( hold ) { - if ( hold ) { - jQuery.readyWait++; - } else { - jQuery.ready( true ); - } - }, - - // Handle when the DOM is ready - ready: function( wait ) { - // Either a released hold or an DOMready/load event and not yet ready - if ( (wait === true && !--jQuery.readyWait) || (wait !== true && !jQuery.isReady) ) { - // Make sure body exists, at least, in case IE gets a little overzealous (ticket #5443). - if ( !document.body ) { - return setTimeout( jQuery.ready, 1 ); - } - - // Remember that the DOM is ready - jQuery.isReady = true; - - // If a normal DOM Ready event fired, decrement, and wait if need be - if ( wait !== true && --jQuery.readyWait > 0 ) { - return; - } - - // If there are functions bound, to execute - readyList.resolveWith( document, [ jQuery ] ); - - // Trigger any bound ready events - if ( jQuery.fn.trigger ) { - jQuery( document ).trigger( "ready" ).unbind( "ready" ); - } - } - }, - - bindReady: function() { - if ( readyList ) { - return; - } - - readyList = jQuery._Deferred(); - - // Catch cases where $(document).ready() is called after the - // browser event has already occurred. - if ( document.readyState === "complete" ) { - // Handle it asynchronously to allow scripts the opportunity to delay ready - return setTimeout( jQuery.ready, 1 ); - } - - // Mozilla, Opera and webkit nightlies currently support this event - if ( document.addEventListener ) { - // Use the handy event callback - document.addEventListener( "DOMContentLoaded", DOMContentLoaded, false ); - - // A fallback to window.onload, that will always work - window.addEventListener( "load", jQuery.ready, false ); - - // If IE event model is used - } else if ( document.attachEvent ) { - // ensure firing before onload, - // maybe late but safe also for iframes - document.attachEvent( "onreadystatechange", DOMContentLoaded ); - - // A fallback to window.onload, that will always work - window.attachEvent( "onload", jQuery.ready ); - - // If IE and not a frame - // continually check to see if the document is ready - var toplevel = false; - - try { - toplevel = window.frameElement == null; - } catch(e) {} - - if ( document.documentElement.doScroll && toplevel ) { - doScrollCheck(); - } - } - }, - - // See test/unit/core.js for details concerning isFunction. - // Since version 1.3, DOM methods and functions like alert - // aren't supported. They return false on IE (#2968). - isFunction: function( obj ) { - return jQuery.type(obj) === "function"; - }, - - isArray: Array.isArray || function( obj ) { - return jQuery.type(obj) === "array"; - }, - - // A crude way of determining if an object is a window - isWindow: function( obj ) { - return obj && typeof obj === "object" && "setInterval" in obj; - }, - - isNaN: function( obj ) { - return obj == null || !rdigit.test( obj ) || isNaN( obj ); - }, - - type: function( obj ) { - return obj == null ? - String( obj ) : - class2type[ toString.call(obj) ] || "object"; - }, - - isPlainObject: function( obj ) { - // Must be an Object. - // Because of IE, we also have to check the presence of the constructor property. - // Make sure that DOM nodes and window objects don't pass through, as well - if ( !obj || jQuery.type(obj) !== "object" || obj.nodeType || jQuery.isWindow( obj ) ) { - return false; - } - - // Not own constructor property must be Object - if ( obj.constructor && - !hasOwn.call(obj, "constructor") && - !hasOwn.call(obj.constructor.prototype, "isPrototypeOf") ) { - return false; - } - - // Own properties are enumerated firstly, so to speed up, - // if last one is own, then all properties are own. - - var key; - for ( key in obj ) {} - - return key === undefined || hasOwn.call( obj, key ); - }, - - isEmptyObject: function( obj ) { - for ( var name in obj ) { - return false; - } - return true; - }, - - error: function( msg ) { - throw msg; - }, - - parseJSON: function( data ) { - if ( typeof data !== "string" || !data ) { - return null; - } - - // Make sure leading/trailing whitespace is removed (IE can't handle it) - data = jQuery.trim( data ); - - // Attempt to parse using the native JSON parser first - if ( window.JSON && window.JSON.parse ) { - return window.JSON.parse( data ); - } - - // Make sure the incoming data is actual JSON - // Logic borrowed from http://json.org/json2.js - if ( rvalidchars.test( data.replace( rvalidescape, "@" ) - .replace( rvalidtokens, "]" ) - .replace( rvalidbraces, "")) ) { - - return (new Function( "return " + data ))(); - - } - jQuery.error( "Invalid JSON: " + data ); - }, - - // Cross-browser xml parsing - // (xml & tmp used internally) - parseXML: function( data , xml , tmp ) { - - if ( window.DOMParser ) { // Standard - tmp = new DOMParser(); - xml = tmp.parseFromString( data , "text/xml" ); - } else { // IE - xml = new ActiveXObject( "Microsoft.XMLDOM" ); - xml.async = "false"; - xml.loadXML( data ); - } - - tmp = xml.documentElement; - - if ( ! tmp || ! tmp.nodeName || tmp.nodeName === "parsererror" ) { - jQuery.error( "Invalid XML: " + data ); - } - - return xml; - }, - - noop: function() {}, - - // Evaluates a script in a global context - // Workarounds based on findings by Jim Driscoll - // http://weblogs.java.net/blog/driscoll/archive/2009/09/08/eval-javascript-global-context - globalEval: function( data ) { - if ( data && rnotwhite.test( data ) ) { - // We use execScript on Internet Explorer - // We use an anonymous function so that context is window - // rather than jQuery in Firefox - ( window.execScript || function( data ) { - window[ "eval" ].call( window, data ); - } )( data ); - } - }, - - // Converts a dashed string to camelCased string; - // Used by both the css and data modules - camelCase: function( string ) { - return string.replace( rdashAlpha, fcamelCase ); - }, - - nodeName: function( elem, name ) { - return elem.nodeName && elem.nodeName.toUpperCase() === name.toUpperCase(); - }, - - // args is for internal usage only - each: function( object, callback, args ) { - var name, i = 0, - length = object.length, - isObj = length === undefined || jQuery.isFunction( object ); - - if ( args ) { - if ( isObj ) { - for ( name in object ) { - if ( callback.apply( object[ name ], args ) === false ) { - break; - } - } - } else { - for ( ; i < length; ) { - if ( callback.apply( object[ i++ ], args ) === false ) { - break; - } - } - } - - // A special, fast, case for the most common use of each - } else { - if ( isObj ) { - for ( name in object ) { - if ( callback.call( object[ name ], name, object[ name ] ) === false ) { - break; - } - } - } else { - for ( ; i < length; ) { - if ( callback.call( object[ i ], i, object[ i++ ] ) === false ) { - break; - } - } - } - } - - return object; - }, - - // Use native String.trim function wherever possible - trim: trim ? - function( text ) { - return text == null ? - "" : - trim.call( text ); - } : - - // Otherwise use our own trimming functionality - function( text ) { - return text == null ? - "" : - text.toString().replace( trimLeft, "" ).replace( trimRight, "" ); - }, - - // results is for internal usage only - makeArray: function( array, results ) { - var ret = results || []; - - if ( array != null ) { - // The window, strings (and functions) also have 'length' - // The extra typeof function check is to prevent crashes - // in Safari 2 (See: #3039) - // Tweaked logic slightly to handle Blackberry 4.7 RegExp issues #6930 - var type = jQuery.type( array ); - - if ( array.length == null || type === "string" || type === "function" || type === "regexp" || jQuery.isWindow( array ) ) { - push.call( ret, array ); - } else { - jQuery.merge( ret, array ); - } - } - - return ret; - }, - - inArray: function( elem, array ) { - - if ( indexOf ) { - return indexOf.call( array, elem ); - } - - for ( var i = 0, length = array.length; i < length; i++ ) { - if ( array[ i ] === elem ) { - return i; - } - } - - return -1; - }, - - merge: function( first, second ) { - var i = first.length, - j = 0; - - if ( typeof second.length === "number" ) { - for ( var l = second.length; j < l; j++ ) { - first[ i++ ] = second[ j ]; - } - - } else { - while ( second[j] !== undefined ) { - first[ i++ ] = second[ j++ ]; - } - } - - first.length = i; - - return first; - }, - - grep: function( elems, callback, inv ) { - var ret = [], retVal; - inv = !!inv; - - // Go through the array, only saving the items - // that pass the validator function - for ( var i = 0, length = elems.length; i < length; i++ ) { - retVal = !!callback( elems[ i ], i ); - if ( inv !== retVal ) { - ret.push( elems[ i ] ); - } - } - - return ret; - }, - - // arg is for internal usage only - map: function( elems, callback, arg ) { - var value, key, ret = [], - i = 0, - length = elems.length, - // jquery objects are treated as arrays - isArray = elems instanceof jQuery || length !== undefined && typeof length === "number" && ( ( length > 0 && elems[ 0 ] && elems[ length -1 ] ) || length === 0 || jQuery.isArray( elems ) ) ; - - // Go through the array, translating each of the items to their - if ( isArray ) { - for ( ; i < length; i++ ) { - value = callback( elems[ i ], i, arg ); - - if ( value != null ) { - ret[ ret.length ] = value; - } - } - - // Go through every key on the object, - } else { - for ( key in elems ) { - value = callback( elems[ key ], key, arg ); - - if ( value != null ) { - ret[ ret.length ] = value; - } - } - } - - // Flatten any nested arrays - return ret.concat.apply( [], ret ); - }, - - // A global GUID counter for objects - guid: 1, - - // Bind a function to a context, optionally partially applying any - // arguments. - proxy: function( fn, context ) { - if ( typeof context === "string" ) { - var tmp = fn[ context ]; - context = fn; - fn = tmp; - } - - // Quick check to determine if target is callable, in the spec - // this throws a TypeError, but we will just return undefined. - if ( !jQuery.isFunction( fn ) ) { - return undefined; - } - - // Simulated bind - var args = slice.call( arguments, 2 ), - proxy = function() { - return fn.apply( context, args.concat( slice.call( arguments ) ) ); - }; - - // Set the guid of unique handler to the same of original handler, so it can be removed - proxy.guid = fn.guid = fn.guid || proxy.guid || jQuery.guid++; - - return proxy; - }, - - // Mutifunctional method to get and set values to a collection - // The value/s can optionally be executed if it's a function - access: function( elems, key, value, exec, fn, pass ) { - var length = elems.length; - - // Setting many attributes - if ( typeof key === "object" ) { - for ( var k in key ) { - jQuery.access( elems, k, key[k], exec, fn, value ); - } - return elems; - } - - // Setting one attribute - if ( value !== undefined ) { - // Optionally, function values get executed if exec is true - exec = !pass && exec && jQuery.isFunction(value); - - for ( var i = 0; i < length; i++ ) { - fn( elems[i], key, exec ? value.call( elems[i], i, fn( elems[i], key ) ) : value, pass ); - } - - return elems; - } - - // Getting an attribute - return length ? fn( elems[0], key ) : undefined; - }, - - now: function() { - return (new Date()).getTime(); - }, - - // Use of jQuery.browser is frowned upon. - // More details: http://docs.jquery.com/Utilities/jQuery.browser - uaMatch: function( ua ) { - ua = ua.toLowerCase(); - - var match = rwebkit.exec( ua ) || - ropera.exec( ua ) || - rmsie.exec( ua ) || - ua.indexOf("compatible") < 0 && rmozilla.exec( ua ) || - []; - - return { browser: match[1] || "", version: match[2] || "0" }; - }, - - sub: function() { - function jQuerySub( selector, context ) { - return new jQuerySub.fn.init( selector, context ); - } - jQuery.extend( true, jQuerySub, this ); - jQuerySub.superclass = this; - jQuerySub.fn = jQuerySub.prototype = this(); - jQuerySub.fn.constructor = jQuerySub; - jQuerySub.sub = this.sub; - jQuerySub.fn.init = function init( selector, context ) { - if ( context && context instanceof jQuery && !(context instanceof jQuerySub) ) { - context = jQuerySub( context ); - } - - return jQuery.fn.init.call( this, selector, context, rootjQuerySub ); - }; - jQuerySub.fn.init.prototype = jQuerySub.fn; - var rootjQuerySub = jQuerySub(document); - return jQuerySub; - }, - - browser: {} -}); - -// Populate the class2type map -jQuery.each("Boolean Number String Function Array Date RegExp Object".split(" "), function(i, name) { - class2type[ "[object " + name + "]" ] = name.toLowerCase(); -}); - -browserMatch = jQuery.uaMatch( userAgent ); -if ( browserMatch.browser ) { - jQuery.browser[ browserMatch.browser ] = true; - jQuery.browser.version = browserMatch.version; -} - -// Deprecated, use jQuery.browser.webkit instead -if ( jQuery.browser.webkit ) { - jQuery.browser.safari = true; -} - -// IE doesn't match non-breaking spaces with \s -if ( rnotwhite.test( "\xA0" ) ) { - trimLeft = /^[\s\xA0]+/; - trimRight = /[\s\xA0]+$/; -} - -// All jQuery objects should point back to these -rootjQuery = jQuery(document); - -// Cleanup functions for the document ready method -if ( document.addEventListener ) { - DOMContentLoaded = function() { - document.removeEventListener( "DOMContentLoaded", DOMContentLoaded, false ); - jQuery.ready(); - }; - -} else if ( document.attachEvent ) { - DOMContentLoaded = function() { - // Make sure body exists, at least, in case IE gets a little overzealous (ticket #5443). - if ( document.readyState === "complete" ) { - document.detachEvent( "onreadystatechange", DOMContentLoaded ); - jQuery.ready(); - } - }; -} - -// The DOM ready check for Internet Explorer -function doScrollCheck() { - if ( jQuery.isReady ) { - return; - } - - try { - // If IE is used, use the trick by Diego Perini - // http://javascript.nwbox.com/IEContentLoaded/ - document.documentElement.doScroll("left"); - } catch(e) { - setTimeout( doScrollCheck, 1 ); - return; - } - - // and execute any waiting functions - jQuery.ready(); -} - -return jQuery; - -})(); - - -var // Promise methods - promiseMethods = "done fail isResolved isRejected promise then always pipe".split( " " ), - // Static reference to slice - sliceDeferred = [].slice; - -jQuery.extend({ - // Create a simple deferred (one callbacks list) - _Deferred: function() { - var // callbacks list - callbacks = [], - // stored [ context , args ] - fired, - // to avoid firing when already doing so - firing, - // flag to know if the deferred has been cancelled - cancelled, - // the deferred itself - deferred = { - - // done( f1, f2, ...) - done: function() { - if ( !cancelled ) { - var args = arguments, - i, - length, - elem, - type, - _fired; - if ( fired ) { - _fired = fired; - fired = 0; - } - for ( i = 0, length = args.length; i < length; i++ ) { - elem = args[ i ]; - type = jQuery.type( elem ); - if ( type === "array" ) { - deferred.done.apply( deferred, elem ); - } else if ( type === "function" ) { - callbacks.push( elem ); - } - } - if ( _fired ) { - deferred.resolveWith( _fired[ 0 ], _fired[ 1 ] ); - } - } - return this; - }, - - // resolve with given context and args - resolveWith: function( context, args ) { - if ( !cancelled && !fired && !firing ) { - // make sure args are available (#8421) - args = args || []; - firing = 1; - try { - while( callbacks[ 0 ] ) { - callbacks.shift().apply( context, args ); - } - } - finally { - fired = [ context, args ]; - firing = 0; - } - } - return this; - }, - - // resolve with this as context and given arguments - resolve: function() { - deferred.resolveWith( this, arguments ); - return this; - }, - - // Has this deferred been resolved? - isResolved: function() { - return !!( firing || fired ); - }, - - // Cancel - cancel: function() { - cancelled = 1; - callbacks = []; - return this; - } - }; - - return deferred; - }, - - // Full fledged deferred (two callbacks list) - Deferred: function( func ) { - var deferred = jQuery._Deferred(), - failDeferred = jQuery._Deferred(), - promise; - // Add errorDeferred methods, then and promise - jQuery.extend( deferred, { - then: function( doneCallbacks, failCallbacks ) { - deferred.done( doneCallbacks ).fail( failCallbacks ); - return this; - }, - always: function() { - return deferred.done.apply( deferred, arguments ).fail.apply( this, arguments ); - }, - fail: failDeferred.done, - rejectWith: failDeferred.resolveWith, - reject: failDeferred.resolve, - isRejected: failDeferred.isResolved, - pipe: function( fnDone, fnFail ) { - return jQuery.Deferred(function( newDefer ) { - jQuery.each( { - done: [ fnDone, "resolve" ], - fail: [ fnFail, "reject" ] - }, function( handler, data ) { - var fn = data[ 0 ], - action = data[ 1 ], - returned; - if ( jQuery.isFunction( fn ) ) { - deferred[ handler ](function() { - returned = fn.apply( this, arguments ); - if ( returned && jQuery.isFunction( returned.promise ) ) { - returned.promise().then( newDefer.resolve, newDefer.reject ); - } else { - newDefer[ action ]( returned ); - } - }); - } else { - deferred[ handler ]( newDefer[ action ] ); - } - }); - }).promise(); - }, - // Get a promise for this deferred - // If obj is provided, the promise aspect is added to the object - promise: function( obj ) { - if ( obj == null ) { - if ( promise ) { - return promise; - } - promise = obj = {}; - } - var i = promiseMethods.length; - while( i-- ) { - obj[ promiseMethods[i] ] = deferred[ promiseMethods[i] ]; - } - return obj; - } - }); - // Make sure only one callback list will be used - deferred.done( failDeferred.cancel ).fail( deferred.cancel ); - // Unexpose cancel - delete deferred.cancel; - // Call given func if any - if ( func ) { - func.call( deferred, deferred ); - } - return deferred; - }, - - // Deferred helper - when: function( firstParam ) { - var args = arguments, - i = 0, - length = args.length, - count = length, - deferred = length <= 1 && firstParam && jQuery.isFunction( firstParam.promise ) ? - firstParam : - jQuery.Deferred(); - function resolveFunc( i ) { - return function( value ) { - args[ i ] = arguments.length > 1 ? sliceDeferred.call( arguments, 0 ) : value; - if ( !( --count ) ) { - // Strange bug in FF4: - // Values changed onto the arguments object sometimes end up as undefined values - // outside the $.when method. Cloning the object into a fresh array solves the issue - deferred.resolveWith( deferred, sliceDeferred.call( args, 0 ) ); - } - }; - } - if ( length > 1 ) { - for( ; i < length; i++ ) { - if ( args[ i ] && jQuery.isFunction( args[ i ].promise ) ) { - args[ i ].promise().then( resolveFunc(i), deferred.reject ); - } else { - --count; - } - } - if ( !count ) { - deferred.resolveWith( deferred, args ); - } - } else if ( deferred !== firstParam ) { - deferred.resolveWith( deferred, length ? [ firstParam ] : [] ); - } - return deferred.promise(); - } -}); - - - -jQuery.support = (function() { - - var div = document.createElement( "div" ), - documentElement = document.documentElement, - all, - a, - select, - opt, - input, - marginDiv, - support, - fragment, - body, - testElementParent, - testElement, - testElementStyle, - tds, - events, - eventName, - i, - isSupported; - - // Preliminary tests - div.setAttribute("className", "t"); - div.innerHTML = "
      a"; - - all = div.getElementsByTagName( "*" ); - a = div.getElementsByTagName( "a" )[ 0 ]; - - // Can't get basic test support - if ( !all || !all.length || !a ) { - return {}; - } - - // First batch of supports tests - select = document.createElement( "select" ); - opt = select.appendChild( document.createElement("option") ); - input = div.getElementsByTagName( "input" )[ 0 ]; - - support = { - // IE strips leading whitespace when .innerHTML is used - leadingWhitespace: ( div.firstChild.nodeType === 3 ), - - // Make sure that tbody elements aren't automatically inserted - // IE will insert them into empty tables - tbody: !div.getElementsByTagName( "tbody" ).length, - - // Make sure that link elements get serialized correctly by innerHTML - // This requires a wrapper element in IE - htmlSerialize: !!div.getElementsByTagName( "link" ).length, - - // Get the style information from getAttribute - // (IE uses .cssText instead) - style: /top/.test( a.getAttribute("style") ), - - // Make sure that URLs aren't manipulated - // (IE normalizes it by default) - hrefNormalized: ( a.getAttribute( "href" ) === "/a" ), - - // Make sure that element opacity exists - // (IE uses filter instead) - // Use a regex to work around a WebKit issue. See #5145 - opacity: /^0.55$/.test( a.style.opacity ), - - // Verify style float existence - // (IE uses styleFloat instead of cssFloat) - cssFloat: !!a.style.cssFloat, - - // Make sure that if no value is specified for a checkbox - // that it defaults to "on". - // (WebKit defaults to "" instead) - checkOn: ( input.value === "on" ), - - // Make sure that a selected-by-default option has a working selected property. - // (WebKit defaults to false instead of true, IE too, if it's in an optgroup) - optSelected: opt.selected, - - // Test setAttribute on camelCase class. If it works, we need attrFixes when doing get/setAttribute (ie6/7) - getSetAttribute: div.className !== "t", - - // Will be defined later - submitBubbles: true, - changeBubbles: true, - focusinBubbles: false, - deleteExpando: true, - noCloneEvent: true, - inlineBlockNeedsLayout: false, - shrinkWrapBlocks: false, - reliableMarginRight: true - }; - - // Make sure checked status is properly cloned - input.checked = true; - support.noCloneChecked = input.cloneNode( true ).checked; - - // Make sure that the options inside disabled selects aren't marked as disabled - // (WebKit marks them as disabled) - select.disabled = true; - support.optDisabled = !opt.disabled; - - // Test to see if it's possible to delete an expando from an element - // Fails in Internet Explorer - try { - delete div.test; - } catch( e ) { - support.deleteExpando = false; - } - - if ( !div.addEventListener && div.attachEvent && div.fireEvent ) { - div.attachEvent( "onclick", function() { - // Cloning a node shouldn't copy over any - // bound event handlers (IE does this) - support.noCloneEvent = false; - }); - div.cloneNode( true ).fireEvent( "onclick" ); - } - - // Check if a radio maintains it's value - // after being appended to the DOM - input = document.createElement("input"); - input.value = "t"; - input.setAttribute("type", "radio"); - support.radioValue = input.value === "t"; - - input.setAttribute("checked", "checked"); - div.appendChild( input ); - fragment = document.createDocumentFragment(); - fragment.appendChild( div.firstChild ); - - // WebKit doesn't clone checked state correctly in fragments - support.checkClone = fragment.cloneNode( true ).cloneNode( true ).lastChild.checked; - - div.innerHTML = ""; - - // Figure out if the W3C box model works as expected - div.style.width = div.style.paddingLeft = "1px"; - - body = document.getElementsByTagName( "body" )[ 0 ]; - // We use our own, invisible, body unless the body is already present - // in which case we use a div (#9239) - testElement = document.createElement( body ? "div" : "body" ); - testElementStyle = { - visibility: "hidden", - width: 0, - height: 0, - border: 0, - margin: 0 - }; - if ( body ) { - jQuery.extend( testElementStyle, { - position: "absolute", - left: -1000, - top: -1000 - }); - } - for ( i in testElementStyle ) { - testElement.style[ i ] = testElementStyle[ i ]; - } - testElement.appendChild( div ); - testElementParent = body || documentElement; - testElementParent.insertBefore( testElement, testElementParent.firstChild ); - - // Check if a disconnected checkbox will retain its checked - // value of true after appended to the DOM (IE6/7) - support.appendChecked = input.checked; - - support.boxModel = div.offsetWidth === 2; - - if ( "zoom" in div.style ) { - // Check if natively block-level elements act like inline-block - // elements when setting their display to 'inline' and giving - // them layout - // (IE < 8 does this) - div.style.display = "inline"; - div.style.zoom = 1; - support.inlineBlockNeedsLayout = ( div.offsetWidth === 2 ); - - // Check if elements with layout shrink-wrap their children - // (IE 6 does this) - div.style.display = ""; - div.innerHTML = "
      "; - support.shrinkWrapBlocks = ( div.offsetWidth !== 2 ); - } - - div.innerHTML = "
      t
      "; - tds = div.getElementsByTagName( "td" ); - - // Check if table cells still have offsetWidth/Height when they are set - // to display:none and there are still other visible table cells in a - // table row; if so, offsetWidth/Height are not reliable for use when - // determining if an element has been hidden directly using - // display:none (it is still safe to use offsets if a parent element is - // hidden; don safety goggles and see bug #4512 for more information). - // (only IE 8 fails this test) - isSupported = ( tds[ 0 ].offsetHeight === 0 ); - - tds[ 0 ].style.display = ""; - tds[ 1 ].style.display = "none"; - - // Check if empty table cells still have offsetWidth/Height - // (IE < 8 fail this test) - support.reliableHiddenOffsets = isSupported && ( tds[ 0 ].offsetHeight === 0 ); - div.innerHTML = ""; - - // Check if div with explicit width and no margin-right incorrectly - // gets computed margin-right based on width of container. For more - // info see bug #3333 - // Fails in WebKit before Feb 2011 nightlies - // WebKit Bug 13343 - getComputedStyle returns wrong value for margin-right - if ( document.defaultView && document.defaultView.getComputedStyle ) { - marginDiv = document.createElement( "div" ); - marginDiv.style.width = "0"; - marginDiv.style.marginRight = "0"; - div.appendChild( marginDiv ); - support.reliableMarginRight = - ( parseInt( ( document.defaultView.getComputedStyle( marginDiv, null ) || { marginRight: 0 } ).marginRight, 10 ) || 0 ) === 0; - } - - // Remove the body element we added - testElement.innerHTML = ""; - testElementParent.removeChild( testElement ); - - // Technique from Juriy Zaytsev - // http://thinkweb2.com/projects/prototype/detecting-event-support-without-browser-sniffing/ - // We only care about the case where non-standard event systems - // are used, namely in IE. Short-circuiting here helps us to - // avoid an eval call (in setAttribute) which can cause CSP - // to go haywire. See: https://developer.mozilla.org/en/Security/CSP - if ( div.attachEvent ) { - for( i in { - submit: 1, - change: 1, - focusin: 1 - } ) { - eventName = "on" + i; - isSupported = ( eventName in div ); - if ( !isSupported ) { - div.setAttribute( eventName, "return;" ); - isSupported = ( typeof div[ eventName ] === "function" ); - } - support[ i + "Bubbles" ] = isSupported; - } - } - - // Null connected elements to avoid leaks in IE - testElement = fragment = select = opt = body = marginDiv = div = input = null; - - return support; -})(); - -// Keep track of boxModel -jQuery.boxModel = jQuery.support.boxModel; - - - - -var rbrace = /^(?:\{.*\}|\[.*\])$/, - rmultiDash = /([a-z])([A-Z])/g; - -jQuery.extend({ - cache: {}, - - // Please use with caution - uuid: 0, - - // Unique for each copy of jQuery on the page - // Non-digits removed to match rinlinejQuery - expando: "jQuery" + ( jQuery.fn.jquery + Math.random() ).replace( /\D/g, "" ), - - // The following elements throw uncatchable exceptions if you - // attempt to add expando properties to them. - noData: { - "embed": true, - // Ban all objects except for Flash (which handle expandos) - "object": "clsid:D27CDB6E-AE6D-11cf-96B8-444553540000", - "applet": true - }, - - hasData: function( elem ) { - elem = elem.nodeType ? jQuery.cache[ elem[jQuery.expando] ] : elem[ jQuery.expando ]; - - return !!elem && !isEmptyDataObject( elem ); - }, - - data: function( elem, name, data, pvt /* Internal Use Only */ ) { - if ( !jQuery.acceptData( elem ) ) { - return; - } - - var internalKey = jQuery.expando, getByName = typeof name === "string", thisCache, - - // We have to handle DOM nodes and JS objects differently because IE6-7 - // can't GC object references properly across the DOM-JS boundary - isNode = elem.nodeType, - - // Only DOM nodes need the global jQuery cache; JS object data is - // attached directly to the object so GC can occur automatically - cache = isNode ? jQuery.cache : elem, - - // Only defining an ID for JS objects if its cache already exists allows - // the code to shortcut on the same path as a DOM node with no cache - id = isNode ? elem[ jQuery.expando ] : elem[ jQuery.expando ] && jQuery.expando; - - // Avoid doing any more work than we need to when trying to get data on an - // object that has no data at all - if ( (!id || (pvt && id && !cache[ id ][ internalKey ])) && getByName && data === undefined ) { - return; - } - - if ( !id ) { - // Only DOM nodes need a new unique ID for each element since their data - // ends up in the global cache - if ( isNode ) { - elem[ jQuery.expando ] = id = ++jQuery.uuid; - } else { - id = jQuery.expando; - } - } - - if ( !cache[ id ] ) { - cache[ id ] = {}; - - // TODO: This is a hack for 1.5 ONLY. Avoids exposing jQuery - // metadata on plain JS objects when the object is serialized using - // JSON.stringify - if ( !isNode ) { - cache[ id ].toJSON = jQuery.noop; - } - } - - // An object can be passed to jQuery.data instead of a key/value pair; this gets - // shallow copied over onto the existing cache - if ( typeof name === "object" || typeof name === "function" ) { - if ( pvt ) { - cache[ id ][ internalKey ] = jQuery.extend(cache[ id ][ internalKey ], name); - } else { - cache[ id ] = jQuery.extend(cache[ id ], name); - } - } - - thisCache = cache[ id ]; - - // Internal jQuery data is stored in a separate object inside the object's data - // cache in order to avoid key collisions between internal data and user-defined - // data - if ( pvt ) { - if ( !thisCache[ internalKey ] ) { - thisCache[ internalKey ] = {}; - } - - thisCache = thisCache[ internalKey ]; - } - - if ( data !== undefined ) { - thisCache[ jQuery.camelCase( name ) ] = data; - } - - // TODO: This is a hack for 1.5 ONLY. It will be removed in 1.6. Users should - // not attempt to inspect the internal events object using jQuery.data, as this - // internal data object is undocumented and subject to change. - if ( name === "events" && !thisCache[name] ) { - return thisCache[ internalKey ] && thisCache[ internalKey ].events; - } - - return getByName ? - // Check for both converted-to-camel and non-converted data property names - thisCache[ jQuery.camelCase( name ) ] || thisCache[ name ] : - thisCache; - }, - - removeData: function( elem, name, pvt /* Internal Use Only */ ) { - if ( !jQuery.acceptData( elem ) ) { - return; - } - - var internalKey = jQuery.expando, isNode = elem.nodeType, - - // See jQuery.data for more information - cache = isNode ? jQuery.cache : elem, - - // See jQuery.data for more information - id = isNode ? elem[ jQuery.expando ] : jQuery.expando; - - // If there is already no cache entry for this object, there is no - // purpose in continuing - if ( !cache[ id ] ) { - return; - } - - if ( name ) { - var thisCache = pvt ? cache[ id ][ internalKey ] : cache[ id ]; - - if ( thisCache ) { - delete thisCache[ name ]; - - // If there is no data left in the cache, we want to continue - // and let the cache object itself get destroyed - if ( !isEmptyDataObject(thisCache) ) { - return; - } - } - } - - // See jQuery.data for more information - if ( pvt ) { - delete cache[ id ][ internalKey ]; - - // Don't destroy the parent cache unless the internal data object - // had been the only thing left in it - if ( !isEmptyDataObject(cache[ id ]) ) { - return; - } - } - - var internalCache = cache[ id ][ internalKey ]; - - // Browsers that fail expando deletion also refuse to delete expandos on - // the window, but it will allow it on all other JS objects; other browsers - // don't care - if ( jQuery.support.deleteExpando || cache != window ) { - delete cache[ id ]; - } else { - cache[ id ] = null; - } - - // We destroyed the entire user cache at once because it's faster than - // iterating through each key, but we need to continue to persist internal - // data if it existed - if ( internalCache ) { - cache[ id ] = {}; - // TODO: This is a hack for 1.5 ONLY. Avoids exposing jQuery - // metadata on plain JS objects when the object is serialized using - // JSON.stringify - if ( !isNode ) { - cache[ id ].toJSON = jQuery.noop; - } - - cache[ id ][ internalKey ] = internalCache; - - // Otherwise, we need to eliminate the expando on the node to avoid - // false lookups in the cache for entries that no longer exist - } else if ( isNode ) { - // IE does not allow us to delete expando properties from nodes, - // nor does it have a removeAttribute function on Document nodes; - // we must handle all of these cases - if ( jQuery.support.deleteExpando ) { - delete elem[ jQuery.expando ]; - } else if ( elem.removeAttribute ) { - elem.removeAttribute( jQuery.expando ); - } else { - elem[ jQuery.expando ] = null; - } - } - }, - - // For internal use only. - _data: function( elem, name, data ) { - return jQuery.data( elem, name, data, true ); - }, - - // A method for determining if a DOM node can handle the data expando - acceptData: function( elem ) { - if ( elem.nodeName ) { - var match = jQuery.noData[ elem.nodeName.toLowerCase() ]; - - if ( match ) { - return !(match === true || elem.getAttribute("classid") !== match); - } - } - - return true; - } -}); - -jQuery.fn.extend({ - data: function( key, value ) { - var data = null; - - if ( typeof key === "undefined" ) { - if ( this.length ) { - data = jQuery.data( this[0] ); - - if ( this[0].nodeType === 1 ) { - var attr = this[0].attributes, name; - for ( var i = 0, l = attr.length; i < l; i++ ) { - name = attr[i].name; - - if ( name.indexOf( "data-" ) === 0 ) { - name = jQuery.camelCase( name.substring(5) ); - - dataAttr( this[0], name, data[ name ] ); - } - } - } - } - - return data; - - } else if ( typeof key === "object" ) { - return this.each(function() { - jQuery.data( this, key ); - }); - } - - var parts = key.split("."); - parts[1] = parts[1] ? "." + parts[1] : ""; - - if ( value === undefined ) { - data = this.triggerHandler("getData" + parts[1] + "!", [parts[0]]); - - // Try to fetch any internally stored data first - if ( data === undefined && this.length ) { - data = jQuery.data( this[0], key ); - data = dataAttr( this[0], key, data ); - } - - return data === undefined && parts[1] ? - this.data( parts[0] ) : - data; - - } else { - return this.each(function() { - var $this = jQuery( this ), - args = [ parts[0], value ]; - - $this.triggerHandler( "setData" + parts[1] + "!", args ); - jQuery.data( this, key, value ); - $this.triggerHandler( "changeData" + parts[1] + "!", args ); - }); - } - }, - - removeData: function( key ) { - return this.each(function() { - jQuery.removeData( this, key ); - }); - } -}); - -function dataAttr( elem, key, data ) { - // If nothing was found internally, try to fetch any - // data from the HTML5 data-* attribute - if ( data === undefined && elem.nodeType === 1 ) { - var name = "data-" + key.replace( rmultiDash, "$1-$2" ).toLowerCase(); - - data = elem.getAttribute( name ); - - if ( typeof data === "string" ) { - try { - data = data === "true" ? true : - data === "false" ? false : - data === "null" ? null : - !jQuery.isNaN( data ) ? parseFloat( data ) : - rbrace.test( data ) ? jQuery.parseJSON( data ) : - data; - } catch( e ) {} - - // Make sure we set the data so it isn't changed later - jQuery.data( elem, key, data ); - - } else { - data = undefined; - } - } - - return data; -} - -// TODO: This is a hack for 1.5 ONLY to allow objects with a single toJSON -// property to be considered empty objects; this property always exists in -// order to make sure JSON.stringify does not expose internal metadata -function isEmptyDataObject( obj ) { - for ( var name in obj ) { - if ( name !== "toJSON" ) { - return false; - } - } - - return true; -} - - - - -function handleQueueMarkDefer( elem, type, src ) { - var deferDataKey = type + "defer", - queueDataKey = type + "queue", - markDataKey = type + "mark", - defer = jQuery.data( elem, deferDataKey, undefined, true ); - if ( defer && - ( src === "queue" || !jQuery.data( elem, queueDataKey, undefined, true ) ) && - ( src === "mark" || !jQuery.data( elem, markDataKey, undefined, true ) ) ) { - // Give room for hard-coded callbacks to fire first - // and eventually mark/queue something else on the element - setTimeout( function() { - if ( !jQuery.data( elem, queueDataKey, undefined, true ) && - !jQuery.data( elem, markDataKey, undefined, true ) ) { - jQuery.removeData( elem, deferDataKey, true ); - defer.resolve(); - } - }, 0 ); - } -} - -jQuery.extend({ - - _mark: function( elem, type ) { - if ( elem ) { - type = (type || "fx") + "mark"; - jQuery.data( elem, type, (jQuery.data(elem,type,undefined,true) || 0) + 1, true ); - } - }, - - _unmark: function( force, elem, type ) { - if ( force !== true ) { - type = elem; - elem = force; - force = false; - } - if ( elem ) { - type = type || "fx"; - var key = type + "mark", - count = force ? 0 : ( (jQuery.data( elem, key, undefined, true) || 1 ) - 1 ); - if ( count ) { - jQuery.data( elem, key, count, true ); - } else { - jQuery.removeData( elem, key, true ); - handleQueueMarkDefer( elem, type, "mark" ); - } - } - }, - - queue: function( elem, type, data ) { - if ( elem ) { - type = (type || "fx") + "queue"; - var q = jQuery.data( elem, type, undefined, true ); - // Speed up dequeue by getting out quickly if this is just a lookup - if ( data ) { - if ( !q || jQuery.isArray(data) ) { - q = jQuery.data( elem, type, jQuery.makeArray(data), true ); - } else { - q.push( data ); - } - } - return q || []; - } - }, - - dequeue: function( elem, type ) { - type = type || "fx"; - - var queue = jQuery.queue( elem, type ), - fn = queue.shift(), - defer; - - // If the fx queue is dequeued, always remove the progress sentinel - if ( fn === "inprogress" ) { - fn = queue.shift(); - } - - if ( fn ) { - // Add a progress sentinel to prevent the fx queue from being - // automatically dequeued - if ( type === "fx" ) { - queue.unshift("inprogress"); - } - - fn.call(elem, function() { - jQuery.dequeue(elem, type); - }); - } - - if ( !queue.length ) { - jQuery.removeData( elem, type + "queue", true ); - handleQueueMarkDefer( elem, type, "queue" ); - } - } -}); - -jQuery.fn.extend({ - queue: function( type, data ) { - if ( typeof type !== "string" ) { - data = type; - type = "fx"; - } - - if ( data === undefined ) { - return jQuery.queue( this[0], type ); - } - return this.each(function() { - var queue = jQuery.queue( this, type, data ); - - if ( type === "fx" && queue[0] !== "inprogress" ) { - jQuery.dequeue( this, type ); - } - }); - }, - dequeue: function( type ) { - return this.each(function() { - jQuery.dequeue( this, type ); - }); - }, - // Based off of the plugin by Clint Helfers, with permission. - // http://blindsignals.com/index.php/2009/07/jquery-delay/ - delay: function( time, type ) { - time = jQuery.fx ? jQuery.fx.speeds[time] || time : time; - type = type || "fx"; - - return this.queue( type, function() { - var elem = this; - setTimeout(function() { - jQuery.dequeue( elem, type ); - }, time ); - }); - }, - clearQueue: function( type ) { - return this.queue( type || "fx", [] ); - }, - // Get a promise resolved when queues of a certain type - // are emptied (fx is the type by default) - promise: function( type, object ) { - if ( typeof type !== "string" ) { - object = type; - type = undefined; - } - type = type || "fx"; - var defer = jQuery.Deferred(), - elements = this, - i = elements.length, - count = 1, - deferDataKey = type + "defer", - queueDataKey = type + "queue", - markDataKey = type + "mark", - tmp; - function resolve() { - if ( !( --count ) ) { - defer.resolveWith( elements, [ elements ] ); - } - } - while( i-- ) { - if (( tmp = jQuery.data( elements[ i ], deferDataKey, undefined, true ) || - ( jQuery.data( elements[ i ], queueDataKey, undefined, true ) || - jQuery.data( elements[ i ], markDataKey, undefined, true ) ) && - jQuery.data( elements[ i ], deferDataKey, jQuery._Deferred(), true ) )) { - count++; - tmp.done( resolve ); - } - } - resolve(); - return defer.promise(); - } -}); - - - - -var rclass = /[\n\t\r]/g, - rspace = /\s+/, - rreturn = /\r/g, - rtype = /^(?:button|input)$/i, - rfocusable = /^(?:button|input|object|select|textarea)$/i, - rclickable = /^a(?:rea)?$/i, - rboolean = /^(?:autofocus|autoplay|async|checked|controls|defer|disabled|hidden|loop|multiple|open|readonly|required|scoped|selected)$/i, - rinvalidChar = /\:|^on/, - formHook, boolHook; - -jQuery.fn.extend({ - attr: function( name, value ) { - return jQuery.access( this, name, value, true, jQuery.attr ); - }, - - removeAttr: function( name ) { - return this.each(function() { - jQuery.removeAttr( this, name ); - }); - }, - - prop: function( name, value ) { - return jQuery.access( this, name, value, true, jQuery.prop ); - }, - - removeProp: function( name ) { - name = jQuery.propFix[ name ] || name; - return this.each(function() { - // try/catch handles cases where IE balks (such as removing a property on window) - try { - this[ name ] = undefined; - delete this[ name ]; - } catch( e ) {} - }); - }, - - addClass: function( value ) { - var classNames, i, l, elem, - setClass, c, cl; - - if ( jQuery.isFunction( value ) ) { - return this.each(function( j ) { - jQuery( this ).addClass( value.call(this, j, this.className) ); - }); - } - - if ( value && typeof value === "string" ) { - classNames = value.split( rspace ); - - for ( i = 0, l = this.length; i < l; i++ ) { - elem = this[ i ]; - - if ( elem.nodeType === 1 ) { - if ( !elem.className && classNames.length === 1 ) { - elem.className = value; - - } else { - setClass = " " + elem.className + " "; - - for ( c = 0, cl = classNames.length; c < cl; c++ ) { - if ( !~setClass.indexOf( " " + classNames[ c ] + " " ) ) { - setClass += classNames[ c ] + " "; - } - } - elem.className = jQuery.trim( setClass ); - } - } - } - } - - return this; - }, - - removeClass: function( value ) { - var classNames, i, l, elem, className, c, cl; - - if ( jQuery.isFunction( value ) ) { - return this.each(function( j ) { - jQuery( this ).removeClass( value.call(this, j, this.className) ); - }); - } - - if ( (value && typeof value === "string") || value === undefined ) { - classNames = (value || "").split( rspace ); - - for ( i = 0, l = this.length; i < l; i++ ) { - elem = this[ i ]; - - if ( elem.nodeType === 1 && elem.className ) { - if ( value ) { - className = (" " + elem.className + " ").replace( rclass, " " ); - for ( c = 0, cl = classNames.length; c < cl; c++ ) { - className = className.replace(" " + classNames[ c ] + " ", " "); - } - elem.className = jQuery.trim( className ); - - } else { - elem.className = ""; - } - } - } - } - - return this; - }, - - toggleClass: function( value, stateVal ) { - var type = typeof value, - isBool = typeof stateVal === "boolean"; - - if ( jQuery.isFunction( value ) ) { - return this.each(function( i ) { - jQuery( this ).toggleClass( value.call(this, i, this.className, stateVal), stateVal ); - }); - } - - return this.each(function() { - if ( type === "string" ) { - // toggle individual class names - var className, - i = 0, - self = jQuery( this ), - state = stateVal, - classNames = value.split( rspace ); - - while ( (className = classNames[ i++ ]) ) { - // check each className given, space seperated list - state = isBool ? state : !self.hasClass( className ); - self[ state ? "addClass" : "removeClass" ]( className ); - } - - } else if ( type === "undefined" || type === "boolean" ) { - if ( this.className ) { - // store className if set - jQuery._data( this, "__className__", this.className ); - } - - // toggle whole className - this.className = this.className || value === false ? "" : jQuery._data( this, "__className__" ) || ""; - } - }); - }, - - hasClass: function( selector ) { - var className = " " + selector + " "; - for ( var i = 0, l = this.length; i < l; i++ ) { - if ( (" " + this[i].className + " ").replace(rclass, " ").indexOf( className ) > -1 ) { - return true; - } - } - - return false; - }, - - val: function( value ) { - var hooks, ret, - elem = this[0]; - - if ( !arguments.length ) { - if ( elem ) { - hooks = jQuery.valHooks[ elem.nodeName.toLowerCase() ] || jQuery.valHooks[ elem.type ]; - - if ( hooks && "get" in hooks && (ret = hooks.get( elem, "value" )) !== undefined ) { - return ret; - } - - ret = elem.value; - - return typeof ret === "string" ? - // handle most common string cases - ret.replace(rreturn, "") : - // handle cases where value is null/undef or number - ret == null ? "" : ret; - } - - return undefined; - } - - var isFunction = jQuery.isFunction( value ); - - return this.each(function( i ) { - var self = jQuery(this), val; - - if ( this.nodeType !== 1 ) { - return; - } - - if ( isFunction ) { - val = value.call( this, i, self.val() ); - } else { - val = value; - } - - // Treat null/undefined as ""; convert numbers to string - if ( val == null ) { - val = ""; - } else if ( typeof val === "number" ) { - val += ""; - } else if ( jQuery.isArray( val ) ) { - val = jQuery.map(val, function ( value ) { - return value == null ? "" : value + ""; - }); - } - - hooks = jQuery.valHooks[ this.nodeName.toLowerCase() ] || jQuery.valHooks[ this.type ]; - - // If set returns undefined, fall back to normal setting - if ( !hooks || !("set" in hooks) || hooks.set( this, val, "value" ) === undefined ) { - this.value = val; - } - }); - } -}); - -jQuery.extend({ - valHooks: { - option: { - get: function( elem ) { - // attributes.value is undefined in Blackberry 4.7 but - // uses .value. See #6932 - var val = elem.attributes.value; - return !val || val.specified ? elem.value : elem.text; - } - }, - select: { - get: function( elem ) { - var value, - index = elem.selectedIndex, - values = [], - options = elem.options, - one = elem.type === "select-one"; - - // Nothing was selected - if ( index < 0 ) { - return null; - } - - // Loop through all the selected options - for ( var i = one ? index : 0, max = one ? index + 1 : options.length; i < max; i++ ) { - var option = options[ i ]; - - // Don't return options that are disabled or in a disabled optgroup - if ( option.selected && (jQuery.support.optDisabled ? !option.disabled : option.getAttribute("disabled") === null) && - (!option.parentNode.disabled || !jQuery.nodeName( option.parentNode, "optgroup" )) ) { - - // Get the specific value for the option - value = jQuery( option ).val(); - - // We don't need an array for one selects - if ( one ) { - return value; - } - - // Multi-Selects return an array - values.push( value ); - } - } - - // Fixes Bug #2551 -- select.val() broken in IE after form.reset() - if ( one && !values.length && options.length ) { - return jQuery( options[ index ] ).val(); - } - - return values; - }, - - set: function( elem, value ) { - var values = jQuery.makeArray( value ); - - jQuery(elem).find("option").each(function() { - this.selected = jQuery.inArray( jQuery(this).val(), values ) >= 0; - }); - - if ( !values.length ) { - elem.selectedIndex = -1; - } - return values; - } - } - }, - - attrFn: { - val: true, - css: true, - html: true, - text: true, - data: true, - width: true, - height: true, - offset: true - }, - - attrFix: { - // Always normalize to ensure hook usage - tabindex: "tabIndex" - }, - - attr: function( elem, name, value, pass ) { - var nType = elem.nodeType; - - // don't get/set attributes on text, comment and attribute nodes - if ( !elem || nType === 3 || nType === 8 || nType === 2 ) { - return undefined; - } - - if ( pass && name in jQuery.attrFn ) { - return jQuery( elem )[ name ]( value ); - } - - // Fallback to prop when attributes are not supported - if ( !("getAttribute" in elem) ) { - return jQuery.prop( elem, name, value ); - } - - var ret, hooks, - notxml = nType !== 1 || !jQuery.isXMLDoc( elem ); - - // Normalize the name if needed - if ( notxml ) { - name = jQuery.attrFix[ name ] || name; - - hooks = jQuery.attrHooks[ name ]; - - if ( !hooks ) { - // Use boolHook for boolean attributes - if ( rboolean.test( name ) ) { - - hooks = boolHook; - - // Use formHook for forms and if the name contains certain characters - } else if ( formHook && name !== "className" && - (jQuery.nodeName( elem, "form" ) || rinvalidChar.test( name )) ) { - - hooks = formHook; - } - } - } - - if ( value !== undefined ) { - - if ( value === null ) { - jQuery.removeAttr( elem, name ); - return undefined; - - } else if ( hooks && "set" in hooks && notxml && (ret = hooks.set( elem, value, name )) !== undefined ) { - return ret; - - } else { - elem.setAttribute( name, "" + value ); - return value; - } - - } else if ( hooks && "get" in hooks && notxml && (ret = hooks.get( elem, name )) !== null ) { - return ret; - - } else { - - ret = elem.getAttribute( name ); - - // Non-existent attributes return null, we normalize to undefined - return ret === null ? - undefined : - ret; - } - }, - - removeAttr: function( elem, name ) { - var propName; - if ( elem.nodeType === 1 ) { - name = jQuery.attrFix[ name ] || name; - - if ( jQuery.support.getSetAttribute ) { - // Use removeAttribute in browsers that support it - elem.removeAttribute( name ); - } else { - jQuery.attr( elem, name, "" ); - elem.removeAttributeNode( elem.getAttributeNode( name ) ); - } - - // Set corresponding property to false for boolean attributes - if ( rboolean.test( name ) && (propName = jQuery.propFix[ name ] || name) in elem ) { - elem[ propName ] = false; - } - } - }, - - attrHooks: { - type: { - set: function( elem, value ) { - // We can't allow the type property to be changed (since it causes problems in IE) - if ( rtype.test( elem.nodeName ) && elem.parentNode ) { - jQuery.error( "type property can't be changed" ); - } else if ( !jQuery.support.radioValue && value === "radio" && jQuery.nodeName(elem, "input") ) { - // Setting the type on a radio button after the value resets the value in IE6-9 - // Reset value to it's default in case type is set after value - // This is for element creation - var val = elem.value; - elem.setAttribute( "type", value ); - if ( val ) { - elem.value = val; - } - return value; - } - } - }, - tabIndex: { - get: function( elem ) { - // elem.tabIndex doesn't always return the correct value when it hasn't been explicitly set - // http://fluidproject.org/blog/2008/01/09/getting-setting-and-removing-tabindex-values-with-javascript/ - var attributeNode = elem.getAttributeNode("tabIndex"); - - return attributeNode && attributeNode.specified ? - parseInt( attributeNode.value, 10 ) : - rfocusable.test( elem.nodeName ) || rclickable.test( elem.nodeName ) && elem.href ? - 0 : - undefined; - } - }, - // Use the value property for back compat - // Use the formHook for button elements in IE6/7 (#1954) - value: { - get: function( elem, name ) { - if ( formHook && jQuery.nodeName( elem, "button" ) ) { - return formHook.get( elem, name ); - } - return name in elem ? - elem.value : - null; - }, - set: function( elem, value, name ) { - if ( formHook && jQuery.nodeName( elem, "button" ) ) { - return formHook.set( elem, value, name ); - } - // Does not return so that setAttribute is also used - elem.value = value; - } - } - }, - - propFix: { - tabindex: "tabIndex", - readonly: "readOnly", - "for": "htmlFor", - "class": "className", - maxlength: "maxLength", - cellspacing: "cellSpacing", - cellpadding: "cellPadding", - rowspan: "rowSpan", - colspan: "colSpan", - usemap: "useMap", - frameborder: "frameBorder", - contenteditable: "contentEditable" - }, - - prop: function( elem, name, value ) { - var nType = elem.nodeType; - - // don't get/set properties on text, comment and attribute nodes - if ( !elem || nType === 3 || nType === 8 || nType === 2 ) { - return undefined; - } - - var ret, hooks, - notxml = nType !== 1 || !jQuery.isXMLDoc( elem ); - - if ( notxml ) { - // Fix name and attach hooks - name = jQuery.propFix[ name ] || name; - hooks = jQuery.propHooks[ name ]; - } - - if ( value !== undefined ) { - if ( hooks && "set" in hooks && (ret = hooks.set( elem, value, name )) !== undefined ) { - return ret; - - } else { - return (elem[ name ] = value); - } - - } else { - if ( hooks && "get" in hooks && (ret = hooks.get( elem, name )) !== undefined ) { - return ret; - - } else { - return elem[ name ]; - } - } - }, - - propHooks: {} -}); - -// Hook for boolean attributes -boolHook = { - get: function( elem, name ) { - // Align boolean attributes with corresponding properties - return jQuery.prop( elem, name ) ? - name.toLowerCase() : - undefined; - }, - set: function( elem, value, name ) { - var propName; - if ( value === false ) { - // Remove boolean attributes when set to false - jQuery.removeAttr( elem, name ); - } else { - // value is true since we know at this point it's type boolean and not false - // Set boolean attributes to the same name and set the DOM property - propName = jQuery.propFix[ name ] || name; - if ( propName in elem ) { - // Only set the IDL specifically if it already exists on the element - elem[ propName ] = true; - } - - elem.setAttribute( name, name.toLowerCase() ); - } - return name; - } -}; - -// IE6/7 do not support getting/setting some attributes with get/setAttribute -if ( !jQuery.support.getSetAttribute ) { - - // propFix is more comprehensive and contains all fixes - jQuery.attrFix = jQuery.propFix; - - // Use this for any attribute on a form in IE6/7 - formHook = jQuery.attrHooks.name = jQuery.attrHooks.title = jQuery.valHooks.button = { - get: function( elem, name ) { - var ret; - ret = elem.getAttributeNode( name ); - // Return undefined if nodeValue is empty string - return ret && ret.nodeValue !== "" ? - ret.nodeValue : - undefined; - }, - set: function( elem, value, name ) { - // Check form objects in IE (multiple bugs related) - // Only use nodeValue if the attribute node exists on the form - var ret = elem.getAttributeNode( name ); - if ( ret ) { - ret.nodeValue = value; - return value; - } - } - }; - - // Set width and height to auto instead of 0 on empty string( Bug #8150 ) - // This is for removals - jQuery.each([ "width", "height" ], function( i, name ) { - jQuery.attrHooks[ name ] = jQuery.extend( jQuery.attrHooks[ name ], { - set: function( elem, value ) { - if ( value === "" ) { - elem.setAttribute( name, "auto" ); - return value; - } - } - }); - }); -} - - -// Some attributes require a special call on IE -if ( !jQuery.support.hrefNormalized ) { - jQuery.each([ "href", "src", "width", "height" ], function( i, name ) { - jQuery.attrHooks[ name ] = jQuery.extend( jQuery.attrHooks[ name ], { - get: function( elem ) { - var ret = elem.getAttribute( name, 2 ); - return ret === null ? undefined : ret; - } - }); - }); -} - -if ( !jQuery.support.style ) { - jQuery.attrHooks.style = { - get: function( elem ) { - // Return undefined in the case of empty string - // Normalize to lowercase since IE uppercases css property names - return elem.style.cssText.toLowerCase() || undefined; - }, - set: function( elem, value ) { - return (elem.style.cssText = "" + value); - } - }; -} - -// Safari mis-reports the default selected property of an option -// Accessing the parent's selectedIndex property fixes it -if ( !jQuery.support.optSelected ) { - jQuery.propHooks.selected = jQuery.extend( jQuery.propHooks.selected, { - get: function( elem ) { - var parent = elem.parentNode; - - if ( parent ) { - parent.selectedIndex; - - // Make sure that it also works with optgroups, see #5701 - if ( parent.parentNode ) { - parent.parentNode.selectedIndex; - } - } - } - }); -} - -// Radios and checkboxes getter/setter -if ( !jQuery.support.checkOn ) { - jQuery.each([ "radio", "checkbox" ], function() { - jQuery.valHooks[ this ] = { - get: function( elem ) { - // Handle the case where in Webkit "" is returned instead of "on" if a value isn't specified - return elem.getAttribute("value") === null ? "on" : elem.value; - } - }; - }); -} -jQuery.each([ "radio", "checkbox" ], function() { - jQuery.valHooks[ this ] = jQuery.extend( jQuery.valHooks[ this ], { - set: function( elem, value ) { - if ( jQuery.isArray( value ) ) { - return (elem.checked = jQuery.inArray( jQuery(elem).val(), value ) >= 0); - } - } - }); -}); - - - - -var rnamespaces = /\.(.*)$/, - rformElems = /^(?:textarea|input|select)$/i, - rperiod = /\./g, - rspaces = / /g, - rescape = /[^\w\s.|`]/g, - fcleanup = function( nm ) { - return nm.replace(rescape, "\\$&"); - }; - -/* - * A number of helper functions used for managing events. - * Many of the ideas behind this code originated from - * Dean Edwards' addEvent library. - */ -jQuery.event = { - - // Bind an event to an element - // Original by Dean Edwards - add: function( elem, types, handler, data ) { - if ( elem.nodeType === 3 || elem.nodeType === 8 ) { - return; - } - - if ( handler === false ) { - handler = returnFalse; - } else if ( !handler ) { - // Fixes bug #7229. Fix recommended by jdalton - return; - } - - var handleObjIn, handleObj; - - if ( handler.handler ) { - handleObjIn = handler; - handler = handleObjIn.handler; - } - - // Make sure that the function being executed has a unique ID - if ( !handler.guid ) { - handler.guid = jQuery.guid++; - } - - // Init the element's event structure - var elemData = jQuery._data( elem ); - - // If no elemData is found then we must be trying to bind to one of the - // banned noData elements - if ( !elemData ) { - return; - } - - var events = elemData.events, - eventHandle = elemData.handle; - - if ( !events ) { - elemData.events = events = {}; - } - - if ( !eventHandle ) { - elemData.handle = eventHandle = function( e ) { - // Discard the second event of a jQuery.event.trigger() and - // when an event is called after a page has unloaded - return typeof jQuery !== "undefined" && (!e || jQuery.event.triggered !== e.type) ? - jQuery.event.handle.apply( eventHandle.elem, arguments ) : - undefined; - }; - } - - // Add elem as a property of the handle function - // This is to prevent a memory leak with non-native events in IE. - eventHandle.elem = elem; - - // Handle multiple events separated by a space - // jQuery(...).bind("mouseover mouseout", fn); - types = types.split(" "); - - var type, i = 0, namespaces; - - while ( (type = types[ i++ ]) ) { - handleObj = handleObjIn ? - jQuery.extend({}, handleObjIn) : - { handler: handler, data: data }; - - // Namespaced event handlers - if ( type.indexOf(".") > -1 ) { - namespaces = type.split("."); - type = namespaces.shift(); - handleObj.namespace = namespaces.slice(0).sort().join("."); - - } else { - namespaces = []; - handleObj.namespace = ""; - } - - handleObj.type = type; - if ( !handleObj.guid ) { - handleObj.guid = handler.guid; - } - - // Get the current list of functions bound to this event - var handlers = events[ type ], - special = jQuery.event.special[ type ] || {}; - - // Init the event handler queue - if ( !handlers ) { - handlers = events[ type ] = []; - - // Check for a special event handler - // Only use addEventListener/attachEvent if the special - // events handler returns false - if ( !special.setup || special.setup.call( elem, data, namespaces, eventHandle ) === false ) { - // Bind the global event handler to the element - if ( elem.addEventListener ) { - elem.addEventListener( type, eventHandle, false ); - - } else if ( elem.attachEvent ) { - elem.attachEvent( "on" + type, eventHandle ); - } - } - } - - if ( special.add ) { - special.add.call( elem, handleObj ); - - if ( !handleObj.handler.guid ) { - handleObj.handler.guid = handler.guid; - } - } - - // Add the function to the element's handler list - handlers.push( handleObj ); - - // Keep track of which events have been used, for event optimization - jQuery.event.global[ type ] = true; - } - - // Nullify elem to prevent memory leaks in IE - elem = null; - }, - - global: {}, - - // Detach an event or set of events from an element - remove: function( elem, types, handler, pos ) { - // don't do events on text and comment nodes - if ( elem.nodeType === 3 || elem.nodeType === 8 ) { - return; - } - - if ( handler === false ) { - handler = returnFalse; - } - - var ret, type, fn, j, i = 0, all, namespaces, namespace, special, eventType, handleObj, origType, - elemData = jQuery.hasData( elem ) && jQuery._data( elem ), - events = elemData && elemData.events; - - if ( !elemData || !events ) { - return; - } - - // types is actually an event object here - if ( types && types.type ) { - handler = types.handler; - types = types.type; - } - - // Unbind all events for the element - if ( !types || typeof types === "string" && types.charAt(0) === "." ) { - types = types || ""; - - for ( type in events ) { - jQuery.event.remove( elem, type + types ); - } - - return; - } - - // Handle multiple events separated by a space - // jQuery(...).unbind("mouseover mouseout", fn); - types = types.split(" "); - - while ( (type = types[ i++ ]) ) { - origType = type; - handleObj = null; - all = type.indexOf(".") < 0; - namespaces = []; - - if ( !all ) { - // Namespaced event handlers - namespaces = type.split("."); - type = namespaces.shift(); - - namespace = new RegExp("(^|\\.)" + - jQuery.map( namespaces.slice(0).sort(), fcleanup ).join("\\.(?:.*\\.)?") + "(\\.|$)"); - } - - eventType = events[ type ]; - - if ( !eventType ) { - continue; - } - - if ( !handler ) { - for ( j = 0; j < eventType.length; j++ ) { - handleObj = eventType[ j ]; - - if ( all || namespace.test( handleObj.namespace ) ) { - jQuery.event.remove( elem, origType, handleObj.handler, j ); - eventType.splice( j--, 1 ); - } - } - - continue; - } - - special = jQuery.event.special[ type ] || {}; - - for ( j = pos || 0; j < eventType.length; j++ ) { - handleObj = eventType[ j ]; - - if ( handler.guid === handleObj.guid ) { - // remove the given handler for the given type - if ( all || namespace.test( handleObj.namespace ) ) { - if ( pos == null ) { - eventType.splice( j--, 1 ); - } - - if ( special.remove ) { - special.remove.call( elem, handleObj ); - } - } - - if ( pos != null ) { - break; - } - } - } - - // remove generic event handler if no more handlers exist - if ( eventType.length === 0 || pos != null && eventType.length === 1 ) { - if ( !special.teardown || special.teardown.call( elem, namespaces ) === false ) { - jQuery.removeEvent( elem, type, elemData.handle ); - } - - ret = null; - delete events[ type ]; - } - } - - // Remove the expando if it's no longer used - if ( jQuery.isEmptyObject( events ) ) { - var handle = elemData.handle; - if ( handle ) { - handle.elem = null; - } - - delete elemData.events; - delete elemData.handle; - - if ( jQuery.isEmptyObject( elemData ) ) { - jQuery.removeData( elem, undefined, true ); - } - } - }, - - // Events that are safe to short-circuit if no handlers are attached. - // Native DOM events should not be added, they may have inline handlers. - customEvent: { - "getData": true, - "setData": true, - "changeData": true - }, - - trigger: function( event, data, elem, onlyHandlers ) { - // Event object or event type - var type = event.type || event, - namespaces = [], - exclusive; - - if ( type.indexOf("!") >= 0 ) { - // Exclusive events trigger only for the exact event (no namespaces) - type = type.slice(0, -1); - exclusive = true; - } - - if ( type.indexOf(".") >= 0 ) { - // Namespaced trigger; create a regexp to match event type in handle() - namespaces = type.split("."); - type = namespaces.shift(); - namespaces.sort(); - } - - if ( (!elem || jQuery.event.customEvent[ type ]) && !jQuery.event.global[ type ] ) { - // No jQuery handlers for this event type, and it can't have inline handlers - return; - } - - // Caller can pass in an Event, Object, or just an event type string - event = typeof event === "object" ? - // jQuery.Event object - event[ jQuery.expando ] ? event : - // Object literal - new jQuery.Event( type, event ) : - // Just the event type (string) - new jQuery.Event( type ); - - event.type = type; - event.exclusive = exclusive; - event.namespace = namespaces.join("."); - event.namespace_re = new RegExp("(^|\\.)" + namespaces.join("\\.(?:.*\\.)?") + "(\\.|$)"); - - // triggerHandler() and global events don't bubble or run the default action - if ( onlyHandlers || !elem ) { - event.preventDefault(); - event.stopPropagation(); - } - - // Handle a global trigger - if ( !elem ) { - // TODO: Stop taunting the data cache; remove global events and always attach to document - jQuery.each( jQuery.cache, function() { - // internalKey variable is just used to make it easier to find - // and potentially change this stuff later; currently it just - // points to jQuery.expando - var internalKey = jQuery.expando, - internalCache = this[ internalKey ]; - if ( internalCache && internalCache.events && internalCache.events[ type ] ) { - jQuery.event.trigger( event, data, internalCache.handle.elem ); - } - }); - return; - } - - // Don't do events on text and comment nodes - if ( elem.nodeType === 3 || elem.nodeType === 8 ) { - return; - } - - // Clean up the event in case it is being reused - event.result = undefined; - event.target = elem; - - // Clone any incoming data and prepend the event, creating the handler arg list - data = data != null ? jQuery.makeArray( data ) : []; - data.unshift( event ); - - var cur = elem, - // IE doesn't like method names with a colon (#3533, #8272) - ontype = type.indexOf(":") < 0 ? "on" + type : ""; - - // Fire event on the current element, then bubble up the DOM tree - do { - var handle = jQuery._data( cur, "handle" ); - - event.currentTarget = cur; - if ( handle ) { - handle.apply( cur, data ); - } - - // Trigger an inline bound script - if ( ontype && jQuery.acceptData( cur ) && cur[ ontype ] && cur[ ontype ].apply( cur, data ) === false ) { - event.result = false; - event.preventDefault(); - } - - // Bubble up to document, then to window - cur = cur.parentNode || cur.ownerDocument || cur === event.target.ownerDocument && window; - } while ( cur && !event.isPropagationStopped() ); - - // If nobody prevented the default action, do it now - if ( !event.isDefaultPrevented() ) { - var old, - special = jQuery.event.special[ type ] || {}; - - if ( (!special._default || special._default.call( elem.ownerDocument, event ) === false) && - !(type === "click" && jQuery.nodeName( elem, "a" )) && jQuery.acceptData( elem ) ) { - - // Call a native DOM method on the target with the same name name as the event. - // Can't use an .isFunction)() check here because IE6/7 fails that test. - // IE<9 dies on focus to hidden element (#1486), may want to revisit a try/catch. - try { - if ( ontype && elem[ type ] ) { - // Don't re-trigger an onFOO event when we call its FOO() method - old = elem[ ontype ]; - - if ( old ) { - elem[ ontype ] = null; - } - - jQuery.event.triggered = type; - elem[ type ](); - } - } catch ( ieError ) {} - - if ( old ) { - elem[ ontype ] = old; - } - - jQuery.event.triggered = undefined; - } - } - - return event.result; - }, - - handle: function( event ) { - event = jQuery.event.fix( event || window.event ); - // Snapshot the handlers list since a called handler may add/remove events. - var handlers = ((jQuery._data( this, "events" ) || {})[ event.type ] || []).slice(0), - run_all = !event.exclusive && !event.namespace, - args = Array.prototype.slice.call( arguments, 0 ); - - // Use the fix-ed Event rather than the (read-only) native event - args[0] = event; - event.currentTarget = this; - - for ( var j = 0, l = handlers.length; j < l; j++ ) { - var handleObj = handlers[ j ]; - - // Triggered event must 1) be non-exclusive and have no namespace, or - // 2) have namespace(s) a subset or equal to those in the bound event. - if ( run_all || event.namespace_re.test( handleObj.namespace ) ) { - // Pass in a reference to the handler function itself - // So that we can later remove it - event.handler = handleObj.handler; - event.data = handleObj.data; - event.handleObj = handleObj; - - var ret = handleObj.handler.apply( this, args ); - - if ( ret !== undefined ) { - event.result = ret; - if ( ret === false ) { - event.preventDefault(); - event.stopPropagation(); - } - } - - if ( event.isImmediatePropagationStopped() ) { - break; - } - } - } - return event.result; - }, - - props: "altKey attrChange attrName bubbles button cancelable charCode clientX clientY ctrlKey currentTarget data detail eventPhase fromElement handler keyCode layerX layerY metaKey newValue offsetX offsetY pageX pageY prevValue relatedNode relatedTarget screenX screenY shiftKey srcElement target toElement view wheelDelta which".split(" "), - - fix: function( event ) { - if ( event[ jQuery.expando ] ) { - return event; - } - - // store a copy of the original event object - // and "clone" to set read-only properties - var originalEvent = event; - event = jQuery.Event( originalEvent ); - - for ( var i = this.props.length, prop; i; ) { - prop = this.props[ --i ]; - event[ prop ] = originalEvent[ prop ]; - } - - // Fix target property, if necessary - if ( !event.target ) { - // Fixes #1925 where srcElement might not be defined either - event.target = event.srcElement || document; - } - - // check if target is a textnode (safari) - if ( event.target.nodeType === 3 ) { - event.target = event.target.parentNode; - } - - // Add relatedTarget, if necessary - if ( !event.relatedTarget && event.fromElement ) { - event.relatedTarget = event.fromElement === event.target ? event.toElement : event.fromElement; - } - - // Calculate pageX/Y if missing and clientX/Y available - if ( event.pageX == null && event.clientX != null ) { - var eventDocument = event.target.ownerDocument || document, - doc = eventDocument.documentElement, - body = eventDocument.body; - - event.pageX = event.clientX + (doc && doc.scrollLeft || body && body.scrollLeft || 0) - (doc && doc.clientLeft || body && body.clientLeft || 0); - event.pageY = event.clientY + (doc && doc.scrollTop || body && body.scrollTop || 0) - (doc && doc.clientTop || body && body.clientTop || 0); - } - - // Add which for key events - if ( event.which == null && (event.charCode != null || event.keyCode != null) ) { - event.which = event.charCode != null ? event.charCode : event.keyCode; - } - - // Add metaKey to non-Mac browsers (use ctrl for PC's and Meta for Macs) - if ( !event.metaKey && event.ctrlKey ) { - event.metaKey = event.ctrlKey; - } - - // Add which for click: 1 === left; 2 === middle; 3 === right - // Note: button is not normalized, so don't use it - if ( !event.which && event.button !== undefined ) { - event.which = (event.button & 1 ? 1 : ( event.button & 2 ? 3 : ( event.button & 4 ? 2 : 0 ) )); - } - - return event; - }, - - // Deprecated, use jQuery.guid instead - guid: 1E8, - - // Deprecated, use jQuery.proxy instead - proxy: jQuery.proxy, - - special: { - ready: { - // Make sure the ready event is setup - setup: jQuery.bindReady, - teardown: jQuery.noop - }, - - live: { - add: function( handleObj ) { - jQuery.event.add( this, - liveConvert( handleObj.origType, handleObj.selector ), - jQuery.extend({}, handleObj, {handler: liveHandler, guid: handleObj.handler.guid}) ); - }, - - remove: function( handleObj ) { - jQuery.event.remove( this, liveConvert( handleObj.origType, handleObj.selector ), handleObj ); - } - }, - - beforeunload: { - setup: function( data, namespaces, eventHandle ) { - // We only want to do this special case on windows - if ( jQuery.isWindow( this ) ) { - this.onbeforeunload = eventHandle; - } - }, - - teardown: function( namespaces, eventHandle ) { - if ( this.onbeforeunload === eventHandle ) { - this.onbeforeunload = null; - } - } - } - } -}; - -jQuery.removeEvent = document.removeEventListener ? - function( elem, type, handle ) { - if ( elem.removeEventListener ) { - elem.removeEventListener( type, handle, false ); - } - } : - function( elem, type, handle ) { - if ( elem.detachEvent ) { - elem.detachEvent( "on" + type, handle ); - } - }; - -jQuery.Event = function( src, props ) { - // Allow instantiation without the 'new' keyword - if ( !this.preventDefault ) { - return new jQuery.Event( src, props ); - } - - // Event object - if ( src && src.type ) { - this.originalEvent = src; - this.type = src.type; - - // Events bubbling up the document may have been marked as prevented - // by a handler lower down the tree; reflect the correct value. - this.isDefaultPrevented = (src.defaultPrevented || src.returnValue === false || - src.getPreventDefault && src.getPreventDefault()) ? returnTrue : returnFalse; - - // Event type - } else { - this.type = src; - } - - // Put explicitly provided properties onto the event object - if ( props ) { - jQuery.extend( this, props ); - } - - // timeStamp is buggy for some events on Firefox(#3843) - // So we won't rely on the native value - this.timeStamp = jQuery.now(); - - // Mark it as fixed - this[ jQuery.expando ] = true; -}; - -function returnFalse() { - return false; -} -function returnTrue() { - return true; -} - -// jQuery.Event is based on DOM3 Events as specified by the ECMAScript Language Binding -// http://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html -jQuery.Event.prototype = { - preventDefault: function() { - this.isDefaultPrevented = returnTrue; - - var e = this.originalEvent; - if ( !e ) { - return; - } - - // if preventDefault exists run it on the original event - if ( e.preventDefault ) { - e.preventDefault(); - - // otherwise set the returnValue property of the original event to false (IE) - } else { - e.returnValue = false; - } - }, - stopPropagation: function() { - this.isPropagationStopped = returnTrue; - - var e = this.originalEvent; - if ( !e ) { - return; - } - // if stopPropagation exists run it on the original event - if ( e.stopPropagation ) { - e.stopPropagation(); - } - // otherwise set the cancelBubble property of the original event to true (IE) - e.cancelBubble = true; - }, - stopImmediatePropagation: function() { - this.isImmediatePropagationStopped = returnTrue; - this.stopPropagation(); - }, - isDefaultPrevented: returnFalse, - isPropagationStopped: returnFalse, - isImmediatePropagationStopped: returnFalse -}; - -// Checks if an event happened on an element within another element -// Used in jQuery.event.special.mouseenter and mouseleave handlers -var withinElement = function( event ) { - - // Check if mouse(over|out) are still within the same parent element - var related = event.relatedTarget, - inside = false, - eventType = event.type; - - event.type = event.data; - - if ( related !== this ) { - - if ( related ) { - inside = jQuery.contains( this, related ); - } - - if ( !inside ) { - - jQuery.event.handle.apply( this, arguments ); - - event.type = eventType; - } - } -}, - -// In case of event delegation, we only need to rename the event.type, -// liveHandler will take care of the rest. -delegate = function( event ) { - event.type = event.data; - jQuery.event.handle.apply( this, arguments ); -}; - -// Create mouseenter and mouseleave events -jQuery.each({ - mouseenter: "mouseover", - mouseleave: "mouseout" -}, function( orig, fix ) { - jQuery.event.special[ orig ] = { - setup: function( data ) { - jQuery.event.add( this, fix, data && data.selector ? delegate : withinElement, orig ); - }, - teardown: function( data ) { - jQuery.event.remove( this, fix, data && data.selector ? delegate : withinElement ); - } - }; -}); - -// submit delegation -if ( !jQuery.support.submitBubbles ) { - - jQuery.event.special.submit = { - setup: function( data, namespaces ) { - if ( !jQuery.nodeName( this, "form" ) ) { - jQuery.event.add(this, "click.specialSubmit", function( e ) { - var elem = e.target, - type = elem.type; - - if ( (type === "submit" || type === "image") && jQuery( elem ).closest("form").length ) { - trigger( "submit", this, arguments ); - } - }); - - jQuery.event.add(this, "keypress.specialSubmit", function( e ) { - var elem = e.target, - type = elem.type; - - if ( (type === "text" || type === "password") && jQuery( elem ).closest("form").length && e.keyCode === 13 ) { - trigger( "submit", this, arguments ); - } - }); - - } else { - return false; - } - }, - - teardown: function( namespaces ) { - jQuery.event.remove( this, ".specialSubmit" ); - } - }; - -} - -// change delegation, happens here so we have bind. -if ( !jQuery.support.changeBubbles ) { - - var changeFilters, - - getVal = function( elem ) { - var type = elem.type, val = elem.value; - - if ( type === "radio" || type === "checkbox" ) { - val = elem.checked; - - } else if ( type === "select-multiple" ) { - val = elem.selectedIndex > -1 ? - jQuery.map( elem.options, function( elem ) { - return elem.selected; - }).join("-") : - ""; - - } else if ( jQuery.nodeName( elem, "select" ) ) { - val = elem.selectedIndex; - } - - return val; - }, - - testChange = function testChange( e ) { - var elem = e.target, data, val; - - if ( !rformElems.test( elem.nodeName ) || elem.readOnly ) { - return; - } - - data = jQuery._data( elem, "_change_data" ); - val = getVal(elem); - - // the current data will be also retrieved by beforeactivate - if ( e.type !== "focusout" || elem.type !== "radio" ) { - jQuery._data( elem, "_change_data", val ); - } - - if ( data === undefined || val === data ) { - return; - } - - if ( data != null || val ) { - e.type = "change"; - e.liveFired = undefined; - jQuery.event.trigger( e, arguments[1], elem ); - } - }; - - jQuery.event.special.change = { - filters: { - focusout: testChange, - - beforedeactivate: testChange, - - click: function( e ) { - var elem = e.target, type = jQuery.nodeName( elem, "input" ) ? elem.type : ""; - - if ( type === "radio" || type === "checkbox" || jQuery.nodeName( elem, "select" ) ) { - testChange.call( this, e ); - } - }, - - // Change has to be called before submit - // Keydown will be called before keypress, which is used in submit-event delegation - keydown: function( e ) { - var elem = e.target, type = jQuery.nodeName( elem, "input" ) ? elem.type : ""; - - if ( (e.keyCode === 13 && !jQuery.nodeName( elem, "textarea" ) ) || - (e.keyCode === 32 && (type === "checkbox" || type === "radio")) || - type === "select-multiple" ) { - testChange.call( this, e ); - } - }, - - // Beforeactivate happens also before the previous element is blurred - // with this event you can't trigger a change event, but you can store - // information - beforeactivate: function( e ) { - var elem = e.target; - jQuery._data( elem, "_change_data", getVal(elem) ); - } - }, - - setup: function( data, namespaces ) { - if ( this.type === "file" ) { - return false; - } - - for ( var type in changeFilters ) { - jQuery.event.add( this, type + ".specialChange", changeFilters[type] ); - } - - return rformElems.test( this.nodeName ); - }, - - teardown: function( namespaces ) { - jQuery.event.remove( this, ".specialChange" ); - - return rformElems.test( this.nodeName ); - } - }; - - changeFilters = jQuery.event.special.change.filters; - - // Handle when the input is .focus()'d - changeFilters.focus = changeFilters.beforeactivate; -} - -function trigger( type, elem, args ) { - // Piggyback on a donor event to simulate a different one. - // Fake originalEvent to avoid donor's stopPropagation, but if the - // simulated event prevents default then we do the same on the donor. - // Don't pass args or remember liveFired; they apply to the donor event. - var event = jQuery.extend( {}, args[ 0 ] ); - event.type = type; - event.originalEvent = {}; - event.liveFired = undefined; - jQuery.event.handle.call( elem, event ); - if ( event.isDefaultPrevented() ) { - args[ 0 ].preventDefault(); - } -} - -// Create "bubbling" focus and blur events -if ( !jQuery.support.focusinBubbles ) { - jQuery.each({ focus: "focusin", blur: "focusout" }, function( orig, fix ) { - - // Attach a single capturing handler while someone wants focusin/focusout - var attaches = 0; - - jQuery.event.special[ fix ] = { - setup: function() { - if ( attaches++ === 0 ) { - document.addEventListener( orig, handler, true ); - } - }, - teardown: function() { - if ( --attaches === 0 ) { - document.removeEventListener( orig, handler, true ); - } - } - }; - - function handler( donor ) { - // Donor event is always a native one; fix it and switch its type. - // Let focusin/out handler cancel the donor focus/blur event. - var e = jQuery.event.fix( donor ); - e.type = fix; - e.originalEvent = {}; - jQuery.event.trigger( e, null, e.target ); - if ( e.isDefaultPrevented() ) { - donor.preventDefault(); - } - } - }); -} - -jQuery.each(["bind", "one"], function( i, name ) { - jQuery.fn[ name ] = function( type, data, fn ) { - var handler; - - // Handle object literals - if ( typeof type === "object" ) { - for ( var key in type ) { - this[ name ](key, data, type[key], fn); - } - return this; - } - - if ( arguments.length === 2 || data === false ) { - fn = data; - data = undefined; - } - - if ( name === "one" ) { - handler = function( event ) { - jQuery( this ).unbind( event, handler ); - return fn.apply( this, arguments ); - }; - handler.guid = fn.guid || jQuery.guid++; - } else { - handler = fn; - } - - if ( type === "unload" && name !== "one" ) { - this.one( type, data, fn ); - - } else { - for ( var i = 0, l = this.length; i < l; i++ ) { - jQuery.event.add( this[i], type, handler, data ); - } - } - - return this; - }; -}); - -jQuery.fn.extend({ - unbind: function( type, fn ) { - // Handle object literals - if ( typeof type === "object" && !type.preventDefault ) { - for ( var key in type ) { - this.unbind(key, type[key]); - } - - } else { - for ( var i = 0, l = this.length; i < l; i++ ) { - jQuery.event.remove( this[i], type, fn ); - } - } - - return this; - }, - - delegate: function( selector, types, data, fn ) { - return this.live( types, data, fn, selector ); - }, - - undelegate: function( selector, types, fn ) { - if ( arguments.length === 0 ) { - return this.unbind( "live" ); - - } else { - return this.die( types, null, fn, selector ); - } - }, - - trigger: function( type, data ) { - return this.each(function() { - jQuery.event.trigger( type, data, this ); - }); - }, - - triggerHandler: function( type, data ) { - if ( this[0] ) { - return jQuery.event.trigger( type, data, this[0], true ); - } - }, - - toggle: function( fn ) { - // Save reference to arguments for access in closure - var args = arguments, - guid = fn.guid || jQuery.guid++, - i = 0, - toggler = function( event ) { - // Figure out which function to execute - var lastToggle = ( jQuery.data( this, "lastToggle" + fn.guid ) || 0 ) % i; - jQuery.data( this, "lastToggle" + fn.guid, lastToggle + 1 ); - - // Make sure that clicks stop - event.preventDefault(); - - // and execute the function - return args[ lastToggle ].apply( this, arguments ) || false; - }; - - // link all the functions, so any of them can unbind this click handler - toggler.guid = guid; - while ( i < args.length ) { - args[ i++ ].guid = guid; - } - - return this.click( toggler ); - }, - - hover: function( fnOver, fnOut ) { - return this.mouseenter( fnOver ).mouseleave( fnOut || fnOver ); - } -}); - -var liveMap = { - focus: "focusin", - blur: "focusout", - mouseenter: "mouseover", - mouseleave: "mouseout" -}; - -jQuery.each(["live", "die"], function( i, name ) { - jQuery.fn[ name ] = function( types, data, fn, origSelector /* Internal Use Only */ ) { - var type, i = 0, match, namespaces, preType, - selector = origSelector || this.selector, - context = origSelector ? this : jQuery( this.context ); - - if ( typeof types === "object" && !types.preventDefault ) { - for ( var key in types ) { - context[ name ]( key, data, types[key], selector ); - } - - return this; - } - - if ( name === "die" && !types && - origSelector && origSelector.charAt(0) === "." ) { - - context.unbind( origSelector ); - - return this; - } - - if ( data === false || jQuery.isFunction( data ) ) { - fn = data || returnFalse; - data = undefined; - } - - types = (types || "").split(" "); - - while ( (type = types[ i++ ]) != null ) { - match = rnamespaces.exec( type ); - namespaces = ""; - - if ( match ) { - namespaces = match[0]; - type = type.replace( rnamespaces, "" ); - } - - if ( type === "hover" ) { - types.push( "mouseenter" + namespaces, "mouseleave" + namespaces ); - continue; - } - - preType = type; - - if ( liveMap[ type ] ) { - types.push( liveMap[ type ] + namespaces ); - type = type + namespaces; - - } else { - type = (liveMap[ type ] || type) + namespaces; - } - - if ( name === "live" ) { - // bind live handler - for ( var j = 0, l = context.length; j < l; j++ ) { - jQuery.event.add( context[j], "live." + liveConvert( type, selector ), - { data: data, selector: selector, handler: fn, origType: type, origHandler: fn, preType: preType } ); - } - - } else { - // unbind live handler - context.unbind( "live." + liveConvert( type, selector ), fn ); - } - } - - return this; - }; -}); - -function liveHandler( event ) { - var stop, maxLevel, related, match, handleObj, elem, j, i, l, data, close, namespace, ret, - elems = [], - selectors = [], - events = jQuery._data( this, "events" ); - - // Make sure we avoid non-left-click bubbling in Firefox (#3861) and disabled elements in IE (#6911) - if ( event.liveFired === this || !events || !events.live || event.target.disabled || event.button && event.type === "click" ) { - return; - } - - if ( event.namespace ) { - namespace = new RegExp("(^|\\.)" + event.namespace.split(".").join("\\.(?:.*\\.)?") + "(\\.|$)"); - } - - event.liveFired = this; - - var live = events.live.slice(0); - - for ( j = 0; j < live.length; j++ ) { - handleObj = live[j]; - - if ( handleObj.origType.replace( rnamespaces, "" ) === event.type ) { - selectors.push( handleObj.selector ); - - } else { - live.splice( j--, 1 ); - } - } - - match = jQuery( event.target ).closest( selectors, event.currentTarget ); - - for ( i = 0, l = match.length; i < l; i++ ) { - close = match[i]; - - for ( j = 0; j < live.length; j++ ) { - handleObj = live[j]; - - if ( close.selector === handleObj.selector && (!namespace || namespace.test( handleObj.namespace )) && !close.elem.disabled ) { - elem = close.elem; - related = null; - - // Those two events require additional checking - if ( handleObj.preType === "mouseenter" || handleObj.preType === "mouseleave" ) { - event.type = handleObj.preType; - related = jQuery( event.relatedTarget ).closest( handleObj.selector )[0]; - - // Make sure not to accidentally match a child element with the same selector - if ( related && jQuery.contains( elem, related ) ) { - related = elem; - } - } - - if ( !related || related !== elem ) { - elems.push({ elem: elem, handleObj: handleObj, level: close.level }); - } - } - } - } - - for ( i = 0, l = elems.length; i < l; i++ ) { - match = elems[i]; - - if ( maxLevel && match.level > maxLevel ) { - break; - } - - event.currentTarget = match.elem; - event.data = match.handleObj.data; - event.handleObj = match.handleObj; - - ret = match.handleObj.origHandler.apply( match.elem, arguments ); - - if ( ret === false || event.isPropagationStopped() ) { - maxLevel = match.level; - - if ( ret === false ) { - stop = false; - } - if ( event.isImmediatePropagationStopped() ) { - break; - } - } - } - - return stop; -} - -function liveConvert( type, selector ) { - return (type && type !== "*" ? type + "." : "") + selector.replace(rperiod, "`").replace(rspaces, "&"); -} - -jQuery.each( ("blur focus focusin focusout load resize scroll unload click dblclick " + - "mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave " + - "change select submit keydown keypress keyup error").split(" "), function( i, name ) { - - // Handle event binding - jQuery.fn[ name ] = function( data, fn ) { - if ( fn == null ) { - fn = data; - data = null; - } - - return arguments.length > 0 ? - this.bind( name, data, fn ) : - this.trigger( name ); - }; - - if ( jQuery.attrFn ) { - jQuery.attrFn[ name ] = true; - } -}); - - - -/*! - * Sizzle CSS Selector Engine - * Copyright 2011, The Dojo Foundation - * Released under the MIT, BSD, and GPL Licenses. - * More information: http://sizzlejs.com/ - */ -(function(){ - -var chunker = /((?:\((?:\([^()]+\)|[^()]+)+\)|\[(?:\[[^\[\]]*\]|['"][^'"]*['"]|[^\[\]'"]+)+\]|\\.|[^ >+~,(\[\\]+)+|[>+~])(\s*,\s*)?((?:.|\r|\n)*)/g, - done = 0, - toString = Object.prototype.toString, - hasDuplicate = false, - baseHasDuplicate = true, - rBackslash = /\\/g, - rNonWord = /\W/; - -// Here we check if the JavaScript engine is using some sort of -// optimization where it does not always call our comparision -// function. If that is the case, discard the hasDuplicate value. -// Thus far that includes Google Chrome. -[0, 0].sort(function() { - baseHasDuplicate = false; - return 0; -}); - -var Sizzle = function( selector, context, results, seed ) { - results = results || []; - context = context || document; - - var origContext = context; - - if ( context.nodeType !== 1 && context.nodeType !== 9 ) { - return []; - } - - if ( !selector || typeof selector !== "string" ) { - return results; - } - - var m, set, checkSet, extra, ret, cur, pop, i, - prune = true, - contextXML = Sizzle.isXML( context ), - parts = [], - soFar = selector; - - // Reset the position of the chunker regexp (start from head) - do { - chunker.exec( "" ); - m = chunker.exec( soFar ); - - if ( m ) { - soFar = m[3]; - - parts.push( m[1] ); - - if ( m[2] ) { - extra = m[3]; - break; - } - } - } while ( m ); - - if ( parts.length > 1 && origPOS.exec( selector ) ) { - - if ( parts.length === 2 && Expr.relative[ parts[0] ] ) { - set = posProcess( parts[0] + parts[1], context ); - - } else { - set = Expr.relative[ parts[0] ] ? - [ context ] : - Sizzle( parts.shift(), context ); - - while ( parts.length ) { - selector = parts.shift(); - - if ( Expr.relative[ selector ] ) { - selector += parts.shift(); - } - - set = posProcess( selector, set ); - } - } - - } else { - // Take a shortcut and set the context if the root selector is an ID - // (but not if it'll be faster if the inner selector is an ID) - if ( !seed && parts.length > 1 && context.nodeType === 9 && !contextXML && - Expr.match.ID.test(parts[0]) && !Expr.match.ID.test(parts[parts.length - 1]) ) { - - ret = Sizzle.find( parts.shift(), context, contextXML ); - context = ret.expr ? - Sizzle.filter( ret.expr, ret.set )[0] : - ret.set[0]; - } - - if ( context ) { - ret = seed ? - { expr: parts.pop(), set: makeArray(seed) } : - Sizzle.find( parts.pop(), parts.length === 1 && (parts[0] === "~" || parts[0] === "+") && context.parentNode ? context.parentNode : context, contextXML ); - - set = ret.expr ? - Sizzle.filter( ret.expr, ret.set ) : - ret.set; - - if ( parts.length > 0 ) { - checkSet = makeArray( set ); - - } else { - prune = false; - } - - while ( parts.length ) { - cur = parts.pop(); - pop = cur; - - if ( !Expr.relative[ cur ] ) { - cur = ""; - } else { - pop = parts.pop(); - } - - if ( pop == null ) { - pop = context; - } - - Expr.relative[ cur ]( checkSet, pop, contextXML ); - } - - } else { - checkSet = parts = []; - } - } - - if ( !checkSet ) { - checkSet = set; - } - - if ( !checkSet ) { - Sizzle.error( cur || selector ); - } - - if ( toString.call(checkSet) === "[object Array]" ) { - if ( !prune ) { - results.push.apply( results, checkSet ); - - } else if ( context && context.nodeType === 1 ) { - for ( i = 0; checkSet[i] != null; i++ ) { - if ( checkSet[i] && (checkSet[i] === true || checkSet[i].nodeType === 1 && Sizzle.contains(context, checkSet[i])) ) { - results.push( set[i] ); - } - } - - } else { - for ( i = 0; checkSet[i] != null; i++ ) { - if ( checkSet[i] && checkSet[i].nodeType === 1 ) { - results.push( set[i] ); - } - } - } - - } else { - makeArray( checkSet, results ); - } - - if ( extra ) { - Sizzle( extra, origContext, results, seed ); - Sizzle.uniqueSort( results ); - } - - return results; -}; - -Sizzle.uniqueSort = function( results ) { - if ( sortOrder ) { - hasDuplicate = baseHasDuplicate; - results.sort( sortOrder ); - - if ( hasDuplicate ) { - for ( var i = 1; i < results.length; i++ ) { - if ( results[i] === results[ i - 1 ] ) { - results.splice( i--, 1 ); - } - } - } - } - - return results; -}; - -Sizzle.matches = function( expr, set ) { - return Sizzle( expr, null, null, set ); -}; - -Sizzle.matchesSelector = function( node, expr ) { - return Sizzle( expr, null, null, [node] ).length > 0; -}; - -Sizzle.find = function( expr, context, isXML ) { - var set; - - if ( !expr ) { - return []; - } - - for ( var i = 0, l = Expr.order.length; i < l; i++ ) { - var match, - type = Expr.order[i]; - - if ( (match = Expr.leftMatch[ type ].exec( expr )) ) { - var left = match[1]; - match.splice( 1, 1 ); - - if ( left.substr( left.length - 1 ) !== "\\" ) { - match[1] = (match[1] || "").replace( rBackslash, "" ); - set = Expr.find[ type ]( match, context, isXML ); - - if ( set != null ) { - expr = expr.replace( Expr.match[ type ], "" ); - break; - } - } - } - } - - if ( !set ) { - set = typeof context.getElementsByTagName !== "undefined" ? - context.getElementsByTagName( "*" ) : - []; - } - - return { set: set, expr: expr }; -}; - -Sizzle.filter = function( expr, set, inplace, not ) { - var match, anyFound, - old = expr, - result = [], - curLoop = set, - isXMLFilter = set && set[0] && Sizzle.isXML( set[0] ); - - while ( expr && set.length ) { - for ( var type in Expr.filter ) { - if ( (match = Expr.leftMatch[ type ].exec( expr )) != null && match[2] ) { - var found, item, - filter = Expr.filter[ type ], - left = match[1]; - - anyFound = false; - - match.splice(1,1); - - if ( left.substr( left.length - 1 ) === "\\" ) { - continue; - } - - if ( curLoop === result ) { - result = []; - } - - if ( Expr.preFilter[ type ] ) { - match = Expr.preFilter[ type ]( match, curLoop, inplace, result, not, isXMLFilter ); - - if ( !match ) { - anyFound = found = true; - - } else if ( match === true ) { - continue; - } - } - - if ( match ) { - for ( var i = 0; (item = curLoop[i]) != null; i++ ) { - if ( item ) { - found = filter( item, match, i, curLoop ); - var pass = not ^ !!found; - - if ( inplace && found != null ) { - if ( pass ) { - anyFound = true; - - } else { - curLoop[i] = false; - } - - } else if ( pass ) { - result.push( item ); - anyFound = true; - } - } - } - } - - if ( found !== undefined ) { - if ( !inplace ) { - curLoop = result; - } - - expr = expr.replace( Expr.match[ type ], "" ); - - if ( !anyFound ) { - return []; - } - - break; - } - } - } - - // Improper expression - if ( expr === old ) { - if ( anyFound == null ) { - Sizzle.error( expr ); - - } else { - break; - } - } - - old = expr; - } - - return curLoop; -}; - -Sizzle.error = function( msg ) { - throw "Syntax error, unrecognized expression: " + msg; -}; - -var Expr = Sizzle.selectors = { - order: [ "ID", "NAME", "TAG" ], - - match: { - ID: /#((?:[\w\u00c0-\uFFFF\-]|\\.)+)/, - CLASS: /\.((?:[\w\u00c0-\uFFFF\-]|\\.)+)/, - NAME: /\[name=['"]*((?:[\w\u00c0-\uFFFF\-]|\\.)+)['"]*\]/, - ATTR: /\[\s*((?:[\w\u00c0-\uFFFF\-]|\\.)+)\s*(?:(\S?=)\s*(?:(['"])(.*?)\3|(#?(?:[\w\u00c0-\uFFFF\-]|\\.)*)|)|)\s*\]/, - TAG: /^((?:[\w\u00c0-\uFFFF\*\-]|\\.)+)/, - CHILD: /:(only|nth|last|first)-child(?:\(\s*(even|odd|(?:[+\-]?\d+|(?:[+\-]?\d*)?n\s*(?:[+\-]\s*\d+)?))\s*\))?/, - POS: /:(nth|eq|gt|lt|first|last|even|odd)(?:\((\d*)\))?(?=[^\-]|$)/, - PSEUDO: /:((?:[\w\u00c0-\uFFFF\-]|\\.)+)(?:\((['"]?)((?:\([^\)]+\)|[^\(\)]*)+)\2\))?/ - }, - - leftMatch: {}, - - attrMap: { - "class": "className", - "for": "htmlFor" - }, - - attrHandle: { - href: function( elem ) { - return elem.getAttribute( "href" ); - }, - type: function( elem ) { - return elem.getAttribute( "type" ); - } - }, - - relative: { - "+": function(checkSet, part){ - var isPartStr = typeof part === "string", - isTag = isPartStr && !rNonWord.test( part ), - isPartStrNotTag = isPartStr && !isTag; - - if ( isTag ) { - part = part.toLowerCase(); - } - - for ( var i = 0, l = checkSet.length, elem; i < l; i++ ) { - if ( (elem = checkSet[i]) ) { - while ( (elem = elem.previousSibling) && elem.nodeType !== 1 ) {} - - checkSet[i] = isPartStrNotTag || elem && elem.nodeName.toLowerCase() === part ? - elem || false : - elem === part; - } - } - - if ( isPartStrNotTag ) { - Sizzle.filter( part, checkSet, true ); - } - }, - - ">": function( checkSet, part ) { - var elem, - isPartStr = typeof part === "string", - i = 0, - l = checkSet.length; - - if ( isPartStr && !rNonWord.test( part ) ) { - part = part.toLowerCase(); - - for ( ; i < l; i++ ) { - elem = checkSet[i]; - - if ( elem ) { - var parent = elem.parentNode; - checkSet[i] = parent.nodeName.toLowerCase() === part ? parent : false; - } - } - - } else { - for ( ; i < l; i++ ) { - elem = checkSet[i]; - - if ( elem ) { - checkSet[i] = isPartStr ? - elem.parentNode : - elem.parentNode === part; - } - } - - if ( isPartStr ) { - Sizzle.filter( part, checkSet, true ); - } - } - }, - - "": function(checkSet, part, isXML){ - var nodeCheck, - doneName = done++, - checkFn = dirCheck; - - if ( typeof part === "string" && !rNonWord.test( part ) ) { - part = part.toLowerCase(); - nodeCheck = part; - checkFn = dirNodeCheck; - } - - checkFn( "parentNode", part, doneName, checkSet, nodeCheck, isXML ); - }, - - "~": function( checkSet, part, isXML ) { - var nodeCheck, - doneName = done++, - checkFn = dirCheck; - - if ( typeof part === "string" && !rNonWord.test( part ) ) { - part = part.toLowerCase(); - nodeCheck = part; - checkFn = dirNodeCheck; - } - - checkFn( "previousSibling", part, doneName, checkSet, nodeCheck, isXML ); - } - }, - - find: { - ID: function( match, context, isXML ) { - if ( typeof context.getElementById !== "undefined" && !isXML ) { - var m = context.getElementById(match[1]); - // Check parentNode to catch when Blackberry 4.6 returns - // nodes that are no longer in the document #6963 - return m && m.parentNode ? [m] : []; - } - }, - - NAME: function( match, context ) { - if ( typeof context.getElementsByName !== "undefined" ) { - var ret = [], - results = context.getElementsByName( match[1] ); - - for ( var i = 0, l = results.length; i < l; i++ ) { - if ( results[i].getAttribute("name") === match[1] ) { - ret.push( results[i] ); - } - } - - return ret.length === 0 ? null : ret; - } - }, - - TAG: function( match, context ) { - if ( typeof context.getElementsByTagName !== "undefined" ) { - return context.getElementsByTagName( match[1] ); - } - } - }, - preFilter: { - CLASS: function( match, curLoop, inplace, result, not, isXML ) { - match = " " + match[1].replace( rBackslash, "" ) + " "; - - if ( isXML ) { - return match; - } - - for ( var i = 0, elem; (elem = curLoop[i]) != null; i++ ) { - if ( elem ) { - if ( not ^ (elem.className && (" " + elem.className + " ").replace(/[\t\n\r]/g, " ").indexOf(match) >= 0) ) { - if ( !inplace ) { - result.push( elem ); - } - - } else if ( inplace ) { - curLoop[i] = false; - } - } - } - - return false; - }, - - ID: function( match ) { - return match[1].replace( rBackslash, "" ); - }, - - TAG: function( match, curLoop ) { - return match[1].replace( rBackslash, "" ).toLowerCase(); - }, - - CHILD: function( match ) { - if ( match[1] === "nth" ) { - if ( !match[2] ) { - Sizzle.error( match[0] ); - } - - match[2] = match[2].replace(/^\+|\s*/g, ''); - - // parse equations like 'even', 'odd', '5', '2n', '3n+2', '4n-1', '-n+6' - var test = /(-?)(\d*)(?:n([+\-]?\d*))?/.exec( - match[2] === "even" && "2n" || match[2] === "odd" && "2n+1" || - !/\D/.test( match[2] ) && "0n+" + match[2] || match[2]); - - // calculate the numbers (first)n+(last) including if they are negative - match[2] = (test[1] + (test[2] || 1)) - 0; - match[3] = test[3] - 0; - } - else if ( match[2] ) { - Sizzle.error( match[0] ); - } - - // TODO: Move to normal caching system - match[0] = done++; - - return match; - }, - - ATTR: function( match, curLoop, inplace, result, not, isXML ) { - var name = match[1] = match[1].replace( rBackslash, "" ); - - if ( !isXML && Expr.attrMap[name] ) { - match[1] = Expr.attrMap[name]; - } - - // Handle if an un-quoted value was used - match[4] = ( match[4] || match[5] || "" ).replace( rBackslash, "" ); - - if ( match[2] === "~=" ) { - match[4] = " " + match[4] + " "; - } - - return match; - }, - - PSEUDO: function( match, curLoop, inplace, result, not ) { - if ( match[1] === "not" ) { - // If we're dealing with a complex expression, or a simple one - if ( ( chunker.exec(match[3]) || "" ).length > 1 || /^\w/.test(match[3]) ) { - match[3] = Sizzle(match[3], null, null, curLoop); - - } else { - var ret = Sizzle.filter(match[3], curLoop, inplace, true ^ not); - - if ( !inplace ) { - result.push.apply( result, ret ); - } - - return false; - } - - } else if ( Expr.match.POS.test( match[0] ) || Expr.match.CHILD.test( match[0] ) ) { - return true; - } - - return match; - }, - - POS: function( match ) { - match.unshift( true ); - - return match; - } - }, - - filters: { - enabled: function( elem ) { - return elem.disabled === false && elem.type !== "hidden"; - }, - - disabled: function( elem ) { - return elem.disabled === true; - }, - - checked: function( elem ) { - return elem.checked === true; - }, - - selected: function( elem ) { - // Accessing this property makes selected-by-default - // options in Safari work properly - if ( elem.parentNode ) { - elem.parentNode.selectedIndex; - } - - return elem.selected === true; - }, - - parent: function( elem ) { - return !!elem.firstChild; - }, - - empty: function( elem ) { - return !elem.firstChild; - }, - - has: function( elem, i, match ) { - return !!Sizzle( match[3], elem ).length; - }, - - header: function( elem ) { - return (/h\d/i).test( elem.nodeName ); - }, - - text: function( elem ) { - var attr = elem.getAttribute( "type" ), type = elem.type; - // IE6 and 7 will map elem.type to 'text' for new HTML5 types (search, etc) - // use getAttribute instead to test this case - return elem.nodeName.toLowerCase() === "input" && "text" === type && ( attr === type || attr === null ); - }, - - radio: function( elem ) { - return elem.nodeName.toLowerCase() === "input" && "radio" === elem.type; - }, - - checkbox: function( elem ) { - return elem.nodeName.toLowerCase() === "input" && "checkbox" === elem.type; - }, - - file: function( elem ) { - return elem.nodeName.toLowerCase() === "input" && "file" === elem.type; - }, - - password: function( elem ) { - return elem.nodeName.toLowerCase() === "input" && "password" === elem.type; - }, - - submit: function( elem ) { - var name = elem.nodeName.toLowerCase(); - return (name === "input" || name === "button") && "submit" === elem.type; - }, - - image: function( elem ) { - return elem.nodeName.toLowerCase() === "input" && "image" === elem.type; - }, - - reset: function( elem ) { - var name = elem.nodeName.toLowerCase(); - return (name === "input" || name === "button") && "reset" === elem.type; - }, - - button: function( elem ) { - var name = elem.nodeName.toLowerCase(); - return name === "input" && "button" === elem.type || name === "button"; - }, - - input: function( elem ) { - return (/input|select|textarea|button/i).test( elem.nodeName ); - }, - - focus: function( elem ) { - return elem === elem.ownerDocument.activeElement; - } - }, - setFilters: { - first: function( elem, i ) { - return i === 0; - }, - - last: function( elem, i, match, array ) { - return i === array.length - 1; - }, - - even: function( elem, i ) { - return i % 2 === 0; - }, - - odd: function( elem, i ) { - return i % 2 === 1; - }, - - lt: function( elem, i, match ) { - return i < match[3] - 0; - }, - - gt: function( elem, i, match ) { - return i > match[3] - 0; - }, - - nth: function( elem, i, match ) { - return match[3] - 0 === i; - }, - - eq: function( elem, i, match ) { - return match[3] - 0 === i; - } - }, - filter: { - PSEUDO: function( elem, match, i, array ) { - var name = match[1], - filter = Expr.filters[ name ]; - - if ( filter ) { - return filter( elem, i, match, array ); - - } else if ( name === "contains" ) { - return (elem.textContent || elem.innerText || Sizzle.getText([ elem ]) || "").indexOf(match[3]) >= 0; - - } else if ( name === "not" ) { - var not = match[3]; - - for ( var j = 0, l = not.length; j < l; j++ ) { - if ( not[j] === elem ) { - return false; - } - } - - return true; - - } else { - Sizzle.error( name ); - } - }, - - CHILD: function( elem, match ) { - var type = match[1], - node = elem; - - switch ( type ) { - case "only": - case "first": - while ( (node = node.previousSibling) ) { - if ( node.nodeType === 1 ) { - return false; - } - } - - if ( type === "first" ) { - return true; - } - - node = elem; - - case "last": - while ( (node = node.nextSibling) ) { - if ( node.nodeType === 1 ) { - return false; - } - } - - return true; - - case "nth": - var first = match[2], - last = match[3]; - - if ( first === 1 && last === 0 ) { - return true; - } - - var doneName = match[0], - parent = elem.parentNode; - - if ( parent && (parent.sizcache !== doneName || !elem.nodeIndex) ) { - var count = 0; - - for ( node = parent.firstChild; node; node = node.nextSibling ) { - if ( node.nodeType === 1 ) { - node.nodeIndex = ++count; - } - } - - parent.sizcache = doneName; - } - - var diff = elem.nodeIndex - last; - - if ( first === 0 ) { - return diff === 0; - - } else { - return ( diff % first === 0 && diff / first >= 0 ); - } - } - }, - - ID: function( elem, match ) { - return elem.nodeType === 1 && elem.getAttribute("id") === match; - }, - - TAG: function( elem, match ) { - return (match === "*" && elem.nodeType === 1) || elem.nodeName.toLowerCase() === match; - }, - - CLASS: function( elem, match ) { - return (" " + (elem.className || elem.getAttribute("class")) + " ") - .indexOf( match ) > -1; - }, - - ATTR: function( elem, match ) { - var name = match[1], - result = Expr.attrHandle[ name ] ? - Expr.attrHandle[ name ]( elem ) : - elem[ name ] != null ? - elem[ name ] : - elem.getAttribute( name ), - value = result + "", - type = match[2], - check = match[4]; - - return result == null ? - type === "!=" : - type === "=" ? - value === check : - type === "*=" ? - value.indexOf(check) >= 0 : - type === "~=" ? - (" " + value + " ").indexOf(check) >= 0 : - !check ? - value && result !== false : - type === "!=" ? - value !== check : - type === "^=" ? - value.indexOf(check) === 0 : - type === "$=" ? - value.substr(value.length - check.length) === check : - type === "|=" ? - value === check || value.substr(0, check.length + 1) === check + "-" : - false; - }, - - POS: function( elem, match, i, array ) { - var name = match[2], - filter = Expr.setFilters[ name ]; - - if ( filter ) { - return filter( elem, i, match, array ); - } - } - } -}; - -var origPOS = Expr.match.POS, - fescape = function(all, num){ - return "\\" + (num - 0 + 1); - }; - -for ( var type in Expr.match ) { - Expr.match[ type ] = new RegExp( Expr.match[ type ].source + (/(?![^\[]*\])(?![^\(]*\))/.source) ); - Expr.leftMatch[ type ] = new RegExp( /(^(?:.|\r|\n)*?)/.source + Expr.match[ type ].source.replace(/\\(\d+)/g, fescape) ); -} - -var makeArray = function( array, results ) { - array = Array.prototype.slice.call( array, 0 ); - - if ( results ) { - results.push.apply( results, array ); - return results; - } - - return array; -}; - -// Perform a simple check to determine if the browser is capable of -// converting a NodeList to an array using builtin methods. -// Also verifies that the returned array holds DOM nodes -// (which is not the case in the Blackberry browser) -try { - Array.prototype.slice.call( document.documentElement.childNodes, 0 )[0].nodeType; - -// Provide a fallback method if it does not work -} catch( e ) { - makeArray = function( array, results ) { - var i = 0, - ret = results || []; - - if ( toString.call(array) === "[object Array]" ) { - Array.prototype.push.apply( ret, array ); - - } else { - if ( typeof array.length === "number" ) { - for ( var l = array.length; i < l; i++ ) { - ret.push( array[i] ); - } - - } else { - for ( ; array[i]; i++ ) { - ret.push( array[i] ); - } - } - } - - return ret; - }; -} - -var sortOrder, siblingCheck; - -if ( document.documentElement.compareDocumentPosition ) { - sortOrder = function( a, b ) { - if ( a === b ) { - hasDuplicate = true; - return 0; - } - - if ( !a.compareDocumentPosition || !b.compareDocumentPosition ) { - return a.compareDocumentPosition ? -1 : 1; - } - - return a.compareDocumentPosition(b) & 4 ? -1 : 1; - }; - -} else { - sortOrder = function( a, b ) { - // The nodes are identical, we can exit early - if ( a === b ) { - hasDuplicate = true; - return 0; - - // Fallback to using sourceIndex (in IE) if it's available on both nodes - } else if ( a.sourceIndex && b.sourceIndex ) { - return a.sourceIndex - b.sourceIndex; - } - - var al, bl, - ap = [], - bp = [], - aup = a.parentNode, - bup = b.parentNode, - cur = aup; - - // If the nodes are siblings (or identical) we can do a quick check - if ( aup === bup ) { - return siblingCheck( a, b ); - - // If no parents were found then the nodes are disconnected - } else if ( !aup ) { - return -1; - - } else if ( !bup ) { - return 1; - } - - // Otherwise they're somewhere else in the tree so we need - // to build up a full list of the parentNodes for comparison - while ( cur ) { - ap.unshift( cur ); - cur = cur.parentNode; - } - - cur = bup; - - while ( cur ) { - bp.unshift( cur ); - cur = cur.parentNode; - } - - al = ap.length; - bl = bp.length; - - // Start walking down the tree looking for a discrepancy - for ( var i = 0; i < al && i < bl; i++ ) { - if ( ap[i] !== bp[i] ) { - return siblingCheck( ap[i], bp[i] ); - } - } - - // We ended someplace up the tree so do a sibling check - return i === al ? - siblingCheck( a, bp[i], -1 ) : - siblingCheck( ap[i], b, 1 ); - }; - - siblingCheck = function( a, b, ret ) { - if ( a === b ) { - return ret; - } - - var cur = a.nextSibling; - - while ( cur ) { - if ( cur === b ) { - return -1; - } - - cur = cur.nextSibling; - } - - return 1; - }; -} - -// Utility function for retreiving the text value of an array of DOM nodes -Sizzle.getText = function( elems ) { - var ret = "", elem; - - for ( var i = 0; elems[i]; i++ ) { - elem = elems[i]; - - // Get the text from text nodes and CDATA nodes - if ( elem.nodeType === 3 || elem.nodeType === 4 ) { - ret += elem.nodeValue; - - // Traverse everything else, except comment nodes - } else if ( elem.nodeType !== 8 ) { - ret += Sizzle.getText( elem.childNodes ); - } - } - - return ret; -}; - -// Check to see if the browser returns elements by name when -// querying by getElementById (and provide a workaround) -(function(){ - // We're going to inject a fake input element with a specified name - var form = document.createElement("div"), - id = "script" + (new Date()).getTime(), - root = document.documentElement; - - form.innerHTML = ""; - - // Inject it into the root element, check its status, and remove it quickly - root.insertBefore( form, root.firstChild ); - - // The workaround has to do additional checks after a getElementById - // Which slows things down for other browsers (hence the branching) - if ( document.getElementById( id ) ) { - Expr.find.ID = function( match, context, isXML ) { - if ( typeof context.getElementById !== "undefined" && !isXML ) { - var m = context.getElementById(match[1]); - - return m ? - m.id === match[1] || typeof m.getAttributeNode !== "undefined" && m.getAttributeNode("id").nodeValue === match[1] ? - [m] : - undefined : - []; - } - }; - - Expr.filter.ID = function( elem, match ) { - var node = typeof elem.getAttributeNode !== "undefined" && elem.getAttributeNode("id"); - - return elem.nodeType === 1 && node && node.nodeValue === match; - }; - } - - root.removeChild( form ); - - // release memory in IE - root = form = null; -})(); - -(function(){ - // Check to see if the browser returns only elements - // when doing getElementsByTagName("*") - - // Create a fake element - var div = document.createElement("div"); - div.appendChild( document.createComment("") ); - - // Make sure no comments are found - if ( div.getElementsByTagName("*").length > 0 ) { - Expr.find.TAG = function( match, context ) { - var results = context.getElementsByTagName( match[1] ); - - // Filter out possible comments - if ( match[1] === "*" ) { - var tmp = []; - - for ( var i = 0; results[i]; i++ ) { - if ( results[i].nodeType === 1 ) { - tmp.push( results[i] ); - } - } - - results = tmp; - } - - return results; - }; - } - - // Check to see if an attribute returns normalized href attributes - div.innerHTML = ""; - - if ( div.firstChild && typeof div.firstChild.getAttribute !== "undefined" && - div.firstChild.getAttribute("href") !== "#" ) { - - Expr.attrHandle.href = function( elem ) { - return elem.getAttribute( "href", 2 ); - }; - } - - // release memory in IE - div = null; -})(); - -if ( document.querySelectorAll ) { - (function(){ - var oldSizzle = Sizzle, - div = document.createElement("div"), - id = "__sizzle__"; - - div.innerHTML = "

      "; - - // Safari can't handle uppercase or unicode characters when - // in quirks mode. - if ( div.querySelectorAll && div.querySelectorAll(".TEST").length === 0 ) { - return; - } - - Sizzle = function( query, context, extra, seed ) { - context = context || document; - - // Only use querySelectorAll on non-XML documents - // (ID selectors don't work in non-HTML documents) - if ( !seed && !Sizzle.isXML(context) ) { - // See if we find a selector to speed up - var match = /^(\w+$)|^\.([\w\-]+$)|^#([\w\-]+$)/.exec( query ); - - if ( match && (context.nodeType === 1 || context.nodeType === 9) ) { - // Speed-up: Sizzle("TAG") - if ( match[1] ) { - return makeArray( context.getElementsByTagName( query ), extra ); - - // Speed-up: Sizzle(".CLASS") - } else if ( match[2] && Expr.find.CLASS && context.getElementsByClassName ) { - return makeArray( context.getElementsByClassName( match[2] ), extra ); - } - } - - if ( context.nodeType === 9 ) { - // Speed-up: Sizzle("body") - // The body element only exists once, optimize finding it - if ( query === "body" && context.body ) { - return makeArray( [ context.body ], extra ); - - // Speed-up: Sizzle("#ID") - } else if ( match && match[3] ) { - var elem = context.getElementById( match[3] ); - - // Check parentNode to catch when Blackberry 4.6 returns - // nodes that are no longer in the document #6963 - if ( elem && elem.parentNode ) { - // Handle the case where IE and Opera return items - // by name instead of ID - if ( elem.id === match[3] ) { - return makeArray( [ elem ], extra ); - } - - } else { - return makeArray( [], extra ); - } - } - - try { - return makeArray( context.querySelectorAll(query), extra ); - } catch(qsaError) {} - - // qSA works strangely on Element-rooted queries - // We can work around this by specifying an extra ID on the root - // and working up from there (Thanks to Andrew Dupont for the technique) - // IE 8 doesn't work on object elements - } else if ( context.nodeType === 1 && context.nodeName.toLowerCase() !== "object" ) { - var oldContext = context, - old = context.getAttribute( "id" ), - nid = old || id, - hasParent = context.parentNode, - relativeHierarchySelector = /^\s*[+~]/.test( query ); - - if ( !old ) { - context.setAttribute( "id", nid ); - } else { - nid = nid.replace( /'/g, "\\$&" ); - } - if ( relativeHierarchySelector && hasParent ) { - context = context.parentNode; - } - - try { - if ( !relativeHierarchySelector || hasParent ) { - return makeArray( context.querySelectorAll( "[id='" + nid + "'] " + query ), extra ); - } - - } catch(pseudoError) { - } finally { - if ( !old ) { - oldContext.removeAttribute( "id" ); - } - } - } - } - - return oldSizzle(query, context, extra, seed); - }; - - for ( var prop in oldSizzle ) { - Sizzle[ prop ] = oldSizzle[ prop ]; - } - - // release memory in IE - div = null; - })(); -} - -(function(){ - var html = document.documentElement, - matches = html.matchesSelector || html.mozMatchesSelector || html.webkitMatchesSelector || html.msMatchesSelector; - - if ( matches ) { - // Check to see if it's possible to do matchesSelector - // on a disconnected node (IE 9 fails this) - var disconnectedMatch = !matches.call( document.createElement( "div" ), "div" ), - pseudoWorks = false; - - try { - // This should fail with an exception - // Gecko does not error, returns false instead - matches.call( document.documentElement, "[test!='']:sizzle" ); - - } catch( pseudoError ) { - pseudoWorks = true; - } - - Sizzle.matchesSelector = function( node, expr ) { - // Make sure that attribute selectors are quoted - expr = expr.replace(/\=\s*([^'"\]]*)\s*\]/g, "='$1']"); - - if ( !Sizzle.isXML( node ) ) { - try { - if ( pseudoWorks || !Expr.match.PSEUDO.test( expr ) && !/!=/.test( expr ) ) { - var ret = matches.call( node, expr ); - - // IE 9's matchesSelector returns false on disconnected nodes - if ( ret || !disconnectedMatch || - // As well, disconnected nodes are said to be in a document - // fragment in IE 9, so check for that - node.document && node.document.nodeType !== 11 ) { - return ret; - } - } - } catch(e) {} - } - - return Sizzle(expr, null, null, [node]).length > 0; - }; - } -})(); - -(function(){ - var div = document.createElement("div"); - - div.innerHTML = "
      "; - - // Opera can't find a second classname (in 9.6) - // Also, make sure that getElementsByClassName actually exists - if ( !div.getElementsByClassName || div.getElementsByClassName("e").length === 0 ) { - return; - } - - // Safari caches class attributes, doesn't catch changes (in 3.2) - div.lastChild.className = "e"; - - if ( div.getElementsByClassName("e").length === 1 ) { - return; - } - - Expr.order.splice(1, 0, "CLASS"); - Expr.find.CLASS = function( match, context, isXML ) { - if ( typeof context.getElementsByClassName !== "undefined" && !isXML ) { - return context.getElementsByClassName(match[1]); - } - }; - - // release memory in IE - div = null; -})(); - -function dirNodeCheck( dir, cur, doneName, checkSet, nodeCheck, isXML ) { - for ( var i = 0, l = checkSet.length; i < l; i++ ) { - var elem = checkSet[i]; - - if ( elem ) { - var match = false; - - elem = elem[dir]; - - while ( elem ) { - if ( elem.sizcache === doneName ) { - match = checkSet[elem.sizset]; - break; - } - - if ( elem.nodeType === 1 && !isXML ){ - elem.sizcache = doneName; - elem.sizset = i; - } - - if ( elem.nodeName.toLowerCase() === cur ) { - match = elem; - break; - } - - elem = elem[dir]; - } - - checkSet[i] = match; - } - } -} - -function dirCheck( dir, cur, doneName, checkSet, nodeCheck, isXML ) { - for ( var i = 0, l = checkSet.length; i < l; i++ ) { - var elem = checkSet[i]; - - if ( elem ) { - var match = false; - - elem = elem[dir]; - - while ( elem ) { - if ( elem.sizcache === doneName ) { - match = checkSet[elem.sizset]; - break; - } - - if ( elem.nodeType === 1 ) { - if ( !isXML ) { - elem.sizcache = doneName; - elem.sizset = i; - } - - if ( typeof cur !== "string" ) { - if ( elem === cur ) { - match = true; - break; - } - - } else if ( Sizzle.filter( cur, [elem] ).length > 0 ) { - match = elem; - break; - } - } - - elem = elem[dir]; - } - - checkSet[i] = match; - } - } -} - -if ( document.documentElement.contains ) { - Sizzle.contains = function( a, b ) { - return a !== b && (a.contains ? a.contains(b) : true); - }; - -} else if ( document.documentElement.compareDocumentPosition ) { - Sizzle.contains = function( a, b ) { - return !!(a.compareDocumentPosition(b) & 16); - }; - -} else { - Sizzle.contains = function() { - return false; - }; -} - -Sizzle.isXML = function( elem ) { - // documentElement is verified for cases where it doesn't yet exist - // (such as loading iframes in IE - #4833) - var documentElement = (elem ? elem.ownerDocument || elem : 0).documentElement; - - return documentElement ? documentElement.nodeName !== "HTML" : false; -}; - -var posProcess = function( selector, context ) { - var match, - tmpSet = [], - later = "", - root = context.nodeType ? [context] : context; - - // Position selectors must be done after the filter - // And so must :not(positional) so we move all PSEUDOs to the end - while ( (match = Expr.match.PSEUDO.exec( selector )) ) { - later += match[0]; - selector = selector.replace( Expr.match.PSEUDO, "" ); - } - - selector = Expr.relative[selector] ? selector + "*" : selector; - - for ( var i = 0, l = root.length; i < l; i++ ) { - Sizzle( selector, root[i], tmpSet ); - } - - return Sizzle.filter( later, tmpSet ); -}; - -// EXPOSE -jQuery.find = Sizzle; -jQuery.expr = Sizzle.selectors; -jQuery.expr[":"] = jQuery.expr.filters; -jQuery.unique = Sizzle.uniqueSort; -jQuery.text = Sizzle.getText; -jQuery.isXMLDoc = Sizzle.isXML; -jQuery.contains = Sizzle.contains; - - -})(); - - -var runtil = /Until$/, - rparentsprev = /^(?:parents|prevUntil|prevAll)/, - // Note: This RegExp should be improved, or likely pulled from Sizzle - rmultiselector = /,/, - isSimple = /^.[^:#\[\.,]*$/, - slice = Array.prototype.slice, - POS = jQuery.expr.match.POS, - // methods guaranteed to produce a unique set when starting from a unique set - guaranteedUnique = { - children: true, - contents: true, - next: true, - prev: true - }; - -jQuery.fn.extend({ - find: function( selector ) { - var self = this, - i, l; - - if ( typeof selector !== "string" ) { - return jQuery( selector ).filter(function() { - for ( i = 0, l = self.length; i < l; i++ ) { - if ( jQuery.contains( self[ i ], this ) ) { - return true; - } - } - }); - } - - var ret = this.pushStack( "", "find", selector ), - length, n, r; - - for ( i = 0, l = this.length; i < l; i++ ) { - length = ret.length; - jQuery.find( selector, this[i], ret ); - - if ( i > 0 ) { - // Make sure that the results are unique - for ( n = length; n < ret.length; n++ ) { - for ( r = 0; r < length; r++ ) { - if ( ret[r] === ret[n] ) { - ret.splice(n--, 1); - break; - } - } - } - } - } - - return ret; - }, - - has: function( target ) { - var targets = jQuery( target ); - return this.filter(function() { - for ( var i = 0, l = targets.length; i < l; i++ ) { - if ( jQuery.contains( this, targets[i] ) ) { - return true; - } - } - }); - }, - - not: function( selector ) { - return this.pushStack( winnow(this, selector, false), "not", selector); - }, - - filter: function( selector ) { - return this.pushStack( winnow(this, selector, true), "filter", selector ); - }, - - is: function( selector ) { - return !!selector && ( typeof selector === "string" ? - jQuery.filter( selector, this ).length > 0 : - this.filter( selector ).length > 0 ); - }, - - closest: function( selectors, context ) { - var ret = [], i, l, cur = this[0]; - - // Array - if ( jQuery.isArray( selectors ) ) { - var match, selector, - matches = {}, - level = 1; - - if ( cur && selectors.length ) { - for ( i = 0, l = selectors.length; i < l; i++ ) { - selector = selectors[i]; - - if ( !matches[ selector ] ) { - matches[ selector ] = POS.test( selector ) ? - jQuery( selector, context || this.context ) : - selector; - } - } - - while ( cur && cur.ownerDocument && cur !== context ) { - for ( selector in matches ) { - match = matches[ selector ]; - - if ( match.jquery ? match.index( cur ) > -1 : jQuery( cur ).is( match ) ) { - ret.push({ selector: selector, elem: cur, level: level }); - } - } - - cur = cur.parentNode; - level++; - } - } - - return ret; - } - - // String - var pos = POS.test( selectors ) || typeof selectors !== "string" ? - jQuery( selectors, context || this.context ) : - 0; - - for ( i = 0, l = this.length; i < l; i++ ) { - cur = this[i]; - - while ( cur ) { - if ( pos ? pos.index(cur) > -1 : jQuery.find.matchesSelector(cur, selectors) ) { - ret.push( cur ); - break; - - } else { - cur = cur.parentNode; - if ( !cur || !cur.ownerDocument || cur === context || cur.nodeType === 11 ) { - break; - } - } - } - } - - ret = ret.length > 1 ? jQuery.unique( ret ) : ret; - - return this.pushStack( ret, "closest", selectors ); - }, - - // Determine the position of an element within - // the matched set of elements - index: function( elem ) { - if ( !elem || typeof elem === "string" ) { - return jQuery.inArray( this[0], - // If it receives a string, the selector is used - // If it receives nothing, the siblings are used - elem ? jQuery( elem ) : this.parent().children() ); - } - // Locate the position of the desired element - return jQuery.inArray( - // If it receives a jQuery object, the first element is used - elem.jquery ? elem[0] : elem, this ); - }, - - add: function( selector, context ) { - var set = typeof selector === "string" ? - jQuery( selector, context ) : - jQuery.makeArray( selector && selector.nodeType ? [ selector ] : selector ), - all = jQuery.merge( this.get(), set ); - - return this.pushStack( isDisconnected( set[0] ) || isDisconnected( all[0] ) ? - all : - jQuery.unique( all ) ); - }, - - andSelf: function() { - return this.add( this.prevObject ); - } -}); - -// A painfully simple check to see if an element is disconnected -// from a document (should be improved, where feasible). -function isDisconnected( node ) { - return !node || !node.parentNode || node.parentNode.nodeType === 11; -} - -jQuery.each({ - parent: function( elem ) { - var parent = elem.parentNode; - return parent && parent.nodeType !== 11 ? parent : null; - }, - parents: function( elem ) { - return jQuery.dir( elem, "parentNode" ); - }, - parentsUntil: function( elem, i, until ) { - return jQuery.dir( elem, "parentNode", until ); - }, - next: function( elem ) { - return jQuery.nth( elem, 2, "nextSibling" ); - }, - prev: function( elem ) { - return jQuery.nth( elem, 2, "previousSibling" ); - }, - nextAll: function( elem ) { - return jQuery.dir( elem, "nextSibling" ); - }, - prevAll: function( elem ) { - return jQuery.dir( elem, "previousSibling" ); - }, - nextUntil: function( elem, i, until ) { - return jQuery.dir( elem, "nextSibling", until ); - }, - prevUntil: function( elem, i, until ) { - return jQuery.dir( elem, "previousSibling", until ); - }, - siblings: function( elem ) { - return jQuery.sibling( elem.parentNode.firstChild, elem ); - }, - children: function( elem ) { - return jQuery.sibling( elem.firstChild ); - }, - contents: function( elem ) { - return jQuery.nodeName( elem, "iframe" ) ? - elem.contentDocument || elem.contentWindow.document : - jQuery.makeArray( elem.childNodes ); - } -}, function( name, fn ) { - jQuery.fn[ name ] = function( until, selector ) { - var ret = jQuery.map( this, fn, until ), - // The variable 'args' was introduced in - // https://github.com/jquery/jquery/commit/52a0238 - // to work around a bug in Chrome 10 (Dev) and should be removed when the bug is fixed. - // http://code.google.com/p/v8/issues/detail?id=1050 - args = slice.call(arguments); - - if ( !runtil.test( name ) ) { - selector = until; - } - - if ( selector && typeof selector === "string" ) { - ret = jQuery.filter( selector, ret ); - } - - ret = this.length > 1 && !guaranteedUnique[ name ] ? jQuery.unique( ret ) : ret; - - if ( (this.length > 1 || rmultiselector.test( selector )) && rparentsprev.test( name ) ) { - ret = ret.reverse(); - } - - return this.pushStack( ret, name, args.join(",") ); - }; -}); - -jQuery.extend({ - filter: function( expr, elems, not ) { - if ( not ) { - expr = ":not(" + expr + ")"; - } - - return elems.length === 1 ? - jQuery.find.matchesSelector(elems[0], expr) ? [ elems[0] ] : [] : - jQuery.find.matches(expr, elems); - }, - - dir: function( elem, dir, until ) { - var matched = [], - cur = elem[ dir ]; - - while ( cur && cur.nodeType !== 9 && (until === undefined || cur.nodeType !== 1 || !jQuery( cur ).is( until )) ) { - if ( cur.nodeType === 1 ) { - matched.push( cur ); - } - cur = cur[dir]; - } - return matched; - }, - - nth: function( cur, result, dir, elem ) { - result = result || 1; - var num = 0; - - for ( ; cur; cur = cur[dir] ) { - if ( cur.nodeType === 1 && ++num === result ) { - break; - } - } - - return cur; - }, - - sibling: function( n, elem ) { - var r = []; - - for ( ; n; n = n.nextSibling ) { - if ( n.nodeType === 1 && n !== elem ) { - r.push( n ); - } - } - - return r; - } -}); - -// Implement the identical functionality for filter and not -function winnow( elements, qualifier, keep ) { - - // Can't pass null or undefined to indexOf in Firefox 4 - // Set to 0 to skip string check - qualifier = qualifier || 0; - - if ( jQuery.isFunction( qualifier ) ) { - return jQuery.grep(elements, function( elem, i ) { - var retVal = !!qualifier.call( elem, i, elem ); - return retVal === keep; - }); - - } else if ( qualifier.nodeType ) { - return jQuery.grep(elements, function( elem, i ) { - return (elem === qualifier) === keep; - }); - - } else if ( typeof qualifier === "string" ) { - var filtered = jQuery.grep(elements, function( elem ) { - return elem.nodeType === 1; - }); - - if ( isSimple.test( qualifier ) ) { - return jQuery.filter(qualifier, filtered, !keep); - } else { - qualifier = jQuery.filter( qualifier, filtered ); - } - } - - return jQuery.grep(elements, function( elem, i ) { - return (jQuery.inArray( elem, qualifier ) >= 0) === keep; - }); -} - - - - -var rinlinejQuery = / jQuery\d+="(?:\d+|null)"/g, - rleadingWhitespace = /^\s+/, - rxhtmlTag = /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/ig, - rtagName = /<([\w:]+)/, - rtbody = /", "" ], - legend: [ 1, "
      ", "
      " ], - thead: [ 1, "", "
      " ], - tr: [ 2, "", "
      " ], - td: [ 3, "", "
      " ], - col: [ 2, "", "
      " ], - area: [ 1, "", "" ], - _default: [ 0, "", "" ] - }; - -wrapMap.optgroup = wrapMap.option; -wrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead; -wrapMap.th = wrapMap.td; - -// IE can't serialize and - Hidden frame for Browser History support. - - diff --git a/client/client/src/js/swf/playerProductInstall.swf b/client/client/src/js/swf/playerProductInstall.swf deleted file mode 100644 index bdc3437856cb0ae54bb9423700ba6ec89f35282c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 657 zcmV;C0&e|7S5pT30{{ScoOM%8YZE~jel|&yP13aKhpyI8)Pu*a7cZru!IYFhQ!%kE z;zt>GCuViByG~|XgJ(bJp~q+`f){V4c=Tk!n-K9Tcv0|Qh}4-)Z5q%$%)ak4^FGh} zG4mKh>p=QFFsz{%nRVYDpaejJ54{eo7BqCbU1T$6A?_UfdU|tzr7->Edg5~QJ`!s!OO;20fpVHsv=YsdQ{lvI<6(v2yrdS7`6LQi8#uy`}SX?Ni6O)r6`%Pye4YxmY_|vs1r$ zYS62JJit*Qq5)1^TgC)o6KZQEG=%VHP4mC>rXSoh>x{G-y~501s42xbb%oj5teYed zUazfuM*8z%%PQW6Lm}m@hf8V%w#-l*H+45VumzOSNh6MI zfwTnD68J}cRU>5EordGe5i?c`=PYmF$$^*q^20~+G3o1>u%sdEL~sE;XrvE~96_TY z1oQ%v(6hbD$HElG!xl|cjZOyoWIw@E;qK|`oT|Xk&*+o6#W@8T{oeJ8I9m-_V~Lc) rrowHdr=QEu;UGRC%}bhmYZ>GFiMOQQ+m?EJQA~aL;e`Gll9T{P!97I~ diff --git a/client/client/src/js/swf/swfobject.js b/client/client/src/js/swf/swfobject.js deleted file mode 100644 index 839d82f3..00000000 --- a/client/client/src/js/swf/swfobject.js +++ /dev/null @@ -1,4 +0,0 @@ -/* SWFObject v2.2 beta1 - is released under the MIT License -*/ -var 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;Y0){for(var af=0;af0){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'}}aa.outerHTML='"+af+"";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\ - \ -
      \ - \ -
      \ - \ - '); - // Is all right? - if (this.onMove == null) { - this.debug([1,8]); - return; - } - // --- - this.leftBegun = this.gebi(this.LEFT_BEGUN_PREFIX + this.id); - if (this.leftBegun == null) { - this.debug([1,2]); - return; - } - this.rightBegun = this.gebi(this.RIGHT_BEGUN_PREFIX + this.id); - if (this.rightBegun == null) { - this.debug([1,3]); - return; - } - this.leftBlock = this.gebi(this.LEFT_BLOCK_PREFIX + this.id); - if (this.leftBlock == null) { - this.debug([1,4]); - return; - } - this.rightBlock = this.gebi(this.RIGHT_BLOCK_PREFIX + this.id); - if (this.rightBlock == null) { - this.debug([1,5]); - return; - } - this.centerBlock = this.gebi(this.CENTER_BLOCK_PREFIX + this.id); - if (this.centerBlock == null) { - this.debug([1,9]); - return; - } - // --- - if (!this.width) { - this.debug([1,6]); - return; - } - if (!this.rightLimit) { - this.debug([1,7]); - return; - } - // Set default - this.valueWidth = this.width - 2 * this.widthRem; - this.rightValue = hash.rightValue || this.rightLimit; - this.leftValue = hash.leftValue || this.leftLimit; - if (!this.dual) this.rightValue = this.leftValue; - this.valueInterval = this.rightLimit - this.leftLimit; - this.leftWidth = parseInt((this.leftValue - this.leftLimit) / this.valueInterval * this.valueWidth) + this.widthRem; - this.rightWidth = this.valueWidth - parseInt((this.rightValue - this.leftLimit) / this.valueInterval * this.valueWidth) + this.widthRem; - // Set limits - if (!this.clearLimits) { - this.leftBlock.firstChild.nextSibling.innerHTML = this.leftLimit; - this.rightBlock.firstChild.nextSibling.innerHTML = this.rightLimit; - } - // Do it! - this.setCurrentState(); - this.onMove(); - // Add handers - var _this = this; - this.addHandler ( - document, - "mousemove", - function(evt) { - if (_this.moveState) _this.moveHandler(evt); - if (_this.moveIntervalState) _this.moveIntervalHandler(evt); - } - ); - this.addHandler ( - document, - "mouseup", - function() { - _this.moveState = false; - _this.moveIntervalState = false; - } - ); - this.addHandler ( - this.leftBegun, - "mousedown", - function(evt) { - evt = evt || window.event; - if (evt.preventDefault) evt.preventDefault(); - evt.returnValue = false; - _this.moveState = "left"; - _this.x0 = _this.defPosition(evt).x; - _this.blockX0 = _this.leftWidth; - } - ); - this.addHandler ( - this.rightBegun, - "mousedown", - function(evt) { - evt = evt || window.event; - if (evt.preventDefault) evt.preventDefault(); - evt.returnValue = false; - _this.moveState = "right"; - _this.x0 = _this.defPosition(evt).x; - _this.blockX0 = _this.rightWidth; - } - ); - this.addHandler ( - this.centerBlock, - "mousedown", - function(evt) { - evt = evt || window.event; - if (evt.preventDefault) evt.preventDefault(); - evt.returnValue = false; - _this.moveIntervalState = true; - _this.intervalWidth = _this.width - _this.rightWidth - _this.leftWidth; - _this.x0 = _this.defPosition(evt).x; - _this.rightX0 = _this.rightWidth; - _this.leftX0 = _this.leftWidth; - } - ), - this.addHandler ( - this.centerBlock, - "click", - function(evt) { - if (!_this.itWasMove) _this.clickMove(evt); - _this.itWasMove = false; - } - ); - this.addHandler ( - this.leftBlock, - "click", - function(evt) { - if (!_this.itWasMove)_this.clickMoveLeft(evt); - _this.itWasMove = false; - } - ); - this.addHandler ( - this.rightBlock, - "click", - function(evt) { - if (!_this.itWasMove)_this.clickMoveRight(evt); - _this.itWasMove = false; - } - ); - } catch(e) {this.debug([1]);} - }, - clickMoveRight : function(evt) { - evt = evt || window.event; - if (evt.preventDefault) evt.preventDefault(); - evt.returnValue = false; - var x = this.defPosition(evt).x - this.absPosition(this.rightBlock).x; - var w = this.rightBlock.offsetWidth; - if (x <= 0 || w <= 0 || w < x || (w - x) < this.widthRem) return; - this.rightWidth = (w - x); - this.rightCounter(); - - this.setCurrentState(); - this.onMove(); - }, - clickMoveLeft : function(evt) { - evt = evt || window.event; - if (evt.preventDefault) evt.preventDefault(); - evt.returnValue = false; - var x = this.defPosition(evt).x - this.absPosition(this.leftBlock).x; - var w = this.leftBlock.offsetWidth; - if (x <= 0 || w <= 0 || w < x || x < this.widthRem) return; - this.leftWidth = x; - this.leftCounter(); - - this.setCurrentState(); - this.onMove(); - }, - clickMove : function(evt) { - evt = evt || window.event; - if (evt.preventDefault) evt.preventDefault(); - evt.returnValue = false; - var x = this.defPosition(evt).x - this.absPosition(this.centerBlock).x; - var w = this.centerBlock.offsetWidth; - if (x <= 0 || w <= 0 || w < x) return; - if (x >= w / 2) { - this.rightWidth += (w - x); - this.rightCounter(); - } else { - this.leftWidth += x; - this.leftCounter(); - } - this.setCurrentState(); - this.onMove(); - }, - setCurrentState : function() { - this.leftBlock.style.width = this.leftWidth + "px"; - if (!this.clearValues) this.leftBlock.firstChild.innerHTML = (!this.dual && this.leftWidth > this.width / 2) ? "" : this.leftValue; - if(!this.dual) { - var x = this.leftBlock.firstChild.offsetWidth; - this.leftBlock.firstChild.style.right = (this.widthRem * (1 - 2 * (this.leftWidth - this.widthRem) / this.width) - ((this.leftWidth - this.widthRem) * x / this.width)) + 'px'; - } - this.rightBlock.style.width = this.rightWidth + "px"; - if (!this.clearValues) this.rightBlock.firstChild.innerHTML = (!this.dual && this.rightWidth >= this.width / 2) ? "" : this.rightValue; - if(!this.dual) { - var x = this.rightBlock.firstChild.offsetWidth; - this.rightBlock.firstChild.style.left = (this.widthRem * (1 - 2 * (this.rightWidth - this.widthRem) / this.width) - ((this.rightWidth - this.widthRem) * x / this.width)) + 'px'; - } - }, - /* OLD setCurrentState : function() { - this.leftBlock.style.width = this.leftWidth + "px"; - this.leftBlock.firstChild.innerHTML = (!this.dual && this.leftWidth > this.width / 2) ? "" : this.leftValue; - this.rightBlock.style.width = this.rightWidth + "px"; - this.rightBlock.firstChild.innerHTML = (!this.dual && this.rightWidth >= this.width / 2) ? "" : this.rightValue; - },*/ - moveHandler : function(evt) { - this.itWasMove = true; - evt = evt || window.event; - if (evt.preventDefault) evt.preventDefault(); - evt.returnValue = false; - if (this.moveState == "left") { - this.leftWidth = this.blockX0 + this.defPosition(evt).x - this.x0; - this.leftCounter(); - } - if (this.moveState == "right") { - this.rightWidth = this.blockX0 + this.x0 - this.defPosition(evt).x; - this.rightCounter(); - } - this.setCurrentState(); - this.onMove(); - }, - moveIntervalHandler : function(evt) { - this.itWasMove = true; - evt = evt || window.event; - if (evt.preventDefault) evt.preventDefault(); - evt.returnValue = false; - var dX = this.defPosition(evt).x - this.x0; - if (dX > 0) { - this.rightWidth = this.rightX0 - dX > this.widthRem ? this.rightX0 - dX : this.widthRem; - this.leftWidth = this.width - this.rightWidth - this.intervalWidth; - } else { - this.leftWidth = this.leftX0 + dX > this.widthRem ? this.leftX0 + dX : this.widthRem; - this.rightWidth = this.width - this.leftWidth - this.intervalWidth; - } - this.rightCounter(); - this.leftCounter(); - this.setCurrentState(); - this.onMove(); - }, - rightCounter : function() { - if (this.dual) { - this.rightWidth = this.rightWidth > this.width - this.leftWidth ? this.width - this.leftWidth : this.rightWidth; - this.rightWidth = this.rightWidth < this.widthRem ? this.widthRem : this.rightWidth; - this.rightValue = this.leftLimit + this.valueInterval - parseInt((this.rightWidth - this.widthRem) / this.valueWidth * this.valueInterval); - if (this.roundUp) this.rightValue = parseInt(this.rightValue / this.roundUp) * this.roundUp; - if (this.leftWidth + this.rightWidth >= this.width) this.rightValue = this.leftValue; - } else { - this.rightWidth = this.rightWidth > (this.width - this.widthRem) ? this.width - this.widthRem : this.rightWidth; - this.rightWidth = this.rightWidth < this.widthRem ? this.widthRem : this.rightWidth; - this.leftWidth = this.width - this.rightWidth; - this.rightValue = this.leftLimit + this.valueInterval - parseInt((this.rightWidth - this.widthRem) / this.valueWidth * this.valueInterval); - if (this.roundUp) this.rightValue = parseInt(this.rightValue / this.roundUp) * this.roundUp; - this.leftValue = this.rightValue; - } - }, - leftCounter : function() { - if (this.dual) { - this.leftWidth = this.leftWidth > this.width - this.rightWidth ? this.width - this.rightWidth : this.leftWidth; - this.leftWidth = this.leftWidth < this.widthRem ? this.widthRem : this.leftWidth; - this.leftValue = this.leftLimit + parseInt((this.leftWidth - this.widthRem) / this.valueWidth * this.valueInterval); - if (this.roundUp) this.leftValue = parseInt(this.leftValue / this.roundUp) * this.roundUp; - if (this.leftWidth + this.rightWidth >= this.width) this.leftValue = this.rightValue; - } else { - this.leftWidth = this.leftWidth > (this.width - this.widthRem) ? this.width - this.widthRem : this.leftWidth; - this.leftWidth = this.leftWidth < this.widthRem ? this.widthRem : this.leftWidth; - this.rightWidth = this.width - this.leftWidth; - this.leftValue = this.leftLimit + parseInt((this.leftWidth - this.widthRem) / this.valueWidth * this.valueInterval); - if (this.roundUp) this.leftValue = parseInt(this.leftValue / this.roundUp) * this.roundUp; - this.rightValue = this.leftValue; - } - } -} \ No newline at end of file diff --git a/client/client/src/js/ui/UIManagerFlash.js b/client/client/src/js/ui/UIManagerFlash.js deleted file mode 100644 index b2d469c0..00000000 --- a/client/client/src/js/ui/UIManagerFlash.js +++ /dev/null @@ -1,87 +0,0 @@ -/** - Copyright (c) 2013 Flashphoner - All rights reserved. This Code and the accompanying materials - are made available under the terms of the GNU Public License v2.0 - which accompanies this distribution, and is available at - http://www.gnu.org/licenses/old-licenses/gpl-2.0.html - - Contributors: - Flashphoner - initial API and implementation - - This code and accompanying materials also available under LGPL and MPL license for Flashphoner buyers. Other license versions by negatiation. Write us support@flashphoner.com with any questions. - */ -var UIManagerFlash = function () { - this.requestUnmute = function() { - trace("UIManagerFlash - requestUnmute"); - - $('#video_requestUnmuteDiv').removeClass().addClass('securityDiv'); - $('#closeButton_video_requestUnmuteDiv').css('visibility', 'hidden'); - $('#sendVideo').css('visibility', 'hidden'); - $('#requestUnmuteText').show(); - - $('#video').width(214); - $('#video').height(138); - getElement('video').style.top = "35px"; - - flashphoner.getAccessToAudioAndVideo(); - }; -} - -UIManagerFlash.prototype = { - requestUnmuteC2C: function() { - trace("UIManagerFlash - requestUnmuteC2C"); - $('.back').show(); - $('.request').show(); - $('#flash').removeClass('init').addClass('security'); - flashphoner.getAccessToAudioAndVideo(); - }, - - getAccessToAudioAndVideo: function() { - this.requestUnmute(); - }, - - getAccessToAudio: function() { - this.requestUnmute(); - }, - - getAccessToVideo: function() { - this.requestUnmute(); - }, - - - openVideoView: function() { - if (flashphoner.hasAccessToVideo()) { - flashphoner.viewVideo(); - $('#video_requestUnmuteDiv').removeClass().addClass('videoDiv'); - $('#closeButton_video_requestUnmuteDiv').css('visibility', 'visible'); - - $('#sendVideo').css('visibility', 'visible'); - $('#requestUnmuteText').hide(); - $('#video_requestUnmuteDiv .bar').html('  Video'); - - if (proportion != 0) { - var newHeight = $('.videoDiv').width() * proportion + 40; - $('.videoDiv').height(newHeight); //we resize video window for new proportion - } - $('#video_requestUnmuteDiv').resize(); - } else { - this.requestUnmute(); - if (intervalId == -1) { - intervalId = setInterval('if (flashphoner.hasAccessToVideo()){flashphoner_UI.closeRequestUnmute(); clearInterval(intervalId); intervalId = -1; flashphoner_UI.openVideoView();}', 500); - } - } - }, - - closeRequestUnmute: function() { - trace("UIManagerFlash - closeRequestUnmute"); - $('#video_requestUnmuteDiv').removeClass().addClass('closed'); - getElement('video').style.top = "20px"; - }, - - closeRequestUnmuteC2C: function() { - trace("UIManagerFlash - closeRequestUnmuteC2C"); - $('.back').hide(); - $('.request').hide(); - $('#flash').addClass('init').removeClass('security'); - } - }; \ No newline at end of file diff --git a/client/client/src/js/ui/UIManagerWebRtc.js b/client/client/src/js/ui/UIManagerWebRtc.js deleted file mode 100644 index 265a4c03..00000000 --- a/client/client/src/js/ui/UIManagerWebRtc.js +++ /dev/null @@ -1,66 +0,0 @@ -/** - Copyright (c) 2013 Flashphoner - All rights reserved. This Code and the accompanying materials - are made available under the terms of the GNU Public License v2.0 - which accompanies this distribution, and is available at - http://www.gnu.org/licenses/old-licenses/gpl-2.0.html - - Contributors: - Flashphoner - initial API and implementation - - This code and accompanying materials also available under LGPL and MPL license for Flashphoner buyers. Other license versions by negatiation. Write us support@flashphoner.com with any questions. - */ -var UIManagerWebRtc = function () { - -} - -UIManagerWebRtc.prototype = { - requestUnmuteC2C: function() { - trace("UIManagerWebRTC - requestUnmute"); - openInfoView("Please allow access to media devices", 0, 60); - flashphoner.getAccessToAudio(); - }, - - getAccessToAudioAndVideo: function() { - trace("UIManagerWebRTC - getAccessToAudio"); - openInfoView("Please allow access to audio and video devices", 0, 60); - flashphoner.getAccessToAudioAndVideo(); - }, - - getAccessToAudio: function() { - trace("UIManagerWebRTC - getAccessToAudio"); - openInfoView("Please allow access to audio device", 0, 60); - flashphoner.getAccessToAudio(); - }, - - openVideoView: function() { - trace("UIManagerWebRTC - openVideoView"); - if (!flashphoner.hasAccessToVideo()){ - openInfoView("Please allow access to video device", 0, 60); - flashphoner.getAccessToAudioAndVideo(); - if (intervalId == -1) { - intervalId = setInterval('if (flashphoner.hasAccessToVideo()){flashphoner_UI.closeRequestUnmute(); clearInterval(intervalId); intervalId = -1; }', 500); - } - } - - $('#video_requestUnmuteDiv').removeClass().addClass('videoDiv'); - $('#closeButton_video_requestUnmuteDiv').css('visibility', 'visible'); - - $('#requestUnmuteText').hide(); - $('#video_requestUnmuteDiv .bar').html('  Video'); - - if (proportion != 0) { - var newHeight = $('.videoDiv').width() * proportion + 40; - $('.videoDiv').height(newHeight); //we resize video window for new proportion - } - $('#video_requestUnmuteDiv').resize(); - }, - - closeRequestUnmute: function() { - closeInfoView(); - }, - - closeRequestUnmuteC2C: function() { - this.closeRequestUnmute(); - } -}; \ No newline at end of file diff --git a/client/client/src/js/ws/Messenger.js b/client/client/src/js/ws/Messenger.js deleted file mode 100644 index c1c6f40b..00000000 --- a/client/client/src/js/ws/Messenger.js +++ /dev/null @@ -1,136 +0,0 @@ -/** - * Created with JetBrains WebStorm. - * User: Alex - * Date: 6/10/13 - * Time: 3:09 PM - * To change this template use File | Settings | File Templates. - */ -var Messenger = function (flashphoner) { - this.sentMessages = new Object(); -}; - -Messenger.prototype = { - - notifyMessage: function (message, notificationResult, sipObject) { - trace("Messenger - notifyMessage message: "+ message+" notificationResult: "+ notificationResult+" sipObject: "+ sipObject); - var sentMessage = this.sentMessages[message.id]; - if (sentMessage != null) { - sentMessage.state = message.state; - } - if (message.state == "SENT") { - this.notifySent(sentMessage); - } else if (message.state == "ACCEPTED") { - this.notifyAccepted(sentMessage); - } else if (message.state == "FAILED") { - this.notifyFailed(sentMessage); - } else if (message.state == "IMDN_DELIVERED") { - this.notifyDelivered(message, notificationResult); - } else if (message.state == "IMDN_FAILED" || message.state == "IMDN_FORBIDDEN" || message.state == "IMDN_ERROR") { - this.notifyDeliveryFailed(message.notificationResult); - } else if (message.state == "RECEIVED") { - //here we will choose what to display on multiple contacts in "from". - if (message.from.indexOf(",") != -1) { - var fromList = message.from.split(","); - message.from = fromList[0]; - } - //Don't show service message to user - if (message.contentType.toLowerCase() == "message/fsservice+xml") { - console.log("Received service message"); - } else { - this.notifyReceived(message, notificationResult); - } - } - }, - - notifyReceived: function (message, notificationResult) { - //received message - //send OK result on MESSAGE request - notifyMessageReceived(message); - this.sendOkResult(notificationResult); - }, - - notifyDeliveryFailed: function (sentMessage, notificationResult) { - if (sentMessage != null) { - //send OK result on IMDN request - notifyMessageDeliveryFailed(sentMessage); - this.removeSentMessage(sentMessage); - this.sendOkResult(notificationResult); - } - }, - - notifyDelivered: function (sentMessage, notificationResult) { - if (sentMessage != null) { - //send OK result on IMDN request - notifyMessageDelivered(sentMessage); - this.removeSentMessage(sentMessage); - this.sendOkResult(notificationResult); - } - }, - - notifyFailed: function (sentMessage) { - if (sentMessage != null) { - notifyMessageFailed(sentMessage); - this.removeSentMessage(sentMessage); - } - }, - - notifySent: function (sentMessage) { - if (sentMessage != null) { - notifyMessageSent(sentMessage); - } - }, - - notifyAccepted: function (sentMessage) { - if (sentMessage != null) { - notifyMessageAccepted(sentMessage); - if (!sentMessage.deliveryNotification) { - this.removeSentMessage(sentMessage); - } - } - }, - - removeSentMessage: function (sentMessage) { - setTimeout(function () { - messenger.sentMessages[sentMessage.id] = null; - }, 5000); - }, - - sendOkResult: function (notificationResult) { - notificationResult.status = "OK"; - this.sendResult(notificationResult); - }, - - sendResult: function (result) { - flashphoner.notificationResult(result); - }, - - sendMessage: function (message) { - this.saveSentMessage(message); - try { - flashphoner.sendMessage(message); - } catch (error) { - trace("Messenger - sending message error: "+error); - } - }, - - saveSentMessage: function (message) { - var id = this.createUUID(); - message.id = id; - this.sentMessages[id] = message; - }, - - createUUID: function () { - var s = []; - var hexDigits = "0123456789abcdef"; - for (var i = 0; i < 36; i++) { - s[i] = hexDigits.substr(Math.floor(Math.random() * 0x10), 1); - } - s[14] = "4"; - s[19] = hexDigits.substr((s[19] & 0x3) | 0x8, 1); - s[8] = s[13] = s[18] = s[23] = "-"; - - var uuid = s.join(""); - - return uuid.substring(0, 18); - } -} \ No newline at end of file diff --git a/client/client/src/js/ws/SoundControl.js b/client/client/src/js/ws/SoundControl.js deleted file mode 100644 index 1b79cf3d..00000000 --- a/client/client/src/js/ws/SoundControl.js +++ /dev/null @@ -1,79 +0,0 @@ -/* - Copyright (c) 2011 Flashphoner - All rights reserved. This Code and the accompanying materials - are made available under the terms of the GNU Public License v2.0 - which accompanies this distribution, and is available at - http://www.gnu.org/licenses/old-licenses/gpl-2.0.html - - Contributors: - Flashphoner - initial API and implementation - - This code and accompanying materials also available under LGPL and MPL license for Flashphoner buyers. Other license versions by negatiation. Write us support@flashphoner.com with any questions. - */ -var SoundControl = function () { - me = this; - //Init sounds - me.registerSound = me.initSound(flashphonerLoader.registerSound, false, "auto"); - me.ringSound = me.initSound(flashphonerLoader.ringSound, true, "none"); - me.busySound = me.initSound(flashphonerLoader.busySound, false, "none"); - me.finishSound = me.initSound(flashphonerLoader.finishSound, false, "none"); -}; - -SoundControl.prototype = { - - //Creates HTML5 audio tag - initSound: function (src, loop, preload) { - if (typeof loop == 'undefined') { - loop = false; - } - var audioTag = document.createElement("audio"); - audioTag.autoplay = false; - audioTag.preload = preload; - if (loop) { - audioTag.loop = true; - } - //add src tag to audio tag - audioTag.src = src; - document.body.appendChild(audioTag); - return audioTag; - }, - - //plays audio - playSound: function (soundName) { - switch (soundName) { - case "RING": - if (!flashphonerLoader.disableLocalRing){ - me.ringSound.play(); - } - break - case "BUSY": - me.busySound.play(); - break - case "REGISTER": - me.registerSound.play(); - break - case "FINISH": - me.finishSound.play(); - break - default: - console.error("Do not know what to play on " + soundName); - - } - }, - - //stops audio - stopSound: function (soundName) { - trace("stopSound soundName: "+soundName+" me: "+me+" me.ringSound: "+me.ringSound); - switch (soundName) { - case "RING": - if (me.ringSound && !me.ringSound.paused) { - me.ringSound.pause(); - me.ringSound.currentTime = 0; - } - break; - default: - console.error("Do not know what to stop on " + soundName); - - } - } -}; \ No newline at end of file diff --git a/client/client/src/js/ws/WebSocketManager.js b/client/client/src/js/ws/WebSocketManager.js deleted file mode 100644 index 3f7e2d11..00000000 --- a/client/client/src/js/ws/WebSocketManager.js +++ /dev/null @@ -1,465 +0,0 @@ -var WebSocketManager = function (localVideoPreview, remoteVideo) { - var me = this; - me.calls = []; - me.isOpened = false; - me.configLoaded = false; - me.webRtcMediaManager = new WebRtcMediaManager(localVideoPreview, remoteVideo); - me.soundControl = new SoundControl(); - me.stripCodecs = new Array(); - - var rtcManager = this.webRtcMediaManager; - var proccessCall = function (call) { - for (var i in me.calls) { - if (call.id == me.calls[i].id) { - me.calls[i] = call; - return; - } - } - me.calls.push(call); - notifyAddCall(call); - }; - - var getCall = function (callId) { - for (var i in me.calls) { - if (callId == me.calls[i].id) { - return me.calls[i]; - } - } - }; - - var removeCall = function (callId) { - for (var i in me.calls) { - if (callId == me.calls[i].id) { - me.calls.splice(i, 1); - } - } - if (me.calls.length == 0) { - rtcManager.close(); - } - }; - - this.callbacks = { - ping: function () { - me.webSocket.send("pong"); - }, - - getUserData: function (user) { - me.user = user; - notifyRegisterRequired(user.regRequired); - notifyConnected(); - }, - - getVersion: function (version) { - notifyVersion(version); - }, - - registered: function (sipHeader) { - notifyRegistered(sipHeader); - }, - - ring: function (call, sipHeader) { - trace("ring call.state: "+call.state+" call.id: "+call.id ) - proccessCall(call); - notify(call); - }, - - sessionProgress: function (call, sipHeader) { - trace("sessionProgress call.state: "+call.state+" call.id: "+call.id ) - proccessCall(call); - notify(call); - }, - - setRemoteSDP: function (call, sdp, isInitiator, sipHeader) { - proccessCall(call); - this.stopSound("RING"); - rtcManager.setRemoteSDP(sdp, isInitiator); - if (!isInitiator && rtcManager.getConnectionState() == "established") { - me.answer(call.id); - } - }, - - talk: function (call, sipHeader) { - proccessCall(call); - notify(call); - }, - - hold: function (call, sipHeader) { - proccessCall(call); - notify(call); - }, - - callbackHold: function (callId, isHold) { - var call = getCall(callId); - notifyCallbackHold(call, isHold); - }, - - finish: function (call, sipHeader) { - proccessCall(call); - notify(call); - notifyRemoveCall(call); - removeCall(call.id); - }, - - busy: function (call, sipHeader) { - proccessCall(call); - notify(call); - }, - - fail: function (errorCode, sipHeader) { - notifyError(errorCode); - }, - - notifyVideoFormat: function (videoFormat) { - //notifyVideoFormat(videoFormat); - }, - - notifyBugReport: function (filename) { - notifyBugReport(filename); - }, - - notifyMessage: function (message, notificationResult, sipObject) { - messenger.notifyMessage(message, notificationResult, sipObject); - }, - - notifyAudioCodec: function (codec) { - }, - - notifySubscription: function (subscriptionObject, sipObject) { - notifySubscription(subscriptionObject, sipObject); - }, - - notifyXcapResponse: function (xcapResponse) { - notifyXcapResponse(xcapResponse); - } - }; - - -}; - -WebSocketManager.prototype = { - - login: function (loginObject, WCSUrl) { - var me = this; - me.webSocket = $.websocket(WCSUrl, { - open: function () { - me.isOpened = true; - me.webSocket.send("connect", loginObject); - }, - close: function (event) { - me.isOpened = false; - if (!event.originalEvent.wasClean) { - notifyError(CONNECTION_ERROR); - } - notifyCloseConnection(); - me.webRtcMediaManager.close(); - }, - error: function () { - }, - context: me, - events: me.callbacks - }); - return 0; - }, - - loginByToken: function (WCSUrl, token, pageUrl) { - var me = this; - var obj = {}; - obj.token = token; - obj.pageUrl = pageUrl; - - me.login(obj, WCSUrl); - return 0; - }, - - callByToken: function (callRequest) { - var me = this; - openInfoView("Configuring WebRTC connection...", 0); - this.webRtcMediaManager.createOffer(function (sdp) { - closeInfoView(); - callRequest.sdp = sdp; - me.webSocket.send("call", callRequest); - }, false); - return 0; - - }, - - logoff: function () { - trace("WebSocketManager - logoff"); - this.webSocket.close(); - }, - - subscribe: function (subscribeObject) { - this.webSocket.send("subscribe", subscribeObject); - }, - - sendXcapRequest: function (xcapUrl) { - this.webSocket.send("sendXcapRequest", xcapUrl); - }, - - call: function (callRequest) { - var me = this; - openInfoView("Configuring WebRTC connection...", 0, 60); - this.webRtcMediaManager.createOffer(function (sdp) { - closeInfoView(); - //here we will strip codecs from SDP if requested - if (me.stripCodecs.length) { - sdp = me.stripCodecsSDP(sdp); - console.log("New SDP: " + sdp); - } - sdp = me.removeCandidatesFromSDP(sdp); - callRequest.sdp = sdp; - me.webSocket.send("call", callRequest); - }, callRequest.hasVideo); - return 0; - }, - - msrpCall: function (callRequest) { - var me = this; - me.webSocket.send("msrpCall", callRequest); - return 0; - }, - - setSendVideo: function (callId, hasVideo) { -// var me = this; -// this.webRtcMediaManager.createOffer(function (sdp) { -// me.webSocket.send("changeMediaRequest", {callId: callId, sdp: sdp}); -// }, hasVideo); -// return 0; - }, - - answer: function (callId, hasVideo) { - var me = this; - openInfoView("Configuring WebRTC connection...", 0, 60); - /** - * If we receive INVITE without SDP, we should send answer with SDP based on webRtcMediaManager.createOffer because we do not have remoteSdp here - */ - if (this.webRtcMediaManager.lastReceivedSdp !== null && this.webRtcMediaManager.lastReceivedSdp.length == 0) { - this.webRtcMediaManager.createOffer(function (sdp) { - closeInfoView(); - //here we will strip codecs from SDP if requested - if (me.stripCodecs.length) { - sdp = me.stripCodecsSDP(sdp); - console.log("New SDP: " + sdp); - } - sdp = me.removeCandidatesFromSDP(sdp); - me.webSocket.send("answer", {callId: callId, hasVideo: hasVideo, sdp: sdp}); - }, hasVideo); - } else { - /** - * If we receive a normal INVITE with SDP we should create answering SDP using normal createAnswer method because we already have remoteSdp here. - */ - this.webRtcMediaManager.createAnswer(function (sdp) { - closeInfoView(); - me.webSocket.send("answer", {callId: callId, hasVideo: hasVideo, sdp: sdp}); - }, hasVideo); - } - }, - - hangup: function (callId) { - if (callId) { - this.webSocket.send("hangup", callId); - } else { - if (this.calls.length == 0) { - closeInfoView(); - toCallState(); - this.webRtcMediaManager.close(); - } - } - }, - - setStatusHold: function (callId, isHold) { - this.webSocket.send("hold", {callId: callId, isHold: isHold}); - }, - - transfer: function (callId, callee) { - this.webSocket.send("transfer", {callId: callId, callee: callee}); - }, - - sendDTMF: function (callId, dtmf) { - this.webSocket.send("sendDtmf", {callId: callId, dtmf: dtmf}); - }, - - setUseProxy: function (useProxy) { - if (this.isOpened) { - this.webSocket.send("setUseProxy", useProxy); - } - }, - - pushLogs: function (logs) { - if (this.isOpened) { - this.webSocket.send("pushLogs", logs) - return true; - } else { - return false; - } - }, - - submitBugReport: function (reportObject) { - if (this.isOpened) { - this.webSocket.send("submitBugReport", reportObject) - return true; - } else { - return false; - } - }, - - setLTState: function (state) { - trace("setLTState: " + state); - this.webSocket.send("setLTState", {state: state}); - }, - - getAccessToAudioAndVideo: function () { - this.webRtcMediaManager.getAccessToAudioAndVideo(); - }, - - getAccessToAudio: function () { - this.webRtcMediaManager.getAccessToAudio(); - }, - - getVolume: function () { - return this.webRtcMediaManager.remoteVideo.volume * 100; - }, - - setVolume: function (value) { - this.webRtcMediaManager.remoteVideo.volume = value / 100; - }, - - hasAccessToAudio: function () { - return this.webRtcMediaManager.isAudioMuted == -1; - }, - - hasAccessToVideo: function () { - return this.webRtcMediaManager.isVideoMuted == -1; - }, - - getInfoAboutMe: function () { - return this.user; - }, - - getCookie: function (c_name) { - var i, x, y, ARRcookies = document.cookie.split(";"); - for (i = 0; i < ARRcookies.length; i++) { - x = ARRcookies[i].substr(0, ARRcookies[i].indexOf("=")); - x = x.replace(/^\s+|\s+$/g, ""); - if (x == c_name) { - return ARRcookies[i].substr(ARRcookies[i].indexOf("=") + 1); - } - } - }, - - setCookie: function (c_name, value) { - var exdate = new Date(); - exdate.setDate(exdate.getDate() + 100); - var c_value = escape(value) + "; expires=" + exdate.toUTCString(); - document.cookie = c_name + "=" + c_value; - }, - - playSound: function (sound) { - this.soundControl.playSound(sound); - }, - - stopSound: function (sound) { - this.soundControl.stopSound(sound); - }, - - sendMessage: function (message) { - this.webSocket.send("sendInstantMessage", message); - }, - - notificationResult: function (result) { - this.webSocket.send("notificationResult", result); - }, - - setStripCodecs: function (array) { - this.stripCodecs = array; - }, - - removeCandidatesFromSDP: function (sdp) { - var sdpArray = sdp.split("\n"); - - for (i = 0; i < sdpArray.length; i++) { - if (sdpArray[i].search("a=candidate:") != -1) { - sdpArray[i] = ""; - } - } - - //normalize sdp after modifications - var result = ""; - for (i = 0; i < sdpArray.length; i++) { - if (sdpArray[i] != "") { - result += sdpArray[i] + "\n"; - } - } - - return result; - }, - - stripCodecsSDP: function (sdp) { - var sdpArray = sdp.split("\n"); - console.dir(this.stripCodecs); - - //search and delete codecs line - var pt = []; - for (p = 0; p < this.stripCodecs.length; p++) { - console.log("Searching for codec " + this.stripCodecs[p]); - for (i = 0; i < sdpArray.length; i++) { - if (sdpArray[i].search(this.stripCodecs[p]) != -1 && sdpArray[i].indexOf("a=rtpmap") == 0) { - console.log(this.stripCodecs[p] + " detected"); - pt.push(sdpArray[i].match(/[0-9]+/)[0]); - sdpArray[i] = ""; - } - } - } - - if (pt.length) { - //searching for fmtp - for (p = 0; p < pt.length; p++) { - for (i = 0; i < sdpArray.length; i++) { - if (sdpArray[i].search("a=fmtp:" + pt[p]) != -1) { - console.log("PT " + pt[p] + " detected"); - sdpArray[i] = ""; - } - if (sdpArray[i].search("a=candidate:") != -1) { - sdpArray[i] = ""; - } - } - } - - //delete entries from m= line - for (i = 0; i < sdpArray.length; i++) { - if (sdpArray[i].search("m=audio") != -1) { - console.log("m line detected " + sdpArray[i]); - var mLineSplitted = sdpArray[i].split(" "); - var newMLine = ""; - for (m = 0; m < mLineSplitted.length; m++) { - if (pt.indexOf(mLineSplitted[m]) == -1 || m <= 2) { - newMLine += mLineSplitted[m]; - if ( m < mLineSplitted.length-1 ){ - newMLine = newMLine + " "; - } - } - } - sdpArray[i]=newMLine; - console.log("Resulting m= line is: " + sdpArray[i]); - break; - } - } - } - - //normalize sdp after modifications - var result = ""; - for (i = 0; i < sdpArray.length; i++) { - if (sdpArray[i] != "") { - result += sdpArray[i] + "\n"; - } - } - - return result; - }, - - setStunServer: function (server) { - this.webRtcMediaManager.setStunServer(server); - } - -}; - diff --git a/client/client/src/phone.mxml b/client/client/src/phone.mxml deleted file mode 100644 index d487016e..00000000 --- a/client/client/src/phone.mxml +++ /dev/null @@ -1,175 +0,0 @@ - - - - - - 0){ - DataPhone.getInstance().viewController.showConnectingView(); - DataPhone.getInstance().flash_API.loginByToken(token); - }else{ - DataPhone.getInstance().viewController.hideConnectingView(); - } - } - } - - private function checkState(event:TimerEvent = null):void{ - if (flash_API.isInitialized()){ - Logger.info("FlashAPI has been initialized"); - flash_API.initMedia(); - dropTimer(); - } - } - - private function onOpenInstantMessageChatView():void{ - if (!flash_API.modelLocator.logged){ - phone(Application.application).onOpenSipAccountView(); - return; - } - var callee:String = mainView.callee.text; - if (((callee != null) && (callee.length > 0)) || (DataPhone.getInstance().tabChatView.size() > 0)){ - PopUpManager.addPopUp(DataPhone.getInstance().tabChatView,this); - PopUpManager.centerPopUp(DataPhone.getInstance().tabChatView); - if ((callee != null) && (callee.length > 0)){ - DataPhone.getInstance().tabChatView.addTab(callee); - } - }else{ - infoView.text = "Enter callee"; - PopUpManager.addPopUp(infoView,DisplayObject(Application.application),true); - PopUpManager.centerPopUp(infoView); - } - } - - private function onOpenMicrophoneSettingsView():void{ - flash_API.soundControl.getMicrophone().setLoopBack(true); - PopUpManager.addPopUp(DataPhone.getInstance().microphoneSettingsView,this); - PopUpManager.centerPopUp(DataPhone.getInstance().microphoneSettingsView); - } - public function onOpenSipAccountView():void{ - if (loginButton.text == "Log in"){ - var token:String; - try{ - if (Application.application.parameters != null && Application.application.parameters.token!=null){ - token = Application.application.parameters.token; - } - } catch (e:Error){ - token = ""; - } - if (token != null && token.length > 0){ - DataPhone.getInstance().viewController.showConnectingView(); - DataPhone.getInstance().flash_API.loginByToken(token); - }else{ - PopUpManager.addPopUp(DataPhone.getInstance().sipAccountView,this); - PopUpManager.centerPopUp(DataPhone.getInstance().sipAccountView); - } - }else{ - logout(); - } - } - public function toLoggedState():void{ - loginButton.text="Log out"; - } - - public function toLoggedOffState():void{ - loginButton.text="Log in"; - } - private function logout():void{ - DataPhone.getInstance().flash_API.logoff(); - toLoggedOffState(); - } - - public function onOpenVideoView():void{ - videoView.init(); - } - - ]]> - - - - - - - - - - - - - - - diff --git a/client/client/src/sounds/BUSY.ogg b/client/client/src/sounds/BUSY.ogg deleted file mode 100644 index 8f3dd0502ea3eb8fd976b6852d454ba7a571cd3f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6741 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 YBS}AP+dhx6L9smU@xIy>=)3fP02#y1FaQ7m diff --git a/client/client/src/sounds/CALL_IN.ogg b/client/client/src/sounds/CALL_IN.ogg deleted file mode 100644 index a343524e0315e001a678cc37a60e45042ea76356..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 28376 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 Fe*jUkQ6~TZ diff --git a/client/client/src/sounds/CALL_OUT.ogg b/client/client/src/sounds/CALL_OUT.ogg deleted file mode 100644 index da21787dfc8b4c6199bd636913e39a5149118de0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 7646 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 U{f%SwaAfaOB~QAJ;PuUa0pPOZ82|tP diff --git a/client/client/src/sounds/HANGUP.ogg b/client/client/src/sounds/HANGUP.ogg deleted file mode 100644 index 7adcd9fd187235430345c0c7301feb828639db15..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 5199 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 G2L1=5tR;2; diff --git a/client/client/src/sounds/REGISTER.ogg b/client/client/src/sounds/REGISTER.ogg deleted file mode 100644 index 912f9bc70805fb60d5330c3fc229a43b18403869..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3619 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 VR_HkbZ)We(>6Z(CQ#{Rc{tw}H9TWfn diff --git a/client/client/src/styles/arial.ttf b/client/client/src/styles/arial.ttf deleted file mode 100644 index 3d6805dff02de4f12668b1733a6ca99e81b09e0c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 774476 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 SxCw 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

      6H2t_Q1 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 KP4Pouy8jIx+kg!K diff --git a/client/client/src/styles/style.css b/client/client/src/styles/style.css deleted file mode 100644 index 4e3f4090..00000000 --- a/client/client/src/styles/style.css +++ /dev/null @@ -1,171 +0,0 @@ -/* -Copyright (c) 2011 Flashphoner -All rights reserved. This Code and the accompanying materials -are made available under the terms of the GNU Public License v2.0 -which accompanies this distribution, and is available at -http://www.gnu.org/licenses/old-licenses/gpl-2.0.html - -Contributors: - Flashphoner - initial API and implementation - -This code and accompanying materials also available under LGPL and MPL license for Flashphoner buyers. Other license versions by negatiation. Write us support@flashphoner.com with any questions. -*/ -ToolTip -{ - cornerRadius: 0; - fontSize: 11; - fontFamily: Arial; - paddingRight: 3; - paddingLeft: 4; - color: #404040; - fontWeight: normal; -} -TextInput -{ - backgroundColor: #DEEEFF; - borderStyle: solid; - fontFamily: Arial; - borderThickness: 1; - cornerRadius: 3; - paddingTop: 2; -} - - -Label.boldText -{ - fontWeight: bold; - fontSize: 11; - fontFamily: Verdana; -} -Button -{ - fontSize: 12; - fontFamily: Arial; - fontWeight: normal; - leading: 2; - cornerRadius: 3; - fillAlphas: 1.0, 1.0; - fillColors: #DCDCDC, #DCDCDC, #EEEEEE, #EEEEEE; - borderColor: #B7BABC; - themeColor: #B7BABC; - color: #000000; - textRollOverColor: #000000; - textSelectedColor: #000000; - paddingLeft: 0; - paddingRight: 0; - -} - - -Button.close -{ - borderColor: #FF0000; - color: #000; - cornerRadius: 10; - fillColors: #FF0000, #FF0000, #FF0000, #FF0000; - fontSize: 10; - fontStyle: normal; - themeColor: #FF0000; - paddingBottom: 3; - paddingLeft: 3; - paddingRight: 3; - paddingTop: 3; - fontWeight: bold; -} - - - -Label.callState -{ - fontWeight: bold; - color: #FF0000; - fontSize: 12; - fontFamily: Verdana; -} - -CallView{ - color:green; -} - -Label.error -{ - fontWeight: bold; - color: #FF0000; - fontSize: 12; - fontFamily: Verdana; -} - -Label.VideoMessage -{ - fontWeight: bold; - color: #FF0000; - fontSize: 16; - fontFamily: Verdana; - text-align:right; -} - - -Application -{ - backgroundGradientAlphas: 1.0, 1.0; - backgroundGradientColors: #FFFFFF, #FFFFFF; - fontFamily: Verdana; - theme-color:#ffffff; - color: #000000; -} -ApplicationControlBar -{ - fillAlphas: 1.0, 1.0; - fillColors: #000000, #000000; -} -LinkButton.AppBarButton -{ - color: #FFFFFF; - textRollOverColor: #FFFFFF; - textSelectedColor: #FFFFFF; - rollOverColor: #A0A0A0; - selectionColor: #A0A0A0; -} -Panel -{ - backgroundColor: #FFFFFF; - borderColor: #A5CCFF; - borderAlpha: 1.0; - titleStyleName: panelTitle; - borderThicknessLeft: 0; - borderThicknessRight: 0; - fontFamily: Arial; - fontSize: 12; - borderThicknessTop: 0; - borderThicknessBottom: 0; - statusStyleName: panelStatus; - controlBarStyleName: panelControlBar; - headerHeight: 0; - cornerRadius: 3; - dropShadowColor: #000000; - dropShadowEnabled: false; -} -Panel.Login -{ - padding-bottom:3; - padding-left:3; - padding-right:3; - padding-top:3; - cornerRadius: 0; - roundedBottomCorners: false; -} - -@font-face { - font-family: Verdana; - fontWeight: normal; - fontStyle: normal; - src: url("verdana.ttf"); -} - -@font-face { - font-family: Arial; - fontWeight: normal; - fontStyle: normal; - src: url("arial.ttf"); -} - diff --git a/client/client/src/styles/style_html.css b/client/client/src/styles/style_html.css deleted file mode 100644 index 26ac907a..00000000 --- a/client/client/src/styles/style_html.css +++ /dev/null @@ -1,961 +0,0 @@ -/* -Copyright (c) 2011 Flashphoner -All rights reserved. This Code and the accompanying materials -are made available under the terms of the GNU Public License v2.0 -which accompanies this distribution, and is available at -http://www.gnu.org/licenses/old-licenses/gpl-2.0.html - -Contributors: - Flashphoner - initial API and implementation - -This code and accompanying materials also available under LGPL and -MPL license for Flashphoner buyers. Other license versions by negatiation. -Write us support@flashphoner.com with any questions. -*/ - -body { - font: 12px Arial; -} -img { - border: 0; -} -button::-moz-focus-inner, -input[type="reset"]::-moz-focus-inner, -input[type="button"]::-moz-focus-inner, -input[type="submit"]::-moz-focus-inner, -input[type="file"] > input[type="button"]::-moz-focus-inner { - border: none; -} - -/* -------- Backgrounds ------- */ -#settingsView, #loginDiv, #infoDiv, #connectingDiv, .login_link, #transfer, #incomingDiv, #newChat { - background: #fff; -} -#controlPanel, .bar, .videoDiv, #chatDiv, #tabul, .button { - background-color: #ddd; -} - -/* ---------- Positions --------- */ -#video, -#phoneDiv, -#loginDiv, -#incomingDiv, -#infoDiv, -#connectingDiv, -#settingsView, -#versionOfProduct, -#controlPanel, -.closeButton, -.transferButton, -.holdButton, -.holdImage, -.bar, -#settingsButtonInCallView, -#answerButton, -#hangupButton, -#callerLogin, -#logoutButton, -#loginMainButton, -#video_requestUnmuteDiv, -#sendVideo, -#requestUnmuteText, -#closeButton_video_requestUnmuteDiv, -#transfer, -.callDiv, -.caller, -#chatDiv, -#micSlider, #speakerSlider, -#micBack, #speakerBack, -#console { - position: absolute; -} -/* ---------- Border ------------ */ -#settingsView, #loginDiv, #infoDiv, #connectingDiv, #transfer, #incomingDiv, #video_requestUnmuteDiv, #controlPanel, #chatDiv { - border-width: 2px 5px 5px\0/; /*only for ie8*/ - border-style: solid\0/; /*only for ie8*/ - border-color: #ddd\0/; /*only for ie8*/ - border: 1px solid #aaa; -} -#connectingDiv, #infoDiv { - border-width: 5px\0/; /*only for ie8*/ -} -/* ---------- Shadow ----------*/ -#settingsView, #transfer, #infoDiv, #loginDiv, #connectingDiv, #video_requestUnmuteDiv, #incomingDiv, #chatDiv -{ - box-shadow: 0 0 10px rgba(0,0,0,0.35); - -moz-box-shadow: 0 0 10px rgba(0,0,0,0.35); - -webkit-box-shadow: 0 0 10px rgba(0,0,0,0.35); -} - -/* ----------------------------- */ -textarea, text, input { - outline: none; - -moz-appearance: none; -} -input::-webkit-input-placeholder { - color: #ccc; - font: 14px Arial; -} -#calleeText { - padding-left: 1px; -} -#phoneDiv { - left: 30px; - height: 240px; - width: 153px; - padding: 10px; - position: relative; - top: 21px; -} -#versionOfProduct { - top: 134px; - right: 17px; - font: 8px Arial; - color: #bbb; -} -#controlPanel { - width: 152px; - height: 20px; - top: 6px; - left: 10px; - border: 1px solid #bbb; - box-shadow: /*0px 1px 0px #fff, */inset 0px 1px 0px #fff; -} - -/* ---------------- Buttons ---------------- */ -.closeButton { - background: url(../assets/close.png); - right: 3px; - opacity: 0.7; - top: 3px; - width: 14px; - height: 14px; -} -#cameraButton { - background: url(../assets/camera.png) no-repeat center; -} -#micButton { - background: url(../assets/mic.png) no-repeat center; -} -#soundButton { - background: url(../assets/speaker.png) no-repeat center; -} -.iconButton { - width: 24px; - height: 20px; - float: left; - cursor: pointer; - /* - -moz-opacity: 0.6; - -khtml-opacity: 0.6; - opacity: 0.6; - */ -} - -.iconBackgroundPressed{ - width: 24px; - height: 20px; - /*background: -webkit-radial-gradient(#aaa, #ddd, #eee, #eee);*/ - float: left; -} - -.iconPressed{ -} - -.iconButton:hover { - -moz-opacity: 1; - -khtml-opacity: 1; - opacity: 1; -} -.transferButton, .holdButton { - top: 97px; - width: 14px; - height: 14px; -} -.closeButton { - background: url(../assets/close.png); - right: 3px; -} -.transferButton { - background: url(../assets/transfer.png); - right: 7px; -} -.holdButton { - background: url(../assets/hold.png); - right: 27px; - visibility:hidden; -} - -.holdImage { - background: url(../assets/hold_big.png); - right: 55px; - top: 57px; - width: 30px; - height: 30px; - visibility: hidden; -} -/* ----------------------------------------- */ -/* ------------- ��������� �������� ------------ */ -.bar { - top: 0; - left: 0; - width: 100%; - height: 20px; - cursor: move; - font: 12px Arial; - font-weight: bolder; - color: #999; - text-shadow: #fff 0px 1px; - line-height: 20px; - text-align: left; - box-shadow: inset 0 1px 0 #fff; -} -/* ----------------------------------- */ -/* ------------- Settings ------------ -#settingsDiv { - top: 80px; - left: 5px; - height: 113px; - width: 230px; - padding-top: 20px; - visibility: hidden; - background: url(../assets/mic_settings_background.png); -} -#settingsButton { - top: 2px; - left: 5px; - background: url(../assets/mic_settings.png); -} -#settingsButtonInCallView { - top: 98px; - left: 5px; - background: url(../assets/mic_settings.png); -} --------------------------------------- */ - -/* ------------- Settings ------------ */ - -#settingsView, #settingsOkButton, #micSelector, #camSelector, -#settingsMicImage, #settingsCamImage { - position: absolute; -} - -#settingsView { - top: 94px; - left: 8px; - height: 123px; - width: 230px; - padding-top: 20px; - display: none; -} -#settingsButton { - background: url(../assets/mic_settings_2.png) no-repeat center; - /*top: 19px; - left: 18px; - /*width: 140px;*/ - opacity: 0.65; -} -#settingsOkButton{ - top: 100px; - left: 72px; - width: 80px; -} -#micSelector{ - top: 32px; - left: 45px; - width: 170px; -} -#camSelector{ - top: 64px; - left: 45px; - width: 170px; -} -#settingsMicImage{ - top: 35px; - left: 14px; -} - -#settingsCamImage{ - top: 67px; - left: 15px; -} -/* -------------------------------------- */ - -/* ----------------- Incoming call view ---------------- */ -#incomingDiv { - top: 110px; - left: 5px; - height: 82px; - width: 215px; - border: 1px solid #bbb; - padding: 5px; - padding-top: 25px; - font: 16px Arial; - text-align: center; - color: #aaa; - display: none; -} -#answerButton, #hangupButton { - width: 80px; - /*height: 22px;*/ - /*color: white;*/ - top: 70px; -} -#answerButton { - background-color: #009900; - left: 28px; -} -#hangupButton { - background-color: #cc0000; - right: 27px; -} -#callerField { - font-weight: bold; - color: #000; -} -/* ------------------ Connecting ------------------------ */ -#connectingDiv { - top: 120px; - left: 10px; - height: 40px; - width: 200px; - padding: 10px; - float: left; - visibility: hidden; - font: 16px Arial; - color: #aaa; - text-align: center; - display: table; -} -#connectingText { - display: table-cell; - vertical-align: middle; -} -/* ------------------ Info ------------------------ */ -#infoDiv { - top: 120px; - left: 10px; - height: 30px; - width: 200px; - padding: 10px; - float: left; - visibility: hidden; - font: 16px Arial; - color: #aaa; - text-align: center; - line-height: 30px; - -moz-opacity: 0.95; - /* Mozilla 1.6 */ - -khtml-opacity: 0.95; - /* Konqueror 3.1, Safari 1.1 */ - opacity: 0.95; - /* CSS3 - Mozilla 1.7b +, Firefox 0.9 +, Safari 1.2+, Opera 9+ */ -} -#infoText { -} -/* --------- Login, logout --------------------------------------------- */ -#callerLogin { - top: 0px; - right: 0px; - font: 12px Arial; - width: 50px; - height: 20px; - float: left; - text-align: right; - overflow: hidden; - color: #333; - display: none; - font: bold 12px Helvetica; - text-shadow: 0 1px 0 #fff; - line-height: 20px; - padding-right: 5px; - cursor: pointer; -} -#logoutButton { - width: 60px; - height: 20px; - bottom: -22px; - right: 0px; - font-size: 12px; - line-height: 20px; - display: none; -} -#loginDiv { - top: 46px; - left: 10px; - height: 172px; - width: 200px; - padding: 20px; - padding-top: 25px; - float: left; - visibility: hidden; -} -#loginMainButton { - top: -1px; - right: -1px; - font-size: 12px; - border: 1px solid #aaa; - padding: 0 5px 0 5px; - margin: 0px; - width:40px; - height: 20px; - line-height: 20px; - text-shadow: 0 1px 0 #eee; - -} - -#loginButton { - margin: 10px 0 0 15px; - width: 80px; -} - -#bugReportText { - position: absolute; - top: 360px; - left: 250px; - height: 50px; - width: 500px; - float: left; - font: 14px Courier; - color: #ffffff; - padding: 1px; - visibility: visible; - text-align: left; - border: 1px solid #aaa; - background-color: #333; -} - -#bugReportButton { - position: absolute; - top: 370px; - left: 760px; - width: 200px; - height: 50px; - font: 14px Courier; - padding: 1px; - visibility: visible; - text-align: center; - text-decoration: underline; - color: #333; - text-shadow: 0px 1px 0 #fff; - box-shadow: /*0px 1px 0px #fff*/ inset 0px 1px 0px #fff; - border-radius: 0px; - cursor: pointer; - border: #333333; -} - -#testButton { - position: absolute; - top: 330px; - left: 250px; - height: 20px; - width: 80px; - float: left; - background-color: green; - font: 14px Courier; - color: #ffffff; - padding: 1px; - visibility: hidden; - text-align: center; -} - -/* ------------ Video + Security settings view -------------- */ -#video_requestUnmuteDiv { - top: 32px; - left: 238px; - overflow: hidden; - padding-top: 20px; - -} -.videoDiv { - visibility: visible; - width: 640px; - height: 520px; -} -.securityDiv { - visibility: visible; - width: 215px; - height: 178px; - background-color: #fff; - padding-top: 20px; - border: 1px solid #ccc; -} -.closed { - width: 1px !important; - height: 1px !important; - visibility: hidden; -} -/* -we use '.init' class to make div size 1x1 basically -Because Firefox can`t operate with swf object located in -div with zero size. -*/ -.init { - width: 1px; - height: 1px; - visibility: hidden; -} - -#sendVideo { - width: 100px; - bottom: 6px; - left: 6px; -} -#requestUnmuteText { - text-align: center; - width: 100%; - font-weight: bolder; -} -#closeButton_video_requestUnmuteDiv{ - background: url(../assets/close.png); - right: 3px; - opacity: 0.7; - top: 3px; - width: 14px; - height: 14px; -} -/* -------------------------------------- */ -/* ------------ Transfer view -------------- */ -#transfer { - width: 200px; - height: 94px; - top: 90px; - left: 20px; - text-align: center; - font: bold 16px Arial; - padding: 10px; - padding-top: 30px; - visibility: hidden; -} -#transferInput { - width: 180px; - margin-bottom: 20px; -} -#transferOk, #transferCansel { - width: 80px; - margin: 0 6px 0 16px; -} -#transferCansel { - margin: 0; -} - -/* -------------------------------------- */ -/* ------ Call view-------- */ -.callDiv { - width: 152px; - height: 118px; - top: 57px; - left: 49px; - float: left; - background: #333; - /*border: 1px solid #B7BABC;*/ - color: #eee; - font: 22px Arial; - visibility: hidden; -} -.caller { - float: left; - top: 35px; - text-align: center; - width: 100%; -} -#callState { - color: #ddd; - position: relative; - top: 64px; - font-size: 12px; - text-align: center; -} -/* ------------------------- */ -/* ------ Chat view -------- */ -#chatDiv { - width: 320px; - top: 250px; - left: 20px; - visibility: hidden; -} -.chatBox { - width: 100%; - height: 100%; - margin: 0; - border: 1px solid #ddd; - background: #fff; -} -.chatTextarea { - border: 0; - width: 305px; - height: 200px; - margin: 5px; - resize: none; - overflow: auto; - word-wrap: break-word; -} -.messageInput { - margin: 4px; - width: 238px; - float: left; -} -.messageSend { - margin-top: 3px; - width: 60px; - margin-right: 3px; -} -.myNick, .yourNick { - color: #ccc; - font-weight: bold; - padding-top: 7px; -} -.yourNick { - color: #91c8ff; -} - -.message_sent { - color: gray; -} - -.message_accepted { - color: green; -} - -.message_failed { - color: red; -} - -.message_delivery_failed{ - color:orange; -} - -.message_delivered { - color: black; -} - -#tabul { - padding: 0; - margin: 0; - margin-left: 50px; - padding: 0; - z-index: 10; -} -#tabul li { - display: inline; - cursor: pointer; - max-width: 200px; - overflow: hidden; - text-overflow: ellipsis; -} -.ntabs { - background: #ddd; - margin-right: -1px; - font-size: 11px; - font-weight: bold; - color: #333; - padding: 4px 2px 2px 6px; - position: relative; - max-width: 200px; - text-overflow: ellipsis; -} -.add { - padding: 3px 5px; -} -.ctab { - background: #fff; - position: relative; - border-bottom-color: #fff; -} -.close { - text-decoration: none; - color: #bbb; - font-size: 16px; - padding: 0 4px; -} -.close:hover { - color: #333; -} -#tabcontent { - z-index: -10; - position: relative; - top: -1px; - border-top: none; - height: 240px; -} -/* ---------------------------------------------------- */ - -.button { - /*background: #dcdcdc;*/ - width: 50px; - height: 28px; - float: left; - margin: 0px -1px 0px 0; - text-align: center; - -moz-user-select: none; - -khtml-user-select: none; - user-select: none; - font: bold 14px Helvetica; - border: 1px solid #aaa; - color: #333; - text-shadow: 0px 1px 0 #fff; - box-shadow: /*0px 1px 0px #fff*/ inset 0px 1px 0px #fff; - text-align: center; - border-radius: 0px; - cursor: pointer; - /* - background: -webkit-gradient(linear, left top, left bottom, from(#ddd), to(#ddd)); - background: -moz-linear-gradient(top, #ddd, #ccc); - background: -o-linear-gradient(top, #ddd, #ccc); - filter: progid: DXImageTransform.Microsoft.gradient(startColorstr='#dddddd', endColorstr='#cccccc'); - */ - line-height: 28px; - font-family: ; -} - -.buttonLine { - float: left; - height: 29px; -} - -.chat, .call, .hangup { - width: 75px; - color: #000; - -} -.chat { - box-shadow: 0px 1px 0px #fff, inset 0px 1px 0px #C2DDF2; /*#A8CFEC;/* #96C6E9;*/ - text-shadow: 0px 1px 0 #A8CFEC; - background: -webkit-gradient(linear, left top, left bottom, from(#A1CCEB), to(#7BB8E4)); - /*background: -webkit-gradient(linear, left top, left bottom, from(#7CB8E3), to(#419AD9));*/ - background: -moz-linear-gradient(top, #ddd, #ccc); - background: -o-linear-gradient(top, #ddd, #ccc); - filter: progid: DXImageTransform.Microsoft.gradient(startColorstr='#dddddd', endColorstr='#cccccc'); - /*color: #1B527A;*/ - width: 76px; -} -.call { - box-shadow: 0px 1px 0px #fff, inset 0px 1px 0px #4DE74D;/*#0d0;*/ - text-shadow: 0px 1px 0px #0d0; - background: -webkit-gradient(linear, left top, left bottom, from(#6ECF6E), to(#4DC34D)); - /*background: -webkit-gradient(linear, left top, left bottom, from(#3b3), to(#0a0));*/ - background: -moz-linear-gradient(top, #3b3, #0a0); - background: -o-linear-gradient(top, #3b3, #0a0); - filter: progid: DXImageTransform.Microsoft.gradient(startColorstr='#33bb33', endColorstr='#00aa00'); - /*color: #004400;*/ - border-left-color: #888; - -} -.hangup { - box-shadow: 0px 1px 0px #fff, inset 0px 1px 0px #FF9494;/*#f66;*/ - text-shadow: 0px 1px 0 #f33; - background: -webkit-gradient(linear, left top, left bottom, from(#E16C6C), to(#DB4D4D)); - /*background: -webkit-gradient(linear, left top, left bottom, from(#f33), to(#c00));*/ - background: -moz-linear-gradient(top, #f33, #c00); - background: -o-linear-gradient(top, #f33, #c00); - filter: progid: DXImageTransform.Microsoft.gradient(startColorstr='#ff3333', endColorstr='#cc0000'); -} - -.pressed { - border-color: #888; - /*border-bottom-color: #fff;*/ - box-shadow: inset 0px 1px 6px #333; - /*height: 23px;*/ - line-height: 30px; - /*border-radius: 4px 4px 5px 5px;*/ - background-color: #d7d7d7; -} - -.disabled { - opacity: 0.7; -} - -.call_button, .chat_button { - width: 81px; - background-color: #009800; - float: left; - height: 30px; - font: 20px Arial; - color: #fff; - text-align: center; - line-height: 30px; - border: 1px outset; - -moz-user-select: none; - -khtml-user-select: none; - user-select: none; - cursor: default; - margin-bottom: 3px; -} - - - -/* ----------- Slider -------------- */ -#micSlider, #speakerSlider { - top: 10px; - display: none; -} -#micBack, #speakerBack { - /* TODO replace sliders within sliderbackground*/ - top: 20px; - width: 24px; - height: 102px; - background: #ddd; - box-shadow: 0px 0px 4px #bbb; - display: none; - border: 1px solid #aaa; - border-top: none; -} -#micBack { - left: 23px; -} -#speakerBack { - left: -1px; -} -#micSlider { - left: 8px; -} -#speakerSlider { - left: 8px; -} -.ui-slider-vertical { - width: 6px !important; - height: 80px !important; - border: 1px solid #999 !important; - background-color: #ddd !important; - box-shadow: inset 0px 0px 1px #777 !important; - } -.ui-slider-handle { - left: -5px !important; - border-radius: 8px !important; -cursor: pointer !important; -border: 1px solid #888 !important; -box-shadow: inset 0px 1px 0px #fff, 0px 0px 1px #777; -background-color: #dcdcdc !important; -/* -background: -webkit-gradient(linear, left top, left bottom, from(#ddd), to(#ccc)) !important; - background: -moz-linear-gradient(top, #777, #555) !important; - background: -o-linear-gradient(top, #777, #555) !important; - filter: progid: DXImageTransform.Microsoft.gradient(startColorstr='#777777', endColorstr='#555555') !important; - */ -height: 14px !important; -width: 14px !important; -cursor: pointer !important; - } -.ui-slider-handle:focus { - outline: none; -} -.ui-slider-range { - border-radius: 10px !important; - box-shadow: inset 2px 0px 5px #222; - - background: -webkit-gradient(linear, left top, left bottom, from(#777), to(#555)) !important; - background: -moz-linear-gradient(top, #777, #555) !important; - background: -o-linear-gradient(top, #777, #555) !important; - filter: progid: DXImageTransform.Microsoft.gradient(startColorstr='#777777', endColorstr='#555555') !important; - left: -1px !important; - bottom: -1px !important; - border: 1px solid #222 !important; -} - -/* -------------------------------------- */ -/* --------- Console ------------*/ -#console { - top: 35px; - left: 250px; - height: 266px; - width: 700px; - float: left; - background-color: #333; - font: 14px Courier; - color: #eee; - padding: 10px; - overflow: auto; - word-wrap: break-word; -} -/* -------------------------------- */ -.phone_screen_1 { - width: 151px; - background: #deeeff; - float: left; - margin: 2px 0 0 0; - font: 22px Arial; - border: 1px solid #b7babc; - border-bottom: none; - color: #5a5a5a; - outline: none; - line-height: 22px; -} -.phone_screen_2 { - width: 152px; - height: 90px; - background: #deeeff; - float: left; - margin: 0 0 -1px 0; - font: 12px Arial; - border: 1px solid #b7babc; - border-top: none; - color: #5a5a5a; - outline: none; -} -.login_label { - float: left; - width: 100px; - height: 22px; - line-height: 22px; -} -.login_input { - float: left; - width: 100px; - height: 22px; -} - -.login_input input{ - width: 100px; -} -/* ---- Additional styles ---- */ -#auto_login_token { - width: 0; - height: 0; - margin: 0; - padding: 0; - border: none; -} - -/* -------------- Z indexes -------------*/ -/*#phoneDiv { - z-index: 12; -} -*/ -#incomingDiv { - z-index: 14; -} -#connectingDiv { - z-index: 15; -} -#settingsDiv { - z-index: 17; -} -#messageDiv { - z-index: 18; -} -#loginDiv { - z-index: 19; -} -#video_requestUnmuteDiv { - z-index: 20; -} -#chatDiv { - z-index: 21; -} - -#transfer { - z-index: 22; -} -#infoDiv { - z-index: 30; -} -#micBack, #speakerBack{ - z-index: 100; -} -.iconBackgroundPressed{ - z-index: 101; -} -.closeButton { - z-index: 101; -} - diff --git a/client/client/src/styles/style_html_c2c.css b/client/client/src/styles/style_html_c2c.css deleted file mode 100644 index 1b5bd0aa..00000000 --- a/client/client/src/styles/style_html_c2c.css +++ /dev/null @@ -1,665 +0,0 @@ -/* -Copyright (c) 2011 Flashphoner -All rights reserved. This Code and the accompanying materials -are made available under the terms of the GNU Public License v2.0 -which accompanies this distribution, and is available at -http://www.gnu.org/licenses/old-licenses/gpl-2.0.html - -Contributors: - Flashphoner - initial API and implementation - -This code and accompanying materials also available under LGPL and -MPL license for Flashphoner buyers. Other license versions by negatiation. -Write us support@flashphoner.com with any questions. -*/ - -body { - font: 12px Arial; - margin: 0; - background-color: #555; -} -img { - border: 0; -} - -/* -------------- Main click2call view ------------- */ -#c2c { - position: absolute; - height: 240px; - width: 320px; - position: relative; - background: #555; - border: 1px solid #111; - box-shadow: inset 0px 1px 0px #777, 0px 1px 0px #666; - top: 10px; - left: 10px; - /* - background: -webkit-gradient(linear, left top, left bottom, from(#666), to(#555)); - background: -moz-linear-gradient(top, #555, #444); - background: -o-linear-gradient(top, #555, #444); - filter: progid: DXImageTransform.Microsoft.gradient(startColorstr='#555555', endColorstr='#444444'); - */ - border-radius: 6px; -} -.caller { - position: absolute; - top: 65px; - font: 50px Arial; - color: #fff; - float: left; - text-align: center; - width: 100%; - text-shadow: 0 1px black; -} -#callState { - position: absolute; - width: 100%; - text-align: center; - top: 125px; - font: 30px Arial; - color: #777; - text-shadow: 0 1px black; -} -/* ------------ Buttons ------------- */ -#buttonsPanel { - height: 40px; - /*background: #444;*/ - border: 1px solid #111; - border-right: none; - border-left: none; - position: absolute; - bottom: -1px; - width: 320px; - box-shadow: inset 0px 1px 0px #777; - /*0px 1px 0px #666*/ - background: -webkit-gradient(linear, left top, left bottom, from(#555), to(#444)); - background: -moz-linear-gradient(top, #555, #444); - background: -o-linear-gradient(top, #555, #444); - filter: progid: DXImageTransform.Microsoft.gradient(startColorstr='#555555', endColorstr='#444444'); - border-radius: 0 0 6px 6px; -} - -.button { - position: absolute; - width: 36px; - height: 24px; - font: 13px Lucida Grande, Lucida Sans Unicode; - border: 1px solid #111; - color: #aaa; - text-shadow: 0px 1px 0 #000; - box-shadow: 0px 1px 0px #666, inset 0px 1px 0px #777; - text-align: center; - border-radius: 6px; - cursor: pointer; - background: -webkit-gradient(linear, left top, left bottom, from(#555), to(#444)); - background: -moz-linear-gradient(top, #555555, #444444); - background: -o-linear-gradient(top, #555555, #444444); - background: -ms-linear-gradient(top, #555555, #444444); - -pie-background: linear-gradient(#555555, #444444); - line-height: 24px; - background-position: 55% center; - background-repeat: no-repeat; - behavior: url(assets/pie/PIE.htc); -} - - -#micButton, #cameraButton, #soundButton, #dialpadButton { - top: 8px; -} - -.call, .hangup { - border-radius: 12px; - color: white; - bottom: 7px; - left: 92px; - width: 134px; -} -.call { - background: -webkit-gradient(linear, left top, left bottom, from(#3b3), to(#0a0)); - background: -moz-linear-gradient(top, #3b3, #0a0); - background: -o-linear-gradient(top, #3b3, #0a0); - /*filter: progid: DXImageTransform.Microsoft.gradient(startColorstr='#33bb33', endColorstr='#00aa00');*/ - -pie-background: linear-gradient(#33bb33, #00aa00); - box-shadow: 0px 1px 0px #666, inset 0px 1px 0px #0f0; - color: #004400; - text-shadow: 0px 1px 0px #0d0; -} -.hangup { - background: -webkit-gradient(linear, left top, left bottom, from(#f33), to(#c00)); - background: -moz-linear-gradient(top, #f33, #c00); - background: -o-linear-gradient(top, #f33, #c00); - /*filter: progid: DXImageTransform.Microsoft.gradient(startColorstr='#ff3333', endColorstr='#cc0000');*/ - -pie-background: linear-gradient(#ff3333, #cc0000); - box-shadow: 0px 1px 0px #666, inset 0px 1px 0px #f66; - color: #600; - text-shadow: 0px 1px 0 #f33; - -} -.pressed { - border-color: #222; - border-bottom-color: #666; - box-shadow: inset 0px 1px 6px #111; - height: 25px; - line-height: 29px; - background-position-y: 63%; -} - -.disabled { - opacity: 0.5; -} -#micButton { - left: 6px; - background-image: url('../assets/c2c_mic.png'); - -pie-background: url(assets/c2c_mic.png) no-repeat center, linear-gradient(#555555, #444444); - background-position-x: 50%; -} - -#cameraButton { - right: 49px; - background-image: url('../assets/c2c_camera.png'); - -pie-background: url(assets/c2c_camera.png) no-repeat center, linear-gradient(#555555, #444444); -} -#soundButton { - left: 49px; - background-image: url('../assets/c2c_sound.png'); - -pie-background: url(assets/c2c_sound.png) no-repeat center, linear-gradient(#555555, #444444); -} -#dialpadButton { - right: 6px; - background-image: url('../assets/c2c_dialpad.png'); - -pie-background: url(assets/c2c_dialpad.png) no-repeat center, linear-gradient(#555555, #444444); -} -#hangupButton { -} -#callMeButton1, #callMeButton2, #callMeButton3 { - top: 340px; - left: 75px; - width: 180px; -} - -#callMeButton2 { - top: 380px; -} - -#callMeButton3 { - top: 420px; -} - -#aboutCallMe { - font: 14px Courier; - color: #eee; - position: absolute; - top: 460px; - left: 13px; - width: 326px; -} - -#c2c-test { -width: 200px; -height: 200px; -} -/* ---------- Dialpad ---------- */ -.dialPad { - position: absolute; - font: 13px Lucida Grande, Lucida Sans Unicode; - border: 1px solid #111; - color: #aaa; - text-shadow: 0px 1px 0 #000; - text-align: center; - border-radius: 4px; - cursor: pointer; - /* backs */ - background: -webkit-gradient(linear, left top, left bottom, from(#555), to(#444)); - background: -moz-linear-gradient(top, #555, #444); - background: -o-linear-gradient(top, #555, #444); - /*filter: progid: DXImageTransform.Microsoft.gradient(startColorstr='#555555', endColorstr='#444444');*/ - -pie-background: linear-gradient(#555, #444); - line-height: 20px; - width: 129px; - height: 152px; - bottom: 38px; - right: 6px; - box-shadow: 0px 0px 10px #222, inset 0px 1px 0px #777; - display: none; - behavior: url(assets/pie/PIE.htc); -} -.dialButton { - position: relative; - margin: 3px 0 0 4px; - float: left; - color: #ccc; -} -.dialButtonLine { - float: left; - height: 30px; -} -.dialScreen { - width: 117px; - height: 20px; - color: white; - text-shadow: none; - float: left; - margin: 4px 4px 2px 4px; - padding: 1px 2px 0 2px; - text-align: right; - font: bolder 18px Arial; - background-color: #000; - border-radius: 4px; - overflow: hidden; -} -/* ----------------------------- */ -/* ----------- Slider -------------- */ -#micSlider, #speakerSlider { - position: absolute; - top: -90px; - display: none; -} -#micBack, #speakerBack { -/* TODO replace sliders within sliderbackground*/ - position: absolute; - bottom: 38px; - width: 27px; - height: 102px; - background: #555; - box-shadow: inset 0px 1px 0px #777, 0px 2px 10px #222; - display: none; - border-radius: 4px; - border: 1px solid #111; - behavior: url(assets/pie/PIE.htc); -} -#micBack { - left: 11px; -} -#speakerBack { - left: 54px; -} -#micSlider { - left: 21px; -} -#speakerSlider { - left: 64px; -} -.ui-slider-vertical { - width: 7px !important; - height: 80px !important; - border: 1px solid #222 !important; - background-color: #555 !important; - box-shadow: inset 0px 0px 3px #111; -} -.ui-slider-handle { - left: -5px !important; - border-radius: 10px !important; - cursor: pointer !important; - border: 1px solid #222 !important; - box-shadow: 0px 0px 10px #333; - background: -webkit-gradient(linear, left top, left bottom, from(#777), to(#555)) !important; - background: -moz-linear-gradient(top, #777, #555) !important; - background: -o-linear-gradient(top, #777, #555) !important; - /*filter: progid: DXImageTransform.Microsoft.gradient(startColorstr='#777777', endColorstr='#555555') !important;*/ - -pie-background: linear-gradient (#777, #555) !important; - behavior: url(assets/pie/PIE.htc); -} -.ui-slider-handle:focus { - outline: none; -} -.ui-slider-range { - border-radius: 10px !important; - box-shadow: inset 2px 0px 5px #0f0; - background: -webkit-gradient(linear, left top, left bottom, from(#3b3), to(#0a0)) !important; - background: -moz-linear-gradient(top, #3b3, #0a0) !important; - background: -o-linear-gradient(top, #3b3, #0a0) !important; - /*filter: progid: DXImageTransform.Microsoft.gradient(startColorstr='#33bb33', endColorstr='#00aa00') !important;*/ - -pie-background: linear-gradient (#33bb33, #00aa00) !important; - behavior: url(assets/pie/PIE.htc); -} -/* --------------- Flash ---------------- */ -#flash { - overflow: hidden; - position: absolute; -} -#video { - height: 138px; - position: absolute; - top: 0px; - right: 0px; -} -.security { - position: absolute; - top: 60px; - left: 52px; - overflow: hidden; - width: 215px; - height: 140px; - visibility: visible; -} -.init { - width: 1px; - height: 1px; - visibility: hidden; -} -/* screen for showing both videos - my and interlocutor */ -.video { - width: 320px; - height: 240px; - background: #666; - position: absolute; - top: 0; - right: 0; - -} -/* screen only for my video */ -.videoMy { - position: absolute; - width: 80px; - height: 60px; - top: 0px; - right: 0px; - /*background: #666;*/ - /*box-shadow: 0px 0px 5px #111;*/ - border: 1px solid #222; -} -.sendVideoButton { - width: 30px; - height: 30px; - position: absolute; - top: 17px; - left: 265px; - opacity: 0.7; - display: none; -} -.sendVideoButtonPressed { - width: 20px; - height: 20px; - top: 22px; - left: 270px; -} -.sendVideoButton img { - width: 100%; - height: 100%; -} -/* ------------- Request ------------ */ -.request { - /*background: #555;*/ - position: absolute; - font: 20px Arial; - color: #fff; - text-shadow: 0 1px black; - top: 20px; - left: 20px; - width: 280px; - height: 180px; - text-align: center; - padding-top: 10px; - background: -webkit-gradient(linear, left top, left bottom, from(#666), to(#555)); - background: -moz-linear-gradient(top, #666, #555); - background: -o-linear-gradient(top, #666, #555); - filter: progid: DXImageTransform.Microsoft.gradient(startColorstr='#666666', endColorstr='#555555'); - box-shadow: 0px 0px 10px #222, inset 0px 1px 0px #777; - border-radius: 4px; - display: none; - border: 1px solid #000; -} -.back { - position: absolute; - width: 320px; - height: 240px; - opacity: 0.4; - top: 0px; - left: 0px; - background-color: #555; - display: none; -} -/* ------------- Connecting ----------- */ -#connectingDiv { - position: absolute; - top: 125px; - width: 320px; - font: 30px Arial; - color: #777; - text-align: center; - text-shadow: 0 1px black; -} -#connectingText { -} -/* -------------------------------------- */ -/* ---------- Border ------------ */ -#settingsDiv, #infoDiv, #connectingDiv, #flash { - border-width: 2px 5px 5px\0/; - /*only for ie8*/ - border-style: solid\0/; - /*only for ie8*/ - border-color: #ddd\0/; - /*only for ie8*/ -} -#connectingDiv, #infoDiv { - border-width: 5px\0/; - /*only for ie8*/ -} -/* ---------- Shadow ---------- */ -#settingsDiv, #infoDiv { - box-shadow: 0 0 10px black; - box-shadow: 0 0 10px rgba(0,0,0,0.5); - -moz-box-shadow: 0 0 10px rgba(0,0,0,0.5); - -webkit-box-shadow: 0 0 10px rgba(0,0,0,0.5); -} -/* ----------------------------- */ -textarea, text, input { - outline: none; - -moz-appearance: none; -} -input::-webkit-input-placeholder { - color: #ccc; - font: 14px Arial; -} -#calleeText { - padding-left: 1px; -} - -#phoneDiv { - left: 30px; - height: 240px; - width: 147px; - padding: 10px; - position: relative; -} -#versionOfProduct { - position: absolute; - top: 2px; - left: 4px; - /*font: 20px Arial;*/ - color: #111; - text-shadow: #777 0px 1px; -} -/* ---------------- Buttons ---------------- */ -.closeButton { - background: url(../assets/close.png); - right: 3px; - opacity: 0.7; - position: absolute; - top: 3px; - width: 14px; - height: 14px; -} -/*.iconButton { - width: 16px; - height: 16px; - float: left; - /* -moz-opacity: 0.6; - -khtml-opacity: 0.6; - opacity: 0.6; -} -*/ -.closeButton { - background: url(../assets/close.png); - right: 3px; -} -/* ----------------------------------------- */ -/* ------------- ��������� �������� ------------ */ -.bar { - position: absolute; - top: 0; - left: 0; - width: 100%; - height: 20px; - background-color: #ddd; - cursor: move; - font: 12px Arial; - font-weight: bolder; - color: #999; - text-shadow: #fff 0px 1px; - line-height: 20px; - text-align: left; -} -/* ----------------------------------- */ -/* ------------- Settings ------------ */ - -#settingsButton, #settingsView, #settingsOkButton, #micSelector, #camSelector, -#settingsMicImage, #settingsCamImage { -position: absolute; -} - -#settingsView { - top: 54px; - left: 50px; - height: 113px; - width: 230px; - padding-top: 20px; -} -#settingsButton { - top: 19px; - left: 18px; - width: 140px; - visibility: hidden; -} -#settingsOkButton{ - top: 94px; - left: 72px; - width: 80px; -} -#micSelector{ - top: 18px; - left: 45px; - width: 170px; -} -#camSelector{ - top: 54px; - left: 45px; - width: 170px; -} -#settingsMicImage{ - top: 22px; - left: 14px; -} - -#settingsCamImage{ - top: 58px; - left: 15px; -} -/* -------------------------------------- */ -/* ------------------ Info ------------------------ */ -#infoDiv { - top: 50px; - height: auto; - width: 200px; - margin: 0 auto; - position: relative; - padding: 10px; - visibility: hidden; - font: 16px Arial; - color: #000000; - background-color: #FFFFFF; - text-align: center; - line-height: 30px; - -moz-opacity: 0.95; -/* Mozilla 1.6 */ - -khtml-opacity: 0.95; -/* Konqueror 3.1, Safari 1.1 */ - opacity: 0.95; -/* CSS3 - Mozilla 1.7b +, Firefox 0.9 +, Safari 1.2+, Opera 9+ */ -} -#infoText { -} -/* ------------ Flash div -------------- */ - -.closed { - width: 1px !important; - height: 1px !important; - visibility: hidden; -} - -#requestUnmuteText { - position: absolute; - text-align: center; - width: 100%; - font-weight: bolder; -} -#closeButton_video_requestUnmuteDiv { - background: url(../assets/close.png); - right: 3px; - opacity: 0.7; - position: absolute; - top: 3px; - width: 14px; - height: 14px; -} - -/* --------- Console ------------*/ -#console { - position: absolute; - top: 10px; - left: 340px; - height: 700px; - width: 700px; - float: left; - background-color: #555; - font: 14px Courier; - color: #eee; - padding: 10px; - overflow: auto; - word-wrap: break-word; - line-height: 18px; -} - -/* --------- Timer ------------*/ - -#timer { -position: absolute; -top: 170px; -left: 135px; -text-shadow: 0 1px black; -color: #999; -display: none; -} - -/* -------------- Z indexes -------------*/ - -#versionOfProduct { - z-index: 4; -} -.video, .videoMy { - z-index: 5; -} -/*#buttonsBack { - z-index: 6; -} -*/ -#micBack, #speakerBack { - z-index: 6; -} -.button, #buttonsPanel { - z-index: 7; -} -#micSlider, #speakerSlider, #dialPad { - z-index: 8; -} -.sendVideoButton, #sendVideoButtonImage { - z-index: 9; -} -.request { - z-index: 10; -} -.security { - z-index: 11; -} -.flash { -} \ No newline at end of file diff --git a/client/client/src/styles/style_jquery_ui_1.8.15.css b/client/client/src/styles/style_jquery_ui_1.8.15.css deleted file mode 100644 index ad0ea5ea..00000000 --- a/client/client/src/styles/style_jquery_ui_1.8.15.css +++ /dev/null @@ -1,565 +0,0 @@ -/* - jQuery UI CSS Framework 1.8.15 - - Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) - Dual licensed under the MIT or GPL Version 2 licenses. - http://jquery.org/license - - http://docs.jquery.com/UI/Theming/API -*/ -.ui-helper-hidden { display: none; } -.ui-helper-hidden-accessible { position: absolute !important; clip: rect(1px 1px 1px 1px); clip: rect(1px,1px,1px,1px); } -.ui-helper-reset { margin: 0; padding: 0; border: 0; outline: 0; line-height: 1.3; text-decoration: none; font-size: 100%; list-style: none; } -.ui-helper-clearfix:after { content: "."; display: block; height: 0; clear: both; visibility: hidden; } -.ui-helper-clearfix { display: inline-block; } -/* required comment for clearfix to work in Opera \*/ -* html .ui-helper-clearfix { height:1%; } -.ui-helper-clearfix { display:block; } -/* end clearfix */ -.ui-helper-zfix { width: 100%; height: 100%; top: 0; left: 0; position: absolute; opacity: 0; filter:Alpha(Opacity=0); } - - -/* Interaction Cues -----------------------------------*/ -.ui-state-disabled { cursor: default !important; } - - -/* Icons -----------------------------------*/ - -/* states and images */ -.ui-icon { display: block; text-indent: -99999px; overflow: hidden; background-repeat: no-repeat; } - - -/* Misc visuals -----------------------------------*/ - -/* Overlays */ -.ui-widget-overlay { position: absolute; top: 0; left: 0; width: 100%; height: 100%; } - - -/* - * jQuery UI CSS Framework 1.8.15 - * - * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) - * Dual licensed under the MIT or GPL Version 2 licenses. - * http://jquery.org/license - * - * http://docs.jquery.com/UI/Theming/API - * - * To view and modify this theme, visit http://jqueryui.com/themeroller/?ffDefault=Trebuchet%20MS,%20Tahoma,%20Verdana,%20Arial,%20sans-serif&fwDefault=bold&fsDefault=1.1em&cornerRadius=4px&bgColorHeader=f6a828&bgTextureHeader=12_gloss_wave.png&bgImgOpacityHeader=35&borderColorHeader=e78f08&fcHeader=ffffff&iconColorHeader=ffffff&bgColorContent=eeeeee&bgTextureContent=03_highlight_soft.png&bgImgOpacityContent=100&borderColorContent=dddddd&fcContent=333333&iconColorContent=222222&bgColorDefault=f6f6f6&bgTextureDefault=02_glass.png&bgImgOpacityDefault=100&borderColorDefault=cccccc&fcDefault=1c94c4&iconColorDefault=ef8c08&bgColorHover=fdf5ce&bgTextureHover=02_glass.png&bgImgOpacityHover=100&borderColorHover=fbcb09&fcHover=c77405&iconColorHover=ef8c08&bgColorActive=ffffff&bgTextureActive=02_glass.png&bgImgOpacityActive=65&borderColorActive=fbd850&fcActive=eb8f00&iconColorActive=ef8c08&bgColorHighlight=ffe45c&bgTextureHighlight=03_highlight_soft.png&bgImgOpacityHighlight=75&borderColorHighlight=fed22f&fcHighlight=363636&iconColorHighlight=228ef1&bgColorError=b81900&bgTextureError=08_diagonals_thick.png&bgImgOpacityError=18&borderColorError=cd0a0a&fcError=ffffff&iconColorError=ffd27a&bgColorOverlay=666666&bgTextureOverlay=08_diagonals_thick.png&bgImgOpacityOverlay=20&opacityOverlay=50&bgColorShadow=000000&bgTextureShadow=01_flat.png&bgImgOpacityShadow=10&opacityShadow=20&thicknessShadow=5px&offsetTopShadow=-5px&offsetLeftShadow=-5px&cornerRadiusShadow=5px - */ - - -/* Component containers -----------------------------------*/ -.ui-widget { font-family: Trebuchet MS, Tahoma, Verdana, Arial, sans-serif; font-size: 1.1em; } -.ui-widget .ui-widget { font-size: 1em; } -.ui-widget input, .ui-widget select, .ui-widget textarea, .ui-widget button { font-family: Trebuchet MS, Tahoma, Verdana, Arial, sans-serif; font-size: 1em; } -.ui-widget-content { border: 1px solid #dddddd; background: #eeeeee url(images/ui-bg_highlight-soft_100_eeeeee_1x100.png) 50% top repeat-x; color: #333333; } -.ui-widget-content a { color: #333333; } -.ui-widget-header { border: 1px solid #e78f08; background: #f6a828 url(images/ui-bg_gloss-wave_35_f6a828_500x100.png) 50% 50% repeat-x; color: #ffffff; font-weight: bold; } -.ui-widget-header a { color: #ffffff; } - -/* Interaction states -----------------------------------*/ -.ui-state-default, .ui-widget-content .ui-state-default, .ui-widget-header .ui-state-default { border: 1px solid #cccccc; background: #f6f6f6 url(images/ui-bg_glass_100_f6f6f6_1x400.png) 50% 50% repeat-x; font-weight: bold; color: #1c94c4; } -.ui-state-default a, .ui-state-default a:link, .ui-state-default a:visited { color: #1c94c4; text-decoration: none; } -.ui-state-hover, .ui-widget-content .ui-state-hover, .ui-widget-header .ui-state-hover, .ui-state-focus, .ui-widget-content .ui-state-focus, .ui-widget-header .ui-state-focus { border: 1px solid #fbcb09; background: #fdf5ce url(images/ui-bg_glass_100_fdf5ce_1x400.png) 50% 50% repeat-x; font-weight: bold; color: #c77405; } -.ui-state-hover a, .ui-state-hover a:hover { color: #c77405; text-decoration: none; } -.ui-state-active, .ui-widget-content .ui-state-active, .ui-widget-header .ui-state-active { border: 1px solid #fbd850; background: #ffffff url(images/ui-bg_glass_65_ffffff_1x400.png) 50% 50% repeat-x; font-weight: bold; color: #eb8f00; } -.ui-state-active a, .ui-state-active a:link, .ui-state-active a:visited { color: #eb8f00; text-decoration: none; } -.ui-widget :active { outline: none; } - -/* Interaction Cues -----------------------------------*/ -.ui-state-highlight, .ui-widget-content .ui-state-highlight, .ui-widget-header .ui-state-highlight {border: 1px solid #fed22f; background: #ffe45c url(images/ui-bg_highlight-soft_75_ffe45c_1x100.png) 50% top repeat-x; color: #363636; } -.ui-state-highlight a, .ui-widget-content .ui-state-highlight a,.ui-widget-header .ui-state-highlight a { color: #363636; } -.ui-state-error, .ui-widget-content .ui-state-error, .ui-widget-header .ui-state-error {border: 1px solid #cd0a0a; background: #b81900 url(images/ui-bg_diagonals-thick_18_b81900_40x40.png) 50% 50% repeat; color: #ffffff; } -.ui-state-error a, .ui-widget-content .ui-state-error a, .ui-widget-header .ui-state-error a { color: #ffffff; } -.ui-state-error-text, .ui-widget-content .ui-state-error-text, .ui-widget-header .ui-state-error-text { color: #ffffff; } -.ui-priority-primary, .ui-widget-content .ui-priority-primary, .ui-widget-header .ui-priority-primary { font-weight: bold; } -.ui-priority-secondary, .ui-widget-content .ui-priority-secondary, .ui-widget-header .ui-priority-secondary { opacity: .7; filter:Alpha(Opacity=70); font-weight: normal; } -.ui-state-disabled, .ui-widget-content .ui-state-disabled, .ui-widget-header .ui-state-disabled { opacity: .35; filter:Alpha(Opacity=35); background-image: none; } - -/* Icons -----------------------------------*/ - -/* states and images */ -.ui-icon { width: 16px; height: 16px; background-image: url(images/ui-icons_222222_256x240.png); } -.ui-widget-content .ui-icon {background-image: url(images/ui-icons_222222_256x240.png); } -.ui-widget-header .ui-icon {background-image: url(images/ui-icons_ffffff_256x240.png); } -.ui-state-default .ui-icon { background-image: url(images/ui-icons_ef8c08_256x240.png); } -.ui-state-hover .ui-icon, .ui-state-focus .ui-icon {background-image: url(images/ui-icons_ef8c08_256x240.png); } -.ui-state-active .ui-icon {background-image: url(images/ui-icons_ef8c08_256x240.png); } -.ui-state-highlight .ui-icon {background-image: url(images/ui-icons_228ef1_256x240.png); } -.ui-state-error .ui-icon, .ui-state-error-text .ui-icon {background-image: url(images/ui-icons_ffd27a_256x240.png); } - -/* positioning */ -.ui-icon-carat-1-n { background-position: 0 0; } -.ui-icon-carat-1-ne { background-position: -16px 0; } -.ui-icon-carat-1-e { background-position: -32px 0; } -.ui-icon-carat-1-se { background-position: -48px 0; } -.ui-icon-carat-1-s { background-position: -64px 0; } -.ui-icon-carat-1-sw { background-position: -80px 0; } -.ui-icon-carat-1-w { background-position: -96px 0; } -.ui-icon-carat-1-nw { background-position: -112px 0; } -.ui-icon-carat-2-n-s { background-position: -128px 0; } -.ui-icon-carat-2-e-w { background-position: -144px 0; } -.ui-icon-triangle-1-n { background-position: 0 -16px; } -.ui-icon-triangle-1-ne { background-position: -16px -16px; } -.ui-icon-triangle-1-e { background-position: -32px -16px; } -.ui-icon-triangle-1-se { background-position: -48px -16px; } -.ui-icon-triangle-1-s { background-position: -64px -16px; } -.ui-icon-triangle-1-sw { background-position: -80px -16px; } -.ui-icon-triangle-1-w { background-position: -96px -16px; } -.ui-icon-triangle-1-nw { background-position: -112px -16px; } -.ui-icon-triangle-2-n-s { background-position: -128px -16px; } -.ui-icon-triangle-2-e-w { background-position: -144px -16px; } -.ui-icon-arrow-1-n { background-position: 0 -32px; } -.ui-icon-arrow-1-ne { background-position: -16px -32px; } -.ui-icon-arrow-1-e { background-position: -32px -32px; } -.ui-icon-arrow-1-se { background-position: -48px -32px; } -.ui-icon-arrow-1-s { background-position: -64px -32px; } -.ui-icon-arrow-1-sw { background-position: -80px -32px; } -.ui-icon-arrow-1-w { background-position: -96px -32px; } -.ui-icon-arrow-1-nw { background-position: -112px -32px; } -.ui-icon-arrow-2-n-s { background-position: -128px -32px; } -.ui-icon-arrow-2-ne-sw { background-position: -144px -32px; } -.ui-icon-arrow-2-e-w { background-position: -160px -32px; } -.ui-icon-arrow-2-se-nw { background-position: -176px -32px; } -.ui-icon-arrowstop-1-n { background-position: -192px -32px; } -.ui-icon-arrowstop-1-e { background-position: -208px -32px; } -.ui-icon-arrowstop-1-s { background-position: -224px -32px; } -.ui-icon-arrowstop-1-w { background-position: -240px -32px; } -.ui-icon-arrowthick-1-n { background-position: 0 -48px; } -.ui-icon-arrowthick-1-ne { background-position: -16px -48px; } -.ui-icon-arrowthick-1-e { background-position: -32px -48px; } -.ui-icon-arrowthick-1-se { background-position: -48px -48px; } -.ui-icon-arrowthick-1-s { background-position: -64px -48px; } -.ui-icon-arrowthick-1-sw { background-position: -80px -48px; } -.ui-icon-arrowthick-1-w { background-position: -96px -48px; } -.ui-icon-arrowthick-1-nw { background-position: -112px -48px; } -.ui-icon-arrowthick-2-n-s { background-position: -128px -48px; } -.ui-icon-arrowthick-2-ne-sw { background-position: -144px -48px; } -.ui-icon-arrowthick-2-e-w { background-position: -160px -48px; } -.ui-icon-arrowthick-2-se-nw { background-position: -176px -48px; } -.ui-icon-arrowthickstop-1-n { background-position: -192px -48px; } -.ui-icon-arrowthickstop-1-e { background-position: -208px -48px; } -.ui-icon-arrowthickstop-1-s { background-position: -224px -48px; } -.ui-icon-arrowthickstop-1-w { background-position: -240px -48px; } -.ui-icon-arrowreturnthick-1-w { background-position: 0 -64px; } -.ui-icon-arrowreturnthick-1-n { background-position: -16px -64px; } -.ui-icon-arrowreturnthick-1-e { background-position: -32px -64px; } -.ui-icon-arrowreturnthick-1-s { background-position: -48px -64px; } -.ui-icon-arrowreturn-1-w { background-position: -64px -64px; } -.ui-icon-arrowreturn-1-n { background-position: -80px -64px; } -.ui-icon-arrowreturn-1-e { background-position: -96px -64px; } -.ui-icon-arrowreturn-1-s { background-position: -112px -64px; } -.ui-icon-arrowrefresh-1-w { background-position: -128px -64px; } -.ui-icon-arrowrefresh-1-n { background-position: -144px -64px; } -.ui-icon-arrowrefresh-1-e { background-position: -160px -64px; } -.ui-icon-arrowrefresh-1-s { background-position: -176px -64px; } -.ui-icon-arrow-4 { background-position: 0 -80px; } -.ui-icon-arrow-4-diag { background-position: -16px -80px; } -.ui-icon-extlink { background-position: -32px -80px; } -.ui-icon-newwin { background-position: -48px -80px; } -.ui-icon-refresh { background-position: -64px -80px; } -.ui-icon-shuffle { background-position: -80px -80px; } -.ui-icon-transfer-e-w { background-position: -96px -80px; } -.ui-icon-transferthick-e-w { background-position: -112px -80px; } -.ui-icon-folder-collapsed { background-position: 0 -96px; } -.ui-icon-folder-open { background-position: -16px -96px; } -.ui-icon-document { background-position: -32px -96px; } -.ui-icon-document-b { background-position: -48px -96px; } -.ui-icon-note { background-position: -64px -96px; } -.ui-icon-mail-closed { background-position: -80px -96px; } -.ui-icon-mail-open { background-position: -96px -96px; } -.ui-icon-suitcase { background-position: -112px -96px; } -.ui-icon-comment { background-position: -128px -96px; } -.ui-icon-person { background-position: -144px -96px; } -.ui-icon-print { background-position: -160px -96px; } -.ui-icon-trash { background-position: -176px -96px; } -.ui-icon-locked { background-position: -192px -96px; } -.ui-icon-unlocked { background-position: -208px -96px; } -.ui-icon-bookmark { background-position: -224px -96px; } -.ui-icon-tag { background-position: -240px -96px; } -.ui-icon-home { background-position: 0 -112px; } -.ui-icon-flag { background-position: -16px -112px; } -.ui-icon-calendar { background-position: -32px -112px; } -.ui-icon-cart { background-position: -48px -112px; } -.ui-icon-pencil { background-position: -64px -112px; } -.ui-icon-clock { background-position: -80px -112px; } -.ui-icon-disk { background-position: -96px -112px; } -.ui-icon-calculator { background-position: -112px -112px; } -.ui-icon-zoomin { background-position: -128px -112px; } -.ui-icon-zoomout { background-position: -144px -112px; } -.ui-icon-search { background-position: -160px -112px; } -.ui-icon-wrench { background-position: -176px -112px; } -.ui-icon-gear { background-position: -192px -112px; } -.ui-icon-heart { background-position: -208px -112px; } -.ui-icon-star { background-position: -224px -112px; } -.ui-icon-link { background-position: -240px -112px; } -.ui-icon-cancel { background-position: 0 -128px; } -.ui-icon-plus { background-position: -16px -128px; } -.ui-icon-plusthick { background-position: -32px -128px; } -.ui-icon-minus { background-position: -48px -128px; } -.ui-icon-minusthick { background-position: -64px -128px; } -.ui-icon-close { background-position: -80px -128px; } -.ui-icon-closethick { background-position: -96px -128px; } -.ui-icon-key { background-position: -112px -128px; } -.ui-icon-lightbulb { background-position: -128px -128px; } -.ui-icon-scissors { background-position: -144px -128px; } -.ui-icon-clipboard { background-position: -160px -128px; } -.ui-icon-copy { background-position: -176px -128px; } -.ui-icon-contact { background-position: -192px -128px; } -.ui-icon-image { background-position: -208px -128px; } -.ui-icon-video { background-position: -224px -128px; } -.ui-icon-script { background-position: -240px -128px; } -.ui-icon-alert { background-position: 0 -144px; } -.ui-icon-info { background-position: -16px -144px; } -.ui-icon-notice { background-position: -32px -144px; } -.ui-icon-help { background-position: -48px -144px; } -.ui-icon-check { background-position: -64px -144px; } -.ui-icon-bullet { background-position: -80px -144px; } -.ui-icon-radio-off { background-position: -96px -144px; } -.ui-icon-radio-on { background-position: -112px -144px; } -.ui-icon-pin-w { background-position: -128px -144px; } -.ui-icon-pin-s { background-position: -144px -144px; } -.ui-icon-play { background-position: 0 -160px; } -.ui-icon-pause { background-position: -16px -160px; } -.ui-icon-seek-next { background-position: -32px -160px; } -.ui-icon-seek-prev { background-position: -48px -160px; } -.ui-icon-seek-end { background-position: -64px -160px; } -.ui-icon-seek-start { background-position: -80px -160px; } -/* ui-icon-seek-first is deprecated, use ui-icon-seek-start instead */ -.ui-icon-seek-first { background-position: -80px -160px; } -.ui-icon-stop { background-position: -96px -160px; } -.ui-icon-eject { background-position: -112px -160px; } -.ui-icon-volume-off { background-position: -128px -160px; } -.ui-icon-volume-on { background-position: -144px -160px; } -.ui-icon-power { background-position: 0 -176px; } -.ui-icon-signal-diag { background-position: -16px -176px; } -.ui-icon-signal { background-position: -32px -176px; } -.ui-icon-battery-0 { background-position: -48px -176px; } -.ui-icon-battery-1 { background-position: -64px -176px; } -.ui-icon-battery-2 { background-position: -80px -176px; } -.ui-icon-battery-3 { background-position: -96px -176px; } -.ui-icon-circle-plus { background-position: 0 -192px; } -.ui-icon-circle-minus { background-position: -16px -192px; } -.ui-icon-circle-close { background-position: -32px -192px; } -.ui-icon-circle-triangle-e { background-position: -48px -192px; } -.ui-icon-circle-triangle-s { background-position: -64px -192px; } -.ui-icon-circle-triangle-w { background-position: -80px -192px; } -.ui-icon-circle-triangle-n { background-position: -96px -192px; } -.ui-icon-circle-arrow-e { background-position: -112px -192px; } -.ui-icon-circle-arrow-s { background-position: -128px -192px; } -.ui-icon-circle-arrow-w { background-position: -144px -192px; } -.ui-icon-circle-arrow-n { background-position: -160px -192px; } -.ui-icon-circle-zoomin { background-position: -176px -192px; } -.ui-icon-circle-zoomout { background-position: -192px -192px; } -.ui-icon-circle-check { background-position: -208px -192px; } -.ui-icon-circlesmall-plus { background-position: 0 -208px; } -.ui-icon-circlesmall-minus { background-position: -16px -208px; } -.ui-icon-circlesmall-close { background-position: -32px -208px; } -.ui-icon-squaresmall-plus { background-position: -48px -208px; } -.ui-icon-squaresmall-minus { background-position: -64px -208px; } -.ui-icon-squaresmall-close { background-position: -80px -208px; } -.ui-icon-grip-dotted-vertical { background-position: 0 -224px; } -.ui-icon-grip-dotted-horizontal { background-position: -16px -224px; } -.ui-icon-grip-solid-vertical { background-position: -32px -224px; } -.ui-icon-grip-solid-horizontal { background-position: -48px -224px; } -.ui-icon-gripsmall-diagonal-se { background-position: -64px -224px; } -.ui-icon-grip-diagonal-se { background-position: -80px -224px; } - - -/* Misc visuals -----------------------------------*/ - -/* Corner radius */ -.ui-corner-all, .ui-corner-top, .ui-corner-left, .ui-corner-tl { -moz-border-radius-topleft: 4px; -webkit-border-top-left-radius: 4px; -khtml-border-top-left-radius: 4px; border-top-left-radius: 4px; } -.ui-corner-all, .ui-corner-top, .ui-corner-right, .ui-corner-tr { -moz-border-radius-topright: 4px; -webkit-border-top-right-radius: 4px; -khtml-border-top-right-radius: 4px; border-top-right-radius: 4px; } -.ui-corner-all, .ui-corner-bottom, .ui-corner-left, .ui-corner-bl { -moz-border-radius-bottomleft: 4px; -webkit-border-bottom-left-radius: 4px; -khtml-border-bottom-left-radius: 4px; border-bottom-left-radius: 4px; } -.ui-corner-all, .ui-corner-bottom, .ui-corner-right, .ui-corner-br { -moz-border-radius-bottomright: 4px; -webkit-border-bottom-right-radius: 4px; -khtml-border-bottom-right-radius: 4px; border-bottom-right-radius: 4px; } - -/* Overlays */ -.ui-widget-overlay { background: #666666 url(images/ui-bg_diagonals-thick_20_666666_40x40.png) 50% 50% repeat; opacity: .50;filter:Alpha(Opacity=50); } -.ui-widget-shadow { margin: -5px 0 0 -5px; padding: 5px; background: #000000 url(images/ui-bg_flat_10_000000_40x100.png) 50% 50% repeat-x; opacity: .20;filter:Alpha(Opacity=20); -moz-border-radius: 5px; -khtml-border-radius: 5px; -webkit-border-radius: 5px; border-radius: 5px; }/* - * jQuery UI Resizable 1.8.15 - * - * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) - * Dual licensed under the MIT or GPL Version 2 licenses. - * http://jquery.org/license - * - * http://docs.jquery.com/UI/Resizable#theming - */ -.ui-resizable { position: relative;} -.ui-resizable-handle { position: absolute;font-size: 0.1px;z-index: 99999; display: block; } -.ui-resizable-disabled .ui-resizable-handle, .ui-resizable-autohide .ui-resizable-handle { display: none; } -.ui-resizable-n { cursor: n-resize; height: 7px; width: 100%; top: -5px; left: 0; } -.ui-resizable-s { cursor: s-resize; height: 7px; width: 100%; bottom: -5px; left: 0; } -.ui-resizable-e { cursor: e-resize; width: 7px; right: -5px; top: 0; height: 100%; } -.ui-resizable-w { cursor: w-resize; width: 7px; left: -5px; top: 0; height: 100%; } -.ui-resizable-se { cursor: se-resize; width: 12px; height: 12px; right: 1px; bottom: 1px; } -.ui-resizable-sw { cursor: sw-resize; width: 9px; height: 9px; left: -5px; bottom: -5px; } -.ui-resizable-nw { cursor: nw-resize; width: 9px; height: 9px; left: -5px; top: -5px; } -.ui-resizable-ne { cursor: ne-resize; width: 9px; height: 9px; right: -5px; top: -5px;}/* - * jQuery UI Selectable 1.8.15 - * - * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) - * Dual licensed under the MIT or GPL Version 2 licenses. - * http://jquery.org/license - * - * http://docs.jquery.com/UI/Selectable#theming - */ -.ui-selectable-helper { position: absolute; z-index: 100; border:1px dotted black; } -/* - * jQuery UI Accordion 1.8.15 - * - * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) - * Dual licensed under the MIT or GPL Version 2 licenses. - * http://jquery.org/license - * - * http://docs.jquery.com/UI/Accordion#theming - */ -/* IE/Win - Fix animation bug - #4615 */ -.ui-accordion { width: 100%; } -.ui-accordion .ui-accordion-header { cursor: pointer; position: relative; margin-top: 1px; zoom: 1; } -.ui-accordion .ui-accordion-li-fix { display: inline; } -.ui-accordion .ui-accordion-header-active { border-bottom: 0 !important; } -.ui-accordion .ui-accordion-header a { display: block; font-size: 1em; padding: .5em .5em .5em .7em; } -.ui-accordion-icons .ui-accordion-header a { padding-left: 2.2em; } -.ui-accordion .ui-accordion-header .ui-icon { position: absolute; left: .5em; top: 50%; margin-top: -8px; } -.ui-accordion .ui-accordion-content { padding: 1em 2.2em; border-top: 0; margin-top: -2px; position: relative; top: 1px; margin-bottom: 2px; overflow: auto; display: none; zoom: 1; } -.ui-accordion .ui-accordion-content-active { display: block; } -/* - * jQuery UI Autocomplete 1.8.15 - * - * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) - * Dual licensed under the MIT or GPL Version 2 licenses. - * http://jquery.org/license - * - * http://docs.jquery.com/UI/Autocomplete#theming - */ -.ui-autocomplete { position: absolute; cursor: default; } - -/* workarounds */ -* html .ui-autocomplete { width:1px; } /* without this, the menu expands to 100% in IE6 */ - -/* - * jQuery UI Menu 1.8.15 - * - * Copyright 2010, AUTHORS.txt (http://jqueryui.com/about) - * Dual licensed under the MIT or GPL Version 2 licenses. - * http://jquery.org/license - * - * http://docs.jquery.com/UI/Menu#theming - */ -.ui-menu { - list-style:none; - padding: 2px; - margin: 0; - display:block; - float: left; -} -.ui-menu .ui-menu { - margin-top: -3px; -} -.ui-menu .ui-menu-item { - margin:0; - padding: 0; - zoom: 1; - float: left; - clear: left; - width: 100%; -} -.ui-menu .ui-menu-item a { - text-decoration:none; - display:block; - padding:.2em .4em; - line-height:1.5; - zoom:1; -} -.ui-menu .ui-menu-item a.ui-state-hover, -.ui-menu .ui-menu-item a.ui-state-active { - font-weight: normal; - margin: -1px; -} -/* - * jQuery UI Button 1.8.15 - * - * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) - * Dual licensed under the MIT or GPL Version 2 licenses. - * http://jquery.org/license - * - * http://docs.jquery.com/UI/Button#theming - */ -.ui-button { display: inline-block; position: relative; padding: 0; margin-right: .1em; text-decoration: none !important; cursor: pointer; text-align: center; zoom: 1; overflow: visible; } /* the overflow property removes extra width in IE */ -.ui-button-icon-only { width: 2.2em; } /* to make room for the icon, a width needs to be set here */ -button.ui-button-icon-only { width: 2.4em; } /* button elements seem to need a little more width */ -.ui-button-icons-only { width: 3.4em; } -button.ui-button-icons-only { width: 3.7em; } - -/*button text element */ -.ui-button .ui-button-text { display: block; line-height: 1.4; } -.ui-button-text-only .ui-button-text { padding: .4em 1em; } -.ui-button-icon-only .ui-button-text, .ui-button-icons-only .ui-button-text { padding: .4em; text-indent: -9999999px; } -.ui-button-text-icon-primary .ui-button-text, .ui-button-text-icons .ui-button-text { padding: .4em 1em .4em 2.1em; } -.ui-button-text-icon-secondary .ui-button-text, .ui-button-text-icons .ui-button-text { padding: .4em 2.1em .4em 1em; } -.ui-button-text-icons .ui-button-text { padding-left: 2.1em; padding-right: 2.1em; } -/* no icon support for input elements, provide padding by default */ -input.ui-button { padding: .4em 1em; } - -/*button icon element(s) */ -.ui-button-icon-only .ui-icon, .ui-button-text-icon-primary .ui-icon, .ui-button-text-icon-secondary .ui-icon, .ui-button-text-icons .ui-icon, .ui-button-icons-only .ui-icon { position: absolute; top: 50%; margin-top: -8px; } -.ui-button-icon-only .ui-icon { left: 50%; margin-left: -8px; } -.ui-button-text-icon-primary .ui-button-icon-primary, .ui-button-text-icons .ui-button-icon-primary, .ui-button-icons-only .ui-button-icon-primary { left: .5em; } -.ui-button-text-icon-secondary .ui-button-icon-secondary, .ui-button-text-icons .ui-button-icon-secondary, .ui-button-icons-only .ui-button-icon-secondary { right: .5em; } -.ui-button-text-icons .ui-button-icon-secondary, .ui-button-icons-only .ui-button-icon-secondary { right: .5em; } - -/*button sets*/ -.ui-buttonset { margin-right: 7px; } -.ui-buttonset .ui-button { margin-left: 0; margin-right: -.3em; } - -/* workarounds */ -button.ui-button::-moz-focus-inner { border: 0; padding: 0; } /* reset extra padding in Firefox */ -/* - * jQuery UI Dialog 1.8.15 - * - * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) - * Dual licensed under the MIT or GPL Version 2 licenses. - * http://jquery.org/license - * - * http://docs.jquery.com/UI/Dialog#theming - */ -.ui-dialog { position: absolute; padding: .2em; width: 300px; overflow: hidden; } -.ui-dialog .ui-dialog-titlebar { padding: .4em 1em; position: relative; } -.ui-dialog .ui-dialog-title { float: left; margin: .1em 16px .1em 0; } -.ui-dialog .ui-dialog-titlebar-close { position: absolute; right: .3em; top: 50%; width: 19px; margin: -10px 0 0 0; padding: 1px; height: 18px; } -.ui-dialog .ui-dialog-titlebar-close span { display: block; margin: 1px; } -.ui-dialog .ui-dialog-titlebar-close:hover, .ui-dialog .ui-dialog-titlebar-close:focus { padding: 0; } -.ui-dialog .ui-dialog-content { position: relative; border: 0; padding: .5em 1em; background: none; overflow: auto; zoom: 1; } -.ui-dialog .ui-dialog-buttonpane { text-align: left; border-width: 1px 0 0 0; background-image: none; margin: .5em 0 0 0; padding: .3em 1em .5em .4em; } -.ui-dialog .ui-dialog-buttonpane .ui-dialog-buttonset { float: right; } -.ui-dialog .ui-dialog-buttonpane button { margin: .5em .4em .5em 0; cursor: pointer; } -.ui-dialog .ui-resizable-se { width: 14px; height: 14px; right: 3px; bottom: 3px; } -.ui-draggable .ui-dialog-titlebar { cursor: move; } -/* - * jQuery UI Slider 1.8.15 - * - * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) - * Dual licensed under the MIT or GPL Version 2 licenses. - * http://jquery.org/license - * - * http://docs.jquery.com/UI/Slider#theming - */ -.ui-slider { position: relative; text-align: left; } -.ui-slider .ui-slider-handle { position: absolute; z-index: 2; width: 1.2em; height: 1.2em; cursor: default; } -.ui-slider .ui-slider-range { position: absolute; z-index: 1; font-size: .7em; display: block; border: 0; background-position: 0 0; } - -.ui-slider-horizontal { height: .8em; } -.ui-slider-horizontal .ui-slider-handle { top: -.3em; margin-left: -.6em; } -.ui-slider-horizontal .ui-slider-range { top: 0; height: 100%; } -.ui-slider-horizontal .ui-slider-range-min { left: 0; } -.ui-slider-horizontal .ui-slider-range-max { right: 0; } - -.ui-slider-vertical { width: .8em; height: 100px; } -.ui-slider-vertical .ui-slider-handle { left: -.3em; margin-left: 0; margin-bottom: -.6em; } -.ui-slider-vertical .ui-slider-range { left: 0; width: 100%; } -.ui-slider-vertical .ui-slider-range-min { bottom: 0; } -.ui-slider-vertical .ui-slider-range-max { top: 0; }/* - * jQuery UI Tabs 1.8.15 - * - * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) - * Dual licensed under the MIT or GPL Version 2 licenses. - * http://jquery.org/license - * - * http://docs.jquery.com/UI/Tabs#theming - */ -.ui-tabs { position: relative; padding: .2em; zoom: 1; } /* position: relative prevents IE scroll bug (element with position: relative inside container with overflow: auto appear as "fixed") */ -.ui-tabs .ui-tabs-nav { margin: 0; padding: .2em .2em 0; } -.ui-tabs .ui-tabs-nav li { list-style: none; float: left; position: relative; top: 1px; margin: 0 .2em 1px 0; border-bottom: 0 !important; padding: 0; white-space: nowrap; } -.ui-tabs .ui-tabs-nav li a { float: left; padding: .5em 1em; text-decoration: none; } -.ui-tabs .ui-tabs-nav li.ui-tabs-selected { margin-bottom: 0; padding-bottom: 1px; } -.ui-tabs .ui-tabs-nav li.ui-tabs-selected a, .ui-tabs .ui-tabs-nav li.ui-state-disabled a, .ui-tabs .ui-tabs-nav li.ui-state-processing a { cursor: text; } -.ui-tabs .ui-tabs-nav li a, .ui-tabs.ui-tabs-collapsible .ui-tabs-nav li.ui-tabs-selected a { cursor: pointer; } /* first selector in group seems obsolete, but required to overcome bug in Opera applying cursor: text overall if defined elsewhere... */ -.ui-tabs .ui-tabs-panel { display: block; border-width: 0; padding: 1em 1.4em; background: none; } -.ui-tabs .ui-tabs-hide { display: none !important; } -/* - * jQuery UI Datepicker 1.8.15 - * - * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) - * Dual licensed under the MIT or GPL Version 2 licenses. - * http://jquery.org/license - * - * http://docs.jquery.com/UI/Datepicker#theming - */ -.ui-datepicker { width: 17em; padding: .2em .2em 0; display: none; } -.ui-datepicker .ui-datepicker-header { position:relative; padding:.2em 0; } -.ui-datepicker .ui-datepicker-prev, .ui-datepicker .ui-datepicker-next { position:absolute; top: 2px; width: 1.8em; height: 1.8em; } -.ui-datepicker .ui-datepicker-prev-hover, .ui-datepicker .ui-datepicker-next-hover { top: 1px; } -.ui-datepicker .ui-datepicker-prev { left:2px; } -.ui-datepicker .ui-datepicker-next { right:2px; } -.ui-datepicker .ui-datepicker-prev-hover { left:1px; } -.ui-datepicker .ui-datepicker-next-hover { right:1px; } -.ui-datepicker .ui-datepicker-prev span, .ui-datepicker .ui-datepicker-next span { display: block; position: absolute; left: 50%; margin-left: -8px; top: 50%; margin-top: -8px; } -.ui-datepicker .ui-datepicker-title { margin: 0 2.3em; line-height: 1.8em; text-align: center; } -.ui-datepicker .ui-datepicker-title select { font-size:1em; margin:1px 0; } -.ui-datepicker select.ui-datepicker-month-year {width: 100%;} -.ui-datepicker select.ui-datepicker-month, -.ui-datepicker select.ui-datepicker-year { width: 49%;} -.ui-datepicker table {width: 100%; font-size: .9em; border-collapse: collapse; margin:0 0 .4em; } -.ui-datepicker th { padding: .7em .3em; text-align: center; font-weight: bold; border: 0; } -.ui-datepicker td { border: 0; padding: 1px; } -.ui-datepicker td span, .ui-datepicker td a { display: block; padding: .2em; text-align: right; text-decoration: none; } -.ui-datepicker .ui-datepicker-buttonpane { background-image: none; margin: .7em 0 0 0; padding:0 .2em; border-left: 0; border-right: 0; border-bottom: 0; } -.ui-datepicker .ui-datepicker-buttonpane button { float: right; margin: .5em .2em .4em; cursor: pointer; padding: .2em .6em .3em .6em; width:auto; overflow:visible; } -.ui-datepicker .ui-datepicker-buttonpane button.ui-datepicker-current { float:left; } - -/* with multiple calendars */ -.ui-datepicker.ui-datepicker-multi { width:auto; } -.ui-datepicker-multi .ui-datepicker-group { float:left; } -.ui-datepicker-multi .ui-datepicker-group table { width:95%; margin:0 auto .4em; } -.ui-datepicker-multi-2 .ui-datepicker-group { width:50%; } -.ui-datepicker-multi-3 .ui-datepicker-group { width:33.3%; } -.ui-datepicker-multi-4 .ui-datepicker-group { width:25%; } -.ui-datepicker-multi .ui-datepicker-group-last .ui-datepicker-header { border-left-width:0; } -.ui-datepicker-multi .ui-datepicker-group-middle .ui-datepicker-header { border-left-width:0; } -.ui-datepicker-multi .ui-datepicker-buttonpane { clear:left; } -.ui-datepicker-row-break { clear:both; width:100%; font-size:0em; } - -/* RTL support */ -.ui-datepicker-rtl { direction: rtl; } -.ui-datepicker-rtl .ui-datepicker-prev { right: 2px; left: auto; } -.ui-datepicker-rtl .ui-datepicker-next { left: 2px; right: auto; } -.ui-datepicker-rtl .ui-datepicker-prev:hover { right: 1px; left: auto; } -.ui-datepicker-rtl .ui-datepicker-next:hover { left: 1px; right: auto; } -.ui-datepicker-rtl .ui-datepicker-buttonpane { clear:right; } -.ui-datepicker-rtl .ui-datepicker-buttonpane button { float: left; } -.ui-datepicker-rtl .ui-datepicker-buttonpane button.ui-datepicker-current { float:right; } -.ui-datepicker-rtl .ui-datepicker-group { float:right; } -.ui-datepicker-rtl .ui-datepicker-group-last .ui-datepicker-header { border-right-width:0; border-left-width:1px; } -.ui-datepicker-rtl .ui-datepicker-group-middle .ui-datepicker-header { border-right-width:0; border-left-width:1px; } - -/* IE6 IFRAME FIX (taken from datepicker 1.5.3 */ -.ui-datepicker-cover { - display: none; /*sorry for IE5*/ - display/**/: block; /*sorry for IE5*/ - position: absolute; /*must have*/ - z-index: -1; /*must have*/ - filter: mask(); /*must have*/ - top: -4px; /*must have*/ - left: -4px; /*must have*/ - width: 200px; /*must have*/ - height: 200px; /*must have*/ -}/* - * jQuery UI Progressbar 1.8.15 - * - * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) - * Dual licensed under the MIT or GPL Version 2 licenses. - * http://jquery.org/license - * - * http://docs.jquery.com/UI/Progressbar#theming - */ -.ui-progressbar { height:2em; text-align: left; } -.ui-progressbar .ui-progressbar-value {margin: -1px; height:100%; } \ No newline at end of file diff --git a/client/client/src/styles/trackbar.css b/client/client/src/styles/trackbar.css deleted file mode 100644 index 5b49022f..00000000 --- a/client/client/src/styles/trackbar.css +++ /dev/null @@ -1,100 +0,0 @@ -/* -Copyright (c) 2011 Flashphoner -All rights reserved. This Code and the accompanying materials -are made available under the terms of the GNU Public License v2.0 -which accompanies this distribution, and is available at -http://www.gnu.org/licenses/old-licenses/gpl-2.0.html - -Contributors: - Flashphoner - initial API and implementation - -This code and accompanying materials also available under LGPL and MPL license for Flashphoner buyers. Other license versions by negatiation. Write us support@flashphoner.com with any questions. -*/ -table.trackbar div, table.trackbar td { - margin: 0; - padding: 0; -} -table.trackbar { - border-collapse: collapse; - border-spacing: 0; -} -table.trackbar img { - border: 0; -} -/* Styles */ -table.trackbar { - width: 250px; - margin: 10px 35px 0 45px; - background: repeat-x url(./imgtrackbar/b_bg_on.gif) top left; -} -table.trackbar .l { - width: 1%; - text-align: right; - font-size: 1px; - background: repeat-x url(./imgtrackbar/b_bg_off.gif) top left; -} -table.trackbar .l div { - position: relative; - width: 0; - text-align: right; - z-index: 500; - white-space: nowrap; -} -table.trackbar .l div img { - cursor: pointer; -} -table.trackbar .l div span { - position: absolute; - top: -12px; - right: 6px; - z-index: 1000; - font: 11px tahoma; - color: #000; -} -table.trackbar .l div span.limit { - text-align: left; - position: absolute; - top: -12px; - right: 100%; - z-index: 100; - font: 11px tahoma; - color: #D0D0D0; -} -table.trackbar .r { - position: relative; - width: 1%; - text-align: left; - font-size: 1px; - background: repeat-x url(./imgtrackbar/b_bg_off.gif) top right; - cursor: default; -} -table.trackbar .r div { - position: relative; - width: 0; - text-align: left; - z-index: 500; - white-space: nowrap; -} -table.trackbar .r div img { - cursor: pointer; -} -table.trackbar .r div span { - position: absolute; - top: -12px; - left: 6px; - z-index: 1000; - font: 11px tahoma; - color: #000; -} -table.trackbar .r div span.limit { - position: absolute; - top: -12px; - left: 100%; - z-index: 100; - font: 11px tahoma; - color: #D0D0D0; -} -table.trackbar .c { - font-size: 1px; - width: 100%; -} diff --git a/client/client/src/styles/verdana.ttf b/client/client/src/styles/verdana.ttf deleted file mode 100644 index 5a059d23c476d9d68d190136ec8cfccd5221310d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 189144 zcmeFacbr^DmG@n@!_0KfIo*!a-P2*FC--QAq!|T|ZCSxawq=lPfrYWbL4ZkKFB#cO zTyiqtC7A`;7_fmQEy3ipWH2T!EU<)KGG^ZIsh-x1jrM)s_w)Rt=ks~0bkDtY!>Ous z&hONzx;?teP)bE1Hg$M;|L&dVMW1_2Sw3-4snm@-msfVEiuHZU^6@LVE4%Z&J^Kfz zy;~^XOnGMK{`0r}u=JA(<&RSS$FmRY-}T*p{08?1Or@;v-Lt>lxpx1P(n=XW;rihV zmd`nO{MS#uN~!R-m9pP=*;Plb{$ckc&sFNVZlwkvec9uVn`gg%t3|0-PVmgj9&z>M zSKa!#tM)4O;wLL*dGF;%uDe>rl!N*X!OwsBl}~uY1q(k-Ds}4?W&A99?C4e3@1MPg zx{~i#>bmoeJ^aYgul(V2N8lyxpE||~->~bAly9Y6I(F6Z>wkLhGd=L$rIh#Uk9zpE zkACb2Z`iLa&pV)$`z2RC=CUKcN4($$rC#+JY2Q^xuD^O<%JLnazlZ0|M<2QB;mh?) zZc>(4{#+^N`By*Yy5psZ)bo|)jmun)Uw!SvuO7PkmrF{$Y=%1iqD0nqd+r;@ayuX9 z+wxnL8sdafZ@po;Ci{=Iy5^ssdH;)CFB&>Vk$%cq63-2}{<@DgHMo9_>qVMV@0zC8 zcgq>*^=eQ(O4)hRuiEMYYIV|9D_1SHfbo2;4B1~{ABSbRx3}J+uD85tNLgG1Hmluc zv)Epz2G*98c`=Or!u*{5rl~lwcK<;3uNSIM4Y`cBo62~tT(ezb{~|kzLsTKj@`c`J ztr$h?+tix}ZdU(lkE&M=y-K~<{sncNrJ`=NzFxhH?M0k_6W70F`Kfvl<(IR+-}?Hs z?{oe+_NWnM|2nyc?HsoEv2k9#g6)ZH*H~X~T*PxfhR0voemiip;kI3(Zb7Oi?boZM z{mJSc`%Bby19kR3b&u`k>YjlK%2suc^`YuH);Fkz{U-HU+i}i+fP4PJ{%m!f?aRHr z{rQ}`UOm(HpQ!Cy>JH&K_)~Sr{v@?*`?(rme*^XZl5GduZM5ON_UPJQX!`-%=hQLV zU)0^U5%oy+SK2n`Y^}u8@xx|E$40DQdj8bxX*fp ze*V$cVYR@u+qrk1Ixb+pMUHI~>Jocc{WEfSBK!Ao?R~o6(s%kTeO~X=)zW_5CTZ7$ zH)$j7+q}`HTP&TmpRxUxWBaMLN&7Z!(yj+==*f10*3oO%_4PJ%a?n^9{wO?Sbx2*Geo0d6xxBPHTY*3-|_p*J&uGF&K!bac4hI#IH@c5m( zL7PPvqKE#TV{Lm6RhO{8L5`&j{Y~4M*czMI1@f7K?=RTL*+R%H&%ViagzW-0kK}hl*3rGqJfxi*1U1h;3l=UfYk*8*SHp_&Qj?Ht83#F^aYeWK*A)jsD-ZzTHf{ zTLdp+v(nB}ys<5@Yq7DueT&^o-=&{oU;VwtUQ1mmZO|CR&iZ@79eun_?;ncYP`2Ji zpTVKnTYoRI5t|b{3MSU~FYLER@F^JS@3joYE=7*AUzbIHZ+mtR-vj@!j?M2No20tR z?owA+|Dc=$`)EJ?v8^GOOVleId$|Ai*zZr(JM3S_zx_~s#r9bB74d17mnfg@E9!-o zud1iX#_{d!ukQE1FQZd?^e;H;%b>qUK3dLyv&UD7Ebv(-`w)6)fXUyme;E6}u)h%* z8loTe&lR60entB=d<**iu$Hf2_1f$@XKmcdqaMi~YwW2HKnkj`w`mfCtR%RJSX2KN7k>rqo}E zY43MnzvADmy**J`)Y!IZqik8f=K<&Co+;7kW?%cj^4bp`Sl;l-|DVtQ55B7Jv)I>c zA0^)TAMRWCNw=-<-!b4s77}MXTX~UbNNi8^-}hDhy|!18bAP;A-;2FzonvpJbL_6? z8`t@s@?$b~5W6B*J(lCE<@gcegJsjP)?d_w<9zI2eAnC6OR0N8Y#Tk-unjxd-v!Qp zD}DpLeqggs|L^htmB9b51p2mm`u*CEPJbSM+4m>^i~WPg?7si`U+o`^xxXnh-r>7k z;OT^8kT~cveezr(t-#hR-lur;?oUy4)SFKT(W$eaD^NX36XEc)XoPrqfCX(uPi)@OaW5*PVv< z&VbAB@zetWm(%Za1`MxZbUOZ`*OTEfc~Z!oB$r>3u89h%w8zRj?vXkTzZB)1*Y6tj z%F*yJoIFOlcO%UW^q$b=PO(!g9w)&)lgZrKyCl^4wN4-%@cNB_liK^|y`JNpfZyx) zdT5`g<4Jh@MNiSwytCP98VJMX@q6pudMD5zXIvQ7Znv%jY_NXD>UYL(MyTT!pW26`q;hnRv?|aPs`P*W))@e#w;Ah0&t5 z9dFtnbr0X!@fyXn@3_}l@{W3Zo@|5mgpUV2LD!uwm(Sz!-05+KoQB_TxZHj}(slWZ zPQRyf{J7KYHN1g9$BPV#D8%axmVB`AHv*w_vk(a6nn=O#DLD;~XEcaTj0~Fb_yW$D zZ`c#)xC3sl$LVpw<<2_|r`LsQ{WMamXkDO9f7R^EcGF%&d%D~c)dm$oX@;Y{hXYt) z+9((WQLay#RFVtU79wf%ZaEXF$GDmL(Ar;>Lph;NOQg?b zU(Dwm5iXNmet4lO}sCp>J4^t0=9#)5;N7SWj zKU0@#dYQV6*^x^8^&_}4t*ZxCYu8u*EY5GX@NRF>iS3n=79<}yUM#QV2S84ia z^=OVCqaFjjT3x;N6LpQc7J99w*Qx6`KCX^KAFCd__V4O(>T%G=tLvfHYx)HB1dgAm zp1Ag7^(6Hq=#$k`pij~C26Y3+f2aO#?MLcHbtCle)l;EQRZoLHP1C2Vr?34`JwrVM z`b_mq=(E(bq0iRzIqErUKTs#s3FuAgCg{!TAE5uBo(p|0^!w_0>Uq%TtLH;spk4rd zp?VSYMbPi5e^mbneX)8m^d;&g(3h&0L0_g`zILB_xu&mBujKfZn!ZZCisM(S*Q|Y4 zy++g5s#`d|Mbp=**Kz!M^@g>3)f?2U&|5YAC-p{-->B)E)SK46qu#9E0)307Z&kN( ze4D0kQ*T@Qw)$uFcIeyHJD~4SC!r@byV44nLBFBiuig*+7xgdD52z19Kd3$g{gC?b+Sk>GHT{VC2*>}b zJ_`M)`WWT4W-P1CQduXFqj_06>}t8c1rLBFNG z4gI#J-%;P;_+EAI+LzRK)qT+WH2t3XKF8nJ^att(YhP49R6m0LNc|Z4WA*RQf7kRU z>L+VoP(M{ah5m>78T4nG{#^Z><6o#>tbJbnr}|ImFV(N0zf!-3{#yM8`Wxuy)PJe} zg8sMqZ|HB;@1Va^zlZ)F`dRe{^#|x5)gPgMQh$d2S^Z`0GwLtue(3$`uh740x~A4R zR`^k6z02WsD67?O9~^WIT5Yz$L95*g?I$@iIN%%_92y!N7#iZf0mqPI(81Xu_Je~q z?ilDLD~l!80jonwHu3-$>}2lbdB@QDZL+hHHj0DPJ|LVOJUi%g2w$#32C0y9T-T?h zPA9eVs>LE#tphfx#%i&7sbP@2?RJ<@-zM$@R?TOK=8)wcsb@$k93s;g*^%Y?038^x zNzpMdXd`PXWg2N8aP+z)O>%LA)$T%E{L|0(D(Laj)XtS&mhR}A96i2p?L9(0bc9Rv zdcY=vm9hm^G}2+=F}f@ww@UK{hwLKALHA)DRSgNf)GQ38Si z^bYOgR*VbX%M%&~TwxD{0ljt5DrX15Ej3GP?AQ*9*N?~*&0KIRh4sWaQI^w5H-?-J zr_{;gJV^b{L4YJy#x*R?f=_LA{B^B0l$JoYr$6wU{K2>kbPpdtCcB zAuhS(#2?vRh*Xym9l~%5ZUt)eNwW~#3a~}|B*87skxLwidlC;vk9xNYlr(N#F7B5{ zxZ#1gmF94jHVL%RmFC2Kl5hs%L>$f@ZaIN-5Zr1;cBh*=HgHP?f}@@to}!x3X-H30 z8&pJv9oZQnIEg9{wj7D+a9+C;WHRWM8=PWOXC`h18>h*AW%u^FW70XLAta*K3KiVi zM2v2yQ)5nZlX|%Aoe(IBbLicm z?MEt=AqeWhoNWVcuId}a%l7K*=}lOi!YwtxxnE6>tCS?WV8$gEd&Y3d0>Qx{St=r^ zkPt%#WBe3%^XU3`D_1mb8TC2VxMfcp__vN*LA)r)HcqNzbhM^lRkl4w`c>!Xa$|Ztw*fEG3Xo; z(Q~MVa9CpW#3ZO-Xwc$x2i@S-4m3Rua66=N+hZnF2bIE|XiEG$nw9YoAR{^t&A=>V zc*G{2Dq zbAr{#A-DK_j1551AS$*F1T`P={tQz*zKOe_LRd&+Xa+l}2ZI(PmEnhWOaFBH00CpH zm^F0?ZpB*dQWhrC7%_e+c`biq7Y*V$lz{bPXx=rUxr4K^>+)WN~@I9)1WQ-~+c32+A~WL+*0MG3cQ_ z^v*@`*c!J|n@4J7_*%amo7#k1u>nL+mf>>)xBBMO;&zCa2V$^J;md6dJ?Kx>-)4 zVCZl-y`CYD#x2Iia42oHTL;1-5pg1?!>y=ZEI{)_Xi^Ubt*t^HmrK3N80G_U%RK;6 zUlt~UTe>9FhfM8*UhO*8Ilzn5=SB_dvs>bPYTble&2{}o89`8%;C7&gTL%yva?nVR zfR!!}xSVeNGz!pC5zvubE-D_>cOwRkY)qVgn{bP(9pL?h+|MPn%+Zh&9cmV`_jsKk z6UhrOMQ2i}5K-L*ZYlS0>(;jtaQGgCTZdS#esF_q2;+fA8+Y`ML{t(2d!$_$tF*TF zgn)p=aErk?>5BLsEJ2U%|3~3gRMt!DT?4ni-U(UMk(hG8ibj?4dC{1YP72oOF<#N@ z(vuYAU`0?Cw>RPiw}8*#bFwVqaOvfj9yh2CDu=ubV#o{s&baKtcwG!?PNv4#lst-r zQ7|hQR{M}uP$yF>?ib<1Qieb$cBzxL3&HKFI^=P^@lFe4loxEo3D~O(B@Vf88br2m z;Tp~Gc^zJsNW|?sWTMH9cH2NiMi6Y&Zs%F*+r)i{eu4>UB}Ok!M(S}na8*o|C5Vvg zA|o+ZE5k2wsZ&HYK-L4Pl(qdxyTGsT^1H$9kdHB$f9tHYK7^Ct!Ra`KTdu>o$5r#y zv9IRp@KLV~y`Y`}dEKbX;-5&;3#ZFH=ytiST8K{E5`sXM`U<$EIdYdwX~oj%jzG;N z=V-=|lkjT5@6*pPX>vMzh(LJ2LJQR8^zfF{>GZ-<20D<69JCn;Zs|60G(wX|2-UF& z=RqNIuh-9BCqWODIb~11o0CZGbXjD*Ig6;o8+xT(R7>hTr#&{M0UAXk{S3GcFAa0{ z-knL6XHe?t{%@&Py_UL2{#3`6!;e}?gJQE{YpitQ{sKO)@F4O8b{GWG^$}#U4ke2! zHkZTV@x^?CTjFQGiz%to4Q}$qHzl@MQ9ti zm9nnD?UBYJWyes!Gvu-l`R!B+D={y@5((*$<&i#a2e}UC9#_p54M~YSlpeEC<@bou+hkG2=5kuS{WG6?8^ zR_>G}iecmDA(*B7*uf(_-PD31;T;Aj%kyyZ1pH3FbOE>Tl7((=WDP7XeoUN*1i?U8 z!sYekV4x$c64wO>u|KH?lyF)m5E6#cJ~9dCL;NfSOnQI{@JzCbDNo~gq+Og58sY~` z1CD^5h(mMGtb~Q!+{-dG)>#I7hh0vJDtcV|Hw74I?eeQ87PFgUA?+w4GoWcOn9&nbLpi0s)957!(zdF!z8HzlJh;ECjzk zKO-)>Y<_MYN~O!hdrTF=1gt zetIv>6vxC7&x*`QERVTdes_o)oPJh0WLP@$lBoA|S*ue5FGCCJa9Mr(I4A0^A0?>$qiI+3mFY0?7cl9VC7Zx|yK5yo{83Epwfr4k`m6 z0eQ*vlcfO-B3i-^ub3GTc2cFtm}r(b+KvV2^;#EUjfMuZY&SNxj$16Dhg)qM+)5&L zlP$o{@?2g_mk^ONZm*2dUPgjJ`2iqZgOev1a0O&0>xH{at+|nxJV}gE$G|d47Tj`r zJvn)0!-A^TzDo}lQV$b|^?}ias4x!BU?m#2gcM}nbC7$ug}K}RJ-7)A{je}_>4h!5C{5oTy;UdF(c>x&mK>lTn5<}ODBzV$nafXw@-ss>zW{^< zjq-wDQ0;fKJc(KeKfQ3$kq%u19^B;fxxB=taPQ%kpSwv-LxJ#m1oZ&i_NBhQ7tx+B zi=Z}V5fvIj0&+L1AnE7mg9HWC?ZV(ZVYwl|EW-VN7H(1WhFwVKB=G~d5LzKI7z!2K ziu(%(1EM^MJkglftvm!8die%9@P5E$^#@Zyja#29Gy)lAb7!IysvIs$JgdZ5B?4xUN@`i#g7LVP-a-G48_*q1Z;8?^V(qvIp${M%gPjHk_XT(nc>kKg_^N+@AR>DHOWG`>R zt#Iyf6~4k%N|J;0!|ry8riOw($&?vOX=G627RSZUZow^W@Pb z5S2=BKFpT&ubG`g!H7l|@|1B;*vVcV+>}JLr^}me(T5@`@rgm)Gi}x9dZsR-B;lbv zo}ecZq$@!h){Dxe#xp7PHUHp!U)jCA?wt_j3S+AzA}Ty6R>4XqfA|&&VFg~o3q+5B zxLIHh`PXqvtm<`H1EEYv-nlva?y#3g%k5{`MZbd(2Ox7u2`WRdMqc=LhsWjj3WzWs zbj^H^J7gpvY-TDvz`Hd-j+ZC6z6Uw&qy#xnH34)$36 z+C+tuj|aSNA{U)mkf-YdJ+7KBT%{yA<%%DVA6L6rk?KqmiAQLr>DBD+!3@w zVlWiyW{xUijDlOpe_Hpjn3eA?`=~j6>YaUuH1X)`=UjF_N|o zltIG0*xcbT?gzsSgImt{_%jjaG$FTZh%ysE;pC5mJ>ed11#vRv^nlx}{Pl-^LBX>? zSIm4p0T^Zq;$293u#kFK4(2r3?a>e-6cy~DX|rekc{E_#Yk9d^Lj(Rm;}mURwuo>R;lq!Nw0|<%ywI5)qY9JUwfZO2s2#l;TPR{i1h>q7 zV?Gv^JONpL-;h0jC&gqi0&KBWKMMjrchHX?;0+TR$C7Zjcxw$kmV^Yidgv!U##0M! zVJV>ZV{SSLMtK1XZZ}d7x1LA@_Y(*QBGk!6tP9HsFcJ(=rb_01-as_siHP6F?aOc| zZRN#{c?!2Y`#{`+3SthhhLw0^2JMo1{2u1z^45jNuAP zg8bSC6%XA+Ik=Nw_fcM^0K-;Fi(Z6AZz}6@($761WYCW9HsS zVl!@;B%c?1hqMdsIV|+I3NR!)|JLD?WP|j9For$_9qCGJrPzX&rICP2)U7i z1opiw%HFVxQ|?N6;@B#QAXY~}h(W}dh++l&aUi%2cp?F>@_VD;RzSn5CW5ksqWLKA z${o(2H|__w-k{)Cz~4)HGU$%NI^f0VnddNW!xN{C#_`Z7UQH@&(+%P^##BQ=hqd16QBoJk4#~D8s%7RIRz@IV&;S`8Ry-~p} zZr>{}mbnq!=4pzoRB1oMkSoK}dUDHaQ5G|LrY=!@G#ZuVA3-hC2(N~aEC_K2sAct7 z{*1GSTdp(eN?Gj59S9Nv5OUDmWC#?w|lUl8F2{0IITN z#R=xdcmh#6gDWCQ#DhMDX&->V*W%awA@Pi`2>JqkP#yO9V&V$;QA;n5#x2uD7c(Jd zLt$j$Mwg5S7!9*!@fl1Mk}^a~k`XV6O~}44_4R$fLRgf*ZpiB!81fE)W)U-QBtx9$ZL3UIeE}9;bP|m6!-;_bxeeo! zgn6MZZ!Cs`2t|W2rgoeOgd{c&MZF#eWyu}8W@ z-0JnDFy|ppVvqsND;&5i3>Xh}mPgi63vTf_o`D`$%@?jxk{pBOAn-*~&R9q?;-T|2 zGRESY&mRagxrwkGL>B|RD?<>-66yKFA$srji6mKjkP%tbKr=!i&Y^S$K~YdLAy|h2 z*urB4`~h^xP>VS5jq!Le;^%cB(!q%ZC62}?3ojQMWHuCrkB3$fn_x6Ukq9>s3B^+D zGarp07Ps{OfY+D$`d&nPy4(}h2GzL5?L=|Uw3QlYgk%giC`Q66rQaV7q+)a>#_ZpJ zM&h=o`#udJzh2g=X6Wi=>6}i=mqaThf>@y%x46GlJcjbTGHD8eSicJT;$e+jd5M7` z*&^|BT;n$EO9oik@P*~g(uVL|E}0C*{iqsq2s&LX#bdm@U?SFvV@ZUacx&`XM8>od z+{WZ--UG_~SI3V`S249v4>uErdWY@Wtai8;*tI)X5nlW^fyh@k<2C6o`}j zp=8__7u@3Z31nsM)W?q)%BOG(=7H`5aZ8MXW1^KlnL&Hv@i<0}3lgWu<6<-x1_}Q8?&FmUtd%_KC+jkb2=+uiZO;n5UXb{{O*m>Rb>)bLC7bQrVs`KZkZs6(GxnN zf}qb9P1RET#>M511~Oq5gac7|ZPsI^8A?#;O9exrNB}!=VY0Ds#Lq%?ARJ7Eh~Wr3 z#e<851Olu}4<;$G*6IrQqcSSPG8iP#W2&u_SE&3zLIwa@D+!gzmP#c9foLj{qE60) zqcX-ull)ANax~1fU@($N1yZa?4KghQShSeveb8OQ81>v$Ca=JrRnLC%4WfFln@KaZ z(HWmFl}aHImz>7315S~q$OzH-27N=ac*h9Gf>?;90bUooq%8OPB2oTV6`67be7Sf4 z*kt6FYJNCqR@$HTCaLm>yh4&J3&n8maTUJ8RZ5amupA2dQ^|-g6pDp|$dcZM;!$3Cdjs6~$nYf|oY;*J)xkUQv^*!lWFU@tGcT9nGZ>A@Y7U!>J^*(@2S5Mw5z|PIoF)bgY6wM%&w;+*LFQh9^&s)7o9nKiD-w(ZdbXG_qb}la21}CGx1=+5e{V1v7jdt zm&|gL_$LyR_+U7iU{;qTfC;$fjXfPd&M#B+ws9D6r(MUEMONDu@K+{?2iuv#lB1;%~(O@W;NQPpd7Z1W9 z&o8A?DSQUuY^I=tJLD&^&1hJLucUbJKsZE5%{a9Cbb!7ETshhy$w!5MP7LI_*4ft8A-z|0?@b+ zCqhYJPG7?bK+4i|shC6oXaN_R3&-QpI6BlUlF@i9pHF0>(R_@jc{$!2kE5bPM!Zyi zJSMhcj(~@8xH1_LWYA|;(2h<5pkyc>k$qq4>-)Z`K6o#J+MGpHao%C)7;vNFpSg;E zBDjc$5@IAioK`d!FPo`o*bIb{QHG^6FM*6rISB%KSri>-9O~s$9arI!EMvrCegH*G z8RjSDpj1`zIh2Q+N&`DH8C8i$A+3Mv$Gdh1hBT1Pck;X|_xMtgQXJeyQi9u_6VQ%8 zg34eX)`>_cnc&Y5f@zF58KWJsJk61?lgO0dFzjZSbA=ryB~~pxkuYwY5G#`6=}00e z!!AiM$_rSBL&DiGw~~T-3+MA@B$6_ddFtd$JQX8+NSWcFhcf0WoRUQ|k{8^j;O-`X z<3@1XiABJ*jJIH(;hNtX^i#+|d=L=tLTz*=7|iGMkz~Xpr(*#g7pW#VgRcO!&Y%wv zN0Q-~m#lFs;+A_u$y7ul=p;?9WWsTGu;dE68J6K7tY8ocC*hQYK_aq&TZvB`J+7KB zT>DDQ(+?-`1+Tt*N;2Z1^E5I)NFQQ}OfZwkIz))E1mQ%Qwk5<%#WE?62wo(K7=SO0 zlM}?)oQtF)jFd5OTP~&OAPn$Mc&tP$jt+6<;czOJh!+aUY&2G&L`WJ=A`n>fIKfUh z4a-ahKEX8H3C_W7Hp>l>kUu|+c61W_q{0dQ_j!Km^S~scJzegJYJ-ZXaGZVGK*M!ZE;XJ>31n=_DG<=hqU=PppQUq>_|N*vXoVC2 zP_nKMZWFk_;ev_s!bG02WF(&w+!ixp^bT26!H@=W<(V??%6)-syqaQy8qdmNjjW0E zQXr7cX2az~BAJOrGHHJx8OfzH(M&QCOC`#QSOSNe#e?G+qu7+w6LpqiQ5*>K;Al3A z%M8S_JRM7CWY$Uw36X{0m>h6xEQWgGY_W2=6pv?1nKE^9CY2SeXN%FWk8(D}wL~IQ zEyc_7LW)US%tQ3XspF_HEs6FEj-{4k!>%<>W^6yyCY!DP%CjS@m@O=Po3HplWZe@pK=1*bXgV(Y4Y}*1zNtQV-xJja6;Y*mYgx)NCxDe)L8!Db9nD}Q%(3Ii zWGOvT&Lv~zP&Av+wMva=QUV#9aux*ivM4$o@8?t9R`EK+3@MaByE70;W& zP$pK)!7r0Z<}&q6GDE0aNTm`;IN?jC+}?z{Mk&d(B$X&6644Yac{-KL=P(>nREWIw zOUXe(*As)rQptL~mP!@s`8suSCRfNZz!s{BSb%aN$F)o*->jwTA%fEa#^xh>OD0qN zwt6X(%IL9F2Gd+F=U#6=ySQ6q8OkS<$cE0uV)c4Gl}`qHBIfZ-B9kx~=n|0BdJ{fhLO5_)7^D*Uq+~N?rh@!#L2}58 zT4L@VSIrl$QX(ho1;Ut2qF&7>LiK{=WWtq7Wocxcpdytq%dxUqac44Fj#&dJ(l!&k zB{SthkmjV^DO8?Hx)CNrdNPtq6bncl3R6JZClR!$6Ag7Qp z)3V=?yFL=po-X%9wLwKpCab8mg4}J=qa^!mBAYTXURZ@<&H$vU&8jILE` zJd=_jZ6g;zKrf4`&2&FY=X6%7HbWFC0-!QtYi^&JQmWIap}b@{Q_kcukhC&Wjj|ZM zD;0{mTxM!;xV59Dcq`^(2O?6ze^1f6CpYL<||sq$+?W1It{_%oIw6v`%r+r{FfDi@KHsl&#fj zW-^slsYRWcY$jjHWABwlIuWE?$!D{0DvdQWEn-_Y=93Q4J{}FYBRg`LoY-hESSpo( zJ!aldNp~)8#v`S4I+f1QnM9)1YGq29pqw_b>_9G^OBWgEfqv4R^d=*POd(TZoHN5Y zmc`ORDa*adQYFJ^7c0@+scO0qNOpW_zd!BIr8O%UWKtz~moi0iAGZ;|$x^wy$5r?W zS1CzuR?;bNF5POB(vfCGaymup^E9&Mqz}1bHBl?p-KZdA7K5faT*#J+v^Z^6D?t%F zcc%~ot}269XRuFI%19Tbmy%|VC9d)DikU9L0Gu|{#iCglF2cf0rz>VL-ySX1bLJ?e zR5X(!5}^~O=#Y?VIF(ITYngH~F`UM8C0Nw-*Xwx5OfuS__h_I;_Z??tqy z%Oa@FSwvODRWzBvnyF$2U9r!n^O<6*L|cd)GN#!qOf~6BD^9}`Qrnr9K*pwAPWQ7Y zx|r=}>6~Q#lj;eX4(0Q)5*QJya0iMRrKU%lC@(GlLw5-S$*E#?tSUzD&O}f_F*7vM zIlIFeU^rGYr%D96W=+<^WKE=(VzFASmg*D=#bGluT#3Yr>3VrMJ6tT}%7w8)PKK|V zX=ZcDTsD|9iMM@YlyXGpX112iCQVrKv{@dO=$Dif!mQY5%0X6FlY*wqT&FW;nzhbw zhdMb^sui*K+GsWvrd%s=txy=A95XvIYa{r}1)S3(44UE|<;b=u9fr>2%EDT%?dJl6kz4Eo6tyVKZxH(>^leTiG1W79&OO$+46p zWnq#YuI1=bqH5++-A1k)Oi%fpCCIb}9df8eH>6$gOnl2WYA_C?(tNT(5%%$b7nf;nL|4|33{s8N?!IN@l8oY zd%D~c)dm$oRkG>$SXGR>LXUDhSIU;mN_JR`B$hUd#j$di0XNr4W*Lv9wlgh(j7_k5trE@wfbEc?MVi@&`RrrDxQ>nR$u^JZIC^QPgxv^S7Rm{nTEHQdya^|U+ zj@Hz^DaFg#M5E9h_9YU9hOCC7;`NkBG#ZV}RJmNK7jpGlEK$z3sw4T4N;zLGPnPq{ ze0dbmqzfh?wJ&7)CJT9@(R8F>HUJHALW8FZ)sbpXooU$#ZVTGe=z22HOd&rtHCZS$ zrbecylWq(*Dg?%jiF_tPxiMTU!fB*CS(r)?oMKM-Fp)TqhJA^BPDqR0|{dO02>?`A9w@ zWnq#VX%v`irbcM)Vmm(^&UOR&P$(ZlE5Zr}1+y3I)(W+POpPTcxDMwYSK%vMr6hT> zkvIKib82EFpO|b&&YQG;m_|-987P!%?aXLx%qK!D*H{B+Rf{9Fd?}wVw;QoMf=7}j zV!&15=km-b%tnKAD19VXVc{dOWlN)+ui?#dRF|*S%GFj47L|OyQLa^HX6l`CWu_vb zbHNT@V zv?r*@t;TOH!(idc`Vy;aX9trI|^Tmv5Kb6{)f^jX6g1y|<@}W{h&1uED9bFk9}XQhtBCT_{D$tW}iC5r67nwOnPji9~qG%n&p0 zr@T+RUb0y%6^f;Ho5^pt+buUs@hSm9Ez9H8Vzo$sS}vB03|;{V!|O!BSKQZZZ3w8|xO`*^7yF&9F`2*Yx8kelVePGF-*A`FdP6 zU$_cS$+PWJAy6&OPPdB5*|y|T!B6LDWYmQy$%UwCp74_VHqy31u` zDM^siE;cH%?@N7sFQPqN?ulxHil7?Bd}^j8Cf=Y&B{B74t=uTKiZDx=$I#eNn=H!A%sozq#Bw-Q>CGELMgw&sg~Qnj*W7Uh-3tK-#H zX|_GAnw9zSB*Bi4MHRolQFcykf5djy0F$}tkzHfKY<6Ti&eAPo)_Tfjr>CdO+gq*n zM16RolgYNqGo8umWV=-xYi(=QT7oul8#bmuYU1ey1B~RBo zlVcbTsVGDyqIKP3S$-KQQCoSWzJ2@Fk&)@`liR72Gh@^3k#c!@sa8%>o*v^`t2Mc6 z+sO7Dv$pB!YArsJW&LJ^-;6w>RR^x({3j_n|rt<|Teng4Fz zzI|k(o@r^Z@_4J-s!njGTCbLa<#0LIsdws=jB{=7sU>U4vHDnDm{caG>ope6CP(V! zbGx;%czIV8U{v8C8WINe>O@_#u+R%zEN*3E__=bh$5r?WSK%pn+jOlOZdJE0P1ds8 zrX|;^w0@LEZuioQR;OE<>&yp5h^-E505hGD$xgLdtF^k*nHr;euwJj`kbRYyrXVM( z)6+<|K3$)zv|Frat)4aAs&#N^l}>$Yt#oWGU1X)TF2KbGOa3YTJv|>6WflYCMzD zWNmYvs`axddc4uk(mBa|HtB4JC{kep^@>#lb0vXnamdENB2&L3x&~nmLUtHr&6IXKR;hv9Uq_Qwnw@%xxz$! zab~VLH!jyvb)`4h#tM?KbKeWoxgl?j9YTKWlE4Iyo~vKRH^f&F^Z}vXtkixi&sNcivf}tHie9 z`T0gGHCia}cq&}DcDy~V$I{%~+#Ilvoa(`7Ju*H#K3wRwT8(C#&eUqFtE;2kc5Zxl zg3RON&GBY;tlMt3oApRNS})ABXWDbE33I|6A8ut^+3EIlTbR`6=G(1GyF54Au03RH zYdTfm8*ipkO*m*)FlaZsZOOtS7wP3fa-z|wM|xa^uW%KflFyoNHDcq+!?FM3CGBMhy z$ce_nJko8?x994Ux@Dxc*lf0owPAkyva-^qrh0MpAllJMkTc(! z9h3cr-1U)&_HADwG$ zo7grnhk=Z%?&zLv`8=;MM+?<(cxKeIWB(2NSp&>hmM1UV5@iOloULRlJ!YC=WqEnI zxqo)HyEHMnv{0yYTRRrEcD8nB$LDAF&5q9!oG(vKb{MY4G82>W%vgLcrHSH5esXMi zY^*T}OP-!s*g7vOEuGE?qv4nYw3E81t7<}b#i9Q^4w&zxxA;- z%u`<8GBpLKtrzZ{++V3gqsz-<X-b%D83zG|zTRYuiw>Ud8 zo*&Q8PtH%yHf9^`t;-Xgk%`*2$%*EXUE}lF)`h7~Cez8xb~Gy(OpGl}NEQ}_crRBn z-7z@#xC&q4Dm=*(`(%yq`ch9}0hHHcRxx|5yBiAHT~$JkV7 z_gRzM+RYuEvB}})NIaf7`)mT5$@cL6BWOn_LC^Ni;+1cUIQg>=~YHG9#OP=no?2_o0G%7@J z+ntf5tLZ>H-PuEjF6wqyFWz;CI=ge-?Wh`%gIPJRhqVA!3J&{;l zotn*eX>qrkPt@Ie@tR)Zc+O>-aGp_k+G7(=KT^z0NoSB`PnWZzG&Y?qxx;tlw z7e|-Kv)#PNbLWg-f{ar)we zyJqSauS%YsN_4y1Xyl;~9avmBud{dMKzwm=E62l2i|4Lv*|jna3>VK^9R`ctcz1TH z-kpt4P0dZUW*F?J&R#{j-PP{yiKWHi;ritdUtOAASzKJ4Sm|CgyRx#hj1E_(v6a=u z9orsuc-Q%hTOYP{dUkqbc6#^d+}zac(%j74>{x5+oT<5)z5C{NPj=3kp6-rxM&ohw zz=19`O^h76a!z~RPDjvl*36E1*>A{QAN5W3!TX-5HmC?{WqM-dqTM*qsg=3esoAN; zsckdcx+~MW#7OGn-KC`qR~~ioIZLyLMyFR7b*)n4nUr?TY|dxR^s^{>$9z9a=X6%x zV+=E-)=n@YRuRvy%qex%;fq$gyJq(;?p@q9d-3Xm+BtV*Z>=VvsgETRD|7zykG|}v zDi()Z`9$>XI|>t)M}%ZuVf>U;L=*}Z#r>QoPwW>U)&E0fK0=NIPY7xwLAnfB<> zqf6&5)R!lAkQbIp%UhPWoU`@Z#Vw0lW>PcRnbzv!>f)aH9V0tNmM0d57lwB)?p|D( zT$!BRvu|O3e6h1KL*{pvX09~16pLGm%Ugt%Fj(Aj?t)}tQBU=9v#>HZHUszaq$iDi*!uVopabd2txR9EgTVf)-IF8`=B3+ceXLiSOz23a~(fd{wR+m>+ z!0C~N)zy{V=x}w*j)jGND`)S#{E_D#THbN_&MotE?S(DpO)M?VE$mpDUs{;#%pI6p znm>5q(w^Dr16#H%wx=if?aRd%FH+NN`{-lwMmh;{_RgQZP4*jd*GD4S)8(G1HmC?{ zmDQLd=dH}G%&jgh%q_6rIlpspb;}-%WT`c?v}4DS)yH0TU}fRx#Fl+4Q&QWRmiEkV z&U@$kSrmQtwtkk*>8zHn*{M_KTreV5kt(e&DfRecm+oEKvv6?b;L4tb%l0j+bGBY_ zu*r-pwbYzUrB;`Mm(X(yUrd%1R#rJOl5Bi6sdtjS#Ul4SFmch!SB3bGsrVZ}{@){i zAQ%cqqOo`)$*&u-IbOLGOXbQiOF<)zW~)6q))}9eoSL4Q?apnPUszn)x@|j_xO3O; zvsTYO=iEK#?cKNk!1)(EEzU$rZx$ExtzVH42@_`S2 z=)>w?Kl-tcf8w4`e(KYo`RwOD{{{8MFMavnzVg+tsc(GqTi^c9z28-~fdh2<9=^Cc zpmwPnjK4FUXS~pOopI7wv!pB+T0UXY)w!Ojj7TY^*AGCeL_EUSte$;-WcQN~n>}#^0&i*?4M>E0; zqzXTNm@vEM7IVQ|HXmzVZ~mS6F7sD;dp?wp^4_4po10etp#@7}fOkK^0B+_GJqgg0#ClH-7mhxt zCvV-$mHN|Kn6CxDeC>pB4d1+0f90?H*3RaO%3If}>Y-}& zFSl@R{g+kuf1PWowZs~KNp%13@Bi)nzy9m5?*Dg=KXL!ve|`G>i}#oQ`|&?;{mAx% zfBE5!a3tQ*`Ok_de=duld$XzWJZuy6#(-d?)#}>90*3 z`iDbh`v>GZwi;$1*VUaOmd61&w#~_ME$5zWdA;QiJjH*BA<4RFZO&@yQx786q_t{o zapyMc@&hkfyALdHl&oiSKbs`$uHOFtom%yq1iZ%^)YH{7tWW0q&_CuI)X(Kh)34^s z&A0MR^%FRZr|~6ez7EVcr(dd`Z5Vu^_?LVc`mKB)_&0nV`1R^-VD004(fLw!8DF73 z%GZ(~&Nq}l$=8wjVzT-y-y?p6`l5U#neRPc&Nqi&z&DY<#MhCJ@pa;#sps%@?nm-% z?yLAR_oLMab_PGgs`TfRYT3>braU4G3t%UCteHqJ55HTD<|zB%tQ z+{SsvUiqT2vCr6V95Bu|E-)Tq95gO8E;24Q4jGpi4>cZU95#;drQ@#{GsdiOsd1Tc z)Ofh@2*YD|jmwQ=hR^UD0VAmHQ{OW}M%Z|yafJ~vqDI$vlyRkTmGNlfF~-$K%!tc3 zu8o9|G_EnOHBv^}$QW7UI^#IsPyQ2MbN+#mGfX3I6pY6jk24-`TyH$Vc%tzndp=Vm!qVKX#+>_r_DzdyQeEYSfIneEZpWn))hVh~_)ed_VeLzAgP7gZw@h0QV#)$D23jPDyi zFn(zK$of1>)l#$6EhCnOrD#MA5}=#lS@ZVs+-K)8y`Ax^Id**>ERLg z(c;k~hYp^!9-*$=6^%J|fD)|P4j(g5+F-0niZkm?lxxQhLyOBib=vcsc5FZRto(;k zCxh%)P6kF!?u66MC;l*HJ+Tshq$$M{C!S@Vyk+mf%~$hs&xIFW7=M5mb`*CUK5=44 z(cE$3@QEXLt=)KO(exKj+`hVc;_8*d=1Fzl!IK8(-+NQ)Bo+J z2NzTM08P#3rN1}bwWKbkaPr2z2YY2xU7ET>Ewx83JZU*BS3cCg5;hZ%x zE$i(Et%L-$bboPm??ngAl@o{8^|pRyrl-Z*Eo$5CMdR6fZ(lN=z5k+vcQY87&pvSQ z4vS&get6r3x0kqf@NN@B(Pu4kR!+(-rWDkwfmPgL8PfNs?p{*rMt#+$Pw4VxcNt2b z>)pgTLtS>4rFYKXzt6%sTkqVGK8LVHjh5{P4sLEWEf)(^>TY#l?L$l1J8GRN{~hKX zOLv@i$JKY-c*iYwoV?=;cieY}^Fw$1>JAIGwsiHoV)3cmvf;ZRcY$Tk`42na@|Xk0 zYY)8RfMxIgm~G$x!`_<*GY@_ezhJXk{*JTg${N*GGyivs;$%=373!jaP1sipf)M ziHglrwnd}0H99tL?V3oZd9`_sd82ug`C8{{=SJry-^LYdR;=H2-L-43U3cwzv$9GT zo@ZX*T)->ybzyntImGocalJ$WhkrQCyIxdY&ukvEScnO2LKVNDXf z)&eoz8Y!k(ZKBhfAi7;eqRUz+zTzkm9kHcitfNqLShGbN&WptDMpzx91vlf({0l}n!$$bTVQ`JZ;30>FA6#*eSN5;i&ztuK_Ezm}-z%E; z`p}$*<}-WW*xR)iYkTL5VMZRhOW=9J@zoO4eizvpQNdM=8oV=-;Qx_>AJ=7jD|R-I z7`$e~hWMRZ!MQtE#MkfB;vC57PO`Cnr?z5bsHrA37q%{3_^0e9d%066*(sMypSV-@ z6fdMNO!S2by2Mnn(@fiDPqCNmw3bZYX+`TlF0!!ufsfP=)gNMQZqZ-;CcT$dFaEr8 zf^3z3l#amiRsmB-k9R7p~`=90#xGL5Rp<_$%FygV6o-v6$P%9fB8g z>0>2#Jv`SVu(v<-ynQ45p@+DgJ+EowT8_SZH~gqaVUZ4S&*Q!I@O^HCReAW5Gv{&Z zxJ}%4cs_5F?i#7*c`H%x;2SQCKL$@>Bj?~UxMFTR{G!X@qwV5eCd2UF0K8X?cNf4% z+KhMi!x#I{#{jO5Yk;3M7q)UgtRj7+x{q5UTRE)yEFGg%6&o0BxvtOQ$v1cX0-tmee+GW= zb=+h8Opf}g&d|SRZUcOuZtaWK0(GAyK zsh_OBU~n5640johVUElS;}qkUrl-yM=2ybg!Z%p@SoTMdhzSwDL>aUR#5v-!;;Q3EBv=yeaMn71a4mI@Lu}UWiSRt& zIg=EV^j30P%Al05# zN#Czox~$l&ysWaUaedqX)Jyt|?lY&)iauNVoXsAWJtw<8`?~BM+559!%RZj{LkZpUBy)msTy0gqw4)?b9Hg`qUw`1Lu(pp=GCmK zxxVJ$i1{O>k@k`4Bae;x$Ece}ybDD!hIJDLPpF+RZNjn%w>Rn<=QqC9)Vpa=)5xZ& zO-q`tX}Y~>SJR74A2j{DDL65F;-*QJlbR+4CznnhJ9+Npm6NZZeBa~)laDmVH$Ok6 zX(~7M;IyV`UrjHV{_gbOX4qy-oVjx5qcdNcwR+Zlvrf&veNOtE5p!nG*)r#!bED^` z&FwdL*xZS87tUQj_vX0|&3$_AvAJK)Ju^?97dtO=-r$y~`MUYB^ZoPBE!ekk*uvwj zfz}%qiHlkmom@O?@v6(Lmw7K6blH(5HA`Mu^68RamL6KRcG-=~9$5C&vLnmBZrjjy zd)w}|uH`o@zi;`z<*zRPczMV2;6L8JeCy@+Uw+{7BbOg<@3+FevSsDkl{c<@Y~>3p zKVI3fvTK!Pm1mW*YW%8&tFBtLYt_qF47+0A74NJjt9!2=ySjb#?$t-uXx7B98L?*V zny1%XT-$eT>)IdJo?FMQ8@z7lx)JNfuA8)O=DOYMo?7?(dd+(C`fclPzp~Gj1y>Hb zvivH|RsX!|_|@dAPzyuKoVnv)8?R-J6>i zZ82@xe|`4#XKy%l!}nYDTb*08whrDpZX3VNvF)yH4{qDF?bx;tZ+!Ts0ooRRWxwGKTL3h4#=dn9Kyz}$BM&EVj zu8TXi-)+Bp!#$Dr+;;D%dq25v;r+$;|8W1W5A1tz-Gd)KH1(mm52rkQ{E^EZEqwIT z$CmFb+WE%L_a7hqc;n;m?MmF0vFoQ@zwN$lPw}3kPfUE`m%UFt8F=#feK+kNuz%!% zoCC!N_8mBM;N=5v9{Av?0|z%hJ>u!vPoMqgrhj%lGyj=&ht@nRJ)8FIvS-gem-XBY z&%N?|MfblKj4$kdaqeON;kLuq9lrVSj>9Kj^1QVDW%1>~FSoz^)hpGn-1ch3s}o** z?6r*79zT+FB>%{;BU6toKeGAA{YUY-}L^E zA7p%x`$6Fc#UDKILDz>BA71m}y&s4mUef_iJ zpSOKs`lA0AAAC9Q|Nr-2QefqmTfTh!%fnxO@#TdRktdQ)3^-ADV(y7`C+<7(?1>Lf zd~;GbX+PQfq;j(Ed{lL zoci?CPhV-ia((6hs^Y8hUwgmK{rd557JYN|H@APY|C_hJ>G)RjZSl9S{d?4RDc?Q* z-P7N_^4+`NefHhij`$8=htkp9vA*Ni???X-_rq5|#{PKVr;?wZJl*Sb@6-KG4?aEg z^oY}APrr8hou7OEJpJcq&p6H$oEdZGvNK!H+*ly!Z!-e7VaK09e@AjC@tZ{yi(a0Jf>@gVBj}+|T#@Cu9 zr^HLX2Ij(@==7dw-~t^vzCfQW0%SJQ;F5yqUG2RePube}G+#uY z=oa9lEAth1ovu}C(X~akMYTn@Ip8xV#7CKJWSWiG62h?Tu+?DIXq|D< zoSjU!6MKTh6NellPl~ZlYB3OO+hVZ92%?dTC9$!_Xa|WG!=H#u;3b_H_5_xki?oXd z4*rQ?HdGmS>?0m%2sA`Q7x+5VCqdB{d+qZzoba9KleO*;9-R&I>3@gTh0|mAD*#n) z0h1mCPb7Q#fjZ-vBe180&!ks^yT_B<-~-cFP7j`@hxbV3_}~#TddA8b#6%D2L4WZ3 z2_!&U&qvGlnnxEl1{9^59bms8=1qI8ElsBHL$_VTEfn8mJ^ zjAePUDT;Wpc$wE@^cxGK3KRX_BID4gVTncFvD%TYkvU`iv$RuOQ_?1TXJ$3`i;h=x zhWz-xy)BqZl3W^V?~@sklAp^7dbvG;BuIKoDYkVq7di`hw_C_{wPRrWxa@X0psUjH zI?j?An~_0LH0G|fPUGa90=)a=)ivsoG&M*1EqMBnjJYgJ_{1v-ac6k z4aAC_QaqO4B*mYTK%((S+r5cDH!t6kW5H{i2XD|u0!gx%h|L;Ba+6am1Btl)^b3nu ze_b0MIjMK<)m5p*@jEttb8PXHcgjo^JJuu&aon(@^PO3nXY<^m)k{{A<=c-&2Dbt? z?2~fX1)u?(@O?1bF%X;Z40eW@7jCdpSzwo!0*0z<{lx8UqfHeH_ty+-#m59 zn5oV6;+CFP?q?r;^yz0G{p-+qA9TYJw2tE)vhU&b>mPY!-MV0Or~$5B*!8&_Dg6lQ z*|`$#b7h_mGvy1zvTRxL{>*^`svM>9RmDr=3^S9O0&UV_ZJT*<{IaB$fh_@S4=<<7 z`BrUIyfxjLZwsV_rN<}dXKAzaidNB=hYhk;#TCU5aSd}1${bW!qpdfNOPV1~)y^_E z#U}*9qA=q&1|Y{FrGG?pzVKj-F+(>{^7#3vfJdL8%`grWe4MqfZ1n}gN+MnHzP_R( znFIGHlvs@pf^`&Z$qR>spJk*4nJwUA3y2T)?m&|R(F2sRy*|8&KgQS%J!Fl}%Znt~ zp+N4Yw+&2BJSj4UCy_FGUS2**>{tUsML)&a1n=f0`vv>_G2>gSu9!6CxnM8nKxbUy zL$@|ONoHjil4WO4F8s0m&0t5a$1~kOcOvTT?wt6@d-izO;t6D-$pkcBysvRiTYW`q zm1kWiN8U2`Nl%$uvU&G7{?VqUALj(G{cPj>pI;omwvTV5vuyLcqNUkcg^#Vxn3vIK ztSh)RwJEpnRaxM=yM<$971Q)KMbGmBF-wHY5SU`m@u_N^tn#i8sdIeeiD0u}#y4zS zol>MDI!z3T(WDBgQWYr^%A_hyBWcvkBl9%vWC_1SZr4O;2nkyz5-t5b?BfGyq!v3p zQRCzk*GGk)>F|0%`9d%{HA@Y|lgwMfBl2@>l(0NjM#AbL(SrHp<1f7M_{o|rfx?RN zfrU3$2Af|4+?|PkpS`9pf2O@H_`%%|1y8JKd#QxOFKr1n^BwFyXDS8IU6D4y7MV33EmTJ~2~Ckpxy5{o&=R@WYKtIZ*dmTZ1d!ho4g0#z?4dVI8w!@e zLCeWu0d2mP+Z-K!*8Ass59c)=KONo(e=eVroDAI;6~TAl#w)k?A6PzgKwwJ^I>HwQ z-wwK7)0e!|wt~bxbT>(DYk#I(|60(6JHL-#EY8QBTexc#T~#EpD7x@`E#>hsXpG~> zNuvy-Otbh|QnR7i)W)|-3k?fRVMI1#he@qP;<2Mhl~^tEBKBZFZ-_b48Od`NqY_TS zwVJRhj9R#fN0u7fZl&s4!bsR9iXAE)e2&4$X~3xDfcar6bHMk+>un&Kq)1Psl#)sE zCFFIJq9t*@65J}Ul!Ds^k$(iQ7(`~uD>Y=65?n1@Huv4&jb!?JbKiJl?z?1K@TPa> z9;GAm78ffW5IdnQ3KWmdfU`;07r{4$@k~ndlq7+05;9;( zq%T*_6(grM4f(9K$hbxDf)96t-(few1$@+2tm|l4cL*IJ!uZadNBCD|>$!s(q&#`< z%C67FP0|k-2M@PS>6J$c47p+bBl_EO6G}+Ap*XA}qQYLB5N0da@$Pa#Z-xx)rEaL% z%>guKz9$-IlvwI>a(4O=cN->gIg@z0egt0|>y~k%f@PxlS~;9b5B7J&x$=#PkR30i zry=w|`b>M>K*D*qi;6#1pn;n7!ymw`>RwcB!lFSDz^I9vE(Fg7&-{8GdB(6`gTG=mc&C|Q*>1Xf1z(FTKf>f%lZy`s z^Mn>u1Yma}z81FUGX-mWqZLIvh}UP7c-l!JfqqNCW*azSOA{GKdIiDPji0e01a~Tf6<)P$GHxU~jST;zuMe_-f$Vq~3mUJIT6HIJMqpjj0@T{yB{G zo#?@Ju)QwW-I{7=larSO*%BpSWh6^~sjty*3d9Ez3Y-;EnX$xF6 z4QDSNguKZeeioFV2Sy(FmW(7Y%+Nc1vZ(TD0BNXhrEEcYf@<0vngpQiLI2$1br-{D zyglyF#+$Aj_s$f3X~(>iMD(Vo%&3@kVzS^qHg-?_fsfl;uTTcR<>`0)>Dn!W2QDd} z@!}}Z@jghya?o)Aw@=xKJwSa9gUy#_NcN=_78?B4KD}~%Lk%U?qFzP5I#Msy8)|(s z4O4wH3zrxc`&#{Ng^t{Q#r^pH{Xk!mY02a>Gt-7Tb$xiV(P`wd&CyVu-s8?^tdx&! zmiXFy?4Kmp<|p)yatpl^`XOl`I2g;|9I(k90dv3^;KObn7=EfD{FK*gi7p7Io;DR6 z)hP@_FfY;93589C2Wy5gTEI7?hKCA^N-Zixi1o5B5h#^-RHW#4Y*A67DQn=+qKem+ zF8{I8TzhI(U}Hva%)rQ8F?8&Z8=t`Z=t%<`-)p2aopWzd+0e%>%UaGK^{$#W^})c9 zqW+#^eTSx}Wz4Lpo{`{;zPEi@UJaH!EgpEx(?2yMYyG(8`|T!e4zx}s_;oiTK|N>W zK2zKx7AH+K<{FEQE!a;AIz+AwGnQd2v6H6GSWXb-9->Sm*GiJ05d>{OU!~`vF`Z^! z6DESCz@LbW_jUcOKu+aa(S=>o^LQqU0lH5(b+`p!&BhFHK0v8w@n$K z*E+Ob?EtOcG9ao#TWlGt9hEjyyG)D4WE|yG$-)#QxrZjn3A|bF1Woj&q1cwJm#ZqC z!~+{pdegqgL)37@Mm#t&{S$9>bFO$D$3Eb0&oE~=GkD#0ugYZz-@s(7gB`x#xy;wl zNlhXP>Zo)37yJc*v>-~hP?@A`C9WAZxa_4XmVGhYG~!<~OV{LPU`|f%4dch`=r643 z9ONDAUb=T!^%(Nu^nVT-QjwGRc5XSQ-7TrAoast-+Qay+$AYb*n3kLWXvkLGhxn`) zm(Sgx^p&xKUO^Hn>hsH!2KOn-ZzOfbYFD*;ihEHXlS4==$7*HKL*oTA?}y=XWcVUH zZZ1LxYxVu_W{dF#$3_?*e5YX31Q@Ve3d{x00^aA=fw%TjhS1&EmwI|k1|fx%J{Vdd~`6cQ5(!%i!n5MI%YXvxiCc zW%Jwh#%Ij2!Jkj&_&xps2R1Y;%XC>&)1%Uyw>|04NP8T-g)EbJ19(g3s+4RL=oFS6iNWOzvdI!<}L(^5eFqjljO>kfg* z;atFGi8pjkc#l7Nai?%WJbl3=^?D3G(z32k#9O4Fxfm{$%O~3XTrvdK2%;uY$)%0N z?uMtk(F+Y_G5svln`_JIg$Z&w#kN7cic?B*s%_(9#>S3yj_TFutM76NUKFaNb`AMsRVFBr=lo>5XY_E-Kj- z5`tURF?YF*^rx9MHyX3u@-_@SH9#2q6Bu}mJPwu|-+Zcn12jNvKt+I(P>+lipO%p= z_pCCd(%M@WvRF(nHu8|uL)RJ6Q|Sy+IG`Aq&?a0|0y(85A@^bQG% zMs&$oCZ#*R6mJQ>ed2WR^J}kIvXEHc{gmi0Uv|y)9rvub{LY#YNmmb^Jj_|M*w@l9 zcFuuKn;#>$KikEfe}4HZ{bl9G1^0jU-aS*E&zB2#@>R3imrO02krvS}a`48^h2!V- zjY{s-=l+@Nc5a2N&F}h>`Gr*0Rx1TsF-A-i3zG`H{@%lqhIxy6j}aTA8|))uTS!}y z*%F^!ZcQt<%JCr$WX>Ku{Ei_gSsna*@VS-+%MD==D5CqOZ&qUN zfP+_@APGf9BZC+2-hMDQGiA??#wD3fTY9Q34Y=)Ch)p@Nu@o&$Qldy5FUfV1R>Nh= zgrl|uekOJ73p)!L+dy*Q+`};B@Z~??At)sN!VWn4p#7=fMt*bXTEmolY@seYB!`?X zd1b#?AeV?`uyFNqv)C%Ws4=sjk~MW&Sq`AAmKQ}XQ~fazuse{Uel@d1IgvD+!B3Xc zh=%^^#Y5duO^~aUR*0`bJ2dWDD3J^d-WN);-kvWc(1VlnK{ZfKplC^!R?+ezZ~{(2 zg&&Psa;QRN;TbStOq}LopMvR*&VzSQe?JWU+{pSlanEuAWqP!qspz6a`zbk5g2zi{T(`TQ z0_`WQ%TtK(w>=faQP|F%ABED*OL|JsQ~XIAFI+BcytqJI#Sic7+Cz{V+|${G`^OCl z9f-fM=pQ#jDW#rpqE+zQtN1FRN-DOGmqyuVh%>^Q?XC9KxG-%C;&vG;CPzi&I(V(K zHbLw1I-Rn!9q*fMx@Z>&%|)wt@mN!wIbc?zc&8XAVTHsvYcFexGvFMQ z#Ak>Zk}uX5m)Ogd;tTi&l`6$$b!G9`<2j|ie6DVaafV~MdrHdGz|=vlQEjm;DXj&q z{ml^)c7`Y&VX`W=*nF!fR*uwWW~SGev;+Di)bts^n*j?+mZFGE>(Gb*(go%kR}F7Z zvl{ZvAa*;Li%U$)pH-~_e;`f=oVX5OPG>gc2G9qy@E{R`WV^> zhMp=PKb$*CN5DOao?c=%WF=DP8xR(Nz)PG05&QKK3kzvggjO@WrXpAtJ9Pb+`(HWx zPMnhRELZfz@C%Wu0ncyU&1p%OgtB{8|(Sr_+Kd|rPy32SPa);eiY@Q0i43H~r~ z%Cso^Mw_{P!9p_l`TZoYXwll`EiJ(pg9IsaP&A)bK*CUZEbgUZFk~ zuw8wNUeN3GvOtze1UW9CR~nrlg>i{o0oZ3Oie_4I9d0fbg(rH+E9FU*Qmr&aYLhg8 zz2K`NRAe~^3|B*80K)^z$}}A$uz}@p=zm)HC$P6%gWDq@c|+WhP(2gg-rTu-^DBG; z(Jl{O2%aam2PaC$E-v9e?o0w}puPt`c#N~*W^#y8iIBo#+A=fmJ^TuRAFA4Kt#~mjEc3 zj~@yhiR#z_kz)a;>a=+1NmRv1-chBaUfJIHBiX;>uAw7_&K|q%(ctdHRNvak-yyX* z*XK)V&nwNka#HXWBCopF-#3@MI`6^!!F{D;_GIt62{UiV)H+||#k`?dqAfTgG9jU{ z^X9QLlVZ%B@5LsjG}FjwVb@7%i1ZyIr+G@9M2tEa$)s4F)s|$-vlUs#X~*ctn8t;V zOKlP+T3h(V<`yfK6?f!D@agHvxw1Zrn~y+<&{)WawF~BDNG@BLl?G5@ag?56)4i&j z0xD4}jua}Mlp;wCdibN1cf0<7fUWX#q#^nBWdkBL!O$x>HHkiYNi#cMpaoA51Ooa^u8Ebvf&1`4(FwcZ? zM~Lfy%`k3jb()<%rvfBNjQ;df{krJ!$=jkop@Rd}G*9!PwCjs;PjoH?}zTc9rv%}w(r8d(p$&Q6MQX71BhQMXtbPw{5Ar$ zeO>P;4mN(x*k2e<451<}{T~hBXWe?@yO5sHU(yvX6vY`YGn0sbsAixZ7wZP(Uu^F* z^Xod79u}UI+`;iXJ9BXJOg_Jq?t*+Ka<3}=HSl9(Q@k8$a-007ax%zNW11pQF-$hK znp&}_s9*6Ak0(qB50B0b!ahumUQj%gD%_%EbFz}mJFqzx{kD#YxDK1O%eA`cNvyNKGb&JOn13}9ONAc3 zl#1>{^bwRW>mJUzvqcu~Q>3jIhn-TX?z6xXmF`*={B+%;!B3`6Yr%Ap+3iGkQ-pJI zLCItD&Igafv6P#hDGSc$N6zg#vZ-kz@jQ=2_N@cT|7{=caHa*H34R~^H26$%0-5uu z$`4Y1#?N2u68tPFgbj>90ByLI*J>p_VtGlc zBElNo!KZS2^50B^C?>)2SU?4z`!jzQvbu9F^3QHUmfN@>`al4 zb?)QKK#wcoth~$UF-7s{#B5p63)w_#oTJwo#_Fwt#E%W(^epiJJo^*ICupdAf<}y4)|p5^@DVvSL8CF`3fSE!!U|e{(LEaHyE*pzZjMz+hI2lmx)>vY zecUhxJR6D2up%Upr$kYlE~G=fU`I7r2DPYd{yj!!zCGnX{@Wj3$+{!YkhUZ+eh!wv z55C9~a>WbpSi<(364FyrTZai#Zo{1;H76}%l>AL;kI~hU@$koVsk*+pp}Oh1t8^de z5O1PPhs5y6qv;ArfzEFzC*`^l!+0{quz*{t4F`m@9#fZivKtCltJ}>R;N`8>6D=QN zOsFdCKy7q!S%~1oYW(b6a2L@EjC;UgO!0zM{+7LZxT=TGsJFz}>-1l+7u8m08yd1z z#E$V6^J8d*&$3RtcnBcYvd#uO^%LhWaJvaDS;?_rmX)+9*wwlFda&HvKXy*zx7`-h zz(@QQ`MhG>Hnl5@K`n_}v=^CFSP+cb*NQ4LoCeuU@&C?>d>gVNa?e=9Vgh>dQme^~ z2TctvzBuAA|Fv}NJk54ef8Z?cDU6gW!q`tmg%t%yYcR9CT5kVk|N@9ST+~7DtJAXbd`muqn-uDB$P{_M(LmvT_L_ zC-#g|$@H+A8fW+p$53|;MhT2;XN=4e8{86XvFbEco8ayTF%o-j{=fEX zDJ#I8?N%_F*~UwV2DS3Lyg-*Di_)!RXk-BVZcnZ_Q{)@!(cIN6l7@QVb=0$4z%?v@ z3Ie)GL3~2o(%HkoNsEJ1_G5D5222%EYc*mlNQ;4EWON+B}hQPtZNYziCUTP=+HT) z8PHI(9B7!jI?M$~K=~3%nC?%>fpmgO_WsbN5ZD!l(h)|Ud2SG9LJd-)-7N~rb z4B!(!5+)VYM>0i~KQuz>U1TTYwJLvTsPcz~Du47Nc5CA7OS}c-M=qs)CtdFwwryH~pn zT3_ud8mAbs(fFd&IWX^VVS3*s&9v#*ZP= z&3AN_1}}d8Ww4WIKly}cq~zw{C;RpVk58O3b^7GV#I=7faZj5xeMaX*(u?#*NdHOj zV}w*#q>04};#TlwIO;F|h4pW&1L7;J74g-kQRXRTO-wGQ3D@x0iq@X17j#;)+v(;l zHdRfxa3W*2ke_u{H(SKFWk3eE5cCGJo$lvm6e_FC^EAO9$Z(sAki7y`H0t- zHIwpS@G|KfcrXd`>0eYzDgTLfF`n`twh@gVZ>TrcTgHR?M#qefZ*_&&I;S`n#kXdP zNl9+MU`WeNkadg?ZM+X$m=Gy*ISZ3P6g6>~Y>VY|GICb2-K>a)%8F?GsH9R>j9r*x z&LQR;XHFnT$oL}@hS)Eg(WwK>hnz80ciG_`-cx|GsO4aVg%lB_{z3yv*Qm$vXOJoi zL6{AdOlkr-N4S(R&lN5j@aWq*d#3G=tXV&9;-?42=GAHQ?Xllo%BI0BX5%xvMBxuC zI+3z&@Q2`46$>tp(F?c#iDA{)_QnvuUQkAAF`YXTlfDb$OUz}~viPy2&RlPuM`rL% z`YDFX$s&V=IvwF0Hp|ZCnf0PaxmE#i%uDuM<`z@7R@?%11~d}*$LExI%E`t!D!fLf zA&o54Ycz(tU{4t*GrJWd=%{`atla;JgQB7>(j^R>-H8Co+dwO2yIHtU~ zXm*TZM_U+u-^#!R_y*YjB35g4rfE~{iOxh{fi^F^Z=~Oump)Wm5?&rz;vAY%oIVEZ zTkEXNoE0-Qc8YVVx5?KQ)#7Y%wWhabu8r{M6cfta=mGAC#gQt;%Wij4E=wx`p>d~T z^He%s4k`>7Ewn5)&h4OCT~&3X@uPwQL)g34Y;$%?Hm{r6r@MF}l-CX=wbei_x`3wd zY-22=Q>R;|r7pEBPQB8yHg%ijrc^ym)LpC(r zLM4WXei>B}W}Op7+X6R^0Ek7cgBAAptfHq>630~mVx`P%pkpR!sUoMZnYlybG&6VX z9eO?*U3dr1n2G{=8_syui389ZU`@u4NcVo<`Q72p?{FvX^Pfs?OwA5Kl=b-fNq#DOm|u2WzpI=qhP~8##)`1#HQ!EL(*>*Y<^BX6=q$c*eFu;6kA;5 zUGxN=i|W5D20-NmKqZ*1Vf(uNrFJWfl^Ef5D6|b@*TL(vtaoUrh6)YjopCYRV3s9p z)?eaNkVL95F}0!FrqJwuvLDewcOe>0pTK2FE3K(~{mN_JEUhU$>`uwpHgne2%oO)w zzV5D{s)r33S~lYA2ZXkZZA-5y7&Lg$;DRl4gsVWSZiHRtu2H69ISr^OQPRkx<+UhB z!B%xd(ukwQwW1(ekww#D4Gx;DUx-|p%t`zry1EXpE#ZdJImUtrV5MIOHJ7=$$lnwE z83eE37ixtmLYp89%^HfD({Knb7&V&I7Ep(T0p|2TgCMxM2!4Q(cYYB(*ZIXeSZm^K z#1|+5KmUc4fcqYgIW8M8#$ntm%7dlCG-0VA7>NP7M_!V&VTNcDBiN-FZHysJNYkbn z`tt=swwS9e)aB^=87lZ|M6+?rQquy1sA`DMM-ku zLZRFhG!WmpkO7Z0U3~9Cg7^jQ3T2ec+c$8}Dccs2Wg1>DN_vNA(`SeteZHT)S(Yk8=Xv1`2jyPSKrfbqqGqi~d_0a~}H=R|h0lET9C0PL`OQMG84KlB#br^sn z`6xb_&*Mumw?!MHP16==%d`@&)##C6k$EE*#U*ojTq#$Lx&FCO68m zJQY|*13ZF;Y&ZhIu;6Vo60q)f&;kzj2NE>sct!*^`h7ctJUJPh8EpE1*94^#SQF%C zU@k6zds8~M^I!Adbnf6AaPOGxB%T5{Xt{Tk@fjpTOx5@`3Q~dUwrKQGa*Q@b zPSw`Q_1Y=&Os!T+`-~~$qQrAXJTaSy(+DEMOK=eFGm4q2^zC{P$_!z2k2+Iv6B=hQ ziAE#H02DO7W~vMgRmRa!AwSwcg(7qrRf6rXb=?jobQ{!~`snZ$gwuIZj5Sn&pkz@Q z1ICw9L_F1b=5XifkI6Q&9ns#w&V~FEp}un}kFpwq`Qn_U1r>B$y^;q|R@O#pleKx; zA=*0aRPAE)c{iXDjYfd3M%+d5W{j>zBl5b146U7^XJ!h5Nr8$Gro+56>Irl-*w-Bb z@f2c@?#mNHkW-a(`5F9DUaS_HSUoZ&G_5|zj4W39jp{=L(&ujo{_wLDMHb`U zrlYb-?bKP$Wp0Y)@d4EX@8z8cn_-55?kqu6vhyjEfA>yQ$4`U8Fe?&>)fi!#3z z0F_+ZTTA=ZI~KDy&MW!!HxabK`!Q%K#~2vwk45@un?>*jIG8ePRUEq+go#{OeG0-XQrpN3>dn1qCWr4DT^Od0)wBb`=+?2x%INicVA{15E1Qs zd3*b<_eqQ8XYk$qFvh-7iQAQ(St3RJ(8fvdV|(V$COf&HsCkG`H!W-*NtKS z*zLz5|INe^#kfp7zk_bZV0C{Tjh~e?=FMG;f|o!q-W022stF+$zCjTIWMP=n);Zv$ zeZu4%jW5)kMUP|mJsWI%a8@zUZ-&YAn|S>ryH7NJ0G^L`)}ypMG+uCI*=Y5^2XsiG z`7yf=xh!}?m-u=b3Ix;A%?Pz7Ph(MMA6#2iRQll5#*HOmI}cXvns@l*bE~(ExWBA= zVfihO^ZD0&Hms^D6DehD=R1Q&2Hy;xdijmgzMU%)JEaw=dbZdHbQ>ufd zyFsfz*8a$Nneo zE?DeKE3@f`WM-F^mHlfAi6DLRQjQgsz5nK`A12ssJ_~qrHh8lr#GAa5ROrZx>+7m= z42~;vjghCzE#bNd!doQ!AQPsOB@D(4R_ovB8a7vhcl1(NOhI|X!&D9nez@>UB8_xL zL>4K5H@{ahsp6p1)Os|`W|dDvQ(9OJb!@EGP8A6fa6!dOucl=@tYyeI=nO(@S&=_& z%e7hz0FG-e;Y2XrCAc(lUyL!Sfnux(j9*n8o?g7Ad;VawB}cflct|WdShI85%m1z^ zDSl$&nDrG04-Q*WdfU$RTdVJ0G-No*C64u+{;QzvgkEtiT#a*2}NRsu_9rtu{vs|u_=0qaan?i6gr*exB)gg8}4hh z7T;jd1k4apH`DiS#)vVL%Ah-68{^t8#HNd{49v^jRJY)(KKjPPbAsOnUnbr&U;OeU*|K%p?l3-f+D(13vc_c`P0a(` zWCM>54xalt{rbCht%i33Z(oRz6F{?vJ7?rC2lJGN9&?6)shm%h7J8_ zRFC36bxLux5TSQACoi2tMh15uY;QmORA5TFG(i_R>zd@-E)Ei&xh?6Xcf+()VuST! z5%|ah49TZt4u~9>o}JMzt5{bNIV^o}Mn%>*(jbkEnn`9$GozMEEiOwhDFR#lDG4Hy z8ES@_Hk4S}Ddb5N!Pt9{O=Fgc>`u&PM2?`ggL-qUL5WBkipn7lPPRjC&nh+lg?wY* zsXxnhwlh1B&3hT^dD*CVW9_V_09k^dl0?VC&XgsfLHx9x&F7+RnYD3T)2ADZrq+a( zig!Q$=pHcdz{}XRfQok#iUgobFPW$VKj9DJ4sH5JaSsNAXX+mqq3`{2bJOJ>PeSeX zC6N9hgARDS`>xeDjku>hcp`Wzjs>7+~TRlMTqM)*B%>IT9uNT zb@4rZVz2l&48v+VwTbLIvUZQ5HKgT?BN>$ZE=tb#??|lXzf_Vt%m0WsNjxlry^106Lv^UxL z@IS~9^ASQa3a4g60v4_t;qrly&aw)9NvfDEZFLzGQyJQ!h*nNU%Af91i0V-8M!;-CET z%5}-EBB1th1^5pY^3^avS_HG7+E-D#} zR!t)77$O}|PGp*dwh`VsFbfr&N}Adk)~6B#(Qb$!p-gKxLGXb}5H#qpu=IHsL&K!? z+MezRWPkpA5(?HizU#SQJ#S+@iQ$eZ9=#NY zMLW8?6E!eKG8oK?##j|iqTBVDui8W>1Tv;TLj@txQ16F+#O^1Ga@Iu!0ta4c(nq&o zx;aCjW0)TUqw|UC7sjwu5?*7{7iF{#@3%s}BKxFOU5 zW{ve?4?8rl4l%|@7f=U~LoPdb5VxXgOieVbo|n9=R0xSeT4Z8mTCuA*`N?$6-XxOb zjE~bs4^HhR#!DnTPOD@RXJ%HWl3AVEk}3WD&1X_W7)|9klX+CcP8BL)J}d6=TNZ1f zaYnIF4kuZZ!wD-d#=EDP8b#wr#mhRwoF_6dJjoCjT5o|7%*+S|2NzOcc7!up(BBDX zzk}Crso{8dGQE5_^NjKCId*y0pjSuZ0%Hd>x)e7Rrf{c&(HWCi@kIyw8QPX>9geu} zK|v#g(8sZp@mgg(G*rf;4OL0UVF@F-7OyE3pf(gtWJGJC6Dy~z2p7VAJt$r`2ZmGq z%pPn20jc#^XZkKv-xLMKZVLg-*JLvz{-nk+B^H|e4_e)(&f#N6nd0ylic%H=}Am^nip;KfiqFnpCfss(!IydHIN@+NRo1 zQLYoRz2KxMlJ;lYiz?>-BikE&iS1=Nk?S_JL8b|*#ib+sCqs)7R#GXwx!+AL9mkO2 zWuy6*CYNy~4CwE+R*lDdjPU=h$^G9ft~xgVv&Cg(hry+h&*$QNP~3o8lJknAzbQ97 z*V;d-!c-hyY^{jWngcq~77+Bn57g=#G}P)FG)}9|c35l-6HscJx^WMv8s`3}mI@UP zOkQvXt?mO=RX%5p^U46q#oV9zy0A`AHENY?hiI&|AXZW zQR<~6W%C8LY*!IqZX4{X1DbTXc6pq>8%>gcCg}`eAv6gf63D{rdz{wsXxKLI8>3V(wzQFoCs@1GH- z;iZFjH;>*>e(+$$Q!`)v{JE<()!bbHfa%tqeBt`fhYzhuP7P*Azby*X2HyyN_v*_- z3Od&%I^JRNSTl>qD7vRny#0j%z)YuP#F%HGIjC9S>f)WyIZBMaWT6juepT+T#`F)u}027oXvm zc;b#f_rlviQkVu87Qg|Hz#I%KXAFlA2LHJn+B3r^RK$Y~WfW_Rl@HS} z69|74-PJI6p0*JOJAlcljv5*vCnkiFcH2vQ@V&w^A398C0BYI&%>Pez7ttzK6-;Nn+e!#!gw zB+Sl2`EJ)q;eBKja>z(!w9M;bZG22@vMxO_TUVGkST`(jg47T-(p~2pl|4_I9o6J& z_D#vQE|c0Vt*)i1t=_B1dgB_$y435*&9Mf~WKRolp&Ue`zuhlsnA+B`RDuTn4~BDX zE=wBxo;sjj3G_lwUdr18Wx;)BbH(Y9{HdbbpPNFFR|>xN0D|fg1E@NQM$s1jqN9ZO zJ3n6j#t?n|N6pKxNlu=fy3)U;t)O4uM`kr2E!LO4K6%s!84x((~&?NSDZ zVS^j5BpAXq1C0i~6dM~2V7e;4J)Spl*Tid$;f%EbmV$QS%*&>2IEfCu77IOv=L7Zm zM6pnlsbPRuNEW);8y|<*TN6jwTf?q_cYjh%uqK*PUb8;#66S{Bt5Jv#%gBVHw;TXo zJ`hs{uKg6_LX1xFuHUgjzSIAYJ`e3`Z$C&@2bXK@QI%D_o1?IvM#R3?_z|~}LBVHk z3kqW;^etKNf>!}O^NjxaZv+pK~ke~*m-pH|c6XoTGE5K!GsXMCUr z$Y}he8ageL8v2@P5;T5cnnb(qQf!2IWtVstA=Sc69cFMamzv>Oe=M1?E33M56Uk(w~O)PXZa2MT0TxfG!X=1>D8x~PBdkJ=3@zI|)1cNVUs@xBS`k_%5h@fB+k=Hq2Lng2 zmkl`K!Va>~kh!-+QI-e#a ziOEu;)@#Tm{UsFpNZ2Yztd~X`=J1omX6;N}vwoIgDftJ#Ky1~v=@#mj84|*1_cacb z#&EiDpv~RIF?s~;-E}b_0A1w9Ckvc|c~=PQz)%}a;i!(8XA(Hv%V$jYp`q5%p@9m2 z%59;QZ>|Ux)B_4b@-tK_fd-51)gl@=IbQ64gOoGPI!D4_M#_1?rZlpTrpS9 z)%4d5&=12dAH@QSh~#2Tg|1SMs(E3oRI3@Qt2NLJ{S2u|Gfy|w;4$-@Ho#|Tt9V8G z555IV?a&+aj93g(5geixXBH4 zav)vINijAWQF(*%8>Z>SRTKtk$Y!NgURr0PE(k;yL}di}W0?)04@x9fYb37dfGhp% z$5{QKx`Xba^RHkzc_cUz+x2A8Rbe|nqSP4x|C&mI29;uiL^gMzT5iIEtg=qfNHIdR zG=!83W4O^|DORS_P@a$+s2eNihKM{TV8H}FjGqo*1oH%GDYx1sDhWfGEJ)l2ZT3>lHScKJX$yl-ByoS6b zrd)hMz@TDwFLEYd;@)*wEwZ0Y+YfWrh6*Lx@xmx=leS%G(dtnZGfrCWe0S_cmdS-DpsLO6aB_Jg_0CS+dgf6j#R$hN%LtZ7G7LD2xP`hl6>QBV_ zt-C+H_o1AehwlA!_tpjL+it${%A4EPF9EI0yJafx458QC@rK>K#=CP}v&bQ}3 zef4A4psa|HWvGcsWe8X-vLR9xNJWT&b5>zMF%J<#117^QU_M&vqmR-G9ZL77(C2Ba z&oh)XcZ8qs6QS@*#Ii6sGJ+c!NUFk~cuBh0nmD4bfxuzDijIqBjul%4$>fwI9arTd zE*Esc6Vw*DQo`T!GAf|t;Xml0-UCe~0V0KsMSU!FQt0Y7bcG4}P82?i%E=L@{h0tN zS;)D+Ai!0OG_*hDYU!A8JF=B^%3u^o>U5F1m>8_eYs0>Z{k6GvtdM0ND~#3G8b`&B zi*J(VS|{2UiOZ~u?9t}9QF7QQ*%{?br=&5bbKzKLm(q?cUEG1iEkQsN(U|B!VufOw zEA$K``2z_}aVOxIhx$K0EwlHk<_VieO&y;-p;>ny7X0yE)zq-1wtDJ-X%hwE_Q{7T zD#uh!{fF|{3(Zeg4jorHebTsBAKix&;es>lWl8SJuf^c4*JIed?y?p4-&CBc1r_7Pi*bEnIlvC;qig zKV^r7!FslGz##4(rA_Y=ym2m@H_6b;o6F}Ia=k@-k)g!f;2h%~lQcGELSQ1_71IvXzwI%toOr2v~_RL88YIHEUB;NWt@c_ zDsrfjTyOr>cn&ax{OflJFut4?c4gV{?$>DB!E-ybm zx%)o;d`{8V>N)=Wc+cOR^WJCbIel~gbRFsAp5NMta}ty&!CcT%!1G)|c!8@xDG<2= z^*asF4?TA{vgcdxf1zG^P;PwEAAVi)c+WW>zs+&RCk3AC7y5Z70W+{q6Rk<=%YCg> znfq1s!vx=SO>$CtW|FTzDbV~gYwWg!GK~k=<))?n4_tj1A%6LI~a&uBE1ZPb4^hp9A9v|~R)H|7-y2ye!DlT{E9mB^&^|tcj-&8f~{?d6WJcaQ3y&nXI>gC%qS_MG>AQ?HZgis1fm9maR+Z*9amR>de} zB{e01?~+2NGH$yA3Em;>zTRaLv>|u}N3RH1Q|gi5u7BgR>n=H~D7fv}6oV36$$n2Ny-NAs?4u7Yh%zcc3m+;kHd1x9s{d z5{YgLF$8}hZNIg`orQg-OFd_X^7aM}>vi%(Q{0500Gdim9PKbIqN4?#W4jSbZgc3) z7-v&_6KEy_{Im{J*aOcC%i-rl z(#~W){dDk#r=Na;W$m9=^Y-95wf=)@k{ZTy?*rMRBbyj)vi;60$eOT`9ij4NNZZ83 z$d~ZbAI~ZJFV1-{bWWW8PuF35ss7eRoWuAszB(R!86P^8@g>XV$n@UTbGx-*(k0hp zXbrpfG3vd4ul6s-9v;!%zdxT-#H;7n?K*6*pjxLtpYz^1^_dI&7i=aCRMlRh4J^%)9r>&AquRJ2!ii zL2}regoF)YgG>oiL2O)rMM1;`?pg=n!hu?gN|oZCtypm@t+a}xT5Bcu@IUW&?hOe) zw*7xXZoYeSa>h5_@14&htIPOn@Poew)3N(}@pAcMnct?aq)E%&D7+#bK-C{b!15LU zV*7mWdixr$6ddCY?7w$KK}Wh-N%pbUU0<~3l{$JN?h|c@S4n$pM%Yr#l5bKZ!|SW%Q8oq zTB1tkRKDH0l%MBZ$FFsQN+Zh_3j3|i?iRP;c3abi0g>A-%Te&iDH&phe^`brGK6tA z7mFIB?1b$krQj!E=0XP{Q!=KL4&pk|T#JMnk;?&%l9)~4hb6ac9s%rC z%7{HcU6p1HdvxL2&(xE=`Gd6!pB!MWePGr3_g9+Lyv=v)92qVZ)mw=BCi>Ig`9dE* zSN)Y(6nVL*&Di}L(}aSJ;y}+^PwjsTGX{7k(iQSoun3-1rbk0n-inYYhP~mO@Bmx8 zZJKYcZI!UfW(@k}p@iYuf|&%BbcBIYNuogJwr54Mgoxk|vh?g=)F7wp>^eE!E(uXi z!9a0>jd~Mq%D*d4+MNZapb8#xL*i2nl8pVD`OgJ}C-Do-lg)@6;PwDWHL&#H3!yqQ zBpfoB>ZC-%?hBh8m2;3vP7OgX<-{hpEJGBFNmray*PgR)U*gq8I~7yY&WTrEL8|5^qro<|Pl zHATw?j&Za^2UREor#oi&##PKUp6gg#IJd&tCeMt{%$b=tt$12p>%b+E#nJiw=PR=Z zZZK|etS($#?zo_J^-RI9pV?YauPe1yR@OF`qWrg#e^xP?FA+$0Vz{n5krM#8hz4BKu@k&pv0F$7Bp0P5ad7~ zVWzakoTJ&K#GIooLE_aRuYVJGb=cwf3uek<($VkmAAC9s*Up_idEkKI&u*A>&vaAE zqf0m4kyl)>z3oU_`^p9L$18)B=P#PHdzz{KsdZg@FyAkm_QKRD|I7%-LK$O=@;ZjP zntcA;NGLe2D0kK%&p=_y;yY^fC09=!v!$Y6O)&CoPQ~m={RX6`<#?*bjk|cxo;rQm zjw$0Vt*WTc2t6BYoIa^;SXx?+x1^;-y*D$;0>UB~Z zDtN41gOc5Dm<tmu;<1c<(f z>U(2S+qFlod##(7zT@9guhTvGub~j3Kfdz%ak}4A$EB^v3$Ee*q70Bryd@>>qN+M~ zT~%$(2;0z__Sk~h1wl(yrKi6)+~^gHImEI0i^g1oKUh|U=#nl2zDH*eHF0HP4*YXJ zq|!8gP?&>}+ukpS=?yt7rjirLO=$~gQ1YZO0S!$}KqHyjl*+~^AjC-<+Lo}W{EV7Suw$c)GTylusu zPxGG~Q9rO-@AA9q%d5IZ-@WJh^DfRB7zt&C^0F_RdGdEszYUK!)i*qFL+8U$W6nnq zirj6dO7ydV&cJpxAQ#`StlwbW;OumFrmYXG&RbQZw+5uFaKM%2$uF{HIWj#(zL-Bd zt2wipmZ+5@Dji zF`PI^&L=oikqgYy)$t0vg`Tz^NNDIus{apzAWNsOWvjf9XW)2EynePSt2g3H=1=kq z@O5&vIzoL3Un9UaUxTm54}PTXzvC{x-;DJQ%?&H&Ml)iOq1D%QHBAjg(uJ#f|0$gc ze{nz^%+4^FKX3`QqFcmk9Ffe~BW7Qmo5=3xa+=ha-D&CY?uvc-ypp?KS(fVYb?Ga! zbg5nj32Sy`ys~7le?a!&_~4T9{_)x4t07? zv{C@2SX(fXQ%VlYg0`5qH5mI}os9X}QA#g8olO2cVx{{xT`QBY1qOGrjwK~f$=O%= zUv#Uwa^h`cKU06?tshRgugOufXUewQc3seNYjc|ZK^6COI@{`{f$-gVmp z^;Our_M-mlTSzS%3VLTMSr%j@Cj6xLaIl&HZwuQM3DE|J_c|W_vBFF%BWo z+FmQ#yWFxxPvM0{apRR&R+ zNDU;i>b~9JInnZU`UPJ-^UP=60;m^-5u#IAr1s}u0*lQ-^%DLUYZCi~QENC}2+2P2 zxl}FUFn%JpfLjYlFY#w;5s6AiMB31GkLa#cw@@`AKUMaNPbV!X#xgjVp9MM1c?f?Q z@L8zcB)2<8lD17a-!Yy^b4Gmn`RCQS&p(eO+vlF6J>wtX6uLo5AP4DkWjr8uEoOsW z5^YY@3t2A`whOll`vk~)khX|ck#|Y$dZ*3MZq)-S(X4p+GOyw#P20@7@Hq}KidKiD zE7epY1v`g^Gfk=u^(PVhfc=5ia2*I-;F&{`YXU?&_{X>dsgnK-vOsT41SECh_Jz9^ zs+0Jm;}dTQGZyVy#NVrCw+p5GV)Y@u@v&=JD%%r3V`g* zx}X%4<5HpApc^TTl))?PGP~Ts2tX`!jl4l8m>f3dG_iS*3Hk$z>ruui+XK)*E*@Rapya1JrX`T=syR;S|%Y5mzMO&6psJm!^VIZi;i7yESb>#=5u%SSEg5Fk*_B zoqit@S@KHPh+W1mQAXS(kS*9}d4*nN z_~Ju5IvJk zVggMp?@{|q<0dOcoyi{X1;l`ZW4$NP!F0b1@<=jUHDnlCT#p#XpiG__< zPdWGTra=RR;~FGYeeE$mcOGAKNJFKnt$k7bexCXcUtdx@X6)!cUxPwP{)sD&jp`m$ zT+%wa?GxHhe#PCQpNUMuG*l>8b1N0pI~&Tqx#^_^S-C|GRf97|RgDuS>Svl}+NQe4 z`KI_Ml+6{EndbTyWi8E~S2VBKAA7L!K~d)dQ(OGO;DcWK1^(4#LSCFJ^IN!Gwc)sB zR}C<~9TZD+06D6(@dVqI>+q9y3n0;wPn~uK;_;yH4=LO(x%ckS#OE*r7}~m?DeC%} z|9E}lheKNaaMd%P{`AtO4+porz4e(-yB9V;F>A}sUFV&Gy!-qjyC{_R;kaI=J6$mM?T1LhZl@2M;?A zZFUqI@D`Jsrz$`8g{?mM#p3t(s0zPY-Nvs}w;j-a;BEgu@}v1yKwUgmx@8N%mhn<5 zj!Y~QuEAYCjf{kOaD#f0ui->ZipMNFkW0!LOcq{n({@8iFVsM)6B<;*gY+Yo>cm*l z@LuC$q6x(ICN%!4z}0}%lpSf2v{`9_wNF`i06UD95s609MQUOu4&G~?Q8Y9o2#s&q zNt2)GCZO@1X7rd?nxqN5lc$Ti;0JC@RfMBWwJWIZA{<({cVbz26jy^g2g;IG0uCpS zH1A{(8Wfypnh=;6X^l>d&kHOF&x_A3SrhCm@z`~_#I_bnPxm&5 zgra7hDPYekaCv}s#T9srNn3*A9JCEU^`$9+U6v$1zy(Qw!E3-&Tjm)cqb#dha~_0w zv9CCj){SkO@bZd--|^O$rry>f2)FJW`}kP%xEE*r^3|qz=;g+p!?*6<+y-FP^>Uim^;J;rdejdp}g;i`?0w&PmJtN#KoOfVf;-2A& zRrHM8Pc_Tkct$fg6kW*2;f&QLp_A(ZQHh6}3L(@}m-8WESwZ(=xy*ck=K6BJ3uw8# zRrVOCQWS&DS~Naqrg}1bflvW0A53;E4y4U=!l|ceP{&T7+=_zeg~td6G11t_sJKa; z*Xns=a`y{|6Z;OoATO1(e#(%K(f0$m>lKii1F(Y4+iQ`wGL}K;R#@K(`w(?!!H4D;JHQG_4Ya&J@?c834Y5R8NFxQg=sXVeB@~ewPDY zI-oWlcu9Ige1^)4S&1?3ato@9x5Kj%@MS<$f>a+pJQW^2Ti}{MqZXK6@Z8YWFKstPS4A(b zs$RJ0K-IExQ*3GG#nn{{7d}S2-N{>CTXwG5^e}rP&3$D#-q5Vjh&V8+0LOjt~b# zN@1KcQ<@5KjKTLse)vA?oN|7uQ%Ni2AVk87<^t@s*1e*3h?X!R?%SJDUQ|48#6=Hw zj2Zj&<=L^!NoC`A=h=#%81wGadxtz;ql}$4qwP{5KEspa_IUSRws>=Pc0}i@R@^RA zne9GnbkA+->VHTMyKBtg(W3{^ldi*)9!vUN%9SV-PPt9rW|kj|c zxZ)f!T$4Qqp+!*zP2tj1EyDfBttW5w*!RDC@x+N2fA{@ko6ldrY18`i!6)(s5;}~3 z{xfeaz6bX1z5iZXflJ^ajNuOQxNnsaMx)UhFa|&aU1Y5i%j7a=m3yc-)V(+` zFElT4x8LL%|PxwrPK zo0O+s@W6)2e8nrEn*~ae`nOlq*Cua(p1$zZXZmL7>2>h5xAE=DDs#Fyl#!k*MXfbb zg|%P*ssRI~f!2}z2M%bnw$)A;HP<@3cK#^0FElDXu4GQh1=e4R1N^2z^?YF1U{|bC;)W5okHu0?j!qWD zs1I<%7#ig;iU5&`iiVbBK%Zy_4KvY@3@awgnjcfeMLk@AM@VkKv}Ima9FfY^y=uHN zo*#q1c$|JcCddJZ^(Q4l(3PpJpS8oPQ|4 zaI0c(0*4-31sanG_AC0Z15%1s1)K+`)6>10{_!6%gcw#0VO`)q$p8_FQ@tRC^v&I` zHr7^co4EY#ftImvFT4B1Xz%oj=4)47|A(dXXY$#1loaH5Hnu!6)mr=7{M-IeH{_)Y z-#z)5oD zGQ|D^CZwe~l=z+Q|V`q4jBQ8*?vun^ozv0Q(SR1j>^8C_mUv`Ym| zqKSPL#=_GI_Sm{)MH`ufsEgw)T0JdBw#Ojq-`~;m)|scym}yKZtYEb zGqZ%jS(&PmH?!gT2eeAPc-~>28}sQkRIOK(b>HWsKYl+HdjGB2*Vgcbvv<}cW=F#B zlJs72>QngO-o$7`xn)2k0@RJ*4rhhy<$BL3S+OcM#XiV4U2d~4m*?B&2iD8$jSg2A zSQH(47gDdqXf&frZxRYc(Glq+az#@VIS}by$;2c*w9+II8TMT4VGw009x}>GNb0HD z=2huT1+JJ6R(Ro+SAJ-Jvh$sP!N+jR;71y7EvXs2Yu!1&uQN&NAAXt?&VTdXIoCHe z%`f;weLXfizjVXc70U>%hI1bAfv>qIb9hRQp5mjaS>jz-Ag0swUkRyt6+t5{M zzCgX`1fciogrmCdAD4-rT+#iqZaOgL-al0$bF63qOFIw6T1;szfIeaVlUg_Wp7a;ZK9M<7Xl22=Uu4Bm zdGqUYLerH2JEs@4R+(Zmin=b&I_KSg!~@ftns!a9Z>f?COo8)me|C%N+qAE$I<7Z9 zYV%xl5C69F~>(BnL;Pq3~p0U7nSo3#nYrV=d^HJ z;X?Dgigo7I6^^{Tvhkrn7QQ(o!db1p@c*4%&jN;Sj#M;b1+i&C>JdfQv=E{Bp78Z>fpK(*#BexCT*3f@R z@#rb;Thkx-_3-U=c^8$8o#?s6{rIh8w$x{Bs2MdrD78L&cvNv!?W_%t9U56u*0Ait zME4WVjVg|eK6k^x7e&&L4Adh1Wu3Ls$N z^VC*#96(dwkuEs7ktEIC+#M*hSPLJL6)2gGRq`qeI43NQS~I=q;6Hu@KT$^xEFd&Q zh$OuU#-2<|fy2DSio;r=bp|0)NhTc(b?pZ^;Aw+RvP*)kjvPo>?ducY2oCioe!kk4 zI4b0-TlrPsU7o<-aRBAaU%$&gJ%xYjka|=_orSjUZxbjQOOy`$Vm)G@Hzaug3nMJJg6nTOIF z(3}G>rjU6C*pzH$sX;NUEXx04-$!40CGnQ_{So~`?pHF)9QjjPX8Is*9?Q5DIEzi@ zQkhTeD3+J29rX_CJt=z^d$jrVQH-O39ff(uvUjgY9#x)9#-(09AM+^#bI^x+j5m}3 zGJ-P8GRiWQ3?*}=w9>RPV|8d{mf2J7q<&`fu}&xNuX0pdL2Bj&bgI+CkUl-0G)4fG zrWvfl1T+x(CQU32)+&4d6H~@AOhammj{f2#s={C*rlr|nyK}4ZB3?a1 zrKIvrs>!7j=@;g*z5aybFXU8UnjF0#!38_L7TriDvBzSk6R>M4A?vgNhU_GLtS1TE zka6<0Lu%rjs~>q_XUo5iOC)(rgd-h00qT!)ySNLU8?wa~+}A=ztri!zBc@CvEST2atYQc+e>)lj2=%S9;| zQ=*h9Rby(}t?i!azUhJXjP}eq);Sq-GCQp+GlP6%p(|V{+VlIzq|)YKQt_^C_L{=3 zLOxJL(F*3hD`MU|yzkan4!Z#PYq8{zWrXrhusR30B0tnPiW8AKMxUY40}gqNiWu?H zRfu-*6-?8rV47A%(9bk2yr{o3yL8>_0ewk>;gsAbMGi*_F$Ipobt|Ehk?r+s$i z3xkKfbJZtbJ}zFp^@;}_PuzLUuG{a~vEwcwxNv8Ad1*_(SL0Rd7cM`a!6bP3x^*iT zU#x!rb^NBA?%Z+VJ8ysd${*i(8=_*D&?sFfypQqo!yi2!Iajh>j-ajw(4mChN|6XC z57LF*8R9Xak@=DFH~Mqf-vA|+{YhVxSp7Nws?fbg2Mec8h<_G+tYS#dwe1)DsP}*m z=lCN=OD)FYIEn-zZ|PGY`LIt3K^fRcIE+HBvH;rRhu~3rD3t<;ATkT4Ycrqf`@p1$ z;L#@a+i$+67xB-4>v>Z^_Kv_^kE=hEyn5?zI0>h=(Y5@zJg_Vr+C4<+rsyN&kEO0F z>XX;ySiDt}VtuboQDo>lZt)rQ+f8@fNiV?C!j-kF^YrZeCU*6bvpl(#T??@jfv!Z^ zjY$4QZ{xw}srXG>)NjA1hruY_j-PexOr=PW#Zv^%xMiFM`J4|y-NeB4J{8@hP^W&o zC3$bOQs3hA@{_VNDZ2+K1snp;6AkxC+C+S|!TrA(qD{yzB z>k+s?H6B#0@4-r!zzb=sz$3yWp`YSYUwy?VPWq+es`%AcqRP7yg|{aPc{fJmzEdyA zAIsy}btfqe!=+)m$gA6U3kVCFe@Y#s4&t8@wk7I?!@}W2J^z84 zrDjoW2diRanX%KcJNUS5A847e4%;kSrw!M)A^c1m4$JFhxZny1$ecp9t|nt$&z*lK&k4dH&D+|MctmdK66( zJMDVzCr&38=~@eR!U3ISZ;k%b#T#6HSH5eqOX6HE(d*9xR#`f7GzBi7$~`Mf!DN^h z<%O(hL6OAST_`-wwHV_5cs`WNcr0e|gW%OsrH4H7CJoOhi9^f6D#9=#wnaxH_(z>} zrH5uRlmHCDOjs~jDl;HXkX=JGqoCcPRy#U)F1@VaP>lQ zmGm)vOxvW;U?dl{mC{Q~fAfp))Jw}Z6^(+;B%D{&QO~dbZtFAS9j%8q+;WO5R*dFo?lS>=79dMKeX0g6-X=bu6^vy z=KkpUC%OBCkENy13yT!vO6XH5br7W>Pyan@&X*5j$OUI;=hIxDGg?5vvFc9ydmHN8wYp3=*pjg5XD*yicat7AyIp&CeP zheujO{ZfV!Gdt=XvjVFF5^(NBuQ$Ef38l3uWJUF)!R$dg3poR66GY<&&3PyXxLK0N z1eyC4^FyKWh7zJ3Q({nCQk;&Ln7>LwunKMRVlmW0Is#ySv>iuCZIO0FLw#x_0%og; zc{364`p-c!&2LUYGKKN8nes_1GU@5mU}|>MntmDS6(-Z*6+nlm?E`oPzU46l%#Kk3 zMPmwDG{rX$xV%&tA_Xg&O7!){r1m%7a2`nf3*e$JJPs4yl(9H--D2TI1}7*!+ua0= z(emHDZq@HKc$Qq5j}fJwABLU}@Gd2NDG(Qg^gwz*Zt`&!dlOJ?c$>jt!ak?xV1^__y2!R*&H3CMk7ho893=k;-0^-sMhKCYX?oZvm@t#49-Fa;!K3$!U~kWfJmH zx|1wX_@U9kiWCSvkIXbGQ|Mc&;FPs;1#gZsr&q~BPuT)B_>;1_fxnDO7w(`JU~}My zIs+CVm*7wFUy1>&LmyHNCW3ykxRh_kzODrqk{jfgUw@6`g4i2=P`~7_LQCXIwB0@ z?F##QAN8t7#fkK&INFuj)%A!de`dZ$J^>5R4kVU5>{!j*DDJSb-DuF6jDB6f(5P?n zqcYm>PYa|s`kD$1xuybtZXmxgr)j8lxP78^vVEZ~4W$-2>k8MFuN$;>gf3@Xsn`N1 zlo%Oj6zrnSFsN``|7g0BE~KZAC?8krHnmt3n_#gGjdS&Uy%MkIs`#psIOpSiRlfYV z#ip|Zkxy`B#O)XzE;H_+NDm$i(H=|yny1uc!5fy(peEQ-2PYRE)&0g3@Z|K9HemiB}g2|H?%$p)z z)6;57{r2IWkE%XCdi0}@kG_A9_-{_Wg4PH4gn#0`%P+tG{>_`!v}EIf?oddAiUkj{_b_It*3rWp37o6ZGW?KF`Ws< zA?Zw9D~_^04rSMwJXxyBw$C*OagE7qLL&BD6O|^y+w7V}>}*?4xq6P0dTMd06wc7= zs3WKHl1Di#r;h@Vf$%B2Gwod4PG#dLrp;m2v^r)vIvv>M9aj7a)8?Qro_YO2r<%@k zedcpu*VlXwTe?;w(oE;`W~9T&$LuU9q3mFWkAw z`-(=i0%E%2nMWM~nT=NOoS7^$KHE{LEAm_n#$PHlO z`Tqk3D%+y4Q)=~u{AuvhKG>(&TNv~y?ttfOWT*HEtKFaK45?ZvesbGyp1A4QXQ-^?PI3GNv;&=x zLsF5h9lqK+Fxm@X2N#Ceq;zY#vCZy?K*0Fg99BAgdOl~#=d2WDpzL6Bzfz!qHp8Fy zx=Kan%a+$nFDM<5S5+llYS?y8MMu1JM69w-)V1%tF)ydEaO&tAZp_OrD40GJPwSU! zMU`0;9)P*GJD|lTEeTuR1*Q=FLEu64<3ZDHc3G5SPAW9zG1#)jbRPqMH*U* zsMDGD8Wr&yQFwE^_^~Lkmn&d;{jyc$@qdbFjdS{Bj2sU&W5voD9Wy#s;Dsb9D@xHE z%1O7mB$$4`XV34AcUzWBo3g~FyK?uDBfBp<|NP5vFG5WA3;$r*)wcb@V4m|LH(v8C zz#S<3|I|;(TJ5IC|5F03b z6=fJ#@eLC4t^(#D0B~?XM9`!_{jhPhPWj(&RO|8CMTc5M z+NWlZa~jljHp{J7ORubylk{Fhn#$N%tR>UP?$+N^Yq<8O^ zqtGW&^6~M*_*qyuh2$JnooWwNE7a^iaR2=W_KWMUPNWI5w%)cy^e0wai=BvZe6szj z1_PId_`#UuPE=JM=<)C~97k3o4g4~AXFhsBt8K2WLijyd|BPK6wfThM(LZ^nisYHB zCP9}viZp`H*qP9xGhM5l$!e0dW3cj0V;boZQ}x+FT?w`_9+Q)o&72hBiLsJthpZP^ z{DktIFnstXoTCRG5PlHDKh6`w7$~ZfkPl!s0^0z21bO{@!+i^cg-$6LHZ&rMBv54$ zBUO6CT8I$Pf61DUdxh5^O%}mukU= zq>Zi3htd?z9=U+X-@_>gcNyhvRj_j-#iwdiyYNn98}!lxgYK0&4|d6|F0*DIUU)whoStEF4@swQzj# za(Q)lb)fKg`a$YT7t7E8ptxeOTz9Cf@ z+haQ*nc~>De^$TXT`w)YX<~HqB=yIEC&q8@;PbNP&E>sVwyLsC`KIIM7)tyI1-Z6XIpmC*+^g)4(W-q%&y(zJ!VbAr^+Hi57J#{R(RsfdSv!a+!l&uxbC%W|mZLOG$nk$s%Hfi<5-0eb^4D#9Q zA|oOboEJF&7!?F-H;>63wSZGcZ)C*XRNjpVPBSn$$Nv{!w*s(sVFK;u3KTSnTMpQ! z<}ASy)O)!94^g+41&Xj}4`cT+EFu8XB9DqqY2(r!S}B^<7072~&~j)q@@^VX23x^& zL)17T--%LK0n~{kOrNi3I%`u|x_)Tm*!ONYeE9II8=oE2KI65jeq|R;J#^1`J4=fS zMECSPb)$x>$Z1jkUR+eY_rl>zvcl@7N9p7RyE{0@R7MM{{vPvF`p%|s#zNQ ze+yBaq^vzVz1hE|G}D|$1UU`q0KYFaXoEmQ+yAJc<*_HxsC#pp5dtT5t+tgA={y7l zNeWF&uzpSDv9tKs8N6oy73#EpU*eBv!cIdUcwcBljts@L!itj{Z-;83$b1=aI-xR> z^OnUgk~*`z?_`nmM=i3&XK{<*mdcZ5F~gnI=39r;gYVYiu=FB7hX(>a|~ zEt(xGxQ-P$dLy4_EjZ_#@k2)Uk31U4y5+*T zH%u*DP{8idj`Hq5ioEK?r2%Haa6Eh_Z3*?qj- z7lGWK>3iLG%BS6vYDr`_)}LWyW12Z3WMD%-guO^QwzFm&{!_=D8x< z$or>0_`7qb%)C@AAGIPgD;CapB)ehQs0oc*#|-X2tSS59VAkb}r>qPZoXbfvBV}0s zYs`Zhp_F zVZd3=&?H`lGvq4ifP_Ll1L%i|d|3QnXQ9*3d9K8H*1?mPEA+pcgD3B|!qvDFz0f2c zzg14(Bm)Hn+KtI$x0zY|-s~e0 z1dLgH3cd3yh4D(5O(c)ZNO+}J67%@okK}3BO(+Fqr(o7H{z=dSdKvPFl7+BsYkCVd zbclNPLQ)A_;-sR`Hv~TEFVgBnldvVRmLI7;cJQ&s#7pE{b;7;s*H@^o@KskxE*imA zr#_SKV0$ZUL0GNta28;XzurHT%w*a9_%prP!iR;i6%OW12Mdo8liCxuKiG@DHk zu7;}*nu8H{O{qB^DJadZ$sXElu8UOV)y1o7ss;>?49*)KA5=4{Y4CuV0J3eXm{c=i z@DgFUw76_u#k`sY17{6gC$BH=tm&*>Ghof&O$C5~gk2h;7aed1x%~2GT~(-GKO`*( zu~?3VLD;Tg5E@}#2osF8&E9gB&r(h?2L|w2p6}(#YePmU%9LKxPSL6SM{Z0g&m7C zZ28_IBw+#d9v%upy&uUBP^K87NMk^?Perb78ed@HZfGa_8wF{Et-X_IYv$)OwhR)$1~Ojz$Ah zmci$hGR&h=9Q3`GADHOJQMte$1tvc2BOdoN(lh#8?;b}~^GtczV589b>GLvV5zDta%C!y~K5q*%9`Ubh5 zr7^Q2yD5K^Jkl~Yb4YeeKBXLYx~#xH4y2_y{JdMzM+Z0nnUy;b?Csp;yf4k20hfhV z)JY9(%1D7gobfZVSSzDfO;S}cdex*`gvD2R7Hh?E$F(>%y=N6>Uuq?v{Em1e-W(UQ z*i_95@+OAgg~&7`y1}-@>MW956iW*;Z7fLoeOR5v>0(aU7mWC_!f}k5j7$M0R|;ZH zWG>T2Lj@JRSXEguY^Ar7??bkD@`(du?mzeNiMGLmADcC0(`fZNe#wC+)GJ#+^!xDU z8(Qy_zCUSMGq4S54$f`wjTzmNo%h2_x;B6~)%niVR(X&tkbQtk%FN=n9!*HLP2g*s$Y8AR?aE>=KVF?pnM1+qAbDKHa^bxM)g5pP)tPb$_Jw+A4wXuW*(nzW zT)x7%JUDY^&Uj_MZ)wgPF*zFhmuW%Qd`EV6 zv^ifIGQeRfLxL|?iJk(poG!g#1QPhLsizhsHHcar9|cNt+@*|Ky_6-fmQvX$D^M$C zX_ch`Qt9xiMy-wp)k{Hfqlza$CZKgScK*nS<`LpR+Dho~fkD)9|D@!QUgKs(Pi}_2 z>SjyQ&Dhi3EKkxJ#$`)v+ew zuaO^SyFeb>1wQJD`^LfsO~OMOKrZX@AeTkxui3nvauN{w}gj8M`cenEjD#}%&3g^@m`%VV*oI?4VeRtaIp(MKU4utKvUy!nhv^v0Ac-; zl13wkl1<7mV&t_FXoHPZgZ{>VPZNG zlq^h4!zqyz(-t--@LOCyRVS6xOH7~6oi2oJK*j+r-xT9D%wL)Xm@z!?S5eh+hL}Es z{92dyQ`b&4@v{urI*+R7|Mjmg*ZdnMY>ZdZcP#k0&sk*S1$CzMDkNc)`wR+`lpz&M z{Uym&Z6|e%G1YK(haElxqpjL3x~qLgpsr_71ScI4oYM*!TO{l~h{G`&I*UUzc~)iG zGkLq)<1sOF0Xv-LJVrx{c~CYMIvrbHkMr2XoX2=iJW>qHKywD+6GD?=pZvf)ZKkEM zR3L%0E_m9Yk|lH25g=uuC5Fd?g||XuHSH0Kr%kb#x7WIoUS&(ktV=vEzTN$;Xs2(r zXWg*iQ+8!21;Mi~DHBN=E=Erh$9NHPRNhgBSi^xZcwDT7;VP*fOydm|gNbXrVv4mj zzSKIaaGmx13K#GW+Cx^pv9dC&tbc)I&!QU8ETbzPWw4Y{GB!h`6Gy=dhSz8SMYq*V zB5L$c;L!X*sizJsPO*?*m1JiUE0f&g!CW?PbD1if%W}VcVo4b>5zy&HZ;YV*$Yp69hp zk`XK;^jY;_@=ON(={ym5LxgecsFvhW+i+Cr{!XD22}M{mly{DB-9eC+T55TzMY;`0 z&m3YsTB->g7qAa$zOd^-CIXBASo}V{1w6>0Z9!szgjgc(4`5wbP=8arkdp?B83wS< zAbAWtTS}D2kb=8P#ua(CaPSLlMWLasF*FE_oN1u+32RW~hc%K^uuDy;&5SLj6A)Fn zPfP_Su$XVI5J5%wEJR2vX>E7gVd4055J}JsK9c8=?7=gEzg8U2!_Td@u1a6W5SdP;I(LDf(J;B$<2TLD-8+QY0NasXhh~DN91ZH z8!0SET>-JMzIZt(b>JrBSc)gdHnIOlGL07D>-`ML0pKBSFv0o`03-~IVcb96J~UUB zY=e6zu3`R*&p+3BPJRy%VrQec?d#qVA07^d1>-ab~d6VfV?^N1G_JQ%Z%yFscYiC#Fgv` zCnS&RmwZOA+th>SP0!f-TpuA$uT`vNMNgj#4&XlL`smcGb}m5pl?may=$s<73>&tv;xoMD`sWgrIcFq8Tul9qaIOZN4vqw`>VlY<^u_{ zJ1*Np5ds|LrlG`-_Bq}|B!*gbn;)tixC}Kdo;9>g2>&!7o&evE)V*}ZgmM zU!6W-SOzUfX-|4;S-1!r-m#=|UI}$PrIE(~c!W@cmS4kw;m9$^YMZ665?_kOURgG> zSdsV=j~6>Bd4^~9cu~SNX>x2IhKg$fKRodVmLW!8W-(X;>4tEi&`=s^H0VJY0q0gU zC!;Ad8j-~`e_2^kv)|ZK(NzIR4n`!QfoISL0Fe!aitHZd;L`cCbYcc~Wko16iIB_I zZcYF++=%gOB!d}Db^AA*)0*tTA85)ifplo;*%=rC-Gr8mt_&gL@^a$DO8rX)=X+Ev z@@p|23n4d1Q>u8^EF0o%IcrA(q>1^xv5UY5ej4&YNLVr)g4C;b;oLk6L!qb_T}A$$ zzD_H3Jbo6&LP!t%lfGhWi$y!Qk4}A+oWo{=Mmj{Y5e$#wdQ<}i5#Rr#GR_R`H!j6P z@o;^pK0GosGCUz;UdE#E>Wp<^TO<-D^2cy5_QzOPOvuOxhaI4RjGaLN3ED>vNe=&s z@{tWKj?;q5XdGqxGa6rNqoLPEL*Iow>dT{jM}v8Oi2D%*GO3}!I56ZNEtrOZAe-{6 zeU44f{WDCE7h)$oI~$~~O?C2LlYH)*@#*88*Q>F=!-Z5T@wZ?9biC;Tn{Pr0C z6h3K1-1VxW@z%1@f9%km&r`(B0Q;O1Ba3v1WfAoz3(*c1GcZQtl{ir z5-K~6&UP`AyV}`4fZfTC3MDBL*imQZ2yI1*f|mDcwkGp`&{t6RdgTa_q+ghnySLXKB zprpXSMa&EGQ`(Y{4vWvqG3bhfzQHn-5s^&;VpJaYl#(fNlFn=~yVAHcUAiURHHn`j zx9ew`CtD{wXS&kVw%;B9V%#3hV{Ey&zK1TmVV|J98n~S=`8;L?X>+&qOR$%-;$_D4CaY0!jW* zV+hp|UL2pxt0g6!E`~-B$LD6LI!>b2;Y6g)%He6V8N}!<>Zz$yXKMhXx1SoOc7O62 zke&=5e#q?ti1zTfiuO+QR( znKE(oxbLp}{k1=|jGFYC(onx`@r)ZQ1`JGWTfD8le!w85{3hYME8iW_(jne`w>Y(J zPB+eN-;*GAkch~i+61q1D@PB0s}LKMP!wTEaj*rB5~P207T*j5Q&?deOYf=#th@Q z{cj1w&#b!oQYod4m)ikMn&wO)$c7{sG_Zh^fjKk{Y+f1|SFT}WEIBI?hdLb&U~Z<< zJ|+YsQ7m<)X9=ZheO&*8e%7hf+nH39SJnNPupu+@{!7olK8*U0^xRdjEz-eq_IIT~ z%#fpL-dt~ksoqwf(G(kP8etom(GqJ6kMF&UjL=QV|x-M$w?G;LF8Z;8`UNVW^5Q8!`78 zn47l1wV91sPAH0}r*|(XDruGa#aG{|UrbbnJUV^!qYK1%;`PBFc3i*q*>lewc=f>M z343qeb+?eGextqw#8=(c-z&r0oXwkuKXR+7WT-tUVP&Z&@7jo z`iuA#{O3!i8)Suat7Te2upa~)y9S5^{t=;^nFM=yT0 zLXe{IP%6?!s9aPkRu-zu!ZFD+EHdK%Fx;?|2wD~LB zvHmgDxO)^|y|+3z(mNz5*_y4gx5+34F%Ov^)C@O<&1SUNfwi2Pk!WaeuPy>v>opG> z*gRz5c-;0#B(fa*Gi(N8YQj(F5B~fN45yYf)->5En0x4AOgLK6_@bh*)4Pf<4HJ&Z zQY}>gp&cZ9e*V{QQT!J;QM)+Af2@AoH2B#&Z~WDr_uRa5H=wdUM_x%IAXeObgU@)^ zh-bUrIr8zVZytSz>=h_Dm{r8Pd!Z6W330PdRygpl!ubK41a~elPk|7Sv59J|@n{g# zI@1~`9g;P^Q!>psT4YCyI7crP>4^zS8_>G z$g(9IUJweMx`2883We2NUXC@OykC1y9fixmSFp`>2 zKw}^%G$5ov0<-1es;%_u1h`St0Bu+qMNO!O?CMH>n{M2Yk%u)1+T8+l);P!c9p*UUBRyg? z)mlq|e1e-K&k@W{Bn_e?iGUldD=7+FN}=^KNG-2;_&%H0H%1w-b-=y%j=E#~jdu%i z!8>$uc6QdFio_7{-i1v=eseG8(+j8mY#{%XGv#PFxxi4VL2QPLqPDqtP*X!oHDBFO9mYJY%0@PI(WI)@ z0=}T2aAH-F2y5=3G6_fO^|mI_7%i-C8QCJ#Rz(8v=U3`pHRn#nrQi zELb;aLVQl`FV3~QKG?s((oj0)mD|e>e81_@;ln1I&fm{>Wv?oqu)oQuJTz^}%7%$0 z^Ga4;_S1}-+R{rWl{nA8zO*!tA9&NVjhTONm-_p*Lnb59P&FLXSeUj}2rx*P7*Bcy{#AF- znIDAjtUv16YB);gP2ht)99Edf%*YDh~{;2d)R%NUc(%qEvPkX~kO zwRTz`w7zbYu?Dq7Ks4TGPlAS)v5m%C+LKt>q_c)e+T+u|Xj$7<1W57Tig<|TkV6Bd zK=ioKl^LED_Riy4(4J$cvK+vSp~jI+FjMCM^8`oZJ%YA$^3x~ zyH`>@ys%-+=G=I}=!Wj6rH&0F+K#>|HnSRao_kwdAZ%uKZ64gUcpeY>y%*dM4_J>R z{tj8hxIu=QvspcI`LptyiR*+Vw720blAoPL&;7SZLR7U05>dSdlEkCb`Gb1!MRY*hPhlPhXl{UZOgCgC5zr737Wa~385SBInHZW9Ss0ehB=~#~ zd_0LkI2!fP)`d_(I2r2;EOW1{vDxvQQH^B>;=>30tCH`c&Qbsi-dwUo-aL zyB{1F(A8{fTvfNM>w*;{*5}xSe`xjfTmDxCz3{ZF;xBK#`1e@s{))=$ZoYo!z${^5 zpJMu+l6ir%pE@pVlK+4nFXXOPtnHyWq0S7^=QleEsp=c07FB;}Q5iubMj1qNoM)@AZzzUAlqZ4AX)kqnYLjy2L>l&dqNbtF zWcsC+p^^sdUaS&#E%?mPVdUC?r9HDT}MYZ8F zr^RZqdC#4URRDLEG*H~fG?g61tA802{AE%5!HEu_HX(^y!&s#$ff$k-%8DBR@H@nP z-L0cVKm8ErbsqaXeAtPGg)uW$w#cR^?2FD1{6cCOLti@1Y_xXYzX z@n5L;h$$YU(Jm79geYRMa@)Dvabw!8;C}Ed#9_dBJ;2K49^!?^AL9j8ee7{n6_m%R z`S@e1%0tu(TqnO*SRmexv!-$20ns_Ka%**tv;g6aee($3Fp=rS2dQAYFQx&X>m{NY|Q7H%XZnLEc2AkR@C=w%;P$g-P2JJI@8&r*=5-Rmz{I^ zY>2{1x3DL~UX4BbPr!|&Cj@Yp9pQg=|11-MJ>hWe3IC}*VP+PpIoT2HEG%}Ro#kCn z%4kpMqKt;qXJOuH?JSi0Z&yIXkjrzqQ7`&Idp>q9_I%p8j&d!@bDeod#K*3k>nN58 z^*QdyuU)NA1p=Py2=_+vECo4w^d*hlnbinKPO@GS%Bq!WfvcvPgq}V}Jp;QZDET88l1GNkNxPKx%rqkKpCdWZ)OAZtrb_z6( zF%K3Re^WxF+~lmOx7RE6LcnWePG=)aBQq|nBby(Pcd3H5N>aL^Z_^eIannmipUxuW z3p-?pV$Jgm0DP@>fGkT5{4oZ(O|~4R3!WL06E6{k`_+#ZoYTqwieK8r8+W-PYwLzQ zxcn#e0~ngRS|2Tsedxhqfcnj?_XU*obp5y29xAY(Jg@0@yQlLJgex-h- zK9d{fmpzcUxL~N=mg7rB>LBEj^8^0=GOmhmRt9BPR8@9X=m0B05v?Ty zy!!HTHbp8cIlmnWQ7pTL6lTV|0-VkdA^HFH*M6l0HGgeQq^7w>C}h5} z!XT_x3_rrv$s9pHizp;rKP(^7zp*;0vi3prS*{-&`svh}{cXp}A)F0B*4!WvK3i8e!ykPJkKE~^}zd3qXOJ06i z_Yq-sX6TK>2cB(~w=v8INCC(jxq->9LbkS#aBGum+hIW-0+SR_k)@gJm{G}NC}S(2 zxcHXf^5AVjG3bO83#J(iIG!V+A;3S+$)7sSJWh zvqi3k+IdjPpwGB8N1BjkcBFwm#{#fh&Sm$Cq6aAf2bmQHQ{*QW3PVFP4u@t z2n~!s5bv2C&Wx7=GC~BF&@W&fQJbcLaDKWSsm!hEK!Y&be4@^S*{Oxv(9pbtXe3Sa zp89w#)P`SZwmKSGTpkTA)W#Zg88oy|n|`Ukm&HRN7|e>^pJ*RZJO<(eX^$*egTt_c zlR2KOJtGqw-<3SP*79e&4=2(O@7{e_`26s0bw?synsD-7;oU@@G~vo`@K4?S$}5ny zZW=jQm|;E}2U`3>h%JU zr9$^hE+ZaGQjGRm$#K6kP7mn}7_mz`yCQsKhtxMc&e_HDFtD__g+_92C5wMja|^%F z<`x=SW(OKnguoImQ}9zsXFtuL4wlMsq5~cvBE2CmC%Tb3jy8T+W0*>nZq3uC@nvK& z<1FcMqwKkt&S}lB4@ZmBvSOVJ$Cg$^V@1B~nAE|4bnzvDXjbNs0T*8qjAUgZ@PU~$ z6ECOqjhIPx?g}KBwu2VDXR?&qo00HsBS{*ez=z$r%*3XQh&f~Xzswmcn=?pd#++H^ z=vgrp-&X+F7eJ42Bx)%{NE~9eT%Y*?wdM3oh$m(VwtxK081y&k_t76!$SQt z2Mz!x3!EC{o4W}2`jP$*=gBmqJQA%qa%atW6U#u|U` zTKmjMGA6m)oBw;h-`HYJJDRih-m9;75t!2`p7S1yH?hMXALhR6^6P$Z^$n9}O`n!L zcVqAT`Ooh>cf)ti$K4@9qt@F_06J2pa;=%I0QsvI15ylcT7`lFy;j9uf$}xFC)6<0 zFqO-cbe6^#XoQoN9rOlA*t5R8hS1-X^MGJQ*!?l(BC|Dz z`(CX>;t`0O`sYQ{LZOVxygavBIO2$Wiv!Maa^G}eA=y_K zCzh*I7(Fej>@{<^#}}Pz_A~(fQjSB_(v7rCUC*jS7Y0Cu-9gNFOCP`>_{&IhV?YE2 zZC6+e#;fX$h!q3r0%Al;OAywwT5F$_mUuxfD-$FuK*(iH-!UBB#q=6L?^eA>AwYJA z>YBQ`s;Du6GC|;o)F+f^Cfuaq&IEDRuYdhB-2XY(l{f}FY<9^Iz`=d-1DE@Ti@Vl^ zb@x}dL|UT664B-7aAbqfbAV;o0lXDK9TyKSw+JhWjm)LvZvZ_~@HB=1~id29!4u8^~sUerR%` zkrE+XPhu$E{UkCUyKGsAN6cpazj^2kL?kHUQXerR=-u=fE{-MOggyz2bQjL58c+>Jlu9}}#BkI!X-KKlKdyRUU@F4mJbY!>UaNe)Ffz^gdt}eq4hzN&U zUE%6?0p9~PelbF%cUakL-pN`7@mRTuLA)bZ#9#r2$8zt2kU|QCG~xLrvRH|b=@6?Y z;k*?58P)=uni1R}i)pe05*1hm$SN8qblQK0behPf1*$_faxp2ucz4f8gL|$gPO-5F!pFw=hN$DxTUF?81?e5vok}V|{Ao z&<=8?lSS@wA)Aon&7pDhybsxKp;tis^DYy4<9KVTpCQ#{B7GOJHk#B)v=5X03`EjS z#OQR|jU?f?tAVN;zE+N{K9O*u^(679QT4($>Ur4hs~av3&g%pxjKmW0S9mNTFGeC35bD+h+H<>Qux+Zo>WK7EvvugYvx{f#GO+k%DYrUh`R-3 zbn32QJY+T<;hx3xiwD;V|o`M zF?`afYXT=H~L$2pU|6K`H1->Vd56vc`(r6`yt z-z#?%T^IPr)69IuevEy+{YR+ex4QwO)ncDwpKo7f-(=q{cH3QWRQH(^k;K?+6JAX0 z$w&8QDW)zq+op&~wuNGzZG~;C=(nZoHnCJJu&LJGwCfHyD*_XtGcsK0QNeX&=@$s; zMB4pOJ~9=_1n*cnkWJ)AT5W^usk=BT7s5U}X+lukJaYh&vy zWARw};vl4V4nnq1fsh-U2sQ}ywZRdq3Za?|-qEp^RbyD+rY4@PEVs7UupZb@RekHx z*KA(1HE2ZAd&Kn$)u&dHMdbIVJ8ud)~km=Np{|UIZlbP5O!hp(lRfu-$36 zuqxIHB4-wYKc4LgQ+`)Z=62H@0MeKjNz2VWl0S|>iS)-oNKSx29R{&7$g@F%%#R>@ z;dm{#0{NRf z@v;&8X3?24`$&jTcacdPlJwg$CL!hvj@#W5odiWiy}`zZ>XmkrRSW$0h6QPMJ?3$+3gnjWXu?+;FNd5s*W zqqJ0=SD02(l3!`*K*Na=9+Le$1N{@JQ2c&mcl#@Vv&V`OO~F{_Xaw#1ayx*q%t34J zc~X<&1*u6v$n5|^!bcJzHK~&WGtM35hi?Zm4sr6RT*%r9b(kN^^TMH4`cf4tkhIw{ zE?F)&6bW18t*2z_Ez@Q1soyh@*0n&wg(k*ss- zahvA#X69%1WNJX6ax8PEDNaoK<@gNb(*d>uK^&A;puS9Ej8bl)5#gx}#A(=b9coO* zs|2M9@DBkh`d6f8CGHn9smE#PLoqXP|9${viu-o&PRzYzCX-~;Oi5eiSP>uot)GPXx3rn0%yT_HDnXQL-dsy-D zhzB!)fI>`mZzhRpJGU`eGe43$1TTLqYxV4fBrfb(B#H2>6w3A;#Uq3QnYxIB;wELI z3{~S{KgfP1cCX0Xs3e>bJNWd;TYX*z?bN&LzY3e4)MT^Yb_ z`yPJb&T~ca4HU?`A@Sz9^A;ahRbCS1Zbt4p;aPEGu%todH_9>AeyAdRbUxSIzhaw* zQ@fZ??Qd*!uF?EL?JN8ac@>f|@+!Yoj3D;RYZKKt@2zr_ZktArz?uEPF}yvpxV zSK&6B5#NP680A%dXI+I`X&@|w@)KZxRKOx=78z!3k*_E;&N;52t#GDuW zyg%{+BtG!0^mjmfLND7EQO6l-qGFTn|dfwX_y;RUGP`Nxf5To2+N! zhg1%SzoR?nwJZ$L341SmW$K)%`wPmduRiglt7^&$_D`KtbHX^?NVUvgc;_jRvVfRA zZSMPbX{R4Ned~p7<0p)t(02LB+W801x%oeOtH)+!bp)-pdBX7CgOxfSQoT|*QJHHC zW0s6oMr)%Q*-j%9y$r%pSeQ4jG_9y8T3La$co4;66%|KpaDe{**sP$VIm$>VrR527 zdMn6PC_xU^ip^z)#~U#JsM2j;T#MIYpEQ(-qeZ0p=S_s$w5e)fC#As z&@7KMfMa{r@cN82!K821Xsr;Pc`Q>0q3Bli>8+eE8@)VOsu5v>WH3d$(zg7*HM^f4 z%!ou6&Yga5_h4QU4gv@U7v7nhdq#KfZ(c#H?Cb?wtE$Uqj@2f7b&G`y0px<4E-EIC za1>gwF5*+y&Jy4?vBo;PnQ2MA4J>L~3v2eJ@;%hO&8K(xJrD}|dwiV^`5x|Uq!XSd zhlAmF9geg6+VAC6JPxw{>GUE8r#UcPC_@=A!?w1)$eDkbw-S35{ozs9Qr;+u7~ zObih89%JCjMZzaOM2iN_(K_b<(38%~9MQUHnQ4|iTqFb9u!UtvTXVSbSC(!)e(i*hM?3u|UHH|R`uCrD-Qz&jF;|h`tNMW4RDfpcS>|O`vDTOwTN+vr>CIaZTN7Fp zS(OJwtzg;=+Z5jt+d|(K^;8Y0B?b9vtJse2_bhxmR-m=&+ktM6b7!+*ymqOr!q;jW zE;aH+l^(Chem7 z#&m9T?sOVXZy74KyuM--ougK!U75fm*iJ$1w(=d|a|@SIg?U1=j0MIj<8(wYR+chI z)O!|46oU)bQKLQj20HMwsgER89}Hv+Exv zwk7Fv3XU4HCjGdAb#14+PRlwacKR5X>S!KUpJ`^obDZwz>6txy;@!52K*fy}S_Q=_ zE9yki^d2N{D)K|)r|aX!J0Rd@lU*@$=4=ykZ}#j`^Wj5(p<*m`fmu?7u>aJ?F zy1EoEps-Y3P+BpCBn}z1Af&ng@s1g$R|lqCGDV#-Me*X-WH!%XK$cNnmV~H6k!!wN zVTdY)OFf|bEQl(F`)L%0sG<-mOFIyjUbD(v(eNcxo)5{4=bUzO($eV*d*|fO>6)Vf zZWEfy%qNkI21mqrR#U^UOw;9AHmigTRHNZSzqT9)gmX z%9M!0o*}E63h#!2tl(dv{)GF>pwDDwSnDYCDk!?5IQsrZZYabzw2|ml)bNljC!?lh zJ@>KEI99b46(@JKuc>V4^}CAJG~|@rxN+kRwMA!ce=LP!H8HsXuf*0n49RNz!eA&f z%bk{Mf5MsN$eUM7JF;n6e&OBMCUQrBS?SfhMQ6@Zk4=0me2}BSO0u8KvUVrS+Ka?n zklBbts$N2MR|4p9Oh!{qIP@ob7t8LOtoN>A*{vxH=0{WB-FGbfh)d;rxc3-ma5!n=WO@eW5pwfb7KR#j^2JV_5hEY(bPIyAhdWMPEn zLe7?>R%1KTC_kY(+k$VJ9G*N7{G*QMkYNCnC&n!(e{GP)#+C?di=FRvf zjdqdpgms4QREBD3w*h*!6$yH)f zUtY{t&$B+6k@_S)JnD0Y>(GgemVpRACpVncfZb+e=rbx@e~hvuTw9UL$f?5hEgr zOjtBRoO|16!fW%(+VVrM*v>Hmwjo>(lW==c`iXWOIJqdy#0TK58G!?j8dGfNY=Kq> z+OK|r@iDqFFE@`H@0;ga7CFwhQQhd8IG6(L#*<1oO7rspv%(( zm6nwin(h%9s#-onIH-40EhOuErD-IU}Ai%9@4h zk{}n5pF+%w{VN2qAt{jjrv@nc2~klY2-%yeAn0GSZ$veAu7Jl$|D_8%h9zF`RpR(# z)33kv)?0>NT62x*>bz#*g%^mmiOa>wiA%iwOSQ>AkACm;b1yvij^~6Z%zU}B{Ha3r;HlEEzT8kesbVUr{)}!dsfX z#=F&Ph{nP~Z+;^XXzfkt9`l6#rC_O2Tqv@9h|_}SB>Ygq&{QOU%xdu!gkk$G_SgpT%GR-E?1lC6=CH`7D|I((W_FwNI8}i4Pe|^>wkhsTdpAPL; zFd0w>6t_zt<1ye?C4RR=-p1!{MQwizBX1K1ILjY(yza;6#+aq}T#E}o+LX3fo7uLl z?NFN`fWN&A$lKZxkhd9no6g4heC5}1<*r*5<;YiVq$|gjcnp=G+v11fhNw|$merhI z^AE5516+9>=D)Y7=I!#z6wwZ<PsO0aOUd@*fF98h-PJXJq}^xgYr5QkEu9vNt4h#J&)z?4P_0X8)qOKQ1< zUW_8?a?EX?CH@2HK1^T6SNXp*w@Iiz!=o9)#r z#}CagU0iKvn-q$HVtZ)z%3P6Y$O>Qz(xTN%V)84%)BFMYDO+JVL!&aciGRnK*=m^v zTnn|VtekJB4BOdDB^B(+fuLLlPijR&72Ab znCyM#>!#kXYr5pIylGlYxod2{p}Q83DG!bKz01sisKPHqgQJpDNS1I;DcvN28gZNl z1R!1MK65xSlq2skCnG18qvd#OVl}-rD{A^{E~&8%Gdq)+4V8N61st5?Q|HO6JP1$> zr*{`@b35!_6q32AEaEey@hOu^wPY@rt}E%4fR`sro$Q!=JnQuWFm51IWL`G9s_a{* z8^7S}lh~0esiK4;XH&_Vph-gfe=bZKKFC}|HsUZ-*_b|N{ur_Q$3ISZfBa*;Ppu;n zk~-1sYvV)*sAB{Cr|MpyCgU;Sf1zjT^>eWgGz9V%n;p}Q6EQ|W$FrI(f}!)-=w2#8 z*l99?-`(mYZHc;2J4s!sovv=u(pAksFOEY1@k_JKNB0IH+6gjkf>ecoq&NQR`xKZB zqQI#d=N`C1MIoaoOY|n@AldsH{q(QSk>5$bp1)H$f5-3QJ306iT)iPzzVa&1BY(?PJM_@0i%J=v7C=4_|hrY=^sE#g$n`_?FMU{h2rOV^F*u({5_ z97x^JbOY>Z8|kDwybgiCE=;^@(P!xk^i}%lx*a>ZkBV2QUJOcw-0yu>ZeM{Dg-$fl zWE}fyqB>Fif?EBFVI26%_=R-`pYu1aPu&sacmtS81y(B?utlHXRUm0U=O;$oMjI}h zP5=TMBCcw#xYJ>nPCpI$+h+!dFbwEU-RannhH8m4)p>%4W*@vu=&5XwqNk30K+DP` z{2D+0=}&yMSD)2oqkumi@MkKzt{jt5sItLCI1INSq!;Zh{e{*D$ zPTyNn(Mo;{{hzo^|3}PppIKj8(Fzm>htsha;#G6I+YzYZQn;fP{Bf6>RS&l09z8KJ_ZvO7|K_h)wM%+>eCMHQ)djFuU-2v&RhE4-3eP{ z=oat{e<=3_p21(jWA@zmF`}P%JPACMXJIV!bT731B=8iaGUk$!?2sX&~NaZ3^PQSkZv^3rBK5{F)UTh<6{L?VN!{kQsLn7Pg^-H#QziXlfAeQn*}Q zu+4FkW4A+#mGqYMm%v#oDfX6hmB4i;O(gRXK@bScpmQX%$u?=utlmFf{mixRbkCl%e{6I7+GC$N=DPTpmi^kr*Z*eX z4ny^=f^VshU}OxCA-OfV(+gEe*v* zz)|8;J+v%p*q7zVRa0CXrLPQlqyeaj={vWn9YLz4-lW{C$dxDt| zmhnId^6EpQ?t2aXrH+D`WM8hq5=P%`oi_%T5(qC z;YU%q_ejbqyumnP1Cgc;L_Gpovo z8PnK(Xm>)r(*kSSG>w~1o+FOA$SlIehdx5grItR8Sx~*02GtL60Mub(t{y&2gjFz* z&RGVSWqci)w=t1oR07&l1jP04ATp2oxnhp3D#ZnkWE6!li};<;V)V`z2{*(k%<;YB z`^RhJDdh`MjxRdC(-%hQg|AQZ>loiv?3bU)O;!%RX1yEutjLba%E6oPp36C6_9`fN zAc>116#{z%{QXa@_uF*_Vz#oJ@90PIcOr)_AZ|ciVt6m~Ja!S@Py0eC%(n;W`tTqj z?dbbl#PwvYqQ~qE#Na&Iy)&W{ODDE2EZtgRtBs|3Te+*vpw|M~vCicMqM$&l>hy@X z2?!idwhwb2V&zekfPToPF$jqe0peXVn~ZW_7I{5BZaVb&Vh(gI$w@b10vnQ984wbD z2gDaFeL%dDj3a-_$AMlVD0|$<&bItE(P*X8Im2U*K;Xz~3=md^CzXGbmNQ;RCE{eN z6wjm*aaJ{kgC}u2c8nRJA7PLV_sCE@8O8+t;q(Lb?X!I$Lqm8Pfn-=$gd~zm1aTdl z9e`TNfrxP{hsx&+hIcm5TJe;AQR43}_3Z8%9Qwo3E627?x?teO!KWs-kG*Vqaq)!j zm(|vsfAaJb3SxN^u9|k`kHp}=CBCSxOcWcxd^=H9TXp`jfuELSMxMQT$-4Yl;HKQX z!ebZopAxUG-qd;U=FjNwRD#=-__$qO)+U5>gLkE@}qcq{D zOGi6z*gpH^Et?YWUs5=&ytF$MFq(;bEYpBG7C@jbi!fO>W^2isJ>f}nsC2IB$PxiZ z4@3m#c({9R_+)dnp29oEvY9!afOpGkJrHbC!(`@aJv_Fm^^{9P`Jok||6R47oYqP0 zau7eVY|p}dVWT{4NAQ~j0&PUB6?R~?v z^F@Fwpg*G29eQoA3)w)3OEVWlK_vpeQTnmET9kHri}Q=s;$mA~C$`l4W)2x6?Yx~l}uykD`I2SS#lf{-f{qLoQCE=q3$&%A9m(?+(y2$iP%rmiNn zxRg=gP%42XErr=a+uy^A(gXN)o_{LkIO1Mk@Gk@b^-Y)B=Glq%z2q@w;cD%3&{asE zB56ne=%^D+95Gm$ek4;V{YKlILhhKC%$A@8-Lo6R6CGMw^i8$J?Z3R{nqRh;)YO!= z{p#wgf7Mn}`%}FkRcM_jl^c zm5`WVjzwPtCcBh|CWjV=R)_34YP&$)zIwH|UA;Z@tm=RZz8~ok#Q7o!?K>UfOQ4^i zkRNd-vQOL@p;lD(hk{xVvSgpxPJA0cTsY)FutC6%%eT2dx8w0A=hxYB$_pRSR?E!u34{H$Ml?JXNmsY@GyYq|0xPBn) zZ<{vImD6E&XVj(D&C2~s{PpC-*=QViUHqtLjCwmjQ3?|OfmK1|L?6IevMX1Z`D&pT zT22kQuv-n?z#`a01hHOKiy#hydqKgc2Q%80QaxtZ4479op*UpNH>MGFCKqr=5cENvS5C2MQ~?O zOS9@(`ItK+aK)vG1;R41TpZ`bV`*7|kh&hkr#SYbN8VUF#l;fUwIgu&PDwq69H0gg ztH_C}oTyJs_SizJH%Vg&y;1tAM`vuG-MwZ0;9%^AWqmtZ1~<0kCx4y z*rAy?sk{gHq%Pr;3gksS6MJHc@}@Z+?V&bjdNjQ_ueiK9yCtusd{X(;j)gS~JJtlZ z2EE}>Q&(f7r?_BTq3G%YL|Hhev9YM2z*iN`0oE`FW+hxCJh9K%VrAcq1R{tp*k7g@ ze6N`R-E7r$$Nfb)zHL}r+DsK>Pbkycc}3cp&FxVi7dlur0{iN|bEa}#7}N|&N)#|q zN)jG2{UJGt7^x2o1Qu-sT1D2fRCAV4_rpR3)b}xHo_%(_VY1(ybK42?wzu1^y&<Ski>neoR4^y^WMfJV#IJMqR!}ORPT6%ZB1F~!|)f`;yrM5=bnYLI%q)e0>fm}ySGkl>FJm_;g!pPuQsV9`m4^ykDu(nxTd=7 z2gI>Ghu~X73I~Pbfq>occCvlXvQ^6f_z)ZZz>R~Q>(mx%tF^7#4x|KJXk3(HnF!`r zHe0`DE{kOe86o4tu%y5*M#Bb2lPD3xhAt|#2qhw%9~Pr!GUDU1>=c9*a<(zU@mOw8 z5VGtPgminEAS;&$sl9EyJ#E`Z;&G4zk`l?%#O)(_(>2_GoQ%MwDuVT+K6~d6pATlm z@=rQy;l{k&>_Kt$>u>z#Ep`9UK;M?ys;cVh>eH91-vd|cA%%BxONHKG}AnzRGr*ekuk@d2Hx=G{{i| z^JI3A2s7Y9k&2R5mnLk8#6cqKF+8I~ZaytttEXX!K+p7Xh!^I^N2$Nv^A?*~Zp~$f zaex*shwg;yt2@yLhCfRHvC4{@{7ZB&?szqEd*bF7#9*T5Rna5ny^!chtW-}Lx)Q0D z{~EeeT|AUY`)D^1fB%F#E)rR0IBF{mZ3?NOac$1&s4A7gT*Ki(yhb`a6u4o10^)Om z2|*k%(gnOswFqH8Y!@W%@LXmDTM&B?;j#CUaa$OW^oIJ3{tPvv2%Aqv8H+-6DvQ`a z$FrZC?1pk6m@jDO3)&+T-j!Sg@mu*>3q_ybN8*j9zp4v%!j4gUOIDPqGOjDUCHV;M zYKS(H^-kMGdg;l?E?fQBSg`Ez3Rut8oHD-q-wE#;e_GKq_qmOaZG3iK@AAR!<}v3^ zd~D*mW5!Mz6pwGXGv3;2Bu)_5*qYl~?%1H-ICS0m?M0<|y7uhBHY2C3{PZpAO02{B zL+{u!u@2)zsab=H`^HK6lNuM~FK9eLKf${uvZnRS$eFF4^0DPk%@!~U(&{^Hu6EOt z-U?r7-(LJ5MgEi_1&dpviq#Gj^;?Nh*j2+`Ew2MCZ!8dY1Pkwua(^bK&tl+a+ z5edO^`xIl=z*9f(R6pzZ1x-?-xD5?k37tJmKGk-lN)yW4Nf$cyw%ZJL@D z$hAG{%*hV5wNE)Z8V+24-n%p^m92-?G zMr<^OT8{eM-rN&Av)SgribsN4ZJuh|$;U@f)a)9Vr$> zTq#P;dyeC?zlJD4JXd)Tb`8B}e5W6QWqJ>?jKJLMMW+h#zapqytn?z19r}qXfccG} zwHqt0WXe&1GyFIuB zxD?q+fHxp1ZPw82Y?5SD7`PXEbRVjM(;zjeI2&V_L~d?=Fe?sF3={=iL-s#K@C27fV89h)ONBVONzWn_geTc-ZDP@Y);5|fn~ZZI5lLbLej;HZ zkRdy~`B1ULFv^H^Vfz(vVv_9FOj7-rwPBw(ebKJ-ztgvDOWl~}hIr$ZXC?l&KQUK7 zA>k48u6bg?%<1CAwR_qp*YC+FEMGUfdt*_df2a^i-`$B5iYJV{&*K02_K&bn{>J>j zNQsMMxIVJpVLDbg`q6XXu!59zoLxQa77raC&@-ooqNcPpD#T zjLD$HuRa_juHYlXh@>s$x1q7Q`>VJN`5Fq7(D0TKV+!nGSgM7m$!I(7!%OcWruR&;PI9jPYf09^dlNE|I_b*tN}N ze=z5^j~#pOhI=pg-IQt5XH2AX$DM-4hd6gFeC`gfPx#;Ed4Of1e!%%sU|GOi_Z=E? z+>E`S4*%{?d#3;=QoQMJ#^L&d$lxwSPAipL@Us^i6u=0K|>3&6kF$!Ost z_ml~#HSr8J`13Qe10K(iV`rl`L)}qeI>15cKp?JUdtK!Gc`+1{i()>5ddO_`u15pB z2>Ii%kEQP&57RNjFs!KSPZ$d8wnGGYfKIEjV%7 z@a)A&nT&@V>O~F#e<7Q3PAqxs^SAg~ljpcn)zt!tNxx!3HYv-5oShN6;;p%)@0Wos6! z-Q7B2j8U-ucMD!ie7I!kNmbRQ+CHHMf>Xs5QFE-Aw0-E|BAh9#5@ed=EMBEDk#80R z^X$z91%dpihUJJX^om$MWnAD%0PK5RfO;#@HNZ>6V~+zYXz=U@Qr`wx&;(d(22gy) zt0UXp@TSkLWnyDC5C~(L0=!It)H0>MU99b)eEv42{TG1od7w7aNC|xP(nn=)bbz)Mq9lpXG^I#YW zmUZ^~zhNy`?ccBdaQ`LFYnZwPu$L?!TQBgjKQ$Xk-uu{tu`+vB(1Nx*Af1=n1`u!7Y<49JKqa)E zC~mZrhu}38tUU1S$7X~sX5o%y(K(azHmQ^>86`$HJgJIdO(Ba^q>^BlnTl0dA6TK` zKsIIHSXUsXp>DKv!Sc_KUv>Amag+B4@?u+8p7^uXtO08Bn;PTIw`{~jxC>`oSXJ9l zS_pZ@^;E16KDG2g2lPP(`V#t!gi?f(4@`$dWu2 zAheqsd-R@zmucS-kKcahowxTNckFtw7kD4LxW>w@{MF2~0pF$BiEae8lAV6sZ^FuA zD=Gt0%8DywIeBfuU^$fesqid^V9U9^pbxrI>OKcdJ&D5iQ zYoeGyD-*?!p(gMRqvSwcVi$JdsLDktQH^SxSRZ-@_nXn1Nf4-LyI=s9WIwY zTT$u6k;B1C4up&VfOwsi9EdMWKOMV;ms)=58?Qt%xSW{oCZl4|J}Fz86QZ5W}k z$U31KzTt|`k&^`n{&$lFrL&!ala#vwA)fQ_E;}X&%4585M{bT-A}mNHWseaAlGBMeO}UGo6YqtmwSUj-r<@prY_%dX|Ti za7f1i5ED;OUXJ}$BDh`9<6&8yM%Iwf%~i3N!ttKv0vkGS^0AM{O$9}ew$!dm;`%36HI z7`ox^1aDh~V%9pFLQNG-X0BO0K0ZHpe(|Qz`rM7h?lON|=YGC2JVy(+vy{+q9D_U*U)uL4` zYl_>HX9{&pZ9*(6%gD}lxa=Na20EX~Cq9`$I=2Q_M;HOJPlt;ASCiw-U}@UzcYZqb*_x+M8v5)#bvTffAxa!J=^vKbE3=I&)HsvwVHG2&-yv=vP|V>Gi$zBJob38X6%4_z|-H* z-+0OxXCrxAQvk>4j^Rh=xZLJg%-P&uFY4W=w6;Bq zq+h#-4orJq-ne$n6U@e;mC_x=7x1_74sGLvh6WGzA_+1^N#Na!&=q7@AO9fdi|sdP zULlJzq_!MZqL$OjKCDG^qJ{G_lGgwSqXHp4P~Wv|O7DB;T>jMz?{QzQpLS<+OG8If z)1^zE-+S*bOUv9)C_67JvpMaJSW8)T{f?yryQ5xb9qU}k#5SA*r^qvl+^TL5 z+cmpA+rCVlXJ4xxYadYi?VBCXsqd+Ov43t)gCcz&O)TD4H3J~kb|72n$R^{j!w&5y z>j^*{AZr+TR@oww1!W_Vu9zUEf_TTwr~Pe}ddPfCDJ_Pw#qCAc7hz`MIwUykS^pE9 zD+%C+tc8@vOprVV@j1jCh_$W}$_b(;73@Y{h7hl0bdo#c09coaV?ua!M%yz(InO<# zzVQqFuCErsxLKoLZE58;Sb$Ds31-1O{-?Zz|JaY{Y)01I-ZYUWSzGdT)&?WJt`&gu zLzvf+^z4}0NF!@78ymCxFt*50==qqT_W-3b+gljJbO2M) zdm+NUQ;5zfhXu-(WpD@r^8Onu`csAcsnY)UIhl^n$lXi?TUf?gYji3YNeM-&Q|#+Q zObu-0a*K~R5I@w0$0Yvy_Ho(8X+wP>nEnu0miQkQ@`uZLV^d=2mhJoZH!UqMpPiRh z>z=hzN4)SysFSlwqc^Z)Z66DeOu?MSwF@r;zO|I!{4@RR4;aCEVhql*Xv4);@Fr?C%?ofe^; zMjp8NEj(~V`-eVuPH&FL`6eG5br;xLRMhmXTXK}Sp; zNbt9tk$C3h%=wvXou>p0)sq!B4AhKbR2f7&#b!9Dt6+pK1i1uC##fiFv%(G!-u0%1 zrM4yNjfyk^L6gl%AgqR44~H26d;pH&+1KRX6%UwPa;U0qZ6XB8D~IBETBbN8#8%PSk=@mn{DgNfr8ZLP1XE6-E+ zSeCP$aEaZ@qv)W;#&PJ)!ilEJq!yEjGPJ6Y4r7N8H~1IX7p&}eWEs592@cR;g=DoX zh=Wp*3EmE3Kg6j_^@4bv-wXnE0k|p%i7*EO?4iAA7-^pTv@RZanVM~1RmCMoA7M@b zFE^_~fCi3OVR+T{&0pevYw52QenJR}?=-Q?q2W%w%CF2Kx>G=JH3OI0ukgNAWJUvs zjUK-D5o^Ww4nPjRt^Lq^GwlL?8{>WXj9Bv7-gOd&uUA+lz> zlDU$PnOL8ifk|n?-W(1Gg2b3YtpL11Du#?#Vh9LCA?59TwwLaP5_aQIc$<^pm!Bj5BF5jw->yr)Rd5c+pa*hMDa$f(!0Si3!4zm;siUcq}C*2q`f^ z$V3hk$wVJp)q%AmVK*smnZ!wiXrxW`5$Qf~IhmsVhQtlxx*SI#*HNE$WIm_TH5>Qu zKT?(r=^Bb=4m|?~TYe^TIM{*t%AID$Fq@M+mgX~9io3LUYnt<;@YYj}~7@LLGxVdZ#7+%hhJ&iY|~4V zS$H>P;X}SzH`zE|+m3r%el>Y)^|62eT0Pk^2Y4YpmWuNOTSmpUMGx z+Qw1Y`r=S=NRA}pq&&)=Bs)IJBmg1!v4>^oMZiasNNqZ0R7S*zkiJTFGf>?w0JQaE zR-CZrxYdb&zvZIDqKrBJbr`ez9&(d;xg%3F0pRticuyXVJ&QJaI6*G3HCp!tRyF8H8L8 z5Y}-{NkVy?0U?hw2)RLtAZ2P>;N`rmckRg8SJxB$^QLc7K;;wUvvTH zX=mb@#EXeb)%QiYh=ck~;tkAHZ4v21_3)bS5jA2;;<&_>iOUnK1(i$CTrB-9obL>r z@4uR!a)1p?%~@(+5~RMm_YtfH!ViM#zUWx6-Mito*2eOoVzn`l zo8LdN_r!|oJc|D_Hlw};l_{|Q!R1rXVReQr7yaFB%FDnv%#Z8iD(c%zy}QC}Tjks2 z+t}o4B6*REU~!?XYP?dCQKFWV*uvvON^6(RRoD;;dCH-VApuc*7lm+;6_X&O1ZIM^ zH;7;JB7l(g8WCn4sW5Hl*!;0wW7V+$7*!WEuyfWB^>90&hpRI^h4enpx$V4J5id)z zmUAUk^`C4%C5BoNXs#Zo5+JS=k@0(O38eh4oipVARO@Nd2-ZHHGA;4zH`YFA_V%QQ zvu4Go{q3oq9W4{SXKwp>eLU{y-n;7P`@BE7Y|%~ARINQ;ySDS{yS0a>JbUhe#Dmjk zE*Ax_bpLQ|-#zi^OET?F{a(yKaCbJue>|&YdS{~Wk%wAq!xMAv`>okh^Ezw>ptkDs zP=lF`9=9gtpy_dGMpi`2&e~jLK+3#^0jQoIx4H&9d(Td>EGGv68a#zkH=i?nKvBvnTcZ*9q*O`P_e%qm3bg1Cz~quEwq7O;Mr1$P zSg;ZSfRf}?Or|V*!*Y#$sLvbUW?p@IqEYNVb6`x@*rR70_r0O~Sml~oPycPk)Z)_I zvBl#`7tj8WpY(67uC5Yu=X|%at`b&pZo!Gu=ABmP3Y{m;EN;)pHWDwp1EKMW39XZJ zefGrV-f(ytG%8j{dkm{%C})`w(FJ6femtw#0Wg7ms&e^_8o@r6ECV4~212q7gvByz z`V0wW%E03VDV>Rs(ph8gP1|7`<{Scd)B`|P78$Wz?5908^ynbKJsv(d4c|;voQcnP zUJm6)Uos2FQo|#XqMa@S`O!`-gTHFV^Dd4Wx?~QNeR(89Wup!eobgPLkYeLQ${LR0 zxIJ7e;Ne;UJo_PlQOU{li02^(0nET#OS*SbcuGfzq=t_MD=FD^*r?KLyfXVfhBEU#PV zSy$&EJBiRN(4_D-`s>}T#rN0L)CKP!PJBl2NtyUOni8Mr!FLts1htC%js{A6*45Z6 z)Xd5*BtCt)FvOHvS3$$kt~m`zd^QZY`WqY-6{0~cuBo#r&*tk9!{_6)Cz=$W%`uFo z#tgKS_B5?)l3rUfiTU5pVGf6}Q(4UaMhdg>Pl;=nJvt|G{_n)DhVK06jQR1&XIxd| zjJgVrHy<_E6u6^~>MPEi9AD5K&Y4vsFu0ulsna7Xj#)6_=9OngCI)AA>Ehi)j&62` zCxlO5ee;w#OO6YJ|512^^yA>>B9W)}?L(7PIPvKicX<`&iOGtzsL8$9;}UW&+88OG$^zzDHQ8 zmK+*gjf-Tav{)%+oD^VBEt)jx*14zra&_ADcTQ|Pv8=MOp|awX`dikQf3F;<$HgVf zidH`}F>T)C%V+;^;)MApA9eg`qV4GKmzNb+*S>5{@n?r7ws%a!X1Upxmf1O}Zd_)j zr?vU#(ZZa4*sIH7OlINa+YdN=FcubhKtQNnOUtNhuxi4of-$`~bg0-!U>-39->Oay-w7R3*;B zh>V%O`q80>?tWCAxLccg@DaW5;4|7-vVTbXuC`@!wz36A&eynx>?CFvW%Y7m@>8?w zNc;;vpYN)p)a3ID<`Bg)G-N3CZ_U(XQ~z)is>M|FI;{x*f6Ua8c}dAs%h5*)7{hP5 zc8&(XCbN=OQgSqtN2eu+S$>kS=dQc<7(W)v7B5*Uh8I9Qe8ugzU$N%sqfWx^eG)5i z7j|z%`FC@ch@nwCs+L7s(i;Quh@qnSDWbTd-YRsd-X92|;x!b|eG#?8$~^kJd~)jB z!pK$1Rgnjk2l1f@y~l_BxerxCq=+yD4a0Q*S8d;^{G+sYDB{TWj&WXeSZjl6JpT>p zTNEGi0Jy`_kLzXn5nw@m)cP#FDOt`uvb;pU>+?kY>cPRj4dv<4wC3wBTR5+0Npbm- zMpa2DdS4=M;*99Hob~-TPn>^rUkF^xJ(SQp!NmgQ=Q7I(5zAS|bP#GMDm9U1?D8VK zDm6a^T=~F*!6YBJ?ndF-Vuib@QoTH>5H%T?eCDMLVB-Lf$!f5K0SpZi1{ecEffp?j zqkumLvvBTBcFSTM>5j$fW2($iQqb-rS=Uc?0sdec9w}AHhI_KWyD?dt3Cq4f?;ONz zPn%|sMM7f>3+FXtj(52nm>SUJYwC3Ab`8?-iFwy{-tp{&&RO|+dFridy1((`KhFK* zYD;?l4xICd1*SjlY`D`iUKL$f#o!qjl7@Fr;> zfKFgR(1yBhcRLMXce>mdu}l0W|Ah$llqCFz#qW_mC!3VK7P4iE>zw`(zquuj_?_-e zkEH{vk?b*pS#Qm9`e!CRD@~|}Pxvc>NE!7~29Gf6(}p)WnQSQ^%vvziRuN<#r5UiG z(5e78z+5z$Uq|%2Vh>+&I!3xXRF*4W0k|D)IdW3>xnU+bx3{nwnlfGhb=ogp; zSvM&DE8)aZ?+{P3MT==;scvxgPnb`3<;@4RE*r21`DoKtBZ9XYA8kzDVO{>;WY8ya z!i#d5GaoR4DuP(xkENr(C4c0+uYbUwkqC^~RKt6UCBP^EM#&ZJ4(+jnll4CEgK&3t zGC$_Ag@59qzi30~=`K*tHjnof^%N~H(yByZdS#$E)Gp%b?SXh`y6ACDO797b4=oW3 z($|Pp>8FW}>3)V1(F+P97;l9#V77TMFOl2nYm6URI@+uirTf;%31@XoQD z>PzQjxTmyKOr19E&C7*bbhVWIV(O%~pMCbtJapEiL1tmJsrE5WiCx)j=4nF51~8Q# zLxsCK+CeqoWJ;_d5E5VvgoJAV@pm(as$}KZeUFmp&DqM@^dp| zVWG$sQH+ApZDsMU0<^^ebR^x|8q&wsb|JI@(<~+KOAoOfQ}?MlZ%UH>-*N#ZiTO zVwC5c4bi+R-Kvde$?1%EfPIWNjUg!c{Pa?|O(d6E=Pwv>! zIs^Sw?HB!UXmeR_!}cFtvOT^`oq6S-XUv#g>rXU^m-324tw_7*_ubQHmE?&(Ci0`@ ziB}UJKJk_>JcLGz-`%bL)fayGmp^-(W<>z*OW(#QAj|m7Jc9VaTO?~m)N}&*7@7Yr zf%7Ug77^0VG9nHRBO%X^ifOPI#DQc{fGnNHGib3U=|gSOR06<-03-Od8&2t@#T-NEw*)zZQ37*l+3G6|yuz&T_UKt4Db z5CWc-Eyq@E+mx=W&de^<0AMbcLKO`u!wW!rET>`EvS_B_08W&q2FM(cIF?pjxg0J- zR+_ZD5Rb;N`IB$%7!>#B6z;i0 zT$T7Yb5%)kY1F3z50W*Tjpm=Ym3K@Rvh4=#N(a7{P%L7K?_hO;20D2PwZLb8Mn zj!GDurQK%S1gvaS9(XZivllHjBP6E`egdTr0+eaqT#%w)t3R+!KhQrY?xVlS-K9Oo z97%j;dj%Zv!b8F|T@_>HCcVW82KjREygxF2g_Hd-y1Y5y@Yb+KGA3^IFqF)5^?P>6dY7-uPU=vdC zq^as$nRzg7WK?EO&8AbMS$VLKYoH-S~k#KJULE_U^ zMKG(pV3iW>^{${n0$y)X@;DM9k7H4!kVQ%%`FeaD3rmS*cx=IL74oz#JSK@`qZg#_ z$e%z#1D?7J1r7BjCW;#Lu(dF(-5n9|SW15oQu>3C(x2JStCRF#_!*LBM6lQojF=-z zJRc##*s?)4YBF69;6284ADwS#O?De2`N>%dKWb&PHAh;ALAeT#0i*5f3jvFs*FoL$ z)h$*WDsHXCO+Wdk%aF^<;JpNC#yYBGkb>>ou}F69fiu!?A;MzOa212aqESpq)zW-z zXC_&qZDe*l`rycY**%!}rcIgT1*HBw*zcdS{eIm8jrs)9ris2)sf%_fvb00_K> zd6$SCSK^0noZoNDk4A%?`TC9M40WY<+MHQAnUs(Dj87~RlTZEWKcZ}bYZl17v%_R*AI?o51;c(^|La^3WO zk6wMljpHW19BxNq7I8_;0+|VvFRD+N^q`ZWEBPK8D5TP^#ho*>$xhwVY1Jrn1@sKV z*_Gp>8U=P)Y!Oe44PI7fB*zdEz-M9fe!$inh=a2AQBG2=!#Ea{DnuaxK4(P;f+}55 zkwEcu`Yb;~Ck(`E$#RA-Bmz!&XRI#P6;plbybYli@xJs3q=r1NAS|dnD=(Qmws=8i zoIuFR8W3_%5+QwQt8f9RVaWodWLD97JhF5FnWRy*3)Hy+X__*(ORVAr0)?P@hN42n zIREy`fAFI_FT3oHgTH!zaPXtB$b9xM!k75;Z*L|3Q?32YtABXu*S~r7=7bGF>S#@L{zL=0;+5&FiDvrCl3)jPt@hcRIsPHO$Nj zNBes!|g3QJXn1${{EGiIeqX;Z4Rx zfmv_l4%P$s8P^z2K=(%&iVHh|8$gGmvT8KKV#uh)2l(pM{I^YjSmQ3lr zXXfDTw-3???8Q$WyXP^Cs{(%9)G3dg7z|ZTdh9wU#=_XTt9rLpR8`DsKlr%**}2zV zdv4;R>2u$DzV4*%_Wt(Wi9@};v(+0u7rlkuwUn9Vyt?iCYKw~DZZrq++RqsS$jPWO zw8Dtw=q}a-XFM?0)$LMY!%0mLAWeXj^=l^bQ>}tDL3ms!qGU9iliR5|W1;$x z8PY<*P=*#!E|xMs5<%z&Yv<$^T`P10-~K(sEh(lkqC_nz=@~`l>k%BnkCDItO}cCL zji;aaiWpYdGg~r*} z{pjkSJU6M4IKdO+xguvFcXME1yf}+7n`ZLk!!VoaJ z1Prk&7J5DwuaB#7%zXz!49C_8Cx(44i4FsIlVH-gYkrj7O!f&IY}9y?tf!)st&(gs zmDY30YGaI;Z%!dtHl3|;ggy6{q+R__atoHt9cvvny1yrF?r%ssScbT?{;V}D6AkwR z8fF~i%syEZ*i&$00VWX#a$<;N>ltEzAwrX13cS`8v44RMlA-z|=^z|b=%i8R*VlBA z3<^O7b#;tZK(HF*5>fQ?YYHfPBpiHF&kP>-z~kx}!;tVPmGb&akeQq-X6@mV+T+X5 zmFOOVuiIyOop9WhTr(G|SXm^tYM6;l!yk+YrYcQWrs%4}n=aDReZ6jAaH>Ge_GCZrFj3v)@IDV! zv=0lJ-kR<}uZu#ydDhW!&|? z19tICy^KaZjLNxFuH&Z6`iipxBR!%fl#vDFxv@O=A8*hN4$vSHo*P_j0g5{FS__%VnU3~#8d+z z#UVdKIupbva%K$;ar?G-J2Lj9vc`o(kv_4X6!!qR6wW9G6d{?=;AmqqO5E79Ggrza8qROO2j2BWjYQYL^ACWPnRiy$+ z2p`1jzkZLK2G#lZ$x=zNe&_?b#~0KNdt7}J5im?&o{wH8gGUr1`bHI&@dA7N%d2cB zsvS3B;4C_N9FJhit`kzD0Pe>&v(sS@+1tf*G08T?zF5q+Ewrx_D{KRz-?P5HKxd0mA)g=%48zUj+q&7V_G=mv0{_nF0b9G>GxS3N)!1!m|egug=X`;{u5O1C(oq^~U<;k#hPxTcjnb|U!? z6uyOjKy#RZ<4zT?lw0H3_3{UL5Xb}N?JH15kOhB*>f{lJ14vTJyQi_!`l0_E+Hk*U zQhV>$9{uT09(?ripFHsBPZqB_e$k@iS1nE)D;`cvGnx;)h~8pT-NxF2oS|H0;v-5X zT;USPOt05H7bhTRjz~vcmT**-23i8E1Dk>S0;odk7x1)kAJibFn@M`Xw8sg>#PLo6 z17C*QIx(l4U0BQ+FVJor>Ronj*~#YOnNu#Q@Q%NF*7bMIJ+a}UR`IDi?uyALlpKHZ z+$l3UVtb>7H=NdY#nDwKR^S`Hr{-uI@eOO0Q%vt#=i0*WI=@?}FYqkI$U5@f#}Y&X z&6}vM%AVs52yY-i&=Xi5_<7(^z!reRIVWH%p<>lJHgBY|JW!ZfSr{m<)}4sX0Dl4d z_@g>Nxk?AqnxbwMy(5;$$z!R@<5HR9-l_yS;$OeX>^z}u?5K~Q-ZS@-@tGyp_RRmz z%4HXxxoG*^MH7Bdl4)MmbIsky%?#^NecHUS7tEZ{F}1U3SG4fL zV;8NDI5JL#O|%y)^Hbcn3)ouiX5PuR?*gmPDbnT`9z(OMS~_6)^h&3aW&x9A!jdUhO5jx!q;sWvCf=r?P^p>jf#--jaABaibP~^UX)p=+GXqGtp1G zfq1?S6$qnY`<}HbjU0bRy zNKDIWNT0vCxwS((Zt`iBRZTgO8?#!1Ik^+dD%-NMGt+J2lM8;Xs=>nIb-0tis|b?d zPHf6}vt%Kl0nrFv388+RvJt#hv^fSwWTRO&14bamaYEw$AIiQ2Fskb6|K0cI&6de5 znJt;gGFd14B$>&CERZ3r0fZ1B5FkJxEMZFsVG|L=3W^J8UBC^n+J1@%iHOxwjf%Kb zC~Xlpz`C^B3T;2@=jXpLFaO`UGg$=f_kBs`=FWZh-R0bK&pr3tbI;)*^pSXyyMH0r zk)3sLb>t`(OONz~lKTStNBEN1El<4ih2**&tJLeFTe@5R8}628!|+y9sKyjyvZutP z*mK2PRk>KMs?D2`rzeBsS>~Ww<&12rRJ9xN^;el zujFXSO(N2<6BHFApo|dJveH6KF`}(piy4sXBe8&@a~Pv*7=_GhWD#8!>F(b=^oy70 zG}e!PVb^`n)zvr8dTIKk(M?4K&as8%S@C5x&KbECL)O+!ULlok*uQuEr1e>G&yTOa1b>CtTHOXaiHv%1zsOwXZk>byONV}K_)JOH!UgU>mGbgn$OZQM^HW!J`Vh?CIipq)#pjlN>2#%q%aH@<&u09JBu0b##E9O*llP~%7BtSjy#EoUcjnCId9!CQ`N4g?jqwS#Nh2JF zeX%j?mH($)`Q$St%(NFSFpa8q#?Kf0QaRtea1pm-{K8R|x_JJQ)@FBVswy-xW0q6r z8(p$|t8ynxW0knHcY$BjE5jI&74X;OpMZ|%2ycZ9F1ncH}M=gtCTOlx}^MtIWPI=5+_e4Ro_22gz$6&*x` z1`g^wQoj!6bGDBg1Qu}M4Mxw#*}aI&zra)wDrhU%jEfesiOfozi%9qk+=Dv4M>S9) zCqnoh5lbPCTA?QV}qlUEj6+p29a}cG?Gf&vjMH$h|yKi6+$_*&q?P98ogJ?&tUj5chq%B zWB|Yb6KC8%2xQ4ElZ$L%RKCqC&h_r{?(_C||L&E)e|P{rs)#caM504-t*@QP#tAth zM+ZDYl~E+JBh>Oy*KWUx{cc(nAxC_0R$*$C@bSU^5JHE@2!YRzxS9Ii@LWAM>8k0+ z=04MU_&BtA+zs`$2gjct7?vBx*S&XId^h})X&dtLvnNzaHQyhN@JQLBY*ODLIE0!| z&dU%zsMWHe&NdHMa#aU=a*wo`=rQ)3j?ujSjfg z^BfW*+(O>jlh_EsR58DygkHh{V0sMXKe!m2Zk0aS`@%0D`usD|`Qc4B$QCB_3T&hD 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 Wa%z020eM!EKP7!_1CK~}(&V2vP|DAJjx>wce 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 QszUv9=YO{&!+&1?2S~60^Z)<= diff --git a/client/load_tool/.actionScriptProperties b/client/load_tool/.actionScriptProperties deleted file mode 100644 index 51f72318..00000000 --- a/client/load_tool/.actionScriptProperties +++ /dev/null @@ -1,22 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - diff --git a/client/load_tool/.flexProperties b/client/load_tool/.flexProperties deleted file mode 100644 index f2072112..00000000 --- a/client/load_tool/.flexProperties +++ /dev/null @@ -1,2 +0,0 @@ - - diff --git a/client/load_tool/.project b/client/load_tool/.project deleted file mode 100644 index f394664d..00000000 --- a/client/load_tool/.project +++ /dev/null @@ -1,25 +0,0 @@ - - - load_tool - - - - - - com.adobe.flexbuilder.project.flexbuilder - - - - - - com.adobe.flexbuilder.project.flexnature - com.adobe.flexbuilder.project.actionscriptnature - - - - bin-debug - 2 - DOCUMENTS/output/load_tool - - - diff --git a/client/load_tool/.settings/org.eclipse.core.resources.prefs b/client/load_tool/.settings/org.eclipse.core.resources.prefs deleted file mode 100644 index e5beadd8..00000000 --- a/client/load_tool/.settings/org.eclipse.core.resources.prefs +++ /dev/null @@ -1,3 +0,0 @@ -#Thu Nov 11 15:11:51 NOVT 2010 -eclipse.preferences.version=1 -encoding/=utf-8 diff --git a/client/load_tool/build.properties b/client/load_tool/build.properties deleted file mode 100644 index ac9ae7a7..00000000 --- a/client/load_tool/build.properties +++ /dev/null @@ -1,3 +0,0 @@ -FLEX_HOME_WINDOWS=C:/Program Files/Adobe/Adobe Flash Builder 4/sdks/3.4 -FLEX_HOME_LINUX=/opt/flex_sdk_3 -TITLE=Flashphoner Load Tool Documentation diff --git a/client/load_tool/build.xml b/client/load_tool/build.xml deleted file mode 100644 index ddbbb049..00000000 --- a/client/load_tool/build.xml +++ /dev/null @@ -1,59 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/client/load_tool/html-template/AC_OETags.js b/client/load_tool/html-template/AC_OETags.js deleted file mode 100644 index 6366467e..00000000 --- a/client/load_tool/html-template/AC_OETags.js +++ /dev/null @@ -1,292 +0,0 @@ -// Flash Player Version Detection - Rev 1.6 -// Detect Client Browser type -// Copyright(c) 2005-2006 Adobe Macromedia Software, LLC. All rights reserved. -var isIE = (navigator.appVersion.indexOf("MSIE") != -1) ? true : false; -var isWin = (navigator.appVersion.toLowerCase().indexOf("win") != -1) ? true : false; -var isOpera = (navigator.userAgent.indexOf("Opera") != -1) ? true : false; - -function ControlVersion() -{ - var version; - var axo; - var e; - - // NOTE : new ActiveXObject(strFoo) throws an exception if strFoo isn't in the registry - - try { - // version will be set for 7.X or greater players - axo = new ActiveXObject("ShockwaveFlash.ShockwaveFlash.7"); - version = axo.GetVariable("$version"); - } catch (e) { - } - - if (!version) - { - try { - // version will be set for 6.X players only - axo = new ActiveXObject("ShockwaveFlash.ShockwaveFlash.6"); - - // installed player is some revision of 6.0 - // GetVariable("$version") crashes for versions 6.0.22 through 6.0.29, - // so we have to be careful. - - // default to the first public version - version = "WIN 6,0,21,0"; - - // throws if AllowScripAccess does not exist (introduced in 6.0r47) - axo.AllowScriptAccess = "always"; - - // safe to call for 6.0r47 or greater - version = axo.GetVariable("$version"); - - } catch (e) { - } - } - - if (!version) - { - try { - // version will be set for 4.X or 5.X player - axo = new ActiveXObject("ShockwaveFlash.ShockwaveFlash.3"); - version = axo.GetVariable("$version"); - } catch (e) { - } - } - - if (!version) - { - try { - // version will be set for 3.X player - axo = new ActiveXObject("ShockwaveFlash.ShockwaveFlash.3"); - version = "WIN 3,0,18,0"; - } catch (e) { - } - } - - if (!version) - { - try { - // version will be set for 2.X player - axo = new ActiveXObject("ShockwaveFlash.ShockwaveFlash"); - version = "WIN 2,0,0,11"; - } catch (e) { - version = -1; - } - } - - return version; -} - -// JavaScript helper required to detect Flash Player PlugIn version information -function GetSwfVer(){ - // NS/Opera version >= 3 check for Flash plugin in plugin array - var flashVer = -1; - - if (navigator.plugins != null && navigator.plugins.length > 0) { - if (navigator.plugins["Shockwave Flash 2.0"] || navigator.plugins["Shockwave Flash"]) { - var swVer2 = navigator.plugins["Shockwave Flash 2.0"] ? " 2.0" : ""; - var flashDescription = navigator.plugins["Shockwave Flash" + swVer2].description; - var descArray = flashDescription.split(" "); - var tempArrayMajor = descArray[2].split("."); - var versionMajor = tempArrayMajor[0]; - var versionMinor = tempArrayMajor[1]; - var versionRevision = descArray[3]; - if (versionRevision == "") { - versionRevision = descArray[4]; - } - if (versionRevision[0] == "d") { - versionRevision = versionRevision.substring(1); - } else if (versionRevision[0] == "r") { - versionRevision = versionRevision.substring(1); - if (versionRevision.indexOf("d") > 0) { - versionRevision = versionRevision.substring(0, versionRevision.indexOf("d")); - } - } else if (versionRevision[0] == "b") { - versionRevision = versionRevision.substring(1); - } - var flashVer = versionMajor + "." + versionMinor + "." + versionRevision; - } - } - // MSN/WebTV 2.6 supports Flash 4 - else if (navigator.userAgent.toLowerCase().indexOf("webtv/2.6") != -1) flashVer = 4; - // WebTV 2.5 supports Flash 3 - else if (navigator.userAgent.toLowerCase().indexOf("webtv/2.5") != -1) flashVer = 3; - // older WebTV supports Flash 2 - else if (navigator.userAgent.toLowerCase().indexOf("webtv") != -1) flashVer = 2; - else if ( isIE && isWin && !isOpera ) { - flashVer = ControlVersion(); - } - return flashVer; -} - -// When called with reqMajorVer, reqMinorVer, reqRevision returns true if that version or greater is available -function DetectFlashVer(reqMajorVer, reqMinorVer, reqRevision) -{ - versionStr = GetSwfVer(); - if (versionStr == -1 ) { - return false; - } else if (versionStr != 0) { - if(isIE && isWin && !isOpera) { - // Given "WIN 2,0,0,11" - tempArray = versionStr.split(" "); // ["WIN", "2,0,0,11"] - tempString = tempArray[1]; // "2,0,0,11" - versionArray = tempString.split(","); // ['2', '0', '0', '11'] - } else { - versionArray = versionStr.split("."); - } - var versionMajor = versionArray[0]; - var versionMinor = versionArray[1]; - var versionRevision = versionArray[2]; - - // is the major.revision >= requested major.revision AND the minor version >= requested minor - if (versionMajor > parseFloat(reqMajorVer)) { - return true; - } else if (versionMajor == parseFloat(reqMajorVer)) { - if (versionMinor > parseFloat(reqMinorVer)) - return true; - else if (versionMinor == parseFloat(reqMinorVer)) { - if (versionRevision >= parseFloat(reqRevision)) - return true; - } - } - return false; - } -} - -function AC_AddExtension(src, ext) -{ - var qIndex = src.indexOf('?'); - if ( qIndex != -1) - { - // Add the extention (if needed) before the query params - var path = src.substring(0, qIndex); - if (path.length >= ext.length && path.lastIndexOf(ext) == (path.length - ext.length)) - return src; - else - return src.replace(/\?/, ext+'?'); - } - else - { - // Add the extension (if needed) to the end of the URL - if (src.length >= ext.length && src.lastIndexOf(ext) == (src.length - ext.length)) - return src; // Already have extension - else - return src + ext; - } -} - -function AC_Generateobj(objAttrs, params, embedAttrs) -{ - var str = ''; - if (isIE && isWin && !isOpera) - { - str += ' '; - str += ''; - } else { - str += ' - - rtmfp://87.226.225.59:1935 - true - flashphoner_app - \ No newline at end of file diff --git a/client/load_tool/html-template/general.xml b/client/load_tool/html-template/general.xml deleted file mode 100644 index 3c3ad19d..00000000 --- a/client/load_tool/html-template/general.xml +++ /dev/null @@ -1,105 +0,0 @@ - - - 1 - 10 - sip:2001@87.226.225.55,87.226.225.55,5060,2001 - sip:2002@87.226.225.55,87.226.225.55,5060,2002 - sip:2003@87.226.225.55,87.226.225.55,5060,2003 - sip:2004@87.226.225.55,87.226.225.55,5060,2004 - sip:2005@87.226.225.55,87.226.225.55,5060,2005 - sip:2006@87.226.225.55,87.226.225.55,5060,2006 - sip:2007@87.226.225.55,87.226.225.55,5060,2007 - sip:2008@87.226.225.55,87.226.225.55,5060,2008 - sip:2009@87.226.225.55,87.226.225.55,5060,2009 - sip:2010@87.226.225.55,87.226.225.55,5060,2010 - sip:2011@87.226.225.55,87.226.225.55,5060,2011 - sip:2012@87.226.225.55,87.226.225.55,5060,2012 - sip:2013@87.226.225.55,87.226.225.55,5060,2013 - sip:2014@87.226.225.55,87.226.225.55,5060,2014 - sip:2015@87.226.225.55,87.226.225.55,5060,2015 - sip:2016@87.226.225.55,87.226.225.55,5060,2016 - sip:2017@87.226.225.55,87.226.225.55,5060,2017 - sip:2018@87.226.225.55,87.226.225.55,5060,2018 - sip:2019@87.226.225.55,87.226.225.55,5060,2019 - sip:2020@87.226.225.55,87.226.225.55,5060,2020 - sip:2021@87.226.225.55,87.226.225.55,5060,2021 - sip:2022@87.226.225.55,87.226.225.55,5060,2022 - sip:2023@87.226.225.55,87.226.225.55,5060,2023 - sip:2024@87.226.225.55,87.226.225.55,5060,2024 - sip:2025@87.226.225.55,87.226.225.55,5060,2025 - sip:2026@87.226.225.55,87.226.225.55,5060,2026 - sip:2027@87.226.225.55,87.226.225.55,5060,2027 - sip:2028@87.226.225.55,87.226.225.55,5060,2028 - sip:2029@87.226.225.55,87.226.225.55,5060,2029 - sip:2030@87.226.225.55,87.226.225.55,5060,2030 - sip:2031@87.226.225.55,87.226.225.55,5060,2031 - sip:2032@87.226.225.55,87.226.225.55,5060,2032 - sip:2033@87.226.225.55,87.226.225.55,5060,2033 - sip:2034@87.226.225.55,87.226.225.55,5060,2034 - sip:2035@87.226.225.55,87.226.225.55,5060,2035 - sip:2036@87.226.225.55,87.226.225.55,5060,2036 - sip:2037@87.226.225.55,87.226.225.55,5060,2037 - sip:2038@87.226.225.55,87.226.225.55,5060,2038 - sip:2039@87.226.225.55,87.226.225.55,5060,2039 - sip:2040@87.226.225.55,87.226.225.55,5060,2040 - sip:2041@87.226.225.55,87.226.225.55,5060,2041 - sip:2042@87.226.225.55,87.226.225.55,5060,2042 - sip:2043@87.226.225.55,87.226.225.55,5060,2043 - sip:2044@87.226.225.55,87.226.225.55,5060,2044 - sip:2045@87.226.225.55,87.226.225.55,5060,2045 - sip:2046@87.226.225.55,87.226.225.55,5060,2046 - sip:2047@87.226.225.55,87.226.225.55,5060,2047 - sip:2048@87.226.225.55,87.226.225.55,5060,2048 - sip:2049@87.226.225.55,87.226.225.55,5060,2049 - sip:2050@87.226.225.55,87.226.225.55,5060,2050 - sip:2051@87.226.225.55,87.226.225.55,5060,2051 - sip:2052@87.226.225.55,87.226.225.55,5060,2052 - sip:2053@87.226.225.55,87.226.225.55,5060,2053 - sip:2054@87.226.225.55,87.226.225.55,5060,2054 - sip:2055@87.226.225.55,87.226.225.55,5060,2055 - sip:2056@87.226.225.55,87.226.225.55,5060,2056 - sip:2057@87.226.225.55,87.226.225.55,5060,2057 - sip:2058@87.226.225.55,87.226.225.55,5060,2058 - sip:2059@87.226.225.55,87.226.225.55,5060,2059 - sip:2060@87.226.225.55,87.226.225.55,5060,2060 - sip:2061@87.226.225.55,87.226.225.55,5060,2061 - sip:2062@87.226.225.55,87.226.225.55,5060,2062 - sip:2063@87.226.225.55,87.226.225.55,5060,2063 - sip:2064@87.226.225.55,87.226.225.55,5060,2064 - sip:2065@87.226.225.55,87.226.225.55,5060,2065 - sip:2066@87.226.225.55,87.226.225.55,5060,2066 - sip:2067@87.226.225.55,87.226.225.55,5060,2067 - sip:2068@87.226.225.55,87.226.225.55,5060,2068 - sip:2069@87.226.225.55,87.226.225.55,5060,2069 - sip:2070@87.226.225.55,87.226.225.55,5060,2070 - sip:2071@87.226.225.55,87.226.225.55,5060,2071 - sip:2072@87.226.225.55,87.226.225.55,5060,2072 - sip:2073@87.226.225.55,87.226.225.55,5060,2073 - sip:2074@87.226.225.55,87.226.225.55,5060,2074 - sip:2075@87.226.225.55,87.226.225.55,5060,2075 - sip:2076@87.226.225.55,87.226.225.55,5060,2076 - sip:2077@87.226.225.55,87.226.225.55,5060,2077 - sip:2078@87.226.225.55,87.226.225.55,5060,2078 - sip:2079@87.226.225.55,87.226.225.55,5060,2079 - sip:2080@87.226.225.55,87.226.225.55,5060,2080 - sip:2081@87.226.225.55,87.226.225.55,5060,2081 - sip:2082@87.226.225.55,87.226.225.55,5060,2082 - sip:2083@87.226.225.55,87.226.225.55,5060,2083 - sip:2084@87.226.225.55,87.226.225.55,5060,2084 - sip:2085@87.226.225.55,87.226.225.55,5060,2085 - sip:2086@87.226.225.55,87.226.225.55,5060,2086 - sip:2087@87.226.225.55,87.226.225.55,5060,2087 - sip:2088@87.226.225.55,87.226.225.55,5060,2088 - sip:2089@87.226.225.55,87.226.225.55,5060,2089 - sip:2090@87.226.225.55,87.226.225.55,5060,2090 - sip:2091@87.226.225.55,87.226.225.55,5060,2091 - sip:2092@87.226.225.55,87.226.225.55,5060,2092 - sip:2093@87.226.225.55,87.226.225.55,5060,2093 - sip:2094@87.226.225.55,87.226.225.55,5060,2094 - sip:2095@87.226.225.55,87.226.225.55,5060,2095 - sip:2096@87.226.225.55,87.226.225.55,5060,2096 - sip:2097@87.226.225.55,87.226.225.55,5060,2097 - sip:2098@87.226.225.55,87.226.225.55,5060,2098 - sip:2099@87.226.225.55,87.226.225.55,5060,2099 - sip:2100@87.226.225.55,87.226.225.55,5060,2100 - \ No newline at end of file diff --git a/client/load_tool/html-template/history/history.css b/client/load_tool/html-template/history/history.css deleted file mode 100644 index dbc47c61..00000000 --- a/client/load_tool/html-template/history/history.css +++ /dev/null @@ -1,6 +0,0 @@ -/* This CSS stylesheet defines styles used by required elements in a flex application page that supports browser history */ - -#ie_historyFrame { width: 0px; height: 0px; display:none } -#firefox_anchorDiv { width: 0px; height: 0px; display:none } -#safari_formDiv { width: 0px; height: 0px; display:none } -#safari_rememberDiv { width: 0px; height: 0px; display:none } diff --git a/client/load_tool/html-template/history/history.js b/client/load_tool/html-template/history/history.js deleted file mode 100644 index 669d4b64..00000000 --- a/client/load_tool/html-template/history/history.js +++ /dev/null @@ -1,669 +0,0 @@ -BrowserHistoryUtils = { - addEvent: function(elm, evType, fn, useCapture) { - useCapture = useCapture || false; - if (elm.addEventListener) { - elm.addEventListener(evType, fn, useCapture); - return true; - } - else if (elm.attachEvent) { - var r = elm.attachEvent('on' + evType, fn); - return r; - } - else { - elm['on' + evType] = fn; - } - } -} - -BrowserHistory = (function() { - // type of browser - var browser = { - ie: false, - firefox: false, - safari: false, - opera: false, - version: -1 - }; - - // if setDefaultURL has been called, our first clue - // that the SWF is ready and listening - //var swfReady = false; - - // the URL we'll send to the SWF once it is ready - //var pendingURL = ''; - - // Default app state URL to use when no fragment ID present - var defaultHash = ''; - - // Last-known app state URL - var currentHref = document.location.href; - - // Initial URL (used only by IE) - var initialHref = document.location.href; - - // Initial URL (used only by IE) - var initialHash = document.location.hash; - - // History frame source URL prefix (used only by IE) - var historyFrameSourcePrefix = 'history/historyFrame.html?'; - - // History maintenance (used only by Safari) - var currentHistoryLength = -1; - - var historyHash = []; - - var initialState = createState(initialHref, initialHref + '#' + initialHash, initialHash); - - var backStack = []; - var forwardStack = []; - - var currentObjectId = null; - - //UserAgent detection - var useragent = navigator.userAgent.toLowerCase(); - - if (useragent.indexOf("opera") != -1) { - browser.opera = true; - } else if (useragent.indexOf("msie") != -1) { - browser.ie = true; - browser.version = parseFloat(useragent.substring(useragent.indexOf('msie') + 4)); - } else if (useragent.indexOf("safari") != -1) { - browser.safari = true; - browser.version = parseFloat(useragent.substring(useragent.indexOf('safari') + 7)); - } else if (useragent.indexOf("gecko") != -1) { - browser.firefox = true; - } - - if (browser.ie == true && browser.version == 7) { - window["_ie_firstload"] = false; - } - - // Accessor functions for obtaining specific elements of the page. - function getHistoryFrame() - { - return document.getElementById('ie_historyFrame'); - } - - function getAnchorElement() - { - return document.getElementById('firefox_anchorDiv'); - } - - function getFormElement() - { - return document.getElementById('safari_formDiv'); - } - - function getRememberElement() - { - return document.getElementById("safari_remember_field"); - } - - // Get the Flash player object for performing ExternalInterface callbacks. - // Updated for changes to SWFObject2. - function getPlayer(id) { - if (id && document.getElementById(id)) { - var r = document.getElementById(id); - if (typeof r.SetVariable != "undefined") { - return r; - } - else { - var o = r.getElementsByTagName("object"); - var e = r.getElementsByTagName("embed"); - if (o.length > 0 && typeof o[0].SetVariable != "undefined") { - return o[0]; - } - else if (e.length > 0 && typeof e[0].SetVariable != "undefined") { - return e[0]; - } - } - } - else { - var o = document.getElementsByTagName("object"); - var e = document.getElementsByTagName("embed"); - if (e.length > 0 && typeof e[0].SetVariable != "undefined") { - return e[0]; - } - else if (o.length > 0 && typeof o[0].SetVariable != "undefined") { - return o[0]; - } - else if (o.length > 1 && typeof o[1].SetVariable != "undefined") { - return o[1]; - } - } - return undefined; - } - - function getPlayers() { - var players = []; - if (players.length == 0) { - var tmp = document.getElementsByTagName('object'); - players = tmp; - } - - if (players.length == 0 || players[0].object == null) { - var tmp = document.getElementsByTagName('embed'); - players = tmp; - } - return players; - } - - function getIframeHash() { - var doc = getHistoryFrame().contentWindow.document; - var hash = String(doc.location.search); - if (hash.length == 1 && hash.charAt(0) == "?") { - hash = ""; - } - else if (hash.length >= 2 && hash.charAt(0) == "?") { - hash = hash.substring(1); - } - return hash; - } - - /* Get the current location hash excluding the '#' symbol. */ - function getHash() { - // It would be nice if we could use document.location.hash here, - // but it's faulty sometimes. - var idx = document.location.href.indexOf('#'); - return (idx >= 0) ? document.location.href.substr(idx+1) : ''; - } - - /* Get the current location hash excluding the '#' symbol. */ - function setHash(hash) { - // It would be nice if we could use document.location.hash here, - // but it's faulty sometimes. - if (hash == '') hash = '#' - document.location.hash = hash; - } - - function createState(baseUrl, newUrl, flexAppUrl) { - return { 'baseUrl': baseUrl, 'newUrl': newUrl, 'flexAppUrl': flexAppUrl, 'title': null }; - } - - /* Add a history entry to the browser. - * baseUrl: the portion of the location prior to the '#' - * newUrl: the entire new URL, including '#' and following fragment - * flexAppUrl: the portion of the location following the '#' only - */ - function addHistoryEntry(baseUrl, newUrl, flexAppUrl) { - - //delete all the history entries - forwardStack = []; - - if (browser.ie) { - //Check to see if we are being asked to do a navigate for the first - //history entry, and if so ignore, because it's coming from the creation - //of the history iframe - if (flexAppUrl == defaultHash && document.location.href == initialHref && window['_ie_firstload']) { - currentHref = initialHref; - return; - } - if ((!flexAppUrl || flexAppUrl == defaultHash) && window['_ie_firstload']) { - newUrl = baseUrl + '#' + defaultHash; - flexAppUrl = defaultHash; - } else { - // for IE, tell the history frame to go somewhere without a '#' - // in order to get this entry into the browser history. - getHistoryFrame().src = historyFrameSourcePrefix + flexAppUrl; - } - setHash(flexAppUrl); - } else { - - //ADR - if (backStack.length == 0 && initialState.flexAppUrl == flexAppUrl) { - initialState = createState(baseUrl, newUrl, flexAppUrl); - } else if(backStack.length > 0 && backStack[backStack.length - 1].flexAppUrl == flexAppUrl) { - backStack[backStack.length - 1] = createState(baseUrl, newUrl, flexAppUrl); - } - - if (browser.safari) { - // for Safari, submit a form whose action points to the desired URL - if (browser.version <= 419.3) { - var file = window.location.pathname.toString(); - file = file.substring(file.lastIndexOf("/")+1); - getFormElement().innerHTML = '

      '; - //get the current elements and add them to the form - var qs = window.location.search.substring(1); - var qs_arr = qs.split("&"); - for (var i = 0; i < qs_arr.length; i++) { - var tmp = qs_arr[i].split("="); - var elem = document.createElement("input"); - elem.type = "hidden"; - elem.name = tmp[0]; - elem.value = tmp[1]; - document.forms.historyForm.appendChild(elem); - } - document.forms.historyForm.submit(); - } else { - top.location.hash = flexAppUrl; - } - // We also have to maintain the history by hand for Safari - historyHash[history.length] = flexAppUrl; - _storeStates(); - } else { - // Otherwise, write an anchor into the page and tell the browser to go there - addAnchor(flexAppUrl); - setHash(flexAppUrl); - } - } - backStack.push(createState(baseUrl, newUrl, flexAppUrl)); - } - - function _storeStates() { - if (browser.safari) { - getRememberElement().value = historyHash.join(","); - } - } - - function handleBackButton() { - //The "current" page is always at the top of the history stack. - var current = backStack.pop(); - if (!current) { return; } - var last = backStack[backStack.length - 1]; - if (!last && backStack.length == 0){ - last = initialState; - } - forwardStack.push(current); - } - - function handleForwardButton() { - //summary: private method. Do not call this directly. - - var last = forwardStack.pop(); - if (!last) { return; } - backStack.push(last); - } - - function handleArbitraryUrl() { - //delete all the history entries - forwardStack = []; - } - - /* Called periodically to poll to see if we need to detect navigation that has occurred */ - function checkForUrlChange() { - - if (browser.ie) { - if (currentHref != document.location.href && currentHref + '#' != document.location.href) { - //This occurs when the user has navigated to a specific URL - //within the app, and didn't use browser back/forward - //IE seems to have a bug where it stops updating the URL it - //shows the end-user at this point, but programatically it - //appears to be correct. Do a full app reload to get around - //this issue. - if (browser.version < 7) { - currentHref = document.location.href; - document.location.reload(); - } else { - if (getHash() != getIframeHash()) { - // this.iframe.src = this.blankURL + hash; - var sourceToSet = historyFrameSourcePrefix + getHash(); - getHistoryFrame().src = sourceToSet; - } - } - } - } - - if (browser.safari) { - // For Safari, we have to check to see if history.length changed. - if (currentHistoryLength >= 0 && history.length != currentHistoryLength) { - //alert("did change: " + history.length + ", " + historyHash.length + "|" + historyHash[history.length] + "|>" + historyHash.join("|")); - var flexAppUrl = getHash(); - if (browser.version < 528.16 /* Anything earlier than Safari 4.0 */) - { - // If it did change and we're running Safari 3.x or earlier, - // then we have to look the old state up in our hand-maintained - // array since document.location.hash won't have changed, - // then call back into BrowserManager. - currentHistoryLength = history.length; - flexAppUrl = historyHash[currentHistoryLength]; - } - - //ADR: to fix multiple - if (typeof BrowserHistory_multiple != "undefined" && BrowserHistory_multiple == true) { - var pl = getPlayers(); - for (var i = 0; i < pl.length; i++) { - pl[i].browserURLChange(flexAppUrl); - } - } else { - getPlayer().browserURLChange(flexAppUrl); - } - _storeStates(); - } - } - if (browser.firefox) { - if (currentHref != document.location.href) { - var bsl = backStack.length; - - var urlActions = { - back: false, - forward: false, - set: false - } - - if ((window.location.hash == initialHash || window.location.href == initialHref) && (bsl == 1)) { - urlActions.back = true; - // FIXME: could this ever be a forward button? - // we can't clear it because we still need to check for forwards. Ugg. - // clearInterval(this.locationTimer); - handleBackButton(); - } - - // first check to see if we could have gone forward. We always halt on - // a no-hash item. - if (forwardStack.length > 0) { - if (forwardStack[forwardStack.length-1].flexAppUrl == getHash()) { - urlActions.forward = true; - handleForwardButton(); - } - } - - // ok, that didn't work, try someplace back in the history stack - if ((bsl >= 2) && (backStack[bsl - 2])) { - if (backStack[bsl - 2].flexAppUrl == getHash()) { - urlActions.back = true; - handleBackButton(); - } - } - - if (!urlActions.back && !urlActions.forward) { - var foundInStacks = { - back: -1, - forward: -1 - } - - for (var i = 0; i < backStack.length; i++) { - if (backStack[i].flexAppUrl == getHash() && i != (bsl - 2)) { - arbitraryUrl = true; - foundInStacks.back = i; - } - } - for (var i = 0; i < forwardStack.length; i++) { - if (forwardStack[i].flexAppUrl == getHash() && i != (bsl - 2)) { - arbitraryUrl = true; - foundInStacks.forward = i; - } - } - handleArbitraryUrl(); - } - - // Firefox changed; do a callback into BrowserManager to tell it. - currentHref = document.location.href; - var flexAppUrl = getHash(); - if (flexAppUrl == '') { - //flexAppUrl = defaultHash; - } - //ADR: to fix multiple - if (typeof BrowserHistory_multiple != "undefined" && BrowserHistory_multiple == true) { - var pl = getPlayers(); - for (var i = 0; i < pl.length; i++) { - pl[i].browserURLChange(flexAppUrl); - } - } else { - getPlayer().browserURLChange(flexAppUrl); - } - } - } - //setTimeout(checkForUrlChange, 50); - } - - /* Write an anchor into the page to legitimize it as a URL for Firefox et al. */ - function addAnchor(flexAppUrl) - { - if (document.getElementsByName(flexAppUrl).length == 0) { - getAnchorElement().innerHTML += "
      " + flexAppUrl + ""; - } - } - - var _initialize = function () { - if (browser.ie) - { - var scripts = document.getElementsByTagName('script'); - for (var i = 0, s; s = scripts[i]; i++) { - if (s.src.indexOf("history.js") > -1) { - var iframe_location = (new String(s.src)).replace("history.js", "historyFrame.html"); - } - } - historyFrameSourcePrefix = iframe_location + "?"; - var src = historyFrameSourcePrefix; - - var iframe = document.createElement("iframe"); - iframe.id = 'ie_historyFrame'; - iframe.name = 'ie_historyFrame'; - //iframe.src = historyFrameSourcePrefix; - try { - document.body.appendChild(iframe); - } catch(e) { - setTimeout(function() { - document.body.appendChild(iframe); - }, 0); - } - } - - if (browser.safari) - { - var rememberDiv = document.createElement("div"); - rememberDiv.id = 'safari_rememberDiv'; - document.body.appendChild(rememberDiv); - rememberDiv.innerHTML = ''; - - var formDiv = document.createElement("div"); - formDiv.id = 'safari_formDiv'; - document.body.appendChild(formDiv); - - var reloader_content = document.createElement('div'); - reloader_content.id = 'safarireloader'; - var scripts = document.getElementsByTagName('script'); - for (var i = 0, s; s = scripts[i]; i++) { - if (s.src.indexOf("history.js") > -1) { - html = (new String(s.src)).replace(".js", ".html"); - } - } - reloader_content.innerHTML = ''; - document.body.appendChild(reloader_content); - reloader_content.style.position = 'absolute'; - reloader_content.style.left = reloader_content.style.top = '-9999px'; - iframe = reloader_content.getElementsByTagName('iframe')[0]; - - if (document.getElementById("safari_remember_field").value != "" ) { - historyHash = document.getElementById("safari_remember_field").value.split(","); - } - - } - - if (browser.firefox) - { - var anchorDiv = document.createElement("div"); - anchorDiv.id = 'firefox_anchorDiv'; - document.body.appendChild(anchorDiv); - } - - //setTimeout(checkForUrlChange, 50); - } - - return { - historyHash: historyHash, - backStack: function() { return backStack; }, - forwardStack: function() { return forwardStack }, - getPlayer: getPlayer, - initialize: function(src) { - _initialize(src); - }, - setURL: function(url) { - document.location.href = url; - }, - getURL: function() { - return document.location.href; - }, - getTitle: function() { - return document.title; - }, - setTitle: function(title) { - try { - backStack[backStack.length - 1].title = title; - } catch(e) { } - //if on safari, set the title to be the empty string. - if (browser.safari) { - if (title == "") { - try { - var tmp = window.location.href.toString(); - title = tmp.substring((tmp.lastIndexOf("/")+1), tmp.lastIndexOf("#")); - } catch(e) { - title = ""; - } - } - } - document.title = title; - }, - setDefaultURL: function(def) - { - defaultHash = def; - def = getHash(); - //trailing ? is important else an extra frame gets added to the history - //when navigating back to the first page. Alternatively could check - //in history frame navigation to compare # and ?. - if (browser.ie) - { - window['_ie_firstload'] = true; - var sourceToSet = historyFrameSourcePrefix + def; - var func = function() { - getHistoryFrame().src = sourceToSet; - window.location.replace("#" + def); - setInterval(checkForUrlChange, 50); - } - try { - func(); - } catch(e) { - window.setTimeout(function() { func(); }, 0); - } - } - - if (browser.safari) - { - currentHistoryLength = history.length; - if (historyHash.length == 0) { - historyHash[currentHistoryLength] = def; - var newloc = "#" + def; - window.location.replace(newloc); - } else { - //alert(historyHash[historyHash.length-1]); - } - //setHash(def); - setInterval(checkForUrlChange, 50); - } - - - if (browser.firefox || browser.opera) - { - var reg = new RegExp("#" + def + "$"); - if (window.location.toString().match(reg)) { - } else { - var newloc ="#" + def; - window.location.replace(newloc); - } - setInterval(checkForUrlChange, 50); - //setHash(def); - } - - }, - - /* Set the current browser URL; called from inside BrowserManager to propagate - * the application state out to the container. - */ - setBrowserURL: function(flexAppUrl, objectId) { - if (browser.ie && typeof objectId != "undefined") { - currentObjectId = objectId; - } - //fromIframe = fromIframe || false; - //fromFlex = fromFlex || false; - //alert("setBrowserURL: " + flexAppUrl); - //flexAppUrl = (flexAppUrl == "") ? defaultHash : flexAppUrl ; - - var pos = document.location.href.indexOf('#'); - var baseUrl = pos != -1 ? document.location.href.substr(0, pos) : document.location.href; - var newUrl = baseUrl + '#' + flexAppUrl; - - if (document.location.href != newUrl && document.location.href + '#' != newUrl) { - currentHref = newUrl; - addHistoryEntry(baseUrl, newUrl, flexAppUrl); - currentHistoryLength = history.length; - } - }, - - browserURLChange: function(flexAppUrl) { - var objectId = null; - if (browser.ie && currentObjectId != null) { - objectId = currentObjectId; - } - pendingURL = ''; - - if (typeof BrowserHistory_multiple != "undefined" && BrowserHistory_multiple == true) { - var pl = getPlayers(); - for (var i = 0; i < pl.length; i++) { - try { - pl[i].browserURLChange(flexAppUrl); - } catch(e) { } - } - } else { - try { - getPlayer(objectId).browserURLChange(flexAppUrl); - } catch(e) { } - } - - currentObjectId = null; - }, - getUserAgent: function() { - return navigator.userAgent; - }, - getPlatform: function() { - return navigator.platform; - } - - } - -})(); - -// Initialization - -// Automated unit testing and other diagnostics - -function setURL(url) -{ - document.location.href = url; -} - -function backButton() -{ - history.back(); -} - -function forwardButton() -{ - history.forward(); -} - -function goForwardOrBackInHistory(step) -{ - history.go(step); -} - -//BrowserHistoryUtils.addEvent(window, "load", function() { BrowserHistory.initialize(); }); -(function(i) { - var u =navigator.userAgent;var e=/*@cc_on!@*/false; - var st = setTimeout; - if(/webkit/i.test(u)){ - st(function(){ - var dr=document.readyState; - if(dr=="loaded"||dr=="complete"){i()} - else{st(arguments.callee,10);}},10); - } else if((/mozilla/i.test(u)&&!/(compati)/.test(u)) || (/opera/i.test(u))){ - document.addEventListener("DOMContentLoaded",i,false); - } else if(e){ - (function(){ - var t=document.createElement('doc:rdy'); - try{t.doScroll('left'); - i();t=null; - }catch(e){st(arguments.callee,0);}})(); - } else{ - window.onload=i; - } -})( function() {BrowserHistory.initialize();} ); diff --git a/client/load_tool/html-template/history/historyFrame.html b/client/load_tool/html-template/history/historyFrame.html deleted file mode 100644 index 07e3806f..00000000 --- a/client/load_tool/html-template/history/historyFrame.html +++ /dev/null @@ -1,29 +0,0 @@ - - - - - - - - Hidden frame for Browser History support. - - diff --git a/client/load_tool/html-template/swfobject.js b/client/load_tool/html-template/swfobject.js deleted file mode 100644 index 839d82f3..00000000 --- a/client/load_tool/html-template/swfobject.js +++ /dev/null @@ -1,4 +0,0 @@ -/* SWFObject v2.2 beta1 - is released under the MIT License -*/ -var 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;Y0){for(var af=0;af0){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'}}aa.outerHTML='"+af+"";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 accounts.loginLogoff && value <= accounts.loginLogoff+accounts.loginAction){ - Logger.info("value > accounts.loginLogoff && value <= accounts.loginLogoff+accounts.loginAction"); - for each (var call:Call in flashAPI.calls){ - if (call.state == Call.STATE_RING && call.incoming){ - Logger.info("call.state == Call.STATE_RING && call.incoming "+call.id); - if (accounts.callsOfTalkState/2 > accounts.maxCountCall){ - Application.application.logs += username+" - execute hangup for callId "+call.id+"\n"; - call.hangup(); - }else if (accounts.callsOfTalkState/2 < accounts.minCountCall){ - Application.application.logs += username+" - execute ANSWER for callId "+call.id+"\n"; - call.answer(); - }else{ - value = PhoneConfig.getRandomInt(1,100); - if (value <= accounts.incomAnswer){ - Application.application.logs += username+" - execute ANSWER for callId "+call.id+"\n"; - call.answer(); - }else if (value > accounts.incomAnswer && value <= accounts.incomAnswer+accounts.incomHangup){ - Application.application.logs += username+" - execute hangup for callId "+call.id+"\n"; - call.hangup(); - } - } - } else if (call.state == Call.STATE_RING && !call.incoming){ - Logger.info("call.state == Call.STATE_RING && !call.incoming: "+call.id); - value = PhoneConfig.getRandomInt(1,100); - if (value <= accounts.callHangup){ - Application.application.logs += username+" - execute hangup for callId "+call.id+"\n"; - call.hangup(); - } - } else if (call.state == Call.STATE_TALK){ - Logger.info("call.state == Call.STATE_TALK: "+call.id); - if (call.timeOfCall > accounts.minTimeCall){ - value = PhoneConfig.getRandomInt(1,100); - if (value <= accounts.talkHangup){ - Application.application.logs += username+" - execute hangup for callId "+call.id+"\n"; - call.hangup(); - }else if (value > accounts.talkHangup && value <= accounts.talkHangup+accounts.talkHolding){ - Application.application.logs += username+" - execute HOLDING for callId "+call.id+"\n"; - call.setStatusHold(true); - }else if (value > accounts.talkHangup+accounts.talkHolding && value <= accounts.talkHangup+accounts.talkHolding + accounts.talkTransfer){ - transfer(call); - }else if (PhoneConfig.VIDEO_ENABLED){ - if (value >accounts.talkHangup+accounts.talkHolding + accounts.talkTransfer && value < accounts.talkHangup+accounts.talkHolding + accounts.talkTransfer + accounts.talkStopStartVideo ){ - if (call.isVideoCall){ - call.setSendVideo(false); - }else{ - call.setSendVideo(true); - } - } - } - } - } else if (call.state == Call.STATE_HOLD && call.iHolded){ - Logger.info("call.state == Call.STATE_HOLD && call.iHolded: "+call.id); - value = PhoneConfig.getRandomInt(1,100); - if (value <= accounts.holdingHangup){ - Application.application.logs += username+" - execute hangup for callId "+call.id+"\n"; - call.hangup(); - }else if (value > accounts.holdingHangup && value <= accounts.holdingHangup+accounts.holdingUnhold){ - Application.application.logs += username+" - execute UNHOLDING for callId "+call.id+"\n"; - call.setStatusHold(false); - } - } else if (call.state == Call.STATE_HOLD && !call.iHolded){ - Logger.info("call.state == Call.STATE_HOLD && !call.iHolded: "+call.id); - value = PhoneConfig.getRandomInt(1,100); - if (value <= accounts.holdedHangup){ - Application.application.logs += username+" - execute hangup for callId "+call.id+"\n"; - call.hangup(); - }else if (value > accounts.holdedHangup && value <= accounts.holdedHangup+accounts.holdedTransfer){ - transfer(call); - } - } - - } - if (flashAPI.calls.length == 0){ - callToUser(); - } - } - } - } - - /** - * Stop execute flashphoner api commands - **/ - public function stopTest():void{ - timer.removeEventListener(TimerEvent.TIMER,timerHandler); - timer.stop(); - timer = null; - if (flashAPI.modelLocator.logged){ - flashAPI.logoff(); - } - } - } - -} \ No newline at end of file diff --git a/client/load_tool/src/Accounts.as b/client/load_tool/src/Accounts.as deleted file mode 100644 index 496bebb5..00000000 --- a/client/load_tool/src/Accounts.as +++ /dev/null @@ -1,283 +0,0 @@ -package -{ - import com.flashphoner.Logger; - import com.flashphoner.api.Call; - import com.flashphoner.api.Flash_API; - import com.flashphoner.api.data.PhoneConfig; - - import flash.events.Event; - import flash.events.IOErrorEvent; - import flash.events.SecurityErrorEvent; - import flash.events.TimerEvent; - import flash.net.URLLoader; - import flash.net.URLRequest; - import flash.sampler.startSampling; - import flash.utils.Timer; - - import mx.collections.ArrayCollection; - import mx.controls.Alert; - import mx.core.Application; - - - [Binable] - /** - * Class loading all Accounts and stores the probabilities of events - **/ - public class Accounts - { - - public var accounts:ArrayCollection = new ArrayCollection(); - - public static var allUsernames:ArrayCollection = new ArrayCollection(); - - private static var accountsObj:Accounts; - private var from:int; - private var to:int; - private var timer:Timer; - - /** - * Minimum count of calls - **/ - public var minCountCall:int = 8; - /** - * Maximum count of calls - **/ - public var maxCountCall:int = 12; - /** - * Minimum time of call - **/ - public var minTimeCall:int = 120; - /** - * Probability login -> logoff - **/ - public var loginLogoff:int = 0; - /** - * Probability login -> any action - **/ - public var loginAction:int = 0; - - /** - * Probability incomming call -> hangup call - **/ - public var incomHangup:int = 0; - /** - * Probability incomming call -> answer - **/ - public var incomAnswer:int = 0; - /** - * Probability call to user -> hangup - **/ - public var callHangup:int = 0; - - /** - * Probability talk -> hangup - **/ - public var talkHangup:int = 0; - /** - * Probability talk -> hold - **/ - public var talkHolding:int = 0; - /** - * Probability talk -> stop start video - **/ - public var talkStopStartVideo = 0; - /** - * Probability talk -> tranfer call - **/ - public var talkTransfer:int = 0; - - /** - * Probability holding call -> hangup - **/ - public var holdingHangup:int = 0; - /** - * Probability holding -> unhold - **/ - public var holdingUnhold:int = 0; - - /** - * Probability holded -> hangup - **/ - public var holdedHangup:int = 0; - /** - * Probability holded -> transfer - **/ - public var holdedTransfer:int = 0; - - /** - * Allow call himself - **/ - public var callMe:Boolean = false; - /** - * Data of current statistic - **/ - public var statisticCollection:ArrayCollection = new ArrayCollection(); - /** - * Count of calls in Talk state - **/ - public var callsOfTalkState:int = 0; - - /** - * Update data of statistic by all accounts - **/ - public function updateStatistic():void{ - statisticCollection.removeAll(); - statisticCollection.addItem({state:"accounts",count:accounts.length}); - var countLogoff:int = 0; - var countLogin:int = 0; - var countIncom:int = 0; - var countCall:int = 0; - var countTalk:int = 0; - var countHolding:int = 0; - var countHolded:int = 0; - var countAllCalls:int = 0; - var sendingVideo = 0; - for each (var temp:* in accounts){ - var account:Account = Account(temp); - if(account.flashAPI.modelLocator.logged){ - countLogin++; - }else{ - countLogoff++; - } - for each (var call:Call in account.flashAPI.calls){ - countAllCalls++; - if (call.state == Call.STATE_RING && call.incoming){ - countIncom++; - } else if (call.state == Call.STATE_RING && !call.incoming){ - countCall++; - } else if (call.state == Call.STATE_TALK){ - if (call.isVideoCall){ - sendingVideo++; - } - countTalk++; - } else if (call.state ==Call.STATE_HOLD && call.iHolded){ - countHolding++; - } else if (call.state ==Call.STATE_HOLD && call.iHolded){ - countHolded++; - } - } - } - callsOfTalkState = countTalk; - statisticCollection.addItem({state:"logoff",count:countLogoff}); - statisticCollection.addItem({state:"login",count:countLogin}); - statisticCollection.addItem({state:"allCalls",count:countAllCalls}); - statisticCollection.addItem({state:"incom",count:countIncom}); - statisticCollection.addItem({state:"call",count:countCall}); - statisticCollection.addItem({state:"talk",count:countTalk}); - statisticCollection.addItem({state:"sending video",count:sendingVideo}); - statisticCollection.addItem({state:"holding",count:countHolding}); - statisticCollection.addItem({state:"holded",count:countHolded}); - } - /** - * Get object of singelton - **/ - public static function getInstance():Accounts{ - if (accountsObj == null){ - accountsObj = new Accounts(); - accountsObj.startTimer(); - } - - return accountsObj; - } - /** - * Initialize accounts from file - * @param from from number in file - * @param to to number in file - **/ - public function initAccounts(from:int, to:int):void{ - this.from = from; - this.to = to; - var loader:URLLoader = new URLLoader(); - var qwe:Object = Application.application.parameters; - var config:String = "general.xml"; - var request:URLRequest = new URLRequest(config); - loader.load(request); - loader.addEventListener(Event.COMPLETE, onComplete); - loader.addEventListener(SecurityErrorEvent.SECURITY_ERROR,seurityErrorHandler); - loader.addEventListener(IOErrorEvent.IO_ERROR,ioErrorHandler); - } - - private function seurityErrorHandler(event:SecurityErrorEvent):void{ - throw new Error(event.toString()); - } - - private function ioErrorHandler(event:IOErrorEvent):void{ - throw new Error(event.toString()); - } - - /** - * Handler on readed the data file - **/ - private function onComplete(event:Event):void - { - var loader:URLLoader = event.target as URLLoader; - if (loader != null) - { - var xml:XML = new XML(loader.data); - var from_A:int = int(xml.from); - var to_A:int = int(xml.to); - - for (var i:int = from_A; i <= to_A; i++){ - var temp:String = xml['account_'+i]; - var array:Array = temp.split(","); - Accounts.allUsernames.addItem(array[0]); - if (i >= from && i <= to){ - var account:Account = new Account(); - account.username = array[0]; - account.outboundProxy = array[1]; - account.port = array[2]; - account.password = array[3]; - Accounts.getInstance().accounts.addItem(account); - } - } - Application.application.accountsLoaded(); - } - else - { - Alert.show("Can not load xml settings. Default settings will be used.","",Alert.OK); - } - } - - /** - * Start load tool for all accounts - **/ - public function startTest():void{ - for each (var temp:* in accounts){ - var account:Account = temp as Account; - account.startTest(); - } - } - /** - * Stop load tool for all accounts - **/ - public function stopTest():void{ - for each (var temp:* in accounts){ - var account:Account = temp as Account; - account.stopTest(); - } - accounts = new ArrayCollection(); - allUsernames = new ArrayCollection(); - } - - /** - * Start timer for update statistics - **/ - public function startTimer():void{ - if (timer!=null){ - timer.removeEventListener(TimerEvent.TIMER,timerHandler); - timer.stop(); - timer = null; - } - timer = new Timer(500); - timer.addEventListener(TimerEvent.TIMER,timerHandler); - timer.start(); - } - /** - * Handler which execute update statistics - **/ - private function timerHandler(timeEvent:TimerEvent):void{ - updateStatistic(); - } - - } -} \ No newline at end of file diff --git a/client/load_tool/src/TestStabApplication.html b/client/load_tool/src/TestStabApplication.html deleted file mode 100644 index cdcd246f..00000000 --- a/client/load_tool/src/TestStabApplication.html +++ /dev/null @@ -1,41 +0,0 @@ - - - -Flash phone - - - - - -
      - - Get Adobe Flash player - -
      - - - - \ No newline at end of file diff --git a/client/load_tool/src/TestStabApplication.mxml b/client/load_tool/src/TestStabApplication.mxml deleted file mode 100644 index 17f67ce0..00000000 --- a/client/load_tool/src/TestStabApplication.mxml +++ /dev/null @@ -1,267 +0,0 @@ - - - - to){ - Alert.show("ERROR!!!","",Alert.OK); - return - } - try{ - var loginLogoff:int = int(textLoginLogoff.text); - var loginAction:int = int(textLoginAction.text); - - var incomHangup:int = int(textIncomHangup.text); - var incomAnswer:int = int(textIncomAnswer.text); - - var callHangup:int = int(textCallHangup.text); - - var talkHangup:int = int(textTalkHangup.text); - var talkHolding:int = int(textTalkHolding.text); - var talkTransfer:int = int(textTalkTransfer.text); - - var holdingHangup:int = int(textHoldingHangup.text); - var holdingUnhold:int = int(textHoldingUnhold.text); - - var holdedHangup:int = int(textHoldedHangup.text); - var holdedTransfer:int = int(textHoldedTransfer.text); - - var talkStopStartVideo = int(textTalkStopStartVideo.text); - }catch(error:Error){ - Alert.show("ERROR Weight!!!","",Alert.OK); - return; - } - if (loginLogoff+loginAction > 100){ - Alert.show("ERROR Free Weight!!!","",Alert.OK); - return; - } - if (incomHangup+incomAnswer > 100){ - Alert.show("ERROR Incom Weight!!!","",Alert.OK); - return; - } - if (callHangup > 100){ - Alert.show("ERROR Call Weight!!!","",Alert.OK); - return; - } - if (talkHangup + talkHolding + talkTransfer + talkStopStartVideo > 100){ - Alert.show("ERROR Talk Weight!!!","",Alert.OK); - return; - } - if (holdingHangup + holdingUnhold > 100){ - Alert.show("ERROR Holding Weight!!!","",Alert.OK); - return; - } - if (holdedHangup + holdedTransfer > 100){ - Alert.show("ERROR Holded Weight!!!","",Alert.OK); - return; - } - - var accounts:Accounts = Accounts.getInstance(); - - accounts.loginLogoff = loginLogoff; - accounts.loginAction = loginAction; - accounts.incomHangup = incomHangup; - accounts.incomAnswer = incomAnswer; - accounts.callHangup = callHangup; - accounts.talkHangup = talkHangup; - accounts.talkHolding= talkHolding; - accounts.talkTransfer= talkTransfer; - accounts.talkStopStartVideo = talkStopStartVideo; - - accounts.holdingHangup = holdingHangup; - accounts.holdingUnhold = holdingUnhold; - - accounts.holdedHangup = holdedHangup; - accounts.holdedTransfer = holdedTransfer; - - accounts.initAccounts(from,to); - buttonGetAccount.enabled = false; - textFrom.enabled = false; - textTo.enabled = false; - textLoginLogoff.enabled = false; - textLoginAction.enabled = false; - textIncomHangup.enabled = false; - textIncomAnswer.enabled = false; - textCallHangup.enabled = false; - - textTalkHangup.enabled = false; - textTalkHolding.enabled = false; - textTalkTransfer.enabled = false; - - textHoldingHangup.enabled = false; - textHoldingUnhold.enabled = false; - - textHoldedHangup.enabled = false; - textHoldedTransfer.enabled = false; - - checkBoxCallMe.enabled = false; - checkBoxEnableVideoCalls.enabled=false; - } - - private function onApplyParameters():void{ - try{ - var minCountCall:int = int(textMinCountCall.text); - var maxCountCall:int = int(textMaxCountCall.text); - var minTimeCall:int = int(textMinTimeCall.text); - }catch(error:Error){ - Alert.show("ERROR!!!","",Alert.OK); - return; - } - if (minCountCall > maxCountCall){ - Alert.show("ERROR!!!","",Alert.OK); - return - } - Accounts.getInstance().minCountCall = minCountCall; - Accounts.getInstance().maxCountCall = maxCountCall; - Accounts.getInstance().minTimeCall = minTimeCall; - } - - private function onStartTest():void{ - if (buttonStartTest.label == "Start"){ - Accounts.getInstance().startTest(); - buttonStartTest.label = "Stop"; - }else{ - Accounts.getInstance().stopTest(); - buttonStartTest.enabled = false; - buttonStartTest.label = "Start"; - buttonGetAccount.enabled = true; - textFrom.enabled = true; - textTo.enabled = true; - - textLoginLogoff.enabled = true; - textLoginAction.enabled = true; - - textIncomHangup.enabled = true; - textIncomAnswer.enabled = true; - - textCallHangup.enabled = true; - - textTalkHangup.enabled = true; - textTalkHolding.enabled = true; - textTalkTransfer.enabled = true; - - textHoldingHangup.enabled = true; - textHoldingUnhold.enabled = true; - - textHoldedHangup.enabled = true; - textHoldedTransfer.enabled = true; - - textTalkStopStartVideo.enabled=true; - checkBoxCallMe.enabled = true; - checkBoxEnableVideoCalls.enabled=true; - - } - } - - private function onChange():void{ - if (checkBoxCallMe.selected){ - Accounts.getInstance().callMe = true; - }else{ - Accounts.getInstance().callMe = false; - } - } - private function onChangeCheckBoxEnableVideoCalls():void{ - if (checkBoxEnableVideoCalls.selected){ - PhoneConfig.VIDEO_ENABLED=true; - } else{ - PhoneConfig.VIDEO_ENABLED=false; - } - } - - public function accountsLoaded():void{ - Application.application.logs += "Accounts loaded\n"; - buttonStartTest.enabled = true; - } - ]]> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/client/wcs_media_client/.idea/.name b/client/wcs_media_client/.idea/.name new file mode 100644 index 00000000..51db1bff --- /dev/null +++ b/client/wcs_media_client/.idea/.name @@ -0,0 +1 @@ +wcs_media_client \ No newline at end of file diff --git a/client/wcs_media_client/.idea/encodings.xml b/client/wcs_media_client/.idea/encodings.xml new file mode 100644 index 00000000..e206d70d --- /dev/null +++ b/client/wcs_media_client/.idea/encodings.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/client/wcs_media_client/.idea/misc.xml b/client/wcs_media_client/.idea/misc.xml new file mode 100644 index 00000000..1162f438 --- /dev/null +++ b/client/wcs_media_client/.idea/misc.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/client/wcs_media_client/.idea/modules.xml b/client/wcs_media_client/.idea/modules.xml new file mode 100644 index 00000000..7f8ada6a --- /dev/null +++ b/client/wcs_media_client/.idea/modules.xml @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/client/wcs_media_client/.idea/scopes/scope_settings.xml b/client/wcs_media_client/.idea/scopes/scope_settings.xml new file mode 100644 index 00000000..922003b8 --- /dev/null +++ b/client/wcs_media_client/.idea/scopes/scope_settings.xml @@ -0,0 +1,5 @@ + + + + \ No newline at end of file diff --git a/client/wcs_media_client/.idea/vcs.xml b/client/wcs_media_client/.idea/vcs.xml new file mode 100644 index 00000000..def6a6a1 --- /dev/null +++ b/client/wcs_media_client/.idea/vcs.xml @@ -0,0 +1,7 @@ + + + + + + + diff --git a/client/wcs_media_client/.idea/wcs_media_client.iml b/client/wcs_media_client/.idea/wcs_media_client.iml new file mode 100644 index 00000000..6b8184f8 --- /dev/null +++ b/client/wcs_media_client/.idea/wcs_media_client.iml @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/client/wcs_media_client/.idea/workspace.xml b/client/wcs_media_client/.idea/workspace.xml new file mode 100644 index 00000000..4e2579a2 --- /dev/null +++ b/client/wcs_media_client/.idea/workspace.xml @@ -0,0 +1,217 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 1397103062857 + 1397103062857 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/client/wcs_media_client/index.html b/client/wcs_media_client/index.html new file mode 100644 index 00000000..0809417e --- /dev/null +++ b/client/wcs_media_client/index.html @@ -0,0 +1,11 @@ + + + + WCS Media Client + + + + + + + \ No newline at end of file diff --git a/client/wcs_media_client/js/main.js b/client/wcs_media_client/js/main.js new file mode 100644 index 00000000..b13b1acd --- /dev/null +++ b/client/wcs_media_client/js/main.js @@ -0,0 +1,4 @@ +/** + * Created by nazar on 10.04.14. + */ + From 71441b613c2ffb15706ff996784fbd829134bfef Mon Sep 17 00:00:00 2001 From: Flashphoner Date: Thu, 10 Apr 2014 17:52:33 +1000 Subject: [PATCH 02/20] [ADD] Added simple connect/disconnect methods. --- client/wcs_media_client/.idea/workspace.xml | 222 +- client/wcs_media_client/css/styles.css | 44 + client/wcs_media_client/flashphoner.xml | 6 + client/wcs_media_client/index.html | 32 +- client/wcs_media_client/js/Adapter.js | 82 + client/wcs_media_client/js/Config.js | 46 + .../wcs_media_client/js/WebRtcMediaManager.js | 355 + .../wcs_media_client/js/WebSocketManager.js | 87 + .../js/jquery/jquery-1.11.0.js | 10337 ++++++++++++++ .../wcs_media_client/js/jquery/jquery-ui.js | 11737 ++++++++++++++++ .../wcs_media_client/js/jquery/jquery.json.js | 199 + .../js/jquery/jquery.websocket.js | 54 + client/wcs_media_client/js/main.js | 39 + 13 files changed, 23216 insertions(+), 24 deletions(-) create mode 100644 client/wcs_media_client/css/styles.css create mode 100644 client/wcs_media_client/flashphoner.xml create mode 100644 client/wcs_media_client/js/Adapter.js create mode 100644 client/wcs_media_client/js/Config.js create mode 100644 client/wcs_media_client/js/WebRtcMediaManager.js create mode 100644 client/wcs_media_client/js/WebSocketManager.js create mode 100644 client/wcs_media_client/js/jquery/jquery-1.11.0.js create mode 100644 client/wcs_media_client/js/jquery/jquery-ui.js create mode 100644 client/wcs_media_client/js/jquery/jquery.json.js create mode 100644 client/wcs_media_client/js/jquery/jquery.websocket.js diff --git a/client/wcs_media_client/.idea/workspace.xml b/client/wcs_media_client/.idea/workspace.xml index 4e2579a2..e6d59a6f 100644 --- a/client/wcs_media_client/.idea/workspace.xml +++ b/client/wcs_media_client/.idea/workspace.xml @@ -26,7 +26,43 @@ - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -43,7 +79,14 @@ @@ -79,7 +122,6 @@ - @@ -112,21 +154,53 @@ + + + + + + + + + + + + + + + + + + + + + - - -