diff --git a/.gitignore b/.gitignore index d38424211..68b3090a0 100644 --- a/.gitignore +++ b/.gitignore @@ -8,8 +8,13 @@ htdocs/tmp/* tmp/* logs/* conf/*.conf +conf/*apache-config conf/*.apache2-config htdocs/site_info.txt bin/wwapache2ctl webwork2.komodoproject #courses.dist/* +node_modules +node_modules/* +WeBWorK.sublime-project +WeBWorK.sublime-workspace diff --git a/.gitmodules b/.gitmodules index 1c418bb5a..8b1378917 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,3 +1 @@ -[submodule "htdocs/mathjax"] - path = htdocs/mathjax - url = https://github.com/mathjax/MathJax.git + diff --git a/VERSION b/VERSION index 628de6c59..31b0c8f2d 100644 --- a/VERSION +++ b/VERSION @@ -1,3 +1,4 @@ -$WW_VERSION ='2.5.1.3'; +$WW_VERSION ='development'; $WW_COPYRIGHT_YEARS = '1996-2013'; + 1; diff --git a/bin/OPL-update b/bin/OPL-update index b55f40619..dc5071b8e 100755 --- a/bin/OPL-update +++ b/bin/OPL-update @@ -26,6 +26,8 @@ use DBI; BEGIN { die "WEBWORK_ROOT not found in environment.\n" unless exists $ENV{WEBWORK_ROOT}; + # Unused variable, but define it to avoid an error message. + $WeBWorK::Constants::WEBWORK_DIRECTORY = ''; } ### Data for creating the database tables @@ -44,6 +46,8 @@ my %OPLtables = ( chapter => 'OPL_chapter', section => 'OPL_section', problem => 'OPL_problem', + morelt => 'OPL_morelt', + morelt_pgfile => 'OPL_morelt_pgfile', pgfile_problem => 'OPL_pgfile_problem', ); @@ -61,6 +65,8 @@ my %NPLtables = ( chapter => 'NPL-chapter', section => 'NPL-section', problem => 'NPL-problem', + morelt => 'NPL-morelt', + morelt_pgfile => 'NPL-morelt-pgfile', pgfile_problem => 'NPL-pgfile-problem', ); @@ -156,6 +162,7 @@ if($libraryVersion eq '2.5') { institution tinyblob, path_id int(15) NOT NULL, filename varchar(255) NOT NULL, + morelt_id int(15), PRIMARY KEY (pgfile_id) '], [$tables{keyword}, ' @@ -209,6 +216,19 @@ if($libraryVersion eq '2.5') { KEY (section_id), PRIMARY KEY (problem_id) '], +[$tables{morelt}, ' + morelt_id int(15) NOT NULL auto_increment, + name varchar(127) NOT NULL, + DBsection_id int(15), + leader int(15), # pgfile_id of the MLT leader + KEY (name), + PRIMARY KEY (morelt_id) +'], +[$tables{morelt_pgfile}, ' + morelt_id int(15) DEFAULT 0 NOT NULL, + pgfile_id int(15) DEFAULT 0 NOT NULL, + PRIMARY KEY (morelt_id, pgfile_id) +'], [$tables{pgfile_problem}, ' pgfile_id int(15) DEFAULT 0 NOT NULL, problem_id int(15) DEFAULT 0 NOT NULL, @@ -414,6 +434,7 @@ sub pgfiles { my $name = $File::Find::name; my ($subject, $chapter, $section, $date, $institution, $author, $text); my ($edition, $textauthor, $textsection, $textproblem, $tagged); + my ($morelt, $morelt_leader); %textinfo=(); my @textproblems = (-1); if ($name =~ /swf$/) { @@ -431,42 +452,54 @@ sub pgfiles { $tagged = 0; while () { SWITCH: { - if (/\bKEYWORDS\((.*)\)/i) { + if (/#.*\bKEYWORDS\((.*)\)/i) { @keyword = keywordcleaner($1); last SWITCH; } - if (/\bDBsubject\s*\(\s*'?(.*?)'?\s*\)/) { + if (/#.*\bDBsubject\s*\(\s*'?(.*?)'?\s*\)/) { $subject = $1; $subject =~ s/'/\'/g; last SWITCH; } - if (/\bDBchapter\s*\(\s*'?(.*?)'?\s*\)/) { + if (/#.*\bDBchapter\s*\(\s*'?(.*?)'?\s*\)/) { $chapter = $1; $chapter =~ s/'/\'/g; $tagged = 1; last SWITCH; } - if (/\bDBsection\s*\(\s*'?(.*?)'?\s*\)/) { + if (/#.*\bDBsection\s*\(\s*'?(.*?)'?\s*\)/) { $section = $1; $section =~ s/'/\'/g; last SWITCH; } - if (/\bDate\s*\(\s*'(.*?)'\s*\)/) { + if (/#.*\bDate\s*\(\s*'(.*?)'\s*\)/) { $date = $1; $date =~ s/'/\'/g; last SWITCH; } - if (/\bInstitution\s*\(\s*'(.*?)'\s*\)/) { + if (/#.*\bInstitution\s*\(\s*'(.*?)'\s*\)/) { $institution = $1; $institution =~ s/'/\'/g; last SWITCH; } - if (/\bAuthor\(\s*'?(.*?)'?\s*\)/) { + if (/#.*\bAuthor\(\s*'?(.*?)'?\s*\)/) { $author = $1; $author =~ s/'/\'/g; last SWITCH; } - if (/\bTitleText(\d+)\(\s*'?(.*?)'?\s*\)/) { + if (/#.*\bMLTleader\(\s*'?(.*?)'?\s*\)/) { + $morelt_leader = $1; + $morelt_leader =~ s/['"]//g; + $morelt_leader= ($morelt_leader =~ /\S/) ? 1 : 0; + last SWITCH; + } + if (/#.*\bMLT\(\s*'?(.*?)'?\s*\)/) { + $morelt = $1; + $morelt =~ s/'//g; + $morelt = lc($morelt); + last SWITCH; + } + if (/#.*\bTitleText(\d+)\(\s*'?(.*?)'?\s*\)/) { $textno = $1; $text = $2; $text =~ s/'/\'/g; @@ -476,7 +509,7 @@ sub pgfiles { } last SWITCH; } - if (/\bEditionText(\d+)\(\s*'?(.*?)'?\s*\)/) { + if (/#.*\bEditionText(\d+)\(\s*'?(.*?)'?\s*\)/) { $textno = $1; $edition = $2; $edition =~ s/'/\'/g; @@ -486,7 +519,7 @@ sub pgfiles { } last SWITCH; } - if (/\bAuthorText(\d+)\(\s*'?(.*?)'?\s*\)/) { + if (/#.*\bAuthorText(\d+)\(\s*'?(.*?)'?\s*\)/) { $textno = $1; $textauthor = $2; $textauthor =~ s/'/\'/g; @@ -496,7 +529,7 @@ sub pgfiles { } last SWITCH; } - if (/\bSection(\d+)\(\s*'?(.*?)'?\s*\)/) { + if (/#.*\bSection(\d+)\(\s*'?(.*?)'?\s*\)/) { $textno = $1; $textsection = $2; $textsection =~ s/'/\'/g; @@ -513,7 +546,7 @@ sub pgfiles { } last SWITCH; } - if (/\bProblem(\d+)\(\s*(.*?)\s*\)/) { + if (/#.*\bProblem(\d+)\(\s*(.*?)\s*\)/) { $textno = $1; $textproblem = $2; $textproblem =~ s/\D/ /g; @@ -537,6 +570,7 @@ sub pgfiles { # # kludge to fix the omission of a subject field unless($subject) { +print "NO SUBJECT $name\n"; if ($text =~ /precalculus/i) { $subject = "Precalculus"; } elsif ($text =~ /calculus/i) { @@ -570,6 +604,10 @@ sub pgfiles { # in that file. # + # Fill in missing data with Misc. instead of blank + $chapter = 'Misc.' unless $chapter =~ /\S/; + $section = 'Misc.' unless $section =~ /\S/; + #selectrow_array returns first field of first row in scalar context or undef # undef for failure also, $dbh->{RaiseError} = 1 should catch that case. # @@ -672,13 +710,47 @@ sub pgfiles { \"$author_id\", \"$institution\", \"$path_id\", - \"$pgfile\" + \"$pgfile\", + \"\" # morelt_id filled in below )" ); dbug "INSERT INTO pgfile VALUES( \"\", \"$DBsection_id\", \"$author_id\", \"$institution\", \"$path_id\", \"$pgfile\", \"\" )\n"; $query = "SELECT pgfile_id FROM `$tables{pgfile}` WHERE filename = \"$pgfile\" and path_id=$path_id"; $pgfile_id = $dbh->selectrow_array($query); + # morelt table, and morelt_pgfile many-many table + if($morelt) { + $query = "SELECT morelt_id FROM `$tables{morelt}` WHERE name = \"$morelt\""; + $morelt_id = $dbh->selectrow_array($query); + if (!defined($morelt_id)) { + $dbh->do("INSERT INTO `$tables{morelt}` + VALUES( + \"\", + \"$morelt\", + \"$DBsection_id\", + \"\" + )"); + dbug "INSERT INTO morelt VALUES( \"\", \"$morelt\", \"$pgfile_id\" )\n"; + } + $morelt_id = $dbh->selectrow_array($query); + $dbh->do("UPDATE `$tables{pgfile}` SET + morelt_id = \"$morelt_id\" + WHERE pgfile_id = \"$pgfile_id\" " + ); + dbug "UPDATE pgfile morelt_id for $pgfile_id to $morelt_id\n"; + if($morelt_leader) { + $dbh->do("UPDATE `$tables{morelt}` SET + leader = \"$pgfile_id\" + WHERE morelt_id = \"$morelt_id\" " + ); + dbug "UPDATE morelt leader for $morelt_id to $pgfile_id\n"; + } + $dbh->do("INSERT INTO `$tables{morelt_pgfile}` + VALUES(\"$morelt_id\", \"$pgfile_id\")"); + dbug "INSERT INTO `$tables{morelt_pgfile}` + VALUES($morelt_id, $pgfile_id)"; + } + # keyword table, and problem_keyword many-many table # foreach my $keyword (@keyword) { diff --git a/conf/database.conf.dist b/conf/database.conf.dist index 3e36baeba..72ba0327b 100644 --- a/conf/database.conf.dist +++ b/conf/database.conf.dist @@ -286,7 +286,8 @@ $dbLayouts{sql_single} = { source => $database_dsn, params => { %sqlParams, tableOverride => "${courseName}_achievement" - + }, + }, past_answer => { record => "WeBWorK::DB::Record::PastAnswer", schema => "WeBWorK::DB::Schema::NewSQL::Std", @@ -297,7 +298,6 @@ $dbLayouts{sql_single} = { }, }, - achievement_user => { record => "WeBWorK::DB::Record::UserAchievement", schema => "WeBWorK::DB::Schema::NewSQL::Std", diff --git a/conf/defaults.config b/conf/defaults.config index 3afe7dcac..9756d46df 100644 --- a/conf/defaults.config +++ b/conf/defaults.config @@ -472,14 +472,22 @@ my $achievementTablesExist = (defined ($dbLayouts{$dbLayoutName}{global_user_ach ################################################################################ # Problem library options ################################################################################ +# +# The problemLibrary configuration data should now be set in localOverrides.conf # For configuration instructions, see: # http://webwork.maa.org/wiki/National_Problem_Library -# Set the location of the library in site.conf -# These values usually do not need to be edited. - -# Problem Library version (currently version 2). -$problemLibrary{version} = "2"; +# The directory containing the natinal problem library files. +# Set the root to "" if no problem +# library is installed. Use version 2.0 for the NPL and use the version 2.5 for the OPL. +# When changing from the NPL to the OPL it is important to change the version number +# because the names of the tables in the database have changed. + +#RE-CONFIGURE problemLibrary values in localOverrides.conf +################################################# +$problemLibrary{root} ="/opt/webwork/libraries/webwork-open-problem-library/OpenProblemLibrary"; +$problemLibrary{version} ="2.0"; # 2.0 for NPL, 2.5 for OPL +########################################################### # Problem Library SQL database connection information $problemLibrary_db = { @@ -623,6 +631,7 @@ $authen{proctor_module} = "WeBWorK::Authen::Proctor"; edit_achievements => "professor", create_and_delete_courses => "professor", fix_course_databases => "professor", + modify_tags => undef, ##### Behavior of the interactive problem processor ##### @@ -1314,4 +1323,5 @@ A value such as 0.1 means 0.1 percent error is allowed.", include("conf/localOverrides.conf"); + 1; #final line of the file to reassure perl that it was read properly. diff --git a/conf/localOverrides.conf.dist b/conf/localOverrides.conf.dist index e3ae1f642..980500a4c 100644 --- a/conf/localOverrides.conf.dist +++ b/conf/localOverrides.conf.dist @@ -90,15 +90,20 @@ $webworkFiles{screenSnippets}{setHeader} = "$webworkDirs{conf}/snippets/ ################################################################################ -# National Problem Library +# National Problem Library / Open Problem Library ################################################################################ # For configuration instructions, see: # http://webwork.maa.org/wiki/National_Problem_Library -# The directory containing the natinal problem library files. Set to "" if no problem -# library is installed. -$problemLibrary{root} ="/opt/webwork/libraries/NationalProblemLibrary"; +# The directory containing the natinal problem library files. +# Set the root to "" if no problem +# library is installed. Use version 2.0 for the NPL and use the version 2.5 for the OPL. +# When changing from the NPL to the OPL it is important to change the version number +* because the names of the tables in the database have changed. + +$problemLibrary{root} ="/opt/webwork/libraries/webwork-open-problem-library/OpenProblemLibrary"; +$problemLibrary{version} ="2.5"; # Additional library buttons can be added to the Library Browser (SetMaker.pm) # by adding the libraries you want to the following line. For each key=>value @@ -152,9 +157,14 @@ $courseFiles{problibs} = { # $permissionLevels{login} = "guest"; + # The above code would give the permission to login to any user with permission # level guest or higher. +$permissionLevels{dont_log_past_answers} = undef; +#$permissionLevels{record_set_version_answers_when_acting_as_student} = "professor"; +#$permissionLevels{record_answers_when_acting_as_student} = "professor"; + ################################################################################ # PG subsystem options ################################################################################ @@ -246,6 +256,7 @@ $problemDefaults{max_attempts} = -1; homeworkseteditor1 => 1, # homeworkseteditor2 => 1, # +# librarybrowsernojs => 1, librarybrowser1 => 1, # librarybrowser2 => 1, # librarybrowser3 => 1, @@ -253,8 +264,10 @@ $problemDefaults{max_attempts} = -1; pgproblemeditor1 => 1, # pgproblemeditor2 => 1, # pgproblemeditor3 => 1, + ); + ################################################################################ # Directory for temporary files ################################################################################ diff --git a/conf/site.conf.dist b/conf/site.conf.dist index a9c4dfada..2b8b233d0 100644 --- a/conf/site.conf.dist +++ b/conf/site.conf.dist @@ -189,18 +189,26 @@ $mail{smtpSender} = ''; # e.g. 'webwork@yourserver.yourschool.edu' # Seconds to wait before timing out when connecting to the SMTP server. $mail{smtpTimeout} = 30; + ################################################################################ # Problem library options ################################################################################ +# +# The problemLibrary configuration data should now be set in localOverrides.conf # For configuration instructions, see: # http://webwork.maa.org/wiki/National_Problem_Library -# The directory containing the WeBWorK Open Problem Library (OPL) files - typically -# /opt/webwork/libraries/webwork-open-problem-library/OpenProblemLibrary -# or for the older National Problem Library (NPL) -# /opt/webwork/libraries/NationalProblemLibrary -# Set to "" if no problem library is installed. -$problemLibrary{root} = ""; +# The directory containing the natinal problem library files. +# Set the root to "" if no problem +# library is installed. Use version 2.0 for the NPL and use the version 2.5 for the OPL. +# When changing from the NPL to the OPL it is important to change the version number +# because the names of the tables in the database have changed. + +#CONFIGURE problemLibrary values in this file. These settings override defaults in default.config +################################################# +$problemLibrary{root} ="/opt/webwork/libraries/webwork-open-problem-library/OpenProblemLibrary"; +$problemLibrary{version} ="2.0"; # 2.0 for NPL, 2.5 for OPL +########################################################### ################################################################################ #Time Zone diff --git a/courses.dist/modelCourse/templates/achievements/TestCourse_achievements.axp b/courses.dist/modelCourse/templates/achievements/TestCourse_achievements.axp deleted file mode 100644 index af4b4c3da..000000000 --- a/courses.dist/modelCourse/templates/achievements/TestCourse_achievements.axp +++ /dev/null @@ -1,62 +0,0 @@ -01_night_owl, Night Owl, secret, Finish a homework set between 12PM and 2AM., 10, , night_owl.at, night_owl.png, -02_crack_o_dawn, Crack O' Dawn, secret, Finish a homework set between 5AM and 7AM., 10, , crack_o_dawn.at, crack_o_dawn.png, -03_on_the_hour, Watching the Clock, secret, Finish a problem at the top of the hour., 10, , on_the_hour.at, on_the_hour.png, -04_last_minute, Last Minute Math, secret, Complete a homework within 30 minutes of the due date., 10, , last_minute.at, last_minute.png, -05_still_not_right, Its Still Not Right, secret, Input the exact same (incorrect) answer 10 times in a row., 5, , still_not_right.at, still_not_right.png, -06_persistance, Persistence is not Futile, secret, Solve a problem after 20 incorrect submissions., 10, , persistance.at, persistance.png, -07_super_persistance, Green Never Looked So Good, secret, Solve a problem after 100 incorrect submissions., 10, , super_persistance.at, super_persistance.png, -08_super_speed_math, Careful Planning and Quick Fingers, secret, Spend less than 10 minutes entering answers to a homework set., 20, , super_speed_math.at, super_speed_math.png, -09_hows_your_finger, Hows Your Finger?, secret, Have more than 250 submissions on a homework problem. , 10, , hows_your_finger.at, hows_your_finger.png, -01_one_click, One Click Is All I Need, 01_one_timer, Earn 100% on a problem in one attempt., 10, , one_click.at, one_click.png, -02_on_one_hand, On One Hand, 01_one_timer, Finish a homework set with less than 5 incorrect submissions., 10, , on_one_hand.at, on_one_hand.png, -03_seeing_green, Seeing Green, 01_one_timer, Finish a homework set with no incorrect submissions., 20, , seeing_green.at, seeing_green.png, -04_early_bird, The Early Bird, 01_one_timer, Finish a homework set within 24 hours of it opening., 10, , early_bird.at, early_bird.png, -05_really_early_bird, The Really Early Bird, 01_one_timer, Finish a homework set within 2 hours of it opening., 20, , really_early_bird.at, really_early_bird.png, -06_back_for_more, Back For More, 01_one_timer, Retry a problem after a 8 hour break., 10, , back_for_more.at, back_for_more.png, -07_chipping_away, Just Keep Chipping Away, 01_one_timer, Work on a single homework set over the course of 48 hours., 10, , chipping_away.at, chipping_away.png, -08_speed_mather, Go Speed Math-er, 01_one_timer, Spend less than 1 hour working on a homework set., 10, , speed_mather.at, speed_mather.png, -09_three_in_a_row, Three in a Row, 01_one_timer, Complete 3 problems in a row with no incorrect answers., 10, 3, three_in_a_row.at, one_click.png, -10_on_fire, Your on Fire!, 01_one_timer, Complete 10 problems in a row with no incorrect answers., 20, 10, on_fire.at, on_fire.png, -01_reaching_a_limit, Reaching a Limit, 02_content, Solve 10 basic limit problems., 10, 10, reaching_a_limit.at, reaching_a_limit.png, -02_by_definition, By Definition, 02_content, Evaluate a derivative using the limit definition., 10, , by_definition.at, by_definition.png, -03_derivative_master, Derivative Master, 02_content, Solve 30 basic derivatives., 20, 30, derivative_master.at, derivative_master.png, -04_optimizer_prime, Optimizer Prime, 02_content, Solve a particularly hard optimization problem., 10, , optimizer_prime.at, optimizer_prime.png, -05_its_all_relative, Its All Relative, 02_content, Solve a particularly hard related rates problem., 10, , its_all_relative.at, its_all_relative.png, -06_pattern_recognition, Pattern Recognition, 02_content, Find the nth derivative of a function., 10, , pattern_recognition.at, pattern_recognition.png, -07_the_lhopital, Take me to the L'Hopital, 02_content, Use L'Hopital's Rule to evaluate a limit., 10, , the_lhopital.at, the_lhopital.png, -08_the_fundamentals, Covering the Fundamentals, 02_content, Use the Fundamental Theorem of Calculus., 10, , the_fundamentals.at, the_fundamentals.png, -09_curvy_geometry, Curvy Geometry, 02_content, Find the area between two curves., 10, , curvy_geometry.at, curvy_geometry.png, -10_doing_it_backwards, Doing It Backwards, 02_content, Solve 5 u-substitution problems., 10, 5, doing_it_backwards.at, doing_it_backwards.png, -01_complete_one_set, One Set Wonder, 03_complete_sets, Get 100% on one homework set., 10, , complete_one_set.at, complete_one_set.png, -02_complete_five_sets, High Five, 03_complete_sets, Get 100% on five homework sets., 10, 5, complete_five_sets.at, complete_five_sets.png, -03_complete_ten_sets, One For Each Finger, 03_complete_sets, Get 100% on ten homework sets., 10, 10, complete_ten_sets.at, complete_ten_sets.png, -04_complete_twenty_sets, Mathbox Twenty, 03_complete_sets, Get 100% on twenty homework sets., 20, 20, complete_twenty_sets.at, complete_twenty_sets.png, -05_complete_thirty_sets, The Long Road, 03_complete_sets, Get 100% on thirty homework sets., 20, 30, complete_thirty_sets.at, complete_thirty_sets.png, -06_complete_all_sets, Perfection, 03_complete_sets, Get 100% on all homework sets., 30, 35, complete_all_sets.at, complete_all_sets.png, -01_challenge_one, Challenge One Complete, 04_challenge, Finish the first challenge problem., 10, , challenge_one.at, challenge_one.png, -02_challenge_two, Challenge Two Complete, 04_challenge, Finish the second challenge problem., 10, , challenge_two.at, challenge_two.png, -03_challenge_three, Challenge Three Complete, 04_challenge, Finish the third challenge problem., 10, , challenge_three.at, challenge_three.png, -04_challenge_four, Challenge Four Complete, 04_challenge, Finish the fourth challenge problem., 10, , challenge_four.at, challenge_four.png, -05_challenge_five, Challenge Five Complete, 04_challenge, Finish the fifth challenge problem., 10, , challenge_five.at, challenge_five.png, -06_challenge_six, Challenge Six Complete, 04_challenge, Finish the sixth challenge problem., 10, , challenge_six.at, challenge_six.png, -07_challenge_seven, Challenge Seven Complete, 04_challenge, Finish the seventh challenge problem., 10, , challenge_seven.at, challenge_seven.png, -08_challenge_eight, Challenge Eight Complete, 04_challenge, Finish the eighth challenge problem., 10, , challenge_eight.at, challenge_eight.png, -09_challenge_nine, Challenge Nine Complete, 04_challenge, Finish the ninth challenge problem., 10, , challenge_nine.at, challenge_nine.png, -10_challenge_ten, Challenge Ten Complete, 04_challenge, Finish the tenth challenge problem., 10, , challenge_ten.at, challenge_ten.png, -11_challenger, Challenger, 04_challenge, Finish all of the challenge problems., 10, 20, challenger.at, challenger.png, -01_complete_one_problem, The First Step, 05_complete_problems, Earn 100% on a homework problem., 10, , complete_one_problem.at, complete_one_problem.png, -02_complete_10_problems, Perfect 10, 05_complete_problems, Earn 100% on 10 homework problems., 10, 10, complete_10_problems.at, complete_10_problems.png, -03_complete_25_problems, Twenty-Five Questions, 05_complete_problems, Earn 100% on 25 homework problems., 10, 25, complete_25_problems.at, complete_25_problems.png, -04_complete_50_problems, 50 Ways to Solve a Math Problem, 05_complete_problems, Earn 100% on 50 homework problems., 10, 50, complete_50_problems.at, complete_50_problems.png, -05_complete_100_problems, Seeing Benjamins, 05_complete_problems, Earn 100% on 100 homework problems., 20, 100, complete_100_problems.at, complete_100_problems.png, -06_complete_150_problems, Sesqui-Centeni-Problems, 05_complete_problems, Earn 100% on 150 homework problems., 20, 150, complete_150_problems.at, complete_150_problems.png, -01_level_one, Level 1 Calculus Initiate, level, , , , level_one.at, level_one.png, -02_level_two, Level 2 Calculus Novice, level, , , , level_two.at, level_two.png, -03_level_three, Level 3 Calculus Apprentice, level, , , , level_three.at, level_three.png, -04_level_four, Level 4 Calculus Journeyman, level, , , , level_four.at, level_four.png, -05_level_five, Level 5 Calculus Fellowcraft, level, , , , level_five.at, level_five.png, -06_level_six, Level 6 Calculus Adept, level, , , , level_six.at, level_six.png, -07_level_seven, Level 7 Calculus Craftsman, level, , , , level_seven.at, level_seven.png, -08_level_eight, Level 8 Calculus Artesian, level, , , , level_eight.at, level_eight.png, -09_level_nine, Level 9 Calculus Specialist, level, , , , level_nine.at, level_nine.png, -10_level_ten, Level 10 Calculus Professor, level, , , , level_ten.at, level_ten.png, diff --git a/courses.dist/modelCourse/templates/achievements/add_anything.at b/courses.dist/modelCourse/templates/achievements/add_anything.at deleted file mode 100644 index e637e74ca..000000000 --- a/courses.dist/modelCourse/templates/achievements/add_anything.at +++ /dev/null @@ -1,84 +0,0 @@ -#This problem checks to see if a particular problem from a list of valid -# sets and problems has been solved. (You would edit this file to say which -# sets and problems count.) - -#constants -my %validproblems = ( - 'SetNameHere' => { #now you show which problems are valid like: - '2' => 1, - '1' => 1, }, #and put more sets here - ); - -#check and see if this problem was solved -if ($validproblems{$problem->set_id} && - $validproblems{$problem->set_id}{$problem->problem_id} && - $problem->status == 1 && - $problem->num_correct == 1) { - return 1; - } - - return 0; - - -# -You have access to a variety of variables: -# - $problem : the problem data (changes to this variable will not be saved!) -# This variable contains the problem data. It is a hash pointer with the -# following values (not all values shown) -# - $problem->status : the score of the current problem -# - $problem->problem_id : the id of the current problem -# - $problem->set_id : the id of the set containing the problem -# - $problem->num_correct : the number of correct attempts -# - $problem->num_incorrect : the number of incorrect attempts -# - $problem->last_answer : the last answer submitted -# - $problem->max_attempts : the maximum number of allowed attempts -# -# - $set : the set data (changes to this variable will not be saved!) -# This variable contains the set data. it is a hash pointer with the -# following values. (not all values shown) -# - $set->open_date : when the set was open -# - $set->due_date : when the set is due -# -# - @setProblems : the problem data for all the problems from this set. -# (changes to this variable will not be saved!) -# This is an array of problem hashes. Each element of the array has the -# save hash keys as the $problem variable above -# -# - $counter : the users counter associated to this achievement -# (changes to this variable *will* be saved!) -# If this achievement has a counter associated to it (i.e. solve 20 problems) -# then this is where you store the students counter for this achievement. -# This variable will initally start as '' -# -# - $maxCounter : the goal for the $counter variable for this achievement -# (changes to this variable will not be saved!) -# If this achievement has a counter associated to it then this variable -# contains the goal for the counter. Your achievement should return 1 -# when $counter >= $maxCounter. These two variables are used to show a -# progress bar for the achievement. -# -# - $localData : this is a hash which stores data for this user and achievement -# (changes to this variable *will* be saved!) -# This hash will persist from evaluation to evaluation. You can store whatever -# you like in here and it can be accessed next time this evaluator is run. -# Two things to keep in mind. The data in this hash will *not* be accessable -# by other achievements. If you plan to store something in this hash you have -# to write code to initialize the data. -# -# - $globalData : this is a hash which stores data for all achievements -# (changes to this variable *will* be saved!) -# This hash will persist from evaluation to evaluation and, like $localData, -# you can store whatever you like in here. This data will be accessable from -# *every* achievement and is unique to the user. Like $localData, you need to -# initialize any variable you plan on using in this hash. There are two -# variables stored in this hash that are maintained by the system. -# - $globalData->{completeSets} : This is the number of sets which the student -# has earned 100% on -# - $globalData->{completeProblems} : This is the number of problems which the -# student has earned 100% on -# Warning: The achievements are always evaluated in the order they are listed -# on the Instructors achievement editor page. To make matters more -# complicated, achievements which have already been earned are not evaluated -# at all. The up-shot of this is that when modifying variables in -# $globalData you need to either write your code so it doesnt matter which -# order the evaluators are run in, or you need to pay very close attention -# to which evaluators are run and when. diff --git a/courses.dist/modelCourse/templates/achievements/back_for_more.at b/courses.dist/modelCourse/templates/achievements/back_for_more.at deleted file mode 100644 index 44bd66b4c..000000000 --- a/courses.dist/modelCourse/templates/achievements/back_for_more.at +++ /dev/null @@ -1,84 +0,0 @@ -#This checks to see if the student has worked on one problem after -# an eight hour break - -# initialize the time thing - -$localData->{lastattempttime} = time() unless $localData->{lastattempttime}; - -# check to see if problem was already previously finished, or if they started -# a different problem -# or if the time interval isn't long enough. -if ($problem->num_correct > 1 || - $problem->set_id ne $localData->{lastset} || - $problem->problem_id ne $localData->{lastproblem} || - abs($localData->{lastattempttime} - time()) < 28800 ){ - $localData->{lastattempttime} = time(); - $localData->{lastset} = $problem->set_id; - $localData->{lastproblem} = $problem->problem_id; - return 0; -} else { - return 1; -} - -# -You have access to a variety of variables: -# - $problem : the problem data (changes to this variable will not be saved!) -# This variable contains the problem data. It is a hash pointer with the -# following values (not all values shown) -# - $problem->status : the score of the current problem -# - $problem->problem_id : the id of the current problem -# - $problem->set_id : the id of the set containing the problem -# - $problem->num_correct : the number of correct attempts -# - $problem->num_incorrect : the number of incorrect attempts -# - $problem->last_answer : the last answer submitted -# - $problem->max_attempts : the maximum number of allowed attempts -# -# - $set : the set data (changes to this variable will not be saved!) -# This variable contains the set data. it is a hash pointer with the -# following values. (not all values shown) -# - $set->open_date : when the set was open -# - $set->due_date : when the set is due -# -# - @setProblems : the problem data for all the problems from this set. -# (changes to this variable will not be saved!) -# This is an array of problem hashes. Each element of the array has the -# save hash keys as the $problem variable above -# -# - $counter : the users counter associated to this achievement -# (changes to this variable *will* be saved!) -# If this achievement has a counter associated to it (i.e. solve 20 problems) -# then this is where you store the students counter for this achievement. -# This variable will initally start as '' -# -# - $maxCounter : the goal for the $counter variable for this achievement -# (changes to this variable will not be saved!) -# If this achievement has a counter associated to it then this variable -# contains the goal for the counter. Your achievement should return 1 -# when $counter >= $maxCounter. These two variables are used to show a -# progress bar for the achievement. -# -# - $localData : this is a hash which stores data for this user and achievement -# (changes to this variable *will* be saved!) -# This hash will persist from evaluation to evaluation. You can store whatever -# you like in here and it can be accessed next time this evaluator is run. -# Two things to keep in mind. The data in this hash will *not* be accessable -# by other achievements. If you plan to store something in this hash you have -# to write code to initialize the data. -# -# - $globalData : this is a hash which stores data for all achievements -# (changes to this variable *will* be saved!) -# This hash will persist from evaluation to evaluation and, like $localData, -# you can store whatever you like in here. This data will be accessable from -# *every* achievement and is unique to the user. Like $localData, you need to -# initialize any variable you plan on using in this hash. There are two -# variables stored in this hash that are maintained by the system. -# - $globalData->{completeSets} : This is the number of sets which the student -# has earned 100% on -# - $globalData->{completeProblems} : This is the number of problems which the -# student has earned 100% on -# Warning: The achievements are always evaluated in the order they are listed -# on the Instructors achievement editor page. To make matters more -# complicated, achievements which have already been earned are not evaluated -# at all. The up-shot of this is that when modifying variables in -# $globalData you need to either write your code so it doesnt matter which -# order the evaluators are run in, or you need to pay very close attention -# to which evaluators are run and when. \ No newline at end of file diff --git a/courses.dist/modelCourse/templates/achievements/by_definition.at b/courses.dist/modelCourse/templates/achievements/by_definition.at deleted file mode 100644 index e637e74ca..000000000 --- a/courses.dist/modelCourse/templates/achievements/by_definition.at +++ /dev/null @@ -1,84 +0,0 @@ -#This problem checks to see if a particular problem from a list of valid -# sets and problems has been solved. (You would edit this file to say which -# sets and problems count.) - -#constants -my %validproblems = ( - 'SetNameHere' => { #now you show which problems are valid like: - '2' => 1, - '1' => 1, }, #and put more sets here - ); - -#check and see if this problem was solved -if ($validproblems{$problem->set_id} && - $validproblems{$problem->set_id}{$problem->problem_id} && - $problem->status == 1 && - $problem->num_correct == 1) { - return 1; - } - - return 0; - - -# -You have access to a variety of variables: -# - $problem : the problem data (changes to this variable will not be saved!) -# This variable contains the problem data. It is a hash pointer with the -# following values (not all values shown) -# - $problem->status : the score of the current problem -# - $problem->problem_id : the id of the current problem -# - $problem->set_id : the id of the set containing the problem -# - $problem->num_correct : the number of correct attempts -# - $problem->num_incorrect : the number of incorrect attempts -# - $problem->last_answer : the last answer submitted -# - $problem->max_attempts : the maximum number of allowed attempts -# -# - $set : the set data (changes to this variable will not be saved!) -# This variable contains the set data. it is a hash pointer with the -# following values. (not all values shown) -# - $set->open_date : when the set was open -# - $set->due_date : when the set is due -# -# - @setProblems : the problem data for all the problems from this set. -# (changes to this variable will not be saved!) -# This is an array of problem hashes. Each element of the array has the -# save hash keys as the $problem variable above -# -# - $counter : the users counter associated to this achievement -# (changes to this variable *will* be saved!) -# If this achievement has a counter associated to it (i.e. solve 20 problems) -# then this is where you store the students counter for this achievement. -# This variable will initally start as '' -# -# - $maxCounter : the goal for the $counter variable for this achievement -# (changes to this variable will not be saved!) -# If this achievement has a counter associated to it then this variable -# contains the goal for the counter. Your achievement should return 1 -# when $counter >= $maxCounter. These two variables are used to show a -# progress bar for the achievement. -# -# - $localData : this is a hash which stores data for this user and achievement -# (changes to this variable *will* be saved!) -# This hash will persist from evaluation to evaluation. You can store whatever -# you like in here and it can be accessed next time this evaluator is run. -# Two things to keep in mind. The data in this hash will *not* be accessable -# by other achievements. If you plan to store something in this hash you have -# to write code to initialize the data. -# -# - $globalData : this is a hash which stores data for all achievements -# (changes to this variable *will* be saved!) -# This hash will persist from evaluation to evaluation and, like $localData, -# you can store whatever you like in here. This data will be accessable from -# *every* achievement and is unique to the user. Like $localData, you need to -# initialize any variable you plan on using in this hash. There are two -# variables stored in this hash that are maintained by the system. -# - $globalData->{completeSets} : This is the number of sets which the student -# has earned 100% on -# - $globalData->{completeProblems} : This is the number of problems which the -# student has earned 100% on -# Warning: The achievements are always evaluated in the order they are listed -# on the Instructors achievement editor page. To make matters more -# complicated, achievements which have already been earned are not evaluated -# at all. The up-shot of this is that when modifying variables in -# $globalData you need to either write your code so it doesnt matter which -# order the evaluators are run in, or you need to pay very close attention -# to which evaluators are run and when. diff --git a/courses.dist/modelCourse/templates/achievements/challenge_eight.at b/courses.dist/modelCourse/templates/achievements/challenge_eight.at deleted file mode 100644 index df90fb557..000000000 --- a/courses.dist/modelCourse/templates/achievements/challenge_eight.at +++ /dev/null @@ -1,84 +0,0 @@ -#This evaluator checks to see if a particular problem of a particular set has -# been solved - -#constants -my %validproblems = ( - 'Challenge' => { - '8' => 1, } - ); - -#check and see if this problem was solved -if ($validproblems{$problem->set_id} && - $validproblems{$problem->set_id}{$problem->problem_id} && - $problem->status == 1 && - $problem->num_correct == 1) { - #update challenger counter - $globalData->{challengerCounter}++; - return 1; - } - - return 0; - - -# -You have access to a variety of variables: -# - $problem : the problem data (changes to this variable will not be saved!) -# This variable contains the problem data. It is a hash pointer with the -# following values (not all values shown) -# - $problem->status : the score of the current problem -# - $problem->problem_id : the id of the current problem -# - $problem->set_id : the id of the set containing the problem -# - $problem->num_correct : the number of correct attempts -# - $problem->num_incorrect : the number of incorrect attempts -# - $problem->last_answer : the last answer submitted -# - $problem->max_attempts : the maximum number of allowed attempts -# -# - $set : the set data (changes to this variable will not be saved!) -# This variable contains the set data. it is a hash pointer with the -# following values. (not all values shown) -# - $set->open_date : when the set was open -# - $set->due_date : when the set is due -# -# - @setProblems : the problem data for all the problems from this set. -# (changes to this variable will not be saved!) -# This is an array of problem hashes. Each element of the array has the -# save hash keys as the $problem variable above -# -# - $counter : the users counter associated to this achievement -# (changes to this variable *will* be saved!) -# If this achievement has a counter associated to it (i.e. solve 20 problems) -# then this is where you store the students counter for this achievement. -# This variable will initally start as '' -# -# - $maxCounter : the goal for the $counter variable for this achievement -# (changes to this variable will not be saved!) -# If this achievement has a counter associated to it then this variable -# contains the goal for the counter. Your achievement should return 1 -# when $counter >= $maxCounter. These two variables are used to show a -# progress bar for the achievement. -# -# - $localData : this is a hash which stores data for this user and achievement -# (changes to this variable *will* be saved!) -# This hash will persist from evaluation to evaluation. You can store whatever -# you like in here and it can be accessed next time this evaluator is run. -# Two things to keep in mind. The data in this hash will *not* be accessable -# by other achievements. If you plan to store something in this hash you have -# to write code to initialize the data. -# -# - $globalData : this is a hash which stores data for all achievements -# (changes to this variable *will* be saved!) -# This hash will persist from evaluation to evaluation and, like $localData, -# you can store whatever you like in here. This data will be accessable from -# *every* achievement and is unique to the user. Like $localData, you need to -# initialize any variable you plan on using in this hash. There are two -# variables stored in this hash that are maintained by the system. -# - $globalData->{completeSets} : This is the number of sets which the student -# has earned 100% on -# - $globalData->{completeProblems} : This is the number of problems which the -# student has earned 100% on -# Warning: The achievements are always evaluated in the order they are listed -# on the Instructors achievement editor page. To make matters more -# complicated, achievements which have already been earned are not evaluated -# at all. The up-shot of this is that when modifying variables in -# $globalData you need to either write your code so it doesnt matter which -# order the evaluators are run in, or you need to pay very close attention -# to which evaluators are run and when. diff --git a/courses.dist/modelCourse/templates/achievements/challenge_five.at b/courses.dist/modelCourse/templates/achievements/challenge_five.at deleted file mode 100644 index d9887bdb8..000000000 --- a/courses.dist/modelCourse/templates/achievements/challenge_five.at +++ /dev/null @@ -1,84 +0,0 @@ -#This evaluator checks to see if a particular problem of a particular set has -# been solved - -#constants -my %validproblems = ( - 'Challenge' => { - '5' => 1, } - ); - -#check and see if this problem was solved -if ($validproblems{$problem->set_id} && - $validproblems{$problem->set_id}{$problem->problem_id} && - $problem->status == 1 && - $problem->num_correct == 1) { - #update challenger counter - $globalData->{challengerCounter}++; - return 1; - } - - return 0; - - -# -You have access to a variety of variables: -# - $problem : the problem data (changes to this variable will not be saved!) -# This variable contains the problem data. It is a hash pointer with the -# following values (not all values shown) -# - $problem->status : the score of the current problem -# - $problem->problem_id : the id of the current problem -# - $problem->set_id : the id of the set containing the problem -# - $problem->num_correct : the number of correct attempts -# - $problem->num_incorrect : the number of incorrect attempts -# - $problem->last_answer : the last answer submitted -# - $problem->max_attempts : the maximum number of allowed attempts -# -# - $set : the set data (changes to this variable will not be saved!) -# This variable contains the set data. it is a hash pointer with the -# following values. (not all values shown) -# - $set->open_date : when the set was open -# - $set->due_date : when the set is due -# -# - @setProblems : the problem data for all the problems from this set. -# (changes to this variable will not be saved!) -# This is an array of problem hashes. Each element of the array has the -# save hash keys as the $problem variable above -# -# - $counter : the users counter associated to this achievement -# (changes to this variable *will* be saved!) -# If this achievement has a counter associated to it (i.e. solve 20 problems) -# then this is where you store the students counter for this achievement. -# This variable will initally start as '' -# -# - $maxCounter : the goal for the $counter variable for this achievement -# (changes to this variable will not be saved!) -# If this achievement has a counter associated to it then this variable -# contains the goal for the counter. Your achievement should return 1 -# when $counter >= $maxCounter. These two variables are used to show a -# progress bar for the achievement. -# -# - $localData : this is a hash which stores data for this user and achievement -# (changes to this variable *will* be saved!) -# This hash will persist from evaluation to evaluation. You can store whatever -# you like in here and it can be accessed next time this evaluator is run. -# Two things to keep in mind. The data in this hash will *not* be accessable -# by other achievements. If you plan to store something in this hash you have -# to write code to initialize the data. -# -# - $globalData : this is a hash which stores data for all achievements -# (changes to this variable *will* be saved!) -# This hash will persist from evaluation to evaluation and, like $localData, -# you can store whatever you like in here. This data will be accessable from -# *every* achievement and is unique to the user. Like $localData, you need to -# initialize any variable you plan on using in this hash. There are two -# variables stored in this hash that are maintained by the system. -# - $globalData->{completeSets} : This is the number of sets which the student -# has earned 100% on -# - $globalData->{completeProblems} : This is the number of problems which the -# student has earned 100% on -# Warning: The achievements are always evaluated in the order they are listed -# on the Instructors achievement editor page. To make matters more -# complicated, achievements which have already been earned are not evaluated -# at all. The up-shot of this is that when modifying variables in -# $globalData you need to either write your code so it doesnt matter which -# order the evaluators are run in, or you need to pay very close attention -# to which evaluators are run and when. diff --git a/courses.dist/modelCourse/templates/achievements/challenge_four.at b/courses.dist/modelCourse/templates/achievements/challenge_four.at deleted file mode 100644 index ae60641b4..000000000 --- a/courses.dist/modelCourse/templates/achievements/challenge_four.at +++ /dev/null @@ -1,84 +0,0 @@ -#This evaluator checks to see if a particular problem of a particular set has -# been solved - -#constants -my %validproblems = ( - 'Challenge' => { - '4' => 1, } - ); - -#check and see if this problem was solved -if ($validproblems{$problem->set_id} && - $validproblems{$problem->set_id}{$problem->problem_id} && - $problem->status == 1 && - $problem->num_correct == 1) { - #update challenger counter - $globalData->{challengerCounter}++; - return 1; - } - - return 0; - - -# -You have access to a variety of variables: -# - $problem : the problem data (changes to this variable will not be saved!) -# This variable contains the problem data. It is a hash pointer with the -# following values (not all values shown) -# - $problem->status : the score of the current problem -# - $problem->problem_id : the id of the current problem -# - $problem->set_id : the id of the set containing the problem -# - $problem->num_correct : the number of correct attempts -# - $problem->num_incorrect : the number of incorrect attempts -# - $problem->last_answer : the last answer submitted -# - $problem->max_attempts : the maximum number of allowed attempts -# -# - $set : the set data (changes to this variable will not be saved!) -# This variable contains the set data. it is a hash pointer with the -# following values. (not all values shown) -# - $set->open_date : when the set was open -# - $set->due_date : when the set is due -# -# - @setProblems : the problem data for all the problems from this set. -# (changes to this variable will not be saved!) -# This is an array of problem hashes. Each element of the array has the -# save hash keys as the $problem variable above -# -# - $counter : the users counter associated to this achievement -# (changes to this variable *will* be saved!) -# If this achievement has a counter associated to it (i.e. solve 20 problems) -# then this is where you store the students counter for this achievement. -# This variable will initally start as '' -# -# - $maxCounter : the goal for the $counter variable for this achievement -# (changes to this variable will not be saved!) -# If this achievement has a counter associated to it then this variable -# contains the goal for the counter. Your achievement should return 1 -# when $counter >= $maxCounter. These two variables are used to show a -# progress bar for the achievement. -# -# - $localData : this is a hash which stores data for this user and achievement -# (changes to this variable *will* be saved!) -# This hash will persist from evaluation to evaluation. You can store whatever -# you like in here and it can be accessed next time this evaluator is run. -# Two things to keep in mind. The data in this hash will *not* be accessable -# by other achievements. If you plan to store something in this hash you have -# to write code to initialize the data. -# -# - $globalData : this is a hash which stores data for all achievements -# (changes to this variable *will* be saved!) -# This hash will persist from evaluation to evaluation and, like $localData, -# you can store whatever you like in here. This data will be accessable from -# *every* achievement and is unique to the user. Like $localData, you need to -# initialize any variable you plan on using in this hash. There are two -# variables stored in this hash that are maintained by the system. -# - $globalData->{completeSets} : This is the number of sets which the student -# has earned 100% on -# - $globalData->{completeProblems} : This is the number of problems which the -# student has earned 100% on -# Warning: The achievements are always evaluated in the order they are listed -# on the Instructors achievement editor page. To make matters more -# complicated, achievements which have already been earned are not evaluated -# at all. The up-shot of this is that when modifying variables in -# $globalData you need to either write your code so it doesnt matter which -# order the evaluators are run in, or you need to pay very close attention -# to which evaluators are run and when. diff --git a/courses.dist/modelCourse/templates/achievements/challenge_nine.at b/courses.dist/modelCourse/templates/achievements/challenge_nine.at deleted file mode 100644 index 3648dd255..000000000 --- a/courses.dist/modelCourse/templates/achievements/challenge_nine.at +++ /dev/null @@ -1,84 +0,0 @@ -#This evaluator checks to see if a particular problem of a particular set has -# been solved - -#constants -my %validproblems = ( - 'Challenge' => { - '9' => 1, } - ); - -#check and see if this problem was solved -if ($validproblems{$problem->set_id} && - $validproblems{$problem->set_id}{$problem->problem_id} && - $problem->status == 1 && - $problem->num_correct == 1) { - #update challenger counter - $globalData->{challengerCounter}++; - return 1; - } - - return 0; - - -# -You have access to a variety of variables: -# - $problem : the problem data (changes to this variable will not be saved!) -# This variable contains the problem data. It is a hash pointer with the -# following values (not all values shown) -# - $problem->status : the score of the current problem -# - $problem->problem_id : the id of the current problem -# - $problem->set_id : the id of the set containing the problem -# - $problem->num_correct : the number of correct attempts -# - $problem->num_incorrect : the number of incorrect attempts -# - $problem->last_answer : the last answer submitted -# - $problem->max_attempts : the maximum number of allowed attempts -# -# - $set : the set data (changes to this variable will not be saved!) -# This variable contains the set data. it is a hash pointer with the -# following values. (not all values shown) -# - $set->open_date : when the set was open -# - $set->due_date : when the set is due -# -# - @setProblems : the problem data for all the problems from this set. -# (changes to this variable will not be saved!) -# This is an array of problem hashes. Each element of the array has the -# save hash keys as the $problem variable above -# -# - $counter : the users counter associated to this achievement -# (changes to this variable *will* be saved!) -# If this achievement has a counter associated to it (i.e. solve 20 problems) -# then this is where you store the students counter for this achievement. -# This variable will initally start as '' -# -# - $maxCounter : the goal for the $counter variable for this achievement -# (changes to this variable will not be saved!) -# If this achievement has a counter associated to it then this variable -# contains the goal for the counter. Your achievement should return 1 -# when $counter >= $maxCounter. These two variables are used to show a -# progress bar for the achievement. -# -# - $localData : this is a hash which stores data for this user and achievement -# (changes to this variable *will* be saved!) -# This hash will persist from evaluation to evaluation. You can store whatever -# you like in here and it can be accessed next time this evaluator is run. -# Two things to keep in mind. The data in this hash will *not* be accessable -# by other achievements. If you plan to store something in this hash you have -# to write code to initialize the data. -# -# - $globalData : this is a hash which stores data for all achievements -# (changes to this variable *will* be saved!) -# This hash will persist from evaluation to evaluation and, like $localData, -# you can store whatever you like in here. This data will be accessable from -# *every* achievement and is unique to the user. Like $localData, you need to -# initialize any variable you plan on using in this hash. There are two -# variables stored in this hash that are maintained by the system. -# - $globalData->{completeSets} : This is the number of sets which the student -# has earned 100% on -# - $globalData->{completeProblems} : This is the number of problems which the -# student has earned 100% on -# Warning: The achievements are always evaluated in the order they are listed -# on the Instructors achievement editor page. To make matters more -# complicated, achievements which have already been earned are not evaluated -# at all. The up-shot of this is that when modifying variables in -# $globalData you need to either write your code so it doesnt matter which -# order the evaluators are run in, or you need to pay very close attention -# to which evaluators are run and when. diff --git a/courses.dist/modelCourse/templates/achievements/challenge_one.at b/courses.dist/modelCourse/templates/achievements/challenge_one.at deleted file mode 100644 index e2c2586c6..000000000 --- a/courses.dist/modelCourse/templates/achievements/challenge_one.at +++ /dev/null @@ -1,84 +0,0 @@ -#This problem checks to see if a particular problem of a particular set has -# been solved - -#constants -my %validproblems = ( - 'Challenge' => { - '1' => 1, } - ); - -#check and see if this problem was solved -if ($validproblems{$problem->set_id} && - $validproblems{$problem->set_id}{$problem->problem_id} && - $problem->status == 1 && - $problem->num_correct == 1) { - #update challenger counter - $globalData->{challengerCounter}++; - return 1; - } - - return 0; - - -# -You have access to a variety of variables: -# - $problem : the problem data (changes to this variable will not be saved!) -# This variable contains the problem data. It is a hash pointer with the -# following values (not all values shown) -# - $problem->status : the score of the current problem -# - $problem->problem_id : the id of the current problem -# - $problem->set_id : the id of the set containing the problem -# - $problem->num_correct : the number of correct attempts -# - $problem->num_incorrect : the number of incorrect attempts -# - $problem->last_answer : the last answer submitted -# - $problem->max_attempts : the maximum number of allowed attempts -# -# - $set : the set data (changes to this variable will not be saved!) -# This variable contains the set data. it is a hash pointer with the -# following values. (not all values shown) -# - $set->open_date : when the set was open -# - $set->due_date : when the set is due -# -# - @setProblems : the problem data for all the problems from this set. -# (changes to this variable will not be saved!) -# This is an array of problem hashes. Each element of the array has the -# save hash keys as the $problem variable above -# -# - $counter : the users counter associated to this achievement -# (changes to this variable *will* be saved!) -# If this achievement has a counter associated to it (i.e. solve 20 problems) -# then this is where you store the students counter for this achievement. -# This variable will initally start as '' -# -# - $maxCounter : the goal for the $counter variable for this achievement -# (changes to this variable will not be saved!) -# If this achievement has a counter associated to it then this variable -# contains the goal for the counter. Your achievement should return 1 -# when $counter >= $maxCounter. These two variables are used to show a -# progress bar for the achievement. -# -# - $localData : this is a hash which stores data for this user and achievement -# (changes to this variable *will* be saved!) -# This hash will persist from evaluation to evaluation. You can store whatever -# you like in here and it can be accessed next time this evaluator is run. -# Two things to keep in mind. The data in this hash will *not* be accessable -# by other achievements. If you plan to store something in this hash you have -# to write code to initialize the data. -# -# - $globalData : this is a hash which stores data for all achievements -# (changes to this variable *will* be saved!) -# This hash will persist from evaluation to evaluation and, like $localData, -# you can store whatever you like in here. This data will be accessable from -# *every* achievement and is unique to the user. Like $localData, you need to -# initialize any variable you plan on using in this hash. There are two -# variables stored in this hash that are maintained by the system. -# - $globalData->{completeSets} : This is the number of sets which the student -# has earned 100% on -# - $globalData->{completeProblems} : This is the number of problems which the -# student has earned 100% on -# Warning: The achievements are always evaluated in the order they are listed -# on the Instructors achievement editor page. To make matters more -# complicated, achievements which have already been earned are not evaluated -# at all. The up-shot of this is that when modifying variables in -# $globalData you need to either write your code so it doesnt matter which -# order the evaluators are run in, or you need to pay very close attention -# to which evaluators are run and when. diff --git a/courses.dist/modelCourse/templates/achievements/challenge_seven.at b/courses.dist/modelCourse/templates/achievements/challenge_seven.at deleted file mode 100644 index c09abd346..000000000 --- a/courses.dist/modelCourse/templates/achievements/challenge_seven.at +++ /dev/null @@ -1,84 +0,0 @@ -#This evaluator checks to see if a particular problem of a particular set has -# been solved - -#constants -my %validproblems = ( - 'Challenge' => { - '7' => 1, } - ); - -#check and see if this problem was solved -if ($validproblems{$problem->set_id} && - $validproblems{$problem->set_id}{$problem->problem_id} && - $problem->status == 1 && - $problem->num_correct == 1) { - #update challenger counter - $globalData->{challengerCounter}++; - return 1; - } - - return 0; - - -# -You have access to a variety of variables: -# - $problem : the problem data (changes to this variable will not be saved!) -# This variable contains the problem data. It is a hash pointer with the -# following values (not all values shown) -# - $problem->status : the score of the current problem -# - $problem->problem_id : the id of the current problem -# - $problem->set_id : the id of the set containing the problem -# - $problem->num_correct : the number of correct attempts -# - $problem->num_incorrect : the number of incorrect attempts -# - $problem->last_answer : the last answer submitted -# - $problem->max_attempts : the maximum number of allowed attempts -# -# - $set : the set data (changes to this variable will not be saved!) -# This variable contains the set data. it is a hash pointer with the -# following values. (not all values shown) -# - $set->open_date : when the set was open -# - $set->due_date : when the set is due -# -# - @setProblems : the problem data for all the problems from this set. -# (changes to this variable will not be saved!) -# This is an array of problem hashes. Each element of the array has the -# save hash keys as the $problem variable above -# -# - $counter : the users counter associated to this achievement -# (changes to this variable *will* be saved!) -# If this achievement has a counter associated to it (i.e. solve 20 problems) -# then this is where you store the students counter for this achievement. -# This variable will initally start as '' -# -# - $maxCounter : the goal for the $counter variable for this achievement -# (changes to this variable will not be saved!) -# If this achievement has a counter associated to it then this variable -# contains the goal for the counter. Your achievement should return 1 -# when $counter >= $maxCounter. These two variables are used to show a -# progress bar for the achievement. -# -# - $localData : this is a hash which stores data for this user and achievement -# (changes to this variable *will* be saved!) -# This hash will persist from evaluation to evaluation. You can store whatever -# you like in here and it can be accessed next time this evaluator is run. -# Two things to keep in mind. The data in this hash will *not* be accessable -# by other achievements. If you plan to store something in this hash you have -# to write code to initialize the data. -# -# - $globalData : this is a hash which stores data for all achievements -# (changes to this variable *will* be saved!) -# This hash will persist from evaluation to evaluation and, like $localData, -# you can store whatever you like in here. This data will be accessable from -# *every* achievement and is unique to the user. Like $localData, you need to -# initialize any variable you plan on using in this hash. There are two -# variables stored in this hash that are maintained by the system. -# - $globalData->{completeSets} : This is the number of sets which the student -# has earned 100% on -# - $globalData->{completeProblems} : This is the number of problems which the -# student has earned 100% on -# Warning: The achievements are always evaluated in the order they are listed -# on the Instructors achievement editor page. To make matters more -# complicated, achievements which have already been earned are not evaluated -# at all. The up-shot of this is that when modifying variables in -# $globalData you need to either write your code so it doesnt matter which -# order the evaluators are run in, or you need to pay very close attention -# to which evaluators are run and when. diff --git a/courses.dist/modelCourse/templates/achievements/challenge_six.at b/courses.dist/modelCourse/templates/achievements/challenge_six.at deleted file mode 100644 index 69f56d2b5..000000000 --- a/courses.dist/modelCourse/templates/achievements/challenge_six.at +++ /dev/null @@ -1,84 +0,0 @@ -#This evaluator checks to see if a particular problem of a particular set has -# been solved - -#constants -my %validproblems = ( - 'Challenge' => { - '6' => 1, } - ); - -#check and see if this problem was solved -if ($validproblems{$problem->set_id} && - $validproblems{$problem->set_id}{$problem->problem_id} && - $problem->status == 1 && - $problem->num_correct == 1) { - #update challenger counter - $globalData->{challengerCounter}++; - return 1; - } - - return 0; - - -# -You have access to a variety of variables: -# - $problem : the problem data (changes to this variable will not be saved!) -# This variable contains the problem data. It is a hash pointer with the -# following values (not all values shown) -# - $problem->status : the score of the current problem -# - $problem->problem_id : the id of the current problem -# - $problem->set_id : the id of the set containing the problem -# - $problem->num_correct : the number of correct attempts -# - $problem->num_incorrect : the number of incorrect attempts -# - $problem->last_answer : the last answer submitted -# - $problem->max_attempts : the maximum number of allowed attempts -# -# - $set : the set data (changes to this variable will not be saved!) -# This variable contains the set data. it is a hash pointer with the -# following values. (not all values shown) -# - $set->open_date : when the set was open -# - $set->due_date : when the set is due -# -# - @setProblems : the problem data for all the problems from this set. -# (changes to this variable will not be saved!) -# This is an array of problem hashes. Each element of the array has the -# save hash keys as the $problem variable above -# -# - $counter : the users counter associated to this achievement -# (changes to this variable *will* be saved!) -# If this achievement has a counter associated to it (i.e. solve 20 problems) -# then this is where you store the students counter for this achievement. -# This variable will initally start as '' -# -# - $maxCounter : the goal for the $counter variable for this achievement -# (changes to this variable will not be saved!) -# If this achievement has a counter associated to it then this variable -# contains the goal for the counter. Your achievement should return 1 -# when $counter >= $maxCounter. These two variables are used to show a -# progress bar for the achievement. -# -# - $localData : this is a hash which stores data for this user and achievement -# (changes to this variable *will* be saved!) -# This hash will persist from evaluation to evaluation. You can store whatever -# you like in here and it can be accessed next time this evaluator is run. -# Two things to keep in mind. The data in this hash will *not* be accessable -# by other achievements. If you plan to store something in this hash you have -# to write code to initialize the data. -# -# - $globalData : this is a hash which stores data for all achievements -# (changes to this variable *will* be saved!) -# This hash will persist from evaluation to evaluation and, like $localData, -# you can store whatever you like in here. This data will be accessable from -# *every* achievement and is unique to the user. Like $localData, you need to -# initialize any variable you plan on using in this hash. There are two -# variables stored in this hash that are maintained by the system. -# - $globalData->{completeSets} : This is the number of sets which the student -# has earned 100% on -# - $globalData->{completeProblems} : This is the number of problems which the -# student has earned 100% on -# Warning: The achievements are always evaluated in the order they are listed -# on the Instructors achievement editor page. To make matters more -# complicated, achievements which have already been earned are not evaluated -# at all. The up-shot of this is that when modifying variables in -# $globalData you need to either write your code so it doesnt matter which -# order the evaluators are run in, or you need to pay very close attention -# to which evaluators are run and when. diff --git a/courses.dist/modelCourse/templates/achievements/challenge_ten.at b/courses.dist/modelCourse/templates/achievements/challenge_ten.at deleted file mode 100644 index 9f3738dd6..000000000 --- a/courses.dist/modelCourse/templates/achievements/challenge_ten.at +++ /dev/null @@ -1,84 +0,0 @@ -#This evaluator checks to see if a particular problem of a particular set has -# been solved - -#constants -my %validproblems = ( - 'Challenge' => { - '10' => 1, } - ); - -#check and see if this problem was solved -if ($validproblems{$problem->set_id} && - $validproblems{$problem->set_id}{$problem->problem_id} && - $problem->status == 1 && - $problem->num_correct == 1) { - #update challenger counter - $globalData->{challengerCounter}++; - return 1; - } - - return 0; - - -# -You have access to a variety of variables: -# - $problem : the problem data (changes to this variable will not be saved!) -# This variable contains the problem data. It is a hash pointer with the -# following values (not all values shown) -# - $problem->status : the score of the current problem -# - $problem->problem_id : the id of the current problem -# - $problem->set_id : the id of the set containing the problem -# - $problem->num_correct : the number of correct attempts -# - $problem->num_incorrect : the number of incorrect attempts -# - $problem->last_answer : the last answer submitted -# - $problem->max_attempts : the maximum number of allowed attempts -# -# - $set : the set data (changes to this variable will not be saved!) -# This variable contains the set data. it is a hash pointer with the -# following values. (not all values shown) -# - $set->open_date : when the set was open -# - $set->due_date : when the set is due -# -# - @setProblems : the problem data for all the problems from this set. -# (changes to this variable will not be saved!) -# This is an array of problem hashes. Each element of the array has the -# save hash keys as the $problem variable above -# -# - $counter : the users counter associated to this achievement -# (changes to this variable *will* be saved!) -# If this achievement has a counter associated to it (i.e. solve 20 problems) -# then this is where you store the students counter for this achievement. -# This variable will initally start as '' -# -# - $maxCounter : the goal for the $counter variable for this achievement -# (changes to this variable will not be saved!) -# If this achievement has a counter associated to it then this variable -# contains the goal for the counter. Your achievement should return 1 -# when $counter >= $maxCounter. These two variables are used to show a -# progress bar for the achievement. -# -# - $localData : this is a hash which stores data for this user and achievement -# (changes to this variable *will* be saved!) -# This hash will persist from evaluation to evaluation. You can store whatever -# you like in here and it can be accessed next time this evaluator is run. -# Two things to keep in mind. The data in this hash will *not* be accessable -# by other achievements. If you plan to store something in this hash you have -# to write code to initialize the data. -# -# - $globalData : this is a hash which stores data for all achievements -# (changes to this variable *will* be saved!) -# This hash will persist from evaluation to evaluation and, like $localData, -# you can store whatever you like in here. This data will be accessable from -# *every* achievement and is unique to the user. Like $localData, you need to -# initialize any variable you plan on using in this hash. There are two -# variables stored in this hash that are maintained by the system. -# - $globalData->{completeSets} : This is the number of sets which the student -# has earned 100% on -# - $globalData->{completeProblems} : This is the number of problems which the -# student has earned 100% on -# Warning: The achievements are always evaluated in the order they are listed -# on the Instructors achievement editor page. To make matters more -# complicated, achievements which have already been earned are not evaluated -# at all. The up-shot of this is that when modifying variables in -# $globalData you need to either write your code so it doesnt matter which -# order the evaluators are run in, or you need to pay very close attention -# to which evaluators are run and when. diff --git a/courses.dist/modelCourse/templates/achievements/challenge_three.at b/courses.dist/modelCourse/templates/achievements/challenge_three.at deleted file mode 100644 index 12aa750fb..000000000 --- a/courses.dist/modelCourse/templates/achievements/challenge_three.at +++ /dev/null @@ -1,84 +0,0 @@ -#This evaluator checks to see if a particular problem of a particular set has -# been solved - -#constants -my %validproblems = ( - 'Challenge' => { - '3' => 1, } - ); - -#check and see if this problem was solved -if ($validproblems{$problem->set_id} && - $validproblems{$problem->set_id}{$problem->problem_id} && - $problem->status == 1 && - $problem->num_correct == 1) { - #update challenger counter - $globalData->{challengerCounter}++; - return 1; - } - - return 0; - - -# -You have access to a variety of variables: -# - $problem : the problem data (changes to this variable will not be saved!) -# This variable contains the problem data. It is a hash pointer with the -# following values (not all values shown) -# - $problem->status : the score of the current problem -# - $problem->problem_id : the id of the current problem -# - $problem->set_id : the id of the set containing the problem -# - $problem->num_correct : the number of correct attempts -# - $problem->num_incorrect : the number of incorrect attempts -# - $problem->last_answer : the last answer submitted -# - $problem->max_attempts : the maximum number of allowed attempts -# -# - $set : the set data (changes to this variable will not be saved!) -# This variable contains the set data. it is a hash pointer with the -# following values. (not all values shown) -# - $set->open_date : when the set was open -# - $set->due_date : when the set is due -# -# - @setProblems : the problem data for all the problems from this set. -# (changes to this variable will not be saved!) -# This is an array of problem hashes. Each element of the array has the -# save hash keys as the $problem variable above -# -# - $counter : the users counter associated to this achievement -# (changes to this variable *will* be saved!) -# If this achievement has a counter associated to it (i.e. solve 20 problems) -# then this is where you store the students counter for this achievement. -# This variable will initally start as '' -# -# - $maxCounter : the goal for the $counter variable for this achievement -# (changes to this variable will not be saved!) -# If this achievement has a counter associated to it then this variable -# contains the goal for the counter. Your achievement should return 1 -# when $counter >= $maxCounter. These two variables are used to show a -# progress bar for the achievement. -# -# - $localData : this is a hash which stores data for this user and achievement -# (changes to this variable *will* be saved!) -# This hash will persist from evaluation to evaluation. You can store whatever -# you like in here and it can be accessed next time this evaluator is run. -# Two things to keep in mind. The data in this hash will *not* be accessable -# by other achievements. If you plan to store something in this hash you have -# to write code to initialize the data. -# -# - $globalData : this is a hash which stores data for all achievements -# (changes to this variable *will* be saved!) -# This hash will persist from evaluation to evaluation and, like $localData, -# you can store whatever you like in here. This data will be accessable from -# *every* achievement and is unique to the user. Like $localData, you need to -# initialize any variable you plan on using in this hash. There are two -# variables stored in this hash that are maintained by the system. -# - $globalData->{completeSets} : This is the number of sets which the student -# has earned 100% on -# - $globalData->{completeProblems} : This is the number of problems which the -# student has earned 100% on -# Warning: The achievements are always evaluated in the order they are listed -# on the Instructors achievement editor page. To make matters more -# complicated, achievements which have already been earned are not evaluated -# at all. The up-shot of this is that when modifying variables in -# $globalData you need to either write your code so it doesnt matter which -# order the evaluators are run in, or you need to pay very close attention -# to which evaluators are run and when. diff --git a/courses.dist/modelCourse/templates/achievements/challenge_two.at b/courses.dist/modelCourse/templates/achievements/challenge_two.at deleted file mode 100644 index b82c300bd..000000000 --- a/courses.dist/modelCourse/templates/achievements/challenge_two.at +++ /dev/null @@ -1,84 +0,0 @@ -#This evaluator checks to see if a particular problem of a particular set has -# been solved - -#constants -my %validproblems = ( - 'Challenge' => { - '2' => 1, } - ); - -#check and see if this problem was solved -if ($validproblems{$problem->set_id} && - $validproblems{$problem->set_id}{$problem->problem_id} && - $problem->status == 1 && - $problem->num_correct == 1) { - #update challenger counter - $globalData->{challengerCounter}++; - return 1; - } - - return 0; - - -# -You have access to a variety of variables: -# - $problem : the problem data (changes to this variable will not be saved!) -# This variable contains the problem data. It is a hash pointer with the -# following values (not all values shown) -# - $problem->status : the score of the current problem -# - $problem->problem_id : the id of the current problem -# - $problem->set_id : the id of the set containing the problem -# - $problem->num_correct : the number of correct attempts -# - $problem->num_incorrect : the number of incorrect attempts -# - $problem->last_answer : the last answer submitted -# - $problem->max_attempts : the maximum number of allowed attempts -# -# - $set : the set data (changes to this variable will not be saved!) -# This variable contains the set data. it is a hash pointer with the -# following values. (not all values shown) -# - $set->open_date : when the set was open -# - $set->due_date : when the set is due -# -# - @setProblems : the problem data for all the problems from this set. -# (changes to this variable will not be saved!) -# This is an array of problem hashes. Each element of the array has the -# save hash keys as the $problem variable above -# -# - $counter : the users counter associated to this achievement -# (changes to this variable *will* be saved!) -# If this achievement has a counter associated to it (i.e. solve 20 problems) -# then this is where you store the students counter for this achievement. -# This variable will initally start as '' -# -# - $maxCounter : the goal for the $counter variable for this achievement -# (changes to this variable will not be saved!) -# If this achievement has a counter associated to it then this variable -# contains the goal for the counter. Your achievement should return 1 -# when $counter >= $maxCounter. These two variables are used to show a -# progress bar for the achievement. -# -# - $localData : this is a hash which stores data for this user and achievement -# (changes to this variable *will* be saved!) -# This hash will persist from evaluation to evaluation. You can store whatever -# you like in here and it can be accessed next time this evaluator is run. -# Two things to keep in mind. The data in this hash will *not* be accessable -# by other achievements. If you plan to store something in this hash you have -# to write code to initialize the data. -# -# - $globalData : this is a hash which stores data for all achievements -# (changes to this variable *will* be saved!) -# This hash will persist from evaluation to evaluation and, like $localData, -# you can store whatever you like in here. This data will be accessable from -# *every* achievement and is unique to the user. Like $localData, you need to -# initialize any variable you plan on using in this hash. There are two -# variables stored in this hash that are maintained by the system. -# - $globalData->{completeSets} : This is the number of sets which the student -# has earned 100% on -# - $globalData->{completeProblems} : This is the number of problems which the -# student has earned 100% on -# Warning: The achievements are always evaluated in the order they are listed -# on the Instructors achievement editor page. To make matters more -# complicated, achievements which have already been earned are not evaluated -# at all. The up-shot of this is that when modifying variables in -# $globalData you need to either write your code so it doesnt matter which -# order the evaluators are run in, or you need to pay very close attention -# to which evaluators are run and when. diff --git a/courses.dist/modelCourse/templates/achievements/challenger.at b/courses.dist/modelCourse/templates/achievements/challenger.at deleted file mode 100644 index d06c963ee..000000000 --- a/courses.dist/modelCourse/templates/achievements/challenger.at +++ /dev/null @@ -1,74 +0,0 @@ -# This is a "solved n problems achievement. Notice how we update $counter -# (even though the appropriate variable is already given to use in -# ($globalData) so that the achievement progress bar works correctly. - -# Update counter from globalData -$counter = $globalData->{'challengerCounter'}; - -if ($counter >= $maxCounter) { - return 1 -} else { - return 0; -} - -# Variable Descriptions: -# - $problem : the problem data (changes tao this variable will not be saved!) -# This variable contains the problem data. It is a hash pointer with the -# following values (not all values shown) -# - $problem->status : the score of the current problem -# - $problem->problem_id : the id of the current problem -# - $problem->set_id : the id of the set containing the problem -# - $problem->num_correct : the number of correct attempts -# - $problem->num_incorrect : the number of incorrect attempts -# - $problem->max_attempts : the maximum number of allowed attempts -# -# - $set : the set data (changes to this variable will not be saved!) -# This variable contains the set data. it is a hash pointer with the -# following values. (not all values shown) -# - $set->open_date : when the set was open -# - $set->due_date : when the set is due -# -# - @setProblems : the problem data for all the problems from this set. -# (changes to this variable will not be saved!) -# This is an array of problem hashes. Each element of the array has the -# save hash keys as the $problem variable above -# -# - $counter : the users counter associated to this achievement -# (changes to this variable *will* be saved!) -# If this achievement has a counter associated to it (i.e. solve 20 problems) -# then this is where you store the students counter for this achievement. -# This variable will initally start as '' -# -# - $maxCounter : the goal for the $counter variable for this achievement -# (changes to this variable will not be saved!) -# If this achievement has a counter associated to it then this variable -# contains the goal for the counter. Your achievement should return 1 -# when $counter >= $maxCounter. These two variables are used to show a -# progress bar for the achievement. -# -# - $localData : this is a hash which stores data for this user and achievement -# (changes to this variable *will* be saved!) -# This hash will persist from evaluation to evaluation. You can store whatever -# you like in here and it can be accessed next time this evaluator is run. -# Two things to keep in mind. The data in this hash will *not* be accessable -# by other achievements. If you plan to store something in this hash you have -# to write code to initialize the data. -# -# - $globalData : this is a hash which stores data for all achievements -# (changes to this variable *will* be saved!) -# This hash will persist from evaluation to evaluation and, like $localData, -# you can store whatever you like in here. This data will be accessable from -# *every* achievement and is unique to the user. Like $localData, you need to -# initialize any variable you plan on using in this hash. There are two -# variables stored in this hash that are maintained by the system. -# - $globalData->{completeSets} : This is the number of sets which the student -# has earned 100% on -# - $globalData->{completeProblems} : This is the number of problems which the -# student has earned 100% on -# Warning: The achievements are always evaluated in the order they are listed -# on the Instructors achievement editor page. To make matters more -# complicated, achievements which have already been earned are not evaluated -# at all. The up-shot of this is that when modifying variables in -# $globalData you need to either write your code so it doesnt matter which -# order the evaluators are run in, or you need to pay very close attention -# to which evaluators are run and when. \ No newline at end of file diff --git a/courses.dist/modelCourse/templates/achievements/chipping_away.at b/courses.dist/modelCourse/templates/achievements/chipping_away.at deleted file mode 100644 index 00d96e700..000000000 --- a/courses.dist/modelCourse/templates/achievements/chipping_away.at +++ /dev/null @@ -1,80 +0,0 @@ -#This checks to see if the student has worked on the set in -# greater than 48 hours from time to first input to time to last answer. - -# If the set id doest equal the id of the last set then set -# *this* set as the last set, and set the start time - -if ($problem->set_id ne $localData->{last_set}) { - $localData->{last_set} = $problem->set_id; - $localData->{start_time} = time(); - return 0; -} - -# of we spent more than 48 hours then done! -if ((time() - $localData->{start_time}) > 172800) { - return 1; -} else { - return 0; -} -# -You have access to a variety of variables: -# - $problem : the problem data (changes to this variable will not be saved!) -# This variable contains the problem data. It is a hash pointer with the -# following values (not all values shown) -# - $problem->status : the score of the current problem -# - $problem->problem_id : the id of the current problem -# - $problem->set_id : the id of the set containing the problem -# - $problem->num_correct : the number of correct attempts -# - $problem->num_incorrect : the number of incorrect attempts -# - $problem->last_answer : the last answer submitted -# - $problem->max_attempts : the maximum number of allowed attempts -# -# - $set : the set data (changes to this variable will not be saved!) -# This variable contains the set data. it is a hash pointer with the -# following values. (not all values shown) -# - $set->open_date : when the set was open -# - $set->due_date : when the set is due -# -# - @setProblems : the problem data for all the problems from this set. -# (changes to this variable will not be saved!) -# This is an array of problem hashes. Each element of the array has the -# save hash keys as the $problem variable above -# -# - $counter : the users counter associated to this achievement -# (changes to this variable *will* be saved!) -# If this achievement has a counter associated to it (i.e. solve 20 problems) -# then this is where you store the students counter for this achievement. -# This variable will initally start as '' -# -# - $maxCounter : the goal for the $counter variable for this achievement -# (changes to this variable will not be saved!) -# If this achievement has a counter associated to it then this variable -# contains the goal for the counter. Your achievement should return 1 -# when $counter >= $maxCounter. These two variables are used to show a -# progress bar for the achievement. -# -# - $localData : this is a hash which stores data for this user and achievement -# (changes to this variable *will* be saved!) -# This hash will persist from evaluation to evaluation. You can store whatever -# you like in here and it can be accessed next time this evaluator is run. -# Two things to keep in mind. The data in this hash will *not* be accessable -# by other achievements. If you plan to store something in this hash you have -# to write code to initialize the data. -# -# - $globalData : this is a hash which stores data for all achievements -# (changes to this variable *will* be saved!) -# This hash will persist from evaluation to evaluation and, like $localData, -# you can store whatever you like in here. This data will be accessable from -# *every* achievement and is unique to the user. Like $localData, you need to -# initialize any variable you plan on using in this hash. There are two -# variables stored in this hash that are maintained by the system. -# - $globalData->{completeSets} : This is the number of sets which the student -# has earned 100% on -# - $globalData->{completeProblems} : This is the number of problems which the -# student has earned 100% on -# Warning: The achievements are always evaluated in the order they are listed -# on the Instructors achievement editor page. To make matters more -# complicated, achievements which have already been earned are not evaluated -# at all. The up-shot of this is that when modifying variables in -# $globalData you need to either write your code so it doesnt matter which -# order the evaluators are run in, or you need to pay very close attention -# to which evaluators are run and when. \ No newline at end of file diff --git a/courses.dist/modelCourse/templates/achievements/complete_100_problems.at b/courses.dist/modelCourse/templates/achievements/complete_100_problems.at deleted file mode 100644 index 199491ef1..000000000 --- a/courses.dist/modelCourse/templates/achievements/complete_100_problems.at +++ /dev/null @@ -1,74 +0,0 @@ -# This is a "solved n problems achievement. Notice how we update $counter -# (even though the appropriate variable is already given to use in -# ($globalData) so that the achievement progress bar works correctly. - -# Update counter from globalData -$counter = $globalData->{'completeProblems'}; - -if ($counter >= $maxCounter) { - return 1 -} else { - return 0; -} - -# Variable Descriptions: -# - $problem : the problem data (changes to this variable will not be saved!) -# This variable contains the problem data. It is a hash pointer with the -# following values (not all values shown) -# - $problem->status : the score of the current problem -# - $problem->problem_id : the id of the current problem -# - $problem->set_id : the id of the set containing the problem -# - $problem->num_correct : the number of correct attempts -# - $problem->num_incorrect : the number of incorrect attempts -# - $problem->max_attempts : the maximum number of allowed attempts -# -# - $set : the set data (changes to this variable will not be saved!) -# This variable contains the set data. it is a hash pointer with the -# following values. (not all values shown) -# - $set->open_date : when the set was open -# - $set->due_date : when the set is due -# -# - @setProblems : the problem data for all the problems from this set. -# (changes to this variable will not be saved!) -# This is an array of problem hashes. Each element of the array has the -# save hash keys as the $problem variable above -# -# - $counter : the users counter associated to this achievement -# (changes to this variable *will* be saved!) -# If this achievement has a counter associated to it (i.e. solve 20 problems) -# then this is where you store the students counter for this achievement. -# This variable will initally start as '' -# -# - $maxCounter : the goal for the $counter variable for this achievement -# (changes to this variable will not be saved!) -# If this achievement has a counter associated to it then this variable -# contains the goal for the counter. Your achievement should return 1 -# when $counter >= $maxCounter. These two variables are used to show a -# progress bar for the achievement. -# -# - $localData : this is a hash which stores data for this user and achievement -# (changes to this variable *will* be saved!) -# This hash will persist from evaluation to evaluation. You can store whatever -# you like in here and it can be accessed next time this evaluator is run. -# Two things to keep in mind. The data in this hash will *not* be accessable -# by other achievements. If you plan to store something in this hash you have -# to write code to initialize the data. -# -# - $globalData : this is a hash which stores data for all achievements -# (changes to this variable *will* be saved!) -# This hash will persist from evaluation to evaluation and, like $localData, -# you can store whatever you like in here. This data will be accessable from -# *every* achievement and is unique to the user. Like $localData, you need to -# initialize any variable you plan on using in this hash. There are two -# variables stored in this hash that are maintained by the system. -# - $globalData->{completeSets} : This is the number of sets which the student -# has earned 100% on -# - $globalData->{completeProblems} : This is the number of problems which the -# student has earned 100% on -# Warning: The achievements are always evaluated in the order they are listed -# on the Instructors achievement editor page. To make matters more -# complicated, achievements which have already been earned are not evaluated -# at all. The up-shot of this is that when modifying variables in -# $globalData you need to either write your code so it doesnt matter which -# order the evaluators are run in, or you need to pay very close attention -# to which evaluators are run and when. \ No newline at end of file diff --git a/courses.dist/modelCourse/templates/achievements/complete_10_problems.at b/courses.dist/modelCourse/templates/achievements/complete_10_problems.at deleted file mode 100644 index 199491ef1..000000000 --- a/courses.dist/modelCourse/templates/achievements/complete_10_problems.at +++ /dev/null @@ -1,74 +0,0 @@ -# This is a "solved n problems achievement. Notice how we update $counter -# (even though the appropriate variable is already given to use in -# ($globalData) so that the achievement progress bar works correctly. - -# Update counter from globalData -$counter = $globalData->{'completeProblems'}; - -if ($counter >= $maxCounter) { - return 1 -} else { - return 0; -} - -# Variable Descriptions: -# - $problem : the problem data (changes to this variable will not be saved!) -# This variable contains the problem data. It is a hash pointer with the -# following values (not all values shown) -# - $problem->status : the score of the current problem -# - $problem->problem_id : the id of the current problem -# - $problem->set_id : the id of the set containing the problem -# - $problem->num_correct : the number of correct attempts -# - $problem->num_incorrect : the number of incorrect attempts -# - $problem->max_attempts : the maximum number of allowed attempts -# -# - $set : the set data (changes to this variable will not be saved!) -# This variable contains the set data. it is a hash pointer with the -# following values. (not all values shown) -# - $set->open_date : when the set was open -# - $set->due_date : when the set is due -# -# - @setProblems : the problem data for all the problems from this set. -# (changes to this variable will not be saved!) -# This is an array of problem hashes. Each element of the array has the -# save hash keys as the $problem variable above -# -# - $counter : the users counter associated to this achievement -# (changes to this variable *will* be saved!) -# If this achievement has a counter associated to it (i.e. solve 20 problems) -# then this is where you store the students counter for this achievement. -# This variable will initally start as '' -# -# - $maxCounter : the goal for the $counter variable for this achievement -# (changes to this variable will not be saved!) -# If this achievement has a counter associated to it then this variable -# contains the goal for the counter. Your achievement should return 1 -# when $counter >= $maxCounter. These two variables are used to show a -# progress bar for the achievement. -# -# - $localData : this is a hash which stores data for this user and achievement -# (changes to this variable *will* be saved!) -# This hash will persist from evaluation to evaluation. You can store whatever -# you like in here and it can be accessed next time this evaluator is run. -# Two things to keep in mind. The data in this hash will *not* be accessable -# by other achievements. If you plan to store something in this hash you have -# to write code to initialize the data. -# -# - $globalData : this is a hash which stores data for all achievements -# (changes to this variable *will* be saved!) -# This hash will persist from evaluation to evaluation and, like $localData, -# you can store whatever you like in here. This data will be accessable from -# *every* achievement and is unique to the user. Like $localData, you need to -# initialize any variable you plan on using in this hash. There are two -# variables stored in this hash that are maintained by the system. -# - $globalData->{completeSets} : This is the number of sets which the student -# has earned 100% on -# - $globalData->{completeProblems} : This is the number of problems which the -# student has earned 100% on -# Warning: The achievements are always evaluated in the order they are listed -# on the Instructors achievement editor page. To make matters more -# complicated, achievements which have already been earned are not evaluated -# at all. The up-shot of this is that when modifying variables in -# $globalData you need to either write your code so it doesnt matter which -# order the evaluators are run in, or you need to pay very close attention -# to which evaluators are run and when. \ No newline at end of file diff --git a/courses.dist/modelCourse/templates/achievements/complete_150_problems.at b/courses.dist/modelCourse/templates/achievements/complete_150_problems.at deleted file mode 100644 index 199491ef1..000000000 --- a/courses.dist/modelCourse/templates/achievements/complete_150_problems.at +++ /dev/null @@ -1,74 +0,0 @@ -# This is a "solved n problems achievement. Notice how we update $counter -# (even though the appropriate variable is already given to use in -# ($globalData) so that the achievement progress bar works correctly. - -# Update counter from globalData -$counter = $globalData->{'completeProblems'}; - -if ($counter >= $maxCounter) { - return 1 -} else { - return 0; -} - -# Variable Descriptions: -# - $problem : the problem data (changes to this variable will not be saved!) -# This variable contains the problem data. It is a hash pointer with the -# following values (not all values shown) -# - $problem->status : the score of the current problem -# - $problem->problem_id : the id of the current problem -# - $problem->set_id : the id of the set containing the problem -# - $problem->num_correct : the number of correct attempts -# - $problem->num_incorrect : the number of incorrect attempts -# - $problem->max_attempts : the maximum number of allowed attempts -# -# - $set : the set data (changes to this variable will not be saved!) -# This variable contains the set data. it is a hash pointer with the -# following values. (not all values shown) -# - $set->open_date : when the set was open -# - $set->due_date : when the set is due -# -# - @setProblems : the problem data for all the problems from this set. -# (changes to this variable will not be saved!) -# This is an array of problem hashes. Each element of the array has the -# save hash keys as the $problem variable above -# -# - $counter : the users counter associated to this achievement -# (changes to this variable *will* be saved!) -# If this achievement has a counter associated to it (i.e. solve 20 problems) -# then this is where you store the students counter for this achievement. -# This variable will initally start as '' -# -# - $maxCounter : the goal for the $counter variable for this achievement -# (changes to this variable will not be saved!) -# If this achievement has a counter associated to it then this variable -# contains the goal for the counter. Your achievement should return 1 -# when $counter >= $maxCounter. These two variables are used to show a -# progress bar for the achievement. -# -# - $localData : this is a hash which stores data for this user and achievement -# (changes to this variable *will* be saved!) -# This hash will persist from evaluation to evaluation. You can store whatever -# you like in here and it can be accessed next time this evaluator is run. -# Two things to keep in mind. The data in this hash will *not* be accessable -# by other achievements. If you plan to store something in this hash you have -# to write code to initialize the data. -# -# - $globalData : this is a hash which stores data for all achievements -# (changes to this variable *will* be saved!) -# This hash will persist from evaluation to evaluation and, like $localData, -# you can store whatever you like in here. This data will be accessable from -# *every* achievement and is unique to the user. Like $localData, you need to -# initialize any variable you plan on using in this hash. There are two -# variables stored in this hash that are maintained by the system. -# - $globalData->{completeSets} : This is the number of sets which the student -# has earned 100% on -# - $globalData->{completeProblems} : This is the number of problems which the -# student has earned 100% on -# Warning: The achievements are always evaluated in the order they are listed -# on the Instructors achievement editor page. To make matters more -# complicated, achievements which have already been earned are not evaluated -# at all. The up-shot of this is that when modifying variables in -# $globalData you need to either write your code so it doesnt matter which -# order the evaluators are run in, or you need to pay very close attention -# to which evaluators are run and when. \ No newline at end of file diff --git a/courses.dist/modelCourse/templates/achievements/complete_25_problems.at b/courses.dist/modelCourse/templates/achievements/complete_25_problems.at deleted file mode 100644 index 199491ef1..000000000 --- a/courses.dist/modelCourse/templates/achievements/complete_25_problems.at +++ /dev/null @@ -1,74 +0,0 @@ -# This is a "solved n problems achievement. Notice how we update $counter -# (even though the appropriate variable is already given to use in -# ($globalData) so that the achievement progress bar works correctly. - -# Update counter from globalData -$counter = $globalData->{'completeProblems'}; - -if ($counter >= $maxCounter) { - return 1 -} else { - return 0; -} - -# Variable Descriptions: -# - $problem : the problem data (changes to this variable will not be saved!) -# This variable contains the problem data. It is a hash pointer with the -# following values (not all values shown) -# - $problem->status : the score of the current problem -# - $problem->problem_id : the id of the current problem -# - $problem->set_id : the id of the set containing the problem -# - $problem->num_correct : the number of correct attempts -# - $problem->num_incorrect : the number of incorrect attempts -# - $problem->max_attempts : the maximum number of allowed attempts -# -# - $set : the set data (changes to this variable will not be saved!) -# This variable contains the set data. it is a hash pointer with the -# following values. (not all values shown) -# - $set->open_date : when the set was open -# - $set->due_date : when the set is due -# -# - @setProblems : the problem data for all the problems from this set. -# (changes to this variable will not be saved!) -# This is an array of problem hashes. Each element of the array has the -# save hash keys as the $problem variable above -# -# - $counter : the users counter associated to this achievement -# (changes to this variable *will* be saved!) -# If this achievement has a counter associated to it (i.e. solve 20 problems) -# then this is where you store the students counter for this achievement. -# This variable will initally start as '' -# -# - $maxCounter : the goal for the $counter variable for this achievement -# (changes to this variable will not be saved!) -# If this achievement has a counter associated to it then this variable -# contains the goal for the counter. Your achievement should return 1 -# when $counter >= $maxCounter. These two variables are used to show a -# progress bar for the achievement. -# -# - $localData : this is a hash which stores data for this user and achievement -# (changes to this variable *will* be saved!) -# This hash will persist from evaluation to evaluation. You can store whatever -# you like in here and it can be accessed next time this evaluator is run. -# Two things to keep in mind. The data in this hash will *not* be accessable -# by other achievements. If you plan to store something in this hash you have -# to write code to initialize the data. -# -# - $globalData : this is a hash which stores data for all achievements -# (changes to this variable *will* be saved!) -# This hash will persist from evaluation to evaluation and, like $localData, -# you can store whatever you like in here. This data will be accessable from -# *every* achievement and is unique to the user. Like $localData, you need to -# initialize any variable you plan on using in this hash. There are two -# variables stored in this hash that are maintained by the system. -# - $globalData->{completeSets} : This is the number of sets which the student -# has earned 100% on -# - $globalData->{completeProblems} : This is the number of problems which the -# student has earned 100% on -# Warning: The achievements are always evaluated in the order they are listed -# on the Instructors achievement editor page. To make matters more -# complicated, achievements which have already been earned are not evaluated -# at all. The up-shot of this is that when modifying variables in -# $globalData you need to either write your code so it doesnt matter which -# order the evaluators are run in, or you need to pay very close attention -# to which evaluators are run and when. \ No newline at end of file diff --git a/courses.dist/modelCourse/templates/achievements/complete_50_problems.at b/courses.dist/modelCourse/templates/achievements/complete_50_problems.at deleted file mode 100644 index 199491ef1..000000000 --- a/courses.dist/modelCourse/templates/achievements/complete_50_problems.at +++ /dev/null @@ -1,74 +0,0 @@ -# This is a "solved n problems achievement. Notice how we update $counter -# (even though the appropriate variable is already given to use in -# ($globalData) so that the achievement progress bar works correctly. - -# Update counter from globalData -$counter = $globalData->{'completeProblems'}; - -if ($counter >= $maxCounter) { - return 1 -} else { - return 0; -} - -# Variable Descriptions: -# - $problem : the problem data (changes to this variable will not be saved!) -# This variable contains the problem data. It is a hash pointer with the -# following values (not all values shown) -# - $problem->status : the score of the current problem -# - $problem->problem_id : the id of the current problem -# - $problem->set_id : the id of the set containing the problem -# - $problem->num_correct : the number of correct attempts -# - $problem->num_incorrect : the number of incorrect attempts -# - $problem->max_attempts : the maximum number of allowed attempts -# -# - $set : the set data (changes to this variable will not be saved!) -# This variable contains the set data. it is a hash pointer with the -# following values. (not all values shown) -# - $set->open_date : when the set was open -# - $set->due_date : when the set is due -# -# - @setProblems : the problem data for all the problems from this set. -# (changes to this variable will not be saved!) -# This is an array of problem hashes. Each element of the array has the -# save hash keys as the $problem variable above -# -# - $counter : the users counter associated to this achievement -# (changes to this variable *will* be saved!) -# If this achievement has a counter associated to it (i.e. solve 20 problems) -# then this is where you store the students counter for this achievement. -# This variable will initally start as '' -# -# - $maxCounter : the goal for the $counter variable for this achievement -# (changes to this variable will not be saved!) -# If this achievement has a counter associated to it then this variable -# contains the goal for the counter. Your achievement should return 1 -# when $counter >= $maxCounter. These two variables are used to show a -# progress bar for the achievement. -# -# - $localData : this is a hash which stores data for this user and achievement -# (changes to this variable *will* be saved!) -# This hash will persist from evaluation to evaluation. You can store whatever -# you like in here and it can be accessed next time this evaluator is run. -# Two things to keep in mind. The data in this hash will *not* be accessable -# by other achievements. If you plan to store something in this hash you have -# to write code to initialize the data. -# -# - $globalData : this is a hash which stores data for all achievements -# (changes to this variable *will* be saved!) -# This hash will persist from evaluation to evaluation and, like $localData, -# you can store whatever you like in here. This data will be accessable from -# *every* achievement and is unique to the user. Like $localData, you need to -# initialize any variable you plan on using in this hash. There are two -# variables stored in this hash that are maintained by the system. -# - $globalData->{completeSets} : This is the number of sets which the student -# has earned 100% on -# - $globalData->{completeProblems} : This is the number of problems which the -# student has earned 100% on -# Warning: The achievements are always evaluated in the order they are listed -# on the Instructors achievement editor page. To make matters more -# complicated, achievements which have already been earned are not evaluated -# at all. The up-shot of this is that when modifying variables in -# $globalData you need to either write your code so it doesnt matter which -# order the evaluators are run in, or you need to pay very close attention -# to which evaluators are run and when. \ No newline at end of file diff --git a/courses.dist/modelCourse/templates/achievements/complete_all_sets.at b/courses.dist/modelCourse/templates/achievements/complete_all_sets.at deleted file mode 100644 index c5d58175a..000000000 --- a/courses.dist/modelCourse/templates/achievements/complete_all_sets.at +++ /dev/null @@ -1,74 +0,0 @@ -# This is a "solved n problems achievement. Notice how we update $counter -# (even though the appropriate variable is already given to use in -# ($globalData) so that the achievement progress bar works correctly. - -# Update counter from globalData -$counter = $globalData->{'completeSets'}; - -if ($counter >= $maxCounter) { - return 1 -} else { - return 0; -} - -# Variable Descriptions: -# - $problem : the problem data (changes tao this variable will not be saved!) -# This variable contains the problem data. It is a hash pointer with the -# following values (not all values shown) -# - $problem->status : the score of the current problem -# - $problem->problem_id : the id of the current problem -# - $problem->set_id : the id of the set containing the problem -# - $problem->num_correct : the number of correct attempts -# - $problem->num_incorrect : the number of incorrect attempts -# - $problem->max_attempts : the maximum number of allowed attempts -# -# - $set : the set data (changes to this variable will not be saved!) -# This variable contains the set data. it is a hash pointer with the -# following values. (not all values shown) -# - $set->open_date : when the set was open -# - $set->due_date : when the set is due -# -# - @setProblems : the problem data for all the problems from this set. -# (changes to this variable will not be saved!) -# This is an array of problem hashes. Each element of the array has the -# save hash keys as the $problem variable above -# -# - $counter : the users counter associated to this achievement -# (changes to this variable *will* be saved!) -# If this achievement has a counter associated to it (i.e. solve 20 problems) -# then this is where you store the students counter for this achievement. -# This variable will initally start as '' -# -# - $maxCounter : the goal for the $counter variable for this achievement -# (changes to this variable will not be saved!) -# If this achievement has a counter associated to it then this variable -# contains the goal for the counter. Your achievement should return 1 -# when $counter >= $maxCounter. These two variables are used to show a -# progress bar for the achievement. -# -# - $localData : this is a hash which stores data for this user and achievement -# (changes to this variable *will* be saved!) -# This hash will persist from evaluation to evaluation. You can store whatever -# you like in here and it can be accessed next time this evaluator is run. -# Two things to keep in mind. The data in this hash will *not* be accessable -# by other achievements. If you plan to store something in this hash you have -# to write code to initialize the data. -# -# - $globalData : this is a hash which stores data for all achievements -# (changes to this variable *will* be saved!) -# This hash will persist from evaluation to evaluation and, like $localData, -# you can store whatever you like in here. This data will be accessable from -# *every* achievement and is unique to the user. Like $localData, you need to -# initialize any variable you plan on using in this hash. There are two -# variables stored in this hash that are maintained by the system. -# - $globalData->{completeSets} : This is the number of sets which the student -# has earned 100% on -# - $globalData->{completeProblems} : This is the number of problems which the -# student has earned 100% on -# Warning: The achievements are always evaluated in the order they are listed -# on the Instructors achievement editor page. To make matters more -# complicated, achievements which have already been earned are not evaluated -# at all. The up-shot of this is that when modifying variables in -# $globalData you need to either write your code so it doesnt matter which -# order the evaluators are run in, or you need to pay very close attention -# to which evaluators are run and when. \ No newline at end of file diff --git a/courses.dist/modelCourse/templates/achievements/complete_five_sets.at b/courses.dist/modelCourse/templates/achievements/complete_five_sets.at deleted file mode 100644 index f21335dee..000000000 --- a/courses.dist/modelCourse/templates/achievements/complete_five_sets.at +++ /dev/null @@ -1,74 +0,0 @@ -# This is a "solved n sets" achievement. Notice how we update $counter -# (even though the appropriate variable is already given to use in -# ($globalData) so that the achievement progress bar works correctly. - -# Update counter from globalData -$counter = $globalData->{'completeSets'}; - -if ($counter >= $maxCounter) { - return 1 -} else { - return 0; -} - -# Variable Descriptions: -# - $problem : the problem data (changes tao this variable will not be saved!) -# This variable contains the problem data. It is a hash pointer with the -# following values (not all values shown) -# - $problem->status : the score of the current problem -# - $problem->problem_id : the id of the current problem -# - $problem->set_id : the id of the set containing the problem -# - $problem->num_correct : the number of correct attempts -# - $problem->num_incorrect : the number of incorrect attempts -# - $problem->max_attempts : the maximum number of allowed attempts -# -# - $set : the set data (changes to this variable will not be saved!) -# This variable contains the set data. it is a hash pointer with the -# following values. (not all values shown) -# - $set->open_date : when the set was open -# - $set->due_date : when the set is due -# -# - @setProblems : the problem data for all the problems from this set. -# (changes to this variable will not be saved!) -# This is an array of problem hashes. Each element of the array has the -# save hash keys as the $problem variable above -# -# - $counter : the users counter associated to this achievement -# (changes to this variable *will* be saved!) -# If this achievement has a counter associated to it (i.e. solve 20 problems) -# then this is where you store the students counter for this achievement. -# This variable will initally start as '' -# -# - $maxCounter : the goal for the $counter variable for this achievement -# (changes to this variable will not be saved!) -# If this achievement has a counter associated to it then this variable -# contains the goal for the counter. Your achievement should return 1 -# when $counter >= $maxCounter. These two variables are used to show a -# progress bar for the achievement. -# -# - $localData : this is a hash which stores data for this user and achievement -# (changes to this variable *will* be saved!) -# This hash will persist from evaluation to evaluation. You can store whatever -# you like in here and it can be accessed next time this evaluator is run. -# Two things to keep in mind. The data in this hash will *not* be accessable -# by other achievements. If you plan to store something in this hash you have -# to write code to initialize the data. -# -# - $globalData : this is a hash which stores data for all achievements -# (changes to this variable *will* be saved!) -# This hash will persist from evaluation to evaluation and, like $localData, -# you can store whatever you like in here. This data will be accessable from -# *every* achievement and is unique to the user. Like $localData, you need to -# initialize any variable you plan on using in this hash. There are two -# variables stored in this hash that are maintained by the system. -# - $globalData->{completeSets} : This is the number of sets which the student -# has earned 100% on -# - $globalData->{completeProblems} : This is the number of problems which the -# student has earned 100% on -# Warning: The achievements are always evaluated in the order they are listed -# on the Instructors achievement editor page. To make matters more -# complicated, achievements which have already been earned are not evaluated -# at all. The up-shot of this is that when modifying variables in -# $globalData you need to either write your code so it doesnt matter which -# order the evaluators are run in, or you need to pay very close attention -# to which evaluators are run and when. \ No newline at end of file diff --git a/courses.dist/modelCourse/templates/achievements/complete_one_problem.at b/courses.dist/modelCourse/templates/achievements/complete_one_problem.at deleted file mode 100644 index cf1008b35..000000000 --- a/courses.dist/modelCourse/templates/achievements/complete_one_problem.at +++ /dev/null @@ -1,72 +0,0 @@ -# This is a "solved n problems achievement. Normally we would have to deal -# with the counter variable, but since n = 1 we dont have to - -# Achievement earned if they did the problem correctly -if ($problem->status == 1) { - return 1 -} else { - return 0; -} - -# Variable Descriptions: -# - $problem : the problem data (changes to this variable will not be saved!) -# This variable contains the problem data. It is a hash pointer with the -# following values (not all values shown) -# - $problem->status : the score of the current problem -# - $problem->problem_id : the id of the current problem -# - $problem->set_id : the id of the set containing the problem -# - $problem->num_correct : the number of correct attempts -# - $problem->num_incorrect : the number of incorrect attempts -# - $problem->last_answer : the last answer submitted -# - $problem->max_attempts : the maximum number of allowed attempts -# -# - $set : the set data (changes to this variable will not be saved!) -# This variable contains the set data. it is a hash pointer with the -# following values. (not all values shown) -# - $set->open_date : when the set was open -# - $set->due_date : when the set is due -# -# - @setProblems : the problem data for all the problems from this set. -# (changes to this variable will not be saved!) -# This is an array of problem hashes. Each element of the array has the -# save hash keys as the $problem variable above -# -# - $counter : the users counter associated to this achievement -# (changes to this variable *will* be saved!) -# If this achievement has a counter associated to it (i.e. solve 20 problems) -# then this is where you store the students counter for this achievement. -# This variable will initally start as '' -# -# - $maxCounter : the goal for the $counter variable for this achievement -# (changes to this variable will not be saved!) -# If this achievement has a counter associated to it then this variable -# contains the goal for the counter. Your achievement should return 1 -# when $counter >= $maxCounter. These two variables are used to show a -# progress bar for the achievement. -# -# - $localData : this is a hash which stores data for this user and achievement -# (changes to this variable *will* be saved!) -# This hash will persist from evaluation to evaluation. You can store whatever -# you like in here and it can be accessed next time this evaluator is run. -# Two things to keep in mind. The data in this hash will *not* be accessable -# by other achievements. If you plan to store something in this hash you have -# to write code to initialize the data. -# -# - $globalData : this is a hash which stores data for all achievements -# (changes to this variable *will* be saved!) -# This hash will persist from evaluation to evaluation and, like $localData, -# you can store whatever you like in here. This data will be accessable from -# *every* achievement and is unique to the user. Like $localData, you need to -# initialize any variable you plan on using in this hash. There are two -# variables stored in this hash that are maintained by the system. -# - $globalData->completeSets : This is the number of sets which the student -# has earned 100% on -# - $globalData->complete Problems : This is the number of problems which the -# student has earned 100% on -# Warning: The achievements are always evaluated in the order they are listed -# on the Instructors achievement editor page. To make matters more -# complicated, achievements which have already been earned are not evaluated -# at all. The up-shot of this is that when modifying variables in -# $globalData you need to either write your code so it doesnt matter which -# order the evaluators are run in, or you need to pay very close attention -# to which evaluators are run and when. \ No newline at end of file diff --git a/courses.dist/modelCourse/templates/achievements/complete_one_set.at b/courses.dist/modelCourse/templates/achievements/complete_one_set.at deleted file mode 100644 index 9b8cc84d4..000000000 --- a/courses.dist/modelCourse/templates/achievements/complete_one_set.at +++ /dev/null @@ -1,70 +0,0 @@ -# This is a "solved n sets" achievement. However, since n=1 we just check to -# see if the student has solved a set - -if ($globalData->{'completeSets'} >= 1) { - return 1 -} else { - return 0; -} - -# Variable Descriptions: -# - $problem : the problem data (changes to this variable will not be saved!) -# This variable contains the problem data. It is a hash pointer with the -# following values (not all values shown) -# - $problem->status : the score of the current problem -# - $problem->problem_id : the id of the current problem -# - $problem->set_id : the id of the set containing the problem -# - $problem->num_correct : the number of correct attempts -# - $problem->num_incorrect : the number of incorrect attempts -# - $problem->max_attempts : the maximum number of allowed attempts -# -# - $set : the set data (changes to this variable will not be saved!) -# This variable contains the set data. it is a hash pointer with the -# following values. (not all values shown) -# - $set->open_date : when the set was open -# - $set->due_date : when the set is due -# -# - @setProblems : the problem data for all the problems from this set. -# (changes to this variable will not be saved!) -# This is an array of problem hashes. Each element of the array has the -# save hash keys as the $problem variable above -# -# - $counter : the users counter associated to this achievement -# (changes to this variable *will* be saved!) -# If this achievement has a counter associated to it (i.e. solve 20 problems) -# then this is where you store the students counter for this achievement. -# This variable will initally start as '' -# -# - $maxCounter : the goal for the $counter variable for this achievement -# (changes to this variable will not be saved!) -# If this achievement has a counter associated to it then this variable -# contains the goal for the counter. Your achievement should return 1 -# when $counter >= $maxCounter. These two variables are used to show a -# progress bar for the achievement. -# -# - $localData : this is a hash which stores data for this user and achievement -# (changes to this variable *will* be saved!) -# This hash will persist from evaluation to evaluation. You can store whatever -# you like in here and it can be accessed next time this evaluator is run. -# Two things to keep in mind. The data in this hash will *not* be accessable -# by other achievements. If you plan to store something in this hash you have -# to write code to initialize the data. -# -# - $globalData : this is a hash which stores data for all achievements -# (changes to this variable *will* be saved!) -# This hash will persist from evaluation to evaluation and, like $localData, -# you can store whatever you like in here. This data will be accessable from -# *every* achievement and is unique to the user. Like $localData, you need to -# initialize any variable you plan on using in this hash. There are two -# variables stored in this hash that are maintained by the system. -# - $globalData->{completeSets} : This is the number of sets which the student -# has earned 100% on -# - $globalData->{completeProblems} : This is the number of problems which the -# student has earned 100% on -# Warning: The achievements are always evaluated in the order they are listed -# on the Instructors achievement editor page. To make matters more -# complicated, achievements which have already been earned are not evaluated -# at all. The up-shot of this is that when modifying variables in -# $globalData you need to either write your code so it doesnt matter which -# order the evaluators are run in, or you need to pay very close attention -# to which evaluators are run and when. \ No newline at end of file diff --git a/courses.dist/modelCourse/templates/achievements/complete_ten_sets.at b/courses.dist/modelCourse/templates/achievements/complete_ten_sets.at deleted file mode 100644 index c5d58175a..000000000 --- a/courses.dist/modelCourse/templates/achievements/complete_ten_sets.at +++ /dev/null @@ -1,74 +0,0 @@ -# This is a "solved n problems achievement. Notice how we update $counter -# (even though the appropriate variable is already given to use in -# ($globalData) so that the achievement progress bar works correctly. - -# Update counter from globalData -$counter = $globalData->{'completeSets'}; - -if ($counter >= $maxCounter) { - return 1 -} else { - return 0; -} - -# Variable Descriptions: -# - $problem : the problem data (changes tao this variable will not be saved!) -# This variable contains the problem data. It is a hash pointer with the -# following values (not all values shown) -# - $problem->status : the score of the current problem -# - $problem->problem_id : the id of the current problem -# - $problem->set_id : the id of the set containing the problem -# - $problem->num_correct : the number of correct attempts -# - $problem->num_incorrect : the number of incorrect attempts -# - $problem->max_attempts : the maximum number of allowed attempts -# -# - $set : the set data (changes to this variable will not be saved!) -# This variable contains the set data. it is a hash pointer with the -# following values. (not all values shown) -# - $set->open_date : when the set was open -# - $set->due_date : when the set is due -# -# - @setProblems : the problem data for all the problems from this set. -# (changes to this variable will not be saved!) -# This is an array of problem hashes. Each element of the array has the -# save hash keys as the $problem variable above -# -# - $counter : the users counter associated to this achievement -# (changes to this variable *will* be saved!) -# If this achievement has a counter associated to it (i.e. solve 20 problems) -# then this is where you store the students counter for this achievement. -# This variable will initally start as '' -# -# - $maxCounter : the goal for the $counter variable for this achievement -# (changes to this variable will not be saved!) -# If this achievement has a counter associated to it then this variable -# contains the goal for the counter. Your achievement should return 1 -# when $counter >= $maxCounter. These two variables are used to show a -# progress bar for the achievement. -# -# - $localData : this is a hash which stores data for this user and achievement -# (changes to this variable *will* be saved!) -# This hash will persist from evaluation to evaluation. You can store whatever -# you like in here and it can be accessed next time this evaluator is run. -# Two things to keep in mind. The data in this hash will *not* be accessable -# by other achievements. If you plan to store something in this hash you have -# to write code to initialize the data. -# -# - $globalData : this is a hash which stores data for all achievements -# (changes to this variable *will* be saved!) -# This hash will persist from evaluation to evaluation and, like $localData, -# you can store whatever you like in here. This data will be accessable from -# *every* achievement and is unique to the user. Like $localData, you need to -# initialize any variable you plan on using in this hash. There are two -# variables stored in this hash that are maintained by the system. -# - $globalData->{completeSets} : This is the number of sets which the student -# has earned 100% on -# - $globalData->{completeProblems} : This is the number of problems which the -# student has earned 100% on -# Warning: The achievements are always evaluated in the order they are listed -# on the Instructors achievement editor page. To make matters more -# complicated, achievements which have already been earned are not evaluated -# at all. The up-shot of this is that when modifying variables in -# $globalData you need to either write your code so it doesnt matter which -# order the evaluators are run in, or you need to pay very close attention -# to which evaluators are run and when. \ No newline at end of file diff --git a/courses.dist/modelCourse/templates/achievements/complete_thirty_sets.at b/courses.dist/modelCourse/templates/achievements/complete_thirty_sets.at deleted file mode 100644 index c5d58175a..000000000 --- a/courses.dist/modelCourse/templates/achievements/complete_thirty_sets.at +++ /dev/null @@ -1,74 +0,0 @@ -# This is a "solved n problems achievement. Notice how we update $counter -# (even though the appropriate variable is already given to use in -# ($globalData) so that the achievement progress bar works correctly. - -# Update counter from globalData -$counter = $globalData->{'completeSets'}; - -if ($counter >= $maxCounter) { - return 1 -} else { - return 0; -} - -# Variable Descriptions: -# - $problem : the problem data (changes tao this variable will not be saved!) -# This variable contains the problem data. It is a hash pointer with the -# following values (not all values shown) -# - $problem->status : the score of the current problem -# - $problem->problem_id : the id of the current problem -# - $problem->set_id : the id of the set containing the problem -# - $problem->num_correct : the number of correct attempts -# - $problem->num_incorrect : the number of incorrect attempts -# - $problem->max_attempts : the maximum number of allowed attempts -# -# - $set : the set data (changes to this variable will not be saved!) -# This variable contains the set data. it is a hash pointer with the -# following values. (not all values shown) -# - $set->open_date : when the set was open -# - $set->due_date : when the set is due -# -# - @setProblems : the problem data for all the problems from this set. -# (changes to this variable will not be saved!) -# This is an array of problem hashes. Each element of the array has the -# save hash keys as the $problem variable above -# -# - $counter : the users counter associated to this achievement -# (changes to this variable *will* be saved!) -# If this achievement has a counter associated to it (i.e. solve 20 problems) -# then this is where you store the students counter for this achievement. -# This variable will initally start as '' -# -# - $maxCounter : the goal for the $counter variable for this achievement -# (changes to this variable will not be saved!) -# If this achievement has a counter associated to it then this variable -# contains the goal for the counter. Your achievement should return 1 -# when $counter >= $maxCounter. These two variables are used to show a -# progress bar for the achievement. -# -# - $localData : this is a hash which stores data for this user and achievement -# (changes to this variable *will* be saved!) -# This hash will persist from evaluation to evaluation. You can store whatever -# you like in here and it can be accessed next time this evaluator is run. -# Two things to keep in mind. The data in this hash will *not* be accessable -# by other achievements. If you plan to store something in this hash you have -# to write code to initialize the data. -# -# - $globalData : this is a hash which stores data for all achievements -# (changes to this variable *will* be saved!) -# This hash will persist from evaluation to evaluation and, like $localData, -# you can store whatever you like in here. This data will be accessable from -# *every* achievement and is unique to the user. Like $localData, you need to -# initialize any variable you plan on using in this hash. There are two -# variables stored in this hash that are maintained by the system. -# - $globalData->{completeSets} : This is the number of sets which the student -# has earned 100% on -# - $globalData->{completeProblems} : This is the number of problems which the -# student has earned 100% on -# Warning: The achievements are always evaluated in the order they are listed -# on the Instructors achievement editor page. To make matters more -# complicated, achievements which have already been earned are not evaluated -# at all. The up-shot of this is that when modifying variables in -# $globalData you need to either write your code so it doesnt matter which -# order the evaluators are run in, or you need to pay very close attention -# to which evaluators are run and when. \ No newline at end of file diff --git a/courses.dist/modelCourse/templates/achievements/complete_twenty_sets.at b/courses.dist/modelCourse/templates/achievements/complete_twenty_sets.at deleted file mode 100644 index c5d58175a..000000000 --- a/courses.dist/modelCourse/templates/achievements/complete_twenty_sets.at +++ /dev/null @@ -1,74 +0,0 @@ -# This is a "solved n problems achievement. Notice how we update $counter -# (even though the appropriate variable is already given to use in -# ($globalData) so that the achievement progress bar works correctly. - -# Update counter from globalData -$counter = $globalData->{'completeSets'}; - -if ($counter >= $maxCounter) { - return 1 -} else { - return 0; -} - -# Variable Descriptions: -# - $problem : the problem data (changes tao this variable will not be saved!) -# This variable contains the problem data. It is a hash pointer with the -# following values (not all values shown) -# - $problem->status : the score of the current problem -# - $problem->problem_id : the id of the current problem -# - $problem->set_id : the id of the set containing the problem -# - $problem->num_correct : the number of correct attempts -# - $problem->num_incorrect : the number of incorrect attempts -# - $problem->max_attempts : the maximum number of allowed attempts -# -# - $set : the set data (changes to this variable will not be saved!) -# This variable contains the set data. it is a hash pointer with the -# following values. (not all values shown) -# - $set->open_date : when the set was open -# - $set->due_date : when the set is due -# -# - @setProblems : the problem data for all the problems from this set. -# (changes to this variable will not be saved!) -# This is an array of problem hashes. Each element of the array has the -# save hash keys as the $problem variable above -# -# - $counter : the users counter associated to this achievement -# (changes to this variable *will* be saved!) -# If this achievement has a counter associated to it (i.e. solve 20 problems) -# then this is where you store the students counter for this achievement. -# This variable will initally start as '' -# -# - $maxCounter : the goal for the $counter variable for this achievement -# (changes to this variable will not be saved!) -# If this achievement has a counter associated to it then this variable -# contains the goal for the counter. Your achievement should return 1 -# when $counter >= $maxCounter. These two variables are used to show a -# progress bar for the achievement. -# -# - $localData : this is a hash which stores data for this user and achievement -# (changes to this variable *will* be saved!) -# This hash will persist from evaluation to evaluation. You can store whatever -# you like in here and it can be accessed next time this evaluator is run. -# Two things to keep in mind. The data in this hash will *not* be accessable -# by other achievements. If you plan to store something in this hash you have -# to write code to initialize the data. -# -# - $globalData : this is a hash which stores data for all achievements -# (changes to this variable *will* be saved!) -# This hash will persist from evaluation to evaluation and, like $localData, -# you can store whatever you like in here. This data will be accessable from -# *every* achievement and is unique to the user. Like $localData, you need to -# initialize any variable you plan on using in this hash. There are two -# variables stored in this hash that are maintained by the system. -# - $globalData->{completeSets} : This is the number of sets which the student -# has earned 100% on -# - $globalData->{completeProblems} : This is the number of problems which the -# student has earned 100% on -# Warning: The achievements are always evaluated in the order they are listed -# on the Instructors achievement editor page. To make matters more -# complicated, achievements which have already been earned are not evaluated -# at all. The up-shot of this is that when modifying variables in -# $globalData you need to either write your code so it doesnt matter which -# order the evaluators are run in, or you need to pay very close attention -# to which evaluators are run and when. \ No newline at end of file diff --git a/courses.dist/modelCourse/templates/achievements/crack_o_dawn.at b/courses.dist/modelCourse/templates/achievements/crack_o_dawn.at deleted file mode 100644 index 94e2d3322..000000000 --- a/courses.dist/modelCourse/templates/achievements/crack_o_dawn.at +++ /dev/null @@ -1,79 +0,0 @@ -# checks to see if a studen finished a set between 5AM and 7AM - my @timeData = localtime(time); - - if ($timeData[2] < 5 || $timeData[2] > 6) { - return 0; - } - - #if it is check to see if we have finished the set - - foreach my $problemRecord (@setProblems) { - if ($problemRecord->status != 1) { - return 0; - } - } - - return 1; - -# -You have access to a variety of variables: -# - $problem : the problem data (changes to this variable will not be saved!) -# This variable contains the problem data. It is a hash pointer with the -# following values (not all values shown) -# - $problem->status : the score of the current problem -# - $problem->problem_id : the id of the current problem -# - $problem->set_id : the id of the set containing the problem -# - $problem->num_correct : the number of correct attempts -# - $problem->num_incorrect : the number of incorrect attempts -# - $problem->last_answer : the last answer submitted -# - $problem->max_attempts : the maximum number of allowed attempts -# -# - $set : the set data (changes to this variable will not be saved!) -# This variable contains the set data. it is a hash pointer with the -# following values. (not all values shown) -# - $set->open_date : when the set was open -# - $set->due_date : when the set is due -# -# - @setProblems : the problem data for all the problems from this set. -# (changes to this variable will not be saved!) -# This is an array of problem hashes. Each element of the array has the -# save hash keys as the $problem variable above -# -# - $counter : the users counter associated to this achievement -# (changes to this variable *will* be saved!) -# If this achievement has a counter associated to it (i.e. solve 20 problems) -# then this is where you store the students counter for this achievement. -# This variable will initally start as '' -# -# - $maxCounter : the goal for the $counter variable for this achievement -# (changes to this variable will not be saved!) -# If this achievement has a counter associated to it then this variable -# contains the goal for the counter. Your achievement should return 1 -# when $counter >= $maxCounter. These two variables are used to show a -# progress bar for the achievement. -# -# - $localData : this is a hash which stores data for this user and achievement -# (changes to this variable *will* be saved!) -# This hash will persist from evaluation to evaluation. You can store whatever -# you like in here and it can be accessed next time this evaluator is run. -# Two things to keep in mind. The data in this hash will *not* be accessable -# by other achievements. If you plan to store something in this hash you have -# to write code to initialize the data. -# -# - $globalData : this is a hash which stores data for all achievements -# (changes to this variable *will* be saved!) -# This hash will persist from evaluation to evaluation and, like $localData, -# you can store whatever you like in here. This data will be accessable from -# *every* achievement and is unique to the user. Like $localData, you need to -# initialize any variable you plan on using in this hash. There are two -# variables stored in this hash that are maintained by the system. -# - $globalData->{completeSets} : This is the number of sets which the student -# has earned 100% on -# - $globalData->{completeProblems} : This is the number of problems which the -# student has earned 100% on -# Warning: The achievements are always evaluated in the order they are listed -# on the Instructors achievement editor page. To make matters more -# complicated, achievements which have already been earned are not evaluated -# at all. The up-shot of this is that when modifying variables in -# $globalData you need to either write your code so it doesnt matter which -# order the evaluators are run in, or you need to pay very close attention -# to which evaluators are run and when. \ No newline at end of file diff --git a/courses.dist/modelCourse/templates/achievements/curvy_geometry.at b/courses.dist/modelCourse/templates/achievements/curvy_geometry.at deleted file mode 100644 index e637e74ca..000000000 --- a/courses.dist/modelCourse/templates/achievements/curvy_geometry.at +++ /dev/null @@ -1,84 +0,0 @@ -#This problem checks to see if a particular problem from a list of valid -# sets and problems has been solved. (You would edit this file to say which -# sets and problems count.) - -#constants -my %validproblems = ( - 'SetNameHere' => { #now you show which problems are valid like: - '2' => 1, - '1' => 1, }, #and put more sets here - ); - -#check and see if this problem was solved -if ($validproblems{$problem->set_id} && - $validproblems{$problem->set_id}{$problem->problem_id} && - $problem->status == 1 && - $problem->num_correct == 1) { - return 1; - } - - return 0; - - -# -You have access to a variety of variables: -# - $problem : the problem data (changes to this variable will not be saved!) -# This variable contains the problem data. It is a hash pointer with the -# following values (not all values shown) -# - $problem->status : the score of the current problem -# - $problem->problem_id : the id of the current problem -# - $problem->set_id : the id of the set containing the problem -# - $problem->num_correct : the number of correct attempts -# - $problem->num_incorrect : the number of incorrect attempts -# - $problem->last_answer : the last answer submitted -# - $problem->max_attempts : the maximum number of allowed attempts -# -# - $set : the set data (changes to this variable will not be saved!) -# This variable contains the set data. it is a hash pointer with the -# following values. (not all values shown) -# - $set->open_date : when the set was open -# - $set->due_date : when the set is due -# -# - @setProblems : the problem data for all the problems from this set. -# (changes to this variable will not be saved!) -# This is an array of problem hashes. Each element of the array has the -# save hash keys as the $problem variable above -# -# - $counter : the users counter associated to this achievement -# (changes to this variable *will* be saved!) -# If this achievement has a counter associated to it (i.e. solve 20 problems) -# then this is where you store the students counter for this achievement. -# This variable will initally start as '' -# -# - $maxCounter : the goal for the $counter variable for this achievement -# (changes to this variable will not be saved!) -# If this achievement has a counter associated to it then this variable -# contains the goal for the counter. Your achievement should return 1 -# when $counter >= $maxCounter. These two variables are used to show a -# progress bar for the achievement. -# -# - $localData : this is a hash which stores data for this user and achievement -# (changes to this variable *will* be saved!) -# This hash will persist from evaluation to evaluation. You can store whatever -# you like in here and it can be accessed next time this evaluator is run. -# Two things to keep in mind. The data in this hash will *not* be accessable -# by other achievements. If you plan to store something in this hash you have -# to write code to initialize the data. -# -# - $globalData : this is a hash which stores data for all achievements -# (changes to this variable *will* be saved!) -# This hash will persist from evaluation to evaluation and, like $localData, -# you can store whatever you like in here. This data will be accessable from -# *every* achievement and is unique to the user. Like $localData, you need to -# initialize any variable you plan on using in this hash. There are two -# variables stored in this hash that are maintained by the system. -# - $globalData->{completeSets} : This is the number of sets which the student -# has earned 100% on -# - $globalData->{completeProblems} : This is the number of problems which the -# student has earned 100% on -# Warning: The achievements are always evaluated in the order they are listed -# on the Instructors achievement editor page. To make matters more -# complicated, achievements which have already been earned are not evaluated -# at all. The up-shot of this is that when modifying variables in -# $globalData you need to either write your code so it doesnt matter which -# order the evaluators are run in, or you need to pay very close attention -# to which evaluators are run and when. diff --git a/courses.dist/modelCourse/templates/achievements/default_achievements.axp b/courses.dist/modelCourse/templates/achievements/default_achievements.axp deleted file mode 100644 index af4b4c3da..000000000 --- a/courses.dist/modelCourse/templates/achievements/default_achievements.axp +++ /dev/null @@ -1,62 +0,0 @@ -01_night_owl, Night Owl, secret, Finish a homework set between 12PM and 2AM., 10, , night_owl.at, night_owl.png, -02_crack_o_dawn, Crack O' Dawn, secret, Finish a homework set between 5AM and 7AM., 10, , crack_o_dawn.at, crack_o_dawn.png, -03_on_the_hour, Watching the Clock, secret, Finish a problem at the top of the hour., 10, , on_the_hour.at, on_the_hour.png, -04_last_minute, Last Minute Math, secret, Complete a homework within 30 minutes of the due date., 10, , last_minute.at, last_minute.png, -05_still_not_right, Its Still Not Right, secret, Input the exact same (incorrect) answer 10 times in a row., 5, , still_not_right.at, still_not_right.png, -06_persistance, Persistence is not Futile, secret, Solve a problem after 20 incorrect submissions., 10, , persistance.at, persistance.png, -07_super_persistance, Green Never Looked So Good, secret, Solve a problem after 100 incorrect submissions., 10, , super_persistance.at, super_persistance.png, -08_super_speed_math, Careful Planning and Quick Fingers, secret, Spend less than 10 minutes entering answers to a homework set., 20, , super_speed_math.at, super_speed_math.png, -09_hows_your_finger, Hows Your Finger?, secret, Have more than 250 submissions on a homework problem. , 10, , hows_your_finger.at, hows_your_finger.png, -01_one_click, One Click Is All I Need, 01_one_timer, Earn 100% on a problem in one attempt., 10, , one_click.at, one_click.png, -02_on_one_hand, On One Hand, 01_one_timer, Finish a homework set with less than 5 incorrect submissions., 10, , on_one_hand.at, on_one_hand.png, -03_seeing_green, Seeing Green, 01_one_timer, Finish a homework set with no incorrect submissions., 20, , seeing_green.at, seeing_green.png, -04_early_bird, The Early Bird, 01_one_timer, Finish a homework set within 24 hours of it opening., 10, , early_bird.at, early_bird.png, -05_really_early_bird, The Really Early Bird, 01_one_timer, Finish a homework set within 2 hours of it opening., 20, , really_early_bird.at, really_early_bird.png, -06_back_for_more, Back For More, 01_one_timer, Retry a problem after a 8 hour break., 10, , back_for_more.at, back_for_more.png, -07_chipping_away, Just Keep Chipping Away, 01_one_timer, Work on a single homework set over the course of 48 hours., 10, , chipping_away.at, chipping_away.png, -08_speed_mather, Go Speed Math-er, 01_one_timer, Spend less than 1 hour working on a homework set., 10, , speed_mather.at, speed_mather.png, -09_three_in_a_row, Three in a Row, 01_one_timer, Complete 3 problems in a row with no incorrect answers., 10, 3, three_in_a_row.at, one_click.png, -10_on_fire, Your on Fire!, 01_one_timer, Complete 10 problems in a row with no incorrect answers., 20, 10, on_fire.at, on_fire.png, -01_reaching_a_limit, Reaching a Limit, 02_content, Solve 10 basic limit problems., 10, 10, reaching_a_limit.at, reaching_a_limit.png, -02_by_definition, By Definition, 02_content, Evaluate a derivative using the limit definition., 10, , by_definition.at, by_definition.png, -03_derivative_master, Derivative Master, 02_content, Solve 30 basic derivatives., 20, 30, derivative_master.at, derivative_master.png, -04_optimizer_prime, Optimizer Prime, 02_content, Solve a particularly hard optimization problem., 10, , optimizer_prime.at, optimizer_prime.png, -05_its_all_relative, Its All Relative, 02_content, Solve a particularly hard related rates problem., 10, , its_all_relative.at, its_all_relative.png, -06_pattern_recognition, Pattern Recognition, 02_content, Find the nth derivative of a function., 10, , pattern_recognition.at, pattern_recognition.png, -07_the_lhopital, Take me to the L'Hopital, 02_content, Use L'Hopital's Rule to evaluate a limit., 10, , the_lhopital.at, the_lhopital.png, -08_the_fundamentals, Covering the Fundamentals, 02_content, Use the Fundamental Theorem of Calculus., 10, , the_fundamentals.at, the_fundamentals.png, -09_curvy_geometry, Curvy Geometry, 02_content, Find the area between two curves., 10, , curvy_geometry.at, curvy_geometry.png, -10_doing_it_backwards, Doing It Backwards, 02_content, Solve 5 u-substitution problems., 10, 5, doing_it_backwards.at, doing_it_backwards.png, -01_complete_one_set, One Set Wonder, 03_complete_sets, Get 100% on one homework set., 10, , complete_one_set.at, complete_one_set.png, -02_complete_five_sets, High Five, 03_complete_sets, Get 100% on five homework sets., 10, 5, complete_five_sets.at, complete_five_sets.png, -03_complete_ten_sets, One For Each Finger, 03_complete_sets, Get 100% on ten homework sets., 10, 10, complete_ten_sets.at, complete_ten_sets.png, -04_complete_twenty_sets, Mathbox Twenty, 03_complete_sets, Get 100% on twenty homework sets., 20, 20, complete_twenty_sets.at, complete_twenty_sets.png, -05_complete_thirty_sets, The Long Road, 03_complete_sets, Get 100% on thirty homework sets., 20, 30, complete_thirty_sets.at, complete_thirty_sets.png, -06_complete_all_sets, Perfection, 03_complete_sets, Get 100% on all homework sets., 30, 35, complete_all_sets.at, complete_all_sets.png, -01_challenge_one, Challenge One Complete, 04_challenge, Finish the first challenge problem., 10, , challenge_one.at, challenge_one.png, -02_challenge_two, Challenge Two Complete, 04_challenge, Finish the second challenge problem., 10, , challenge_two.at, challenge_two.png, -03_challenge_three, Challenge Three Complete, 04_challenge, Finish the third challenge problem., 10, , challenge_three.at, challenge_three.png, -04_challenge_four, Challenge Four Complete, 04_challenge, Finish the fourth challenge problem., 10, , challenge_four.at, challenge_four.png, -05_challenge_five, Challenge Five Complete, 04_challenge, Finish the fifth challenge problem., 10, , challenge_five.at, challenge_five.png, -06_challenge_six, Challenge Six Complete, 04_challenge, Finish the sixth challenge problem., 10, , challenge_six.at, challenge_six.png, -07_challenge_seven, Challenge Seven Complete, 04_challenge, Finish the seventh challenge problem., 10, , challenge_seven.at, challenge_seven.png, -08_challenge_eight, Challenge Eight Complete, 04_challenge, Finish the eighth challenge problem., 10, , challenge_eight.at, challenge_eight.png, -09_challenge_nine, Challenge Nine Complete, 04_challenge, Finish the ninth challenge problem., 10, , challenge_nine.at, challenge_nine.png, -10_challenge_ten, Challenge Ten Complete, 04_challenge, Finish the tenth challenge problem., 10, , challenge_ten.at, challenge_ten.png, -11_challenger, Challenger, 04_challenge, Finish all of the challenge problems., 10, 20, challenger.at, challenger.png, -01_complete_one_problem, The First Step, 05_complete_problems, Earn 100% on a homework problem., 10, , complete_one_problem.at, complete_one_problem.png, -02_complete_10_problems, Perfect 10, 05_complete_problems, Earn 100% on 10 homework problems., 10, 10, complete_10_problems.at, complete_10_problems.png, -03_complete_25_problems, Twenty-Five Questions, 05_complete_problems, Earn 100% on 25 homework problems., 10, 25, complete_25_problems.at, complete_25_problems.png, -04_complete_50_problems, 50 Ways to Solve a Math Problem, 05_complete_problems, Earn 100% on 50 homework problems., 10, 50, complete_50_problems.at, complete_50_problems.png, -05_complete_100_problems, Seeing Benjamins, 05_complete_problems, Earn 100% on 100 homework problems., 20, 100, complete_100_problems.at, complete_100_problems.png, -06_complete_150_problems, Sesqui-Centeni-Problems, 05_complete_problems, Earn 100% on 150 homework problems., 20, 150, complete_150_problems.at, complete_150_problems.png, -01_level_one, Level 1 Calculus Initiate, level, , , , level_one.at, level_one.png, -02_level_two, Level 2 Calculus Novice, level, , , , level_two.at, level_two.png, -03_level_three, Level 3 Calculus Apprentice, level, , , , level_three.at, level_three.png, -04_level_four, Level 4 Calculus Journeyman, level, , , , level_four.at, level_four.png, -05_level_five, Level 5 Calculus Fellowcraft, level, , , , level_five.at, level_five.png, -06_level_six, Level 6 Calculus Adept, level, , , , level_six.at, level_six.png, -07_level_seven, Level 7 Calculus Craftsman, level, , , , level_seven.at, level_seven.png, -08_level_eight, Level 8 Calculus Artesian, level, , , , level_eight.at, level_eight.png, -09_level_nine, Level 9 Calculus Specialist, level, , , , level_nine.at, level_nine.png, -10_level_ten, Level 10 Calculus Professor, level, , , , level_ten.at, level_ten.png, diff --git a/courses.dist/modelCourse/templates/achievements/derivative_master.at b/courses.dist/modelCourse/templates/achievements/derivative_master.at deleted file mode 100644 index e1b17b06b..000000000 --- a/courses.dist/modelCourse/templates/achievements/derivative_master.at +++ /dev/null @@ -1,88 +0,0 @@ -#This problem checks to see if a particular problem from a list of valid -# sets and problems has been solved. If it has then it updates the counter -#(You would edit this file to say which sets and problems count.) - -#constants -my %validproblems = ( - 'SetNameHere' => { #now you show which problems are valid like: - '2' => 1, - '1' => 1, }, #and put more sets here - ); - -#check and see if this problem was solved -if ($validproblems{$problem->set_id} && - $validproblems{$problem->set_id}{$problem->problem_id} && - $problem->status == 1 && - $problem->num_correct == 1) { - #update counter; - $counter++; - } - -if ($counter >= $maxCounter) { - return 1; -} else { - return 0; -} - -# -You have access to a variety of variables: -# - $problem : the problem data (changes to this variable will not be saved!) -# This variable contains the problem data. It is a hash pointer with the -# following values (not all values shown) -# - $problem->status : the score of the current problem -# - $problem->problem_id : the id of the current problem -# - $problem->set_id : the id of the set containing the problem -# - $problem->num_correct : the number of correct attempts -# - $problem->num_incorrect : the number of incorrect attempts -# - $problem->last_answer : the last answer submitted -# - $problem->max_attempts : the maximum number of allowed attempts -# -# - $set : the set data (changes to this variable will not be saved!) -# This variable contains the set data. it is a hash pointer with the -# following values. (not all values shown) -# - $set->open_date : when the set was open -# - $set->due_date : when the set is due -# -# - @setProblems : the problem data for all the problems from this set. -# (changes to this variable will not be saved!) -# This is an array of problem hashes. Each element of the array has the -# save hash keys as the $problem variable above -# -# - $counter : the users counter associated to this achievement -# (changes to this variable *will* be saved!) -# If this achievement has a counter associated to it (i.e. solve 20 problems) -# then this is where you store the students counter for this achievement. -# This variable will initally start as '' -# -# - $maxCounter : the goal for the $counter variable for this achievement -# (changes to this variable will not be saved!) -# If this achievement has a counter associated to it then this variable -# contains the goal for the counter. Your achievement should return 1 -# when $counter >= $maxCounter. These two variables are used to show a -# progress bar for the achievement. -# -# - $localData : this is a hash which stores data for this user and achievement -# (changes to this variable *will* be saved!) -# This hash will persist from evaluation to evaluation. You can store whatever -# you like in here and it can be accessed next time this evaluator is run. -# Two things to keep in mind. The data in this hash will *not* be accessable -# by other achievements. If you plan to store something in this hash you have -# to write code to initialize the data. -# -# - $globalData : this is a hash which stores data for all achievements -# (changes to this variable *will* be saved!) -# This hash will persist from evaluation to evaluation and, like $localData, -# you can store whatever you like in here. This data will be accessable from -# *every* achievement and is unique to the user. Like $localData, you need to -# initialize any variable you plan on using in this hash. There are two -# variables stored in this hash that are maintained by the system. -# - $globalData->{completeSets} : This is the number of sets which the student -# has earned 100% on -# - $globalData->{completeProblems} : This is the number of problems which the -# student has earned 100% on -# Warning: The achievements are always evaluated in the order they are listed -# on the Instructors achievement editor page. To make matters more -# complicated, achievements which have already been earned are not evaluated -# at all. The up-shot of this is that when modifying variables in -# $globalData you need to either write your code so it doesnt matter which -# order the evaluators are run in, or you need to pay very close attention -# to which evaluators are run and when. diff --git a/courses.dist/modelCourse/templates/achievements/doing_it_backwards.at b/courses.dist/modelCourse/templates/achievements/doing_it_backwards.at deleted file mode 100644 index 716da57d7..000000000 --- a/courses.dist/modelCourse/templates/achievements/doing_it_backwards.at +++ /dev/null @@ -1,89 +0,0 @@ -#This problem checks to see if a particular problem from a list of valid -# sets and problems has been solved. If it has then it updates the counter -#(You would edit this file to say which sets and problems count.) - -#constants -my %validproblems = ( - 'SetNameHere' => { #now you show which problems are valid like: - '2' => 1, - '1' => 1, }, #and put more sets here - ); - -#check and see if this problem was solved -if ($validproblems{$problem->set_id} && - $validproblems{$problem->set_id}{$problem->problem_id} && - $problem->status == 1 && - $problem->num_correct == 1) { - #update counter; - $counter++; - } - -if ($counter >= $maxCounter) { - return 1; -} else { - return 0; -} - - -# -You have access to a variety of variables: -# - $problem : the problem data (changes to this variable will not be saved!) -# This variable contains the problem data. It is a hash pointer with the -# following values (not all values shown) -# - $problem->status : the score of the current problem -# - $problem->problem_id : the id of the current problem -# - $problem->set_id : the id of the set containing the problem -# - $problem->num_correct : the number of correct attempts -# - $problem->num_incorrect : the number of incorrect attempts -# - $problem->last_answer : the last answer submitted -# - $problem->max_attempts : the maximum number of allowed attempts -# -# - $set : the set data (changes to this variable will not be saved!) -# This variable contains the set data. it is a hash pointer with the -# following values. (not all values shown) -# - $set->open_date : when the set was open -# - $set->due_date : when the set is due -# -# - @setProblems : the problem data for all the problems from this set. -# (changes to this variable will not be saved!) -# This is an array of problem hashes. Each element of the array has the -# save hash keys as the $problem variable above -# -# - $counter : the users counter associated to this achievement -# (changes to this variable *will* be saved!) -# If this achievement has a counter associated to it (i.e. solve 20 problems) -# then this is where you store the students counter for this achievement. -# This variable will initally start as '' -# -# - $maxCounter : the goal for the $counter variable for this achievement -# (changes to this variable will not be saved!) -# If this achievement has a counter associated to it then this variable -# contains the goal for the counter. Your achievement should return 1 -# when $counter >= $maxCounter. These two variables are used to show a -# progress bar for the achievement. -# -# - $localData : this is a hash which stores data for this user and achievement -# (changes to this variable *will* be saved!) -# This hash will persist from evaluation to evaluation. You can store whatever -# you like in here and it can be accessed next time this evaluator is run. -# Two things to keep in mind. The data in this hash will *not* be accessable -# by other achievements. If you plan to store something in this hash you have -# to write code to initialize the data. -# -# - $globalData : this is a hash which stores data for all achievements -# (changes to this variable *will* be saved!) -# This hash will persist from evaluation to evaluation and, like $localData, -# you can store whatever you like in here. This data will be accessable from -# *every* achievement and is unique to the user. Like $localData, you need to -# initialize any variable you plan on using in this hash. There are two -# variables stored in this hash that are maintained by the system. -# - $globalData->{completeSets} : This is the number of sets which the student -# has earned 100% on -# - $globalData->{completeProblems} : This is the number of problems which the -# student has earned 100% on -# Warning: The achievements are always evaluated in the order they are listed -# on the Instructors achievement editor page. To make matters more -# complicated, achievements which have already been earned are not evaluated -# at all. The up-shot of this is that when modifying variables in -# $globalData you need to either write your code so it doesnt matter which -# order the evaluators are run in, or you need to pay very close attention -# to which evaluators are run and when. diff --git a/courses.dist/modelCourse/templates/achievements/early_bird.at b/courses.dist/modelCourse/templates/achievements/early_bird.at deleted file mode 100644 index 649890e43..000000000 --- a/courses.dist/modelCourse/templates/achievements/early_bird.at +++ /dev/null @@ -1,78 +0,0 @@ -#This checks to see if the student has finished the set within a certain time - - #test to see if it is before 1 day after the open date - if ((time()-$set->open_date) > 86400) { - return 0; - } - - #if it is check to see if we have finished the set - foreach my $problemRecord (@setProblems) { - if ($problemRecord->status != 1) { - return 0; - } - } - - return 1; - -# -You have access to a variety of variables: -# - $problem : the problem data (changes to this variable will not be saved!) -# This variable contains the problem data. It is a hash pointer with the -# following values (not all values shown) -# - $problem->status : the score of the current problem -# - $problem->problem_id : the id of the current problem -# - $problem->set_id : the id of the set containing the problem -# - $problem->num_correct : the number of correct attempts -# - $problem->num_incorrect : the number of incorrect attempts -# - $problem->last_answer : the last answer submitted -# - $problem->max_attempts : the maximum number of allowed attempts -# -# - $set : the set data (changes to this variable will not be saved!) -# This variable contains the set data. it is a hash pointer with the -# following values. (not all values shown) -# - $set->open_date : when the set was open -# - $set->due_date : when the set is due -# -# - @setProblems : the problem data for all the problems from this set. -# (changes to this variable will not be saved!) -# This is an array of problem hashes. Each element of the array has the -# save hash keys as the $problem variable above -# -# - $counter : the users counter associated to this achievement -# (changes to this variable *will* be saved!) -# If this achievement has a counter associated to it (i.e. solve 20 problems) -# then this is where you store the students counter for this achievement. -# This variable will initally start as '' -# -# - $maxCounter : the goal for the $counter variable for this achievement -# (changes to this variable will not be saved!) -# If this achievement has a counter associated to it then this variable -# contains the goal for the counter. Your achievement should return 1 -# when $counter >= $maxCounter. These two variables are used to show a -# progress bar for the achievement. -# -# - $localData : this is a hash which stores data for this user and achievement -# (changes to this variable *will* be saved!) -# This hash will persist from evaluation to evaluation. You can store whatever -# you like in here and it can be accessed next time this evaluator is run. -# Two things to keep in mind. The data in this hash will *not* be accessable -# by other achievements. If you plan to store something in this hash you have -# to write code to initialize the data. -# -# - $globalData : this is a hash which stores data for all achievements -# (changes to this variable *will* be saved!) -# This hash will persist from evaluation to evaluation and, like $localData, -# you can store whatever you like in here. This data will be accessable from -# *every* achievement and is unique to the user. Like $localData, you need to -# initialize any variable you plan on using in this hash. There are two -# variables stored in this hash that are maintained by the system. -# - $globalData->{completeSets} : This is the number of sets which the student -# has earned 100% on -# - $globalData->{completeProblems} : This is the number of problems which the -# student has earned 100% on -# Warning: The achievements are always evaluated in the order they are listed -# on the Instructors achievement editor page. To make matters more -# complicated, achievements which have already been earned are not evaluated -# at all. The up-shot of this is that when modifying variables in -# $globalData you need to either write your code so it doesnt matter which -# order the evaluators are run in, or you need to pay very close attention -# to which evaluators are run and when. \ No newline at end of file diff --git a/courses.dist/modelCourse/templates/achievements/heart_area.at b/courses.dist/modelCourse/templates/achievements/heart_area.at deleted file mode 100644 index e637e74ca..000000000 --- a/courses.dist/modelCourse/templates/achievements/heart_area.at +++ /dev/null @@ -1,84 +0,0 @@ -#This problem checks to see if a particular problem from a list of valid -# sets and problems has been solved. (You would edit this file to say which -# sets and problems count.) - -#constants -my %validproblems = ( - 'SetNameHere' => { #now you show which problems are valid like: - '2' => 1, - '1' => 1, }, #and put more sets here - ); - -#check and see if this problem was solved -if ($validproblems{$problem->set_id} && - $validproblems{$problem->set_id}{$problem->problem_id} && - $problem->status == 1 && - $problem->num_correct == 1) { - return 1; - } - - return 0; - - -# -You have access to a variety of variables: -# - $problem : the problem data (changes to this variable will not be saved!) -# This variable contains the problem data. It is a hash pointer with the -# following values (not all values shown) -# - $problem->status : the score of the current problem -# - $problem->problem_id : the id of the current problem -# - $problem->set_id : the id of the set containing the problem -# - $problem->num_correct : the number of correct attempts -# - $problem->num_incorrect : the number of incorrect attempts -# - $problem->last_answer : the last answer submitted -# - $problem->max_attempts : the maximum number of allowed attempts -# -# - $set : the set data (changes to this variable will not be saved!) -# This variable contains the set data. it is a hash pointer with the -# following values. (not all values shown) -# - $set->open_date : when the set was open -# - $set->due_date : when the set is due -# -# - @setProblems : the problem data for all the problems from this set. -# (changes to this variable will not be saved!) -# This is an array of problem hashes. Each element of the array has the -# save hash keys as the $problem variable above -# -# - $counter : the users counter associated to this achievement -# (changes to this variable *will* be saved!) -# If this achievement has a counter associated to it (i.e. solve 20 problems) -# then this is where you store the students counter for this achievement. -# This variable will initally start as '' -# -# - $maxCounter : the goal for the $counter variable for this achievement -# (changes to this variable will not be saved!) -# If this achievement has a counter associated to it then this variable -# contains the goal for the counter. Your achievement should return 1 -# when $counter >= $maxCounter. These two variables are used to show a -# progress bar for the achievement. -# -# - $localData : this is a hash which stores data for this user and achievement -# (changes to this variable *will* be saved!) -# This hash will persist from evaluation to evaluation. You can store whatever -# you like in here and it can be accessed next time this evaluator is run. -# Two things to keep in mind. The data in this hash will *not* be accessable -# by other achievements. If you plan to store something in this hash you have -# to write code to initialize the data. -# -# - $globalData : this is a hash which stores data for all achievements -# (changes to this variable *will* be saved!) -# This hash will persist from evaluation to evaluation and, like $localData, -# you can store whatever you like in here. This data will be accessable from -# *every* achievement and is unique to the user. Like $localData, you need to -# initialize any variable you plan on using in this hash. There are two -# variables stored in this hash that are maintained by the system. -# - $globalData->{completeSets} : This is the number of sets which the student -# has earned 100% on -# - $globalData->{completeProblems} : This is the number of problems which the -# student has earned 100% on -# Warning: The achievements are always evaluated in the order they are listed -# on the Instructors achievement editor page. To make matters more -# complicated, achievements which have already been earned are not evaluated -# at all. The up-shot of this is that when modifying variables in -# $globalData you need to either write your code so it doesnt matter which -# order the evaluators are run in, or you need to pay very close attention -# to which evaluators are run and when. diff --git a/courses.dist/modelCourse/templates/achievements/hows_your_finger.at b/courses.dist/modelCourse/templates/achievements/hows_your_finger.at deleted file mode 100644 index 7ef8eb8c8..000000000 --- a/courses.dist/modelCourse/templates/achievements/hows_your_finger.at +++ /dev/null @@ -1,71 +0,0 @@ -#This checks to see if the student has above a certain number of attempts - - if ($problem->num_correct + $problem->num_incorrect >= 250) { - return 1; - } else { - return 0; - } - - -# -You have access to a variety of variables: -# - $problem : the problem data (changes to this variable will not be saved!) -# This variable contains the problem data. It is a hash pointer with the -# following values (not all values shown) -# - $problem->status : the score of the current problem -# - $problem->problem_id : the id of the current problem -# - $problem->set_id : the id of the set containing the problem -# - $problem->num_correct : the number of correct attempts -# - $problem->num_incorrect : the number of incorrect attempts -# - $problem->last_answer : the last answer submitted -# - $problem->max_attempts : the maximum number of allowed attempts -# -# - $set : the set data (changes to this variable will not be saved!) -# This variable contains the set data. it is a hash pointer with the -# following values. (not all values shown) -# - $set->open_date : when the set was open -# - $set->due_date : when the set is due -# -# - @setProblems : the problem data for all the problems from this set. -# (changes to this variable will not be saved!) -# This is an array of problem hashes. Each element of the array has the -# save hash keys as the $problem variable above -# -# - $counter : the users counter associated to this achievement -# (changes to this variable *will* be saved!) -# If this achievement has a counter associated to it (i.e. solve 20 problems) -# then this is where you store the students counter for this achievement. -# This variable will initally start as '' -# -# - $maxCounter : the goal for the $counter variable for this achievement -# (changes to this variable will not be saved!) -# If this achievement has a counter associated to it then this variable -# contains the goal for the counter. Your achievement should return 1 -# when $counter >= $maxCounter. These two variables are used to show a -# progress bar for the achievement. -# -# - $localData : this is a hash which stores data for this user and achievement -# (changes to this variable *will* be saved!) -# This hash will persist from evaluation to evaluation. You can store whatever -# you like in here and it can be accessed next time this evaluator is run. -# Two things to keep in mind. The data in this hash will *not* be accessable -# by other achievements. If you plan to store something in this hash you have -# to write code to initialize the data. -# -# - $globalData : this is a hash which stores data for all achievements -# (changes to this variable *will* be saved!) -# This hash will persist from evaluation to evaluation and, like $localData, -# you can store whatever you like in here. This data will be accessable from -# *every* achievement and is unique to the user. Like $localData, you need to -# initialize any variable you plan on using in this hash. There are two -# variables stored in this hash that are maintained by the system. -# - $globalData->{completeSets} : This is the number of sets which the student -# has earned 100% on -# - $globalData->{completeProblems} : This is the number of problems which the -# student has earned 100% on -# Warning: The achievements are always evaluated in the order they are listed -# on the Instructors achievement editor page. To make matters more -# complicated, achievements which have already been earned are not evaluated -# at all. The up-shot of this is that when modifying variables in -# $globalData you need to either write your code so it doesnt matter which -# order the evaluators are run in, or you need to pay very close attention -# to which evaluators are run and when. \ No newline at end of file diff --git a/courses.dist/modelCourse/templates/achievements/integral_master.at b/courses.dist/modelCourse/templates/achievements/integral_master.at deleted file mode 100644 index e637e74ca..000000000 --- a/courses.dist/modelCourse/templates/achievements/integral_master.at +++ /dev/null @@ -1,84 +0,0 @@ -#This problem checks to see if a particular problem from a list of valid -# sets and problems has been solved. (You would edit this file to say which -# sets and problems count.) - -#constants -my %validproblems = ( - 'SetNameHere' => { #now you show which problems are valid like: - '2' => 1, - '1' => 1, }, #and put more sets here - ); - -#check and see if this problem was solved -if ($validproblems{$problem->set_id} && - $validproblems{$problem->set_id}{$problem->problem_id} && - $problem->status == 1 && - $problem->num_correct == 1) { - return 1; - } - - return 0; - - -# -You have access to a variety of variables: -# - $problem : the problem data (changes to this variable will not be saved!) -# This variable contains the problem data. It is a hash pointer with the -# following values (not all values shown) -# - $problem->status : the score of the current problem -# - $problem->problem_id : the id of the current problem -# - $problem->set_id : the id of the set containing the problem -# - $problem->num_correct : the number of correct attempts -# - $problem->num_incorrect : the number of incorrect attempts -# - $problem->last_answer : the last answer submitted -# - $problem->max_attempts : the maximum number of allowed attempts -# -# - $set : the set data (changes to this variable will not be saved!) -# This variable contains the set data. it is a hash pointer with the -# following values. (not all values shown) -# - $set->open_date : when the set was open -# - $set->due_date : when the set is due -# -# - @setProblems : the problem data for all the problems from this set. -# (changes to this variable will not be saved!) -# This is an array of problem hashes. Each element of the array has the -# save hash keys as the $problem variable above -# -# - $counter : the users counter associated to this achievement -# (changes to this variable *will* be saved!) -# If this achievement has a counter associated to it (i.e. solve 20 problems) -# then this is where you store the students counter for this achievement. -# This variable will initally start as '' -# -# - $maxCounter : the goal for the $counter variable for this achievement -# (changes to this variable will not be saved!) -# If this achievement has a counter associated to it then this variable -# contains the goal for the counter. Your achievement should return 1 -# when $counter >= $maxCounter. These two variables are used to show a -# progress bar for the achievement. -# -# - $localData : this is a hash which stores data for this user and achievement -# (changes to this variable *will* be saved!) -# This hash will persist from evaluation to evaluation. You can store whatever -# you like in here and it can be accessed next time this evaluator is run. -# Two things to keep in mind. The data in this hash will *not* be accessable -# by other achievements. If you plan to store something in this hash you have -# to write code to initialize the data. -# -# - $globalData : this is a hash which stores data for all achievements -# (changes to this variable *will* be saved!) -# This hash will persist from evaluation to evaluation and, like $localData, -# you can store whatever you like in here. This data will be accessable from -# *every* achievement and is unique to the user. Like $localData, you need to -# initialize any variable you plan on using in this hash. There are two -# variables stored in this hash that are maintained by the system. -# - $globalData->{completeSets} : This is the number of sets which the student -# has earned 100% on -# - $globalData->{completeProblems} : This is the number of problems which the -# student has earned 100% on -# Warning: The achievements are always evaluated in the order they are listed -# on the Instructors achievement editor page. To make matters more -# complicated, achievements which have already been earned are not evaluated -# at all. The up-shot of this is that when modifying variables in -# $globalData you need to either write your code so it doesnt matter which -# order the evaluators are run in, or you need to pay very close attention -# to which evaluators are run and when. diff --git a/courses.dist/modelCourse/templates/achievements/its_all_relative.at b/courses.dist/modelCourse/templates/achievements/its_all_relative.at deleted file mode 100644 index ca38f8801..000000000 --- a/courses.dist/modelCourse/templates/achievements/its_all_relative.at +++ /dev/null @@ -1,84 +0,0 @@ -#This problem checks to see if a particular problem from a list of valid -# sets and problems has been solved. (You would edit this file to say which -# sets and problems count.) - -#constants -my %validproblems = ( - 'TestSet' => { #now you show which problems are valid like: - '1' => 1, - '2' => 1, }, #and put more sets here - ); - -#check and see if this problem was solved -if ($validproblems{$problem->set_id} && - $validproblems{$problem->set_id}{$problem->problem_id} && - $problem->status == 1 && - $problem->num_correct == 1) { - return 1; - } - - return 0; - - -# -You have access to a variety of variables: -# - $problem : the problem data (changes to this variable will not be saved!) -# This variable contains the problem data. It is a hash pointer with the -# following values (not all values shown) -# - $problem->status : the score of the current problem -# - $problem->problem_id : the id of the current problem -# - $problem->set_id : the id of the set containing the problem -# - $problem->num_correct : the number of correct attempts -# - $problem->num_incorrect : the number of incorrect attempts -# - $problem->last_answer : the last answer submitted -# - $problem->max_attempts : the maximum number of allowed attempts -# -# - $set : the set data (changes to this variable will not be saved!) -# This variable contains the set data. it is a hash pointer with the -# following values. (not all values shown) -# - $set->open_date : when the set was open -# - $set->due_date : when the set is due -# -# - @setProblems : the problem data for all the problems from this set. -# (changes to this variable will not be saved!) -# This is an array of problem hashes. Each element of the array has the -# save hash keys as the $problem variable above -# -# - $counter : the users counter associated to this achievement -# (changes to this variable *will* be saved!) -# If this achievement has a counter associated to it (i.e. solve 20 problems) -# then this is where you store the students counter for this achievement. -# This variable will initally start as '' -# -# - $maxCounter : the goal for the $counter variable for this achievement -# (changes to this variable will not be saved!) -# If this achievement has a counter associated to it then this variable -# contains the goal for the counter. Your achievement should return 1 -# when $counter >= $maxCounter. These two variables are used to show a -# progress bar for the achievement. -# -# - $localData : this is a hash which stores data for this user and achievement -# (changes to this variable *will* be saved!) -# This hash will persist from evaluation to evaluation. You can store whatever -# you like in here and it can be accessed next time this evaluator is run. -# Two things to keep in mind. The data in this hash will *not* be accessable -# by other achievements. If you plan to store something in this hash you have -# to write code to initialize the data. -# -# - $globalData : this is a hash which stores data for all achievements -# (changes to this variable *will* be saved!) -# This hash will persist from evaluation to evaluation and, like $localData, -# you can store whatever you like in here. This data will be accessable from -# *every* achievement and is unique to the user. Like $localData, you need to -# initialize any variable you plan on using in this hash. There are two -# variables stored in this hash that are maintained by the system. -# - $globalData->{completeSets} : This is the number of sets which the student -# has earned 100% on -# - $globalData->{completeProblems} : This is the number of problems which the -# student has earned 100% on -# Warning: The achievements are always evaluated in the order they are listed -# on the Instructors achievement editor page. To make matters more -# complicated, achievements which have already been earned are not evaluated -# at all. The up-shot of this is that when modifying variables in -# $globalData you need to either write your code so it doesnt matter which -# order the evaluators are run in, or you need to pay very close attention -# to which evaluators are run and when. diff --git a/courses.dist/modelCourse/templates/achievements/la_revolucion.at b/courses.dist/modelCourse/templates/achievements/la_revolucion.at deleted file mode 100644 index e637e74ca..000000000 --- a/courses.dist/modelCourse/templates/achievements/la_revolucion.at +++ /dev/null @@ -1,84 +0,0 @@ -#This problem checks to see if a particular problem from a list of valid -# sets and problems has been solved. (You would edit this file to say which -# sets and problems count.) - -#constants -my %validproblems = ( - 'SetNameHere' => { #now you show which problems are valid like: - '2' => 1, - '1' => 1, }, #and put more sets here - ); - -#check and see if this problem was solved -if ($validproblems{$problem->set_id} && - $validproblems{$problem->set_id}{$problem->problem_id} && - $problem->status == 1 && - $problem->num_correct == 1) { - return 1; - } - - return 0; - - -# -You have access to a variety of variables: -# - $problem : the problem data (changes to this variable will not be saved!) -# This variable contains the problem data. It is a hash pointer with the -# following values (not all values shown) -# - $problem->status : the score of the current problem -# - $problem->problem_id : the id of the current problem -# - $problem->set_id : the id of the set containing the problem -# - $problem->num_correct : the number of correct attempts -# - $problem->num_incorrect : the number of incorrect attempts -# - $problem->last_answer : the last answer submitted -# - $problem->max_attempts : the maximum number of allowed attempts -# -# - $set : the set data (changes to this variable will not be saved!) -# This variable contains the set data. it is a hash pointer with the -# following values. (not all values shown) -# - $set->open_date : when the set was open -# - $set->due_date : when the set is due -# -# - @setProblems : the problem data for all the problems from this set. -# (changes to this variable will not be saved!) -# This is an array of problem hashes. Each element of the array has the -# save hash keys as the $problem variable above -# -# - $counter : the users counter associated to this achievement -# (changes to this variable *will* be saved!) -# If this achievement has a counter associated to it (i.e. solve 20 problems) -# then this is where you store the students counter for this achievement. -# This variable will initally start as '' -# -# - $maxCounter : the goal for the $counter variable for this achievement -# (changes to this variable will not be saved!) -# If this achievement has a counter associated to it then this variable -# contains the goal for the counter. Your achievement should return 1 -# when $counter >= $maxCounter. These two variables are used to show a -# progress bar for the achievement. -# -# - $localData : this is a hash which stores data for this user and achievement -# (changes to this variable *will* be saved!) -# This hash will persist from evaluation to evaluation. You can store whatever -# you like in here and it can be accessed next time this evaluator is run. -# Two things to keep in mind. The data in this hash will *not* be accessable -# by other achievements. If you plan to store something in this hash you have -# to write code to initialize the data. -# -# - $globalData : this is a hash which stores data for all achievements -# (changes to this variable *will* be saved!) -# This hash will persist from evaluation to evaluation and, like $localData, -# you can store whatever you like in here. This data will be accessable from -# *every* achievement and is unique to the user. Like $localData, you need to -# initialize any variable you plan on using in this hash. There are two -# variables stored in this hash that are maintained by the system. -# - $globalData->{completeSets} : This is the number of sets which the student -# has earned 100% on -# - $globalData->{completeProblems} : This is the number of problems which the -# student has earned 100% on -# Warning: The achievements are always evaluated in the order they are listed -# on the Instructors achievement editor page. To make matters more -# complicated, achievements which have already been earned are not evaluated -# at all. The up-shot of this is that when modifying variables in -# $globalData you need to either write your code so it doesnt matter which -# order the evaluators are run in, or you need to pay very close attention -# to which evaluators are run and when. diff --git a/courses.dist/modelCourse/templates/achievements/last_minute.at b/courses.dist/modelCourse/templates/achievements/last_minute.at deleted file mode 100644 index e15f79783..000000000 --- a/courses.dist/modelCourse/templates/achievements/last_minute.at +++ /dev/null @@ -1,77 +0,0 @@ -# checks to see if a studen finished a set close to the due date - - #test to see if it is within 30 min of the due date - if (($set->due_date - time()) > 1800) { - return 0; - } - - foreach my $problemRecord (@setProblems) { - if ($problemRecord->status != 1) { - return 0; - } - } - - return 1; - -# -You have access to a variety of variables: -# - $problem : the problem data (changes to this variable will not be saved!) -# This variable contains the problem data. It is a hash pointer with the -# following values (not all values shown) -# - $problem->status : the score of the current problem -# - $problem->problem_id : the id of the current problem -# - $problem->set_id : the id of the set containing the problem -# - $problem->num_correct : the number of correct attempts -# - $problem->num_incorrect : the number of incorrect attempts -# - $problem->last_answer : the last answer submitted -# - $problem->max_attempts : the maximum number of allowed attempts -# -# - $set : the set data (changes to this variable will not be saved!) -# This variable contains the set data. it is a hash pointer with the -# following values. (not all values shown) -# - $set->open_date : when the set was open -# - $set->due_date : when the set is due -# -# - @setProblems : the problem data for all the problems from this set. -# (changes to this variable will not be saved!) -# This is an array of problem hashes. Each element of the array has the -# save hash keys as the $problem variable above -# -# - $counter : the users counter associated to this achievement -# (changes to this variable *will* be saved!) -# If this achievement has a counter associated to it (i.e. solve 20 problems) -# then this is where you store the students counter for this achievement. -# This variable will initally start as '' -# -# - $maxCounter : the goal for the $counter variable for this achievement -# (changes to this variable will not be saved!) -# If this achievement has a counter associated to it then this variable -# contains the goal for the counter. Your achievement should return 1 -# when $counter >= $maxCounter. These two variables are used to show a -# progress bar for the achievement. -# -# - $localData : this is a hash which stores data for this user and achievement -# (changes to this variable *will* be saved!) -# This hash will persist from evaluation to evaluation. You can store whatever -# you like in here and it can be accessed next time this evaluator is run. -# Two things to keep in mind. The data in this hash will *not* be accessable -# by other achievements. If you plan to store something in this hash you have -# to write code to initialize the data. -# -# - $globalData : this is a hash which stores data for all achievements -# (changes to this variable *will* be saved!) -# This hash will persist from evaluation to evaluation and, like $localData, -# you can store whatever you like in here. This data will be accessable from -# *every* achievement and is unique to the user. Like $localData, you need to -# initialize any variable you plan on using in this hash. There are two -# variables stored in this hash that are maintained by the system. -# - $globalData->{completeSets} : This is the number of sets which the student -# has earned 100% on -# - $globalData->{completeProblems} : This is the number of problems which the -# student has earned 100% on -# Warning: The achievements are always evaluated in the order they are listed -# on the Instructors achievement editor page. To make matters more -# complicated, achievements which have already been earned are not evaluated -# at all. The up-shot of this is that when modifying variables in -# $globalData you need to either write your code so it doesnt matter which -# order the evaluators are run in, or you need to pay very close attention -# to which evaluators are run and when. \ No newline at end of file diff --git a/courses.dist/modelCourse/templates/achievements/level_eight.at b/courses.dist/modelCourse/templates/achievements/level_eight.at deleted file mode 100644 index f005f9a94..000000000 --- a/courses.dist/modelCourse/templates/achievements/level_eight.at +++ /dev/null @@ -1,86 +0,0 @@ -# This is a "level" achievement and they behave slightly differently. When -# a level achievement is earned the system uses the icon and title of the -# level achievement as the icon and title of that students level. There -# are two additional variables available to level achievements -# - $achievementPoints : the number of achievement points the current -# user has. (Changes to this variable will *not* be saved.) -# - $nextLevelPoints : the number of points needed to earn a level. -# (Changes to this variable will be saved if a new level is earned.) -# These variables are used to construct the users level progress bar - -#Constants: -#Threshold for level 9 -my $newLevelThreshold = 1200; - -#Code - -if ($achievementPoints >= $nextLevelPoints) { - #set new threshold and return 1 - $nextLevelPoints = $newLevelThreshold; - return 1; -} else { - return 0; -} - -# Variable Descriptions: -# - $problem : the problem data (changes to this variable will not be saved!) -# This variable contains the problem data. It is a hash pointer with the -# following values (not all values shown) -# - $problem->status : the score of the current problem -# - $problem->problem_id : the id of the current problem -# - $problem->set_id : the id of the set containing the problem -# - $problem->num_correct : the number of correct attempts -# - $problem->num_incorrect : the number of incorrect attempts -# - $problem->last_answer : the last answer submitted -# - $problem->max_attempts : the maximum number of allowed attempts -# -# - $set : the set data (changes to this variable will not be saved!) -# This variable contains the set data. it is a hash pointer with the -# following values. (not all values shown) -# - $set->open_date : when the set was open -# - $set->due_date : when the set is due -# -# - @setProblems : the problem data for all the problems from this set. -# (changes to this variable will not be saved!) -# This is an array of problem hashes. Each element of the array has the -# save hash keys as the $problem variable above -# -# - $counter : the users counter associated to this achievement -# (changes to this variable *will* be saved!) -# If this achievement has a counter associated to it (i.e. solve 20 problems) -# then this is where you store the students counter for this achievement. -# This variable will initally start as '' -# -# - $maxCounter : the goal for the $counter variable for this achievement -# (changes to this variable will not be saved!) -# If this achievement has a counter associated to it then this variable -# contains the goal for the counter. Your achievement should return 1 -# when $counter >= $maxCounter. These two variables are used to show a -# progress bar for the achievement. -# -# - $localData : this is a hash which stores data for this user and achievement -# (changes to this variable *will* be saved!) -# This hash will persist from evaluation to evaluation. You can store whatever -# you like in here and it can be accessed next time this evaluator is run. -# Two things to keep in mind. The data in this hash will *not* be accessable -# by other achievements. If you plan to store something in this hash you have -# to write code to initialize the data. -# -# - $globalData : this is a hash which stores data for all achievements -# (changes to this variable *will* be saved!) -# This hash will persist from evaluation to evaluation and, like $localData, -# you can store whatever you like in here. This data will be accessable from -# *every* achievement and is unique to the user. Like $localData, you need to -# initialize any variable you plan on using in this hash. There are two -# variables stored in this hash that are maintained by the system. -# - $globalData->completeSets : This is the number of sets which the student -# has earned 100% on -# - $globalData->complete Problems : This is the number of problems which the -# student has earned 100% on -# Warning: The achievements are always evaluated in the order they are listed -# on the Instructors achievement editor page. To make matters more -# complicated, achievements which have already been earned are not evaluated -# at all. The up-shot of this is that when modifying variables in -# $globalData you need to either write your code so it doesnt matter which -# order the evaluators are run in, or you need to pay very close attention -# to which evaluators are run and when. \ No newline at end of file diff --git a/courses.dist/modelCourse/templates/achievements/level_five.at b/courses.dist/modelCourse/templates/achievements/level_five.at deleted file mode 100644 index 79dfd3909..000000000 --- a/courses.dist/modelCourse/templates/achievements/level_five.at +++ /dev/null @@ -1,86 +0,0 @@ -# This is a "level" achievement and they behave slightly differently. When -# a level achievement is earned the system uses the icon and title of the -# level achievement as the icon and title of that students level. There -# are two additional variables available to level achievements -# - $achievementPoints : the number of achievement points the current -# user has. (Changes to this variable will *not* be saved.) -# - $nextLevelPoints : the number of points needed to earn a level. -# (Changes to this variable will be saved if a new level is earned.) -# These variables are used to construct the users level progress bar - -#Constants: -#Threshold for level 6 -my $newLevelThreshold = 750; - -#Code - -if ($achievementPoints >= $nextLevelPoints) { - #set new threshold and return 1 - $nextLevelPoints = $newLevelThreshold; - return 1; -} else { - return 0; -} - -# Variable Descriptions: -# - $problem : the problem data (changes to this variable will not be saved!) -# This variable contains the problem data. It is a hash pointer with the -# following values (not all values shown) -# - $problem->status : the score of the current problem -# - $problem->problem_id : the id of the current problem -# - $problem->set_id : the id of the set containing the problem -# - $problem->num_correct : the number of correct attempts -# - $problem->num_incorrect : the number of incorrect attempts -# - $problem->last_answer : the last answer submitted -# - $problem->max_attempts : the maximum number of allowed attempts -# -# - $set : the set data (changes to this variable will not be saved!) -# This variable contains the set data. it is a hash pointer with the -# following values. (not all values shown) -# - $set->open_date : when the set was open -# - $set->due_date : when the set is due -# -# - @setProblems : the problem data for all the problems from this set. -# (changes to this variable will not be saved!) -# This is an array of problem hashes. Each element of the array has the -# save hash keys as the $problem variable above -# -# - $counter : the users counter associated to this achievement -# (changes to this variable *will* be saved!) -# If this achievement has a counter associated to it (i.e. solve 20 problems) -# then this is where you store the students counter for this achievement. -# This variable will initally start as '' -# -# - $maxCounter : the goal for the $counter variable for this achievement -# (changes to this variable will not be saved!) -# If this achievement has a counter associated to it then this variable -# contains the goal for the counter. Your achievement should return 1 -# when $counter >= $maxCounter. These two variables are used to show a -# progress bar for the achievement. -# -# - $localData : this is a hash which stores data for this user and achievement -# (changes to this variable *will* be saved!) -# This hash will persist from evaluation to evaluation. You can store whatever -# you like in here and it can be accessed next time this evaluator is run. -# Two things to keep in mind. The data in this hash will *not* be accessable -# by other achievements. If you plan to store something in this hash you have -# to write code to initialize the data. -# -# - $globalData : this is a hash which stores data for all achievements -# (changes to this variable *will* be saved!) -# This hash will persist from evaluation to evaluation and, like $localData, -# you can store whatever you like in here. This data will be accessable from -# *every* achievement and is unique to the user. Like $localData, you need to -# initialize any variable you plan on using in this hash. There are two -# variables stored in this hash that are maintained by the system. -# - $globalData->completeSets : This is the number of sets which the student -# has earned 100% on -# - $globalData->complete Problems : This is the number of problems which the -# student has earned 100% on -# Warning: The achievements are always evaluated in the order they are listed -# on the Instructors achievement editor page. To make matters more -# complicated, achievements which have already been earned are not evaluated -# at all. The up-shot of this is that when modifying variables in -# $globalData you need to either write your code so it doesnt matter which -# order the evaluators are run in, or you need to pay very close attention -# to which evaluators are run and when. \ No newline at end of file diff --git a/courses.dist/modelCourse/templates/achievements/level_four.at b/courses.dist/modelCourse/templates/achievements/level_four.at deleted file mode 100644 index d7187aaac..000000000 --- a/courses.dist/modelCourse/templates/achievements/level_four.at +++ /dev/null @@ -1,86 +0,0 @@ -# This is a "level" achievement and they behave slightly differently. When -# a level achievement is earned the system uses the icon and title of the -# level achievement as the icon and title of that students level. There -# are two additional variables available to level achievements -# - $achievementPoints : the number of achievement points the current -# user has. (Changes to this variable will *not* be saved.) -# - $nextLevelPoints : the number of points needed to earn a level. -# (Changes to this variable will be saved if a new level is earned.) -# These variables are used to construct the users level progress bar - -#Constants: -#Threshold for level 5 -my $newLevelThreshold = 600; - -#Code - -if ($achievementPoints >= $nextLevelPoints) { - #set new threshold and return 1 - $nextLevelPoints = $newLevelThreshold; - return 1; -} else { - return 0; -} - -# Variable Descriptions: -# - $problem : the problem data (changes to this variable will not be saved!) -# This variable contains the problem data. It is a hash pointer with the -# following values (not all values shown) -# - $problem->status : the score of the current problem -# - $problem->problem_id : the id of the current problem -# - $problem->set_id : the id of the set containing the problem -# - $problem->num_correct : the number of correct attempts -# - $problem->num_incorrect : the number of incorrect attempts -# - $problem->last_answer : the last answer submitted -# - $problem->max_attempts : the maximum number of allowed attempts -# -# - $set : the set data (changes to this variable will not be saved!) -# This variable contains the set data. it is a hash pointer with the -# following values. (not all values shown) -# - $set->open_date : when the set was open -# - $set->due_date : when the set is due -# -# - @setProblems : the problem data for all the problems from this set. -# (changes to this variable will not be saved!) -# This is an array of problem hashes. Each element of the array has the -# save hash keys as the $problem variable above -# -# - $counter : the users counter associated to this achievement -# (changes to this variable *will* be saved!) -# If this achievement has a counter associated to it (i.e. solve 20 problems) -# then this is where you store the students counter for this achievement. -# This variable will initally start as '' -# -# - $maxCounter : the goal for the $counter variable for this achievement -# (changes to this variable will not be saved!) -# If this achievement has a counter associated to it then this variable -# contains the goal for the counter. Your achievement should return 1 -# when $counter >= $maxCounter. These two variables are used to show a -# progress bar for the achievement. -# -# - $localData : this is a hash which stores data for this user and achievement -# (changes to this variable *will* be saved!) -# This hash will persist from evaluation to evaluation. You can store whatever -# you like in here and it can be accessed next time this evaluator is run. -# Two things to keep in mind. The data in this hash will *not* be accessable -# by other achievements. If you plan to store something in this hash you have -# to write code to initialize the data. -# -# - $globalData : this is a hash which stores data for all achievements -# (changes to this variable *will* be saved!) -# This hash will persist from evaluation to evaluation and, like $localData, -# you can store whatever you like in here. This data will be accessable from -# *every* achievement and is unique to the user. Like $localData, you need to -# initialize any variable you plan on using in this hash. There are two -# variables stored in this hash that are maintained by the system. -# - $globalData->completeSets : This is the number of sets which the student -# has earned 100% on -# - $globalData->complete Problems : This is the number of problems which the -# student has earned 100% on -# Warning: The achievements are always evaluated in the order they are listed -# on the Instructors achievement editor page. To make matters more -# complicated, achievements which have already been earned are not evaluated -# at all. The up-shot of this is that when modifying variables in -# $globalData you need to either write your code so it doesnt matter which -# order the evaluators are run in, or you need to pay very close attention -# to which evaluators are run and when. \ No newline at end of file diff --git a/courses.dist/modelCourse/templates/achievements/level_nine.at b/courses.dist/modelCourse/templates/achievements/level_nine.at deleted file mode 100644 index 810989e66..000000000 --- a/courses.dist/modelCourse/templates/achievements/level_nine.at +++ /dev/null @@ -1,86 +0,0 @@ -# This is a "level" achievement and they behave slightly differently. When -# a level achievement is earned the system uses the icon and title of the -# level achievement as the icon and title of that students level. There -# are two additional variables available to level achievements -# - $achievementPoints : the number of achievement points the current -# user has. (Changes to this variable will *not* be saved.) -# - $nextLevelPoints : the number of points needed to earn a level. -# (Changes to this variable will be saved if a new level is earned.) -# These variables are used to construct the users level progress bar - -#Constants: -#Level 10 threshold -my $newLevelThreshold = 1350; - -#Code - -if ($achievementPoints >= $nextLevelPoints) { - #set new threshold and return 1 - $nextLevelPoints = $newLevelThreshold; - return 1; -} else { - return 0; -} - -# Variable Descriptions: -# - $problem : the problem data (changes to this variable will not be saved!) -# This variable contains the problem data. It is a hash pointer with the -# following values (not all values shown) -# - $problem->status : the score of the current problem -# - $problem->problem_id : the id of the current problem -# - $problem->set_id : the id of the set containing the problem -# - $problem->num_correct : the number of correct attempts -# - $problem->num_incorrect : the number of incorrect attempts -# - $problem->last_answer : the last answer submitted -# - $problem->max_attempts : the maximum number of allowed attempts -# -# - $set : the set data (changes to this variable will not be saved!) -# This variable contains the set data. it is a hash pointer with the -# following values. (not all values shown) -# - $set->open_date : when the set was open -# - $set->due_date : when the set is due -# -# - @setProblems : the problem data for all the problems from this set. -# (changes to this variable will not be saved!) -# This is an array of problem hashes. Each element of the array has the -# save hash keys as the $problem variable above -# -# - $counter : the users counter associated to this achievement -# (changes to this variable *will* be saved!) -# If this achievement has a counter associated to it (i.e. solve 20 problems) -# then this is where you store the students counter for this achievement. -# This variable will initally start as '' -# -# - $maxCounter : the goal for the $counter variable for this achievement -# (changes to this variable will not be saved!) -# If this achievement has a counter associated to it then this variable -# contains the goal for the counter. Your achievement should return 1 -# when $counter >= $maxCounter. These two variables are used to show a -# progress bar for the achievement. -# -# - $localData : this is a hash which stores data for this user and achievement -# (changes to this variable *will* be saved!) -# This hash will persist from evaluation to evaluation. You can store whatever -# you like in here and it can be accessed next time this evaluator is run. -# Two things to keep in mind. The data in this hash will *not* be accessable -# by other achievements. If you plan to store something in this hash you have -# to write code to initialize the data. -# -# - $globalData : this is a hash which stores data for all achievements -# (changes to this variable *will* be saved!) -# This hash will persist from evaluation to evaluation and, like $localData, -# you can store whatever you like in here. This data will be accessable from -# *every* achievement and is unique to the user. Like $localData, you need to -# initialize any variable you plan on using in this hash. There are two -# variables stored in this hash that are maintained by the system. -# - $globalData->completeSets : This is the number of sets which the student -# has earned 100% on -# - $globalData->complete Problems : This is the number of problems which the -# student has earned 100% on -# Warning: The achievements are always evaluated in the order they are listed -# on the Instructors achievement editor page. To make matters more -# complicated, achievements which have already been earned are not evaluated -# at all. The up-shot of this is that when modifying variables in -# $globalData you need to either write your code so it doesnt matter which -# order the evaluators are run in, or you need to pay very close attention -# to which evaluators are run and when. \ No newline at end of file diff --git a/courses.dist/modelCourse/templates/achievements/level_one.at b/courses.dist/modelCourse/templates/achievements/level_one.at deleted file mode 100644 index 78d684638..000000000 --- a/courses.dist/modelCourse/templates/achievements/level_one.at +++ /dev/null @@ -1,83 +0,0 @@ -# This is a "level" achievement and they behave slightly differently. When -# a level achievement is earned the system uses the icon and title of the -# level achievement as the icon and title of that students level. There -# are two additional variables available to level achievements -# - $achievementPoints : the number of achievement points the current -# user has. (Changes to this variable will *not* be saved.) -# - $nextLevelPoints : the number of points needed to earn a level. -# (Changes to this variable will be saved if a new level is earned.) -# These variables are used to construct the users level progress bar - -#Constants: -#Threshold for level 2 -my $newLevelThreshold = 150; - -#Code - -#level 1 is earned immediately -$nextLevelPoints = $newLevelThreshold; -return 1; - - -# Variable Descriptions: -# - $problem : the problem data (changes to this variable will not be saved!) -# This variable contains the problem data. It is a hash pointer with the -# following values (not all values shown) -# - $problem->status : the score of the current problem -# - $problem->problem_id : the id of the current problem -# - $problem->set_id : the id of the set containing the problem -# - $problem->num_correct : the number of correct attempts -# - $problem->num_incorrect : the number of incorrect attempts -# - $problem->last_answer : the last answer submitted -# - $problem->max_attempts : the maximum number of allowed attempts -# -# - $set : the set data (changes to this variable will not be saved!) -# This variable contains the set data. it is a hash pointer with the -# following values. (not all values shown) -# - $set->open_date : when the set was open -# - $set->due_date : when the set is due -# -# - @setProblems : the problem data for all the problems from this set. -# (changes to this variable will not be saved!) -# This is an array of problem hashes. Each element of the array has the -# save hash keys as the $problem variable above -# -# - $counter : the users counter associated to this achievement -# (changes to this variable *will* be saved!) -# If this achievement has a counter associated to it (i.e. solve 20 problems) -# then this is where you store the students counter for this achievement. -# This variable will initally start as '' -# -# - $maxCounter : the goal for the $counter variable for this achievement -# (changes to this variable will not be saved!) -# If this achievement has a counter associated to it then this variable -# contains the goal for the counter. Your achievement should return 1 -# when $counter >= $maxCounter. These two variables are used to show a -# progress bar for the achievement. -# -# - $localData : this is a hash which stores data for this user and achievement -# (changes to this variable *will* be saved!) -# This hash will persist from evaluation to evaluation. You can store whatever -# you like in here and it can be accessed next time this evaluator is run. -# Two things to keep in mind. The data in this hash will *not* be accessable -# by other achievements. If you plan to store something in this hash you have -# to write code to initialize the data. -# -# - $globalData : this is a hash which stores data for all achievements -# (changes to this variable *will* be saved!) -# This hash will persist from evaluation to evaluation and, like $localData, -# you can store whatever you like in here. This data will be accessable from -# *every* achievement and is unique to the user. Like $localData, you need to -# initialize any variable you plan on using in this hash. There are two -# variables stored in this hash that are maintained by the system. -# - $globalData->completeSets : This is the number of sets which the student -# has earned 100% on -# - $globalData->complete Problems : This is the number of problems which the -# student has earned 100% on -# Warning: The achievements are always evaluated in the order they are listed -# on the Instructors achievement editor page. To make matters more -# complicated, achievements which have already been earned are not evaluated -# at all. The up-shot of this is that when modifying variables in -# $globalData you need to either write your code so it doesnt matter which -# order the evaluators are run in, or you need to pay very close attention -# to which evaluators are run and when. \ No newline at end of file diff --git a/courses.dist/modelCourse/templates/achievements/level_seven.at b/courses.dist/modelCourse/templates/achievements/level_seven.at deleted file mode 100644 index ce250d0bb..000000000 --- a/courses.dist/modelCourse/templates/achievements/level_seven.at +++ /dev/null @@ -1,86 +0,0 @@ -# This is a "level" achievement and they behave slightly differently. When -# a level achievement is earned the system uses the icon and title of the -# level achievement as the icon and title of that students level. There -# are two additional variables available to level achievements -# - $achievementPoints : the number of achievement points the current -# user has. (Changes to this variable will *not* be saved.) -# - $nextLevelPoints : the number of points needed to earn a level. -# (Changes to this variable will be saved if a new level is earned.) -# These variables are used to construct the users level progress bar - -#Constants: -#Threshold for level 8 -my $newLevelThreshold = 1050; - -#Code - -if ($achievementPoints >= $nextLevelPoints) { - #set new threshold and return 1 - $nextLevelPoints = $newLevelThreshold; - return 1; -} else { - return 0; -} - -# Variable Descriptions: -# - $problem : the problem data (changes to this variable will not be saved!) -# This variable contains the problem data. It is a hash pointer with the -# following values (not all values shown) -# - $problem->status : the score of the current problem -# - $problem->problem_id : the id of the current problem -# - $problem->set_id : the id of the set containing the problem -# - $problem->num_correct : the number of correct attempts -# - $problem->num_incorrect : the number of incorrect attempts -# - $problem->last_answer : the last answer submitted -# - $problem->max_attempts : the maximum number of allowed attempts -# -# - $set : the set data (changes to this variable will not be saved!) -# This variable contains the set data. it is a hash pointer with the -# following values. (not all values shown) -# - $set->open_date : when the set was open -# - $set->due_date : when the set is due -# -# - @setProblems : the problem data for all the problems from this set. -# (changes to this variable will not be saved!) -# This is an array of problem hashes. Each element of the array has the -# save hash keys as the $problem variable above -# -# - $counter : the users counter associated to this achievement -# (changes to this variable *will* be saved!) -# If this achievement has a counter associated to it (i.e. solve 20 problems) -# then this is where you store the students counter for this achievement. -# This variable will initally start as '' -# -# - $maxCounter : the goal for the $counter variable for this achievement -# (changes to this variable will not be saved!) -# If this achievement has a counter associated to it then this variable -# contains the goal for the counter. Your achievement should return 1 -# when $counter >= $maxCounter. These two variables are used to show a -# progress bar for the achievement. -# -# - $localData : this is a hash which stores data for this user and achievement -# (changes to this variable *will* be saved!) -# This hash will persist from evaluation to evaluation. You can store whatever -# you like in here and it can be accessed next time this evaluator is run. -# Two things to keep in mind. The data in this hash will *not* be accessable -# by other achievements. If you plan to store something in this hash you have -# to write code to initialize the data. -# -# - $globalData : this is a hash which stores data for all achievements -# (changes to this variable *will* be saved!) -# This hash will persist from evaluation to evaluation and, like $localData, -# you can store whatever you like in here. This data will be accessable from -# *every* achievement and is unique to the user. Like $localData, you need to -# initialize any variable you plan on using in this hash. There are two -# variables stored in this hash that are maintained by the system. -# - $globalData->completeSets : This is the number of sets which the student -# has earned 100% on -# - $globalData->complete Problems : This is the number of problems which the -# student has earned 100% on -# Warning: The achievements are always evaluated in the order they are listed -# on the Instructors achievement editor page. To make matters more -# complicated, achievements which have already been earned are not evaluated -# at all. The up-shot of this is that when modifying variables in -# $globalData you need to either write your code so it doesnt matter which -# order the evaluators are run in, or you need to pay very close attention -# to which evaluators are run and when. \ No newline at end of file diff --git a/courses.dist/modelCourse/templates/achievements/level_six.at b/courses.dist/modelCourse/templates/achievements/level_six.at deleted file mode 100644 index d76f6c735..000000000 --- a/courses.dist/modelCourse/templates/achievements/level_six.at +++ /dev/null @@ -1,86 +0,0 @@ -# This is a "level" achievement and they behave slightly differently. When -# a level achievement is earned the system uses the icon and title of the -# level achievement as the icon and title of that students level. There -# are two additional variables available to level achievements -# - $achievementPoints : the number of achievement points the current -# user has. (Changes to this variable will *not* be saved.) -# - $nextLevelPoints : the number of points needed to earn a level. -# (Changes to this variable will be saved if a new level is earned.) -# These variables are used to construct the users level progress bar - -#Constants: -#Threshold for level 7 -my $newLevelThreshold = 900; - -#Code - -if ($achievementPoints >= $nextLevelPoints) { - #set new threshold and return 1 - $nextLevelPoints = $newLevelThreshold; - return 1; -} else { - return 0; -} - -# Variable Descriptions: -# - $problem : the problem data (changes to this variable will not be saved!) -# This variable contains the problem data. It is a hash pointer with the -# following values (not all values shown) -# - $problem->status : the score of the current problem -# - $problem->problem_id : the id of the current problem -# - $problem->set_id : the id of the set containing the problem -# - $problem->num_correct : the number of correct attempts -# - $problem->num_incorrect : the number of incorrect attempts -# - $problem->last_answer : the last answer submitted -# - $problem->max_attempts : the maximum number of allowed attempts -# -# - $set : the set data (changes to this variable will not be saved!) -# This variable contains the set data. it is a hash pointer with the -# following values. (not all values shown) -# - $set->open_date : when the set was open -# - $set->due_date : when the set is due -# -# - @setProblems : the problem data for all the problems from this set. -# (changes to this variable will not be saved!) -# This is an array of problem hashes. Each element of the array has the -# save hash keys as the $problem variable above -# -# - $counter : the users counter associated to this achievement -# (changes to this variable *will* be saved!) -# If this achievement has a counter associated to it (i.e. solve 20 problems) -# then this is where you store the students counter for this achievement. -# This variable will initally start as '' -# -# - $maxCounter : the goal for the $counter variable for this achievement -# (changes to this variable will not be saved!) -# If this achievement has a counter associated to it then this variable -# contains the goal for the counter. Your achievement should return 1 -# when $counter >= $maxCounter. These two variables are used to show a -# progress bar for the achievement. -# -# - $localData : this is a hash which stores data for this user and achievement -# (changes to this variable *will* be saved!) -# This hash will persist from evaluation to evaluation. You can store whatever -# you like in here and it can be accessed next time this evaluator is run. -# Two things to keep in mind. The data in this hash will *not* be accessable -# by other achievements. If you plan to store something in this hash you have -# to write code to initialize the data. -# -# - $globalData : this is a hash which stores data for all achievements -# (changes to this variable *will* be saved!) -# This hash will persist from evaluation to evaluation and, like $localData, -# you can store whatever you like in here. This data will be accessable from -# *every* achievement and is unique to the user. Like $localData, you need to -# initialize any variable you plan on using in this hash. There are two -# variables stored in this hash that are maintained by the system. -# - $globalData->completeSets : This is the number of sets which the student -# has earned 100% on -# - $globalData->complete Problems : This is the number of problems which the -# student has earned 100% on -# Warning: The achievements are always evaluated in the order they are listed -# on the Instructors achievement editor page. To make matters more -# complicated, achievements which have already been earned are not evaluated -# at all. The up-shot of this is that when modifying variables in -# $globalData you need to either write your code so it doesnt matter which -# order the evaluators are run in, or you need to pay very close attention -# to which evaluators are run and when. \ No newline at end of file diff --git a/courses.dist/modelCourse/templates/achievements/level_ten.at b/courses.dist/modelCourse/templates/achievements/level_ten.at deleted file mode 100644 index 4212d7ff2..000000000 --- a/courses.dist/modelCourse/templates/achievements/level_ten.at +++ /dev/null @@ -1,86 +0,0 @@ -# This is a "level" achievement and they behave slightly differently. When -# a level achievement is earned the system uses the icon and title of the -# level achievement as the icon and title of that students level. There -# are two additional variables available to level achievements -# - $achievementPoints : the number of achievement points the current -# user has. (Changes to this variable will *not* be saved.) -# - $nextLevelPoints : the number of points needed to earn a level. -# (Changes to this variable will be saved if a new level is earned.) -# These variables are used to construct the users level progress bar - -#Constants: -#Level 10 is the last level so dont set a threshhold to remove the progress bar -my $newLevelThreshold = ''; - -#Code - -if ($achievementPoints >= $nextLevelPoints) { - #set new threshold and return 1 - $nextLevelPoints = $newLevelThreshold; - return 1; -} else { - return 0; -} - -# Variable Descriptions: -# - $problem : the problem data (changes to this variable will not be saved!) -# This variable contains the problem data. It is a hash pointer with the -# following values (not all values shown) -# - $problem->status : the score of the current problem -# - $problem->problem_id : the id of the current problem -# - $problem->set_id : the id of the set containing the problem -# - $problem->num_correct : the number of correct attempts -# - $problem->num_incorrect : the number of incorrect attempts -# - $problem->last_answer : the last answer submitted -# - $problem->max_attempts : the maximum number of allowed attempts -# -# - $set : the set data (changes to this variable will not be saved!) -# This variable contains the set data. it is a hash pointer with the -# following values. (not all values shown) -# - $set->open_date : when the set was open -# - $set->due_date : when the set is due -# -# - @setProblems : the problem data for all the problems from this set. -# (changes to this variable will not be saved!) -# This is an array of problem hashes. Each element of the array has the -# save hash keys as the $problem variable above -# -# - $counter : the users counter associated to this achievement -# (changes to this variable *will* be saved!) -# If this achievement has a counter associated to it (i.e. solve 20 problems) -# then this is where you store the students counter for this achievement. -# This variable will initally start as '' -# -# - $maxCounter : the goal for the $counter variable for this achievement -# (changes to this variable will not be saved!) -# If this achievement has a counter associated to it then this variable -# contains the goal for the counter. Your achievement should return 1 -# when $counter >= $maxCounter. These two variables are used to show a -# progress bar for the achievement. -# -# - $localData : this is a hash which stores data for this user and achievement -# (changes to this variable *will* be saved!) -# This hash will persist from evaluation to evaluation. You can store whatever -# you like in here and it can be accessed next time this evaluator is run. -# Two things to keep in mind. The data in this hash will *not* be accessable -# by other achievements. If you plan to store something in this hash you have -# to write code to initialize the data. -# -# - $globalData : this is a hash which stores data for all achievements -# (changes to this variable *will* be saved!) -# This hash will persist from evaluation to evaluation and, like $localData, -# you can store whatever you like in here. This data will be accessable from -# *every* achievement and is unique to the user. Like $localData, you need to -# initialize any variable you plan on using in this hash. There are two -# variables stored in this hash that are maintained by the system. -# - $globalData->completeSets : This is the number of sets which the student -# has earned 100% on -# - $globalData->complete Problems : This is the number of problems which the -# student has earned 100% on -# Warning: The achievements are always evaluated in the order they are listed -# on the Instructors achievement editor page. To make matters more -# complicated, achievements which have already been earned are not evaluated -# at all. The up-shot of this is that when modifying variables in -# $globalData you need to either write your code so it doesnt matter which -# order the evaluators are run in, or you need to pay very close attention -# to which evaluators are run and when. \ No newline at end of file diff --git a/courses.dist/modelCourse/templates/achievements/level_three.at b/courses.dist/modelCourse/templates/achievements/level_three.at deleted file mode 100644 index ec34e20aa..000000000 --- a/courses.dist/modelCourse/templates/achievements/level_three.at +++ /dev/null @@ -1,86 +0,0 @@ -# This is a "level" achievement and they behave slightly differently. When -# a level achievement is earned the system uses the icon and title of the -# level achievement as the icon and title of that students level. There -# are two additional variables available to level achievements -# - $achievementPoints : the number of achievement points the current -# user has. (Changes to this variable will *not* be saved.) -# - $nextLevelPoints : the number of points needed to earn a level. -# (Changes to this variable will be saved if a new level is earned.) -# These variables are used to construct the users level progress bar - -#Constants: -#Threshold for level 4 -my $newLevelThreshold = 450; - -#Code - -if ($achievementPoints >= $nextLevelPoints) { - #set new threshold and return 1 - $nextLevelPoints = $newLevelThreshold; - return 1; -} else { - return 0; -} - -# Variable Descriptions: -# - $problem : the problem data (changes to this variable will not be saved!) -# This variable contains the problem data. It is a hash pointer with the -# following values (not all values shown) -# - $problem->status : the score of the current problem -# - $problem->problem_id : the id of the current problem -# - $problem->set_id : the id of the set containing the problem -# - $problem->num_correct : the number of correct attempts -# - $problem->num_incorrect : the number of incorrect attempts -# - $problem->last_answer : the last answer submitted -# - $problem->max_attempts : the maximum number of allowed attempts -# -# - $set : the set data (changes to this variable will not be saved!) -# This variable contains the set data. it is a hash pointer with the -# following values. (not all values shown) -# - $set->open_date : when the set was open -# - $set->due_date : when the set is due -# -# - @setProblems : the problem data for all the problems from this set. -# (changes to this variable will not be saved!) -# This is an array of problem hashes. Each element of the array has the -# save hash keys as the $problem variable above -# -# - $counter : the users counter associated to this achievement -# (changes to this variable *will* be saved!) -# If this achievement has a counter associated to it (i.e. solve 20 problems) -# then this is where you store the students counter for this achievement. -# This variable will initally start as '' -# -# - $maxCounter : the goal for the $counter variable for this achievement -# (changes to this variable will not be saved!) -# If this achievement has a counter associated to it then this variable -# contains the goal for the counter. Your achievement should return 1 -# when $counter >= $maxCounter. These two variables are used to show a -# progress bar for the achievement. -# -# - $localData : this is a hash which stores data for this user and achievement -# (changes to this variable *will* be saved!) -# This hash will persist from evaluation to evaluation. You can store whatever -# you like in here and it can be accessed next time this evaluator is run. -# Two things to keep in mind. The data in this hash will *not* be accessable -# by other achievements. If you plan to store something in this hash you have -# to write code to initialize the data. -# -# - $globalData : this is a hash which stores data for all achievements -# (changes to this variable *will* be saved!) -# This hash will persist from evaluation to evaluation and, like $localData, -# you can store whatever you like in here. This data will be accessable from -# *every* achievement and is unique to the user. Like $localData, you need to -# initialize any variable you plan on using in this hash. There are two -# variables stored in this hash that are maintained by the system. -# - $globalData->completeSets : This is the number of sets which the student -# has earned 100% on -# - $globalData->complete Problems : This is the number of problems which the -# student has earned 100% on -# Warning: The achievements are always evaluated in the order they are listed -# on the Instructors achievement editor page. To make matters more -# complicated, achievements which have already been earned are not evaluated -# at all. The up-shot of this is that when modifying variables in -# $globalData you need to either write your code so it doesnt matter which -# order the evaluators are run in, or you need to pay very close attention -# to which evaluators are run and when. \ No newline at end of file diff --git a/courses.dist/modelCourse/templates/achievements/level_two.at b/courses.dist/modelCourse/templates/achievements/level_two.at deleted file mode 100644 index e6290d20c..000000000 --- a/courses.dist/modelCourse/templates/achievements/level_two.at +++ /dev/null @@ -1,86 +0,0 @@ -# This is a "level" achievement and they behave slightly differently. When -# a level achievement is earned the system uses the icon and title of the -# level achievement as the icon and title of that students level. There -# are two additional variables available to level achievements -# - $achievementPoints : the number of achievement points the current -# user has. (Changes to this variable will *not* be saved.) -# - $nextLevelPoints : the number of points needed to earn a level. -# (Changes to this variable will be saved if a new level is earned.) -# These variables are used to construct the users level progress bar - -#Constants: -#Threshold for level 3 -my $newLevelThreshold = 300; - -#Code - -if ($achievementPoints >= $nextLevelPoints) { - #set new threshold and return 1 - $nextLevelPoints = $newLevelThreshold; - return 1; -} else { - return 0; -} - -# Variable Descriptions: -# - $problem : the problem data (changes to this variable will not be saved!) -# This variable contains the problem data. It is a hash pointer with the -# following values (not all values shown) -# - $problem->status : the score of the current problem -# - $problem->problem_id : the id of the current problem -# - $problem->set_id : the id of the set containing the problem -# - $problem->num_correct : the number of correct attempts -# - $problem->num_incorrect : the number of incorrect attempts -# - $problem->last_answer : the last answer submitted -# - $problem->max_attempts : the maximum number of allowed attempts -# -# - $set : the set data (changes to this variable will not be saved!) -# This variable contains the set data. it is a hash pointer with the -# following values. (not all values shown) -# - $set->open_date : when the set was open -# - $set->due_date : when the set is due -# -# - @setProblems : the problem data for all the problems from this set. -# (changes to this variable will not be saved!) -# This is an array of problem hashes. Each element of the array has the -# save hash keys as the $problem variable above -# -# - $counter : the users counter associated to this achievement -# (changes to this variable *will* be saved!) -# If this achievement has a counter associated to it (i.e. solve 20 problems) -# then this is where you store the students counter for this achievement. -# This variable will initally start as '' -# -# - $maxCounter : the goal for the $counter variable for this achievement -# (changes to this variable will not be saved!) -# If this achievement has a counter associated to it then this variable -# contains the goal for the counter. Your achievement should return 1 -# when $counter >= $maxCounter. These two variables are used to show a -# progress bar for the achievement. -# -# - $localData : this is a hash which stores data for this user and achievement -# (changes to this variable *will* be saved!) -# This hash will persist from evaluation to evaluation. You can store whatever -# you like in here and it can be accessed next time this evaluator is run. -# Two things to keep in mind. The data in this hash will *not* be accessable -# by other achievements. If you plan to store something in this hash you have -# to write code to initialize the data. -# -# - $globalData : this is a hash which stores data for all achievements -# (changes to this variable *will* be saved!) -# This hash will persist from evaluation to evaluation and, like $localData, -# you can store whatever you like in here. This data will be accessable from -# *every* achievement and is unique to the user. Like $localData, you need to -# initialize any variable you plan on using in this hash. There are two -# variables stored in this hash that are maintained by the system. -# - $globalData->completeSets : This is the number of sets which the student -# has earned 100% on -# - $globalData->complete Problems : This is the number of problems which the -# student has earned 100% on -# Warning: The achievements are always evaluated in the order they are listed -# on the Instructors achievement editor page. To make matters more -# complicated, achievements which have already been earned are not evaluated -# at all. The up-shot of this is that when modifying variables in -# $globalData you need to either write your code so it doesnt matter which -# order the evaluators are run in, or you need to pay very close attention -# to which evaluators are run and when. \ No newline at end of file diff --git a/courses.dist/modelCourse/templates/achievements/many_fractions.at b/courses.dist/modelCourse/templates/achievements/many_fractions.at deleted file mode 100644 index e637e74ca..000000000 --- a/courses.dist/modelCourse/templates/achievements/many_fractions.at +++ /dev/null @@ -1,84 +0,0 @@ -#This problem checks to see if a particular problem from a list of valid -# sets and problems has been solved. (You would edit this file to say which -# sets and problems count.) - -#constants -my %validproblems = ( - 'SetNameHere' => { #now you show which problems are valid like: - '2' => 1, - '1' => 1, }, #and put more sets here - ); - -#check and see if this problem was solved -if ($validproblems{$problem->set_id} && - $validproblems{$problem->set_id}{$problem->problem_id} && - $problem->status == 1 && - $problem->num_correct == 1) { - return 1; - } - - return 0; - - -# -You have access to a variety of variables: -# - $problem : the problem data (changes to this variable will not be saved!) -# This variable contains the problem data. It is a hash pointer with the -# following values (not all values shown) -# - $problem->status : the score of the current problem -# - $problem->problem_id : the id of the current problem -# - $problem->set_id : the id of the set containing the problem -# - $problem->num_correct : the number of correct attempts -# - $problem->num_incorrect : the number of incorrect attempts -# - $problem->last_answer : the last answer submitted -# - $problem->max_attempts : the maximum number of allowed attempts -# -# - $set : the set data (changes to this variable will not be saved!) -# This variable contains the set data. it is a hash pointer with the -# following values. (not all values shown) -# - $set->open_date : when the set was open -# - $set->due_date : when the set is due -# -# - @setProblems : the problem data for all the problems from this set. -# (changes to this variable will not be saved!) -# This is an array of problem hashes. Each element of the array has the -# save hash keys as the $problem variable above -# -# - $counter : the users counter associated to this achievement -# (changes to this variable *will* be saved!) -# If this achievement has a counter associated to it (i.e. solve 20 problems) -# then this is where you store the students counter for this achievement. -# This variable will initally start as '' -# -# - $maxCounter : the goal for the $counter variable for this achievement -# (changes to this variable will not be saved!) -# If this achievement has a counter associated to it then this variable -# contains the goal for the counter. Your achievement should return 1 -# when $counter >= $maxCounter. These two variables are used to show a -# progress bar for the achievement. -# -# - $localData : this is a hash which stores data for this user and achievement -# (changes to this variable *will* be saved!) -# This hash will persist from evaluation to evaluation. You can store whatever -# you like in here and it can be accessed next time this evaluator is run. -# Two things to keep in mind. The data in this hash will *not* be accessable -# by other achievements. If you plan to store something in this hash you have -# to write code to initialize the data. -# -# - $globalData : this is a hash which stores data for all achievements -# (changes to this variable *will* be saved!) -# This hash will persist from evaluation to evaluation and, like $localData, -# you can store whatever you like in here. This data will be accessable from -# *every* achievement and is unique to the user. Like $localData, you need to -# initialize any variable you plan on using in this hash. There are two -# variables stored in this hash that are maintained by the system. -# - $globalData->{completeSets} : This is the number of sets which the student -# has earned 100% on -# - $globalData->{completeProblems} : This is the number of problems which the -# student has earned 100% on -# Warning: The achievements are always evaluated in the order they are listed -# on the Instructors achievement editor page. To make matters more -# complicated, achievements which have already been earned are not evaluated -# at all. The up-shot of this is that when modifying variables in -# $globalData you need to either write your code so it doesnt matter which -# order the evaluators are run in, or you need to pay very close attention -# to which evaluators are run and when. diff --git a/courses.dist/modelCourse/templates/achievements/night_owl.at b/courses.dist/modelCourse/templates/achievements/night_owl.at deleted file mode 100644 index 09afe57e9..000000000 --- a/courses.dist/modelCourse/templates/achievements/night_owl.at +++ /dev/null @@ -1,80 +0,0 @@ -# checks to see if a studen finished a set between 12AM and 2AM - my @timeData = localtime(time); - - #test to see if it is between midnight and 2am - if ($timeData[2] > 1) { - return 0; - } - - #if it is check to see if we have finished the set - - foreach my $problemRecord (@setProblems) { - if ($problemRecord->status != 1) { - return 0; - } - } - - return 1; - -# -You have access to a variety of variables: -# - $problem : the problem data (changes to this variable will not be saved!) -# This variable contains the problem data. It is a hash pointer with the -# following values (not all values shown) -# - $problem->status : the score of the current problem -# - $problem->problem_id : the id of the current problem -# - $problem->set_id : the id of the set containing the problem -# - $problem->num_correct : the number of correct attempts -# - $problem->num_incorrect : the number of incorrect attempts -# - $problem->last_answer : the last answer submitted -# - $problem->max_attempts : the maximum number of allowed attempts -# -# - $set : the set data (changes to this variable will not be saved!) -# This variable contains the set data. it is a hash pointer with the -# following values. (not all values shown) -# - $set->open_date : when the set was open -# - $set->due_date : when the set is due -# -# - @setProblems : the problem data for all the problems from this set. -# (changes to this variable will not be saved!) -# This is an array of problem hashes. Each element of the array has the -# save hash keys as the $problem variable above -# -# - $counter : the users counter associated to this achievement -# (changes to this variable *will* be saved!) -# If this achievement has a counter associated to it (i.e. solve 20 problems) -# then this is where you store the students counter for this achievement. -# This variable will initally start as '' -# -# - $maxCounter : the goal for the $counter variable for this achievement -# (changes to this variable will not be saved!) -# If this achievement has a counter associated to it then this variable -# contains the goal for the counter. Your achievement should return 1 -# when $counter >= $maxCounter. These two variables are used to show a -# progress bar for the achievement. -# -# - $localData : this is a hash which stores data for this user and achievement -# (changes to this variable *will* be saved!) -# This hash will persist from evaluation to evaluation. You can store whatever -# you like in here and it can be accessed next time this evaluator is run. -# Two things to keep in mind. The data in this hash will *not* be accessable -# by other achievements. If you plan to store something in this hash you have -# to write code to initialize the data. -# -# - $globalData : this is a hash which stores data for all achievements -# (changes to this variable *will* be saved!) -# This hash will persist from evaluation to evaluation and, like $localData, -# you can store whatever you like in here. This data will be accessable from -# *every* achievement and is unique to the user. Like $localData, you need to -# initialize any variable you plan on using in this hash. There are two -# variables stored in this hash that are maintained by the system. -# - $globalData->{completeSets} : This is the number of sets which the student -# has earned 100% on -# - $globalData->{completeProblems} : This is the number of problems which the -# student has earned 100% on -# Warning: The achievements are always evaluated in the order they are listed -# on the Instructors achievement editor page. To make matters more -# complicated, achievements which have already been earned are not evaluated -# at all. The up-shot of this is that when modifying variables in -# $globalData you need to either write your code so it doesnt matter which -# order the evaluators are run in, or you need to pay very close attention -# to which evaluators are run and when. \ No newline at end of file diff --git a/courses.dist/modelCourse/templates/achievements/on_fire.at b/courses.dist/modelCourse/templates/achievements/on_fire.at deleted file mode 100644 index b97b53c83..000000000 --- a/courses.dist/modelCourse/templates/achievements/on_fire.at +++ /dev/null @@ -1,82 +0,0 @@ -#This checks to see if the student has solved 10 problems without having any -# incorrect answers - -# reset counter if they got something wrong -if ($problem->status < 1) { - $counter = 0; - return 0; -# if they are right update the counter -} elsif ($problem->status == 1 && - $problem->num_correct == 1 && - $problem->num_incorrect == 0 ) { - $counter++; -} - -if ($counter >= $maxCounter) { - return 1; -} else { - return 0; -} - -# -You have access to a variety of variables: -# - $problem : the problem data (changes to this variable will not be saved!) -# This variable contains the problem data. It is a hash pointer with the -# following values (not all values shown) -# - $problem->status : the score of the current problem -# - $problem->problem_id : the id of the current problem -# - $problem->set_id : the id of the set containing the problem -# - $problem->num_correct : the number of correct attempts -# - $problem->num_incorrect : the number of incorrect attempts -# - $problem->last_answer : the last answer submitted -# - $problem->max_attempts : the maximum number of allowed attempts -# -# - $set : the set data (changes to this variable will not be saved!) -# This variable contains the set data. it is a hash pointer with the -# following values. (not all values shown) -# - $set->open_date : when the set was open -# - $set->due_date : when the set is due -# -# - @setProblems : the problem data for all the problems from this set. -# (changes to this variable will not be saved!) -# This is an array of problem hashes. Each element of the array has the -# save hash keys as the $problem variable above -# -# - $counter : the users counter associated to this achievement -# (changes to this variable *will* be saved!) -# If this achievement has a counter associated to it (i.e. solve 20 problems) -# then this is where you store the students counter for this achievement. -# This variable will initally start as '' -# -# - $maxCounter : the goal for the $counter variable for this achievement -# (changes to this variable will not be saved!) -# If this achievement has a counter associated to it then this variable -# contains the goal for the counter. Your achievement should return 1 -# when $counter >= $maxCounter. These two variables are used to show a -# progress bar for the achievement. -# -# - $localData : this is a hash which stores data for this user and achievement -# (changes to this variable *will* be saved!) -# This hash will persist from evaluation to evaluation. You can store whatever -# you like in here and it can be accessed next time this evaluator is run. -# Two things to keep in mind. The data in this hash will *not* be accessable -# by other achievements. If you plan to store something in this hash you have -# to write code to initialize the data. -# -# - $globalData : this is a hash which stores data for all achievements -# (changes to this variable *will* be saved!) -# This hash will persist from evaluation to evaluation and, like $localData, -# you can store whatever you like in here. This data will be accessable from -# *every* achievement and is unique to the user. Like $localData, you need to -# initialize any variable you plan on using in this hash. There are two -# variables stored in this hash that are maintained by the system. -# - $globalData->{completeSets} : This is the number of sets which the student -# has earned 100% on -# - $globalData->{completeProblems} : This is the number of problems which the -# student has earned 100% on -# Warning: The achievements are always evaluated in the order they are listed -# on the Instructors achievement editor page. To make matters more -# complicated, achievements which have already been earned are not evaluated -# at all. The up-shot of this is that when modifying variables in -# $globalData you need to either write your code so it doesnt matter which -# order the evaluators are run in, or you need to pay very close attention -# to which evaluators are run and when. diff --git a/courses.dist/modelCourse/templates/achievements/on_one_hand.at b/courses.dist/modelCourse/templates/achievements/on_one_hand.at deleted file mode 100644 index 0d9203d7e..000000000 --- a/courses.dist/modelCourse/templates/achievements/on_one_hand.at +++ /dev/null @@ -1,78 +0,0 @@ -#This checks to see if the student has finished the set -# with fewer than a certain number of incorrect submissions - - my $numfails = 0; - - #cycle through and leave if we have too many incorrects or a wrong problem - foreach my $problemRecord (@setProblems) { - $numfails += $problemRecord->num_incorrect; - if ($problemRecord->status != 1 || $numfails >5) { - return 0; - } - } - - return 1; - - -# -You have access to a variety of variables: -# - $problem : the problem data (changes to this variable will not be saved!) -# This variable contains the problem data. It is a hash pointer with the -# following values (not all values shown) -# - $problem->status : the score of the current problem -# - $problem->problem_id : the id of the current problem -# - $problem->set_id : the id of the set containing the problem -# - $problem->num_correct : the number of correct attempts -# - $problem->num_incorrect : the number of incorrect attempts -# - $problem->last_answer : the last answer submitted -# - $problem->max_attempts : the maximum number of allowed attempts -# -# - $set : the set data (changes to this variable will not be saved!) -# This variable contains the set data. it is a hash pointer with the -# following values. (not all values shown) -# - $set->open_date : when the set was open -# - $set->due_date : when the set is due -# -# - @setProblems : the problem data for all the problems from this set. -# (changes to this variable will not be saved!) -# This is an array of problem hashes. Each element of the array has the -# save hash keys as the $problem variable above -# -# - $counter : the users counter associated to this achievement -# (changes to this variable *will* be saved!) -# If this achievement has a counter associated to it (i.e. solve 20 problems) -# then this is where you store the students counter for this achievement. -# This variable will initally start as '' -# -# - $maxCounter : the goal for the $counter variable for this achievement -# (changes to this variable will not be saved!) -# If this achievement has a counter associated to it then this variable -# contains the goal for the counter. Your achievement should return 1 -# when $counter >= $maxCounter. These two variables are used to show a -# progress bar for the achievement. -# -# - $localData : this is a hash which stores data for this user and achievement -# (changes to this variable *will* be saved!) -# This hash will persist from evaluation to evaluation. You can store whatever -# you like in here and it can be accessed next time this evaluator is run. -# Two things to keep in mind. The data in this hash will *not* be accessable -# by other achievements. If you plan to store something in this hash you have -# to write code to initialize the data. -# -# - $globalData : this is a hash which stores data for all achievements -# (changes to this variable *will* be saved!) -# This hash will persist from evaluation to evaluation and, like $localData, -# you can store whatever you like in here. This data will be accessable from -# *every* achievement and is unique to the user. Like $localData, you need to -# initialize any variable you plan on using in this hash. There are two -# variables stored in this hash that are maintained by the system. -# - $globalData->{completeSets} : This is the number of sets which the student -# has earned 100% on -# - $globalData->{completeProblems} : This is the number of problems which the -# student has earned 100% on -# Warning: The achievements are always evaluated in the order they are listed -# on the Instructors achievement editor page. To make matters more -# complicated, achievements which have already been earned are not evaluated -# at all. The up-shot of this is that when modifying variables in -# $globalData you need to either write your code so it doesnt matter which -# order the evaluators are run in, or you need to pay very close attention -# to which evaluators are run and when. \ No newline at end of file diff --git a/courses.dist/modelCourse/templates/achievements/on_the_hour.at b/courses.dist/modelCourse/templates/achievements/on_the_hour.at deleted file mode 100644 index bc393439b..000000000 --- a/courses.dist/modelCourse/templates/achievements/on_the_hour.at +++ /dev/null @@ -1,77 +0,0 @@ -# checks to see if a studen finished a problem at the top of an hour - my @timeData = localtime(time); - - #test to see if it is near the top of an hour - if ($timeData[1] > 0) { - return 0; - } - - #test to see if the problem is correct and this is the first run - if ($problem-> status != 1 || $problem->num_correct != 1) { - return 0; - } - - return 1; - -# -You have access to a variety of variables: -# - $problem : the problem data (changes to this variable will not be saved!) -# This variable contains the problem data. It is a hash pointer with the -# following values (not all values shown) -# - $problem->status : the score of the current problem -# - $problem->problem_id : the id of the current problem -# - $problem->set_id : the id of the set containing the problem -# - $problem->num_correct : the number of correct attempts -# - $problem->num_incorrect : the number of incorrect attempts -# - $problem->last_answer : the last answer submitted -# - $problem->max_attempts : the maximum number of allowed attempts -# -# - $set : the set data (changes to this variable will not be saved!) -# This variable contains the set data. it is a hash pointer with the -# following values. (not all values shown) -# - $set->open_date : when the set was open -# - $set->due_date : when the set is due -# -# - @setProblems : the problem data for all the problems from this set. -# (changes to this variable will not be saved!) -# This is an array of problem hashes. Each element of the array has the -# save hash keys as the $problem variable above -# -# - $counter : the users counter associated to this achievement -# (changes to this variable *will* be saved!) -# If this achievement has a counter associated to it (i.e. solve 20 problems) -# then this is where you store the students counter for this achievement. -# This variable will initally start as '' -# -# - $maxCounter : the goal for the $counter variable for this achievement -# (changes to this variable will not be saved!) -# If this achievement has a counter associated to it then this variable -# contains the goal for the counter. Your achievement should return 1 -# when $counter >= $maxCounter. These two variables are used to show a -# progress bar for the achievement. -# -# - $localData : this is a hash which stores data for this user and achievement -# (changes to this variable *will* be saved!) -# This hash will persist from evaluation to evaluation. You can store whatever -# you like in here and it can be accessed next time this evaluator is run. -# Two things to keep in mind. The data in this hash will *not* be accessable -# by other achievements. If you plan to store something in this hash you have -# to write code to initialize the data. -# -# - $globalData : this is a hash which stores data for all achievements -# (changes to this variable *will* be saved!) -# This hash will persist from evaluation to evaluation and, like $localData, -# you can store whatever you like in here. This data will be accessable from -# *every* achievement and is unique to the user. Like $localData, you need to -# initialize any variable you plan on using in this hash. There are two -# variables stored in this hash that are maintained by the system. -# - $globalData->{completeSets} : This is the number of sets which the student -# has earned 100% on -# - $globalData->{completeProblems} : This is the number of problems which the -# student has earned 100% on -# Warning: The achievements are always evaluated in the order they are listed -# on the Instructors achievement editor page. To make matters more -# complicated, achievements which have already been earned are not evaluated -# at all. The up-shot of this is that when modifying variables in -# $globalData you need to either write your code so it doesnt matter which -# order the evaluators are run in, or you need to pay very close attention -# to which evaluators are run and when. \ No newline at end of file diff --git a/courses.dist/modelCourse/templates/achievements/one_click.at b/courses.dist/modelCourse/templates/achievements/one_click.at deleted file mode 100644 index c83ad25ac..000000000 --- a/courses.dist/modelCourse/templates/achievements/one_click.at +++ /dev/null @@ -1,72 +0,0 @@ -#This checks to see if the student has finished the problem with no -# incorrect submissions - - if ($problem->status == 1 && $problem->num_incorrect == 0) { - return 1; - } else { - return 0; - } - - -# -You have access to a variety of variables: -# - $problem : the problem data (changes to this variable will not be saved!) -# This variable contains the problem data. It is a hash pointer with the -# following values (not all values shown) -# - $problem->status : the score of the current problem -# - $problem->problem_id : the id of the current problem -# - $problem->set_id : the id of the set containing the problem -# - $problem->num_correct : the number of correct attempts -# - $problem->num_incorrect : the number of incorrect attempts -# - $problem->last_answer : the last answer submitted -# - $problem->max_attempts : the maximum number of allowed attempts -# -# - $set : the set data (changes to this variable will not be saved!) -# This variable contains the set data. it is a hash pointer with the -# following values. (not all values shown) -# - $set->open_date : when the set was open -# - $set->due_date : when the set is due -# -# - @setProblems : the problem data for all the problems from this set. -# (changes to this variable will not be saved!) -# This is an array of problem hashes. Each element of the array has the -# save hash keys as the $problem variable above -# -# - $counter : the users counter associated to this achievement -# (changes to this variable *will* be saved!) -# If this achievement has a counter associated to it (i.e. solve 20 problems) -# then this is where you store the students counter for this achievement. -# This variable will initally start as '' -# -# - $maxCounter : the goal for the $counter variable for this achievement -# (changes to this variable will not be saved!) -# If this achievement has a counter associated to it then this variable -# contains the goal for the counter. Your achievement should return 1 -# when $counter >= $maxCounter. These two variables are used to show a -# progress bar for the achievement. -# -# - $localData : this is a hash which stores data for this user and achievement -# (changes to this variable *will* be saved!) -# This hash will persist from evaluation to evaluation. You can store whatever -# you like in here and it can be accessed next time this evaluator is run. -# Two things to keep in mind. The data in this hash will *not* be accessable -# by other achievements. If you plan to store something in this hash you have -# to write code to initialize the data. -# -# - $globalData : this is a hash which stores data for all achievements -# (changes to this variable *will* be saved!) -# This hash will persist from evaluation to evaluation and, like $localData, -# you can store whatever you like in here. This data will be accessable from -# *every* achievement and is unique to the user. Like $localData, you need to -# initialize any variable you plan on using in this hash. There are two -# variables stored in this hash that are maintained by the system. -# - $globalData->{completeSets} : This is the number of sets which the student -# has earned 100% on -# - $globalData->{completeProblems} : This is the number of problems which the -# student has earned 100% on -# Warning: The achievements are always evaluated in the order they are listed -# on the Instructors achievement editor page. To make matters more -# complicated, achievements which have already been earned are not evaluated -# at all. The up-shot of this is that when modifying variables in -# $globalData you need to either write your code so it doesnt matter which -# order the evaluators are run in, or you need to pay very close attention -# to which evaluators are run and when. \ No newline at end of file diff --git a/courses.dist/modelCourse/templates/achievements/optimizer_prime.at b/courses.dist/modelCourse/templates/achievements/optimizer_prime.at deleted file mode 100644 index e637e74ca..000000000 --- a/courses.dist/modelCourse/templates/achievements/optimizer_prime.at +++ /dev/null @@ -1,84 +0,0 @@ -#This problem checks to see if a particular problem from a list of valid -# sets and problems has been solved. (You would edit this file to say which -# sets and problems count.) - -#constants -my %validproblems = ( - 'SetNameHere' => { #now you show which problems are valid like: - '2' => 1, - '1' => 1, }, #and put more sets here - ); - -#check and see if this problem was solved -if ($validproblems{$problem->set_id} && - $validproblems{$problem->set_id}{$problem->problem_id} && - $problem->status == 1 && - $problem->num_correct == 1) { - return 1; - } - - return 0; - - -# -You have access to a variety of variables: -# - $problem : the problem data (changes to this variable will not be saved!) -# This variable contains the problem data. It is a hash pointer with the -# following values (not all values shown) -# - $problem->status : the score of the current problem -# - $problem->problem_id : the id of the current problem -# - $problem->set_id : the id of the set containing the problem -# - $problem->num_correct : the number of correct attempts -# - $problem->num_incorrect : the number of incorrect attempts -# - $problem->last_answer : the last answer submitted -# - $problem->max_attempts : the maximum number of allowed attempts -# -# - $set : the set data (changes to this variable will not be saved!) -# This variable contains the set data. it is a hash pointer with the -# following values. (not all values shown) -# - $set->open_date : when the set was open -# - $set->due_date : when the set is due -# -# - @setProblems : the problem data for all the problems from this set. -# (changes to this variable will not be saved!) -# This is an array of problem hashes. Each element of the array has the -# save hash keys as the $problem variable above -# -# - $counter : the users counter associated to this achievement -# (changes to this variable *will* be saved!) -# If this achievement has a counter associated to it (i.e. solve 20 problems) -# then this is where you store the students counter for this achievement. -# This variable will initally start as '' -# -# - $maxCounter : the goal for the $counter variable for this achievement -# (changes to this variable will not be saved!) -# If this achievement has a counter associated to it then this variable -# contains the goal for the counter. Your achievement should return 1 -# when $counter >= $maxCounter. These two variables are used to show a -# progress bar for the achievement. -# -# - $localData : this is a hash which stores data for this user and achievement -# (changes to this variable *will* be saved!) -# This hash will persist from evaluation to evaluation. You can store whatever -# you like in here and it can be accessed next time this evaluator is run. -# Two things to keep in mind. The data in this hash will *not* be accessable -# by other achievements. If you plan to store something in this hash you have -# to write code to initialize the data. -# -# - $globalData : this is a hash which stores data for all achievements -# (changes to this variable *will* be saved!) -# This hash will persist from evaluation to evaluation and, like $localData, -# you can store whatever you like in here. This data will be accessable from -# *every* achievement and is unique to the user. Like $localData, you need to -# initialize any variable you plan on using in this hash. There are two -# variables stored in this hash that are maintained by the system. -# - $globalData->{completeSets} : This is the number of sets which the student -# has earned 100% on -# - $globalData->{completeProblems} : This is the number of problems which the -# student has earned 100% on -# Warning: The achievements are always evaluated in the order they are listed -# on the Instructors achievement editor page. To make matters more -# complicated, achievements which have already been earned are not evaluated -# at all. The up-shot of this is that when modifying variables in -# $globalData you need to either write your code so it doesnt matter which -# order the evaluators are run in, or you need to pay very close attention -# to which evaluators are run and when. diff --git a/courses.dist/modelCourse/templates/achievements/pattern_recognition.at b/courses.dist/modelCourse/templates/achievements/pattern_recognition.at deleted file mode 100644 index e637e74ca..000000000 --- a/courses.dist/modelCourse/templates/achievements/pattern_recognition.at +++ /dev/null @@ -1,84 +0,0 @@ -#This problem checks to see if a particular problem from a list of valid -# sets and problems has been solved. (You would edit this file to say which -# sets and problems count.) - -#constants -my %validproblems = ( - 'SetNameHere' => { #now you show which problems are valid like: - '2' => 1, - '1' => 1, }, #and put more sets here - ); - -#check and see if this problem was solved -if ($validproblems{$problem->set_id} && - $validproblems{$problem->set_id}{$problem->problem_id} && - $problem->status == 1 && - $problem->num_correct == 1) { - return 1; - } - - return 0; - - -# -You have access to a variety of variables: -# - $problem : the problem data (changes to this variable will not be saved!) -# This variable contains the problem data. It is a hash pointer with the -# following values (not all values shown) -# - $problem->status : the score of the current problem -# - $problem->problem_id : the id of the current problem -# - $problem->set_id : the id of the set containing the problem -# - $problem->num_correct : the number of correct attempts -# - $problem->num_incorrect : the number of incorrect attempts -# - $problem->last_answer : the last answer submitted -# - $problem->max_attempts : the maximum number of allowed attempts -# -# - $set : the set data (changes to this variable will not be saved!) -# This variable contains the set data. it is a hash pointer with the -# following values. (not all values shown) -# - $set->open_date : when the set was open -# - $set->due_date : when the set is due -# -# - @setProblems : the problem data for all the problems from this set. -# (changes to this variable will not be saved!) -# This is an array of problem hashes. Each element of the array has the -# save hash keys as the $problem variable above -# -# - $counter : the users counter associated to this achievement -# (changes to this variable *will* be saved!) -# If this achievement has a counter associated to it (i.e. solve 20 problems) -# then this is where you store the students counter for this achievement. -# This variable will initally start as '' -# -# - $maxCounter : the goal for the $counter variable for this achievement -# (changes to this variable will not be saved!) -# If this achievement has a counter associated to it then this variable -# contains the goal for the counter. Your achievement should return 1 -# when $counter >= $maxCounter. These two variables are used to show a -# progress bar for the achievement. -# -# - $localData : this is a hash which stores data for this user and achievement -# (changes to this variable *will* be saved!) -# This hash will persist from evaluation to evaluation. You can store whatever -# you like in here and it can be accessed next time this evaluator is run. -# Two things to keep in mind. The data in this hash will *not* be accessable -# by other achievements. If you plan to store something in this hash you have -# to write code to initialize the data. -# -# - $globalData : this is a hash which stores data for all achievements -# (changes to this variable *will* be saved!) -# This hash will persist from evaluation to evaluation and, like $localData, -# you can store whatever you like in here. This data will be accessable from -# *every* achievement and is unique to the user. Like $localData, you need to -# initialize any variable you plan on using in this hash. There are two -# variables stored in this hash that are maintained by the system. -# - $globalData->{completeSets} : This is the number of sets which the student -# has earned 100% on -# - $globalData->{completeProblems} : This is the number of problems which the -# student has earned 100% on -# Warning: The achievements are always evaluated in the order they are listed -# on the Instructors achievement editor page. To make matters more -# complicated, achievements which have already been earned are not evaluated -# at all. The up-shot of this is that when modifying variables in -# $globalData you need to either write your code so it doesnt matter which -# order the evaluators are run in, or you need to pay very close attention -# to which evaluators are run and when. diff --git a/courses.dist/modelCourse/templates/achievements/persistance.at b/courses.dist/modelCourse/templates/achievements/persistance.at deleted file mode 100644 index 027894be0..000000000 --- a/courses.dist/modelCourse/templates/achievements/persistance.at +++ /dev/null @@ -1,72 +0,0 @@ -#This checks to see if the student has solved the problem after a certain -# number of incorrect attempts - - if ($problem->status == 1 && $problem->num_incorrect >= 20) { - return 1 - } else { - return 0; - } - - -# -You have access to a variety of variables: -# - $problem : the problem data (changes to this variable will not be saved!) -# This variable contains the problem data. It is a hash pointer with the -# following values (not all values shown) -# - $problem->status : the score of the current problem -# - $problem->problem_id : the id of the current problem -# - $problem->set_id : the id of the set containing the problem -# - $problem->num_correct : the number of correct attempts -# - $problem->num_incorrect : the number of incorrect attempts -# - $problem->last_answer : the last answer submitted -# - $problem->max_attempts : the maximum number of allowed attempts -# -# - $set : the set data (changes to this variable will not be saved!) -# This variable contains the set data. it is a hash pointer with the -# following values. (not all values shown) -# - $set->open_date : when the set was open -# - $set->due_date : when the set is due -# -# - @setProblems : the problem data for all the problems from this set. -# (changes to this variable will not be saved!) -# This is an array of problem hashes. Each element of the array has the -# save hash keys as the $problem variable above -# -# - $counter : the users counter associated to this achievement -# (changes to this variable *will* be saved!) -# If this achievement has a counter associated to it (i.e. solve 20 problems) -# then this is where you store the students counter for this achievement. -# This variable will initally start as '' -# -# - $maxCounter : the goal for the $counter variable for this achievement -# (changes to this variable will not be saved!) -# If this achievement has a counter associated to it then this variable -# contains the goal for the counter. Your achievement should return 1 -# when $counter >= $maxCounter. These two variables are used to show a -# progress bar for the achievement. -# -# - $localData : this is a hash which stores data for this user and achievement -# (changes to this variable *will* be saved!) -# This hash will persist from evaluation to evaluation. You can store whatever -# you like in here and it can be accessed next time this evaluator is run. -# Two things to keep in mind. The data in this hash will *not* be accessable -# by other achievements. If you plan to store something in this hash you have -# to write code to initialize the data. -# -# - $globalData : this is a hash which stores data for all achievements -# (changes to this variable *will* be saved!) -# This hash will persist from evaluation to evaluation and, like $localData, -# you can store whatever you like in here. This data will be accessable from -# *every* achievement and is unique to the user. Like $localData, you need to -# initialize any variable you plan on using in this hash. There are two -# variables stored in this hash that are maintained by the system. -# - $globalData->{completeSets} : This is the number of sets which the student -# has earned 100% on -# - $globalData->{completeProblems} : This is the number of problems which the -# student has earned 100% on -# Warning: The achievements are always evaluated in the order they are listed -# on the Instructors achievement editor page. To make matters more -# complicated, achievements which have already been earned are not evaluated -# at all. The up-shot of this is that when modifying variables in -# $globalData you need to either write your code so it doesnt matter which -# order the evaluators are run in, or you need to pay very close attention -# to which evaluators are run and when. \ No newline at end of file diff --git a/courses.dist/modelCourse/templates/achievements/put_me_in_coach.at b/courses.dist/modelCourse/templates/achievements/put_me_in_coach.at deleted file mode 100644 index e637e74ca..000000000 --- a/courses.dist/modelCourse/templates/achievements/put_me_in_coach.at +++ /dev/null @@ -1,84 +0,0 @@ -#This problem checks to see if a particular problem from a list of valid -# sets and problems has been solved. (You would edit this file to say which -# sets and problems count.) - -#constants -my %validproblems = ( - 'SetNameHere' => { #now you show which problems are valid like: - '2' => 1, - '1' => 1, }, #and put more sets here - ); - -#check and see if this problem was solved -if ($validproblems{$problem->set_id} && - $validproblems{$problem->set_id}{$problem->problem_id} && - $problem->status == 1 && - $problem->num_correct == 1) { - return 1; - } - - return 0; - - -# -You have access to a variety of variables: -# - $problem : the problem data (changes to this variable will not be saved!) -# This variable contains the problem data. It is a hash pointer with the -# following values (not all values shown) -# - $problem->status : the score of the current problem -# - $problem->problem_id : the id of the current problem -# - $problem->set_id : the id of the set containing the problem -# - $problem->num_correct : the number of correct attempts -# - $problem->num_incorrect : the number of incorrect attempts -# - $problem->last_answer : the last answer submitted -# - $problem->max_attempts : the maximum number of allowed attempts -# -# - $set : the set data (changes to this variable will not be saved!) -# This variable contains the set data. it is a hash pointer with the -# following values. (not all values shown) -# - $set->open_date : when the set was open -# - $set->due_date : when the set is due -# -# - @setProblems : the problem data for all the problems from this set. -# (changes to this variable will not be saved!) -# This is an array of problem hashes. Each element of the array has the -# save hash keys as the $problem variable above -# -# - $counter : the users counter associated to this achievement -# (changes to this variable *will* be saved!) -# If this achievement has a counter associated to it (i.e. solve 20 problems) -# then this is where you store the students counter for this achievement. -# This variable will initally start as '' -# -# - $maxCounter : the goal for the $counter variable for this achievement -# (changes to this variable will not be saved!) -# If this achievement has a counter associated to it then this variable -# contains the goal for the counter. Your achievement should return 1 -# when $counter >= $maxCounter. These two variables are used to show a -# progress bar for the achievement. -# -# - $localData : this is a hash which stores data for this user and achievement -# (changes to this variable *will* be saved!) -# This hash will persist from evaluation to evaluation. You can store whatever -# you like in here and it can be accessed next time this evaluator is run. -# Two things to keep in mind. The data in this hash will *not* be accessable -# by other achievements. If you plan to store something in this hash you have -# to write code to initialize the data. -# -# - $globalData : this is a hash which stores data for all achievements -# (changes to this variable *will* be saved!) -# This hash will persist from evaluation to evaluation and, like $localData, -# you can store whatever you like in here. This data will be accessable from -# *every* achievement and is unique to the user. Like $localData, you need to -# initialize any variable you plan on using in this hash. There are two -# variables stored in this hash that are maintained by the system. -# - $globalData->{completeSets} : This is the number of sets which the student -# has earned 100% on -# - $globalData->{completeProblems} : This is the number of problems which the -# student has earned 100% on -# Warning: The achievements are always evaluated in the order they are listed -# on the Instructors achievement editor page. To make matters more -# complicated, achievements which have already been earned are not evaluated -# at all. The up-shot of this is that when modifying variables in -# $globalData you need to either write your code so it doesnt matter which -# order the evaluators are run in, or you need to pay very close attention -# to which evaluators are run and when. diff --git a/courses.dist/modelCourse/templates/achievements/reaching_a_limit.at b/courses.dist/modelCourse/templates/achievements/reaching_a_limit.at deleted file mode 100644 index 8c1c78fc8..000000000 --- a/courses.dist/modelCourse/templates/achievements/reaching_a_limit.at +++ /dev/null @@ -1,89 +0,0 @@ -#This problem checks to see if a particular problem from a list of valid -# sets and problems has been solved. If it has then it updates the counter -#(You would edit this file to say which sets and problems count.) - -#constants -my %validproblems = ( - 'SetNameHere' => { #now you show which problems are valid like: - '2' => 1, - '1' => 1, }, #and put more sets here - ); - -#check and see if this problem was solved -if ($validproblems{$problem->set_id} && - $validproblems{$problem->set_id}{$problem->problem_id} && - $problem->status == 1 && - $problem->num_correct == 1) { - #update counter; - $counter++; - } - -if ($counter >= $maxCounter) { - return 1; -} else { - return 0; -} - - -# -You have access to a variety of variables: -# - $problem : the problem data (changes to this variable will not be saved!) -# This variable contains the problem data. It is a hash pointer with the -# following values (not all values shown) -# - $problem->status : the score of the current problem -# - $problem->problem_id : the id of the current problem -# - $problem->set_id : the id of the set containing the problem -# - $problem->num_correct : the number of correct attempts -# - $problem->num_incorrect : the number of incorrect attempts -# - $problem->last_answer : the last answer submitted -# - $problem->max_attempts : the maximum number of allowed attempts -# -# - $set : the set data (changes to this variable will not be saved!) -# This variable contains the set data. it is a hash pointer with the -# following values. (not all values shown) -# - $set->open_date : when the set was open -# - $set->due_date : when the set is due -# -# - @setProblems : the problem data for all the problems from this set. -# (changes to this variable will not be saved!) -# This is an array of problem hashes. Each element of the array has the -# save hash keys as the $problem variable above -# -# - $counter : the users counter associated to this achievement -# (changes to this variable *will* be saved!) -# If this achievement has a counter associated to it (i.e. solve 20 problems) -# then this is where you store the students counter for this achievement. -# This variable will initally start as '' -# -# - $maxCounter : the goal for the $counter variable for this achievement -# (changes to this variable will not be saved!) -# If this achievement has a counter associated to it then this variable -# contains the goal for the counter. Your achievement should return 1 -# when $counter >= $maxCounter. These two variables are used to show a -# progress bar for the achievement. -# -# - $localData : this is a hash which stores data for this user and achievement -# (changes to this variable *will* be saved!) -# This hash will persist from evaluation to evaluation. You can store whatever -# you like in here and it can be accessed next time this evaluator is run. -# Two things to keep in mind. The data in this hash will *not* be accessable -# by other achievements. If you plan to store something in this hash you have -# to write code to initialize the data. -# -# - $globalData : this is a hash which stores data for all achievements -# (changes to this variable *will* be saved!) -# This hash will persist from evaluation to evaluation and, like $localData, -# you can store whatever you like in here. This data will be accessable from -# *every* achievement and is unique to the user. Like $localData, you need to -# initialize any variable you plan on using in this hash. There are two -# variables stored in this hash that are maintained by the system. -# - $globalData->{completeSets} : This is the number of sets which the student -# has earned 100% on -# - $globalData->{completeProblems} : This is the number of problems which the -# student has earned 100% on -# Warning: The achievements are always evaluated in the order they are listed -# on the Instructors achievement editor page. To make matters more -# complicated, achievements which have already been earned are not evaluated -# at all. The up-shot of this is that when modifying variables in -# $globalData you need to either write your code so it doesnt matter which -# order the evaluators are run in, or you need to pay very close attention -# to which evaluators are run and when. diff --git a/courses.dist/modelCourse/templates/achievements/really_early_bird.at b/courses.dist/modelCourse/templates/achievements/really_early_bird.at deleted file mode 100644 index 7d5c62138..000000000 --- a/courses.dist/modelCourse/templates/achievements/really_early_bird.at +++ /dev/null @@ -1,78 +0,0 @@ -#This checks to see if the student has finished the set within a certain time - - #test to see if it is before 2 hours after the open date - if ((time()-$set->open_date) > 7200) { - return 0; - } - - #if it is check to see if we have finished the set - foreach my $problemRecord (@setProblems) { - if ($problemRecord->status != 1) { - return 0; - } - } - - return 1; - -# -You have access to a variety of variables: -# - $problem : the problem data (changes to this variable will not be saved!) -# This variable contains the problem data. It is a hash pointer with the -# following values (not all values shown) -# - $problem->status : the score of the current problem -# - $problem->problem_id : the id of the current problem -# - $problem->set_id : the id of the set containing the problem -# - $problem->num_correct : the number of correct attempts -# - $problem->num_incorrect : the number of incorrect attempts -# - $problem->last_answer : the last answer submitted -# - $problem->max_attempts : the maximum number of allowed attempts -# -# - $set : the set data (changes to this variable will not be saved!) -# This variable contains the set data. it is a hash pointer with the -# following values. (not all values shown) -# - $set->open_date : when the set was open -# - $set->due_date : when the set is due -# -# - @setProblems : the problem data for all the problems from this set. -# (changes to this variable will not be saved!) -# This is an array of problem hashes. Each element of the array has the -# save hash keys as the $problem variable above -# -# - $counter : the users counter associated to this achievement -# (changes to this variable *will* be saved!) -# If this achievement has a counter associated to it (i.e. solve 20 problems) -# then this is where you store the students counter for this achievement. -# This variable will initally start as '' -# -# - $maxCounter : the goal for the $counter variable for this achievement -# (changes to this variable will not be saved!) -# If this achievement has a counter associated to it then this variable -# contains the goal for the counter. Your achievement should return 1 -# when $counter >= $maxCounter. These two variables are used to show a -# progress bar for the achievement. -# -# - $localData : this is a hash which stores data for this user and achievement -# (changes to this variable *will* be saved!) -# This hash will persist from evaluation to evaluation. You can store whatever -# you like in here and it can be accessed next time this evaluator is run. -# Two things to keep in mind. The data in this hash will *not* be accessable -# by other achievements. If you plan to store something in this hash you have -# to write code to initialize the data. -# -# - $globalData : this is a hash which stores data for all achievements -# (changes to this variable *will* be saved!) -# This hash will persist from evaluation to evaluation and, like $localData, -# you can store whatever you like in here. This data will be accessable from -# *every* achievement and is unique to the user. Like $localData, you need to -# initialize any variable you plan on using in this hash. There are two -# variables stored in this hash that are maintained by the system. -# - $globalData->{completeSets} : This is the number of sets which the student -# has earned 100% on -# - $globalData->{completeProblems} : This is the number of problems which the -# student has earned 100% on -# Warning: The achievements are always evaluated in the order they are listed -# on the Instructors achievement editor page. To make matters more -# complicated, achievements which have already been earned are not evaluated -# at all. The up-shot of this is that when modifying variables in -# $globalData you need to either write your code so it doesnt matter which -# order the evaluators are run in, or you need to pay very close attention -# to which evaluators are run and when. \ No newline at end of file diff --git a/courses.dist/modelCourse/templates/achievements/revolucion_redux.at b/courses.dist/modelCourse/templates/achievements/revolucion_redux.at deleted file mode 100644 index e637e74ca..000000000 --- a/courses.dist/modelCourse/templates/achievements/revolucion_redux.at +++ /dev/null @@ -1,84 +0,0 @@ -#This problem checks to see if a particular problem from a list of valid -# sets and problems has been solved. (You would edit this file to say which -# sets and problems count.) - -#constants -my %validproblems = ( - 'SetNameHere' => { #now you show which problems are valid like: - '2' => 1, - '1' => 1, }, #and put more sets here - ); - -#check and see if this problem was solved -if ($validproblems{$problem->set_id} && - $validproblems{$problem->set_id}{$problem->problem_id} && - $problem->status == 1 && - $problem->num_correct == 1) { - return 1; - } - - return 0; - - -# -You have access to a variety of variables: -# - $problem : the problem data (changes to this variable will not be saved!) -# This variable contains the problem data. It is a hash pointer with the -# following values (not all values shown) -# - $problem->status : the score of the current problem -# - $problem->problem_id : the id of the current problem -# - $problem->set_id : the id of the set containing the problem -# - $problem->num_correct : the number of correct attempts -# - $problem->num_incorrect : the number of incorrect attempts -# - $problem->last_answer : the last answer submitted -# - $problem->max_attempts : the maximum number of allowed attempts -# -# - $set : the set data (changes to this variable will not be saved!) -# This variable contains the set data. it is a hash pointer with the -# following values. (not all values shown) -# - $set->open_date : when the set was open -# - $set->due_date : when the set is due -# -# - @setProblems : the problem data for all the problems from this set. -# (changes to this variable will not be saved!) -# This is an array of problem hashes. Each element of the array has the -# save hash keys as the $problem variable above -# -# - $counter : the users counter associated to this achievement -# (changes to this variable *will* be saved!) -# If this achievement has a counter associated to it (i.e. solve 20 problems) -# then this is where you store the students counter for this achievement. -# This variable will initally start as '' -# -# - $maxCounter : the goal for the $counter variable for this achievement -# (changes to this variable will not be saved!) -# If this achievement has a counter associated to it then this variable -# contains the goal for the counter. Your achievement should return 1 -# when $counter >= $maxCounter. These two variables are used to show a -# progress bar for the achievement. -# -# - $localData : this is a hash which stores data for this user and achievement -# (changes to this variable *will* be saved!) -# This hash will persist from evaluation to evaluation. You can store whatever -# you like in here and it can be accessed next time this evaluator is run. -# Two things to keep in mind. The data in this hash will *not* be accessable -# by other achievements. If you plan to store something in this hash you have -# to write code to initialize the data. -# -# - $globalData : this is a hash which stores data for all achievements -# (changes to this variable *will* be saved!) -# This hash will persist from evaluation to evaluation and, like $localData, -# you can store whatever you like in here. This data will be accessable from -# *every* achievement and is unique to the user. Like $localData, you need to -# initialize any variable you plan on using in this hash. There are two -# variables stored in this hash that are maintained by the system. -# - $globalData->{completeSets} : This is the number of sets which the student -# has earned 100% on -# - $globalData->{completeProblems} : This is the number of problems which the -# student has earned 100% on -# Warning: The achievements are always evaluated in the order they are listed -# on the Instructors achievement editor page. To make matters more -# complicated, achievements which have already been earned are not evaluated -# at all. The up-shot of this is that when modifying variables in -# $globalData you need to either write your code so it doesnt matter which -# order the evaluators are run in, or you need to pay very close attention -# to which evaluators are run and when. diff --git a/courses.dist/modelCourse/templates/achievements/seeing_green.at b/courses.dist/modelCourse/templates/achievements/seeing_green.at deleted file mode 100644 index 948a4eed4..000000000 --- a/courses.dist/modelCourse/templates/achievements/seeing_green.at +++ /dev/null @@ -1,80 +0,0 @@ -#This checks to see if the student has finished the set -# with fewer than a certain number of incorrect submissions - - my $allcorrect = 1; - - foreach my $problemRecord (@setProblems) { - if ($problemRecord->status != 1 || $problemRecord->num_incorrect != 0) { - $allcorrect = 0; - last; - } - } - - if ($allcorrect) { - return 1; - } else { - return 0; - } - -# -You have access to a variety of variables: -# - $problem : the problem data (changes to this variable will not be saved!) -# This variable contains the problem data. It is a hash pointer with the -# following values (not all values shown) -# - $problem->status : the score of the current problem -# - $problem->problem_id : the id of the current problem -# - $problem->set_id : the id of the set containing the problem -# - $problem->num_correct : the number of correct attempts -# - $problem->num_incorrect : the number of incorrect attempts -# - $problem->last_answer : the last answer submitted -# - $problem->max_attempts : the maximum number of allowed attempts -# -# - $set : the set data (changes to this variable will not be saved!) -# This variable contains the set data. it is a hash pointer with the -# following values. (not all values shown) -# - $set->open_date : when the set was open -# - $set->due_date : when the set is due -# -# - @setProblems : the problem data for all the problems from this set. -# (changes to this variable will not be saved!) -# This is an array of problem hashes. Each element of the array has the -# save hash keys as the $problem variable above -# -# - $counter : the users counter associated to this achievement -# (changes to this variable *will* be saved!) -# If this achievement has a counter associated to it (i.e. solve 20 problems) -# then this is where you store the students counter for this achievement. -# This variable will initally start as '' -# -# - $maxCounter : the goal for the $counter variable for this achievement -# (changes to this variable will not be saved!) -# If this achievement has a counter associated to it then this variable -# contains the goal for the counter. Your achievement should return 1 -# when $counter >= $maxCounter. These two variables are used to show a -# progress bar for the achievement. -# -# - $localData : this is a hash which stores data for this user and achievement -# (changes to this variable *will* be saved!) -# This hash will persist from evaluation to evaluation. You can store whatever -# you like in here and it can be accessed next time this evaluator is run. -# Two things to keep in mind. The data in this hash will *not* be accessable -# by other achievements. If you plan to store something in this hash you have -# to write code to initialize the data. -# -# - $globalData : this is a hash which stores data for all achievements -# (changes to this variable *will* be saved!) -# This hash will persist from evaluation to evaluation and, like $localData, -# you can store whatever you like in here. This data will be accessable from -# *every* achievement and is unique to the user. Like $localData, you need to -# initialize any variable you plan on using in this hash. There are two -# variables stored in this hash that are maintained by the system. -# - $globalData->{completeSets} : This is the number of sets which the student -# has earned 100% on -# - $globalData->{completeProblems} : This is the number of problems which the -# student has earned 100% on -# Warning: The achievements are always evaluated in the order they are listed -# on the Instructors achievement editor page. To make matters more -# complicated, achievements which have already been earned are not evaluated -# at all. The up-shot of this is that when modifying variables in -# $globalData you need to either write your code so it doesnt matter which -# order the evaluators are run in, or you need to pay very close attention -# to which evaluators are run and when. \ No newline at end of file diff --git a/courses.dist/modelCourse/templates/achievements/speed_mather.at b/courses.dist/modelCourse/templates/achievements/speed_mather.at deleted file mode 100644 index e251c0aac..000000000 --- a/courses.dist/modelCourse/templates/achievements/speed_mather.at +++ /dev/null @@ -1,89 +0,0 @@ -#This checks to see if the student has finished the whole set in -# less than 10 minutes from time to first input to time to last answer. - -# If the set id doest equal the id of the last set then set -# *this* set as the last set, and set the start time - -if ($problem->set_id ne $localData->{last_set}) { - $localData->{last_set} = $problem->set_id; - $localData->{start_time} = time(); - return 0; -} - -# of we spent more than 10 minutes on the set then leave -if ((time() - $localData->{start_time}) > 3600) { - return 0; -} else { #if it is check to see if we have finished the set - - foreach my $problemRecord (@setProblems) { - if ($problemRecord->status != 1) { - return 0; - } - } - - #the set is done so we are finished - return 1; -} - -# -You have access to a variety of variables: -# - $problem : the problem data (changes to this variable will not be saved!) -# This variable contains the problem data. It is a hash pointer with the -# following values (not all values shown) -# - $problem->status : the score of the current problem -# - $problem->problem_id : the id of the current problem -# - $problem->set_id : the id of the set containing the problem -# - $problem->num_correct : the number of correct attempts -# - $problem->num_incorrect : the number of incorrect attempts -# - $problem->last_answer : the last answer submitted -# - $problem->max_attempts : the maximum number of allowed attempts -# -# - $set : the set data (changes to this variable will not be saved!) -# This variable contains the set data. it is a hash pointer with the -# following values. (not all values shown) -# - $set->open_date : when the set was open -# - $set->due_date : when the set is due -# -# - @setProblems : the problem data for all the problems from this set. -# (changes to this variable will not be saved!) -# This is an array of problem hashes. Each element of the array has the -# save hash keys as the $problem variable above -# -# - $counter : the users counter associated to this achievement -# (changes to this variable *will* be saved!) -# If this achievement has a counter associated to it (i.e. solve 20 problems) -# then this is where you store the students counter for this achievement. -# This variable will initally start as '' -# -# - $maxCounter : the goal for the $counter variable for this achievement -# (changes to this variable will not be saved!) -# If this achievement has a counter associated to it then this variable -# contains the goal for the counter. Your achievement should return 1 -# when $counter >= $maxCounter. These two variables are used to show a -# progress bar for the achievement. -# -# - $localData : this is a hash which stores data for this user and achievement -# (changes to this variable *will* be saved!) -# This hash will persist from evaluation to evaluation. You can store whatever -# you like in here and it can be accessed next time this evaluator is run. -# Two things to keep in mind. The data in this hash will *not* be accessable -# by other achievements. If you plan to store something in this hash you have -# to write code to initialize the data. -# -# - $globalData : this is a hash which stores data for all achievements -# (changes to this variable *will* be saved!) -# This hash will persist from evaluation to evaluation and, like $localData, -# you can store whatever you like in here. This data will be accessable from -# *every* achievement and is unique to the user. Like $localData, you need to -# initialize any variable you plan on using in this hash. There are two -# variables stored in this hash that are maintained by the system. -# - $globalData->{completeSets} : This is the number of sets which the student -# has earned 100% on -# - $globalData->{completeProblems} : This is the number of problems which the -# student has earned 100% on -# Warning: The achievements are always evaluated in the order they are listed -# on the Instructors achievement editor page. To make matters more -# complicated, achievements which have already been earned are not evaluated -# at all. The up-shot of this is that when modifying variables in -# $globalData you need to either write your code so it doesnt matter which -# order the evaluators are run in, or you need to pay very close attention -# to which evaluators are run and when. \ No newline at end of file diff --git a/courses.dist/modelCourse/templates/achievements/still_not_right.at b/courses.dist/modelCourse/templates/achievements/still_not_right.at deleted file mode 100644 index cccacee82..000000000 --- a/courses.dist/modelCourse/templates/achievements/still_not_right.at +++ /dev/null @@ -1,85 +0,0 @@ -# checks to see if the student has inputted the same answer many times in a -# row. Because the $problem-last_answer field is updated *after* the -# achievements are evaluated, this acheivement will pop up late. - - $localData->{incorrect_streak} = 0 unless $localData->{incorrect_streak}; - - if ($problem->status == 1) { - return 0; - } elsif ($problem->set_id ne $localData->{set_id} || - $problem->problem_id ne $localData->{problem_id} || - $problem->last_answer ne $localData->{last_answer}) { - $localData->{set_id} = $problem->set_id; - $localData->{problem_id} = $problem->problem_id; - $localData->{last_answer} = $problem->last_answer; - $localData->{incorrect_streak} = 1; - return 0; - } elsif ($localData->{incorrect_streak} == 9) { - return 1; - } else { - $localData->{incorrect_streak}++; - return 0; - } - -# -You have access to a variety of variables: -# - $problem : the problem data (changes to this variable will not be saved!) -# This variable contains the problem data. It is a hash pointer with the -# following values (not all values shown) -# - $problem->status : the score of the current problem -# - $problem->problem_id : the id of the current problem -# - $problem->set_id : the id of the set containing the problem -# - $problem->num_correct : the number of correct attempts -# - $problem->num_incorrect : the number of incorrect attempts -# - $problem->last_answer : the last answer submitted -# - $problem->max_attempts : the maximum number of allowed attempts -# -# - $set : the set data (changes to this variable will not be saved!) -# This variable contains the set data. it is a hash pointer with the -# following values. (not all values shown) -# - $set->open_date : when the set was open -# - $set->due_date : when the set is due -# -# - @setProblems : the problem data for all the problems from this set. -# (changes to this variable will not be saved!) -# This is an array of problem hashes. Each element of the array has the -# save hash keys as the $problem variable above -# -# - $counter : the users counter associated to this achievement -# (changes to this variable *will* be saved!) -# If this achievement has a counter associated to it (i.e. solve 20 problems) -# then this is where you store the students counter for this achievement. -# This variable will initally start as '' -# -# - $maxCounter : the goal for the $counter variable for this achievement -# (changes to this variable will not be saved!) -# If this achievement has a counter associated to it then this variable -# contains the goal for the counter. Your achievement should return 1 -# when $counter >= $maxCounter. These two variables are used to show a -# progress bar for the achievement. -# -# - $localData : this is a hash which stores data for this user and achievement -# (changes to this variable *will* be saved!) -# This hash will persist from evaluation to evaluation. You can store whatever -# you like in here and it can be accessed next time this evaluator is run. -# Two things to keep in mind. The data in this hash will *not* be accessable -# by other achievements. If you plan to store something in this hash you have -# to write code to initialize the data. -# -# - $globalData : this is a hash which stores data for all achievements -# (changes to this variable *will* be saved!) -# This hash will persist from evaluation to evaluation and, like $localData, -# you can store whatever you like in here. This data will be accessable from -# *every* achievement and is unique to the user. Like $localData, you need to -# initialize any variable you plan on using in this hash. There are two -# variables stored in this hash that are maintained by the system. -# - $globalData->{completeSets} : This is the number of sets which the student -# has earned 100% on -# - $globalData->{completeProblems} : This is the number of problems which the -# student has earned 100% on -# Warning: The achievements are always evaluated in the order they are listed -# on the Instructors achievement editor page. To make matters more -# complicated, achievements which have already been earned are not evaluated -# at all. The up-shot of this is that when modifying variables in -# $globalData you need to either write your code so it doesnt matter which -# order the evaluators are run in, or you need to pay very close attention -# to which evaluators are run and when. \ No newline at end of file diff --git a/courses.dist/modelCourse/templates/achievements/super_persistance.at b/courses.dist/modelCourse/templates/achievements/super_persistance.at deleted file mode 100644 index 931b2e6ec..000000000 --- a/courses.dist/modelCourse/templates/achievements/super_persistance.at +++ /dev/null @@ -1,72 +0,0 @@ -#This checks to see if the student has solved the problem after a certain -# number of incorrect attempts - - if ($problem->status == 1 && $problem->num_incorrect >= 100) { - return 1 - } else { - return 0; - } - - -# -You have access to a variety of variables: -# - $problem : the problem data (changes to this variable will not be saved!) -# This variable contains the problem data. It is a hash pointer with the -# following values (not all values shown) -# - $problem->status : the score of the current problem -# - $problem->problem_id : the id of the current problem -# - $problem->set_id : the id of the set containing the problem -# - $problem->num_correct : the number of correct attempts -# - $problem->num_incorrect : the number of incorrect attempts -# - $problem->last_answer : the last answer submitted -# - $problem->max_attempts : the maximum number of allowed attempts -# -# - $set : the set data (changes to this variable will not be saved!) -# This variable contains the set data. it is a hash pointer with the -# following values. (not all values shown) -# - $set->open_date : when the set was open -# - $set->due_date : when the set is due -# -# - @setProblems : the problem data for all the problems from this set. -# (changes to this variable will not be saved!) -# This is an array of problem hashes. Each element of the array has the -# save hash keys as the $problem variable above -# -# - $counter : the users counter associated to this achievement -# (changes to this variable *will* be saved!) -# If this achievement has a counter associated to it (i.e. solve 20 problems) -# then this is where you store the students counter for this achievement. -# This variable will initally start as '' -# -# - $maxCounter : the goal for the $counter variable for this achievement -# (changes to this variable will not be saved!) -# If this achievement has a counter associated to it then this variable -# contains the goal for the counter. Your achievement should return 1 -# when $counter >= $maxCounter. These two variables are used to show a -# progress bar for the achievement. -# -# - $localData : this is a hash which stores data for this user and achievement -# (changes to this variable *will* be saved!) -# This hash will persist from evaluation to evaluation. You can store whatever -# you like in here and it can be accessed next time this evaluator is run. -# Two things to keep in mind. The data in this hash will *not* be accessable -# by other achievements. If you plan to store something in this hash you have -# to write code to initialize the data. -# -# - $globalData : this is a hash which stores data for all achievements -# (changes to this variable *will* be saved!) -# This hash will persist from evaluation to evaluation and, like $localData, -# you can store whatever you like in here. This data will be accessable from -# *every* achievement and is unique to the user. Like $localData, you need to -# initialize any variable you plan on using in this hash. There are two -# variables stored in this hash that are maintained by the system. -# - $globalData->{completeSets} : This is the number of sets which the student -# has earned 100% on -# - $globalData->{completeProblems} : This is the number of problems which the -# student has earned 100% on -# Warning: The achievements are always evaluated in the order they are listed -# on the Instructors achievement editor page. To make matters more -# complicated, achievements which have already been earned are not evaluated -# at all. The up-shot of this is that when modifying variables in -# $globalData you need to either write your code so it doesnt matter which -# order the evaluators are run in, or you need to pay very close attention -# to which evaluators are run and when. \ No newline at end of file diff --git a/courses.dist/modelCourse/templates/achievements/super_speed_math.at b/courses.dist/modelCourse/templates/achievements/super_speed_math.at deleted file mode 100644 index 9e121de52..000000000 --- a/courses.dist/modelCourse/templates/achievements/super_speed_math.at +++ /dev/null @@ -1,89 +0,0 @@ -#This checks to see if the student has finished the whole set in -# less than 10 minutes from time to first input to time to last answer. - -# If the set id doest equal the id of the last set then set -# *this* set as the last set, and set the start time - -if ($problem->set_id ne $localData->{last_set}) { - $localData->{last_set} = $problem->set_id; - $localData->{start_time} = time(); - return 0; -} - -# of we spent more than 10 minutes on the set then leave -if ((time() - $localData->{start_time}) > 600) { - return 0; -} else { #if it is check to see if we have finished the set - - foreach my $problemRecord (@setProblems) { - if ($problemRecord->status != 1) { - return 0; - } - } - - #the set is done so we are finished - return 1; -} - -# -You have access to a variety of variables: -# - $problem : the problem data (changes to this variable will not be saved!) -# This variable contains the problem data. It is a hash pointer with the -# following values (not all values shown) -# - $problem->status : the score of the current problem -# - $problem->problem_id : the id of the current problem -# - $problem->set_id : the id of the set containing the problem -# - $problem->num_correct : the number of correct attempts -# - $problem->num_incorrect : the number of incorrect attempts -# - $problem->last_answer : the last answer submitted -# - $problem->max_attempts : the maximum number of allowed attempts -# -# - $set : the set data (changes to this variable will not be saved!) -# This variable contains the set data. it is a hash pointer with the -# following values. (not all values shown) -# - $set->open_date : when the set was open -# - $set->due_date : when the set is due -# -# - @setProblems : the problem data for all the problems from this set. -# (changes to this variable will not be saved!) -# This is an array of problem hashes. Each element of the array has the -# save hash keys as the $problem variable above -# -# - $counter : the users counter associated to this achievement -# (changes to this variable *will* be saved!) -# If this achievement has a counter associated to it (i.e. solve 20 problems) -# then this is where you store the students counter for this achievement. -# This variable will initally start as '' -# -# - $maxCounter : the goal for the $counter variable for this achievement -# (changes to this variable will not be saved!) -# If this achievement has a counter associated to it then this variable -# contains the goal for the counter. Your achievement should return 1 -# when $counter >= $maxCounter. These two variables are used to show a -# progress bar for the achievement. -# -# - $localData : this is a hash which stores data for this user and achievement -# (changes to this variable *will* be saved!) -# This hash will persist from evaluation to evaluation. You can store whatever -# you like in here and it can be accessed next time this evaluator is run. -# Two things to keep in mind. The data in this hash will *not* be accessable -# by other achievements. If you plan to store something in this hash you have -# to write code to initialize the data. -# -# - $globalData : this is a hash which stores data for all achievements -# (changes to this variable *will* be saved!) -# This hash will persist from evaluation to evaluation and, like $localData, -# you can store whatever you like in here. This data will be accessable from -# *every* achievement and is unique to the user. Like $localData, you need to -# initialize any variable you plan on using in this hash. There are two -# variables stored in this hash that are maintained by the system. -# - $globalData->{completeSets} : This is the number of sets which the student -# has earned 100% on -# - $globalData->{completeProblems} : This is the number of problems which the -# student has earned 100% on -# Warning: The achievements are always evaluated in the order they are listed -# on the Instructors achievement editor page. To make matters more -# complicated, achievements which have already been earned are not evaluated -# at all. The up-shot of this is that when modifying variables in -# $globalData you need to either write your code so it doesnt matter which -# order the evaluators are run in, or you need to pay very close attention -# to which evaluators are run and when. \ No newline at end of file diff --git a/courses.dist/modelCourse/templates/achievements/taylor_hero.at b/courses.dist/modelCourse/templates/achievements/taylor_hero.at deleted file mode 100644 index e637e74ca..000000000 --- a/courses.dist/modelCourse/templates/achievements/taylor_hero.at +++ /dev/null @@ -1,84 +0,0 @@ -#This problem checks to see if a particular problem from a list of valid -# sets and problems has been solved. (You would edit this file to say which -# sets and problems count.) - -#constants -my %validproblems = ( - 'SetNameHere' => { #now you show which problems are valid like: - '2' => 1, - '1' => 1, }, #and put more sets here - ); - -#check and see if this problem was solved -if ($validproblems{$problem->set_id} && - $validproblems{$problem->set_id}{$problem->problem_id} && - $problem->status == 1 && - $problem->num_correct == 1) { - return 1; - } - - return 0; - - -# -You have access to a variety of variables: -# - $problem : the problem data (changes to this variable will not be saved!) -# This variable contains the problem data. It is a hash pointer with the -# following values (not all values shown) -# - $problem->status : the score of the current problem -# - $problem->problem_id : the id of the current problem -# - $problem->set_id : the id of the set containing the problem -# - $problem->num_correct : the number of correct attempts -# - $problem->num_incorrect : the number of incorrect attempts -# - $problem->last_answer : the last answer submitted -# - $problem->max_attempts : the maximum number of allowed attempts -# -# - $set : the set data (changes to this variable will not be saved!) -# This variable contains the set data. it is a hash pointer with the -# following values. (not all values shown) -# - $set->open_date : when the set was open -# - $set->due_date : when the set is due -# -# - @setProblems : the problem data for all the problems from this set. -# (changes to this variable will not be saved!) -# This is an array of problem hashes. Each element of the array has the -# save hash keys as the $problem variable above -# -# - $counter : the users counter associated to this achievement -# (changes to this variable *will* be saved!) -# If this achievement has a counter associated to it (i.e. solve 20 problems) -# then this is where you store the students counter for this achievement. -# This variable will initally start as '' -# -# - $maxCounter : the goal for the $counter variable for this achievement -# (changes to this variable will not be saved!) -# If this achievement has a counter associated to it then this variable -# contains the goal for the counter. Your achievement should return 1 -# when $counter >= $maxCounter. These two variables are used to show a -# progress bar for the achievement. -# -# - $localData : this is a hash which stores data for this user and achievement -# (changes to this variable *will* be saved!) -# This hash will persist from evaluation to evaluation. You can store whatever -# you like in here and it can be accessed next time this evaluator is run. -# Two things to keep in mind. The data in this hash will *not* be accessable -# by other achievements. If you plan to store something in this hash you have -# to write code to initialize the data. -# -# - $globalData : this is a hash which stores data for all achievements -# (changes to this variable *will* be saved!) -# This hash will persist from evaluation to evaluation and, like $localData, -# you can store whatever you like in here. This data will be accessable from -# *every* achievement and is unique to the user. Like $localData, you need to -# initialize any variable you plan on using in this hash. There are two -# variables stored in this hash that are maintained by the system. -# - $globalData->{completeSets} : This is the number of sets which the student -# has earned 100% on -# - $globalData->{completeProblems} : This is the number of problems which the -# student has earned 100% on -# Warning: The achievements are always evaluated in the order they are listed -# on the Instructors achievement editor page. To make matters more -# complicated, achievements which have already been earned are not evaluated -# at all. The up-shot of this is that when modifying variables in -# $globalData you need to either write your code so it doesnt matter which -# order the evaluators are run in, or you need to pay very close attention -# to which evaluators are run and when. diff --git a/courses.dist/modelCourse/templates/achievements/the_fundamentals.at b/courses.dist/modelCourse/templates/achievements/the_fundamentals.at deleted file mode 100644 index e637e74ca..000000000 --- a/courses.dist/modelCourse/templates/achievements/the_fundamentals.at +++ /dev/null @@ -1,84 +0,0 @@ -#This problem checks to see if a particular problem from a list of valid -# sets and problems has been solved. (You would edit this file to say which -# sets and problems count.) - -#constants -my %validproblems = ( - 'SetNameHere' => { #now you show which problems are valid like: - '2' => 1, - '1' => 1, }, #and put more sets here - ); - -#check and see if this problem was solved -if ($validproblems{$problem->set_id} && - $validproblems{$problem->set_id}{$problem->problem_id} && - $problem->status == 1 && - $problem->num_correct == 1) { - return 1; - } - - return 0; - - -# -You have access to a variety of variables: -# - $problem : the problem data (changes to this variable will not be saved!) -# This variable contains the problem data. It is a hash pointer with the -# following values (not all values shown) -# - $problem->status : the score of the current problem -# - $problem->problem_id : the id of the current problem -# - $problem->set_id : the id of the set containing the problem -# - $problem->num_correct : the number of correct attempts -# - $problem->num_incorrect : the number of incorrect attempts -# - $problem->last_answer : the last answer submitted -# - $problem->max_attempts : the maximum number of allowed attempts -# -# - $set : the set data (changes to this variable will not be saved!) -# This variable contains the set data. it is a hash pointer with the -# following values. (not all values shown) -# - $set->open_date : when the set was open -# - $set->due_date : when the set is due -# -# - @setProblems : the problem data for all the problems from this set. -# (changes to this variable will not be saved!) -# This is an array of problem hashes. Each element of the array has the -# save hash keys as the $problem variable above -# -# - $counter : the users counter associated to this achievement -# (changes to this variable *will* be saved!) -# If this achievement has a counter associated to it (i.e. solve 20 problems) -# then this is where you store the students counter for this achievement. -# This variable will initally start as '' -# -# - $maxCounter : the goal for the $counter variable for this achievement -# (changes to this variable will not be saved!) -# If this achievement has a counter associated to it then this variable -# contains the goal for the counter. Your achievement should return 1 -# when $counter >= $maxCounter. These two variables are used to show a -# progress bar for the achievement. -# -# - $localData : this is a hash which stores data for this user and achievement -# (changes to this variable *will* be saved!) -# This hash will persist from evaluation to evaluation. You can store whatever -# you like in here and it can be accessed next time this evaluator is run. -# Two things to keep in mind. The data in this hash will *not* be accessable -# by other achievements. If you plan to store something in this hash you have -# to write code to initialize the data. -# -# - $globalData : this is a hash which stores data for all achievements -# (changes to this variable *will* be saved!) -# This hash will persist from evaluation to evaluation and, like $localData, -# you can store whatever you like in here. This data will be accessable from -# *every* achievement and is unique to the user. Like $localData, you need to -# initialize any variable you plan on using in this hash. There are two -# variables stored in this hash that are maintained by the system. -# - $globalData->{completeSets} : This is the number of sets which the student -# has earned 100% on -# - $globalData->{completeProblems} : This is the number of problems which the -# student has earned 100% on -# Warning: The achievements are always evaluated in the order they are listed -# on the Instructors achievement editor page. To make matters more -# complicated, achievements which have already been earned are not evaluated -# at all. The up-shot of this is that when modifying variables in -# $globalData you need to either write your code so it doesnt matter which -# order the evaluators are run in, or you need to pay very close attention -# to which evaluators are run and when. diff --git a/courses.dist/modelCourse/templates/achievements/the_lhopital.at b/courses.dist/modelCourse/templates/achievements/the_lhopital.at deleted file mode 100644 index e637e74ca..000000000 --- a/courses.dist/modelCourse/templates/achievements/the_lhopital.at +++ /dev/null @@ -1,84 +0,0 @@ -#This problem checks to see if a particular problem from a list of valid -# sets and problems has been solved. (You would edit this file to say which -# sets and problems count.) - -#constants -my %validproblems = ( - 'SetNameHere' => { #now you show which problems are valid like: - '2' => 1, - '1' => 1, }, #and put more sets here - ); - -#check and see if this problem was solved -if ($validproblems{$problem->set_id} && - $validproblems{$problem->set_id}{$problem->problem_id} && - $problem->status == 1 && - $problem->num_correct == 1) { - return 1; - } - - return 0; - - -# -You have access to a variety of variables: -# - $problem : the problem data (changes to this variable will not be saved!) -# This variable contains the problem data. It is a hash pointer with the -# following values (not all values shown) -# - $problem->status : the score of the current problem -# - $problem->problem_id : the id of the current problem -# - $problem->set_id : the id of the set containing the problem -# - $problem->num_correct : the number of correct attempts -# - $problem->num_incorrect : the number of incorrect attempts -# - $problem->last_answer : the last answer submitted -# - $problem->max_attempts : the maximum number of allowed attempts -# -# - $set : the set data (changes to this variable will not be saved!) -# This variable contains the set data. it is a hash pointer with the -# following values. (not all values shown) -# - $set->open_date : when the set was open -# - $set->due_date : when the set is due -# -# - @setProblems : the problem data for all the problems from this set. -# (changes to this variable will not be saved!) -# This is an array of problem hashes. Each element of the array has the -# save hash keys as the $problem variable above -# -# - $counter : the users counter associated to this achievement -# (changes to this variable *will* be saved!) -# If this achievement has a counter associated to it (i.e. solve 20 problems) -# then this is where you store the students counter for this achievement. -# This variable will initally start as '' -# -# - $maxCounter : the goal for the $counter variable for this achievement -# (changes to this variable will not be saved!) -# If this achievement has a counter associated to it then this variable -# contains the goal for the counter. Your achievement should return 1 -# when $counter >= $maxCounter. These two variables are used to show a -# progress bar for the achievement. -# -# - $localData : this is a hash which stores data for this user and achievement -# (changes to this variable *will* be saved!) -# This hash will persist from evaluation to evaluation. You can store whatever -# you like in here and it can be accessed next time this evaluator is run. -# Two things to keep in mind. The data in this hash will *not* be accessable -# by other achievements. If you plan to store something in this hash you have -# to write code to initialize the data. -# -# - $globalData : this is a hash which stores data for all achievements -# (changes to this variable *will* be saved!) -# This hash will persist from evaluation to evaluation and, like $localData, -# you can store whatever you like in here. This data will be accessable from -# *every* achievement and is unique to the user. Like $localData, you need to -# initialize any variable you plan on using in this hash. There are two -# variables stored in this hash that are maintained by the system. -# - $globalData->{completeSets} : This is the number of sets which the student -# has earned 100% on -# - $globalData->{completeProblems} : This is the number of problems which the -# student has earned 100% on -# Warning: The achievements are always evaluated in the order they are listed -# on the Instructors achievement editor page. To make matters more -# complicated, achievements which have already been earned are not evaluated -# at all. The up-shot of this is that when modifying variables in -# $globalData you need to either write your code so it doesnt matter which -# order the evaluators are run in, or you need to pay very close attention -# to which evaluators are run and when. diff --git a/courses.dist/modelCourse/templates/achievements/third_time.at b/courses.dist/modelCourse/templates/achievements/third_time.at deleted file mode 100644 index 36572713a..000000000 --- a/courses.dist/modelCourse/templates/achievements/third_time.at +++ /dev/null @@ -1,71 +0,0 @@ -#This checks to see if the student has a certain number of attempts - - if ($problem->num_correct == 1 and $problem->num_incorrect == 2) { - return 1; - } else { - return 0; - } - - -# -You have access to a variety of variables: -# - $problem : the problem data (changes to this variable will not be saved!) -# This variable contains the problem data. It is a hash pointer with the -# following values (not all values shown) -# - $problem->status : the score of the current problem -# - $problem->problem_id : the id of the current problem -# - $problem->set_id : the id of the set containing the problem -# - $problem->num_correct : the number of correct attempts -# - $problem->num_incorrect : the number of incorrect attempts -# - $problem->last_answer : the last answer submitted -# - $problem->max_attempts : the maximum number of allowed attempts -# -# - $set : the set data (changes to this variable will not be saved!) -# This variable contains the set data. it is a hash pointer with the -# following values. (not all values shown) -# - $set->open_date : when the set was open -# - $set->due_date : when the set is due -# -# - @setProblems : the problem data for all the problems from this set. -# (changes to this variable will not be saved!) -# This is an array of problem hashes. Each element of the array has the -# save hash keys as the $problem variable above -# -# - $counter : the users counter associated to this achievement -# (changes to this variable *will* be saved!) -# If this achievement has a counter associated to it (i.e. solve 20 problems) -# then this is where you store the students counter for this achievement. -# This variable will initally start as '' -# -# - $maxCounter : the goal for the $counter variable for this achievement -# (changes to this variable will not be saved!) -# If this achievement has a counter associated to it then this variable -# contains the goal for the counter. Your achievement should return 1 -# when $counter >= $maxCounter. These two variables are used to show a -# progress bar for the achievement. -# -# - $localData : this is a hash which stores data for this user and achievement -# (changes to this variable *will* be saved!) -# This hash will persist from evaluation to evaluation. You can store whatever -# you like in here and it can be accessed next time this evaluator is run. -# Two things to keep in mind. The data in this hash will *not* be accessable -# by other achievements. If you plan to store something in this hash you have -# to write code to initialize the data. -# -# - $globalData : this is a hash which stores data for all achievements -# (changes to this variable *will* be saved!) -# This hash will persist from evaluation to evaluation and, like $localData, -# you can store whatever you like in here. This data will be accessable from -# *every* achievement and is unique to the user. Like $localData, you need to -# initialize any variable you plan on using in this hash. There are two -# variables stored in this hash that are maintained by the system. -# - $globalData->{completeSets} : This is the number of sets which the student -# has earned 100% on -# - $globalData->{completeProblems} : This is the number of problems which the -# student has earned 100% on -# Warning: The achievements are always evaluated in the order they are listed -# on the Instructors achievement editor page. To make matters more -# complicated, achievements which have already been earned are not evaluated -# at all. The up-shot of this is that when modifying variables in -# $globalData you need to either write your code so it doesnt matter which -# order the evaluators are run in, or you need to pay very close attention -# to which evaluators are run and when. \ No newline at end of file diff --git a/courses.dist/modelCourse/templates/achievements/three_in_a_row.at b/courses.dist/modelCourse/templates/achievements/three_in_a_row.at deleted file mode 100644 index b97b53c83..000000000 --- a/courses.dist/modelCourse/templates/achievements/three_in_a_row.at +++ /dev/null @@ -1,82 +0,0 @@ -#This checks to see if the student has solved 10 problems without having any -# incorrect answers - -# reset counter if they got something wrong -if ($problem->status < 1) { - $counter = 0; - return 0; -# if they are right update the counter -} elsif ($problem->status == 1 && - $problem->num_correct == 1 && - $problem->num_incorrect == 0 ) { - $counter++; -} - -if ($counter >= $maxCounter) { - return 1; -} else { - return 0; -} - -# -You have access to a variety of variables: -# - $problem : the problem data (changes to this variable will not be saved!) -# This variable contains the problem data. It is a hash pointer with the -# following values (not all values shown) -# - $problem->status : the score of the current problem -# - $problem->problem_id : the id of the current problem -# - $problem->set_id : the id of the set containing the problem -# - $problem->num_correct : the number of correct attempts -# - $problem->num_incorrect : the number of incorrect attempts -# - $problem->last_answer : the last answer submitted -# - $problem->max_attempts : the maximum number of allowed attempts -# -# - $set : the set data (changes to this variable will not be saved!) -# This variable contains the set data. it is a hash pointer with the -# following values. (not all values shown) -# - $set->open_date : when the set was open -# - $set->due_date : when the set is due -# -# - @setProblems : the problem data for all the problems from this set. -# (changes to this variable will not be saved!) -# This is an array of problem hashes. Each element of the array has the -# save hash keys as the $problem variable above -# -# - $counter : the users counter associated to this achievement -# (changes to this variable *will* be saved!) -# If this achievement has a counter associated to it (i.e. solve 20 problems) -# then this is where you store the students counter for this achievement. -# This variable will initally start as '' -# -# - $maxCounter : the goal for the $counter variable for this achievement -# (changes to this variable will not be saved!) -# If this achievement has a counter associated to it then this variable -# contains the goal for the counter. Your achievement should return 1 -# when $counter >= $maxCounter. These two variables are used to show a -# progress bar for the achievement. -# -# - $localData : this is a hash which stores data for this user and achievement -# (changes to this variable *will* be saved!) -# This hash will persist from evaluation to evaluation. You can store whatever -# you like in here and it can be accessed next time this evaluator is run. -# Two things to keep in mind. The data in this hash will *not* be accessable -# by other achievements. If you plan to store something in this hash you have -# to write code to initialize the data. -# -# - $globalData : this is a hash which stores data for all achievements -# (changes to this variable *will* be saved!) -# This hash will persist from evaluation to evaluation and, like $localData, -# you can store whatever you like in here. This data will be accessable from -# *every* achievement and is unique to the user. Like $localData, you need to -# initialize any variable you plan on using in this hash. There are two -# variables stored in this hash that are maintained by the system. -# - $globalData->{completeSets} : This is the number of sets which the student -# has earned 100% on -# - $globalData->{completeProblems} : This is the number of problems which the -# student has earned 100% on -# Warning: The achievements are always evaluated in the order they are listed -# on the Instructors achievement editor page. To make matters more -# complicated, achievements which have already been earned are not evaluated -# at all. The up-shot of this is that when modifying variables in -# $globalData you need to either write your code so it doesnt matter which -# order the evaluators are run in, or you need to pay very close attention -# to which evaluators are run and when. diff --git a/courses.dist/modelCourse/templates/achievements/to_infinity.at b/courses.dist/modelCourse/templates/achievements/to_infinity.at deleted file mode 100644 index e637e74ca..000000000 --- a/courses.dist/modelCourse/templates/achievements/to_infinity.at +++ /dev/null @@ -1,84 +0,0 @@ -#This problem checks to see if a particular problem from a list of valid -# sets and problems has been solved. (You would edit this file to say which -# sets and problems count.) - -#constants -my %validproblems = ( - 'SetNameHere' => { #now you show which problems are valid like: - '2' => 1, - '1' => 1, }, #and put more sets here - ); - -#check and see if this problem was solved -if ($validproblems{$problem->set_id} && - $validproblems{$problem->set_id}{$problem->problem_id} && - $problem->status == 1 && - $problem->num_correct == 1) { - return 1; - } - - return 0; - - -# -You have access to a variety of variables: -# - $problem : the problem data (changes to this variable will not be saved!) -# This variable contains the problem data. It is a hash pointer with the -# following values (not all values shown) -# - $problem->status : the score of the current problem -# - $problem->problem_id : the id of the current problem -# - $problem->set_id : the id of the set containing the problem -# - $problem->num_correct : the number of correct attempts -# - $problem->num_incorrect : the number of incorrect attempts -# - $problem->last_answer : the last answer submitted -# - $problem->max_attempts : the maximum number of allowed attempts -# -# - $set : the set data (changes to this variable will not be saved!) -# This variable contains the set data. it is a hash pointer with the -# following values. (not all values shown) -# - $set->open_date : when the set was open -# - $set->due_date : when the set is due -# -# - @setProblems : the problem data for all the problems from this set. -# (changes to this variable will not be saved!) -# This is an array of problem hashes. Each element of the array has the -# save hash keys as the $problem variable above -# -# - $counter : the users counter associated to this achievement -# (changes to this variable *will* be saved!) -# If this achievement has a counter associated to it (i.e. solve 20 problems) -# then this is where you store the students counter for this achievement. -# This variable will initally start as '' -# -# - $maxCounter : the goal for the $counter variable for this achievement -# (changes to this variable will not be saved!) -# If this achievement has a counter associated to it then this variable -# contains the goal for the counter. Your achievement should return 1 -# when $counter >= $maxCounter. These two variables are used to show a -# progress bar for the achievement. -# -# - $localData : this is a hash which stores data for this user and achievement -# (changes to this variable *will* be saved!) -# This hash will persist from evaluation to evaluation. You can store whatever -# you like in here and it can be accessed next time this evaluator is run. -# Two things to keep in mind. The data in this hash will *not* be accessable -# by other achievements. If you plan to store something in this hash you have -# to write code to initialize the data. -# -# - $globalData : this is a hash which stores data for all achievements -# (changes to this variable *will* be saved!) -# This hash will persist from evaluation to evaluation and, like $localData, -# you can store whatever you like in here. This data will be accessable from -# *every* achievement and is unique to the user. Like $localData, you need to -# initialize any variable you plan on using in this hash. There are two -# variables stored in this hash that are maintained by the system. -# - $globalData->{completeSets} : This is the number of sets which the student -# has earned 100% on -# - $globalData->{completeProblems} : This is the number of problems which the -# student has earned 100% on -# Warning: The achievements are always evaluated in the order they are listed -# on the Instructors achievement editor page. To make matters more -# complicated, achievements which have already been earned are not evaluated -# at all. The up-shot of this is that when modifying variables in -# $globalData you need to either write your code so it doesnt matter which -# order the evaluators are run in, or you need to pay very close attention -# to which evaluators are run and when. diff --git a/courses.dist/modelCourse/templates/achievements/trig_ninja.at b/courses.dist/modelCourse/templates/achievements/trig_ninja.at deleted file mode 100644 index e637e74ca..000000000 --- a/courses.dist/modelCourse/templates/achievements/trig_ninja.at +++ /dev/null @@ -1,84 +0,0 @@ -#This problem checks to see if a particular problem from a list of valid -# sets and problems has been solved. (You would edit this file to say which -# sets and problems count.) - -#constants -my %validproblems = ( - 'SetNameHere' => { #now you show which problems are valid like: - '2' => 1, - '1' => 1, }, #and put more sets here - ); - -#check and see if this problem was solved -if ($validproblems{$problem->set_id} && - $validproblems{$problem->set_id}{$problem->problem_id} && - $problem->status == 1 && - $problem->num_correct == 1) { - return 1; - } - - return 0; - - -# -You have access to a variety of variables: -# - $problem : the problem data (changes to this variable will not be saved!) -# This variable contains the problem data. It is a hash pointer with the -# following values (not all values shown) -# - $problem->status : the score of the current problem -# - $problem->problem_id : the id of the current problem -# - $problem->set_id : the id of the set containing the problem -# - $problem->num_correct : the number of correct attempts -# - $problem->num_incorrect : the number of incorrect attempts -# - $problem->last_answer : the last answer submitted -# - $problem->max_attempts : the maximum number of allowed attempts -# -# - $set : the set data (changes to this variable will not be saved!) -# This variable contains the set data. it is a hash pointer with the -# following values. (not all values shown) -# - $set->open_date : when the set was open -# - $set->due_date : when the set is due -# -# - @setProblems : the problem data for all the problems from this set. -# (changes to this variable will not be saved!) -# This is an array of problem hashes. Each element of the array has the -# save hash keys as the $problem variable above -# -# - $counter : the users counter associated to this achievement -# (changes to this variable *will* be saved!) -# If this achievement has a counter associated to it (i.e. solve 20 problems) -# then this is where you store the students counter for this achievement. -# This variable will initally start as '' -# -# - $maxCounter : the goal for the $counter variable for this achievement -# (changes to this variable will not be saved!) -# If this achievement has a counter associated to it then this variable -# contains the goal for the counter. Your achievement should return 1 -# when $counter >= $maxCounter. These two variables are used to show a -# progress bar for the achievement. -# -# - $localData : this is a hash which stores data for this user and achievement -# (changes to this variable *will* be saved!) -# This hash will persist from evaluation to evaluation. You can store whatever -# you like in here and it can be accessed next time this evaluator is run. -# Two things to keep in mind. The data in this hash will *not* be accessable -# by other achievements. If you plan to store something in this hash you have -# to write code to initialize the data. -# -# - $globalData : this is a hash which stores data for all achievements -# (changes to this variable *will* be saved!) -# This hash will persist from evaluation to evaluation and, like $localData, -# you can store whatever you like in here. This data will be accessable from -# *every* achievement and is unique to the user. Like $localData, you need to -# initialize any variable you plan on using in this hash. There are two -# variables stored in this hash that are maintained by the system. -# - $globalData->{completeSets} : This is the number of sets which the student -# has earned 100% on -# - $globalData->{completeProblems} : This is the number of problems which the -# student has earned 100% on -# Warning: The achievements are always evaluated in the order they are listed -# on the Instructors achievement editor page. To make matters more -# complicated, achievements which have already been earned are not evaluated -# at all. The up-shot of this is that when modifying variables in -# $globalData you need to either write your code so it doesnt matter which -# order the evaluators are run in, or you need to pay very close attention -# to which evaluators are run and when. diff --git a/htdocs/codemirror2/LICENSE b/htdocs/codemirror2/LICENSE new file mode 100644 index 000000000..3f7c0bb18 --- /dev/null +++ b/htdocs/codemirror2/LICENSE @@ -0,0 +1,19 @@ +Copyright (C) 2011 by Marijn Haverbeke + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/htdocs/codemirror2/README.md b/htdocs/codemirror2/README.md new file mode 100644 index 000000000..624b5409b --- /dev/null +++ b/htdocs/codemirror2/README.md @@ -0,0 +1,6 @@ +# CodeMirror 2 + +CodeMirror 2 is a rewrite of [CodeMirror +1](http://github.com/marijnh/CodeMirror). The docs live +[here](http://codemirror.net/2/manual.html), and the project page is +[http://codemirror.net/2/](http://codemirror.net/2/). diff --git a/htdocs/codemirror2/codeshard.html b/htdocs/codemirror2/codeshard.html new file mode 100644 index 000000000..b37bbb19a --- /dev/null +++ b/htdocs/codemirror2/codeshard.html @@ -0,0 +1,18 @@ + + + +CodeShard + + + +

CodeShard

+ +

A minimal version of CodeMirror, designed to edit single lines of code at a time.

+ + + + + + diff --git a/htdocs/codemirror2/compress.html b/htdocs/codemirror2/compress.html new file mode 100644 index 000000000..234775676 --- /dev/null +++ b/htdocs/codemirror2/compress.html @@ -0,0 +1,81 @@ + + + + CodeMirror: Compression Helper + + + + + +

{ } CodeMirror

+ +
+/* Script compression
+   helper */
+
+ +

To optimize loading CodeMirror, especially when including a + bunch of different modes, it is recommended that you combine and + minify (and preferably also gzip) the scripts. This page makes + those first two steps very easy. Simply select the version and + scripts you need in the form below, and + click Compress to download the minified script + file.

+ +
+ +

Version:

+ +

+ +

+ with UglifyJS +

+ +

Custom code to add to the compressed file:

+
+ + + + + + + diff --git a/htdocs/codemirror2/css/baboon.png b/htdocs/codemirror2/css/baboon.png new file mode 100644 index 000000000..55d97f70b Binary files /dev/null and b/htdocs/codemirror2/css/baboon.png differ diff --git a/htdocs/codemirror2/css/baboon_vector.svg b/htdocs/codemirror2/css/baboon_vector.svg new file mode 100644 index 000000000..dc1667af9 --- /dev/null +++ b/htdocs/codemirror2/css/baboon_vector.svg @@ -0,0 +1,153 @@ + + + +image/svg+xml \ No newline at end of file diff --git a/htdocs/codemirror2/css/docs.css b/htdocs/codemirror2/css/docs.css new file mode 100644 index 000000000..c1b99dfa3 --- /dev/null +++ b/htdocs/codemirror2/css/docs.css @@ -0,0 +1,157 @@ +body { + font-family: Arial, sans-serif; + line-height: 1.5; + max-width: 64.3em; + margin: 3em auto; + padding: 0 1em; +} +body.droid { + font-family: Droid Sans, Arial, sans-serif; +} + +h1 { + letter-spacing: -3px; + font-size: 3.23em; + font-weight: bold; + margin: 0; +} + +h2 { + font-size: 1.23em; + font-weight: bold; + margin: .5em 0; + letter-spacing: -1px; +} + +h3 { + font-size: 1em; + font-weight: bold; + margin: .4em 0; +} + +pre { + background-color: #eee; + -moz-border-radius: 6px; + -webkit-border-radius: 6px; + border-radius: 6px; + padding: 1em; +} + +pre.code { + margin: 0 1em; +} + +.grey { + font-size: 2.2em; + padding: .5em 1em; + line-height: 1.2em; + margin-top: .5em; + position: relative; +} + +img.logo { + position: absolute; + right: -25px; + bottom: 4px; +} + +a:link, a:visited, .quasilink { + color: #df0019; + cursor: pointer; + text-decoration: none; +} + +a:hover, .quasilink:hover { + color: #800004; +} + +h1 a:link, h1 a:visited, h1 a:hover { + color: black; +} + +ul { + margin: 0; + padding-left: 1.2em; +} + +a.download { + color: white; + background-color: #df0019; + width: 100%; + display: block; + text-align: center; + font-size: 1.23em; + font-weight: bold; + text-decoration: none; + -moz-border-radius: 6px; + -webkit-border-radius: 6px; + border-radius: 6px; + padding: .5em 0; + margin-bottom: 1em; +} + +a.download:hover { + background-color: #bb0010; +} + +.rel { + margin-bottom: 0; +} + +.rel-note { + color: #777; + font-size: .9em; + margin-top: .1em; +} + +.logo-braces { + color: #df0019; + position: relative; + top: -4px; +} + +.blk { + float: left; +} + +.left { + width: 37em; + padding-right: 6.53em; + padding-bottom: 1em; +} + +.left1 { + width: 15.24em; + padding-right: 6.45em; +} + +.left2 { + width: 15.24em; +} + +.right { + width: 20.68em; +} + +.leftbig { + width: 42.44em; + padding-right: 6.53em; +} + +.rightsmall { + width: 15.24em; +} + +.clear:after { + visibility: hidden; + display: block; + font-size: 0; + content: " "; + clear: both; + height: 0; +} +.clear { display: inline-block; } +/* start commented backslash hack \*/ +* html .clear { height: 1%; } +.clear { display: block; } +/* close commented backslash hack */ diff --git a/htdocs/codemirror2/css/font.js b/htdocs/codemirror2/css/font.js new file mode 100644 index 000000000..58b559aa6 --- /dev/null +++ b/htdocs/codemirror2/css/font.js @@ -0,0 +1,18 @@ +function waitForStyles() { + for (var i = 0; i < document.styleSheets.length; i++) + if (/googleapis/.test(document.styleSheets[i].href)) + return document.body.className += " droid"; + setTimeout(waitForStyles, 100); +} + +document.body.style.display = "none"; +setTimeout(function() { + document.body.style.display = ""; + if (/AppleWebKit/.test(navigator.userAgent) && /iP[oa]d|iPhone/.test(navigator.userAgent)) return; + var link = document.createElement("LINK"); + link.type = "text/css"; + link.rel = "stylesheet"; + link.href = "http://fonts.googleapis.com/css?family=Droid+Sans|Droid+Sans:bold"; + document.documentElement.getElementsByTagName("HEAD")[0].appendChild(link); + waitForStyles(); +}, 30); diff --git a/htdocs/codemirror2/demo/activeline.html b/htdocs/codemirror2/demo/activeline.html new file mode 100644 index 000000000..7a169663e --- /dev/null +++ b/htdocs/codemirror2/demo/activeline.html @@ -0,0 +1,71 @@ + + + + CodeMirror 2: Active Line Demo + + + + + + + + + +

CodeMirror 2: Active Line Demo

+ +
+ + + +

Styling the current cursor line.

+ + + diff --git a/htdocs/codemirror2/demo/codeshard.html b/htdocs/codemirror2/demo/codeshard.html new file mode 100644 index 000000000..2617beb7f --- /dev/null +++ b/htdocs/codemirror2/demo/codeshard.html @@ -0,0 +1,30 @@ + + + + CodeMirror2/CodeShard Demo + + + + + + + + + +

CodeMirror2 / CodeShard Demo

+
This is a test. Input one: . And some more text. +
+ +
+
+
+
+ + + diff --git a/htdocs/codemirror2/demo/codeshard.js b/htdocs/codemirror2/demo/codeshard.js new file mode 100644 index 000000000..b68b8de01 --- /dev/null +++ b/htdocs/codemirror2/demo/codeshard.js @@ -0,0 +1,3 @@ +(function () { + var editor = CodeShard.fromInputField(document.getElementById("code"),{matchBrackets: true}); +})(); diff --git a/htdocs/codemirror2/demo/codeshard2.html b/htdocs/codemirror2/demo/codeshard2.html new file mode 100644 index 000000000..f4e082fce --- /dev/null +++ b/htdocs/codemirror2/demo/codeshard2.html @@ -0,0 +1,48 @@ + + + + CodeMirror2/CodeShard Demo + + + + + + + + + +

CodeMirror2 / CodeShard Demo

+
+ This is a test. Input one: . And some more text. + Input two: Text at end. + +
+
+
+ + + diff --git a/htdocs/codemirror2/demo/codeshard2.js b/htdocs/codemirror2/demo/codeshard2.js new file mode 100644 index 000000000..d377944c9 --- /dev/null +++ b/htdocs/codemirror2/demo/codeshard2.js @@ -0,0 +1,11 @@ +(function () { + var textareas = document.getElementsByClassName("codeshard"); + var editors = []; + for (i=0; i + + + CodeMirror 2: Autocomplete Demo + + + + + + + + + +

CodeMirror 2: Autocomplete demo

+ +
+ +

Press ctrl-space to activate autocompletion. See +the code to figure out how it works.

+ + + + diff --git a/htdocs/codemirror2/demo/complete.js b/htdocs/codemirror2/demo/complete.js new file mode 100644 index 000000000..29b7c26c7 --- /dev/null +++ b/htdocs/codemirror2/demo/complete.js @@ -0,0 +1,150 @@ +(function () { + // Minimal event-handling wrapper. + function stopEvent() { + if (this.preventDefault) {this.preventDefault(); this.stopPropagation();} + else {this.returnValue = false; this.cancelBubble = true;} + } + function addStop(event) { + if (!event.stop) event.stop = stopEvent; + return event; + } + function connect(node, type, handler) { + function wrapHandler(event) {handler(addStop(event || window.event));} + if (typeof node.addEventListener == "function") + node.addEventListener(type, wrapHandler, false); + else + node.attachEvent("on" + type, wrapHandler); + } + + function forEach(arr, f) { + for (var i = 0, e = arr.length; i < e; ++i) f(arr[i]); + } + + var editor = CodeMirror.fromTextArea(document.getElementById("code"), { + lineNumbers: true, + onKeyEvent: function(i, e) { + // Hook into ctrl-space + if (e.keyCode == 32 && (e.ctrlKey || e.metaKey) && !e.altKey) { + e.stop(); + return startComplete(); + } + } + }); + + function startComplete() { + // We want a single cursor position. + if (editor.somethingSelected()) return; + // Find the token at the cursor + var cur = editor.getCursor(false), token = editor.getTokenAt(cur), tprop = token; + // If it's not a 'word-style' token, ignore the token. + if (!/^[\w$_]*$/.test(token.string)) { + token = tprop = {start: cur.ch, end: cur.ch, string: "", state: token.state, + className: token.string == "." ? "js-property" : null}; + } + // If it is a property, find out what it is a property of. + while (tprop.className == "js-property") { + tprop = editor.getTokenAt({line: cur.line, ch: tprop.start}); + if (tprop.string != ".") return; + tprop = editor.getTokenAt({line: cur.line, ch: tprop.start}); + if (!context) var context = []; + context.push(tprop); + } + var completions = getCompletions(token, context); + if (!completions.length) return; + function insert(str) { + editor.replaceRange(str, {line: cur.line, ch: token.start}, {line: cur.line, ch: token.end}); + } + // When there is only one completion, use it directly. + if (completions.length == 1) {insert(completions[0]); return true;} + + // Build the select widget + var complete = document.createElement("div"); + complete.className = "completions"; + var sel = complete.appendChild(document.createElement("select")); + sel.multiple = true; + for (var i = 0; i < completions.length; ++i) { + var opt = sel.appendChild(document.createElement("option")); + opt.appendChild(document.createTextNode(completions[i])); + } + sel.firstChild.selected = true; + sel.size = Math.min(10, completions.length); + var pos = editor.cursorCoords(); + complete.style.left = pos.x + "px"; + complete.style.top = pos.yBot + "px"; + document.body.appendChild(complete); + // Hack to hide the scrollbar. + if (completions.length <= 10) + complete.style.width = (sel.clientWidth - 1) + "px"; + + var done = false; + function close() { + if (done) return; + done = true; + complete.parentNode.removeChild(complete); + } + function pick() { + insert(sel.options[sel.selectedIndex].value); + close(); + setTimeout(function(){editor.focus();}, 50); + } + connect(sel, "blur", close); + connect(sel, "keydown", function(event) { + var code = event.keyCode; + // Enter and space + if (code == 13 || code == 32) {event.stop(); pick();} + // Escape + else if (code == 27) {event.stop(); close(); editor.focus();} + else if (code != 38 && code != 40) {close(); editor.focus(); setTimeout(startComplete, 50);} + }); + connect(sel, "dblclick", pick); + + sel.focus(); + // Opera sometimes ignores focusing a freshly created node + if (window.opera) setTimeout(function(){if (!done) sel.focus();}, 100); + return true; + } + + var stringProps = ("charAt charCodeAt indexOf lastIndexOf substring substr slice trim trimLeft trimRight " + + "toUpperCase toLowerCase split concat match replace search").split(" "); + var arrayProps = ("length concat join splice push pop shift unshift slice reverse sort indexOf " + + "lastIndexOf every some filter forEach map reduce reduceRight ").split(" "); + var funcProps = "prototype apply call bind".split(" "); + var keywords = ("break case catch continue debugger default delete do else false finally for function " + + "if in instanceof new null return switch throw true try typeof var void while with").split(" "); + + function getCompletions(token, context) { + var found = [], start = token.string; + function maybeAdd(str) { + if (str.indexOf(start) == 0) found.push(str); + } + function gatherCompletions(obj) { + if (typeof obj == "string") forEach(stringProps, maybeAdd); + else if (obj instanceof Array) forEach(arrayProps, maybeAdd); + else if (obj instanceof Function) forEach(funcProps, maybeAdd); + for (var name in obj) maybeAdd(name); + } + + if (context) { + // If this is a property, see if it belongs to some object we can + // find in the current environment. + var obj = context.pop(), base; + if (obj.className == "js-variable") + base = window[obj.string]; + else if (obj.className == "js-string") + base = ""; + else if (obj.className == "js-atom") + base = 1; + while (base != null && context.length) + base = base[context.pop().string]; + if (base != null) gatherCompletions(base); + } + else { + // If not, just look in the window object and any local scope + // (reading into JS mode internals to get at the local variables) + for (var v = token.state.localVars; v; v = v.next) maybeAdd(v.name); + gatherCompletions(window); + forEach(keywords, maybeAdd); + } + return found; + } +})(); diff --git a/htdocs/codemirror2/demo/marker.html b/htdocs/codemirror2/demo/marker.html new file mode 100644 index 000000000..7b3a2ba9d --- /dev/null +++ b/htdocs/codemirror2/demo/marker.html @@ -0,0 +1,53 @@ + + + + CodeMirror 2: Breakpoint Demo + + + + + + + + + +

CodeMirror 2: Breakpoint demo

+ +
+ +

Click the line-number gutter to add or remove 'breakpoints'.

+ + + + + diff --git a/htdocs/codemirror2/demo/mustache.html b/htdocs/codemirror2/demo/mustache.html new file mode 100644 index 000000000..6541f1059 --- /dev/null +++ b/htdocs/codemirror2/demo/mustache.html @@ -0,0 +1,57 @@ + + + + CodeMirror 2: Overlay Parser Demo + + + + + + + + + + +

CodeMirror 2: Overlay Parser Demo

+ +
+ + + +

Demonstration of a mode that parses HTML, highlighting + the Mustache templating + directives inside of it by using the code + in overlay.js. View + source to see the 15 lines of code needed to accomplish this.

+ + + diff --git a/htdocs/codemirror2/demo/resize.html b/htdocs/codemirror2/demo/resize.html new file mode 100644 index 000000000..0022044d2 --- /dev/null +++ b/htdocs/codemirror2/demo/resize.html @@ -0,0 +1,38 @@ + + + + CodeMirror 2: Autoresize Demo + + + + + + + + + +

CodeMirror 2: Autoresize demo

+ +
+ +

By setting a single CSS property, CodeMirror can be made to +automatically resize to fit the content. Use max-height +to prevent it from growing past a given point (on halfway modern +browsers).

+ + + + + diff --git a/htdocs/codemirror2/demo/search.html b/htdocs/codemirror2/demo/search.html new file mode 100644 index 000000000..5fe8c9d0b --- /dev/null +++ b/htdocs/codemirror2/demo/search.html @@ -0,0 +1,106 @@ + + + + CodeMirror 2: Search/Replace Demo + + + + + + + + + +

CodeMirror 2: Search/Replace Demo

+ +
+ + or + it by + + + + +

Demonstration of search/replace functionality and marking + text.

+ + + diff --git a/htdocs/codemirror2/index.html b/htdocs/codemirror2/index.html new file mode 100644 index 000000000..f006411b2 --- /dev/null +++ b/htdocs/codemirror2/index.html @@ -0,0 +1,229 @@ + + + + CodeMirror + + + + + + +

{ } CodeMirror

+ +
+/* In-browser code editing
+   made bearable */
+
+ +
+ +

CodeMirror is a JavaScript library that can + be used to create a relatively pleasant editor interface for + code-like content ― computer programs, HTML markup, and + similar. If a mode has been written for the language you are + editing, the code will be coloured, and the editor will optionally + help you with indentation.

+ +

This is the project page for CodeMirror 2, the currently more + actively developed, and recommended + version. CodeMirror 1 is still available + from here.

+ + + +

Getting the code

+ +

All of CodeMirror is released under a MIT-style license. To get it, you can download + the latest + release or the current development + snapshot as zip files. To create a custom minified script file, + you can use the compression API.

+ +

We use git for version control. + The main repository can be fetched in this way:

+ +
git clone http://marijnhaverbeke.nl/git/codemirror2
+ +

CodeMirror can also be found on GitHub at marijnh/CodeMirror2. + If you plan to hack on the code and contribute patches, the best way + to do it is to create a GitHub fork, and send pull requests.

+ +

Documentation

+ +

The manual is your first stop for + learning how to use this library. It starts with a quick explanation + of how to use the editor, and then describes all of the (many) + options and methods that CodeMirror exposes.

+ +

For those who want to learn more about the code, there is + an overview of the internals available. + The source code + itself is, for the most part, also well commented.

+ +

Support and bug reports

+ +

There is + a Google + group (a sort of mailing list/newsgroup thing) for discussion + and news related to CodeMirror. Reporting bugs is best done + on github. + You can also e-mail me + directly: Marijn + Haverbeke.

+ +

Supported browsers

+ +

The following browsers are able to run CodeMirror:

+ +
    +
  • Firefox 2 or higher
  • +
  • Chrome, any version
  • +
  • Safari 3 or higher
  • +
  • Internet Explorer 6 or higher
  • +
  • Opera 9 or higher (with some key-handling problems on OS X)
  • +
+ +

I am not actively testing against every new browser release, and + vendors have a habit of introducing bugs all the time, so I am + relying on the community to tell me when something breaks. + See here for information on how to contact + me.

+ +
+ +
+ + Download the latest release + +

Make a donation

+ +
    +
  • Paypal
  • +
  • Bank
  • +
+ + + +

Releases:

+ +

28-03-2011: Version 2.0:

+

CodeMirror 2 is a complete rewrite that's + faster, smaller, simpler to use, and less dependent on browser + quirks. See this + and this + for more information. + +

28-03-2011: Version 1.0:

+
    +
  • Fix error when debug history overflows.
  • +
  • Refine handling of C# verbatim strings.
  • +
  • Fix some issues with JavaScript indentation.
  • +
+ +

22-02-2011: Version 2.0 beta 2:

+

Somewhate more mature API, lots of bugs shaken out. + +

17-02-2011: Version 0.94:

+
    +
  • tabMode: "spaces" was modified slightly (now indents when something is selected).
  • +
  • Fixes a bug that would cause the selection code to break on some IE versions.
  • +
  • Disabling spell-check on WebKit browsers now works.
  • +
+ +

08-02-2011: Version 2.0 beta 1:

+

CodeMirror 2 is a complete rewrite of + CodeMirror, no longer depending on an editable frame.

+ +

19-01-2011: Version 0.93:

+
    +
  • Added a Regular Expression parser.
  • +
  • Fixes to the PHP parser.
  • +
  • Support for regular expression in search/replace.
  • +
  • Add save method to instances created with fromTextArea.
  • +
  • Add support for MS T-SQL in the SQL parser.
  • +
  • Support use of CSS classes for highlighting brackets.
  • +
  • Fix yet another hang with line-numbering in hidden editors.
  • +
+ +

17-12-2010: Version 0.92:

+
    +
  • Make CodeMirror work in XHTML documents.
  • +
  • Fix bug in handling of backslashes in Python strings.
  • +
  • The styleNumbers option is now officially + supported and documented.
  • +
  • onLineNumberClick option added.
  • +
  • More consistent names onLoad and + onCursorActivity callbacks. Old names still work, but + are deprecated.
  • +
  • Add a Freemarker mode.
  • +
+ +

11-11-2010: Version 0.91:

+
    +
  • Adds support for Java.
  • +
  • Small additions to the PHP and SQL parsers.
  • +
  • Work around various Webkit issues.
  • +
  • Fix toTextArea to update the code in the textarea.
  • +
  • Add a noScriptCaching option (hack to ease development).
  • +
  • Make sub-modes of HTML mixed mode configurable.
  • +
+ +

Older releases...

+ +
+ +
 
+ +
+ + +
+ + + + + + diff --git a/htdocs/codemirror2/internals.html b/htdocs/codemirror2/internals.html new file mode 100644 index 000000000..6a9dba4c9 --- /dev/null +++ b/htdocs/codemirror2/internals.html @@ -0,0 +1,382 @@ + + + + CodeMirror: Internals + + + + + + +

{ } CodeMirror

+ +
+/* (Re-) Implementing A Syntax-
+   Highlighting Editor in JavaScript */
+
+ +
+ +

+ Topic: JavaScript, code editor implementation
+ Author: Marijn Haverbeke
+ Date: March 2nd 2011 +

+ +

This is a followup to +my Brutal Odyssey to the +Dark Side of the DOM Tree story. That one describes the +mind-bending process of implementing (what would become) CodeMirror 1. +This one describes the internals of CodeMirror 2, a complete rewrite +and rethink of the old code base. I wanted to give this piece another +Hunter Thompson copycat subtitle, but somehow that would be out of +place—the process this time around was one of straightforward +engineering, requiring no serious mind-bending whatsoever.

+ +

So, what is wrong with CodeMirror 1? I'd estimate, by mailing list +activity and general search-engine presence, that it has been +integrated into about a thousand systems by now. The most prominent +one, since a few weeks, +being Google +code's project hosting. It works, and it's being used widely. + +

Still, I did not start replacing it because I was bored. CodeMirror +1 was heavily reliant on designMode +or contentEditable (depending on the browser). Neither of +these are well specified (HTML5 tries +to specify +their basics), and, more importantly, they tend to be one of the more +obscure and buggy areas of browser functionality—CodeMirror, by using +this functionality in a non-typical way, was constantly running up +against browser bugs. WebKit wouldn't show an empty line at the end of +the document, and in some releases would suddenly get unbearably slow. +Firefox would show the cursor in the wrong place. Internet Explorer +would insist on linkifying everything that looked like a URL or email +address, a behaviour that can't be turned off. Some bugs I managed to +work around (which was often a frustrating, painful process), others, +such as the Firefox cursor placement, I gave up on, and had to tell +user after user that they were known problems, but not something I +could help.

+ +

Also, there is the fact that designMode (which seemed +to be less buggy than contentEditable in Webkit and +Firefox, and was thus used by CodeMirror 1 in those browsers) requires +a frame. Frames are another tricky area. It takes some effort to +prevent getting tripped up by domain restrictions, they don't +initialize synchronously, behave strangely in response to the back +button, and, on several browsers, can't be moved around the DOM +without having them re-initialize. They did provide a very nice way to +namespace the library, though—CodeMirror 1 could freely pollute the +namespace inside the frame.

+ +

Finally, working with an editable document means working with +selection in arbitrary DOM structures. Internet Explorer (8 and +before) has an utterly different (and awkward) selection API than all +of the other browsers, and even among the different implementations of +document.selection, details about how exactly a selection +is represented vary quite a bit. Add to that the fact that Opera's +selection support tended to be very buggy until recently, and you can +imagine why CodeMirror 1 contains 700 lines of selection-handling +code.

+ +

And that brings us to the main issue with the CodeMirror 1 +code base: The proportion of browser-bug-workarounds to real +application code was getting dangerously high. By building on top of a +few dodgy features, I put the system in a vulnerable position—any +incompatibility and bugginess in these features, I had to paper over +with my own code. Not only did I have to do some serious stunt-work to +get it to work on older browsers (as detailed in the +previous story), things +also kept breaking in newly released versions, requiring me to come up +with new scary hacks in order to keep up. This was starting +to lose its appeal.

+ +

General Approach

+ +

What CodeMirror 2 does is try to sidestep most of the hairy hacks +that came up in version 1. I owe a lot to the +ACE editor for inspiration on how to +approach this.

+ +

I absolutely did not want to be completely reliant on key events to +generate my input. Every JavaScript programmer knows that key event +information is horrible and incomplete. Some people (most awesomely +Mihai Bazon with Ymacs) have been able +to build more or less functioning editors by directly reading key +events, but it takes a lot of work (the kind of never-ending, fragile +work I described earlier), and will never be able to properly support +things like multi-keystoke international character input.

+ +

So what I do is focus a hidden textarea, and let the browser +believe that the user is typing into that. What we show to the user is +a DOM structure we built to represent his document. If this is updated +quickly enough, and shows some kind of believable cursor, it feels +like a real text-input control.

+ +

Another big win is that this DOM representation does not have to +span the whole document. Some CodeMirror 1 users insisted that they +needed to put a 30 thousand line XML document into CodeMirror. Putting +all that into the DOM takes a while, especially since, for some +reason, an editable DOM tree is slower than a normal one on most +browsers. If we have full control over what we show, we must only +ensure that the visible part of the document has been added, and can +do the rest only when needed. (Fortunately, the onscroll +event works almost the same on all browsers, and lends itself well to +displaying things only as they are scrolled into view.)

+ +

Input

+ +

ACE uses its hidden textarea only as a text input shim, and does +all cursor movement and things like text deletion itself by directly +handling key events. CodeMirror's way is to let the browser do its +thing as much as possible, and not, for example, define its own set of +key bindings. One way to do this would have been to have the whole +document inside the hidden textarea, and after each key event update +the display DOM to reflect what's in that textarea.

+ +

That'd be simple, but it is not realistic. For even medium-sized +document the editor would be constantly munging huge strings, and get +terribly slow. What CodeMirror 2 does is put the current selection, +along with an extra line on the top and on the bottom, into the +textarea.

+ +

This means that the arrow keys (and their ctrl-variations), home, +end, etcetera, do not have to be handled specially. We just read the +cursor position in the textarea, and update our cursor to match it. +Also, copy and paste work pretty much for free, and people get their +native key bindings, without any special work on my part. For example, +I have emacs key bindings configured for Chrome and Firefox. There is +no way for a script to detect this.

+ +

Of course, since only a small part of the document sits in the +textarea, keys like page up and ctrl-end won't do the right thing. +CodeMirror is catching those events and handling them itself.

+ +

Selection

+ +

Getting and setting the selection range of a textarea in modern +browsers is trivial—you just use the selectionStart +and selectionEnd properties. On IE you have to do some +insane stuff with temporary ranges and compensating for the fact that +moving the selection by a 'character' will treat \r\n as a single +character, but even there it is possible to build functions that +reliably set and get the selection range.

+ +

But consider this typical case: When I'm somewhere in my document, +press shift, and press the up arrow, something gets selected. Then, if +I, still holding shift, press the up arrow again, the top of my +selection is adjusted. The selection remembers where its head +and its anchor are, and moves the head when we shift-move. +This is a generally accepted property of selections, and done right by +every editing component built in the past twenty years.

+ +

But not something that the browser selection APIs expose.

+ +

Great. So when someone creates an 'upside-down' selection, the next +time CodeMirror has to update the textarea, it'll re-create the +selection as an 'upside-up' selection, with the anchor at the top, and +the next cursor motion will behave in an unexpected way—our second +up-arrow press in the example above will not do anything, since it is +interpreted in exactly the same way as the first.

+ +

No problem. We'll just, ehm, detect that the selection is +upside-down (you can tell by the way it was created), and then, when +an upside-down selection is present, and a cursor-moving key is +pressed in combination with shift, we quickly collapse the selection +in the textarea to its start, allow the key to take effect, and then +combine its new head with its old anchor to get the real +selection.

+ +

In short, scary hacks could not be avoided entirely in CodeMirror +2.

+ +

And, the observant reader might ask, how do you even know that a +key combo is a cursor-moving combo, if you claim you support any +native key bindings? Well, we don't, but we can learn. The editor +keeps a set known cursor-movement combos (initialized to the +predictable defaults), and updates this set when it observes that +pressing a certain key had (only) the effect of moving the cursor. +This, of course, doesn't work if the first time the key is used was +for extending an inverted selection, but it works most of the +time.

+ +

Intelligent Updating

+ +

One thing that always comes up when you have a complicated internal +state that's reflected in some user-visible external representation +(in this case, the displayed code and the textarea's content) is +keeping the two in sync. The naive way is to just update the display +every time you change your state, but this is not only error prone +(you'll forget), it also easily leads to duplicate work on big, +composite operations. Then you start passing around flags indicating +whether the display should be updated in an attempt to be efficient +again and, well, at that point you might as well give up completely.

+ +

I did go down that road, but then switched to a much simpler model: +simply keep track of all the things that have been changed during an +action, and then, only at the end, use this information to update the +user-visible display.

+ +

CodeMirror uses a concept of operations, which start by +calling a specific set-up function that clears the state and end by +calling another function that reads this state and does the required +updating. Most event handlers, and all the user-visible methods that +change state are wrapped like this. There's a method +called operation that accepts a function, and returns +another function that wraps the given function as an operation.

+ +

It's trivial to extend this (as CodeMirror does) to detect nesting, +and, when an operation is started inside an operation, simply +increment the nesting count, and only do the updating when this count +reaches zero again.

+ +

If we have a set of changed ranges and know the currently shown +range, we can (with some awkward code to deal with the fact that +changes can add and remove lines, so we're dealing with a changing +coordinate system) construct a map of the ranges that were left +intact. We can then compare this map with the part of the document +that's currently visible (based on scroll offset and editor height) to +determine whether something needs to be updated.

+ +

CodeMirror uses two update algorithms—a full refresh, where it just +discards the whole part of the DOM that contains the edited text and +rebuilds it, and a patch algorithm, where it uses the information +about changed and intact ranges to update only the out-of-date parts +of the DOM. When more than 30 percent (which is the current heuristic, +might change) of the lines need to be updated, the full refresh is +chosen (since it's faster to do than painstakingly finding and +updating all the changed lines), in the other case it does the +patching (so that, if you scroll a line or select another character, +the whole screen doesn't have to be re-rendered).

+ +

All updating uses innerHTML rather than direct DOM +manipulation, since that still seems to be by far the fastest way to +build documents. There's a per-line function that combines the +highlighting, marking, and +selection info for that line into a snippet of HTML. The patch updater +uses this to reset individual lines, the refresh updater builds an +HTML chunk for the whole visible document at once, and then uses a +single innerHTML update to do the refresh.

+ +

Parsers can be Simple

+ +

When I wrote CodeMirror 1, I +thought interruptable +parsers were a hugely scary and complicated thing, and I used a +bunch of heavyweight abstractions to keep this supposed complexity +under control: parsers +were iterators +that consumed input from another iterator, and used funny +closure-resetting tricks to copy and resume themselves.

+ +

This made for a rather nice system, in that parsers formed strictly +separate modules, and could be composed in predictable ways. +Unfortunately, it was quite slow (stacking three or four iterators on +top of each other), and extremely intimidating to people not used to a +functional programming style.

+ +

With a few small changes, however, we can keep all those +advantages, but simplify the API and make the whole thing less +indirect and inefficient. CodeMirror +2's mode API uses explicit state +objects, and makes the parser/tokenizer a function that simply takes a +state and a character stream abstraction, advances the stream one +token, and returns the way the token should be styled. This state may +be copied, optionally in a mode-defined way, in order to be able to +continue a parse at a given point. Even someone who's never touched a +lambda in his life can understand this approach. Additionally, far +fewer objects are allocated in the course of parsing now.

+ +

The biggest speedup comes from the fact that the parsing no longer +has to touch the DOM though. In CodeMirror 1, on an older browser, you +could see the parser work its way through the document, +managing some twenty lines in each 50-millisecond time slice it got. It +was reading its input from the DOM, and updating the DOM as it went +along, which any experienced JavaScript programmer will immediately +spot as a recipe for slowness. In CodeMirror 2, the parser usually +finishes the whole document in a single 100-millisecond time slice—it +manages some 1500 lines during that time on Chrome. All it has to do +is munge strings, so there is no real reason for it to be slow +anymore.

+ +

What Gives?

+ +

Given all this, what can you expect from CodeMirror 2? First, the +good:

+ +
    + +
  • Small. the base library is some 32k when minified +now, 12k when gzipped. It's smaller than its own logo.
  • + +
  • Lightweight. CodeMirror 2 initializes very +quickly, and does almost no work when it is not focused. This means +you can treat it almost like a textarea, have multiple instances on a +page without trouble.
  • + +
  • Huge document support. Since highlighting is +really fast, and no DOM structure is being built for non-visible +content, you don't have to worry about locking up your browser when a +user enters a megabyte-sized document.
  • + +
  • Extended API. Some things kept coming up in the +mailing list, such as marking pieces of text or lines, which were +extremely hard to do with CodeMirror 1. The new version has proper +support for these built in.
  • + +
  • Tab support. Tabs inside editable documents were, +for some reason, a no-go. At least six different people announced they +were going to add tab support to CodeMirror 1, none survived (I mean, +none delivered a working version). CodeMirror 2 no longer removes tabs +from your document.
  • + +
  • Sane styling. iframe nodes aren't +really known for respecting document flow. Now that an editor instance +is a plain div element, it is much easier to size it to +fit the surrounding elements. You don't even have to make it scroll if +you do not want to.
  • + +
+ +

Then, the bad:

+ +
    + +
  • No line-wrapping. I'd have liked to get +line-wrapping to work, but it doesn't match the model I'm using very +well. It is important that cursor movement in the textarea matches +what you see on the screen, and it seems to be impossible to have the +lines wrapped the same in the textarea and the normal DOM.
  • + +
  • Some cursor flakiness. The textarea hack does not +really do justice to the complexity of cursor handling—a selection is +typically more than just an offset into a string. For example, if you +use the up and down arrow keys to move to a shorter line and then +back, you'll end up in your old position in most editor controls, but +CodeMirror 2 currently doesn't remember the 'real' cursor column in +this case. These can be worked around on a case-by-case basis, but +I haven't put much energy into that yet.
  • + +
+ +
+ +
 
+ + + + diff --git a/htdocs/codemirror2/lib/codemirror.css b/htdocs/codemirror2/lib/codemirror.css new file mode 100644 index 000000000..d93e72d74 --- /dev/null +++ b/htdocs/codemirror2/lib/codemirror.css @@ -0,0 +1,67 @@ +.CodeMirror { + line-height: 1em; + font-family: monospace; +} + +.CodeMirror-scroll { + overflow: auto; + height: 300px; + /* This is needed to prevent an IE[67] bug where the scrolled content + is visible outside of the scrolling box. */ + position: relative; +} + +.CodeMirror-gutter { + position: absolute; left: 0; top: 0; + background-color: #f7f7f7; + border-right: 1px solid #eee; + min-width: 2em; + height: 100%; +} +.CodeMirror-gutter-text { + color: #aaa; + text-align: right; + padding: .4em .2em .4em .4em; +} +.CodeMirror-lines { + padding: .4em; +} + +.CodeMirror pre { + -moz-border-radius: 0; + -webkit-border-radius: 0; + -o-border-radius: 0; + border-radius: 0; + border-width: 0; margin: 0; padding: 0; background: transparent; + font-family: inherit; + font-size: inherit; + padding: 0; margin: 0; + white-space: pre; + word-wrap: normal; +} + +.CodeMirror textarea { + font-family: inherit !important; + font-size: inherit !important; +} + +.CodeMirror-cursor { + z-index: 10; + position: absolute; + visibility: hidden; + border-left: 1px solid black !important; +} +.CodeMirror-focused .CodeMirror-cursor { + visibility: visible; +} + +span.CodeMirror-selected { + background: #ccc !important; + color: HighlightText !important; +} +.CodeMirror-focused span.CodeMirror-selected { + background: Highlight !important; +} + +.CodeMirror-matchingbracket {color: #0f0 !important;} +.CodeMirror-nonmatchingbracket {color: #f22 !important;} diff --git a/htdocs/codemirror2/lib/codemirror.js b/htdocs/codemirror2/lib/codemirror.js new file mode 100644 index 000000000..5b03c8b63 --- /dev/null +++ b/htdocs/codemirror2/lib/codemirror.js @@ -0,0 +1,2152 @@ +// All functions that need access to the editor's state live inside +// the CodeMirror function. Below that, at the bottom of the file, +// some utilities are defined. + +// CodeMirror is the only global var we claim +var CodeMirror = (function() { + // This is the function that produces an editor instance. It's + // closure is used to store the editor state. + function CodeMirror(place, givenOptions) { + // Determine effective options based on given values and defaults. + var options = {}, defaults = CodeMirror.defaults; + for (var opt in defaults) + if (defaults.hasOwnProperty(opt)) + options[opt] = (givenOptions && givenOptions.hasOwnProperty(opt) ? givenOptions : defaults)[opt]; + + var targetDocument = options["document"]; + // The element in which the editor lives. + var wrapper = targetDocument.createElement("div"); + wrapper.className = "CodeMirror"; + // This mess creates the base DOM structure for the editor. + wrapper.innerHTML = + '
' + // Wraps and hides input textarea + '
' + + '
' + + '
' + // Set to the height of the text, causes scrolling + '
' + + '
' + // Moved around its parent to cover visible view + '
' + + // Provides positioning relative to (visible) text origin + '
' + + '
 
' + // Absolutely positioned blinky cursor + '
' + // This DIV contains the actual code + '
'; + if (place.appendChild) place.appendChild(wrapper); else place(wrapper); + // I've never seen more elegant code in my life. + var inputDiv = wrapper.firstChild, input = inputDiv.firstChild, + scroller = wrapper.lastChild, code = scroller.firstChild, + measure = code.firstChild, mover = measure.nextSibling, + gutter = mover.firstChild, gutterText = gutter.firstChild, + lineSpace = gutter.nextSibling.firstChild, + cursor = lineSpace.firstChild, lineDiv = cursor.nextSibling; + if (options.tabindex != null) input.tabindex = options.tabindex; + if (!options.gutter && !options.lineNumbers) gutter.style.display = "none"; + + // Delayed object wrap timeouts, making sure only one is active. blinker holds an interval. + var poll = new Delayed(), highlight = new Delayed(), blinker; + + // mode holds a mode API object. lines an array of Line objects + // (see Line constructor), work an array of lines that should be + // parsed, and history the undo history (instance of History + // constructor). + var mode, lines = [new Line("")], work, history = new History(), focused; + loadMode(); + // The selection. These are always maintained to point at valid + // positions. Inverted is used to remember that the user is + // selecting bottom-to-top. + var sel = {from: {line: 0, ch: 0}, to: {line: 0, ch: 0}, inverted: false}; + // Selection-related flags. shiftSelecting obviously tracks + // whether the user is holding shift. reducedSelection is a hack + // to get around the fact that we can't create inverted + // selections. See below. + var shiftSelecting, reducedSelection, lastDoubleClick; + // Variables used by startOperation/endOperation to track what + // happened during the operation. + var updateInput, changes, textChanged, selectionChanged, leaveInputAlone; + // Current visible range (may be bigger than the view window). + var showingFrom = 0, showingTo = 0, lastHeight = 0, curKeyId = null; + // editing will hold an object describing the things we put in the + // textarea, to help figure out whether something changed. + // bracketHighlighted is used to remember that a backet has been + // marked. + var editing, bracketHighlighted; + // Tracks the maximum line length so that the horizontal scrollbar + // can be kept static when scrolling. + var maxLine = "", maxWidth; + + // Initialize the content. + operation(function(){setValue(options.value || ""); updateInput = false;})(); + + // Register our event handlers. + connect(scroller, "mousedown", operation(onMouseDown)); + // Gecko browsers fire contextmenu *after* opening the menu, at + // which point we can't mess with it anymore. Context menu is + // handled in onMouseDown for Gecko. + if (!gecko) connect(scroller, "contextmenu", onContextMenu); + connect(code, "dblclick", operation(onDblClick)); + connect(scroller, "scroll", function() {updateDisplay([]); if (options.onScroll) options.onScroll(instance);}); + connect(window, "resize", function() {updateDisplay(true);}); + connect(input, "keyup", operation(onKeyUp)); + connect(input, "keydown", operation(onKeyDown)); + connect(input, "keypress", operation(onKeyPress)); + connect(input, "focus", onFocus); + connect(input, "blur", onBlur); + + connect(scroller, "dragenter", e_stop); + connect(scroller, "dragover", e_stop); + connect(scroller, "drop", operation(onDrop)); + connect(scroller, "paste", function(){focusInput(); fastPoll();}); + connect(input, "paste", function(){fastPoll();}); + connect(input, "cut", function(){fastPoll();}); + + // IE throws unspecified error in certain cases, when + // trying to access activeElement before onload + var hasFocus; try { hasFocus = (targetDocument.activeElement == input); } catch(e) { } + if (hasFocus) setTimeout(onFocus, 20); + else onBlur(); + + function isLine(l) {return l >= 0 && l < lines.length;} + // The instance object that we'll return. Mostly calls out to + // local functions in the CodeMirror function. Some do some extra + // range checking and/or clipping. operation is used to wrap the + // call so that changes it makes are tracked, and the display is + // updated afterwards. + var instance = { + getValue: getValue, + setValue: operation(setValue), + getSelection: getSelection, + replaceSelection: operation(replaceSelection), + focus: function(){focusInput(); onFocus(); fastPoll();}, + setOption: function(option, value) { + options[option] = value; + if (option == "lineNumbers" || option == "gutter") gutterChanged(); + else if (option == "mode" || option == "indentUnit") loadMode(); + else if (option == "readOnly" && value == "nocursor") input.blur(); + else if (option == "theme") scroller.className = scroller.className.replace(/cm-s-\w+/, "cm-s-" + value); + }, + getOption: function(option) {return options[option];}, + undo: operation(undo), + redo: operation(redo), + indentLine: operation(function(n, dir) { + if (isLine(n)) indentLine(n, dir == null ? "smart" : dir ? "add" : "subtract"); + }), + historySize: function() {return {undo: history.done.length, redo: history.undone.length};}, + matchBrackets: operation(function(){matchBrackets(true);}), + getTokenAt: function(pos) { + pos = clipPos(pos); + return lines[pos.line].getTokenAt(mode, getStateBefore(pos.line), pos.ch); + }, + getStateAfter: function(line) { + line = clipLine(line == null ? lines.length - 1: line); + return getStateBefore(line + 1); + }, + cursorCoords: function(start){ + if (start == null) start = sel.inverted; + return pageCoords(start ? sel.from : sel.to); + }, + charCoords: function(pos){return pageCoords(clipPos(pos));}, + coordsChar: function(coords) { + var off = eltOffset(lineSpace); + var line = clipLine(Math.min(lines.length - 1, showingFrom + Math.floor((coords.y - off.top) / lineHeight()))); + return clipPos({line: line, ch: charFromX(clipLine(line), coords.x - off.left)}); + }, + getSearchCursor: function(query, pos, caseFold) {return new SearchCursor(query, pos, caseFold);}, + markText: operation(function(a, b, c){return operation(markText(a, b, c));}), + setMarker: addGutterMarker, + clearMarker: removeGutterMarker, + setLineClass: operation(setLineClass), + lineInfo: lineInfo, + addWidget: function(pos, node, scroll, where) { + pos = localCoords(clipPos(pos)); + var top = pos.yBot, left = pos.x; + node.style.position = "absolute"; + code.appendChild(node); + node.style.left = left + "px"; + if (where == "over") top = pos.y; + else if (where == "near") { + var vspace = Math.max(scroller.offsetHeight, lines.length * lineHeight()), + hspace = Math.max(code.clientWidth, lineSpace.clientWidth) - paddingLeft(); + if (pos.yBot + node.offsetHeight > vspace && pos.y > node.offsetHeight) + top = pos.y - node.offsetHeight; + if (left + node.offsetWidth > hspace) + left = hspace - node.offsetWidth; + } + node.style.top = (top + paddingTop()) + "px"; + node.style.left = (left + paddingLeft()) + "px"; + if (scroll) + scrollIntoView(left, top, left + node.offsetWidth, top + node.offsetHeight); + }, + + lineCount: function() {return lines.length;}, + getCursor: function(start) { + if (start == null) start = sel.inverted; + return copyPos(start ? sel.from : sel.to); + }, + somethingSelected: function() {return !posEq(sel.from, sel.to);}, + setCursor: operation(function(line, ch) { + if (ch == null && typeof line.line == "number") setCursor(line.line, line.ch); + else setCursor(line, ch); + }), + setSelection: operation(function(from, to) {setSelection(clipPos(from), clipPos(to || from));}), + getLine: function(line) {if (isLine(line)) return lines[line].text;}, + setLine: operation(function(line, text) { + if (isLine(line)) replaceRange(text, {line: line, ch: 0}, {line: line, ch: lines[line].text.length}); + }), + removeLine: operation(function(line) { + if (isLine(line)) replaceRange("", {line: line, ch: 0}, clipPos({line: line+1, ch: 0})); + }), + replaceRange: operation(replaceRange), + getRange: function(from, to) {return getRange(clipPos(from), clipPos(to));}, + + operation: function(f){return operation(f)();}, + refresh: function(){updateDisplay(true);}, + getInputField: function(){return input;}, + getWrapperElement: function(){return wrapper;}, + getScrollerElement: function(){return scroller;}, + getGutterElement: function(){return gutter;} + }; + + function setValue(code) { + history = null; + var top = {line: 0, ch: 0}; + updateLines(top, {line: lines.length - 1, ch: lines[lines.length-1].text.length}, + splitLines(code), top, top); + history = new History(); + } + function getValue(code) { + var text = []; + for (var i = 0, l = lines.length; i < l; ++i) + text.push(lines[i].text); + return text.join("\n"); + } + + function onMouseDown(e) { + // Check whether this is a click in a widget + for (var n = e_target(e); n != wrapper; n = n.parentNode) + if (n.parentNode == code && n != mover) return; + var ld = lastDoubleClick; lastDoubleClick = null; + // First, see if this is a click in the gutter + for (var n = e_target(e); n != wrapper; n = n.parentNode) + if (n.parentNode == gutterText) { + if (options.onGutterClick) + options.onGutterClick(instance, indexOf(gutterText.childNodes, n) + showingFrom); + return e_preventDefault(e); + } + + var start = posFromMouse(e); + + switch (e_button(e)) { + case 3: + if (gecko && !mac) onContextMenu(e); + return; + case 2: + if (start) setCursor(start.line, start.ch, true); + return; + } + // For button 1, if it was clicked inside the editor + // (posFromMouse returning non-null), we have to adjust the + // selection. + if (!start) {if (e_target(e) == scroller) e_preventDefault(e); return;} + + if (!focused) onFocus(); + e_preventDefault(e); + if (ld && +new Date - ld < 400) return selectLine(start.line); + + setCursor(start.line, start.ch, true); + var last = start, going; + // And then we have to see if it's a drag event, in which case + // the dragged-over text must be selected. + function end() { + focusInput(); + updateInput = true; + move(); up(); + } + function extend(e) { + var cur = posFromMouse(e, true); + if (cur && !posEq(cur, last)) { + if (!focused) onFocus(); + last = cur; + setSelectionUser(start, cur); + updateInput = false; + var visible = visibleLines(); + if (cur.line >= visible.to || cur.line < visible.from) + going = setTimeout(operation(function(){extend(e);}), 150); + } + } + + var move = connect(targetDocument, "mousemove", operation(function(e) { + clearTimeout(going); + e_preventDefault(e); + extend(e); + }), true); + var up = connect(targetDocument, "mouseup", operation(function(e) { + clearTimeout(going); + var cur = posFromMouse(e); + if (cur) setSelectionUser(start, cur); + e_preventDefault(e); + end(); + }), true); + } + function onDblClick(e) { + var pos = posFromMouse(e); + if (!pos) return; + selectWordAt(pos); + e_preventDefault(e); + lastDoubleClick = +new Date; + } + function onDrop(e) { + e.preventDefault(); + var pos = posFromMouse(e, true), files = e.dataTransfer.files; + if (!pos || options.readOnly) return; + if (files && files.length && window.FileReader && window.File) { + function loadFile(file, i) { + var reader = new FileReader; + reader.onload = function() { + text[i] = reader.result; + if (++read == n) replaceRange(text.join(""), clipPos(pos), clipPos(pos)); + }; + reader.readAsText(file); + } + var n = files.length, text = Array(n), read = 0; + for (var i = 0; i < n; ++i) loadFile(files[i], i); + } + else { + try { + var text = e.dataTransfer.getData("Text"); + if (text) replaceRange(text, pos, pos); + } + catch(e){} + } + } + function onKeyDown(e) { + if (!focused) onFocus(); + + var code = e.keyCode; + // IE does strange things with escape. + if (ie && code == 27) { e.returnValue = false; } + // Tries to detect ctrl on non-mac, cmd on mac. + var mod = (mac ? e.metaKey : e.ctrlKey) && !e.altKey, anyMod = e.ctrlKey || e.altKey || e.metaKey; + if (code == 16 || e.shiftKey) shiftSelecting = shiftSelecting || (sel.inverted ? sel.to : sel.from); + else shiftSelecting = null; + // First give onKeyEvent option a chance to handle this. + if (options.onKeyEvent && options.onKeyEvent(instance, addStop(e))) return; + + if (code == 33 || code == 34) {scrollPage(code == 34); return e_preventDefault(e);} // page up/down + if (mod && ((code == 36 || code == 35) || // ctrl-home/end + mac && (code == 38 || code == 40))) { // cmd-up/down + scrollEnd(code == 36 || code == 38); return e_preventDefault(e); + } + if (mod && code == 65) {selectAll(); return e_preventDefault(e);} // ctrl-a + if (!options.readOnly) { + if (!anyMod && code == 13) {return;} // enter + if (!anyMod && code == 9 && handleTab(e.shiftKey)) return e_preventDefault(e); // tab + if (mod && code == 90) {undo(); return e_preventDefault(e);} // ctrl-z + if (mod && ((e.shiftKey && code == 90) || code == 89)) {redo(); return e_preventDefault(e);} // ctrl-shift-z, ctrl-y + } + + // Key id to use in the movementKeys map. We also pass it to + // fastPoll in order to 'self learn'. We need this because + // reducedSelection, the hack where we collapse the selection to + // its start when it is inverted and a movement key is pressed + // (and later restore it again), shouldn't be used for + // non-movement keys. + curKeyId = (mod ? "c" : "") + (e.altKey ? "a" : "") + code; + if (sel.inverted && movementKeys[curKeyId] === true) { + var range = selRange(input); + if (range) { + reducedSelection = {anchor: range.start}; + setSelRange(input, range.start, range.start); + } + } + // Don't save the key as a movementkey unless it had a modifier + if (!mod && !e.altKey) curKeyId = null; + fastPoll(curKeyId); + } + function onKeyUp(e) { + if (options.onKeyEvent && options.onKeyEvent(instance, addStop(e))) return; + if (reducedSelection) { + reducedSelection = null; + updateInput = true; + } + if (e.keyCode == 16) shiftSelecting = null; + } + function onKeyPress(e) { + if (options.onKeyEvent && options.onKeyEvent(instance, addStop(e))) return; + if (options.electricChars && mode.electricChars) { + var ch = String.fromCharCode(e.charCode == null ? e.keyCode : e.charCode); + if (mode.electricChars.indexOf(ch) > -1) + setTimeout(operation(function() {indentLine(sel.to.line, "smart");}), 50); + } + var code = e.keyCode; + // Re-stop tab and enter. Necessary on some browsers. + if (code == 13) {if (!options.readOnly) handleEnter(); e_preventDefault(e);} + else if (!e.ctrlKey && !e.altKey && !e.metaKey && code == 9 && options.tabMode != "default") e_preventDefault(e); + else fastPoll(curKeyId); + } + + function onFocus() { + if (options.readOnly == "nocursor") return; + if (!focused) { + if (options.onFocus) options.onFocus(instance); + focused = true; + if (wrapper.className.search(/\bCodeMirror-focused\b/) == -1) + wrapper.className += " CodeMirror-focused"; + if (!leaveInputAlone) prepareInput(); + } + slowPoll(); + restartBlink(); + } + function onBlur() { + if (focused) { + if (options.onBlur) options.onBlur(instance); + focused = false; + wrapper.className = wrapper.className.replace(" CodeMirror-focused", ""); + } + clearInterval(blinker); + setTimeout(function() {if (!focused) shiftSelecting = null;}, 150); + } + + // Replace the range from from to to by the strings in newText. + // Afterwards, set the selection to selFrom, selTo. + function updateLines(from, to, newText, selFrom, selTo) { + if (history) { + var old = []; + for (var i = from.line, e = to.line + 1; i < e; ++i) old.push(lines[i].text); + history.addChange(from.line, newText.length, old); + while (history.done.length > options.undoDepth) history.done.shift(); + } + updateLinesNoUndo(from, to, newText, selFrom, selTo); + } + function unredoHelper(from, to) { + var change = from.pop(); + if (change) { + var replaced = [], end = change.start + change.added; + for (var i = change.start; i < end; ++i) replaced.push(lines[i].text); + to.push({start: change.start, added: change.old.length, old: replaced}); + var pos = clipPos({line: change.start + change.old.length - 1, + ch: editEnd(replaced[replaced.length-1], change.old[change.old.length-1])}); + updateLinesNoUndo({line: change.start, ch: 0}, {line: end - 1, ch: lines[end-1].text.length}, change.old, pos, pos); + updateInput = true; + } + } + function undo() {unredoHelper(history.done, history.undone);} + function redo() {unredoHelper(history.undone, history.done);} + + function updateLinesNoUndo(from, to, newText, selFrom, selTo) { + var recomputeMaxLength = false, maxLineLength = maxLine.length; + for (var i = from.line; i <= to.line; ++i) { + if (lines[i].text.length == maxLineLength) {recomputeMaxLength = true; break;} + } + + var nlines = to.line - from.line, firstLine = lines[from.line], lastLine = lines[to.line]; + // First adjust the line structure, taking some care to leave highlighting intact. + if (firstLine == lastLine) { + if (newText.length == 1) + firstLine.replace(from.ch, to.ch, newText[0]); + else { + lastLine = firstLine.split(to.ch, newText[newText.length-1]); + var spliceargs = [from.line + 1, nlines]; + firstLine.replace(from.ch, firstLine.text.length, newText[0]); + for (var i = 1, e = newText.length - 1; i < e; ++i) spliceargs.push(new Line(newText[i])); + spliceargs.push(lastLine); + lines.splice.apply(lines, spliceargs); + } + } + else if (newText.length == 1) { + firstLine.replace(from.ch, firstLine.text.length, newText[0] + lastLine.text.slice(to.ch)); + lines.splice(from.line + 1, nlines); + } + else { + var spliceargs = [from.line + 1, nlines - 1]; + firstLine.replace(from.ch, firstLine.text.length, newText[0]); + lastLine.replace(0, to.ch, newText[newText.length-1]); + for (var i = 1, e = newText.length - 1; i < e; ++i) spliceargs.push(new Line(newText[i])); + lines.splice.apply(lines, spliceargs); + } + + + for (var i = from.line, e = i + newText.length; i < e; ++i) { + var l = lines[i].text; + if (l.length > maxLineLength) { + maxLine = l; maxLineLength = l.length; maxWidth = null; + recomputeMaxLength = false; + } + } + if (recomputeMaxLength) { + maxLineLength = 0; maxLine = ""; maxWidth = null; + for (var i = 0, e = lines.length; i < e; ++i) { + var l = lines[i].text; + if (l.length > maxLineLength) { + maxLineLength = l.length; maxLine = l; + } + } + } + + // Add these lines to the work array, so that they will be + // highlighted. Adjust work lines if lines were added/removed. + var newWork = [], lendiff = newText.length - nlines - 1; + for (var i = 0, l = work.length; i < l; ++i) { + var task = work[i]; + if (task < from.line) newWork.push(task); + else if (task > to.line) newWork.push(task + lendiff); + } + if (newText.length < 5) { + highlightLines(from.line, from.line + newText.length); + newWork.push(from.line + newText.length); + } else { + newWork.push(from.line); + } + work = newWork; + startWorker(100); + // Remember that these lines changed, for updating the display + changes.push({from: from.line, to: to.line + 1, diff: lendiff}); + textChanged = {from: from, to: to, text: newText}; + + // Update the selection + function updateLine(n) {return n <= Math.min(to.line, to.line + lendiff) ? n : n + lendiff;} + setSelection(selFrom, selTo, updateLine(sel.from.line), updateLine(sel.to.line)); + + // Make sure the scroll-size div has the correct height. + code.style.height = (lines.length * lineHeight() + 2 * paddingTop()) + "px"; + } + + function replaceRange(code, from, to) { + from = clipPos(from); + if (!to) to = from; else to = clipPos(to); + code = splitLines(code); + function adjustPos(pos) { + if (posLess(pos, from)) return pos; + if (!posLess(to, pos)) return end; + var line = pos.line + code.length - (to.line - from.line) - 1; + var ch = pos.ch; + if (pos.line == to.line) + ch += code[code.length-1].length - (to.ch - (to.line == from.line ? from.ch : 0)); + return {line: line, ch: ch}; + } + var end; + replaceRange1(code, from, to, function(end1) { + end = end1; + return {from: adjustPos(sel.from), to: adjustPos(sel.to)}; + }); + return end; + } + function replaceSelection(code, collapse) { + replaceRange1(splitLines(code), sel.from, sel.to, function(end) { + if (collapse == "end") return {from: end, to: end}; + else if (collapse == "start") return {from: sel.from, to: sel.from}; + else return {from: sel.from, to: end}; + }); + } + function replaceRange1(code, from, to, computeSel) { + var endch = code.length == 1 ? code[0].length + from.ch : code[code.length-1].length; + var newSel = computeSel({line: from.line + code.length - 1, ch: endch}); + updateLines(from, to, code, newSel.from, newSel.to); + } + + function getRange(from, to) { + var l1 = from.line, l2 = to.line; + if (l1 == l2) return lines[l1].text.slice(from.ch, to.ch); + var code = [lines[l1].text.slice(from.ch)]; + for (var i = l1 + 1; i < l2; ++i) code.push(lines[i].text); + code.push(lines[l2].text.slice(0, to.ch)); + return code.join("\n"); + } + function getSelection() { + return getRange(sel.from, sel.to); + } + + var pollingFast = false; // Ensures slowPoll doesn't cancel fastPoll + function slowPoll() { + if (pollingFast) return; + poll.set(2000, function() { + startOperation(); + readInput(); + if (focused) slowPoll(); + endOperation(); + }); + } + function fastPoll(keyId) { + var missed = false; + pollingFast = true; + function p() { + startOperation(); + var changed = readInput(); + if (changed && keyId) { + if (changed == "moved" && movementKeys[keyId] == null) movementKeys[keyId] = true; + if (changed == "changed") movementKeys[keyId] = false; + } + if (!changed && !missed) {missed = true; poll.set(80, p);} + else {pollingFast = false; slowPoll();} + endOperation(); + } + poll.set(20, p); + } + + // Inspects the textarea, compares its state (content, selection) + // to the data in the editing variable, and updates the editor + // content or cursor if something changed. + function readInput() { + if (leaveInputAlone || !focused) return; + var changed = false, text = input.value, sr = selRange(input); + if (!sr) return false; + var changed = editing.text != text, rs = reducedSelection; + var moved = changed || sr.start != editing.start || sr.end != (rs ? editing.start : editing.end); + if (!moved && !rs) return false; + if (changed) { + shiftSelecting = reducedSelection = null; + if (options.readOnly) {updateInput = true; return "changed";} + } + + // Compute selection start and end based on start/end offsets in textarea + function computeOffset(n, startLine) { + var pos = 0; + for (;;) { + var found = text.indexOf("\n", pos); + if (found == -1 || (text.charAt(found-1) == "\r" ? found - 1 : found) >= n) + return {line: startLine, ch: n - pos}; + ++startLine; + pos = found + 1; + } + } + var from = computeOffset(sr.start, editing.from), + to = computeOffset(sr.end, editing.from); + // Here we have to take the reducedSelection hack into account, + // so that you can, for example, press shift-up at the start of + // your selection and have the right thing happen. + if (rs) { + var head = sr.start == rs.anchor ? to : from; + var tail = shiftSelecting ? sel.to : sr.start == rs.anchor ? from : to; + if (sel.inverted = posLess(head, tail)) { from = head; to = tail; } + else { reducedSelection = null; from = tail; to = head; } + } + + // In some cases (cursor on same line as before), we don't have + // to update the textarea content at all. + if (from.line == to.line && from.line == sel.from.line && from.line == sel.to.line && !shiftSelecting) + updateInput = false; + + // Magic mess to extract precise edited range from the changed + // string. + if (changed) { + var start = 0, end = text.length, len = Math.min(end, editing.text.length); + var c, line = editing.from, nl = -1; + while (start < len && (c = text.charAt(start)) == editing.text.charAt(start)) { + ++start; + if (c == "\n") {line++; nl = start;} + } + var ch = nl > -1 ? start - nl : start, endline = editing.to - 1, edend = editing.text.length; + for (;;) { + c = editing.text.charAt(edend); + if (text.charAt(end) != c) {++end; ++edend; break;} + if (c == "\n") endline--; + if (edend <= start || end <= start) break; + --end; --edend; + } + var nl = editing.text.lastIndexOf("\n", edend - 1), endch = nl == -1 ? edend : edend - nl - 1; + updateLines({line: line, ch: ch}, {line: endline, ch: endch}, splitLines(text.slice(start, end)), from, to); + if (line != endline || from.line != line) updateInput = true; + } + else setSelection(from, to); + + editing.text = text; editing.start = sr.start; editing.end = sr.end; + return changed ? "changed" : moved ? "moved" : false; + } + + // Set the textarea content and selection range to match the + // editor state. + function prepareInput() { + var text = []; + var from = Math.max(0, sel.from.line - 1), to = Math.min(lines.length, sel.to.line + 2); + for (var i = from; i < to; ++i) text.push(lines[i].text); + text = input.value = text.join(lineSep); + var startch = sel.from.ch, endch = sel.to.ch; + for (var i = from; i < sel.from.line; ++i) + startch += lineSep.length + lines[i].text.length; + for (var i = from; i < sel.to.line; ++i) + endch += lineSep.length + lines[i].text.length; + editing = {text: text, from: from, to: to, start: startch, end: endch}; + setSelRange(input, startch, reducedSelection ? startch : endch); + } + function focusInput() { + if (options.readOnly != "nocursor") input.focus(); + } + + function scrollCursorIntoView() { + var cursor = localCoords(sel.inverted ? sel.from : sel.to); + return scrollIntoView(cursor.x, cursor.y, cursor.x, cursor.yBot); + } + function scrollIntoView(x1, y1, x2, y2) { + var pl = paddingLeft(), pt = paddingTop(), lh = lineHeight(); + y1 += pt; y2 += pt; x1 += pl; x2 += pl; + var screen = scroller.clientHeight, screentop = scroller.scrollTop, scrolled = false, result = true; + if (y1 < screentop) {scroller.scrollTop = Math.max(0, y1 - 2*lh); scrolled = true;} + else if (y2 > screentop + screen) {scroller.scrollTop = y2 + lh - screen; scrolled = true;} + + var screenw = scroller.clientWidth, screenleft = scroller.scrollLeft; + if (x1 < screenleft) { + if (x1 < 50) x1 = 0; + scroller.scrollLeft = Math.max(0, x1 - 10); + scrolled = true; + } + else if (x2 > screenw + screenleft) { + scroller.scrollLeft = x2 + 10 - screenw; + scrolled = true; + if (x2 > code.clientWidth) result = false; + } + if (scrolled && options.onScroll) options.onScroll(instance); + return result; + } + + function visibleLines() { + var lh = lineHeight(), top = scroller.scrollTop - paddingTop(); + return {from: Math.min(lines.length, Math.max(0, Math.floor(top / lh))), + to: Math.min(lines.length, Math.ceil((top + scroller.clientHeight) / lh))}; + } + // Uses a set of changes plus the current scroll position to + // determine which DOM updates have to be made, and makes the + // updates. + function updateDisplay(changes) { + if (!scroller.clientWidth) { + showingFrom = showingTo = 0; + return; + } + // First create a range of theoretically intact lines, and punch + // holes in that using the change info. + var intact = changes === true ? [] : [{from: showingFrom, to: showingTo, domStart: 0}]; + for (var i = 0, l = changes.length || 0; i < l; ++i) { + var change = changes[i], intact2 = [], diff = change.diff || 0; + for (var j = 0, l2 = intact.length; j < l2; ++j) { + var range = intact[j]; + if (change.to <= range.from) + intact2.push({from: range.from + diff, to: range.to + diff, domStart: range.domStart}); + else if (range.to <= change.from) + intact2.push(range); + else { + if (change.from > range.from) + intact2.push({from: range.from, to: change.from, domStart: range.domStart}) + if (change.to < range.to) + intact2.push({from: change.to + diff, to: range.to + diff, + domStart: range.domStart + (change.to - range.from)}); + } + } + intact = intact2; + } + + // Then, determine which lines we'd want to see, and which + // updates have to be made to get there. + var visible = visibleLines(); + var from = Math.min(showingFrom, Math.max(visible.from - 3, 0)), + to = Math.min(lines.length, Math.max(showingTo, visible.to + 3)), + updates = [], domPos = 0, domEnd = showingTo - showingFrom, pos = from, changedLines = 0; + + for (var i = 0, l = intact.length; i < l; ++i) { + var range = intact[i]; + if (range.to <= from) continue; + if (range.from >= to) break; + if (range.domStart > domPos || range.from > pos) { + updates.push({from: pos, to: range.from, domSize: range.domStart - domPos, domStart: domPos}); + changedLines += range.from - pos; + } + pos = range.to; + domPos = range.domStart + (range.to - range.from); + } + if (domPos != domEnd || pos != to) { + changedLines += Math.abs(to - pos); + updates.push({from: pos, to: to, domSize: domEnd - domPos, domStart: domPos}); + } + + if (!updates.length) return; + lineDiv.style.display = "none"; + // If more than 30% of the screen needs update, just do a full + // redraw (which is quicker than patching) + if (changedLines > (visible.to - visible.from) * .3) + refreshDisplay(from = Math.max(visible.from - 10, 0), to = Math.min(visible.to + 7, lines.length)); + // Otherwise, only update the stuff that needs updating. + else + patchDisplay(updates); + lineDiv.style.display = ""; + + // Position the mover div to align with the lines it's supposed + // to be showing (which will cover the visible display) + var different = from != showingFrom || to != showingTo || lastHeight != scroller.clientHeight; + showingFrom = from; showingTo = to; + mover.style.top = (from * lineHeight()) + "px"; + if (different) { + lastHeight = scroller.clientHeight; + code.style.height = (lines.length * lineHeight() + 2 * paddingTop()) + "px"; + updateGutter(); + } + + if (maxWidth == null) maxWidth = stringWidth(maxLine); + if (maxWidth > scroller.clientWidth) { + lineSpace.style.width = maxWidth + "px"; + // Needed to prevent odd wrapping/hiding of widgets placed in here. + code.style.width = ""; + code.style.width = scroller.scrollWidth + "px"; + } else { + lineSpace.style.width = code.style.width = ""; + } + + // Since this is all rather error prone, it is honoured with the + // only assertion in the whole file. + if (lineDiv.childNodes.length != showingTo - showingFrom) + throw new Error("BAD PATCH! " + JSON.stringify(updates) + " size=" + (showingTo - showingFrom) + + " nodes=" + lineDiv.childNodes.length); + updateCursor(); + } + + function refreshDisplay(from, to) { + var html = [], start = {line: from, ch: 0}, inSel = posLess(sel.from, start) && !posLess(sel.to, start); + for (var i = from; i < to; ++i) { + var ch1 = null, ch2 = null; + if (inSel) { + ch1 = 0; + if (sel.to.line == i) {inSel = false; ch2 = sel.to.ch;} + } + else if (sel.from.line == i) { + if (sel.to.line == i) {ch1 = sel.from.ch; ch2 = sel.to.ch;} + else {inSel = true; ch1 = sel.from.ch;} + } + html.push(lines[i].getHTML(ch1, ch2, true)); + } + lineDiv.innerHTML = html.join(""); + } + function patchDisplay(updates) { + // Slightly different algorithm for IE (badInnerHTML), since + // there .innerHTML on PRE nodes is dumb, and discards + // whitespace. + var sfrom = sel.from.line, sto = sel.to.line, off = 0, + scratch = badInnerHTML && targetDocument.createElement("div"); + for (var i = 0, e = updates.length; i < e; ++i) { + var rec = updates[i]; + var extra = (rec.to - rec.from) - rec.domSize; + var nodeAfter = lineDiv.childNodes[rec.domStart + rec.domSize + off] || null; + if (badInnerHTML) + for (var j = Math.max(-extra, rec.domSize); j > 0; --j) + lineDiv.removeChild(nodeAfter ? nodeAfter.previousSibling : lineDiv.lastChild); + else if (extra) { + for (var j = Math.max(0, extra); j > 0; --j) + lineDiv.insertBefore(targetDocument.createElement("pre"), nodeAfter); + for (var j = Math.max(0, -extra); j > 0; --j) + lineDiv.removeChild(nodeAfter ? nodeAfter.previousSibling : lineDiv.lastChild); + } + var node = lineDiv.childNodes[rec.domStart + off], inSel = sfrom < rec.from && sto >= rec.from; + for (var j = rec.from; j < rec.to; ++j) { + var ch1 = null, ch2 = null; + if (inSel) { + ch1 = 0; + if (sto == j) {inSel = false; ch2 = sel.to.ch;} + } + else if (sfrom == j) { + if (sto == j) {ch1 = sel.from.ch; ch2 = sel.to.ch;} + else {inSel = true; ch1 = sel.from.ch;} + } + if (badInnerHTML) { + scratch.innerHTML = lines[j].getHTML(ch1, ch2, true); + lineDiv.insertBefore(scratch.firstChild, nodeAfter); + } + else { + node.innerHTML = lines[j].getHTML(ch1, ch2, false); + node.className = lines[j].className || ""; + node = node.nextSibling; + } + } + off += extra; + } + } + + function updateGutter() { + if (!options.gutter && !options.lineNumbers) return; + var hText = mover.offsetHeight, hEditor = scroller.clientHeight; + gutter.style.height = (hText - hEditor < 2 ? hEditor : hText) + "px"; + var html = []; + for (var i = showingFrom; i < Math.max(showingTo, showingFrom + 1); ++i) { + var marker = lines[i].gutterMarker; + var text = options.lineNumbers ? i + options.firstLineNumber : null; + if (marker && marker.text) + text = marker.text.replace("%N%", text != null ? text : ""); + else if (text == null) + text = "\u00a0"; + html.push((marker && marker.style ? '
' : "
"), text, "
"); + } + gutter.style.display = "none"; + gutterText.innerHTML = html.join(""); + var minwidth = String(lines.length).length, firstNode = gutterText.firstChild, val = eltText(firstNode), pad = ""; + while (val.length + pad.length < minwidth) pad += "\u00a0"; + if (pad) firstNode.insertBefore(targetDocument.createTextNode(pad), firstNode.firstChild); + gutter.style.display = ""; + lineSpace.style.marginLeft = gutter.offsetWidth + "px"; + } + function updateCursor() { + var head = sel.inverted ? sel.from : sel.to, lh = lineHeight(); + var x = charX(head.line, head.ch) + "px", y = (head.line - showingFrom) * lh + "px"; + inputDiv.style.top = (head.line * lh - scroller.scrollTop) + "px"; + if (posEq(sel.from, sel.to)) { + cursor.style.top = y; cursor.style.left = x; + cursor.style.display = ""; + } + else cursor.style.display = "none"; + } + + function setSelectionUser(from, to) { + var sh = shiftSelecting && clipPos(shiftSelecting); + if (sh) { + if (posLess(sh, from)) from = sh; + else if (posLess(to, sh)) to = sh; + } + setSelection(from, to); + } + // Update the selection. Last two args are only used by + // updateLines, since they have to be expressed in the line + // numbers before the update. + function setSelection(from, to, oldFrom, oldTo) { + if (posEq(sel.from, from) && posEq(sel.to, to)) return; + if (posLess(to, from)) {var tmp = to; to = from; from = tmp;} + + if (posEq(from, to)) sel.inverted = false; + else if (posEq(from, sel.to)) sel.inverted = false; + else if (posEq(to, sel.from)) sel.inverted = true; + + // Some ugly logic used to only mark the lines that actually did + // see a change in selection as changed, rather than the whole + // selected range. + if (oldFrom == null) {oldFrom = sel.from.line; oldTo = sel.to.line;} + if (posEq(from, to)) { + if (!posEq(sel.from, sel.to)) + changes.push({from: oldFrom, to: oldTo + 1}); + } + else if (posEq(sel.from, sel.to)) { + changes.push({from: from.line, to: to.line + 1}); + } + else { + if (!posEq(from, sel.from)) { + if (from.line < oldFrom) + changes.push({from: from.line, to: Math.min(to.line, oldFrom) + 1}); + else + changes.push({from: oldFrom, to: Math.min(oldTo, from.line) + 1}); + } + if (!posEq(to, sel.to)) { + if (to.line < oldTo) + changes.push({from: Math.max(oldFrom, from.line), to: oldTo + 1}); + else + changes.push({from: Math.max(from.line, oldTo), to: to.line + 1}); + } + } + sel.from = from; sel.to = to; + selectionChanged = true; + } + function setCursor(line, ch, user) { + var pos = clipPos({line: line, ch: ch || 0}); + (user ? setSelectionUser : setSelection)(pos, pos); + } + + function clipLine(n) {return Math.max(0, Math.min(n, lines.length-1));} + function clipPos(pos) { + if (pos.line < 0) return {line: 0, ch: 0}; + if (pos.line >= lines.length) return {line: lines.length-1, ch: lines[lines.length-1].text.length}; + var ch = pos.ch, linelen = lines[pos.line].text.length; + if (ch == null || ch > linelen) return {line: pos.line, ch: linelen}; + else if (ch < 0) return {line: pos.line, ch: 0}; + else return pos; + } + + function scrollPage(down) { + var linesPerPage = Math.floor(scroller.clientHeight / lineHeight()), head = sel.inverted ? sel.from : sel.to; + setCursor(head.line + (Math.max(linesPerPage - 1, 1) * (down ? 1 : -1)), head.ch, true); + } + function scrollEnd(top) { + var pos = top ? {line: 0, ch: 0} : {line: lines.length - 1, ch: lines[lines.length-1].text.length}; + setSelectionUser(pos, pos); + } + function selectAll() { + var endLine = lines.length - 1; + setSelection({line: 0, ch: 0}, {line: endLine, ch: lines[endLine].text.length}); + } + function selectWordAt(pos) { + var line = lines[pos.line].text; + var start = pos.ch, end = pos.ch; + while (start > 0 && /\w/.test(line.charAt(start - 1))) --start; + while (end < line.length && /\w/.test(line.charAt(end))) ++end; + setSelectionUser({line: pos.line, ch: start}, {line: pos.line, ch: end}); + } + function selectLine(line) { + setSelectionUser({line: line, ch: 0}, {line: line, ch: lines[line].text.length}); + } + function handleEnter() { + replaceSelection("\n", "end"); + if (options.enterMode != "flat") + indentLine(sel.from.line, options.enterMode == "keep" ? "prev" : "smart"); + } + function handleTab(shift) { + function indentSelected(mode) { + if (posEq(sel.from, sel.to)) return indentLine(sel.from.line, mode); + var e = sel.to.line - (sel.to.ch ? 0 : 1); + for (var i = sel.from.line; i <= e; ++i) indentLine(i, mode); + } + shiftSelecting = null; + switch (options.tabMode) { + case "default": + return false; + case "indent": + indentSelected("smart"); + break; + case "classic": + if (posEq(sel.from, sel.to)) { + if (shift) indentLine(sel.from.line, "smart"); + else replaceSelection("\t", "end"); + break; + } + case "shift": + indentSelected(shift ? "subtract" : "add"); + break; + } + return true; + } + + function indentLine(n, how) { + if (how == "smart") { + if (!mode.indent) how = "prev"; + else var state = getStateBefore(n); + } + + var line = lines[n], curSpace = line.indentation(), curSpaceString = line.text.match(/^\s*/)[0], indentation; + if (how == "prev") { + if (n) indentation = lines[n-1].indentation(); + else indentation = 0; + } + else if (how == "smart") indentation = mode.indent(state, line.text.slice(curSpaceString.length)); + else if (how == "add") indentation = curSpace + options.indentUnit; + else if (how == "subtract") indentation = curSpace - options.indentUnit; + indentation = Math.max(0, indentation); + var diff = indentation - curSpace; + + if (!diff) { + if (sel.from.line != n && sel.to.line != n) return; + var indentString = curSpaceString; + } + else { + var indentString = "", pos = 0; + if (options.indentWithTabs) + for (var i = Math.floor(indentation / tabSize); i; --i) {pos += tabSize; indentString += "\t";} + while (pos < indentation) {++pos; indentString += " ";} + } + + replaceRange(indentString, {line: n, ch: 0}, {line: n, ch: curSpaceString.length}); + } + + function loadMode() { + mode = CodeMirror.getMode(options, options.mode); + for (var i = 0, l = lines.length; i < l; ++i) + lines[i].stateAfter = null; + work = [0]; + startWorker(); + } + function gutterChanged() { + var visible = options.gutter || options.lineNumbers; + gutter.style.display = visible ? "" : "none"; + if (visible) updateGutter(); + else lineDiv.parentNode.style.marginLeft = 0; + } + + function markText(from, to, className) { + from = clipPos(from); to = clipPos(to); + var accum = []; + function add(line, from, to, className) { + var line = lines[line], mark = line.addMark(from, to, className); + mark.line = line; + accum.push(mark); + } + if (from.line == to.line) add(from.line, from.ch, to.ch, className); + else { + add(from.line, from.ch, null, className); + for (var i = from.line + 1, e = to.line; i < e; ++i) + add(i, 0, null, className); + add(to.line, 0, to.ch, className); + } + changes.push({from: from.line, to: to.line + 1}); + return function() { + var start, end; + for (var i = 0; i < accum.length; ++i) { + var mark = accum[i], found = indexOf(lines, mark.line); + mark.line.removeMark(mark); + if (found > -1) { + if (start == null) start = found; + end = found; + } + } + if (start != null) changes.push({from: start, to: end + 1}); + }; + } + + function addGutterMarker(line, text, className) { + if (typeof line == "number") line = lines[clipLine(line)]; + line.gutterMarker = {text: text, style: className}; + updateGutter(); + return line; + } + function removeGutterMarker(line) { + if (typeof line == "number") line = lines[clipLine(line)]; + line.gutterMarker = null; + updateGutter(); + } + function setLineClass(line, className) { + if (typeof line == "number") { + var no = line; + line = lines[clipLine(line)]; + } + else { + var no = indexOf(lines, line); + if (no == -1) return null; + } + if (line.className != className) { + line.className = className; + changes.push({from: no, to: no + 1}); + } + return line; + } + + function lineInfo(line) { + if (typeof line == "number") { + var n = line; + line = lines[line]; + if (!line) return null; + } + else { + var n = indexOf(lines, line); + if (n == -1) return null; + } + var marker = line.gutterMarker; + return {line: n, text: line.text, markerText: marker && marker.text, markerClass: marker && marker.style}; + } + + function stringWidth(str) { + measure.innerHTML = "
x
"; + measure.firstChild.firstChild.firstChild.nodeValue = str; + return measure.firstChild.firstChild.offsetWidth || 10; + } + // These are used to go from pixel positions to character + // positions, taking varying character widths into account. + function charX(line, pos) { + if (pos == 0) return 0; + measure.innerHTML = "
" + lines[line].getHTML(null, null, false, pos) + "
"; + return measure.firstChild.firstChild.offsetWidth; + } + function charFromX(line, x) { + if (x <= 0) return 0; + var lineObj = lines[line], text = lineObj.text; + function getX(len) { + measure.innerHTML = "
" + lineObj.getHTML(null, null, false, len) + "
"; + return measure.firstChild.firstChild.offsetWidth; + } + var from = 0, fromX = 0, to = text.length, toX; + // Guess a suitable upper bound for our search. + var estimated = Math.min(to, Math.ceil(x / stringWidth("x"))); + for (;;) { + var estX = getX(estimated); + if (estX <= x && estimated < to) estimated = Math.min(to, Math.ceil(estimated * 1.2)); + else {toX = estX; to = estimated; break;} + } + if (x > toX) return to; + // Try to guess a suitable lower bound as well. + estimated = Math.floor(to * 0.8); estX = getX(estimated); + if (estX < x) {from = estimated; fromX = estX;} + // Do a binary search between these bounds. + for (;;) { + if (to - from <= 1) return (toX - x > x - fromX) ? from : to; + var middle = Math.ceil((from + to) / 2), middleX = getX(middle); + if (middleX > x) {to = middle; toX = middleX;} + else {from = middle; fromX = middleX;} + } + } + + function localCoords(pos, inLineWrap) { + var lh = lineHeight(), line = pos.line - (inLineWrap ? showingFrom : 0); + return {x: charX(pos.line, pos.ch), y: line * lh, yBot: (line + 1) * lh}; + } + function pageCoords(pos) { + var local = localCoords(pos, true), off = eltOffset(lineSpace); + return {x: off.left + local.x, y: off.top + local.y, yBot: off.top + local.yBot}; + } + + function lineHeight() { + var nlines = lineDiv.childNodes.length; + if (nlines) return (lineDiv.offsetHeight / nlines) || 1; + measure.innerHTML = "
x
"; + return measure.firstChild.offsetHeight || 1; + } + function paddingTop() {return lineSpace.offsetTop;} + function paddingLeft() {return lineSpace.offsetLeft;} + + function posFromMouse(e, liberal) { + var offW = eltOffset(scroller, true), x, y; + // Fails unpredictably on IE[67] when mouse is dragged around quickly. + try { x = e.clientX; y = e.clientY; } catch (e) { return null; } + // This is a mess of a heuristic to try and determine whether a + // scroll-bar was clicked or not, and to return null if one was + // (and !liberal). + if (!liberal && (x - offW.left > scroller.clientWidth || y - offW.top > scroller.clientHeight)) + return null; + var offL = eltOffset(lineSpace, true); + var line = showingFrom + Math.floor((y - offL.top) / lineHeight()); + return clipPos({line: line, ch: charFromX(clipLine(line), x - offL.left)}); + } + function onContextMenu(e) { + var pos = posFromMouse(e); + if (!pos || window.opera) return; // Opera is difficult. + if (posEq(sel.from, sel.to) || posLess(pos, sel.from) || !posLess(pos, sel.to)) + operation(setCursor)(pos.line, pos.ch); + + var oldCSS = input.style.cssText; + inputDiv.style.position = "absolute"; + input.style.cssText = "position: fixed; width: 30px; height: 30px; top: " + (e_pageY(e) - 1) + + "px; left: " + (e_pageX(e) - 1) + "px; z-index: 1000; background: white; " + + "border-width: 0; outline: none; overflow: hidden; opacity: .05; filter: alpha(opacity=5);"; + leaveInputAlone = true; + var val = input.value = getSelection(); + focusInput(); + setSelRange(input, 0, input.value.length); + function rehide() { + var newVal = splitLines(input.value).join("\n"); + if (newVal != val) operation(replaceSelection)(newVal, "end"); + inputDiv.style.position = "relative"; + input.style.cssText = oldCSS; + leaveInputAlone = false; + prepareInput(); + slowPoll(); + } + + if (gecko) { + e_stop(e); + var mouseup = connect(window, "mouseup", function() { + mouseup(); + setTimeout(rehide, 20); + }, true); + } + else { + setTimeout(rehide, 50); + } + } + + // Cursor-blinking + function restartBlink() { + clearInterval(blinker); + var on = true; + cursor.style.visibility = ""; + blinker = setInterval(function() { + cursor.style.visibility = (on = !on) ? "" : "hidden"; + }, 650); + } + + var matching = {"(": ")>", ")": "(<", "[": "]>", "]": "[<", "{": "}>", "}": "{<"}; + function matchBrackets(autoclear) { + var head = sel.inverted ? sel.from : sel.to, line = lines[head.line], pos = head.ch - 1; + var match = (pos >= 0 && matching[line.text.charAt(pos)]) || matching[line.text.charAt(++pos)]; + if (!match) return; + var ch = match.charAt(0), forward = match.charAt(1) == ">", d = forward ? 1 : -1, st = line.styles; + for (var off = pos + 1, i = 0, e = st.length; i < e; i+=2) + if ((off -= st[i].length) <= 0) {var style = st[i+1]; break;} + + var stack = [line.text.charAt(pos)], re = /[(){}[\]]/; + function scan(line, from, to) { + if (!line.text) return; + var st = line.styles, pos = forward ? 0 : line.text.length - 1, cur; + for (var i = forward ? 0 : st.length - 2, e = forward ? st.length : -2; i != e; i += 2*d) { + var text = st[i]; + if (st[i+1] != null && st[i+1] != style) {pos += d * text.length; continue;} + for (var j = forward ? 0 : text.length - 1, te = forward ? text.length : -1; j != te; j += d, pos+=d) { + if (pos >= from && pos < to && re.test(cur = text.charAt(j))) { + var match = matching[cur]; + if (match.charAt(1) == ">" == forward) stack.push(cur); + else if (stack.pop() != match.charAt(0)) return {pos: pos, match: false}; + else if (!stack.length) return {pos: pos, match: true}; + } + } + } + } + for (var i = head.line, e = forward ? Math.min(i + 100, lines.length) : Math.max(-1, i - 100); i != e; i+=d) { + var line = lines[i], first = i == head.line; + var found = scan(line, first && forward ? pos + 1 : 0, first && !forward ? pos : line.text.length); + if (found) break; + } + if (!found) found = {pos: null, match: false}; + var style = found.match ? "CodeMirror-matchingbracket" : "CodeMirror-nonmatchingbracket"; + var one = markText({line: head.line, ch: pos}, {line: head.line, ch: pos+1}, style), + two = found.pos != null + ? markText({line: i, ch: found.pos}, {line: i, ch: found.pos + 1}, style) + : function() {}; + var clear = operation(function(){one(); two();}); + if (autoclear) setTimeout(clear, 800); + else bracketHighlighted = clear; + } + + // Finds the line to start with when starting a parse. Tries to + // find a line with a stateAfter, so that it can start with a + // valid state. If that fails, it returns the line with the + // smallest indentation, which tends to need the least context to + // parse correctly. + function findStartLine(n) { + var minindent, minline; + for (var search = n, lim = n - 40; search > lim; --search) { + if (search == 0) return 0; + var line = lines[search-1]; + if (line.stateAfter) return search; + var indented = line.indentation(); + if (minline == null || minindent > indented) { + minline = search; + minindent = indented; + } + } + return minline; + } + function getStateBefore(n) { + var start = findStartLine(n), state = start && lines[start-1].stateAfter; + if (!state) state = startState(mode); + else state = copyState(mode, state); + for (var i = start; i < n; ++i) { + var line = lines[i]; + line.highlight(mode, state); + line.stateAfter = copyState(mode, state); + } + if (n < lines.length && !lines[n].stateAfter) work.push(n); + return state; + } + function highlightLines(start, end) { + var state = getStateBefore(start); + for (var i = start; i < end; ++i) { + var line = lines[i]; + line.highlight(mode, state); + line.stateAfter = copyState(mode, state); + } + } + function highlightWorker() { + var end = +new Date + options.workTime; + var foundWork = work.length; + while (work.length) { + if (!lines[showingFrom].stateAfter) var task = showingFrom; + else var task = work.pop(); + if (task >= lines.length) continue; + var start = findStartLine(task), state = start && lines[start-1].stateAfter; + if (state) state = copyState(mode, state); + else state = startState(mode); + + var unchanged = 0, compare = mode.compareStates; + for (var i = start, l = lines.length; i < l; ++i) { + var line = lines[i], hadState = line.stateAfter; + if (+new Date > end) { + work.push(i); + startWorker(options.workDelay); + changes.push({from: task, to: i + 1}); + return; + } + var changed = line.highlight(mode, state); + line.stateAfter = copyState(mode, state); + if (compare) { + if (hadState && compare(hadState, state)) break; + } else { + if (changed || !hadState) unchanged = 0; + else if (++unchanged > 3) break; + } + } + changes.push({from: task, to: i + 1}); + } + if (foundWork && options.onHighlightComplete) + options.onHighlightComplete(instance); + } + function startWorker(time) { + if (!work.length) return; + highlight.set(time, operation(highlightWorker)); + } + + // Operations are used to wrap changes in such a way that each + // change won't have to update the cursor and display (which would + // be awkward, slow, and error-prone), but instead updates are + // batched and then all combined and executed at once. + function startOperation() { + updateInput = null; changes = []; textChanged = selectionChanged = false; + } + function endOperation() { + var reScroll = false; + if (selectionChanged) reScroll = !scrollCursorIntoView(); + if (changes.length) updateDisplay(changes); + else if (selectionChanged) updateCursor(); + if (reScroll) scrollCursorIntoView(); + if (selectionChanged) restartBlink(); + + // updateInput can be set to a boolean value to force/prevent an + // update. + if (focused && !leaveInputAlone && + (updateInput === true || (updateInput !== false && selectionChanged))) + prepareInput(); + + if (selectionChanged && options.matchBrackets) + setTimeout(operation(function() { + if (bracketHighlighted) {bracketHighlighted(); bracketHighlighted = null;} + matchBrackets(false); + }), 20); + var tc = textChanged; // textChanged can be reset by cursoractivity callback + if (selectionChanged && options.onCursorActivity) + options.onCursorActivity(instance); + if (tc && options.onChange && instance) + options.onChange(instance, tc); + } + var nestedOperation = 0; + function operation(f) { + return function() { + if (!nestedOperation++) startOperation(); + try {var result = f.apply(this, arguments);} + finally {if (!--nestedOperation) endOperation();} + return result; + }; + } + + function SearchCursor(query, pos, caseFold) { + this.atOccurrence = false; + if (caseFold == null) caseFold = typeof query == "string" && query == query.toLowerCase(); + + if (pos && typeof pos == "object") pos = clipPos(pos); + else pos = {line: 0, ch: 0}; + this.pos = {from: pos, to: pos}; + + // The matches method is filled in based on the type of query. + // It takes a position and a direction, and returns an object + // describing the next occurrence of the query, or null if no + // more matches were found. + if (typeof query != "string") // Regexp match + this.matches = function(reverse, pos) { + if (reverse) { + var line = lines[pos.line].text.slice(0, pos.ch), match = line.match(query), start = 0; + while (match) { + var ind = line.indexOf(match[0]); + start += ind; + line = line.slice(ind + 1); + var newmatch = line.match(query); + if (newmatch) match = newmatch; + else break; + start++; + } + } + else { + var line = lines[pos.line].text.slice(pos.ch), match = line.match(query), + start = match && pos.ch + line.indexOf(match[0]); + } + if (match) + return {from: {line: pos.line, ch: start}, + to: {line: pos.line, ch: start + match[0].length}, + match: match}; + }; + else { // String query + if (caseFold) query = query.toLowerCase(); + var fold = caseFold ? function(str){return str.toLowerCase();} : function(str){return str;}; + var target = query.split("\n"); + // Different methods for single-line and multi-line queries + if (target.length == 1) + this.matches = function(reverse, pos) { + var line = fold(lines[pos.line].text), len = query.length, match; + if (reverse ? (pos.ch >= len && (match = line.lastIndexOf(query, pos.ch - len)) != -1) + : (match = line.indexOf(query, pos.ch)) != -1) + return {from: {line: pos.line, ch: match}, + to: {line: pos.line, ch: match + len}}; + }; + else + this.matches = function(reverse, pos) { + var ln = pos.line, idx = (reverse ? target.length - 1 : 0), match = target[idx], line = fold(lines[ln].text); + var offsetA = (reverse ? line.indexOf(match) + match.length : line.lastIndexOf(match)); + if (reverse ? offsetA >= pos.ch || offsetA != match.length + : offsetA <= pos.ch || offsetA != line.length - match.length) + return; + for (;;) { + if (reverse ? !ln : ln == lines.length - 1) return; + line = fold(lines[ln += reverse ? -1 : 1].text); + match = target[reverse ? --idx : ++idx]; + if (idx > 0 && idx < target.length - 1) { + if (line != match) return; + else continue; + } + var offsetB = (reverse ? line.lastIndexOf(match) : line.indexOf(match) + match.length); + if (reverse ? offsetB != line.length - match.length : offsetB != match.length) + return; + var start = {line: pos.line, ch: offsetA}, end = {line: ln, ch: offsetB}; + return {from: reverse ? end : start, to: reverse ? start : end}; + } + }; + } + } + + SearchCursor.prototype = { + findNext: function() {return this.find(false);}, + findPrevious: function() {return this.find(true);}, + + find: function(reverse) { + var self = this, pos = clipPos(reverse ? this.pos.from : this.pos.to); + function savePosAndFail(line) { + var pos = {line: line, ch: 0}; + self.pos = {from: pos, to: pos}; + self.atOccurrence = false; + return false; + } + + for (;;) { + if (this.pos = this.matches(reverse, pos)) { + this.atOccurrence = true; + return this.pos.match || true; + } + if (reverse) { + if (!pos.line) return savePosAndFail(0); + pos = {line: pos.line-1, ch: lines[pos.line-1].text.length}; + } + else { + if (pos.line == lines.length - 1) return savePosAndFail(lines.length); + pos = {line: pos.line+1, ch: 0}; + } + } + }, + + from: function() {if (this.atOccurrence) return copyPos(this.pos.from);}, + to: function() {if (this.atOccurrence) return copyPos(this.pos.to);}, + + replace: function(newText) { + var self = this; + if (this.atOccurrence) + operation(function() { + self.pos.to = replaceRange(newText, self.pos.from, self.pos.to); + })(); + } + }; + + for (var ext in extensions) + if (extensions.propertyIsEnumerable(ext) && + !instance.propertyIsEnumerable(ext)) + instance[ext] = extensions[ext]; + return instance; + } // (end of function CodeMirror) + + // The default configuration options. + CodeMirror.defaults = { + value: "", + mode: null, + theme: "default", + indentUnit: 2, + indentWithTabs: false, + tabMode: "classic", + enterMode: "indent", + electricChars: true, + onKeyEvent: null, + lineNumbers: false, + gutter: false, + firstLineNumber: 1, + readOnly: false, + onChange: null, + onCursorActivity: null, + onGutterClick: null, + onHighlightComplete: null, + onFocus: null, onBlur: null, onScroll: null, + matchBrackets: false, + workTime: 100, + workDelay: 200, + undoDepth: 40, + tabindex: null, + document: window.document + }; + + // Known modes, by name and by MIME + var modes = {}, mimeModes = {}; + CodeMirror.defineMode = function(name, mode) { + if (!CodeMirror.defaults.mode && name != "null") CodeMirror.defaults.mode = name; + modes[name] = mode; + }; + CodeMirror.defineMIME = function(mime, spec) { + mimeModes[mime] = spec; + }; + CodeMirror.getMode = function(options, spec) { + if (typeof spec == "string" && mimeModes.hasOwnProperty(spec)) + spec = mimeModes[spec]; + if (typeof spec == "string") + var mname = spec, config = {}; + else if (spec != null) + var mname = spec.name, config = spec; + var mfactory = modes[mname]; + if (!mfactory) { + if (window.console) console.warn("No mode " + mname + " found, falling back to plain text."); + return CodeMirror.getMode(options, "text/plain"); + } + return mfactory(options, config || {}); + }; + CodeMirror.listModes = function() { + var list = []; + for (var m in modes) + if (modes.propertyIsEnumerable(m)) list.push(m); + return list; + }; + CodeMirror.listMIMEs = function() { + var list = []; + for (var m in mimeModes) + if (mimeModes.propertyIsEnumerable(m)) list.push(m); + return list; + }; + + var extensions = {}; + CodeMirror.defineExtension = function(name, func) { + extensions[name] = func; + }; + + CodeMirror.fromTextArea = function(textarea, options) { + if (!options) options = {}; + options.value = textarea.value; + if (!options.tabindex && textarea.tabindex) + options.tabindex = textarea.tabindex; + + function save() {textarea.value = instance.getValue();} + if (textarea.form) { + // Deplorable hack to make the submit method do the right thing. + var rmSubmit = connect(textarea.form, "submit", save, true); + if (typeof textarea.form.submit == "function") { + var realSubmit = textarea.form.submit; + function wrappedSubmit() { + save(); + textarea.form.submit = realSubmit; + textarea.form.submit(); + textarea.form.submit = wrappedSubmit; + } + textarea.form.submit = wrappedSubmit; + } + } + + textarea.style.display = "none"; + var instance = CodeMirror(function(node) { + textarea.parentNode.insertBefore(node, textarea.nextSibling); + }, options); + instance.save = save; + instance.toTextArea = function() { + save(); + textarea.parentNode.removeChild(instance.getWrapperElement()); + textarea.style.display = ""; + if (textarea.form) { + rmSubmit(); + if (typeof textarea.form.submit == "function") + textarea.form.submit = realSubmit; + } + }; + return instance; + }; + + // Utility functions for working with state. Exported because modes + // sometimes need to do this. + function copyState(mode, state) { + if (state === true) return state; + if (mode.copyState) return mode.copyState(state); + var nstate = {}; + for (var n in state) { + var val = state[n]; + if (val instanceof Array) val = val.concat([]); + nstate[n] = val; + } + return nstate; + } + CodeMirror.startState = startState; + function startState(mode, a1, a2) { + return mode.startState ? mode.startState(a1, a2) : true; + } + CodeMirror.copyState = copyState; + + // The character stream used by a mode's parser. + function StringStream(string) { + this.pos = this.start = 0; + this.string = string; + } + StringStream.prototype = { + eol: function() {return this.pos >= this.string.length;}, + sol: function() {return this.pos == 0;}, + peek: function() {return this.string.charAt(this.pos);}, + next: function() { + if (this.pos < this.string.length) + return this.string.charAt(this.pos++); + }, + eat: function(match) { + var ch = this.string.charAt(this.pos); + if (typeof match == "string") var ok = ch == match; + else var ok = ch && (match.test ? match.test(ch) : match(ch)); + if (ok) {++this.pos; return ch;} + }, + eatWhile: function(match) { + var start = this.start; + while (this.eat(match)){} + return this.pos > start; + }, + eatSpace: function() { + var start = this.pos; + while (/[\s\u00a0]/.test(this.string.charAt(this.pos))) ++this.pos; + return this.pos > start; + }, + skipToEnd: function() {this.pos = this.string.length;}, + skipTo: function(ch) { + var found = this.string.indexOf(ch, this.pos); + if (found > -1) {this.pos = found; return true;} + }, + backUp: function(n) {this.pos -= n;}, + column: function() {return countColumn(this.string, this.start);}, + indentation: function() {return countColumn(this.string);}, + match: function(pattern, consume, caseInsensitive) { + if (typeof pattern == "string") { + function cased(str) {return caseInsensitive ? str.toLowerCase() : str;} + if (cased(this.string).indexOf(cased(pattern), this.pos) == this.pos) { + if (consume !== false) this.pos += pattern.length; + return true; + } + } + else { + var match = this.string.slice(this.pos).match(pattern); + if (match && consume !== false) this.pos += match[0].length; + return match; + } + }, + current: function(){return this.string.slice(this.start, this.pos);} + }; + CodeMirror.StringStream = StringStream; + + // Line objects. These hold state related to a line, including + // highlighting info (the styles array). + function Line(text, styles) { + this.styles = styles || [text, null]; + this.stateAfter = null; + this.text = text; + this.marked = this.gutterMarker = this.className = null; + } + Line.prototype = { + // Replace a piece of a line, keeping the styles around it intact. + replace: function(from, to, text) { + var st = [], mk = this.marked; + copyStyles(0, from, this.styles, st); + if (text) st.push(text, null); + copyStyles(to, this.text.length, this.styles, st); + this.styles = st; + this.text = this.text.slice(0, from) + text + this.text.slice(to); + this.stateAfter = null; + if (mk) { + var diff = text.length - (to - from), end = this.text.length; + function fix(n) {return n <= Math.min(to, to + diff) ? n : n + diff;} + for (var i = 0; i < mk.length; ++i) { + var mark = mk[i], del = false; + if (mark.from >= end) del = true; + else {mark.from = fix(mark.from); if (mark.to != null) mark.to = fix(mark.to);} + if (del || mark.from >= mark.to) {mk.splice(i, 1); i--;} + } + } + }, + // Split a line in two, again keeping styles intact. + split: function(pos, textBefore) { + var st = [textBefore, null]; + copyStyles(pos, this.text.length, this.styles, st); + return new Line(textBefore + this.text.slice(pos), st); + }, + addMark: function(from, to, style) { + var mk = this.marked, mark = {from: from, to: to, style: style}; + if (this.marked == null) this.marked = []; + this.marked.push(mark); + this.marked.sort(function(a, b){return a.from - b.from;}); + return mark; + }, + removeMark: function(mark) { + var mk = this.marked; + if (!mk) return; + for (var i = 0; i < mk.length; ++i) + if (mk[i] == mark) {mk.splice(i, 1); break;} + }, + // Run the given mode's parser over a line, update the styles + // array, which contains alternating fragments of text and CSS + // classes. + highlight: function(mode, state) { + var stream = new StringStream(this.text), st = this.styles, pos = 0; + var changed = false, curWord = st[0], prevWord; + if (this.text == "" && mode.blankLine) mode.blankLine(state); + while (!stream.eol()) { + var style = mode.token(stream, state); + var substr = this.text.slice(stream.start, stream.pos); + stream.start = stream.pos; + if (pos && st[pos-1] == style) + st[pos-2] += substr; + else if (substr) { + if (!changed && (st[pos+1] != style || (pos && st[pos-2] != prevWord))) changed = true; + st[pos++] = substr; st[pos++] = style; + prevWord = curWord; curWord = st[pos]; + } + // Give up when line is ridiculously long + if (stream.pos > 5000) { + st[pos++] = this.text.slice(stream.pos); st[pos++] = null; + break; + } + } + if (st.length != pos) {st.length = pos; changed = true;} + if (pos && st[pos-2] != prevWord) changed = true; + // Short lines with simple highlights always count as changed, + // because they are likely to highlight the same way in various + // contexts. + return changed || (st.length < 5 && this.text.length < 10); + }, + // Fetch the parser token for a given character. Useful for hacks + // that want to inspect the mode state (say, for completion). + getTokenAt: function(mode, state, ch) { + var txt = this.text, stream = new StringStream(txt); + while (stream.pos < ch && !stream.eol()) { + stream.start = stream.pos; + var style = mode.token(stream, state); + } + return {start: stream.start, + end: stream.pos, + string: stream.current(), + className: style || null, + state: state}; + }, + indentation: function() {return countColumn(this.text);}, + // Produces an HTML fragment for the line, taking selection, + // marking, and highlighting into account. + getHTML: function(sfrom, sto, includePre, endAt) { + var html = []; + if (includePre) + html.push(this.className ? '
': "
");
+      function span(text, style) {
+        if (!text) return;
+        if (style) html.push('', htmlEscape(text), "");
+        else html.push(htmlEscape(text));
+      }
+      var st = this.styles, allText = this.text, marked = this.marked;
+      if (sfrom == sto) sfrom = null;
+      var len = allText.length;
+      if (endAt != null) len = Math.min(endAt, len);
+
+      if (!allText && endAt == null)
+        span(" ", sfrom != null && sto == null ? "CodeMirror-selected" : null);
+      else if (!marked && sfrom == null)
+        for (var i = 0, ch = 0; ch < len; i+=2) {
+          var str = st[i], l = str.length;
+          if (ch + l > len) str = str.slice(0, len - ch);
+          ch += l;
+          span(str, "cm-" + st[i+1]);
+        }
+      else {
+        var pos = 0, i = 0, text = "", style, sg = 0;
+        var markpos = -1, mark = null;
+        function nextMark() {
+          if (marked) {
+            markpos += 1;
+            mark = (markpos < marked.length) ? marked[markpos] : null;
+          }
+        }
+        nextMark();
+        while (pos < len) {
+          var upto = len;
+          var extraStyle = "";
+          if (sfrom != null) {
+            if (sfrom > pos) upto = sfrom;
+            else if (sto == null || sto > pos) {
+              extraStyle = " CodeMirror-selected";
+              if (sto != null) upto = Math.min(upto, sto);
+            }
+          }
+          while (mark && mark.to != null && mark.to <= pos) nextMark();
+          if (mark) {
+            if (mark.from > pos) upto = Math.min(upto, mark.from);
+            else {
+              extraStyle += " " + mark.style;
+              if (mark.to != null) upto = Math.min(upto, mark.to);
+            }
+          }
+          for (;;) {
+            var end = pos + text.length;
+            var appliedStyle = style;
+            if (extraStyle) appliedStyle = style ? style + extraStyle : extraStyle;
+            span(end > upto ? text.slice(0, upto - pos) : text, appliedStyle);
+            if (end >= upto) {text = text.slice(upto - pos); pos = upto; break;}
+            pos = end;
+            text = st[i++]; style = "cm-" + st[i++];
+          }
+        }
+        if (sfrom != null && sto == null) span(" ", "CodeMirror-selected");
+      }
+      if (includePre) html.push("
"); + return html.join(""); + } + }; + // Utility used by replace and split above + function copyStyles(from, to, source, dest) { + for (var i = 0, pos = 0, state = 0; pos < to; i+=2) { + var part = source[i], end = pos + part.length; + if (state == 0) { + if (end > from) dest.push(part.slice(from - pos, Math.min(part.length, to - pos)), source[i+1]); + if (end >= from) state = 1; + } + else if (state == 1) { + if (end > to) dest.push(part.slice(0, to - pos), source[i+1]); + else dest.push(part, source[i+1]); + } + pos = end; + } + } + + // The history object 'chunks' changes that are made close together + // and at almost the same time into bigger undoable units. + function History() { + this.time = 0; + this.done = []; this.undone = []; + } + History.prototype = { + addChange: function(start, added, old) { + this.undone.length = 0; + var time = +new Date, last = this.done[this.done.length - 1]; + if (time - this.time > 400 || !last || + last.start > start + added || last.start + last.added < start - last.added + last.old.length) + this.done.push({start: start, added: added, old: old}); + else { + var oldoff = 0; + if (start < last.start) { + for (var i = last.start - start - 1; i >= 0; --i) + last.old.unshift(old[i]); + last.added += last.start - start; + last.start = start; + } + else if (last.start < start) { + oldoff = start - last.start; + added += oldoff; + } + for (var i = last.added - oldoff, e = old.length; i < e; ++i) + last.old.push(old[i]); + if (last.added < added) last.added = added; + } + this.time = time; + } + }; + + function stopMethod() {e_stop(this);} + // Ensure an event has a stop method. + function addStop(event) { + if (!event.stop) event.stop = stopMethod; + return event; + } + + function e_preventDefault(e) { + if (e.preventDefault) e.preventDefault(); + else e.returnValue = false; + } + function e_stopPropagation(e) { + if (e.stopPropagation) e.stopPropagation(); + else e.cancelBubble = true; + } + function e_stop(e) {e_preventDefault(e); e_stopPropagation(e);} + function e_target(e) {return e.target || e.srcElement;} + function e_button(e) { + if (e.which) return e.which; + else if (e.button & 1) return 1; + else if (e.button & 2) return 3; + else if (e.button & 4) return 2; + } + function e_pageX(e) { + if (e.pageX != null) return e.pageX; + var doc = e_target(e).ownerDocument; + return e.clientX + doc.body.scrollLeft + doc.documentElement.scrollLeft; + } + function e_pageY(e) { + if (e.pageY != null) return e.pageY; + var doc = e_target(e).ownerDocument; + return e.clientY + doc.body.scrollTop + doc.documentElement.scrollTop; + } + + // Event handler registration. If disconnect is true, it'll return a + // function that unregisters the handler. + function connect(node, type, handler, disconnect) { + function wrapHandler(event) {handler(event || window.event);} + if (typeof node.addEventListener == "function") { + node.addEventListener(type, wrapHandler, false); + if (disconnect) return function() {node.removeEventListener(type, wrapHandler, false);}; + } + else { + node.attachEvent("on" + type, wrapHandler); + if (disconnect) return function() {node.detachEvent("on" + type, wrapHandler);}; + } + } + + function Delayed() {this.id = null;} + Delayed.prototype = {set: function(ms, f) {clearTimeout(this.id); this.id = setTimeout(f, ms);}}; + + // Some IE versions don't preserve whitespace when setting the + // innerHTML of a PRE tag. + var badInnerHTML = (function() { + var pre = document.createElement("pre"); + pre.innerHTML = " "; return !pre.innerHTML; + })(); + + var gecko = /gecko\/\d{7}/i.test(navigator.userAgent); + var ie = /MSIE \d/.test(navigator.userAgent); + var safari = /Apple Computer/.test(navigator.vendor); + + var lineSep = "\n"; + // Feature-detect whether newlines in textareas are converted to \r\n + (function () { + var te = document.createElement("textarea"); + te.value = "foo\nbar"; + if (te.value.indexOf("\r") > -1) lineSep = "\r\n"; + }()); + + var tabSize = 8; + var mac = /Mac/.test(navigator.platform); + var movementKeys = {}; + for (var i = 35; i <= 40; ++i) + movementKeys[i] = movementKeys["c" + i] = true; + + // Counts the column offset in a string, taking tabs into account. + // Used mostly to find indentation. + function countColumn(string, end) { + if (end == null) { + end = string.search(/[^\s\u00a0]/); + if (end == -1) end = string.length; + } + for (var i = 0, n = 0; i < end; ++i) { + if (string.charAt(i) == "\t") n += tabSize - (n % tabSize); + else ++n; + } + return n; + } + + function computedStyle(elt) { + if (elt.currentStyle) return elt.currentStyle; + return window.getComputedStyle(elt, null); + } + // Find the position of an element by following the offsetParent chain. + // If screen==true, it returns screen (rather than page) coordinates. + function eltOffset(node, screen) { + var doc = node.ownerDocument.body; + var x = 0, y = 0, skipDoc = false; + for (var n = node; n; n = n.offsetParent) { + x += n.offsetLeft; y += n.offsetTop; + if (screen && computedStyle(n).position == "fixed") + skipDoc = true; + } + var e = screen && !skipDoc ? null : doc; + for (var n = node.parentNode; n != e; n = n.parentNode) + if (n.scrollLeft != null) { x -= n.scrollLeft; y -= n.scrollTop;} + return {left: x, top: y}; + } + // Get a node's text content. + function eltText(node) { + return node.textContent || node.innerText || node.nodeValue || ""; + } + + // Operations on {line, ch} objects. + function posEq(a, b) {return a.line == b.line && a.ch == b.ch;} + function posLess(a, b) {return a.line < b.line || (a.line == b.line && a.ch < b.ch);} + function copyPos(x) {return {line: x.line, ch: x.ch};} + + var escapeElement = document.createElement("div"); + function htmlEscape(str) { + escapeElement.innerText = escapeElement.textContent = str; + return escapeElement.innerHTML; + } + CodeMirror.htmlEscape = htmlEscape; + + // Used to position the cursor after an undo/redo by finding the + // last edited character. + function editEnd(from, to) { + if (!to) return from ? from.length : 0; + if (!from) return to.length; + for (var i = from.length, j = to.length; i >= 0 && j >= 0; --i, --j) + if (from.charAt(i) != to.charAt(j)) break; + return j + 1; + } + + function indexOf(collection, elt) { + if (collection.indexOf) return collection.indexOf(elt); + for (var i = 0, e = collection.length; i < e; ++i) + if (collection[i] == elt) return i; + return -1; + } + + // See if "".split is the broken IE version, if so, provide an + // alternative way to split lines. + var splitLines, selRange, setSelRange; + if ("\n\nb".split(/\n/).length != 3) + splitLines = function(string) { + var pos = 0, nl, result = []; + while ((nl = string.indexOf("\n", pos)) > -1) { + result.push(string.slice(pos, string.charAt(nl-1) == "\r" ? nl - 1 : nl)); + pos = nl + 1; + } + result.push(string.slice(pos)); + return result; + }; + else + splitLines = function(string){return string.split(/\r?\n/);}; + CodeMirror.splitLines = splitLines; + + // Sane model of finding and setting the selection in a textarea + if (window.getSelection) { + selRange = function(te) { + try {return {start: te.selectionStart, end: te.selectionEnd};} + catch(e) {return null;} + }; + if (safari) + // On Safari, selection set with setSelectionRange are in a sort + // of limbo wrt their anchor. If you press shift-left in them, + // the anchor is put at the end, and the selection expanded to + // the left. If you press shift-right, the anchor ends up at the + // front. This is not what CodeMirror wants, so it does a + // spurious modify() call to get out of limbo. + setSelRange = function(te, start, end) { + if (start == end) + te.setSelectionRange(start, end); + else { + te.setSelectionRange(start, end - 1); + window.getSelection().modify("extend", "forward", "character"); + } + }; + else + setSelRange = function(te, start, end) { + try {te.setSelectionRange(start, end);} + catch(e) {} // Fails on Firefox when textarea isn't part of the document + }; + } + // IE model. Don't ask. + else { + selRange = function(te) { + try {var range = te.ownerDocument.selection.createRange();} + catch(e) {return null;} + if (!range || range.parentElement() != te) return null; + var val = te.value, len = val.length, localRange = te.createTextRange(); + localRange.moveToBookmark(range.getBookmark()); + var endRange = te.createTextRange(); + endRange.collapse(false); + + if (localRange.compareEndPoints("StartToEnd", endRange) > -1) + return {start: len, end: len}; + + var start = -localRange.moveStart("character", -len); + for (var i = val.indexOf("\r"); i > -1 && i < start; i = val.indexOf("\r", i+1), start++) {} + + if (localRange.compareEndPoints("EndToEnd", endRange) > -1) + return {start: start, end: len}; + + var end = -localRange.moveEnd("character", -len); + for (var i = val.indexOf("\r"); i > -1 && i < end; i = val.indexOf("\r", i+1), end++) {} + return {start: start, end: end}; + }; + setSelRange = function(te, start, end) { + var range = te.createTextRange(); + range.collapse(true); + var endrange = range.duplicate(); + var newlines = 0, txt = te.value; + for (var pos = txt.indexOf("\n"); pos > -1 && pos < start; pos = txt.indexOf("\n", pos + 1)) + ++newlines; + range.move("character", start - newlines); + for (; pos > -1 && pos < end; pos = txt.indexOf("\n", pos + 1)) + ++newlines; + endrange.move("character", end - newlines); + range.setEndPoint("EndToEnd", endrange); + range.select(); + }; + } + + CodeMirror.defineMode("null", function() { + return {token: function(stream) {stream.skipToEnd();}}; + }); + CodeMirror.defineMIME("text/plain", "null"); + + return CodeMirror; +})() +; \ No newline at end of file diff --git a/htdocs/codemirror2/lib/codeshard.css b/htdocs/codemirror2/lib/codeshard.css new file mode 100644 index 000000000..4b50bff2e --- /dev/null +++ b/htdocs/codemirror2/lib/codeshard.css @@ -0,0 +1,76 @@ +span.CodeShard { + overflow: hidden; + height: 30px; + line-height: 1em; + font-family: monospace; + margin: 0; + padding: 0; + position: relative; + + width: 200px; + min-height: 30px; + display: -moz-inline-stack; + display: inline-block; + vertical-align: top; + zoom: 1; + *display: inline; + _height: 250px; +} + +span.CodeShard-gutter { + position: absolute; left: 0; top: 0; + background-color: #f7faaa; + border-right: 1px solid #eee; + min-width: 1em; + height: 100%; +} +span.CodeMirror-gutter-text { + color: #aaa; + text-align: right; + padding: .4em .2em .4em .4em; +} + +span.CodeShard-lines { + padding: .4em; +} + +span.dmover span.CodeShard-lines { + background: #eee; +} + +span.CodeShard span.dcode { + -moz-border-radius: 1; + -webkit-border-radius: 1; + -o-border-radius: 1; + height: 30px; + border-radius: 1; + border-width: 1; margin: 0; padding: 0; + /*background: transparent;*/ + font-family: inherit; + position: relative; +} + +span.CodeShard { + font-family: monospace !important; +} + +span.CodeShard-cursor { + z-index: 10; + position: absolute; + visibility: hidden; + border-left: 1px solid black !important; +} +span.CodeShard-focused span.CodeShard-cursor { + visibility: visible; +} + +span.CodeShard-selected { + background: #ccc !important; + color: HighlightText !important; +} +span.CodeShard-focused span.CodeShard-selected { + background: Highlight !important; +} + +span.CodeShard-matchingbracket {color: #0f0 !important;} +span.CodeShard-nonmatchingbracket {color: #f22 !important;} diff --git a/htdocs/codemirror2/lib/codeshard.js b/htdocs/codemirror2/lib/codeshard.js new file mode 100644 index 000000000..a65545faf --- /dev/null +++ b/htdocs/codemirror2/lib/codeshard.js @@ -0,0 +1,2050 @@ +// All functions that need access to the editor's state live inside +// the CodeShard function. Below that, at the bottom of the file, +// some utilities are defined. + +// CodeShard is the only global var we claim +var CodeShard = (function() { + // This is the function that produces an editor instance. It's + // closure is used to store the editor state. + function CodeShard(place, givenOptions) { + // Determine effective options based on given values and defaults. + var options = {}, defaults = CodeShard.defaults; + for (var opt in defaults) + if (defaults.hasOwnProperty(opt)) + options[opt] = (givenOptions && givenOptions.hasOwnProperty(opt) ? givenOptions : defaults)[opt]; + + // The element in which the editor lives. Takes care of scrolling + // (if enabled). + + var debugconsole = document.getElementById("debugconsole"); + + var reporter = {}; + + function makeReporter(reportername) { + reporter[reportername] = document.createElement("div"); + reporter[reportername].style.float = "left"; + reporter[reportername].style.clear = "both"; + reporter[reportername].style.border = "1px solid #ddd"; + var reporter_label = document.createElement("span"); + reporter[reportername].appendChild(reporter_label); + var reporter_field = document.createElement("span"); + reporter[reportername].appendChild(reporter_field); + reporter_label.innerHTML = reportername + ": "; + debugconsole.appendChild(reporter[reportername]); + function report(val) { + reporter_field.innerHTML = val; + } + return report; + } + + spanw_r = makeReporter('spanw'); + childw_r = makeReporter('childw'); + childtext_r = makeReporter('childtext'); + posx_r = makeReporter('posx'); + + var wrapper = document.createElement("span"); + + wrapper.style.display = "inline-block"; + wrapper.style.width = "200px"; + + wrapper.className = "CodeShard"; + // Work around http://www.quirksmode.org/bugreports/archives/2006/09/Overflow_Hidden_not_hiding.html + if (window.ActiveXObject && /MSIE [1-7][\b\.]/.test(navigator.userAgent)) + wrapper.style.position = "relative"; + // This mess creates the base DOM structure for the editor. + wrapper.innerHTML = + '' + // Set to the height of the text, causes scrolling + ''+ + '
'+ + '' + // Moved around its parent to cover visible view + '' + + '' + // Wraps and hides input textarea + '' + + // Provides positioning relative to (visible) text origin + '' + + ' ' + // Absolutely positioned blinky cursor + ''+ // This SPAN contains the actual code + '
'; + if (place.appendChild) place.appendChild(wrapper); else place(wrapper); + // I've never seen more elegant code in my life. + var code = wrapper.firstChild, + measure = code.firstChild.firstChild, + mover = code.firstChild.nextSibling, + gutter = mover.firstChild, + gutterText = gutter.firstChild, + inputSpan = gutter.nextSibling, + input = inputSpan.firstChild, + lineSpace = inputSpan.nextSibling.firstChild, + cursor = lineSpace.firstChild, + lineSpan = cursor.nextSibling; + if (options.tabindex != null) input.tabindex = options.tabindex; + if (!options.gutter && !options.lineNumbers) gutter.style.display = "none"; + + // Delayed object wrap timeouts, making sure only one is active. blinker holds an interval. + var poll = new Delayed(), highlight = new Delayed(), blinker; + + // mode holds a mode API object. lines an array of Line objects + // (see Line constructor), work an array of lines that should be + // parsed, and history the undo history (instance of History + // constructor). + var mode, lines = [new Line("")], work, history = new History(), focused; + loadMode(); + // The selection. These are always maintained to point at valid + // positions. Inverted is used to remember that the user is + // selecting bottom-to-top. + var sel = {from: {line: 0, ch: 0}, to: {line: 0, ch: 0}, inverted: false}; + // Selection-related flags. shiftSelecting obviously tracks + // whether the user is holding shift. reducedSelection is a hack + // to get around the fact that we can't create inverted + // selections. See below. + var shiftSelecting, reducedSelection, lastDoubleClick; + // Variables used by startOperation/endOperation to track what + // happened during the operation. + var updateInput, changes, textChanged, selectionChanged, leaveInputAlone; + // Current visible range (may be bigger than the view window). + var showingFrom = 0, showingTo = 0, lastHeight = 0, curKeyId = null; + // editing will hold an object describing the things we put in the + // textarea, to help figure out whether something changed. + // bracketHighlighted is used to remember that a backet has been + // marked. + var editing, bracketHighlighted; + // Tracks the maximum line length so that the horizontal scrollbar + // can be kept static when scrolling. + var maxLine = ""; + // shardWidth holds the target width of the displayed Shard input widget, + // set from options. + var shardWidth = 200; + + // Initialize the content. Somewhat hacky (delayed prepareInput) + // to work around browser issues. + operation(function(){setValue(options.value || ""); updateInput = false;})(); + setTimeout(prepareInput, 20); + + // Register our event handlers. + connect(wrapper, "mousedown", operation(onMouseDown)); + // Gecko browsers fire contextmenu *after* opening the menu, at + // which point we can't mess with it anymore. Context menu is + // handled in onMouseDown for Gecko. + if (!gecko) connect(wrapper, "contextmenu", operation(onContextMenu)); + connect(code, "dblclick", operation(onDblClick)); + connect(wrapper, "scroll", function() {updateDisplay([]); if (options.onScroll) options.onScroll(instance);}); + connect(window, "resize", function() {updateDisplay(true);}); + connect(input, "keyup", operation(onKeyUp)); + connect(input, "keydown", operation(onKeyDown)); + connect(input, "keypress", operation(onKeyPress)); + connect(input, "focus", onFocus); + connect(input, "blur", onBlur); + + connect(wrapper, "dragenter", function(e){e.stop();}); + connect(wrapper, "dragover", function(e){e.stop();}); + connect(wrapper, "drop", operation(onDrop)); + connect(wrapper, "paste", function(){input.focus(); fastPoll();}); + connect(input, "paste", function(){fastPoll();}); + connect(input, "cut", function(){fastPoll();}); + + if (document.activeElement == input) onFocus(); + else onBlur(); + + function isLine(l) {return l >= 0 && l < lines.length;} + // The instance object that we'll return. Mostly calls out to + // local functions in the CodeShard function. Some do some extra + // range checking and/or clipping. operation is used to wrap the + // call so that changes it makes are tracked, and the display is + // updated afterwards. + var instance = { + getValue: getValue, + setValue: operation(setValue), + getSelection: getSelection, + replaceSelection: operation(replaceSelection), + focus: function(){input.focus(); onFocus(); fastPoll();}, + setOption: function(option, value) { + options[option] = value; + if (option == "lineNumbers" || option == "gutter") gutterChanged(); + else if (option == "mode" || option == "indentUnit") loadMode(); + }, + getOption: function(option) {return options[option];}, + undo: operation(undo), + redo: operation(redo), + indentLine: operation(function(n) {if (isLine(n)) indentLine(n, "smart");}), + historySize: function() {return {undo: history.done.length, redo: history.undone.length};}, + matchBrackets: operation(function(){matchBrackets(true);}), + getTokenAt: function(pos) { + pos = clipPos(pos); + return lines[pos.line].getTokenAt(mode, getStateBefore(pos.line), pos.ch); + }, + cursorCoords: function(start){ + if (start == null) start = sel.inverted; + return pageCoords(start ? sel.from : sel.to); + }, + charCoords: function(pos){return pageCoords(clipPos(pos));}, + coordsChar: function(coords) { + var off = eltOffset(lineSpace); + var line = clipLine(Math.min(lines.length - 1, showingFrom + Math.floor((coords.y - off.top) / lineHeight()))); + return clipPos({line: line, ch: charFromX(clipLine(line), coords.x - off.left)}); + }, + getSearchCursor: function(query, pos, caseFold) {return new SearchCursor(query, pos, caseFold);}, + markText: operation(function(a, b, c){return operation(markText(a, b, c));}), + setMarker: addGutterMarker, + clearMarker: removeGutterMarker, + setLineClass: operation(setLineClass), + lineInfo: lineInfo, + addWidget: function(pos, node, scroll) { + var pos = localCoords(clipPos(pos), true); + node.style.top = (showingFrom * lineHeight() + pos.yBot + paddingTop()) + "px"; + node.style.left = (pos.x + paddingLeft()) + "px"; + code.appendChild(node); + if (scroll) + scrollIntoView(pos.x, pos.yBot, pos.x + node.offsetWidth, pos.yBot + node.offsetHeight); + }, + + lineCount: function() {return lines.length;}, + getCursor: function(start) { + if (start == null) start = sel.inverted; + return copyPos(start ? sel.from : sel.to); + }, + somethingSelected: function() {return !posEq(sel.from, sel.to);}, + setCursor: operation(function(line, ch) { + if (ch == null && typeof line.line == "number") setCursor(line.line, line.ch); + else setCursor(line, ch); + }), + setSelection: operation(function(from, to) {setSelection(clipPos(from), clipPos(to || from));}), + getLine: function(line) {if (isLine(line)) return lines[line].text;}, + setLine: operation(function(line, text) { + if (isLine(line)) replaceRange(text, {line: line, ch: 0}, {line: line, ch: lines[line].text.length}); + }), + removeLine: operation(function(line) { + if (isLine(line)) replaceRange("", {line: line, ch: 0}, clipPos({line: line+1, ch: 0})); + }), + replaceRange: operation(replaceRange), + getRange: function(from, to) {return getRange(clipPos(from), clipPos(to));}, + + operation: function(f){return operation(f)();}, + refresh: function(){updateDisplay(true);}, + getInputField: function(){return input;}, + getWrapperElement: function(){return wrapper;} + }; + + function setValue(code) { + history = null; + var top = {line: 0, ch: 0}; + updateLines(top, {line: lines.length - 1, ch: lines[lines.length-1].text.length}, + splitLines(code), top, top); + history = new History(); + } + function getValue(code) { + var text = []; + for (var i = 0, l = lines.length; i < l; ++i) + text.push(lines[i].text); + return text.join("\n"); + } + + function onMouseDown(e) { + var ld = lastDoubleClick; lastDoubleClick = null; + // First, see if this is a click in the gutter + for (var n = e.target(); n != wrapper; n = n.parentNode) + if (n.parentNode == gutterText) { + if (options.onGutterClick) + options.onGutterClick(instance, indexOf(gutterText.childNodes, n) + showingFrom); + return e.stop(); + } + + if (gecko && e.button() == 3) onContextMenu(e); + if (e.button() != 1) return; + // For button 1, if it was clicked inside the editor + // (posFromMouse returning non-null), we have to adjust the + // selection. + var start = posFromMouse(e), last = start, going; + if (!start) {if (e.target() == wrapper) e.stop(); return;} + + if (!focused) onFocus(); + e.stop(); + if (ld && +new Date - ld < 400) return selectLine(start.line); + + setCursor(start.line, start.ch, false); + // And then we have to see if it's a drag event, in which case + // the dragged-over text must be selected. + function end() { + input.focus(); + updateInput = true; + move(); up(); + } + function extend(e) { + var cur = posFromMouse(e, true); + if (cur && !posEq(cur, last)) { + if (!focused) onFocus(); + last = cur; + setSelection(start, cur); + updateInput = false; + var visible = visibleLines(); + if (cur.line >= visible.to || cur.line < visible.from) + going = setTimeout(operation(function(){extend(e);}), 150); + } + } + + var move = connect(document, "mousemove", operation(function(e) { + clearTimeout(going); + e.stop(); + extend(e); + }), true); + var up = connect(document, "mouseup", operation(function(e) { + clearTimeout(going); + var cur = posFromMouse(e); + if (cur) setSelection(start, cur); + e.stop(); + end(); + }), true); + } + function onDblClick(e) { + var pos = posFromMouse(e); + if (!pos) return; + selectWordAt(pos); + e.stop(); + lastDoubleClick = +new Date; + } + function onDrop(e) { + var pos = posFromMouse(e, true), files = e.e.dataTransfer.files; + if (!pos || options.readOnly) return; + if (files && files.length && window.FileReader && window.File) { + var n = files.length, text = Array(n), read = 0; + for (var i = 0; i < n; ++i) loadFile(files[i], i); + function loadFile(file, i) { + var reader = new FileReader; + reader.onload = function() { + text[i] = reader.result; + if (++read == n) replaceRange(text.join(""), clipPos(pos), clipPos(pos)); + }; + reader.readAsText(file); + } + } + else { + try { + var text = e.e.dataTransfer.getData("Text"); + if (text) replaceRange(text, pos, pos); + } + catch(e){} + } + } + function onKeyDown(e) { + if (!focused) onFocus(); + + var code = e.e.keyCode; + // Tries to detect ctrl on non-mac, cmd on mac. + var mod = (mac ? e.e.metaKey : e.e.ctrlKey) && !e.e.altKey, anyMod = e.e.ctrlKey || e.e.altKey || e.e.metaKey; + if (code == 16 || e.e.shiftKey) shiftSelecting = shiftSelecting || (sel.inverted ? sel.to : sel.from); + else shiftSelecting = null; + // First give onKeyEvent option a chance to handle this. + if (options.onKeyEvent && options.onKeyEvent(instance, addStop(e.e))) return; + + if (code == 33 || code == 34) {scrollPage(code == 34); return e.stop();} // page up/down + if (mod && ((code == 36 || code == 35) || // ctrl-home/end + mac && (code == 38 || code == 40))) { // cmd-up/down + scrollEnd(code == 36 || code == 38); return e.stop(); + } + if (mod && code == 65) {selectAll(); return e.stop();} // ctrl-a + if (!options.readOnly) { + if (!anyMod && code == 13) {return;} // enter + if (!anyMod && code == 9 && handleTab(e.e.shiftKey)) return e.stop(); // tab + if (mod && code == 90) {undo(); return e.stop();} // ctrl-z + if (mod && ((e.e.shiftKey && code == 90) || code == 89)) {redo(); return e.stop();} // ctrl-shift-z, ctrl-y + } + + // Key id to use in the movementKeys map. We also pass it to + // fastPoll in order to 'self learn'. We need this because + // reducedSelection, the hack where we collapse the selection to + // its start when it is inverted and a movement key is pressed + // (and later restore it again), shouldn't be used for + // non-movement keys. + curKeyId = (mod ? "c" : "") + code; + if (sel.inverted && movementKeys.hasOwnProperty(curKeyId)) { + var range = selRange(input); + if (range) { + reducedSelection = {anchor: range.start}; + setSelRange(input, range.start, range.start); + } + } + fastPoll(curKeyId); + } + function onKeyUp(e) { + if (reducedSelection) { + reducedSelection = null; + updateInput = true; + } + if (e.e.keyCode == 16) shiftSelecting = null; + } + function onKeyPress(e) { + if (options.onKeyEvent && options.onKeyEvent(instance, addStop(e.e))) return; + if (options.electricChars && mode.electricChars) { + var ch = String.fromCharCode(e.e.charCode == null ? e.e.keyCode : e.e.charCode); + if (mode.electricChars.indexOf(ch) > -1) + setTimeout(operation(function() {indentLine(sel.to.line, "smart");}), 50); + } + var code = e.e.keyCode; + // Re-stop tab and enter. Necessary on some browsers. + if (code == 13) {handleEnter(); e.stop();} + else if (code == 9 && options.tabMode != "default") e.stop(); + else fastPoll(curKeyId); + } + + function onFocus() { + if (!focused && options.onFocus) options.onFocus(instance); + focused = true; + slowPoll(); + if (wrapper.className.search(/\bCodeShard-focused\b/) == -1) + wrapper.className += " CodeShard-focused"; + restartBlink(); + } + function onBlur() { + if (focused && options.onBlur) options.onBlur(instance); + clearInterval(blinker); + shiftSelecting = null; + focused = false; + wrapper.className = wrapper.className.replace(" CodeShard-focused", ""); + } + + // Replace the range from from to to by the strings in newText. + // Afterwards, set the selection to selFrom, selTo. + function updateLines(from, to, newText, selFrom, selTo) { + if (history) { + var old = []; + for (var i = from.line, e = to.line + 1; i < e; ++i) old.push(lines[i].text); + history.addChange(from.line, newText.length, old); + while (history.done.length > options.undoDepth) history.done.shift(); + } + updateLinesNoUndo(from, to, newText, selFrom, selTo); + } + function unredoHelper(from, to) { + var change = from.pop(); + if (change) { + var replaced = [], end = change.start + change.added; + for (var i = change.start; i < end; ++i) replaced.push(lines[i].text); + to.push({start: change.start, added: change.old.length, old: replaced}); + var pos = clipPos({line: change.start + change.old.length - 1, + ch: editEnd(replaced[replaced.length-1], change.old[change.old.length-1])}); + updateLinesNoUndo({line: change.start, ch: 0}, {line: end - 1, ch: lines[end-1].text.length}, change.old, pos, pos); + } + } + function undo() {unredoHelper(history.done, history.undone);} + function redo() {unredoHelper(history.undone, history.done);} + + function updateLinesNoUndo(from, to, newText, selFrom, selTo) { + var recomputeMaxLength = false, maxLineLength = maxLine.length; + for (var i = from.line; i < to.line; ++i) { + if (lines[i].text.length == maxLineLength) {recomputeMaxLength = true; break;} + } + + var nlines = to.line - from.line, firstLine = lines[from.line], lastLine = lines[to.line]; + // First adjust the line structure, taking some care to leave highlighting intact. + if (firstLine == lastLine) { + if (newText.length == 1) + firstLine.replace(from.ch, to.ch, newText[0]); + else { + lastLine = firstLine.split(to.ch, newText[newText.length-1]); + var spliceargs = [from.line + 1, nlines]; + firstLine.replace(from.ch, firstLine.text.length, newText[0]); + for (var i = 1, e = newText.length - 1; i < e; ++i) spliceargs.push(new Line(newText[i])); + spliceargs.push(lastLine); + lines.splice.apply(lines, spliceargs); + } + } + else if (newText.length == 1) { + firstLine.replace(from.ch, firstLine.text.length, newText[0] + lastLine.text.slice(to.ch)); + lines.splice(from.line + 1, nlines); + } + else { + var spliceargs = [from.line + 1, nlines - 1]; + firstLine.replace(from.ch, firstLine.text.length, newText[0]); + lastLine.replace(0, to.ch, newText[newText.length-1]); + for (var i = 1, e = newText.length - 1; i < e; ++i) spliceargs.push(new Line(newText[i])); + lines.splice.apply(lines, spliceargs); + } + + + for (var i = from.line, e = i + newText.length; i < e; ++i) { + var l = lines[i].text; + if (l.length > maxLineLength) { + maxLine = l; maxLineLength = l.length; + recomputeMaxLength = false; + } + } + if (recomputeMaxLength) { + maxLineLength = 0; + for (var i = 0, e = lines.length; i < e; ++i) { + var l = lines[i].text; + if (l.length > maxLineLength) { + maxLineLength = l.length; maxLine = l; + } + } + } + + // Add these lines to the work array, so that they will be + // highlighted. Adjust work lines if lines were added/removed. + var newWork = [], lendiff = newText.length - nlines - 1; + for (var i = 0, l = work.length; i < l; ++i) { + var task = work[i]; + if (task < from.line) newWork.push(task); + else if (task > to.line) newWork.push(task + lendiff); + } + if (newText.length) newWork.push(from.line); + work = newWork; + startWorker(100); + // Remember that these lines changed, for updating the display + changes.push({from: from.line, to: to.line + 1, diff: lendiff}); + textChanged = {from: from, to: to, text: newText}; + + // Update the selection + function updateLine(n) {return n <= Math.min(to.line, to.line + lendiff) ? n : n + lendiff;} + setSelection(selFrom, selTo, updateLine(sel.from.line), updateLine(sel.to.line)); + + // Make sure the scroll-size span has the correct height. + code.style.height = (lines.length * lineHeight() + 2 * paddingTop()) + "px"; + } + + function replaceRange(code, from, to) { + from = clipPos(from); + if (!to) to = from; else to = clipPos(to); + code = splitLines(code); + function adjustPos(pos) { + if (posLess(pos, from)) return pos; + if (!posLess(to, pos)) return end; + var line = pos.line + code.length - (to.line - from.line) - 1; + var ch = pos.ch; + if (pos.line == to.line) + ch += code[code.length-1].length - (to.ch - (to.line == from.line ? from.ch : 0)); + return {line: line, ch: ch}; + } + var end; + replaceRange1(code, from, to, function(end1) { + end = end1; + return {from: adjustPos(sel.from), to: adjustPos(sel.to)}; + }); + return end; + } + function replaceSelection(code, collapse) { + replaceRange1(splitLines(code), sel.from, sel.to, function(end) { + if (collapse == "end") return {from: end, to: end}; + else if (collapse == "start") return {from: sel.from, to: sel.from}; + else return {from: sel.from, to: end}; + }); + } + function replaceRange1(code, from, to, computeSel) { + var endch = code.length == 1 ? code[0].length + from.ch : code[code.length-1].length; + var newSel = computeSel({line: from.line + code.length - 1, ch: endch}); + updateLines(from, to, code, newSel.from, newSel.to); + } + + function getRange(from, to) { + var l1 = from.line, l2 = to.line; + if (l1 == l2) return lines[l1].text.slice(from.ch, to.ch); + var code = [lines[l1].text.slice(from.ch)]; + for (var i = l1 + 1; i < l2; ++i) code.push(lines[i].text); + code.push(lines[l2].text.slice(0, to.ch)); + return code.join("\n"); + } + function getSelection() { + return getRange(sel.from, sel.to); + } + + var pollingFast = false; // Ensures slowPoll doesn't cancel fastPoll + function slowPoll() { + if (pollingFast) return; + poll.set(2000, function() { + startOperation(); + readInput(); + if (focused) slowPoll(); + endOperation(); + }); + } + function fastPoll(keyId) { + var missed = false; + pollingFast = true; + function p() { + startOperation(); + var changed = readInput(); + if (changed == "moved" && keyId) movementKeys[keyId] = true; + if (!changed && !missed) {missed = true; poll.set(80, p);} + else {pollingFast = false; slowPoll();} + endOperation(); + } + poll.set(20, p); + } + + // Inspects the textarea, compares its state (content, selection) + // to the data in the editing variable, and updates the editor + // content or cursor if something changed. + function readInput() { + var changed = false, text = input.value, sr = selRange(input); + if (!sr) return false; + var changed = editing.text != text, rs = reducedSelection; + var moved = changed || sr.start != editing.start || sr.end != (rs ? editing.start : editing.end); + if (!moved && !rs) return false; + if (changed) { + shiftSelecting = reducedSelection = null; + if (options.readOnly) {updateInput = true; return "changed";} + } + + // Compute selection start and end based on start/end offsets in textarea + function computeOffset(n, startLine) { + var pos = 0; + for (;;) { + var found = text.indexOf("\n", pos); + if (found == -1 || (text.charAt(found-1) == "\r" ? found - 1 : found) >= n) + return {line: startLine, ch: n - pos}; + ++startLine; + pos = found + 1; + } + } + var from = computeOffset(sr.start, editing.from), + to = computeOffset(sr.end, editing.from); + // Here we have to take the reducedSelection hack into account, + // so that you can, for example, press shift-up at the start of + // your selection and have the right thing happen. + if (rs) { + from = sr.start == rs.anchor ? to : from; + to = shiftSelecting ? sel.to : sr.start == rs.anchor ? from : to; + if (!posLess(from, to)) { + reducedSelection = null; + sel.inverted = false; + var tmp = from; from = to; to = tmp; + } + } + + // In some cases (cursor on same line as before), we don't have + // to update the textarea content at all. + if (from.line == to.line && from.line == sel.from.line && from.line == sel.to.line && !shiftSelecting) + updateInput = false; + + // Magic mess to extract precise edited range from the changed + // string. + if (changed) { + var start = 0, end = text.length, len = Math.min(end, editing.text.length); + var c, line = editing.from, nl = -1; + while (start < len && (c = text.charAt(start)) == editing.text.charAt(start)) { + ++start; + if (c == "\n") {line++; nl = start;} + } + var ch = nl > -1 ? start - nl : start, endline = editing.to - 1, edend = editing.text.length; + for (;;) { + c = editing.text.charAt(edend); + if (c == "\n") endline--; + if (text.charAt(end) != c) {++end; ++edend; break;} + if (edend <= start || end <= start) break; + --end; --edend; + } + var nl = editing.text.lastIndexOf("\n", edend - 1), endch = nl == -1 ? edend : edend - nl - 1; + updateLines({line: line, ch: ch}, {line: endline, ch: endch}, splitLines(text.slice(start, end)), from, to); + if (line != endline || from.line != line) updateInput = true; + } + else setSelection(from, to); + + editing.text = text; editing.start = sr.start; editing.end = sr.end; + return changed ? "changed" : moved ? "moved" : false; + } + + // Set the textarea content and selection range to match the + // editor state. + function prepareInput() { + var text = []; + var from = Math.max(0, sel.from.line - 1), to = Math.min(lines.length, sel.to.line + 2); + for (var i = from; i < to; ++i) text.push(lines[i].text); + text = input.value = text.join(lineSep); + var startch = sel.from.ch, endch = sel.to.ch; + for (var i = from; i < sel.from.line; ++i) + startch += lineSep.length + lines[i].text.length; + for (var i = from; i < sel.to.line; ++i) + endch += lineSep.length + lines[i].text.length; + editing = {text: text, from: from, to: to, start: startch, end: endch}; + setSelRange(input, startch, reducedSelection ? startch : endch); + } + + function scrollCursorIntoView() { + var cursor = localCoords(sel.inverted ? sel.from : sel.to); + return scrollIntoView(cursor.x, cursor.y, cursor.x, cursor.yBot); + } + function scrollIntoView(x1, y1, x2, y2) { + var pl = paddingLeft(), pt = paddingTop(); + y1 += pt; y2 += pt; x1 += pl; x2 += pl; + var screen = wrapper.clientHeight, screentop = wrapper.scrollTop, scrolled = false, result = true; + if (y1 < screentop) {wrapper.scrollTop = Math.max(0, y1 - 10); scrolled = true;} + else if (y2 > screentop + screen) {wrapper.scrollTop = y2 + 10 - screen; scrolled = true;} + + var screenw = wrapper.clientWidth, screenleft = wrapper.scrollLeft; + if (x1 < screenleft) {wrapper.scrollLeft = Math.max(0, x1 - 10); scrolled = true;} + else if (x2 > screenw + screenleft) { + wrapper.scrollLeft = x2 + 10 - screenw; + scrolled = true; + if (x2 > code.clientWidth) result = false; + } + if (scrolled && options.onScroll) options.onScroll(instance); + return result; + } + + function visibleLines() { + var lh = lineHeight(), top = wrapper.scrollTop - paddingTop(); + return {from: Math.min(lines.length, Math.max(0, Math.floor(top / lh))), + to: Math.min(lines.length, Math.ceil((top + wrapper.clientHeight) / lh))}; + } + // Uses a set of changes plus the current scroll position to + // determine which DOM updates have to be made, and makes the + // updates. + function updateDisplay(changes) { + if (!wrapper.offsetWidth) { + showingFrom = showingTo = 0; + return; + } + // First create a range of theoretically intact lines, and punch + // holes in that using the change info. + var intact = changes === true ? [] : [{from: showingFrom, to: showingTo, domStart: 0}]; + for (var i = 0, l = changes.length || 0; i < l; ++i) { + var change = changes[i], intact2 = [], diff = change.diff || 0; + for (var j = 0, l2 = intact.length; j < l2; ++j) { + var range = intact[j]; + if (change.to <= range.from) + intact2.push({from: range.from + diff, to: range.to + diff, domStart: range.domStart}); + else if (range.to <= change.from) + intact2.push(range); + else { + if (change.from > range.from) + intact2.push({from: range.from, to: change.from, domStart: range.domStart}) + if (change.to < range.to) + intact2.push({from: change.to + diff, to: range.to + diff, + domStart: range.domStart + (change.to - range.from)}); + } + } + intact = intact2; + } + + // Then, determine which lines we'd want to see, and which + // updates have to be made to get there. + var visible = visibleLines(); + var from = Math.min(showingFrom, Math.max(visible.from - 3, 0)), + to = Math.min(lines.length, Math.max(showingTo, visible.to + 3)), + updates = [], domPos = 0, domEnd = showingTo - showingFrom, pos = from, changedLines = 0; + + for (var i = 0, l = intact.length; i < l; ++i) { + var range = intact[i]; + if (range.to <= from) continue; + if (range.from >= to) break; + if (range.domStart > domPos || range.from > pos) { + updates.push({from: pos, to: range.from, domSize: range.domStart - domPos, domStart: domPos}); + changedLines += range.from - pos; + } + pos = range.to; + domPos = range.domStart + (range.to - range.from); + } + if (domPos != domEnd || pos != to) { + changedLines += Math.abs(to - pos); + updates.push({from: pos, to: to, domSize: domEnd - domPos, domStart: domPos}); + } + + if (!updates.length) return; + lineSpan.style.display = "none"; + // If more than 30% of the screen needs update, just do a full + // redraw (which is quicker than patching) + if (changedLines > (visible.to - visible.from) * .3) + refreshDisplay(from = Math.max(visible.from - 10, 0), to = Math.min(visible.to + 7, lines.length)); + // Otherwise, only update the stuff that needs updating. + else + + patchDisplay(updates); + lineSpan.style.display = ""; + + // Position the mover span to align with the lines it's supposed + // to be showing (which will cover the visible display) + var different = from != showingFrom || to != showingTo || lastHeight != wrapper.clientHeight; + showingFrom = from; showingTo = to; + mover.style.top = (from * lineHeight()) + "px"; + if (different) { + lastHeight = wrapper.clientHeight; + code.style.height = (lines.length * lineHeight() + 2 * paddingTop()) + "px"; + updateGutter(); + } + + var textWidth = stringWidth(maxLine); + //lineSpace.style.width = textWidth > wrapper.clientWidth ? textWidth + "px" : ""; + + var childWidth = lineSpan.firstChild.offsetWidth; + //var childWidth = measure.offsetWidth; + childw_r(childWidth); + childtext_r(lineSpan.firstChild.innerHTML); + + var spanw; + if (shardWidth > childWidth) + spanw = shardWidth - childWidth; + else + spanw = 0; + + spanw += "px"; + + spanw_r(spanw); + + //lineSpan.style.marginRight = spanw; + wrapper.style.position = "relative"; + + //lineSpan.style.overflowX = "hidden"; + + // Since this is all rather error prone, it is honoured with the + // only assertion in the whole file. + if (lineSpan.childNodes.length != showingTo - showingFrom) + throw new Error("BAD PATCH! " + JSON.stringify(updates) + " size=" + (showingTo - showingFrom) + + " nodes=" + lineSpan.childNodes.length); + + updateCursor(); + } + + function refreshDisplay(from, to) { + var html = [], start = {line: from, ch: 0}, inSel = posLess(sel.from, start) && !posLess(sel.to, start); + for (var i = from; i < to; ++i) { + var ch1 = null, ch2 = null; + if (inSel) { + ch1 = 0; + if (sel.to.line == i) {inSel = false; ch2 = sel.to.ch;} + } + else if (sel.from.line == i) { + if (sel.to.line == i) {ch1 = sel.from.ch; ch2 = sel.to.ch;} + else {inSel = true; ch1 = sel.from.ch;} + } + html.push(lines[i].getHTML(ch1, ch2, true)); + } + lineSpan.innerHTML = html.join(""); + } + + function patchDisplay(updates) { + // Slightly different algorithm for IE (badInnerHTML), since + // there .innerHTML on PRE nodes is dumb, and discards + // whitespace. + var sfrom = sel.from.line, sto = sel.to.line, off = 0, + scratch = badInnerHTML && document.createElement("span"); + for (var i = 0, e = updates.length; i < e; ++i) { + var rec = updates[i]; + var extra = (rec.to - rec.from) - rec.domSize; + var nodeAfter = lineSpan.childNodes[rec.domStart + rec.domSize + off] || null; + if (badInnerHTML) + for (var j = Math.max(-extra, rec.domSize); j > 0; --j) + lineSpan.removeChild(nodeAfter ? nodeAfter.previousSibling : lineSpan.lastChild); + else if (extra) { + for (var j = Math.max(0, extra); j > 0; --j) + lineSpan.insertBefore(document.createElement("span"), nodeAfter); + for (var j = Math.max(0, -extra); j > 0; --j) + lineSpan.removeChild(nodeAfter ? nodeAfter.previousSibling : lineSpan.lastChild); + } + var node = lineSpan.childNodes[rec.domStart + off], inSel = sfrom < rec.from && sto >= rec.from; + for (var j = rec.from; j < rec.to; ++j) { + var ch1 = null, ch2 = null; + if (inSel) { + ch1 = 0; + if (sto == j) {inSel = false; ch2 = sel.to.ch;} + } + else if (sfrom == j) { + if (sto == j) {ch1 = sel.from.ch; ch2 = sel.to.ch;} + else {inSel = true; ch1 = sel.from.ch;} + } + if (badInnerHTML) { + scratch.innerHTML = lines[j].getHTML(ch1, ch2, true); + lineSpan.insertBefore(scratch.firstChild, nodeAfter); + } + else { + node.innerHTML = lines[j].getHTML(ch1, ch2, false); + node.className = lines[j].className || ""; + node = node.nextSibling; + } + } + off += extra; + } + } + + function updateGutter() { + if (!options.gutter && !options.lineNumbers) return; + var hText = mover.offsetHeight, hEditor = wrapper.clientHeight; + gutter.style.height = (hText - hEditor < 2 ? hEditor : hText) + "px"; + var html = []; + for (var i = showingFrom; i < showingTo; ++i) { + var marker = lines[i].gutterMarker; + var text = options.lineNumbers ? i + options.firstLineNumber : null; + if (marker && marker.text) + text = marker.text.replace("%N%", text != null ? text : ""); + else if (text == null) + text = "\u00a0"; + html.push((marker && marker.style ? '
' : "
"), text, "
"); + } + gutter.style.display = "none"; + gutterText.innerHTML = html.join(""); + var minwidth = String(lines.length).length, firstNode = gutterText.firstChild, val = eltText(firstNode), pad = ""; + while (val.length + pad.length < minwidth) pad += "\u00a0"; + if (pad) firstNode.insertBefore(document.createTextNode(pad), firstNode.firstChild); + gutter.style.display = ""; + lineSpace.style.marginLeft = gutter.offsetWidth + "px"; + } + function updateCursor() { + var head = sel.inverted ? sel.from : sel.to; + var x = charX(head.line, head.ch) + "px"; + var y = (head.line - showingFrom) * lineHeight() + "px"; + inputSpan.style.top = y; inputSpan.style.left = x; + if (posEq(sel.from, sel.to)) { + cursor.style.top = y; cursor.style.left = x; + cursor.style.display = ""; + } + else cursor.style.display = "none"; + } + + // Update the selection. Last two args are only used by + // updateLines, since they have to be expressed in the line + // numbers before the update. + function setSelection(from, to, oldFrom, oldTo) { + if (posEq(sel.from, from) && posEq(sel.to, to)) return; + var sh = shiftSelecting && clipPos(shiftSelecting); + if (posLess(to, from)) {var tmp = to; to = from; from = tmp;} + if (sh) { + if (posLess(sh, from)) from = sh; + else if (posLess(to, sh)) to = sh; + } + + var startEq = posEq(sel.to, to), endEq = posEq(sel.from, from); + if (posEq(from, to)) sel.inverted = false; + else if (startEq && !endEq) sel.inverted = true; + else if (endEq && !startEq) sel.inverted = false; + + // Some ugly logic used to only mark the lines that actually did + // see a change in selection as changed, rather than the whole + // selected range. + if (oldFrom == null) {oldFrom = sel.from.line; oldTo = sel.to.line;} + if (posEq(from, to)) { + if (!posEq(sel.from, sel.to)) + changes.push({from: oldFrom, to: oldTo + 1}); + } + else if (posEq(sel.from, sel.to)) { + changes.push({from: from.line, to: to.line + 1}); + } + else { + if (!posEq(from, sel.from)) { + if (from.line < oldFrom) + changes.push({from: from.line, to: Math.min(to.line, oldFrom) + 1}); + else + changes.push({from: oldFrom, to: Math.min(oldTo, from.line) + 1}); + } + if (!posEq(to, sel.to)) { + if (to.line < oldTo) + changes.push({from: Math.max(oldFrom, from.line), to: oldTo + 1}); + else + changes.push({from: Math.max(from.line, oldTo), to: to.line + 1}); + } + } + sel.from = from; sel.to = to; + selectionChanged = true; + } + function setCursor(line, ch) { + var pos = clipPos({line: line, ch: ch || 0}); + setSelection(pos, pos); + } + + function clipLine(n) {return Math.max(0, Math.min(n, lines.length-1));} + function clipPos(pos) { + if (pos.line < 0) return {line: 0, ch: 0}; + if (pos.line >= lines.length) return {line: lines.length-1, ch: lines[lines.length-1].text.length}; + var ch = pos.ch, linelen = lines[pos.line].text.length; + if (ch == null || ch > linelen) return {line: pos.line, ch: linelen}; + else if (ch < 0) return {line: pos.line, ch: 0}; + else return pos; + } + + function scrollPage(down) { + var linesPerPage = Math.floor(wrapper.clientHeight / lineHeight()), head = sel.inverted ? sel.from : sel.to; + setCursor(head.line + (Math.max(linesPerPage - 1, 1) * (down ? 1 : -1)), head.ch); + } + function scrollEnd(top) { + setCursor(top ? 0 : lines.length - 1); + } + function selectAll() { + var endLine = lines.length - 1; + setSelection({line: 0, ch: 0}, {line: endLine, ch: lines[endLine].text.length}); + } + function selectWordAt(pos) { + var line = lines[pos.line].text; + var start = pos.ch, end = pos.ch; + while (start > 0 && /\w/.test(line.charAt(start - 1))) --start; + while (end < line.length && /\w/.test(line.charAt(end))) ++end; + setSelection({line: pos.line, ch: start}, {line: pos.line, ch: end}); + } + function selectLine(line) { + setSelection({line: line, ch: 0}, {line: line, ch: lines[line].text.length}); + } + function handleEnter() { + replaceSelection("\n", "end"); + if (options.enterMode != "flat") + indentLine(sel.from.line, options.enterMode == "keep" ? "prev" : "smart"); + } + function handleTab(shift) { + shiftSelecting = null; + switch (options.tabMode) { + case "default": + return false; + case "indent": + for (var i = sel.from.line, e = sel.to.line; i <= e; ++i) indentLine(i, "smart"); + break; + case "classic": + if (posEq(sel.from, sel.to)) { + if (shift) indentLine(sel.from.line, "smart"); + else replaceSelection("\t", "end"); + break; + } + case "shift": + for (var i = sel.from.line, e = sel.to.line; i <= e; ++i) indentLine(i, shift ? "subtract" : "add"); + break; + } + return true; + } + + function indentLine(n, how) { + if (how == "smart") { + if (!mode.indent) how = "prev"; + else var state = getStateBefore(n); + } + + var line = lines[n], curSpace = line.indentation(), curSpaceString = line.text.match(/^\s*/)[0], indentation; + if (how == "prev") { + if (n) indentation = lines[n-1].indentation(); + else indentation = 0; + } + else if (how == "smart") indentation = mode.indent(state, line.text.slice(curSpaceString.length)); + else if (how == "add") indentation = curSpace + options.indentUnit; + else if (how == "subtract") indentation = curSpace - options.indentUnit; + indentation = Math.max(0, indentation); + var diff = indentation - curSpace; + + if (!diff) { + if (sel.from.line != n && sel.to.line != n) return; + var indentString = curSpaceString; + } + else { + var indentString = "", pos = 0; + if (options.indentWithTabs) + for (var i = Math.floor(indentation / tabSize); i; --i) {pos += tabSize; indentString += "\t";} + while (pos < indentation) {++pos; indentString += " ";} + } + + replaceRange(indentString, {line: n, ch: 0}, {line: n, ch: curSpaceString.length}); + } + + function loadMode() { + mode = CodeShard.getMode(options, options.mode); + for (var i = 0, l = lines.length; i < l; ++i) + lines[i].stateAfter = null; + work = [0]; + } + function gutterChanged() { + var visible = options.gutter || options.lineNumbers; + gutter.style.display = visible ? "" : "none"; + if (visible) updateGutter(); + else lineSpan.parentNode.style.marginLeft = 0; + } + + function markText(from, to, className) { + from = clipPos(from); to = clipPos(to); + var accum = []; + function add(line, from, to, className) { + var line = lines[line], mark = line.addMark(from, to, className); + mark.line = line; + accum.push(mark); + } + if (from.line == to.line) add(from.line, from.ch, to.ch, className); + else { + add(from.line, from.ch, null, className); + for (var i = from.line + 1, e = to.line; i < e; ++i) + add(i, 0, null, className); + add(to.line, 0, to.ch, className); + } + changes.push({from: from.line, to: to.line + 1}); + return function() { + var start, end; + for (var i = 0; i < accum.length; ++i) { + var mark = accum[i], found = indexOf(lines, mark.line); + mark.line.removeMark(mark); + if (found > -1) { + if (start == null) start = found; + end = found; + } + } + if (start != null) changes.push({from: start, to: end + 1}); + }; + } + + function addGutterMarker(line, text, className) { + if (typeof line == "number") line = lines[clipLine(line)]; + line.gutterMarker = {text: text, style: className}; + updateGutter(); + return line; + } + function removeGutterMarker(line) { + if (typeof line == "number") line = lines[clipLine(line)]; + line.gutterMarker = null; + updateGutter(); + } + function setLineClass(line, className) { + if (typeof line == "number") { + var no = line; + line = lines[clipLine(line)]; + } + else { + var no = indexOf(lines, line); + if (no == -1) return null; + } + line.className = className; + changes.push({from: no, to: no + 1}); + return line; + } + + function lineInfo(line) { + if (typeof line == "number") { + var n = line; + line = lines[line]; + if (!line) return null; + } + else { + var n = indexOf(lines, line); + if (n == -1) return null; + } + var marker = line.gutterMarker; + return {line: n, text: line.text, markerText: marker && marker.text, markerClass: marker && marker.style}; + } + + function stringWidth(str) { + measure.innerHTML = "x"; + measure.firstChild.firstChild.firstChild.nodeValue = str; + return measure.firstChild.firstChild.offsetWidth || 10; + } + // These are used to go from pixel positions to character + // positions, taking varying character widths into account. + function charX(line, pos) { + if (pos == 0) return 0; + measure.innerHTML = "
" + lines[line].getHTML(null, null, false, pos) + "
"; + + var childWidth = 0; + + childWidth += measure.firstChild.firstChild.offsetWidth; + posx_r(childWidth); + return childWidth; + } + function charFromX(line, x) { + if (x <= 0) return 0; + var lineObj = lines[line], text = lineObj.text; + function getX(len) { + measure.innerHTML = "" + lineObj.getHTML(null, null, false, len) + ""; + return measure.firstChild.firstChild.offsetWidth; + } + var from = 0, fromX = 0, to = text.length, toX; + // Guess a suitable upper bound for our search. + var estimated = Math.min(to, Math.ceil(x / stringWidth("x"))); + for (;;) { + var estX = getX(estimated); + if (estX <= x && estimated < to) estimated = Math.min(to, Math.ceil(estimated * 1.2)); + else {toX = estX; to = estimated; break;} + } + if (x > toX) return to; + // Try to guess a suitable lower bound as well. + estimated = Math.floor(to * 0.8); estX = getX(estimated); + if (estX < x) {from = estimated; fromX = estX;} + // Do a binary search between these bounds. + for (;;) { + if (to - from <= 1) return (toX - x > x - fromX) ? from : to; + var middle = Math.ceil((from + to) / 2), middleX = getX(middle); + if (middleX > x) {to = middle; toX = middleX;} + else {from = middle; fromX = middleX;} + } + } + + function localCoords(pos, inLineWrap) { + var lh = lineHeight(), line = pos.line - (inLineWrap ? showingFrom : 0); + return {x: charX(pos.line, pos.ch), y: line * lh, yBot: (line + 1) * lh}; + } + function pageCoords(pos) { + var local = localCoords(pos, true), off = eltOffset(lineSpace); + return {x: off.left + local.x, y: off.top + local.y, yBot: off.top + local.yBot}; + } + + function lineHeight() { + var nlines = lineSpan.childNodes.length; + if (nlines) return lineSpan.offsetHeight / nlines; + measure.innerHTML = "x"; + return measure.firstChild.offsetHeight || 1; + } + function paddingTop() {return lineSpace.offsetTop;} + function paddingLeft() {return lineSpace.offsetLeft;} + + function posFromMouse(e, liberal) { + var off = eltOffset(lineSpace), + x = e.pageX() - off.left, + y = e.pageY() - off.top; + // This is a mess of a heuristic to try and determine whether a + // scroll-bar was clicked or not, and to return null if one was + // (and !liberal). + if (!liberal && e.target() != lineSpace.parentNode && + !(e.target() == wrapper && y > (lines.length * lineHeight()) && wrapper.clientHeight > code.offsetHeight)) + for (var n = e.target(); n != lineSpan && n != cursor; n = n.parentNode) + if (!n || n == wrapper) return null; + var line = showingFrom + Math.floor(y / lineHeight()); + return clipPos({line: line, ch: charFromX(clipLine(line), x)}); + } + function onContextMenu(e) { + var pos = posFromMouse(e); + if (!pos || window.opera) return; // Opera is difficult. + if (posEq(sel.from, sel.to) || posLess(pos, sel.from) || !posLess(pos, sel.to)) + setCursor(pos.line, pos.ch); + + var oldCSS = input.style.cssText; + input.style.cssText = "position: fixed; width: 30px; height: 30px; top: " + (e.pageY() - 1) + + "px; left: " + (e.pageX() - 1) + "px; z-index: 1000; background: white; " + + "border-width: 0; outline: none; overflow: hidden;"; + var val = input.value = getSelection(); + input.focus(); + setSelRange(input, 0, val.length); + if (gecko) e.stop(); + leaveInputAlone = true; + setTimeout(function() { + if (input.value != val) operation(replaceSelection)(input.value, "end"); + input.style.cssText = oldCSS; + leaveInputAlone = false; + prepareInput(); + slowPoll(); + }, 50); + } + + // Cursor-blinking + function restartBlink() { + clearInterval(blinker); + var on = true; + cursor.style.visibility = ""; + blinker = setInterval(function() { + cursor.style.visibility = (on = !on) ? "" : "hidden"; + }, 650); + } + + var matching = {"(": ")>", ")": "(<", "[": "]>", "]": "[<", "{": "}>", "}": "{<"}; + function matchBrackets(autoclear) { + var head = sel.inverted ? sel.from : sel.to, line = lines[head.line], pos = head.ch - 1; + var match = (pos >= 0 && matching[line.text.charAt(pos)]) || matching[line.text.charAt(++pos)]; + if (!match) return; + var ch = match.charAt(0), forward = match.charAt(1) == ">", d = forward ? 1 : -1, st = line.styles; + for (var off = pos + 1, i = 0, e = st.length; i < e; i+=2) + if ((off -= st[i].length) <= 0) {var style = st[i+1]; break;} + + var stack = [line.text.charAt(pos)], re = /[(){}[\]]/; + function scan(line, from, to) { + if (!line.text) return; + var st = line.styles, pos = forward ? 0 : line.text.length - 1, cur; + for (var i = forward ? 0 : st.length - 2, e = forward ? st.length : -2; i != e; i += 2*d) { + var text = st[i]; + if (st[i+1] != null && st[i+1] != style) {pos += d * text.length; continue;} + for (var j = forward ? 0 : text.length - 1, te = forward ? text.length : -1; j != te; j += d, pos+=d) { + if (pos >= from && pos < to && re.test(cur = text.charAt(j))) { + var match = matching[cur]; + if (match.charAt(1) == ">" == forward) stack.push(cur); + else if (stack.pop() != match.charAt(0)) return {pos: pos, match: false}; + else if (!stack.length) return {pos: pos, match: true}; + } + } + } + } + for (var i = head.line, e = forward ? Math.min(i + 50, lines.length) : Math.max(0, i - 50); i != e; i+=d) { + var line = lines[i], first = i == head.line; + var found = scan(line, first && forward ? pos + 1 : 0, first && !forward ? pos : line.text.length); + if (found) { + var style = found.match ? "CodeShard-matchingbracket" : "CodeShard-nonmatchingbracket"; + var one = markText({line: head.line, ch: pos}, {line: head.line, ch: pos+1}, style), + two = markText({line: i, ch: found.pos}, {line: i, ch: found.pos + 1}, style); + var clear = operation(function(){one(); two();}); + if (autoclear) setTimeout(clear, 800); + else bracketHighlighted = clear; + break; + } + } + } + + // Finds the line to start with when starting a parse. Tries to + // find a line with a stateAfter, so that it can start with a + // valid state. If that fails, it returns the line with the + // smallest indentation, which tends to need the least context to + // parse correctly. + function findStartLine(n) { + var minindent, minline; + for (var search = n, lim = n - 40; search > lim; --search) { + if (search == 0) return 0; + var line = lines[search-1]; + if (line.stateAfter) return search; + var indented = line.indentation(); + if (minline == null || minindent > indented) { + minline = search; + minindent = indented; + } + } + return minline; + } + function getStateBefore(n) { + var start = findStartLine(n), state = start && lines[start-1].stateAfter; + if (!state) state = startState(mode); + else state = copyState(mode, state); + for (var i = start; i < n; ++i) { + var line = lines[i]; + line.highlight(mode, state); + line.stateAfter = copyState(mode, state); + } + if (!lines[n].stateAfter) work.push(n); + return state; + } + function highlightWorker() { + var end = +new Date + options.workTime; + while (work.length) { + if (!lines[showingFrom].stateAfter) var task = showingFrom; + else var task = work.pop(); + if (task >= lines.length) continue; + var start = findStartLine(task), state = start && lines[start-1].stateAfter; + if (state) state = copyState(mode, state); + else state = startState(mode); + + for (var i = start, l = lines.length; i < l; ++i) { + var line = lines[i], hadState = line.stateAfter; + if (+new Date > end) { + work.push(i); + startWorker(options.workDelay); + changes.push({from: task, to: i}); + return; + } + var changed = line.highlight(mode, state); + line.stateAfter = copyState(mode, state); + if (hadState && !changed && line.text) break; + } + changes.push({from: task, to: i}); + } + } + function startWorker(time) { + if (!work.length) return; + highlight.set(time, operation(highlightWorker)); + } + + // Operations are used to wrap changes in such a way that each + // change won't have to update the cursor and display (which would + // be awkward, slow, and error-prone), but instead updates are + // batched and then all combined and executed at once. + function startOperation() { + updateInput = null; changes = []; textChanged = selectionChanged = false; + } + function endOperation() { + var reScroll = false; + if (selectionChanged) reScroll = !scrollCursorIntoView(); + if (changes.length) updateDisplay(changes); + else if (selectionChanged) updateCursor(); + if (reScroll) scrollCursorIntoView(); + if (selectionChanged) restartBlink(); + + // updateInput can be set to a boolean value to force/prevent an + // update. + if (!leaveInputAlone && (updateInput === true || (updateInput !== false && selectionChanged))) + prepareInput(); + + if (selectionChanged && options.matchBrackets) + setTimeout(operation(function() { + if (bracketHighlighted) {bracketHighlighted(); bracketHighlighted = null;} + matchBrackets(false); + }), 20); + var tc = textChanged; // textChanged can be reset by cursoractivity callback + if (selectionChanged && options.onCursorActivity) + options.onCursorActivity(instance); + if (tc && options.onChange && instance) + options.onChange(instance, tc); + } + var nestedOperation = 0; + function operation(f) { + return function() { + if (!nestedOperation++) startOperation(); + try {var result = f.apply(this, arguments);} + finally {if (!--nestedOperation) endOperation();} + return result; + }; + } + + function SearchCursor(query, pos, caseFold) { + this.atOccurrence = false; + if (caseFold == null) caseFold = typeof query == "string" && query == query.toLowerCase(); + + if (pos && typeof pos == "object") pos = clipPos(pos); + else pos = {line: 0, ch: 0}; + this.pos = {from: pos, to: pos}; + + // The matches method is filled in based on the type of query. + // It takes a position and a direction, and returns an object + // describing the next occurrence of the query, or null if no + // more matches were found. + if (typeof query != "string") // Regexp match + this.matches = function(reverse, pos) { + if (reverse) { + var line = lines[pos.line].text.slice(0, pos.ch), match = line.match(query), start = 0; + while (match) { + var ind = line.indexOf(match[0]); + start += ind; + line = line.slice(ind + 1); + var newmatch = line.match(query); + if (newmatch) match = newmatch; + else break; + } + } + else { + var line = lines[pos.line].text.slice(pos.ch), match = line.match(query), + start = match && pos.ch + line.indexOf(match[0]); + } + if (match) + return {from: {line: pos.line, ch: start}, + to: {line: pos.line, ch: start + match[0].length}, + match: match}; + }; + else { // String query + if (caseFold) query = query.toLowerCase(); + var fold = caseFold ? function(str){return str.toLowerCase();} : function(str){return str;}; + var target = query.split("\n"); + // Different methods for single-line and multi-line queries + if (target.length == 1) + this.matches = function(reverse, pos) { + var line = fold(lines[pos.line].text), len = query.length, match; + if (reverse ? (pos.ch >= len && (match = line.lastIndexOf(query, pos.ch - len)) != -1) + : (match = line.indexOf(query, pos.ch)) != -1) + return {from: {line: pos.line, ch: match}, + to: {line: pos.line, ch: match + len}}; + }; + else + this.matches = function(reverse, pos) { + var ln = pos.line, idx = (reverse ? target.length - 1 : 0), match = target[idx], line = fold(lines[ln].text); + var offsetA = (reverse ? line.indexOf(match) + match.length : line.lastIndexOf(match)); + if (reverse ? offsetA >= pos.ch || offsetA != match.length + : offsetA <= pos.ch || offsetA != line.length - match.length) + return; + for (;;) { + if (reverse ? !ln : ln == lines.length - 1) return; + line = fold(lines[ln += reverse ? -1 : 1].text); + match = target[reverse ? --idx : ++idx]; + if (idx > 0 && idx < target.length - 1) { + if (line != match) return; + else continue; + } + var offsetB = (reverse ? line.lastIndexOf(match) : line.indexOf(match) + match.length); + if (reverse ? offsetB != line.length - match.length : offsetB != match.length) + return; + var start = {line: pos.line, ch: offsetA}, end = {line: ln, ch: offsetB}; + return {from: reverse ? end : start, to: reverse ? start : end}; + } + }; + } + } + + SearchCursor.prototype = { + findNext: function() {return this.find(false);}, + findPrevious: function() {return this.find(true);}, + + find: function(reverse) { + var self = this, pos = clipPos(reverse ? this.pos.from : this.pos.to); + function savePosAndFail(line) { + var pos = {line: line, ch: 0}; + self.pos = {from: pos, to: pos}; + self.atOccurrence = false; + return false; + } + + for (;;) { + if (this.pos = this.matches(reverse, pos)) { + this.atOccurrence = true; + return this.pos.match || true; + } + if (reverse) { + if (!pos.line) return savePosAndFail(0); + pos = {line: pos.line-1, ch: lines[pos.line-1].text.length}; + } + else { + if (pos.line == lines.length - 1) return savePosAndFail(lines.length); + pos = {line: pos.line+1, ch: 0}; + } + } + }, + + from: function() {if (this.atOccurrence) return copyPos(this.pos.from);}, + to: function() {if (this.atOccurrence) return copyPos(this.pos.to);} + }; + + return instance; + } // (end of function CodeShard) + + // The default configuration options. + CodeShard.defaults = { + value: "", + mode: null, + indentUnit: 2, + indentWithTabs: false, + tabMode: "classic", + enterMode: "indent", + electricChars: true, + onKeyEvent: null, + lineNumbers: false, + gutter: false, + shardWidth: 200, + firstLineNumber: 1, + readOnly: false, + onChange: null, + onCursorActivity: null, + onGutterClick: null, + onFocus: null, onBlur: null, onScroll: null, + matchBrackets: false, + workTime: 100, + workDelay: 200, + undoDepth: 40, + tabindex: null + }; + + // Known modes, by name and by MIME + var modes = {}, mimeModes = {}; + CodeShard.defineMode = function(name, mode) { + if (!CodeShard.defaults.mode && name != "null") CodeShard.defaults.mode = name; + modes[name] = mode; + }; + CodeShard.defineMIME = function(mime, spec) { + mimeModes[mime] = spec; + }; + CodeShard.getMode = function(options, spec) { + if (typeof spec == "string" && mimeModes.hasOwnProperty(spec)) + spec = mimeModes[spec]; + if (typeof spec == "string") + var mname = spec, config = {}; + else + var mname = spec.name, config = spec; + var mfactory = modes[mname]; + if (!mfactory) { + if (window.console) console.warn("No mode " + mname + " found, falling back to plain text."); + return CodeShard.getMode(options, "text/plain"); + } + return mfactory(options, config); + } + CodeShard.listModes = function() { + var list = []; + for (var m in modes) + if (modes.propertyIsEnumerable(m)) list.push(m); + return list; + }; + CodeShard.listMIMEs = function() { + var list = []; + for (var m in mimeModes) + if (mimeModes.propertyIsEnumerable(m)) list.push(m); + return list; + }; + + CodeShard.fromInputField = function(textfield, options) { + if (!options) options = {}; + options.value = textfield.value; + if (!options.tabindex && textfield.tabindex) + options.tabindex = textfield.tabindex; + + function save() {textfield.value = instance.getValue();} + if (textfield.form) { + // Deplorable hack to make the submit method do the right thing. + var rmSubmit = connect(textfield.form, "submit", save, true); + if (typeof textfield.form.submit == "function") { + var realSubmit = textfield.form.submit; + function wrappedSubmit() { + save(); + textfield.form.submit = realSubmit; + textfield.form.submit(); + textfield.form.submit = wrappedSubmit; + } + textfield.form.submit = wrappedSubmit; + } + } + + textfield.style.display = "none"; + var instance = CodeShard(function(node) { + textfield.parentNode.insertBefore(node, textfield.nextSibling); + }, options); + instance.save = save; + instance.toTextfield = function() { + save(); + textfield.parentNode.removeChild(instance.getWrapperElement()); + textfield.style.display = ""; + if (textfield.form) { + rmSubmit(); + if (typeof textfield.form.submit == "function") + textfield.form.submit = realSubmit; + } + }; + return instance; + }; + + // Utility functions for working with state. Exported because modes + // sometimes need to do this. + function copyState(mode, state) { + if (state === true) return state; + if (mode.copyState) return mode.copyState(state); + var nstate = {}; + for (var n in state) { + var val = state[n]; + if (val instanceof Array) val = val.concat([]); + nstate[n] = val; + } + return nstate; + } + CodeShard.startState = startState; + function startState(mode, a1, a2) { + return mode.startState ? mode.startState(a1, a2) : true; + } + CodeShard.copyState = copyState; + + // The character stream used by a mode's parser. + function StringStream(string) { + this.pos = this.start = 0; + this.string = string; + } + StringStream.prototype = { + eol: function() {return this.pos >= this.string.length;}, + sol: function() {return this.pos == 0;}, + peek: function() {return this.string.charAt(this.pos);}, + next: function() { + if (this.pos < this.string.length) + return this.string.charAt(this.pos++); + }, + eat: function(match) { + var ch = this.string.charAt(this.pos); + if (typeof match == "string") var ok = ch == match; + else var ok = ch && (match.test ? match.test(ch) : match(ch)); + if (ok) {++this.pos; return ch;} + }, + eatWhile: function(match) { + var start = this.start; + while (this.eat(match)){} + return this.pos > start; + }, + eatSpace: function() { + var start = this.pos; + while (/[\s\u00a0]/.test(this.string.charAt(this.pos))) ++this.pos; + return this.pos > start; + }, + skipToEnd: function() {this.pos = this.string.length;}, + skipTo: function(ch) { + var found = this.string.indexOf(ch, this.pos); + if (found > -1) {this.pos = found; return true;} + }, + backUp: function(n) {this.pos -= n;}, + column: function() {return countColumn(this.string, this.start);}, + indentation: function() {return countColumn(this.string);}, + match: function(pattern, consume, caseInsensitive) { + if (typeof pattern == "string") { + function cased(str) {return caseInsensitive ? str.toLowerCase() : str;} + if (cased(this.string).indexOf(cased(pattern), this.pos) == this.pos) { + if (consume !== false) this.pos += pattern.length; + return true; + } + } + else { + var match = this.string.slice(this.pos).match(pattern); + if (match && consume !== false) this.pos += match[0].length; + return match; + } + }, + current: function(){return this.string.slice(this.start, this.pos);} + }; + + // Line objects. These hold state related to a line, including + // highlighting info (the styles array). + function Line(text, styles) { + this.styles = styles || [text, null]; + this.stateAfter = null; + this.text = text; + this.marked = this.gutterMarker = this.className = null; + } + Line.prototype = { + // Replace a piece of a line, keeping the styles around it intact. + replace: function(from, to, text) { + var st = [], mk = this.marked; + copyStyles(0, from, this.styles, st); + if (text) st.push(text, null); + copyStyles(to, this.text.length, this.styles, st); + this.styles = st; + this.text = this.text.slice(0, from) + text + this.text.slice(to); + this.stateAfter = null; + if (mk) { + var diff = text.length - (to - from), end = this.text.length; + function fix(n) {return n <= Math.min(to, to + diff) ? n : n + diff;} + for (var i = 0; i < mk.length; ++i) { + var mark = mk[i], del = false; + if (mark.from >= end) del = true; + else {mark.from = fix(mark.from); if (mark.to != null) mark.to = fix(mark.to);} + if (del || mark.from >= mark.to) {mk.splice(i, 1); i--;} + } + } + }, + // Split a line in two, again keeping styles intact. + split: function(pos, textBefore) { + var st = [textBefore, null]; + copyStyles(pos, this.text.length, this.styles, st); + return new Line(textBefore + this.text.slice(pos), st); + }, + addMark: function(from, to, style) { + var mk = this.marked, mark = {from: from, to: to, style: style}; + if (this.marked == null) this.marked = []; + this.marked.push(mark); + this.marked.sort(function(a, b){return a.from - b.from;}); + return mark; + }, + removeMark: function(mark) { + var mk = this.marked; + if (!mk) return; + for (var i = 0; i < mk.length; ++i) + if (mk[i] == mark) {mk.splice(i, 1); break;} + }, + // Run the given mode's parser over a line, update the styles + // array, which contains alternating fragments of text and CSS + // classes. + highlight: function(mode, state) { + var stream = new StringStream(this.text), st = this.styles, pos = 0; + var changed = false, curWord = st[0], prevWord; + while (!stream.eol()) { + var style = mode.token(stream, state); + var substr = this.text.slice(stream.start, stream.pos); + stream.start = stream.pos; + if (pos && st[pos-1] == style) + st[pos-2] += substr; + else if (substr) { + if (!changed && (st[pos+1] != style || (pos && st[pos-2] != prevWord))) changed = true; + st[pos++] = substr; st[pos++] = style; + prevWord = curWord; curWord = st[pos]; + } + // Give up when line is ridiculously long + if (stream.pos > 5000) { + st[pos++] = this.text.slice(stream.pos); st[pos++] = null; + break; + } + } + if (st.length != pos) {st.length = pos; changed = true;} + if (pos && st[pos-2] != prevWord) changed = true; + return changed; + }, + // Fetch the parser token for a given character. Useful for hacks + // that want to inspect the mode state (say, for completion). + getTokenAt: function(mode, state, ch) { + var txt = this.text, stream = new StringStream(txt); + while (stream.pos < ch && !stream.eol()) { + stream.start = stream.pos; + var style = mode.token(stream, state); + } + return {start: stream.start, + end: stream.pos, + string: stream.current(), + className: style || null, + state: state}; + }, + indentation: function() {return countColumn(this.text);}, + // Produces an HTML fragment for the line, taking selection, + // marking, and highlighting into account. + getHTML: function(sfrom, sto, includePre, endAt) { + var html = []; + if (includePre) + html.push(this.className ? '': ""); + function span(text, style) { + if (!text) return; + if (style) html.push('', htmlEscape(text), ""); + else html.push(htmlEscape(text)); + } + var st = this.styles, allText = this.text, marked = this.marked; + if (sfrom == sto) sfrom = null; + var len = allText.length; + if (endAt != null) len = Math.min(endAt, len); + + if (!allText && endAt == null) + span(" ", sfrom != null && sto == null ? "CodeShard-selected" : null); + else if (!marked && sfrom == null) + for (var i = 0, ch = 0; ch < len; i+=2) { + var str = st[i], l = str.length; + if (ch + l > len) str = str.slice(0, len - ch); + ch += l; + span(str, st[i+1]); + } + else { + var pos = 0, i = 0, text = "", style, sg = 0; + var markpos = -1, mark = null; + function nextMark() { + if (marked) { + markpos += 1; + mark = (markpos < marked.length) ? marked[markpos] : null; + } + } + nextMark(); + while (pos < len) { + var upto = len; + var extraStyle = ""; + if (sfrom != null) { + if (sfrom > pos) upto = sfrom; + else if (sto == null || sto > pos) { + extraStyle = " CodeShard-selected"; + if (sto != null) upto = Math.min(upto, sto); + } + } + while (mark && mark.to != null && mark.to <= pos) nextMark(); + if (mark) { + if (mark.from > pos) upto = Math.min(upto, mark.from); + else { + extraStyle += " " + mark.style; + if (mark.to != null) upto = Math.min(upto, mark.to); + } + } + for (;;) { + var end = pos + text.length; + var apliedStyle = style; + if (extraStyle) apliedStyle = style ? style + extraStyle : extraStyle; + span(end > upto ? text.slice(0, upto - pos) : text, apliedStyle); + if (end >= upto) {text = text.slice(upto - pos); pos = upto; break;} + pos = end; + text = st[i++]; style = st[i++]; + } + } + if (sfrom != null && sto == null) span(" ", "CodeShard-selected"); + } + if (includePre) html.push(""); + return html.join(""); + } + }; + // Utility used by replace and split above + function copyStyles(from, to, source, dest) { + for (var i = 0, pos = 0, state = 0; pos < to; i+=2) { + var part = source[i], end = pos + part.length; + if (state == 0) { + if (end > from) dest.push(part.slice(from - pos, Math.min(part.length, to - pos)), source[i+1]); + if (end >= from) state = 1; + } + else if (state == 1) { + if (end > to) dest.push(part.slice(0, to - pos), source[i+1]); + else dest.push(part, source[i+1]); + } + pos = end; + } + } + + // The history object 'chunks' changes that are made close together + // and at almost the same time into bigger undoable units. + function History() { + this.time = 0; + this.done = []; this.undone = []; + } + History.prototype = { + addChange: function(start, added, old) { + this.undone.length = 0; + var time = +new Date, last = this.done[this.done.length - 1]; + if (time - this.time > 400 || !last || + last.start > start + added || last.start + last.added < start - last.added + last.old.length) + this.done.push({start: start, added: added, old: old}); + else { + var oldoff = 0; + if (start < last.start) { + for (var i = last.start - start - 1; i >= 0; --i) + last.old.unshift(old[i]); + last.added += last.start - start; + last.start = start; + } + else if (last.start < start) { + oldoff = start - last.start; + added += oldoff; + } + for (var i = last.added - oldoff, e = old.length; i < e; ++i) + last.old.push(old[i]); + if (last.added < added) last.added = added; + } + this.time = time; + } + }; + + // Event stopping compatibility wrapper. + function stopEvent() { + if (this.preventDefault) {this.preventDefault(); this.stopPropagation();} + else {this.returnValue = false; this.cancelBubble = true;} + } + // Ensure an event has a stop method. + function addStop(event) { + if (!event.stop) event.stop = stopEvent; + return event; + } + + // Event wrapper, exposing the few operations we need. + function Event(orig) {this.e = orig;} + Event.prototype = { + stop: function() {stopEvent.call(this.e);}, + target: function() {return this.e.target || this.e.srcElement;}, + button: function() { + if (this.e.which) return this.e.which; + else if (this.e.button & 1) return 1; + else if (this.e.button & 2) return 3; + else if (this.e.button & 4) return 2; + }, + pageX: function() { + if (this.e.pageX != null) return this.e.pageX; + else return this.e.clientX + document.body.scrollLeft + document.documentElement.scrollLeft; + }, + pageY: function() { + if (this.e.pageY != null) return this.e.pageY; + else return this.e.clientY + document.body.scrollTop + document.documentElement.scrollTop; + } + }; + + // Event handler registration. If disconnect is true, it'll return a + // function that unregisters the handler. + function connect(node, type, handler, disconnect) { + function wrapHandler(event) {handler(new Event(event || window.event));} + if (typeof node.addEventListener == "function") { + node.addEventListener(type, wrapHandler, false); + if (disconnect) return function() {node.removeEventListener(type, wrapHandler, false);}; + } + else { + node.attachEvent("on" + type, wrapHandler); + if (disconnect) return function() {node.detachEvent("on" + type, wrapHandler);}; + } + } + + function Delayed() {this.id = null;} + Delayed.prototype = {set: function(ms, f) {clearTimeout(this.id); this.id = setTimeout(f, ms);}}; + + // Some IE versions don't preserve whitespace when setting the + // innerHTML of a PRE tag. + var badInnerHTML = (function() { + var pre = document.createElement("pre"); + pre.innerHTML = " "; return !pre.innerHTML; + })(); + + var gecko = /gecko\/\d{7}/i.test(navigator.userAgent); + + var lineSep = "\n"; + // Feature-detect whether newlines in textfields are converted to \r\n + (function () { + var te = document.createElement("textarea"); + te.value = "foo\nbar"; + if (te.value.indexOf("\r") > -1) lineSep = "\r\n"; + }()); + + var tabSize = 8; + var mac = /Mac/.test(navigator.platform); + var movementKeys = {}; + for (var i = 35; i <= 40; ++i) + movementKeys[i] = movementKeys["c" + i] = true; + + // Counts the column offset in a string, taking tabs into account. + // Used mostly to find indentation. + function countColumn(string, end) { + if (end == null) { + end = string.search(/[^\s\u00a0]/); + if (end == -1) end = string.length; + } + for (var i = 0, n = 0; i < end; ++i) { + if (string.charAt(i) == "\t") n += tabSize - (n % tabSize); + else ++n; + } + return n; + } + + // Find the position of an element by following the offsetParent chain. + function eltOffset(node) { + var x = 0, y = 0, n2 = node; + for (var n = node; n; n = n.offsetParent) {x += n.offsetLeft; y += n.offsetTop;} + for (var n = node; n != document.body; n = n.parentNode) {x -= n.scrollLeft; y -= n.scrollTop;} + return {left: x, top: y}; + } + // Get a node's text content. + function eltText(node) { + return node.textContent || node.innerText || node.nodeValue || ""; + } + + // Operations on {line, ch} objects. + function posEq(a, b) {return a.line == b.line && a.ch == b.ch;} + function posLess(a, b) {return a.line < b.line || (a.line == b.line && a.ch < b.ch);} + function copyPos(x) {return {line: x.line, ch: x.ch};} + + function htmlEscape(str) { + return str.replace(/[<&]/g, function(str) {return str == "&" ? "&" : "<";}); + } + + // Used to position the cursor after an undo/redo by finding the + // last edited character. + function editEnd(from, to) { + if (!to) return from ? from.length : 0; + if (!from) return to.length; + for (var i = from.length, j = to.length; i >= 0 && j >= 0; --i, --j) + if (from.charAt(i) != to.charAt(j)) break; + return j + 1; + } + + function indexOf(collection, elt) { + if (collection.indexOf) return collection.indexOf(elt); + for (var i = 0, e = collection.length; i < e; ++i) + if (collection[i] == elt) return i; + return -1; + } + + // See if "".split is the broken IE version, if so, provide an + // alternative way to split lines. + if ("\n\nb".split(/\n/).length != 3) + var splitLines = function(string) { + var pos = 0, nl, result = []; + while ((nl = string.indexOf("\n", pos)) > -1) { + result.push(string.slice(pos, string.charAt(nl-1) == "\r" ? nl - 1 : nl)); + pos = nl + 1; + } + result.push(string.slice(pos)); + return result; + }; + else + var splitLines = function(string){return string.split(/\r?\n/);}; + + // Sane model of finding and setting the selection in a textfield + if (window.getSelection) { + var selRange = function(te) { + try {return {start: te.selectionStart, end: te.selectionEnd};} + catch(e) {return null;} + }; + var setSelRange = function(te, start, end) { + try {te.setSelectionRange(start, end);} + catch(e) {} // Fails on Firefox when textfield isn't part of the document + }; + } + // IE model. Don't ask. + else { + var selRange = function(te) { + try {var range = document.selection.createRange();} + catch(e) {return null;} + if (!range || range.parentElement() != te) return null; + var val = te.value, len = val.length, localRange = te.createTextRange(); + localRange.moveToBookmark(range.getBookmark()); + var endRange = te.createTextRange(); + endRange.collapse(false); + + if (localRange.compareEndPoints("StartToEnd", endRange) > -1) + return {start: len, end: len}; + + var start = -localRange.moveStart("character", -len); + for (var i = val.indexOf("\r"); i > -1 && i < start; i = val.indexOf("\r", i+1), start++) {} + + if (localRange.compareEndPoints("EndToEnd", endRange) > -1) + return {start: start, end: len}; + + var end = -localRange.moveEnd("character", -len); + for (var i = val.indexOf("\r"); i > -1 && i < end; i = val.indexOf("\r", i+1), end++) {} + return {start: start, end: end}; + }; + var setSelRange = function(te, start, end) { + var range = te.createTextRange(); + range.collapse(true); + var endrange = range.duplicate(); + var newlines = 0, txt = te.value; + for (var pos = txt.indexOf("\n"); pos > -1 && pos < start; pos = txt.indexOf("\n", pos + 1)) + ++newlines; + range.move("character", start - newlines); + for (; pos > -1 && pos < end; pos = txt.indexOf("\n", pos + 1)) + ++newlines; + endrange.move("character", end - newlines); + range.setEndPoint("EndToEnd", endrange); + range.select(); + }; + } + + CodeShard.defineMode("null", function() { + return {token: function(stream) {stream.skipToEnd();}}; + }); + CodeShard.defineMIME("text/plain", "null"); + + return CodeShard; +})(); diff --git a/htdocs/codemirror2/lib/overlay.js b/htdocs/codemirror2/lib/overlay.js new file mode 100644 index 000000000..c4cdf9fc8 --- /dev/null +++ b/htdocs/codemirror2/lib/overlay.js @@ -0,0 +1,51 @@ +// Utility function that allows modes to be combined. The mode given +// as the base argument takes care of most of the normal mode +// functionality, but a second (typically simple) mode is used, which +// can override the style of text. Both modes get to parse all of the +// text, but when both assign a non-null style to a piece of code, the +// overlay wins, unless the combine argument was true, in which case +// the styles are combined. + +CodeMirror.overlayParser = function(base, overlay, combine) { + return { + startState: function() { + return { + base: CodeMirror.startState(base), + overlay: CodeMirror.startState(overlay), + basePos: 0, baseCur: null, + overlayPos: 0, overlayCur: null + }; + }, + copyState: function(state) { + return { + base: CodeMirror.copyState(base, state.base), + overlay: CodeMirror.copyState(overlay, state.overlay), + basePos: state.basePos, baseCur: null, + overlayPos: state.overlayPos, overlayCur: null + }; + }, + + token: function(stream, state) { + if (stream.start == state.basePos) { + state.baseCur = base.token(stream, state.base); + state.basePos = stream.pos; + } + if (stream.start == state.overlayPos) { + stream.pos = stream.start; + state.overlayCur = overlay.token(stream, state.overlay); + state.overlayPos = stream.pos; + } + stream.pos = Math.min(state.basePos, state.overlayPos); + if (stream.eol()) state.basePos = state.overlayPos = 0; + + if (state.overlayCur == null) return state.baseCur; + if (state.baseCur != null && combine) return state.baseCur + " " + state.overlayCur; + else return state.overlayCur; + }, + + indent: function(state, textAfter) { + return base.indent(state.base, textAfter); + }, + electricChars: base.electricChars + }; +}; diff --git a/htdocs/codemirror2/manual.html b/htdocs/codemirror2/manual.html new file mode 100644 index 000000000..e633ec311 --- /dev/null +++ b/htdocs/codemirror2/manual.html @@ -0,0 +1,779 @@ + + + + CodeMirror: User Manual + + + + + + +

{ } CodeMirror

+ +
+/* User manual and
+   reference guide */
+
+ +
+ +

Overview

+ +

CodeMirror is a code-editor component that can be embedded in + Web pages. It provides only the editor component, no + accompanying buttons + (see CodeMirror + UI for a drop-in button bar), auto-completion, or other IDE + functionality. It does provide a rich API on top of which such + functionality can be straightforwardly implemented.

+ +

CodeMirror works with language-specific modes. Modes are + JavaScript programs that help color (and optionally indent) text + written in a given language. The distribution comes with a few + modes (see the mode/ directory), and it isn't hard + to write new ones for other languages.

+ +

Basic Usage

+ +

The easiest way to use CodeMirror is to simply load the script + and style sheet found under lib/ in the distribution, + plus the script and style sheet for the mode(s) you want to use. + (See also the compresion helper.) For + example:

+ +
<script src="lib/codemirror.js"></script>
+<link rel="stylesheet" href="lib/codemirror.css">
+<script src="mode/javascript/javascript.js"></script>
+<link rel="stylesheet" href="mode/javascript/javascript.css">
+ +

Having done this, an editor instance can be created like + this:

+ +
var myCodeMirror = CodeMirror(document.body);
+ +

The editor will be appended to the document body, will start + empty, and will use the mode that we loaded. To have more control + over the new editor, a configuration object can be passed + to CodeMirror as a second argument:

+ +
var myCodeMirror = CodeMirror(document.body, {
+  value: "function myScript(){return 100;}\n",
+  mode:  "javascript"
+});
+ +

This will initialize the editor with a piece of code already in + it, and explicitly tell it to use the JavaScript mode (which is + useful when multiple modes are loaded). + See below for a full discussion of the + configuration options that CodeMirror accepts.

+ +

In cases where you don't want to append the editor to an + element, and need more control over the way it is inserted, the + first argument to the CodeMirror function can also + be a function that, when given a DOM element, inserts it into the + document somewhere. This could be used to, for example, replace a + textarea with a real editor:

+ +
var myCodeMirror = CodeMirror(function(elt) {
+  myTextArea.parentNode.replaceChild(myTextArea, elt);
+}, {value: myTextArea.value});
+ +

However, for this use case, which is a common way to use + CodeMirror, the library provides a much more powerful + shortcut:

+ +
var myCodeMirror = CodeMirror.fromTextArea(myTextArea);
+ +

This will, among other things, ensure that the textarea's value + is updated when the form (if it is part of a form) is submitted. + See the API reference for a full + description of this method.

+ +

Configuration

+ +

Both the CodeMirror function and + its fromTextArea method take as second (optional) + argument an object containing configuration options. Any option + not supplied like this will be taken + from CodeMirror.defaults, an object containing the + default options. You can update this object to change the defaults + on your page.

+ +

Options are not checked in any way, so setting bogus option + values is bound to lead to odd errors.

+ +

Note: CodeMirror + 2 does not support + line-wrapping. I would have very much liked to support it, but it + combines extremely poorly with the way the editor is + implemented.

+ +

These are the supported options:

+ +
+
value (string)
+
The starting value of the editor.
+ +
mode (string or object)
+
The mode to use. When not given, this will default to the + first mode that was loaded. It may be a string, which either + simply names the mode or is + a MIME type + associated with the mode. Alternatively, it may be an object + containing configuration options for the mode, with + a name property that names the mode (for + example {name: "javascript", json: true}). The demo + pages for each mode contain information about what configuration + parameters the mode supports. You can ask CodeMirror which modes + and MIME types are loaded with + the CodeMirror.listModes + and CodeMirror.listMIMEs functions.
+ +
indentUnit (integer)
+
How many spaces a block (whatever that means in the edited + language) should be indented. The default is 2.
+ +
indentWithTabs (boolean)
+
Whether, when indenting, the first N*8 spaces should be + replaced by N tabs. Default is false.
+ +
tabMode (string)
+
Determines what happens when the user presses the tab key. + Must be one of the following: +
+
"classic" (the default)
+
When nothing is selected, insert a tab. Otherwise, + behave like the "shift" mode. (When shift is + held, this behaves like the "indent" mode.)
+
"shift"
+
Indent all selected lines by + one indentUnit. + If shift was held while pressing tab, un-indent all selected + lines one unit.
+
"indent"
+
Indent the line the 'correctly', based on its syntactic + context. Only works if the + mode supports it.
+
"default"
+
Do not capture tab presses, let the browser apply its + default behaviour (which usually means it skips to the next + control).
+
+ +
enterMode (string)
+
Determines whether and how new lines are indented when the + enter key is pressed. The following modes are supported: +
+
"indent" (the default)
+
Use the mode's indentation rules to give the new line + the correct indentation.
+
"keep"
+
Indent the line the same as the previous line.
+
"flat"
+
Do not indent the new line.
+
+ +
electricChars (boolean)
+
Configures whether the editor should re-indent the current + line when a character is typed that might change its proper + indentation (only works if the mode supports indentation). + Default is true.
+ +
lineNumbers (boolean)
+
Whether to show line numbers to the left of the editor.
+ +
firstLineNumber (integer)
+
At which number to start counting lines. Default is 1.
+ +
gutter (boolean)
+
Can be used to force a 'gutter' (empty space on the left of + the editor) to be shown even when no line numbers are active. + This is useful for setting markers.
+ +
readOnly (boolean)
+
This disables editing of the editor content by the user. + (Changes through API functions will still be possible.)
+ +
onChange (function)
+
When given, this function will be called every time the + content of the editor is changed. It will be given the editor + instance as only argument.
+ +
onCursorActivity (function)
+
Like onChange, but will also be called when the + cursor moves without any changes being made.
+ +
onGutterClick (function)
+
When given, will be called whenever the editor gutter (the + line-number area) is clicked. Will be given the editor instance + as first argument, and the (zero-based) number of the line that + was clicked as second argument.
+ +
onFocus, onBlur (function)
+
The given functions will be called whenever the editor is + focused or unfocused.
+ +
onScroll (function)
+
When given, will be called whenever the editor is + scrolled.
+ +
matchBrackets (boolean)
+
Determines whether brackets are matched whenever the cursor + is moved next to a bracket.
+ +
workTime, workDelay (number)
+
Highlighting is done by a pseudo background-thread that will + work for workTime milliseconds, and then use + timeout to sleep for workDelay milliseconds. The + defaults are 200 and 300, you can change these options to make + the highlighting more or less aggressive.
+ +
undoDepth (integer)
+
The maximum number of undo levels that the editor stores. + Defaults to 40.
+ +
tabindex (integer)
+
The tab + index to assign to the editor. If not given, no tab index + will be assigned.
+ +
onKeyEvent (function)
+
This provides a rather low-level hook into CodeMirror's key + handling. If provided, this function will be called on + every keydown and keypress event that + CodeMirror captures. It will be passed two arguments, the editor + instance and the key event. This key event is pretty much the + raw key event, except that a stop() method is + always added to it. You could feed it to, for + example, jQuery.Event to further normalize + it.
This function can inspect the key event, and handle it if + it wants to. It may return true to tell CodeMirror to ignore the + event. Be wary that, on some browsers, stopping + a keydown does not stop the keypress + from firing, whereas on others it does. If you respond to an + event, you should probably inspect its type + property and only do something when it is keydown + (or keypress for actions that need character + data).
+
+ +

Customized Styling

+ +

Up to a certain extent, CodeMirror's look can be changed by + modifying style sheet files. The style sheets supplied by modes + simply provide the colors for that mode, and can be adapted in a + very straightforward way. To style the editor itself, it is + possible to alter or override the styles defined + in codemirror.css.

+ +

Some care must be taken there, since a lot of the rules in this + file are necessary to have CodeMirror function properly. Adjusting + colors should be safe, of course, and with some care a lot of + other things can be changed as well. The CSS classes defined in + this file serve the following roles:

+ +
+
CodeMirror
+
The outer element of the editor. This determines whether the + editor scrolls (overflow: auto + fixed height). Can + also be used to set styles that should hold for everything + inside the editor, or to set a background.
+ +
CodeMirror-focused
+
Whenever the editor is focused, the top element gets this + class. This is used to hide the cursor and give the selection a + different color when the editor is not focused.
+ +
CodeMirror-gutter
+
Use this for giving a background or a border to the editor + gutter. Don't set any padding here, + use CodeMirror-gutter-text for that. By default, + the gutter is 'fluid', meaning it will adjust its width to the + maximum line number or line marker width. You can also set a + fixed width if you want.
+ +
CodeMirror-gutter-text
+
Used to style the actual line numbers. For the numbers to + line up, you'll want this style to use exactly the same font and + vertical padding as normal edited text, as per + the CodeMirror-lines class.
+ +
CodeMirror-lines
+
The visible lines. If this has vertical + padding, CodeMirror-gutter should have the same + padding.
+ +
CodeMirror-cursor
+
The cursor is a block element that is absolutely positioned. + You can make it look whichever way you want.
+ +
CodeMirror-selected
+
The selection is represented by span elements + with this class.
+ +
CodeMirror-matchingbracket, + CodeMirror-matchingbracket
+
These are used to style matched (or unmatched) brackets.
+
+ +

The actual lines, as well as the cursor, are represented + by pre elements. By default no text styling (such as + bold) that might change line height is applied. If you do want + such effects, you'll have to give CodeMirror pre a + fixed height. Also, you must still take care that character width + is constant.

+ +

If your page's style sheets do funky things to + all div or pre elements (you probably + shouldn't do that), you'll have to define rules to cancel these + effects out again for elements under the CodeMirror + class.

+ +

Programming API

+ +

A lot of CodeMirror features are only available through its API. + This has the disadvantage that you need to do work to enable them, + and the advantage that CodeMirror will fit seamlessly into your + application.

+ +

Whenever points in the document are represented, the API uses + objects with line and ch properties. + Both are zero-based. CodeMirror makes sure to 'clip' any positions + passed by client code so that they fit inside the document, so you + shouldn't worry too much about sanitizing your coordinates. If you + give ch a value of null, or don't + specify it, it will be replaced with the length of the specified + line.

+ +
+
getValue() → string
+
Get the current editor content.
+
setValue(string)
+
Set the editor content.
+ +
getSelection() → string
+
Get the currently selected code.
+
replaceSelection(string)
+
Replace the selection with the given string.
+ +
focus()
+
Give the editor focus.
+ +
setOption(option, value)
+
Change the configuration of the editor. option + should the name of an option, + and value should be a valid value for that + option.
+
getOption(option) → value
+
Retrieves the current value of the given option for this + editor instance.
+ +
cursorCoords(start) → object
+
Returns an {x, y, yBot} object containing the + coordinates of the cursor relative to the top-left corner of the + page. yBot is the coordinate of the bottom of the + cursor. start is a boolean indicating whether you + want the start or the end of the selection.
+
charCoords(pos) → object
+
Like cursorCoords, but returns the position of + an arbitrary characters. pos should be + a {line, ch} object.
+
coordsChar(object) → pos
+
Given an {x, y} object (in page coordinates), + returns the {line, ch} position that corresponds to + it.
+ +
undo()
+
Undo one edit (if any undo events are stored).
+
redo()
+
Redo one undone edit.
+
historySize() → object
+
Returns an object with {undo, redo} properties, + both of which hold integers, indicating the amount of stored + undo and redo operations.
+ +
indentLine(line)
+
Reset the given line's indentation to the indentation + prescribed by the mode.
+ +
getSearchCursor(query, start, caseFold) → cursor
+
Used to implement search/replace + functionality. query can be a regular expression or + a string (only strings will match across lines—if they contain + newlines). start provides the starting position of + the search. It can be a {line, ch} object, or can + be left off to default to the start of the + document. caseFold is only relevant when matching a + string. It will cause the search to be case-insensitive. A + search cursor has the following methods: +
+
findNext(), findPrevious() → boolean
+
Search forward or backward from the current position. + The return value indicates whether a match was found. If + matching a regular expression, the return value will be the + array returned by the match method, in case you + want to extract matched groups.
+
from(), to() → object
+
These are only valid when the last call + to findNext or findPrevious did + not return false. They will return {line, ch} + objects pointing at the start and end of the match.
+
+ +
getTokenAt(pos) → object
+
Retrieves information about the token the current mode found + at the given position (a {line, ch} object). The + returned object has the following properties: +
+
start
The character (on the given line) at which the token starts.
+
end
The character at which the token ends.
+
string
The token's string.
+
className
The class the mode assigned + to the token. (Can be null when no class was assigned.)
+
+ +
markText(from, to, className) → function
+
Can be used to mark a range of text with a specific CSS + class name. from and to should + be {line, ch} objects. The method will return a + function that can be called to remove the marking.
+ +
setMarker(line, text, className) → lineHandle
+
Add a gutter marker for the given line. Gutter markers are + shown in the line-number area (instead of the number for this + line). Both text and className are + optional. Setting text to a Unicode character like + ● tends to give a nice effect. To put a picture in the gutter, + set text to a space and className to + something that sets a background image. If you + specify text, the given text (which may contain + HTML) will, by default, replace the line number for that line. + If this is not what you want, you can include the + string %N% in the text, which will be replaced by + the line number.
+
clearMarker(line)
+
Clears a marker created + with setMarker. line can be either a + number or a handle returned by setMarker (since a + number may now refer to a different line if something was added + or deleted).
+
setLineClass(line, className) → lineHandle
+
Set a CSS class name for the given line. line + can be a number or a line handle (as returned + by setMarker or this function). + Pass null to clear the class for a line.
+ +
lineInfo(line) → object
+
Returns the line number, text content, and marker status of + the given line, which can be either a number or a handle + returned by setMarker. The returned object has the + structure {line, text, markerText, markerClass}.
+ +
addWidget(pos, node, scrollIntoView)
+
Puts node, which should be an absolutely + positioned DOM node, into the editor, positioned right below the + given {line, ch} position. + When scrollIntoView is true, the editor will ensure + that the entire node is visible (if possible). To remove the + widget again, simply use DOM methods (move it somewhere else, or + call removeChild on its parent).
+ +
matchBrackets()
+
Force matching-bracket-highlighting to happen.
+ +
lineCount() → number
+
Get the number of lines in the editor.
+ +
getCursor(start) → object
+
start is a boolean indicating whether the start + or the end of the selection must be retrieved. If it is not + given, the current cursor pos, i.e. the side of the selection + that would move if you pressed an arrow key, is chosen. + A {line, ch} object will be returned.
+
somethingSelected() → boolean
+
Return true if any text is selected.
+
setCursor(pos)
+
Set the cursor position. You can either pass a + single {line, ch} object, or the line and the + character as two separate parameters.
+
setSelection(start, end)
+
Set the selection range. start + and end should be {line, ch} objects.
+ +
getLine(n) → string
+
Get the content of line n.
+
setLine(n, text)
+
Set the content of line n.
+
removeLine(n)
+
Remove the given line from the document.
+ +
getRange(from, to) → string +
Get the text between the given points in the editor, which + should be {line, ch} objects.
+
replaceRange(string, from, to)
+
Replace the part of the document between from + and to with the given string. from + and to must be {line, ch} + objects. to can be left off to simply insert the + string at position from.
+
+ +

The following are more low-level methods:

+ +
+
operation(func) → result
+
CodeMirror internally buffers changes and only updates its + DOM structure after it has finished performing some operation. + If you need to perform a lot of operations on a CodeMirror + instance, you can call this method with a function argument. It + will call the function, buffering up all changes, and only doing + the expensive update after the function returns. This can be a + lot faster. The return value from this method will be the return + value of your function.
+ +
refresh()
+
If your code does something to change the size of the editor + element (window resizes are already listened for), or unhides + it, you should probably follow up by calling this method to + ensure CodeMirror is still looking as intended.
+ +
getInputField() → textarea
+
Returns the hiden textarea used to read input.
+
getWrapperElement() → node
+
Returns the DOM node that represents the editor. Remove this + from your tree to delete an editor instance.
+
+ +

Finally, the CodeMirror object + itself has a method fromTextArea. This takes a + textarea DOM node as first argument and an optional configuration + object as second. It will replace the textarea with a CodeMirror + instance, and wire up the form of that textarea (if any) to make + sure the editor contents are put into the textarea when the form + is submitted. A CodeMirror instance created this way has two + additional methods:

+ +
+
save()
+
Copy the content of the editor into the textarea.
+ +
toTextArea()
+
Remove the editor, and restore the original textarea (with + the editor's current content).
+
+ +

Writing CodeMirror Modes

+ +

Modes typically consist of a JavaScript file and a CSS file. + The CSS file (see, for + example javascript.css) + defines the classes that will be used to style the syntactic + elements of the code, and the script contains the logic to + actually assign these classes to the right pieces of text.

+ +

You'll usually want to use some kind of prefix for your CSS + classes, so that they are unlikely to clash with other classes, + both those used by other modes and those defined by the page in + which CodeMirror is embedded.

+ +

The mode script should + call CodeMirror.defineMode to register itself with + CodeMirror. This function takes two arguments. The first should be + the name of the mode, for which you should use a lowercase string, + preferably one that is also the name of the files that define the + mode (i.e. "xml" is defined xml.js). The + second argument should be a function that, given a CodeMirror + configuration object (the thing passed to + the CodeMirror function) and a mode configuration + object (as in the mode + option), returns a mode object.

+ +

Typically, you should use this second argument + to defineMode as your module scope function (modes + should not leak anything into the global scope!), i.e. write your + whole mode inside this function.

+ +

The main responsibility of a mode script is parsing + the content of the editor. Depending on the language and the + amount of functionality desired, this can be done in really easy + or extremely complicated ways. Some parsers can be stateless, + meaning that they look at one element (token) of the code + at a time, with no memory of what came before. Most, however, will + need to remember something. This is done by using a state + object, which is an object that can be mutated every time a + new token is read.

+ +

Modes that use a state must define + a startState method on their mode object. This is a + function of no arguments that produces a state object to be used + at the start of a document.

+ +

The most important part of a mode object is + its token(stream, state) method. All modes must + define this method. It should read one token from the stream it is + given as an argument, optionally update its state, and return a + CSS class string, or null for tokens that do not have + to be styled.

+ +

The stream object encapsulates a line of code + (tokens may never span lines) and our current position in that + line. It has the following API:

+ +
+
eol() → boolean
+
Returns true only if the stream is at the end of the + line.
+
sol() → boolean
+
Returns true only if the stream is at the start of the + line.
+ +
peek() → character
+
Returns the next character in the stream without advancing + it. Will return undefined at the end of the + line.
+
next() → character
+
Returns the next character in the stream and advances it. + Also returns undefined when no more characters are + available.
+ +
eat(match) → character
+
match can be a character, a regular expression, + or a function that takes a character and returns a boolean. If + the next character in the stream 'matches' the given argument, + it is consumed and returned. Otherwise, undefined + is returned.
+
eatWhile(match) → boolean
+
Repeatedly calls eat with the given argument, + until it fails. Returns true if any characters were eaten.
+
eatSpace() → boolean
+
Shortcut for eatWhile when matching + white-space.
+
skipToEnd()
+
Moves the position to the end of the line.
+
skipTo(ch) → boolean
+
Skips to the next occurrence of the given character, if + found. Returns true if the character was found.
+
match(pattern, consume, caseFold) → boolean
+
Act like a + multi-character eat—if consume is true + or not given—or a look-ahead that doesn't update the stream + position—if it is false. pattern can be either a + string or a regular expression starting with ^. + When it is a string, caseFold can be set to true to + make the match case-insensitive. When successfully matching a + regular expression, the returned value will be the array + returned by match, in case you need to extract + matched groups.
+ +
backUp(n)
+
Backs up the stream n characters. Backing it up + further than the start of the current token will cause things to + break, so be careful.
+
column() → integer
+
Returns the column (taking into account tabs) at which the + current token starts. Can be used to find out whether a token + starts a new line.
+
indentation() → integer
+
Tells you how far the current line has been indented, in + spaces. Corrects for tab characters.
+ +
current() → string
+
Get the string between the start of the current token and + the current stream position.
+
+ +

Because state object are mutated, and CodeMirror + needs to keep valid versions of a state around so that it can + restart a parse at any line, copies must be made of state objects. + The default algorithm used is that a new state object is created, + which gets all the properties of the old object. Any properties + which hold arrays get a copy of these arrays (since arrays tend to + be used as mutable stacks). When this is not correct, for example + because a mode mutates non-array properties of its state object, a + mode object should define a copyState method, + which is given a state and should return a safe copy of that + state.

+ +

If you want your mode to provide smart indentation + (see entermode + and tabMode when they + have a value of "indent"), you must define + an indent(state, textAfter) method on your mode + object.

+ +

The indentation method should inspect the given state object, + and optionally the textAfter string, which contains + the text on the line that is being indented, and return an + integer, the amount of spaces to indent. It should usually take + the indentUnit + option into account.

+ +

Finally, a mode may define + an electricChars property, which should hold a string + containing all the characters that should trigger the behaviour + described for + the electricChars + option.

+ +

So, to summarize, a mode must provide + a token method, and it may + provide startState, copyState, + and indent methods. For an example of a trivial mode, + see the diff mode, for a more + involved example, see + the JavaScript + mode.

+ +

Sometimes, it is useful for modes to nest—to have one + mode delegate work to another mode. An example of this kind of + mode is the mixed-mode HTML + mode. To implement such nesting, it is usually necessary to + create mode objects and copy states yourself. To create a mode + object, there are CodeMirror.getMode(options, + parserConfig), where the first argument is a configuration + object as passed to the mode constructor function, and the second + argument is a mode specification as in + the mode option. To copy a + state object, call CodeMirror.copyState(mode, state), + where mode is the mode that created the given + state.

+ +

To make indentation work properly in a nested parser, it is + advisable to give the startState method of modes that + are intended to be nested an optional argument that provides the + base indentation for the block of code. The JavaScript and CSS + parser do this, for example, to allow JavaScript and CSS code + inside the mixed-mode HTML mode to be properly indented.

+ +

Finally, it is possible to associate your mode, or a certain + configuration of your mode, with + a MIME type. For + example, the JavaScript mode associates itself + with text/javascript, and its JSON variant + with application/json. To do this, + call CodeMirror.defineMIME(mime, modeSpec), + where modeSpec can be a string or object specifying a + mode, as in the mode + option.

+ +
+ +
 
+ + + + + diff --git a/htdocs/codemirror2/mode/clike/clike.css b/htdocs/codemirror2/mode/clike/clike.css new file mode 100644 index 000000000..052010f9d --- /dev/null +++ b/htdocs/codemirror2/mode/clike/clike.css @@ -0,0 +1,7 @@ +span.c-like-keyword {color: #90b;} +span.c-like-number {color: #291;} +span.c-like-comment {color: #a70;} +span.c-like-string {color: #a22;} +span.c-like-preprocessor {color: #049;} +span.c-like-var {color: #22b;} +span.c-like-annotation {color: #666;} diff --git a/htdocs/codemirror2/mode/clike/clike.js b/htdocs/codemirror2/mode/clike/clike.js new file mode 100644 index 000000000..73f418e70 --- /dev/null +++ b/htdocs/codemirror2/mode/clike/clike.js @@ -0,0 +1,187 @@ +CodeMirror.defineMode("clike", function(config, parserConfig) { + var indentUnit = config.indentUnit, keywords = parserConfig.keywords, + cpp = parserConfig.useCPP, multiLineStrings = parserConfig.multiLineStrings, + $vars = parserConfig.$vars, atAnnotations = parserConfig.atAnnotations; + var isOperatorChar = /[+\-*&%=<>!?|]/; + + function chain(stream, state, f) { + state.tokenize = f; + return f(stream, state); + } + + var type; + function ret(tp, style) { + type = tp; + return style; + } + + function tokenBase(stream, state) { + var ch = stream.next(); + if (ch == '"' || ch == "'") + return chain(stream, state, tokenString(ch)); + else if (/[\[\]{}\(\),;\:\.]/.test(ch)) + return ret(ch); + else if (ch == "#" && cpp && state.startOfLine) { + stream.skipToEnd(); + return ret("directive", "c-like-preprocessor"); + } + else if (/\d/.test(ch)) { + stream.eatWhile(/[\w\.]/) + return ret("number", "c-like-number"); + } + else if (ch == "/") { + if (stream.eat("*")) { + return chain(stream, state, tokenComment); + } + else if (stream.eat("/")) { + stream.skipToEnd(); + return ret("comment", "c-like-comment"); + } + else { + stream.eatWhile(isOperatorChar); + return ret("operator"); + } + } + else if (isOperatorChar.test(ch)) { + stream.eatWhile(isOperatorChar); + return ret("operator"); + } + else if (atAnnotations && ch == "@") { + stream.eatWhile(/[\w\$_]/); + return ret("annotation", "c-like-annotation"); + } + else if ($vars && ch == "$") { + stream.eatWhile(/[\w\$_]/); + return ret("word", "c-like-var"); + } + else { + stream.eatWhile(/[\w\$_]/); + if (keywords && keywords.propertyIsEnumerable(stream.current())) return ret("keyword", "c-like-keyword"); + return ret("word", "c-like-word"); + } + } + + function tokenString(quote) { + return function(stream, state) { + var escaped = false, next, end = false; + while ((next = stream.next()) != null) { + if (next == quote && !escaped) {end = true; break;} + escaped = !escaped && next == "\\"; + } + if (end || !(escaped || multiLineStrings)) + state.tokenize = tokenBase; + return ret("string", "c-like-string"); + }; + } + + function tokenComment(stream, state) { + var maybeEnd = false, ch; + while (ch = stream.next()) { + if (ch == "/" && maybeEnd) { + state.tokenize = tokenBase; + break; + } + maybeEnd = (ch == "*"); + } + return ret("comment", "c-like-comment"); + } + + function Context(indented, column, type, align, prev) { + this.indented = indented; + this.column = column; + this.type = type; + this.align = align; + this.prev = prev; + } + + function pushContext(state, col, type) { + return state.context = new Context(state.indented, col, type, null, state.context); + } + function popContext(state) { + return state.context = state.context.prev; + } + + // Interface + + return { + startState: function(basecolumn) { + return { + tokenize: tokenBase, + context: new Context((basecolumn || 0) - indentUnit, 0, "top", false), + indented: 0, + startOfLine: true + }; + }, + + token: function(stream, state) { + var ctx = state.context; + if (stream.sol()) { + if (ctx.align == null) ctx.align = false; + state.indented = stream.indentation(); + state.startOfLine = true; + } + if (stream.eatSpace()) return null; + var style = state.tokenize(stream, state); + if (type == "comment") return style; + if (ctx.align == null) ctx.align = true; + + if ((type == ";" || type == ":") && ctx.type == "statement") popContext(state); + else if (type == "{") pushContext(state, stream.column(), "}"); + else if (type == "[") pushContext(state, stream.column(), "]"); + else if (type == "(") pushContext(state, stream.column(), ")"); + else if (type == "}") { + if (ctx.type == "statement") ctx = popContext(state); + if (ctx.type == "}") ctx = popContext(state); + if (ctx.type == "statement") ctx = popContext(state); + } + else if (type == ctx.type) popContext(state); + else if (ctx.type == "}" || ctx.type == "top") pushContext(state, stream.column(), "statement"); + state.startOfLine = false; + return style; + }, + + indent: function(state, textAfter) { + if (state.tokenize != tokenBase) return 0; + var firstChar = textAfter && textAfter.charAt(0), ctx = state.context, closing = firstChar == ctx.type; + if (ctx.type == "statement") return ctx.indented + (firstChar == "{" ? 0 : indentUnit); + else if (ctx.align) return ctx.column + (closing ? 0 : 1); + else return ctx.indented + (closing ? 0 : indentUnit); + }, + + electricChars: "{}" + }; +}); + +(function() { + function keywords(str) { + var obj = {}, words = str.split(" "); + for (var i = 0; i < words.length; ++i) obj[words[i]] = true; + return obj; + } + var cKeywords = "auto if break int case long char register continue return default short do sizeof " + + "double static else struct entry switch extern typedef float union for unsigned " + + "goto while enum void const signed volatile"; + + CodeMirror.defineMIME("text/x-csrc", { + name: "clike", + useCPP: true, + keywords: keywords(cKeywords) + }); + CodeMirror.defineMIME("text/x-c++src", { + name: "clike", + useCPP: true, + keywords: keywords(cKeywords + " asm dynamic_cast namespace reinterpret_cast try bool explicit new " + + "static_cast typeid catch false operator template typename class friend private " + + "this using const_cast inline public throw virtual delete mutable protected true " + + "wchar_t") + }); + CodeMirror.defineMIME("text/x-java", { + name: "clike", + atAnnotations: true, + keywords: keywords("abstract assert boolean break byte case catch char class const continue default " + + "do double else enum extends false final finally float for goto if implements import " + + "instanceof int interface long native new null package private protected public " + + "return short static strictfp super switch synchronized this throw throws transient " + + "true try void volatile while") + }); +}()); diff --git a/htdocs/codemirror2/mode/clike/index.html b/htdocs/codemirror2/mode/clike/index.html new file mode 100644 index 000000000..0836535d2 --- /dev/null +++ b/htdocs/codemirror2/mode/clike/index.html @@ -0,0 +1,101 @@ + + + + CodeMirror 2: C-like mode + + + + + + + + +

CodeMirror 2: C-like mode

+ +
+ + + +

Simple mode that tries to handle C-like languages as well as it + can. Takes two configuration parameters: keywords, an + object whose property names are the keywords in the language, + and useCPP, which determines whether C preprocessor + directives are recognized.

+ +

MIME types defined: text/x-csrc + (C code), text/x-c++src (C++ + code), text/x-java (Java code).

+ + diff --git a/htdocs/codemirror2/mode/css/css.css b/htdocs/codemirror2/mode/css/css.css new file mode 100644 index 000000000..02d40ecb2 --- /dev/null +++ b/htdocs/codemirror2/mode/css/css.css @@ -0,0 +1,9 @@ +span.css-at {color: #708;} +span.css-unit {color: #281;} +span.css-value {color: #708;} +span.css-identifier {color: black;} +span.css-selector {color: #11B;} +span.css-important {color: #00F;} +span.css-colorcode {color: #299;} +span.css-comment {color: #A70;} +span.css-string {color: #A22;} diff --git a/htdocs/codemirror2/mode/css/css.js b/htdocs/codemirror2/mode/css/css.js new file mode 100644 index 000000000..5faad7b2f --- /dev/null +++ b/htdocs/codemirror2/mode/css/css.js @@ -0,0 +1,124 @@ +CodeMirror.defineMode("css", function(config) { + var indentUnit = config.indentUnit, type; + function ret(style, tp) {type = tp; return style;} + + function tokenBase(stream, state) { + var ch = stream.next(); + if (ch == "@") {stream.eatWhile(/\w/); return ret("css-at", stream.current());} + else if (ch == "/" && stream.eat("*")) { + state.tokenize = tokenCComment; + return tokenCComment(stream, state); + } + else if (ch == "<" && stream.eat("!")) { + state.tokenize = tokenSGMLComment; + return tokenSGMLComment(stream, state); + } + else if (ch == "=") ret(null, "compare"); + else if ((ch == "~" || ch == "|") && stream.eat("=")) return ret(null, "compare"); + else if (ch == "\"" || ch == "'") { + state.tokenize = tokenString(ch); + return state.tokenize(stream, state); + } + else if (ch == "#") { + stream.eatWhile(/\w/); + return ret("css-selector", "hash"); + } + else if (ch == "!") { + stream.match(/^\s*\w*/); + return ret("css-important", "important"); + } + else if (/\d/.test(ch)) { + stream.eatWhile(/[\w.%]/); + return ret("css-unit", "unit"); + } + else if (/[,.+>*\/]/.test(ch)) { + return ret(null, "select-op"); + } + else if (/[;{}:\[\]]/.test(ch)) { + return ret(null, ch); + } + else { + stream.eatWhile(/[\w\\\-_]/); + return ret("css-identifier", "identifier"); + } + } + + function tokenCComment(stream, state) { + var maybeEnd = false, ch; + while ((ch = stream.next()) != null) { + if (maybeEnd && ch == "/") { + state.tokenize = tokenBase; + break; + } + maybeEnd = (ch == "*"); + } + return ret("css-comment", "comment"); + } + + function tokenSGMLComment(stream, state) { + var dashes = 0, ch; + while ((ch = stream.next()) != null) { + if (dashes >= 2 && ch == ">") { + state.tokenize = tokenBase; + break; + } + dashes = (ch == "-") ? dashes + 1 : 0; + } + return ret("css-comment", "comment"); + } + + function tokenString(quote) { + return function(stream, state) { + var escaped = false, ch; + while ((ch = stream.next()) != null) { + if (ch == quote && !escaped) + break; + escaped = !escaped && ch == "\\"; + } + if (!escaped) state.tokenize = tokenBase; + return ret("css-string", "string"); + }; + } + + return { + startState: function(base) { + return {tokenize: tokenBase, + baseIndent: base || 0, + stack: []}; + }, + + token: function(stream, state) { + if (stream.eatSpace()) return null; + var style = state.tokenize(stream, state); + + var context = state.stack[state.stack.length-1]; + if (type == "hash" && context == "rule") style = "css-colorcode"; + else if (style == "css-identifier") { + if (context == "rule") style = "css-value"; + else if (!context || context == "@media{") style = "css-selector"; + } + + if (context == "rule" && /^[\{\};]$/.test(type)) + state.stack.pop(); + if (type == "{") { + if (context == "@media") state.stack[state.stack.length-1] = "@media{"; + else state.stack.push("{"); + } + else if (type == "}") state.stack.pop(); + else if (type == "@media") state.stack.push("@media"); + else if (context != "rule" && context != "@media" && type != "comment") state.stack.push("rule"); + return style; + }, + + indent: function(state, textAfter) { + var n = state.stack.length; + if (/^\}/.test(textAfter)) + n -= state.stack[state.stack.length-1] == "rule" ? 2 : 1; + return state.baseIndent + n * indentUnit; + }, + + electricChars: "}" + }; +}); + +CodeMirror.defineMIME("text/css", "css"); diff --git a/htdocs/codemirror2/mode/css/index.html b/htdocs/codemirror2/mode/css/index.html new file mode 100644 index 000000000..ad895610f --- /dev/null +++ b/htdocs/codemirror2/mode/css/index.html @@ -0,0 +1,56 @@ + + + + CodeMirror 2: CSS mode + + + + + + + + +

CodeMirror 2: CSS mode

+
+ + +

MIME types defined: text/css.

+ + + diff --git a/htdocs/codemirror2/mode/diff/diff.css b/htdocs/codemirror2/mode/diff/diff.css new file mode 100644 index 000000000..60c1379ed --- /dev/null +++ b/htdocs/codemirror2/mode/diff/diff.css @@ -0,0 +1,3 @@ +span.diff-rangeinfo {color: #a0b;} +span.diff-minus {color: #a22;} +span.diff-plus {color: #2b2;} diff --git a/htdocs/codemirror2/mode/diff/diff.js b/htdocs/codemirror2/mode/diff/diff.js new file mode 100644 index 000000000..619d74e2a --- /dev/null +++ b/htdocs/codemirror2/mode/diff/diff.js @@ -0,0 +1,13 @@ +CodeMirror.defineMode("diff", function() { + return { + token: function(stream) { + var ch = stream.next(); + stream.skipToEnd(); + if (ch == "+") return "diff-plus"; + if (ch == "-") return "diff-minus"; + if (ch == "@") return "diff-rangeinfo"; + } + }; +}); + +CodeMirror.defineMIME("text/x-diff", "diff"); diff --git a/htdocs/codemirror2/mode/diff/index.html b/htdocs/codemirror2/mode/diff/index.html new file mode 100644 index 000000000..2748f2fa8 --- /dev/null +++ b/htdocs/codemirror2/mode/diff/index.html @@ -0,0 +1,99 @@ + + + + CodeMirror 2: Diff mode + + + + + + + + +

CodeMirror 2: Diff mode

+
+ + +

MIME types defined: text/x-diff.

+ + + diff --git a/htdocs/codemirror2/mode/haskell/haskell.css b/htdocs/codemirror2/mode/haskell/haskell.css new file mode 100644 index 000000000..41f915556 --- /dev/null +++ b/htdocs/codemirror2/mode/haskell/haskell.css @@ -0,0 +1,25 @@ +span.hs-char, +span.hs-float, +span.hs-integer, +span.hs-string {color: #762;} + +span.hs-comment {color: #262;font-style: italic;} +span.hs-pragma {color: #555;font-style: italic;} + +span.hs-special, +span.hs-varid, +span.hs-varsym {color: #000;} + +span.hs-conid, +span.hs-consym {color: #b11;} + +span.hs-qualifier {color: #555;} + +span.hs-reservedid, +span.hs-reservedop {color: #730;} + +span.hs-prelude-varid, +span.hs-prelude-varsym {color: #30a;} +span.hs-prelude-conid {color: #b11;} + +span.hs-error {background-color: #fdd;} diff --git a/htdocs/codemirror2/mode/haskell/haskell.js b/htdocs/codemirror2/mode/haskell/haskell.js new file mode 100644 index 000000000..107885c20 --- /dev/null +++ b/htdocs/codemirror2/mode/haskell/haskell.js @@ -0,0 +1,242 @@ +CodeMirror.defineMode("haskell", function(cmCfg, modeCfg) { + + function switchState(source, setState, f) { + setState(f); + return f(source, setState); + } + + // These should all be Unicode extended, as per the Haskell 2010 report + var smallRE = /[a-z_]/; + var largeRE = /[A-Z]/; + var digitRE = /[0-9]/; + var hexitRE = /[0-9A-Fa-f]/; + var octitRE = /[0-7]/; + var idRE = /[a-z_A-Z0-9']/; + var symbolRE = /[-!#$%&*+.\/<=>?@\\^|~:]/; + var specialRE = /[(),;[\]`{}]/; + var whiteCharRE = /[ \t\v\f]/; // newlines are handled in tokenizer + + function normal(source, setState) { + if (source.eatWhile(whiteCharRE)) { + return null; + } + + var ch = source.next(); + if (specialRE.test(ch)) { + if (ch == '{' && source.eat('-')) { + var t = "hs-comment"; + if (source.eat('#')) { + t = "hs-pragma"; + } + return switchState(source, setState, ncomment(t, 1)); + } + return "hs-special"; + } + + if (ch == '\'') { + if (source.eat('\\')) { + source.next(); // should handle other escapes here + } + else { + source.next(); + } + if (source.eat('\'')) { + return "hs-char"; + } + return "hs-error"; + } + + if (ch == '"') { + return switchState(source, setState, stringLiteral); + } + + if (largeRE.test(ch)) { + source.eatWhile(idRE); + if (source.eat('.')) { + return "hs-qualifier"; + } + return "hs-conid"; + } + + if (smallRE.test(ch)) { + source.eatWhile(idRE); + return "hs-varid"; + } + + if (digitRE.test(ch)) { + if (ch == '0') { + if (source.eat(/[xX]/)) { + source.eatWhile(hexitRE); // should require at least 1 + return "hs-integer"; + } + if (source.eat(/[oO]/)) { + source.eatWhile(octitRE); // should require at least 1 + return "hs-integer"; + } + } + source.eatWhile(digitRE); + var t = "hs-integer"; + if (source.eat('.')) { + t = "hs-float"; + source.eatWhile(digitRE); // should require at least 1 + } + if (source.eat(/[eE]/)) { + t = "hs-float"; + source.eat(/[-+]/); + source.eatWhile(digitRE); // should require at least 1 + } + return t; + } + + if (symbolRE.test(ch)) { + if (ch == '-' && source.eat(/-/)) { + source.eatWhile(/-/); + if (!source.eat(symbolRE)) { + source.skipToEnd(); + return "hs-comment"; + } + } + var t = "hs-varsym"; + if (ch == ':') { + t = "hs-consym"; + } + source.eatWhile(symbolRE); + return t; + } + + return "hs-error"; + } + + function ncomment(type, nest) { + if (nest == 0) { + return normal; + } + return function(source, setState) { + var currNest = nest; + while (!source.eol()) { + ch = source.next(); + if (ch == '{' && source.eat('-')) { + ++currNest; + } + else if (ch == '-' && source.eat('}')) { + --currNest; + if (currNest == 0) { + setState(normal); + return type; + } + } + } + setState(ncomment(type, currNest)); + return type; + } + } + + function stringLiteral(source, setState) { + while (!source.eol()) { + var ch = source.next(); + if (ch == '"') { + setState(normal); + return "hs-string"; + } + if (ch == '\\') { + if (source.eol() || source.eat(whiteCharRE)) { + setState(stringGap); + return "hs-string"; + } + if (source.eat('&')) { + } + else { + source.next(); // should handle other escapes here + } + } + } + setState(normal); + return "hs-error"; + } + + function stringGap(source, setState) { + if (source.eat('\\')) { + return switchState(source, setState, stringLiteral); + } + source.next(); + setState(normal); + return "hs-error"; + } + + + var wellKnownWords = (function() { + var wkw = {}; + function setType(t) { + return function () { + for (var i = 0; i < arguments.length; i++) + wkw[arguments[i]] = t; + } + } + + setType("hs-reservedid")( + "case", "class", "data", "default", "deriving", "do", "else", "foreign", + "if", "import", "in", "infix", "infixl", "infixr", "instance", "let", + "module", "newtype", "of", "then", "type", "where", "_"); + + setType("hs-reservedop")( + "\.\.", ":", "::", "=", "\\", "\"", "<-", "->", "@", "~", "=>"); + + setType("hs-prelude-varsym")( + "!!", "$!", "$", "&&", "+", "++", "-", ".", "/", "/=", "<", "<=", "=<<", + "==", ">", ">=", ">>", ">>=", "^", "^^", "||", "*", "**"); + + setType("hs-prelude-conid")( + "Bool", "Bounded", "Char", "Double", "EQ", "Either", "Enum", "Eq", + "False", "FilePath", "Float", "Floating", "Fractional", "Functor", "GT", + "IO", "IOError", "Int", "Integer", "Integral", "Just", "LT", "Left", + "Maybe", "Monad", "Nothing", "Num", "Ord", "Ordering", "Rational", "Read", + "ReadS", "Real", "RealFloat", "RealFrac", "Right", "Show", "ShowS", + "String", "True"); + + setType("hs-prelude-varid")( + "abs", "acos", "acosh", "all", "and", "any", "appendFile", "asTypeOf", + "asin", "asinh", "atan", "atan2", "atanh", "break", "catch", "ceiling", + "compare", "concat", "concatMap", "const", "cos", "cosh", "curry", + "cycle", "decodeFloat", "div", "divMod", "drop", "dropWhile", "either", + "elem", "encodeFloat", "enumFrom", "enumFromThen", "enumFromThenTo", + "enumFromTo", "error", "even", "exp", "exponent", "fail", "filter", + "flip", "floatDigits", "floatRadix", "floatRange", "floor", "fmap", + "foldl", "foldl1", "foldr", "foldr1", "fromEnum", "fromInteger", + "fromIntegral", "fromRational", "fst", "gcd", "getChar", "getContents", + "getLine", "head", "id", "init", "interact", "ioError", "isDenormalized", + "isIEEE", "isInfinite", "isNaN", "isNegativeZero", "iterate", "last", + "lcm", "length", "lex", "lines", "log", "logBase", "lookup", "map", + "mapM", "mapM_", "max", "maxBound", "maximum", "maybe", "min", "minBound", + "minimum", "mod", "negate", "not", "notElem", "null", "odd", "or", + "otherwise", "pi", "pred", "print", "product", "properFraction", + "putChar", "putStr", "putStrLn", "quot", "quotRem", "read", "readFile", + "readIO", "readList", "readLn", "readParen", "reads", "readsPrec", + "realToFrac", "recip", "rem", "repeat", "replicate", "return", "reverse", + "round", "scaleFloat", "scanl", "scanl1", "scanr", "scanr1", "seq", + "sequence", "sequence_", "show", "showChar", "showList", "showParen", + "showString", "shows", "showsPrec", "significand", "signum", "sin", + "sinh", "snd", "span", "splitAt", "sqrt", "subtract", "succ", "sum", + "tail", "take", "takeWhile", "tan", "tanh", "toEnum", "toInteger", + "toRational", "truncate", "uncurry", "undefined", "unlines", "until", + "unwords", "unzip", "unzip3", "userError", "words", "writeFile", "zip", + "zip3", "zipWith", "zipWith3"); + + return wkw; + })(); + + + + return { + startState: function () { return { f: normal }; }, + copyState: function (s) { return { f: s.f }; }, + + token: function(stream, state) { + var t = state.f(stream, function(s) { state.f = s; }); + var w = stream.current(); + return (w in wellKnownWords) ? wellKnownWords[w] : t; + } + }; + +}); + +CodeMirror.defineMIME("text/x-haskell", "haskell"); diff --git a/htdocs/codemirror2/mode/haskell/index.html b/htdocs/codemirror2/mode/haskell/index.html new file mode 100644 index 000000000..0bf34d570 --- /dev/null +++ b/htdocs/codemirror2/mode/haskell/index.html @@ -0,0 +1,59 @@ + + + + CodeMirror 2: Haskell mode + + + + + + + + +

CodeMirror 2: Haskell mode

+ +
+ + + +

MIME types defined: text/x-haskell.

+ + diff --git a/htdocs/codemirror2/mode/htmlmixed/htmlmixed.js b/htdocs/codemirror2/mode/htmlmixed/htmlmixed.js new file mode 100644 index 000000000..1de5c9ee8 --- /dev/null +++ b/htdocs/codemirror2/mode/htmlmixed/htmlmixed.js @@ -0,0 +1,74 @@ +CodeMirror.defineMode("htmlmixed", function(config, parserConfig) { + var htmlMode = CodeMirror.getMode(config, {name: "xml", htmlMode: true}); + var jsMode = CodeMirror.getMode(config, "javascript"); + var cssMode = CodeMirror.getMode(config, "css"); + + function html(stream, state) { + var style = htmlMode.token(stream, state.htmlState); + if (style == "xml-tag" && stream.current() == ">" && state.htmlState.context) { + if (/^script$/i.test(state.htmlState.context.tagName)) { + state.token = javascript; + state.localState = jsMode.startState(htmlMode.indent(state.htmlState, "")); + } + else if (/^style$/i.test(state.htmlState.context.tagName)) { + state.token = css; + state.localState = cssMode.startState(htmlMode.indent(state.htmlState, "")); + } + } + return style; + } + function maybeBackup(stream, pat, style) { + var cur = stream.current(); + var close = cur.search(pat); + if (close > -1) stream.backUp(cur.length - close); + return style; + } + function javascript(stream, state) { + if (stream.match(/^<\/\s*script\s*>/i, false)) { + state.token = html; + state.curState = null; + return html(stream, state); + } + return maybeBackup(stream, /<\/\s*script\s*>/, + jsMode.token(stream, state.localState)); + } + function css(stream, state) { + if (stream.match(/^<\/\s*style\s*>/i, false)) { + state.token = html; + state.localState = null; + return html(stream, state); + } + return maybeBackup(stream, /<\/\s*style\s*>/, + cssMode.token(stream, state.localState)); + } + + return { + startState: function() { + var state = htmlMode.startState(); + return {token: html, localState: null, htmlState: state}; + }, + + copyState: function(state) { + if (state.localState) + var local = CodeMirror.copyState(state.token == css ? cssMode : jsMode, state.localState); + return {token: state.token, localState: local, htmlState: CodeMirror.copyState(htmlMode, state.htmlState)}; + }, + + token: function(stream, state) { + return state.token(stream, state); + }, + + indent: function(state, textAfter) { + if (state.token == html || /^\s*<\//.test(textAfter)) + return htmlMode.indent(state.htmlState, textAfter); + else if (state.token == javascript) + return jsMode.indent(state.localState, textAfter); + else + return cssMode.indent(state.localState, textAfter); + }, + + electricChars: "/{}:" + } +}); + +CodeMirror.defineMIME("text/html", "htmlmixed"); diff --git a/htdocs/codemirror2/mode/htmlmixed/index.html b/htdocs/codemirror2/mode/htmlmixed/index.html new file mode 100644 index 000000000..c661c98d5 --- /dev/null +++ b/htdocs/codemirror2/mode/htmlmixed/index.html @@ -0,0 +1,54 @@ + + + + CodeMirror 2: HTML mixed mode + + + + + + + + + + + + + +

CodeMirror 2: HTML mixed mode

+
+ + +

The HTML mixed mode depends on the XML, JavaScript, and CSS modes.

+ +

MIME types defined: text/html + (redefined, only takes effect if you load this parser after the + XML parser).

+ + + diff --git a/htdocs/codemirror2/mode/javascript/index.html b/htdocs/codemirror2/mode/javascript/index.html new file mode 100644 index 000000000..7b528e041 --- /dev/null +++ b/htdocs/codemirror2/mode/javascript/index.html @@ -0,0 +1,78 @@ + + + + CodeMirror 2: JavaScript mode + + + + + + + + +

CodeMirror 2: JavaScript mode

+ +
+ + + +

JavaScript mode supports a single configuration + option, json, which will set the mode to expect JSON + data rather than a JavaScript program.

+ +

MIME types defined: text/javascript, application/json.

+ + diff --git a/htdocs/codemirror2/mode/javascript/javascript.css b/htdocs/codemirror2/mode/javascript/javascript.css new file mode 100644 index 000000000..84fb1dfd4 --- /dev/null +++ b/htdocs/codemirror2/mode/javascript/javascript.css @@ -0,0 +1,6 @@ +span.js-keyword {color: #90b;} +span.js-atom {color: #291;} +span.js-variabledef {color: #00f;} +span.js-localvariable {color: #049;} +span.js-comment {color: #a70;} +span.js-string {color: #a22;} diff --git a/htdocs/codemirror2/mode/javascript/javascript.js b/htdocs/codemirror2/mode/javascript/javascript.js new file mode 100644 index 000000000..065216591 --- /dev/null +++ b/htdocs/codemirror2/mode/javascript/javascript.js @@ -0,0 +1,348 @@ +CodeMirror.defineMode("javascript", function(config, parserConfig) { + var indentUnit = config.indentUnit; + var jsonMode = parserConfig.json; + + // Tokenizer + + var keywords = function(){ + function kw(type) {return {type: type, style: "js-keyword"};} + var A = kw("keyword a"), B = kw("keyword b"), C = kw("keyword c"); + var operator = kw("operator"), atom = {type: "atom", style: "js-atom"}; + return { + "if": A, "while": A, "with": A, "else": B, "do": B, "try": B, "finally": B, + "return": C, "break": C, "continue": C, "new": C, "delete": C, "throw": C, + "var": kw("var"), "function": kw("function"), "catch": kw("catch"), + "for": kw("for"), "switch": kw("switch"), "case": kw("case"), "default": kw("default"), + "in": operator, "typeof": operator, "instanceof": operator, + "true": atom, "false": atom, "null": atom, "undefined": atom, "NaN": atom, "Infinity": atom + }; + }(); + + var isOperatorChar = /[+\-*&%=<>!?|]/; + + function chain(stream, state, f) { + state.tokenize = f; + return f(stream, state); + } + + function nextUntilUnescaped(stream, end) { + var escaped = false, next; + while ((next = stream.next()) != null) { + if (next == end && !escaped) + return false; + escaped = !escaped && next == "\\"; + } + return escaped; + } + + // Used as scratch variables to communicate multiple values without + // consing up tons of objects. + var type, content; + function ret(tp, style, cont) { + type = tp; content = cont; + return style; + } + + function jsTokenBase(stream, state) { + var ch = stream.next(); + if (ch == '"' || ch == "'") + return chain(stream, state, jsTokenString(ch)); + else if (/[\[\]{}\(\),;\:\.]/.test(ch)) + return ret(ch); + else if (ch == "0" && stream.eat(/x/i)) { + stream.eatWhile(/[\da-f]/i); + return ret("number", "js-atom"); + } + else if (/\d/.test(ch)) { + stream.match(/^\d*(?:\.\d*)?(?:e[+\-]?\d+)?/); + return ret("number", "js-atom"); + } + else if (ch == "/") { + if (stream.eat("*")) { + return chain(stream, state, jsTokenComment); + } + else if (stream.eat("/")) { + stream.skipToEnd(); + return ret("comment", "js-comment"); + } + else if (state.reAllowed) { + nextUntilUnescaped(stream, "/"); + stream.eatWhile(/[gimy]/); // 'y' is "sticky" option in Mozilla + return ret("regexp", "js-string"); + } + else { + stream.eatWhile(isOperatorChar); + return ret("operator", null, stream.current()); + } + } + else if (isOperatorChar.test(ch)) { + stream.eatWhile(isOperatorChar); + return ret("operator", null, stream.current()); + } + else { + stream.eatWhile(/[\w\$_]/); + var word = stream.current(), known = keywords.propertyIsEnumerable(word) && keywords[word]; + return known ? ret(known.type, known.style, word) : + ret("variable", "js-variable", word); + } + } + + function jsTokenString(quote) { + return function(stream, state) { + if (!nextUntilUnescaped(stream, quote)) + state.tokenize = jsTokenBase; + return ret("string", "js-string"); + }; + } + + function jsTokenComment(stream, state) { + var maybeEnd = false, ch; + while (ch = stream.next()) { + if (ch == "/" && maybeEnd) { + state.tokenize = jsTokenBase; + break; + } + maybeEnd = (ch == "*"); + } + return ret("comment", "js-comment"); + } + + // Parser + + var atomicTypes = {"atom": true, "number": true, "variable": true, "string": true, "regexp": true}; + + function JSLexical(indented, column, type, align, prev, info) { + this.indented = indented; + this.column = column; + this.type = type; + this.prev = prev; + this.info = info; + if (align != null) this.align = align; + } + + function inScope(state, varname) { + for (var v = state.localVars; v; v = v.next) + if (v.name == varname) return true; + } + + function parseJS(state, style, type, content, stream) { + var cc = state.cc; + // Communicate our context to the combinators. + // (Less wasteful than consing up a hundred closures on every call.) + cx.state = state; cx.stream = stream; cx.marked = null, cx.cc = cc; + + if (!state.lexical.hasOwnProperty("align")) + state.lexical.align = true; + + while(true) { + var combinator = cc.length ? cc.pop() : jsonMode ? expression : statement; + if (combinator(type, content)) { + while(cc.length && cc[cc.length - 1].lex) + cc.pop()(); + if (cx.marked) return cx.marked; + if (type == "variable" && inScope(state, content)) return "js-localvariable"; + return style; + } + } + } + + // Combinator utils + + var cx = {state: null, column: null, marked: null, cc: null}; + function pass() { + for (var i = arguments.length - 1; i >= 0; i--) cx.cc.push(arguments[i]); + } + function cont() { + pass.apply(null, arguments); + return true; + } + function register(varname) { + var state = cx.state; + if (state.context) { + cx.marked = "js-variabledef"; + for (var v = state.localVars; v; v = v.next) + if (v.name == varname) return; + state.localVars = {name: varname, next: state.localVars}; + } + } + + // Combinators + + var defaultVars = {name: "this", next: {name: "arguments"}}; + function pushcontext() { + if (!cx.state.context) cx.state.localVars = defaultVars; + cx.state.context = {prev: cx.state.context, vars: cx.state.localVars}; + } + function popcontext() { + cx.state.localVars = cx.state.context.vars; + cx.state.context = cx.state.context.prev; + } + function pushlex(type, info) { + var result = function() { + var state = cx.state; + state.lexical = new JSLexical(state.indented, cx.stream.column(), type, null, state.lexical, info) + }; + result.lex = true; + return result; + } + function poplex() { + var state = cx.state; + if (state.lexical.prev) { + if (state.lexical.type == ")") + state.indented = state.lexical.indented; + state.lexical = state.lexical.prev; + } + } + poplex.lex = true; + + function expect(wanted) { + return function expecting(type) { + if (type == wanted) return cont(); + else if (wanted == ";") return pass(); + else return cont(arguments.callee); + }; + } + + function statement(type) { + if (type == "var") return cont(pushlex("vardef"), vardef1, expect(";"), poplex); + if (type == "keyword a") return cont(pushlex("form"), expression, statement, poplex); + if (type == "keyword b") return cont(pushlex("form"), statement, poplex); + if (type == "{") return cont(pushlex("}"), block, poplex); + if (type == ";") return cont(); + if (type == "function") return cont(functiondef); + if (type == "for") return cont(pushlex("form"), expect("("), pushlex(")"), forspec1, expect(")"), + poplex, statement, poplex); + if (type == "variable") return cont(pushlex("stat"), maybelabel); + if (type == "switch") return cont(pushlex("form"), expression, pushlex("}", "switch"), expect("{"), + block, poplex, poplex); + if (type == "case") return cont(expression, expect(":")); + if (type == "default") return cont(expect(":")); + if (type == "catch") return cont(pushlex("form"), pushcontext, expect("("), funarg, expect(")"), + statement, poplex, popcontext); + return pass(pushlex("stat"), expression, expect(";"), poplex); + } + function expression(type) { + if (atomicTypes.hasOwnProperty(type)) return cont(maybeoperator); + if (type == "function") return cont(functiondef); + if (type == "keyword c") return cont(expression); + if (type == "(") return cont(pushlex(")"), expression, expect(")"), poplex, maybeoperator); + if (type == "operator") return cont(expression); + if (type == "[") return cont(pushlex("]"), commasep(expression, "]"), poplex, maybeoperator); + if (type == "{") return cont(pushlex("}"), commasep(objprop, "}"), poplex, maybeoperator); + return cont(); + } + function maybeoperator(type, value) { + if (type == "operator" && /\+\+|--/.test(value)) return cont(maybeoperator); + if (type == "operator") return cont(expression); + if (type == ";") return; + if (type == "(") return cont(pushlex(")"), commasep(expression, ")"), poplex, maybeoperator); + if (type == ".") return cont(property, maybeoperator); + if (type == "[") return cont(pushlex("]"), expression, expect("]"), poplex, maybeoperator); + } + function maybelabel(type) { + if (type == ":") return cont(poplex, statement); + return pass(maybeoperator, expect(";"), poplex); + } + function property(type) { + if (type == "variable") {cx.marked = "js-property"; return cont();} + } + function objprop(type) { + if (type == "variable") cx.marked = "js-property"; + if (atomicTypes.hasOwnProperty(type)) return cont(expect(":"), expression); + } + function commasep(what, end) { + function proceed(type) { + if (type == ",") return cont(what, proceed); + if (type == end) return cont(); + return cont(expect(end)); + } + return function commaSeparated(type) { + if (type == end) return cont(); + else return pass(what, proceed); + }; + } + function block(type) { + if (type == "}") return cont(); + return pass(statement, block); + } + function vardef1(type, value) { + if (type == "variable"){register(value); return cont(vardef2);} + return cont(); + } + function vardef2(type, value) { + if (value == "=") return cont(expression, vardef2); + if (type == ",") return cont(vardef1); + } + function forspec1(type) { + if (type == "var") return cont(vardef1, forspec2); + if (type == ";") return pass(forspec2); + if (type == "variable") return cont(formaybein); + return pass(forspec2); + } + function formaybein(type, value) { + if (value == "in") return cont(expression); + return cont(maybeoperator, forspec2); + } + function forspec2(type, value) { + if (type == ";") return cont(forspec3); + if (value == "in") return cont(expression); + return cont(expression, expect(";"), forspec3); + } + function forspec3(type) { + if (type != ")") cont(expression); + } + function functiondef(type, value) { + if (type == "variable") {register(value); return cont(functiondef);} + if (type == "(") return cont(pushlex(")"), pushcontext, commasep(funarg, ")"), poplex, statement, popcontext); + } + function funarg(type, value) { + if (type == "variable") {register(value); return cont();} + } + + // Interface + + return { + startState: function(basecolumn) { + return { + tokenize: jsTokenBase, + reAllowed: true, + cc: [], + lexical: new JSLexical((basecolumn || 0) - indentUnit, 0, "block", false), + localVars: null, + context: null, + indented: 0 + }; + }, + + token: function(stream, state) { + if (stream.sol()) { + if (!state.lexical.hasOwnProperty("align")) + state.lexical.align = false; + state.indented = stream.indentation(); + } + if (stream.eatSpace()) return null; + var style = state.tokenize(stream, state); + if (type == "comment") return style; + state.reAllowed = type == "operator" || type == "keyword c" || type.match(/^[\[{}\(,;:]$/); + return parseJS(state, style, type, content, stream); + }, + + indent: function(state, textAfter) { + if (state.tokenize != jsTokenBase) return 0; + var firstChar = textAfter && textAfter.charAt(0), lexical = state.lexical, + type = lexical.type, closing = firstChar == type; + if (type == "vardef") return lexical.indented + 4; + else if (type == "form" && firstChar == "{") return lexical.indented; + else if (type == "stat" || type == "form") return lexical.indented + indentUnit; + else if (lexical.info == "switch" && !closing) + return lexical.indented + (/^(?:case|default)\b/.test(textAfter) ? indentUnit : 2 * indentUnit); + else if (lexical.align) return lexical.column + (closing ? 0 : 1); + else return lexical.indented + (closing ? 0 : indentUnit); + }, + + electricChars: ":{}" + }; +}); + +CodeMirror.defineMIME("text/javascript", "javascript"); +CodeMirror.defineMIME("application/json", {name: "javascript", json: true}); diff --git a/htdocs/codemirror2/mode/math/LICENSE.txt b/htdocs/codemirror2/mode/math/LICENSE.txt new file mode 100644 index 000000000..918866b42 --- /dev/null +++ b/htdocs/codemirror2/mode/math/LICENSE.txt @@ -0,0 +1,21 @@ +The MIT License + +Copyright (c) 2010 Timothy Farrell + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. \ No newline at end of file diff --git a/htdocs/codemirror2/mode/math/index.html b/htdocs/codemirror2/mode/math/index.html new file mode 100644 index 000000000..e9640e9e4 --- /dev/null +++ b/htdocs/codemirror2/mode/math/index.html @@ -0,0 +1,123 @@ + + + + CodeMirror 2: Python mode + + + + + + + + +

CodeMirror 2: Python mode

+ +
+ +

Configuration Options:

+
    +
  • version - 2/3 - The version of Python to recognize. Default is 2.
  • +
  • singleLineStringErrors - true/false - If you have a single-line string that is not terminated at the end of the line, this will show subsequent lines as errors if true, otherwise it will consider the newline as the end of the string. Default is false.
  • +
+ +

MIME types defined: text/x-python.

+ + diff --git a/htdocs/codemirror2/mode/math/math.css b/htdocs/codemirror2/mode/math/math.css new file mode 100644 index 000000000..8058dafa7 --- /dev/null +++ b/htdocs/codemirror2/mode/math/math.css @@ -0,0 +1,9 @@ +span.cm-math-keyword {color: #90b;} +span.cm-math-atom {color: #291;} +span.cm-math-variabledef {color: #00f;} +span.cm-math-localvariable {color: #049;} +span.cm-math-variable {color: #049;} +span.cm-math-funccall {color: #0aa;} +span.cm-math-comment {color: #a70;} +span.cm-math-string {color: #a22;} + diff --git a/htdocs/codemirror2/mode/math/math.js b/htdocs/codemirror2/mode/math/math.js new file mode 100644 index 000000000..2947029e1 --- /dev/null +++ b/htdocs/codemirror2/mode/math/math.js @@ -0,0 +1,351 @@ +CodeMirror.defineMode("math", function(config, parserConfig) { + var indentUnit = config.indentUnit; + var jsonMode = parserConfig.json; + + // Tokenizer + + var keywords = function(){ + function kw(type) {return {type: type, style: "math-keyword"};} + var A = kw("keyword a"), B = kw("keyword b"), C = kw("keyword c"); + var operator = kw("operator"), atom = {type: "atom", style: "math-atom"}; + return { + "if": A, "while": A, "with": A, "else": B, "do": B, "try": B, "finally": B, + "return": C, "break": C, "continue": C, "new": C, "delete": C, "throw": C, + "var": kw("var"), "function": kw("function"), "catch": kw("catch"), + "for": kw("for"), "switch": kw("switch"), "case": kw("case"), "default": kw("default"), + "in": operator, "typeof": operator, "instanceof": operator, + "true": atom, "false": atom, "null": atom, "undefined": atom, "NaN": atom, "Infinity": atom + }; + }(); + + var isOperatorChar = /[+\-*&%=<>!?|^]/; + + function chain(stream, state, f) { + state.tokenize = f; + return f(stream, state); + } + + function nextUntilUnescaped(stream, end) { + var escaped = false, next; + while ((next = stream.next()) != null) { + if (next == end && !escaped) + return false; + escaped = !escaped && next == "\\"; + } + return escaped; + } + + // Used as scratch variables to communicate multiple values without + // consing up tons of objects. + var type, content; + function ret(tp, style, cont) { + type = tp; content = cont; + return style; + } + + function jsTokenBase(stream, state) { + var ch = stream.next(); + if (ch == '"' || ch == "'") + return chain(stream, state, jsTokenString(ch)); + else if (/[\[\]{}\(\),;\:\.]/.test(ch)) + return ret(ch); + else if (ch == "0" && stream.eat(/x/i)) { + stream.eatWhile(/[\da-f]/i); + return ret("number", "math-atom"); + } + else if (/\d/.test(ch)) { + stream.match(/^\d*(?:\.\d*)?(?:e[+\-]?\d+)?/); + return ret("number", "math-atom"); + } + else if (ch == "#") { + stream.skipToEnd(); + return ret("comment", "math-comment"); + } + else if (ch == "/") { + if (stream.eat("*")) { + return chain(stream, state, jsTokenComment); + } + else if (stream.eat("/")) { + stream.skipToEnd(); + return ret("comment", "math-comment"); + } + else if (state.reAllowed) { + nextUntilUnescaped(stream, "/"); + stream.eatWhile(/[gimy]/); // 'y' is "sticky" option in Mozilla + return ret("regexp", "math-string"); + } + else { + stream.eatWhile(isOperatorChar); + return ret("operator", null, stream.current()); + } + } + else if (isOperatorChar.test(ch)) { + stream.eatWhile(isOperatorChar); + return ret("operator", null, stream.current()); + } + else { + stream.eatWhile(/[\w\$_]/); + var word = stream.current(), known = keywords.propertyIsEnumerable(word) && keywords[word]; + return known ? ret(known.type, known.style, word) : + ret("variable", "math-variable", word); + } + } + + function jsTokenString(quote) { + return function(stream, state) { + if (!nextUntilUnescaped(stream, quote)) + state.tokenize = jsTokenBase; + return ret("string", "math-string"); + }; + } + + function jsTokenComment(stream, state) { + var maybeEnd = false, ch; + while (ch = stream.next()) { + if (ch == "/" && maybeEnd) { + state.tokenize = jsTokenBase; + break; + } + maybeEnd = (ch == "*"); + } + return ret("comment", "math-comment"); + } + + // Parser + + var atomicTypes = {"atom": true, "number": true, "variable": true, "string": true, "regexp": true}; + + function JSLexical(indented, column, type, align, prev, info) { + this.indented = indented; + this.column = column; + this.type = type; + this.prev = prev; + this.info = info; + if (align != null) this.align = align; + } + + function inScope(state, varname) { + for (var v = state.localVars; v; v = v.next) + if (v.name == varname) return true; + } + + function parseJS(state, style, type, content, stream) { + var cc = state.cc; + // Communicate our context to the combinators. + // (Less wasteful than consing up a hundred closures on every call.) + cx.state = state; cx.stream = stream; cx.marked = null, cx.cc = cc; + + if (!state.lexical.hasOwnProperty("align")) + state.lexical.align = true; + + while(true) { + var combinator = cc.length ? cc.pop() : jsonMode ? expression : statement; + if (combinator(type, content)) { + while(cc.length && cc[cc.length - 1].lex) + cc.pop()(); + if (cx.marked) return cx.marked; + if (type == "variable" && inScope(state, content)) return "math-localvariable"; + return style; + } + } + } + + // Combinator utils + + var cx = {state: null, column: null, marked: null, cc: null}; + function pass() { + for (var i = arguments.length - 1; i >= 0; i--) cx.cc.push(arguments[i]); + } + function cont() { + pass.apply(null, arguments); + return true; + } + function register(varname) { + var state = cx.state; + if (state.context) { + cx.marked = "math-variabledef"; + for (var v = state.localVars; v; v = v.next) + if (v.name == varname) return; + state.localVars = {name: varname, next: state.localVars}; + } + } + + // Combinators + + var defaultVars = {name: "this", next: {name: "arguments"}}; + function pushcontext() { + if (!cx.state.context) cx.state.localVars = defaultVars; + cx.state.context = {prev: cx.state.context, vars: cx.state.localVars}; + } + function popcontext() { + cx.state.localVars = cx.state.context.vars; + cx.state.context = cx.state.context.prev; + } + function pushlex(type, info) { + var result = function() { + var state = cx.state; + state.lexical = new JSLexical(state.indented, cx.stream.column(), type, null, state.lexical, info) + }; + result.lex = true; + return result; + } + function poplex() { + var state = cx.state; + if (state.lexical.prev) { + if (state.lexical.type == ")") + state.indented = state.lexical.indented; + state.lexical = state.lexical.prev; + } + } + poplex.lex = true; + + function expect(wanted) { + return function expecting(type) { + if (type == wanted) return cont(); + else if (wanted == ";") return pass(); + else return cont(arguments.callee); + }; + } + + function statement(type) { + if (type == "var") return cont(pushlex("vardef"), vardef1, expect(";"), poplex); + if (type == "keyword a") return cont(pushlex("form"), expression, statement, poplex); + if (type == "keyword b") return cont(pushlex("form"), statement, poplex); + if (type == "{") return cont(pushlex("}"), block, poplex); + if (type == ";") return cont(); + if (type == "function") return cont(functiondef); + if (type == "for") return cont(pushlex("form"), expect("("), pushlex(")"), forspec1, expect(")"), + poplex, statement, poplex); + if (type == "variable") return cont(pushlex("stat"), maybelabel); + if (type == "switch") return cont(pushlex("form"), expression, pushlex("}", "switch"), expect("{"), + block, poplex, poplex); + if (type == "case") return cont(expression, expect(":")); + if (type == "default") return cont(expect(":")); + if (type == "catch") return cont(pushlex("form"), pushcontext, expect("("), funarg, expect(")"), + statement, poplex, popcontext); + return pass(pushlex("stat"), expression, expect(";"), poplex); + } + function expression(type) { + if (atomicTypes.hasOwnProperty(type)) return cont(maybeoperator); + if (type == "function") return cont(functiondef); + if (type == "keyword c") return cont(expression); + if (type == "(") return cont(pushlex(")"), expression, expect(")"), poplex, maybeoperator); + if (type == "operator") return cont(expression); + if (type == "[") return cont(pushlex("]"), commasep(expression, "]"), poplex, maybeoperator); + if (type == "{") return cont(pushlex("}"), commasep(objprop, "}"), poplex, maybeoperator); + return cont(); + } + function maybeoperator(type, value) { + if (type == "operator" && /\+\+|--/.test(value)) return cont(maybeoperator); + if (type == "operator") return cont(expression); + if (type == ";") return; + if (type == "(") return cont(pushlex(")"), commasep(expression, ")"), poplex, maybeoperator); + if (type == ".") return cont(property, maybeoperator); + if (type == "[") return cont(pushlex("]"), expression, expect("]"), poplex, maybeoperator); + } + function maybelabel(type) { + if (type == ":") return cont(poplex, statement); + return pass(maybeoperator, expect(";"), poplex); + } + function property(type) { + if (type == "variable") {cx.marked = "math-property"; return cont();} + } + function objprop(type) { + if (type == "variable") cx.marked = "math-property"; + if (atomicTypes.hasOwnProperty(type)) return cont(expect(":"), expression); + } + function commasep(what, end) { + function proceed(type) { + if (type == ",") return cont(what, proceed); + if (type == end) return cont(); + return cont(expect(end)); + } + return function commaSeparated(type) { + if (type == end) return cont(); + else return pass(what, proceed); + }; + } + function block(type) { + if (type == "}") return cont(); + return pass(statement, block); + } + function vardef1(type, value) { + if (type == "variable"){register(value); return cont(vardef2);} + return cont(); + } + function vardef2(type, value) { + if (value == "=") return cont(expression, vardef2); + if (type == ",") return cont(vardef1); + } + function forspec1(type) { + if (type == "var") return cont(vardef1, forspec2); + if (type == ";") return pass(forspec2); + if (type == "variable") return cont(formaybein); + return pass(forspec2); + } + function formaybein(type, value) { + if (value == "in") return cont(expression); + return cont(maybeoperator, forspec2); + } + function forspec2(type, value) { + if (type == ";") return cont(forspec3); + if (value == "in") return cont(expression); + return cont(expression, expect(";"), forspec3); + } + function forspec3(type) { + if (type != ")") cont(expression); + } + function functiondef(type, value) { + if (type == "variable") {register(value); return cont(functiondef);} + if (type == "(") return cont(pushlex(")"), pushcontext, commasep(funarg, ")"), poplex, statement, popcontext); + } + function funarg(type, value) { + if (type == "variable") {register(value); return cont();} + } + + // Interface + + return { + startState: function(basecolumn) { + return { + tokenize: jsTokenBase, + reAllowed: true, + cc: [], + lexical: new JSLexical((basecolumn || 0) - indentUnit, 0, "block", false), + localVars: null, + context: null, + indented: 0 + }; + }, + + token: function(stream, state) { + if (stream.sol()) { + if (!state.lexical.hasOwnProperty("align")) + state.lexical.align = false; + state.indented = stream.indentation(); + } + if (stream.eatSpace()) return null; + var style = state.tokenize(stream, state); + if (type == "comment") return style; + state.reAllowed = type == "operator" || type == "keyword c" || type.match(/^[\[{}\(,;:]$/); + return parseJS(state, style, type, content, stream); + }, + + indent: function(state, textAfter) { + if (state.tokenize != jsTokenBase) return 0; + var firstChar = textAfter && textAfter.charAt(0), lexical = state.lexical, + type = lexical.type, closing = firstChar == type; + if (type == "vardef") return lexical.indented + 4; + else if (type == "form" && firstChar == "{") return lexical.indented; + else if (type == "stat" || type == "form") return lexical.indented + indentUnit; + else if (lexical.info == "switch" && !closing) + return lexical.indented + (/^(?:case|default)\b/.test(textAfter) ? indentUnit : 2 * indentUnit); + else if (lexical.align) return lexical.column + (closing ? 0 : 1); + else return lexical.indented + (closing ? 0 : indentUnit); + }, + + electricChars: ":{}" + }; +}); + +CodeMirror.defineMIME("text/math", "math"); diff --git a/htdocs/codemirror2/mode/pg/LICENSE.txt b/htdocs/codemirror2/mode/pg/LICENSE.txt new file mode 100644 index 000000000..918866b42 --- /dev/null +++ b/htdocs/codemirror2/mode/pg/LICENSE.txt @@ -0,0 +1,21 @@ +The MIT License + +Copyright (c) 2010 Timothy Farrell + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. \ No newline at end of file diff --git a/htdocs/codemirror2/mode/pg/index.html b/htdocs/codemirror2/mode/pg/index.html new file mode 100644 index 000000000..e9640e9e4 --- /dev/null +++ b/htdocs/codemirror2/mode/pg/index.html @@ -0,0 +1,123 @@ + + + + CodeMirror 2: Python mode + + + + + + + + +

CodeMirror 2: Python mode

+ +
+ +

Configuration Options:

+
    +
  • version - 2/3 - The version of Python to recognize. Default is 2.
  • +
  • singleLineStringErrors - true/false - If you have a single-line string that is not terminated at the end of the line, this will show subsequent lines as errors if true, otherwise it will consider the newline as the end of the string. Default is false.
  • +
+ +

MIME types defined: text/x-python.

+ + diff --git a/htdocs/codemirror2/mode/pg/pg.css b/htdocs/codemirror2/mode/pg/pg.css new file mode 100644 index 000000000..c815d850f --- /dev/null +++ b/htdocs/codemirror2/mode/pg/pg.css @@ -0,0 +1,8 @@ +span.cm-pg-keyword {color: #90b;} +span.cm-pg-atom {color: #291;} +span.cm-pg-variabledef {color: #00f;} +span.cm-pg-localvariable {color: #049;} +span.cm-pg-variable {color: #049;} +span.cm-pg-funccall {color: #0aa;} +span.cm-pg-comment {color: #a70;} +span.cm-pg-string {color: #a22;} diff --git a/htdocs/codemirror2/mode/pg/pg.js b/htdocs/codemirror2/mode/pg/pg.js new file mode 100644 index 000000000..b6bb19256 --- /dev/null +++ b/htdocs/codemirror2/mode/pg/pg.js @@ -0,0 +1,359 @@ +CodeMirror.defineMode("pg", function(config, parserConfig) { + var indentUnit = config.indentUnit; + var jsonMode = parserConfig.json; + + // Tokenizer + + var keywords = function(){ + function kw(type) {return {type: type, style: "pg-keyword"};} + var A = kw("keyword a"), B = kw("keyword b"), C = kw("keyword c"); + var operator = kw("operator"), atom = {type: "atom", style: "pg-atom"}; + return { + "if": A, "while": A, "with": A, "else": B, "do": B, "try": B, "finally": B, + "return": C, "break": C, "continue": C, "new": C, "delete": C, "throw": C, + "var": kw("var"), "function": kw("function"), "catch": kw("catch"), + "for": kw("for"), "switch": kw("switch"), "case": kw("case"), "default": kw("default"), + "in": operator, "typeof": operator, "instanceof": operator, + "true": atom, "false": atom, "null": atom, "undefined": atom, "NaN": atom, "Infinity": atom + }; + }(); + + var isOperatorChar = /[+\-*&%=<>!?|]/; + + function chain(stream, state, f) { + state.tokenize = f; + return f(stream, state); + } + + function nextUntilUnescaped(stream, end) { + var escaped = false, next; + while ((next = stream.next()) != null) { + if (next == end && !escaped) + return false; + escaped = !escaped && next == "\\"; + } + return escaped; + } + + // Used as scratch variables to communicate multiple values without + // consing up tons of objects. + var type, content; + function ret(tp, style, cont) { + type = tp; content = cont; + return style; + } + + function jsTokenBase(stream, state) { + var ch = stream.next(); + if (ch == '"' || ch == "'") + return chain(stream, state, jsTokenString(ch)); + else if (/[\[\]{}\(\),;\:\.]/.test(ch)) + return ret(ch); + else if (ch == "0" && stream.eat(/x/i)) { + stream.eatWhile(/[\da-f]/i); + return ret("number", "pg-atom"); + } + else if (/\d/.test(ch)) { + stream.match(/^\d*(?:\.\d*)?(?:e[+\-]?\d+)?/); + return ret("number", "pg-atom"); + } + else if (ch == "$" || ch == "@") { + stream.match(/[a-z_][a-z\d_]*/i); + return ret("variable", "pg-variable"); + } + else if (ch == "\\") { + stream.match(/[a-z_][a-z\d_]*/i); + return ret("variable", "pg-variable"); + } + else if (ch == "#") { + stream.skipToEnd(); + return ret("comment", "pg-comment"); + } + else if (ch == "/") { + if (stream.eat("*")) { + return chain(stream, state, jsTokenComment); + } + else if (stream.eat("/")) { + stream.skipToEnd(); + return ret("comment", "pg-comment"); + } + else if (state.reAllowed) { + nextUntilUnescaped(stream, "/"); + stream.eatWhile(/[gimy]/); // 'y' is "sticky" option in Mozilla + return ret("regexp", "pg-string"); + } + else { + stream.eatWhile(isOperatorChar); + return ret("operator", null, stream.current()); + } + } + else if (isOperatorChar.test(ch)) { + stream.eatWhile(isOperatorChar); + return ret("operator", null, stream.current()); + } + else { + stream.eatWhile(/[\w\$_]/); + var word = stream.current(), known = keywords.propertyIsEnumerable(word) && keywords[word]; + return known ? ret(known.type, known.style, word) : + ret("funcall", "pg-funccall", word); + } + } + + function jsTokenString(quote) { + return function(stream, state) { + if (!nextUntilUnescaped(stream, quote)) + state.tokenize = jsTokenBase; + return ret("string", "pg-string"); + }; + } + + function jsTokenComment(stream, state) { + var maybeEnd = false, ch; + while (ch = stream.next()) { + if (ch == "/" && maybeEnd) { + state.tokenize = jsTokenBase; + break; + } + maybeEnd = (ch == "*"); + } + return ret("comment", "pg-comment"); + } + + // Parser + + var atomicTypes = {"atom": true, "number": true, "variable": true, "string": true, "regexp": true}; + + function JSLexical(indented, column, type, align, prev, info) { + this.indented = indented; + this.column = column; + this.type = type; + this.prev = prev; + this.info = info; + if (align != null) this.align = align; + } + + function inScope(state, varname) { + for (var v = state.localVars; v; v = v.next) + if (v.name == varname) return true; + } + + function parseJS(state, style, type, content, stream) { + var cc = state.cc; + // Communicate our context to the combinators. + // (Less wasteful than consing up a hundred closures on every call.) + cx.state = state; cx.stream = stream; cx.marked = null, cx.cc = cc; + + if (!state.lexical.hasOwnProperty("align")) + state.lexical.align = true; + + while(true) { + var combinator = cc.length ? cc.pop() : jsonMode ? expression : statement; + if (combinator(type, content)) { + while(cc.length && cc[cc.length - 1].lex) + cc.pop()(); + if (cx.marked) return cx.marked; + if (type == "variable" && inScope(state, content)) return "pg-localvariable"; + return style; + } + } + } + + // Combinator utils + + var cx = {state: null, column: null, marked: null, cc: null}; + function pass() { + for (var i = arguments.length - 1; i >= 0; i--) cx.cc.push(arguments[i]); + } + function cont() { + pass.apply(null, arguments); + return true; + } + function register(varname) { + var state = cx.state; + if (state.context) { + cx.marked = "pg-variabledef"; + for (var v = state.localVars; v; v = v.next) + if (v.name == varname) return; + state.localVars = {name: varname, next: state.localVars}; + } + } + + // Combinators + + var defaultVars = {name: "this", next: {name: "arguments"}}; + function pushcontext() { + if (!cx.state.context) cx.state.localVars = defaultVars; + cx.state.context = {prev: cx.state.context, vars: cx.state.localVars}; + } + function popcontext() { + cx.state.localVars = cx.state.context.vars; + cx.state.context = cx.state.context.prev; + } + function pushlex(type, info) { + var result = function() { + var state = cx.state; + state.lexical = new JSLexical(state.indented, cx.stream.column(), type, null, state.lexical, info) + }; + result.lex = true; + return result; + } + function poplex() { + var state = cx.state; + if (state.lexical.prev) { + if (state.lexical.type == ")") + state.indented = state.lexical.indented; + state.lexical = state.lexical.prev; + } + } + poplex.lex = true; + + function expect(wanted) { + return function expecting(type) { + if (type == wanted) return cont(); + else if (wanted == ";") return pass(); + else return cont(arguments.callee); + }; + } + + function statement(type) { + if (type == "var") return cont(pushlex("vardef"), vardef1, expect(";"), poplex); + if (type == "keyword a") return cont(pushlex("form"), expression, statement, poplex); + if (type == "keyword b") return cont(pushlex("form"), statement, poplex); + if (type == "{") return cont(pushlex("}"), block, poplex); + if (type == ";") return cont(); + if (type == "function") return cont(functiondef); + if (type == "for") return cont(pushlex("form"), expect("("), pushlex(")"), forspec1, expect(")"), + poplex, statement, poplex); + if (type == "variable") return cont(pushlex("stat"), maybelabel); + if (type == "switch") return cont(pushlex("form"), expression, pushlex("}", "switch"), expect("{"), + block, poplex, poplex); + if (type == "case") return cont(expression, expect(":")); + if (type == "default") return cont(expect(":")); + if (type == "catch") return cont(pushlex("form"), pushcontext, expect("("), funarg, expect(")"), + statement, poplex, popcontext); + return pass(pushlex("stat"), expression, expect(";"), poplex); + } + function expression(type) { + if (atomicTypes.hasOwnProperty(type)) return cont(maybeoperator); + if (type == "function") return cont(functiondef); + if (type == "keyword c") return cont(expression); + if (type == "(") return cont(pushlex(")"), expression, expect(")"), poplex, maybeoperator); + if (type == "operator") return cont(expression); + if (type == "[") return cont(pushlex("]"), commasep(expression, "]"), poplex, maybeoperator); + if (type == "{") return cont(pushlex("}"), commasep(objprop, "}"), poplex, maybeoperator); + return cont(); + } + function maybeoperator(type, value) { + if (type == "operator" && /\+\+|--/.test(value)) return cont(maybeoperator); + if (type == "operator") return cont(expression); + if (type == ";") return; + if (type == "(") return cont(pushlex(")"), commasep(expression, ")"), poplex, maybeoperator); + if (type == ".") return cont(property, maybeoperator); + if (type == "[") return cont(pushlex("]"), expression, expect("]"), poplex, maybeoperator); + } + function maybelabel(type) { + if (type == ":") return cont(poplex, statement); + return pass(maybeoperator, expect(";"), poplex); + } + function property(type) { + if (type == "variable") {cx.marked = "pg-property"; return cont();} + } + function objprop(type) { + if (type == "variable") cx.marked = "pg-property"; + if (atomicTypes.hasOwnProperty(type)) return cont(expect(":"), expression); + } + function commasep(what, end) { + function proceed(type) { + if (type == ",") return cont(what, proceed); + if (type == end) return cont(); + return cont(expect(end)); + } + return function commaSeparated(type) { + if (type == end) return cont(); + else return pass(what, proceed); + }; + } + function block(type) { + if (type == "}") return cont(); + return pass(statement, block); + } + function vardef1(type, value) { + if (type == "variable"){register(value); return cont(vardef2);} + return cont(); + } + function vardef2(type, value) { + if (value == "=") return cont(expression, vardef2); + if (type == ",") return cont(vardef1); + } + function forspec1(type) { + if (type == "var") return cont(vardef1, forspec2); + if (type == ";") return pass(forspec2); + if (type == "variable") return cont(formaybein); + return pass(forspec2); + } + function formaybein(type, value) { + if (value == "in") return cont(expression); + return cont(maybeoperator, forspec2); + } + function forspec2(type, value) { + if (type == ";") return cont(forspec3); + if (value == "in") return cont(expression); + return cont(expression, expect(";"), forspec3); + } + function forspec3(type) { + if (type != ")") cont(expression); + } + function functiondef(type, value) { + if (type == "variable") {register(value); return cont(functiondef);} + if (type == "(") return cont(pushlex(")"), pushcontext, commasep(funarg, ")"), poplex, statement, popcontext); + } + function funarg(type, value) { + if (type == "variable") {register(value); return cont();} + } + + // Interface + + return { + startState: function(basecolumn) { + return { + tokenize: jsTokenBase, + reAllowed: true, + cc: [], + lexical: new JSLexical((basecolumn || 0) - indentUnit, 0, "block", false), + localVars: null, + context: null, + indented: 0 + }; + }, + + token: function(stream, state) { + if (stream.sol()) { + if (!state.lexical.hasOwnProperty("align")) + state.lexical.align = false; + state.indented = stream.indentation(); + } + if (stream.eatSpace()) return null; + var style = state.tokenize(stream, state); + if (type == "comment") return style; + state.reAllowed = type == "operator" || type == "keyword c" || type.match(/^[\[{}\(,;:]$/); + return parseJS(state, style, type, content, stream); + }, + + indent: function(state, textAfter) { + if (state.tokenize != jsTokenBase) return 0; + var firstChar = textAfter && textAfter.charAt(0), lexical = state.lexical, + type = lexical.type, closing = firstChar == type; + if (type == "vardef") return lexical.indented + 4; + else if (type == "form" && firstChar == "{") return lexical.indented; + else if (type == "stat" || type == "form") return lexical.indented + indentUnit; + else if (lexical.info == "switch" && !closing) + return lexical.indented + (/^(?:case|default)\b/.test(textAfter) ? indentUnit : 2 * indentUnit); + else if (lexical.align) return lexical.column + (closing ? 0 : 1); + else return lexical.indented + (closing ? 0 : indentUnit); + }, + + electricChars: ":{}" + }; +}); + +CodeMirror.defineMIME("text/pg", "pg"); diff --git a/htdocs/codemirror2/mode/php/index.html b/htdocs/codemirror2/mode/php/index.html new file mode 100644 index 000000000..020e24898 --- /dev/null +++ b/htdocs/codemirror2/mode/php/index.html @@ -0,0 +1,52 @@ + + + + CodeMirror 2: PHP mode + + + + + + + + + + + + + + + +

CodeMirror 2: PHP mode

+ +
+ + + +

Simple HTML/PHP mode based on + the C-like mode. Depends on XML, + JavaScript, CSS, and C-like modes.

+ +

MIME types defined: application/x-httpd-php.

+ + diff --git a/htdocs/codemirror2/mode/php/php.js b/htdocs/codemirror2/mode/php/php.js new file mode 100644 index 000000000..a23538f6b --- /dev/null +++ b/htdocs/codemirror2/mode/php/php.js @@ -0,0 +1,83 @@ +(function() { + function keywords(str) { + var obj = {}, words = str.split(" "); + for (var i = 0; i < words.length; ++i) obj[words[i]] = true; + return obj; + } + var phpKeywords = + keywords("abstract and array as break case catch cfunction class clone const continue declare " + + "default do else elseif enddeclare endfor endforeach endif endswitch endwhile extends " + + "final for foreach function global goto if implements interface instanceof namespace " + + "new or private protected public static switch throw try use var while xor"); + + CodeMirror.defineMode("php", function(config, parserConfig) { + var htmlMode = CodeMirror.getMode(config, "text/html"); + var jsMode = CodeMirror.getMode(config, "text/javascript"); + var cssMode = CodeMirror.getMode(config, "text/css"); + var phpMode = CodeMirror.getMode(config, {name: "clike", keywords: phpKeywords, multiLineStrings: true, $vars: true}); + + function dispatch(stream, state) { // TODO open PHP inside text/css + if (state.curMode == htmlMode) { + var style = htmlMode.token(stream, state.curState); + if (style == "xml-processing" && /^<\?/.test(stream.current())) { + state.curMode = phpMode; + state.curState = state.php; + state.curClose = /^\?>/; + } + else if (style == "xml-tag" && stream.current() == ">" && state.curState.context) { + if (/^script$/i.test(state.curState.context.tagName)) { + state.curMode = jsMode; + state.curState = jsMode.startState(htmlMode.indent(state.curState, "")); + state.curClose = /^<\/\s*script\s*>/i; + } + else if (/^style$/i.test(state.curState.context.tagName)) { + state.curMode = cssMode; + state.curState = cssMode.startState(htmlMode.indent(state.curState, "")); + state.curClose = /^<\/\s*style\s*>/i; + } + } + return style; + } + else if (stream.match(state.curClose, false)) { + state.curMode = htmlMode; + state.curState = state.html; + state.curClose = null; + return dispatch(stream, state); + } + else return state.curMode.token(stream, state.curState); + } + + return { + startState: function() { + var html = htmlMode.startState(); + return {html: html, + php: phpMode.startState(), + curMode: htmlMode, + curState: html, + curClose: null} + }, + + copyState: function(state) { + var html = state.html, htmlNew = CodeMirror.copyState(htmlMode, html), + php = state.php, phpNew = CodeMirror.copyState(phpMode, php), cur; + if (state.curState == html) cur = htmlNew; + else if (state.curState == php) cur = phpNew; + else cur = CodeMirror.copyState(state.curMode, state.curState); + return {html: htmlNew, php: phpNew, curMode: state.curMode, curState: cur, curClose: state.curClose}; + }, + + token: dispatch, + + indent: function(state, textAfter) { + if ((state.curMode != phpMode && /^\s*<\//.test(textAfter)) || + (state.curMode == phpMode && /^\?>/.test(textAfter))) + return htmlMode.indent(state.html, textAfter); + return state.curMode.indent(state.curState, textAfter); + }, + + electricChars: "/{}:" + } + }); +})(); + +CodeMirror.defineMIME("application/x-httpd-php", "php"); diff --git a/htdocs/codemirror2/mode/python/LICENSE.txt b/htdocs/codemirror2/mode/python/LICENSE.txt new file mode 100644 index 000000000..918866b42 --- /dev/null +++ b/htdocs/codemirror2/mode/python/LICENSE.txt @@ -0,0 +1,21 @@ +The MIT License + +Copyright (c) 2010 Timothy Farrell + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. \ No newline at end of file diff --git a/htdocs/codemirror2/mode/python/index.html b/htdocs/codemirror2/mode/python/index.html new file mode 100644 index 000000000..e9640e9e4 --- /dev/null +++ b/htdocs/codemirror2/mode/python/index.html @@ -0,0 +1,123 @@ + + + + CodeMirror 2: Python mode + + + + + + + + +

CodeMirror 2: Python mode

+ +
+ +

Configuration Options:

+
    +
  • version - 2/3 - The version of Python to recognize. Default is 2.
  • +
  • singleLineStringErrors - true/false - If you have a single-line string that is not terminated at the end of the line, this will show subsequent lines as errors if true, otherwise it will consider the newline as the end of the string. Default is false.
  • +
+ +

MIME types defined: text/x-python.

+ + diff --git a/htdocs/codemirror2/mode/python/python.css b/htdocs/codemirror2/mode/python/python.css new file mode 100644 index 000000000..353fd963a --- /dev/null +++ b/htdocs/codemirror2/mode/python/python.css @@ -0,0 +1,23 @@ +span.py-delimiter, +span.py-special {color: #666666;} + +span.py-operator {color: #666666;} + +span.py-error {background-color: #660000; color: #FFFFFF;} + +span.py-keyword {color: #770088; font-weight: bold;} + +span.py-number {color: #228811;} + +span.py-identifier, +span.py-func {color: black;} + +span.py-type, +span.py-decorator {color: #0000FF;} + +span.py-comment {color: #AA7700;} + +span.py-string, +span.py-bytes, +span.py-raw, +span.py-unicode {color: #AA2222;} \ No newline at end of file diff --git a/htdocs/codemirror2/mode/python/python.js b/htdocs/codemirror2/mode/python/python.js new file mode 100644 index 000000000..373f51ce0 --- /dev/null +++ b/htdocs/codemirror2/mode/python/python.js @@ -0,0 +1,318 @@ +CodeMirror.defineMode("python", function(conf) { + var ERRORCLASS = 'py-error'; + + function wordRegexp(words) { + return new RegExp("^((" + words.join(")|(") + "))\\b"); + } + + var singleOperators = new RegExp("^[\\+\\-\\*/%&|\\^~<>!]"); + var singleDelimiters = new RegExp('^[\\(\\)\\[\\]\\{\\}@,:`=;\\.]'); + var doubleOperators = new RegExp("^((==)|(!=)|(<=)|(>=)|(<>)|(<<)|(>>)|(//)|(\\*\\*))"); + var doubleDelimiters = new RegExp("^((\\+=)|(\\-=)|(\\*=)|(%=)|(/=)|(&=)|(\\|=)|(\\^=))"); + var tripleDelimiters = new RegExp("^((//=)|(>>=)|(<<=)|(\\*\\*=))"); + var identifiers = new RegExp("^[_A-Za-z][_A-Za-z0-9]*"); + + var wordOperators = wordRegexp(['and', 'or', 'not', 'is', 'in']); + var commonkeywords = ['as', 'assert', 'break', 'class', 'continue', + 'def', 'del', 'elif', 'else', 'except', 'finally', + 'for', 'from', 'global', 'if', 'import', + 'lambda', 'pass', 'raise', 'return', + 'try', 'while', 'with', 'yield']; + var commontypes = ['bool', 'classmethod', 'complex', 'dict', 'enumerate', + 'float', 'frozenset', 'int', 'list', 'object', + 'property', 'reversed', 'set', 'slice', 'staticmethod', + 'str', 'super', 'tuple', 'type']; + var py2 = {'types': ['basestring', 'buffer', 'file', 'long', 'unicode', + 'xrange'], + 'keywords': ['exec', 'print']}; + var py3 = {'types': ['bytearray', 'bytes', 'filter', 'map', 'memoryview', + 'open', 'range', 'zip'], + 'keywords': ['nonlocal']}; + + if (!!conf.mode.version && parseInt(conf.mode.version, 10) === 3) { + commonkeywords = commonkeywords.concat(py3.keywords); + commontypes = commontypes.concat(py3.types); + var stringPrefixes = new RegExp("^(([rb]|(br))?('{3}|\"{3}|['\"]))", "i"); + } else { + commonkeywords = commonkeywords.concat(py2.keywords); + commontypes = commontypes.concat(py2.types); + var stringPrefixes = new RegExp("^(([rub]|(ur)|(br))?('{3}|\"{3}|['\"]))", "i"); + } + var keywords = wordRegexp(commonkeywords); + var types = wordRegexp(commontypes); + + // tokenizers + function tokenBase(stream, state) { + // Handle scope changes + if (stream.sol()) { + var scopeOffset = state.scopes[0].offset; + if (stream.eatSpace()) { + var lineOffset = stream.indentation(); + if (lineOffset > scopeOffset) { + return 'py-indent'; + } else if (lineOffset < scopeOffset) { + return 'py-dedent'; + } + return 'whitespace'; + } else { + if (scopeOffset > 0) { + dedent(stream, state); + } + } + } + if (stream.eatSpace()) { + return 'py-space'; + } + + var ch = stream.peek(); + + // Handle Comments + if (ch === '#') { + stream.skipToEnd(); + return 'py-comment'; + } + + // Handle Number Literals + if (stream.match(/^[0-9\.]/, false)) { + var floatLiteral = false; + // Floats + if (stream.match(/^\d*\.\d+(e[\+\-]?\d+)?/i)) { floatLiteral = true; } + if (stream.match(/^\d+\.\d*/)) { floatLiteral = true; } + if (stream.match(/^\.\d+/)) { floatLiteral = true; } + if (floatLiteral) { + // Float literals may be "imaginary" + stream.eat(/J/i); + return 'py-literal'; + } + // Integers + var intLiteral = false; + // Hex + if (stream.match(/^0x[0-9a-f]+/i)) { intLiteral = true; } + // Binary + if (stream.match(/^0b[01]+/i)) { intLiteral = true; } + // Octal + if (stream.match(/^0o[0-7]+/i)) { intLiteral = true; } + // Decimal + if (stream.match(/^[1-9]\d*(e[\+\-]?\d+)?/)) { + // Decimal literals may be "imaginary" + stream.eat(/J/i); + // TODO - Can you have imaginary longs? + intLiteral = true; + } + // Zero by itself with no other piece of number. + if (stream.match(/^0(?![\dx])/i)) { intLiteral = true; } + if (intLiteral) { + // Integer literals may be "long" + stream.eat(/L/i); + return 'py-literal'; + } + } + + // Handle Strings + if (stream.match(stringPrefixes)) { + state.tokenize = tokenStringFactory(stream.current()); + return state.tokenize(stream, state); + } + + // Handle operators and Delimiters + if (stream.match(tripleDelimiters) || stream.match(doubleDelimiters)) { + return 'py-delimiter'; + } + if (stream.match(doubleOperators) + || stream.match(singleOperators) + || stream.match(wordOperators)) { + return 'py-operator'; + } + if (stream.match(singleDelimiters)) { + return 'py-delimiter'; + } + + if (stream.match(types)) { + return 'py-type'; + } + + if (stream.match(keywords)) { + return 'py-keyword'; + } + + if (stream.match(identifiers)) { + return 'py-identifier'; + } + + // Handle non-detected items + stream.next(); + return ERRORCLASS; + } + + function tokenStringFactory(delimiter) { + while ('rub'.indexOf(delimiter[0].toLowerCase()) >= 0) { + delimiter = delimiter.substr(1); + } + var delim_re = new RegExp(delimiter); + var singleline = delimiter.length == 1; + var OUTCLASS = 'py-string'; + + return function tokenString(stream, state) { + while (!stream.eol()) { + stream.eatWhile(/[^'"\\]/); + if (stream.eat('\\')) { + stream.next(); + if (singleline && stream.eol()) { + return OUTCLASS; + } + } else if (stream.match(delim_re)) { + state.tokenize = tokenBase; + return OUTCLASS; + } else { + stream.eat(/['"]/); + } + } + if (singleline) { + if (conf.mode.singleLineStringErrors) { + OUTCLASS = ERRORCLASS + } else { + state.tokenize = tokenBase; + } + } + return OUTCLASS; + }; + } + + function indent(stream, state, type) { + type = type || 'py'; + var indentUnit = 0; + if (type === 'py') { + for (var i = 0; i < state.scopes.length; ++i) { + if (state.scopes[i].type === 'py') { + indentUnit = state.scopes[i].offset + conf.indentUnit; + break; + } + } + } else { + indentUnit = stream.column() + stream.current().length; + } + state.scopes.unshift({ + offset: indentUnit, + type: type + }); + } + + function dedent(stream, state) { + if (state.scopes.length == 1) return; + if (state.scopes[0].type === 'py') { + var _indent = stream.indentation(); + var _indent_index = -1; + for (var i = 0; i < state.scopes.length; ++i) { + if (_indent === state.scopes[i].offset) { + _indent_index = i; + break; + } + } + if (_indent_index === -1) { + return true; + } + while (state.scopes[0].offset !== _indent) { + state.scopes.shift(); + } + return false + } else { + state.scopes.shift(); + return false; + } + } + + function tokenLexer(stream, state) { + var style = state.tokenize(stream, state); + var current = stream.current(); + + // Handle '.' connected identifiers + if (current === '.') { + style = state.tokenize(stream, state); + current = stream.current(); + if (style === 'py-identifier') { + return 'py-identifier'; + } else { + return ERRORCLASS; + } + } + + // Handle decorators + if (current === '@') { + style = state.tokenize(stream, state); + current = stream.current(); + if (style === 'py-identifier' + || current === '@staticmethod' + || current === '@classmethod') { + return 'py-decorator'; + } else { + return ERRORCLASS; + } + } + + // Handle scope changes. + if (current === 'pass' || current === 'return') { + state.dedent += 1; + } + if ((current === ':' && !state.lambda && state.scopes[0].type == 'py') + || style === 'py-indent') { + indent(stream, state); + } + var delimiter_index = '[({'.indexOf(current); + if (delimiter_index !== -1) { + indent(stream, state, '])}'.slice(delimiter_index, delimiter_index+1)); + } + if (style === 'py-dedent') { + if (dedent(stream, state)) { + return ERRORCLASS; + } + } + delimiter_index = '])}'.indexOf(current); + if (delimiter_index !== -1) { + if (dedent(stream, state)) { + return ERRORCLASS; + } + } + if (state.dedent > 0 && stream.eol() && state.scopes[0].type == 'py') { + if (state.scopes.length > 1) state.scopes.shift(); + state.dedent -= 1; + } + + return style; + } + + var external = { + startState: function(basecolumn) { + return { + tokenize: tokenBase, + scopes: [{offset:basecolumn || 0, type:'py'}], + lastToken: null, + lambda: false, + dedent: 0 + }; + }, + + token: function(stream, state) { + var style = tokenLexer(stream, state); + + state.lastToken = {style:style, content: stream.current()}; + + if (stream.eol() && stream.lambda) { + state.lambda = false; + } + + return style; + }, + + indent: function(state, textAfter) { + if (state.tokenize != tokenBase) { + return 0; + } + + return state.scopes[0].offset; + } + + }; + return external; +}); + +CodeMirror.defineMIME("text/x-python", "python"); diff --git a/htdocs/codemirror2/mode/rst/index.html b/htdocs/codemirror2/mode/rst/index.html new file mode 100644 index 000000000..0831dff46 --- /dev/null +++ b/htdocs/codemirror2/mode/rst/index.html @@ -0,0 +1,526 @@ + + + + CodeMirror 2: reStructuredText mode + + + + + + + + +

CodeMirror 2: reStructuredText mode

+ +
+ + +

The reStructuredText mode supports one configuration parameter:

+
+
verbatim (string)
+
A name or MIME type of a mode that will be used for highlighting + verbatim blocks. By default, reStructuredText mode uses uniform color + for whole block of verbatim text if no mode is given.
+
+

If python mode is available (not a part of CodeMirror 2 yet), + it will be used for highlighting blocks containing Python/IPython terminal + sessions (blocks starting with >>> (for Python) or + In [num]: (for IPython). + +

MIME types defined: text/x-rst.

+ + + diff --git a/htdocs/codemirror2/mode/rst/rst.css b/htdocs/codemirror2/mode/rst/rst.css new file mode 100644 index 000000000..90ba05e30 --- /dev/null +++ b/htdocs/codemirror2/mode/rst/rst.css @@ -0,0 +1,77 @@ + +span.rst-emphasis { + font-style: italic; +} + +span.rst-strong { + font-weight: bold; +} + +span.rst-interpreted { + color: #33cc66; +} + +span.rst-inline { + color: #3399cc; +} + +span.rst-role { + color: #666699; +} + +span.rst-list { + color: #cc0099; + font-weight: bold; +} + +span.rst-body { + color: #6699cc; +} + +span.rst-verbatim { + color: #3366ff; +} + +span.rst-comment { + color: #aa7700; +} + +span.rst-directive { + font-weight: bold; + color: #3399ff; +} + +span.rst-hyperlink { + font-weight: bold; + color: #3366ff; +} + +span.rst-footnote { + font-weight: bold; + color: #3333ff; +} + +span.rst-citation { + font-weight: bold; + color: #3300ff; +} + +span.rst-replacement { + color: #9933cc; +} + +span.rst-section { + font-weight: bold; + color: #cc0099; +} + +span.rst-directive-marker { + font-weight: bold; + color: #3399ff; +} + +span.rst-verbatim-marker { + font-weight: bold; + color: #9900ff; +} + diff --git a/htdocs/codemirror2/mode/rst/rst.js b/htdocs/codemirror2/mode/rst/rst.js new file mode 100644 index 000000000..731fcab40 --- /dev/null +++ b/htdocs/codemirror2/mode/rst/rst.js @@ -0,0 +1,335 @@ + +CodeMirror.defineMode('rst', function(config, options) { + function setState(state, fn, ctx) { + state.fn = fn; + setCtx(state, ctx); + } + + function setCtx(state, ctx) { + state.ctx = ctx || {}; + } + + function setNormal(state, ch) { + if (ch && (typeof ch !== 'string')) { + var str = ch.current(); + ch = str[str.length-1]; + } + + setState(state, normal, {back: ch}); + } + + function hasMode(mode) { + if (mode) { + var modes = CodeMirror.listModes(); + + for (var i in modes) { + if (modes[i] == mode) { + return true; + } + } + } + + return false; + } + + function getMode(mode) { + if (hasMode(mode)) { + return CodeMirror.getMode(config, mode); + } else { + return null; + } + } + + var verbatimMode = getMode(options.verbatim); + var pythonMode = getMode('python'); + + var reSection = /^[!"#$%&'()*+,-./:;<=>?@[\\\]^_`{|}~]/; + var reDirective = /^\s*\w([-:.\w]*\w)?::(\s|$)/; + var reHyperlink = /^\s*_[\w-]+:(\s|$)/; + var reFootnote = /^\s*\[(\d+|#)\](\s|$)/; + var reCitation = /^\s*\[[A-Za-z][\w-]*\](\s|$)/; + var reFootnoteRef = /^\[(\d+|#)\]_/; + var reCitationRef = /^\[[A-Za-z][\w-]*\]_/; + var reDirectiveMarker = /^\.\.(\s|$)/; + var reVerbatimMarker = /^::\s*$/; + var rePreInline = /^[-\s"([{/:.,;!?\\_]/; + var reEnumeratedList = /^\s*((\d+|[A-Za-z#])[.)]|\((\d+|[A-Z-a-z#])\))\s/; + var reBulletedList = /^\s*[-\+\*]\s/; + var reExamples = /^\s+(>>>|In \[\d+\]:)\s/; + + function normal(stream, state) { + var ch, sol, i; + + if (stream.eat(/\\/)) { + ch = stream.next(); + setNormal(state, ch); + return null; + } + + sol = stream.sol(); + + if (sol && (ch = stream.eat(reSection))) { + for (i = 0; stream.eat(ch); i++); + + if (i >= 3 && stream.match(/^\s*$/)) { + setNormal(state, null); + return 'rst-section'; + } else { + stream.backUp(i + 1); + } + } + + if (sol && stream.match(reDirectiveMarker)) { + if (!stream.eol()) { + setState(state, directive); + } + + return 'rst-directive-marker'; + } + + if (stream.match(reVerbatimMarker)) { + if (!verbatimMode) { + setState(state, verbatim); + } else { + var mode = verbatimMode; + + setState(state, verbatim, { + mode: mode, + local: mode.startState() + }); + } + + return 'rst-verbatim-marker'; + } + + if (sol && stream.match(reExamples, false)) { + if (!pythonMode) { + setState(state, verbatim); + return 'rst-verbatim-marker'; + } else { + var mode = pythonMode; + + setState(state, verbatim, { + mode: mode, + local: mode.startState() + }); + + return null; + } + } + + if (sol && (stream.match(reEnumeratedList) || + stream.match(reBulletedList))) { + setNormal(state, stream); + return 'rst-list'; + } + + function testBackward(re) { + return sol || !state.ctx.back || re.test(state.ctx.back); + } + + function testForward(re) { + return stream.eol() || stream.match(re, false); + } + + function testInline(re) { + return stream.match(re) && testBackward(/\W/) && testForward(/\W/); + } + + if (testInline(reFootnoteRef)) { + setNormal(state, stream); + return 'rst-footnote'; + } + + if (testInline(reCitationRef)) { + setNormal(state, stream); + return 'rst-citation'; + } + + ch = stream.next(); + + if (testBackward(rePreInline)) { + if ((ch === ':' || ch === '|') && stream.eat(/\S/)) { + var token; + + if (ch === ':') { + token = 'rst-role'; + } else { + token = 'rst-replacement'; + } + + setState(state, inline, { + ch: ch, + wide: false, + prev: null, + token: token + }); + + return token; + } + + if (ch === '*' || ch === '`') { + var orig = ch, + wide = false; + + ch = stream.next(); + + if (ch == orig) { + wide = true; + ch = stream.next(); + } + + if (ch && !/\s/.test(ch)) { + var token; + + if (orig === '*') { + token = wide ? 'rst-strong' : 'rst-emphasis'; + } else { + token = wide ? 'rst-inline' : 'rst-interpreted'; + } + + setState(state, inline, { + ch: orig, // inline() has to know what to search for + wide: wide, // are we looking for `ch` or `chch` + prev: null, // terminator must not be preceeded with whitespace + token: token, // I don't want to recompute this all the time + }); + + return token; + } + } + } + + setNormal(state, ch); + return null; + } + + function inline(stream, state) { + var ch = stream.next(), + token = state.ctx.token; + + function finish(ch) { + state.ctx.prev = ch; + return token; + } + + if (ch != state.ctx.ch) { + return finish(ch); + } + + if (/\s/.test(state.ctx.prev)) { + return finish(ch); + } + + if (state.ctx.wide) { + ch = stream.next(); + + if (ch != state.ctx.ch) { + return finish(ch); + } + } + + if (!stream.eol() && !rePostInline.test(stream.peek())) { + if (state.ctx.wide) { + stream.backUp(1); + } + + return finish(ch); + } + + setState(state, normal); + setNormal(state, ch); + + return token; + } + + function directive(stream, state) { + var token = null; + + if (stream.match(reDirective)) { + token = 'rst-directive'; + } else if (stream.match(reHyperlink)) { + token = 'rst-hyperlink'; + } else if (stream.match(reFootnote)) { + token = 'rst-footnote'; + } else if (stream.match(reCitation)) { + token = 'rst-citation'; + } else { + stream.eatSpace(); + + if (stream.eol()) { + setNormal(state, stream); + return null; + } else { + stream.skipToEnd(); + setState(state, comment); + return 'rst-comment'; + } + } + + setState(state, body, {start: true}); + return token; + } + + function body(stream, state) { + var token = 'rst-body'; + + if (!state.ctx.start || stream.sol()) { + return block(stream, state, token); + } + + stream.skipToEnd(); + setCtx(state); + + return token; + } + + function comment(stream, state) { + return block(stream, state, 'rst-comment'); + } + + function verbatim(stream, state) { + if (!verbatimMode) { + return block(stream, state, 'rst-verbatim'); + } else { + if (stream.sol()) { + if (!stream.eatSpace()) { + setNormal(state, stream); + } + + return null; + } + + return verbatimMode.token(stream, state.ctx.local); + } + } + + function block(stream, state, token) { + if (stream.eol() || stream.eatSpace()) { + stream.skipToEnd(); + return token; + } else { + setNormal(state, stream); + return null; + } + } + + return { + startState: function() { + return {fn: normal, ctx: {}}; + }, + + copyState: function(state) { + return {fn: state.fn, ctx: state.ctx}; + }, + + token: function(stream, state) { + var token = state.fn(stream, state); + return token; + } + }; +}); + +CodeMirror.defineMIME("text/x-rst", "rst"); + diff --git a/htdocs/codemirror2/mode/smalltalk/index.html b/htdocs/codemirror2/mode/smalltalk/index.html new file mode 100644 index 000000000..fe56b5891 --- /dev/null +++ b/htdocs/codemirror2/mode/smalltalk/index.html @@ -0,0 +1,56 @@ + + + + CodeMirror 2: Smalltalk mode + + + + + + + + +

CodeMirror 2: Smalltalk mode

+ +
+ + + +

Simple Smalltalk mode.

+ +

MIME types defined: text/x-stsrc.

+ + diff --git a/htdocs/codemirror2/mode/smalltalk/smalltalk.css b/htdocs/codemirror2/mode/smalltalk/smalltalk.css new file mode 100644 index 000000000..7c2daa49d --- /dev/null +++ b/htdocs/codemirror2/mode/smalltalk/smalltalk.css @@ -0,0 +1,5 @@ +span.st-keyword {color: #90b;} +span.st-number {color: #291;} +span.st-comment {color: #a70;} +span.st-string {color: #a22;} +span.st-var {color: #22b;} diff --git a/htdocs/codemirror2/mode/smalltalk/smalltalk.js b/htdocs/codemirror2/mode/smalltalk/smalltalk.js new file mode 100644 index 000000000..763f70de8 --- /dev/null +++ b/htdocs/codemirror2/mode/smalltalk/smalltalk.js @@ -0,0 +1,122 @@ +CodeMirror.defineMode("smalltalk", function(config, parserConfig) { + var keywords = {"true": 1, "false": 1, nil: 1, self: 1, "super": 1, thisContext: 1}; + var indentUnit = config.indentUnit; + + function chain(stream, state, f) { + state.tokenize = f; + return f(stream, state); + } + + var type; + function ret(tp, style) { + type = tp; + return style; + } + + function tokenBase(stream, state) { + var ch = stream.next(); + if (ch == '"') + return chain(stream, state, tokenComment(ch)); + else if (ch == "'") + return chain(stream, state, tokenString(ch)); + else if (ch == "#") { + stream.eatWhile(/[\w\$_]/); + return ret("string", "st-string"); + } + else if (/\d/.test(ch)) { + stream.eatWhile(/[\w\.]/) + return ret("number", "st-number"); + } + else if (/[\[\]()]/.test(ch)) { + return ret(ch, null); + } + else { + stream.eatWhile(/[\w\$_]/); + if (keywords && keywords.propertyIsEnumerable(stream.current())) return ret("keyword", "st-keyword"); + return ret("word", "st-word"); + } + } + + function tokenString(quote) { + return function(stream, state) { + var escaped = false, next, end = false; + while ((next = stream.next()) != null) { + if (next == quote && !escaped) {end = true; break;} + escaped = !escaped && next == "\\"; + } + if (end || !(escaped)) + state.tokenize = tokenBase; + return ret("string", "st-string"); + }; + } + + function tokenComment(quote) { + return function(stream, state) { + var next, end = false; + while ((next = stream.next()) != null) { + if (next == quote) {end = true; break;} + } + if (end) + state.tokenize = tokenBase; + return ret("comment", "st-comment"); + }; + } + + function Context(indented, column, type, align, prev) { + this.indented = indented; + this.column = column; + this.type = type; + this.align = align; + this.prev = prev; + } + + function pushContext(state, col, type) { + return state.context = new Context(state.indented, col, type, null, state.context); + } + function popContext(state) { + return state.context = state.context.prev; + } + + // Interface + + return { + startState: function(basecolumn) { + return { + tokenize: tokenBase, + context: new Context((basecolumn || 0) - indentUnit, 0, "top", false), + indented: 0, + startOfLine: true + }; + }, + + token: function(stream, state) { + var ctx = state.context; + if (stream.sol()) { + if (ctx.align == null) ctx.align = false; + state.indented = stream.indentation(); + state.startOfLine = true; + } + if (stream.eatSpace()) return null; + var style = state.tokenize(stream, state); + if (type == "comment") return style; + if (ctx.align == null) ctx.align = true; + + if (type == "[") pushContext(state, stream.column(), "]"); + else if (type == "(") pushContext(state, stream.column(), ")"); + else if (type == ctx.type) popContext(state); + state.startOfLine = false; + return style; + }, + + indent: function(state, textAfter) { + if (state.tokenize != tokenBase) return 0; + var firstChar = textAfter && textAfter.charAt(0), ctx = state.context, closing = firstChar == ctx.type; + if (ctx.align) return ctx.column + (closing ? 0 : 1); + else return ctx.indented + (closing ? 0 : indentUnit); + }, + + electricChars: "]" + }; +}); + +CodeMirror.defineMIME("text/x-stsrc", {name: "smalltalk"}); diff --git a/htdocs/codemirror2/mode/stex/index.html b/htdocs/codemirror2/mode/stex/index.html new file mode 100644 index 000000000..73b07ac13 --- /dev/null +++ b/htdocs/codemirror2/mode/stex/index.html @@ -0,0 +1,96 @@ + + + + CodeMirror 2: sTeX mode + + + + + + + + +

CodeMirror 2: sTeX mode

+
+ + +

MIME types defined: text/stex.

+ + + diff --git a/htdocs/codemirror2/mode/stex/stex.css b/htdocs/codemirror2/mode/stex/stex.css new file mode 100644 index 000000000..64b975e98 --- /dev/null +++ b/htdocs/codemirror2/mode/stex/stex.css @@ -0,0 +1,20 @@ +span.css-at {color: #708;} +span.css-unit {color: #281;} +span.css-value {color: #708;} +span.css-identifier {color: black;} +span.css-selector {color: #11B;} +span.css-important {color: #00F;} +span.css-colorcode {color: #299;} +span.css-comment {color: #A70;} +span.css-string {color: #A22;} + +span.stex-unit { color: #281; } +span.stex-identifier { color: black; } +span.stex-slash { color: #FAA; } +span.stex-command { color: #00F; } +span.stex-comment { color: #A70; } +span.stex-import { color: #00F; } +span.stex-filepath { color: #852626; } +span.stex-module { color: #852626; } +span.stex-error { text-decoration: underline; color: red; } +span.stex-string { color: #A22; } diff --git a/htdocs/codemirror2/mode/stex/stex.js b/htdocs/codemirror2/mode/stex/stex.js new file mode 100644 index 000000000..10e0d6cad --- /dev/null +++ b/htdocs/codemirror2/mode/stex/stex.js @@ -0,0 +1,167 @@ +/* + * Author: Constantin Jucovschi (c.jucovschi@jacobs-university.de) + * Licence: MIT + */ + +CodeMirror.defineMode("stex", function(cmCfg, modeCfg) +{ + function pushCommand(state, command) { + state.cmdState.push(command); + } + + function peekCommand(state) { + if (state.cmdState.length>0) + return state.cmdState[state.cmdState.length-1]; + else + return null; + } + + function popCommand(state) { + if (state.cmdState.length>0) { + var plug = state.cmdState.pop(); + plug.closeBracket(); + } + } + + function applyMostPowerful(state) { + context = state.cmdState; + for (var i = context.length - 1; i >= 0; i--) { + var plug = context[i]; + if (plug.name=="DEFAULT") + continue; + return plug.styleIdentifier(); + } + return "stex-identifier"; + } + + function addPluginPattern(pluginName, cmdStyle, brackets, styles) { + return function () { + this.name=pluginName; + this.bracketNo = 0; + this.style=cmdStyle; + this.styles = styles; + this.brackets = brackets; + + this.styleIdentifier = function(content) { + if (this.bracketNo<=this.styles.length) + return this.styles[this.bracketNo-1]; + else + return null; + }; + this.openBracket = function(content) { + this.bracketNo++; + return "stex-bracket"; + }; + this.closeBracket = function(content) { + }; + } + } + + var plugins = new Array(); + + plugins["importmodule"] = addPluginPattern("importmodule", "stex-command", "{[", ["stex-filepath", "stex-module"]); + plugins["documentclass"] = addPluginPattern("documentclass", "stex-command", "{[", ["", "stex-unit"]); + plugins["usepackage"] = addPluginPattern("documentclass", "stex-command", "[", ["stex-unit"]); + plugins["begin"] = addPluginPattern("documentclass", "stex-command", "[", ["stex-unit"]); + plugins["end"] = addPluginPattern("documentclass", "stex-command", "[", ["stex-unit"]); + + plugins["DEFAULT"] = function () { + this.name="DEFAULT"; + this.style="stex-command"; + + this.styleIdentifier = function(content) { + }; + this.openBracket = function(content) { + }; + this.closeBracket = function(content) { + }; + }; + + function setState(state, f) { + state.f = f; + } + + function normal(source, state) { + if (source.match(/^\\[a-z]+/)) { + cmdName = source.current(); + cmdName = cmdName.substr(1, cmdName.length-1); + var plug = plugins[cmdName]; + if (typeof(plug) == 'undefined') { + plug = plugins["DEFAULT"]; + } + plug = new plug(); + pushCommand(state, plug); + setState(state, beginParams); + return plug.style; + } + + var ch = source.next(); + if (ch == "%") { + setState(state, inCComment); + return "stex-comment"; + } + else if (ch=='}' || ch==']') { + plug = peekCommand(state); + if (plug) { + plug.closeBracket(ch); + setState(state, beginParams); + } else + return "stex-error"; + return "stex-bracket"; + } else if (ch=='{' || ch=='[') { + plug = plugins["DEFAULT"]; + plug = new plug(); + pushCommand(state, plug); + return "stex-bracket"; + } + else if (/\d/.test(ch)) { + source.eatWhile(/[\w.%]/); + return "stex-unit"; + } + else { + source.eatWhile(/[\w-_]/); + return applyMostPowerful(state); + } + } + + function inCComment(source, state) { + source.skipToEnd(); + setState(state, normal); + return "css-comment"; + } + + function beginParams(source, state) { + var ch = source.peek(); + if (ch == '{' || ch == '[') { + lastPlug = peekCommand(state); + style = lastPlug.openBracket(ch); + source.eat(ch); + setState(state, normal); + return "stex-bracket"; + } + if (/[ \t\r]/.test(ch)) { + source.eat(ch); + return null; + } + setState(state, normal); + lastPlug = peekCommand(state); + if (lastPlug) { + popCommand(state); + } + return normal(source, state); + } + + return { + startState: function() { return { f:normal, cmdState:[] }; }, + copyState: function(s) { return { f: s.f, cmdState: s.cmdState.slice(0, s.cmdState.length) }; }, + + token: function(stream, state) { + var t = state.f(stream, state); + var w = stream.current(); + return t; + } + }; +}); + + +CodeMirror.defineMIME("text/x-stex", "stex"); diff --git a/htdocs/codemirror2/mode/xml/index.html b/htdocs/codemirror2/mode/xml/index.html new file mode 100644 index 000000000..5ad7c63fe --- /dev/null +++ b/htdocs/codemirror2/mode/xml/index.html @@ -0,0 +1,42 @@ + + + + CodeMirror 2: XML mode + + + + + + + + +

CodeMirror 2: XML mode

+
+ +

The XML mode supports two configuration parameters:

+
+
htmlMode (boolean)
+
This switches the mode to parse HTML instead of XML. This + means attributes do not have to be quoted, and some elements + (such as br) do not require a closing tag.
+
alignCDATA (boolean)
+
Setting this to true will force the opening tag of CDATA + blocks to not be indented.
+
+ +

MIME types defined: application/xml, text/html.

+ + diff --git a/htdocs/codemirror2/mode/xml/xml.css b/htdocs/codemirror2/mode/xml/xml.css new file mode 100644 index 000000000..86845faa6 --- /dev/null +++ b/htdocs/codemirror2/mode/xml/xml.css @@ -0,0 +1,7 @@ +span.xml-tag {color: #a0b;} +span.xml-attribute {color: #281;} +span.xml-attname {color: #00f;} +span.xml-comment {color: #a70;} +span.xml-cdata {color: #48a;} +span.xml-processing {color: #999;} +span.xml-entity {color: #a22;} diff --git a/htdocs/codemirror2/mode/xml/xml.js b/htdocs/codemirror2/mode/xml/xml.js new file mode 100644 index 000000000..1d92c4e7b --- /dev/null +++ b/htdocs/codemirror2/mode/xml/xml.js @@ -0,0 +1,206 @@ +CodeMirror.defineMode("xml", function(config, parserConfig) { + var indentUnit = config.indentUnit; + var Kludges = parserConfig.htmlMode ? { + autoSelfClosers: {"br": true, "img": true, "hr": true, "link": true, "input": true, + "meta": true, "col": true, "frame": true, "base": true, "area": true}, + doNotIndent: {"pre": true, "!cdata": true}, + allowUnquoted: true + } : {autoSelfClosers: {}, doNotIndent: {"!cdata": true}, allowUnquoted: false}; + var alignCDATA = parserConfig.alignCDATA; + + // Return variables for tokenizers + var tagName, type; + + function inText(stream, state) { + function chain(parser) { + state.tokenize = parser; + return parser(stream, state); + } + + var ch = stream.next(); + if (ch == "<") { + if (stream.eat("!")) { + if (stream.eat("[")) { + if (stream.match("CDATA[")) return chain(inBlock("xml-cdata", "]]>")); + else return null; + } + else if (stream.match("--")) return chain(inBlock("xml-comment", "-->")); + else if (stream.match("DOCTYPE")) { + stream.eatWhile(/[\w\._\-]/); + return chain(inBlock("xml-doctype", ">")); + } + else return null; + } + else if (stream.eat("?")) { + stream.eatWhile(/[\w\._\-]/); + state.tokenize = inBlock("xml-processing", "?>"); + return "xml-processing"; + } + else { + type = stream.eat("/") ? "closeTag" : "openTag"; + stream.eatSpace(); + tagName = ""; + var c; + while ((c = stream.eat(/[^\s\u00a0=<>\"\'\/?]/))) tagName += c; + state.tokenize = inTag; + return "xml-tag"; + } + } + else if (ch == "&") { + stream.eatWhile(/[^;]/); + stream.eat(";"); + return "xml-entity"; + } + else { + stream.eatWhile(/[^&<]/); + return null; + } + } + + function inTag(stream, state) { + var ch = stream.next(); + if (ch == ">" || (ch == "/" && stream.eat(">"))) { + state.tokenize = inText; + type = ch == ">" ? "endTag" : "selfcloseTag"; + return "xml-tag"; + } + else if (ch == "=") { + type = "equals"; + return null; + } + else if (/[\'\"]/.test(ch)) { + state.tokenize = inAttribute(ch); + return state.tokenize(stream, state); + } + else { + stream.eatWhile(/[^\s\u00a0=<>\"\'\/?]/); + return "xml-word"; + } + } + + function inAttribute(quote) { + return function(stream, state) { + while (!stream.eol()) { + if (stream.next() == quote) { + state.tokenize = inTag; + break; + } + } + return "xml-attribute"; + }; + } + + function inBlock(style, terminator) { + return function(stream, state) { + while (!stream.eol()) { + if (stream.match(terminator)) { + state.tokenize = inText; + break; + } + stream.next(); + } + return style; + }; + } + + var curState, setStyle; + function pass() { + for (var i = arguments.length - 1; i >= 0; i--) curState.cc.push(arguments[i]); + } + function cont() { + pass.apply(null, arguments); + return true; + } + + function pushContext(tagName, startOfLine) { + var noIndent = Kludges.doNotIndent.hasOwnProperty(tagName) || (curState.context && curState.context.noIndent); + curState.context = { + prev: curState.context, + tagName: tagName, + indent: curState.indented, + startOfLine: startOfLine, + noIndent: noIndent + }; + } + function popContext() { + if (curState.context) curState.context = curState.context.prev; + } + + function element(type) { + if (type == "openTag") {curState.tagName = tagName; return cont(attributes, endtag(curState.startOfLine));} + else if (type == "closeTag") {popContext(); return cont(endclosetag);} + else if (type == "xml-cdata") { + if (!curState.context || curState.context.name != "!cdata") pushContext("!cdata"); + if (curState.tokenize == inText) popContext(); + return cont(); + } + else return cont(); + } + function endtag(startOfLine) { + return function(type) { + if (type == "selfcloseTag" || + (type == "endTag" && Kludges.autoSelfClosers.hasOwnProperty(curState.tagName.toLowerCase()))) + return cont(); + if (type == "endTag") {pushContext(curState.tagName, startOfLine); return cont();} + return cont(); + }; + } + function endclosetag(type) { + if (type == "endTag") return cont(); + return pass(); + } + + function attributes(type) { + if (type == "xml-word") {setStyle = "xml-attname"; return cont(attributes);} + if (type == "equals") return cont(attvalue, attributes); + return pass(); + } + function attvalue(type) { + if (type == "xml-word" && Kludges.allowUnquoted) {setStyle = "xml-attribute"; return cont();} + if (type == "xml-attribute") return cont(); + return pass(); + } + + return { + startState: function() { + return {tokenize: inText, cc: [], indented: 0, startOfLine: true, tagName: null, context: null}; + }, + + token: function(stream, state) { + if (stream.sol()) { + state.startOfLine = true; + state.indented = stream.indentation(); + } + if (stream.eatSpace()) return null; + + setStyle = type = tagName = null; + var style = state.tokenize(stream, state); + if ((style || type) && style != "xml-comment") { + curState = state; + while (true) { + var comb = state.cc.pop() || element; + if (comb(type || style)) break; + } + } + state.startOfLine = false; + return setStyle || style; + }, + + indent: function(state, textAfter) { + var context = state.context; + if (context && context.noIndent) return 0; + if (alignCDATA && / + + + CodeMirror + + + + + + +

{ } CodeMirror

+ +
+/* Old release history */
+
+
+ +

02-10-2010: Version 0.9:

+
    +
  • Add support for searching backwards.
  • +
  • There are now parsers for Scheme, XQuery, and OmetaJS.
  • +
  • Makes height: "dynamic" more robust.
  • +
  • Fixes bug where paste did not work on OS X.
  • +
  • Add a enterMode and electricChars options to make indentation even more customizable.
  • +
  • Add firstLineNumber option.
  • +
  • Fix bad handling of @media rules by the CSS parser.
  • +
  • Take a new, more robust approach to working around the invisible-last-line bug in WebKit.
  • +
+ +

22-07-2010: Version 0.8:

+
    +
  • Add a cursorCoords method to find the screen + coordinates of the cursor.
  • +
  • A number of fixes and support for more syntax in the PHP parser.
  • +
  • Fix indentation problem with JSON-mode JS parser in Webkit.
  • +
  • Add a minification UI.
  • +
  • Support a height: dynamic mode, where the editor's + height will adjust to the size of its content.
  • +
  • Better support for IME input mode.
  • +
  • Fix JavaScript parser getting confused when seeing a no-argument + function call.
  • +
  • Have CSS parser see the difference between selectors and other + identifiers.
  • +
  • Fix scrolling bug when pasting in a horizontally-scrolled + editor.
  • +
  • Support toTextArea method in instances created with + fromTextArea.
  • +
  • Work around new Opera cursor bug that causes the cursor to jump + when pressing backspace at the end of a line.
  • +
+ +

27-04-2010: Version + 0.67:

+

More consistent page-up/page-down behaviour + across browsers. Fix some issues with hidden editors looping forever + when line-numbers were enabled. Make PHP parser parse + "\\" correctly. Have jumpToLine work on + line handles, and add cursorLine function to fetch the + line handle where the cursor currently is. Add new + setStylesheet function to switch style-sheets in a + running editor.

+ +

01-03-2010: Version + 0.66:

+

Adds removeLine method to API. + Introduces the PLSQL parser. + Marks XML errors by adding (rather than replacing) a CSS class, so + that they can be disabled by modifying their style. Fixes several + selection bugs, and a number of small glitches.

+ +

12-11-2009: Version + 0.65:

+

Add support for having both line-wrapping and + line-numbers turned on, make paren-highlighting style customisable + (markParen and unmarkParen config + options), work around a selection bug that Opera + reintroduced in version 10.

+ +

23-10-2009: Version + 0.64:

+

Solves some issues introduced by the + paste-handling changes from the previous release. Adds + setSpellcheck, setTextWrapping, + setIndentUnit, setUndoDepth, + setTabMode, and setLineNumbers to + customise a running editor. Introduces an SQL parser. Fixes a few small + problems in the Python + parser. And, as usual, add workarounds for various newly discovered + browser incompatibilities.

+ +

31-08-2009: Version +0.63:

+

Overhaul of paste-handling (less fragile), fixes for several +serious IE8 issues (cursor jumping, end-of-document bugs) and a number +of small problems.

+ +

30-05-2009: Version +0.62:

+

Introduces Python +and Lua parsers. Add +setParser (on-the-fly mode changing) and +clearHistory methods. Make parsing passes time-based +instead of lines-based (see the passTime option).

+ + + + diff --git a/htdocs/codemirror2/test/index.html b/htdocs/codemirror2/test/index.html new file mode 100644 index 000000000..a0a05c553 --- /dev/null +++ b/htdocs/codemirror2/test/index.html @@ -0,0 +1,30 @@ + + + + CodeMirror 2: Test Suite + + + + + + + + + +

CodeMirror 2: Test Suite

+ +

A limited set of programmatic sanity tests for CodeMirror.

+ +

+
+    
+
+    
+  
+
diff --git a/htdocs/codemirror2/test/test.js b/htdocs/codemirror2/test/test.js
new file mode 100644
index 000000000..af18b5b4a
--- /dev/null
+++ b/htdocs/codemirror2/test/test.js
@@ -0,0 +1,248 @@
+var tests = [];
+
+test("fromTextArea", function() {
+  var te = document.getElementById("code");
+  te.value = "CONTENT";
+  var cm = CodeMirror.fromTextArea(te);
+  is(!te.offsetHeight);
+  eq(cm.getValue(), "CONTENT");
+  cm.setValue("foo\nbar");
+  eq(cm.getValue(), "foo\nbar");
+  cm.save();
+  is(/^foo\r?\nbar$/.test(te.value));
+  cm.setValue("xxx");
+  cm.toTextArea();
+  is(te.offsetHeight);
+  eq(te.value, "xxx");
+});
+
+testCM("getRange", function(cm) {
+  eq(cm.getLine(0), "1234");
+  eq(cm.getLine(1), "5678");
+  eq(cm.getLine(2), null);
+  eq(cm.getLine(-1), null);
+  eq(cm.getRange({line: 0, ch: 0}, {line: 0, ch: 3}), "123");
+  eq(cm.getRange({line: 0, ch: -1}, {line: 0, ch: 200}), "1234");
+  eq(cm.getRange({line: 0, ch: 2}, {line: 1, ch: 2}), "34\n56");
+  eq(cm.getRange({line: 1, ch: 2}, {line: 100, ch: 0}), "78");
+}, {value: "1234\n5678"});
+
+testCM("replaceRange", function(cm) {
+  eq(cm.getValue(), "");
+  cm.replaceRange("foo\n", {line: 0, ch: 0});
+  eq(cm.getValue(), "foo\n");
+  cm.replaceRange("a\nb", {line: 0, ch: 1});
+  eq(cm.getValue(), "fa\nboo\n");
+  eq(cm.lineCount(), 3);
+  cm.replaceRange("xyzzy", {line: 0, ch: 0}, {line: 1, ch: 1});
+  eq(cm.getValue(), "xyzzyoo\n");
+  cm.replaceRange("abc", {line: 0, ch: 0}, {line: 10, ch: 0});
+  eq(cm.getValue(), "abc");
+  eq(cm.lineCount(), 1);
+});
+
+testCM("selection", function(cm) {
+  cm.setSelection({line: 0, ch: 4}, {line: 2, ch: 2});
+  is(cm.somethingSelected());
+  eq(cm.getSelection(), "11\n222222\n33");
+  eqPos(cm.getCursor(false), {line: 2, ch: 2});
+  eqPos(cm.getCursor(true), {line: 0, ch: 4});
+  cm.setSelection({line: 1, ch: 0});
+  is(!cm.somethingSelected());
+  eq(cm.getSelection(), "");
+  eqPos(cm.getCursor(true), {line: 1, ch: 0});
+  cm.replaceSelection("abc");
+  eq(cm.getSelection(), "abc");
+  eq(cm.getValue(), "111111\nabc222222\n333333");
+  cm.replaceSelection("def", "end");
+  eq(cm.getSelection(), "");
+  eqPos(cm.getCursor(true), {line: 1, ch: 3});
+  cm.setCursor({line: 2, ch: 1});
+  eqPos(cm.getCursor(true), {line: 2, ch: 1});
+  cm.setCursor(1, 2);
+  eqPos(cm.getCursor(true), {line: 1, ch: 2});
+}, {value: "111111\n222222\n333333"});
+
+testCM("lines", function(cm) {
+  eq(cm.getLine(0), "111111");
+  eq(cm.getLine(1), "222222");
+  eq(cm.getLine(-1), null);
+  cm.removeLine(1);
+  cm.setLine(1, "abc");
+  eq(cm.getValue(), "111111\nabc");
+}, {value: "111111\n222222\n333333"});
+
+testCM("indent", function(cm) {
+  cm.indentLine(1);
+  eq(cm.getLine(1), "   blah();");
+  cm.setOption("indentUnit", 8);
+  cm.indentLine(1);
+  eq(cm.getLine(1), "\tblah();");
+}, {value: "if (x) {\nblah();\n}", indentUnit: 3, indentWithTabs: true});
+
+test("defaults", function() {
+  var olddefaults = CodeMirror.defaults, defs = CodeMirror.defaults = {};
+  for (var opt in olddefaults) defs[opt] = olddefaults[opt];
+  defs.indentUnit = 5;
+  defs.value = "uu";
+  defs.enterMode = "keep";
+  defs.tabindex = 55;
+  var place = document.getElementById("testground"), cm = CodeMirror(place);
+  try {
+    eq(cm.getOption("indentUnit"), 5);
+    cm.setOption("indentUnit", 10);
+    eq(defs.indentUnit, 5);
+    eq(cm.getValue(), "uu");
+    eq(cm.getOption("enterMode"), "keep");
+    eq(cm.getInputField().tabindex, 55);
+  }
+  finally {
+    CodeMirror.defaults = olddefaults;
+    place.removeChild(cm.getWrapperElement());
+  }
+});
+
+testCM("lineInfo", function(cm) {
+  eq(cm.lineInfo(-1), null);
+  var lh = cm.setMarker(1, "FOO", "bar");
+  var info = cm.lineInfo(1);
+  eq(info.text, "222222");
+  eq(info.markerText, "FOO");
+  eq(info.markerClass, "bar");
+  eq(info.line, 1);
+  eq(cm.lineInfo(2).markerText, null);
+  cm.clearMarker(lh);
+  eq(cm.lineInfo(1).markerText, null);
+}, {value: "111111\n222222\n333333"});
+
+testCM("coords", function(cm) {
+  cm.getWrapperElement().style.height = "100px";
+  var content = [];
+  for (var i = 0; i < 200; ++i) content.push("------------------------------" + i);
+  cm.setValue(content.join("\n"));
+  var top = cm.charCoords({line: 0, ch: 0});
+  var bot = cm.charCoords({line: 200, ch: 30});
+  is(top.x < bot.x);
+  is(top.y < bot.y);
+  is(top.y < top.yBot);
+  cm.getWrapperElement().scrollTop = 100;
+  cm.refresh();
+  var top2 = cm.charCoords({line: 0, ch: 0});
+  is(top.y > top2.y);
+  eq(top.x, top2.x);
+});
+
+testCM("coordsChar", function(cm) {
+  var content = [];
+  for (var i = 0; i < 70; ++i) content.push("xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
+  cm.setValue(content.join("\n"));
+  for (var x = 0; x < 35; x += 2) {
+    for (var y = 0; y < 70; y += 5) {
+      cm.setCursor(y, x);
+      var pos = cm.coordsChar(cm.charCoords({line: y, ch: x}));
+      eq(pos.line, y);
+      eq(pos.ch, x);
+    }
+  }
+});
+
+testCM("undo", function(cm) {
+  cm.setLine(0, "def");
+  eq(cm.historySize().undo, 1);
+  cm.undo();
+  eq(cm.getValue(), "abc");
+  eq(cm.historySize().undo, 0);
+  eq(cm.historySize().redo, 1);
+  cm.redo();
+  eq(cm.getValue(), "def");
+  eq(cm.historySize().undo, 1);
+  eq(cm.historySize().redo, 0);
+  cm.setValue("1\n\n\n2");
+  eq(cm.historySize().undo, 0);
+  for (var i = 0; i < 20; ++i) {
+    cm.replaceRange("a", {line: 0, ch: 0});
+    cm.replaceRange("b", {line: 3, ch: 0});
+  }
+  eq(cm.historySize().undo, 40);
+  for (var i = 0; i < 38; ++i) cm.undo();
+  eq(cm.historySize().undo, 2);
+  eq(cm.historySize().redo, 38);
+  eq(cm.getValue(), "a1\n\n\nb2");
+  cm.setOption("undoDepth", 10);
+  for (var i = 0; i < 20; ++i) {
+    cm.replaceRange("a", {line: 0, ch: 0});
+    cm.replaceRange("b", {line: 3, ch: 0});
+  }
+  eq(cm.historySize().undo, 10);
+}, {value: "abc"});
+
+testCM("undoMultiLine", function(cm) {
+  cm.replaceRange("x", {line:0, ch: 0});
+  cm.replaceRange("y", {line:1, ch: 0});
+  cm.undo();
+  eq(cm.getValue(), "abc\ndef\nghi");
+  cm.replaceRange("y", {line:1, ch: 0});
+  cm.replaceRange("x", {line:0, ch: 0});
+  cm.undo();
+  eq(cm.getValue(), "abc\ndef\nghi");
+  cm.replaceRange("y", {line:2, ch: 0});
+  cm.replaceRange("x", {line:1, ch: 0});
+  cm.replaceRange("z", {line:2, ch: 0});
+  cm.undo();
+  eq(cm.getValue(), "abc\ndef\nghi");
+}, {value: "abc\ndef\nghi"});
+
+// Scaffolding
+
+function htmlEscape(str) {
+  return str.replace(/[<&]/g, function(str) {return str == "&" ? "&" : "<";});
+}
+function forEach(arr, f) {
+  for (var i = 0, e = arr.length; i < e; ++i) f(arr[i]);
+}
+
+function Failure(why) {this.message = why;}
+
+function test(name, run) {tests.push({name: name, func: run});}
+function testCM(name, run, opts) {
+  test(name, function() {
+    var place = document.getElementById("testground"), cm = CodeMirror(place, opts);
+    try {run(cm);}
+    finally {place.removeChild(cm.getWrapperElement());}
+  });
+}
+
+function runTests() {
+  var failures = [], run = 0;
+  for (var i = 0; i < tests.length; ++i) {
+    var test = tests[i];
+    try {test.func();}
+    catch(e) {
+      if (e instanceof Failure)
+        failures.push({type: "failure", test: test.name, text: e.message});
+      else
+        failures.push({type: "error", test: test.name, text: e.toString()});
+    }
+    run++;
+  }
+  var html = [run + " tests run."];
+  if (failures.length)
+    forEach(failures, function(fail) {
+      html.push(fail.test + ': ' + htmlEscape(fail.text) + "");
+    });
+  else html.push('All passed.');
+  document.getElementById("output").innerHTML = html.join("\n");
+}
+
+function eq(a, b, msg) {
+  if (a != b) throw new Failure(a + " != " + b + (msg ? " (" + msg + ")" : ""));
+}
+function eqPos(a, b, msg) {
+  eq(a.line, b.line, msg);
+  eq(a.ch, b.ch, msg);
+}
+function is(a, msg) {
+  if (!a) throw new Failure("assertion failed" + (msg ? " (" + msg + ")" : ""));
+}
+
+window.onload = runTests;
diff --git a/htdocs/css/problemsetlist.css b/htdocs/css/problemsetlist.css
new file mode 100644
index 000000000..9e08933ba
--- /dev/null
+++ b/htdocs/css/problemsetlist.css
@@ -0,0 +1,49 @@
+.Body{
+    padding: 20px;
+}
+
+#calendar-table {border: 1px solid black; border-collapse: collapse; background: lightgray;}
+#calendar-table td {border: 1px solid black; width: 13%;  vertical-align: top;}
+
+.month-view {height: 100px;}
+.week-view {height: 200px;}
+
+.this-month {background-color: lightyellow}
+.today {background-color: orange}
+.highlight-day { border: 2px solid black; background-color: green;}
+
+.assign-open {background-color: rgb(180,180,255);}
+
+.assign-reduced-credit {background-color: rgb(255,128,0);}
+
+.empty {background-color: none;}
+
+.assign { border-left: -2px; border-right: -2px; height: 15px;  width: 103%; margin-top: 2px; margin-bottom: 2px;
+float: left; display: table-cell; vertical-align: bottom;  z-index: 2; font-size: 13px;}
+
+.assign-set-name {cursor: pointer;}
+
+.calendar-button-row {margin: 20px;}
+
+.list {list-style: none;}
+
+.lib-problem-viewer { overflow: scroll;}
+
+.prob-list {overflow: scroll;}
+
+.num-problems {margin-left: 10px;}
+
+.view-pane {display: none;}
+.view-header {display: none; font-size:125%; font-weight: bold;}
+
+.active {display: block;}
+
+.no-bullets {list-style-type: none;}
+
+label.checklist {display: inline; margin-left: 8px;}
+
+.hw-assigned {color: blue;}
+
+
+
+
diff --git a/htdocs/html-templates/classlist-manager.html b/htdocs/html-templates/classlist-manager.html
new file mode 100644
index 000000000..49f931276
--- /dev/null
+++ b/htdocs/html-templates/classlist-manager.html
@@ -0,0 +1,152 @@
+
+ +
+ + + + + + + + + + + + + diff --git a/htdocs/html-templates/classlist3.html b/htdocs/html-templates/classlist3.html deleted file mode 100644 index fc5189e1e..000000000 --- a/htdocs/html-templates/classlist3.html +++ /dev/null @@ -1,132 +0,0 @@ -
- - - - - - - - - - - - - diff --git a/htdocs/html-templates/frontpage.html b/htdocs/html-templates/frontpage.html new file mode 100644 index 000000000..503dff77a --- /dev/null +++ b/htdocs/html-templates/frontpage.html @@ -0,0 +1,35 @@ +
+
Loading...
+
+
+ + + + + + + + diff --git a/htdocs/html-templates/homework-manager.html b/htdocs/html-templates/homework-manager.html new file mode 100644 index 000000000..829062cc5 --- /dev/null +++ b/htdocs/html-templates/homework-manager.html @@ -0,0 +1,279 @@ +
+
+
+ + + +
+ +
+
Calendar
+
Problem Set Details
+
List of all Problem Sets
+
Import and Export Problem Sets
+
Settings
+
View Problem Library by Subject
+
View Problem Library by Directory
+
Search the Problem Library
+
View the Local Libraries
+ +
+ +
+
+
+
+

The Importing and Exporting of homework sets is not implemented yet.

+
+
+
+

The Searching of the libraries is not implemented yet.

+

The viewing of the local libraries is not implemented yet.

+ +
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/htdocs/js/apps/ClasslistManager/AddStudentFileView.js b/htdocs/js/apps/ClasslistManager/AddStudentFileView.js new file mode 100644 index 000000000..9b50815d4 --- /dev/null +++ b/htdocs/js/apps/ClasslistManager/AddStudentFileView.js @@ -0,0 +1,225 @@ + // This is the View for the dialog for addings students manually + +define(['Backbone', + 'underscore', + 'Closeable', + '../../lib/webwork/models/User', + '../../lib/vendor/FileSaver', + '../../lib/vendor/BlobBuilder', + 'config', + '../../lib/webwork/util'], function(Backbone, _,Closeable,User,saveAs,BlobBuilder,config,util){ + var AddStudentFileView = Backbone.View.extend({ + tagName: "div", + id: "addStudFileDialog", + + initialize: function(){ + _.bindAll(this, 'render','importStudents','addStudent','appendRow'); // every function that uses 'this' as the current object should be in here + this.collection = new TempUserList(); + this.model = new User(); + Backbone.Validation.bind(this); + this.parent = this.options.parent; + this.render(); + + //for(var i = 0; i<1; i++) {this.collection.add(new webwork.User())} // add a single blank line. + + this.$el.dialog({autoOpen: false, modal: true, title: "Add Students from a File", + width: (0.95*window.innerWidth), height: (0.95*window.innerHeight) }); + }, + events: { + "click button#importStudFromFileButton": "importStudents", + "change input#files": "readFile", + "change input#useLST" : "setHeadersForLST", + "change input#useFirst" : "useFirstRow" + }, + openDialog: function () { this.$el.dialog("open");}, + closeDialog: function () {this.$el.dialog("close");}, + render: function(){ + var self = this; + this.errorPane = new Closeable({id: "error-bar"}); + this.errorPane.$el.addClass("alert-error"); + this.$el.html(this.errorPane.el); + $("button.close",this.errorPane.el).click(function () {self.errorPane.close();}); // for some reason the event inside this.error is not working this is a hack. + + this.$el.append($("#add_student_file_dialog_content").html()); + + return this; + }, + readFile: function(evt){ + var self = this; + $("li#step1").css("display","none"); // Hide the first step of the Wizard + $("li#step2").css("display","block"); // And show the next step. + $("button#importStudFromFileButton").css("display","block"); + + this.file = $("#files").get(0).files[0]; + $('#list').html('' + escape(this.file.name) + ''); + + + + // Need to test if the browser can handle this new object. If not, find alternative route. + + var sizeInBytes = 1024 * 1024, + prefix = 'filetest'; + + /* FSFactory(sizeInBytes, 'test_fs', function(err, fs) { + fs.readFile(this.file, function(err, data){ + console.log(data); + }); + }); */ + + var reader = new FileReader(); + + reader.onload = function(event) { + var content = event.target.result; + headers = _(config.userProps).map(function(prop) {return prop.longName;}); + headers.splice(0,0,""); + // Parse the CSV file + + var str = util.CSVToHTMLTable(content,headers); + + // build the table and set it up to scroll nicely. + $("#studentTable").html(str); + $("#selectAllASW").click(function(){ $(".selRow").attr("checked",$("#selectAllASW").is(":checked")); }); + $("div.inner").width(25+($("#sTable thead td").length)*175); + $("#inner-table td").width($("#sTable thead td:nth-child(2)").width()+4) + $("#inner-table td:nth-child(1)").width($("#sTable thead td:nth-child(1)").width()) + + // test if it is a classlist file and then set the headers appropriately + + var re=new RegExp("\.lst$","i"); + if (re.test(self.file.name)){self.setHeadersForLST();} + + $("select.colHeader").change(function(evt) {self.updateHeaders(evt.target);}) + } + + reader.readAsText(this.file); + + + }, + importStudents: function () { // PLS: Still need to check if student import is sucessful, like making sure that user_id is valid (not repeating, ...) + // First check to make sure that the headers are not repeated. + var self = this; + var headers = []; + _($("select[class='colHeader']")).each(function(obj,j){if ($(obj).val() != "") headers.push({header: $(obj).val(), position: j});}); + + //console.log(headers); + var heads = _(headers).map(function (obj) {return obj.header;}); + var sortedHeads = _(heads).sortBy(function (str) {return str;}); + + // Determine if the user has selected a unique set of headers. + + var validHeaders=true; + for (var i=0;i0){ // skip the header row + var value = $(cell).html().trim(), + errorMessage = self.model.preValidate(changedProperty,value); + if ((errorMessage !== "") && (errorMessage !== false)) { + self.errorPane.appendHTML("Error for the " + changedHeader + " with value " + value + ": " + errorMessage + "
"); + $(cell).css("background-color","rgba(255,0,0,0.5)"); + + } + } + + }); + + }, + setHeadersForLST: function(){ + var self = this; + self.errorPane.clear(); + + _(config.userProps).each(function (prop,i) { + var col = $("select#col"+i); + col.val(prop.longName); + self.updateHeaders(col); }); + }, + appendRow: function(user){ + var tableRow = new UserRowView({model: user}); + $("table#man_student_table tbody",this.el).append(tableRow.el); + }, + addStudent: function (){ this.collection.add(new User);} + }); + + // This is a Backbone collection of webwork.User(s). This is different than the webwork.userList class because we don't need + // the added expense of additions to the server. + + var TempUserList = Backbone.Collection.extend({model:User}); + + + return AddStudentFileView; + +}); \ No newline at end of file diff --git a/htdocs/js/apps/ClasslistManager/AddStudentManView.js b/htdocs/js/apps/ClasslistManager/AddStudentManView.js new file mode 100644 index 000000000..f30923793 --- /dev/null +++ b/htdocs/js/apps/ClasslistManager/AddStudentManView.js @@ -0,0 +1,86 @@ + // This is the View for the dialog for addings students manually + +define(['Backbone', + 'underscore', + 'Closeable'], function(Backbone, _,Closeable){ + var AddStudentManView = Backbone.View.extend({ + tagName: "div", + id: "addStudManDialog", + + initialize: function(){ + var self=this; + _.bindAll(this, 'render','importStudents','addStudent','appendRow','openDialog','closeDialog'); // every function that uses 'this' as the current object should be in here + this.collection = new TempUserList(); + + + this.collection.bind('add', this.appendRow); + this.parent = this.options.parent; + this.render(); + + this.collection.add(new User); // add a single blank line. + + + this.$el.dialog({autoOpen: false, modal: true, title: "Add Students by Hand", + width: (0.95*window.innerWidth), height: (0.95*window.innerHeight) }); + + this.collection.on('error',function(model, error) { + self.errorPane.appendHTML(error.message + "
"); + }); + + Backbone.Validation.bind(this); + }, + events: { + "click button#import_stud_button": "importStudents", + "click button#add_more_button": "addStudent" + }, + openDialog: function () { this.$el.dialog("open");}, + closeDialog: function () {this.$el.dialog("close");}, + template: _.template($("#add_student_man_dialog_content").html()), + render: function(){ + var self = this; + var tableHTML = "" + tableHTML += (_(config.userProps).map(function (prop) {return "";})).join("") + "
Delete" + prop.longName + "
"; + + this.$el.append(this.template({content: tableHTML})); + _(this.collection).each(function(user){ self.appendRow(user);}, this); + + + this.errorPane = new Closeable({el: this.$("#error-pane-add-man"), classes : ["alert-error"]}); + + + + }, + importStudents: function(){ // validate each student data then if successful upload to the server. + var self = this, + usersValid = new Array(); + + this.errorPane.setHTML(""); + + _(this.collection.models).each(function(user){ + _(user.attributes).each(function(value,key) { + + var errorMessage = user.preValidate(key, value); + if ((errorMessage!=="") && (errorMessage !== false)) { + self.collection.trigger("error",user, {type: key, message: errorMessage}); + } + }); + + usersValid.push(user.isValid(true)===true); + }); + + console.log(usersValid); + + if (_.all(usersValid, _.identity)) { this.closeDialog();} + }, + appendRow: function(user){ + var tableRow = new UserRowView({model: user}); + $("table#man_student_table tbody",this.el).append(tableRow.el); + }, + addStudent: function (){ this.collection.add(new User());} + }); + + + return AddStudentManView; + +}); + \ No newline at end of file diff --git a/htdocs/js/apps/ClasslistManager/classlistManager.js b/htdocs/js/apps/ClasslistManager/classlistManager.js new file mode 100644 index 000000000..893622e4c --- /dev/null +++ b/htdocs/js/apps/ClasslistManager/classlistManager.js @@ -0,0 +1,459 @@ +/* userlist.js: + This is the base javascript code for the UserList3.pm (Classlist Editor3). This sets up the View and the classlist object. + +*/ + +require.config({ + paths: { + "Backbone": "/webwork2_files/js/lib/webwork/components/backbone/Backbone", + "backbone-validation": "/webwork2_files/js/lib/vendor/backbone-validation", + "jquery-ui": "/webwork2_files/js/lib/vendor/jquery-drag-drop/js/jquery-ui-1.9.2.custom", + "underscore": "/webwork2_files/js/lib/webwork/components/underscore/underscore", + "jquery": "/webwork2_files/js/lib/webwork/components/jquery/jquery-1.8.3", + "bootstrap": "/webwork2_files/js/lib/vendor/bootstrap/js/bootstrap", + "util": "/webwork2_files/js/lib/webwork/util", + "XDate": "/webwork2_files/js/lib/vendor/xdate", + "WebPage": "/webwork2_files/js/lib/webwork/views/WebPage", + "config": "/webwork2_files/js/apps/config", + "Closeable": "/webwork2_files/js/lib/webwork/views/Closeable", + "jquery-ui-custom": '/webwork2_files/js/lib/vendor/jquery-ui-1.9.2.custom/js/jquery-ui-1.9.2.custom.min' + }, + urlArgs: "bust=" + (new Date()).getTime(), + waitSeconds: 15, + shim: { + 'jquery-ui': ['jquery'], + 'jquery-ui-custom': ['jquery'], + 'underscore': { exports: '_' }, + 'Backbone': { deps: ['underscore', 'jquery'], exports: 'Backbone'}, + 'bootstrap':['jquery'], + 'backbone-validation': ['Backbone'], + 'XDate':{ exports: 'XDate'}, + 'config': ['XDate'] + } +}); + +require(['Backbone', + 'underscore', + '../../lib/webwork/models/User', + '../../lib/webwork/models/UserList', + '../../lib/vendor/editablegrid-2.0.1/editablegrid', + 'WebPage', + '../../lib/webwork/views/EmailStudentsView', + '../../lib/webwork/views/ChangePasswordView', + './AddStudentFileView', + './AddStudentManView', + '../../lib/webwork/util', + 'config', /*no exports*/, + 'jquery-ui', + 'backbone-validation', + 'bootstrap', + 'jquery-ui-custom'], +function(Backbone, _, User, UserList, EditableGrid, WebPage, EmailStudentsView, + ChangePasswordView, AddStudentFileView, AddStudentManView, util, config){ + + + var UserListView = WebPage.extend({ + tagName: "div", + initialize: function(){ + this.constructor.__super__.initialize.apply(this, {el: this.el}); + _.bindAll(this, 'render','addOne','addAll','deleteUsers','changePassword'); // include all functions that need the this object + var self = this; + this.collection = new UserList(); // This is a Backbone.Collection of users + + + + this.grid = new EditableGrid("UserListTable", { enableSort: true}); +//what's here? + this.grid.load({ metadata: config.userTableHeaders, data: [{id:0, values:{}}]}); + + this.render(); + + this.grid.renderGrid('users_table', 'usersTableClass', 'userTable'); + this.collection.fetch(); + this.grid.refreshGrid(); + + + + this.grid.modelChanged = function(rowIndex, columnIndex, oldValue, newValue) { + + if (columnIndex == 1 ) // the takeAction column has been selected. + { + + switch (newValue){ + case "action1": // Change Password + self.changePassword([rowIndex]); + break; + case "action2": // deleteUser + self.deleteUsers([rowIndex]); + break; + case "action3": // Act as User + var username = self.grid.getValueAt(rowIndex,2); // + + // send a relative path, but is this the best way? + var url = "../../?user=" + config.requestObject.user + "&effectiveUser=" + username + "&key=" + + config.requestObject.session_key; + location.href = url; + break; + case "action4": // Student Progress + var username = self.grid.getValueAt(rowIndex,2); // + + // send a relative path, but is this the best way? + var url = "../progress/student/" + username + "/?user=" + config.requestObject.user + "&effectiveUser=" + username + "&key=" + + config.requestObject.session_key; + location.href = url; + break; + case "action5": // Email Student + + self.emailStudents([rowIndex]); + break; + + } + + // make sure that the cog icon is visible again. + $("#users_table tr[id*='UserListTable'] td:nth-child(2)").html(""); + + } + + // check to make sure that the updated information needs to be sent to the server + + else if (oldValue != newValue ){ + var cid = self.grid.getRowId(rowIndex); + var property = self.grid.getColumnName(columnIndex); + var editedModel = self.collection.getByCid(cid); + if(property == 'permission'){ + newValue = {name: "", value: newValue}; // Do we need to make sure to set the name correctly too? + } + console.log("just before editedModel.set"); + + // The following checks if the data validates. + + if(!(editedModel.set(property, newValue))){ + self.errorPane.setHTML("There is an error in setting the " + property + " for user " + editedModel.attributes.user_id + + " in the red box below.
" + self.error.errorText); + $("tr#UserListTable_" + cid + " td:nth-child("+(columnIndex+1) + ")").css("background-color","rgba(255,0,0,0.5)"); + + } else { + self.errorPane.close(); + $("tr#UserListTable_" + cid + " td:nth-child("+(columnIndex+1) + ")").css("background","none"); + + self.updatedUser = {user_id: editedModel.attributes.user_id, property: property, oldValue: oldValue, newValue: newValue}; + } + } + + }; + + // Resets the grid by deleting all rows and readding. + + this.collection.on('reset', function(){ + while(self.grid.getRowCount() > 1){ + self.grid.remove(1); + } + self.addAll(); + }, this); + + + this.collection.on('add',this.addOne,this); + + // This handles all of the messages posted at the top of the page when updates are made to the user list. + this.collection.on('success', function (type, user) { + + + // PLS: this seems clunky. Perhaps we can clean up this code. + switch(type) { + case "user_added": + if (this.messageType == "user_added"){ + this.announce.appendHTML(", " + user.attributes.user_id); + } else { + this.messageType = "user_added"; + this.announce.setHTML("Success in adding the following users: " + user.attributes.user_id); + } + break; + case "user_deleted": + if (this.messageType == "user_deleted"){ + this.announce.appendHTML(", " + user.attributes.user_id); + } else { + this.messageType = "user_deleted"; + this.announce.setHTML("Success in deleting the following users: " + user.attributes.user_id); + } + break; + case "property_changed": + if (this.updatedUser){ + this.announce.setHTML("The " + this.updatedUser.property + " of user " + this.updatedUser.user_id + " has changed.
" + + "Old Value: " + this.updatedUser.oldValue + "
" + + "New Value: " + this.updatedUser.newValue); + this.updatedUser = null; + } + break; + } + // make sure that the cog icon is visible again. + $("#users_table tr[id*='UserListTable'] td:nth-child(2)").html(""); + + },this); + + this.collection.on('fetchSuccess', function() {this.postLoadingTasks()},this); + + $("div#addStudFromFile").dialog({autoOpen: false, modal: true, title: "Add Student from a File", + width: (0.95*window.innerWidth), height: (0.95*window.innerHeight) }); + + + // Make sure the take Action menu item is reset + $("select#mainActionMenu").val("takeAction"); + $("button#help-link").click(function () {self.helpPane.open();}); + + + }, + events: { + 'change select.actionMenu' : 'takeBulkAction', + 'change select#import-export' : 'importExportOptions', + 'change input#selectAllCB' : 'toggleAllCheckBoxes', + 'keyup input#filter' : 'filterUsers', + 'click button#clear-filter-text': 'clearFilterText' + }, + filterUsers: function (evt) { + this.grid.filter($("#filter").val()); + $("#usersShownInfo").html(this.grid.getRowCount() + " of " + this.collection.length + " users shown."); + }, + clearFilterText: function () { + $("input#filter").val(""); + this.grid.filter(""); + }, + importExportOptions: function (evt) { + switch(evt.target.value){ + case "Add Students from a File": + var addStudFileDialog = new AddStudentFileView({parent: this}); + addStudFileDialog.openDialog(); + break; + case "Add Students Manually": + var addStudManDialog = new AddStudentManView({parent: this}); + addStudManDialog.openDialog(); + break; + case "Export Students to a File": + var bb = new BlobBuilder; + + // Write the headers out + bb.append((_(config.userProps).map(function (prop) { return "\"" + prop.longName + "\"";})).join(",") + "\n"); + + // Write out the user Props + this.collection.each(function(user){bb.append(user.toCSVString())}); + + // need a more appropriate filename + + saveAs(bb.getBlob("text/csv;charset=utf-8"), "hello world.csv"); + + + break; + } + + $(evt.target).val("Import or Export Students"); + }, + + takeBulkAction: function (evt) { + + var selectedRows = []; + + for(var i = 0; i < this.grid.getRowCount(); i++){ + if ($("#"+ $(this.grid.getRow(i)).attr("id") + " input:checkbox").attr("checked") === "checked"){ + selectedRows.push(i); + } + + } + + switch (evt.target.value){ + case "menuEmail": + this.emailStudents(selectedRows); + break; + case "menuChangePassword": + this.changePassword(selectedRows); + break; + case "menuDelete": + this.deleteUsers(selectedRows); + break; + } + // reset the action menu + $ (evt.target).val("takeAction"); + }, + toggleAllCheckBoxes: function () { + + $("input:checkbox[id!='selectAllCB']").attr("checked",$("#selectAllCB").is(":checked")); + + for(var i = 0; i< this.grid.data.length; i++) { + if ($("input:checkbox#selectAllCB").attr("checked") === "checked") { + this.grid.setValueAt(i,0,true,true); + } else { + this.grid.setValueAt(i,0,false,true); + } + } + }, + + // This function contains tasks after the users have been received from the database. + // Decorate the Table: + // set the action column to have a cog initially. Note: this is a hack to get an icon set in the Editable Table + // also set the color to green for those users who are logged in. + + + postLoadingTasks: function () { + var self = this; + for(var i = 0; i < this.grid.getRowCount(); i++) + { + if (this.grid.getRowValues(i).user_id==='') {this.grid.remove(i);} // this is a hack to remove the row with empty values. + } + + $("#users_table tr[id*='UserListTable'] td:nth-child(2)").html(""); + _(this.loggedInUsers).each(function(user){ + $("tr#UserListTable_" + user + " td:nth-child(3)").css("color","green").css("font-weight","bold"); + }); + + this.loggedInUsers = []; + // Display the number of users shown + $("#usersShownInfo").html(this.grid.getRowCount() + " of " + this.collection.length + " users shown."); + + // bind the collection to the Validation. See Backbone.Validation at https://github.com/thedersen/backbone.validation + + Backbone.Validation.bind(this,{ + valid: function(view, attr, selector) { + //console.log("running valid"); + }, + invalid: function(view, attr, error,selector) { + console.log("running invalid"); + self.error = {errorAttr: attr, errorText: error}; + } + }); + + + }, + render: function(){ + this.constructor.__super__.render.apply(this); // Call WebPage.render(); + var self = this; + + + this.$el.append(_.template($("#userListTable").html())); + + this.$el.append(this.passwordPane = new ChangePasswordView({model: new TempUserList()})); + this.$el.append(this.emailPane = new EmailStudentsView({model: new TempUserList()})); + return this; + }, + addOne: function(user){ + var userInfo = user.toJSON(); + userInfo.permission = ""+userInfo.permission.value; // return only the String version of the Permission + this.grid.append(user.cid, userInfo); + if (userInfo.login_status==1){ + this.loggedInUsers.push(user.cid); + } + }, + + addAll: function(){ + this.loggedInUsers=[]; // this will store the rows of the users who are currently logged in. Perhaps this should go elsewhere. + var self = this; + this.collection.each(function(user){self.addOne(user)}); + this.grid.refreshGrid(); + }, + deleteUsers: function(rows){ + rowsBackwards = _(rows).sortBy(function (num) { return -1*num;}); // the rows need to be sorted in decreasing order so the rows in the table are + // removed correctly. + var self = this; + var str = "Do you wish to delete the following students: " + _(rows).each(function (row) {str += self.grid.getDisplayValueAt(row,4) + " "+ self.grid.getDisplayValueAt(row,5) + " " }); + var del = confirm(str); + + if (del){ + _.each(rowsBackwards,function (row){ + console.log("Remove " + self.grid.getDisplayValueAt(row,2)); // The user_id property is in column 2 + var user = self.collection.where({user_id: self.grid.getDisplayValueAt(row,2)})[0]; + self.collection.remove(user); + + // Was the deletion successful? How to test? + self.grid.remove(row); + + }); + this.selectedRows=[]; + } + }, + changePassword: function(rows){ + var tempUsers = new TempUserList(); + var self = this; + _.each(rows, function (row){ + tempUsers.add(self.collection.where({user_id: self.grid.getDisplayValueAt(row,2)})[0]); + }) + this.passwordPane.model=tempUsers; + this.passwordPane.render(); + this.passwordPane.$el.dialog("open"); + }, + emailStudents: function(rows){ + var tempUsers = new TempUserList(); + var self = this; + _.each(rows, function (row){ + tempUsers.add(self.collection.where({user_id: self.grid.getDisplayValueAt(row,2)})[0]); + }) + this.emailPane.model=tempUsers; + this.emailPane.render(); + this.emailPane.$el.dialog("open"); + }, + messageType: "", // the type of message shown at the top of the page. + + selectedRows: [] // which rows in the table are selected. + + + }); + + // This is a Backbone collection of webwork.User(s). This is different than the webwork.userList class because we don't need + // the added expense of additions to the server. + + var TempUserList = Backbone.Collection.extend({model:User}); + + // This the view class of the Add Students Manually for a row of the table. + +var UserRowView = Backbone.View.extend({ + tagName: "tr", + className: "userRow", + initialize: function(){ + _.bindAll(this, 'render','unrender','updateProp','removeUser'); // every function that uses 'this' as the current object should be in here + this.model.bind('remove', this.unrender); + this.model.on('validated:invalid', function (model,error) { + console.log(error); + }); + + this.render(); + + }, + events: { + 'change input': 'updateProp', + 'click button.removeUser': 'removeUser' + }, + render: function(){ + var self = this; + self.$el.append(""); + _.each(config.userProps, function (prop){self.$el.append(""); }); + return this; // for chainable calls, like .render().el + }, + updateProp: function(evt){ + var changedAttr = evt.target.className.split("for-")[1]; + this.model.set(changedAttr,evt.target.value,{silent: true}); + var errorMessage = this.model.preValidate(changedAttr, evt.target.value); + if(errorMessage) + { + $(evt.target).css("background-color","rgba(255,0,0,0.5)"); + this.model.trigger("error",this.model, {type: changedAttr, message: errorMessage}); + } else + { + $(evt.target).css("background","none"); + } + + }, + unrender: function(){ + this.$el.remove(); + }, + removeUser: function() {this.model.destroy();} +}); + + +// var userListView = new UserListView(); + + var App = new UserListView({el: $("div#main")}); + + + + + +}); + + diff --git a/htdocs/js/apps/FrontPage/FrontPage.js b/htdocs/js/apps/FrontPage/FrontPage.js new file mode 100644 index 000000000..2fcce99bf --- /dev/null +++ b/htdocs/js/apps/FrontPage/FrontPage.js @@ -0,0 +1,92 @@ +//require config +require.config({ + paths: { + "Backbone": "/webwork2_files/js/lib/webwork/components/backbone/Backbone", + "backbone-validation": "/webwork2_files/js/lib/vendor/backbone-validation", + "jquery-ui": "/webwork2_files/js/lib/vendor/jquery-drag-drop/js/jquery-ui-1.9.2.custom", + "underscore": "/webwork2_files/js/lib/webwork/components/underscore/underscore", + "jquery": "/webwork2_files/js/lib/webwork/components/jquery/jquery-1.8.3", + "bootstrap": "/webwork2_files/js/lib/vendor/bootstrap/js/bootstrap", + "util": "/webwork2_files/js/lib/webwork/util", + "XDate": "/webwork2_files/js/lib/vendor/xdate", + "WebPage": "/webwork2_files/js/lib/webwork/views/WebPage", + "config": "/webwork2_files/js/apps/config", + "Closeable": "/webwork2_files/js/lib/webwork/views/Closeable" + }, + urlArgs: "bust=" + (new Date()).getTime(), + waitSeconds: 15, + shim: { + 'jquery-ui': ['jquery'], + 'underscore': { exports: '_' }, + 'Backbone': { deps: ['underscore', 'jquery'], exports: 'Backbone'}, + 'bootstrap':['jquery'], + 'backbone-validation': ['Backbone'], + 'XDate':{ exports: 'XDate'}, + 'util': ['XDate'] + } +}); + +require(['Backbone', + 'underscore', + '../../lib/webwork/models/User', + '../../lib/webwork/models/ProblemSetList', + '../../lib/webwork/models/Problem', + '../../lib/webwork/views/WebPage', + '../../lib/webwork/views/CalendarView', + '../../lib/webwork/views/ProblemSetListView', + 'util', + 'config', /*no exports*/, + 'bootstrap', + 'backbone-validation'], +function(Backbone, _, User, ProblemSetList, Problem, WebPage, CalendarView, ProblemSetListView, util, config){ + + var FrontPage = WebPage.extend({ + tagName: "div", + initialize: function(){ + this.constructor.__super__.initialize.apply(this, {el: this.el}); + //WebPage.prototype.initialize.apply(this, ); + _.bindAll(this, 'render','postHWLoaded'); // include all functions that need the this object + var self = this; + this.dispatcher = _.clone(Backbone.Events); + + this.problemSets = new ProblemSetList(); + + + this.problemSets.fetch(); + + this.dispatcher.on('problem-sets-loaded',this.postHWLoaded); + + this.render(); + + + + }, + render: function(){ + this.constructor.__super__.render.apply(this); // Call WebPage.render(); + + this.probSetListView = new ProblemSetListView({el: $("#left-column"), viewType: "student", + collection: this.problemSets, parent: this}); + + this.helpPane.open(); + + + }, + postHWLoaded: function () { + var self = this; + + self.calendarView = new CalendarView({el: $("#cal"), collection: self.problemSets, parent: this, view: "student"}); + + $(".problem-set").on("click",function(evt) { + console.log($(evt.target).data("setname")); // Not the best way to do this, but should work. + location.href="./" + $(evt.target).data("setname") + "?effectiveUser=" + $("#hidden_effectiveUser").val() + + "&key=" + $("#hidden_key").val() + "?user=" + $("#hidden_user").val(); + }) + // Set the popover on the set name + // $("span.pop").popover({title: "Homework Set Details", placement: "top", offset: 10}); + + //self.setListView = new SetListView({collection: self.collection, el:$("div#list")}); + } + }); + + var App = new FrontPage({el: $("#main")}); +}); \ No newline at end of file diff --git a/htdocs/js/apps/HomeworkManager/HWDetailView.js b/htdocs/js/apps/HomeworkManager/HWDetailView.js new file mode 100644 index 000000000..4826dcf4c --- /dev/null +++ b/htdocs/js/apps/HomeworkManager/HWDetailView.js @@ -0,0 +1,178 @@ +/** + * This is the HWDetailView, which is part of the HomeworkManagmentView. The view contains the interface to all of the + * details of a given homework set including the changing of HWSet properties and assigning of users. + * + * One must pass a ProblemSet as a model to this. + * + **/ + + +define(['Backbone', + 'underscore', + '../../lib/webwork/views/EditableCell', + '../../lib/webwork/views/ProblemListView', + '../../lib/webwork/models/ProblemList'], + function(Backbone, _,EditableCell,ProblemListView,ProblemList){ + var HWDetailView = Backbone.View.extend({ + className: "set-detail-view", + tagName: "div", + initialize: function () { + _.bindAll(this,'render','changeHWSet','renderProblems','updateNumProblems'); + this.parent = this.options.parent; + this.dispatcher = _.clone(Backbone.Events); + this.render(); + }, + changeHWSet: function (setName) + { + var self = this; + $("#view-header-list div[data-view='problem-set']").html("Problem Set Details for " + setName); + + $("#problem-set-tabs a:first").tab("show"); // shows the problems + + // this.model will be a ProblemSet + this.model = this.collection.find(function(model) {return model.get("set_id")===setName;}); + + + if(this.model.problems){ + console.log("changing the HW Set to " + setName); + this.renderProblems(); + this.model.problems.on("add",function (){ + console.log("Added a Problem"); + self.parent.announce.appendHTML("Problem Added to set: " + self.model.get("set_id")); + }); + + new HWPropertiesView({el: $("#property-tab"), model: this.model}); + + + this.model.countSetUsers(); + this.model.on("countUsers",function(_assignedUsers){ + console.log("in countUsers"); + $("#num-users-assigned").html(_assignedUsers.length + " of " + self.parent.users.length); + $("#user-tab").html((new AssignUsersView({users: self.parent.users, assignedUsers: _assignedUsers, + model: self.model})).el); + + }); + + // This sets messages + this.model.on("deleteProblem",function (setName,place) { + var str = "Problem #" + (place +1) + " Deleted from set: " + setName + "
" + + "To undo this, click the Undo button above the problem list. "; + self.parent.announce.appendHTML(str); + }); + + this.model.problems.on("remove",self.updateNumProblems); + + } else { + this.model.problems = new ProblemList({type: "Problem Set", setName: setName}); + this.model.problems.on("fetchSuccess",function() {self.changeHWSet(setName)}); + } + + this.dispatcher.off("num-problems-shown"); + this.dispatcher.on("num-problems-shown", self.updateNumProblems); + }, + render: function () { + var self = this; + this.$el.html(_.template($("#HW-detail-template").html())); + // activate the tabs + $('#problem-set-tabs a').click(function (e) { + e.preventDefault(); + $(this).tab('show'); + }); + + + return this; + + }, + renderProblems: function (){ + console.log("showing the problems for problem set " + this.model.get("set_id")); + $("#prob-tab").html(_.template($("#problem-set-header").html(),{set: this.model.get("set_id")})); + var plv = new ProblemListView({el: this.$(".prob-list"), parent: this, collection: this.model.problems, + reorderable: true, deletable: true, draggable: false}); + plv.render(); + }, + updateNumProblems: function () { + console.log("firing num-problems-shown"); + var num = this.$("li.problem").size(); + this.$("div.num-probs").html(num + " of " + this.model.problems.size() + " shown"); + } + }); + + var HWPropertiesView = Backbone.View.extend({ + initialize: function () { + _.bindAll(this,'render'); + _.extend(this,this.options); + this.render(); + }, + render: function () { + // Update the HW Properties Tab + + console.log("in HWPropertiesView render"); + + this.$el.html(_.template($("#hwset-dates-tmpl").html())); + + + this.$("#due-date-row").append( (new EditableCell({model : this.model, type: "datetime", property: "open_date"})).render().el); + this.$("#due-date-row").append( (new EditableCell({model : this.model, type: "datetime", property: "due_date"})).render().el); + this.$("#due-date-row").append( (new EditableCell({model : this.model, type: "datetime", property: "answer_date"})).render().el); + + this.$("#hwset-visible").html((new EditableCell({model: this.model, property: "visible"})).render().el); + this.$("#reduced-credit").html((new EditableCell({model: this.model, property: "enable_reduced_scoring"})).render().el); + + } + }); + + var AssignUsersView = Backbone.View.extend({ + tagName: "div", + template: _.template($("#selected-users-template").html()), + initialize: function () { + _.bindAll(this,'render','selectAll','assignToSelected'); + _.extend(this,this.options); + this.render(); + }, + render: function () { + var self = this; + this.$el.html(_.template($("#users-assigned-tmpl").html())); + + var allUsers = this.users.sortBy(function(_user) { return _user.get("last_name");}); + + _(allUsers).each(function(user,i) { + var cl = null; + if (i" + this.property.get("doc") + ""); + switch(this.property.get("type")){ + case "text": + case "number": + this.$el.append(""); + break; + case "checkboxlist": + var opts = _(self.property.get("values")).map(function(v) {return "
  • " + v + "
  • ";}); + this.$el.append("
      " + opts.join("") + "
    "); + _(self.property.get("value")).each(function(v){ + self.$("#prop-" + self.property.cid + " input:checkbox[value='" + v + "']").attr("checked","checked"); + }) + break; + case "popuplist": + var opts = _(self.property.get("values")).map(function(v) {return "";}); + this.$el.append(""); + self.$("#prop-" + self.property.cid + " select.popuplist option[value='" + self.property.get("value") + "']").attr("selected","selected"); + break; + case "boolean": + this.$el.append("" + + ""); }); - return this; // for chainable calls, like .render().el - }, - updateProp: function(evt){ - var changedAttr = evt.target.className.split("for-")[1]; - this.model.set(changedAttr,evt.target.value,{silent: true}); - console.log("new value: " + evt.target.value); - }, - unrender: function(){ - this.$el.remove(); - }, - removeUser: function() {console.log("in removeUser"); this.model.destroy();} - }); - - // This is the View for the dialog for addings students manually - - var AddStudentManView = Backbone.View.extend({ - tagName: "div", - id: "addStudManDialog", - - initialize: function(){ - _.bindAll(this, 'render','importStudents','addStudent','appendRow'); // every function that uses 'this' as the current object should be in here - this.users = new TempUserList(); - this.users.bind('add', this.appendRow); - this.parent = this.options.parent; - this.render(); - - this.users.add(new webwork.User()); // add a single blank line. - - this.$el.dialog({autoOpen: false, modal: true, title: "Add Students by Hand", - width: (0.95*window.innerWidth), height: (0.95*window.innerHeight) }); - }, - events: { - "click button#import_stud_button": "importStudents", - "click button#add_more_button": "addStudent" - }, - openDialog: function () { this.$el.dialog("open");}, - closeDialog: function () {this.$el.dialog("close");}, - template: _.template($("#add_student_man_dialog_content").html()), - render: function(){ - var self = this; - var tableHTML = "" - tableHTML += (_(webwork.userProps).map(function (prop) {return "";})).join("") + "
    Delete" + prop.longName + "
    "; - - this.$el.html(this.template({content: tableHTML})); - _(this.users).each(function(user){ self.appendRow(user);}, this); - }, - importStudents: function(){ // validate each student data then upload to the server. - console.log('in importStudents'); - _(this.users.models).each(function(user){ - App.users.add(user); - console.log("Adding the following student: " + JSON.stringify(user)) - }); - this.closeDialog(); - }, - appendRow: function(user){ - var tableRow = new UserRowView({model: user}); - $("table#man_student_table tbody",this.el).append(tableRow.el); - }, - addStudent: function (){ this.users.add(new webwork.User());} - }); - - - - var AddStudentFileView = Backbone.View.extend({ - tagName: "div", - id: "addStudFileDialog", - - initialize: function(){ - _.bindAll(this, 'render','importStudents','addStudent','appendRow'); // every function that uses 'this' as the current object should be in here - this.users = new TempUserList(); - this.parent = this.options.parent; - this.render(); - - //for(var i = 0; i<1; i++) {this.users.add(new webwork.User())} // add a single blank line. - - this.$el.dialog({autoOpen: false, modal: true, title: "Add Students from a File", - width: (0.95*window.innerWidth), height: (0.95*window.innerHeight) }); - }, - events: { - "click button#importStudFromFileButton": "importStudents", - "change input#files": "readFile", - "change input#useLST" : "setHeadersForLST", - "change input#useFirst" : "useFirstRow" - }, - openDialog: function () { this.$el.dialog("open");}, - closeDialog: function () {this.$el.dialog("close");}, - render: function(){ - this.$el.html($("#add_student_file_dialog_content").html()); - return this; - }, - readFile: function(evt){ - var self = this; - console.log("in loadFile"); - $("li#step1").css("display","none"); // Hide the first step of the Wizard - $("li#step2").css("display","block"); // And show the next step. - $("button#importStudFromFileButton").css("display","block"); - - this.file = $("#files").get(0).files[0]; - $('#list').html('' + escape(this.file.name)); - - - - // Need to test if the browser can handle this new object. If not, find alternative route. - - var reader = new FileReader(); - - reader.onload = function(event) { - var content = event.target.result; - headers = _(webwork.userProps).map(function(prop) {return prop.longName;}); - headers.splice(0,0,""); - - // Parse the CSV file - - var str = util.CSVToHTMLTable(content,headers); - - // build the table and set it up to scroll nicely. - $("#studentTable").html(str); - $("#selectAllASW").click(function(){ $(".selRow").attr("checked",$("#selectAllASW").is(":checked")); }); - $("div.inner").width(25+($("#sTable thead td").length)*175); - $("#inner-table td").width($("#sTable thead td:nth-child(2)").width()+4) - $("#inner-table td:nth-child(1)").width($("#sTable thead td:nth-child(1)").width()) - - // test if it is a classlist file and then set the headers appropriately - - var re=new RegExp("\.lst$","i"); - if (re.test(self.file.name)){self.setHeadersForLST();} - - $("select.colHeader").change(function(evt) {self.updateHeaders(evt.target);}) - - - - console.log("loaded file"); - } - - reader.readAsText(this.file); - - - }, - updateHeaders: function(target) { // Detect where the Login Name column is in the table and show duplicate entries of users. - if ($(target).val() == webwork.userProps[8].longName) { - var loginCol = Number($(target).attr("id").split("col")[1])+2; - var impUsers = $("#inner-table td:nth-child(" + loginCol + ")").map(function (i,cell) { return $.trim($(cell).html()).toLowerCase();}); - - var users = App.users.map(function (user) {return user.attributes.user_id.toLowerCase();}); - var duplicateUsers = _.intersection(impUsers,users); - - $("#inner-table td:nth-child(" + loginCol + ")").each(function (i,cell) { - if (_(duplicateUsers).any(function (user) { return user.toLowerCase() == $.trim($(cell).html()).toLowerCase();})){ - $("#inner-table tr#row" + i).css("background-color","#EE5555"); - } - }); - } - }, - importStudents: function () { // PLS: Still need to check if student import is sucessful, like making sure that user_id is valid (not repeating, ...) - // First check to make sure that the headers are not repeated. - var headers = []; - _($("select[class='colHeader']")).each(function(obj,j){if ($(obj).val() != "") headers.push({header: $(obj).val(), position: j});}); - - //console.log(headers); - var heads = _(headers).map(function (obj) {return obj.header;}); - var sortedHeads = _(heads).sortBy(function (str) {return str;}); - - // Determine if the user has selected a unique set of headers. - - var validHeaders=true; - for (var i=0;i
    "); + this.collection.each(function (model) { + var setName = model.get("set_id"); + $("#probSetList").append("
    " + setName + "
    ") + $("div#HW-" + setName ).click(function(evt) { + if (self.objectDragging) return; + $('#hwedTabs a[href="#details"]').tab('show'); + self.showDetails($(evt.target).attr("id").split("HW-")[1]); + }); + + }); + $(".ps-drag").draggable({revert: "valid", start: function (event,ui) { self.objectDragging=true;}, + stop: function(event, ui) {self.objectDragging=false;}}); + + + this.calendarView = new CalendarView({collection: this.collection, view: "student"}); + + $("#cal").append(this.calendarView.el); + + $(".calendar-day").droppable({ // This doesn't work right now. + hoverClass: "highlight-day", + drop: function( event, ui ) { + App.dragging = true; + //$(this).addClass("ui-state-highlight"); + console.log( "Dropped on " + self.$el.attr("id")); + } + }); + + // Set the popover on the set name + $("span.pop").popover({title: "Homework Set Details", placement: "top", offset: 10}); + + self.setListView = new SetListView({collection: self.collection, el:$("div#list")}); + }, this); + }, + render: function(){ + var self = this; + + // Create an announcement pane for successful messages. + + this.announce = new Closeable({id: "announce-bar"}); + this.announce.$el.addClass("alert-success"); + this.$el.append(this.announce.el) + $("button.close",this.announce.el).click(function () {self.announce.close();}); // for some reason the event inside this.announce is not working this is a hack. + //this.announce.delegateEvents(); + + // Create an announcement pane for successful messages. + + this.errorPane = new Closeable({id: "error-bar", classes: ["alert-error"]}); + this.$el.append(this.errorPane.el) + $("button.close",this.errorPane.el).click(function () {self.errorPane.close();}); // for some reason the event inside this.announce is not working this is a hack. + + + this.helpPane = new Closeable({display: "block",text: $("#homeworkEditorHelp").html(),id: "helpPane"}); + this.$el.append(this.helpPane.el) + $("button.close",this.helpPane.el).click(function () {self.helpPane.close();}); // for some reason the event inside this.announce is not working this is a hack. + + this.$el.append("
    Loading Homework Sets...
    "); + + $("#tab-container").append(_.template($("#tab-setup").html())); + $('#hwedTabs a').click(function (e) { + e.preventDefault(); + $(this).tab('show'); + }); + + $("body").droppable(); // This helps in making drags return to their original place. + + new SettingsView({el: $("#settings")}); + + + + }, + showDetails: function(setName) { // Show the details of the set with name: setName + var self = this; + var _model = self.collection.find(function(model) {return model.get("set_id")===setName;}); + this.detailView = new HWDetailView({model: _model, el: $("#details")}); + } + }); + + var HWDetailRowView = Backbone.View.extend({ + className: "set-detail-row", + tagName: "tr", + initialize: function () { + _.bindAll(this,'render','edit'); + this.property = this.options.property; + this.dateRE =/(\d\d\/\d\d\/\d\d\d\d)\sat\s((\d\d:\d\d)([apAP][mM])\s([a-zA-Z]{3}))/; + this.render(); + return this; + }, + render: function() { + this.$el.html("" + this.property + " " + this.model.get(this.property) + ""); + } + , + events: { + "click .edit-button": "edit" + }, + edit: function(evt){ + var value; + switch(this.property){ + case "set_header": + case "hardcopy_header": + value = this.$("#value-col").html(); + this.$("#value-col").html(""); + this.$("input#edit-box").val(value); + break; + case "open_date": + case "due_date": + case "answer_date": + + var dateParts = this.dateRE.exec(this.$("#value-col").html()); + theDate = dateParts[1]; + theTime = dateParts[2]; + this.$("#value-col").html(""); + this.$("input#edit-box").val(theDate); + this.$("input#edit-box").datepicker({showButtonPanel: true}); + + break; + + } + } + }); + + var HWProblemView = Backbone.View.extend({ + className: "set-detail-problem-view", + tagName: "div", + + initialize: function () { + _.bindAll(this,"render"); + var self = this; + this.render(); + this.model.on('rendered', function () { + self.$el.html(self.model.get("data")); + }) + }, + render: function () { + this.$el.html(this.model.get("path")); + this.model.render(); + } + + + }); + + var HWDetailView = Backbone.View.extend({ + className: "set-detail-view", + tagName: "div", + initialize: function () { + _.bindAll(this,'render'); + var self = this; + this.render(); + this.problemPathList = new ProblemSetPathList(); + this.problemPathList.fetch(this.model.get("set_id")); + this.problemPathList.on("fetchSuccess",function () { + var hwDetailDiv = $("#hw-detail-problems"); + self.problemPathList.each(function(_problem){ + var hwpv = new HWProblemView({model: new Problem({path: _problem.get("path")})}); + hwDetailDiv.append(hwpv.el); +// $("#hw-detail-problems").html((self.problemPathList.map(function(ProblemSet) {return ProblemSet.get("path");})).join(",")); + }); + + }); + return this; + }, + render: function () { + var self = this; + this.$el.html(_.template($("#HW-detail-template").html())) + _(this.model.attributes).each(function(value,key) { $("#detail-table").append((new HWDetailRowView({model: self.model, property: key})).el)}); + return this; + } + }); + + var SetListRowView = Backbone.View.extend({ + className: "set-list-row", + tagName: "tr", + initialize: function () { + _.bindAll(this,'render'); + var self = this; + this.render(); + return this; + }, + render: function () { + var self = this; + this.$el.append((_(["set_id","open_date","due_date","answer_date"]).map(function(v) {return "" + self.model.get(v) + "";})).join("")); + } + }); + + var SetListView = Backbone.View.extend({ + className: "set-list-view", + initialize: function () { + _.bindAll(this, 'render'); // include all functions that need the this object + var self = this; + + this.render(); + return this; + }, + render: function () { + var self = this; + this.$el.append("
    NameOpen DateDue DateAnswer Date
    "); + var tab = $("#set-list-table"); + this.collection.each(function(m){ + tab.append((new SetListRowView({model: m})).el); + }); + + } + }); + + + var SettingsRowView = Backbone.View.extend({ + tagName: "tr", + initialize: function () { + _.bindAll(this, 'render','editRow'); // include all functions that need the this object + this.render(); + }, + render: function () { + this.$el.html(" " + this.model.get("name") + " " + this.model.get("value") + ""); + return this; + + }, + events: {"click .srv-value": "editRow"}, + editRow: function () { + var tableCell = this.$(".srv-value"); + var value = tableCell.html(); + tableCell.html(""); + var inputBox = this.$(".srv-edit-box"); + inputBox.val(value); + inputBox.click(function (event) {event.stopPropagation();}); + this.$(".srv-edit-box").focusout(function() { + tableCell.html(inputBox.val()); + model.set("value",inputBox.val()); // should validate here as well. + + // need to also set the property on the server or + }); + } + + + }); + + var SettingsView = Backbone.View.extend({ + className: "settings-view", + initialize: function () { + _.bindAll(this, 'render'); // include all functions that need the this object + this.render(); + }, + render: function () { + this.$el.html("
    PropertyValue
    "); + var tab = this.$("table"); + HomeworkEditor.settings.each(function(setting){ tab.append((new SettingsRowView({model: setting})).el)}); + + } + }); + + + var App = new HomeworkEditorView({el: $("div#mainDiv")}); + //var libraryApp = new LibraryBrowser({el:$("div#library")}); +}); diff --git a/htdocs/js/lib/vendor/jquery-ui-for-classlist3/css/ui-lightness/images/ui-bg_diagonals-thick_18_b81900_40x40.png b/htdocs/js/jquery-ui-1.9.0.custom/css/ui-lightness/images/ui-bg_diagonals-thick_18_b81900_40x40.png similarity index 100% rename from htdocs/js/lib/vendor/jquery-ui-for-classlist3/css/ui-lightness/images/ui-bg_diagonals-thick_18_b81900_40x40.png rename to htdocs/js/jquery-ui-1.9.0.custom/css/ui-lightness/images/ui-bg_diagonals-thick_18_b81900_40x40.png diff --git a/htdocs/js/lib/vendor/jquery-ui-for-classlist3/css/ui-lightness/images/ui-bg_diagonals-thick_20_666666_40x40.png b/htdocs/js/jquery-ui-1.9.0.custom/css/ui-lightness/images/ui-bg_diagonals-thick_20_666666_40x40.png similarity index 100% rename from htdocs/js/lib/vendor/jquery-ui-for-classlist3/css/ui-lightness/images/ui-bg_diagonals-thick_20_666666_40x40.png rename to htdocs/js/jquery-ui-1.9.0.custom/css/ui-lightness/images/ui-bg_diagonals-thick_20_666666_40x40.png diff --git a/htdocs/js/lib/vendor/jquery-ui-for-classlist3/css/ui-lightness/images/ui-bg_flat_10_000000_40x100.png b/htdocs/js/jquery-ui-1.9.0.custom/css/ui-lightness/images/ui-bg_flat_10_000000_40x100.png similarity index 100% rename from htdocs/js/lib/vendor/jquery-ui-for-classlist3/css/ui-lightness/images/ui-bg_flat_10_000000_40x100.png rename to htdocs/js/jquery-ui-1.9.0.custom/css/ui-lightness/images/ui-bg_flat_10_000000_40x100.png diff --git a/htdocs/js/lib/vendor/jquery-ui-for-classlist3/css/ui-lightness/images/ui-bg_glass_100_f6f6f6_1x400.png b/htdocs/js/jquery-ui-1.9.0.custom/css/ui-lightness/images/ui-bg_glass_100_f6f6f6_1x400.png similarity index 100% rename from htdocs/js/lib/vendor/jquery-ui-for-classlist3/css/ui-lightness/images/ui-bg_glass_100_f6f6f6_1x400.png rename to htdocs/js/jquery-ui-1.9.0.custom/css/ui-lightness/images/ui-bg_glass_100_f6f6f6_1x400.png diff --git a/htdocs/js/lib/vendor/jquery-ui-for-classlist3/css/ui-lightness/images/ui-bg_glass_100_fdf5ce_1x400.png b/htdocs/js/jquery-ui-1.9.0.custom/css/ui-lightness/images/ui-bg_glass_100_fdf5ce_1x400.png similarity index 100% rename from htdocs/js/lib/vendor/jquery-ui-for-classlist3/css/ui-lightness/images/ui-bg_glass_100_fdf5ce_1x400.png rename to htdocs/js/jquery-ui-1.9.0.custom/css/ui-lightness/images/ui-bg_glass_100_fdf5ce_1x400.png diff --git a/htdocs/js/lib/vendor/jquery-ui-for-classlist3/css/ui-lightness/images/ui-bg_glass_65_ffffff_1x400.png b/htdocs/js/jquery-ui-1.9.0.custom/css/ui-lightness/images/ui-bg_glass_65_ffffff_1x400.png similarity index 100% rename from htdocs/js/lib/vendor/jquery-ui-for-classlist3/css/ui-lightness/images/ui-bg_glass_65_ffffff_1x400.png rename to htdocs/js/jquery-ui-1.9.0.custom/css/ui-lightness/images/ui-bg_glass_65_ffffff_1x400.png diff --git a/htdocs/js/lib/vendor/jquery-ui-for-classlist3/css/ui-lightness/images/ui-bg_gloss-wave_35_f6a828_500x100.png b/htdocs/js/jquery-ui-1.9.0.custom/css/ui-lightness/images/ui-bg_gloss-wave_35_f6a828_500x100.png similarity index 100% rename from htdocs/js/lib/vendor/jquery-ui-for-classlist3/css/ui-lightness/images/ui-bg_gloss-wave_35_f6a828_500x100.png rename to htdocs/js/jquery-ui-1.9.0.custom/css/ui-lightness/images/ui-bg_gloss-wave_35_f6a828_500x100.png diff --git a/htdocs/js/lib/vendor/jquery-ui-for-classlist3/css/ui-lightness/images/ui-bg_highlight-soft_100_eeeeee_1x100.png b/htdocs/js/jquery-ui-1.9.0.custom/css/ui-lightness/images/ui-bg_highlight-soft_100_eeeeee_1x100.png similarity index 100% rename from htdocs/js/lib/vendor/jquery-ui-for-classlist3/css/ui-lightness/images/ui-bg_highlight-soft_100_eeeeee_1x100.png rename to htdocs/js/jquery-ui-1.9.0.custom/css/ui-lightness/images/ui-bg_highlight-soft_100_eeeeee_1x100.png diff --git a/htdocs/js/lib/vendor/jquery-ui-for-classlist3/css/ui-lightness/images/ui-bg_highlight-soft_75_ffe45c_1x100.png b/htdocs/js/jquery-ui-1.9.0.custom/css/ui-lightness/images/ui-bg_highlight-soft_75_ffe45c_1x100.png similarity index 100% rename from htdocs/js/lib/vendor/jquery-ui-for-classlist3/css/ui-lightness/images/ui-bg_highlight-soft_75_ffe45c_1x100.png rename to htdocs/js/jquery-ui-1.9.0.custom/css/ui-lightness/images/ui-bg_highlight-soft_75_ffe45c_1x100.png diff --git a/htdocs/js/lib/vendor/jquery-ui-for-classlist3/css/ui-lightness/images/ui-icons_222222_256x240.png b/htdocs/js/jquery-ui-1.9.0.custom/css/ui-lightness/images/ui-icons_222222_256x240.png similarity index 100% rename from htdocs/js/lib/vendor/jquery-ui-for-classlist3/css/ui-lightness/images/ui-icons_222222_256x240.png rename to htdocs/js/jquery-ui-1.9.0.custom/css/ui-lightness/images/ui-icons_222222_256x240.png diff --git a/htdocs/js/lib/vendor/jquery-ui-for-classlist3/css/ui-lightness/images/ui-icons_228ef1_256x240.png b/htdocs/js/jquery-ui-1.9.0.custom/css/ui-lightness/images/ui-icons_228ef1_256x240.png similarity index 100% rename from htdocs/js/lib/vendor/jquery-ui-for-classlist3/css/ui-lightness/images/ui-icons_228ef1_256x240.png rename to htdocs/js/jquery-ui-1.9.0.custom/css/ui-lightness/images/ui-icons_228ef1_256x240.png diff --git a/htdocs/js/lib/vendor/jquery-ui-for-classlist3/css/ui-lightness/images/ui-icons_ef8c08_256x240.png b/htdocs/js/jquery-ui-1.9.0.custom/css/ui-lightness/images/ui-icons_ef8c08_256x240.png similarity index 100% rename from htdocs/js/lib/vendor/jquery-ui-for-classlist3/css/ui-lightness/images/ui-icons_ef8c08_256x240.png rename to htdocs/js/jquery-ui-1.9.0.custom/css/ui-lightness/images/ui-icons_ef8c08_256x240.png diff --git a/htdocs/js/lib/vendor/jquery-ui-for-classlist3/css/ui-lightness/images/ui-icons_ffd27a_256x240.png b/htdocs/js/jquery-ui-1.9.0.custom/css/ui-lightness/images/ui-icons_ffd27a_256x240.png similarity index 100% rename from htdocs/js/lib/vendor/jquery-ui-for-classlist3/css/ui-lightness/images/ui-icons_ffd27a_256x240.png rename to htdocs/js/jquery-ui-1.9.0.custom/css/ui-lightness/images/ui-icons_ffd27a_256x240.png diff --git a/htdocs/js/lib/vendor/jquery-ui-for-classlist3/css/ui-lightness/images/ui-icons_ffffff_256x240.png b/htdocs/js/jquery-ui-1.9.0.custom/css/ui-lightness/images/ui-icons_ffffff_256x240.png similarity index 100% rename from htdocs/js/lib/vendor/jquery-ui-for-classlist3/css/ui-lightness/images/ui-icons_ffffff_256x240.png rename to htdocs/js/jquery-ui-1.9.0.custom/css/ui-lightness/images/ui-icons_ffffff_256x240.png diff --git a/htdocs/js/jquery-ui-1.9.0.custom/css/ui-lightness/jquery-ui-1.9.0.custom.css b/htdocs/js/jquery-ui-1.9.0.custom/css/ui-lightness/jquery-ui-1.9.0.custom.css new file mode 100755 index 000000000..12b99b1be --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/css/ui-lightness/jquery-ui-1.9.0.custom.css @@ -0,0 +1,458 @@ +/*! jQuery UI - v1.9.0 - 2012-10-13 +* http://jqueryui.com +* Includes: jquery.ui.core.css, jquery.ui.resizable.css, jquery.ui.selectable.css, jquery.ui.accordion.css, jquery.ui.autocomplete.css, jquery.ui.button.css, jquery.ui.datepicker.css, jquery.ui.dialog.css, jquery.ui.menu.css, jquery.ui.progressbar.css, jquery.ui.slider.css, jquery.ui.spinner.css, jquery.ui.tabs.css, jquery.ui.tooltip.css +* To view and modify this theme, visit http://jqueryui.com/themeroller/?ffDefault=Trebuchet%20MS%2CTahoma%2CVerdana%2CArial%2Csans-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 +* Copyright (c) 2012 jQuery Foundation and other contributors Licensed MIT */ + +/* Layout helpers +----------------------------------*/ +.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:before, .ui-helper-clearfix:after { content: ""; display: table; } +.ui-helper-clearfix:after { clear: both; } +.ui-helper-clearfix { zoom: 1; } +.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%; } +.ui-resizable { position: relative;} +.ui-resizable-handle { position: absolute;font-size: 0.1px; 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;}.ui-selectable-helper { position: absolute; z-index: 100; border:1px dotted black; } +.ui-accordion .ui-accordion-header { display: block; cursor: pointer; position: relative; margin-top: 2px; padding: .5em .5em .5em .7em; zoom: 1; } +.ui-accordion .ui-accordion-icons { padding-left: 2.2em; } +.ui-accordion .ui-accordion-noicons { padding-left: .7em; } +.ui-accordion .ui-accordion-icons .ui-accordion-icons { padding-left: 2.2em; } +.ui-accordion .ui-accordion-header .ui-accordion-header-icon { position: absolute; left: .5em; top: 50%; margin-top: -8px; } +.ui-accordion .ui-accordion-content { padding: 1em 2.2em; border-top: 0; overflow: auto; zoom: 1; } +.ui-autocomplete { position: absolute; cursor: default; } + +/* workarounds */ +* html .ui-autocomplete { width:1px; } /* without this, the menu expands to 100% in IE6 */ +.ui-button { display: inline-block; position: relative; padding: 0; margin-right: .1em; cursor: pointer; text-align: center; zoom: 1; overflow: visible; } /* the overflow property removes extra width in IE */ +.ui-button, .ui-button:link, .ui-button:visited, .ui-button:hover, .ui-button:active { text-decoration: none; } +.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 */ +.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 { + 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*/ +}.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; } +.ui-menu { list-style:none; padding: 2px; margin: 0; display:block; outline: none; } +.ui-menu .ui-menu { margin-top: -3px; position: absolute; } +.ui-menu .ui-menu-item { margin: 0; padding: 0; zoom: 1; width: 100%; } +.ui-menu .ui-menu-divider { margin: 5px -2px 5px -2px; height: 0; font-size: 0; line-height: 0; border-width: 1px 0 0 0; } +.ui-menu .ui-menu-item a { text-decoration: none; display: block; padding: 2px .4em; line-height: 1.5; zoom: 1; font-weight: normal; } +.ui-menu .ui-menu-item a.ui-state-focus, +.ui-menu .ui-menu-item a.ui-state-active { font-weight: normal; margin: -1px; } + +.ui-menu .ui-state-disabled { font-weight: normal; margin: .4em 0 .2em; line-height: 1.5; } +.ui-menu .ui-state-disabled a { cursor: default; } + +/* icon support */ +.ui-menu-icons { position: relative; } +.ui-menu-icons .ui-menu-item a { position: relative; padding-left: 2em; } + +/* left-aligned */ +.ui-menu .ui-icon { position: absolute; top: .2em; left: .2em; } + +/* right-aligned */ +.ui-menu .ui-menu-icon { position: static; float: right; } +.ui-progressbar { height:2em; text-align: left; overflow: hidden; } +.ui-progressbar .ui-progressbar-value {margin: -1px; height:100%; }.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; }.ui-spinner { position:relative; display: inline-block; overflow: hidden; padding: 0; vertical-align: middle; } +.ui-spinner-input { border: none; background: none; padding: 0; margin: .2em 0; vertical-align: middle; margin-left: .4em; margin-right: 22px; } +.ui-spinner-button { width: 16px; height: 50%; font-size: .5em; padding: 0; margin: 0; z-index: 100; text-align: center; position: absolute; cursor: default; display: block; overflow: hidden; right: 0; } +.ui-spinner a.ui-spinner-button { border-top: none; border-bottom: none; border-right: none; } /* more specificity required here to overide default borders */ +.ui-spinner .ui-icon { position: absolute; margin-top: -8px; top: 50%; left: 0; } /* vertical centre icon */ +.ui-spinner-up { top: 0; } +.ui-spinner-down { bottom: 0; } + +/* TR overrides */ +span.ui-spinner { background: none; } +.ui-spinner .ui-icon-triangle-1-s { + /* need to fix icons sprite */ + background-position:-65px -16px; +} +.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: 0; margin: 1px .2em 0 0; border-bottom: 0; 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-active { margin-bottom: -1px; padding-bottom: 1px; } +.ui-tabs .ui-tabs-nav li.ui-tabs-active a, .ui-tabs .ui-tabs-nav li.ui-state-disabled a, .ui-tabs .ui-tabs-nav li.ui-tabs-loading a { cursor: text; } +.ui-tabs .ui-tabs-nav li a, .ui-tabs-collapsible .ui-tabs-nav li.ui-tabs-active 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-tooltip { + padding:8px; + position:absolute; + z-index:9999; + -o-box-shadow: 0 0 5px #aaa; + -moz-box-shadow: 0 0 5px #aaa; + -webkit-box-shadow: 0 0 5px #aaa; + box-shadow: 0 0 5px #aaa; +} +/* Fades and background-images don't work well together in IE6, drop the image */ +* html .ui-tooltip { + background-image: none; +} +body .ui-tooltip { border-width:2px; } + +/* 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; } + +/* 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-on { background-position: -96px -144px; } +.ui-icon-radio-off { 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: .5;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: .2;filter:Alpha(Opacity=20); -moz-border-radius: 5px; -khtml-border-radius: 5px; -webkit-border-radius: 5px; border-radius: 5px; } \ No newline at end of file diff --git a/htdocs/js/jquery-ui-1.9.0.custom/css/ui-lightness/jquery-ui-1.9.0.custom.min.css b/htdocs/js/jquery-ui-1.9.0.custom/css/ui-lightness/jquery-ui-1.9.0.custom.min.css new file mode 100755 index 000000000..ed3003d5e --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/css/ui-lightness/jquery-ui-1.9.0.custom.min.css @@ -0,0 +1,5 @@ +/*! jQuery UI - v1.9.0 - 2012-10-13 +* http://jqueryui.com +* Includes: jquery.ui.core.css, jquery.ui.resizable.css, jquery.ui.selectable.css, jquery.ui.accordion.css, jquery.ui.autocomplete.css, jquery.ui.button.css, jquery.ui.datepicker.css, jquery.ui.dialog.css, jquery.ui.menu.css, jquery.ui.progressbar.css, jquery.ui.slider.css, jquery.ui.spinner.css, jquery.ui.tabs.css, jquery.ui.tooltip.css +* To view and modify this theme, visit http://jqueryui.com/themeroller/?ffDefault=Trebuchet%20MS%2CTahoma%2CVerdana%2CArial%2Csans-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 +* Copyright (c) 2012 jQuery Foundation and other contributors Licensed MIT */.ui-helper-hidden{display:none}.ui-helper-hidden-accessible{position:absolute!important;clip:rect(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:before,.ui-helper-clearfix:after{content:"";display:table}.ui-helper-clearfix:after{clear:both}.ui-helper-clearfix{zoom:1}.ui-helper-zfix{width:100%;height:100%;top:0;left:0;position:absolute;opacity:0;filter:Alpha(Opacity=0)}.ui-state-disabled{cursor:default!important}.ui-icon{display:block;text-indent:-99999px;overflow:hidden;background-repeat:no-repeat}.ui-widget-overlay{position:absolute;top:0;left:0;width:100%;height:100%}.ui-resizable{position:relative}.ui-resizable-handle{position:absolute;font-size:0.1px;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}.ui-selectable-helper{position:absolute;z-index:100;border:1px dotted black}.ui-accordion .ui-accordion-header{display:block;cursor:pointer;position:relative;margin-top:2px;padding:.5em .5em .5em .7em;zoom:1}.ui-accordion .ui-accordion-icons{padding-left:2.2em}.ui-accordion .ui-accordion-noicons{padding-left:.7em}.ui-accordion .ui-accordion-icons .ui-accordion-icons{padding-left:2.2em}.ui-accordion .ui-accordion-header .ui-accordion-header-icon{position:absolute;left:.5em;top:50%;margin-top:-8px}.ui-accordion .ui-accordion-content{padding:1em 2.2em;border-top:0;overflow:auto;zoom:1}.ui-autocomplete{position:absolute;cursor:default}* html .ui-autocomplete{width:1px}.ui-button{display:inline-block;position:relative;padding:0;margin-right:.1em;cursor:pointer;text-align:center;zoom:1;overflow:visible}.ui-button,.ui-button:link,.ui-button:visited,.ui-button:hover,.ui-button:active{text-decoration:none}.ui-button-icon-only{width:2.2em}button.ui-button-icon-only{width:2.4em}.ui-button-icons-only{width:3.4em}button.ui-button-icons-only{width:3.7em}.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}input.ui-button{padding:.4em 1em}.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}.ui-buttonset{margin-right:7px}.ui-buttonset .ui-button{margin-left:0;margin-right:-.3em}button.ui-button::-moz-focus-inner{border:0;padding:0}.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}.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}.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}.ui-datepicker-cover{position:absolute;z-index:-1;filter:mask();top:-4px;left:-4px;width:200px;height:200px}.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}.ui-menu{list-style:none;padding:2px;margin:0;display:block;outline:none}.ui-menu .ui-menu{margin-top:-3px;position:absolute}.ui-menu .ui-menu-item{margin:0;padding:0;zoom:1;width:100%}.ui-menu .ui-menu-divider{margin:5px -2px 5px -2px;height:0;font-size:0;line-height:0;border-width:1px 0 0 0}.ui-menu .ui-menu-item a{text-decoration:none;display:block;padding:2px .4em;line-height:1.5;zoom:1;font-weight:normal}.ui-menu .ui-menu-item a.ui-state-focus,.ui-menu .ui-menu-item a.ui-state-active{font-weight:normal;margin:-1px}.ui-menu .ui-state-disabled{font-weight:normal;margin:.4em 0 .2em;line-height:1.5}.ui-menu .ui-state-disabled a{cursor:default}.ui-menu-icons{position:relative}.ui-menu-icons .ui-menu-item a{position:relative;padding-left:2em}.ui-menu .ui-icon{position:absolute;top:.2em;left:.2em}.ui-menu .ui-menu-icon{position:static;float:right}.ui-progressbar{height:2em;text-align:left;overflow:hidden}.ui-progressbar .ui-progressbar-value{margin:-1px;height:100%}.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}.ui-spinner{position:relative;display:inline-block;overflow:hidden;padding:0;vertical-align:middle}.ui-spinner-input{border:none;background:none;padding:0;margin:.2em 0;vertical-align:middle;margin-left:.4em;margin-right:22px}.ui-spinner-button{width:16px;height:50%;font-size:.5em;padding:0;margin:0;z-index:100;text-align:center;position:absolute;cursor:default;display:block;overflow:hidden;right:0}.ui-spinner a.ui-spinner-button{border-top:none;border-bottom:none;border-right:none}.ui-spinner .ui-icon{position:absolute;margin-top:-8px;top:50%;left:0}.ui-spinner-up{top:0}.ui-spinner-down{bottom:0}span.ui-spinner{background:none}.ui-spinner .ui-icon-triangle-1-s{background-position:-65px -16px}.ui-tabs{position:relative;padding:.2em;zoom:1}.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:0;margin:1px .2em 0 0;border-bottom:0;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-active{margin-bottom:-1px;padding-bottom:1px}.ui-tabs .ui-tabs-nav li.ui-tabs-active a,.ui-tabs .ui-tabs-nav li.ui-state-disabled a,.ui-tabs .ui-tabs-nav li.ui-tabs-loading a{cursor:text}.ui-tabs .ui-tabs-nav li a,.ui-tabs-collapsible .ui-tabs-nav li.ui-tabs-active a{cursor:pointer}.ui-tabs .ui-tabs-panel{display:block;border-width:0;padding:1em 1.4em;background:none}.ui-tooltip{padding:8px;position:absolute;z-index:9999;-o-box-shadow:0 0 5px #aaa;-moz-box-shadow:0 0 5px #aaa;-webkit-box-shadow:0 0 5px #aaa;box-shadow:0 0 5px #aaa}* html .ui-tooltip{background-image:none}body .ui-tooltip{border-width:2px}.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 #ddd;background:#eee url(images/ui-bg_highlight-soft_100_eeeeee_1x100.png) 50% top repeat-x;color:#333}.ui-widget-content a{color:#333}.ui-widget-header{border:1px solid #e78f08;background:#f6a828 url(images/ui-bg_gloss-wave_35_f6a828_500x100.png) 50% 50% repeat-x;color:#fff;font-weight:bold}.ui-widget-header a{color:#fff}.ui-state-default,.ui-widget-content .ui-state-default,.ui-widget-header .ui-state-default{border:1px solid #ccc;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:#fff 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-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:#fff}.ui-state-error a,.ui-widget-content .ui-state-error a,.ui-widget-header .ui-state-error a{color:#fff}.ui-state-error-text,.ui-widget-content .ui-state-error-text,.ui-widget-header .ui-state-error-text{color:#fff}.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}.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)}.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-on{background-position:-96px -144px}.ui-icon-radio-off{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{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}.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}.ui-widget-overlay{background:#666 url(images/ui-bg_diagonals-thick_20_666666_40x40.png) 50% 50% repeat;opacity:.5;filter:Alpha(Opacity=50)}.ui-widget-shadow{margin:-5px 0 0 -5px;padding:5px;background:#000 url(images/ui-bg_flat_10_000000_40x100.png) 50% 50% repeat-x;opacity:.2;filter:Alpha(Opacity=20);-moz-border-radius:5px;-khtml-border-radius:5px;-webkit-border-radius:5px;border-radius:5px} \ No newline at end of file diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/AUTHORS.txt b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/AUTHORS.txt new file mode 100755 index 000000000..892e2ec76 --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/AUTHORS.txt @@ -0,0 +1,210 @@ +Authors ordered by first contribution +A list of current team members is available at http://jqueryui.com/about + +Paul Bakaus +Richard Worth +Yehuda Katz +Sean Catchpole +John Resig +Tane Piper +Dmitri Gaskin +Klaus Hartl +Stefan Petre +Gilles van den Hoven +Micheil Smith +Jörn Zaefferer +Marc Grabanski +Keith Wood +Brandon Aaron +Scott González +Eduardo Lundgren +Aaron Eisenberger +Joan Piedra +Bruno Basto +Remy Sharp +Bohdan Ganicky +David Bolter +Chi Cheng +Ca-Phun Ung +Ariel Flesler +Maggie Costello Wachs +Scott Jehl +Todd Parker +Andrew Powell +Brant Burnett +Douglas Neiner +Paul Irish +Ralph Whitbeck +Thibault Duplessis +Dominique Vincent +Jack Hsu +Adam Sontag +Carl Fürstenberg +Kevin Dalman +Alberto Fernández Capel +Jacek Jędrzejewski (http://jacek.jedrzejewski.name) +Ting Kuei +Samuel Cormier-Iijima +Jon Palmer +Ben Hollis +Justin MacCarthy +Eyal Kobrigo +Tiago Freire +Diego Tres +Holger Rüprich +Ziling Zhao +Mike Alsup +Robson Braga Araujo +Pierre-Henri Ausseil +Christopher McCulloh +Andrew Newcomb +Lim Chee Aun +Jorge Barreiro +Daniel Steigerwald +John Firebaugh +John Enters +Andrey Kapitcyn +Dmitry Petrov +Eric Hynds +Chairat Sunthornwiphat +Josh Varner +Stéphane Raimbault +Jay Merrifield +J. Ryan Stinnett +Peter Heiberg +Alex Dovenmuehle +Jamie Gegerson +Raymond Schwartz +Phillip Barnes +Kyle Wilkinson +Khaled AlHourani +Marian Rudzynski +Jean-Francois Remy +Doug Blood +Filippo Cavallarin +Heiko Henning +Aliaxandr Rahalevich +Mario Visic +Xavi Ramirez +Max Schnur +Saji Nediyanchath +Corey Frang +Aaron Peterson +Ivan Peters +Mohamed Cherif Bouchelaghem +Marcos Sousa +Michael DellaNoce +George Marshall +Tobias Brunner +Martin Solli +David Petersen +Dan Heberden +William Kevin Manire +Gilmore Davidson +Michael Wu +Adam Parod +Guillaume Gautreau +Marcel Toele +Dan Streetman +Matt Hoskins +Giovanni Giacobbi +Kyle Florence +Pavol Hluchý +Hans Hillen +Mark Johnson +Trey Hunner +Shane Whittet +Edward Faulkner +Adam Baratz +Kato Kazuyoshi +Eike Send +Kris Borchers +Eddie Monge +Israel Tsadok +Carson McDonald +Jason Davies +Garrison Locke +David Murdoch +Ben Boyle +Jesse Baird +Jonathan Vingiano +Dylan Just +Tomy Kaira +Glenn Goodrich +Ashek Elahi +Ryan Neufeld +Marc Neuwirth +Philip Graham +Benjamin Sterling +Wesley Walser +Kouhei Sutou +Karl Kirch +Chris Kelly +Jay Oster +Alex Polomoshnov +David Leal +igor milla +Dave Methvin +Florian Gutmann +Marwan Al Jubeh +Milan Broum +Sebastian Sauer +Gaëtan Muller +Michel Weimerskirch +William Griffiths +Stojce Slavkovski +David Soms +David De Sloovere +Michael P. Jung +Shannon Pekary +Matthew Hutton +James Khoury +Rob Loach +Alberto Monteiro +Alex Rhea +Krzysztof Rosiński +Ryan Olton +Genie <386@mail.com> +Rick Waldron +Ian Simpson +Lev Kitsis +TJ VanToll +Justin Domnitz +Douglas Cerna +Bert ter Heide +Jasvir Nagra +Petr Hromadko +Harri Kilpiö +Lado Lomidze +Amir E. Aharoni +Simon Sattes +Jo Liss +Guntupalli Karunakar +Shahyar Ghobadpour +Lukasz Lipinski +Timo Tijhof +Jason Moon +Martin Frost +Eneko Illarramendi +EungJun Yi +Courtland Allen +Viktar Varvanovich +Danny Trunk +Pavel Stetina +Mike Stay +Steven Roussey +Mike Hollis +Lee Rowlands +Timmy Willison +Karl Swedberg +Baoju Yuan +Maciej Mroziński +Luis Dalmolin +Mark Aaron Shirley +Martin Hoch +Jiayi Yang +Philipp Benjamin Köppchen +Sindre Sorhus +Bernhard Sirlinger +Jared A. Scheel +Rafael Xavier de Souza diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/MIT-LICENSE.txt b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/MIT-LICENSE.txt new file mode 100755 index 000000000..741585591 --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/MIT-LICENSE.txt @@ -0,0 +1,26 @@ +Copyright 2012 jQuery Foundation and other contributors, +http://jqueryui.com/ + +This software consists of voluntary contributions made by many +individuals (AUTHORS.txt, http://jqueryui.com/about) For exact +contribution history, see the revision history and logs, available +at http://jquery-ui.googlecode.com/svn/ + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/README.md b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/README.md new file mode 100755 index 000000000..e7ae90e8a --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/README.md @@ -0,0 +1,99 @@ +[jQuery UI](http://jqueryui.com/) - Interactions and Widgets for the web +================================ + +jQuery UI provides interactions like Drag and Drop and widgets like Autocomplete, Tabs and Slider and makes these as easy to use as jQuery itself. + +If you want to use jQuery UI, go to [jqueryui.com](http://jqueryui.com) to get started. Or visit the [Using jQuery UI Forum](http://forum.jquery.com/using-jquery-ui) for discussions and questions. + +If you are interested in helping develop jQuery UI, you are in the right place. +To discuss development with team members and the community, visit the [Developing jQuery UI Forum](http://forum.jquery.com/developing-jquery-ui) or in #jquery on irc.freednode.net. + + +For contributors +--- + +If you want to help and provide a patch for a bugfix or new feature, please take +a few minutes and look at [our Getting Involved guide](http://wiki.jqueryui.com/w/page/35263114/Getting-Involved). +In particular check out the [Coding standards](http://wiki.jqueryui.com/w/page/12137737/Coding-standards) +and [Commit Message Style Guide](http://wiki.jqueryui.com/w/page/25941597/Commit-Message-Style-Guide). + +In general, fork the project, create a branch for a specific change and send a +pull request for that branch. Don't mix unrelated changes. You can use the commit +message as the description for the pull request. + + +Running the Unit Tests +--- + +Run the unit tests with a local server that supports PHP. No database is required. Pre-configured php local servers are available for Windows and Mac. Here are some options: + +- Windows: [WAMP download](http://www.wampserver.com/en/) +- Mac: [MAMP download](http://www.mamp.info/en/index.html) +- Linux: [Setting up LAMP](https://www.linux.com/learn/tutorials/288158-easy-lamp-server-installation) +- [Mongoose (most platforms)](http://code.google.com/p/mongoose/) + + +Building jQuery UI +--- + +jQuery UI uses the [grunt](http://github.com/cowboy/grunt) build system. Building jQuery UI requires node.js and a command line zip program. + +Install grunt. + +`npm install grunt -g` + +Clone the jQuery UI git repo. + +`git clone git://github.com/jquery/jquery-ui.git` + +`cd jquery-ui` + +Install node modules. + +`npm install` + +Run grunt. + +`grunt build` + +There are many other tasks that can be run through grunt. For a list of all tasks: + +`grunt --help` + + +For committers +--- + +When looking at pull requests, first check for [proper commit messages](http://wiki.jqueryui.com/w/page/12137724/Bug-Fixing-Guide). + +Do not merge pull requests directly through GitHub's interface. +Most pull requests are a single commit; cherry-picking will avoid creating a merge commit. +It's also common for contributors to make minor fixes in an additional one or two commits. +These should be squashed before landing in master. + +**Make sure the author has a valid name and email address associated with the commit.** + +Fetch the remote first: + + git fetch [their-fork.git] [their-branch] + +Then cherry-pick the commit(s): + + git cherry-pick [sha-of-commit] + +If you need to edit the commit message: + + git cherry-pick -e [sha-of-commit] + +If you need to edit the changes: + + git cherry-pick -n [sha-of-commit] + # make changes + git commit --author="[author-name-and-email]" + +If it should go to the stable brach, cherry-pick it to stable: + + git checkout 1-8-stable + git cherry-pick -x [sha-of-commit-from-master] + +*NOTE: Do not cherry-pick into 1-8-stable until you have pushed the commit from master upstream.* diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/accordion/collapsible.html b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/accordion/collapsible.html new file mode 100755 index 000000000..5fa3ba9a5 --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/accordion/collapsible.html @@ -0,0 +1,50 @@ + + + + + jQuery UI Accordion - Collapse content + + + + + + + + + + +
    +

    Section 1

    +
    +

    Mauris mauris ante, blandit et, ultrices a, suscipit eget, quam. Integer ut neque. Vivamus nisi metus, molestie vel, gravida in, condimentum sit amet, nunc. Nam a nibh. Donec suscipit eros. Nam mi. Proin viverra leo ut odio. Curabitur malesuada. Vestibulum a velit eu ante scelerisque vulputate.

    +
    +

    Section 2

    +
    +

    Sed non urna. Donec et ante. Phasellus eu ligula. Vestibulum sit amet purus. Vivamus hendrerit, dolor at aliquet laoreet, mauris turpis porttitor velit, faucibus interdum tellus libero ac justo. Vivamus non quam. In suscipit faucibus urna.

    +
    +

    Section 3

    +
    +

    Nam enim risus, molestie et, porta ac, aliquam ac, risus. Quisque lobortis. Phasellus pellentesque purus in massa. Aenean in pede. Phasellus ac libero ac tellus pellentesque semper. Sed ac felis. Sed commodo, magna quis lacinia ornare, quam ante aliquam nisi, eu iaculis leo purus venenatis dui.

    +
      +
    • List item one
    • +
    • List item two
    • +
    • List item three
    • +
    +
    +

    Section 4

    +
    +

    Cras dictum. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Aenean lacinia mauris vel est.

    Suspendisse eu nisl. Nullam ut libero. Integer dignissim consequat lectus. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos.

    +
    +
    + +
    +

    By default, accordions always keep one section open. To allow for all sections to be be collapsible, set the collapsible option to true. Click on the currently open section to collapse its content pane.

    +
    + + diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/accordion/custom-icons.html b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/accordion/custom-icons.html new file mode 100755 index 000000000..660f1e198 --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/accordion/custom-icons.html @@ -0,0 +1,64 @@ + + + + + jQuery UI Accordion - Customize icons + + + + + + + + + + + +
    +

    Section 1

    +
    +

    Mauris mauris ante, blandit et, ultrices a, suscipit eget, quam. Integer ut neque. Vivamus nisi metus, molestie vel, gravida in, condimentum sit amet, nunc. Nam a nibh. Donec suscipit eros. Nam mi. Proin viverra leo ut odio. Curabitur malesuada. Vestibulum a velit eu ante scelerisque vulputate.

    +
    +

    Section 2

    +
    +

    Sed non urna. Donec et ante. Phasellus eu ligula. Vestibulum sit amet purus. Vivamus hendrerit, dolor at aliquet laoreet, mauris turpis porttitor velit, faucibus interdum tellus libero ac justo. Vivamus non quam. In suscipit faucibus urna.

    +
    +

    Section 3

    +
    +

    Nam enim risus, molestie et, porta ac, aliquam ac, risus. Quisque lobortis. Phasellus pellentesque purus in massa. Aenean in pede. Phasellus ac libero ac tellus pellentesque semper. Sed ac felis. Sed commodo, magna quis lacinia ornare, quam ante aliquam nisi, eu iaculis leo purus venenatis dui.

    +
      +
    • List item one
    • +
    • List item two
    • +
    • List item three
    • +
    +
    +

    Section 4

    +
    +

    Cras dictum. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Aenean lacinia mauris vel est.

    Suspendisse eu nisl. Nullam ut libero. Integer dignissim consequat lectus. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos.

    +
    +
    + + + +
    +

    Customize the header icons with the icons option, which accepts classes for the header's default and active (open) state. Use any class from the UI CSS framework, or create custom classes with background images.

    +
    + + diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/accordion/default.html b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/accordion/default.html new file mode 100755 index 000000000..28fe7cc6d --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/accordion/default.html @@ -0,0 +1,80 @@ + + + + + jQuery UI Accordion - Default functionality + + + + + + + + + + +
    +

    Section 1

    +
    +

    + Mauris mauris ante, blandit et, ultrices a, suscipit eget, quam. Integer + ut neque. Vivamus nisi metus, molestie vel, gravida in, condimentum sit + amet, nunc. Nam a nibh. Donec suscipit eros. Nam mi. Proin viverra leo ut + odio. Curabitur malesuada. Vestibulum a velit eu ante scelerisque vulputate. +

    +
    +

    Section 2

    +
    +

    + Sed non urna. Donec et ante. Phasellus eu ligula. Vestibulum sit amet + purus. Vivamus hendrerit, dolor at aliquet laoreet, mauris turpis porttitor + velit, faucibus interdum tellus libero ac justo. Vivamus non quam. In + suscipit faucibus urna. +

    +
    +

    Section 3

    +
    +

    + Nam enim risus, molestie et, porta ac, aliquam ac, risus. Quisque lobortis. + Phasellus pellentesque purus in massa. Aenean in pede. Phasellus ac libero + ac tellus pellentesque semper. Sed ac felis. Sed commodo, magna quis + lacinia ornare, quam ante aliquam nisi, eu iaculis leo purus venenatis dui. +

    +
      +
    • List item one
    • +
    • List item two
    • +
    • List item three
    • +
    +
    +

    Section 4

    +
    +

    + Cras dictum. Pellentesque habitant morbi tristique senectus et netus + et malesuada fames ac turpis egestas. Vestibulum ante ipsum primis in + faucibus orci luctus et ultrices posuere cubilia Curae; Aenean lacinia + mauris vel est. +

    +

    + Suspendisse eu nisl. Nullam ut libero. Integer dignissim consequat lectus. + Class aptent taciti sociosqu ad litora torquent per conubia nostra, per + inceptos himenaeos. +

    +
    +
    + +
    +

    +Click headers to expand/collapse content that is broken into logical sections, much like tabs. +Optionally, toggle sections open/closed on mouseover. +

    +

    +The underlying HTML markup is a series of headers (H3 tags) and content divs so the content is +usable without JavaScript. +

    +
    + + diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/accordion/fillspace.html b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/accordion/fillspace.html new file mode 100755 index 000000000..bdc2939c5 --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/accordion/fillspace.html @@ -0,0 +1,72 @@ + + + + + jQuery UI Accordion - Fill space + + + + + + + + + + + + + +

    Resize the outer container:

    + +
    +
    +

    Section 1

    +
    +

    Mauris mauris ante, blandit et, ultrices a, suscipit eget, quam. Integer ut neque. Vivamus nisi metus, molestie vel, gravida in, condimentum sit amet, nunc. Nam a nibh. Donec suscipit eros. Nam mi. Proin viverra leo ut odio. Curabitur malesuada. Vestibulum a velit eu ante scelerisque vulputate.

    +
    +

    Section 2

    +
    +

    Sed non urna. Donec et ante. Phasellus eu ligula. Vestibulum sit amet purus. Vivamus hendrerit, dolor at aliquet laoreet, mauris turpis porttitor velit, faucibus interdum tellus libero ac justo. Vivamus non quam. In suscipit faucibus urna.

    +
    +

    Section 3

    +
    +

    Nam enim risus, molestie et, porta ac, aliquam ac, risus. Quisque lobortis. Phasellus pellentesque purus in massa. Aenean in pede. Phasellus ac libero ac tellus pellentesque semper. Sed ac felis. Sed commodo, magna quis lacinia ornare, quam ante aliquam nisi, eu iaculis leo purus venenatis dui.

    +
      +
    • List item one
    • +
    • List item two
    • +
    • List item three
    • +
    +
    +

    Section 4

    +
    +

    Cras dictum. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Aenean lacinia mauris vel est.

    Suspendisse eu nisl. Nullam ut libero. Integer dignissim consequat lectus. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos.

    +
    +
    +
    + +
    +

    Because the accordion is comprised of block-level elements, by default its width fills the available horizontal space. To fill the vertical space allocated by its container, set the heightStyle option to "fill", and the script will automatically set the dimensions of the accordion to the height of its parent container.

    +
    + + diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/accordion/hoverintent.html b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/accordion/hoverintent.html new file mode 100755 index 000000000..232773c84 --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/accordion/hoverintent.html @@ -0,0 +1,133 @@ + + + + + jQuery UI Accordion - Open on hoverintent + + + + + + + + + + +
    +

    Section 1

    +
    +

    + Mauris mauris ante, blandit et, ultrices a, suscipit eget, quam. Integer + ut neque. Vivamus nisi metus, molestie vel, gravida in, condimentum sit + amet, nunc. Nam a nibh. Donec suscipit eros. Nam mi. Proin viverra leo ut + odio. Curabitur malesuada. Vestibulum a velit eu ante scelerisque vulputate. +

    +
    +

    Section 2

    +
    +

    + Sed non urna. Donec et ante. Phasellus eu ligula. Vestibulum sit amet + purus. Vivamus hendrerit, dolor at aliquet laoreet, mauris turpis porttitor + velit, faucibus interdum tellus libero ac justo. Vivamus non quam. In + suscipit faucibus urna. +

    +
    +

    Section 3

    +
    +

    + Nam enim risus, molestie et, porta ac, aliquam ac, risus. Quisque lobortis. + Phasellus pellentesque purus in massa. Aenean in pede. Phasellus ac libero + ac tellus pellentesque semper. Sed ac felis. Sed commodo, magna quis + lacinia ornare, quam ante aliquam nisi, eu iaculis leo purus venenatis dui. +

    +
      +
    • List item one
    • +
    • List item two
    • +
    • List item three
    • +
    +
    +

    Section 4

    +
    +

    + Cras dictum. Pellentesque habitant morbi tristique senectus et netus + et malesuada fames ac turpis egestas. Vestibulum ante ipsum primis in + faucibus orci luctus et ultrices posuere cubilia Curae; Aenean lacinia + mauris vel est. +

    +

    + Suspendisse eu nisl. Nullam ut libero. Integer dignissim consequat lectus. + Class aptent taciti sociosqu ad litora torquent per conubia nostra, per + inceptos himenaeos. +

    +
    +
    + +
    +

    +Click headers to expand/collapse content that is broken into logical sections, much like tabs. +Optionally, toggle sections open/closed on mouseover. +

    +

    +The underlying HTML markup is a series of headers (H3 tags) and content divs so the content is +usable without JavaScript. +

    +
    + + diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/accordion/index.html b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/accordion/index.html new file mode 100755 index 000000000..92bd33d9b --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/accordion/index.html @@ -0,0 +1,20 @@ + + + + + jQuery UI Accordion Demos + + + + + + + diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/accordion/no-auto-height.html b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/accordion/no-auto-height.html new file mode 100755 index 000000000..a6356413a --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/accordion/no-auto-height.html @@ -0,0 +1,50 @@ + + + + + jQuery UI Accordion - No auto height + + + + + + + + + + +
    +

    Section 1

    +
    +

    Mauris mauris ante, blandit et, ultrices a, susceros. Nam mi. Proin viverra leo ut odio. Curabitur malesuada. Vestibulum a velit eu ante scelerisque vulputate.

    +
    +

    Section 2

    +
    +

    Sed non urna. Donec et ante. Phasellus eu ligula. Vestibulum sit amet purus. Vivamus hendrerit, dolor at aliquet laoreet, mauris turpis porttitor velit, faucibus interdum tellus libero ac justo. Vivamus non quam. In suscipit faucibus urna.

    +
    +

    Section 3

    +
    +

    Nam enim risus, molestie et, porta ac, aliquam ac, risus. Quisque lobortis. Phasellus pellentesque purus in massa. Aenean in pede. Phasellus ac libero ac tellus pellentesque semper. Sed ac felis. Sed commodo, magna quis lacinia ornare, quam ante aliquam nisi, eu iaculis leo purus venenatis dui.

    +
      +
    • List item
    • +
    • List item
    • +
    • List item
    • +
    • List item
    • +
    • List item
    • +
    • List item
    • +
    • List item
    • +
    +
    +
    + +
    +

    Setting heightStyle: "content" allows the accordion panels to keep their native height.

    +
    + + diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/accordion/sortable.html b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/accordion/sortable.html new file mode 100755 index 000000000..70841b3f2 --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/accordion/sortable.html @@ -0,0 +1,74 @@ + + + + + jQuery UI Accordion - Sortable + + + + + + + + + + + + + +
    +
    +

    Section 1

    +
    +

    Mauris mauris ante, blandit et, ultrices a, suscipit eget, quam. Integer ut neque. Vivamus nisi metus, molestie vel, gravida in, condimentum sit amet, nunc. Nam a nibh. Donec suscipit eros. Nam mi. Proin viverra leo ut odio. Curabitur malesuada. Vestibulum a velit eu ante scelerisque vulputate.

    +
    +
    +
    +

    Section 2

    +
    +

    Sed non urna. Donec et ante. Phasellus eu ligula. Vestibulum sit amet purus. Vivamus hendrerit, dolor at aliquet laoreet, mauris turpis porttitor velit, faucibus interdum tellus libero ac justo. Vivamus non quam. In suscipit faucibus urna.

    +
    +
    +
    +

    Section 3

    +
    +

    Nam enim risus, molestie et, porta ac, aliquam ac, risus. Quisque lobortis. Phasellus pellentesque purus in massa. Aenean in pede. Phasellus ac libero ac tellus pellentesque semper. Sed ac felis. Sed commodo, magna quis lacinia ornare, quam ante aliquam nisi, eu iaculis leo purus venenatis dui.

    +
      +
    • List item one
    • +
    • List item two
    • +
    • List item three
    • +
    +
    +
    +
    +

    Section 4

    +
    +

    Cras dictum. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Aenean lacinia mauris vel est.

    Suspendisse eu nisl. Nullam ut libero. Integer dignissim consequat lectus. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos.

    +
    +
    +
    + +
    +

    Drag the header to re-order panels.

    +
    + + diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/autocomplete/categories.html b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/autocomplete/categories.html new file mode 100755 index 000000000..842ebfa8a --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/autocomplete/categories.html @@ -0,0 +1,67 @@ + + + + + jQuery UI Autocomplete - Categories + + + + + + + + + + + + + + + + + +
    +

    A categorized search result. Try typing "a" or "n".

    +
    + + diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/autocomplete/combobox.html b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/autocomplete/combobox.html new file mode 100755 index 000000000..cc43f4527 --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/autocomplete/combobox.html @@ -0,0 +1,211 @@ + + + + + jQuery UI Autocomplete - Combobox + + + + + + + + + + + + + + + +
    + + +
    + + +
    +

    A custom widget built by composition of Autocomplete and Button. You can either type something into the field to get filtered suggestions based on your input, or use the button to get the full list of selections.

    +

    The input is read from an existing select-element for progressive enhancement, passed to Autocomplete with a customized source-option.

    +

    This is not a supported or even complete widget. Its purely for demoing what autocomplete can do with a bit of customization. For a detailed explanation of how the widget works, check out this Learning jQuery article.

    +
    + + diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/autocomplete/custom-data.html b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/autocomplete/custom-data.html new file mode 100755 index 000000000..1e64df047 --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/autocomplete/custom-data.html @@ -0,0 +1,91 @@ + + + + + jQuery UI Autocomplete - Custom data and display + + + + + + + + + + + + + +
    Select a project (type "j" for a start):
    + + + +

    + +
    +

    You can use your own custom data formats and displays by simply overriding the default focus and select actions.

    +

    Try typing "j" to get a list of projects or just press the down arrow.

    +
    + + diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/autocomplete/default.html b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/autocomplete/default.html new file mode 100755 index 000000000..3f996598a --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/autocomplete/default.html @@ -0,0 +1,58 @@ + + + + + jQuery UI Autocomplete - Default functionality + + + + + + + + + + + + +
    + + +
    + +
    +

    The Autocomplete widgets provides suggestions while you type into the field. Here the suggestions are tags for programming languages, give "ja" (for Java or JavaScript) a try.

    +

    The datasource is a simple JavaScript array, provided to the widget using the source-option.

    +
    + + diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/autocomplete/folding.html b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/autocomplete/folding.html new file mode 100755 index 000000000..43b6620c8 --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/autocomplete/folding.html @@ -0,0 +1,56 @@ + + + + + jQuery UI Autocomplete - Accent folding + + + + + + + + + + + + +
    +
    + + +
    +
    + +
    +

    The autocomplete field uses a custom source option which will match results that have accented characters even when the text field doesn't contain accented characters. However if the you type in accented characters in the text field it is smart enough not to show results that aren't accented.

    +

    Try typing "Jo" to see "John" and "Jörn", then type "Jö" to see only "Jörn".

    +
    + + diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/autocomplete/images/jquery_32x32.png b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/autocomplete/images/jquery_32x32.png new file mode 100755 index 000000000..9312f02d5 Binary files /dev/null and b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/autocomplete/images/jquery_32x32.png differ diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/autocomplete/images/jqueryui_32x32.png b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/autocomplete/images/jqueryui_32x32.png new file mode 100755 index 000000000..e003d16c1 Binary files /dev/null and b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/autocomplete/images/jqueryui_32x32.png differ diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/autocomplete/images/sizzlejs_32x32.png b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/autocomplete/images/sizzlejs_32x32.png new file mode 100755 index 000000000..4ce0704d1 Binary files /dev/null and b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/autocomplete/images/sizzlejs_32x32.png differ diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/autocomplete/images/transparent_1x1.png b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/autocomplete/images/transparent_1x1.png new file mode 100755 index 000000000..c2da5b889 Binary files /dev/null and b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/autocomplete/images/transparent_1x1.png differ diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/autocomplete/images/ui-anim_basic_16x16.gif b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/autocomplete/images/ui-anim_basic_16x16.gif new file mode 100755 index 000000000..084ecb879 Binary files /dev/null and b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/autocomplete/images/ui-anim_basic_16x16.gif differ diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/autocomplete/index.html b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/autocomplete/index.html new file mode 100755 index 000000000..faa18d438 --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/autocomplete/index.html @@ -0,0 +1,25 @@ + + + + + jQuery UI Autocomplete Demos + + + + + + + diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/autocomplete/london.xml b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/autocomplete/london.xml new file mode 100755 index 000000000..262854998 --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/autocomplete/london.xml @@ -0,0 +1,114 @@ + + +6987 + +London +51.5084152563931 +-0.125532746315002 +2643743 +GB +United Kingdom + +P +PPLC + + +London +42.983389283 +-81.233042387 +6058560 +CA +Canada + +P +PPL + + +East London +-33.0152850934643 +27.9116249084473 +1006984 +ZA +South Africa + +P +PPL + + +City +51.5133363996235 +-0.0890064239501953 +2643744 +GB +United Kingdom + +A +ADM2 + + +London +37.1289771 +-84.0832646 +4298960 +US +United States + +P +PPL + + +The Tower of London +51.5082349601834 +-0.0763034820556641 +6286786 +GB +United Kingdom + +S +CSTL + + +London Reefs +8.85 +112.5333333 +1879967 + + + +U +RFSU + + +Greater London +51.5 +-0.1666667 +2648110 +GB +United Kingdom + +A +ADM2 + + +London +46.1666667 +6.0166667 +2661811 +CH +Switzerland + +H +STM + + +London Borough of Islington +51.5333333 +-0.1333333 +3333156 +GB +United Kingdom + +A +ADM2 + + diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/autocomplete/maxheight.html b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/autocomplete/maxheight.html new file mode 100755 index 000000000..4c5e8e4c9 --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/autocomplete/maxheight.html @@ -0,0 +1,71 @@ + + + + + jQuery UI Autocomplete - Scrollable results + + + + + + + + + + + + + +
    + + +
    + +
    +

    When displaying a long list of options, you can simply set the max-height for the autocomplete menu to prevent the menu from growing too large. Try typing "a" or "s" above to get a long list of results that you can scroll through.

    +
    + + diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/autocomplete/multiple-remote.html b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/autocomplete/multiple-remote.html new file mode 100755 index 000000000..5b901db0f --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/autocomplete/multiple-remote.html @@ -0,0 +1,80 @@ + + + + + jQuery UI Autocomplete - Multiple, remote + + + + + + + + + + + + + +
    + + +
    + +
    +

    Usage: Enter at least two characters to get bird name suggestions. Select a value to continue adding more names.

    +

    This is an example showing how to use the source-option along with some events to enable autocompleting multiple values into a single field.

    +
    + + diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/autocomplete/multiple.html b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/autocomplete/multiple.html new file mode 100755 index 000000000..4fbb45722 --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/autocomplete/multiple.html @@ -0,0 +1,93 @@ + + + + + jQuery UI Autocomplete - Multiple values + + + + + + + + + + + + +
    + + +
    + +
    +

    Usage: Type something, eg. "j" to see suggestions for tagging with programming languages. Select a value, then continue typing to add more.

    +

    This is an example showing how to use the source-option along with some events to enable autocompleting multiple values into a single field.

    +
    + + diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/autocomplete/remote-jsonp.html b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/autocomplete/remote-jsonp.html new file mode 100755 index 000000000..9f23815bb --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/autocomplete/remote-jsonp.html @@ -0,0 +1,82 @@ + + + + + jQuery UI Autocomplete - Remote JSONP datasource + + + + + + + + + + + + + +
    + + + Powered by geonames.org +
    + +
    + Result: +
    +
    + +
    +

    The Autocomplete widgets provides suggestions while you type into the field. Here the suggestions are cities, displayed when at least two characters are entered into the field.

    +

    In this case, the datasource is the geonames.org webservice. While only the city name itself ends up in the input after selecting an element, more info is displayed in the suggestions to help find the right entry. That data is also available in callbacks, as illustrated by the Result area below the input.

    +
    + + diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/autocomplete/remote-with-cache.html b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/autocomplete/remote-with-cache.html new file mode 100755 index 000000000..bc1de7746 --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/autocomplete/remote-with-cache.html @@ -0,0 +1,52 @@ + + + + + jQuery UI Autocomplete - Remote with caching + + + + + + + + + + + + + +
    + + +
    + +
    +

    The Autocomplete widgets provides suggestions while you type into the field. Here the suggestions are bird names, displayed when at least two characters are entered into the field.

    +

    Similar to the remote datasource demo, though this adds some local caching to improve performance. The cache here saves just one query, and could be extended to cache multiple values, one for each term.

    +
    + + diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/autocomplete/remote.html b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/autocomplete/remote.html new file mode 100755 index 000000000..56863a8d8 --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/autocomplete/remote.html @@ -0,0 +1,55 @@ + + + + + jQuery UI Autocomplete - Remote datasource + + + + + + + + + + + + + +
    + + +
    + +
    + Result: +
    +
    + +
    +

    The Autocomplete widgets provides suggestions while you type into the field. Here the suggestions are bird names, displayed when at least two characters are entered into the field.

    +

    The datasource is a server-side script which returns JSON data, specified via a simple URL for the source-option. In addition, the minLength-option is set to 2 to avoid queries that would return too many results and the select-event is used to display some feedback.

    +
    + + diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/autocomplete/search.php b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/autocomplete/search.php new file mode 100755 index 000000000..835772dee --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/autocomplete/search.php @@ -0,0 +1,590 @@ +"Botaurus stellaris", +"Little Grebe"=>"Tachybaptus ruficollis", +"Black-necked Grebe"=>"Podiceps nigricollis", +"Little Bittern"=>"Ixobrychus minutus", +"Black-crowned Night Heron"=>"Nycticorax nycticorax", +"Purple Heron"=>"Ardea purpurea", +"White Stork"=>"Ciconia ciconia", +"Spoonbill"=>"Platalea leucorodia", +"Red-crested Pochard"=>"Netta rufina", +"Common Eider"=>"Somateria mollissima", +"Red Kite"=>"Milvus milvus", +"Hen Harrier"=>"Circus cyaneus", +"Montagu`s Harrier"=>"Circus pygargus", +"Black Grouse"=>"Tetrao tetrix", +"Grey Partridge"=>"Perdix perdix", +"Spotted Crake"=>"Porzana porzana", +"Corncrake"=>"Crex crex", +"Common Crane"=>"Grus grus", +"Avocet"=>"Recurvirostra avosetta", +"Stone Curlew"=>"Burhinus oedicnemus", +"Common Ringed Plover"=>"Charadrius hiaticula", +"Kentish Plover"=>"Charadrius alexandrinus", +"Ruff"=>"Philomachus pugnax", +"Common Snipe"=>"Gallinago gallinago", +"Black-tailed Godwit"=>"Limosa limosa", +"Common Redshank"=>"Tringa totanus", +"Sandwich Tern"=>"Sterna sandvicensis", +"Common Tern"=>"Sterna hirundo", +"Arctic Tern"=>"Sterna paradisaea", +"Little Tern"=>"Sternula albifrons", +"Black Tern"=>"Chlidonias niger", +"Barn Owl"=>"Tyto alba", +"Little Owl"=>"Athene noctua", +"Short-eared Owl"=>"Asio flammeus", +"European Nightjar"=>"Caprimulgus europaeus", +"Common Kingfisher"=>"Alcedo atthis", +"Eurasian Hoopoe"=>"Upupa epops", +"Eurasian Wryneck"=>"Jynx torquilla", +"European Green Woodpecker"=>"Picus viridis", +"Crested Lark"=>"Galerida cristata", +"White-headed Duck"=>"Oxyura leucocephala", +"Pale-bellied Brent Goose"=>"Branta hrota", +"Tawny Pipit"=>"Anthus campestris", +"Whinchat"=>"Saxicola rubetra", +"European Stonechat"=>"Saxicola rubicola", +"Northern Wheatear"=>"Oenanthe oenanthe", +"Savi`s Warbler"=>"Locustella luscinioides", +"Sedge Warbler"=>"Acrocephalus schoenobaenus", +"Great Reed Warbler"=>"Acrocephalus arundinaceus", +"Bearded Reedling"=>"Panurus biarmicus", +"Red-backed Shrike"=>"Lanius collurio", +"Great Grey Shrike"=>"Lanius excubitor", +"Woodchat Shrike"=>"Lanius senator", +"Common Raven"=>"Corvus corax", +"Yellowhammer"=>"Emberiza citrinella", +"Ortolan Bunting"=>"Emberiza hortulana", +"Corn Bunting"=>"Emberiza calandra", +"Great Cormorant"=>"Phalacrocorax carbo", +"Hawfinch"=>"Coccothraustes coccothraustes", +"Common Shelduck"=>"Tadorna tadorna", +"Bluethroat"=>"Luscinia svecica", +"Grey Heron"=>"Ardea cinerea", +"Barn Swallow"=>"Hirundo rustica", +"Hooded Crow"=>"Corvus cornix", +"Dunlin"=>"Calidris alpina", +"Eurasian Pied Flycatcher"=>"Ficedula hypoleuca", +"Eurasian Nuthatch"=>"Sitta europaea", +"Short-toed Tree Creeper"=>"Certhia brachydactyla", +"Wood Lark"=>"Lullula arborea", +"Tree Pipit"=>"Anthus trivialis", +"Eurasian Hobby"=>"Falco subbuteo", +"Marsh Warbler"=>"Acrocephalus palustris", +"Wood Sandpiper"=>"Tringa glareola", +"Tawny Owl"=>"Strix aluco", +"Lesser Whitethroat"=>"Sylvia curruca", +"Barnacle Goose"=>"Branta leucopsis", +"Common Goldeneye"=>"Bucephala clangula", +"Western Marsh Harrier"=>"Circus aeruginosus", +"Common Buzzard"=>"Buteo buteo", +"Sanderling"=>"Calidris alba", +"Little Gull"=>"Larus minutus", +"Eurasian Magpie"=>"Pica pica", +"Willow Warbler"=>"Phylloscopus trochilus", +"Wood Warbler"=>"Phylloscopus sibilatrix", +"Great Crested Grebe"=>"Podiceps cristatus", +"Eurasian Jay"=>"Garrulus glandarius", +"Common Redstart"=>"Phoenicurus phoenicurus", +"Blue-headed Wagtail"=>"Motacilla flava", +"Common Swift"=>"Apus apus", +"Marsh Tit"=>"Poecile palustris", +"Goldcrest"=>"Regulus regulus", +"European Golden Plover"=>"Pluvialis apricaria", +"Eurasian Bullfinch"=>"Pyrrhula pyrrhula", +"Common Whitethroat"=>"Sylvia communis", +"Meadow Pipit"=>"Anthus pratensis", +"Greylag Goose"=>"Anser anser", +"Spotted Flycatcher"=>"Muscicapa striata", +"European Greenfinch"=>"Carduelis chloris", +"Common Greenshank"=>"Tringa nebularia", +"Great Spotted Woodpecker"=>"Dendrocopos major", +"Greater Canada Goose"=>"Branta canadensis", +"Mistle Thrush"=>"Turdus viscivorus", +"Great Black-backed Gull"=>"Larus marinus", +"Goosander"=>"Mergus merganser", +"Great Egret"=>"Casmerodius albus", +"Northern Goshawk"=>"Accipiter gentilis", +"Dunnock"=>"Prunella modularis", +"Stock Dove"=>"Columba oenas", +"Common Wood Pigeon"=>"Columba palumbus", +"Eurasian Woodcock"=>"Scolopax rusticola", +"House Sparrow"=>"Passer domesticus", +"Common House Martin"=>"Delichon urbicum", +"Red Knot"=>"Calidris canutus", +"Western Jackdaw"=>"Corvus monedula", +"Brambling"=>"Fringilla montifringilla", +"Northern Lapwing"=>"Vanellus vanellus", +"European Reed Warbler"=>"Acrocephalus scirpaceus", +"Lesser Black-backed Gull"=>"Larus fuscus", +"Little Egret"=>"Egretta garzetta", +"Little Stint"=>"Calidris minuta", +"Common Linnet"=>"Carduelis cannabina", +"Mute Swan"=>"Cygnus olor", +"Common Cuckoo"=>"Cuculus canorus", +"Black-headed Gull"=>"Larus ridibundus", +"Greater White-fronted Goose"=>"Anser albifrons", +"Great Tit"=>"Parus major", +"Redwing"=>"Turdus iliacus", +"Gadwall"=>"Anas strepera", +"Fieldfare"=>"Turdus pilaris", +"Tufted Duck"=>"Aythya fuligula", +"Crested Tit"=>"Lophophanes cristatus", +"Willow Tit"=>"Poecile montanus", +"Eurasian Coot"=>"Fulica atra", +"Common Blackbird"=>"Turdus merula", +"Smew"=>"Mergus albellus", +"Common Sandpiper"=>"Actitis hypoleucos", +"Sand Martin"=>"Riparia riparia", +"Purple Sandpiper"=>"Calidris maritima", +"Northern Pintail"=>"Anas acuta", +"Blue Tit"=>"Cyanistes caeruleus", +"European Goldfinch"=>"Carduelis carduelis", +"Eurasian Whimbrel"=>"Numenius phaeopus", +"Common Reed Bunting"=>"Emberiza schoeniclus", +"Eurasian Tree Sparrow"=>"Passer montanus", +"Rook"=>"Corvus frugilegus", +"European Robin"=>"Erithacus rubecula", +"Bar-tailed Godwit"=>"Limosa lapponica", +"Dark-bellied Brent Goose"=>"Branta bernicla", +"Eurasian Oystercatcher"=>"Haematopus ostralegus", +"Eurasian Siskin"=>"Carduelis spinus", +"Northern Shoveler"=>"Anas clypeata", +"Eurasian Wigeon"=>"Anas penelope", +"Eurasian Sparrow Hawk"=>"Accipiter nisus", +"Icterine Warbler"=>"Hippolais icterina", +"Common Starling"=>"Sturnus vulgaris", +"Long-tailed Tit"=>"Aegithalos caudatus", +"Ruddy Turnstone"=>"Arenaria interpres", +"Mew Gull"=>"Larus canus", +"Common Pochard"=>"Aythya ferina", +"Common Chiffchaff"=>"Phylloscopus collybita", +"Greater Scaup"=>"Aythya marila", +"Common Kestrel"=>"Falco tinnunculus", +"Garden Warbler"=>"Sylvia borin", +"Eurasian Collared Dove"=>"Streptopelia decaocto", +"Eurasian Skylark"=>"Alauda arvensis", +"Common Chaffinch"=>"Fringilla coelebs", +"Common Moorhen"=>"Gallinula chloropus", +"Water Pipit"=>"Anthus spinoletta", +"Mallard"=>"Anas platyrhynchos", +"Winter Wren"=>"Troglodytes troglodytes", +"Common Teal"=>"Anas crecca", +"Green Sandpiper"=>"Tringa ochropus", +"White Wagtail"=>"Motacilla alba", +"Eurasian Curlew"=>"Numenius arquata", +"Song Thrush"=>"Turdus philomelos", +"European Herring Gull"=>"Larus argentatus", +"Grey Plover"=>"Pluvialis squatarola", +"Carrion Crow"=>"Corvus corone", +"Coal Tit"=>"Periparus ater", +"Spotted Redshank"=>"Tringa erythropus", +"Blackcap"=>"Sylvia atricapilla", +"Egyptian Vulture"=>"Neophron percnopterus", +"Razorbill"=>"Alca torda", +"Alpine Swift"=>"Apus melba", +"Long-legged Buzzard"=>"Buteo rufinus", +"Audouin`s Gull"=>"Larus audouinii", +"Balearic Shearwater"=>"Puffinus mauretanicus", +"Upland Sandpiper"=>"Bartramia longicauda", +"Greater Spotted Eagle"=>"Aquila clanga", +"Ring Ouzel"=>"Turdus torquatus", +"Yellow-browed Warbler"=>"Phylloscopus inornatus", +"Blue Rock Thrush"=>"Monticola solitarius", +"Buff-breasted Sandpiper"=>"Tryngites subruficollis", +"Jack Snipe"=>"Lymnocryptes minimus", +"White-rumped Sandpiper"=>"Calidris fuscicollis", +"Ruddy Shelduck"=>"Tadorna ferruginea", +"Cetti's Warbler"=>"Cettia cetti", +"Citrine Wagtail"=>"Motacilla citreola", +"Roseate Tern"=>"Sterna dougallii", +"Black-legged Kittiwake"=>"Rissa tridactyla", +"Pygmy Cormorant"=>"Phalacrocorax pygmeus", +"Booted Eagle"=>"Aquila pennata", +"Lesser White-fronted Goose"=>"Anser erythropus", +"Little Bunting"=>"Emberiza pusilla", +"Eleonora's Falcon"=>"Falco eleonorae", +"European Serin"=>"Serinus serinus", +"Twite"=>"Carduelis flavirostris", +"Yellow-legged Gull"=>"Larus michahellis", +"Gyr Falcon"=>"Falco rusticolus", +"Greenish Warbler"=>"Phylloscopus trochiloides", +"Red-necked Phalarope"=>"Phalaropus lobatus", +"Mealy Redpoll"=>"Carduelis flammea", +"Glaucous Gull"=>"Larus hyperboreus", +"Great Skua"=>"Stercorarius skua", +"Great Bustard"=>"Otis tarda", +"Velvet Scoter"=>"Melanitta fusca", +"Pine Grosbeak"=>"Pinicola enucleator", +"House Crow"=>"Corvus splendens", +"Hume`s Leaf Warbler"=>"Phylloscopus humei", +"Great Northern Loon"=>"Gavia immer", +"Long-tailed Duck"=>"Clangula hyemalis", +"Lapland Longspur"=>"Calcarius lapponicus", +"Northern Gannet"=>"Morus bassanus", +"Eastern Imperial Eagle"=>"Aquila heliaca", +"Little Auk"=>"Alle alle", +"Lesser Spotted Woodpecker"=>"Dendrocopos minor", +"Iceland Gull"=>"Larus glaucoides", +"Parasitic Jaeger"=>"Stercorarius parasiticus", +"Bewick`s Swan"=>"Cygnus bewickii", +"Little Bustard"=>"Tetrax tetrax", +"Little Crake"=>"Porzana parva", +"Baillon`s Crake"=>"Porzana pusilla", +"Long-tailed Jaeger"=>"Stercorarius longicaudus", +"King Eider"=>"Somateria spectabilis", +"Greater Short-toed Lark"=>"Calandrella brachydactyla", +"Houbara Bustard"=>"Chlamydotis undulata", +"Curlew Sandpiper"=>"Calidris ferruginea", +"Common Crossbill"=>"Loxia curvirostra", +"European Shag"=>"Phalacrocorax aristotelis", +"Horned Grebe"=>"Podiceps auritus", +"Common Quail"=>"Coturnix coturnix", +"Bearded Vulture"=>"Gypaetus barbatus", +"Lanner Falcon"=>"Falco biarmicus", +"Middle Spotted Woodpecker"=>"Dendrocopos medius", +"Pomarine Jaeger"=>"Stercorarius pomarinus", +"Red-breasted Merganser"=>"Mergus serrator", +"Eurasian Black Vulture"=>"Aegypius monachus", +"Eurasian Dotterel"=>"Charadrius morinellus", +"Common Nightingale"=>"Luscinia megarhynchos", +"Northern willow warbler"=>"Phylloscopus trochilus acredula", +"Manx Shearwater"=>"Puffinus puffinus", +"Northern Fulmar"=>"Fulmarus glacialis", +"Eurasian Eagle Owl"=>"Bubo bubo", +"Orphean Warbler"=>"Sylvia hortensis", +"Melodious Warbler"=>"Hippolais polyglotta", +"Pallas's Leaf Warbler"=>"Phylloscopus proregulus", +"Atlantic Puffin"=>"Fratercula arctica", +"Black-throated Loon"=>"Gavia arctica", +"Bohemian Waxwing"=>"Bombycilla garrulus", +"Marsh Sandpiper"=>"Tringa stagnatilis", +"Great Snipe"=>"Gallinago media", +"Squacco Heron"=>"Ardeola ralloides", +"Long-eared Owl"=>"Asio otus", +"Caspian Tern"=>"Hydroprogne caspia", +"Red-breasted Goose"=>"Branta ruficollis", +"Red-throated Loon"=>"Gavia stellata", +"Common Rosefinch"=>"Carpodacus erythrinus", +"Red-footed Falcon"=>"Falco vespertinus", +"Ross's Goose"=>"Anser rossii", +"Red Phalarope"=>"Phalaropus fulicarius", +"Pied Wagtail"=>"Motacilla yarrellii", +"Rose-coloured Starling"=>"Sturnus roseus", +"Rough-legged Buzzard"=>"Buteo lagopus", +"Saker Falcon"=>"Falco cherrug", +"European Roller"=>"Coracias garrulus", +"Short-toed Eagle"=>"Circaetus gallicus", +"Peregrine Falcon"=>"Falco peregrinus", +"Merlin"=>"Falco columbarius", +"Snow Goose"=>"Anser caerulescens", +"Snowy Owl"=>"Bubo scandiacus", +"Snow Bunting"=>"Plectrophenax nivalis", +"Common Grasshopper Warbler"=>"Locustella naevia", +"Golden Eagle"=>"Aquila chrysaetos", +"Black-winged Stilt"=>"Himantopus himantopus", +"Steppe Eagle"=>"Aquila nipalensis", +"Pallid Harrier"=>"Circus macrourus", +"European Storm-petrel"=>"Hydrobates pelagicus", +"Horned Lark"=>"Eremophila alpestris", +"Eurasian Treecreeper"=>"Certhia familiaris", +"Taiga Bean Goose"=>"Anser fabalis", +"Temminck`s Stint"=>"Calidris temminckii", +"Terek Sandpiper"=>"Xenus cinereus", +"Tundra Bean Goose"=>"Anser serrirostris", +"European Turtle Dove"=>"Streptopelia turtur", +"Leach`s Storm-petrel"=>"Oceanodroma leucorhoa", +"Eurasian Griffon Vulture"=>"Gyps fulvus", +"Paddyfield Warbler"=>"Acrocephalus agricola", +"Osprey"=>"Pandion haliaetus", +"Firecrest"=>"Regulus ignicapilla", +"Water Rail"=>"Rallus aquaticus", +"European Honey Buzzard"=>"Pernis apivorus", +"Eurasian Golden Oriole"=>"Oriolus oriolus", +"Whooper Swan"=>"Cygnus cygnus", +"Two-barred Crossbill"=>"Loxia leucoptera", +"White-tailed Eagle"=>"Haliaeetus albicilla", +"Atlantic Murre"=>"Uria aalge", +"Garganey"=>"Anas querquedula", +"Black Redstart"=>"Phoenicurus ochruros", +"Common Scoter"=>"Melanitta nigra", +"Rock Pipit"=>"Anthus petrosus", +"Lesser Spotted Eagle"=>"Aquila pomarina", +"Cattle Egret"=>"Bubulcus ibis", +"White-winged Black Tern"=>"Chlidonias leucopterus", +"Black Stork"=>"Ciconia nigra", +"Mediterranean Gull"=>"Larus melanocephalus", +"Black Kite"=>"Milvus migrans", +"Yellow Wagtail"=>"Motacilla flavissima", +"Red-necked Grebe"=>"Podiceps grisegena", +"Gull-billed Tern"=>"Gelochelidon nilotica", +"Pectoral Sandpiper"=>"Calidris melanotos", +"Barred Warbler"=>"Sylvia nisoria", +"Red-throated Pipit"=>"Anthus cervinus", +"Grey Wagtail"=>"Motacilla cinerea", +"Richard`s Pipit"=>"Anthus richardi", +"Black Woodpecker"=>"Dryocopus martius", +"Little Ringed Plover"=>"Charadrius dubius", +"Whiskered Tern"=>"Chlidonias hybrida", +"Lesser Redpoll"=>"Carduelis cabaret", +"Pallas' Bunting"=>"Emberiza pallasi", +"Ferruginous Duck"=>"Aythya nyroca", +"Whistling Swan"=>"Cygnus columbianus", +"Black Brant"=>"Branta nigricans", +"Marbled Teal"=>"Marmaronetta angustirostris", +"Canvasback"=>"Aythya valisineria", +"Redhead"=>"Aythya americana", +"Lesser Scaup"=>"Aythya affinis", +"Steller`s Eider"=>"Polysticta stelleri", +"Spectacled Eider"=>"Somateria fischeri", +"Harlequin Duck"=>"Histronicus histrionicus", +"Black Scoter"=>"Melanitta americana", +"Surf Scoter"=>"Melanitta perspicillata", +"Barrow`s Goldeneye"=>"Bucephala islandica", +"Falcated Duck"=>"Anas falcata", +"American Wigeon"=>"Anas americana", +"Blue-winged Teal"=>"Anas discors", +"American Black Duck"=>"Anas rubripes", +"Baikal Teal"=>"Anas formosa", +"Green-Winged Teal"=>"Anas carolinensis", +"Hazel Grouse"=>"Bonasa bonasia", +"Rock Partridge"=>"Alectoris graeca", +"Red-legged Partridge"=>"Alectoris rufa", +"Yellow-billed Loon"=>"Gavia adamsii", +"Cory`s Shearwater"=>"Calonectris borealis", +"Madeiran Storm-Petrel"=>"Oceanodroma castro", +"Great White Pelican"=>"Pelecanus onocrotalus", +"Dalmatian Pelican"=>"Pelecanus crispus", +"American Bittern"=>"Botaurus lentiginosus", +"Glossy Ibis"=>"Plegadis falcinellus", +"Spanish Imperial Eagle"=>"Aquila adalberti", +"Lesser Kestrel"=>"Falco naumanni", +"Houbara Bustard"=>"Chlamydotis undulata", +"Crab-Plover"=>"Dromas ardeola", +"Cream-coloured Courser"=>"Cursorius cursor", +"Collared Pratincole"=>"Glareola pratincola", +"Black-winged Pratincole"=>"Glareola nordmanni", +"Killdeer"=>"Charadrius vociferus", +"Lesser Sand Plover"=>"Charadrius mongolus", +"Greater Sand Plover"=>"Charadrius leschenaultii", +"Caspian Plover"=>"Charadrius asiaticus", +"American Golden Plover"=>"Pluvialis dominica", +"Pacific Golden Plover"=>"Pluvialis fulva", +"Sharp-tailed Sandpiper"=>"Calidris acuminata", +"Broad-billed Sandpiper"=>"Limicola falcinellus", +"Spoon-Billed Sandpiper"=>"Eurynorhynchus pygmaeus", +"Short-Billed Dowitcher"=>"Limnodromus griseus", +"Long-billed Dowitcher"=>"Limnodromus scolopaceus", +"Hudsonian Godwit"=>"Limosa haemastica", +"Little Curlew"=>"Numenius minutus", +"Lesser Yellowlegs"=>"Tringa flavipes", +"Wilson`s Phalarope"=>"Phalaropus tricolor", +"Pallas`s Gull"=>"Larus ichthyaetus", +"Laughing Gull"=>"Larus atricilla", +"Franklin`s Gull"=>"Larus pipixcan", +"Bonaparte`s Gull"=>"Larus philadelphia", +"Ring-billed Gull"=>"Larus delawarensis", +"American Herring Gull"=>"Larus smithsonianus", +"Caspian Gull"=>"Larus cachinnans", +"Ivory Gull"=>"Pagophila eburnea", +"Royal Tern"=>"Sterna maxima", +"Brünnich`s Murre"=>"Uria lomvia", +"Crested Auklet"=>"Aethia cristatella", +"Parakeet Auklet"=>"Cyclorrhynchus psittacula", +"Tufted Puffin"=>"Lunda cirrhata", +"Laughing Dove"=>"Streptopelia senegalensis", +"Great Spotted Cuckoo"=>"Clamator glandarius", +"Great Grey Owl"=>"Strix nebulosa", +"Tengmalm`s Owl"=>"Aegolius funereus", +"Red-Necked Nightjar"=>"Caprimulgus ruficollis", +"Chimney Swift"=>"Chaetura pelagica", +"Green Bea-Eater"=>"Merops orientalis", +"Grey-headed Woodpecker"=>"Picus canus", +"Lesser Short-Toed Lark"=>"Calandrella rufescens", +"Eurasian Crag Martin"=>"Hirundo rupestris", +"Red-rumped Swallow"=>"Cecropis daurica", +"Blyth`s Pipit"=>"Anthus godlewskii", +"Pechora Pipit"=>"Anthus gustavi", +"Grey-headed Wagtail"=>"Motacilla thunbergi", +"Yellow-Headed Wagtail"=>"Motacilla lutea", +"White-throated Dipper"=>"Cinclus cinclus", +"Rufous-Tailed Scrub Robin"=>"Cercotrichas galactotes", +"Thrush Nightingale"=>"Luscinia luscinia", +"White-throated Robin"=>"Irania gutturalis", +"Caspian Stonechat"=>"Saxicola maura variegata", +"Western Black-eared Wheatear"=>"Oenanthe hispanica", +"Rufous-tailed Rock Thrush"=>"Monticola saxatilis", +"Red-throated Thrush/Black-throated"=>"Turdus ruficollis", +"American Robin"=>"Turdus migratorius", +"Zitting Cisticola"=>"Cisticola juncidis", +"Lanceolated Warbler"=>"Locustella lanceolata", +"River Warbler"=>"Locustella fluviatilis", +"Blyth`s Reed Warbler"=>"Acrocephalus dumetorum", +"Caspian Reed Warbler"=>"Acrocephalus fuscus", +"Aquatic Warbler"=>"Acrocephalus paludicola", +"Booted Warbler"=>"Acrocephalus caligatus", +"Marmora's Warbler"=>"Sylvia sarda", +"Dartford Warbler"=>"Sylvia undata", +"Subalpine Warbler"=>"Sylvia cantillans", +"Ménétries's Warbler"=>"Sylvia mystacea", +"Rüppel's Warbler"=>"Sylvia rueppelli", +"Asian Desert Warbler"=>"Sylvia nana", +"Western Orphean Warbler"=>"Sylvia hortensis hortensis", +"Arctic Warbler"=>"Phylloscopus borealis", +"Radde`s Warbler"=>"Phylloscopus schwarzi", +"Western Bonelli`s Warbler"=>"Phylloscopus bonelli", +"Red-breasted Flycatcher"=>"Ficedula parva", +"Eurasian Penduline Tit"=>"Remiz pendulinus", +"Daurian Shrike"=>"Lanius isabellinus", +"Long-Tailed Shrike"=>"Lanius schach", +"Lesser Grey Shrike"=>"Lanius minor", +"Southern Grey Shrike"=>"Lanius meridionalis", +"Masked Shrike"=>"Lanius nubicus", +"Spotted Nutcracker"=>"Nucifraga caryocatactes", +"Daurian Jackdaw"=>"Corvus dauuricus", +"Purple-Backed Starling"=>"Sturnus sturninus", +"Red-Fronted Serin"=>"Serinus pusillus", +"Arctic Redpoll"=>"Carduelis hornemanni", +"Scottish Crossbill"=>"Loxia scotica", +"Parrot Crossbill"=>"Loxia pytyopsittacus", +"Black-faced Bunting"=>"Emberiza spodocephala", +"Pink-footed Goose"=>"Anser brachyrhynchus", +"Black-winged Kite"=>"Elanus caeruleus", +"European Bee-eater"=>"Merops apiaster", +"Sabine`s Gull"=>"Larus sabini", +"Sooty Shearwater"=>"Puffinus griseus", +"Lesser Canada Goose"=>"Branta hutchinsii", +"Ring-necked Duck"=>"Aythya collaris", +"Greater Flamingo"=>"Phoenicopterus roseus", +"Iberian Chiffchaff"=>"Phylloscopus ibericus", +"Ashy-headed Wagtail"=>"Motacilla cinereocapilla", +"Stilt Sandpiper"=>"Calidris himantopus", +"Siberian Stonechat"=>"Saxicola maurus", +"Greater Yellowlegs"=>"Tringa melanoleuca", +"Forster`s Tern"=>"Sterna forsteri", +"Dusky Warbler"=>"Phylloscopus fuscatus", +"Cirl Bunting"=>"Emberiza cirlus", +"Olive-backed Pipit"=>"Anthus hodgsoni", +"Sociable Lapwing"=>"Vanellus gregarius", +"Spotted Sandpiper"=>"Actitis macularius", +"Baird`s Sandpiper"=>"Calidris bairdii", +"Rustic Bunting"=>"Emberiza rustica", +"Yellow-browed Bunting"=>"Emberiza chrysophrys", +"Great Shearwater"=>"Puffinus gravis", +"Bonelli`s Eagle"=>"Aquila fasciata", +"Calandra Lark"=>"Melanocorypha calandra", +"Sardinian Warbler"=>"Sylvia melanocephala", +"Ross's Gull"=>"Larus roseus", +"Yellow-Breasted Bunting"=>"Emberiza aureola", +"Pine Bunting"=>"Emberiza leucocephalos", +"Black Guillemot"=>"Cepphus grylle", +"Pied-billed Grebe"=>"Podilymbus podiceps", +"Soft-plumaged Petrel"=>"Pterodroma mollis", +"Bulwer's Petrel"=>"Bulweria bulwerii", +"White-Faced Storm-Petrel"=>"Pelagodroma marina", +"Pallas’s Fish Eagle"=>"Haliaeetus leucoryphus", +"Sandhill Crane"=>"Grus canadensis", +"Macqueen’s Bustard"=>"Chlamydotis macqueenii", +"White-tailed Lapwing"=>"Vanellus leucurus", +"Great Knot"=>"Calidris tenuirostris", +"Semipalmated Sandpiper"=>"Calidris pusilla", +"Red-necked Stint"=>"Calidris ruficollis", +"Slender-billed Curlew"=>"Numenius tenuirostris", +"Bridled Tern"=>"Onychoprion anaethetus", +"Pallas’s Sandgrouse"=>"Syrrhaptes paradoxus", +"European Scops Owl"=>"Otus scops", +"Northern Hawk Owl"=>"Surnia ulula", +"White-Throated Needletail"=>"Hirundapus caudacutus", +"Belted Kingfisher"=>"Ceryle alcyon", +"Blue-cheeked Bee-eater"=>"Merops persicus", +"Black-headed Wagtail"=>"Motacilla feldegg", +"Northern Mockingbird"=>"Mimus polyglottos", +"Alpine Accentor"=>"Prunella collaris", +"Red-flanked Bluetail"=>"Tarsiger cyanurus", +"Isabelline Wheatear"=>"Oenanthe isabellina", +"Pied Wheatear"=>"Oenanthe pleschanka", +"Eastern Black-eared Wheatear"=>"Oenanthe melanoleuca", +"Desert Wheatear"=>"Oenanthe deserti", +"White`s Thrush"=>"Zoothera aurea", +"Siberian Thrush"=>"Zoothera sibirica", +"Eyebrowed Thrush"=>"Turdus obscurus", +"Dusky Thrush"=>"Turdus eunomus", +"Black-throated Thrush"=>"Turdus atrogularis", +"Pallas`s Grasshopper Warbler"=>"Locustella certhiola", +"Spectacled Warbler"=>"Sylvia conspicillata", +"Two-barred Warbler"=>"Phylloscopus plumbeitarsus", +"Eastern Bonelli’s Warbler"=>"Phylloscopus orientalis", +"Collared Flycatcher"=>"Ficedula albicollis", +"Wallcreeper"=>"Tichodroma muraria", +"Turkestan Shrike"=>"Lanius phoenicuroides", +"Steppe Grey Shrike"=>"Lanius pallidirostris", +"Spanish Sparrow"=>"Passer hispaniolensis", +"Red-eyed Vireo"=>"Vireo olivaceus", +"Myrtle Warbler"=>"Dendroica coronata", +"White-crowned Sparrow"=>"Zonotrichia leucophrys", +"White-throated Sparrow"=>"Zonotrichia albicollis", +"Cretzschmar`s Bunting"=>"Emberiza caesia", +"Chestnut Bunting"=>"Emberiza rutila", +"Red-headed Bunting"=>"Emberiza bruniceps", +"Black-headed Bunting"=>"Emberiza melanocephala", +"Indigo Bunting"=>"Passerina cyanea", +"Balearic Woodchat Shrike"=>"Lanius senator badius", +"Demoiselle Crane"=>"Grus virgo", +"Chough"=>"Pyrrhocorax pyrrhocorax", +"Red-Billed Chough"=>"Pyrrhocorax graculus", +"Elegant Tern"=>"Sterna elegans", +"Chukar"=>"Alectoris chukar", +"Yellow-Billed Cuckoo"=>"Coccyzus americanus", +"American Sandwich Tern"=>"Sterna sandvicensis acuflavida", +"Olive-Tree Warbler"=>"Hippolais olivetorum", +"Eastern Olivaceous Warbler"=>"Acrocephalus pallidus", +"Indian Cormorant"=>"Phalacrocorax fuscicollis", +"Spur-Winged Lapwing"=>"Vanellus spinosus", +"Yelkouan Shearwater"=>"Puffinus yelkouan", +"Trumpeter Finch"=>"Bucanetes githagineus", +"Red Grouse"=>"Lagopus scoticus", +"Rock Ptarmigan"=>"Lagopus mutus", +"Long-Tailed Cormorant"=>"Phalacrocorax africanus", +"Double-crested Cormorant"=>"Phalacrocorax auritus", +"Magnificent Frigatebird"=>"Fregata magnificens", +"Naumann's Thrush"=>"Turdus naumanni", +"Oriental Pratincole"=>"Glareola maldivarum", +"Bufflehead"=>"Bucephala albeola", +"Snowfinch"=>"Montifrigilla nivalis", +"Ural owl"=>"Strix uralensis", +"Spanish Wagtail"=>"Motacilla iberiae", +"Song Sparrow"=>"Melospiza melodia", +"Rock Bunting"=>"Emberiza cia", +"Siberian Rubythroat"=>"Luscinia calliope", +"Pallid Swift"=>"Apus pallidus", +"Eurasian Pygmy Owl"=>"Glaucidium passerinum", +"Madeira Little Shearwater"=>"Puffinus baroli", +"House Finch"=>"Carpodacus mexicanus", +"Green Heron"=>"Butorides virescens", +"Solitary Sandpiper"=>"Tringa solitaria", +"Heuglin's Gull"=>"Larus heuglini" +); + + +$result = array(); +foreach ($items as $key=>$value) { + if (strpos(strtolower($key), $q) !== false) { + array_push($result, array("id"=>$value, "label"=>$key, "value" => strip_tags($key))); + } + if (count($result) > 11) + break; +} + +// json_encode is available in PHP 5.2 and above, or you can install a PECL module in earlier versions +echo json_encode($result); + +?> \ No newline at end of file diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/autocomplete/xml.html b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/autocomplete/xml.html new file mode 100755 index 000000000..059c33d67 --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/autocomplete/xml.html @@ -0,0 +1,66 @@ + + + + + jQuery UI Autocomplete - XML data parsed once + + + + + + + + + + + + + +
    + + +
    + +
    + Result: +
    +
    + +
    +

    This demo shows how to retrieve some XML data, parse it using jQuery's methods, then provide it to the autocomplete as the datasource.

    +

    This should also serve as a reference on how to parse a remote XML datasource - the parsing would just happen for each request within the source-callback.

    +
    + + diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/button/checkbox.html b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/button/checkbox.html new file mode 100755 index 000000000..4d597049a --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/button/checkbox.html @@ -0,0 +1,37 @@ + + + + + jQuery UI Button - Checkboxes + + + + + + + + + + + + + +
    + + + +
    + +
    +

    A checkbox is styled as a toggle button with the button widget. The label element associated with the checkbox is used for the button text.

    +

    This demo also demonstrates three checkboxes styled as a button set by calling .buttonset() on a common container.

    +
    + + diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/button/default.html b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/button/default.html new file mode 100755 index 000000000..2423aa1a2 --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/button/default.html @@ -0,0 +1,34 @@ + + + + + jQuery UI Button - Default functionality + + + + + + + + + + + + + + +An anchor + +
    +

    Examples of the markup that can be used for buttons: A button element, an input of type submit and an anchor.

    +
    + + diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/button/icons.html b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/button/icons.html new file mode 100755 index 000000000..8c4bf5a30 --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/button/icons.html @@ -0,0 +1,49 @@ + + + + + jQuery UI Button - Icons + + + + + + + + + + + + + + + +
    +

    Some buttons with various combinations of text and icons, here specified via metadata.

    +
    + + diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/button/index.html b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/button/index.html new file mode 100755 index 000000000..79560595b --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/button/index.html @@ -0,0 +1,19 @@ + + + + + jQuery UI Button Demos + + + + + + + diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/button/radio.html b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/button/radio.html new file mode 100755 index 000000000..763a50385 --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/button/radio.html @@ -0,0 +1,32 @@ + + + + + jQuery UI Button - Radios + + + + + + + + + + +
    +
    + + + +
    +
    + +
    +

    A set of three radio buttons transformed into a button set.

    +
    + + diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/button/splitbutton.html b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/button/splitbutton.html new file mode 100755 index 000000000..5b6493de5 --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/button/splitbutton.html @@ -0,0 +1,69 @@ + + + + + jQuery UI Button - Split button + + + + + + + + + + + + + +
    +
    + + +
    + +
    + +
    +

    An example of a split button built with two buttons: A plain button with just text, one with only a primary icon +and no text. Both are grouped together in a set.

    +
    + + diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/button/toolbar.html b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/button/toolbar.html new file mode 100755 index 000000000..342ac8401 --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/button/toolbar.html @@ -0,0 +1,113 @@ + + + + + jQuery UI Button - Toolbar + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    +

    + A mediaplayer toolbar. Take a look at the underlying markup: A few button elements, + an input of type checkbox for the Shuffle button, and three inputs of type radio for the Repeat options. +

    +
    + + diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/datepicker/alt-field.html b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/datepicker/alt-field.html new file mode 100755 index 000000000..2599cd145 --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/datepicker/alt-field.html @@ -0,0 +1,29 @@ + + + + + jQuery UI Datepicker - Populate alternate field + + + + + + + + + + +

    Date:  

    + +
    +

    Populate an alternate field with its own date format whenever a date is selected using the altField and altFormat options. This feature could be used to present a human-friendly date for user selection, while passing a more computer-friendly date through for further processing.

    +
    + + diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/datepicker/animation.html b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/datepicker/animation.html new file mode 100755 index 000000000..8e170ad8e --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/datepicker/animation.html @@ -0,0 +1,51 @@ + + + + + jQuery UI Datepicker - Animations + + + + + + + + + + + + + + + + + +

    Date:

    + +

    Animations:
    + +

    + +
    +

    Use different animations when opening or closing the datepicker. Choose an animation from the dropdown, then click on the input to see its effect. You can use one of the three standard animations or any of the UI Effects.

    +
    + + diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/datepicker/buttonbar.html b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/datepicker/buttonbar.html new file mode 100755 index 000000000..b0b4650bb --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/datepicker/buttonbar.html @@ -0,0 +1,28 @@ + + + + + jQuery UI Datepicker - Display button bar + + + + + + + + + + +

    Date:

    + +
    +

    Display a button for selecting Today's date and a Done button for closing the calendar with the boolean showButtonPanel option. Each button is enabled by default when the bar is displayed, but can be turned off with additional options. Button text is customizable.

    +
    + + diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/datepicker/date-formats.html b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/datepicker/date-formats.html new file mode 100755 index 000000000..b50a92172 --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/datepicker/date-formats.html @@ -0,0 +1,40 @@ + + + + + jQuery UI Datepicker - Format date + + + + + + + + + + +

    Date:

    + +

    Format options:
    + +

    + +
    +

    Display date feedback in a variety of ways. Choose a date format from the dropdown, then click on the input and select a date to see it in that format.

    +
    + + diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/datepicker/date-range.html b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/datepicker/date-range.html new file mode 100755 index 000000000..284b6b3be --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/datepicker/date-range.html @@ -0,0 +1,44 @@ + + + + + jQuery UI Datepicker - Select a Date Range + + + + + + + + + + + + + + + +
    +

    Select the date range to search for.

    +
    + + diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/datepicker/default.html b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/datepicker/default.html new file mode 100755 index 000000000..5a51a538c --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/datepicker/default.html @@ -0,0 +1,26 @@ + + + + + jQuery UI Datepicker - Default functionality + + + + + + + + + + +

    Date:

    + +
    +

    The datepicker is tied to a standard form input field. Focus on the input (click, or use the tab key) to open an interactive calendar in a small overlay. Choose a date, click elsewhere on the page (blur the input), or hit the Esc key to close. If a date is chosen, feedback is shown as the input's value.

    +
    + + diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/datepicker/dropdown-month-year.html b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/datepicker/dropdown-month-year.html new file mode 100755 index 000000000..ea4600a6f --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/datepicker/dropdown-month-year.html @@ -0,0 +1,29 @@ + + + + + jQuery UI Datepicker - Display month & year menus + + + + + + + + + + +

    Date:

    + +
    +

    Show month and year dropdowns in place of the static month/year header to facilitate navigation through large timeframes. Add the boolean changeMonth and changeYear options.

    +
    + + diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/datepicker/icon-trigger.html b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/datepicker/icon-trigger.html new file mode 100755 index 000000000..9fca9b790 --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/datepicker/icon-trigger.html @@ -0,0 +1,30 @@ + + + + + jQuery UI Datepicker - Icon trigger + + + + + + + + + + +

    Date:

    + +
    +

    Click the icon next to the input field to show the datepicker. Set the datepicker to open on focus (default behavior), on icon click, or both.

    +
    + + diff --git a/htdocs/js/lib/vendor/jquery-ui-for-classlist3/development-bundle/demos/images/calendar.gif b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/datepicker/images/calendar.gif similarity index 100% rename from htdocs/js/lib/vendor/jquery-ui-for-classlist3/development-bundle/demos/images/calendar.gif rename to htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/datepicker/images/calendar.gif diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/datepicker/index.html b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/datepicker/index.html new file mode 100755 index 000000000..eb903a220 --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/datepicker/index.html @@ -0,0 +1,27 @@ + + + + + jQuery UI Datepicker Demos + + + + + + + diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/datepicker/inline.html b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/datepicker/inline.html new file mode 100755 index 000000000..ec01533ee --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/datepicker/inline.html @@ -0,0 +1,26 @@ + + + + + jQuery UI Datepicker - Display inline + + + + + + + + + + +Date:
    + +
    +

    Display the datepicker embedded in the page instead of in an overlay. Simply call .datepicker() on a div instead of an input.

    +
    + + diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/datepicker/localization.html b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/datepicker/localization.html new file mode 100755 index 000000000..4fd7a1c46 --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/datepicker/localization.html @@ -0,0 +1,169 @@ + + + + + jQuery UI Datepicker - Localize calendar + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

    Date:   +

    + +
    +

    Localize the datepicker calendar language and format (English / Western formatting is the default). The datepicker includes built-in support for languages that read right-to-left, such as Arabic and Hebrew.

    +
    + + diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/datepicker/min-max.html b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/datepicker/min-max.html new file mode 100755 index 000000000..cc28a7583 --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/datepicker/min-max.html @@ -0,0 +1,26 @@ + + + + + jQuery UI Datepicker - Restrict date range + + + + + + + + + + +

    Date:

    + +
    +

    Restrict the range of selectable dates with the minDate and maxDate options. Set the beginning and end dates as actual dates (new Date(2009, 1 - 1, 26)), as a numeric offset from today (-20), or as a string of periods and units ('+1M +10D'). For the last, use 'D' for days, 'W' for weeks, 'M' for months, or 'Y' for years.

    +
    + + diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/datepicker/multiple-calendars.html b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/datepicker/multiple-calendars.html new file mode 100755 index 000000000..1a8b7e0eb --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/datepicker/multiple-calendars.html @@ -0,0 +1,29 @@ + + + + + jQuery UI Datepicker - Display multiple months + + + + + + + + + + +

    Date:

    + +
    +

    Set the numberOfMonths option to an integer of 2 or more to show multiple months in a single datepicker.

    +
    + + diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/datepicker/other-months.html b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/datepicker/other-months.html new file mode 100755 index 000000000..e735385ec --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/datepicker/other-months.html @@ -0,0 +1,30 @@ + + + + + jQuery UI Datepicker - Dates in other months + + + + + + + + + + +

    Date:

    + +
    +

    The datepicker can show dates that come from other than the main month + being displayed. These other dates can also be made selectable.

    +
    + + diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/datepicker/show-week.html b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/datepicker/show-week.html new file mode 100755 index 000000000..931e85be8 --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/datepicker/show-week.html @@ -0,0 +1,32 @@ + + + + + jQuery UI Datepicker - Show week of the year + + + + + + + + + + +

    Date:

    + +
    +

    The datepicker can show the week of the year. The default calculation follows + the ISO 8601 definition: the week starts on Monday, the first week of the year + contains the first Thursday of the year. This means that some days from one + year may be placed into weeks 'belonging' to another year.

    +
    + + diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/demos.css b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/demos.css new file mode 100755 index 000000000..da9ad833a --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/demos.css @@ -0,0 +1,19 @@ +body { + font-size: 62.5%; + font-family: "Trebuchet MS", "Arial", "Helvetica", "Verdana", "sans-serif"; +} + +table { + font-size: 1em; +} + +.demo-description { + clear: both; + padding: 12px; + font-size: 1.3em; + line-height: 1.4em; +} + +.ui-draggable, .ui-droppable { + background-position: top; +} diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/dialog/animated.html b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/dialog/animated.html new file mode 100755 index 000000000..8a27150de --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/dialog/animated.html @@ -0,0 +1,49 @@ + + + + + jQuery UI Dialog - Animation + + + + + + + + + + + + + + + + + + +
    +

    This is an animated dialog which is useful for displaying information. The dialog window can be moved, resized and closed with the 'x' icon.

    +
    + + + +
    +

    Dialogs may be animated by specifying an effect for the show and/or hide properties. You must include the individual effects file for any effects you would like to use.

    +
    + + diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/dialog/default.html b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/dialog/default.html new file mode 100755 index 000000000..5dcb1a05c --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/dialog/default.html @@ -0,0 +1,33 @@ + + + + + jQuery UI Dialog - Default functionality + + + + + + + + + + + + + + + +
    +

    This is the default dialog which is useful for displaying information. The dialog window can be moved, resized and closed with the 'x' icon.

    +
    + +
    +

    The basic dialog window is an overlay positioned within the viewport and is protected from page content (like select elements) shining through with an iframe. It has a title bar and a content area, and can be moved, resized and closed with the 'x' icon by default.

    +
    + + diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/dialog/index.html b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/dialog/index.html new file mode 100755 index 000000000..6aaa3ecb5 --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/dialog/index.html @@ -0,0 +1,19 @@ + + + + + jQuery UI Dialog Demos + + + + + + + diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/dialog/modal-confirmation.html b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/dialog/modal-confirmation.html new file mode 100755 index 000000000..cca3b296d --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/dialog/modal-confirmation.html @@ -0,0 +1,47 @@ + + + + + jQuery UI Dialog - Modal confirmation + + + + + + + + + + + + + + + +
    +

    These items will be permanently deleted and cannot be recovered. Are you sure?

    +
    + +

    Sed vel diam id libero rutrum convallis. Donec aliquet leo vel magna. Phasellus rhoncus faucibus ante. Etiam bibendum, enim faucibus aliquet rhoncus, arcu felis ultricies neque, sit amet auctor elit eros a lectus.

    + +
    +

    Confirm an action that may be destructive or important. Set the modal option to true, and specify primary and secondary user actions with the buttons option.

    +
    + + diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/dialog/modal-form.html b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/dialog/modal-form.html new file mode 100755 index 000000000..48452f862 --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/dialog/modal-form.html @@ -0,0 +1,157 @@ + + + + + jQuery UI Dialog - Modal form + + + + + + + + + + + + + + + + + + +
    +

    All form fields are required.

    + +
    +
    + + + + + + +
    +
    +
    + + +
    +

    Existing Users:

    + + + + + + + + + + + + + + + +
    NameEmailPassword
    John Doejohn.doe@example.comjohndoe1
    +
    + + +
    +

    Use a modal dialog to require that the user enter data during a multi-step process. Embed form markup in the content area, set the modal option to true, and specify primary and secondary user actions with the buttons option.

    +
    + + diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/dialog/modal-message.html b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/dialog/modal-message.html new file mode 100755 index 000000000..d44331017 --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/dialog/modal-message.html @@ -0,0 +1,49 @@ + + + + + jQuery UI Dialog - Modal message + + + + + + + + + + + + + + + + +
    +

    + + Your files have downloaded successfully into the My Downloads folder. +

    +

    + Currently using 36% of your storage space. +

    +
    + +

    Sed vel diam id libero rutrum convallis. Donec aliquet leo vel magna. Phasellus rhoncus faucibus ante. Etiam bibendum, enim faucibus aliquet rhoncus, arcu felis ultricies neque, sit amet auctor elit eros a lectus.

    + +
    +

    Use a modal dialog to explicitly acknowledge information or an action before continuing their work. Set the modal option to true, and specify a primary action (Ok) with the buttons option.

    +
    + + diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/dialog/modal.html b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/dialog/modal.html new file mode 100755 index 000000000..2b1ac2574 --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/dialog/modal.html @@ -0,0 +1,38 @@ + + + + + jQuery UI Dialog - Basic modal + + + + + + + + + + + + + + + +
    +

    Adding the modal overlay screen makes the dialog look more prominent because it dims out the page content.

    +
    + +

    Sed vel diam id libero rutrum convallis. Donec aliquet leo vel magna. Phasellus rhoncus faucibus ante. Etiam bibendum, enim faucibus aliquet rhoncus, arcu felis ultricies neque, sit amet auctor elit eros a lectus.

    + +
    +

    A modal dialog prevents the user from interacting with the rest of the page until it is closed.

    +
    + + diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/draggable/constrain-movement.html b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/draggable/constrain-movement.html new file mode 100755 index 000000000..0bbcdf147 --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/draggable/constrain-movement.html @@ -0,0 +1,58 @@ + + + + + jQuery UI Draggable - Constrain movement + + + + + + + + + + + + +

    Constrain movement along an axis:

    + +
    +

    I can be dragged only vertically

    +
    + +
    +

    I can be dragged only horizontally

    +
    + +

    Or to within another DOM element:

    +
    +
    +

    I'm contained within the box

    +
    + +
    +

    I'm contained within my parent

    +
    +
    + +
    +

    Constrain the movement of each draggable by defining the boundaries of the draggable area. Set the axis option to limit the draggable's path to the x- or y-axis, or use the containment option to specify a parent DOM element or a jQuery selector, like 'document.'

    +
    + + diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/draggable/cursor-style.html b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/draggable/cursor-style.html new file mode 100755 index 000000000..5ee09386c --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/draggable/cursor-style.html @@ -0,0 +1,42 @@ + + + + + jQuery UI Draggable - Cursor style + + + + + + + + + + + + +
    +

    I will always stick to the center (relative to the mouse)

    +
    + +
    +

    My cursor is at left -5 and top -5

    +
    + +
    +

    My cursor position is only controlled for the 'bottom' value

    +
    + +
    +

    Position the cursor while dragging the object. By default the cursor appears in the center of the dragged object; use the cursorAt option to specify another location relative to the draggable (specify a pixel value from the top, right, bottom, and/or left). Customize the cursor's appearance by supplying the cursor option with a valid CSS cursor value: default, move, pointer, crosshair, etc.

    +
    + + diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/draggable/default.html b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/draggable/default.html new file mode 100755 index 000000000..9d9d1a8ec --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/draggable/default.html @@ -0,0 +1,32 @@ + + + + + jQuery UI Draggable - Default functionality + + + + + + + + + + + + +
    +

    Drag me around

    +
    + +
    +

    Enable draggable functionality on any DOM element. Move the draggable object by clicking on it with the mouse and dragging it anywhere within the viewport.

    +
    + + diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/draggable/delay-start.html b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/draggable/delay-start.html new file mode 100755 index 000000000..fe74e908f --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/draggable/delay-start.html @@ -0,0 +1,38 @@ + + + + + jQuery UI Draggable - Delay start + + + + + + + + + + + + +
    +

    Only if you drag me by 20 pixels, the dragging will start

    +
    + +
    +

    Regardless of the distance, you have to drag and wait for 1000ms before dragging starts

    +
    + +
    +

    Delay the start of dragging for a number of milliseconds with the delay option; prevent dragging until the cursor is held down and dragged a specifed number of pixels with the distance option.

    +
    + + diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/draggable/events.html b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/draggable/events.html new file mode 100755 index 000000000..9c2f2c046 --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/draggable/events.html @@ -0,0 +1,70 @@ + + + + + jQuery UI Draggable - Events + + + + + + + + + + + + +
    + +

    Drag me to trigger the chain of events.

    + +
      +
    • "start" invoked 0x
    • +
    • "drag" invoked 0x
    • +
    • "stop" invoked 0x
    • +
    +
    + +
    +

    Layer functionality onto the draggable using the start, drag, and stop events. Start is fired at the start of the drag; drag during the drag; and stop when dragging stops.

    +
    + + diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/draggable/handle.html b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/draggable/handle.html new file mode 100755 index 000000000..b2863bff6 --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/draggable/handle.html @@ -0,0 +1,41 @@ + + + + + jQuery UI Draggable - Handles + + + + + + + + + + + + +
    +

    I can be dragged only by this handle

    +
    + +
    +

    You can drag me around…

    +

    …but you can't drag me by this handle.

    +
    + +
    +

    Allow dragging only when the cursor is over a specific part of the draggable. Use the handle option to specify the jQuery selector of an element (or group of elements) used to drag the object.

    +

    Or prevent dragging when the cursor is over a specific element (or group of elements) within the draggable. Use the cancel option to specify a jQuery selector over which to "cancel" draggable functionality.

    +
    + + diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/draggable/index.html b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/draggable/index.html new file mode 100755 index 000000000..93850684d --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/draggable/index.html @@ -0,0 +1,24 @@ + + + + + jQuery UI Draggable Demos + + + + + + + diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/draggable/revert.html b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/draggable/revert.html new file mode 100755 index 000000000..b898d632a --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/draggable/revert.html @@ -0,0 +1,37 @@ + + + + + jQuery UI Draggable - Revert position + + + + + + + + + + + + +
    +

    Revert the original

    +
    + +
    +

    Revert the helper

    +
    + +
    +

    Return the draggable (or it's helper) to its original location when dragging stops with the boolean revert option.

    +
    + + diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/draggable/scroll.html b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/draggable/scroll.html new file mode 100755 index 000000000..c4498096c --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/draggable/scroll.html @@ -0,0 +1,44 @@ + + + + + jQuery UI Draggable - Auto-scroll + + + + + + + + + + + + +
    +

    Scroll set to true, default settings

    +
    + +
    +

    scrollSensitivity set to 100

    +
    + +
    +

    scrollSpeed set to 100

    +
    + +
    + +
    +

    Automatically scroll the document when the draggable is moved beyond the viewport. Set the scroll option to true to enable auto-scrolling, and fine-tune when scrolling is triggered and its speed with the scrollSensitivity and scrollSpeed options.

    +
    + + diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/draggable/snap-to.html b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/draggable/snap-to.html new file mode 100755 index 000000000..33feb68d4 --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/draggable/snap-to.html @@ -0,0 +1,61 @@ + + + + + jQuery UI Draggable - Snap to element or grid + + + + + + + + + + + + +
    +

    I'm a snap target

    +
    + +
    + +
    +

    Default (snap: true), snaps to all other draggable elements

    +
    + +
    +

    I only snap to the big box

    +
    + +
    +

    I only snap to the outer edges of the big box

    +
    + +
    +

    I snap to a 20 x 20 grid

    +
    + +
    +

    I snap to a 80 x 80 grid

    +
    + +
    +

    Snap the draggable to the inner or outer boundaries of a DOM element. Use the snap, snapMode (inner, outer, both), and snapTolerance (distance in pixels the draggable must be from the element when snapping is invoked) options.

    +

    Or snap the draggable to a grid. Set the dimensions of grid cells (height and width in pixels) with the grid option.

    +
    + + diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/draggable/sortable.html b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/draggable/sortable.html new file mode 100755 index 000000000..55bfd591f --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/draggable/sortable.html @@ -0,0 +1,50 @@ + + + + + jQuery UI Draggable + Sortable + + + + + + + + + + + + + +
      +
    • Drag me down
    • +
    + +
      +
    • Item 1
    • +
    • Item 2
    • +
    • Item 3
    • +
    • Item 4
    • +
    • Item 5
    • +
    + +
    +

    Draggables are built to interact seamlessly with sortables.

    +
    + + diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/draggable/visual-feedback.html b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/draggable/visual-feedback.html new file mode 100755 index 000000000..d0b058366 --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/draggable/visual-feedback.html @@ -0,0 +1,70 @@ + + + + + jQuery UI Draggable - Visual feedback + + + + + + + + + + + + +

    With helpers:

    + +
    +

    Original

    +
    + +
    +

    Semi-transparent clone

    +
    + +
    +

    Custom helper (in combination with cursorAt)

    +
    + +

    Stacked:

    +
    +
    +

    We are draggables..

    +
    + +
    +

    ..whose z-indexes are controlled automatically..

    +
    + +
    +

    ..with the stack option.

    +
    +
    + +
    +

    Provide feedback to users as they drag an object in the form of a helper. The helper option accepts the values 'original' (the draggable object moves with the cursor), 'clone' (a duplicate of the draggable moves with the cursor), or a function that returns a DOM element (that element is shown near the cursor during drag). Control the helper's transparency with the opacity option.

    +

    To clarify which draggable is in play, bring the draggable in motion to front. Use the zIndex option to set a higher z-index for the helper, if in play, or use the stack option to ensure that the last item dragged will appear on top of others in the same group on drag stop.

    +
    + + diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/droppable/accepted-elements.html b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/droppable/accepted-elements.html new file mode 100755 index 000000000..455e8bd5f --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/droppable/accepted-elements.html @@ -0,0 +1,53 @@ + + + + + jQuery UI Droppable - Accept + + + + + + + + + + + + + +
    +

    I'm draggable but can't be dropped

    +
    + +
    +

    Drag me to my target

    +
    + +
    +

    accept: '#draggable'

    +
    + +
    +

    Specify using the accept option which element (or group of elements) is accepted by the target droppable.

    +
    + + diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/droppable/default.html b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/droppable/default.html new file mode 100755 index 000000000..381098b4b --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/droppable/default.html @@ -0,0 +1,46 @@ + + + + + jQuery UI Droppable - Default functionality + + + + + + + + + + + + + +
    +

    Drag me to my target

    +
    + +
    +

    Drop here

    +
    + +
    +

    Enable any DOM element to be droppable, a target for draggable elements.

    +
    + + diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/droppable/images/high_tatras.jpg b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/droppable/images/high_tatras.jpg new file mode 100755 index 000000000..5723680df Binary files /dev/null and b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/droppable/images/high_tatras.jpg differ diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/droppable/images/high_tatras2.jpg b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/droppable/images/high_tatras2.jpg new file mode 100755 index 000000000..1acad3afb Binary files /dev/null and b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/droppable/images/high_tatras2.jpg differ diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/droppable/images/high_tatras2_min.jpg b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/droppable/images/high_tatras2_min.jpg new file mode 100755 index 000000000..493e0824a Binary files /dev/null and b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/droppable/images/high_tatras2_min.jpg differ diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/droppable/images/high_tatras3.jpg b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/droppable/images/high_tatras3.jpg new file mode 100755 index 000000000..e158b1ae0 Binary files /dev/null and b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/droppable/images/high_tatras3.jpg differ diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/droppable/images/high_tatras3_min.jpg b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/droppable/images/high_tatras3_min.jpg new file mode 100755 index 000000000..4aa96b01e Binary files /dev/null and b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/droppable/images/high_tatras3_min.jpg differ diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/droppable/images/high_tatras4.jpg b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/droppable/images/high_tatras4.jpg new file mode 100755 index 000000000..da4124d88 Binary files /dev/null and b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/droppable/images/high_tatras4.jpg differ diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/droppable/images/high_tatras4_min.jpg b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/droppable/images/high_tatras4_min.jpg new file mode 100755 index 000000000..794dbdf78 Binary files /dev/null and b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/droppable/images/high_tatras4_min.jpg differ diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/droppable/images/high_tatras_min.jpg b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/droppable/images/high_tatras_min.jpg new file mode 100755 index 000000000..51e0cdedf Binary files /dev/null and b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/droppable/images/high_tatras_min.jpg differ diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/droppable/index.html b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/droppable/index.html new file mode 100755 index 000000000..deca6e4bc --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/droppable/index.html @@ -0,0 +1,20 @@ + + + + + jQuery UI Droppable Demos + + + + + + + diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/droppable/photo-manager.html b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/droppable/photo-manager.html new file mode 100755 index 000000000..315473761 --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/droppable/photo-manager.html @@ -0,0 +1,182 @@ + + + + + jQuery UI Droppable - Simple photo manager + + + + + + + + + + + + + + + + +
    + + + +
    +

    Trash Trash

    +
    + +
    + +
    +

    You can delete an image either by dragging it to the Trash or by clicking the trash icon.

    +

    You can "recycle" an image by dragging it back to the gallery or by clicking the recycle icon.

    +

    You can view larger image by clicking the zoom icon. jQuery UI dialog widget is used for the modal window.

    +
    + + diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/droppable/propagation.html b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/droppable/propagation.html new file mode 100755 index 000000000..4aae2fcab --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/droppable/propagation.html @@ -0,0 +1,73 @@ + + + + + jQuery UI Droppable - Prevent propagation + + + + + + + + + + + + + +
    +

    Drag me to my target

    +
    + +
    +

    Outer droppable

    +
    +

    Inner droppable (not greedy)

    +
    +
    + +
    +

    Outer droppable

    +
    +

    Inner droppable (greedy)

    +
    +
    + +
    +

    When working with nested droppables — for example, you may have an editable directory structure displayed as a tree, with folder and document nodes — the greedy option set to true prevents event propagation when a draggable is dropped on a child node (droppable).

    +
    + + diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/droppable/revert.html b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/droppable/revert.html new file mode 100755 index 000000000..1d2ce2aa7 --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/droppable/revert.html @@ -0,0 +1,54 @@ + + + + + jQuery UI Droppable - Revert draggable position + + + + + + + + + + + + + +
    +

    I revert when I'm dropped

    +
    + +
    +

    I revert when I'm not dropped

    +
    + +
    +

    Drop me here

    +
    + +
    +

    Return the draggable (or it's helper) to its original location when dragging stops with the boolean revert option set on the draggable.

    +
    + + diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/droppable/shopping-cart.html b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/droppable/shopping-cart.html new file mode 100755 index 000000000..60468aab7 --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/droppable/shopping-cart.html @@ -0,0 +1,94 @@ + + + + + jQuery UI Droppable - Shopping Cart Demo + + + + + + + + + + + + + + + +
    +

    Products

    +
    +

    T-Shirts

    +
    +
      +
    • Lolcat Shirt
    • +
    • Cheezeburger Shirt
    • +
    • Buckit Shirt
    • +
    +
    +

    Bags

    +
    +
      +
    • Zebra Striped
    • +
    • Black Leather
    • +
    • Alligator Leather
    • +
    +
    +

    Gadgets

    +
    +
      +
    • iPhone
    • +
    • iPod
    • +
    • iPad
    • +
    +
    +
    +
    + +
    +

    Shopping Cart

    +
    +
      +
    1. Add your items here
    2. +
    +
    +
    + +
    +

    Demonstrate how to use an accordion to structure products into a catalog and make use drag and drop for adding them to a shopping cart, where they are sortable.

    +
    + + diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/droppable/visual-feedback.html b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/droppable/visual-feedback.html new file mode 100755 index 000000000..08f96ed2d --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/droppable/visual-feedback.html @@ -0,0 +1,72 @@ + + + + + jQuery UI Droppable - Visual feedback + + + + + + + + + + + + + +

    Feedback on hover:

    + +
    +

    Drag me to my target

    +
    + +
    +

    Drop here

    +
    + +

    Feedback on activating draggable:

    + +
    +

    Drag me to my target

    +
    + +
    +

    Drop here

    +
    + +
    +

    Change the droppable's appearance on hover, or when the droppable is active (an acceptable draggable is dropped on it). Use the hoverClass or activeClass options to specify respective classes.

    +
    + + diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/effect/default.html b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/effect/default.html new file mode 100755 index 000000000..455fb1f34 --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/effect/default.html @@ -0,0 +1,102 @@ + + + + + jQuery UI Effects - Effect demo + + + + + + + + + + + + + + + + + + + + + + +
    +
    +

    Effect

    +

    + Etiam libero neque, luctus a, eleifend nec, semper at, lorem. Sed pede. Nulla lorem metus, adipiscing ut, luctus sed, hendrerit vitae, mi. +

    +
    +
    + + + +Run Effect + +
    +

    Click the button above to show the effect.

    +
    + + diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/effect/easing.html b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/effect/easing.html new file mode 100755 index 000000000..4ccc9691b --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/effect/easing.html @@ -0,0 +1,102 @@ + + + + + jQuery UI Effects - Easing demo + + + + + + + + + +
    + +
    +

    All easings provided by jQuery UI are drawn above, using a HTML canvas element. Click a diagram to see the easing in action.

    +
    + + diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/effect/index.html b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/effect/index.html new file mode 100755 index 000000000..5da6bc612 --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/effect/index.html @@ -0,0 +1,15 @@ + + + + + jQuery UI Effects Demos + + + + + + + diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/images/calendar.gif b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/images/calendar.gif new file mode 100755 index 000000000..d0abaa7c0 Binary files /dev/null and b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/images/calendar.gif differ diff --git a/htdocs/js/lib/vendor/jquery-ui-for-classlist3/development-bundle/demos/images/demo-config-on-tile.gif b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/images/demo-config-on-tile.gif similarity index 100% rename from htdocs/js/lib/vendor/jquery-ui-for-classlist3/development-bundle/demos/images/demo-config-on-tile.gif rename to htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/images/demo-config-on-tile.gif diff --git a/htdocs/js/lib/vendor/jquery-ui-for-classlist3/development-bundle/demos/images/demo-config-on.gif b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/images/demo-config-on.gif similarity index 100% rename from htdocs/js/lib/vendor/jquery-ui-for-classlist3/development-bundle/demos/images/demo-config-on.gif rename to htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/images/demo-config-on.gif diff --git a/htdocs/js/lib/vendor/jquery-ui-for-classlist3/development-bundle/demos/images/demo-spindown-closed.gif b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/images/demo-spindown-closed.gif similarity index 100% rename from htdocs/js/lib/vendor/jquery-ui-for-classlist3/development-bundle/demos/images/demo-spindown-closed.gif rename to htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/images/demo-spindown-closed.gif diff --git a/htdocs/js/lib/vendor/jquery-ui-for-classlist3/development-bundle/demos/images/demo-spindown-open.gif b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/images/demo-spindown-open.gif similarity index 100% rename from htdocs/js/lib/vendor/jquery-ui-for-classlist3/development-bundle/demos/images/demo-spindown-open.gif rename to htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/images/demo-spindown-open.gif diff --git a/htdocs/js/lib/vendor/jquery-ui-for-classlist3/development-bundle/demos/images/icon-docs-info.gif b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/images/icon-docs-info.gif similarity index 100% rename from htdocs/js/lib/vendor/jquery-ui-for-classlist3/development-bundle/demos/images/icon-docs-info.gif rename to htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/images/icon-docs-info.gif diff --git a/htdocs/js/lib/vendor/jquery-ui-for-classlist3/development-bundle/demos/images/pbar-ani.gif b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/images/pbar-ani.gif similarity index 100% rename from htdocs/js/lib/vendor/jquery-ui-for-classlist3/development-bundle/demos/images/pbar-ani.gif rename to htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/images/pbar-ani.gif diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/menu/default.html b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/menu/default.html new file mode 100755 index 000000000..27b1f249c --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/menu/default.html @@ -0,0 +1,42 @@ + + + + + jQuery UI Menu - Default functionality + + + + + + + + + + + + +
    +

    A menu with the default configuration. A list is transformed, adding theming, mouse and keyboard navigation support. Try to tab to the menu then use the cursor keys to navigate.

    +
    + + diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/menu/index.html b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/menu/index.html new file mode 100755 index 000000000..07556c6ec --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/menu/index.html @@ -0,0 +1,16 @@ + + + + + jQuery UI Menu Demos + + + + + + + diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/menu/navigationmenu.html b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/menu/navigationmenu.html new file mode 100755 index 000000000..c2bb307ba --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/menu/navigationmenu.html @@ -0,0 +1,74 @@ + + + + + jQuery UI Menu - Navigation Menu + + + + + + + + + + + + + + +
    +

    A navigation menu. A list is transformed, adding theming, mouse and keyboard navigation support. Try to tab to the menu then use the cursor keys to navigate.

    +
    + + diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/menu/topalignmenu.html b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/menu/topalignmenu.html new file mode 100755 index 000000000..4f34b98c2 --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/menu/topalignmenu.html @@ -0,0 +1,87 @@ + + + + + Menu Demo: Top-aligned Menu + + + + + + + + + + + + + + +
    +

    Menus can use custom positioning. There is a delay before activing an item on hover and a delay before closing a menu on mouse out to allow for moving to a submenu that is not touching its parent item.

    +
    + + diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/position/cycler.html b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/position/cycler.html new file mode 100755 index 000000000..dc3bbc86e --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/position/cycler.html @@ -0,0 +1,105 @@ + + + + + jQuery UI Position - Default functionality + + + + + + + + + + + +
    + earth + flight + rocket + + + +
    + +
    +

    A prototype for the Photoviewer using Position to place images at the center, left and right and cycle them. +
    Use the links at the top to cycle, or click on the images on the left and right. +
    Note how the images are repositioned when resizing the window. +
    Warning: Doesn't currently work inside the demo viewer; open in a new window instead!

    +
    + + diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/position/default.html b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/position/default.html new file mode 100755 index 000000000..223788b1f --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/position/default.html @@ -0,0 +1,142 @@ + + + + + jQuery UI Position - Default functionality + + + + + + + + + + + + + +
    +

    + This is the position parent element. +

    +
    + +
    +

    + to position +

    +
    + +
    +

    + to position 2 +

    +
    + +
    + position... +
    + my: + + +
    +
    + at: + + +
    +
    + offset: + +
    +
    + collision: + + +
    +
    + +
    +

    Use the form controls to configure the positioning, or drag the positioned element to modify its offset. +
    Drag around the parent element to see collision detection in action.

    +
    + + diff --git a/htdocs/js/lib/vendor/jquery-ui-for-classlist3/development-bundle/demos/position/images/earth.jpg b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/position/images/earth.jpg similarity index 100% rename from htdocs/js/lib/vendor/jquery-ui-for-classlist3/development-bundle/demos/position/images/earth.jpg rename to htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/position/images/earth.jpg diff --git a/htdocs/js/lib/vendor/jquery-ui-for-classlist3/development-bundle/demos/position/images/flight.jpg b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/position/images/flight.jpg similarity index 100% rename from htdocs/js/lib/vendor/jquery-ui-for-classlist3/development-bundle/demos/position/images/flight.jpg rename to htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/position/images/flight.jpg diff --git a/htdocs/js/lib/vendor/jquery-ui-for-classlist3/development-bundle/demos/position/images/rocket.jpg b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/position/images/rocket.jpg similarity index 100% rename from htdocs/js/lib/vendor/jquery-ui-for-classlist3/development-bundle/demos/position/images/rocket.jpg rename to htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/position/images/rocket.jpg diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/position/index.html b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/position/index.html new file mode 100755 index 000000000..a7b754876 --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/position/index.html @@ -0,0 +1,15 @@ + + + + + jQuery UI Position Demo + + + + + + + diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/progressbar/animated.html b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/progressbar/animated.html new file mode 100755 index 000000000..df82d047e --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/progressbar/animated.html @@ -0,0 +1,37 @@ + + + + + jQuery UI Progressbar - Animated + + + + + + + + + + + +
    + +
    +

    +This progressbar has an animated fill by setting the +background-image +on the +.ui-progressbar-value +element, using css. +

    +
    + + diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/progressbar/default.html b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/progressbar/default.html new file mode 100755 index 000000000..a814adbe2 --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/progressbar/default.html @@ -0,0 +1,28 @@ + + + + + jQuery UI Progressbar - Default functionality + + + + + + + + + + +
    + +
    +

    Default determinate progress bar.

    +
    + + diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/progressbar/images/pbar-ani.gif b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/progressbar/images/pbar-ani.gif new file mode 100755 index 000000000..cb59a04f9 Binary files /dev/null and b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/progressbar/images/pbar-ani.gif differ diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/progressbar/index.html b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/progressbar/index.html new file mode 100755 index 000000000..5080520c2 --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/progressbar/index.html @@ -0,0 +1,16 @@ + + + + + jQuery UI Progressbar Demos + + + + + + + diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/progressbar/resize.html b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/progressbar/resize.html new file mode 100755 index 000000000..d7209fbbc --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/progressbar/resize.html @@ -0,0 +1,33 @@ + + + + + jQuery UI Progressbar - Resizable + + + + + + + + + + + + +
    +
    +
    + +
    +

    The progress bar's widths are specified in percentages for flexible sizing so it will resize to fit its container. Try resizing the height and width of this bar to see how it maintains the correct proportions. (This is not necessarily a real-world example, but it's a good illustration of how flexibly all the plugins are coded.)

    +
    + + diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/resizable/animate.html b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/resizable/animate.html new file mode 100755 index 000000000..c5373b45d --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/resizable/animate.html @@ -0,0 +1,36 @@ + + + + + jQuery UI Resizable - Animate + + + + + + + + + + + + +
    +

    Animate

    +
    + +
    +

    Animate the resize action using the animate option (boolean). When this option is set to true, drag the outline to the desired location; the element animates to that size on drag stop.

    +
    + + diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/resizable/aspect-ratio.html b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/resizable/aspect-ratio.html new file mode 100755 index 000000000..ad853073f --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/resizable/aspect-ratio.html @@ -0,0 +1,35 @@ + + + + + jQuery UI Resizable - Preserve aspect ratio + + + + + + + + + + + + +
    +

    Preserve aspect ratio

    +
    + +
    +

    Maintain the existing aspect ratio or set a new one to constrain the proportions on resize. Set the aspectRatio option to true, and optionally pass in a new ratio (i.e., 4/3)

    +
    + + diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/resizable/constrain-area.html b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/resizable/constrain-area.html new file mode 100755 index 000000000..562a1c29b --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/resizable/constrain-area.html @@ -0,0 +1,40 @@ + + + + + jQuery UI Resizable - Constrain resize area + + + + + + + + + + + + +
    +

    Containment

    +
    +

    Resizable

    +
    +
    + +
    +

    Define the boundaries of the resizable area. Use the containment option to specify a parent DOM element or a jQuery selector, like 'document.'

    +
    + + diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/resizable/default.html b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/resizable/default.html new file mode 100755 index 000000000..17388197d --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/resizable/default.html @@ -0,0 +1,33 @@ + + + + + jQuery UI Resizable - Default functionality + + + + + + + + + + + + +
    +

    Resizable

    +
    + +
    +

    Enable any DOM element to be resizable. With the cursor grab the right or bottom border and drag to the desired width or height.

    +
    + + diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/resizable/delay-start.html b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/resizable/delay-start.html new file mode 100755 index 000000000..2cf2245e7 --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/resizable/delay-start.html @@ -0,0 +1,45 @@ + + + + + jQuery UI Resizable - Delay start + + + + + + + + + + + + +

    Time delay (ms):

    +
    +

    Time

    +
    + +

    Distance delay (px):

    +
    +

    Distance

    +
    + +
    +

    Delay the start of resizng for a number of milliseconds with the delay option; prevent resizing until the cursor is held down and dragged a specifed number of pixels with the distance option.

    +
    + + diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/resizable/helper.html b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/resizable/helper.html new file mode 100755 index 000000000..57d284cc2 --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/resizable/helper.html @@ -0,0 +1,36 @@ + + + + + jQuery UI Resizable - Helper + + + + + + + + + + + + +
    +

    Helper

    +
    + +
    +

    Display only an outline of the element while resizing by setting the helper option to a CSS class.

    +
    + + diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/resizable/index.html b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/resizable/index.html new file mode 100755 index 000000000..7c626e253 --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/resizable/index.html @@ -0,0 +1,24 @@ + + + + + jQuery UI Resizable Demos + + + + + + + diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/resizable/max-min.html b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/resizable/max-min.html new file mode 100755 index 000000000..301d93c20 --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/resizable/max-min.html @@ -0,0 +1,38 @@ + + + + + jQuery UI Resizable - Maximum / minimum size + + + + + + + + + + + + +
    +

    Resize larger / smaller

    +
    + +
    +

    Limit the resizable element to a maximum or minimum height or width using the maxHeight, maxWidth, minHeight, and minWidth options.

    +
    + + diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/resizable/snap-to-grid.html b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/resizable/snap-to-grid.html new file mode 100755 index 000000000..4b973efac --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/resizable/snap-to-grid.html @@ -0,0 +1,35 @@ + + + + + jQuery UI Resizable - Snap to grid + + + + + + + + + + + + +
    +

    Grid

    +
    + +
    +

    Snap the resizable element to a grid. Set the dimensions of grid cells (height and width in pixels) with the grid option.

    +
    + + diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/resizable/synchronous-resize.html b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/resizable/synchronous-resize.html new file mode 100755 index 000000000..77812df3d --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/resizable/synchronous-resize.html @@ -0,0 +1,42 @@ + + + + + jQuery UI Resizable - Synchronous resize + + + + + + + + + + + + +
    +

    Resize

    +
    + +
    +

    will also resize

    +
    + +
    +

    Resize multiple elements simultaneously by clicking and dragging the sides of one. Pass a shared selector into the alsoResize option.

    +
    + + diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/resizable/textarea.html b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/resizable/textarea.html new file mode 100755 index 000000000..c6ac48806 --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/resizable/textarea.html @@ -0,0 +1,34 @@ + + + + + jQuery UI Resizable - Textarea + + + + + + + + + + + + + + +
    +

    Display only an outline of the element while resizing by setting the helper option to a CSS class.

    +
    + + diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/resizable/visual-feedback.html b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/resizable/visual-feedback.html new file mode 100755 index 000000000..3577c7556 --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/resizable/visual-feedback.html @@ -0,0 +1,36 @@ + + + + + jQuery UI Resizable - Visual feedback + + + + + + + + + + + + +
    +

    Ghost

    +
    + +
    +

    Instead of showing the actual element during resize, set the ghost option to true to show a semi-transparent part of the element.

    +
    + + diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/selectable/default.html b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/selectable/default.html new file mode 100755 index 000000000..da39ffe84 --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/selectable/default.html @@ -0,0 +1,43 @@ + + + + + jQuery UI Selectable - Default functionality + + + + + + + + + + + + + +
      +
    1. Item 1
    2. +
    3. Item 2
    4. +
    5. Item 3
    6. +
    7. Item 4
    8. +
    9. Item 5
    10. +
    11. Item 6
    12. +
    13. Item 7
    14. +
    + +
    +

    Enable a DOM element (or group of elements) to be selectable. Draw a box with your cursor to select items. Hold down the Ctrl key to make multiple non-adjacent selections.

    +
    + + diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/selectable/display-grid.html b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/selectable/display-grid.html new file mode 100755 index 000000000..221490f88 --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/selectable/display-grid.html @@ -0,0 +1,48 @@ + + + + + jQuery UI Selectable - Display as grid + + + + + + + + + + + + + +
      +
    1. 1
    2. +
    3. 2
    4. +
    5. 3
    6. +
    7. 4
    8. +
    9. 5
    10. +
    11. 6
    12. +
    13. 7
    14. +
    15. 8
    16. +
    17. 9
    18. +
    19. 10
    20. +
    21. 11
    22. +
    23. 12
    24. +
    + +
    +

    To arrange selectable items as a grid, give them identical dimensions and float them using CSS.

    +
    + + diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/selectable/index.html b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/selectable/index.html new file mode 100755 index 000000000..a82830c60 --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/selectable/index.html @@ -0,0 +1,16 @@ + + + + + jQuery UI Selectable Demos + + + + + + + diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/selectable/serialize.html b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/selectable/serialize.html new file mode 100755 index 000000000..09935b130 --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/selectable/serialize.html @@ -0,0 +1,54 @@ + + + + + jQuery UI Selectable - Serialize + + + + + + + + + + + + + +

    +You've selected: none. +

    + +
      +
    1. Item 1
    2. +
    3. Item 2
    4. +
    5. Item 3
    6. +
    7. Item 4
    8. +
    9. Item 5
    10. +
    11. Item 6
    12. +
    + +
    +

    Write a function that fires on the stop event to collect the index values of selected items. Present values as feedback, or pass as a data string.

    +
    + + diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/slider/colorpicker.html b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/slider/colorpicker.html new file mode 100755 index 000000000..db0339ff3 --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/slider/colorpicker.html @@ -0,0 +1,87 @@ + + + + + jQuery UI Slider - Colorpicker + + + + + + + + + + + + +

    + + Simple Colorpicker +

    + +
    +
    +
    + +
    + +
    +

    Combine three sliders to create a simple RGB colorpicker.

    +
    + + diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/slider/default.html b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/slider/default.html new file mode 100755 index 000000000..ff30e41e4 --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/slider/default.html @@ -0,0 +1,27 @@ + + + + + jQuery UI Slider - Default functionality + + + + + + + + + + + +
    + +
    +

    The basic slider is horizontal and has a single handle that can be moved with the mouse or by using the arrow keys.

    +
    + + diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/slider/hotelrooms.html b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/slider/hotelrooms.html new file mode 100755 index 000000000..d866261b5 --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/slider/hotelrooms.html @@ -0,0 +1,49 @@ + + + + + jQuery UI Slider - Range with fixed minimum + + + + + + + + + + + +
    + + +
    + +
    +

    How to bind a slider to an existing select element. The select stays visible to display the change. When the select is changed, the slider is updated, too.

    +
    + + diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/slider/index.html b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/slider/index.html new file mode 100755 index 000000000..2d05bb58b --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/slider/index.html @@ -0,0 +1,24 @@ + + + + + jQuery UI Slider Demos + + + + + + + diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/slider/multiple-vertical.html b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/slider/multiple-vertical.html new file mode 100755 index 000000000..5a529b287 --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/slider/multiple-vertical.html @@ -0,0 +1,69 @@ + + + + + jQuery UI Slider - Multiple sliders + + + + + + + + + + + + +

    + + Master volume +

    + +
    + +

    + + Graphic EQ +

    + +
    + 88 + 77 + 55 + 33 + 40 + 45 + 70 +
    + +
    +

    Combine horizontal and vertical sliders, each with their own options, to create the UI for a music player.

    +
    + + diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/slider/range-vertical.html b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/slider/range-vertical.html new file mode 100755 index 000000000..8f6da21da --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/slider/range-vertical.html @@ -0,0 +1,41 @@ + + + + + jQuery UI Slider - Vertical range slider + + + + + + + + + + + +

    + + +

    + +
    + +
    +

    Change the orientation of the range slider to vertical. Assign a height value via .height() or by setting the height through CSS, and set the orientation option to "vertical."

    +
    + + diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/slider/range.html b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/slider/range.html new file mode 100755 index 000000000..052c2f5a8 --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/slider/range.html @@ -0,0 +1,42 @@ + + + + + jQuery UI Slider - Range slider + + + + + + + + + + + +

    + + +

    + +
    + +
    +

    Set the range option to true to capture a range of values with two drag handles. The space between the handles is filled with a different background color to indicate those values are selected.

    +
    + + diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/slider/rangemax.html b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/slider/rangemax.html new file mode 100755 index 000000000..8107c66d2 --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/slider/rangemax.html @@ -0,0 +1,40 @@ + + + + + jQuery UI Slider - Range with fixed maximum + + + + + + + + + + + +

    + + +

    +
    + +
    +

    Fix the maximum value of the range slider so that the user can only select a minimum. Set the range option to "max."

    +
    + + diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/slider/rangemin.html b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/slider/rangemin.html new file mode 100755 index 000000000..5a0bed662 --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/slider/rangemin.html @@ -0,0 +1,41 @@ + + + + + jQuery UI Slider - Range with fixed minimum + + + + + + + + + + + +

    + + +

    + +
    + +
    +

    Fix the minimum value of the range slider so that the user can only select a maximum. Set the range option to "min."

    +
    + + diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/slider/side-scroll.html b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/slider/side-scroll.html new file mode 100755 index 000000000..4ca49b9c2 --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/slider/side-scroll.html @@ -0,0 +1,132 @@ + + + + + jQuery UI Slider - Slider scrollbar + + + + + + + + + + + + +
    +
    +
    1
    +
    2
    +
    3
    +
    4
    +
    5
    +
    6
    +
    7
    +
    8
    +
    9
    +
    10
    +
    11
    +
    12
    +
    13
    +
    14
    +
    15
    +
    16
    +
    17
    +
    18
    +
    19
    +
    20
    +
    +
    +
    +
    +
    + +
    +

    Use a slider to manipulate the positioning of content on the page. In this case, it acts as a scrollbar with the potential to capture values if needed.

    +
    + + diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/slider/slider-vertical.html b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/slider/slider-vertical.html new file mode 100755 index 000000000..45e93330d --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/slider/slider-vertical.html @@ -0,0 +1,42 @@ + + + + + jQuery UI Slider - Vertical slider + + + + + + + + + + + +

    + + +

    + +
    + +
    +

    Change the orientation of the slider to vertical. Assign a height value via .height() or by setting the height through CSS, and set the orientation option to "vertical."

    +
    + + diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/slider/steps.html b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/slider/steps.html new file mode 100755 index 000000000..7f1ec6314 --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/slider/steps.html @@ -0,0 +1,41 @@ + + + + + jQuery UI Slider - Snap to increments + + + + + + + + + + + +

    + + +

    + +
    + +
    +

    Increment slider values with the step option set to an integer, commonly a dividend of the slider's maximum value. The default increment is 1.

    +
    + + diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/sortable/connect-lists-through-tabs.html b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/sortable/connect-lists-through-tabs.html new file mode 100755 index 000000000..92ebb7e6f --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/sortable/connect-lists-through-tabs.html @@ -0,0 +1,72 @@ + + + + + jQuery UI Sortable - Connect lists with Tabs + + + + + + + + + + + + + + +
    + +
    +
      +
    • Item 1
    • +
    • Item 2
    • +
    • Item 3
    • +
    • Item 4
    • +
    • Item 5
    • +
    +
    +
    +
      +
    • Item 1
    • +
    • Item 2
    • +
    • Item 3
    • +
    • Item 4
    • +
    • Item 5
    • +
    +
    +
    + +
    +

    Sort items from one list into another and vice versa, by dropping the list item on the appropriate tab above.

    +
    + + diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/sortable/connect-lists.html b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/sortable/connect-lists.html new file mode 100755 index 000000000..1ed6165da --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/sortable/connect-lists.html @@ -0,0 +1,52 @@ + + + + + jQuery UI Sortable - Connect lists + + + + + + + + + + + + +
      +
    • Item 1
    • +
    • Item 2
    • +
    • Item 3
    • +
    • Item 4
    • +
    • Item 5
    • +
    + +
      +
    • Item 1
    • +
    • Item 2
    • +
    • Item 3
    • +
    • Item 4
    • +
    • Item 5
    • +
    + +
    +

    + Sort items from one list into another and vice versa, by passing a selector into + the connectWith option. The simplest way to do this is to + group all related lists with a CSS class, and then pass that class into the + sortable function (i.e., connectWith: '.myclass'). +

    +
    + + diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/sortable/default.html b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/sortable/default.html new file mode 100755 index 000000000..9fc4afabe --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/sortable/default.html @@ -0,0 +1,45 @@ + + + + + jQuery UI Sortable - Default functionality + + + + + + + + + + + + +
      +
    • Item 1
    • +
    • Item 2
    • +
    • Item 3
    • +
    • Item 4
    • +
    • Item 5
    • +
    • Item 6
    • +
    • Item 7
    • +
    + +
    +

    + Enable a group of DOM elements to be sortable. Click on and drag an + element to a new spot within the list, and the other items will adjust to + fit. By default, sortable items share draggable properties. +

    +
    + + diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/sortable/delay-start.html b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/sortable/delay-start.html new file mode 100755 index 000000000..3afe83ae0 --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/sortable/delay-start.html @@ -0,0 +1,61 @@ + + + + + jQuery UI Sortable - Delay start + + + + + + + + + + + + +

    Time delay of 300ms:

    + +
      +
    • Item 1
    • +
    • Item 2
    • +
    • Item 3
    • +
    • Item 4
    • +
    + +

    Distance delay of 15px:

    + +
      +
    • Item 1
    • +
    • Item 2
    • +
    • Item 3
    • +
    • Item 4
    • +
    + +
    +

    + Prevent accidental sorting either by delay (time) or distance. Set a number of + milliseconds the element needs to be dragged before sorting starts + with the delay option. Set a distance in pixels the element + needs to be dragged before sorting starts with the distance + option. +

    +
    + + diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/sortable/display-grid.html b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/sortable/display-grid.html new file mode 100755 index 000000000..e471a58b0 --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/sortable/display-grid.html @@ -0,0 +1,48 @@ + + + + + jQuery UI Sortable - Display as grid + + + + + + + + + + + + +
      +
    • 1
    • +
    • 2
    • +
    • 3
    • +
    • 4
    • +
    • 5
    • +
    • 6
    • +
    • 7
    • +
    • 8
    • +
    • 9
    • +
    • 10
    • +
    • 11
    • +
    • 12
    • +
    + +
    +

    + To arrange sortable items as a grid, give them identical dimensions and + float them using CSS. +

    +
    + + diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/sortable/empty-lists.html b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/sortable/empty-lists.html new file mode 100755 index 000000000..4d5d425b7 --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/sortable/empty-lists.html @@ -0,0 +1,63 @@ + + + + + jQuery UI Sortable - Handle empty lists + + + + + + + + + + + + +
      +
    • Can be dropped..
    • +
    • ..on an empty list
    • +
    • Item 3
    • +
    • Item 4
    • +
    • Item 5
    • +
    + +
      +
    • Cannot be dropped..
    • +
    • ..on an empty list
    • +
    • Item 3
    • +
    • Item 4
    • +
    • Item 5
    • +
    + +
      +
    + +
    + +
    +

    + Prevent all items in a list from being dropped into a separate, empty list + using the dropOnEmpty option set to false. By default, + sortable items can be dropped on empty lists. +

    +
    + + diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/sortable/index.html b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/sortable/index.html new file mode 100755 index 000000000..66b0b5ced --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/sortable/index.html @@ -0,0 +1,22 @@ + + + + + jQuery UI Sortable Demos + + + + + + + diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/sortable/items.html b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/sortable/items.html new file mode 100755 index 000000000..7ecc616ae --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/sortable/items.html @@ -0,0 +1,64 @@ + + + + + jQuery UI Sortable - Include / exclude items + + + + + + + + + + + + +

    Specify which items are sortable:

    + +
      +
    • Item 1
    • +
    • (I'm not sortable or a drop target)
    • +
    • (I'm not sortable or a drop target)
    • +
    • Item 4
    • +
    + +

    Cancel sorting (but keep as drop targets):

    + +
      +
    • Item 1
    • +
    • (I'm not sortable)
    • +
    • (I'm not sortable)
    • +
    • Item 4
    • +
    + +
    +

    + Specify which items are eligible to sort by passing a jQuery selector into + the items option. Items excluded from this option are not + sortable, nor are they valid targets for sortable items. +

    +

    + To only prevent sorting on certain items, pass a jQuery selector into the + cancel option. Cancelled items remain valid sort targets for + others. +

    +
    + + diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/sortable/placeholder.html b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/sortable/placeholder.html new file mode 100755 index 000000000..158226672 --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/sortable/placeholder.html @@ -0,0 +1,50 @@ + + + + + jQuery UI Sortable - Drop placeholder + + + + + + + + + + + + +
      +
    • Item 1
    • +
    • Item 2
    • +
    • Item 3
    • +
    • Item 4
    • +
    • Item 5
    • +
    • Item 6
    • +
    • Item 7
    • +
    + +
    +

    + When dragging a sortable item to a new location, other items will make room + for the that item by shifting to allow white space between them. Pass a + class into the placeholder option to style that space to + be visible. Use the boolean forcePlaceholderSize option + to set dimensions on the placeholder. +

    +
    + + diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/sortable/portlets.html b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/sortable/portlets.html new file mode 100755 index 000000000..545c4df59 --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/sortable/portlets.html @@ -0,0 +1,90 @@ + + + + + jQuery UI Sortable - Portlets + + + + + + + + + + + + +
    + +
    +
    Feeds
    +
    Lorem ipsum dolor sit amet, consectetuer adipiscing elit
    +
    + +
    +
    News
    +
    Lorem ipsum dolor sit amet, consectetuer adipiscing elit
    +
    + +
    + +
    + +
    +
    Shopping
    +
    Lorem ipsum dolor sit amet, consectetuer adipiscing elit
    +
    + +
    + +
    + +
    +
    Links
    +
    Lorem ipsum dolor sit amet, consectetuer adipiscing elit
    +
    + +
    +
    Images
    +
    Lorem ipsum dolor sit amet, consectetuer adipiscing elit
    +
    + +
    + +
    +

    + Enable portlets (styled divs) as sortables and use the connectWith + option to allow sorting between columns. +

    +
    + + diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/spinner/currency.html b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/spinner/currency.html new file mode 100755 index 000000000..f15511ab7 --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/spinner/currency.html @@ -0,0 +1,52 @@ + + + + + jQuery UI Spinner - Default functionality + + + + + + + + + + + + + + + +

    + + +

    +

    + + +

    + +
    +

    Example of a donation form, with currency selection and amount spinner.

    +
    + + diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/spinner/decimal.html b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/spinner/decimal.html new file mode 100755 index 000000000..3ab3ea073 --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/spinner/decimal.html @@ -0,0 +1,56 @@ + + + + + jQuery UI Spinner - Decimal + + + + + + + + + + + + + + + +

    + + +

    +

    + + +

    + +
    +

    + Example of a decimal spinner. Step is set to 0.01. +
    The code handling the culture change reads the current spinner value, + then changes the culture, then sets the value again, resulting in an updated + formatting, based on the new culture. +

    +
    + + diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/spinner/default.html b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/spinner/default.html new file mode 100755 index 000000000..a79f4d45d --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/spinner/default.html @@ -0,0 +1,64 @@ + + + + + jQuery UI Spinner - Default functionality + + + + + + + + + + + + +

    + + +

    + +

    + + +

    + +

    + + +

    + +
    +

    Default spinner.

    +
    + + diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/spinner/index.html b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/spinner/index.html new file mode 100755 index 000000000..f3c74d0b1 --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/spinner/index.html @@ -0,0 +1,19 @@ + + + + + jQuery UI Spinner Demos + + + + + + + diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/spinner/latlong.html b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/spinner/latlong.html new file mode 100755 index 000000000..4a662b42e --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/spinner/latlong.html @@ -0,0 +1,57 @@ + + + + + jQuery UI Spinner - Map + + + + + + + + + + + + + + + + +
    + + + +
    + +
    +

    Google Maps integration, using spinners to change latidude and longitude.

    +
    + + diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/spinner/overflow.html b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/spinner/overflow.html new file mode 100755 index 000000000..6889f5feb --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/spinner/overflow.html @@ -0,0 +1,44 @@ + + + + + jQuery UI Spinner - Overflow + + + + + + + + + + + + +

    + + +

    + +
    +

    +Overflowing spinner restricted to a range of -10 to 10. +For anything above 10, it'll overflow to -10, and the other way round. +

    +
    + + diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/spinner/time.html b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/spinner/time.html new file mode 100755 index 000000000..155a04fe9 --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/spinner/time.html @@ -0,0 +1,74 @@ + + + + + jQuery UI Spinner - Time + + + + + + + + + + + + + + +

    + + +

    +

    + + +

    + +
    +

    + A custom widget extending spinner. Use the Globalization plugin to parse and output + a timestamp, with custom step and page options. Cursor up/down spins minutes, page up/down + spins hours. +

    +
    + + diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/tabs/ajax.html b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/tabs/ajax.html new file mode 100755 index 000000000..a7146c7af --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/tabs/ajax.html @@ -0,0 +1,46 @@ + + + + + jQuery UI Tabs - Content via Ajax + + + + + + + + + + +
    + +
    +

    Proin elit arcu, rutrum commodo, vehicula tempus, commodo a, risus. Curabitur nec arcu. Donec sollicitudin mi sit amet mauris. Nam elementum quam ullamcorper ante. Etiam aliquet massa et lorem. Mauris dapibus lacus auctor risus. Aenean tempor ullamcorper leo. Vivamus sed magna quis ligula eleifend adipiscing. Duis orci. Aliquam sodales tortor vitae ipsum. Aliquam nulla. Duis aliquam molestie erat. Ut et mauris vel pede varius sollicitudin. Sed ut dolor nec orci tincidunt interdum. Phasellus ipsum. Nunc tristique tempus lectus.

    +
    +
    + +
    +

    Fetch external content via Ajax for the tabs by setting an href value in the tab links. While the Ajax request is waiting for a response, the tab label changes to say "Loading...", then returns to the normal label once loaded.

    +

    Tabs 3 and 4 demonstrate slow-loading and broken AJAX tabs, and how to handle serverside errors in those cases. Note: These two require a webserver to interpret PHP. They won't work from the filesystem.

    +
    + + diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/tabs/ajax/content1.html b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/tabs/ajax/content1.html new file mode 100755 index 000000000..472bdfb36 --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/tabs/ajax/content1.html @@ -0,0 +1,4 @@ +

    This content was loaded via ajax.

    +

    Proin elit arcu, rutrum commodo, vehicula tempus, commodo a, risus. Curabitur nec arcu. Donec sollicitudin mi sit amet mauris. Nam elementum quam ullamcorper ante. Etiam aliquet massa et lorem. Mauris dapibus lacus auctor risus. Aenean tempor ullamcorper leo. Vivamus sed magna quis ligula eleifend adipiscing. Duis orci. Aliquam sodales tortor vitae ipsum. Aliquam nulla. Duis aliquam molestie erat. Ut et mauris vel pede varius sollicitudin. Sed ut dolor nec orci tincidunt interdum. Phasellus ipsum. Nunc tristique tempus lectus.

    +

    Mauris vitae ante. Curabitur augue. Nulla purus nibh, lobortis ut, feugiat at, aliquam id, purus. Sed venenatis, lorem venenatis volutpat commodo, purus quam lacinia justo, mattis interdum pede pede a odio. Fusce nibh. Morbi nisl mauris, dapibus in, tristique eget, accumsan et, pede. Donec mauris risus, pulvinar ut, faucibus eu, mollis in, nunc. In augue massa, commodo a, cursus vehicula, varius eu, dui. Suspendisse sodales suscipit lorem. Morbi malesuada, eros quis condimentum dignissim, lectus nibh tristique urna, non bibendum diam massa vel risus. Morbi suscipit. Proin egestas, eros at scelerisque scelerisque, dolor lacus fringilla lacus, ut ullamcorper mi magna at quam. Aliquam sed elit. Aliquam turpis purus, congue quis, iaculis id, ullamcorper sit amet, justo. Maecenas sed mauris. Proin magna justo, interdum in, tincidunt eu, viverra eu, turpis. Suspendisse mollis. In magna. Phasellus pellentesque, urna pellentesque convallis pellentesque, augue sem blandit pede, at rhoncus libero nisl a odio.

    +

    Sed vitae nibh non magna semper tempor. Duis dolor. Nam congue laoreet arcu. Fusce lobortis enim quis ligula. Maecenas commodo odio id mi. Maecenas scelerisque tellus eu odio. Etiam dolor purus, lacinia a, imperdiet in, aliquam et, eros. In pellentesque. Nullam ac massa. Integer et turpis. Ut quam augue, congue non, imperdiet id, eleifend ac, nisi. Etiam ac arcu. Cras iaculis accumsan erat. Nullam vulputate sapien nec nisi pretium rhoncus. Aliquam a nibh. Vivamus est ante, fermentum a, tincidunt ut, imperdiet nec, velit. Aenean non tortor. Sed nec mauris eget tellus condimentum rutrum.

    \ No newline at end of file diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/tabs/ajax/content2.html b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/tabs/ajax/content2.html new file mode 100755 index 000000000..18b03e40b --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/tabs/ajax/content2.html @@ -0,0 +1,4 @@ +

    This other content was loaded via ajax.

    +

    Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aenean nec turpis justo, et facilisis ligula. In congue interdum odio, a scelerisque eros posuere ac. Aenean massa tellus, dictum sit amet laoreet ut, aliquam in orci. Duis eu aliquam ligula. Nullam vel placerat ligula. Fusce venenatis viverra dictum. Phasellus dui dolor, imperdiet in sodales at, mattis sed libero. Morbi ac ipsum ligula. Quisque suscipit dui vel diam pretium nec cursus lacus malesuada. Donec sollicitudin, eros eget dignissim mollis, risus leo feugiat tellus, vel posuere nisl ipsum eu erat. Quisque posuere lacinia imperdiet. Quisque nunc leo, elementum quis ultricies et, vehicula sit amet turpis. Nullam sed nunc nec nibh condimentum mattis. Quisque sed ligula sit amet nisi ultricies bibendum eget id nisi.

    +

    Proin ut erat vel nunc tincidunt commodo. Curabitur feugiat, nisi et vehicula viverra, nisl orci eleifend arcu, sed blandit lectus nisl quis nisi. In hac habitasse platea dictumst. In hac habitasse platea dictumst. Aenean rutrum gravida velit ac imperdiet. Integer vitae arcu risus. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Proin tincidunt orci at leo egestas porta. Vivamus ac augue et enim bibendum hendrerit ut id urna. Donec sollicitudin pulvinar turpis vitae scelerisque. Etiam tempor porttitor est sed blandit. Phasellus varius consequat leo eget tincidunt. Aliquam ac dui lectus. In et consectetur orci. Duis posuere nulla ac turpis faucibus vestibulum. Sed ut velit et dolor rhoncus dapibus. Sed sit amet pellentesque est.

    +

    Nam in volutpat orci. Morbi sit amet orci in erat egestas dignissim. Etiam mi sapien, tempus sed iaculis a, adipiscing quis tellus. Suspendisse potenti. Nam malesuada tristique vestibulum. In tempor tellus dignissim neque consectetur eu vestibulum nisl pellentesque. Phasellus ultrices cursus velit, id aliquam nisl fringilla quis. Cras varius elit sed urna ultrices congue. Sed ornare odio sed velit pellentesque id varius nisl sodales. Sed auctor ligula egestas mi pharetra ut consectetur erat pharetra.

    \ No newline at end of file diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/tabs/ajax/content3-slow.php b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/tabs/ajax/content3-slow.php new file mode 100755 index 000000000..7ad43ec06 --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/tabs/ajax/content3-slow.php @@ -0,0 +1,7 @@ + +

    This content was loaded via ajax, though it took a second.

    +

    Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aenean nec turpis justo, et facilisis ligula. In congue interdum odio, a scelerisque eros posuere ac. Aenean massa tellus, dictum sit amet laoreet ut, aliquam in orci. Duis eu aliquam ligula. Nullam vel placerat ligula. Fusce venenatis viverra dictum. Phasellus dui dolor, imperdiet in sodales at, mattis sed libero. Morbi ac ipsum ligula. Quisque suscipit dui vel diam pretium nec cursus lacus malesuada. Donec sollicitudin, eros eget dignissim mollis, risus leo feugiat tellus, vel posuere nisl ipsum eu erat. Quisque posuere lacinia imperdiet. Quisque nunc leo, elementum quis ultricies et, vehicula sit amet turpis. Nullam sed nunc nec nibh condimentum mattis. Quisque sed ligula sit amet nisi ultricies bibendum eget id nisi.

    +

    Proin ut erat vel nunc tincidunt commodo. Curabitur feugiat, nisi et vehicula viverra, nisl orci eleifend arcu, sed blandit lectus nisl quis nisi. In hac habitasse platea dictumst. In hac habitasse platea dictumst. Aenean rutrum gravida velit ac imperdiet. Integer vitae arcu risus. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Proin tincidunt orci at leo egestas porta. Vivamus ac augue et enim bibendum hendrerit ut id urna. Donec sollicitudin pulvinar turpis vitae scelerisque. Etiam tempor porttitor est sed blandit. Phasellus varius consequat leo eget tincidunt. Aliquam ac dui lectus. In et consectetur orci. Duis posuere nulla ac turpis faucibus vestibulum. Sed ut velit et dolor rhoncus dapibus. Sed sit amet pellentesque est.

    +

    Nam in volutpat orci. Morbi sit amet orci in erat egestas dignissim. Etiam mi sapien, tempus sed iaculis a, adipiscing quis tellus. Suspendisse potenti. Nam malesuada tristique vestibulum. In tempor tellus dignissim neque consectetur eu vestibulum nisl pellentesque. Phasellus ultrices cursus velit, id aliquam nisl fringilla quis. Cras varius elit sed urna ultrices congue. Sed ornare odio sed velit pellentesque id varius nisl sodales. Sed auctor ligula egestas mi pharetra ut consectetur erat pharetra.

    \ No newline at end of file diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/tabs/ajax/content4-broken.php b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/tabs/ajax/content4-broken.php new file mode 100755 index 000000000..55ea2fe9f --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/tabs/ajax/content4-broken.php @@ -0,0 +1,3 @@ + \ No newline at end of file diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/tabs/bottom.html b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/tabs/bottom.html new file mode 100755 index 000000000..1618166d3 --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/tabs/bottom.html @@ -0,0 +1,58 @@ + + + + + jQuery UI Tabs - Tabs at bottom + + + + + + + + + + + +
    + +
    +
    +

    Proin elit arcu, rutrum commodo, vehicula tempus, commodo a, risus. Curabitur nec arcu. Donec sollicitudin mi sit amet mauris. Nam elementum quam ullamcorper ante. Etiam aliquet massa et lorem. Mauris dapibus lacus auctor risus. Aenean tempor ullamcorper leo. Vivamus sed magna quis ligula eleifend adipiscing. Duis orci. Aliquam sodales tortor vitae ipsum. Aliquam nulla. Duis aliquam molestie erat. Ut et mauris vel pede varius sollicitudin. Sed ut dolor nec orci tincidunt interdum. Phasellus ipsum. Nunc tristique tempus lectus.

    +
    +
    +

    Morbi tincidunt, dui sit amet facilisis feugiat, odio metus gravida ante, ut pharetra massa metus id nunc. Duis scelerisque molestie turpis. Sed fringilla, massa eget luctus malesuada, metus eros molestie lectus, ut tempus eros massa ut dolor. Aenean aliquet fringilla sem. Suspendisse sed ligula in ligula suscipit aliquam. Praesent in eros vestibulum mi adipiscing adipiscing. Morbi facilisis. Curabitur ornare consequat nunc. Aenean vel metus. Ut posuere viverra nulla. Aliquam erat volutpat. Pellentesque convallis. Maecenas feugiat, tellus pellentesque pretium posuere, felis lorem euismod felis, eu ornare leo nisi vel felis. Mauris consectetur tortor et purus.

    +
    +
    +

    Mauris eleifend est et turpis. Duis id erat. Suspendisse potenti. Aliquam vulputate, pede vel vehicula accumsan, mi neque rutrum erat, eu congue orci lorem eget lorem. Vestibulum non ante. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Fusce sodales. Quisque eu urna vel enim commodo pellentesque. Praesent eu risus hendrerit ligula tempus pretium. Curabitur lorem enim, pretium nec, feugiat nec, luctus a, lacus.

    +

    Duis cursus. Maecenas ligula eros, blandit nec, pharetra at, semper at, magna. Nullam ac lacus. Nulla facilisi. Praesent viverra justo vitae neque. Praesent blandit adipiscing velit. Suspendisse potenti. Donec mattis, pede vel pharetra blandit, magna ligula faucibus eros, id euismod lacus dolor eget odio. Nam scelerisque. Donec non libero sed nulla mattis commodo. Ut sagittis. Donec nisi lectus, feugiat porttitor, tempor ac, tempor vitae, pede. Aenean vehicula velit eu tellus interdum rutrum. Maecenas commodo. Pellentesque nec elit. Fusce in lacus. Vivamus a libero vitae lectus hendrerit hendrerit.

    +
    +
    + +
    +

    With some additional CSS (for positioning) and JS (to put the right classes on elements) the tabs can be placed below their content.

    +
    + + diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/tabs/collapsible.html b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/tabs/collapsible.html new file mode 100755 index 000000000..7faac574d --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/tabs/collapsible.html @@ -0,0 +1,48 @@ + + + + + jQuery UI Tabs - Collapse content + + + + + + + + + + +
    + +
    +

    Click this tab again to close the content pane.

    +

    Proin elit arcu, rutrum commodo, vehicula tempus, commodo a, risus. Curabitur nec arcu. Donec sollicitudin mi sit amet mauris. Nam elementum quam ullamcorper ante. Etiam aliquet massa et lorem. Mauris dapibus lacus auctor risus. Aenean tempor ullamcorper leo. Vivamus sed magna quis ligula eleifend adipiscing. Duis orci. Aliquam sodales tortor vitae ipsum. Aliquam nulla. Duis aliquam molestie erat. Ut et mauris vel pede varius sollicitudin. Sed ut dolor nec orci tincidunt interdum. Phasellus ipsum. Nunc tristique tempus lectus.

    +
    +
    +

    Click this tab again to close the content pane.

    +

    Morbi tincidunt, dui sit amet facilisis feugiat, odio metus gravida ante, ut pharetra massa metus id nunc. Duis scelerisque molestie turpis. Sed fringilla, massa eget luctus malesuada, metus eros molestie lectus, ut tempus eros massa ut dolor. Aenean aliquet fringilla sem. Suspendisse sed ligula in ligula suscipit aliquam. Praesent in eros vestibulum mi adipiscing adipiscing. Morbi facilisis. Curabitur ornare consequat nunc. Aenean vel metus. Ut posuere viverra nulla. Aliquam erat volutpat. Pellentesque convallis. Maecenas feugiat, tellus pellentesque pretium posuere, felis lorem euismod felis, eu ornare leo nisi vel felis. Mauris consectetur tortor et purus.

    +
    +
    +

    Click this tab again to close the content pane.

    +

    Duis cursus. Maecenas ligula eros, blandit nec, pharetra at, semper at, magna. Nullam ac lacus. Nulla facilisi. Praesent viverra justo vitae neque. Praesent blandit adipiscing velit. Suspendisse potenti. Donec mattis, pede vel pharetra blandit, magna ligula faucibus eros, id euismod lacus dolor eget odio. Nam scelerisque. Donec non libero sed nulla mattis commodo. Ut sagittis. Donec nisi lectus, feugiat porttitor, tempor ac, tempor vitae, pede. Aenean vehicula velit eu tellus interdum rutrum. Maecenas commodo. Pellentesque nec elit. Fusce in lacus. Vivamus a libero vitae lectus hendrerit hendrerit.

    +
    +
    + +
    +

    Click the selected tab to toggle its content closed/open. To enable this functionality, set the collapsible option to true.

    +
    collapsible: true
    +
    +
    + + diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/tabs/default.html b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/tabs/default.html new file mode 100755 index 000000000..5b95757ea --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/tabs/default.html @@ -0,0 +1,42 @@ + + + + + jQuery UI Tabs - Default functionality + + + + + + + + + + +
    + +
    +

    Proin elit arcu, rutrum commodo, vehicula tempus, commodo a, risus. Curabitur nec arcu. Donec sollicitudin mi sit amet mauris. Nam elementum quam ullamcorper ante. Etiam aliquet massa et lorem. Mauris dapibus lacus auctor risus. Aenean tempor ullamcorper leo. Vivamus sed magna quis ligula eleifend adipiscing. Duis orci. Aliquam sodales tortor vitae ipsum. Aliquam nulla. Duis aliquam molestie erat. Ut et mauris vel pede varius sollicitudin. Sed ut dolor nec orci tincidunt interdum. Phasellus ipsum. Nunc tristique tempus lectus.

    +
    +
    +

    Morbi tincidunt, dui sit amet facilisis feugiat, odio metus gravida ante, ut pharetra massa metus id nunc. Duis scelerisque molestie turpis. Sed fringilla, massa eget luctus malesuada, metus eros molestie lectus, ut tempus eros massa ut dolor. Aenean aliquet fringilla sem. Suspendisse sed ligula in ligula suscipit aliquam. Praesent in eros vestibulum mi adipiscing adipiscing. Morbi facilisis. Curabitur ornare consequat nunc. Aenean vel metus. Ut posuere viverra nulla. Aliquam erat volutpat. Pellentesque convallis. Maecenas feugiat, tellus pellentesque pretium posuere, felis lorem euismod felis, eu ornare leo nisi vel felis. Mauris consectetur tortor et purus.

    +
    +
    +

    Mauris eleifend est et turpis. Duis id erat. Suspendisse potenti. Aliquam vulputate, pede vel vehicula accumsan, mi neque rutrum erat, eu congue orci lorem eget lorem. Vestibulum non ante. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Fusce sodales. Quisque eu urna vel enim commodo pellentesque. Praesent eu risus hendrerit ligula tempus pretium. Curabitur lorem enim, pretium nec, feugiat nec, luctus a, lacus.

    +

    Duis cursus. Maecenas ligula eros, blandit nec, pharetra at, semper at, magna. Nullam ac lacus. Nulla facilisi. Praesent viverra justo vitae neque. Praesent blandit adipiscing velit. Suspendisse potenti. Donec mattis, pede vel pharetra blandit, magna ligula faucibus eros, id euismod lacus dolor eget odio. Nam scelerisque. Donec non libero sed nulla mattis commodo. Ut sagittis. Donec nisi lectus, feugiat porttitor, tempor ac, tempor vitae, pede. Aenean vehicula velit eu tellus interdum rutrum. Maecenas commodo. Pellentesque nec elit. Fusce in lacus. Vivamus a libero vitae lectus hendrerit hendrerit.

    +
    +
    + +
    +

    Click tabs to swap between content that is broken into logical sections.

    +
    + + diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/tabs/index.html b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/tabs/index.html new file mode 100755 index 000000000..779dfd2da --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/tabs/index.html @@ -0,0 +1,20 @@ + + + + + jQuery UI Tabs Demos + + + + + + + diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/tabs/manipulation.html b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/tabs/manipulation.html new file mode 100755 index 000000000..67ed3d304 --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/tabs/manipulation.html @@ -0,0 +1,114 @@ + + + + + jQuery UI Tabs - Simple manipulation + + + + + + + + + + + + + + +
    +
    +
    + + + + +
    +
    +
    + + + +
    + +
    +

    Proin elit arcu, rutrum commodo, vehicula tempus, commodo a, risus. Curabitur nec arcu. Donec sollicitudin mi sit amet mauris. Nam elementum quam ullamcorper ante. Etiam aliquet massa et lorem. Mauris dapibus lacus auctor risus. Aenean tempor ullamcorper leo. Vivamus sed magna quis ligula eleifend adipiscing. Duis orci. Aliquam sodales tortor vitae ipsum. Aliquam nulla. Duis aliquam molestie erat. Ut et mauris vel pede varius sollicitudin. Sed ut dolor nec orci tincidunt interdum. Phasellus ipsum. Nunc tristique tempus lectus.

    +
    +
    + +
    +

    Simple tabs adding and removing.

    +
    + + diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/tabs/mouseover.html b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/tabs/mouseover.html new file mode 100755 index 000000000..631fd84c0 --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/tabs/mouseover.html @@ -0,0 +1,44 @@ + + + + + jQuery UI Tabs - Open on mouseover + + + + + + + + + + +
    + +
    +

    Proin elit arcu, rutrum commodo, vehicula tempus, commodo a, risus. Curabitur nec arcu. Donec sollicitudin mi sit amet mauris. Nam elementum quam ullamcorper ante. Etiam aliquet massa et lorem. Mauris dapibus lacus auctor risus. Aenean tempor ullamcorper leo. Vivamus sed magna quis ligula eleifend adipiscing. Duis orci. Aliquam sodales tortor vitae ipsum. Aliquam nulla. Duis aliquam molestie erat. Ut et mauris vel pede varius sollicitudin. Sed ut dolor nec orci tincidunt interdum. Phasellus ipsum. Nunc tristique tempus lectus.

    +
    +
    +

    Morbi tincidunt, dui sit amet facilisis feugiat, odio metus gravida ante, ut pharetra massa metus id nunc. Duis scelerisque molestie turpis. Sed fringilla, massa eget luctus malesuada, metus eros molestie lectus, ut tempus eros massa ut dolor. Aenean aliquet fringilla sem. Suspendisse sed ligula in ligula suscipit aliquam. Praesent in eros vestibulum mi adipiscing adipiscing. Morbi facilisis. Curabitur ornare consequat nunc. Aenean vel metus. Ut posuere viverra nulla. Aliquam erat volutpat. Pellentesque convallis. Maecenas feugiat, tellus pellentesque pretium posuere, felis lorem euismod felis, eu ornare leo nisi vel felis. Mauris consectetur tortor et purus.

    +
    +
    +

    Mauris eleifend est et turpis. Duis id erat. Suspendisse potenti. Aliquam vulputate, pede vel vehicula accumsan, mi neque rutrum erat, eu congue orci lorem eget lorem. Vestibulum non ante. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Fusce sodales. Quisque eu urna vel enim commodo pellentesque. Praesent eu risus hendrerit ligula tempus pretium. Curabitur lorem enim, pretium nec, feugiat nec, luctus a, lacus.

    +

    Duis cursus. Maecenas ligula eros, blandit nec, pharetra at, semper at, magna. Nullam ac lacus. Nulla facilisi. Praesent viverra justo vitae neque. Praesent blandit adipiscing velit. Suspendisse potenti. Donec mattis, pede vel pharetra blandit, magna ligula faucibus eros, id euismod lacus dolor eget odio. Nam scelerisque. Donec non libero sed nulla mattis commodo. Ut sagittis. Donec nisi lectus, feugiat porttitor, tempor ac, tempor vitae, pede. Aenean vehicula velit eu tellus interdum rutrum. Maecenas commodo. Pellentesque nec elit. Fusce in lacus. Vivamus a libero vitae lectus hendrerit hendrerit.

    +
    +
    + +
    +

    Toggle sections open/closed on mouseover with the event option. The default value for event is "click."

    +
    + + diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/tabs/sortable.html b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/tabs/sortable.html new file mode 100755 index 000000000..59a0ba963 --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/tabs/sortable.html @@ -0,0 +1,51 @@ + + + + + jQuery UI Tabs - Sortable + + + + + + + + + + + + +
    + +
    +

    Proin elit arcu, rutrum commodo, vehicula tempus, commodo a, risus. Curabitur nec arcu. Donec sollicitudin mi sit amet mauris. Nam elementum quam ullamcorper ante. Etiam aliquet massa et lorem. Mauris dapibus lacus auctor risus. Aenean tempor ullamcorper leo. Vivamus sed magna quis ligula eleifend adipiscing. Duis orci. Aliquam sodales tortor vitae ipsum. Aliquam nulla. Duis aliquam molestie erat. Ut et mauris vel pede varius sollicitudin. Sed ut dolor nec orci tincidunt interdum. Phasellus ipsum. Nunc tristique tempus lectus.

    +
    +
    +

    Morbi tincidunt, dui sit amet facilisis feugiat, odio metus gravida ante, ut pharetra massa metus id nunc. Duis scelerisque molestie turpis. Sed fringilla, massa eget luctus malesuada, metus eros molestie lectus, ut tempus eros massa ut dolor. Aenean aliquet fringilla sem. Suspendisse sed ligula in ligula suscipit aliquam. Praesent in eros vestibulum mi adipiscing adipiscing. Morbi facilisis. Curabitur ornare consequat nunc. Aenean vel metus. Ut posuere viverra nulla. Aliquam erat volutpat. Pellentesque convallis. Maecenas feugiat, tellus pellentesque pretium posuere, felis lorem euismod felis, eu ornare leo nisi vel felis. Mauris consectetur tortor et purus.

    +
    +
    +

    Mauris eleifend est et turpis. Duis id erat. Suspendisse potenti. Aliquam vulputate, pede vel vehicula accumsan, mi neque rutrum erat, eu congue orci lorem eget lorem. Vestibulum non ante. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Fusce sodales. Quisque eu urna vel enim commodo pellentesque. Praesent eu risus hendrerit ligula tempus pretium. Curabitur lorem enim, pretium nec, feugiat nec, luctus a, lacus.

    +

    Duis cursus. Maecenas ligula eros, blandit nec, pharetra at, semper at, magna. Nullam ac lacus. Nulla facilisi. Praesent viverra justo vitae neque. Praesent blandit adipiscing velit. Suspendisse potenti. Donec mattis, pede vel pharetra blandit, magna ligula faucibus eros, id euismod lacus dolor eget odio. Nam scelerisque. Donec non libero sed nulla mattis commodo. Ut sagittis. Donec nisi lectus, feugiat porttitor, tempor ac, tempor vitae, pede. Aenean vehicula velit eu tellus interdum rutrum. Maecenas commodo. Pellentesque nec elit. Fusce in lacus. Vivamus a libero vitae lectus hendrerit hendrerit.

    +
    +
    + +
    +

    Drag the tabs above to re-order them.

    +

    Making tabs sortable is as simple as calling .sortable() on the .ui-tabs-nav element.

    +
    + + diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/tabs/vertical.html b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/tabs/vertical.html new file mode 100755 index 000000000..b68ec50c8 --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/tabs/vertical.html @@ -0,0 +1,54 @@ + + + + + jQuery UI Tabs - Vertical Tabs functionality + + + + + + + + + + + +
    + +
    +

    Content heading 1

    +

    Proin elit arcu, rutrum commodo, vehicula tempus, commodo a, risus. Curabitur nec arcu. Donec sollicitudin mi sit amet mauris. Nam elementum quam ullamcorper ante. Etiam aliquet massa et lorem. Mauris dapibus lacus auctor risus. Aenean tempor ullamcorper leo. Vivamus sed magna quis ligula eleifend adipiscing. Duis orci. Aliquam sodales tortor vitae ipsum. Aliquam nulla. Duis aliquam molestie erat. Ut et mauris vel pede varius sollicitudin. Sed ut dolor nec orci tincidunt interdum. Phasellus ipsum. Nunc tristique tempus lectus.

    +
    +
    +

    Content heading 2

    +

    Morbi tincidunt, dui sit amet facilisis feugiat, odio metus gravida ante, ut pharetra massa metus id nunc. Duis scelerisque molestie turpis. Sed fringilla, massa eget luctus malesuada, metus eros molestie lectus, ut tempus eros massa ut dolor. Aenean aliquet fringilla sem. Suspendisse sed ligula in ligula suscipit aliquam. Praesent in eros vestibulum mi adipiscing adipiscing. Morbi facilisis. Curabitur ornare consequat nunc. Aenean vel metus. Ut posuere viverra nulla. Aliquam erat volutpat. Pellentesque convallis. Maecenas feugiat, tellus pellentesque pretium posuere, felis lorem euismod felis, eu ornare leo nisi vel felis. Mauris consectetur tortor et purus.

    +
    +
    +

    Content heading 3

    +

    Mauris eleifend est et turpis. Duis id erat. Suspendisse potenti. Aliquam vulputate, pede vel vehicula accumsan, mi neque rutrum erat, eu congue orci lorem eget lorem. Vestibulum non ante. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Fusce sodales. Quisque eu urna vel enim commodo pellentesque. Praesent eu risus hendrerit ligula tempus pretium. Curabitur lorem enim, pretium nec, feugiat nec, luctus a, lacus.

    +

    Duis cursus. Maecenas ligula eros, blandit nec, pharetra at, semper at, magna. Nullam ac lacus. Nulla facilisi. Praesent viverra justo vitae neque. Praesent blandit adipiscing velit. Suspendisse potenti. Donec mattis, pede vel pharetra blandit, magna ligula faucibus eros, id euismod lacus dolor eget odio. Nam scelerisque. Donec non libero sed nulla mattis commodo. Ut sagittis. Donec nisi lectus, feugiat porttitor, tempor ac, tempor vitae, pede. Aenean vehicula velit eu tellus interdum rutrum. Maecenas commodo. Pellentesque nec elit. Fusce in lacus. Vivamus a libero vitae lectus hendrerit hendrerit.

    +
    +
    + +
    +

    Click tabs to swap between content that is broken into logical sections.

    +
    + + diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/tooltip/ajax/content1.html b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/tooltip/ajax/content1.html new file mode 100755 index 000000000..a1401b26d --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/tooltip/ajax/content1.html @@ -0,0 +1 @@ +

    This content was loaded via ajax.

    \ No newline at end of file diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/tooltip/ajax/content2.html b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/tooltip/ajax/content2.html new file mode 100755 index 000000000..f4132d731 --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/tooltip/ajax/content2.html @@ -0,0 +1 @@ +

    This other content was loaded via ajax.

    \ No newline at end of file diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/tooltip/custom-animation.html b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/tooltip/custom-animation.html new file mode 100755 index 000000000..774a9d2a7 --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/tooltip/custom-animation.html @@ -0,0 +1,54 @@ + + + + + jQuery UI Tooltip - Custom animation demo + + + + + + + + + + + + + +

    There are various ways to customize the animation of a tooltip.

    +

    You can use the show and +hide options.

    +

    You can also use the open event.

    + +
    +

    This demo shows how to customize animations using the show and hide options, +as well as the open event.

    +
    + + diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/tooltip/custom-content.html b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/tooltip/custom-content.html new file mode 100755 index 000000000..93172524a --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/tooltip/custom-content.html @@ -0,0 +1,80 @@ + + + + + jQuery UI Tooltip - Custom content + + + + + + + + + + + + +
    +
    +

    St. Stephen's Cathedral

    +

    Vienna, Austria

    +
    + + St. Stephen's Cathedral + +
    + +
    +
    +

    Tower Bridge

    +

    London, England

    +
    + + Tower Bridge + +
    + +

    All images are part of Wikimedia Commons +and are licensed under CC BY-SA 3.0 by the copyright holder.

    + +
    +

    Shows how to combine different event delegated tooltips into a single instance, by customizing the items and content options.

    +

    We realize you may want to interact with the map tooltips. This is a planned feature for a future version.

    +
    + + diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/tooltip/custom-style.html b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/tooltip/custom-style.html new file mode 100755 index 000000000..f18522e54 --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/tooltip/custom-style.html @@ -0,0 +1,95 @@ + + + + + jQuery UI Tooltip - Default functionality + + + + + + + + + + + + +

    Tooltips can be attached to any element. When you hover +the element with your mouse, the title attribute is displayed in a little box next to the element, just like a native tooltip.

    +

    But as it's not a native tooltip, it can be styled. Any themes built with +ThemeRoller +will also style tooltips accordingly.

    +

    Tooltips are also useful for form elements, to show some additional information in the context of each field.

    +

    +

    Hover the field to see the tooltip.

    + +
    +

    Hover the links above or use the tab key to cycle the focus on each element.

    +
    + + diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/tooltip/default.html b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/tooltip/default.html new file mode 100755 index 000000000..8392e5504 --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/tooltip/default.html @@ -0,0 +1,40 @@ + + + + + jQuery UI Tooltip - Default functionality + + + + + + + + + + + + +

    Tooltips can be attached to any element. When you hover +the element with your mouse, the title attribute is displayed in a little box next to the element, just like a native tooltip.

    +

    But as it's not a native tooltip, it can be styled. Any themes built with +ThemeRoller +will also style tooltips accordingly.

    +

    Tooltips are also useful for form elements, to show some additional information in the context of each field.

    +

    +

    Hover the field to see the tooltip.

    + +
    +

    Hover the links above or use the tab key to cycle the focus on each element.

    +
    + + diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/tooltip/forms.html b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/tooltip/forms.html new file mode 100755 index 000000000..da3affa2d --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/tooltip/forms.html @@ -0,0 +1,65 @@ + + + + + jQuery UI Tooltip - Default demo + + + + + + + + + + + + + +
    +
    +
    + + +
    +
    + + +
    +
    + + +
    +
    +
    + +
    +

    Use the button below to display the help texts, or just focus or mouseover the indivdual inputs.

    +

    A fixed width is defined in CSS to make the tooltips look consistent when displayed all at once.

    +
    + + diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/tooltip/images/st-stephens.jpg b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/tooltip/images/st-stephens.jpg new file mode 100755 index 000000000..30fc36d67 Binary files /dev/null and b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/tooltip/images/st-stephens.jpg differ diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/tooltip/images/tower-bridge.jpg b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/tooltip/images/tower-bridge.jpg new file mode 100755 index 000000000..d1e14d6d2 Binary files /dev/null and b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/tooltip/images/tower-bridge.jpg differ diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/tooltip/index.html b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/tooltip/index.html new file mode 100755 index 000000000..cebedd0c3 --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/tooltip/index.html @@ -0,0 +1,20 @@ + + + + + jQuery UI Tooltip Demos + + + + + + + diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/tooltip/tracking.html b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/tooltip/tracking.html new file mode 100755 index 000000000..1bb1c773a --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/tooltip/tracking.html @@ -0,0 +1,42 @@ + + + + + jQuery UI Tooltip - Track the mouse + + + + + + + + + + + + +

    Tooltips can be attached to any element. When you hover +the element with your mouse, the title attribute is displayed in a little box next to the element, just like a native tooltip.

    +

    But as it's not a native tooltip, it can be styled. Any themes built with +ThemeRoller +will also style tooltips accordingly.

    +

    Tooltips are also useful for form elements, to show some additional information in the context of each field.

    +

    +

    Hover the field to see the tooltip.

    + +
    +

    Here the tooltips are positioned relative to the mouse, and follow the mouse while it moves above the element.

    +
    + + diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/tooltip/video-player.html b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/tooltip/video-player.html new file mode 100755 index 000000000..8be3c52ef --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/tooltip/video-player.html @@ -0,0 +1,117 @@ + + + + + jQuery UI Tooltip - Video Player demo + + + + + + + + + + + + + + + + +
    Here Be Video (HTML5?)
    +
    + + + + +
    + + +
    + + +
    + +
    +

    A fake video player with like/share/stats button, each with a custom-styled tooltip.

    +
    + + diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/widget/default.html b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/widget/default.html new file mode 100755 index 000000000..5959bccdb --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/widget/default.html @@ -0,0 +1,178 @@ + + + + + jQuery UI Widget - Default functionality + + + + + + + + + + + + +
    +
    color me
    +
    color me
    +
    color me
    + + +
    + +
    +

    This demo shows a simple custom widget built using the widget factory (jquery.ui.widget.js).

    +

    The three boxes are initialized in different ways. Clicking them changes their background color. View source to see how it works, its heavily commented

    +
    + + diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/widget/index.html b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/widget/index.html new file mode 100755 index 000000000..d518b070d --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/demos/widget/index.html @@ -0,0 +1,14 @@ + + + + + jQuery UI Widget Demo + + + + + + + diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/docs/accordion.html b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/docs/accordion.html new file mode 100755 index 000000000..49e2ca857 --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/docs/accordion.html @@ -0,0 +1,392 @@ + + + + + jQuery UI accordion documentation + + + + + +

    QuickNav

    + +

    +Accordion Widgetversion added: 1.0 +

    +
    +

    Description: Convert a pair of headers and content panels into an accordion.

    +

    Options

    +

    activeType: Boolean or Integer +

    +
    +Default: 0 +
    +
    + Which panel is currently open. +
    +Multiple types supported:
      +
    • +Boolean: Setting active to false will collapse all panels. This requires the collapsible option to be true.
    • +
    • +Integer: The zero-based index of the panel that is active (open). A negative value selects panels going backward from the last panel.
    • +
    +
    +
    +

    animateType: Boolean or Number or String or Object +

    +
    +Default: {} +
    +
    If and how to animate changing panels.
    +Multiple types supported:
      +
    • +Boolean: A value of false will disable animations.
    • +
    • +Number: Duration in milliseconds with default easing.
    • +
    • +String: Name of easing to use with default duration.
    • +
    • +Object: Animation settings with easing and duration properties. +
        +
      • Can also contain a down property with any of the above options.
      • +
      • "Down" animations occur when the panel being activated has a lower index than the currently active panel.
      • +
      +
    • +
    +
    +
    +

    collapsibleType: Boolean +

    +
    +Default: false +
    +
    Whether all the sections can be closed at once. Allows collapsing the active section.
    +
    +
    +

    disabledType: Boolean +

    +
    +Default: false +
    +
    Disables the accordion if set to true.
    +
    +
    +

    eventType: String +

    +
    +Default: "click" +
    +
    The event that accordion headers will react to in order to activate the associated panel. Multiple events can be specificed, separated by a space.
    +
    +
    +

    headerType: Selector +

    +
    +Default: "> li > :first-child,> :not(li):even" +
    +
    +

    Selector for the header element, applied via .find() on the main accordion element. Content panels must be the sibling immedately after their associated headers.

    +
    +
    +
    +

    heightStyleType: String +

    +
    +Default: "auto" +
    +
    +

    Controls the height of the accordion and each panel. Possible values:

    +
      +
    • +"auto": All panels will be set to the height of the tallest panel.
    • +
    • +"fill": Expand to the available height based on the accordion's parent height.
    • +
    • +"content": Each panel will be only as tall as its content.
    • +
    +
    +
    +
    +

    iconsType: Object +

    +
    +Default: { "header": "ui-icon-triangle-1-e", "activeHeader": "ui-icon-triangle-1-s" } +
    +
    +

    Icons to use for headers, matching an icon defined by the jQuery UI CSS Framework. Set to false to have no icons displayed.

    +
      +
    • header (string, default: "ui-icon-triangle-1-e")
    • +
    • activeHeader (string, default: "ui-icon-triangle-1-s")
    • +
    +
    +

    Methods

    +

    destroy()

    +
    + Removes the accordion functionality completely. This will return the element back to its pre-init state. +
    +
    +
    +

    disable()

    +
    + Disables the accordion. +
    +
    +
    +

    enable()

    +
    + Enables the accordion. +
    +
    +
    +
    +

    option( optionName ) Returns: Object +

    +
    Gets the value currently associated with the specified optionName.
    +
    • +
      optionName
      +
      Type: String +
      +
      The name of the option to get.
      +
    +
    +
    +

    option() Returns: PlainObject +

    +
    Gets an object containing key/value pairs representing the current accordion options hash.
    +
    +
    +

    option( optionName, value )

    +
    Sets the value of the accordion option associated with the specified optionName.
    +
      +
    • +
      optionName
      +
      Type: String +
      +
      The name of the option to set.
      +
    • +
    • +
      value
      +
      Type: Object +
      +
      A value to set for the option.
      +
    • +
    +
    +
    +

    option( options )

    +
    Sets one or more options for the accordion.
    +
    • +
      options
      +
      Type: Object +
      +
      A map of option-value pairs to set.
      +
    +
    +
    +
    +

    refresh()

    +
    Recompute the height of the accordion panels. Results depend on the content and the heightStyle option.
    +
    +
    +

    widget() Returns: jQuery +

    +
    + Returns a jQuery object containing the accordion. +
    +

    Events

    +

    activate( event, ui )

    +
    Triggered after a panel has been activated (after animation completes). If the accordion was previously collapsed, ui.oldHeader and ui.oldPanel will be empty jQuery objects. If the accordion is collapsing, ui.newHeader and ui.newPanel will be empty jQuery objects.
    +
      +
    • +
      event
      +
      Type: Event +
      +
      +
    • +
    • +
      ui
      +
      Type: Object +
      +
      +
        +
      • +
        newHeader
        +
        Type: jQuery +
        +
        The header that was just activated.
        +
      • +
      • +
        oldHeader
        +
        Type: jQuery +
        +
        The header that was just deactivated.
        +
      • +
      • +
        newPanel
        +
        Type: jQuery +
        +
        The panel that was just activated.
        +
      • +
      • +
        oldPanel
        +
        Type: jQuery +
        +
        The panel that was just deactivated.
        +
      • +
      +
    • +
    +
    +
    +

    beforeActivate( event, ui )

    +
    Triggered directly after a panel is activated. Can be canceled to prevent the panel from activating. If the accordion is currently collapsed, ui.oldHeader and ui.oldPanel will be empty jQuery objects. If the accordion is collapsing, ui.newHeader and ui.newPanel will be empty jQuery objects.
    +
      +
    • +
      event
      +
      Type: Event +
      +
      +
    • +
    • +
      ui
      +
      Type: Object +
      +
      +
        +
      • +
        newHeader
        +
        Type: jQuery +
        +
        The header that is about to be activated.
        +
      • +
      • +
        oldHeader
        +
        Type: jQuery +
        +
        The header that is about to be deactivated.
        +
      • +
      • +
        newPanel
        +
        Type: jQuery +
        +
        The panel that is about to be activated.
        +
      • +
      • +
        oldPanel
        +
        Type: jQuery +
        +
        The panel that is about to be deactivated.
        +
      • +
      +
    • +
    +
    +
    +

    create( event, ui )

    +
    Triggered when the accordion is created. If the accordion is collapsed, ui.header and ui.panel will be empty jQuery objects.
    +
      +
    • +
      event
      +
      Type: Event +
      +
      +
    • +
    • +
      ui
      +
      Type: Object +
      +
      +
        +
      • +
        header
        +
        Type: jQuery +
        +
        The active header.
        +
      • +
      • +
        panel
        +
        Type: jQuery +
        +
        The active panel.
        +
      • +
      +
    • +
    +
    +

    The markup of your accordion container needs pairs of headers and content panels:

    + +
    1
    2
    3
    4
    5
    6
    <div id="accordion">
        <h3>First header</h3>
        <div>First content panel</div>
        <h3>Second header</h3>
        <div>Second content panel</div>
    </div>
    + +

    Accordions support arbitrary markup, but each content panel must always be the next sibling after its associated header. See the header option for information on how to use custom markup structures.

    +

    The panels can be activated programmatically by setting the active option.

    + +

    Keyboard interaction

    + +

    When focus is on a header, the following key commands are available:

    +
      +
    • UP/LEFT - Move focus to the previous header. If on first header, moves focus to last header.
    • +
    • DOWN/RIGHT - Move focus to the next header. If on last header, moves focus to first header.
    • +
    • HOME - Move focus to the first header.
    • +
    • END - Move focus to the last header.
    • +
    • SPACE/ENTER - Activate panel associated with focused header.
    • +
    + +

    When focus is in a panel:

    +
      +
    • CTRL+UP: Move focus to associated header.
    • +
    +
    +

    Additional Notes:

    +
    • + This widget requires some functional CSS, otherwise it won't work. If you build a custom theme, use the widget's specific CSS file as a starting point. +
    +

    Example:

    +

    A simple jQuery UI Accordion

    +
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    <!doctype html>
    <html lang="en">
    <head>
        <meta charset="utf-8">
        <title>accordion demo</title>
        <link rel="stylesheet" href="http://code.jquery.com/ui/1.9.0/themes/base/jquery-ui.css">
        <script src="http://code.jquery.com/jquery-1.8.2.js"></script>
        <script src="http://code.jquery.com/ui/1.9.0/jquery-ui.js"></script>
    </head>
    <body>
     
    <div id="accordion">
        <h3>Section 1</h3>
        <div>
            <p>Mauris mauris ante, blandit et, ultrices a, suscipit eget.
            Integer ut neque. Vivamus nisi metus, molestie vel, gravida in,
            condimentum sit amet, nunc. Nam a nibh. Donec suscipit eros.
            Nam mi. Proin viverra leo ut odio.</p>
        </div>
        <h3>Section 2</h3>
        <div>
            <p>Sed non urna. Phasellus eu ligula. Vestibulum sit amet purus.
            Vivamus hendrerit, dolor aliquet laoreet, mauris turpis velit,
            faucibus interdum tellus libero ac justo.</p>
        </div>
        <h3>Section 3</h3>
        <div>
            <p>Nam enim risus, molestie et, porta ac, aliquam ac, risus.
            Quisque lobortis.Phasellus pellentesque purus in massa.</p>
            <ul>
                <li>List item one</li>
                <li>List item two</li>
                <li>List item three</li>
            </ul>
        </div>
    </div>
     
    <script>
    $( "#accordion" ).accordion();
    </script>
     
    </body>
    </html>
    +

    Demo:

    +
    +
    +
    + + + diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/docs/autocomplete.html b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/docs/autocomplete.html new file mode 100755 index 000000000..5fb84ad82 --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/docs/autocomplete.html @@ -0,0 +1,437 @@ + + + + + jQuery UI autocomplete documentation + + + + + +

    QuickNav

    + +

    +Autocomplete Widgetversion added: 1.8 +

    +
    +

    Description: Autocomplete enables users to quickly find and select from a pre-populated list of values as they type, leveraging searching and filtering.

    +

    Options

    +

    appendToType: Selector +

    +
    +Default: "body" +
    +
    Which element the menu should be appended to. Override this when the autocomplete is inside a position: fixed element. Otherwise the popup menu would still scroll with the page.
    +
    +
    +

    autoFocusType: Boolean +

    +
    +Default: false +
    +
    If set to true the first item will automatically be focused when the menu is shown.
    +
    +
    +

    delayType: Integer +

    +
    +Default: 300 +
    +
    The delay in milliseconds between when a keystroke occurs and when a search is performed. A zero-delay makes sense for local data (more responsive), but can produce a lot of load for remote data, while being less responsive.
    +
    +
    +

    disabledType: Boolean +

    +
    +Default: false +
    +
    Disables the autocomplete if set to true.
    +
    +
    +

    minLengthType: Integer +

    +
    +Default: 1 +
    +
    The minimum number of characters a user must type before a search is performed. Zero is useful for local data with just a few items, but a higher value should be used when a single character search could match a few thousand items.
    +
    +
    +

    positionType: Object +

    +
    +Default: { my: "left top", at: "left bottom", collision: "none" } +
    +
    Identifies the position of the suggestions menu in relation to the associated input element. The of option defaults to the input element, but you can specify another element to position against. You can refer to the jQuery UI Position utility for more details about the various options.
    +
    +
    +

    sourceType: Array or String or Function( Object request, Function response( Object data ) ) +

    +
    +Default: none; must be specified +
    +
    + Defines the data to use, must be specified. +

    Independent of the variant you use, the label is always treated as text. If you want the label to be treated as html you can use Scott González' html extension. The demos all focus on different variations of the source option - look for one that matches your use case, and check out the code.

    +
    +Multiple types supported:
      +
    • +Array: + An array can be used for local data. There are two supported formats: +
        +
      • An array of strings: [ "Choice1", "Choice2" ] +
      • +
      • An array of objects with label and value properties: [ { label: "Choice1", value: "value1" }, ... ] +
      • +
      + The label property is displayed in the suggestion menu. The value will be inserted into the input element when a user selects an item. If just one property is specified, it will be used for both, e.g., if you provide only value properties, the value will also be used as the label. +
    • +
    • +String: When a string is used, the Autocomplete plugin expects that string to point to a URL resource that will return JSON data. It can be on the same host or on a different one (must provide JSONP). The Autocomplete plugin does not filter the results, instead the request parameter term gets added to the URL, which the server-side script should use for filtering the results. The data itself can be in the same format as the local data described above.
    • +
    • +Function: + The third variation, a callback, provides the most flexibility and can be used to connect any data source to Autocomplete. The callback gets two arguments: +
        +
      • A request object, with a single term property, which refers to the value currently in the text input. For example, if the user enters "new yo" in a city field, the Autocomplete term will equal "new yo".
      • +
      • A response callback, which expects a single argument: the data to suggest to the user. This data should be filtered based on the provided term, and can be in any of the formats described above for simple local data. It's important when providing a custom source callback to handle errors during the request. You must always call the response callback even if you encounter an error. This ensures that the widget always has the correct state.
      • +
      +
    • +
    +

    Methods

    +

    close()

    +
    Closes the Autocomplete menu. Useful in combination with the search method, to close the open menu.
    +
    +
    +

    destroy()

    +
    + Removes the autocomplete functionality completely. This will return the element back to its pre-init state. +
    +
    +
    +

    disable()

    +
    + Disables the autocomplete. +
    +
    +
    +

    enable()

    +
    + Enables the autocomplete. +
    +
    +
    +
    +

    option( optionName ) Returns: Object +

    +
    Gets the value currently associated with the specified optionName.
    +
    • +
      optionName
      +
      Type: String +
      +
      The name of the option to get.
      +
    +
    +
    +

    option() Returns: PlainObject +

    +
    Gets an object containing key/value pairs representing the current autocomplete options hash.
    +
    +
    +

    option( optionName, value )

    +
    Sets the value of the autocomplete option associated with the specified optionName.
    +
      +
    • +
      optionName
      +
      Type: String +
      +
      The name of the option to set.
      +
    • +
    • +
      value
      +
      Type: Object +
      +
      A value to set for the option.
      +
    • +
    +
    +
    +

    option( options )

    +
    Sets one or more options for the autocomplete.
    +
    • +
      options
      +
      Type: Object +
      +
      A map of option-value pairs to set.
      +
    +
    +
    + +
    +

    widget()

    +
    Returns a jQuery object containing the menu element. Although the menu items are constantly created and destroyed, the menu element itself is created during initialization and is constantly reused.
    +

    Events

    +

    change( event, ui )

    +
    Triggered when the field is blurred, if the value has changed.
    +
      +
    • +
      event
      +
      Type: Event +
      +
      +
    • +
    • +
      ui
      +
      Type: Object +
      +
      +
      • +
        item
        +
        Type: jQuery +
        +
        The item selected from the menu, if any. Otherwise the property is null.
        +
      +
    • +
    +
    +
    +

    close( event, ui )

    +
    Triggered when the menu is hidden. Not every close event will be accompanied by a change event.
    +
      +
    • +
      event
      +
      Type: Event +
      +
      +
    • +
    • +
      ui
      +
      Type: Object +
      +
      +
    • +
    +
    +
    +

    create( event, ui )

    +
    + Triggered when the autocomplete is created. +
    +
      +
    • +
      event
      +
      Type: Event +
      +
      +
    • +
    • +
      ui
      +
      Type: Object +
      +
      +
    • +
    +
    +
    +

    focus( event, ui )

    +
    + Triggered when focus is moved to an item (not selecting). The default action is to replace the text field's value with the value of the focused item, though only if the event was triggered by a keyboard interaction. +

    Canceling this event prevents the value from being updated, but does not prevent the menu item from being focused.

    +
    +
      +
    • +
      event
      +
      Type: Event +
      +
      +
    • +
    • +
      ui
      +
      Type: Object +
      +
      +
      • +
        item
        +
        Type: jQuery +
        +
        The focused item.
        +
      +
    • +
    +
    +
    +

    open( event, ui )

    +
    Triggered when the suggestion menu is opened or updated.
    +
      +
    • +
      event
      +
      Type: Event +
      +
      +
    • +
    • +
      ui
      +
      Type: Object +
      +
      +
    • +
    +
    +
    +

    response( event, ui )

    +
    Triggered after a search completes, before the menu is shown. Useful for local manipulation of suggestion data, where a custom source option callback is not required. This event is always triggered when a search completes, even if the menu will not be shown because there are no results or the Autocomplete is disabled.
    +
      +
    • +
      event
      +
      Type: Event +
      +
      +
    • +
    • +
      ui
      +
      Type: Object +
      +
      +
      • +
        content
        +
        Type: Array +
        +
        Contains the response data and can be modified to change the results that will be shown. This data is already normalized, so if you modify the data, make sure to include both value and label properties for each item.
        +
      +
    • +
    +
    + +
    +

    select( event, ui )

    +
    + Triggered when an item is selected from the menu. The default action is to replace the text field's value with the value of the selected item. +

    Canceling this event prevents the value from being updated, but does not prevent the menu from closing.

    +
    +
      +
    • +
      event
      +
      Type: Event +
      +
      +
    • +
    • +
      ui
      +
      Type: Object +
      +
      +
      • +
        item
        +
        Type: jQuery +
        +
        The selected item.
        +
      +
    • +
    +
    +

    By giving an Autocomplete field focus or entering something into it, the plugin starts searching for entries that match and displays a list of values to choose from. By entering more characters, the user can filter down the list to better matches.

    + +

    This can be used to choose previously selected values, such as entering tags for articles or entering email addresses from an address book. Autocomplete can also be used to populate associated information, such as entering a city name and getting the zip code.

    + +

    You can pull data in from a local or remote source: Local is good for small data sets, e.g., an address book with 50 entries; remote is necessary for big data sets, such as a database with hundreds or millions of entries to select from. To find out more about customizing the data soure, see the documentation for the source option.

    + +

    Keyboard interaction

    + +

    When the menu is open, the following key commands are available:

    +
      +
    • UP - Move focus to the previous item. If on first item, move focus to the input. If on the input, move focus to last item.
    • +
    • DOWN - Move focus to the next item. If on last item, move focus to the input. If on the input, move focus to the first item.
    • +
    • ESCAPE - Close the menu.
    • +
    • ENTER - Select the currently focused item and close the menu.
    • +
    • TAB - Select the currently focused item, close the menu, and move focus to the next focusable element.
    • +
    • PAGE UP/DOWN - Scroll through a page of items (based on height of menu). It's generally a bad idea to display so many items that users need to page..
    • +
    + +

    When the menu is closed, the following key commands are available:

    +
      +
    • UP/DOWN - Open the menu, if the minLength has been met.
    • +
    +
    +

    Additional Notes:

    +
    • + This widget requires some functional CSS, otherwise it won't work. If you build a custom theme, use the widget's specific CSS file as a starting point. +
    +

    Example:

    +

    A simple jQuery UI Autocomplete

    +
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    <!doctype html>
    <html lang="en">
    <head>
        <meta charset="utf-8">
        <title>autocomplete demo</title>
        <link rel="stylesheet" href="http://code.jquery.com/ui/1.9.0/themes/base/jquery-ui.css">
        <script src="http://code.jquery.com/jquery-1.8.2.js"></script>
        <script src="http://code.jquery.com/ui/1.9.0/jquery-ui.js"></script>
    </head>
    <body>
     
    <label for="autocomplete">Select a programming language: </label>
    <input id="autocomplete">
     
    <script>
    $( "#autocomplete" ).autocomplete({
        source: [ "c++", "java", "php", "coldfusion", "javascript", "asp", "ruby" ]
    });
    </script>
     
    </body>
    </html>
    +

    Demo:

    +
    +
    +
    + + + diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/docs/blind-effect.html b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/docs/blind-effect.html new file mode 100755 index 000000000..3e6484cf2 --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/docs/blind-effect.html @@ -0,0 +1,58 @@ + + + + + jQuery UI blind-effect documentation + + + + + +

    Blind Effect

    +
    +

    Description: + The blind effect hides or shows an element by wrapping the element in a container, and "pulling the blinds" +

    +
    • +

      blind

      +
      • +
        +direction (default: "up")
        +
        Type: String +
        +
        +

        The direction the blind will be pulled to hide the element, or the direction from which the element will be revealed.

        +

        Possible Values: up, down, left, right, vertical, horizontal.

        +
        +
      +
    +
    +

    The container has overflow: hidden applied, so height changes affect what's visible.

    +
    +

    Example:

    +

    Toggle a div using the blind effect.

    +
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    <!doctype html>
    <html lang="en">
    <head>
        <meta charset="utf-8">
        <title>blind demo</title>
        <link rel="stylesheet" href="http://code.jquery.com/ui/1.9.0/themes/base/jquery-ui.css">
        <style>
        #toggle {
            width: 100px;
            height: 100px;
            background: #ccc;
        }
        </style>
        <script src="http://code.jquery.com/jquery-1.8.2.js"></script>
        <script src="http://code.jquery.com/ui/1.9.0/jquery-ui.js"></script>
    </head>
    <body>
     
    <p>Click anywhere to toggle the box.</p>
    <div id="toggle"></div>
     
    <script>
    $( document ).click(function() {
        $( "#toggle" ).toggle( "blind" );
    });
    </script>
     
    </body>
    </html>
    +

    Demo:

    +
    +
    +
    + + + diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/docs/bounce-effect.html b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/docs/bounce-effect.html new file mode 100755 index 000000000..1d72fa250 --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/docs/bounce-effect.html @@ -0,0 +1,61 @@ + + + + + jQuery UI bounce-effect documentation + + + + + +

    Bounce Effect

    +
    +

    Description: + The bounce effect bounces an element. When used with hide or show, the last or first bounce will also fade in/out. +

    +
    • +

      bounce

      +
        +
      • +
        +distance (default: 20)
        +
        Type: Number +
        +
        The distance of the largest "bounce" in pixels.
        +
      • +
      • +
        +times (default: 5)
        +
        Type: Integer +
        +
        The number of times the element will bounce. When used with hide or show, there is an extra "half" bounce for the fade in/out.
        +
      • +
      +
    +

    Example:

    +

    Toggle a div using the bounce effect.

    +
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    <!doctype html>
    <html lang="en">
    <head>
        <meta charset="utf-8">
        <title>bounce demo</title>
        <link rel="stylesheet" href="http://code.jquery.com/ui/1.9.0/themes/base/jquery-ui.css">
        <style>
        #toggle {
            width: 100px;
            height: 100px;
            background: #ccc;
        }
        </style>
        <script src="http://code.jquery.com/jquery-1.8.2.js"></script>
        <script src="http://code.jquery.com/ui/1.9.0/jquery-ui.js"></script>
    </head>
    <body>
     
    <p>Click anywhere to toggle the box.</p>
    <div id="toggle"></div>
     
    <script>
    $( document ).click(function() {
        $( "#toggle" ).toggle( "bounce", { times: 3 }, "slow" );
    });
    </script>
     
    </body>
    </html>
    +

    Demo:

    +
    +
    +
    + + + diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/docs/button.html b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/docs/button.html new file mode 100755 index 000000000..8cf3028a9 --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/docs/button.html @@ -0,0 +1,206 @@ + + + + + jQuery UI button documentation + + + + + +

    QuickNav

    +

    Options

    + + + + +
    + +
    +

    Events

    + +

    +Button Widgetversion added: 1.8 +

    +
    +

    Description: Themable buttons and button sets.

    +

    Options

    +

    disabledType: Boolean +

    +
    +Default: false +
    +
    Disables the button if set to true.
    +
    +
    +

    iconsType: Object +

    +
    +Default: { primary: null, secondary: null } +
    +
    Icons to display, with or without text (see text option). By default, the primary icon is displayed on the left of the label text and the secondary is displayed on the right. The positioning can be controlled via CSS. The value for the primary and secondary properties must be a class name, e.g., "ui-icon-gear". For using only one icon: icons: { primary: "ui-icon-locked" }. For using two icons: icons: { primary: "ui-icon-gear", secondary: "ui-icon-triangle-1-s" }.
    +
    +
    +

    labelType: String +

    +
    +Default: null +
    +
    Text to show in the button. When not specified (null), the element's HTML content is used, or its value attribute if the element is an input element of type submit or reset, or the HTML content of the associated label element if the element is an input of type radio or checkbox.
    +
    +
    +

    textType: Boolean +

    +
    +Default: true +
    +
    Whether to show the label. When set to false no text will be displayed, but the icons option must be enabled, otherwise the text option will be ignored.
    +

    Methods

    +

    destroy()

    +
    + Removes the button functionality completely. This will return the element back to its pre-init state. +
    +
    +
    +

    disable()

    +
    + Disables the button. +
    +
    +
    +

    enable()

    +
    + Enables the button. +
    +
    +
    +
    +

    option( optionName ) Returns: Object +

    +
    Gets the value currently associated with the specified optionName.
    +
    • +
      optionName
      +
      Type: String +
      +
      The name of the option to get.
      +
    +
    +
    +

    option() Returns: PlainObject +

    +
    Gets an object containing key/value pairs representing the current button options hash.
    +
    +
    +

    option( optionName, value )

    +
    Sets the value of the button option associated with the specified optionName.
    +
      +
    • +
      optionName
      +
      Type: String +
      +
      The name of the option to set.
      +
    • +
    • +
      value
      +
      Type: Object +
      +
      A value to set for the option.
      +
    • +
    +
    +
    +

    option( options )

    +
    Sets one or more options for the button.
    +
    • +
      options
      +
      Type: Object +
      +
      A map of option-value pairs to set.
      +
    +
    +
    +
    +

    refresh()

    +
    Refreshes the visual state of the button. Useful for updating button state after the native element's checked or disabled state is changed programmatically.
    +
    +
    +

    widget() Returns: jQuery +

    +
    + Returns a jQuery object containing the element visually representing the button. +
    +

    Events

    +

    create( event, ui )

    +
    + Triggered when the button is created. +
    +
      +
    • +
      event
      +
      Type: Event +
      +
      +
    • +
    • +
      ui
      +
      Type: Object +
      +
      +
    • +
    +
    +

    Button enhances standard form elements like buttons, inputs and anchors to themable buttons with appropiate hover and active styles.

    + +

    In addition to basic push buttons, radio buttons and checkboxes (inputs of type radio and checkbox) can be converted to buttons. Their associated label is styled to appear as the button, while the underlying input is updated on click.

    + +

    In order to group radio buttons, Button also provides an additional widget, called Buttonset. Buttonset is used by selecting a container element (which contains the radio buttons) and calling .buttonset(). Buttonset will also provide visual grouping, and therefore should be used whenever you have a group of buttons. It works by selecting all descendants and applying .button() to them. You can enable and disable a button set, which will enable and disable all contained buttons. Destroying a button set also calls each button's destroy method.

    + +

    When using an input of type button, submit or reset, support is limited to plain text labels with no icons.

    +
    +

    Additional Notes:

    +
    • + This widget requires some functional CSS, otherwise it won't work. If you build a custom theme, use the widget's specific CSS file as a starting point. +
    +

    Examples:

    +

    Example: A simple jQuery UI Button +

    +
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    <!doctype html>
    <html lang="en">
    <head>
        <meta charset="utf-8">
        <title>button demo</title>
        <link rel="stylesheet" href="http://code.jquery.com/ui/1.9.0/themes/base/jquery-ui.css">
        <script src="http://code.jquery.com/jquery-1.8.2.js"></script>
        <script src="http://code.jquery.com/ui/1.9.0/jquery-ui.js"></script>
    </head>
    <body>
     
    <button>Button label</button>
     
    <script>
    $( "button" ).button();
    </script>
     
    </body>
    </html>
    +

    Demo:

    +
    +
    +
    +

    Example: A simple jQuery UI Buttonset +

    +
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    <!doctype html>
    <html lang="en">
    <head>
        <meta charset="utf-8">
        <title>button demo</title>
        <link rel="stylesheet" href="http://code.jquery.com/ui/1.9.0/themes/base/jquery-ui.css">
        <script src="http://code.jquery.com/jquery-1.8.2.js"></script>
        <script src="http://code.jquery.com/ui/1.9.0/jquery-ui.js"></script>
    </head>
    <body>
     
    <div id="radio">
        <input type="radio" id="radio1" name="radio"><label for="radio1">Choice 1</label>
        <input type="radio" id="radio2" name="radio" checked="checked"><label for="radio2">Choice 2</label>
        <input type="radio" id="radio3" name="radio"><label for="radio3">Choice 3</label>
    </div>
     
    <script>
    $( "#radio" ).buttonset();
    </script>
     
    </body>
    </html>
    +

    Demo:

    +
    +
    +
    + + + diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/docs/clip-effect.html b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/docs/clip-effect.html new file mode 100755 index 000000000..4cd85b2f9 --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/docs/clip-effect.html @@ -0,0 +1,55 @@ + + + + + jQuery UI clip-effect documentation + + + + + +

    Clip Effect

    +
    +

    Description: + The clip effect will hide or show an element by clipping the element vertically or horizontally. +

    +
    • +

      clip

      +
      • +
        +direction (default: "up")
        +
        Type: String +
        +
        +

        The plane in which the clip effect will hide or show its element.

        +

        vertical clips the top and bottom edges, while horizontal clips the right and left edges.

        +
        +
      +
    +

    Example:

    +

    Toggle a div using the clip effect.

    +
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    <!doctype html>
    <html lang="en">
    <head>
        <meta charset="utf-8">
        <title>clip demo</title>
        <link rel="stylesheet" href="http://code.jquery.com/ui/1.9.0/themes/base/jquery-ui.css">
        <style>
        #toggle {
            width: 100px;
            height: 100px;
            background: #ccc;
        }
        </style>
        <script src="http://code.jquery.com/jquery-1.8.2.js"></script>
        <script src="http://code.jquery.com/ui/1.9.0/jquery-ui.js"></script>
    </head>
    <body>
     
    <p>Click anywhere to toggle the box.</p>
    <div id="toggle"></div>
     
    <script>
    $( document ).click(function() {
        $( "#toggle" ).toggle( "clip" );
    });
    </script>
     
    </body>
    </html>
    +

    Demo:

    +
    +
    +
    + + + diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/docs/datepicker.html b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/docs/datepicker.html new file mode 100755 index 000000000..e2b997eb3 --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/docs/datepicker.html @@ -0,0 +1,650 @@ + + + + + jQuery UI datepicker documentation + + + + + +

    QuickNav

    + +

    Events

    +Datepicker Widgetversion added: 1.0 +

    +
    +

    Description: Select a date from a popup or inline calendar

    +

    Options

    +

    altFieldType: Selector or jQuery or Element +

    +
    +Default: "" +
    +
    An input element that is to be updated with the selected date from the datepicker. Use the altFormat option to change the format of the date within this field. Leave as blank for no alternate field.
    +
    +
    +

    altFormatType: String +

    +
    +Default: "" +
    +
    The dateFormat to be used for the altField option. This allows one date format to be shown to the user for selection purposes, while a different format is actually sent behind the scenes. For a full list of the possible formats see the [[UI/Datepicker/formatDate|formatDate]] function
    +
    +
    +

    appendTextType: String +

    +
    +Default: "" +
    +
    The text to display after each date field, e.g., to show the required format.
    +
    +
    +

    autoSizeType: Boolean +

    +
    +Default: false +
    +
    Set to true to automatically resize the input field to accommodate dates in the current dateFormat.
    +
    +
    +

    beforeShowType: Function( Element input, Object inst ) +

    +
    +Default: null +
    +
    A function that takes an input field and current datepicker instance and returns an options object to update the datepicker with. It is called just before the datepicker is displayed.
    +
    +
    +

    beforeShowDayType: Function( Date date ) +

    +
    +Default: null +
    +
    A function takes a date as a parameter and must return an array with [0] equal to true/false indicating whether or not this date is selectable, [1] equal to a CSS class name or "" for the default presentation, and [2] an optional popup tooltip for this date. It is called for each day in the datepicker before it is displayed.
    +
    +
    +

    buttonImageType: String +

    +
    +Default: "" +
    +
    The URL for the popup button image. If set, the buttonText option becomes the alt value and is not directly displayed.
    +
    +
    +

    buttonImageOnlyType: Boolean +

    +
    +Default: false +
    +
    Whether the button image should be rendered by itself instead of inside a button element.
    +
    +
    +

    buttonTextType: String +

    +
    +Default: "..." +
    +
    The text to display on the trigger button. Use in conjunction with the showOn option set to "button" or "both".
    +
    +
    +

    calculateWeekType: Function() +

    +
    +Default: jQuery.datepicker.iso8601Week +
    +
    A function to calculate the week of the year for a given date. The default implementation uses the ISO 8601 definition: weeks start on a Monday; the first week of the year contains the first Thursday of the year.
    +
    +
    +

    changeMonthType: Boolean +

    +
    +Default: false +
    +
    Whether the month should be rendered as a dropdown instead of text.
    +
    +
    +

    changeYearType: Boolean +

    +
    +Default: false +
    +
    Whether the year should be rendered as a dropdown instead of text. Use the yearRange option to control which years are made available for selection.
    +
    +
    +

    closeTextType: String +

    +
    +Default: "Done" +
    +
    The text to display for the close link. Use the showButtonPanel option to display this button.
    +
    +
    +

    constrainInputType: Boolean +

    +
    +Default: true +
    +
    When true, entry in the input field is constrained to those characters allowed by the current dateFormat option.
    +
    +
    +

    currentTextType: String +

    +
    +Default: "Today" +
    +
    The text to display for the current day link. Use the showButtonPanel option to display this button.
    +
    +
    +

    dateFormatType: String +

    +
    +Default: "mm/dd/yy" +
    +
    The format for parsed and displayed dates. For a full list of the possible formats see the [[UI/Datepicker/formatDate|formatDate]] function.
    +
    +
    +

    dayNamesType: Array +

    +
    +Default: [ "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday" ] +
    +
    The list of long day names, starting from Sunday, for use as requested via the dateFormat option.
    +
    +
    +

    dayNamesMinType: Array +

    +
    +Default: [ "Su", "Mo", "Tu", "We", "Th", "Fr", "Sa" ] +
    +
    The list of minimised day names, starting from Sunday, for use as column headers within the datepicker.
    +
    +
    +

    dayNamesShortType: Array +

    +
    +Default: [ "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" ] +
    +
    The list of abbreviated day names, starting from Sunday, for use as requested via the dateFormat option.
    +
    +
    +

    defaultDateType: Date or Number or String +

    +
    +Default: null +
    +
    Set the date to highlight on first opening if the field is blank. Specify either an actual date via a Date object or as a string in the current [[UI/Datepicker#option-dateFormat|dateFormat]], or a number of days from today (e.g. +7) or a string of values and periods ('y' for years, 'm' for months, 'w' for weeks, 'd' for days, e.g. '+1m +7d'), or null for today.
    +Multiple types supported:
      +
    • +Date: A date object containing the default date.
    • +
    • +Number: A number of days from today. For example 2 represents two days from today and -1 represents yesterday.
    • +
    • +String: A string in the format defined by the dateFormat option, or a relative date. Relative dates must contain value and period pairs; valid periods are "y" for years, "m" for months, "w" for weeks, and "d" for days. For example, "+1m +7d" represents one month and seven days from today.
    • +
    +
    +
    +

    durationType: or String +

    +
    +Default: "normal" +
    +
    Control the speed at which the datepicker appears, it may be a time in milliseconds or a string representing one of the three predefined speeds ("slow", "normal", "fast").
    +
    +
    +

    firstDayType: Integer +

    +
    +Default: 0 +
    +
    Set the first day of the week: Sunday is 0, Monday is 1, etc.
    +
    +
    +

    gotoCurrentType: Boolean +

    +
    +Default: false +
    +
    When true, the current day link moves to the currently selected date instead of today.
    +
    +
    +

    hideIfNoPrevNextType: Boolean +

    +
    +Default: false +
    +
    Normally the previous and next links are disabled when not applicable (see the minDate and maxDate options). You can hide them altogether by setting this attribute to true.
    +
    +
    +

    isRTLType: Boolean +

    +
    +Default: false +
    +
    Whether the current language is drawn from right to left.
    +
    +
    +

    maxDateType: Date or Number or String +

    +
    +Default: null +
    +
    The maximum selectable date. When set to null, there is no maximum.
    +Multiple types supported:
      +
    • +Date: A date object containing the maximum date.
    • +
    • +Number: A number of days from today. For example 2 represents two days from today and -1 represents yesterday.
    • +
    • +String: A string in the format defined by the dateFormat option, or a relative date. Relative dates must contain value and period pairs; valid periods are "y" for years, "m" for months, "w" for weeks, and "d" for days. For example, "+1m +7d" represents one month and seven days from today.
    • +
    +
    +
    +

    minDateType: Date or Number or String +

    +
    +Default: null +
    +
    The minimum selectable date. When set to null, there is no minimum.
    +Multiple types supported:
      +
    • +Date: A date object containing the minimum date.
    • +
    • +Number: A number of days from today. For example 2 represents two days from today and -1 represents yesterday.
    • +
    • +String: A string in the format defined by the dateFormat option, or a relative date. Relative dates must contain value and period pairs; valid periods are "y" for years, "m" for months, "w" for weeks, and "d" for days. For example, "+1m +7d" represents one month and seven days from today.
    • +
    +
    +
    +

    monthNamesType: Array +

    +
    +Default: [ "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December" ] +
    +
    The list of full month names, for use as requested via the dateFormat option.
    +
    +
    +

    monthNamesShortType: Array +

    +
    +Default: [ "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" ] +
    +
    The list of abbreviated month names, as used in the month header on each datepicker and as requested via the dateFormat option.
    +
    +
    +

    navigationAsDateFormatType: Boolean +

    +
    +Default: false +
    +
    Whether the prevText and nextText options should be parsed as dates by the [[UI/Datepicker/formatDate|formatDate]] function, allowing them to display the target month names for example.
    +
    +
    +

    nextTextType: String +

    +
    +Default: "Next" +
    +
    The text to display for the next month link. With the standard ThemeRoller styling, this value is replaced by an icon.
    +
    +
    +

    numberOfMonthsType: Number or Array +

    +
    +Default: 1 +
    +
    The number of months to show at once.
    +Multiple types supported:
      +
    • +Number: The number of months to display in a single row.
    • +
    • +Array: An array defining the number of rows and columns to display.
    • +
    +
    +
    +

    onChangeMonthYearType: Function( Integer year, Integer month, Object inst ) +

    +
    +Default: null +
    +
    Called when the datepicker moves to a new month and/or year. The function receives the selected year, month (1-12), and the datepicker instance as parameters. this refers to the associated input field.
    +
    +
    +

    onCloseType: Function( String dateText, Object inst ) +

    +
    +Default: null +
    +
    Called when the datepicker is closed, whether or not a date is selected. The function receives the selected date as text ("" if none) and the datepicker instance as parameters. this refers to the associated input field.
    +
    +
    +

    onSelectType: Function( String dateText, Object inst ) +

    +
    +Default: null +
    +
    Called when the datepicker is selected. The function receives the selected date as text and the datepicker instance as parameters. this refers to the associated input field.
    +
    +
    +

    prevTextType: String +

    +
    +Default: "Prev" +
    +
    The text to display for the previous month link. With the standard ThemeRoller styling, this value is replaced by an icon.
    +
    +
    +

    selectOtherMonthsType: Boolean +

    +
    +Default: false +
    +
    Whether days in other months shown before or after the current month are selectable. This only applies if the showOtherMonths option is set to true.
    +
    +
    +

    shortYearCutoffType: Number or String +

    +
    +Default: "+10" +
    +
    The cutoff year for determining the century for a date (used in conjunction with [[UI/Datepicker#option-dateFormat|dateFormat]] 'y'). Any dates entered with a year value less than or equal to the cutoff year are considered to be in the current century, while those greater than it are deemed to be in the previous century.
    +Multiple types supported:
      +
    • +Number: A value between 0 and 99 indicating the cutoff year.
    • +
    • +String: A relative number of years from the current year, e.g., "+3" or "-5".
    • +
    +
    +
    +

    showAnimType: String +

    +
    +Default: "show" +
    +
    The name of the animation used to show and hide the datepicker. Use "show" (the default), "slideDown", "fadeIn", any of the jQuery UI effects. Set to an empty string to disable animation.
    +
    +
    +

    showButtonPanelType: Boolean +

    +
    +Default: false +
    +
    Whether to show the button panel.
    +
    +
    +

    showCurrentAtPosType: Number +

    +
    +Default: 0 +
    +
    When displaying multiple months via the numberOfMonths option, the showCurrentAtPos option defines which position to display the current month in.
    +
    +
    +

    showMonthAfterYearType: Boolean +

    +
    +Default: false +
    +
    Whether to show the month after the year in the header.
    +
    +
    +

    showOnType: String +

    +
    +Default: "focus" +
    +
    When the datepicker should appear. The datepicker can appear when the field receives focus ("focus"), when a button is clicked ("button"), or when either event occurs ("both").
    +
    +
    +

    showOptionsType: Object +

    +
    +Default: {} +
    +
    If using one of the jQuery UI effects for the showAnim option, you can provide additional settings for that animation via this option.
    +
    +
    +

    showOtherMonthsType: Boolean +

    +
    +Default: false +
    +
    Whether to display dates in other months (non-selectable) at the start or end of the current month. To make these days selectable use the selectOtherMonths option.
    +
    +
    +

    showWeekType: Boolean +

    +
    +Default: false +
    +
    When true, a column is added to show the week of the year. The calculateWeek option determines how the week of the year is calculated. You may also want to change the firstDay option.
    +
    +
    +

    stepMonthsType: Number +

    +
    +Default: 1 +
    +
    Set how many months to move when clicking the previous/next links.
    +
    +
    +

    weekHeaderType: String +

    +
    +Default: "Wk" +
    +
    The text to display for the week of the year column heading. Use the showWeek option to display this column.
    +
    +
    +

    yearRangeType: String +

    +
    +Default: "c-10:c+10" +
    +
    The range of years displayed in the year drop-down: either relative to today's year ("-nn:+nn"), relative to the currently selected year ("c-nn:c+nn"), absolute ("nnnn:nnnn"), or combinations of these formats ("nnnn:-nn"). Note that this option only affects what appears in the drop-down, to restrict which dates may be selected use the minDate and/or maxDate options.
    +
    +
    +

    yearSuffixType: String +

    +
    +Default: "" +
    +
    Additional text to display after the year in the month headers.
    +

    Methods

    +

    destroy()

    +
    + Removes the datepicker functionality completely. This will return the element back to its pre-init state. +
    +
    +
    +

    dialog( date [, onSelect ] [, settings ] [, pos ] )

    +
    Opens the datepicker in a dialog box.
    +
      +
    • +
      date
      +
      Type: String or Date +
      +
      The initial date.
      +
    • +
    • +
      onSelect
      +
      Type: Function()
      +
      A callback function when a date is selected. The function receives the date text and date picker instance as parameters.
      +
    • +
    • +
      settings
      +
      Type: Options +
      +
      The new settings for the date picker.
      +
    • +
    • +
      pos
      + +
      The position of the top/left of the dialog as [x, y] or a MouseEvent that contains the coordinates. If not specified the dialog is centered on the screen.
      +
    • +
    +
    +
    +

    getDate() Returns: Date +

    +
    Returns the current date for the datepicker or null if no date has been selected.
    +
    +
    +

    hide()

    +
    Close a previously opened date picker.
    +
    +
    +

    isDisabled() Returns: Boolean +

    +
    Determine whether a date picker has been disabled.
    +
    +
    +

    refresh()

    +
    Redraw the date picker, after having made some external modifications.
    +
    +
    +

    setDate( date )

    +
    Sets the date for the datepicker. The new date may be a Date object or a string in the current date format (e.g., "01/26/2009"), a number of days from today (e.g., +7) or a string of values and periods ("y" for years, "m" for months, "w" for weeks, "d" for days, e.g., "+1m +7d"), or null to clear the selected date.
    +
    • +
      date
      +
      Type: Date +
      +
      The new date.
      +
    +
    +
    +

    show()

    +
    Open the date picker. If the datepicker is attached to an input, the input must be visible for the datepicker to be shown.
    +
    +

    The jQuery UI Datepicker is a highly configurable plugin that adds datepicker functionality to your pages. You can customize the date format and language, restrict the selectable date ranges and add in buttons and other navigation options easily.

    + +

    By default, the datepicker calendar opens in a small overlay when the associated text field gains focus. For an inline calendar, simply attach the datepicker to a div or span.

    + +

    Keyboard interaction

    +

    While the datepicker is open, the following key commands are available:

    +
      +
    • PAGE UP: Move to the previous month.
    • +
    • PAGE DOWN: Move to the next month.
    • +
    • CTRL+PAGE UP: Move to the previous year.
    • +
    • CTRL+PAGE DOWN: Move to the next year.
    • +
    • CTRL+HOME: Move to the current month. Open the datepicker if closed.
    • +
    • CTRL+LEFT: Move to the previous day.
    • +
    • CTRL+RIGHT: Move to the next day.
    • +
    • CTRL+UP: Move to the previous week.
    • +
    • CTRL+DOWN: Move the next week.
    • +
    • ENTER: Select the focused date.
    • +
    • CTRL+END: Close the datepicker and erase the date.
    • +
    • ESCAPE: Close the datepicker without selection.
    • +
    + +

    Utility functions

    +
      +
    • $.datepicker.setDefaults( settings ) - Set settings for all datepicker instances.
    • +
    • $.datepicker.formatDate( format, date, settings ) - Format a date into a string value with a specified format.
    • +
    • $.datepicker.parseDate( format, value, settings ) - Extract a date from a string value with a specified format.
    • +
    • $.datepicker.iso8601Week( date ) - Determine the week of the year for a given date: 1 to 53.
    • +
    • $.datepicker.noWeekends - Set as beforeShowDay function to prevent selection of weekends.
    • +
    + +

    Localization

    +

    Datepicker provides support for localizing its content to cater for different languages and date formats. Each localization is contained within its own file with the language code appended to the name, e.g., jquery.ui.datepicker-fr.js for French. The desired localization file should be included after the main datepicker code. Each localization file adds its settings to the set of available localizations and automatically applies them as defaults for all instances.

    +

    The $.datepicker.regional attribute holds an array of localizations, indexed by language code, with "" referring to the default (English). Each entry is an object with the following attributes: closeText, prevText, nextText, currentText, monthNames, monthNamesShort, dayNames, dayNamesShort, dayNamesMin, weekHeader, dateFormat, firstDay, isRTL, showMonthAfterYear, and yearSuffix.

    +

    You can restore the default localizations with:

    + $.datepicker.setDefaults( $.datepicker.regional[ "" ] ); +

    And can then override an individual datepicker for a specific locale:

    + $( selector ).datepicker( $.datepicker.regional[ "fr" ] ); +
    +

    Additional Notes:

    +
    • + This widget requires some functional CSS, otherwise it won't work. If you build a custom theme, use the widget's specific CSS file as a starting point. +
    +

    Example:

    +

    A simple jQuery UI Datepicker.

    +
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    <!doctype html>
    <html lang="en">
    <head>
        <meta charset="utf-8">
        <title>datepicker demo</title>
        <link rel="stylesheet" href="http://code.jquery.com/ui/1.9.0/themes/base/jquery-ui.css">
        <script src="http://code.jquery.com/jquery-1.8.2.js"></script>
        <script src="http://code.jquery.com/ui/1.9.0/jquery-ui.js"></script>
    </head>
    <body>
     
    <div id="datepicker"></div>
     
    <script>
    $( "#datepicker" ).datepicker();
    </script>
     
    </body>
    </html>
    +

    Demo:

    +
    +
    +
    + + + diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/docs/dialog.html b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/docs/dialog.html new file mode 100755 index 000000000..1095240e1 --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/docs/dialog.html @@ -0,0 +1,719 @@ + + + + + jQuery UI dialog documentation + + + + + +

    QuickNav

    + +

    +Dialog Widgetversion added: 1.0 +

    +
    +

    Description: Open content in an interactive overlay.

    +

    Options

    +

    autoOpenType: Boolean +

    +
    +Default: true +
    +
    If set to true, the dialog will automatically open upon initialization. If false, the dialog will stay hidden until the open() method is called.
    +
    +
    +

    buttonsType: Object or Array +

    +
    +Default: {} +
    +
    Specifies which buttons should be displayed on the dialog. The context of the callback is the dialog element; if you need access to the button, it is available as the target of the event object.
    +Multiple types supported:
      +
    • +Object: The keys are the button labels and the values are the callbacks for when the associated button is clicked.
    • +
    • +Array: Each element of the array must be an object defining the attributes, properties, and event handlers to set on the button.
    • +
    +
    +
    +

    closeOnEscapeType: Boolean +

    +
    +Default: true +
    +
    Specifies whether the dialog should close when it has focus and the user presses the esacpe (ESC) key.
    +
    +
    +

    closeTextType: String +

    +
    +Default: "close" +
    +
    Specifies the text for the close button. Note that the close text is visibly hidden when using a standard theme.
    +
    +
    +

    dialogClassType: String +

    +
    +Default: "" +
    +
    The specified class name(s) will be added to the dialog, for additional theming.
    +
    +
    +

    disabledType: Boolean +

    +
    +Default: false +
    +
    Disables the dialog if set to true.
    +
    +
    +

    draggableType: Boolean +

    +
    +Default: true +
    +
    If set to true, the dialog will be draggable by the title bar. Requires the jQuery UI Draggable wiget to be included.
    +
    +
    +

    heightType: Number or String +

    +
    +Default: "auto" +
    +
    The height of the dialog.
    +Multiple types supported:
      +
    • +Number: The height in pixels.
    • +
    • +String: The only supported string value is "auto" which will allow the dialog height to adjust based on its content.
    • +
    +
    +
    +

    maxHeightType: Number +

    +
    +Default: false +
    +
    The maximum height to which the dialog can be resized, in pixels.
    +
    +
    +

    maxWidthType: Number +

    +
    +Default: false +
    +
    The maximum width to which the dialog can be resized, in pixels.
    +
    +
    +

    minHeightType: Number +

    +
    +Default: 150 +
    +
    The minimum height to which the dialog can be resized, in pixels.
    +
    +
    +

    minWidthType: Number +

    +
    +Default: 150 +
    +
    The minimum width to which the dialog can be resized, in pixels.
    +
    +
    +

    modalType: Boolean +

    +
    +Default: false +
    +
    If set to true, the dialog will have modal behavior; other items on the page will be disabled, i.e., cannot be interacted with. Modal dialogs create an overlay below the dialog but above other page elements.
    +
    +
    +

    positionType: Object or String or Array +

    +
    +Default: { my: "center", at: "center", of: window } +
    +
    Specifies where the dialog should be displayed. The dialog will handle collisions such that as much of the dialog is visible as possible.
    +Multiple types supported:
      +
    • +Object: Identifies the position of the dialog when opened. The of option defaults to the window, but you can specify another element to position against. You can refer to the jQuery UI Position utility for more details about the various options.
    • +
    • +String: A string representing the position within the viewport. Possible values: "center", "left", "right", "top", "botom".
    • +
    • +Array: An array containing an x, y coordinate pair in pixel offset from the top left corner of the viewport or the name of a possible string value.
    • +
    +
    +
    +

    resizableType: Boolean +

    +
    +Default: true +
    +
    If set to true, the dialog will be resizable. Requires the jQuery UI Resizable widget to be included.
    +
    +
    +

    showType: Number or String or Object +

    +
    +Default: null +
    +
    If and how to animate the hiding of the dialog.
    +Multiple types supported:
      +
    • +Number: + The dialog will fade out while animating the height and width for the specified duration. +
    • +
    • +String: + The dialog will be hidden using the specified jQuery UI effect. See the list of effects for possible values. +
    • +
    • +Object: If the value is an object, then effect, duration, and easing properties may be provided. The effect property must be the name of a jQuery UI effect. When using a jQuery UI effect that supports additional settings, you may include those settings in the object and they will be passed to the effect. If duration or easing is omitted, then the default values will be used.
    • +
    +
    +
    +

    showType: Number or String or Object +

    +
    +Default: null +
    +
    If and how to animate the showing of the dialog.
    +Multiple types supported:
      +
    • +Number: + The dialog will fade in while animating the height and width for the specified duration. +
    • +
    • +String: + The dialog will be shown using the specified jQuery UI effect. See the list of effects for possible values. +
    • +
    • +Object: If the value is an object, then effect, duration, and easing properties may be provided. The effect property must be the name of a jQuery UI effect. When using a jQuery UI effect that supports additional settings, you may include those settings in the object and they will be passed to the effect. If duration or easing is omitted, then the default values will be used.
    • +
    +
    +
    +

    stackType: Boolean +

    +
    +Default: true +
    +
    Specifies whether the dialog will stack on top of other dialogs. This will cause the dialog to move to the front of other dialogs when it gains focus.
    +
    +
    +

    titleType: String +

    +
    +Default: "" +
    +
    Specifies the title of the dialog. Any valid HTML may be set as the title. The title can also be specified by the title attribute on the dialog source element.
    +
    +
    +

    widthType: Number +

    +
    +Default: 300 +
    +
    The width of the dialog, in pixels.
    +
    +
    +

    zIndexType: Integer +

    +
    +Default: 1000 +
    +
    The starting z-index for the dialog.
    +

    Methods

    +

    close()

    +
    Closes the dialog.
    +
    +
    +

    destroy()

    +
    + Removes the dialog functionality completely. This will return the element back to its pre-init state. +
    +
    +
    +

    disable()

    +
    + Disables the dialog. +
    +
    +
    +

    enable()

    +
    + Enables the dialog. +
    +
    +
    +

    isOpen() Returns: Boolean +

    +
    Whether the dialog is currently open.
    +
    +
    +

    moveToTop()

    +
    Moves the dialog to the top of the dialog stack.
    +
    +
    +

    open()

    +
    Opens the dialog.
    +
    +
    +
    +

    option( optionName ) Returns: Object +

    +
    Gets the value currently associated with the specified optionName.
    +
    • +
      optionName
      +
      Type: String +
      +
      The name of the option to get.
      +
    +
    +
    +

    option() Returns: PlainObject +

    +
    Gets an object containing key/value pairs representing the current dialog options hash.
    +
    +
    +

    option( optionName, value )

    +
    Sets the value of the dialog option associated with the specified optionName.
    +
      +
    • +
      optionName
      +
      Type: String +
      +
      The name of the option to set.
      +
    • +
    • +
      value
      +
      Type: Object +
      +
      A value to set for the option.
      +
    • +
    +
    +
    +

    option( options )

    +
    Sets one or more options for the dialog.
    +
    • +
      options
      +
      Type: Object +
      +
      A map of option-value pairs to set.
      +
    +
    +
    +
    +

    widget() Returns: jQuery +

    +
    + Returns a jQuery object containing the generated wrapper. +
    +

    Events

    +

    beforeClose( event, ui )

    +
    Triggered when a dialog is about to close. If canceled, the dialog will not close.
    +
      +
    • +
      event
      +
      Type: Event +
      +
      +
    • +
    • +
      ui
      +
      Type: Object +
      +
      +
    • +
    +
    +
    +

    close( event, ui )

    +
    Triggered when the dialog is closed.
    +
      +
    • +
      event
      +
      Type: Event +
      +
      +
    • +
    • +
      ui
      +
      Type: Object +
      +
      +
    • +
    +
    +
    +

    create( event, ui )

    +
    + Triggered when the dialog is created. +
    +
      +
    • +
      event
      +
      Type: Event +
      +
      +
    • +
    • +
      ui
      +
      Type: Object +
      +
      +
    • +
    +
    +
    +

    drag( event, ui )

    +
    Triggered while the dialog is being dragged.
    +
      +
    • +
      event
      +
      Type: Event +
      +
      +
    • +
    • +
      ui
      +
      Type: Object +
      +
      +
        +
      • +
        position
        +
        Type: Object +
        +
        The current CSS position of the dialog.
        +
      • +
      • +
        offset
        +
        Type: Object +
        +
        The current offset position of the dialog.
        +
      • +
      +
    • +
    +
    +
    +

    dragStart( event, ui )

    +
    Triggered when the user starts dragging the dialog.
    +
      +
    • +
      event
      +
      Type: Event +
      +
      +
    • +
    • +
      ui
      +
      Type: Object +
      +
      +
        +
      • +
        position
        +
        Type: Object +
        +
        The current CSS position of the dialog.
        +
      • +
      • +
        offset
        +
        Type: Object +
        +
        The current offset position of the dialog.
        +
      • +
      +
    • +
    +
    +
    +

    dragStop( event, ui )

    +
    Triggered after the dialog has been dragged.
    +
      +
    • +
      event
      +
      Type: Event +
      +
      +
    • +
    • +
      ui
      +
      Type: Object +
      +
      +
        +
      • +
        position
        +
        Type: Object +
        +
        The current CSS position of the dialog.
        +
      • +
      • +
        offset
        +
        Type: Object +
        +
        The current offset position of the dialog.
        +
      • +
      +
    • +
    +
    +
    +

    focus( event, ui )

    +
    Triggered when the dialog gains focus.
    +
      +
    • +
      event
      +
      Type: Event +
      +
      +
    • +
    • +
      ui
      +
      Type: Object +
      +
      +
    • +
    +
    +
    +

    open( event, ui )

    +
    Triggered when the dialog is opened.
    +
      +
    • +
      event
      +
      Type: Event +
      +
      +
    • +
    • +
      ui
      +
      Type: Object +
      +
      +
    • +
    +
    +
    +

    resize( event, ui )

    +
    Triggered while the dialog is being resized.
    +
      +
    • +
      event
      +
      Type: Event +
      +
      +
    • +
    • +
      ui
      +
      Type: Object +
      +
      +
        +
      • +
        orginalPosition
        +
        Type: Object +
        +
        The CSS position of the dialog prior to being resized.
        +
      • +
      • +
        position
        +
        Type: Object +
        +
        The current CSS position of the dialog.
        +
      • +
      • +
        originalSize
        +
        Type: Object +
        +
        The size of the dialog prior to being resized.
        +
      • +
      • +
        size
        +
        Type: Object +
        +
        The current size of the dialog.
        +
      • +
      +
    • +
    +
    +
    +

    resizeStart( event, ui )

    +
    Triggered when the user starts resizing the dialog.
    +
      +
    • +
      event
      +
      Type: Event +
      +
      +
    • +
    • +
      ui
      +
      Type: Object +
      +
      +
        +
      • +
        orginalPosition
        +
        Type: Object +
        +
        The CSS position of the dialog prior to being resized.
        +
      • +
      • +
        position
        +
        Type: Object +
        +
        The current CSS position of the dialog.
        +
      • +
      • +
        originalSize
        +
        Type: Object +
        +
        The size of the dialog prior to being resized.
        +
      • +
      • +
        size
        +
        Type: Object +
        +
        The current size of the dialog.
        +
      • +
      +
    • +
    +
    +
    +

    resizeStop( event, ui )

    +
    Triggered after the dialog has been resized.
    +
      +
    • +
      event
      +
      Type: Event +
      +
      +
    • +
    • +
      ui
      +
      Type: Object +
      +
      +
        +
      • +
        orginalPosition
        +
        Type: Object +
        +
        The CSS position of the dialog prior to being resized.
        +
      • +
      • +
        position
        +
        Type: Object +
        +
        The current CSS position of the dialog.
        +
      • +
      • +
        originalSize
        +
        Type: Object +
        +
        The size of the dialog prior to being resized.
        +
      • +
      • +
        size
        +
        Type: Object +
        +
        The current size of the dialog.
        +
      • +
      +
    • +
    +
    +

    A dialog is a floating window that contains a title bar and a content area. The dialog window can be moved, resized and closed with the 'x' icon by default.

    + +

    If the content length exceeds the maximum height, a scrollbar will automatically appear.

    + +

    A bottom button bar and semi-transparent modal overlay layer are common options that can be added.

    +
    +

    Additional Notes:

    +
    • + This widget requires some functional CSS, otherwise it won't work. If you build a custom theme, use the widget's specific CSS file as a starting point. +
    +

    Example:

    +

    A simple jQuery UI Dialog

    +
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    <!doctype html>
    <html lang="en">
    <head>
        <meta charset="utf-8">
        <title>dialog demo</title>
        <link rel="stylesheet" href="http://code.jquery.com/ui/1.9.0/themes/base/jquery-ui.css">
        <script src="http://code.jquery.com/jquery-1.8.2.js"></script>
        <script src="http://code.jquery.com/ui/1.9.0/jquery-ui.js"></script>
    </head>
    <body>
     
    <button id="opener">open the dialog</button>
    <div id="dialog" title="Dialog Title">I'm a dialog</div>
     
    <script>
    $( "#dialog" ).dialog({ autoOpen: false });
    $( "#opener" ).click(function() {
        $( "#dialog" ).dialog( "open" );
    });
    </script>
     
    </body>
    </html>
    +

    Demo:

    +
    +
    +
    + + + diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/docs/draggable.html b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/docs/draggable.html new file mode 100755 index 000000000..7a4e7831e --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/docs/draggable.html @@ -0,0 +1,563 @@ + + + + + jQuery UI draggable documentation + + + + + +

    QuickNav

    + +
    +

    Events

    + + + + +

    +Draggable Widgetversion added: 1.0 +

    +
    +

    Description: Allow elements to be moved using the mouse.

    +

    Options

    +

    addClassesType: Boolean +

    +
    +Default: true +
    +
    If set to false, will prevent the ui-draggable class from being added. This may be desired as a performance optimization when calling .draggable() on hundreds of elements.
    +
    +
    +

    appendToType: jQuery or Element or Selector or String +

    +
    +Default: "parent" +
    +
    Which element the draggable helper should be appended to while dragging.
    +Multiple types supported:
      +
    • +jQuery: A jQuery object containing the element to append the helper to.
    • +
    • +Element: The element to append the helper to.
    • +
    • +Selector: A selector specifying which element to append the helper to.
    • +
    • +String: The string "parent" will cause the helper to be a sibling of the draggable.
    • +
    +
    +
    +

    axisType: String +

    +
    +Default: false +
    +
    Constrains dragging to either the horizontal (x) or vertical (y) axis. Possible values: "x", "y".
    +
    +
    +

    cancelType: Selector +

    +
    +Default: "input,textarea,button,select,option" +
    +
    Prevents dragging from starting on specified elements.
    +
    +
    +

    connectToSortableType: Selector +

    +
    +Default: false +
    +
    Allows the draggable to be dropped onto the specified sortables. If this option is used, a draggable can be dropped onto a sortable list and then becomes part of it. Note: The helper option must be set to "clone" in order to work flawlessly. Requires the jQuery UI Sortable plugin to be included.
    +
    +
    +

    containmentType: Selector or Element or String or Array +

    +
    +Default: false +
    +
    Constrains dragging to within the bounds of the specified element or region.
    +Multiple types supported:
      +
    • +Selector: The draggable element will be contained to the bounding box of the first element found by the selector. If no element is found, no containment will be set.
    • +
    • +Element: The draggable element will be contained to the bounding box of this element.
    • +
    • +String: Possible values: "parent", "document", "window".
    • +
    • +Array: An array defining a bounding box in the form [ x1, y1, x2, y2 ].
    • +
    +
    +
    +

    cursorType: String +

    +
    +Default: "auto" +
    +
    The CSS cursor during the drag operation.
    +
    +
    +

    cursorAtType: Object +

    +
    +Default: false +
    +
    Sets the offset of the dragging helper relative to the mouse cursor. Coordinates can be given as a hash using a combination of one or two keys: { top, left, right, bottom }.
    +
    +
    +

    delayType: Number +

    +
    +Default: 0 +
    +
    Time in milliseconds after mousedown until dragging should start. This option can be used to prevent unwanted drags when clicking on an element.
    +
    +
    +

    disabledType: Boolean +

    +
    +Default: false +
    +
    Disables the draggable if set to true.
    +
    +
    +

    distanceType: Number +

    +
    +Default: 1 +
    +
    Distance in pixels after mousedown the mouse must move before dragging should start. This option can be used to prevent unwanted drags when clicking on an element.
    +
    +
    +

    gridType: Array +

    +
    +Default: false +
    +
    Snaps the dragging helper to a grid, every x and y pixels. The array must be of the form [ x, y ].
    +
    +
    +

    handleType: Selector or Element +

    +
    +Default: false +
    +
    If specified, restricts dragging from starting unless the mousedown occurs on the specified element(s).
    +
    +
    +

    helperType: String or Function() +

    +
    +Default: "original" +
    +
    Allows for a helper element to be used for dragging display.
    +Multiple types supported:
      +
    • +String: If set to "clone", then the element will be cloned and the clone will be dragged.
    • +
    • +Function: A function that will return a DOMElement to use while dragging.
    • +
    +
    +
    +

    iframeFixType: Boolean or Selector +

    +
    +Default: false +
    +
    Prevent iframes from capturing the mousemove events during a drag. Useful in combination with the cursorAt option, or in any case where the mouse cursor may not be over the helper.
    +Multiple types supported:
      +
    • +Boolean: When set to true, transparent overlays will be placed over all iframes on the page.
    • +
    • +Selector: Any iframes matching the selector will be covered by transparent overlays.
    • +
    +
    +
    +

    opacityType: Number +

    +
    +Default: false +
    +
    Opacity for the helper while being dragged.
    +
    +
    +

    refreshPositionsType: Boolean +

    +
    +Default: false +
    +
    + If set to true, all droppable positions are calculated on every mousemove. + Caution: This solves issues on highly dynamic pages, but dramatically decreases performance. +
    +
    +
    +

    revertType: Boolean or String +

    +
    +Default: false +
    +
    Whether the element should revert to its start position when dragging stops.
    +Multiple types supported:
      +
    • +Boolean: If set to true the element will always revert.
    • +
    • +String: If set to "invalid", revert will only occur if the draggable has not been dropped on a droppable. For "valid", it's the other way around.
    • +
    +
    +
    +

    revertDurationType: Number +

    +
    +Default: 500 +
    +
    The duration of the revert animation, in milliseconds. Ignored if the revert option is false.
    +
    +
    +

    scopeType: String +

    +
    +Default: "default" +
    +
    Used to group sets of draggable and droppable items, in addition to droppable's accept option. A draggable with the same scope value as a droppable will be accepted by the droppable.
    +
    +
    +

    scrollType: Boolean +

    +
    +Default: true +
    +
    If set to true, container auto-scrolls while dragging.
    +
    +
    +

    scrollSensitivityType: Number +

    +
    +Default: 20 +
    +
    Distance in pixels from the edge of the viewport after which the viewport should scroll. Distance is relative to pointer, not the draggable. Ignored if the scroll option is false.
    +
    +
    +

    scrollSpeedType: Number +

    +
    +Default: 20 +
    +
    The speed at which the window should scroll once the mouse pointer gets within the scrollSensitivity distance. Ignored if the scroll option is false.
    +
    +
    +

    snapType: Boolean or Selector +

    +
    +Default: false +
    +
    Whether the element should snap to other elements.
    +Multiple types supported:
      +
    • +Boolean: When set to true, the element will snap to all other draggable elements.
    • +
    • +Selector: A selector specifying which elements to snap to.
    • +
    +
    +
    +

    snapModeType: String +

    +
    +Default: "both" +
    +
    Determines which edges of snap elements the draggable will snap to. Ignored if the snap option is false. Possible values: "inner", "outer", "both".
    +
    +
    +

    snapToleranceType: Number +

    +
    +Default: 20 +
    +
    The distance in pixels from the snap element edges at which snapping should occur. Ignored if the snap option is false.
    +
    +
    +

    stackType: Selector +

    +
    +Default: false +
    +
    Controls the z-index of the set of elements that match the selector, always brings the currently dragged item to the front. Very useful in things like window managers.
    +
    +
    +

    zIndexType: Number +

    +
    +Default: false +
    +
    Z-index for the helper while being dragged.
    +

    Methods

    +

    destroy()

    +
    + Removes the draggable functionality completely. This will return the element back to its pre-init state. +
    +
    +
    +

    disable()

    +
    + Disables the draggable. +
    +
    +
    +

    enable()

    +
    + Enables the draggable. +
    +
    +
    +
    +

    option( optionName ) Returns: Object +

    +
    Gets the value currently associated with the specified optionName.
    +
    • +
      optionName
      +
      Type: String +
      +
      The name of the option to get.
      +
    +
    +
    +

    option() Returns: PlainObject +

    +
    Gets an object containing key/value pairs representing the current draggable options hash.
    +
    +
    +

    option( optionName, value )

    +
    Sets the value of the draggable option associated with the specified optionName.
    +
      +
    • +
      optionName
      +
      Type: String +
      +
      The name of the option to set.
      +
    • +
    • +
      value
      +
      Type: Object +
      +
      A value to set for the option.
      +
    • +
    +
    +
    +

    option( options )

    +
    Sets one or more options for the draggable.
    +
    • +
      options
      +
      Type: Object +
      +
      A map of option-value pairs to set.
      +
    +
    +
    +
    +

    widget() Returns: jQuery +

    +
    + Returns a jQuery object containing the draggable element. +
    +

    Events

    +

    create( event, ui )

    +
    + Triggered when the draggable is created. +
    +
      +
    • +
      event
      +
      Type: Event +
      +
      +
    • +
    • +
      ui
      +
      Type: Object +
      +
      +
    • +
    +
    +
    +

    drag( event, ui )

    +
    Triggered while the mouse is moved during the dragging.
    +
      +
    • +
      event
      +
      Type: Event +
      +
      +
    • +
    • +
      ui
      +
      Type: Object +
      +
      +
        +
      • +
        helper
        +
        Type: jQuery +
        +
        The jQuery object representing the helper that's being dragged.
        +
      • +
      • +
        position
        +
        Type: Object +
        +
        Current CSS position of the helper as { top, left } object.
        +
      • +
      • +
        offset
        +
        Type: Object +
        +
        Current offset position of the helper as { top, left } object.
        +
      • +
      +
    • +
    +
    +
    +

    start( event, ui )

    +
    Triggered when dragging starts.
    +
      +
    • +
      event
      +
      Type: Event +
      +
      +
    • +
    • +
      ui
      +
      Type: Object +
      +
      +
        +
      • +
        helper
        +
        Type: jQuery +
        +
        The jQuery object representing the helper that's being dragged.
        +
      • +
      • +
        position
        +
        Type: Object +
        +
        Current CSS position of the helper as { top, left } object.
        +
      • +
      • +
        offset
        +
        Type: Object +
        +
        Current offset position of the helper as { top, left } object.
        +
      • +
      +
    • +
    +
    +
    +

    stop( event, ui )

    +
    Triggered when dragging stops.
    +
      +
    • +
      event
      +
      Type: Event +
      +
      +
    • +
    • +
      ui
      +
      Type: Object +
      +
      +
        +
      • +
        helper
        +
        Type: jQuery +
        +
        The jQuery object representing the helper that's being dragged.
        +
      • +
      • +
        position
        +
        Type: Object +
        +
        Current CSS position of the helper as { top, left } object.
        +
      • +
      • +
        offset
        +
        Type: Object +
        +
        Current offset position of the helper as { top, left } object.
        +
      • +
      +
    • +
    +
    +

    Make the selected elements draggable by mouse. If you want not just drag, but drag & drop, see the jQuery UI Droppable plugin, which provides a drop target for draggables.

    +
    +

    Example:

    +

    A simple jQuery UI Draggable

    +
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    <!doctype html>
    <html lang="en">
    <head>
        <meta charset="utf-8">
        <title>draggable demo</title>
        <link rel="stylesheet" href="http://code.jquery.com/ui/1.9.0/themes/base/jquery-ui.css">
        <style>
        #draggable {
            width: 100px;
            height: 100px;
            background: #ccc;
        }
        </style>
        <script src="http://code.jquery.com/jquery-1.8.2.js"></script>
        <script src="http://code.jquery.com/ui/1.9.0/jquery-ui.js"></script>
    </head>
    <body>
     
    <div id="draggable">Drag me</div>
     
    <script>
    $( "#draggable" ).draggable();
    </script>
     
    </body>
    </html>
    +

    Demo:

    +
    +
    +
    + + + diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/docs/drop-effect.html b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/docs/drop-effect.html new file mode 100755 index 000000000..9c808b947 --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/docs/drop-effect.html @@ -0,0 +1,55 @@ + + + + + jQuery UI drop-effect documentation + + + + + +

    Drop Effect

    +
    +

    Description: + The drop effect hides or shows an element fading in/out and sliding in a direction. +

    +
    • +

      drop

      +
      • +
        +direction (default: "left")
        +
        Type: String +
        +
        +

        The direction the element will fall to hide the element, or the direction from which the element will be revealed.

        +

        Possible Values: up, down, left, right.

        +
        +
      +
    +

    Example:

    +

    Toggle a div using the drop effect.

    +
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    <!doctype html>
    <html lang="en">
    <head>
        <meta charset="utf-8">
        <title>drop demo</title>
        <link rel="stylesheet" href="http://code.jquery.com/ui/1.9.0/themes/base/jquery-ui.css">
        <style>
        #toggle {
            width: 100px;
            height: 100px;
            background: #ccc;
        }
        </style>
        <script src="http://code.jquery.com/jquery-1.8.2.js"></script>
        <script src="http://code.jquery.com/ui/1.9.0/jquery-ui.js"></script>
    </head>
    <body>
     
    <p>Click anywhere to toggle the box.</p>
    <div id="toggle"></div>
     
    <script>
    $( document ).click(function() {
        $( "#toggle" ).toggle( "drop" );
    });
    </script>
     
    </body>
    </html>
    +

    Demo:

    +
    +
    +
    + + + diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/docs/droppable.html b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/docs/droppable.html new file mode 100755 index 000000000..579a487ec --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/docs/droppable.html @@ -0,0 +1,436 @@ + + + + + jQuery UI droppable documentation + + + + + +

    QuickNav

    + +

    +Droppable Widgetversion added: 1.0 +

    +
    +

    Description: Create targets for draggable elements.

    +

    Options

    +

    acceptType: Selector or Function() +

    +
    +Default: "*" +
    +
    Controls which draggable elements are accepted by the droppable.
    +Multiple types supported:
      +
    • +Selector: A selector indicating which draggable elements are accepted.
    • +
    • +Function: A function that will be called for each draggable on the page (passed as the first argument to the function). The function must return true if the draggable should be accepted.
    • +
    +
    +
    +

    activeClassType: String +

    +
    +Default: false +
    +
    If specified, the class will be added to the droppable while an acceptable draggable is being dragged.
    +
    +
    +

    addClassesType: Boolean +

    +
    +Default: true +
    +
    If set to false, will prevent the ui-droppable class from being added. This may be desired as a performance optimization when calling .droppable() init on hundreds of elements.
    +
    +
    +

    disabledType: Boolean +

    +
    +Default: false +
    +
    Disables the droppable if set to true.
    +
    +
    +

    greedyType: Boolean +

    +
    +Default: false +
    +
    By default, when an element is dropped on nested droppables, each droppable will receive the element. However, by setting this option to true, any parent droppables will not receive the element.
    +
    +
    +

    hoverClassType: String +

    +
    +Default: false +
    +
    If specified, the class will be added to the droppable while an acceptable draggable is being hovered over the droppable.
    +
    +
    +

    scopeType: String +

    +
    +Default: "default" +
    +
    Used to group sets of draggable and droppable items, in addition to the accept option. A draggable with the same scope value as a droppable will be accepted.
    +
    +
    +

    toleranceType: String +

    +
    +Default: "intersect" +
    +
    + Specifies which mode to use for testing whether a draggable is hovering over a droppable. Possible values: +
      +
    • +"fit": Draggable overlaps the droppable entirely.
    • +
    • +"intersect": Draggable overlaps the droppable at least 50% in both directions.
    • +
    • +"pointer": Mouse pointer overlaps the droppable.
    • +
    • +"touch": Draggable overlaps the droppable any amount.
    • +
    +
    +

    Methods

    +

    destroy()

    +
    + Removes the droppable functionality completely. This will return the element back to its pre-init state. +
    +
    +
    +

    disable()

    +
    + Disables the droppable. +
    +
    +
    +

    enable()

    +
    + Enables the droppable. +
    +
    +
    +
    +

    option( optionName ) Returns: Object +

    +
    Gets the value currently associated with the specified optionName.
    +
    • +
      optionName
      +
      Type: String +
      +
      The name of the option to get.
      +
    +
    +
    +

    option() Returns: PlainObject +

    +
    Gets an object containing key/value pairs representing the current droppable options hash.
    +
    +
    +

    option( optionName, value )

    +
    Sets the value of the droppable option associated with the specified optionName.
    +
      +
    • +
      optionName
      +
      Type: String +
      +
      The name of the option to set.
      +
    • +
    • +
      value
      +
      Type: Object +
      +
      A value to set for the option.
      +
    • +
    +
    +
    +

    option( options )

    +
    Sets one or more options for the droppable.
    +
    • +
      options
      +
      Type: Object +
      +
      A map of option-value pairs to set.
      +
    +
    +
    +
    +

    widget() Returns: jQuery +

    +
    + Returns a jQuery object containing the droppable element. +
    +

    Events

    +

    activate( event, ui )

    +
    Triggered when an accepted draggable starts dragging. This can be useful if you want to make the droppable "light up" when it can be dropped on.
    +
      +
    • +
      event
      +
      Type: Event +
      +
      +
    • +
    • +
      ui
      +
      Type: Object +
      +
      +
        +
      • +
        draggable
        +
        Type: jQuery +
        +
        A jQuery object representing the draggable element.
        +
      • +
      • +
        helper
        +
        Type: jQuery +
        +
        A jQuery object representing the helper that is being dragged.
        +
      • +
      • +
        position
        +
        Type: Object +
        +
        Current CSS position of the draggable helper as { top, left } object.
        +
      • +
      • +
        offset
        +
        Type: Object +
        +
        Current offset position of the draggable helper as { top, left } object.
        +
      • +
      +
    • +
    +
    +
    +

    create( event, ui )

    +
    + Triggered when the droppable is created. +
    +
      +
    • +
      event
      +
      Type: Event +
      +
      +
    • +
    • +
      ui
      +
      Type: Object +
      +
      +
    • +
    +
    +
    +

    deactivate( event, ui )

    +
    Triggered when an accepted draggable stops dragging.
    +
      +
    • +
      event
      +
      Type: Event +
      +
      +
    • +
    • +
      ui
      +
      Type: Object +
      +
      +
        +
      • +
        draggable
        +
        Type: jQuery +
        +
        A jQuery object representing the draggable element.
        +
      • +
      • +
        helper
        +
        Type: jQuery +
        +
        A jQuery object representing the helper that is being dragged.
        +
      • +
      • +
        position
        +
        Type: Object +
        +
        Current CSS position of the draggable helper as { top, left } object.
        +
      • +
      • +
        offset
        +
        Type: Object +
        +
        Current offset position of the draggable helper as { top, left } object.
        +
      • +
      +
    • +
    +
    +
    +

    drop( event, ui )

    +
    Triggered when an accepted draggable is dropped on the droppable (based on thetolerance option).
    +
      +
    • +
      event
      +
      Type: Event +
      +
      +
    • +
    • +
      ui
      +
      Type: Object +
      +
      +
        +
      • +
        draggable
        +
        Type: jQuery +
        +
        A jQuery object representing the draggable element.
        +
      • +
      • +
        helper
        +
        Type: jQuery +
        +
        A jQuery object representing the helper that is being dragged.
        +
      • +
      • +
        position
        +
        Type: Object +
        +
        Current CSS position of the draggable helper as { top, left } object.
        +
      • +
      • +
        offset
        +
        Type: Object +
        +
        Current offset position of the draggable helper as { top, left } object.
        +
      • +
      +
    • +
    +
    +
    +

    out( event, ui )

    +
    Triggered when an accepted draggable is dragged out of the droppable (based on thetolerance option).
    +
      +
    • +
      event
      +
      Type: Event +
      +
      +
    • +
    • +
      ui
      +
      Type: Object +
      +
      +
    • +
    +
    +
    +

    over( event, ui )

    +
    Triggered when an accepted draggable is dragged over the droppable (based on thetolerance option).
    +
      +
    • +
      event
      +
      Type: Event +
      +
      +
    • +
    • +
      ui
      +
      Type: Object +
      +
      +
        +
      • +
        draggable
        +
        Type: jQuery +
        +
        A jQuery object representing the draggable element.
        +
      • +
      • +
        helper
        +
        Type: jQuery +
        +
        A jQuery object representing the helper that is being dragged.
        +
      • +
      • +
        position
        +
        Type: Object +
        +
        Current CSS position of the draggable helper as { top, left } object.
        +
      • +
      • +
        offset
        +
        Type: Object +
        +
        Current offset position of the draggable helper as { top, left } object.
        +
      • +
      +
    • +
    +
    +

    The jQuery UI Droppable plugin makes selected elements droppable (meaning they accept being dropped on by draggables). You can specify which draggables each will accept.

    +
    +

    Example:

    +

    A pair of draggable and droppable elements.

    +
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    <!doctype html>
    <html lang="en">
    <head>
        <meta charset="utf-8">
        <title>droppable demo</title>
        <link rel="stylesheet" href="http://code.jquery.com/ui/1.9.0/themes/base/jquery-ui.css">
        <style>
        #draggable {
            width: 100px;
            height: 100px;
            background: #ccc;
        }
        #droppable {
            position: absolute;
            left: 250px;
            top: 0;
            width: 125px;
            height: 125px;
            background: #999;
            color: #fff;
            padding: 10px;
        }
        </style>
        <script src="http://code.jquery.com/jquery-1.8.2.js"></script>
        <script src="http://code.jquery.com/ui/1.9.0/jquery-ui.js"></script>
    </head>
    <body>
     
    <div id="droppable">Drop here</div>
    <div id="draggable">Drag me</div>
     
    <script>
    $( "#draggable" ).draggable();
    $( "#droppable" ).droppable({
        drop: function() {
            alert( "dropped" );
        }
    });
    </script>
     
    </body>
    </html>
    +

    Demo:

    +
    +
    +
    + + + diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/docs/explode-effect.html b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/docs/explode-effect.html new file mode 100755 index 000000000..cee2d1ece --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/docs/explode-effect.html @@ -0,0 +1,52 @@ + + + + + jQuery UI explode-effect documentation + + + + + +

    Explode Effect

    +
    +

    Description: + The explode effect hides or shows an element by splitting it into pieces. +

    +
    • +

      explode

      +
      • +
        +pieces (default: 9)
        +
        Type: Integer +
        +
        The number of pieces to explode, should be a perfect square, any other values are rounded to the nearest square.
        +
      +
    +

    Example:

    +

    Toggle a div using the explode effect.

    +
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    <!doctype html>
    <html lang="en">
    <head>
        <meta charset="utf-8">
        <title>explode demo</title>
        <link rel="stylesheet" href="http://code.jquery.com/ui/1.9.0/themes/base/jquery-ui.css">
        <style>
        #toggle {
            width: 100px;
            height: 100px;
            background: #ccc;
        }
        </style>
        <script src="http://code.jquery.com/jquery-1.8.2.js"></script>
        <script src="http://code.jquery.com/ui/1.9.0/jquery-ui.js"></script>
    </head>
    <body>
     
    <p>Click anywhere to toggle the box.</p>
    <div id="toggle"></div>
     
    <script>
    $( document ).click(function() {
        $( "#toggle" ).toggle( "explode" );
    });
    </script>
     
    </body>
    </html>
    +

    Demo:

    +
    +
    +
    + + + diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/docs/fade-effect.html b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/docs/fade-effect.html new file mode 100755 index 000000000..f05a7a3a3 --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/docs/fade-effect.html @@ -0,0 +1,43 @@ + + + + + jQuery UI fade-effect documentation + + + + + +

    Fade Effect

    +
    +

    Description: + The fade effect hides or shows an element by fading it. +

    +
    • fade

    +

    Example:

    +

    Toggle a div using the fade effect.

    +
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    <!doctype html>
    <html lang="en">
    <head>
        <meta charset="utf-8">
        <title>fade demo</title>
        <link rel="stylesheet" href="http://code.jquery.com/ui/1.9.0/themes/base/jquery-ui.css">
        <style>
        #toggle {
            width: 100px;
            height: 100px;
            background: #ccc;
        }
        </style>
        <script src="http://code.jquery.com/jquery-1.8.2.js"></script>
        <script src="http://code.jquery.com/ui/1.9.0/jquery-ui.js"></script>
    </head>
    <body>
     
    <p>Click anywhere to toggle the box.</p>
    <div id="toggle"></div>
     
    <script>
    $( document ).click(function() {
        $( "#toggle" ).toggle( "fade" );
    });
    </script>
     
    </body>
    </html>
    +

    Demo:

    +
    +
    +
    + + + diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/docs/fold-effect.html b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/docs/fold-effect.html new file mode 100755 index 000000000..5e64ea181 --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/docs/fold-effect.html @@ -0,0 +1,61 @@ + + + + + jQuery UI fold-effect documentation + + + + + +

    Fold Effect

    +
    +

    Description: + The fold effect hides or shows an element by folding it. +

    +
    • +

      fold

      +
        +
      • +
        +size (default: 15)
        +
        Type: Number or String +
        +
        The size of the "folded" element.
        +
      • +
      • +
        +horizFirst (default: false)
        +
        Type: Boolean +
        +
        Whether the horizontal direction happens first when hiding. Remember, showing inverts hiding.
        +
      • +
      +
    +

    Example:

    +

    Toggle a div using the fold effect.

    +
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    <!doctype html>
    <html lang="en">
    <head>
        <meta charset="utf-8">
        <title>fold demo</title>
        <link rel="stylesheet" href="http://code.jquery.com/ui/1.9.0/themes/base/jquery-ui.css">
        <style>
        #toggle {
            width: 100px;
            height: 100px;
            background: #ccc;
        }
        </style>
        <script src="http://code.jquery.com/jquery-1.8.2.js"></script>
        <script src="http://code.jquery.com/ui/1.9.0/jquery-ui.js"></script>
    </head>
    <body>
     
    <p>Click anywhere to toggle the box.</p>
    <div id="toggle"></div>
     
    <script>
    $( document ).click(function() {
        $( "#toggle" ).toggle( "fold" );
    });
    </script>
     
    </body>
    </html>
    +

    Demo:

    +
    +
    +
    + + + diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/docs/highlight-effect.html b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/docs/highlight-effect.html new file mode 100755 index 000000000..b4e1338a8 --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/docs/highlight-effect.html @@ -0,0 +1,52 @@ + + + + + jQuery UI highlight-effect documentation + + + + + +

    Highlight Effect

    +
    +

    Description: + The highlight effect hides or shows an element by animating its background color first. +

    +
    • +

      highlight

      +
      • +
        +color (default: "#ffff99")
        +
        Type: String +
        +
        The background color used during the animation.
        +
      +
    +

    Example:

    +

    Toggle a div using the highlight effect.

    +
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    <!doctype html>
    <html lang="en">
    <head>
        <meta charset="utf-8">
        <title>highlight demo</title>
        <link rel="stylesheet" href="http://code.jquery.com/ui/1.9.0/themes/base/jquery-ui.css">
        <style>
        #toggle {
            width: 100px;
            height: 100px;
            background: #ccc;
        }
        </style>
        <script src="http://code.jquery.com/jquery-1.8.2.js"></script>
        <script src="http://code.jquery.com/ui/1.9.0/jquery-ui.js"></script>
    </head>
    <body>
     
    <p>Click anywhere to toggle the box.</p>
    <div id="toggle"></div>
     
    <script>
    $( document ).click(function() {
        $( "#toggle" ).toggle( "highlight" );
    });
    </script>
     
    </body>
    </html>
    +

    Demo:

    +
    +
    +
    + + + diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/docs/jQuery.widget.html b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/docs/jQuery.widget.html new file mode 100755 index 000000000..5ae51d7bf --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/docs/jQuery.widget.html @@ -0,0 +1,565 @@ + + + + + jQuery UI jQuery documentation + + + + + +
    +

    Contents:

    + +

    jQuery.widget( name [, base ], prototype )

    +
    +

    Description: Create stateful jQuery plugins using the same abstraction as all jQuery UI widgets.

    +
    • +

      jQuery.widget( name [, base ], prototype )

      +
        +
      • +
        name
        +
        Type: String +
        +
        The name of the widget to create, including the namespace.
        +
      • +
      • +
        base
        +
        Type: Function()
        +
        The base widget to inherit from. This must be a constructor that can be instantiated with the `new` keyword. Defaults to jQuery.Widget.
        +
      • +
      • +
        prototype
        +
        Type: PlainObject +
        +
        The object to use as a prototype for the widget.
        +
      • +
      +
    +
    +

    You can create new widgets from scratch, using just the $.Widget object as a base to inherit from, or you can explicitly inherit from existing jQuery UI or third-party widgets. Defining a widget with the same name as you inherit from even allows you to extend widgets in place.

    + +

    jQuery UI contains many widgets that maintain state and therefore have a slightly different usage pattern than typical jQuery plugins. All of jQuery UI's widgets use the same patterns, which is defined by the widget factory. So if you learn how to use one widget, then you'll know how to use all of them.

    + +

    Note: This documentation shows examples using the progressbar widget but the syntax is the same for every widget.

    + +

    Initialization

    + +

    In order to track the state of the widget, we must introduce a full life cycle for the widget. The life cycle starts when the widget is initalized. To initialize a widget, we simply call the plugin on one or more elements.

    + +
    $( "#elem" ).progressbar();
    + +

    This will initialize each element in the jQuery object, in this case the element with an id of "elem". Because we called the progressbar() method with no parameters, the widget is initialized with its default options. We can pass a set of options during initialization in order to override the default options.

    + +
    $( "#elem" ).progressbar({ value: 20 });
    + +

    We can pass as many or as few options as we want during initialization. Any options that we don't pass will just use their default values.

    + +

    The options are part of the widget's state, so we can set options after initialization as well. We'll see this later with the option method.

    + +

    Methods

    + +

    Now that the widget is initialized, we can query its state or perform actions on the widget. All actions after initialization take the form of a method call. To call a method on a widget, we pass the name of the method to the jQuery plugin. For example, to call the value() method on our progressbar widget, we would use:

    + +
    $( "#elem" ).progressbar( "value" );
    + +

    If the method accepts parameters, we can pass them after the method name. For example, to pass the parameter 40 to the value() method, we can use:

    + +
    $( "#elem" ).progressbar( "value", 40 );
    + +

    Just like other methods in jQuery, most widget methods return the jQuery object for chaining.

    + +
    $( "#elem" )
        .progressbar( "value", 90 )
        .addClass( "almost-done" );
    + +

    Each widget will have its own set of methods based on the functionality that the widget provides. However, there are a few methods that exist on all widgets, which are documented below.

    + +

    Events

    + +

    All widgets have events associated with their various behaviors to notify you when the state is changing. For most widgets, when the events are triggered, the names are prefixed with the widget name. For example, we can bind to progressbar's change event which is triggered whenever the value changes.

    + +
    $( "#elem" ).bind( "progressbarchange", function() {
        alert( "The value has changed!" );
    });
    + +

    Each event has a corresponding callback, which is exposed as an option. We can hook into progressbar's change callback instead of binding to the progressbarchange event, if we want to.

    + +
    $( "#elem" ).progressbar({
        change: function() {
            alert( "The value has changed!" );
        }
    });
    + +

    All widgets have a create event which is triggered upon instantiation.

    +
    +

    QuickNav

    +

    Options

    + + + +
    + +
    +

    Events

    + +

    Base Widget

    +
    +

    Description: The base widget used by the widget factory.

    +

    Options

    +

    disabledType: Boolean +

    +
    +Default: false +
    +
    Disables the jQuery.Widget if set to true.
    +
    +
    +

    hideType: Boolean or Number or String or Object +

    +
    +Default: null +
    +
    If and how to animate the hiding of the element.
    +Multiple types supported:
      +
    • +Boolean: + When set to false, no animation will be used and the element will be hidden immediately. + When set to true, the element will fade out with the default duration and the default easing. +
    • +
    • +Number: + The element will fade out with the specified duration and the default easing. +
    • +
    • +String: + The element will be hidden using the specified effect. + The value can either be the name of a built-in jQuery animateion method, such as "slideUp", or the name of a jQuery UI effect, such as "fold". + In either case the effect will be used with the default duration and the default easing. +
    • +
    • +Object: If the value is an object, then effect, duration, and easing properties may be provided. If the effect property contains the name of a jQuery method, then that method will be used; otherwise it is assumed to be the name of a jQuery UI effect. When using a jQuery UI effect that supports additional settings, you may include those settings in the object and they will be passed to the effect. If duration or easing is omitted, then the default values will be used. If effect is omitted, then "fadeOut" will be used.
    • +
    +
    +
    +

    showType: Boolean or Number or String or Object +

    +
    +Default: null +
    +
    If and how to animate the showing of the element.
    +Multiple types supported:
      +
    • +Boolean: + When set to false, no animation will be used and the element will be shown immediately. + When set to true, the element will fade in with the default duration and the default easing. +
    • +
    • +Number: + The element will fade in with the specified duration and the default easing. +
    • +
    • +String: + The element will be shown using the specified effect. + The value can either be the name of a built-in jQuery animateion method, such as "slideDown", or the name of a jQuery UI effect, such as "fold". + In either case the effect will be used with the default duration and the default easing. +
    • +
    • +Object: If the value is an object, then effect, duration, and easing properties may be provided. If the effect property contains the name of a jQuery method, then that method will be used; otherwise it is assumed to be the name of a jQuery UI effect. When using a jQuery UI effect that supports additional settings, you may include those settings in the object and they will be passed to the effect. If duration or easing is omitted, then the default values will be used. If effect is omitted, then "fadeIn" will be used.
    • +
    +

    Methods

    +

    _create()

    +
    + The _create() method is the widget's constructor. + There are no parameters, but this.element and this.options are already set. +
    +
    +
    +

    _delay( fn [, delay ] ) Returns: Number +

    +
    + Invokes the provided function after a specified delay. Keeps this context correct. Essentially setTimeout(). +

    Returns the timeout ID for use with clearTimeout().

    +
    +
      +
    • +
      fn
      +
      Type: Function() or String +
      +
      The function to invoke. Can also be the name of a method on the widget.
      +
    • +
    • +
      delay
      +
      Type: Number +
      +
      The number of milliseconds to wait before invoking the function. Deafults to 0.
      +
    • +
    +
    +
    +

    _destroy()

    +
    + The public destroy() method cleans up all common data, events, etc. and then delegates out to _destroy() for custom, widget-specific, cleanup. +
    +
    +
    +

    _focusable( element )

    +
    + Sets up element to apply the ui-state-focus class on focus. +

    The event handlers are automatically cleaned up on destroy.

    +
    +
    • +
      element
      +
      Type: jQuery +
      +
      The element(s) to apply the focusable behavior to.
      +
    +
    +
    +

    _getCreateEventData() Returns: Object +

    +
    + All widgets trigger the create event. By default, no data is provided in the event, but this method can return an object which will be passed as the create event's data. +
    +
    +
    +

    _getCreateOptions() Returns: Object +

    +
    + This method allows the widget to define a custom method for defining options during instantiation. This user-provided options override the options returned by this method which override the default options. +
    +
    +
    +

    _hoverable( element )

    +
    + Sets up element to apply the ui-state-hover class on hover. +

    The event handlers are automatically cleaned up on destroy.

    +
    +
    • +
      element
      +
      Type: jQuery +
      +
      The element(s) to apply the hoverable behavior to.
      +
    +
    +
    +

    _init()

    +
    + Widgets have the concept of initialization that is distinct from creation. Any time the plugin is called with no arguments or with only an option hash, the widget is initialized; this includes when the widget is created. + +

    Note: Initialization should only be handled if there is a logical action to perform on successive calls to the widget with no arguments.

    +
    +
    +
    +

    _off( element, eventName )

    +
    + Unbinds event handlers from the specified element(s). +
    +
      +
    • +
      element
      +
      Type: jQuery +
      +
      + The element(s) to unbind the event handlers from. Unlike the _on() method, the elements are required for _off(). +
      +
    • +
    • +
      eventName
      +
      Type: String +
      +
      One or more space-separated event types.
      +
    • +
    +
    +
    +

    _on( [element ], handlers )

    +
    + Binds event handlers to the specified element(s). Delegation is supported via selectors inside the event names, e.g., "click .foo". The _on() method provides several benefits of direct event binding: +
      +
    • Maintains proper this context inside the handlers.
    • +
    • Automatically handles disabled widgets: If the widget is disabled or the event occurs on an element with the ui-state-disabled class, the event handler is not invoked.
    • +
    • Event handlers are automatically namespaced and cleaned up on destroy.
    • +
    +
    +
      +
    • +
      element
      +
      Type: jQuery +
      +
      Which element(s) to bind the event handlers to. If no element is provided, this.element is used.
      +
    • +
    • +
      handlers
      +
      Type: Object +
      +
      + A map in which the string keys represent the event type and optional selector for delegation, and the values represent a handler function to be called for the event. +
      +
    • +
    +
    +
    +

    _setOption( key, value )

    +
    + Called from the _setOptions() method for each individual option. Widget state should be updated based on changes. +
    +
      +
    • +
      key
      +
      Type: String +
      +
      The name of the option to set.
      +
    • +
    • +
      value
      +
      Type: Object +
      +
      A value to set for the option.
      +
    • +
    +
    +
    +

    _setOptions( options )

    +
    + Called whenever the option() method is called, regardless of the form in which the option() method was called. +

    Overriding this is useful if you can defer processor-intensive changes for multiple option changes.

    +
    +
    • +
      options
      +
      Type: Object +
      +
      A map of option-value pairs to set.
      +
    +
    +
    +

    _show( element, option [, callback ] )

    +
    + Shows an element immediately, using built-in animation methods, or using custom effects. + See the show option for possible option values. +
    +
      +
    • +
      element
      +
      Type: jQuery +
      +
      The element(s) to show.
      +
    • +
    • +
      option
      +
      Type: Object +
      +
      The settings defining how to show the element.
      +
    • +
    • +
      callback
      +
      Type: Function()
      +
      Callback to invoke after the element has been fully shown.
      +
    • +
    +
    +
    +

    _show( element, option [, callback ] )

    +
    + Hides an element immediately, using built-in animation methods, or using custom effects. + See the hide option for possible option values. +
    +
      +
    • +
      element
      +
      Type: jQuery +
      +
      The element(s) to hide.
      +
    • +
    • +
      option
      +
      Type: Object +
      +
      The settings defining how to hide the element.
      +
    • +
    • +
      callback
      +
      Type: Function()
      +
      Callback to invoke after the element has been fully hidden.
      +
    • +
    +
    +
    +

    _super()

    +
    + Invokes the method of the same name from the parent widget, with any specified arguments. Essentially .call(). +
    +
    +
    +

    _superApply( arguments )

    +
    + Invokes the method of the same name from the parent widget, with the array of arguments. Essentially .apply(). +
    +
    • +
      arguments
      +
      Type: Array +
      +
      Array of arguments to pass to the parent method.
      +
    +
    +
    +

    _trigger( type [, event ] [, data ] )

    +
    + Triggers an event and its associated callback. +

    The option with the name equal to type is invoked as the callback.

    +

    The event name is the widget name + type.

    +

    Note: When providing data, you must provide all three parameters. If there is no event to pass along, just pass null.

    +
    +
      +
    • +
      type
      +
      Type: String +
      +
      The type should match the name of a callback option. The full event type will be generated automatically.
      +
    • +
    • +
      event
      +
      Type: Event +
      +
      The original event that caused this event to occur; useful for providing context to the listener.
      +
    • +
    • +
      data
      +
      Type: Object +
      +
      A hash of data associated with the event.
      +
    • +
    +
    +
    +

    destroy()

    +
    + Removes the jQuery.Widget functionality completely. This will return the element back to its pre-init state. +
    +
    +
    +

    disable()

    +
    + Disables the jQuery.Widget. +
    +
    +
    +

    enable()

    +
    + Enables the jQuery.Widget. +
    +
    +
    +
    +

    option( optionName ) Returns: Object +

    +
    Gets the value currently associated with the specified optionName.
    +
    • +
      optionName
      +
      Type: String +
      +
      The name of the option to get.
      +
    +
    +
    +

    option() Returns: PlainObject +

    +
    Gets an object containing key/value pairs representing the current jQuery.Widget options hash.
    +
    +
    +

    option( optionName, value )

    +
    Sets the value of the jQuery.Widget option associated with the specified optionName.
    +
      +
    • +
      optionName
      +
      Type: String +
      +
      The name of the option to set.
      +
    • +
    • +
      value
      +
      Type: Object +
      +
      A value to set for the option.
      +
    • +
    +
    +
    +

    option( options )

    +
    Sets one or more options for the jQuery.Widget.
    +
    • +
      options
      +
      Type: Object +
      +
      A map of option-value pairs to set.
      +
    +
    +
    +
    +

    widget() Returns: jQuery +

    +
    + Returns a jQuery object containing the original element or other relevant generated element. +
    +

    Events

    +

    create( event, ui )

    +
    + Triggered when the jQuery.Widget is created. +
    +
      +
    • +
      event
      +
      Type: Event +
      +
      +
    • +
    • +
      ui
      +
      Type: Object +
      +
      +
    • +
    +
    +
    + + + diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/docs/menu.html b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/docs/menu.html new file mode 100755 index 000000000..0f19c3dd4 --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/docs/menu.html @@ -0,0 +1,494 @@ + + + + + jQuery UI menu documentation + + + + + +

    QuickNav

    +

    Options

    + + + + + +
    + +
    +

    Events

    + + + + +

    +Menu Widgetversion added: 1.9 +

    +
    +

    Description: + Themeable menu with mouse and keyboard interactions for navigation. +

    +

    Options

    +

    disabledType: Boolean +

    +
    +Default: false +
    +
    Disables the menu if set to true.
    +
    +
    +

    iconsType: Object +

    +
    +Default: { submenu: "ui-icon-carat-1-e" } +
    +
    + Icons to use for submenus, matching an icon defined by the jQuery UI CSS Framework. +
      +
    • submenu (string, default: "ui-icon-carat-1-e")
    • +
    +
    +
    +
    +

    menusType: String +

    +
    +Default: "ul" +
    +
    Selector for the elements that serve as the menu container, including sub-menus.
    +
    +
    +

    positionType: Object +

    +
    +Default: { my: "top left", at: "top right" } +
    +
    Identifies the position of submenus in relation to the associated parent menu item. The of option defaults to the parent menu item, but you can specify another element to position against. You can refer to the jQuery UI Position utility for more details about the various options.
    +
    +
    +

    roleType: String +

    +
    +Default: "menu" +
    +
    Customize the ARIA roles used for the menu and menu items. The default uses "menuitem" for items. Setting the role option to "listbox" will use "option" for items. If set to null, no roles will be set, which is useful if the menu is being controlled by another element that is maintaining focus.
    +

    Methods

    +

    blur( [event ] )

    +
    + Removes focus from a menu, resets any active element styles and triggers the menu's blur event. +
    +
    • +
      event
      +
      Type: Event +
      +
      What triggered the menu to blur.
      +
    +
    +
    +

    collapse( [event ] )

    +
    + Closes the currently active sub-menu. +
    +
    • +
      event
      +
      Type: Event +
      +
      What triggered the menu to collapse.
      +
    +
    +
    +

    collapseAll( [event ] [, all ] )

    +
    + Closes all open sub-menus. +
    +
      +
    • +
      event
      +
      Type: Event +
      +
      What triggered the menu to collapse.
      +
    • +
    • +
      all
      +
      Type: Boolean +
      +
      Indicates whether all sub-menus should be closed or only sub-menus below and including the menu that is or contains the target of the triggering event.
      +
    • +
    +
    +
    +

    destroy()

    +
    + Removes the menu functionality completely. This will return the element back to its pre-init state. +
    +
    +
    +

    disable()

    +
    + Disables the menu. +
    +
    +
    +

    enable()

    +
    + Enables the menu. +
    +
    +
    +

    expand( [event ] )

    +
    + Opens the sub-menu below the currently active item, if one exists. +
    +
    • +
      event
      +
      Type: Event +
      +
      What triggered the menu to expand.
      +
    +
    +
    +

    focus( [event ] [, item ] )

    +
    + Activates a particular menu item, begins opening any sub-menu if present and triggers the menu's focus event. +
    +
      +
    • +
      event
      +
      Type: Event +
      +
      What triggered the menu item to gain focus.
      +
    • +
    • +
      item
      +
      Type: jQuery +
      +
      The menu item to focus/activate.
      +
    • +
    +
    +
    +

    isFirstItem()

    +
    + Returns a boolean value stating whether or not the currently active item is the first item in the menu. +
    +
    +
    +

    isLastItem()

    +
    + Returns a boolean value stating whether or not the currently active item is the last item in the menu. +
    +
    +
    +

    next( [event ] )

    +
    + Moves active state to next menu item. +
    +
    • +
      event
      +
      Type: Event +
      +
      What triggered the focus to move.
      +
    +
    +
    +

    nextPage( [event ] )

    +
    + Moves active state to first menu item below the bottom of a scrollable menu or the last item if not scrollable. +
    +
    • +
      event
      +
      Type: Event +
      +
      What triggered the focus to move.
      +
    +
    +
    +
    +

    option( optionName ) Returns: Object +

    +
    Gets the value currently associated with the specified optionName.
    +
    • +
      optionName
      +
      Type: String +
      +
      The name of the option to get.
      +
    +
    +
    +

    option() Returns: PlainObject +

    +
    Gets an object containing key/value pairs representing the current menu options hash.
    +
    +
    +

    option( optionName, value )

    +
    Sets the value of the menu option associated with the specified optionName.
    +
      +
    • +
      optionName
      +
      Type: String +
      +
      The name of the option to set.
      +
    • +
    • +
      value
      +
      Type: Object +
      +
      A value to set for the option.
      +
    • +
    +
    +
    +

    option( options )

    +
    Sets one or more options for the menu.
    +
    • +
      options
      +
      Type: Object +
      +
      A map of option-value pairs to set.
      +
    +
    +
    +
    +

    previous( [event ] )

    +
    + Moves active state to previous menu item. +
    +
    • +
      event
      +
      Type: Event +
      +
      What triggered the focus to move.
      +
    +
    +
    +

    previousPage( [event ] )

    +
    + Moves active state to first menu item above the top of a scrollable menu or the first item if not scrollable. +
    +
    • +
      event
      +
      Type: Event +
      +
      What triggered the focus to move.
      +
    +
    +
    +

    refresh()

    +
    + Initializes sub-menus and menu items that have not already been initialized. New menu items, including sub-menus can be added to the menu or all of the contents of the menu can be replaced and then initialized with the refresh() method. +
    +
    +
    +

    select( [event ] )

    +
    + Selects the currently active menu item, collapses all sub-menus and triggers the menu's select event. +
    +
    • +
      event
      +
      Type: Event +
      +
      What triggered the selection.
      +
    +
    +
    +

    widget() Returns: jQuery +

    +
    + Returns a jQuery object containing the menu. +
    +

    Events

    +

    blur( event, ui )

    +
    + Triggered when the menu loses focus. +
    +
      +
    • +
      event
      +
      Type: Event +
      +
      +
    • +
    • +
      ui
      +
      Type: Object +
      +
      +
      • +
        item
        +
        Type: jQuery +
        +
        + The currently active menu item. +
        +
      +
    • +
    +
    +
    +

    create( event, ui )

    +
    + Triggered when the menu is created. +
    +
      +
    • +
      event
      +
      Type: Event +
      +
      +
    • +
    • +
      ui
      +
      Type: Object +
      +
      +
    • +
    +
    +
    +

    focus( event, ui )

    +
    + Triggered when a menu gains focus or when any menu item is activated. +
    +
      +
    • +
      event
      +
      Type: Event +
      +
      +
    • +
    • +
      ui
      +
      Type: Object +
      +
      +
      • +
        item
        +
        Type: jQuery +
        +
        + The currently active menu item. +
        +
      +
    • +
    +
    +
    +

    select( event, ui )

    +
    + Triggered when a menu item is selected. +
    +
      +
    • +
      event
      +
      Type: Event +
      +
      +
    • +
    • +
      ui
      +
      Type: Object +
      +
      +
      • +
        item
        +
        Type: jQuery +
        +
        + The currently active menu item. +
        +
      +
    • +
    +
    +

    A menu can be created from any valid markup as long as the elements have a strict parent/child relationship and each menu item has an anchor. The most commonly used element is the unordered list (<ul>):

    + +
    +<ul id="menu">
    +	<li><a href="#">Item 1</a></li>
    +	<li><a href="#">Item 2</a></li>
    +	<li><a href="#">Item 3</a>
    +		<ul>
    +			<li><a href="#">Item 3-1</a></li>
    +			<li><a href="#">Item 3-2</a></li>
    +			<li><a href="#">Item 3-3</a></li>
    +			<li><a href="#">Item 3-4</a></li>
    +			<li><a href="#">Item 3-5</a></li>
    +		</ul>
    +	</li>
    +	<li><a href="#">Item 4</a></li>
    +	<li><a href="#">Item 5</a></li>
    +</ul>
    +
    + +

    If you use a structure other than <ul>/<li>, including using the same element for the menu and the menu items, use the menus option to specify a way to differentiate the two elements, e.g., menus: "div.menuElement".

    + +

    Any menu item can be disabled by adding the ui-state-disabled class to that element.

    + +

    Keyboard interaction

    + +
      +
    • ENTER/SPACE: Invoke the focused menu item's action, which may be opening a submenu.
    • +
    • UP: Move focus to the previous menu item.
    • +
    • DOWN: Move focus to the next menu item.
    • +
    • RIGHT: Open the submenu, if available.
    • +
    • LEFT: Close the current submenu and move focus to the parent menu item. If not in a submenu, do nothing.
    • +
    • ESCAPE: Close the current submenu and move focus to the parent menu item. If not in a submenu, do nothing.
    • +
    + +

    Typing a letter moves focus to the first item whose title starts with that character. Repeating the same character cycles through matching items. Typing more characters within the one second timer matches those characters.

    + +

    Disabled items can receive keyboard focus, but do not allow any other interaction.

    +
    +

    Additional Notes:

    +
    • + This widget requires some functional CSS, otherwise it won't work. If you build a custom theme, use the widget's specific CSS file as a starting point. +
    +

    Example:

    +

    A simple jQuery UI Menu

    +
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    <!doctype html>
    <html lang="en">
    <head>
        <meta charset="utf-8">
        <title>menu demo</title>
        <link rel="stylesheet" href="http://code.jquery.com/ui/1.9.0/themes/base/jquery-ui.css">
        <style>
        .ui-menu {
            width: 200px;
        }
        </style>
        <script src="http://code.jquery.com/jquery-1.8.2.js"></script>
        <script src="http://code.jquery.com/ui/1.9.0/jquery-ui.js"></script>
    </head>
    <body>
     
    <ul id="menu">
        <li><a href="#">Item 1</a></li>
        <li><a href="#">Item 2</a></li>
        <li><a href="#">Item 3</a>
            <ul>
                <li><a href="#">Item 3-1</a></li>
                <li><a href="#">Item 3-2</a></li>
                <li><a href="#">Item 3-3</a></li>
                <li><a href="#">Item 3-4</a></li>
                <li><a href="#">Item 3-5</a></li>
            </ul>
        </li>
        <li><a href="#">Item 4</a></li>
        <li><a href="#">Item 5</a></li>
    </ul>
     
    <script>
    $( "#menu" ).menu();
    </script>
     
    </body>
    </html>
    +

    Demo:

    +
    +
    +
    + + + diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/docs/mouse.html b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/docs/mouse.html new file mode 100755 index 000000000..352d8e1d3 --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/docs/mouse.html @@ -0,0 +1,148 @@ + + + + + jQuery UI mouse documentation + + + + + +

    QuickNav

    +

    Options

    + + + +
    + +

    Events

    Mouse Interaction

    +
    +

    Description: The base interaction layer.

    +

    Options

    +

    cancelType: Selector +

    +
    +Default: "input,textarea,button,select,option" +
    +
    Prevents interactions from starting on specified elements.
    +
    +
    +

    delayType: Number +

    +
    +Default: 0 +
    +
    Time in milliseconds after mousedown until the interaction should start. This option can be used to prevent unwanted interactions when clicking on an element.
    +
    +
    +

    distanceType: Number +

    +
    +Default: 1 +
    +
    Distance in pixels after mousedown the mouse must move before the interaction should start. This option can be used to prevent unwanted interactions when clicking on an element.
    +

    Methods

    +

    _mouseCapture() Returns: Boolean +

    +
    + Determines whether an interaction should start based on event target of the interaction. The default implementation always returns true. +
    +
    +
    +

    _mouseDelayMet() Returns: Boolean +

    +
    + Determines whether the delay option has been met for the current interaction. +
    +
    +
    +

    _mouseDestroy()

    +
    + Destroys the interaction event handlers. This must be called from the extending widget's _destroy() method. +
    +
    +
    +

    _mouseDistanceMet() Returns: Boolean +

    +
    + Determines whether the distance option has been met for the current interaction. +
    +
    +
    +

    _mouseDown()

    +
    + Handles the beginning of an interaction. Verifies that the event is associated with the primary mouse button and ensures that the delay and distance options are met prior to starting the interaction. When the interaction is ready to start, invokes the _mouseStart() method for the extending widget to handle. +
    +
    +
    +

    _mouseDrag()

    +
    + The extending widget should implement a _mouseDrag() method to handle each movement of an interaction. This method will receive the mouse event associated with the movement. +
    +
    +
    +

    _mouseInit()

    +
    + Initializes the interaction event handlers. This must be called from the extending widget's _create() method. +
    +
    +
    +

    _mouseMove()

    +
    + Handles each movement of the interaction. Invokes the mouseDrag() method for the extending widget to handle. +
    +
    +
    +

    _mouseStart()

    +
    + The extending widget should implement a _mouseStart() method to handle the beginning of an interaction. This method will receive the mouse event associated with the start of the interaction. +
    +
    +
    +

    _mouseStop()

    +
    + The extending widget should implement a _mouseStop() method to handle the end of an interaction. This method will receive the mouse event associated with the end of the interaction. +
    +
    +
    +

    _mouseUp()

    +
    + Handles the end of the interaction. Invokes the mouseStop() method for the extending widget to handle. +
    +
    +

    Similar to jQuery.Widget, the mouse interaction is not intended to be used directly. It is purely a base layer for other widgets to inherit from. This page only documents what is added to jQuery.Widget, but it does include internal methods that are not intended to be overwritten. The intended public API is _mouseStart(), _mouseDrag(), _mouseStop(), and _mouseCapture().

    +
    +
    + + + diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/docs/position.html b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/docs/position.html new file mode 100755 index 000000000..351d60764 --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/docs/position.html @@ -0,0 +1,116 @@ + + + + + jQuery UI position documentation + + + + + +

    +.position( options ) Returns: jQueryversion added: 1.8 +

    +
    +

    Description: Position an element relative to another.

    +
    • +

      .position( options )

      +
      • +
        options
        +
        Type: Object +
        +
        +
          +
        • +
          +my (default: "center")
          +
          Type: String +
          +
          Defines which position on the element being positioned to align with the target element: "horizontal vertical" alignment. A single value such as "right" will be normalized to "right center", "top" will be normalized to "center top" (following CSS convention). Acceptable horizontal values: "left", "center", "right". Acceptable vertical values: "top", "center", "bottom". Example: "left top" or "center center". Each dimension can also contain offsets, in pixels or percent, e.g., "right+10 top-25%". Perecentage offsets are relative to the element being positioned.
          +
        • +
        • +
          +at (default: "center")
          +
          Type: String +
          +
          Defines which position on the target element to align the positioned element against: "horizontal vertical" alignment. See the my option for full details on possible values. Perecentage offsets are relative to the target element.
          +
        • +
        • +
          +of (default: null)
          +
          Type: Selector or Element or jQuery or Event +
          +
          Which element to position against. If you provide a selector or jQuery object, the first matching element will be used. If you provide an event object, the pageX and pageY properties will be used. Example: "#top-menu" +
          +
        • +
        • +
          +collision (default: "flip")
          +
          Type: String +
          +
          +

          When the positioned element overflows the window in some direction, move it to an alternative position. Similar to my and at, this accepts a single value or a pair for horizontal/vertical, e.g., "flip", "fit", "fit flip", "fit none".

          +
            +
          • +"flip": Flips the element to the opposite side of the target and the collision detection is run again to see if it will fit. Whichever side allows more of the element to be visible will be used.
          • +
          • +"fit": Shift the element away from the edge of the window.
          • +
          • +"flipfit": First applies the flip logic, placing the element on whichever side allows more of the element to be visible. Then the fit logic is applied to ensure as much of the element is visible as possible.
          • +
          • +"none": Does not apply any collision detection.
          • +
          +
          +
        • +
        • +
          +using (default: null)
          +
          Type: Function()
          +
          + When specified, the actual property setting is delegated to this callback. Receives two parameters: The first is a hash of top and left values for the position that should be set and can be forwarded to .position() or .animate(). +

          The second provides feedback about the position and dimensions of both elements, as well as calculations to their relative position. Both target and element have these properties: element, left, top, width, height. In addition, there's horizontal, vertical and important, giving you twelve potential directions like { horizontal: "center", vertical: "left", important: "horizontal" }.

          +
          +
        • +
        • +
          +within (default: window)
          +
          Type: Selector or Element or jQuery +
          +
          Element to position within, affecting collision detection. If you provide a selector or jQuery object, the first matching element will be used.
          +
        • +
        +
      +
    +
    +

    The jQuery UI .position() method allows you to position an element relative to the window, document, another element, or the cursor/mouse, without worrying about offset parents.

    +

    Note: jQuery UI does not support positioning hidden elements.

    +

    This is a standalone jQuery plugin and has no dependencies on other jQuery UI components.

    +

    This plugin extends jQuery's built-in .position() method. If jQuery UI is not loaded, calling the .position() method may not fail directly, as the method still exists. However, the expected behavior will not occur.

    +
    +

    Example:

    +

    A simple jQuery UI Position example.

    +
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    <!doctype html>
    <html lang="en">
    <head>
        <meta charset="utf-8">
        <title>position demo</title>
        <link rel="stylesheet" href="http://code.jquery.com/ui/1.9.0/themes/base/jquery-ui.css">
        <style>
        .positionDiv {
            position: absolute;
            width: 75px;
            height: 75px;
            background: green;
        }
        </style>
        <script src="http://code.jquery.com/jquery-1.8.2.js"></script>
        <script src="http://code.jquery.com/ui/1.9.0/jquery-ui.js"></script>
    </head>
    <body>
     
    <div id="targetElement">
        <div class="positionDiv" id="position1"></div>
        <div class="positionDiv" id="position2"></div>
        <div class="positionDiv" id="position3"></div>
        <div class="positionDiv" id="position4"></div>
    </div>
     
    <script>
    $( "#position1" ).position({
        my: "center",
        at: "center",
        of: "#targetElement"
    });
     
    $( "#position2" ).position({
        my: "left top",
        at: "left top",
        of: "#targetElement"
    });
     
    $( "#position3" ).position({
        my: "right center",
        at: "right bottom",
        of: "#targetElement"
    });
     
    $( document ).mousemove(function( event ) {
        $( "#position4" ).position({
            my: "left+3 bottom-3",
            of: event,
            collision: "fit"
        });
    });
    </script>
     
    </body>
    </html>
    +

    Demo:

    +
    +
    +
    + + + diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/docs/progressbar.html b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/docs/progressbar.html new file mode 100755 index 000000000..2e50b4aa7 --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/docs/progressbar.html @@ -0,0 +1,230 @@ + + + + + jQuery UI progressbar documentation + + + + + +

    QuickNav

    +

    Options

    + + +
    + +
    +

    Events

    + + + +

    +Progressbar Widgetversion added: 1.6 +

    +
    +

    Description: Display status of a determinate process.

    +

    Options

    +

    disabledType: Boolean +

    +
    +Default: false +
    +
    Disables the progressbar if set to true.
    +
    +
    +

    valueType: Number +

    +
    +Default: 0 +
    +
    The value of the progressbar.
    +

    Methods

    +

    destroy()

    +
    + Removes the progressbar functionality completely. This will return the element back to its pre-init state. +
    +
    +
    +

    disable()

    +
    + Disables the progressbar. +
    +
    +
    +

    enable()

    +
    + Enables the progressbar. +
    +
    +
    +
    +

    option( optionName ) Returns: Object +

    +
    Gets the value currently associated with the specified optionName.
    +
    • +
      optionName
      +
      Type: String +
      +
      The name of the option to get.
      +
    +
    +
    +

    option() Returns: PlainObject +

    +
    Gets an object containing key/value pairs representing the current progressbar options hash.
    +
    +
    +

    option( optionName, value )

    +
    Sets the value of the progressbar option associated with the specified optionName.
    +
      +
    • +
      optionName
      +
      Type: String +
      +
      The name of the option to set.
      +
    • +
    • +
      value
      +
      Type: Object +
      +
      A value to set for the option.
      +
    • +
    +
    +
    +

    option( options )

    +
    Sets one or more options for the progressbar.
    +
    • +
      options
      +
      Type: Object +
      +
      A map of option-value pairs to set.
      +
    +
    +
    +
    +
    +

    value() Returns: Number +

    +
    Gets the current value of the progressbar.
    +
    +
    +

    value( value )

    +
    Sets the current value of the progressbar.
    +
    • +
      value
      +
      Type: Number +
      +
      The value to set.
      +
    +
    +
    +
    +

    widget() Returns: jQuery +

    +
    + Returns a jQuery object containing the progressbar. +
    +

    Events

    +

    change( event, ui )

    +
    Triggered when the value of the progressbar changes.
    +
      +
    • +
      event
      +
      Type: Event +
      +
      +
    • +
    • +
      ui
      +
      Type: Object +
      +
      +
    • +
    +
    +
    +

    complete( event, ui )

    +
    Triggered when the value of the progressbar reaches the maximum value.
    +
      +
    • +
      event
      +
      Type: Event +
      +
      +
    • +
    • +
      ui
      +
      Type: Object +
      +
      +
    • +
    +
    +
    +

    create( event, ui )

    +
    + Triggered when the progressbar is created. +
    +
      +
    • +
      event
      +
      Type: Event +
      +
      +
    • +
    • +
      ui
      +
      Type: Object +
      +
      +
    • +
    +
    +

    + The progress bar is designed to display the current percent complete for a process. The bar is coded to be flexibly sized through CSS and will scale to fit inside its parent container by default. +

    +

    + This is a determinate progress bar, meaning that it should only be used in situations where the system can accurately update the current status. A determinate progress bar should never fill from left to right, then loop back to empty for a single process — if the actual status cannot be calculated, an indeterminate progress bar or spinner animation is a better way to provide user feedback. +

    +
    +

    Additional Notes:

    +
    • + This widget requires some functional CSS, otherwise it won't work. If you build a custom theme, use the widget's specific CSS file as a starting point. +
    +

    Example:

    +

    A simple jQuery UI Progressbar

    +
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    <!doctype html>
    <html lang="en">
    <head>
        <meta charset="utf-8">
        <title>progressbar demo</title>
        <link rel="stylesheet" href="http://code.jquery.com/ui/1.9.0/themes/base/jquery-ui.css">
        <script src="http://code.jquery.com/jquery-1.8.2.js"></script>
        <script src="http://code.jquery.com/ui/1.9.0/jquery-ui.js"></script>
    </head>
    <body>
     
    <div id="progressbar"></div>
     
    <script>
    $( "#progressbar" ).progressbar({
        value: 37
    });
    </script>
     
    </body>
    </html>
    +

    Demo:

    +
    +
    +
    + + + diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/docs/puff-effect.html b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/docs/puff-effect.html new file mode 100755 index 000000000..c695d5e4f --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/docs/puff-effect.html @@ -0,0 +1,32 @@ +

    Puff Effect

    +
    +

    Description: + Creates a puff effect by scaling the element up and hiding it at the same time. +

    +
    • +

      puff

      +
      • +
        +percent (default: 150)
        +
        Type: Number +
        +
        The percentage to scale to.
        +
      +
    +

    Example:

    +

    Toggle a div using the puff effect.

    +
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    <!doctype html>
    <html lang="en">
    <head>
        <meta charset="utf-8">
        <title>puff demo</title>
        <link rel="stylesheet" href="http://code.jquery.com/ui/1.9.0/themes/base/jquery-ui.css">
        <style>
        #toggle {
            width: 100px;
            height: 100px;
            background: #ccc;
        }
        </style>
        <script src="http://code.jquery.com/jquery-1.8.2.js"></script>
        <script src="http://code.jquery.com/ui/1.9.0/jquery-ui.js"></script>
    </head>
    <body>
     
    <p>Click anywhere to toggle the box.</p>
    <div id="toggle"></div>
     
    <script>
    $( document ).click(function() {
        $( "#toggle" ).toggle( "puff" );
    });
    </script>
     
    </body>
    </html>
    +

    Demo:

    +
    +
    +
    \ No newline at end of file diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/docs/pulsate-effect.html b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/docs/pulsate-effect.html new file mode 100755 index 000000000..d8c44a2df --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/docs/pulsate-effect.html @@ -0,0 +1,52 @@ + + + + + jQuery UI pulsate-effect documentation + + + + + +

    Pulsate Effect

    +
    +

    Description: + The pulsate effect hides or shows an element by pulsing it in or out. +

    +
    • +

      pulsate

      +
      • +
        +times (default: 5)
        +
        Type: Integer +
        +
        The number of times the element should pulse. An extra half pulse is added for hide/show.
        +
      +
    +

    Example:

    +

    Toggle a div using the pulsate effect.

    +
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    <!doctype html>
    <html lang="en">
    <head>
        <meta charset="utf-8">
        <title>pulsate demo</title>
        <link rel="stylesheet" href="http://code.jquery.com/ui/1.9.0/themes/base/jquery-ui.css">
        <style>
        #toggle {
            width: 100px;
            height: 100px;
            background: #ccc;
        }
        </style>
        <script src="http://code.jquery.com/jquery-1.8.2.js"></script>
        <script src="http://code.jquery.com/ui/1.9.0/jquery-ui.js"></script>
    </head>
    <body>
     
    <p>Click anywhere to toggle the box.</p>
    <div id="toggle"></div>
     
    <script>
    $( document ).click(function() {
        $( "#toggle" ).toggle( "pulsate" );
    });
    </script>
     
    </body>
    </html>
    +

    Demo:

    +
    +
    +
    + + + diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/docs/resizable.html b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/docs/resizable.html new file mode 100755 index 000000000..41ec9143a --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/docs/resizable.html @@ -0,0 +1,543 @@ + + + + + jQuery UI resizable documentation + + + + + +

    QuickNav

    + +
    +

    Events

    + + + + +

    +Resizable Widgetversion added: 1.0 +

    +
    +

    Description: Change the size of an element using the mouse.

    +

    Options

    +

    alsoResizeType: Selector or jQuery or Element +

    +
    +Default: false +
    +
    One or more elements to resize synchronously with the resizable element.
    +
    +
    +

    animateType: Boolean +

    +
    +Default: false +
    +
    Animates to the final size after resizing.
    +
    +
    +

    animateDurationType: Number or String +

    +
    +Default: "slow" +
    +
    How long to animate when using the animate option.
    +Multiple types supported:
      +
    • +Number: Duration in milliseconds.
    • +
    • +String: A named duration, such as "slow" or "fast".
    • +
    +
    +
    +

    animateEasingType: String +

    +
    +Default: "swing" +
    +
    Which easing to apply when using the animate option.
    +
    +
    +

    aspectRatioType: Boolean or Number +

    +
    +Default: false +
    +
    Whether the element should be constrained to a specific aspect ratio.
    +Multiple types supported:
      +
    • +Boolean: When set to true, the element will maintain its original aspect ratio.
    • +
    • +Number: Force the element to maintain a specific aspect ratio during resizing.
    • +
    +
    +
    +

    autoHideType: Boolean +

    +
    +Default: false +
    +
    Whether the handles should hide when the user is not hovering over the element.
    +
    +
    +

    cancelType: Selector +

    +
    +Default: "input,textarea,button,select,option" +
    +
    Prevents resizing from starting on specified elements.
    +
    +
    +

    containmentType: Selector or Element or String +

    +
    +Default: false +
    +
    Constrains resizing to within the bounds of the specified element or region.
    +Multiple types supported:
      +
    • +Selector: The resizable element will be contained to the bounding box of the first element found by the selector. If no element is found, no containment will be set.
    • +
    • +Element: The resizable element will be contained to the bounding box of this element.
    • +
    • +String: Possible values: "parent" and "document".
    • +
    +
    +
    +

    delayType: Number +

    +
    +Default: 0 +
    +
    Tolerance, in milliseconds, for when resizing should start. If specified, resizing will not start until after mouse is moved beyond duration. This can help prevent unintended resizing when clicking on an element.
    +
    +
    +

    disabledType: Boolean +

    +
    +Default: false +
    +
    Disables the resizable if set to true.
    +
    +
    +

    distanceType: Number +

    +
    +Default: 1 +
    +
    Tolerance, in pixels, for when resizing should start. If specified, resizing will not start until after mouse is moved beyond distance. This can help prevent unintended resizing when clicking on an element.
    +
    +
    +

    ghostType: Boolean +

    +
    +Default: false +
    +
    If set to true, a semi-transparent helper element is shown for resizing.
    +
    +
    +

    gridType: Array +

    +
    +Default: false +
    +
    Snaps the resizing element to a grid, every x and y pixels. Array values: [ x, y ].
    +
    +
    +

    handlesType: String or Object +

    +
    +Default: "e, s, se" +
    +
    Which handles can be used for resizing.
    +Multiple types supported:
      +
    • +String: A comma delimited list of any of the following: n, e, s, w, ne, se, sw, nw, all. The necessary handles will be auto-generated by the plugin.
    • +
    • +Object: The following keys are supported: { n, e, s, w, ne, se, sw, nw }. The value of any specified should be a jQuery selector matching the child element of the resizable to use as that handle. If the handle is not a child of the resizable, you can pass in the DOMElement or a valid jQuery object directly.
    • +
    +
    +
    +

    helperType: String +

    +
    +Default: false +
    +
    A class name that will be added to a proxy element to outline the resize during the drag of the resize handle. Once the resize is complete, the original element is sized.
    +
    +
    +

    maxHeightType: Number +

    +
    +Default: null +
    +
    The maximum height the resizable should be allowed to resize to.
    +
    +
    +

    maxWidthType: Number +

    +
    +Default: null +
    +
    The maximum width the resizable should be allowed to resize to.
    +
    +
    +

    minHeightType: Number +

    +
    +Default: 10 +
    +
    The minimum height the resizable should be allowed to resize to.
    +
    +
    +

    minWidthType: Number +

    +
    +Default: 10 +
    +
    The minimum width the resizable should be allowed to resize to.
    +

    Methods

    +

    destroy()

    +
    + Removes the resizable functionality completely. This will return the element back to its pre-init state. +
    +
    +
    +

    disable()

    +
    + Disables the resizable. +
    +
    +
    +

    enable()

    +
    + Enables the resizable. +
    +
    +
    +
    +

    option( optionName ) Returns: Object +

    +
    Gets the value currently associated with the specified optionName.
    +
    • +
      optionName
      +
      Type: String +
      +
      The name of the option to get.
      +
    +
    +
    +

    option() Returns: PlainObject +

    +
    Gets an object containing key/value pairs representing the current resizable options hash.
    +
    +
    +

    option( optionName, value )

    +
    Sets the value of the resizable option associated with the specified optionName.
    +
      +
    • +
      optionName
      +
      Type: String +
      +
      The name of the option to set.
      +
    • +
    • +
      value
      +
      Type: Object +
      +
      A value to set for the option.
      +
    • +
    +
    +
    +

    option( options )

    +
    Sets one or more options for the resizable.
    +
    • +
      options
      +
      Type: Object +
      +
      A map of option-value pairs to set.
      +
    +
    +
    +
    +

    widget() Returns: jQuery +

    +
    + Returns a jQuery object containing the resizable element. +
    +

    Events

    +

    create( event, ui )

    +
    + Triggered when the resizable is created. +
    +
      +
    • +
      event
      +
      Type: Event +
      +
      +
    • +
    • +
      ui
      +
      Type: Object +
      +
      +
    • +
    +
    +
    +

    resize( event, ui )

    +
    This event is triggered during the resize, on the drag of the resize handler.
    +
      +
    • +
      event
      +
      Type: Event +
      +
      +
    • +
    • +
      ui
      +
      Type: Object +
      +
      +
        +
      • +
        element
        +
        Type: jQuery +
        +
        The jQuery object representing the element to be resized
        +
      • +
      • +
        helper
        +
        Type: jQuery +
        +
        The jQuery object representing the helper that's being resized
        +
      • +
      • +
        originalElement
        +
        Type: jQuery +
        +
        The jQuery object representing the original element before it is wrapped
        +
      • +
      • +
        originalPosition
        +
        Type: Object +
        +
        The position represented as { left, top } before the resizable is resized
        +
      • +
      • +
        originalSize
        +
        Type: Object +
        +
        The size represented as { width, height } before the resizable is resized
        +
      • +
      • +
        position
        +
        Type: Object +
        +
        The current position represented as { left, top } +
        +
      • +
      • +
        size
        +
        Type: Object +
        +
        The current size represented as { width, height } +
        +
      • +
      +
    • +
    +
    +
    +

    start( event, ui )

    +
    This event is triggered at the start of a resize operation.
    +
      +
    • +
      event
      +
      Type: Event +
      +
      +
    • +
    • +
      ui
      +
      Type: Object +
      +
      +
        +
      • +
        element
        +
        Type: jQuery +
        +
        The jQuery object representing the element to be resized
        +
      • +
      • +
        helper
        +
        Type: jQuery +
        +
        The jQuery object representing the helper that's being resized
        +
      • +
      • +
        originalElement
        +
        Type: jQuery +
        +
        The jQuery object representing the original element before it is wrapped
        +
      • +
      • +
        originalPosition
        +
        Type: Object +
        +
        The position represented as { left, top } before the resizable is resized
        +
      • +
      • +
        originalSize
        +
        Type: Object +
        +
        The size represented as { width, height } before the resizable is resized
        +
      • +
      • +
        position
        +
        Type: Object +
        +
        The current position represented as { left, top } +
        +
      • +
      • +
        size
        +
        Type: Object +
        +
        The current size represented as { width, height } +
        +
      • +
      +
    • +
    +
    +
    +

    stop( event, ui )

    +
    This event is triggered at the end of a resize operation.
    +
      +
    • +
      event
      +
      Type: Event +
      +
      +
    • +
    • +
      ui
      +
      Type: Object +
      +
      +
        +
      • +
        element
        +
        Type: jQuery +
        +
        The jQuery object representing the element to be resized
        +
      • +
      • +
        helper
        +
        Type: jQuery +
        +
        The jQuery object representing the helper that's being resized
        +
      • +
      • +
        originalElement
        +
        Type: jQuery +
        +
        The jQuery object representing the original element before it is wrapped
        +
      • +
      • +
        originalPosition
        +
        Type: Object +
        +
        The position represented as { left, top } before the resizable is resized
        +
      • +
      • +
        originalSize
        +
        Type: Object +
        +
        The size represented as { width, height } before the resizable is resized
        +
      • +
      • +
        position
        +
        Type: Object +
        +
        The current position represented as { left, top } +
        +
      • +
      • +
        size
        +
        Type: Object +
        +
        The current size represented as { width, height } +
        +
      • +
      +
    • +
    +
    +

    The jQuery UI Resizable plugin makes selected elements resizable (meaning they have draggable resize handles). You can specify one or more handles as well as min and max width and height.

    +
    +

    Additional Notes:

    +
    • + This widget requires some functional CSS, otherwise it won't work. If you build a custom theme, use the widget's specific CSS file as a starting point. +
    +

    Example:

    +

    A simple jQuery UI Resizable.

    +
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    <!doctype html>
    <html lang="en">
    <head>
        <meta charset="utf-8">
        <title>resizable demo</title>
        <link rel="stylesheet" href="http://code.jquery.com/ui/1.9.0/themes/base/jquery-ui.css">
        <style>
        #resizable {
            width: 100px;
            height: 100px;
            background: #ccc;
    }   </style>
        <script src="http://code.jquery.com/jquery-1.8.2.js"></script>
        <script src="http://code.jquery.com/ui/1.9.0/jquery-ui.js"></script>
    </head>
    <body>
     
    <div id="resizable"></div>
     
    <script>
    $( "#resizable" ).resizable();
    </script>
     
    </body>
    </html>
    +

    Demo:

    +
    +
    +
    + + + diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/docs/scale-effect.html b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/docs/scale-effect.html new file mode 100755 index 000000000..0cb121441 --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/docs/scale-effect.html @@ -0,0 +1,82 @@ + + + + + jQuery UI scale-effect documentation + + + + + +

    Scale Effect

    +
    +

    Description: + Shrink or grow an element by a percentage factor. +

    +
    • +

      scale

      +
        +
      • +
        +direction (default: "both")
        +
        Type: String +
        +
        The direction of the effect. Possible values: "both", "vertical" or "horizontal".
        +
      • +
      • +
        +origin (default: [ "middle", "center" ])
        +
        Type: Array +
        +
        The vanishing point.
        +
      • +
      • +
        percent
        +
        Type: Number +
        +
        The percentage to scale to.
        +
      • +
      • +
        +scale (default: "both")
        +
        Type: String +
        +
        Which areas of the element will be resized: "both", "box", "content". Box resizes the border and padding of the element; content resizes any content inside of the element.
        +
      • +
      +
    +

    Examples:

    +

    Example: Toggle a div using the scale effect. +

    +
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    <!doctype html>
    <html lang="en">
    <head>
        <meta charset="utf-8">
        <title>scale demo</title>
        <link rel="stylesheet" href="http://code.jquery.com/ui/1.9.0/themes/base/jquery-ui.css">
        <style>
        #toggle {
            width: 100px;
            height: 100px;
            background: #ccc;
        }
        </style>
        <script src="http://code.jquery.com/jquery-1.8.2.js"></script>
        <script src="http://code.jquery.com/ui/1.9.0/jquery-ui.js"></script>
    </head>
    <body>
     
    <p>Click anywhere to toggle the box.</p>
    <div id="toggle"></div>
     
    <script>
    $( document ).click(function() {
        $( "#toggle" ).toggle( "scale" );
    });
    </script>
     
    </body>
    </html>
    +

    Demo:

    +
    +
    +
    +

    Example: Toggle a div using the scale effect in just one direction. +

    +
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    <!doctype html>
    <html lang="en">
    <head>
        <meta charset="utf-8">
        <title>scale demo</title>
        <link rel="stylesheet" href="http://code.jquery.com/ui/1.9.0/themes/base/jquery-ui.css">
        <style>
        #toggle {
            width: 100px;
            height: 100px;
            background: #ccc;
        }
        </style>
        <script src="http://code.jquery.com/jquery-1.8.2.js"></script>
        <script src="http://code.jquery.com/ui/1.9.0/jquery-ui.js"></script>
    </head>
    <body>
     
    <p>Click anywhere to toggle the box.</p>
    <div id="toggle"></div>
     
    <script>
    $( document ).click(function() {
        $( "#toggle" ).toggle({ effect: "scale", direction: "horizontal" });
    });
    </script>
     
    </body>
    </html>
    +

    Demo:

    +
    +
    +
    + + + diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/docs/selectable.html b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/docs/selectable.html new file mode 100755 index 000000000..72fb001ce --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/docs/selectable.html @@ -0,0 +1,365 @@ + + + + + jQuery UI selectable documentation + + + + + +

    QuickNav

    + +

    +Selectable Widgetversion added: 1.0 +

    +
    +

    Description: Use the mouse to select elements, individually or in a group.

    +

    Options

    +

    autoRefreshType: Boolean +

    +
    +Default: true +
    +
    This determines whether to refresh (recalculate) the position and size of each selectee at the beginning of each select operation. If you have many items, you may want to set this to false and call the refresh() method manually.
    +
    +
    +

    cancelType: Selector +

    +
    +Default: "input,textarea,button,select,option" +
    +
    Prevents selecting if you start on elements matching the selector.
    +
    +
    +

    delayType: Integer +

    +
    +Default: 0 +
    +
    Time in milliseconds to define when the selecting should start. This helps prevent unwanted selections when clicking on an element.
    +
    +
    +

    disabledType: Boolean +

    +
    +Default: false +
    +
    Disables the selectable if set to true.
    +
    +
    +

    distanceType: Number +

    +
    +Default: 0 +
    +
    Tolerance, in pixels, for when selecting should start. If specified, selecting will not start until the mouse has been dragged beyond the specified distance.
    +
    +
    +

    filterType: Selector +

    +
    +Default: "*" +
    +
    The matching child elements will be made selectees (able to be selected).
    +
    +
    +

    toleranceType: String +

    +
    +Default: "touch" +
    +
    + Specifies which mode to use for testing whether the lasso should select an item. Possible values: +
      +
    • +"fit": Lasso overlaps the item entirely.
    • +
    • +"touch": Lasso overlaps the item by any amount.
    • +
    +
    +

    Methods

    +

    destroy()

    +
    + Removes the selectable functionality completely. This will return the element back to its pre-init state. +
    +
    +
    +

    disable()

    +
    + Disables the selectable. +
    +
    +
    +

    enable()

    +
    + Enables the selectable. +
    +
    +
    +
    +

    option( optionName ) Returns: Object +

    +
    Gets the value currently associated with the specified optionName.
    +
    • +
      optionName
      +
      Type: String +
      +
      The name of the option to get.
      +
    +
    +
    +

    option() Returns: PlainObject +

    +
    Gets an object containing key/value pairs representing the current selectable options hash.
    +
    +
    +

    option( optionName, value )

    +
    Sets the value of the selectable option associated with the specified optionName.
    +
      +
    • +
      optionName
      +
      Type: String +
      +
      The name of the option to set.
      +
    • +
    • +
      value
      +
      Type: Object +
      +
      A value to set for the option.
      +
    • +
    +
    +
    +

    option( options )

    +
    Sets one or more options for the selectable.
    +
    • +
      options
      +
      Type: Object +
      +
      A map of option-value pairs to set.
      +
    +
    +
    +
    +

    refresh()

    +
    Refresh the position and size of each selectee element. This method can be used to manually recalculate the position and size of each selectee when the autoRefresh option is set to false.
    +
    +
    +

    widget() Returns: jQuery +

    +
    + Returns a jQuery object containing the selectable element. +
    +

    Events

    +

    create( event, ui )

    +
    + Triggered when the selectable is created. +
    +
      +
    • +
      event
      +
      Type: Event +
      +
      +
    • +
    • +
      ui
      +
      Type: Object +
      +
      +
    • +
    +
    +
    +

    selected( event, ui )

    +
    Triggered at the end of the select operation, on each element added to the selection.
    +
      +
    • +
      event
      +
      Type: Event +
      +
      +
    • +
    • +
      ui
      +
      Type: Object +
      +
      +
      • +
        selected
        +
        Type: Element +
        +
        The selectable item that has been selected.
        +
      +
    • +
    +
    +
    +

    selecting( event, ui )

    +
    Triggered during the select operation, on each element added to the selection.
    +
      +
    • +
      event
      +
      Type: Event +
      +
      +
    • +
    • +
      ui
      +
      Type: Object +
      +
      +
      • +
        selecting
        +
        Type: Element +
        +
        The current selectable item being selected.
        +
      +
    • +
    +
    +
    +

    start( event, ui )

    +
    Triggered at the beginning of the select operation.
    +
      +
    • +
      event
      +
      Type: Event +
      +
      +
    • +
    • +
      ui
      +
      Type: Object +
      +
      +
    • +
    +
    +
    +

    stop( event, ui )

    +
    Triggered at the end of the select operation.
    +
      +
    • +
      event
      +
      Type: Event +
      +
      +
    • +
    • +
      ui
      +
      Type: Object +
      +
      +
    • +
    +
    +
    +

    unselected( event, ui )

    +
    Triggered at the end of the select operation, on each element removed from the selection.
    +
      +
    • +
      event
      +
      Type: Event +
      +
      +
    • +
    • +
      ui
      +
      Type: Object +
      +
      +
      • +
        unselected
        +
        Type: Element +
        +
        The selectable item that has been unselected.
        +
      +
    • +
    +
    +
    +

    unselecting( event, ui )

    +
    Triggered during the select operation, on each element removed from the selection.
    +
      +
    • +
      event
      +
      Type: Event +
      +
      +
    • +
    • +
      ui
      +
      Type: Object +
      +
      +
      • +
        unselecting
        +
        Type: Element +
        +
        The current selectable item being unselected.
        +
      +
    • +
    +
    +

    The jQuery UI Selectable plugin allows for elements to be selected by dragging a box (sometimes called a lasso) with the mouse over the elements. Elements can also be selected via click or drag while holding the ctrl/meta key, allowing for multiple (non-contiguous) selections.

    +
    +

    Additional Notes:

    +
    • + This widget requires some functional CSS, otherwise it won't work. If you build a custom theme, use the widget's specific CSS file as a starting point. +
    +

    Example:

    +

    A simple jQuery UI Selectable.

    +
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    <!doctype html>
    <html lang="en">
    <head>
        <meta charset="utf-8">
        <title>selectable demo</title>
        <link rel="stylesheet" href="http://code.jquery.com/ui/1.9.0/themes/base/jquery-ui.css">
        <style>
        #selectable .ui-selecting {
            background: #ccc;
        }
        #selectable .ui-selected {
            background: #999;
        }
        </style>
        <script src="http://code.jquery.com/jquery-1.8.2.js"></script>
        <script src="http://code.jquery.com/ui/1.9.0/jquery-ui.js"></script>
    </head>
    <body>
     
    <ul id="selectable">
        <li>Item 1</li>
        <li>Item 2</li>
        <li>Item 3</li>
        <li>Item 4</li>
        <li>Item 5</li>
    </ul>
     
    <script>
    $( "#selectable" ).selectable();
    </script>
     
    </body>
    </html>
    +

    Demo:

    +
    +
    +
    + + + diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/docs/shake-effect.html b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/docs/shake-effect.html new file mode 100755 index 000000000..fde8a6ade --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/docs/shake-effect.html @@ -0,0 +1,66 @@ + + + + + jQuery UI shake-effect documentation + + + + + +

    Shake Effect

    +
    +

    Description: Shakes the element multiple times, vertically or horizontally.

    +
    • +

      shake

      +
        +
      • +
        +direction (default: "both")
        +
        Type: String +
        +
        The direction of the effect. Possible values: "left", "right", "up", "down".
        +
      • +
      • +
        +distance (default: 20)
        +
        Type: Number +
        +
        Distance to shake.
        +
      • +
      • +
        +times (default: 3)
        +
        Type: Integer +
        +
        Times to shake.
        +
      • +
      +
    +

    Example:

    +

    Shake a div.

    +
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    <!doctype html>
    <html lang="en">
    <head>
        <meta charset="utf-8">
        <title>shake demo</title>
        <link rel="stylesheet" href="http://code.jquery.com/ui/1.9.0/themes/base/jquery-ui.css">
        <style>
        #toggle {
            width: 100px;
            height: 100px;
            background: #ccc;
        }
        </style>
        <script src="http://code.jquery.com/jquery-1.8.2.js"></script>
        <script src="http://code.jquery.com/ui/1.9.0/jquery-ui.js"></script>
    </head>
    <body>
     
    <p>Click anywhere to shake the box.</p>
    <div id="toggle"></div>
     
    <script>
    $( document ).click(function() {
        $( "#toggle" ).effect( "shake" );
    });
    </script>
     
    </body>
    </html>
    +

    Demo:

    +
    +
    +
    + + + diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/docs/size-effect.html b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/docs/size-effect.html new file mode 100755 index 000000000..dc1db01bb --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/docs/size-effect.html @@ -0,0 +1,45 @@ +

    Size Effect

    +
    +

    Description: Resize an element to a specified width and height.

    +
    • +

      size

      +
        +
      • +
        to
        +
        Type: Object +
        +
        Height and width to resize to.
        +
      • +
      • +
        +origin (default: [ "top", "left" ])
        +
        Type: Array +
        +
        The vanishing point.
        +
      • +
      • +
        +scale (default: "both")
        +
        Type: String +
        +
        Which areas of the element will be resized: "both", "box", "content". Box resizes the border and padding of the element; content resizes any content inside of the element.
        +
      • +
      +
    +

    Example:

    +

    Resize the element using the size effect.

    +
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    <!doctype html>
    <html lang="en">
    <head>
        <meta charset="utf-8">
        <title>size demo</title>
        <link rel="stylesheet" href="http://code.jquery.com/ui/1.9.0/themes/base/jquery-ui.css">
        <style>
        #toggle {
            width: 100px;
            height: 100px;
            background: #ccc;
        }
        </style>
        <script src="http://code.jquery.com/jquery-1.8.2.js"></script>
        <script src="http://code.jquery.com/ui/1.9.0/jquery-ui.js"></script>
    </head>
    <body>
     
    <p>Click anywhere to resize the box.</p>
    <div id="toggle"></div>
     
    <script>
    $( document ).click(function() {
        $( "#toggle" ).effect( "size", {
            to: { width: 200, height: 60 }
        }, 1000 );
    });
    </script>
     
    </body>
    </html>
    +

    Demo:

    +
    +
    +
    \ No newline at end of file diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/docs/slide-effect.html b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/docs/slide-effect.html new file mode 100755 index 000000000..a6c0d5f07 --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/docs/slide-effect.html @@ -0,0 +1,59 @@ + + + + + jQuery UI slide-effect documentation + + + + + +

    Slide Effect

    +
    +

    Description: Slides the element out of the viewport.

    +
    • +

      slide

      +
        +
      • +
        +direction (default: "both")
        +
        Type: String +
        +
        The direction of the effect. Possible values: "left", "right", "up", "down".
        +
      • +
      • +
        +distance (default: element's outerWidth)
        +
        Type: Number +
        +
        The distance of the effect. Defaults to either the height or width of the elemenet depending on the direction argument. Can be set to any integer less than the width/height of the element.
        +
      • +
      +
    +

    Example:

    +

    Toggle a div using the slide effect.

    +
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    <!doctype html>
    <html lang="en">
    <head>
        <meta charset="utf-8">
        <title>slide demo</title>
        <link rel="stylesheet" href="http://code.jquery.com/ui/1.9.0/themes/base/jquery-ui.css">
        <style>
        #toggle {
            width: 100px;
            height: 100px;
            background: #ccc;
        }
        </style>
        <script src="http://code.jquery.com/jquery-1.8.2.js"></script>
        <script src="http://code.jquery.com/ui/1.9.0/jquery-ui.js"></script>
    </head>
    <body>
     
    <p>Click anywhere to toggle the box.</p>
    <div id="toggle"></div>
     
    <script>
    $( document ).click(function() {
        $( "#toggle" ).toggle( "slide" );
    });
    </script>
     
    </body>
    </html>
    +

    Demo:

    +
    +
    +
    + + + diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/docs/slider.html b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/docs/slider.html new file mode 100755 index 000000000..8c4f5fe43 --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/docs/slider.html @@ -0,0 +1,451 @@ + + + + + jQuery UI slider documentation + + + + + +

    QuickNav

    + +
    +

    Events

    + + + + + +

    +Slider Widgetversion added: 1.5 +

    +
    +

    Description: Drag a handle to select a numeric value.

    +

    Options

    +

    animateType: Boolean or String or Number +

    +
    +Default: false +
    +
    Whether to slide the handle smoothly when the user clicks on the slider track. Also accepts any valid animation duration.
    +Multiple types supported:
      +
    • +Boolean: When set to true, the handle will animate with the default duration.
    • +
    • +String: The name of a speed, such as "fast" or "slow".
    • +
    • +Number: The duration of the animation, in milliseconds.
    • +
    +
    +
    +

    disabledType: Boolean +

    +
    +Default: false +
    +
    Disables the slider if set to true.
    +
    +
    +

    maxType: Number +

    +
    +Default: 100 +
    +
    The maximum value of the slider.
    +
    +
    +

    minType: Number +

    +
    +Default: 0 +
    +
    The minimum value of the slider.
    +
    +
    +

    orientationType: String +

    +
    +Default: "horizontal" +
    +
    Determines whether the slider handles move horizontally (min on left, max on right) or vertically (min on bottom, max on top). Possible values: "horizontal", "vertical".
    +
    +
    +

    rangeType: Boolean or String +

    +
    +Default: false +
    +
    Whether the slider represents a range.
    +Multiple types supported:
      +
    • +Boolean: If set to true, the slider will detect if you have two handles and create a stylable range element between these two.
    • +
    • +String: Either "min" or "max". A min range goes from the slider min to one handle. A max range goes from one handle to the slider max.
    • +
    +
    +
    +

    stepType: Number +

    +
    +Default: 1 +
    +
    Determines the size or amount of each interval or step the slider takes between the min and max. The full specified value range of the slider (max - min) should be evenly divisible by the step.
    +
    +
    +

    valueType: Number +

    +
    +Default: 0 +
    +
    Determines the value of the slider, if there's only one handle. If there is more than one handle, determines the value of the first handle.
    +
    +
    +

    valuesType: Array +

    +
    +Default: null +
    +
    This option can be used to specify multiple handles. If the range option is set to true, the length of values should be 2.
    +

    Methods

    +

    destroy()

    +
    + Removes the slider functionality completely. This will return the element back to its pre-init state. +
    +
    +
    +

    disable()

    +
    + Disables the slider. +
    +
    +
    +

    enable()

    +
    + Enables the slider. +
    +
    +
    +
    +

    option( optionName ) Returns: Object +

    +
    Gets the value currently associated with the specified optionName.
    +
    • +
      optionName
      +
      Type: String +
      +
      The name of the option to get.
      +
    +
    +
    +

    option() Returns: PlainObject +

    +
    Gets an object containing key/value pairs representing the current slider options hash.
    +
    +
    +

    option( optionName, value )

    +
    Sets the value of the slider option associated with the specified optionName.
    +
      +
    • +
      optionName
      +
      Type: String +
      +
      The name of the option to set.
      +
    • +
    • +
      value
      +
      Type: Object +
      +
      A value to set for the option.
      +
    • +
    +
    +
    +

    option( options )

    +
    Sets one or more options for the slider.
    +
    • +
      options
      +
      Type: Object +
      +
      A map of option-value pairs to set.
      +
    +
    +
    +
    +
    +

    value() Returns: Number +

    +
    Get the value of the slider.
    +
    +
    +

    value( value )

    +
    Set the value of the slider.
    +
    • +
      value
      +
      Type: Number +
      +
      The value to set.
      +
    +
    +
    +
    +
    +

    values() Returns: Array +

    +
    Get the value for all handles.
    +
    +
    +

    values( index ) Returns: Number +

    +
    Get the value for the specified handle.
    +
    • +
      index
      +
      Type: Integer +
      +
      The zero-based index of the handle.
      +
    +
    +
    +

    values( index, value )

    +
    Set the value for the specified handle.
    +
      +
    • +
      index
      +
      Type: Integer +
      +
      The zero-based index of the handle.
      +
    • +
    • +
      value
      +
      Type: Number +
      +
      The value to set.
      +
    • +
    +
    +
    +

    values( values )

    +
    Set the value for all handles.
    +
    • +
      values
      +
      Type: Array +
      +
      The values to set.
      +
    +
    +
    +
    +

    widget() Returns: jQuery +

    +
    + Returns a jQuery object containing the slider. +
    +

    Events

    +

    change( event, ui )

    +
    Triggered after the user slides a handle, if the value has changed; or if the value is changed programmatically via the value method.
    +
      +
    • +
      event
      +
      Type: Event +
      +
      +
    • +
    • +
      ui
      +
      Type: Object +
      +
      +
        +
      • +
        handle
        +
        Type: jQuery +
        +
        The jQuery object representing the handle that was changed.
        +
      • +
      • +
        value
        +
        Type: Number +
        +
        The current value of the slider.
        +
      • +
      +
    • +
    +
    +
    +

    create( event, ui )

    +
    + Triggered when the slider is created. +
    +
      +
    • +
      event
      +
      Type: Event +
      +
      +
    • +
    • +
      ui
      +
      Type: Object +
      +
      +
    • +
    +
    +
    +

    slide( event, ui )

    +
    Triggered on every mouse move during slide. The value provided in the event as ui.value represents the value that the handle will have as a result of the current movement. Canceling the event will prevent the handle from moving and the handle will continue to have its previous value.
    +
      +
    • +
      event
      +
      Type: Event +
      +
      +
    • +
    • +
      ui
      +
      Type: Object +
      +
      +
        +
      • +
        handle
        +
        Type: jQuery +
        +
        The jQuery object representing the handle being moved.
        +
      • +
      • +
        value
        +
        Type: Number +
        +
        The value that the handle will move to if the event is not canceled.
        +
      • +
      • +
        values
        +
        Type: Array +
        +
        An array of the current values of a multi-handled slider.
        +
      • +
      +
    • +
    +
    +
    +

    start( event, ui )

    +
    Triggered when the user starts sliding.
    +
      +
    • +
      event
      +
      Type: Event +
      +
      +
    • +
    • +
      ui
      +
      Type: Object +
      +
      +
        +
      • +
        handle
        +
        Type: jQuery +
        +
        The jQuery object representing the handle being moved.
        +
      • +
      • +
        value
        +
        Type: Number +
        +
        The current value of the slider.
        +
      • +
      +
    • +
    +
    +
    +

    stop( event, ui )

    +
    Triggered after the user slides a handle.
    +
      +
    • +
      event
      +
      Type: Event +
      +
      +
    • +
    • +
      ui
      +
      Type: Object +
      +
      +
        +
      • +
        handle
        +
        Type: jQuery +
        +
        The jQuery object representing the handle that was moved.
        +
      • +
      • +
        value
        +
        Type: Number +
        +
        The current value of the slider.
        +
      • +
      +
    • +
    +
    +

    The jQuery UI Slider plugin makes selected elements into sliders. There are various options such as multiple handles and ranges. The handle can be moved with the mouse or the arrow keys.

    + +

    The slider widget will create handle elements with the class ui-slider-handle on initialization. You can specify custom handle elements by creating and appending the elements and adding the ui-slider-handle class before initialization. It will only create the number of handles needed to match the length of value/values. For example, if you specify values: [ 1, 5, 18 ] and create one custom handle, the plugin will create the other two.

    +
    +

    Additional Notes:

    +
    • + This widget requires some functional CSS, otherwise it won't work. If you build a custom theme, use the widget's specific CSS file as a starting point. +
    +

    Example:

    +

    A simple jQuery UI Slider.

    +
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    <!doctype html>
    <html lang="en">
    <head>
        <meta charset="utf-8">
        <title>slider demo</title>
        <link rel="stylesheet" href="http://code.jquery.com/ui/1.9.0/themes/base/jquery-ui.css">
        <style>#slider { margin: 10px; }  </style>
        <script src="http://code.jquery.com/jquery-1.8.2.js"></script>
        <script src="http://code.jquery.com/ui/1.9.0/jquery-ui.js"></script>
    </head>
    <body>
     
    <div id="slider"></div>
     
    <script>
    $( "#slider" ).slider();
    </script>
     
    </body>
    </html>
    +

    Demo:

    +
    +
    +
    + + + diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/docs/sortable.html b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/docs/sortable.html new file mode 100755 index 000000000..56366d58a --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/docs/sortable.html @@ -0,0 +1,1191 @@ + + + + + jQuery UI sortable documentation + + + + + +

    QuickNav

    + +

    +Sortable Widgetversion added: 1.0 +

    +
    +

    Description: Reorder elements in a list or grid using the mouse.

    +

    Options

    +

    appendToType: jQuery or Element or Selector or String +

    +
    +Default: "parent" +
    +
    Defines where the helper that moves with the mouse is being appended to during the drag (for example, to resolve overlap/zIndex issues).
    +Multiple types supported:
      +
    • +jQuery: A jQuery object containing the element to append the helper to.
    • +
    • +Element: The element to append the helper to.
    • +
    • +Selector: A selector specifying which element to append the helper to.
    • +
    • +String: The string "parent" will cause the helper to be a sibling of the sortable item.
    • +
    +
    +
    +

    axisType: String +

    +
    +Default: false +
    +
    If defined, the items can be dragged only horizontally or vertically. Possible values: "x", "y".
    +
    +
    +

    cancelType: Selector +

    +
    +Default: ":input,button" +
    +
    Prevents sorting if you start on elements matching the selector.
    +
    +
    +

    connectWithType: Selector +

    +
    +Default: false +
    +
    A selector of other sortable elements that the items from this list should be connected to. This is a one-way relationship, if you want the items to be connected in both directions, the connectWith option must be set on both sortable elements.
    +
    +
    +

    containmentType: Element or Selector or String +

    +
    +Default: false +
    +
    +

    Defines a bounding box that the sortable items are contrained to while dragging.

    + +

    Note: The element specified for containment must have a calculated width and height (though it need not be explicit). For example, if you have float: left sortable children and specify containment: "parent" be sure to have float: left on the sortable/parent container as well or it will have height: 0, causing undefined behavior.

    +
    +Multiple types supported:
      +
    • +Element: An element to use as the container.
    • +
    • +Selector: A selector specifying an element to use as the container.
    • +
    • +String: A string identifying an element to use as the container. Possible values: "parent", "document", "window".
    • +
    +
    +
    +

    cursorType: String +

    +
    +Default: "auto" +
    +
    Defines the cursor that is being shown while sorting.
    +
    +
    +

    cursorAtType: Object +

    +
    +Default: false +
    +
    Moves the sorting element or helper so the cursor always appears to drag from the same position. Coordinates can be given as a hash using a combination of one or two keys: { top, left, right, bottom }.
    +
    +
    +

    delayType: Integer +

    +
    +Default: 0 +
    +
    Time in milliseconds to define when the sorting should start. Adding a delay helps preventing unwanted drags when clicking on an element.
    +
    +
    +

    disabledType: Boolean +

    +
    +Default: false +
    +
    Disables the sortable if set to true.
    +
    +
    +

    distanceType: Number +

    +
    +Default: 1 +
    +
    Tolerance, in pixels, for when sorting should start. If specified, sorting will not start until after mouse is dragged beyond distance. Can be used to allow for clicks on elements within a handle.
    +
    +
    +

    dropOnEmptyType: Boolean +

    +
    +Default: true +
    +
    If false, items from this sortable can't be dropped on an empty connect sortable (see the connectWith option.
    +
    +
    +

    forceHelperSizeType: Boolean +

    +
    +Default: false +
    +
    If true, forces the helper to have a size.
    +
    +
    +

    forcePlaceholderSizeType: Boolean +

    +
    +Default: false +
    +
    If true, forces the placeholder to have a size.
    +
    +
    +

    gridType: Array +

    +
    +Default: false +
    +
    Snaps the sorting element or helper to a grid, every x and y pixels. Array values: [ x, y ].
    +
    +
    +

    handleType: Selector or Element +

    +
    +Default: false +
    +
    Restricts sort start click to the specified element.
    +
    +
    +

    helperType: String or Function() +

    +
    +Default: "original" +
    +
    Allows for a helper element to be used for dragging display.
    +Multiple types supported:
      +
    • +String: If set to "clone", then the element will be cloned and the clone will be dragged.
    • +
    • +Function: A function that will return a DOMElement to use while dragging. The function receives the event and the element being sorted.
    • +
    +
    +
    +

    itemsType: Selector +

    +
    +Default: "> *" +
    +
    Specifies which items inside the element should be sortable.
    +
    +
    +

    opacityType: Number +

    +
    +Default: false +
    +
    Defines the opacity of the helper while sorting. From 0.01 to 1.
    +
    +
    +

    placeholderType: String +

    +
    +Default: false +
    +
    A class name that gets applied to the otherwise white space.
    +
    +
    +

    revertType: Boolean or Number +

    +
    +Default: false +
    +
    Whether the sortable items should revert to their new positions using a smooth animation.
    +Multiple types supported:
      +
    • +Boolean: When set to true, the items will animate with the default duration.
    • +
    • +Number: The duration for the animation, in milliseconds.
    • +
    +
    +
    +

    scrollType: Boolean +

    +
    +Default: true +
    +
    If set to true, the page scrolls when coming to an edge.
    +
    +
    +

    scrollSensitivityType: Number +

    +
    +Default: 20 +
    +
    Defines how near the mouse must be to an edge to start scrolling.
    +
    +
    +

    scrollSpeedType: Number +

    +
    +Default: 20 +
    +
    The speed at which the window should scroll once the mouse pointer gets within the scrollSensitivity distance.
    +
    +
    +

    toleranceType: String +

    +
    +Default: "intersect" +
    +
    + Specifies which mode to use for testing whether the item being moved is hovering over another item. Possible values: +
      +
    • +"intersect": The item overlaps the other item by at least 50%.
    • +
    • +"pointer": The mouse pointer overlaps the other item.
    • +
    +
    +
    +
    +

    zIndexType: Integer +

    +
    +Default: 1000 +
    +
    Z-index for element/helper while being sorted.
    +

    Methods

    +

    cancel()

    +
    Cancels a change in the current sortable and reverts it to the state prior to when the current sort was started. Useful in the stop and receive callback functions.
    +
    +
    +

    destroy()

    +
    + Removes the sortable functionality completely. This will return the element back to its pre-init state. +
    +
    +
    +

    disable()

    +
    + Disables the sortable. +
    +
    +
    +

    enable()

    +
    + Enables the sortable. +
    +
    +
    +
    +

    option( optionName ) Returns: Object +

    +
    Gets the value currently associated with the specified optionName.
    +
    • +
      optionName
      +
      Type: String +
      +
      The name of the option to get.
      +
    +
    +
    +

    option() Returns: PlainObject +

    +
    Gets an object containing key/value pairs representing the current sortable options hash.
    +
    +
    +

    option( optionName, value )

    +
    Sets the value of the sortable option associated with the specified optionName.
    +
      +
    • +
      optionName
      +
      Type: String +
      +
      The name of the option to set.
      +
    • +
    • +
      value
      +
      Type: Object +
      +
      A value to set for the option.
      +
    • +
    +
    +
    +

    option( options )

    +
    Sets one or more options for the sortable.
    +
    • +
      options
      +
      Type: Object +
      +
      A map of option-value pairs to set.
      +
    +
    +
    +
    +

    refresh()

    +
    Refresh the sortable items. Triggers the reloading of all sortable items, causing new items to be recognized.
    +
    +
    +

    refreshPositions()

    +
    Refresh the cached positions of the sortable items. Calling this method refreshes the cached item positions of all sortables.
    +
    +
    +

    serialize( options )

    +
    +

    Serializes the sortable's item ids into a form/ajax submittable string. Calling this method produces a hash that can be appended to any url to easily submit a new item order back to the server.

    + +

    It works by default by looking at the id of each item in the format "setname_number", and it spits out a hash like "setname[]=number&setname[]=number".

    + +

    Note: If serialize returns an empty string, make sure the id attributes include an underscore. They must be in the form: "set_number" For example, a 3 element list with id attributes "foo_1", "foo_5", "foo_2" will serialize to "foo[]=1&foo[]=5&foo[]=2". You can use an underscore, equal sign or hyphen to separate the set and number. For example "foo=1", "foo-1", and "foo_1" all serialize to "foo[]=1".

    +
    +
    • +
      options
      +
      Type: Object +
      +
      Options to customize the serialization.
      +
        +
      • +
        key
        +
        Type: String +
        +
        Replaces part1[] with the specified value.
        +
      • +
      • +
        attribute
        +
        Type: String +
        +
        The name of the attribute to use for the values.
        +
      • +
      • +
        expression
        +
        Type: RegExp +
        +
        A regular expression used to split the attribute value into key and value parts.
        +
      • +
      +
    +
    +
    +

    toArray()

    +
    Serializes the sortable's item id's into an array of string.
    +
    +
    +

    widget() Returns: jQuery +

    +
    + Returns a jQuery object containing the sortable element. +
    +

    Events

    +

    activate( event, ui )

    +
    This event is triggered when using connected lists, every connected list on drag start receives it.
    +
      +
    • +
      event
      +
      Type: Event +
      +
      +
    • +
    • +
      ui
      +
      Type: Object +
      +
      +
        +
      • +
        helper
        +
        Type: jQuery +
        +
        The jQuery object representing the helper being sorted
        +
      • +
      • +
        item
        +
        Type: jQuery +
        +
        The jQuery object representing the current dragged element
        +
      • +
      • +
        offset
        +
        Type: Object +
        +
        The current absolute position of the helper represented as { top, left } +
        +
      • +
      • +
        position
        +
        Type: Object +
        +
        The current position of the helper represented as { top, left } +
        +
      • +
      • +
        originalPosition
        +
        Type: Object +
        +
        The original position of the element represented as { top, left } +
        +
      • +
      • +
        sender
        +
        Type: jQuery +
        +
        The sortable that the item comes from if moving from one sortable to another
        +
      • +
      +
    • +
    +
    +
    +

    beforeStop( event, ui )

    +
    This event is triggered when sorting stops, but when the placeholder/helper is still available.
    +
      +
    • +
      event
      +
      Type: Event +
      +
      +
    • +
    • +
      ui
      +
      Type: Object +
      +
      +
        +
      • +
        helper
        +
        Type: jQuery +
        +
        The jQuery object representing the helper being sorted
        +
      • +
      • +
        item
        +
        Type: jQuery +
        +
        The jQuery object representing the current dragged element
        +
      • +
      • +
        offset
        +
        Type: Object +
        +
        The current absolute position of the helper represented as { top, left } +
        +
      • +
      • +
        position
        +
        Type: Object +
        +
        The current position of the helper represented as { top, left } +
        +
      • +
      • +
        originalPosition
        +
        Type: Object +
        +
        The original position of the element represented as { top, left } +
        +
      • +
      • +
        sender
        +
        Type: jQuery +
        +
        The sortable that the item comes from if moving from one sortable to another
        +
      • +
      +
    • +
    +
    +
    +

    change( event, ui )

    +
    This event is triggered during sorting, but only when the DOM position has changed.
    +
      +
    • +
      event
      +
      Type: Event +
      +
      +
    • +
    • +
      ui
      +
      Type: Object +
      +
      +
        +
      • +
        helper
        +
        Type: jQuery +
        +
        The jQuery object representing the helper being sorted
        +
      • +
      • +
        item
        +
        Type: jQuery +
        +
        The jQuery object representing the current dragged element
        +
      • +
      • +
        offset
        +
        Type: Object +
        +
        The current absolute position of the helper represented as { top, left } +
        +
      • +
      • +
        position
        +
        Type: Object +
        +
        The current position of the helper represented as { top, left } +
        +
      • +
      • +
        originalPosition
        +
        Type: Object +
        +
        The original position of the element represented as { top, left } +
        +
      • +
      • +
        sender
        +
        Type: jQuery +
        +
        The sortable that the item comes from if moving from one sortable to another
        +
      • +
      +
    • +
    +
    +
    +

    create( event, ui )

    +
    + Triggered when the sortable is created. +
    +
      +
    • +
      event
      +
      Type: Event +
      +
      +
    • +
    • +
      ui
      +
      Type: Object +
      +
      +
    • +
    +
    +
    +

    deactivate( event, ui )

    +
    This event is triggered when sorting was stopped, is propagated to all possible connected lists.
    +
      +
    • +
      event
      +
      Type: Event +
      +
      +
    • +
    • +
      ui
      +
      Type: Object +
      +
      +
        +
      • +
        helper
        +
        Type: jQuery +
        +
        The jQuery object representing the helper being sorted
        +
      • +
      • +
        item
        +
        Type: jQuery +
        +
        The jQuery object representing the current dragged element
        +
      • +
      • +
        offset
        +
        Type: Object +
        +
        The current absolute position of the helper represented as { top, left } +
        +
      • +
      • +
        position
        +
        Type: Object +
        +
        The current position of the helper represented as { top, left } +
        +
      • +
      • +
        originalPosition
        +
        Type: Object +
        +
        The original position of the element represented as { top, left } +
        +
      • +
      • +
        sender
        +
        Type: jQuery +
        +
        The sortable that the item comes from if moving from one sortable to another
        +
      • +
      +
    • +
    +
    +
    +

    out( event, ui )

    +
    This event is triggered when a sortable item is moved away from a connected list.
    +
      +
    • +
      event
      +
      Type: Event +
      +
      +
    • +
    • +
      ui
      +
      Type: Object +
      +
      +
        +
      • +
        helper
        +
        Type: jQuery +
        +
        The jQuery object representing the helper being sorted
        +
      • +
      • +
        item
        +
        Type: jQuery +
        +
        The jQuery object representing the current dragged element
        +
      • +
      • +
        offset
        +
        Type: Object +
        +
        The current absolute position of the helper represented as { top, left } +
        +
      • +
      • +
        position
        +
        Type: Object +
        +
        The current position of the helper represented as { top, left } +
        +
      • +
      • +
        originalPosition
        +
        Type: Object +
        +
        The original position of the element represented as { top, left } +
        +
      • +
      • +
        sender
        +
        Type: jQuery +
        +
        The sortable that the item comes from if moving from one sortable to another
        +
      • +
      +
    • +
    +
    +
    +

    over( event, ui )

    +
    This event is triggered when a sortable item is moved into a connected list.
    +
      +
    • +
      event
      +
      Type: Event +
      +
      +
    • +
    • +
      ui
      +
      Type: Object +
      +
      +
        +
      • +
        helper
        +
        Type: jQuery +
        +
        The jQuery object representing the helper being sorted
        +
      • +
      • +
        item
        +
        Type: jQuery +
        +
        The jQuery object representing the current dragged element
        +
      • +
      • +
        offset
        +
        Type: Object +
        +
        The current absolute position of the helper represented as { top, left } +
        +
      • +
      • +
        position
        +
        Type: Object +
        +
        The current position of the helper represented as { top, left } +
        +
      • +
      • +
        originalPosition
        +
        Type: Object +
        +
        The original position of the element represented as { top, left } +
        +
      • +
      • +
        sender
        +
        Type: jQuery +
        +
        The sortable that the item comes from if moving from one sortable to another
        +
      • +
      +
    • +
    +
    +
    +

    receive( event, ui )

    +
    This event is triggered when a connected sortable list has received an item from another list.
    +
      +
    • +
      event
      +
      Type: Event +
      +
      +
    • +
    • +
      ui
      +
      Type: Object +
      +
      +
        +
      • +
        helper
        +
        Type: jQuery +
        +
        The jQuery object representing the helper being sorted
        +
      • +
      • +
        item
        +
        Type: jQuery +
        +
        The jQuery object representing the current dragged element
        +
      • +
      • +
        offset
        +
        Type: Object +
        +
        The current absolute position of the helper represented as { top, left } +
        +
      • +
      • +
        position
        +
        Type: Object +
        +
        The current position of the helper represented as { top, left } +
        +
      • +
      • +
        originalPosition
        +
        Type: Object +
        +
        The original position of the element represented as { top, left } +
        +
      • +
      • +
        sender
        +
        Type: jQuery +
        +
        The sortable that the item comes from if moving from one sortable to another
        +
      • +
      +
    • +
    +
    +
    +

    remove( event, ui )

    +
    This event is triggered when a sortable item has been dragged out from the list and into another.
    +
      +
    • +
      event
      +
      Type: Event +
      +
      +
    • +
    • +
      ui
      +
      Type: Object +
      +
      +
        +
      • +
        helper
        +
        Type: jQuery +
        +
        The jQuery object representing the helper being sorted
        +
      • +
      • +
        item
        +
        Type: jQuery +
        +
        The jQuery object representing the current dragged element
        +
      • +
      • +
        offset
        +
        Type: Object +
        +
        The current absolute position of the helper represented as { top, left } +
        +
      • +
      • +
        position
        +
        Type: Object +
        +
        The current position of the helper represented as { top, left } +
        +
      • +
      • +
        originalPosition
        +
        Type: Object +
        +
        The original position of the element represented as { top, left } +
        +
      • +
      • +
        sender
        +
        Type: jQuery +
        +
        The sortable that the item comes from if moving from one sortable to another
        +
      • +
      +
    • +
    +
    +
    +

    sort( event, ui )

    +
    This event is triggered during sorting.
    +
      +
    • +
      event
      +
      Type: Event +
      +
      +
    • +
    • +
      ui
      +
      Type: Object +
      +
      +
        +
      • +
        helper
        +
        Type: jQuery +
        +
        The jQuery object representing the helper being sorted
        +
      • +
      • +
        item
        +
        Type: jQuery +
        +
        The jQuery object representing the current dragged element
        +
      • +
      • +
        offset
        +
        Type: Object +
        +
        The current absolute position of the helper represented as { top, left } +
        +
      • +
      • +
        position
        +
        Type: Object +
        +
        The current position of the helper represented as { top, left } +
        +
      • +
      • +
        originalPosition
        +
        Type: Object +
        +
        The original position of the element represented as { top, left } +
        +
      • +
      • +
        sender
        +
        Type: jQuery +
        +
        The sortable that the item comes from if moving from one sortable to another
        +
      • +
      +
    • +
    +
    +
    +

    start( event, ui )

    +
    This event is triggered when sorting starts.
    +
      +
    • +
      event
      +
      Type: Event +
      +
      +
    • +
    • +
      ui
      +
      Type: Object +
      +
      +
        +
      • +
        helper
        +
        Type: jQuery +
        +
        The jQuery object representing the helper being sorted
        +
      • +
      • +
        item
        +
        Type: jQuery +
        +
        The jQuery object representing the current dragged element
        +
      • +
      • +
        offset
        +
        Type: Object +
        +
        The current absolute position of the helper represented as { top, left } +
        +
      • +
      • +
        position
        +
        Type: Object +
        +
        The current position of the helper represented as { top, left } +
        +
      • +
      • +
        originalPosition
        +
        Type: Object +
        +
        The original position of the element represented as { top, left } +
        +
      • +
      • +
        sender
        +
        Type: jQuery +
        +
        The sortable that the item comes from if moving from one sortable to another
        +
      • +
      +
    • +
    +
    +
    +

    stop( event, ui )

    +
    This event is triggered when sorting has stopped.
    +
      +
    • +
      event
      +
      Type: Event +
      +
      +
    • +
    • +
      ui
      +
      Type: Object +
      +
      +
        +
      • +
        helper
        +
        Type: jQuery +
        +
        The jQuery object representing the helper being sorted
        +
      • +
      • +
        item
        +
        Type: jQuery +
        +
        The jQuery object representing the current dragged element
        +
      • +
      • +
        offset
        +
        Type: Object +
        +
        The current absolute position of the helper represented as { top, left } +
        +
      • +
      • +
        position
        +
        Type: Object +
        +
        The current position of the helper represented as { top, left } +
        +
      • +
      • +
        originalPosition
        +
        Type: Object +
        +
        The original position of the element represented as { top, left } +
        +
      • +
      • +
        sender
        +
        Type: jQuery +
        +
        The sortable that the item comes from if moving from one sortable to another
        +
      • +
      +
    • +
    +
    +
    +

    update( event, ui )

    +
    This event is triggered when the user stopped sorting and the DOM position has changed.
    +
      +
    • +
      event
      +
      Type: Event +
      +
      +
    • +
    • +
      ui
      +
      Type: Object +
      +
      +
        +
      • +
        helper
        +
        Type: jQuery +
        +
        The jQuery object representing the helper being sorted
        +
      • +
      • +
        item
        +
        Type: jQuery +
        +
        The jQuery object representing the current dragged element
        +
      • +
      • +
        offset
        +
        Type: Object +
        +
        The current absolute position of the helper represented as { top, left } +
        +
      • +
      • +
        position
        +
        Type: Object +
        +
        The current position of the helper represented as { top, left } +
        +
      • +
      • +
        originalPosition
        +
        Type: Object +
        +
        The original position of the element represented as { top, left } +
        +
      • +
      • +
        sender
        +
        Type: jQuery +
        +
        The sortable that the item comes from if moving from one sortable to another
        +
      • +
      +
    • +
    +
    +

    The jQuery UI Sortable plugin makes selected elements sortable by dragging with the mouse.

    +
    +

    Example:

    +

    A simple jQuery UI Sortable.

    +
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    <!doctype html>
    <html lang="en">
    <head>
        <meta charset="utf-8">
        <title>sortable demo</title>
        <link rel="stylesheet" href="http://code.jquery.com/ui/1.9.0/themes/base/jquery-ui.css">
        <script src="http://code.jquery.com/jquery-1.8.2.js"></script>
        <script src="http://code.jquery.com/ui/1.9.0/jquery-ui.js"></script>
    </head>
    <body>
     
    <ul id="sortable">
        <li>Item 1</li>
        <li>Item 2</li>
        <li>Item 3</li>
        <li>Item 4</li>
        <li>Item 5</li>
    </ul>
     
    <script>$("#sortable").sortable();</script>
     
    </body>
    </html>
    +

    Demo:

    +
    +
    +
    + + + diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/docs/spinner.html b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/docs/spinner.html new file mode 100755 index 000000000..d0fee19f8 --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/docs/spinner.html @@ -0,0 +1,436 @@ + + + + + jQuery UI spinner documentation + + + + + +

    QuickNav

    + +
    +

    Events

    + + + + + +

    +Spinner Widgetversion added: 1.9 +

    +
    +

    Description: + Enhance a text input for entering numeric values, with up/down buttons and arrow key handling. +

    +

    Options

    +

    cultureType: String +

    +
    +Default: null +
    +
    Sets the culture to use for parsing and formatting the value. If null, the currently set culture in Globalize is used, see Globalize docs for available cultures. Only relevant if the numberFormat option is set. Requires Globalize to be included.
    +
    +
    +

    disabledType: Boolean +

    +
    +Default: false +
    +
    Disables the spinner if set to true.
    +
    +
    +

    iconsType: Object +

    +
    +Default: { down: "ui-icon-triangle-1-s", up: "ui-icon-triangle-1-n" } +
    +
    + Icons to use for buttons, matching an icon defined by the jQuery UI CSS Framework. +
      +
    • up (string, default: "ui-icon-triangle-1-n")
    • +
    • down (string, default: "ui-icon-triangle-1-s")
    • +
    +
    +
    +
    +

    incrementalType: Boolean or Function() +

    +
    +Default: true +
    +
    Controls the number of steps taken when holding down a spin button.
    +Multiple types supported:
      +
    • +Boolean: When set to true, the stepping delta will increase when spun incessantly. When set to false, all steps are equal (as defined by the step option).
    • +
    • +Function: Receives one parameter: the number of spins that have occurred. Must return the number of steps that should occur for the current spin.
    • +
    +
    +
    +

    maxType: Number or String +

    +
    +Default: null +
    +
    The maximum allowed value. The element's max attribute is used if it exists and the option is not explicitly set. If null, there is no maximum enforced.
    +Multiple types supported:
      +
    • +Number: The maximum value.
    • +
    • +String: If Globalize is included, the max option can be passed as a string which will be parsed based on the numberFormat and culture options; otherwise it will fall back to the native parseFloat() method.
    • +
    +
    +
    +

    minType: Number or String +

    +
    +Default: null +
    +
    The minimum allowed value. The element's min attribute is used if it exists and the option is not explicitly set. If null, there is no minimum enforced.
    +Multiple types supported:
      +
    • +Number: The minimum value.
    • +
    • +String: If Globalize is included, the min option can be passed as a string which will be parsed based on the numberFormat and culture options; otherwise it will fall back to the native parseFloat() method.
    • +
    +
    +
    +

    numberFormatType: String +

    +
    +Default: null +
    +
    Format of numbers passed to Globalize, if available. Most common are "n" for a decimal number and "C" for a currency value. Also see the culture option.
    +
    +
    +

    pageType: Number +

    +
    +Default: null +
    +
    The number of steps to take when paging via the pageUp/pageDown methods.
    +
    +
    +

    stepType: Number or String +

    +
    +Default: null +
    +
    The size of the step to take when spinning via buttons or via the stepUp()/stepDown() methods. The element's step attribute is used if it exists and the option is not explicitly set.
    +Multiple types supported:
      +
    • +Number: The size of the step.
    • +
    • +String: If Globalize is included, the step option can be passed as a string which will be parsed based on the numberFormat and culture options, otherwise it will fall back to the native parseFloat.
    • +
    +

    Methods

    +

    destroy()

    +
    + Removes the spinner functionality completely. This will return the element back to its pre-init state. +
    +
    +
    +

    disable()

    +
    + Disables the spinner. +
    +
    +
    +

    enable()

    +
    + Enables the spinner. +
    +
    +
    +
    +

    option( optionName ) Returns: Object +

    +
    Gets the value currently associated with the specified optionName.
    +
    • +
      optionName
      +
      Type: String +
      +
      The name of the option to get.
      +
    +
    +
    +

    option() Returns: PlainObject +

    +
    Gets an object containing key/value pairs representing the current spinner options hash.
    +
    +
    +

    option( optionName, value )

    +
    Sets the value of the spinner option associated with the specified optionName.
    +
      +
    • +
      optionName
      +
      Type: String +
      +
      The name of the option to set.
      +
    • +
    • +
      value
      +
      Type: Object +
      +
      A value to set for the option.
      +
    • +
    +
    +
    +

    option( options )

    +
    Sets one or more options for the spinner.
    +
    • +
      options
      +
      Type: Object +
      +
      A map of option-value pairs to set.
      +
    +
    +
    +
    +

    pageDown( [pages ] )

    +
    + Decrements the value by the specified number of pages, as defined by the page option. Without the parameter, a single page is decremented. +
    +
    • +
      pages
      +
      Type: Number +
      +
      Number of pages to decrement, defaults to 1.
      +
    +
    +
    +

    pageUp( [pages ] )

    +
    + Increments the value by the specified number of pages, as defined by the page option. Without the parameter, a single page is incremented. +
    +
    • +
      pages
      +
      Type: Number +
      +
      Number of pages to increment, defaults to 1.
      +
    +
    +
    +

    stepDown( [steps ] )

    +
    + Decrements the value by the specified number of steps. Without the parameter, a single step is decremented. +

    If the resulting value is above the max, below the min, or reuslts in a step mismatch, the value will be adjusted to the closest valid value.

    +
    +
    • +
      steps
      +
      Type: Number +
      +
      Number of steps to decrement, defaults to 1.
      +
    +
    +
    +

    stepUp( [steps ] )

    +
    + Increments the value by the specified number of steps. Without the parameter, a single step is incremented. +

    If the resulting value is above the max, below the min, or reuslts in a step mismatch, the value will be adjusted to the closest valid value.

    +
    +
    • +
      steps
      +
      Type: Number +
      +
      Number of steps to increment, defaults to 1.
      +
    +
    +
    +
    +

    value() Returns: Number +

    +
    Gets the current value as a number. The value is parsed based on the numberFormat and culture options.
    +
    +
    +

    value( value )

    +
    + +
    +
    +
    +

    widget() Returns: jQuery +

    +
    + Returns a jQuery object containing the generated wrapper. +
    +

    Events

    +

    change( event, ui )

    +
    + Triggered when the value of the spinner has changed and the input is no longer focused. +
    +
      +
    • +
      event
      +
      Type: Event +
      +
      +
    • +
    • +
      ui
      +
      Type: Object +
      +
      +
    • +
    +
    +
    +

    create( event, ui )

    +
    + Triggered when the spinner is created. +
    +
      +
    • +
      event
      +
      Type: Event +
      +
      +
    • +
    • +
      ui
      +
      Type: Object +
      +
      +
    • +
    +
    +
    +

    spin( event, ui )

    +
    + Triggered during increment/decrement (to determine direction of spin compare current value with ui.value). +

    Can be canceled, preventing the value from being updated.

    +
    +
      +
    • +
      event
      +
      Type: Event +
      +
      +
    • +
    • +
      ui
      +
      Type: Object +
      +
      +
      • +
        value
        +
        Type: Number +
        +
        The new value to be set, unless the event is cancelled.
        +
      +
    • +
    +
    +
    +

    start( event, ui )

    +
    + Triggered before a spin. Can be canceled, preventing the spin from occurring. +
    +
      +
    • +
      event
      +
      Type: Event +
      +
      +
    • +
    • +
      ui
      +
      Type: Object +
      +
      +
    • +
    +
    +
    +

    stop( event, ui )

    +
    Triggered after a spin.
    +
      +
    • +
      event
      +
      Type: Event +
      +
      +
    • +
    • +
      ui
      +
      Type: Object +
      +
      +
    • +
    +
    +

    Spinner wraps a text input, adds two buttons to increment and decrement the current value, along with handling key events for the same purpose. It delegates to Globalize for number formatting and parsing.

    + +

    Keyboard interaction

    + +
      +
    • UP: Increment the value by one step.
    • +
    • DOWN: Decrement the value by one step.
    • +
    • PAGE UP: Increment the value by one page.
    • +
    • PAGE DOWN: Decrement the value by one page.
    • +
    + +

    Focus stays in the text field, even after using the mouse to click one of the spin buttons.

    +
    +

    Additional Notes:

    +
    • + This widget requires some functional CSS, otherwise it won't work. If you build a custom theme, use the widget's specific CSS file as a starting point. +
    +

    Example:

    +

    Plain number spinner

    +
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    <!doctype html>
    <html lang="en">
    <head>
        <meta charset="utf-8">
        <title>spinner demo</title>
        <link rel="stylesheet" href="http://code.jquery.com/ui/1.9.0/themes/base/jquery-ui.css">
        <script src="http://code.jquery.com/jquery-1.8.2.js"></script>
        <script src="http://code.jquery.com/ui/1.9.0/jquery-ui.js"></script>
    </head>
    <body>
     
    <input id="spinner">
     
    <script>
    $( "#spinner" ).spinner();
    </script>
     
    </body>
    </html>
    +

    Demo:

    +
    +
    +
    + + + diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/docs/tabs.html b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/docs/tabs.html new file mode 100755 index 000000000..f73eb71ce --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/docs/tabs.html @@ -0,0 +1,517 @@ + + + + + jQuery UI tabs documentation + + + + + +

    QuickNav

    + +

    +Tabs Widgetversion added: 1.0 +

    +
    +

    Description: A single content area with multiple panels, each associated with a header in a list.

    +

    Options

    +

    activeType: Boolean or Integer +

    +
    +Default: 0 +
    +
    + Which panel is currently open. +
    +Multiple types supported:
      +
    • +Boolean: Setting active to false will collapse all panels. This requires the collapsible option to be true.
    • +
    • +Integer: The zero-based index of the panel that is active (open). A negative value selects panels going backward from the last panel.
    • +
    +
    +
    +

    collapsibleType: Boolean +

    +
    +Default: false +
    +
    When set to true, the active panel can be closed.
    +
    +
    +

    disabledType: Boolean or Array +

    +
    +Default: false +
    +
    Which tabs are disabled.
    +Multiple types supported:
      +
    • +Boolean: Enable or disable all tabs.
    • +
    • +Array: An array containing the zero-based indexes of the tabs that should be disabled, e.g., [ 0, 2 ] would disable the first and third tab.
    • +
    +
    +
    +

    eventType: String +

    +
    +Default: "click" +
    +
    The type of event that the tabs should react to in order to activate the tab. To activate on hover, use "mouseover".
    +
    +
    +

    heightStyleType: String +

    +
    +Default: "auto" +
    +
    + Controls the height of the tabs widget and each panel. Possible values: +
      +
    • +"auto": All panels will be set to the height of the tallest panel.
    • +
    • +"fill": Expand to the available height based on the tabs' parent height.
    • +
    • +"content": Each panel will be only as tall as its content.
    • +
    +
    +
    +
    +

    hideType: Boolean or Number or String or Object +

    +
    +Default: null +
    +
    If and how to animate the hiding of the panel.
    +Multiple types supported:
      +
    • +Boolean: + When set to false, no animation will be used and the panel will be hidden immediately. + When set to true, the panel will fade out with the default duration and the default easing. +
    • +
    • +Number: + The panel will fade out with the specified duration and the default easing. +
    • +
    • +String: + The panel will be hidden using the specified effect. + The value can either be the name of a built-in jQuery animateion method, such as "slideUp", or the name of a jQuery UI effect, such as "fold". + In either case the effect will be used with the default duration and the default easing. +
    • +
    • +Object: If the value is an object, then effect, duration, and easing properties may be provided. If the effect property contains the name of a jQuery method, then that method will be used; otherwise it is assumed to be the name of a jQuery UI effect. When using a jQuery UI effect that supports additional settings, you may include those settings in the object and they will be passed to the effect. If duration or easing is omitted, then the default values will be used. If effect is omitted, then "fadeOut" will be used.
    • +
    +
    +
    +

    showType: Boolean or Number or String or Object +

    +
    +Default: null +
    +
    If and how to animate the showing of the panel.
    +Multiple types supported:
      +
    • +Boolean: + When set to false, no animation will be used and the panel will be shown immediately. + When set to true, the panel will fade in with the default duration and the default easing. +
    • +
    • +Number: + The panel will fade in with the specified duration and the default easing. +
    • +
    • +String: + The panel will be shown using the specified effect. + The value can either be the name of a built-in jQuery animateion method, such as "slideDown", or the name of a jQuery UI effect, such as "fold". + In either case the effect will be used with the default duration and the default easing. +
    • +
    • +Object: If the value is an object, then effect, duration, and easing properties may be provided. If the effect property contains the name of a jQuery method, then that method will be used; otherwise it is assumed to be the name of a jQuery UI effect. When using a jQuery UI effect that supports additional settings, you may include those settings in the object and they will be passed to the effect. If duration or easing is omitted, then the default values will be used. If effect is omitted, then "fadeIn" will be used.
    • +
    +

    Methods

    +

    destroy()

    +
    + Removes the tabs functionality completely. This will return the element back to its pre-init state. +
    +
    +
    +
    +

    disable()

    +
    Disables all tabs.
    +
    +
    +

    disable( index )

    +
    + Disables a tab. The selected tab cannot be disabled. To disable more than one tab at once, set the disabled option: $( "#tabs" ).tabs( "option", "disabled", [ 1, 2, 3 ] ). +
    + +
    +
    +
    +
    +

    enable()

    +
    Enables all tabs.
    +
    +
    +

    enable( index )

    +
    Enables a tab. To enable more than one tab at once reset the disabled property like: $( "#example" ).tabs( "option", "disabled", [] );.
    + +
    +
    +
    +

    load( index )

    +
    Loads the panel content of a remote tab.
    + +
    +
    +
    +

    option( optionName ) Returns: Object +

    +
    Gets the value currently associated with the specified optionName.
    +
    • +
      optionName
      +
      Type: String +
      +
      The name of the option to get.
      +
    +
    +
    +

    option() Returns: PlainObject +

    +
    Gets an object containing key/value pairs representing the current tabs options hash.
    +
    +
    +

    option( optionName, value )

    +
    Sets the value of the tabs option associated with the specified optionName.
    +
      +
    • +
      optionName
      +
      Type: String +
      +
      The name of the option to set.
      +
    • +
    • +
      value
      +
      Type: Object +
      +
      A value to set for the option.
      +
    • +
    +
    +
    +

    option( options )

    +
    Sets one or more options for the tabs.
    +
    • +
      options
      +
      Type: Object +
      +
      A map of option-value pairs to set.
      +
    +
    +
    +
    +

    refresh()

    +
    Process any tabs that were added or removed directly in the DOM and recompute the height of the tab panels. Results depend on the content and the heightStyle option.
    +
    +
    +

    widget() Returns: jQuery +

    +
    + Returns a jQuery object containing the tabs container. +
    +

    Events

    +

    activate( event, ui )

    +
    Triggered after a tab has been activated (after animation completes). If the tabs were previously collapsed, ui.oldTab and ui.oldPanel will be empty jQuery objects. If the tabs are collapsing, ui.newTab and ui.newPanel will be empty jQuery objects.
    +
      +
    • +
      event
      +
      Type: Event +
      +
      +
    • +
    • +
      ui
      +
      Type: Object +
      +
      +
        +
      • +
        newTab
        +
        Type: jQuery +
        +
        The tab that was just activated.
        +
      • +
      • +
        oldTab
        +
        Type: jQuery +
        +
        The tab that was just deactivated.
        +
      • +
      • +
        newPanel
        +
        Type: jQuery +
        +
        The panel that was just activated.
        +
      • +
      • +
        oldPanel
        +
        Type: jQuery +
        +
        The panel that was just deactivated.
        +
      • +
      +
    • +
    +
    +
    +

    beforeActivate( event, ui )

    +
    Triggered directly after a tab is activated. Can be canceled to prevent the tab from activating. If the tabs are currently collapsed, ui.oldTab and ui.oldPanel will be empty jQuery objects. If the tabs are collapsing, ui.newTab and ui.newPanel will be empty jQuery objects.
    +
      +
    • +
      event
      +
      Type: Event +
      +
      +
    • +
    • +
      ui
      +
      Type: Object +
      +
      +
        +
      • +
        newTab
        +
        Type: jQuery +
        +
        The tab that is about to be activated.
        +
      • +
      • +
        oldTab
        +
        Type: jQuery +
        +
        The tab that is about to be deactivated.
        +
      • +
      • +
        newPanel
        +
        Type: jQuery +
        +
        The panel that is about to be activated.
        +
      • +
      • +
        oldPanel
        +
        Type: jQuery +
        +
        The panel that is about to be deactivated.
        +
      • +
      +
    • +
    +
    +
    +

    beforeLoad( event, ui )

    +
    Triggered when a remote tab is about to be loaded, after the beforeActivate event. Can be canceled to prevent the tab panel from loading content; though the panel will still be activated. This event is triggered just before the Ajax request is made, so modifications can be made to ui.jqXHR and ui.ajaxSettings.
    +
      +
    • +
      event
      +
      Type: Event +
      +
      +
    • +
    • +
      ui
      +
      Type: Object +
      +
      +
        +
      • +
        tab
        +
        Type: jQuery +
        +
        The tab that is being loaded.
        +
      • +
      • +
        panel
        +
        Type: jQuery +
        +
        The panel which will be populated by the Ajax response.
        +
      • +
      • +
        jqXHR
        +
        Type: jqXHR +
        +
        The jqXHR object that is requesting the content.
        +
      • +
      • +
        ajaxSettings
        +
        Type: Object +
        +
        The settings that will be used by jQuery.ajax to request the content.
        +
      • +
      +
    • +
    +
    +
    +

    create( event, ui )

    +
    Triggered when the tabs are created. If the tabs are collapsed, ui.tab and ui.panel will be empty jQuery objects.
    +
      +
    • +
      event
      +
      Type: Event +
      +
      +
    • +
    • +
      ui
      +
      Type: Object +
      +
      +
        +
      • +
        tab
        +
        Type: jQuery +
        +
        The active tab.
        +
      • +
      • +
        panel
        +
        Type: jQuery +
        +
        The active panel.
        +
      • +
      +
    • +
    +
    +
    +

    load( event, ui )

    +
    Triggered after a remote tab has been loaded.
    +
      +
    • +
      event
      +
      Type: Event +
      +
      +
    • +
    • +
      ui
      +
      Type: Object +
      +
      +
        +
      • +
        tab
        +
        Type: jQuery +
        +
        The tab that was just loaded.
        +
      • +
      • +
        panel
        +
        Type: jQuery +
        +
        The panel which was just populated by the Ajax response.
        +
      • +
      +
    • +
    +
    +

    Tabs are generally used to break content into multiple sections that can be swapped to save space, much like an accordion.

    + +

    The content for each tab panel can be defined in-page or can be loaded via Ajax; both are handled automatically based on the href of the anchor associated with the tab. By default tabs are activated on click, but the events can be changed to hover via the event option.

    + +

    Keyboard interaction

    + +

    When focus is on a tab, the following key commands are available:

    +
      +
    • UP/LEFT: Move focus to the previous tab. If on first tab, moves focus to last tab. Activate focused tab after a short delay.
    • +
    • DOWN/RIGHT: Move focus to the next tab. If on last tab, moves focus to first tab. Activate focused tab after a short delay.
    • +
    • HOME: Move focus to the first tab. Activate focused tab after a short delay.
    • +
    • END: Move focus to the last tab. Activate focused tab after a short delay.
    • +
    • SPACE: Activate panel associated with focused tab.
    • +
    • ENTER: Activate or toggle panel associated with focused tab.
    • +
    • ALT+PAGE UP: Move focus to the previous tab and immediately activate.
    • +
    • ALT+PAGE DOWN: Move focus to the next tab and immediately activate.
    • +
    + +

    When focus is in a panel, the following key commands are available:

    +
      +
    • CTRL+UP: Move focus to associated tab.
    • +
    • ALT+PAGE UP: Move focus to the previous tab and immediately activate.
    • +
    • ALT+PAGE DOWN: Move focus to the next tab and immediately activate.
    • +
    +
    +

    Additional Notes:

    +
    • + This widget requires some functional CSS, otherwise it won't work. If you build a custom theme, use the widget's specific CSS file as a starting point. +
    +

    Example:

    +

    A simple jQuery UI Tabs

    +
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    <!doctype html>
    <html lang="en">
    <head>
        <meta charset="utf-8">
        <title>tabs demo</title>
        <link rel="stylesheet" href="http://code.jquery.com/ui/1.9.0/themes/base/jquery-ui.css">
        <script src="http://code.jquery.com/jquery-1.8.2.js"></script>
        <script src="http://code.jquery.com/ui/1.9.0/jquery-ui.js"></script>
    </head>
    <body>
     
    <div id="tabs">
        <ul>
            <li><a href="#fragment-1"><span>One</span></a></li>
            <li><a href="#fragment-2"><span>Two</span></a></li>
            <li><a href="#fragment-3"><span>Three</span></a></li>
        </ul>
        <div id="fragment-1">
            <p>First tab is active by default:</p>
            <pre><code>$( "#tabs" ).tabs(); </code></pre>
        </div>
        <div id="fragment-2">
            Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat.
            Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat.
        </div>
        <div id="fragment-3">
            Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat.
            Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat.
            Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat.
        </div>
    </div>
     
    <script>
    $( "#tabs" ).tabs();
    </script>
     
    </body>
    </html>
    +

    Demo:

    +
    +
    +
    + + + diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/docs/tooltip.html b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/docs/tooltip.html new file mode 100755 index 000000000..f1ecf2daf --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/docs/tooltip.html @@ -0,0 +1,378 @@ + + + + + jQuery UI tooltip documentation + + + + + +

    QuickNav

    + +
    +

    Events

    + + + +

    +Tooltip Widgetversion added: 1.9 +

    +
    +

    Description: Customizable, themeable tooltips, replacing native tooltips.

    +

    Options

    +

    contentType: Function() or String +

    +
    +Default: function returning the title attribute +
    +
    +

    The content of the tooltip.

    + +

    When changing this option, you likely need to also change the items option.

    +
    +Multiple types supported:
      +
    • +Function: A callback which can either return the content directly, or call the first argument, passing in the content, e.g., for Ajax content.
    • +
    • +String: A string of HTML to use for the tooltip content.
    • +
    +
    +
    +

    disabledType: Boolean +

    +
    +Default: false +
    +
    Disables the tooltip if set to true.
    +
    +
    +

    hideType: Boolean or Number or String or Object +

    +
    +Default: null +
    +
    If and how to animate the hiding of the tooltip.
    +Multiple types supported:
      +
    • +Boolean: + When set to false, no animation will be used and the tooltip will be hidden immediately. + When set to true, the tooltip will fade out with the default duration and the default easing. +
    • +
    • +Number: + The tooltip will fade out with the specified duration and the default easing. +
    • +
    • +String: + The tooltip will be hidden using the specified effect. + The value can either be the name of a built-in jQuery animateion method, such as "slideUp", or the name of a jQuery UI effect, such as "fold". + In either case the effect will be used with the default duration and the default easing. +
    • +
    • +Object: If the value is an object, then effect, duration, and easing properties may be provided. If the effect property contains the name of a jQuery method, then that method will be used; otherwise it is assumed to be the name of a jQuery UI effect. When using a jQuery UI effect that supports additional settings, you may include those settings in the object and they will be passed to the effect. If duration or easing is omitted, then the default values will be used. If effect is omitted, then "fadeOut" will be used.
    • +
    +
    +
    +

    itemsType: Selector +

    +
    +Default: [title] +
    +
    +

    A selector indicating which items should show tooltips. Customize if you're using something other then the title attribute for the tooltip content, or if you need a different selector for event delegation.

    + +

    When changing this option, you likely need to also change the content option.

    +
    +
    +
    +

    positionType: Object +

    +
    +Default: { my: "left+15 center", at: "right center", collision: "flipfit" } +
    +
    Configuration for the Position utility. The of property defaults to the target element, but can also be overriden.
    +
    +
    +

    showType: Boolean or Number or String or Object +

    +
    +Default: null +
    +
    If and how to animate the showing of the tooltip.
    +Multiple types supported:
      +
    • +Boolean: + When set to false, no animation will be used and the tooltip will be shown immediately. + When set to true, the tooltip will fade in with the default duration and the default easing. +
    • +
    • +Number: + The tooltip will fade in with the specified duration and the default easing. +
    • +
    • +String: + The tooltip will be shown using the specified effect. + The value can either be the name of a built-in jQuery animateion method, such as "slideDown", or the name of a jQuery UI effect, such as "fold". + In either case the effect will be used with the default duration and the default easing. +
    • +
    • +Object: If the value is an object, then effect, duration, and easing properties may be provided. If the effect property contains the name of a jQuery method, then that method will be used; otherwise it is assumed to be the name of a jQuery UI effect. When using a jQuery UI effect that supports additional settings, you may include those settings in the object and they will be passed to the effect. If duration or easing is omitted, then the default values will be used. If effect is omitted, then "fadeIn" will be used.
    • +
    +
    +
    +

    tooltipClassType: String +

    +
    +Default: null +
    +
    + A class to add to the widget, can be used to display various tooltip types, like warnings or errors. +

    This may get replaced by the classes option.

    +
    +
    +
    +

    trackType: Boolean +

    +
    +Default: false +
    +
    + Whether the tooltip should track (follow) the mouse. +
    +

    Methods

    +

    close( [event ] )

    +
    + Closes a tooltip. If the widget's element is the target, the event argument is optional. Otherwise you have to pass an event object with the currentTarget property pointing at the target. +
    +
    • +
      event
      +
      Type: Event +
      +
      What triggered the tooltip to close.
      +
    +
    +
    +

    destroy()

    +
    + Removes the tooltip functionality completely. This will return the element back to its pre-init state. +
    +
    +
    +

    disable()

    +
    + Disables the tooltip. +
    +
    +
    +

    enable()

    +
    + Enables the tooltip. +
    +
    +
    +

    open( [event ] )

    +
    + Programmatically open a tooltip. If the widget's element is the target, the event argument is optional. Otherwise you have to pass an event object with the currentTarget property pointing at the target. +
    +
    • +
      event
      +
      Type: Event +
      +
      What triggered the tooltip to open.
      +
    +
    +
    +
    +

    option( optionName ) Returns: Object +

    +
    Gets the value currently associated with the specified optionName.
    +
    • +
      optionName
      +
      Type: String +
      +
      The name of the option to get.
      +
    +
    +
    +

    option() Returns: PlainObject +

    +
    Gets an object containing key/value pairs representing the current tooltip options hash.
    +
    +
    +

    option( optionName, value )

    +
    Sets the value of the tooltip option associated with the specified optionName.
    +
      +
    • +
      optionName
      +
      Type: String +
      +
      The name of the option to set.
      +
    • +
    • +
      value
      +
      Type: Object +
      +
      A value to set for the option.
      +
    • +
    +
    +
    +

    option( options )

    +
    Sets one or more options for the tooltip.
    +
    • +
      options
      +
      Type: Object +
      +
      A map of option-value pairs to set.
      +
    +
    +
    +
    +

    widget() Returns: jQuery +

    +
    + Returns a jQuery object containing the original element. +
    +

    Events

    +

    close( event, ui )

    +
    + Triggered when a tooltip is closed, triggered on focusout or mouseleave. +
    +
      +
    • +
      event
      +
      Type: Event +
      +
      +
    • +
    • +
      ui
      +
      Type: Object +
      +
      +
      • +
        tooltip
        +
        Type: jQuery +
        +
        The generated tooltip element.
        +
      +
    • +
    +
    +
    +

    create( event, ui )

    +
    + Triggered when the tooltip is created. +
    +
      +
    • +
      event
      +
      Type: Event +
      +
      +
    • +
    • +
      ui
      +
      Type: Object +
      +
      +
    • +
    +
    +
    +

    open( event, ui )

    +
    + Triggered when a tooltip is shown, triggered on focusin or mouseover. +
    +
      +
    • +
      event
      +
      Type: Event +
      +
      +
    • +
    • +
      ui
      +
      Type: Object +
      +
      +
      • +
        tooltip
        +
        Type: jQuery +
        +
        The generated tooltip element.
        +
      +
    • +
    +
    +

    Tooltip replaces native tooltips, making them themable as well as allowing various customizations:

    + +
      +
    • Display other content than just the title, like inline footnotes or extra content retrieved via Ajax.
    • +
    • Customize the positioning, e.g., to center the tooltip above elements.
    • +
    • Add extra styling to customize the appearance, for warning or error fields.
    • +
    + +

    A fade animation is used by default to show and hide the tooltip, making the appearance a bit more organic, compared to just toggling the visiblity. This can be customized with the show and hide options.

    + +

    The items and content options need to stay in-sync. If you change one of them, you need to change the other.

    +
    +

    Additional Notes:

    +
    • + This widget requires some functional CSS, otherwise it won't work. If you build a custom theme, use the widget's specific CSS file as a starting point. +
    +

    Examples:

    +

    Example: Create a tooltip on the document, using event delegation for all elements with a title attribute. +

    +
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    <!doctype html>
    <html lang="en">
    <head>
        <meta charset="utf-8">
        <title>tooltip demo</title>
        <link rel="stylesheet" href="http://code.jquery.com/ui/1.9.0/themes/base/jquery-ui.css">
        <script src="http://code.jquery.com/jquery-1.8.2.js"></script>
        <script src="http://code.jquery.com/ui/1.9.0/jquery-ui.js"></script>
    </head>
    <body>
     
    <p>
        <a href="#" title="Anchor description">Anchor text</a>
        <input title="Input help">
    </p>
    <script>
        $( document ).tooltip();
    </script>
     
    </body>
    </html>
    +

    Demo:

    +
    +
    +
    +

    Example: Create a tooltip on the paragraph element, matching all images with an alt attribute. Use the alt attribute as the tooltip's content for each image. +

    +
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    <!doctype html>
    <html lang="en">
    <head>
        <meta charset="utf-8">
        <title>tooltip demo</title>
        <link rel="stylesheet" href="http://code.jquery.com/ui/1.9.0/themes/base/jquery-ui.css">
        <script src="http://code.jquery.com/jquery-1.8.2.js"></script>
        <script src="http://code.jquery.com/ui/1.9.0/jquery-ui.js"></script>
    </head>
    <body>
     
    <p>
        <img src="/resources/images/st-stephens.jpg" alt="St. Stephen's Cathedral">
        <img src="/resources/images/tower-bridge.jpg" alt="Tower Bridge">
    </p>
     
    <script>
    $( "p" ).tooltip({
        items: "img[alt]",
        content: function() {
            return $( this ).attr( "alt" );
        }
    });
    </script>
     
    </body>
    </html>
    +

    Demo:

    +
    +
    +
    + + + diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/docs/transfer-effect.html b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/docs/transfer-effect.html new file mode 100755 index 000000000..8d2cf4a39 --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/docs/transfer-effect.html @@ -0,0 +1,61 @@ + + + + + jQuery UI transfer-effect documentation + + + + + +

    Transfer Effect

    +
    +

    Description: Transfers the outline of an element to another element

    +
    • +

      transfer

      +
        +
      • +
        className
        +
        Type: String +
        +
        argumental class name the transfer element will receive.
        +
      • +
      • +
        to
        +
        Type: String +
        +
        jQuery selector, the element to transfer to.
        +
      • +
      +
    +
    +

    Very useful when trying to visualize interaction between two elements.

    +

    The transfer element iself has the class ui-effects-transfer, and needs to be styled by you, for example by adding a background or border.

    +
    +

    Example:

    +

    Clicking on the green element transfers to the other.

    +
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    <!doctype html>
    <html lang="en">
    <head>
        <meta charset="utf-8">
        <title>transfer demo</title>
        <link rel="stylesheet" href="http://code.jquery.com/ui/1.9.0/themes/base/jquery-ui.css">
        <style>
        div.green {
            width: 100px;
            height: 80px;
            background: green;
            border: 1px solid black;
            position: relative;
        }
        div.red {
            margin-top: 10px;
            width: 50px;
            height: 30px;
            background: red;
            border: 1px solid black;
            position: relative;
        }
        .ui-effects-transfer {
            border: 1px dotted black;
        }
        </style>
        <script src="http://code.jquery.com/jquery-1.8.2.js"></script>
        <script src="http://code.jquery.com/ui/1.9.0/jquery-ui.js"></script>
    </head>
    <body>
     
    <div class="green"></div>
    <div class="red"></div>
     
    <script>
    $( "div" ).click(function() {
        var i = 1 - $( "div" ).index( this );
        $( this ).effect( "transfer", { to: $( "div" ).eq( i ) }, 1000 );
    });
    </script>
     
    </body>
    </html>
    +

    Demo:

    +
    +
    +
    + + + diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/external/globalize.culture.de-DE.js b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/external/globalize.culture.de-DE.js new file mode 100755 index 000000000..5466bd75e --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/external/globalize.culture.de-DE.js @@ -0,0 +1,81 @@ +/* + * Globalize Culture de-DE + * + * http://github.com/jquery/globalize + * + * Copyright Software Freedom Conservancy, Inc. + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * This file was generated by the Globalize Culture Generator + * Translation: bugs found in this file need to be fixed in the generator + */ + +(function( window, undefined ) { + +var Globalize; + +if ( typeof require !== "undefined" + && typeof exports !== "undefined" + && typeof module !== "undefined" ) { + // Assume CommonJS + Globalize = require( "globalize" ); +} else { + // Global variable + Globalize = window.Globalize; +} + +Globalize.addCultureInfo( "de-DE", "default", { + name: "de-DE", + englishName: "German (Germany)", + nativeName: "Deutsch (Deutschland)", + language: "de", + numberFormat: { + ",": ".", + ".": ",", + NaN: "n. def.", + negativeInfinity: "-unendlich", + positiveInfinity: "+unendlich", + percent: { + pattern: ["-n%","n%"], + ",": ".", + ".": "," + }, + currency: { + pattern: ["-n $","n $"], + ",": ".", + ".": ",", + symbol: "€" + } + }, + calendars: { + standard: { + "/": ".", + firstDay: 1, + days: { + names: ["Sonntag","Montag","Dienstag","Mittwoch","Donnerstag","Freitag","Samstag"], + namesAbbr: ["So","Mo","Di","Mi","Do","Fr","Sa"], + namesShort: ["So","Mo","Di","Mi","Do","Fr","Sa"] + }, + months: { + names: ["Januar","Februar","März","April","Mai","Juni","Juli","August","September","Oktober","November","Dezember",""], + namesAbbr: ["Jan","Feb","Mrz","Apr","Mai","Jun","Jul","Aug","Sep","Okt","Nov","Dez",""] + }, + AM: null, + PM: null, + eras: [{"name":"n. Chr.","start":null,"offset":0}], + patterns: { + d: "dd.MM.yyyy", + D: "dddd, d. MMMM yyyy", + t: "HH:mm", + T: "HH:mm:ss", + f: "dddd, d. MMMM yyyy HH:mm", + F: "dddd, d. MMMM yyyy HH:mm:ss", + M: "dd MMMM", + Y: "MMMM yyyy" + } + } + } +}); + +}( this )); diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/external/globalize.culture.ja-JP.js b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/external/globalize.culture.ja-JP.js new file mode 100755 index 000000000..a9469d709 --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/external/globalize.culture.ja-JP.js @@ -0,0 +1,100 @@ +/* + * Globalize Culture ja-JP + * + * http://github.com/jquery/globalize + * + * Copyright Software Freedom Conservancy, Inc. + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * This file was generated by the Globalize Culture Generator + * Translation: bugs found in this file need to be fixed in the generator + */ + +(function( window, undefined ) { + +var Globalize; + +if ( typeof require !== "undefined" + && typeof exports !== "undefined" + && typeof module !== "undefined" ) { + // Assume CommonJS + Globalize = require( "globalize" ); +} else { + // Global variable + Globalize = window.Globalize; +} + +Globalize.addCultureInfo( "ja-JP", "default", { + name: "ja-JP", + englishName: "Japanese (Japan)", + nativeName: "日本語 (日本)", + language: "ja", + numberFormat: { + NaN: "NaN (非数値)", + negativeInfinity: "-∞", + positiveInfinity: "+∞", + percent: { + pattern: ["-n%","n%"] + }, + currency: { + pattern: ["-$n","$n"], + decimals: 0, + symbol: "¥" + } + }, + calendars: { + standard: { + days: { + names: ["日曜日","月曜日","火曜日","水曜日","木曜日","金曜日","土曜日"], + namesAbbr: ["日","月","火","水","木","金","土"], + namesShort: ["日","月","火","水","木","金","土"] + }, + months: { + names: ["1月","2月","3月","4月","5月","6月","7月","8月","9月","10月","11月","12月",""], + namesAbbr: ["1","2","3","4","5","6","7","8","9","10","11","12",""] + }, + AM: ["午前","午前","午前"], + PM: ["午後","午後","午後"], + eras: [{"name":"西暦","start":null,"offset":0}], + patterns: { + d: "yyyy/MM/dd", + D: "yyyy'年'M'月'd'日'", + t: "H:mm", + T: "H:mm:ss", + f: "yyyy'年'M'月'd'日' H:mm", + F: "yyyy'年'M'月'd'日' H:mm:ss", + M: "M'月'd'日'", + Y: "yyyy'年'M'月'" + } + }, + Japanese: { + name: "Japanese", + days: { + names: ["日曜日","月曜日","火曜日","水曜日","木曜日","金曜日","土曜日"], + namesAbbr: ["日","月","火","水","木","金","土"], + namesShort: ["日","月","火","水","木","金","土"] + }, + months: { + names: ["1月","2月","3月","4月","5月","6月","7月","8月","9月","10月","11月","12月",""], + namesAbbr: ["1","2","3","4","5","6","7","8","9","10","11","12",""] + }, + AM: ["午前","午前","午前"], + PM: ["午後","午後","午後"], + eras: [{"name":"平成","start":null,"offset":1867},{"name":"昭和","start":-1812153600000,"offset":1911},{"name":"大正","start":-1357603200000,"offset":1925},{"name":"明治","start":60022080000,"offset":1988}], + twoDigitYearMax: 99, + patterns: { + d: "gg y/M/d", + D: "gg y'年'M'月'd'日'", + t: "H:mm", + T: "H:mm:ss", + f: "gg y'年'M'月'd'日' H:mm", + F: "gg y'年'M'月'd'日' H:mm:ss", + M: "M'月'd'日'", + Y: "gg y'年'M'月'" + } + } + } +}); + +}( this )); diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/external/globalize.js b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/external/globalize.js new file mode 100755 index 000000000..ebaca1748 --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/external/globalize.js @@ -0,0 +1,1573 @@ +/*! + * Globalize + * + * http://github.com/jquery/globalize + * + * Copyright Software Freedom Conservancy, Inc. + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + */ + +(function( window, undefined ) { + +var Globalize, + // private variables + regexHex, + regexInfinity, + regexParseFloat, + regexTrim, + // private JavaScript utility functions + arrayIndexOf, + endsWith, + extend, + isArray, + isFunction, + isObject, + startsWith, + trim, + truncate, + zeroPad, + // private Globalization utility functions + appendPreOrPostMatch, + expandFormat, + formatDate, + formatNumber, + getTokenRegExp, + getEra, + getEraYear, + parseExact, + parseNegativePattern; + +// Global variable (Globalize) or CommonJS module (globalize) +Globalize = function( cultureSelector ) { + return new Globalize.prototype.init( cultureSelector ); +}; + +if ( typeof require !== "undefined" + && typeof exports !== "undefined" + && typeof module !== "undefined" ) { + // Assume CommonJS + module.exports = Globalize; +} else { + // Export as global variable + window.Globalize = Globalize; +} + +Globalize.cultures = {}; + +Globalize.prototype = { + constructor: Globalize, + init: function( cultureSelector ) { + this.cultures = Globalize.cultures; + this.cultureSelector = cultureSelector; + + return this; + } +}; +Globalize.prototype.init.prototype = Globalize.prototype; + +// 1. When defining a culture, all fields are required except the ones stated as optional. +// 2. Each culture should have a ".calendars" object with at least one calendar named "standard" +// which serves as the default calendar in use by that culture. +// 3. Each culture should have a ".calendar" object which is the current calendar being used, +// it may be dynamically changed at any time to one of the calendars in ".calendars". +Globalize.cultures[ "default" ] = { + // A unique name for the culture in the form - + name: "en", + // the name of the culture in the english language + englishName: "English", + // the name of the culture in its own language + nativeName: "English", + // whether the culture uses right-to-left text + isRTL: false, + // "language" is used for so-called "specific" cultures. + // For example, the culture "es-CL" means "Spanish, in Chili". + // It represents the Spanish-speaking culture as it is in Chili, + // which might have different formatting rules or even translations + // than Spanish in Spain. A "neutral" culture is one that is not + // specific to a region. For example, the culture "es" is the generic + // Spanish culture, which may be a more generalized version of the language + // that may or may not be what a specific culture expects. + // For a specific culture like "es-CL", the "language" field refers to the + // neutral, generic culture information for the language it is using. + // This is not always a simple matter of the string before the dash. + // For example, the "zh-Hans" culture is netural (Simplified Chinese). + // And the "zh-SG" culture is Simplified Chinese in Singapore, whose lanugage + // field is "zh-CHS", not "zh". + // This field should be used to navigate from a specific culture to it's + // more general, neutral culture. If a culture is already as general as it + // can get, the language may refer to itself. + language: "en", + // numberFormat defines general number formatting rules, like the digits in + // each grouping, the group separator, and how negative numbers are displayed. + numberFormat: { + // [negativePattern] + // Note, numberFormat.pattern has no "positivePattern" unlike percent and currency, + // but is still defined as an array for consistency with them. + // negativePattern: one of "(n)|-n|- n|n-|n -" + pattern: [ "-n" ], + // number of decimal places normally shown + decimals: 2, + // string that separates number groups, as in 1,000,000 + ",": ",", + // string that separates a number from the fractional portion, as in 1.99 + ".": ".", + // array of numbers indicating the size of each number group. + // TODO: more detailed description and example + groupSizes: [ 3 ], + // symbol used for positive numbers + "+": "+", + // symbol used for negative numbers + "-": "-", + // symbol used for NaN (Not-A-Number) + NaN: "NaN", + // symbol used for Negative Infinity + negativeInfinity: "-Infinity", + // symbol used for Positive Infinity + positiveInfinity: "Infinity", + percent: { + // [negativePattern, positivePattern] + // negativePattern: one of "-n %|-n%|-%n|%-n|%n-|n-%|n%-|-% n|n %-|% n-|% -n|n- %" + // positivePattern: one of "n %|n%|%n|% n" + pattern: [ "-n %", "n %" ], + // number of decimal places normally shown + decimals: 2, + // array of numbers indicating the size of each number group. + // TODO: more detailed description and example + groupSizes: [ 3 ], + // string that separates number groups, as in 1,000,000 + ",": ",", + // string that separates a number from the fractional portion, as in 1.99 + ".": ".", + // symbol used to represent a percentage + symbol: "%" + }, + currency: { + // [negativePattern, positivePattern] + // negativePattern: one of "($n)|-$n|$-n|$n-|(n$)|-n$|n-$|n$-|-n $|-$ n|n $-|$ n-|$ -n|n- $|($ n)|(n $)" + // positivePattern: one of "$n|n$|$ n|n $" + pattern: [ "($n)", "$n" ], + // number of decimal places normally shown + decimals: 2, + // array of numbers indicating the size of each number group. + // TODO: more detailed description and example + groupSizes: [ 3 ], + // string that separates number groups, as in 1,000,000 + ",": ",", + // string that separates a number from the fractional portion, as in 1.99 + ".": ".", + // symbol used to represent currency + symbol: "$" + } + }, + // calendars defines all the possible calendars used by this culture. + // There should be at least one defined with name "standard", and is the default + // calendar used by the culture. + // A calendar contains information about how dates are formatted, information about + // the calendar's eras, a standard set of the date formats, + // translations for day and month names, and if the calendar is not based on the Gregorian + // calendar, conversion functions to and from the Gregorian calendar. + calendars: { + standard: { + // name that identifies the type of calendar this is + name: "Gregorian_USEnglish", + // separator of parts of a date (e.g. "/" in 11/05/1955) + "/": "/", + // separator of parts of a time (e.g. ":" in 05:44 PM) + ":": ":", + // the first day of the week (0 = Sunday, 1 = Monday, etc) + firstDay: 0, + days: { + // full day names + names: [ "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday" ], + // abbreviated day names + namesAbbr: [ "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" ], + // shortest day names + namesShort: [ "Su", "Mo", "Tu", "We", "Th", "Fr", "Sa" ] + }, + months: { + // full month names (13 months for lunar calendards -- 13th month should be "" if not lunar) + names: [ "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December", "" ], + // abbreviated month names + namesAbbr: [ "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec", "" ] + }, + // AM and PM designators in one of these forms: + // The usual view, and the upper and lower case versions + // [ standard, lowercase, uppercase ] + // The culture does not use AM or PM (likely all standard date formats use 24 hour time) + // null + AM: [ "AM", "am", "AM" ], + PM: [ "PM", "pm", "PM" ], + eras: [ + // eras in reverse chronological order. + // name: the name of the era in this culture (e.g. A.D., C.E.) + // start: when the era starts in ticks (gregorian, gmt), null if it is the earliest supported era. + // offset: offset in years from gregorian calendar + { + "name": "A.D.", + "start": null, + "offset": 0 + } + ], + // when a two digit year is given, it will never be parsed as a four digit + // year greater than this year (in the appropriate era for the culture) + // Set it as a full year (e.g. 2029) or use an offset format starting from + // the current year: "+19" would correspond to 2029 if the current year 2010. + twoDigitYearMax: 2029, + // set of predefined date and time patterns used by the culture + // these represent the format someone in this culture would expect + // to see given the portions of the date that are shown. + patterns: { + // short date pattern + d: "M/d/yyyy", + // long date pattern + D: "dddd, MMMM dd, yyyy", + // short time pattern + t: "h:mm tt", + // long time pattern + T: "h:mm:ss tt", + // long date, short time pattern + f: "dddd, MMMM dd, yyyy h:mm tt", + // long date, long time pattern + F: "dddd, MMMM dd, yyyy h:mm:ss tt", + // month/day pattern + M: "MMMM dd", + // month/year pattern + Y: "yyyy MMMM", + // S is a sortable format that does not vary by culture + S: "yyyy\u0027-\u0027MM\u0027-\u0027dd\u0027T\u0027HH\u0027:\u0027mm\u0027:\u0027ss" + } + // optional fields for each calendar: + /* + monthsGenitive: + Same as months but used when the day preceeds the month. + Omit if the culture has no genitive distinction in month names. + For an explaination of genitive months, see http://blogs.msdn.com/michkap/archive/2004/12/25/332259.aspx + convert: + Allows for the support of non-gregorian based calendars. This convert object is used to + to convert a date to and from a gregorian calendar date to handle parsing and formatting. + The two functions: + fromGregorian( date ) + Given the date as a parameter, return an array with parts [ year, month, day ] + corresponding to the non-gregorian based year, month, and day for the calendar. + toGregorian( year, month, day ) + Given the non-gregorian year, month, and day, return a new Date() object + set to the corresponding date in the gregorian calendar. + */ + } + }, + // For localized strings + messages: {} +}; + +Globalize.cultures[ "default" ].calendar = Globalize.cultures[ "default" ].calendars.standard; + +Globalize.cultures[ "en" ] = Globalize.cultures[ "default" ]; + +Globalize.cultureSelector = "en"; + +// +// private variables +// + +regexHex = /^0x[a-f0-9]+$/i; +regexInfinity = /^[+-]?infinity$/i; +regexParseFloat = /^[+-]?\d*\.?\d*(e[+-]?\d+)?$/; +regexTrim = /^\s+|\s+$/g; + +// +// private JavaScript utility functions +// + +arrayIndexOf = function( array, item ) { + if ( array.indexOf ) { + return array.indexOf( item ); + } + for ( var i = 0, length = array.length; i < length; i++ ) { + if ( array[i] === item ) { + return i; + } + } + return -1; +}; + +endsWith = function( value, pattern ) { + return value.substr( value.length - pattern.length ) === pattern; +}; + +extend = function( deep ) { + 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" && !isFunction(target) ) { + target = {}; + } + + 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 && ( isObject(copy) || (copyIsArray = isArray(copy)) ) ) { + if ( copyIsArray ) { + copyIsArray = false; + clone = src && isArray(src) ? src : []; + + } else { + clone = src && isObject(src) ? src : {}; + } + + // Never move original objects, clone them + target[ name ] = extend( deep, clone, copy ); + + // Don't bring in undefined values + } else if ( copy !== undefined ) { + target[ name ] = copy; + } + } + } + } + + // Return the modified object + return target; +}; + +isArray = Array.isArray || function( obj ) { + return Object.prototype.toString.call( obj ) === "[object Array]"; +}; + +isFunction = function( obj ) { + return Object.prototype.toString.call( obj ) === "[object Function]" +} + +isObject = function( obj ) { + return Object.prototype.toString.call( obj ) === "[object Object]"; +}; + +startsWith = function( value, pattern ) { + return value.indexOf( pattern ) === 0; +}; + +trim = function( value ) { + return ( value + "" ).replace( regexTrim, "" ); +}; + +truncate = function( value ) { + return value | 0; +}; + +zeroPad = function( str, count, left ) { + var l; + for ( l = str.length; l < count; l += 1 ) { + str = ( left ? ("0" + str) : (str + "0") ); + } + return str; +}; + +// +// private Globalization utility functions +// + +appendPreOrPostMatch = function( preMatch, strings ) { + // appends pre- and post- token match strings while removing escaped characters. + // Returns a single quote count which is used to determine if the token occurs + // in a string literal. + var quoteCount = 0, + escaped = false; + for ( var i = 0, il = preMatch.length; i < il; i++ ) { + var c = preMatch.charAt( i ); + switch ( c ) { + case "\'": + if ( escaped ) { + strings.push( "\'" ); + } + else { + quoteCount++; + } + escaped = false; + break; + case "\\": + if ( escaped ) { + strings.push( "\\" ); + } + escaped = !escaped; + break; + default: + strings.push( c ); + escaped = false; + break; + } + } + return quoteCount; +}; + +expandFormat = function( cal, format ) { + // expands unspecified or single character date formats into the full pattern. + format = format || "F"; + var pattern, + patterns = cal.patterns, + len = format.length; + if ( len === 1 ) { + pattern = patterns[ format ]; + if ( !pattern ) { + throw "Invalid date format string \'" + format + "\'."; + } + format = pattern; + } + else if ( len === 2 && format.charAt(0) === "%" ) { + // %X escape format -- intended as a custom format string that is only one character, not a built-in format. + format = format.charAt( 1 ); + } + return format; +}; + +formatDate = function( value, format, culture ) { + var cal = culture.calendar, + convert = cal.convert; + + if ( !format || !format.length || format === "i" ) { + var ret; + if ( culture && culture.name.length ) { + if ( convert ) { + // non-gregorian calendar, so we cannot use built-in toLocaleString() + ret = formatDate( value, cal.patterns.F, culture ); + } + else { + var eraDate = new Date( value.getTime() ), + era = getEra( value, cal.eras ); + eraDate.setFullYear( getEraYear(value, cal, era) ); + ret = eraDate.toLocaleString(); + } + } + else { + ret = value.toString(); + } + return ret; + } + + var eras = cal.eras, + sortable = format === "s"; + format = expandFormat( cal, format ); + + // Start with an empty string + ret = []; + var hour, + zeros = [ "0", "00", "000" ], + foundDay, + checkedDay, + dayPartRegExp = /([^d]|^)(d|dd)([^d]|$)/g, + quoteCount = 0, + tokenRegExp = getTokenRegExp(), + converted; + + function padZeros( num, c ) { + var r, s = num + ""; + if ( c > 1 && s.length < c ) { + r = ( zeros[c - 2] + s); + return r.substr( r.length - c, c ); + } + else { + r = s; + } + return r; + } + + function hasDay() { + if ( foundDay || checkedDay ) { + return foundDay; + } + foundDay = dayPartRegExp.test( format ); + checkedDay = true; + return foundDay; + } + + function getPart( date, part ) { + if ( converted ) { + return converted[ part ]; + } + switch ( part ) { + case 0: return date.getFullYear(); + case 1: return date.getMonth(); + case 2: return date.getDate(); + } + } + + if ( !sortable && convert ) { + converted = convert.fromGregorian( value ); + } + + for ( ; ; ) { + // Save the current index + var index = tokenRegExp.lastIndex, + // Look for the next pattern + ar = tokenRegExp.exec( format ); + + // Append the text before the pattern (or the end of the string if not found) + var preMatch = format.slice( index, ar ? ar.index : format.length ); + quoteCount += appendPreOrPostMatch( preMatch, ret ); + + if ( !ar ) { + break; + } + + // do not replace any matches that occur inside a string literal. + if ( quoteCount % 2 ) { + ret.push( ar[0] ); + continue; + } + + var current = ar[ 0 ], + clength = current.length; + + switch ( current ) { + case "ddd": + //Day of the week, as a three-letter abbreviation + case "dddd": + // Day of the week, using the full name + var names = ( clength === 3 ) ? cal.days.namesAbbr : cal.days.names; + ret.push( names[value.getDay()] ); + break; + case "d": + // Day of month, without leading zero for single-digit days + case "dd": + // Day of month, with leading zero for single-digit days + foundDay = true; + ret.push( + padZeros( getPart(value, 2), clength ) + ); + break; + case "MMM": + // Month, as a three-letter abbreviation + case "MMMM": + // Month, using the full name + var part = getPart( value, 1 ); + ret.push( + ( cal.monthsGenitive && hasDay() ) + ? + cal.monthsGenitive[ clength === 3 ? "namesAbbr" : "names" ][ part ] + : + cal.months[ clength === 3 ? "namesAbbr" : "names" ][ part ] + ); + break; + case "M": + // Month, as digits, with no leading zero for single-digit months + case "MM": + // Month, as digits, with leading zero for single-digit months + ret.push( + padZeros( getPart(value, 1) + 1, clength ) + ); + break; + case "y": + // Year, as two digits, but with no leading zero for years less than 10 + case "yy": + // Year, as two digits, with leading zero for years less than 10 + case "yyyy": + // Year represented by four full digits + part = converted ? converted[ 0 ] : getEraYear( value, cal, getEra(value, eras), sortable ); + if ( clength < 4 ) { + part = part % 100; + } + ret.push( + padZeros( part, clength ) + ); + break; + case "h": + // Hours with no leading zero for single-digit hours, using 12-hour clock + case "hh": + // Hours with leading zero for single-digit hours, using 12-hour clock + hour = value.getHours() % 12; + if ( hour === 0 ) hour = 12; + ret.push( + padZeros( hour, clength ) + ); + break; + case "H": + // Hours with no leading zero for single-digit hours, using 24-hour clock + case "HH": + // Hours with leading zero for single-digit hours, using 24-hour clock + ret.push( + padZeros( value.getHours(), clength ) + ); + break; + case "m": + // Minutes with no leading zero for single-digit minutes + case "mm": + // Minutes with leading zero for single-digit minutes + ret.push( + padZeros( value.getMinutes(), clength ) + ); + break; + case "s": + // Seconds with no leading zero for single-digit seconds + case "ss": + // Seconds with leading zero for single-digit seconds + ret.push( + padZeros( value.getSeconds(), clength ) + ); + break; + case "t": + // One character am/pm indicator ("a" or "p") + case "tt": + // Multicharacter am/pm indicator + part = value.getHours() < 12 ? ( cal.AM ? cal.AM[0] : " " ) : ( cal.PM ? cal.PM[0] : " " ); + ret.push( clength === 1 ? part.charAt(0) : part ); + break; + case "f": + // Deciseconds + case "ff": + // Centiseconds + case "fff": + // Milliseconds + ret.push( + padZeros( value.getMilliseconds(), 3 ).substr( 0, clength ) + ); + break; + case "z": + // Time zone offset, no leading zero + case "zz": + // Time zone offset with leading zero + hour = value.getTimezoneOffset() / 60; + ret.push( + ( hour <= 0 ? "+" : "-" ) + padZeros( Math.floor(Math.abs(hour)), clength ) + ); + break; + case "zzz": + // Time zone offset with leading zero + hour = value.getTimezoneOffset() / 60; + ret.push( + ( hour <= 0 ? "+" : "-" ) + padZeros( Math.floor(Math.abs(hour)), 2 ) + // Hard coded ":" separator, rather than using cal.TimeSeparator + // Repeated here for consistency, plus ":" was already assumed in date parsing. + + ":" + padZeros( Math.abs(value.getTimezoneOffset() % 60), 2 ) + ); + break; + case "g": + case "gg": + if ( cal.eras ) { + ret.push( + cal.eras[ getEra(value, eras) ].name + ); + } + break; + case "/": + ret.push( cal["/"] ); + break; + default: + throw "Invalid date format pattern \'" + current + "\'."; + break; + } + } + return ret.join( "" ); +}; + +// formatNumber +(function() { + var expandNumber; + + expandNumber = function( number, precision, formatInfo ) { + var groupSizes = formatInfo.groupSizes, + curSize = groupSizes[ 0 ], + curGroupIndex = 1, + factor = Math.pow( 10, precision ), + rounded = Math.round( number * factor ) / factor; + + if ( !isFinite(rounded) ) { + rounded = number; + } + number = rounded; + + var numberString = number+"", + right = "", + split = numberString.split( /e/i ), + exponent = split.length > 1 ? parseInt( split[1], 10 ) : 0; + numberString = split[ 0 ]; + split = numberString.split( "." ); + numberString = split[ 0 ]; + right = split.length > 1 ? split[ 1 ] : ""; + + var l; + if ( exponent > 0 ) { + right = zeroPad( right, exponent, false ); + numberString += right.slice( 0, exponent ); + right = right.substr( exponent ); + } + else if ( exponent < 0 ) { + exponent = -exponent; + numberString = zeroPad( numberString, exponent + 1 ); + right = numberString.slice( -exponent, numberString.length ) + right; + numberString = numberString.slice( 0, -exponent ); + } + + if ( precision > 0 ) { + right = formatInfo[ "." ] + + ( (right.length > precision) ? right.slice(0, precision) : zeroPad(right, precision) ); + } + else { + right = ""; + } + + var stringIndex = numberString.length - 1, + sep = formatInfo[ "," ], + ret = ""; + + while ( stringIndex >= 0 ) { + if ( curSize === 0 || curSize > stringIndex ) { + return numberString.slice( 0, stringIndex + 1 ) + ( ret.length ? (sep + ret + right) : right ); + } + ret = numberString.slice( stringIndex - curSize + 1, stringIndex + 1 ) + ( ret.length ? (sep + ret) : "" ); + + stringIndex -= curSize; + + if ( curGroupIndex < groupSizes.length ) { + curSize = groupSizes[ curGroupIndex ]; + curGroupIndex++; + } + } + + return numberString.slice( 0, stringIndex + 1 ) + sep + ret + right; + }; + + formatNumber = function( value, format, culture ) { + if ( !isFinite(value) ) { + if ( value === Infinity ) { + return culture.numberFormat.positiveInfinity; + } + if ( value === -Infinity ) { + return culture.numberFormat.negativeInfinity; + } + return culture.numberFormat.NaN; + } + if ( !format || format === "i" ) { + return culture.name.length ? value.toLocaleString() : value.toString(); + } + format = format || "D"; + + var nf = culture.numberFormat, + number = Math.abs( value ), + precision = -1, + pattern; + if ( format.length > 1 ) precision = parseInt( format.slice(1), 10 ); + + var current = format.charAt( 0 ).toUpperCase(), + formatInfo; + + switch ( current ) { + case "D": + pattern = "n"; + number = truncate( number ); + if ( precision !== -1 ) { + number = zeroPad( "" + number, precision, true ); + } + if ( value < 0 ) number = "-" + number; + break; + case "N": + formatInfo = nf; + // fall through + case "C": + formatInfo = formatInfo || nf.currency; + // fall through + case "P": + formatInfo = formatInfo || nf.percent; + pattern = value < 0 ? formatInfo.pattern[ 0 ] : ( formatInfo.pattern[1] || "n" ); + if ( precision === -1 ) precision = formatInfo.decimals; + number = expandNumber( number * (current === "P" ? 100 : 1), precision, formatInfo ); + break; + default: + throw "Bad number format specifier: " + current; + } + + var patternParts = /n|\$|-|%/g, + ret = ""; + for ( ; ; ) { + var index = patternParts.lastIndex, + ar = patternParts.exec( pattern ); + + ret += pattern.slice( index, ar ? ar.index : pattern.length ); + + if ( !ar ) { + break; + } + + switch ( ar[0] ) { + case "n": + ret += number; + break; + case "$": + ret += nf.currency.symbol; + break; + case "-": + // don't make 0 negative + if ( /[1-9]/.test(number) ) { + ret += nf[ "-" ]; + } + break; + case "%": + ret += nf.percent.symbol; + break; + } + } + + return ret; + }; + +}()); + +getTokenRegExp = function() { + // regular expression for matching date and time tokens in format strings. + return /\/|dddd|ddd|dd|d|MMMM|MMM|MM|M|yyyy|yy|y|hh|h|HH|H|mm|m|ss|s|tt|t|fff|ff|f|zzz|zz|z|gg|g/g; +}; + +getEra = function( date, eras ) { + if ( !eras ) return 0; + var start, ticks = date.getTime(); + for ( var i = 0, l = eras.length; i < l; i++ ) { + start = eras[ i ].start; + if ( start === null || ticks >= start ) { + return i; + } + } + return 0; +}; + +getEraYear = function( date, cal, era, sortable ) { + var year = date.getFullYear(); + if ( !sortable && cal.eras ) { + // convert normal gregorian year to era-shifted gregorian + // year by subtracting the era offset + year -= cal.eras[ era ].offset; + } + return year; +}; + +// parseExact +(function() { + var expandYear, + getDayIndex, + getMonthIndex, + getParseRegExp, + outOfRange, + toUpper, + toUpperArray; + + expandYear = function( cal, year ) { + // expands 2-digit year into 4 digits. + var now = new Date(), + era = getEra( now ); + if ( year < 100 ) { + var twoDigitYearMax = cal.twoDigitYearMax; + twoDigitYearMax = typeof twoDigitYearMax === "string" ? new Date().getFullYear() % 100 + parseInt( twoDigitYearMax, 10 ) : twoDigitYearMax; + var curr = getEraYear( now, cal, era ); + year += curr - ( curr % 100 ); + if ( year > twoDigitYearMax ) { + year -= 100; + } + } + return year; + }; + + getDayIndex = function ( cal, value, abbr ) { + var ret, + days = cal.days, + upperDays = cal._upperDays; + if ( !upperDays ) { + cal._upperDays = upperDays = [ + toUpperArray( days.names ), + toUpperArray( days.namesAbbr ), + toUpperArray( days.namesShort ) + ]; + } + value = toUpper( value ); + if ( abbr ) { + ret = arrayIndexOf( upperDays[1], value ); + if ( ret === -1 ) { + ret = arrayIndexOf( upperDays[2], value ); + } + } + else { + ret = arrayIndexOf( upperDays[0], value ); + } + return ret; + }; + + getMonthIndex = function( cal, value, abbr ) { + var months = cal.months, + monthsGen = cal.monthsGenitive || cal.months, + upperMonths = cal._upperMonths, + upperMonthsGen = cal._upperMonthsGen; + if ( !upperMonths ) { + cal._upperMonths = upperMonths = [ + toUpperArray( months.names ), + toUpperArray( months.namesAbbr ) + ]; + cal._upperMonthsGen = upperMonthsGen = [ + toUpperArray( monthsGen.names ), + toUpperArray( monthsGen.namesAbbr ) + ]; + } + value = toUpper( value ); + var i = arrayIndexOf( abbr ? upperMonths[1] : upperMonths[0], value ); + if ( i < 0 ) { + i = arrayIndexOf( abbr ? upperMonthsGen[1] : upperMonthsGen[0], value ); + } + return i; + }; + + getParseRegExp = function( cal, format ) { + // converts a format string into a regular expression with groups that + // can be used to extract date fields from a date string. + // check for a cached parse regex. + var re = cal._parseRegExp; + if ( !re ) { + cal._parseRegExp = re = {}; + } + else { + var reFormat = re[ format ]; + if ( reFormat ) { + return reFormat; + } + } + + // expand single digit formats, then escape regular expression characters. + var expFormat = expandFormat( cal, format ).replace( /([\^\$\.\*\+\?\|\[\]\(\)\{\}])/g, "\\\\$1" ), + regexp = [ "^" ], + groups = [], + index = 0, + quoteCount = 0, + tokenRegExp = getTokenRegExp(), + match; + + // iterate through each date token found. + while ( (match = tokenRegExp.exec(expFormat)) !== null ) { + var preMatch = expFormat.slice( index, match.index ); + index = tokenRegExp.lastIndex; + + // don't replace any matches that occur inside a string literal. + quoteCount += appendPreOrPostMatch( preMatch, regexp ); + if ( quoteCount % 2 ) { + regexp.push( match[0] ); + continue; + } + + // add a regex group for the token. + var m = match[ 0 ], + len = m.length, + add; + switch ( m ) { + case "dddd": case "ddd": + case "MMMM": case "MMM": + case "gg": case "g": + add = "(\\D+)"; + break; + case "tt": case "t": + add = "(\\D*)"; + break; + case "yyyy": + case "fff": + case "ff": + case "f": + add = "(\\d{" + len + "})"; + break; + case "dd": case "d": + case "MM": case "M": + case "yy": case "y": + case "HH": case "H": + case "hh": case "h": + case "mm": case "m": + case "ss": case "s": + add = "(\\d\\d?)"; + break; + case "zzz": + add = "([+-]?\\d\\d?:\\d{2})"; + break; + case "zz": case "z": + add = "([+-]?\\d\\d?)"; + break; + case "/": + add = "(\\" + cal[ "/" ] + ")"; + break; + default: + throw "Invalid date format pattern \'" + m + "\'."; + break; + } + if ( add ) { + regexp.push( add ); + } + groups.push( match[0] ); + } + appendPreOrPostMatch( expFormat.slice(index), regexp ); + regexp.push( "$" ); + + // allow whitespace to differ when matching formats. + var regexpStr = regexp.join( "" ).replace( /\s+/g, "\\s+" ), + parseRegExp = { "regExp": regexpStr, "groups": groups }; + + // cache the regex for this format. + return re[ format ] = parseRegExp; + }; + + outOfRange = function( value, low, high ) { + return value < low || value > high; + }; + + toUpper = function( value ) { + // "he-IL" has non-breaking space in weekday names. + return value.split( "\u00A0" ).join( " " ).toUpperCase(); + }; + + toUpperArray = function( arr ) { + var results = []; + for ( var i = 0, l = arr.length; i < l; i++ ) { + results[ i ] = toUpper( arr[i] ); + } + return results; + }; + + parseExact = function( value, format, culture ) { + // try to parse the date string by matching against the format string + // while using the specified culture for date field names. + value = trim( value ); + var cal = culture.calendar, + // convert date formats into regular expressions with groupings. + // use the regexp to determine the input format and extract the date fields. + parseInfo = getParseRegExp( cal, format ), + match = new RegExp( parseInfo.regExp ).exec( value ); + if ( match === null ) { + return null; + } + // found a date format that matches the input. + var groups = parseInfo.groups, + era = null, year = null, month = null, date = null, weekDay = null, + hour = 0, hourOffset, min = 0, sec = 0, msec = 0, tzMinOffset = null, + pmHour = false; + // iterate the format groups to extract and set the date fields. + for ( var j = 0, jl = groups.length; j < jl; j++ ) { + var matchGroup = match[ j + 1 ]; + if ( matchGroup ) { + var current = groups[ j ], + clength = current.length, + matchInt = parseInt( matchGroup, 10 ); + switch ( current ) { + case "dd": case "d": + // Day of month. + date = matchInt; + // check that date is generally in valid range, also checking overflow below. + if ( outOfRange(date, 1, 31) ) return null; + break; + case "MMM": case "MMMM": + month = getMonthIndex( cal, matchGroup, clength === 3 ); + if ( outOfRange(month, 0, 11) ) return null; + break; + case "M": case "MM": + // Month. + month = matchInt - 1; + if ( outOfRange(month, 0, 11) ) return null; + break; + case "y": case "yy": + case "yyyy": + year = clength < 4 ? expandYear( cal, matchInt ) : matchInt; + if ( outOfRange(year, 0, 9999) ) return null; + break; + case "h": case "hh": + // Hours (12-hour clock). + hour = matchInt; + if ( hour === 12 ) hour = 0; + if ( outOfRange(hour, 0, 11) ) return null; + break; + case "H": case "HH": + // Hours (24-hour clock). + hour = matchInt; + if ( outOfRange(hour, 0, 23) ) return null; + break; + case "m": case "mm": + // Minutes. + min = matchInt; + if ( outOfRange(min, 0, 59) ) return null; + break; + case "s": case "ss": + // Seconds. + sec = matchInt; + if ( outOfRange(sec, 0, 59) ) return null; + break; + case "tt": case "t": + // AM/PM designator. + // see if it is standard, upper, or lower case PM. If not, ensure it is at least one of + // the AM tokens. If not, fail the parse for this format. + pmHour = cal.PM && ( matchGroup === cal.PM[0] || matchGroup === cal.PM[1] || matchGroup === cal.PM[2] ); + if ( + !pmHour && ( + !cal.AM || ( matchGroup !== cal.AM[0] && matchGroup !== cal.AM[1] && matchGroup !== cal.AM[2] ) + ) + ) return null; + break; + case "f": + // Deciseconds. + case "ff": + // Centiseconds. + case "fff": + // Milliseconds. + msec = matchInt * Math.pow( 10, 3 - clength ); + if ( outOfRange(msec, 0, 999) ) return null; + break; + case "ddd": + // Day of week. + case "dddd": + // Day of week. + weekDay = getDayIndex( cal, matchGroup, clength === 3 ); + if ( outOfRange(weekDay, 0, 6) ) return null; + break; + case "zzz": + // Time zone offset in +/- hours:min. + var offsets = matchGroup.split( /:/ ); + if ( offsets.length !== 2 ) return null; + hourOffset = parseInt( offsets[0], 10 ); + if ( outOfRange(hourOffset, -12, 13) ) return null; + var minOffset = parseInt( offsets[1], 10 ); + if ( outOfRange(minOffset, 0, 59) ) return null; + tzMinOffset = ( hourOffset * 60 ) + ( startsWith(matchGroup, "-") ? -minOffset : minOffset ); + break; + case "z": case "zz": + // Time zone offset in +/- hours. + hourOffset = matchInt; + if ( outOfRange(hourOffset, -12, 13) ) return null; + tzMinOffset = hourOffset * 60; + break; + case "g": case "gg": + var eraName = matchGroup; + if ( !eraName || !cal.eras ) return null; + eraName = trim( eraName.toLowerCase() ); + for ( var i = 0, l = cal.eras.length; i < l; i++ ) { + if ( eraName === cal.eras[i].name.toLowerCase() ) { + era = i; + break; + } + } + // could not find an era with that name + if ( era === null ) return null; + break; + } + } + } + var result = new Date(), defaultYear, convert = cal.convert; + defaultYear = convert ? convert.fromGregorian( result )[ 0 ] : result.getFullYear(); + if ( year === null ) { + year = defaultYear; + } + else if ( cal.eras ) { + // year must be shifted to normal gregorian year + // but not if year was not specified, its already normal gregorian + // per the main if clause above. + year += cal.eras[( era || 0 )].offset; + } + // set default day and month to 1 and January, so if unspecified, these are the defaults + // instead of the current day/month. + if ( month === null ) { + month = 0; + } + if ( date === null ) { + date = 1; + } + // now have year, month, and date, but in the culture's calendar. + // convert to gregorian if necessary + if ( convert ) { + result = convert.toGregorian( year, month, date ); + // conversion failed, must be an invalid match + if ( result === null ) return null; + } + else { + // have to set year, month and date together to avoid overflow based on current date. + result.setFullYear( year, month, date ); + // check to see if date overflowed for specified month (only checked 1-31 above). + if ( result.getDate() !== date ) return null; + // invalid day of week. + if ( weekDay !== null && result.getDay() !== weekDay ) { + return null; + } + } + // if pm designator token was found make sure the hours fit the 24-hour clock. + if ( pmHour && hour < 12 ) { + hour += 12; + } + result.setHours( hour, min, sec, msec ); + if ( tzMinOffset !== null ) { + // adjust timezone to utc before applying local offset. + var adjustedMin = result.getMinutes() - ( tzMinOffset + result.getTimezoneOffset() ); + // Safari limits hours and minutes to the range of -127 to 127. We need to use setHours + // to ensure both these fields will not exceed this range. adjustedMin will range + // somewhere between -1440 and 1500, so we only need to split this into hours. + result.setHours( result.getHours() + parseInt(adjustedMin / 60, 10), adjustedMin % 60 ); + } + return result; + }; +}()); + +parseNegativePattern = function( value, nf, negativePattern ) { + var neg = nf[ "-" ], + pos = nf[ "+" ], + ret; + switch ( negativePattern ) { + case "n -": + neg = " " + neg; + pos = " " + pos; + // fall through + case "n-": + if ( endsWith(value, neg) ) { + ret = [ "-", value.substr(0, value.length - neg.length) ]; + } + else if ( endsWith(value, pos) ) { + ret = [ "+", value.substr(0, value.length - pos.length) ]; + } + break; + case "- n": + neg += " "; + pos += " "; + // fall through + case "-n": + if ( startsWith(value, neg) ) { + ret = [ "-", value.substr(neg.length) ]; + } + else if ( startsWith(value, pos) ) { + ret = [ "+", value.substr(pos.length) ]; + } + break; + case "(n)": + if ( startsWith(value, "(") && endsWith(value, ")") ) { + ret = [ "-", value.substr(1, value.length - 2) ]; + } + break; + } + return ret || [ "", value ]; +}; + +// +// public instance functions +// + +Globalize.prototype.findClosestCulture = function( cultureSelector ) { + return Globalize.findClosestCulture.call( this, cultureSelector ); +}; + +Globalize.prototype.format = function( value, format, cultureSelector ) { + return Globalize.format.call( this, value, format, cultureSelector ); +}; + +Globalize.prototype.localize = function( key, cultureSelector ) { + return Globalize.localize.call( this, key, cultureSelector ); +}; + +Globalize.prototype.parseInt = function( value, radix, cultureSelector ) { + return Globalize.parseInt.call( this, value, radix, cultureSelector ); +}; + +Globalize.prototype.parseFloat = function( value, radix, cultureSelector ) { + return Globalize.parseFloat.call( this, value, radix, cultureSelector ); +}; + +Globalize.prototype.culture = function( cultureSelector ) { + return Globalize.culture.call( this, cultureSelector ); +}; + +// +// public singleton functions +// + +Globalize.addCultureInfo = function( cultureName, baseCultureName, info ) { + + var base = {}, + isNew = false; + + if ( typeof cultureName !== "string" ) { + // cultureName argument is optional string. If not specified, assume info is first + // and only argument. Specified info deep-extends current culture. + info = cultureName; + cultureName = this.culture().name; + base = this.cultures[ cultureName ]; + } else if ( typeof baseCultureName !== "string" ) { + // baseCultureName argument is optional string. If not specified, assume info is second + // argument. Specified info deep-extends specified culture. + // If specified culture does not exist, create by deep-extending default + info = baseCultureName; + isNew = ( this.cultures[ cultureName ] == null ); + base = this.cultures[ cultureName ] || this.cultures[ "default" ]; + } else { + // cultureName and baseCultureName specified. Assume a new culture is being created + // by deep-extending an specified base culture + isNew = true; + base = this.cultures[ baseCultureName ]; + } + + this.cultures[ cultureName ] = extend(true, {}, + base, + info + ); + // Make the standard calendar the current culture if it's a new culture + if ( isNew ) { + this.cultures[ cultureName ].calendar = this.cultures[ cultureName ].calendars.standard; + } +}; + +Globalize.findClosestCulture = function( name ) { + var match; + if ( !name ) { + return this.cultures[ this.cultureSelector ] || this.cultures[ "default" ]; + } + if ( typeof name === "string" ) { + name = name.split( "," ); + } + if ( isArray(name) ) { + var lang, + cultures = this.cultures, + list = name, + i, l = list.length, + prioritized = []; + for ( i = 0; i < l; i++ ) { + name = trim( list[i] ); + var pri, parts = name.split( ";" ); + lang = trim( parts[0] ); + if ( parts.length === 1 ) { + pri = 1; + } + else { + name = trim( parts[1] ); + if ( name.indexOf("q=") === 0 ) { + name = name.substr( 2 ); + pri = parseFloat( name ); + pri = isNaN( pri ) ? 0 : pri; + } + else { + pri = 1; + } + } + prioritized.push({ lang: lang, pri: pri }); + } + prioritized.sort(function( a, b ) { + return a.pri < b.pri ? 1 : -1; + }); + + // exact match + for ( i = 0; i < l; i++ ) { + lang = prioritized[ i ].lang; + match = cultures[ lang ]; + if ( match ) { + return match; + } + } + + // neutral language match + for ( i = 0; i < l; i++ ) { + lang = prioritized[ i ].lang; + do { + var index = lang.lastIndexOf( "-" ); + if ( index === -1 ) { + break; + } + // strip off the last part. e.g. en-US => en + lang = lang.substr( 0, index ); + match = cultures[ lang ]; + if ( match ) { + return match; + } + } + while ( 1 ); + } + + // last resort: match first culture using that language + for ( i = 0; i < l; i++ ) { + lang = prioritized[ i ].lang; + for ( var cultureKey in cultures ) { + var culture = cultures[ cultureKey ]; + if ( culture.language == lang ) { + return culture; + } + } + } + } + else if ( typeof name === "object" ) { + return name; + } + return match || null; +}; + +Globalize.format = function( value, format, cultureSelector ) { + culture = this.findClosestCulture( cultureSelector ); + if ( value instanceof Date ) { + value = formatDate( value, format, culture ); + } + else if ( typeof value === "number" ) { + value = formatNumber( value, format, culture ); + } + return value; +}; + +Globalize.localize = function( key, cultureSelector ) { + return this.findClosestCulture( cultureSelector ).messages[ key ] || + this.cultures[ "default" ].messages[ key ]; +}; + +Globalize.parseDate = function( value, formats, culture ) { + culture = this.findClosestCulture( culture ); + + var date, prop, patterns; + if ( formats ) { + if ( typeof formats === "string" ) { + formats = [ formats ]; + } + if ( formats.length ) { + for ( var i = 0, l = formats.length; i < l; i++ ) { + var format = formats[ i ]; + if ( format ) { + date = parseExact( value, format, culture ); + if ( date ) { + break; + } + } + } + } + } else { + patterns = culture.calendar.patterns; + for ( prop in patterns ) { + date = parseExact( value, patterns[prop], culture ); + if ( date ) { + break; + } + } + } + + return date || null; +}; + +Globalize.parseInt = function( value, radix, cultureSelector ) { + return truncate( Globalize.parseFloat(value, radix, cultureSelector) ); +}; + +Globalize.parseFloat = function( value, radix, cultureSelector ) { + // radix argument is optional + if ( typeof radix !== "number" ) { + cultureSelector = radix; + radix = 10; + } + + var culture = this.findClosestCulture( cultureSelector ); + var ret = NaN, + nf = culture.numberFormat; + + if ( value.indexOf(culture.numberFormat.currency.symbol) > -1 ) { + // remove currency symbol + value = value.replace( culture.numberFormat.currency.symbol, "" ); + // replace decimal seperator + value = value.replace( culture.numberFormat.currency["."], culture.numberFormat["."] ); + } + + // trim leading and trailing whitespace + value = trim( value ); + + // allow infinity or hexidecimal + if ( regexInfinity.test(value) ) { + ret = parseFloat( value ); + } + else if ( !radix && regexHex.test(value) ) { + ret = parseInt( value, 16 ); + } + else { + + // determine sign and number + var signInfo = parseNegativePattern( value, nf, nf.pattern[0] ), + sign = signInfo[ 0 ], + num = signInfo[ 1 ]; + + // #44 - try parsing as "(n)" + if ( sign === "" && nf.pattern[0] !== "(n)" ) { + signInfo = parseNegativePattern( value, nf, "(n)" ); + sign = signInfo[ 0 ]; + num = signInfo[ 1 ]; + } + + // try parsing as "-n" + if ( sign === "" && nf.pattern[0] !== "-n" ) { + signInfo = parseNegativePattern( value, nf, "-n" ); + sign = signInfo[ 0 ]; + num = signInfo[ 1 ]; + } + + sign = sign || "+"; + + // determine exponent and number + var exponent, + intAndFraction, + exponentPos = num.indexOf( "e" ); + if ( exponentPos < 0 ) exponentPos = num.indexOf( "E" ); + if ( exponentPos < 0 ) { + intAndFraction = num; + exponent = null; + } + else { + intAndFraction = num.substr( 0, exponentPos ); + exponent = num.substr( exponentPos + 1 ); + } + // determine decimal position + var integer, + fraction, + decSep = nf[ "." ], + decimalPos = intAndFraction.indexOf( decSep ); + if ( decimalPos < 0 ) { + integer = intAndFraction; + fraction = null; + } + else { + integer = intAndFraction.substr( 0, decimalPos ); + fraction = intAndFraction.substr( decimalPos + decSep.length ); + } + // handle groups (e.g. 1,000,000) + var groupSep = nf[ "," ]; + integer = integer.split( groupSep ).join( "" ); + var altGroupSep = groupSep.replace( /\u00A0/g, " " ); + if ( groupSep !== altGroupSep ) { + integer = integer.split( altGroupSep ).join( "" ); + } + // build a natively parsable number string + var p = sign + integer; + if ( fraction !== null ) { + p += "." + fraction; + } + if ( exponent !== null ) { + // exponent itself may have a number patternd + var expSignInfo = parseNegativePattern( exponent, nf, "-n" ); + p += "e" + ( expSignInfo[0] || "+" ) + expSignInfo[ 1 ]; + } + if ( regexParseFloat.test(p) ) { + ret = parseFloat( p ); + } + } + return ret; +}; + +Globalize.culture = function( cultureSelector ) { + // setter + if ( typeof cultureSelector !== "undefined" ) { + this.cultureSelector = cultureSelector; + } + // getter + return this.findClosestCulture( cultureSelector ) || this.culture[ "default" ]; +}; + +}( this )); diff --git a/htdocs/js/lib/vendor/jquery-ui-for-classlist3/development-bundle/external/jquery.bgiframe-2.1.2.js b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/external/jquery.bgiframe-2.1.2.js similarity index 100% rename from htdocs/js/lib/vendor/jquery-ui-for-classlist3/development-bundle/external/jquery.bgiframe-2.1.2.js rename to htdocs/js/jquery-ui-1.9.0.custom/development-bundle/external/jquery.bgiframe-2.1.2.js diff --git a/htdocs/js/lib/vendor/jquery-ui-for-classlist3/development-bundle/external/jquery.cookie.js b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/external/jquery.cookie.js similarity index 100% rename from htdocs/js/lib/vendor/jquery-ui-for-classlist3/development-bundle/external/jquery.cookie.js rename to htdocs/js/jquery-ui-1.9.0.custom/development-bundle/external/jquery.cookie.js diff --git a/htdocs/js/lib/vendor/jquery-ui-for-classlist3/development-bundle/external/jquery.metadata.js b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/external/jquery.metadata.js similarity index 100% rename from htdocs/js/lib/vendor/jquery-ui-for-classlist3/development-bundle/external/jquery.metadata.js rename to htdocs/js/jquery-ui-1.9.0.custom/development-bundle/external/jquery.metadata.js diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/external/jquery.mousewheel.js b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/external/jquery.mousewheel.js new file mode 100755 index 000000000..808e12b89 --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/external/jquery.mousewheel.js @@ -0,0 +1,84 @@ +/*! Copyright (c) 2011 Brandon Aaron (http://brandonaaron.net) + * Licensed under the MIT License (LICENSE.txt). + * + * Thanks to: http://adomas.org/javascript-mouse-wheel/ for some pointers. + * Thanks to: Mathias Bank(http://www.mathias-bank.de) for a scope bug fix. + * Thanks to: Seamus Leahy for adding deltaX and deltaY + * + * Version: 3.0.6 + * + * Requires: 1.2.2+ + */ + +(function($) { + +var types = ['DOMMouseScroll', 'mousewheel']; + +if ($.event.fixHooks) { + for ( var i=types.length; i; ) { + $.event.fixHooks[ types[--i] ] = $.event.mouseHooks; + } +} + +$.event.special.mousewheel = { + setup: function() { + if ( this.addEventListener ) { + for ( var i=types.length; i; ) { + this.addEventListener( types[--i], handler, false ); + } + } else { + this.onmousewheel = handler; + } + }, + + teardown: function() { + if ( this.removeEventListener ) { + for ( var i=types.length; i; ) { + this.removeEventListener( types[--i], handler, false ); + } + } else { + this.onmousewheel = null; + } + } +}; + +$.fn.extend({ + mousewheel: function(fn) { + return fn ? this.bind("mousewheel", fn) : this.trigger("mousewheel"); + }, + + unmousewheel: function(fn) { + return this.unbind("mousewheel", fn); + } +}); + + +function handler(event) { + var orgEvent = event || window.event, args = [].slice.call( arguments, 1 ), delta = 0, returnValue = true, deltaX = 0, deltaY = 0; + event = $.event.fix(orgEvent); + event.type = "mousewheel"; + + // Old school scrollwheel delta + if ( orgEvent.wheelDelta ) { delta = orgEvent.wheelDelta/120; } + if ( orgEvent.detail ) { delta = -orgEvent.detail/3; } + + // New school multidimensional scroll (touchpads) deltas + deltaY = delta; + + // Gecko + if ( orgEvent.axis !== undefined && orgEvent.axis === orgEvent.HORIZONTAL_AXIS ) { + deltaY = 0; + deltaX = -1*delta; + } + + // Webkit + if ( orgEvent.wheelDeltaY !== undefined ) { deltaY = orgEvent.wheelDeltaY/120; } + if ( orgEvent.wheelDeltaX !== undefined ) { deltaX = -1*orgEvent.wheelDeltaX/120; } + + // Add event and delta to the front of the arguments + args.unshift(event, delta, deltaX, deltaY); + + return ($.event.dispatch || $.event.handle).apply(this, args); +} + +})(jQuery); \ No newline at end of file diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/external/jshint.js b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/external/jshint.js new file mode 100755 index 000000000..5bf937c4b --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/external/jshint.js @@ -0,0 +1,4390 @@ +/*! + * JSHint, by JSHint Community. + * + * Licensed under the same slightly modified MIT license that JSLint is. + * It stops evil-doers everywhere. + * + * JSHint is a derivative work of JSLint: + * + * Copyright (c) 2002 Douglas Crockford (www.JSLint.com) + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom + * the Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * The Software shall be used for Good, not Evil. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + * JSHint was forked from 2010-12-16 edition of JSLint. + * + */ + +/* + JSHINT is a global function. It takes two parameters. + + var myResult = JSHINT(source, option); + + The first parameter is either a string or an array of strings. If it is a + string, it will be split on '\n' or '\r'. If it is an array of strings, it + is assumed that each string represents one line. The source can be a + JavaScript text or a JSON text. + + The second parameter is an optional object of options which control the + operation of JSHINT. Most of the options are booleans: They are all + optional and have a default value of false. One of the options, predef, + can be an array of names, which will be used to declare global variables, + or an object whose keys are used as global names, with a boolean value + that determines if they are assignable. + + If it checks out, JSHINT returns true. Otherwise, it returns false. + + If false, you can inspect JSHINT.errors to find out the problems. + JSHINT.errors is an array of objects containing these members: + + { + line : The line (relative to 0) at which the lint was found + character : The character (relative to 0) at which the lint was found + reason : The problem + evidence : The text line in which the problem occurred + raw : The raw message before the details were inserted + a : The first detail + b : The second detail + c : The third detail + d : The fourth detail + } + + If a fatal error was found, a null will be the last element of the + JSHINT.errors array. + + You can request a Function Report, which shows all of the functions + and the parameters and vars that they use. This can be used to find + implied global variables and other problems. The report is in HTML and + can be inserted in an HTML . + + var myReport = JSHINT.report(limited); + + If limited is true, then the report will be limited to only errors. + + You can request a data structure which contains JSHint's results. + + var myData = JSHINT.data(); + + It returns a structure with this form: + + { + errors: [ + { + line: NUMBER, + character: NUMBER, + reason: STRING, + evidence: STRING + } + ], + functions: [ + name: STRING, + line: NUMBER, + last: NUMBER, + param: [ + STRING + ], + closure: [ + STRING + ], + var: [ + STRING + ], + exception: [ + STRING + ], + outer: [ + STRING + ], + unused: [ + STRING + ], + global: [ + STRING + ], + label: [ + STRING + ] + ], + globals: [ + STRING + ], + member: { + STRING: NUMBER + }, + unused: [ + { + name: STRING, + line: NUMBER + } + ], + implieds: [ + { + name: STRING, + line: NUMBER + } + ], + urls: [ + STRING + ], + json: BOOLEAN + } + + Empty arrays will not be included. + +*/ + +/*jshint + evil: true, nomen: false, onevar: false, regexp: false, strict: true, boss: true, + undef: true, maxlen: 100, indent:4 +*/ + +/*members "\b", "\t", "\n", "\f", "\r", "!=", "!==", "\"", "%", "(begin)", + "(breakage)", "(context)", "(error)", "(global)", "(identifier)", "(last)", + "(line)", "(loopage)", "(name)", "(onevar)", "(params)", "(scope)", + "(statement)", "(verb)", "*", "+", "++", "-", "--", "\/", "<", "<=", "==", + "===", ">", ">=", $, $$, $A, $F, $H, $R, $break, $continue, $w, Abstract, Ajax, + __filename, __dirname, ActiveXObject, Array, ArrayBuffer, ArrayBufferView, Audio, + Autocompleter, Assets, Boolean, Builder, Buffer, Browser, COM, CScript, Canvas, + CustomAnimation, Class, Control, Chain, Color, Cookie, Core, DataView, Date, + Debug, Draggable, Draggables, Droppables, Document, DomReady, DOMReady, Drag, + E, Enumerator, Enumerable, Element, Elements, Error, Effect, EvalError, Event, + Events, FadeAnimation, Field, Flash, Float32Array, Float64Array, Form, + FormField, Frame, FormData, Function, Fx, GetObject, Group, Hash, HotKey, + HTMLElement, HTMLAnchorElement, HTMLBaseElement, HTMLBlockquoteElement, + HTMLBodyElement, HTMLBRElement, HTMLButtonElement, HTMLCanvasElement, HTMLDirectoryElement, + HTMLDivElement, HTMLDListElement, HTMLFieldSetElement, + HTMLFontElement, HTMLFormElement, HTMLFrameElement, HTMLFrameSetElement, + HTMLHeadElement, HTMLHeadingElement, HTMLHRElement, HTMLHtmlElement, + HTMLIFrameElement, HTMLImageElement, HTMLInputElement, HTMLIsIndexElement, + HTMLLabelElement, HTMLLayerElement, HTMLLegendElement, HTMLLIElement, + HTMLLinkElement, HTMLMapElement, HTMLMenuElement, HTMLMetaElement, + HTMLModElement, HTMLObjectElement, HTMLOListElement, HTMLOptGroupElement, + HTMLOptionElement, HTMLParagraphElement, HTMLParamElement, HTMLPreElement, + HTMLQuoteElement, HTMLScriptElement, HTMLSelectElement, HTMLStyleElement, + HtmlTable, HTMLTableCaptionElement, HTMLTableCellElement, HTMLTableColElement, + HTMLTableElement, HTMLTableRowElement, HTMLTableSectionElement, + HTMLTextAreaElement, HTMLTitleElement, HTMLUListElement, HTMLVideoElement, + Iframe, IframeShim, Image, Int16Array, Int32Array, Int8Array, + Insertion, InputValidator, JSON, Keyboard, Locale, LN10, LN2, LOG10E, LOG2E, + MAX_VALUE, MIN_VALUE, Mask, Math, MenuItem, MoveAnimation, MooTools, Native, + NEGATIVE_INFINITY, Number, Object, ObjectRange, Option, Options, OverText, PI, + POSITIVE_INFINITY, PeriodicalExecuter, Point, Position, Prototype, RangeError, + Rectangle, ReferenceError, RegExp, ResizeAnimation, Request, RotateAnimation, + SQRT1_2, SQRT2, ScrollBar, ScriptEngine, ScriptEngineBuildVersion, + ScriptEngineMajorVersion, ScriptEngineMinorVersion, Scriptaculous, Scroller, + Slick, Slider, Selector, SharedWorker, String, Style, SyntaxError, Sortable, Sortables, + SortableObserver, Sound, Spinner, System, Swiff, Text, TextArea, Template, + Timer, Tips, Type, TypeError, Toggle, Try, "use strict", unescape, URI, URIError, URL, + VBArray, WSH, WScript, XDomainRequest, Web, Window, XMLDOM, XMLHttpRequest, XPathEvaluator, + XPathException, XPathExpression, XPathNamespace, XPathNSResolver, XPathResult, "\\", a, + addEventListener, address, alert, apply, applicationCache, arguments, arity, + asi, b, basic, basicToken, bitwise, block, blur, boolOptions, boss, browser, c, call, callee, + caller, cases, charAt, charCodeAt, character, clearInterval, clearTimeout, + close, closed, closure, comment, condition, confirm, console, constructor, + content, couch, create, css, curly, d, data, datalist, dd, debug, decodeURI, + decodeURIComponent, defaultStatus, defineClass, deserialize, devel, document, + dojo, dijit, dojox, define, else, emit, encodeURI, encodeURIComponent, + entityify, eqeqeq, eqnull, errors, es5, escape, esnext, eval, event, evidence, evil, + ex, exception, exec, exps, expr, exports, FileReader, first, floor, focus, + forin, fragment, frames, from, fromCharCode, fud, funcscope, funct, function, functions, + g, gc, getComputedStyle, getRow, getter, getterToken, GLOBAL, global, globals, globalstrict, + hasOwnProperty, help, history, i, id, identifier, immed, implieds, importPackage, include, + indent, indexOf, init, ins, instanceOf, isAlpha, isApplicationRunning, isArray, + isDigit, isFinite, isNaN, iterator, java, join, jshint, + JSHINT, json, jquery, jQuery, keys, label, labelled, last, lastsemic, laxbreak, laxcomma, + latedef, lbp, led, left, length, line, load, loadClass, localStorage, location, + log, loopfunc, m, match, maxerr, maxlen, member,message, meta, module, moveBy, + moveTo, mootools, multistr, name, navigator, new, newcap, noarg, node, noempty, nomen, + nonew, nonstandard, nud, onbeforeunload, onblur, onerror, onevar, onecase, onfocus, + onload, onresize, onunload, open, openDatabase, openURL, opener, opera, options, outer, param, + parent, parseFloat, parseInt, passfail, plusplus, predef, print, process, prompt, + proto, prototype, prototypejs, provides, push, quit, range, raw, reach, reason, regexp, + readFile, readUrl, regexdash, removeEventListener, replace, report, require, + reserved, resizeBy, resizeTo, resolvePath, resumeUpdates, respond, rhino, right, + runCommand, scroll, screen, scripturl, scrollBy, scrollTo, scrollbar, search, seal, + send, serialize, sessionStorage, setInterval, setTimeout, setter, setterToken, shift, slice, + smarttabs, sort, spawn, split, stack, status, start, strict, sub, substr, supernew, shadow, + supplant, sum, sync, test, toLowerCase, toString, toUpperCase, toint32, token, top, trailing, + type, typeOf, Uint16Array, Uint32Array, Uint8Array, undef, undefs, unused, urls, validthis, + value, valueOf, var, version, WebSocket, white, window, Worker, wsh*/ + +/*global exports: false */ + +// We build the application inside a function so that we produce only a single +// global variable. That function will be invoked immediately, and its return +// value is the JSHINT function itself. + +var JSHINT = (function () { + "use strict"; + + var anonname, // The guessed name for anonymous functions. + +// These are operators that should not be used with the ! operator. + + bang = { + '<' : true, + '<=' : true, + '==' : true, + '===': true, + '!==': true, + '!=' : true, + '>' : true, + '>=' : true, + '+' : true, + '-' : true, + '*' : true, + '/' : true, + '%' : true + }, + + // These are the JSHint boolean options. + boolOptions = { + asi : true, // if automatic semicolon insertion should be tolerated + bitwise : true, // if bitwise operators should not be allowed + boss : true, // if advanced usage of assignments should be allowed + browser : true, // if the standard browser globals should be predefined + couch : true, // if CouchDB globals should be predefined + curly : true, // if curly braces around all blocks should be required + debug : true, // if debugger statements should be allowed + devel : true, // if logging globals should be predefined (console, + // alert, etc.) + dojo : true, // if Dojo Toolkit globals should be predefined + eqeqeq : true, // if === should be required + eqnull : true, // if == null comparisons should be tolerated + es5 : true, // if ES5 syntax should be allowed + esnext : true, // if es.next specific syntax should be allowed + evil : true, // if eval should be allowed + expr : true, // if ExpressionStatement should be allowed as Programs + forin : true, // if for in statements must filter + funcscope : true, // if only function scope should be used for scope tests + globalstrict: true, // if global "use strict"; should be allowed (also + // enables 'strict') + immed : true, // if immediate invocations must be wrapped in parens + iterator : true, // if the `__iterator__` property should be allowed + jquery : true, // if jQuery globals should be predefined + lastsemic : true, // if semicolons may be ommitted for the trailing + // statements inside of a one-line blocks. + latedef : true, // if the use before definition should not be tolerated + laxbreak : true, // if line breaks should not be checked + laxcomma : true, // if line breaks should not be checked around commas + loopfunc : true, // if functions should be allowed to be defined within + // loops + mootools : true, // if MooTools globals should be predefined + multistr : true, // allow multiline strings + newcap : true, // if constructor names must be capitalized + noarg : true, // if arguments.caller and arguments.callee should be + // disallowed + node : true, // if the Node.js environment globals should be + // predefined + noempty : true, // if empty blocks should be disallowed + nonew : true, // if using `new` for side-effects should be disallowed + nonstandard : true, // if non-standard (but widely adopted) globals should + // be predefined + nomen : true, // if names should be checked + onevar : true, // if only one var statement per function should be + // allowed + onecase : true, // if one case switch statements should be allowed + passfail : true, // if the scan should stop on first error + plusplus : true, // if increment/decrement should not be allowed + proto : true, // if the `__proto__` property should be allowed + prototypejs : true, // if Prototype and Scriptaculous globals should be + // predefined + regexdash : true, // if unescaped first/last dash (-) inside brackets + // should be tolerated + regexp : true, // if the . should not be allowed in regexp literals + rhino : true, // if the Rhino environment globals should be predefined + undef : true, // if variables should be declared before used + scripturl : true, // if script-targeted URLs should be tolerated + shadow : true, // if variable shadowing should be tolerated + smarttabs : true, // if smarttabs should be tolerated + // (http://www.emacswiki.org/emacs/SmartTabs) + strict : true, // require the "use strict"; pragma + sub : true, // if all forms of subscript notation are tolerated + supernew : true, // if `new function () { ... };` and `new Object;` + // should be tolerated + trailing : true, // if trailing whitespace rules apply + validthis : true, // if 'this' inside a non-constructor function is valid. + // This is a function scoped option only. + white : true, // if strict whitespace rules apply + wsh : true // if the Windows Scripting Host environment globals + // should be predefined + }, + + // browser contains a set of global names which are commonly provided by a + // web browser environment. + browser = { + ArrayBuffer : false, + ArrayBufferView : false, + Audio : false, + addEventListener : false, + applicationCache : false, + blur : false, + clearInterval : false, + clearTimeout : false, + close : false, + closed : false, + DataView : false, + defaultStatus : false, + document : false, + event : false, + FileReader : false, + Float32Array : false, + Float64Array : false, + FormData : false, + focus : false, + frames : false, + getComputedStyle : false, + HTMLElement : false, + HTMLAnchorElement : false, + HTMLBaseElement : false, + HTMLBlockquoteElement : false, + HTMLBodyElement : false, + HTMLBRElement : false, + HTMLButtonElement : false, + HTMLCanvasElement : false, + HTMLDirectoryElement : false, + HTMLDivElement : false, + HTMLDListElement : false, + HTMLFieldSetElement : false, + HTMLFontElement : false, + HTMLFormElement : false, + HTMLFrameElement : false, + HTMLFrameSetElement : false, + HTMLHeadElement : false, + HTMLHeadingElement : false, + HTMLHRElement : false, + HTMLHtmlElement : false, + HTMLIFrameElement : false, + HTMLImageElement : false, + HTMLInputElement : false, + HTMLIsIndexElement : false, + HTMLLabelElement : false, + HTMLLayerElement : false, + HTMLLegendElement : false, + HTMLLIElement : false, + HTMLLinkElement : false, + HTMLMapElement : false, + HTMLMenuElement : false, + HTMLMetaElement : false, + HTMLModElement : false, + HTMLObjectElement : false, + HTMLOListElement : false, + HTMLOptGroupElement : false, + HTMLOptionElement : false, + HTMLParagraphElement : false, + HTMLParamElement : false, + HTMLPreElement : false, + HTMLQuoteElement : false, + HTMLScriptElement : false, + HTMLSelectElement : false, + HTMLStyleElement : false, + HTMLTableCaptionElement : false, + HTMLTableCellElement : false, + HTMLTableColElement : false, + HTMLTableElement : false, + HTMLTableRowElement : false, + HTMLTableSectionElement : false, + HTMLTextAreaElement : false, + HTMLTitleElement : false, + HTMLUListElement : false, + HTMLVideoElement : false, + history : false, + Int16Array : false, + Int32Array : false, + Int8Array : false, + Image : false, + length : false, + localStorage : false, + location : false, + moveBy : false, + moveTo : false, + name : false, + navigator : false, + onbeforeunload : true, + onblur : true, + onerror : true, + onfocus : true, + onload : true, + onresize : true, + onunload : true, + open : false, + openDatabase : false, + opener : false, + Option : false, + parent : false, + print : false, + removeEventListener : false, + resizeBy : false, + resizeTo : false, + screen : false, + scroll : false, + scrollBy : false, + scrollTo : false, + sessionStorage : false, + setInterval : false, + setTimeout : false, + SharedWorker : false, + status : false, + top : false, + Uint16Array : false, + Uint32Array : false, + Uint8Array : false, + WebSocket : false, + window : false, + Worker : false, + XMLHttpRequest : false, + XPathEvaluator : false, + XPathException : false, + XPathExpression : false, + XPathNamespace : false, + XPathNSResolver : false, + XPathResult : false + }, + + couch = { + "require" : false, + respond : false, + getRow : false, + emit : false, + send : false, + start : false, + sum : false, + log : false, + exports : false, + module : false, + provides : false + }, + + devel = { + alert : false, + confirm : false, + console : false, + Debug : false, + opera : false, + prompt : false + }, + + dojo = { + dojo : false, + dijit : false, + dojox : false, + define : false, + "require" : false + }, + + escapes = { + '\b': '\\b', + '\t': '\\t', + '\n': '\\n', + '\f': '\\f', + '\r': '\\r', + '"' : '\\"', + '/' : '\\/', + '\\': '\\\\' + }, + + funct, // The current function + + functionicity = [ + 'closure', 'exception', 'global', 'label', + 'outer', 'unused', 'var' + ], + + functions, // All of the functions + + global, // The global scope + implied, // Implied globals + inblock, + indent, + jsonmode, + + jquery = { + '$' : false, + jQuery : false + }, + + lines, + lookahead, + member, + membersOnly, + + mootools = { + '$' : false, + '$$' : false, + Assets : false, + Browser : false, + Chain : false, + Class : false, + Color : false, + Cookie : false, + Core : false, + Document : false, + DomReady : false, + DOMReady : false, + Drag : false, + Element : false, + Elements : false, + Event : false, + Events : false, + Fx : false, + Group : false, + Hash : false, + HtmlTable : false, + Iframe : false, + IframeShim : false, + InputValidator : false, + instanceOf : false, + Keyboard : false, + Locale : false, + Mask : false, + MooTools : false, + Native : false, + Options : false, + OverText : false, + Request : false, + Scroller : false, + Slick : false, + Slider : false, + Sortables : false, + Spinner : false, + Swiff : false, + Tips : false, + Type : false, + typeOf : false, + URI : false, + Window : false + }, + + nexttoken, + + node = { + __filename : false, + __dirname : false, + Buffer : false, + console : false, + exports : false, + GLOBAL : false, + global : false, + module : false, + process : false, + require : false, + setTimeout : false, + clearTimeout : false, + setInterval : false, + clearInterval : false + }, + + noreach, + option, + predefined, // Global variables defined by option + prereg, + prevtoken, + + prototypejs = { + '$' : false, + '$$' : false, + '$A' : false, + '$F' : false, + '$H' : false, + '$R' : false, + '$break' : false, + '$continue' : false, + '$w' : false, + Abstract : false, + Ajax : false, + Class : false, + Enumerable : false, + Element : false, + Event : false, + Field : false, + Form : false, + Hash : false, + Insertion : false, + ObjectRange : false, + PeriodicalExecuter: false, + Position : false, + Prototype : false, + Selector : false, + Template : false, + Toggle : false, + Try : false, + Autocompleter : false, + Builder : false, + Control : false, + Draggable : false, + Draggables : false, + Droppables : false, + Effect : false, + Sortable : false, + SortableObserver : false, + Sound : false, + Scriptaculous : false + }, + + rhino = { + defineClass : false, + deserialize : false, + gc : false, + help : false, + importPackage: false, + "java" : false, + load : false, + loadClass : false, + print : false, + quit : false, + readFile : false, + readUrl : false, + runCommand : false, + seal : false, + serialize : false, + spawn : false, + sync : false, + toint32 : false, + version : false + }, + + scope, // The current scope + stack, + + // standard contains the global names that are provided by the + // ECMAScript standard. + standard = { + Array : false, + Boolean : false, + Date : false, + decodeURI : false, + decodeURIComponent : false, + encodeURI : false, + encodeURIComponent : false, + Error : false, + 'eval' : false, + EvalError : false, + Function : false, + hasOwnProperty : false, + isFinite : false, + isNaN : false, + JSON : false, + Math : false, + Number : false, + Object : false, + parseInt : false, + parseFloat : false, + RangeError : false, + ReferenceError : false, + RegExp : false, + String : false, + SyntaxError : false, + TypeError : false, + URIError : false + }, + + // widely adopted global names that are not part of ECMAScript standard + nonstandard = { + escape : false, + unescape : false + }, + + standard_member = { + E : true, + LN2 : true, + LN10 : true, + LOG2E : true, + LOG10E : true, + MAX_VALUE : true, + MIN_VALUE : true, + NEGATIVE_INFINITY : true, + PI : true, + POSITIVE_INFINITY : true, + SQRT1_2 : true, + SQRT2 : true + }, + + directive, + syntax = {}, + tab, + token, + urls, + useESNextSyntax, + warnings, + + wsh = { + ActiveXObject : true, + Enumerator : true, + GetObject : true, + ScriptEngine : true, + ScriptEngineBuildVersion : true, + ScriptEngineMajorVersion : true, + ScriptEngineMinorVersion : true, + VBArray : true, + WSH : true, + WScript : true, + XDomainRequest : true + }; + + // Regular expressions. Some of these are stupidly long. + var ax, cx, tx, nx, nxg, lx, ix, jx, ft; + (function () { + /*jshint maxlen:300 */ + + // unsafe comment or string + ax = /@cc|<\/?|script|\]\s*\]|<\s*!|</i; + + // unsafe characters that are silently deleted by one or more browsers + cx = /[\u0000-\u001f\u007f-\u009f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/; + + // token + tx = /^\s*([(){}\[.,:;'"~\?\]#@]|==?=?|\/(\*(jshint|jslint|members?|global)?|=|\/)?|\*[\/=]?|\+(?:=|\++)?|-(?:=|-+)?|%=?|&[&=]?|\|[|=]?|>>?>?=?|<([\/=!]|\!(\[|--)?|<=?)?|\^=?|\!=?=?|[a-zA-Z_$][a-zA-Z0-9_$]*|[0-9]+([xX][0-9a-fA-F]+|\.[0-9]*)?([eE][+\-]?[0-9]+)?)/; + + // characters in strings that need escapement + nx = /[\u0000-\u001f&<"\/\\\u007f-\u009f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/; + nxg = /[\u0000-\u001f&<"\/\\\u007f-\u009f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g; + + // star slash + lx = /\*\/|\/\*/; + + // identifier + ix = /^([a-zA-Z_$][a-zA-Z0-9_$]*)$/; + + // javascript url + jx = /^(?:javascript|jscript|ecmascript|vbscript|mocha|livescript)\s*:/i; + + // catches /* falls through */ comments + ft = /^\s*\/\*\s*falls\sthrough\s*\*\/\s*$/; + }()); + + function F() {} // Used by Object.create + + function is_own(object, name) { + +// The object.hasOwnProperty method fails when the property under consideration +// is named 'hasOwnProperty'. So we have to use this more convoluted form. + + return Object.prototype.hasOwnProperty.call(object, name); + } + +// Provide critical ES5 functions to ES3. + + if (typeof Array.isArray !== 'function') { + Array.isArray = function (o) { + return Object.prototype.toString.apply(o) === '[object Array]'; + }; + } + + if (typeof Object.create !== 'function') { + Object.create = function (o) { + F.prototype = o; + return new F(); + }; + } + + if (typeof Object.keys !== 'function') { + Object.keys = function (o) { + var a = [], k; + for (k in o) { + if (is_own(o, k)) { + a.push(k); + } + } + return a; + }; + } + +// Non standard methods + + if (typeof String.prototype.entityify !== 'function') { + String.prototype.entityify = function () { + return this + .replace(/&/g, '&') + .replace(//g, '>'); + }; + } + + if (typeof String.prototype.isAlpha !== 'function') { + String.prototype.isAlpha = function () { + return (this >= 'a' && this <= 'z\uffff') || + (this >= 'A' && this <= 'Z\uffff'); + }; + } + + if (typeof String.prototype.isDigit !== 'function') { + String.prototype.isDigit = function () { + return (this >= '0' && this <= '9'); + }; + } + + if (typeof String.prototype.supplant !== 'function') { + String.prototype.supplant = function (o) { + return this.replace(/\{([^{}]*)\}/g, function (a, b) { + var r = o[b]; + return typeof r === 'string' || typeof r === 'number' ? r : a; + }); + }; + } + + if (typeof String.prototype.name !== 'function') { + String.prototype.name = function () { + +// If the string looks like an identifier, then we can return it as is. +// If the string contains no control characters, no quote characters, and no +// backslash characters, then we can simply slap some quotes around it. +// Otherwise we must also replace the offending characters with safe +// sequences. + + if (ix.test(this)) { + return this; + } + if (nx.test(this)) { + return '"' + this.replace(nxg, function (a) { + var c = escapes[a]; + if (c) { + return c; + } + return '\\u' + ('0000' + a.charCodeAt().toString(16)).slice(-4); + }) + '"'; + } + return '"' + this + '"'; + }; + } + + + function combine(t, o) { + var n; + for (n in o) { + if (is_own(o, n)) { + t[n] = o[n]; + } + } + } + + function assume() { + if (option.couch) { + combine(predefined, couch); + } + + if (option.rhino) { + combine(predefined, rhino); + } + + if (option.prototypejs) { + combine(predefined, prototypejs); + } + + if (option.node) { + combine(predefined, node); + } + + if (option.devel) { + combine(predefined, devel); + } + + if (option.dojo) { + combine(predefined, dojo); + } + + if (option.browser) { + combine(predefined, browser); + } + + if (option.nonstandard) { + combine(predefined, nonstandard); + } + + if (option.jquery) { + combine(predefined, jquery); + } + + if (option.mootools) { + combine(predefined, mootools); + } + + if (option.wsh) { + combine(predefined, wsh); + } + + if (option.esnext) { + useESNextSyntax(); + } + + if (option.globalstrict && option.strict !== false) { + option.strict = true; + } + } + + + // Produce an error warning. + function quit(message, line, chr) { + var percentage = Math.floor((line / lines.length) * 100); + + throw { + name: 'JSHintError', + line: line, + character: chr, + message: message + " (" + percentage + "% scanned).", + raw: message + }; + } + + function isundef(scope, m, t, a) { + return JSHINT.undefs.push([scope, m, t, a]); + } + + function warning(m, t, a, b, c, d) { + var ch, l, w; + t = t || nexttoken; + if (t.id === '(end)') { // `~ + t = token; + } + l = t.line || 0; + ch = t.from || 0; + w = { + id: '(error)', + raw: m, + evidence: lines[l - 1] || '', + line: l, + character: ch, + a: a, + b: b, + c: c, + d: d + }; + w.reason = m.supplant(w); + JSHINT.errors.push(w); + if (option.passfail) { + quit('Stopping. ', l, ch); + } + warnings += 1; + if (warnings >= option.maxerr) { + quit("Too many errors.", l, ch); + } + return w; + } + + function warningAt(m, l, ch, a, b, c, d) { + return warning(m, { + line: l, + from: ch + }, a, b, c, d); + } + + function error(m, t, a, b, c, d) { + var w = warning(m, t, a, b, c, d); + } + + function errorAt(m, l, ch, a, b, c, d) { + return error(m, { + line: l, + from: ch + }, a, b, c, d); + } + + + +// lexical analysis and token construction + + var lex = (function lex() { + var character, from, line, s; + +// Private lex methods + + function nextLine() { + var at, + tw; // trailing whitespace check + + if (line >= lines.length) + return false; + + character = 1; + s = lines[line]; + line += 1; + + // If smarttabs option is used check for spaces followed by tabs only. + // Otherwise check for any occurence of mixed tabs and spaces. + if (option.smarttabs) + at = s.search(/ \t/); + else + at = s.search(/ \t|\t /); + + if (at >= 0) + warningAt("Mixed spaces and tabs.", line, at + 1); + + s = s.replace(/\t/g, tab); + at = s.search(cx); + + if (at >= 0) + warningAt("Unsafe character.", line, at); + + if (option.maxlen && option.maxlen < s.length) + warningAt("Line too long.", line, s.length); + + // Check for trailing whitespaces + tw = /\s+$/.test(s); + if (option.trailing && tw && !/^\s+$/.test(s)) { + warningAt("Trailing whitespace.", line, tw); + } + return true; + } + +// Produce a token object. The token inherits from a syntax symbol. + + function it(type, value) { + var i, t; + if (type === '(color)' || type === '(range)') { + t = {type: type}; + } else if (type === '(punctuator)' || + (type === '(identifier)' && is_own(syntax, value))) { + t = syntax[value] || syntax['(error)']; + } else { + t = syntax[type]; + } + t = Object.create(t); + if (type === '(string)' || type === '(range)') { + if (!option.scripturl && jx.test(value)) { + warningAt("Script URL.", line, from); + } + } + if (type === '(identifier)') { + t.identifier = true; + if (value === '__proto__' && !option.proto) { + warningAt("The '{a}' property is deprecated.", + line, from, value); + } else if (value === '__iterator__' && !option.iterator) { + warningAt("'{a}' is only available in JavaScript 1.7.", + line, from, value); + } else if (option.nomen && (value.charAt(0) === '_' || + value.charAt(value.length - 1) === '_')) { + if (!option.node || token.id === '.' || + (value !== '__dirname' && value !== '__filename')) { + warningAt("Unexpected {a} in '{b}'.", line, from, "dangling '_'", value); + } + } + } + t.value = value; + t.line = line; + t.character = character; + t.from = from; + i = t.id; + if (i !== '(endline)') { + prereg = i && + (('(,=:[!&|?{};'.indexOf(i.charAt(i.length - 1)) >= 0) || + i === 'return' || + i === 'case'); + } + return t; + } + + // Public lex methods + return { + init: function (source) { + if (typeof source === 'string') { + lines = source + .replace(/\r\n/g, '\n') + .replace(/\r/g, '\n') + .split('\n'); + } else { + lines = source; + } + + // If the first line is a shebang (#!), make it a blank and move on. + // Shebangs are used by Node scripts. + if (lines[0] && lines[0].substr(0, 2) === '#!') + lines[0] = ''; + + line = 0; + nextLine(); + from = 1; + }, + + range: function (begin, end) { + var c, value = ''; + from = character; + if (s.charAt(0) !== begin) { + errorAt("Expected '{a}' and instead saw '{b}'.", + line, character, begin, s.charAt(0)); + } + for (;;) { + s = s.slice(1); + character += 1; + c = s.charAt(0); + switch (c) { + case '': + errorAt("Missing '{a}'.", line, character, c); + break; + case end: + s = s.slice(1); + character += 1; + return it('(range)', value); + case '\\': + warningAt("Unexpected '{a}'.", line, character, c); + } + value += c; + } + + }, + + + // token -- this is called by advance to get the next token + token: function () { + var b, c, captures, d, depth, high, i, l, low, q, t, isLiteral, isInRange; + + function match(x) { + var r = x.exec(s), r1; + if (r) { + l = r[0].length; + r1 = r[1]; + c = r1.charAt(0); + s = s.substr(l); + from = character + l - r1.length; + character += l; + return r1; + } + } + + function string(x) { + var c, j, r = '', allowNewLine = false; + + if (jsonmode && x !== '"') { + warningAt("Strings must use doublequote.", + line, character); + } + + function esc(n) { + var i = parseInt(s.substr(j + 1, n), 16); + j += n; + if (i >= 32 && i <= 126 && + i !== 34 && i !== 92 && i !== 39) { + warningAt("Unnecessary escapement.", line, character); + } + character += n; + c = String.fromCharCode(i); + } + j = 0; +unclosedString: for (;;) { + while (j >= s.length) { + j = 0; + + var cl = line, cf = from; + if (!nextLine()) { + errorAt("Unclosed string.", cl, cf); + break unclosedString; + } + + if (allowNewLine) { + allowNewLine = false; + } else { + warningAt("Unclosed string.", cl, cf); + } + } + c = s.charAt(j); + if (c === x) { + character += 1; + s = s.substr(j + 1); + return it('(string)', r, x); + } + if (c < ' ') { + if (c === '\n' || c === '\r') { + break; + } + warningAt("Control character in string: {a}.", + line, character + j, s.slice(0, j)); + } else if (c === '\\') { + j += 1; + character += 1; + c = s.charAt(j); + switch (c) { + case '\\': + case '"': + case '/': + break; + case '\'': + if (jsonmode) { + warningAt("Avoid \\'.", line, character); + } + break; + case 'b': + c = '\b'; + break; + case 'f': + c = '\f'; + break; + case 'n': + c = '\n'; + break; + case 'r': + c = '\r'; + break; + case 't': + c = '\t'; + break; + case 'u': + esc(4); + break; + case 'v': + if (jsonmode) { + warningAt("Avoid \\v.", line, character); + } + c = '\v'; + break; + case 'x': + if (jsonmode) { + warningAt("Avoid \\x-.", line, character); + } + esc(2); + break; + case '': + // last character is escape character + // always allow new line if escaped, but show + // warning if option is not set + allowNewLine = true; + if (option.multistr) { + if (jsonmode) { + warningAt("Avoid EOL escapement.", line, character); + } + c = ''; + character -= 1; + break; + } + warningAt("Bad escapement of EOL. Use option multistr if needed.", + line, character); + break; + default: + warningAt("Bad escapement.", line, character); + } + } + r += c; + character += 1; + j += 1; + } + } + + for (;;) { + if (!s) { + return it(nextLine() ? '(endline)' : '(end)', ''); + } + t = match(tx); + if (!t) { + t = ''; + c = ''; + while (s && s < '!') { + s = s.substr(1); + } + if (s) { + errorAt("Unexpected '{a}'.", line, character, s.substr(0, 1)); + s = ''; + } + } else { + + // identifier + + if (c.isAlpha() || c === '_' || c === '$') { + return it('(identifier)', t); + } + + // number + + if (c.isDigit()) { + if (!isFinite(Number(t))) { + warningAt("Bad number '{a}'.", + line, character, t); + } + if (s.substr(0, 1).isAlpha()) { + warningAt("Missing space after '{a}'.", + line, character, t); + } + if (c === '0') { + d = t.substr(1, 1); + if (d.isDigit()) { + if (token.id !== '.') { + warningAt("Don't use extra leading zeros '{a}'.", + line, character, t); + } + } else if (jsonmode && (d === 'x' || d === 'X')) { + warningAt("Avoid 0x-. '{a}'.", + line, character, t); + } + } + if (t.substr(t.length - 1) === '.') { + warningAt( +"A trailing decimal point can be confused with a dot '{a}'.", line, character, t); + } + return it('(number)', t); + } + switch (t) { + + // string + + case '"': + case "'": + return string(t); + + // // comment + + case '//': + s = ''; + token.comment = true; + break; + + // /* comment + + case '/*': + for (;;) { + i = s.search(lx); + if (i >= 0) { + break; + } + if (!nextLine()) { + errorAt("Unclosed comment.", line, character); + } + } + character += i + 2; + if (s.substr(i, 1) === '/') { + errorAt("Nested comment.", line, character); + } + s = s.substr(i + 2); + token.comment = true; + break; + + // /*members /*jshint /*global + + case '/*members': + case '/*member': + case '/*jshint': + case '/*jslint': + case '/*global': + case '*/': + return { + value: t, + type: 'special', + line: line, + character: character, + from: from + }; + + case '': + break; + // / + case '/': + if (token.id === '/=') { + errorAt("A regular expression literal can be confused with '/='.", + line, from); + } + if (prereg) { + depth = 0; + captures = 0; + l = 0; + for (;;) { + b = true; + c = s.charAt(l); + l += 1; + switch (c) { + case '': + errorAt("Unclosed regular expression.", line, from); + return quit('Stopping.', line, from); + case '/': + if (depth > 0) { + warningAt("{a} unterminated regular expression " + + "group(s).", line, from + l, depth); + } + c = s.substr(0, l - 1); + q = { + g: true, + i: true, + m: true + }; + while (q[s.charAt(l)] === true) { + q[s.charAt(l)] = false; + l += 1; + } + character += l; + s = s.substr(l); + q = s.charAt(0); + if (q === '/' || q === '*') { + errorAt("Confusing regular expression.", + line, from); + } + return it('(regexp)', c); + case '\\': + c = s.charAt(l); + if (c < ' ') { + warningAt( +"Unexpected control character in regular expression.", line, from + l); + } else if (c === '<') { + warningAt( +"Unexpected escaped character '{a}' in regular expression.", line, from + l, c); + } + l += 1; + break; + case '(': + depth += 1; + b = false; + if (s.charAt(l) === '?') { + l += 1; + switch (s.charAt(l)) { + case ':': + case '=': + case '!': + l += 1; + break; + default: + warningAt( +"Expected '{a}' and instead saw '{b}'.", line, from + l, ':', s.charAt(l)); + } + } else { + captures += 1; + } + break; + case '|': + b = false; + break; + case ')': + if (depth === 0) { + warningAt("Unescaped '{a}'.", + line, from + l, ')'); + } else { + depth -= 1; + } + break; + case ' ': + q = 1; + while (s.charAt(l) === ' ') { + l += 1; + q += 1; + } + if (q > 1) { + warningAt( +"Spaces are hard to count. Use {{a}}.", line, from + l, q); + } + break; + case '[': + c = s.charAt(l); + if (c === '^') { + l += 1; + if (option.regexp) { + warningAt("Insecure '{a}'.", + line, from + l, c); + } else if (s.charAt(l) === ']') { + errorAt("Unescaped '{a}'.", + line, from + l, '^'); + } + } + if (c === ']') { + warningAt("Empty class.", line, + from + l - 1); + } + isLiteral = false; + isInRange = false; +klass: do { + c = s.charAt(l); + l += 1; + switch (c) { + case '[': + case '^': + warningAt("Unescaped '{a}'.", + line, from + l, c); + if (isInRange) { + isInRange = false; + } else { + isLiteral = true; + } + break; + case '-': + if (isLiteral && !isInRange) { + isLiteral = false; + isInRange = true; + } else if (isInRange) { + isInRange = false; + } else if (s.charAt(l) === ']') { + isInRange = true; + } else { + if (option.regexdash !== (l === 2 || (l === 3 && + s.charAt(1) === '^'))) { + warningAt("Unescaped '{a}'.", + line, from + l - 1, '-'); + } + isLiteral = true; + } + break; + case ']': + if (isInRange && !option.regexdash) { + warningAt("Unescaped '{a}'.", + line, from + l - 1, '-'); + } + break klass; + case '\\': + c = s.charAt(l); + if (c < ' ') { + warningAt( +"Unexpected control character in regular expression.", line, from + l); + } else if (c === '<') { + warningAt( +"Unexpected escaped character '{a}' in regular expression.", line, from + l, c); + } + l += 1; + + // \w, \s and \d are never part of a character range + if (/[wsd]/i.test(c)) { + if (isInRange) { + warningAt("Unescaped '{a}'.", + line, from + l, '-'); + isInRange = false; + } + isLiteral = false; + } else if (isInRange) { + isInRange = false; + } else { + isLiteral = true; + } + break; + case '/': + warningAt("Unescaped '{a}'.", + line, from + l - 1, '/'); + + if (isInRange) { + isInRange = false; + } else { + isLiteral = true; + } + break; + case '<': + if (isInRange) { + isInRange = false; + } else { + isLiteral = true; + } + break; + default: + if (isInRange) { + isInRange = false; + } else { + isLiteral = true; + } + } + } while (c); + break; + case '.': + if (option.regexp) { + warningAt("Insecure '{a}'.", line, + from + l, c); + } + break; + case ']': + case '?': + case '{': + case '}': + case '+': + case '*': + warningAt("Unescaped '{a}'.", line, + from + l, c); + } + if (b) { + switch (s.charAt(l)) { + case '?': + case '+': + case '*': + l += 1; + if (s.charAt(l) === '?') { + l += 1; + } + break; + case '{': + l += 1; + c = s.charAt(l); + if (c < '0' || c > '9') { + warningAt( +"Expected a number and instead saw '{a}'.", line, from + l, c); + } + l += 1; + low = +c; + for (;;) { + c = s.charAt(l); + if (c < '0' || c > '9') { + break; + } + l += 1; + low = +c + (low * 10); + } + high = low; + if (c === ',') { + l += 1; + high = Infinity; + c = s.charAt(l); + if (c >= '0' && c <= '9') { + l += 1; + high = +c; + for (;;) { + c = s.charAt(l); + if (c < '0' || c > '9') { + break; + } + l += 1; + high = +c + (high * 10); + } + } + } + if (s.charAt(l) !== '}') { + warningAt( +"Expected '{a}' and instead saw '{b}'.", line, from + l, '}', c); + } else { + l += 1; + } + if (s.charAt(l) === '?') { + l += 1; + } + if (low > high) { + warningAt( +"'{a}' should not be greater than '{b}'.", line, from + l, low, high); + } + } + } + } + c = s.substr(0, l - 1); + character += l; + s = s.substr(l); + return it('(regexp)', c); + } + return it('(punctuator)', t); + + // punctuator + + case '#': + return it('(punctuator)', t); + default: + return it('(punctuator)', t); + } + } + } + } + }; + }()); + + + function addlabel(t, type) { + + if (t === 'hasOwnProperty') { + warning("'hasOwnProperty' is a really bad name."); + } + +// Define t in the current function in the current scope. + if (is_own(funct, t) && !funct['(global)']) { + if (funct[t] === true) { + if (option.latedef) + warning("'{a}' was used before it was defined.", nexttoken, t); + } else { + if (!option.shadow && type !== "exception") + warning("'{a}' is already defined.", nexttoken, t); + } + } + + funct[t] = type; + if (funct['(global)']) { + global[t] = funct; + if (is_own(implied, t)) { + if (option.latedef) + warning("'{a}' was used before it was defined.", nexttoken, t); + delete implied[t]; + } + } else { + scope[t] = funct; + } + } + + + function doOption() { + var b, obj, filter, o = nexttoken.value, t, v; + switch (o) { + case '*/': + error("Unbegun comment."); + break; + case '/*members': + case '/*member': + o = '/*members'; + if (!membersOnly) { + membersOnly = {}; + } + obj = membersOnly; + break; + case '/*jshint': + case '/*jslint': + obj = option; + filter = boolOptions; + break; + case '/*global': + obj = predefined; + break; + default: + error("What?"); + } + t = lex.token(); +loop: for (;;) { + for (;;) { + if (t.type === 'special' && t.value === '*/') { + break loop; + } + if (t.id !== '(endline)' && t.id !== ',') { + break; + } + t = lex.token(); + } + if (t.type !== '(string)' && t.type !== '(identifier)' && + o !== '/*members') { + error("Bad option.", t); + } + v = lex.token(); + if (v.id === ':') { + v = lex.token(); + if (obj === membersOnly) { + error("Expected '{a}' and instead saw '{b}'.", + t, '*/', ':'); + } + if (t.value === 'indent' && (o === '/*jshint' || o === '/*jslint')) { + b = +v.value; + if (typeof b !== 'number' || !isFinite(b) || b <= 0 || + Math.floor(b) !== b) { + error("Expected a small integer and instead saw '{a}'.", + v, v.value); + } + obj.white = true; + obj.indent = b; + } else if (t.value === 'maxerr' && (o === '/*jshint' || o === '/*jslint')) { + b = +v.value; + if (typeof b !== 'number' || !isFinite(b) || b <= 0 || + Math.floor(b) !== b) { + error("Expected a small integer and instead saw '{a}'.", + v, v.value); + } + obj.maxerr = b; + } else if (t.value === 'maxlen' && (o === '/*jshint' || o === '/*jslint')) { + b = +v.value; + if (typeof b !== 'number' || !isFinite(b) || b <= 0 || + Math.floor(b) !== b) { + error("Expected a small integer and instead saw '{a}'.", + v, v.value); + } + obj.maxlen = b; + } else if (t.value === 'validthis') { + if (funct['(global)']) { + error("Option 'validthis' can't be used in a global scope."); + } else { + if (v.value === 'true' || v.value === 'false') + obj[t.value] = v.value === 'true'; + else + error("Bad option value.", v); + } + } else if (v.value === 'true') { + obj[t.value] = true; + } else if (v.value === 'false') { + obj[t.value] = false; + } else { + error("Bad option value.", v); + } + t = lex.token(); + } else { + if (o === '/*jshint' || o === '/*jslint') { + error("Missing option value.", t); + } + obj[t.value] = false; + t = v; + } + } + if (filter) { + assume(); + } + } + + +// We need a peek function. If it has an argument, it peeks that much farther +// ahead. It is used to distinguish +// for ( var i in ... +// from +// for ( var i = ... + + function peek(p) { + var i = p || 0, j = 0, t; + + while (j <= i) { + t = lookahead[j]; + if (!t) { + t = lookahead[j] = lex.token(); + } + j += 1; + } + return t; + } + + + +// Produce the next token. It looks for programming errors. + + function advance(id, t) { + switch (token.id) { + case '(number)': + if (nexttoken.id === '.') { + warning("A dot following a number can be confused with a decimal point.", token); + } + break; + case '-': + if (nexttoken.id === '-' || nexttoken.id === '--') { + warning("Confusing minusses."); + } + break; + case '+': + if (nexttoken.id === '+' || nexttoken.id === '++') { + warning("Confusing plusses."); + } + break; + } + + if (token.type === '(string)' || token.identifier) { + anonname = token.value; + } + + if (id && nexttoken.id !== id) { + if (t) { + if (nexttoken.id === '(end)') { + warning("Unmatched '{a}'.", t, t.id); + } else { + warning("Expected '{a}' to match '{b}' from line {c} and instead saw '{d}'.", + nexttoken, id, t.id, t.line, nexttoken.value); + } + } else if (nexttoken.type !== '(identifier)' || + nexttoken.value !== id) { + warning("Expected '{a}' and instead saw '{b}'.", + nexttoken, id, nexttoken.value); + } + } + + prevtoken = token; + token = nexttoken; + for (;;) { + nexttoken = lookahead.shift() || lex.token(); + if (nexttoken.id === '(end)' || nexttoken.id === '(error)') { + return; + } + if (nexttoken.type === 'special') { + doOption(); + } else { + if (nexttoken.id !== '(endline)') { + break; + } + } + } + } + + +// This is the heart of JSHINT, the Pratt parser. In addition to parsing, it +// is looking for ad hoc lint patterns. We add .fud to Pratt's model, which is +// like .nud except that it is only used on the first token of a statement. +// Having .fud makes it much easier to define statement-oriented languages like +// JavaScript. I retained Pratt's nomenclature. + +// .nud Null denotation +// .fud First null denotation +// .led Left denotation +// lbp Left binding power +// rbp Right binding power + +// They are elements of the parsing method called Top Down Operator Precedence. + + function expression(rbp, initial) { + var left, isArray = false; + + if (nexttoken.id === '(end)') + error("Unexpected early end of program.", token); + + advance(); + if (initial) { + anonname = 'anonymous'; + funct['(verb)'] = token.value; + } + if (initial === true && token.fud) { + left = token.fud(); + } else { + if (token.nud) { + left = token.nud(); + } else { + if (nexttoken.type === '(number)' && token.id === '.') { + warning("A leading decimal point can be confused with a dot: '.{a}'.", + token, nexttoken.value); + advance(); + return token; + } else { + error("Expected an identifier and instead saw '{a}'.", + token, token.id); + } + } + while (rbp < nexttoken.lbp) { + isArray = token.value === 'Array'; + advance(); + if (isArray && token.id === '(' && nexttoken.id === ')') + warning("Use the array literal notation [].", token); + if (token.led) { + left = token.led(left); + } else { + error("Expected an operator and instead saw '{a}'.", + token, token.id); + } + } + } + return left; + } + + +// Functions for conformance of style. + + function adjacent(left, right) { + left = left || token; + right = right || nexttoken; + if (option.white) { + if (left.character !== right.from && left.line === right.line) { + left.from += (left.character - left.from); + warning("Unexpected space after '{a}'.", left, left.value); + } + } + } + + function nobreak(left, right) { + left = left || token; + right = right || nexttoken; + if (option.white && (left.character !== right.from || left.line !== right.line)) { + warning("Unexpected space before '{a}'.", right, right.value); + } + } + + function nospace(left, right) { + left = left || token; + right = right || nexttoken; + if (option.white && !left.comment) { + if (left.line === right.line) { + adjacent(left, right); + } + } + } + + function nonadjacent(left, right) { + if (option.white) { + left = left || token; + right = right || nexttoken; + if (left.line === right.line && left.character === right.from) { + left.from += (left.character - left.from); + warning("Missing space after '{a}'.", + left, left.value); + } + } + } + + function nobreaknonadjacent(left, right) { + left = left || token; + right = right || nexttoken; + if (!option.laxbreak && left.line !== right.line) { + warning("Bad line breaking before '{a}'.", right, right.id); + } else if (option.white) { + left = left || token; + right = right || nexttoken; + if (left.character === right.from) { + left.from += (left.character - left.from); + warning("Missing space after '{a}'.", + left, left.value); + } + } + } + + function indentation(bias) { + var i; + if (option.white && nexttoken.id !== '(end)') { + i = indent + (bias || 0); + if (nexttoken.from !== i) { + warning( +"Expected '{a}' to have an indentation at {b} instead at {c}.", + nexttoken, nexttoken.value, i, nexttoken.from); + } + } + } + + function nolinebreak(t) { + t = t || token; + if (t.line !== nexttoken.line) { + warning("Line breaking error '{a}'.", t, t.value); + } + } + + + function comma() { + if (token.line !== nexttoken.line) { + if (!option.laxcomma) { + if (comma.first) { + warning("Comma warnings can be turned off with 'laxcomma'"); + comma.first = false; + } + warning("Bad line breaking before '{a}'.", token, nexttoken.id); + } + } else if (!token.comment && token.character !== nexttoken.from && option.white) { + token.from += (token.character - token.from); + warning("Unexpected space after '{a}'.", token, token.value); + } + advance(','); + nonadjacent(token, nexttoken); + } + + comma.first = true; + + +// Functional constructors for making the symbols that will be inherited by +// tokens. + + function symbol(s, p) { + var x = syntax[s]; + if (!x || typeof x !== 'object') { + syntax[s] = x = { + id: s, + lbp: p, + value: s + }; + } + return x; + } + + + function delim(s) { + return symbol(s, 0); + } + + + function stmt(s, f) { + var x = delim(s); + x.identifier = x.reserved = true; + x.fud = f; + return x; + } + + + function blockstmt(s, f) { + var x = stmt(s, f); + x.block = true; + return x; + } + + + function reserveName(x) { + var c = x.id.charAt(0); + if ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z')) { + x.identifier = x.reserved = true; + } + return x; + } + + + function prefix(s, f) { + var x = symbol(s, 150); + reserveName(x); + x.nud = (typeof f === 'function') ? f : function () { + this.right = expression(150); + this.arity = 'unary'; + if (this.id === '++' || this.id === '--') { + if (option.plusplus) { + warning("Unexpected use of '{a}'.", this, this.id); + } else if ((!this.right.identifier || this.right.reserved) && + this.right.id !== '.' && this.right.id !== '[') { + warning("Bad operand.", this); + } + } + return this; + }; + return x; + } + + + function type(s, f) { + var x = delim(s); + x.type = s; + x.nud = f; + return x; + } + + + function reserve(s, f) { + var x = type(s, f); + x.identifier = x.reserved = true; + return x; + } + + + function reservevar(s, v) { + return reserve(s, function () { + if (typeof v === 'function') { + v(this); + } + return this; + }); + } + + + function infix(s, f, p, w) { + var x = symbol(s, p); + reserveName(x); + x.led = function (left) { + if (!w) { + nobreaknonadjacent(prevtoken, token); + nonadjacent(token, nexttoken); + } + if (s === "in" && left.id === "!") { + warning("Confusing use of '{a}'.", left, '!'); + } + if (typeof f === 'function') { + return f(left, this); + } else { + this.left = left; + this.right = expression(p); + return this; + } + }; + return x; + } + + + function relation(s, f) { + var x = symbol(s, 100); + x.led = function (left) { + nobreaknonadjacent(prevtoken, token); + nonadjacent(token, nexttoken); + var right = expression(100); + if ((left && left.id === 'NaN') || (right && right.id === 'NaN')) { + warning("Use the isNaN function to compare with NaN.", this); + } else if (f) { + f.apply(this, [left, right]); + } + if (left.id === '!') { + warning("Confusing use of '{a}'.", left, '!'); + } + if (right.id === '!') { + warning("Confusing use of '{a}'.", right, '!'); + } + this.left = left; + this.right = right; + return this; + }; + return x; + } + + + function isPoorRelation(node) { + return node && + ((node.type === '(number)' && +node.value === 0) || + (node.type === '(string)' && node.value === '') || + (node.type === 'null' && !option.eqnull) || + node.type === 'true' || + node.type === 'false' || + node.type === 'undefined'); + } + + + function assignop(s, f) { + symbol(s, 20).exps = true; + return infix(s, function (left, that) { + var l; + that.left = left; + if (predefined[left.value] === false && + scope[left.value]['(global)'] === true) { + warning("Read only.", left); + } else if (left['function']) { + warning("'{a}' is a function.", left, left.value); + } + if (left) { + if (option.esnext && funct[left.value] === 'const') { + warning("Attempting to override '{a}' which is a constant", left, left.value); + } + if (left.id === '.' || left.id === '[') { + if (!left.left || left.left.value === 'arguments') { + warning('Bad assignment.', that); + } + that.right = expression(19); + return that; + } else if (left.identifier && !left.reserved) { + if (funct[left.value] === 'exception') { + warning("Do not assign to the exception parameter.", left); + } + that.right = expression(19); + return that; + } + if (left === syntax['function']) { + warning( +"Expected an identifier in an assignment and instead saw a function invocation.", + token); + } + } + error("Bad assignment.", that); + }, 20); + } + + + function bitwise(s, f, p) { + var x = symbol(s, p); + reserveName(x); + x.led = (typeof f === 'function') ? f : function (left) { + if (option.bitwise) { + warning("Unexpected use of '{a}'.", this, this.id); + } + this.left = left; + this.right = expression(p); + return this; + }; + return x; + } + + + function bitwiseassignop(s) { + symbol(s, 20).exps = true; + return infix(s, function (left, that) { + if (option.bitwise) { + warning("Unexpected use of '{a}'.", that, that.id); + } + nonadjacent(prevtoken, token); + nonadjacent(token, nexttoken); + if (left) { + if (left.id === '.' || left.id === '[' || + (left.identifier && !left.reserved)) { + expression(19); + return that; + } + if (left === syntax['function']) { + warning( +"Expected an identifier in an assignment, and instead saw a function invocation.", + token); + } + return that; + } + error("Bad assignment.", that); + }, 20); + } + + + function suffix(s, f) { + var x = symbol(s, 150); + x.led = function (left) { + if (option.plusplus) { + warning("Unexpected use of '{a}'.", this, this.id); + } else if ((!left.identifier || left.reserved) && + left.id !== '.' && left.id !== '[') { + warning("Bad operand.", this); + } + this.left = left; + return this; + }; + return x; + } + + + // fnparam means that this identifier is being defined as a function + // argument (see identifier()) + function optionalidentifier(fnparam) { + if (nexttoken.identifier) { + advance(); + if (token.reserved && !option.es5) { + // `undefined` as a function param is a common pattern to protect + // against the case when somebody does `undefined = true` and + // help with minification. More info: https://gist.github.com/315916 + if (!fnparam || token.value !== 'undefined') { + warning("Expected an identifier and instead saw '{a}' (a reserved word).", + token, token.id); + } + } + return token.value; + } + } + + // fnparam means that this identifier is being defined as a function + // argument + function identifier(fnparam) { + var i = optionalidentifier(fnparam); + if (i) { + return i; + } + if (token.id === 'function' && nexttoken.id === '(') { + warning("Missing name in function declaration."); + } else { + error("Expected an identifier and instead saw '{a}'.", + nexttoken, nexttoken.value); + } + } + + + function reachable(s) { + var i = 0, t; + if (nexttoken.id !== ';' || noreach) { + return; + } + for (;;) { + t = peek(i); + if (t.reach) { + return; + } + if (t.id !== '(endline)') { + if (t.id === 'function') { + if (!option.latedef) { + break; + } + warning( +"Inner functions should be listed at the top of the outer function.", t); + break; + } + warning("Unreachable '{a}' after '{b}'.", t, t.value, s); + break; + } + i += 1; + } + } + + + function statement(noindent) { + var i = indent, r, s = scope, t = nexttoken; + + if (t.id === ";") { + advance(";"); + return; + } + +// Is this a labelled statement? + + if (t.identifier && !t.reserved && peek().id === ':') { + advance(); + advance(':'); + scope = Object.create(s); + addlabel(t.value, 'label'); + if (!nexttoken.labelled) { + warning("Label '{a}' on {b} statement.", + nexttoken, t.value, nexttoken.value); + } + if (jx.test(t.value + ':')) { + warning("Label '{a}' looks like a javascript url.", + t, t.value); + } + nexttoken.label = t.value; + t = nexttoken; + } + +// Parse the statement. + + if (!noindent) { + indentation(); + } + r = expression(0, true); + + // Look for the final semicolon. + if (!t.block) { + if (!option.expr && (!r || !r.exps)) { + warning("Expected an assignment or function call and instead saw an expression.", + token); + } else if (option.nonew && r.id === '(' && r.left.id === 'new') { + warning("Do not use 'new' for side effects."); + } + + if (nexttoken.id !== ';') { + if (!option.asi) { + // If this is the last statement in a block that ends on + // the same line *and* option lastsemic is on, ignore the warning. + // Otherwise, complain about missing semicolon. + if (!option.lastsemic || nexttoken.id !== '}' || + nexttoken.line !== token.line) { + warningAt("Missing semicolon.", token.line, token.character); + } + } + } else { + adjacent(token, nexttoken); + advance(';'); + nonadjacent(token, nexttoken); + } + } + +// Restore the indentation. + + indent = i; + scope = s; + return r; + } + + + function statements(startLine) { + var a = [], f, p; + + while (!nexttoken.reach && nexttoken.id !== '(end)') { + if (nexttoken.id === ';') { + p = peek(); + if (!p || p.id !== "(") { + warning("Unnecessary semicolon."); + } + advance(';'); + } else { + a.push(statement(startLine === nexttoken.line)); + } + } + return a; + } + + + /* + * read all directives + * recognizes a simple form of asi, but always + * warns, if it is used + */ + function directives() { + var i, p, pn; + + for (;;) { + if (nexttoken.id === "(string)") { + p = peek(0); + if (p.id === "(endline)") { + i = 1; + do { + pn = peek(i); + i = i + 1; + } while (pn.id === "(endline)"); + + if (pn.id !== ";") { + if (pn.id !== "(string)" && pn.id !== "(number)" && + pn.id !== "(regexp)" && pn.identifier !== true && + pn.id !== "}") { + break; + } + warning("Missing semicolon.", nexttoken); + } else { + p = pn; + } + } else if (p.id === "}") { + // directive with no other statements, warn about missing semicolon + warning("Missing semicolon.", p); + } else if (p.id !== ";") { + break; + } + + indentation(); + advance(); + if (directive[token.value]) { + warning("Unnecessary directive \"{a}\".", token, token.value); + } + + if (token.value === "use strict") { + option.newcap = true; + option.undef = true; + } + + // there's no directive negation, so always set to true + directive[token.value] = true; + + if (p.id === ";") { + advance(";"); + } + continue; + } + break; + } + } + + + /* + * Parses a single block. A block is a sequence of statements wrapped in + * braces. + * + * ordinary - true for everything but function bodies and try blocks. + * stmt - true if block can be a single statement (e.g. in if/for/while). + * isfunc - true if block is a function body + */ + function block(ordinary, stmt, isfunc) { + var a, + b = inblock, + old_indent = indent, + m, + s = scope, + t, + line, + d; + + inblock = ordinary; + if (!ordinary || !option.funcscope) scope = Object.create(scope); + nonadjacent(token, nexttoken); + t = nexttoken; + + if (nexttoken.id === '{') { + advance('{'); + line = token.line; + if (nexttoken.id !== '}') { + indent += option.indent; + while (!ordinary && nexttoken.from > indent) { + indent += option.indent; + } + + if (isfunc) { + m = {}; + for (d in directive) { + if (is_own(directive, d)) { + m[d] = directive[d]; + } + } + directives(); + + if (option.strict && funct['(context)']['(global)']) { + if (!m["use strict"] && !directive["use strict"]) { + warning("Missing \"use strict\" statement."); + } + } + } + + a = statements(line); + + if (isfunc) { + directive = m; + } + + indent -= option.indent; + if (line !== nexttoken.line) { + indentation(); + } + } else if (line !== nexttoken.line) { + indentation(); + } + advance('}', t); + indent = old_indent; + } else if (!ordinary) { + error("Expected '{a}' and instead saw '{b}'.", + nexttoken, '{', nexttoken.value); + } else { + if (!stmt || option.curly) + warning("Expected '{a}' and instead saw '{b}'.", + nexttoken, '{', nexttoken.value); + + noreach = true; + indent += option.indent; + // test indentation only if statement is in new line + a = [statement(nexttoken.line === token.line)]; + indent -= option.indent; + noreach = false; + } + funct['(verb)'] = null; + if (!ordinary || !option.funcscope) scope = s; + inblock = b; + if (ordinary && option.noempty && (!a || a.length === 0)) { + warning("Empty block."); + } + return a; + } + + + function countMember(m) { + if (membersOnly && typeof membersOnly[m] !== 'boolean') { + warning("Unexpected /*member '{a}'.", token, m); + } + if (typeof member[m] === 'number') { + member[m] += 1; + } else { + member[m] = 1; + } + } + + + function note_implied(token) { + var name = token.value, line = token.line, a = implied[name]; + if (typeof a === 'function') { + a = false; + } + + if (!a) { + a = [line]; + implied[name] = a; + } else if (a[a.length - 1] !== line) { + a.push(line); + } + } + + + // Build the syntax table by declaring the syntactic elements of the language. + + type('(number)', function () { + return this; + }); + + type('(string)', function () { + return this; + }); + + syntax['(identifier)'] = { + type: '(identifier)', + lbp: 0, + identifier: true, + nud: function () { + var v = this.value, + s = scope[v], + f; + + if (typeof s === 'function') { + // Protection against accidental inheritance. + s = undefined; + } else if (typeof s === 'boolean') { + f = funct; + funct = functions[0]; + addlabel(v, 'var'); + s = funct; + funct = f; + } + + // The name is in scope and defined in the current function. + if (funct === s) { + // Change 'unused' to 'var', and reject labels. + switch (funct[v]) { + case 'unused': + funct[v] = 'var'; + break; + case 'unction': + funct[v] = 'function'; + this['function'] = true; + break; + case 'function': + this['function'] = true; + break; + case 'label': + warning("'{a}' is a statement label.", token, v); + break; + } + } else if (funct['(global)']) { + // The name is not defined in the function. If we are in the global + // scope, then we have an undefined variable. + // + // Operators typeof and delete do not raise runtime errors even if + // the base object of a reference is null so no need to display warning + // if we're inside of typeof or delete. + + if (option.undef && typeof predefined[v] !== 'boolean') { + // Attempting to subscript a null reference will throw an + // error, even within the typeof and delete operators + if (!(anonname === 'typeof' || anonname === 'delete') || + (nexttoken && (nexttoken.value === '.' || nexttoken.value === '['))) { + + isundef(funct, "'{a}' is not defined.", token, v); + } + } + note_implied(token); + } else { + // If the name is already defined in the current + // function, but not as outer, then there is a scope error. + + switch (funct[v]) { + case 'closure': + case 'function': + case 'var': + case 'unused': + warning("'{a}' used out of scope.", token, v); + break; + case 'label': + warning("'{a}' is a statement label.", token, v); + break; + case 'outer': + case 'global': + break; + default: + // If the name is defined in an outer function, make an outer entry, + // and if it was unused, make it var. + if (s === true) { + funct[v] = true; + } else if (s === null) { + warning("'{a}' is not allowed.", token, v); + note_implied(token); + } else if (typeof s !== 'object') { + // Operators typeof and delete do not raise runtime errors even + // if the base object of a reference is null so no need to + // display warning if we're inside of typeof or delete. + if (option.undef) { + // Attempting to subscript a null reference will throw an + // error, even within the typeof and delete operators + if (!(anonname === 'typeof' || anonname === 'delete') || + (nexttoken && + (nexttoken.value === '.' || nexttoken.value === '['))) { + + isundef(funct, "'{a}' is not defined.", token, v); + } + } + funct[v] = true; + note_implied(token); + } else { + switch (s[v]) { + case 'function': + case 'unction': + this['function'] = true; + s[v] = 'closure'; + funct[v] = s['(global)'] ? 'global' : 'outer'; + break; + case 'var': + case 'unused': + s[v] = 'closure'; + funct[v] = s['(global)'] ? 'global' : 'outer'; + break; + case 'closure': + case 'parameter': + funct[v] = s['(global)'] ? 'global' : 'outer'; + break; + case 'label': + warning("'{a}' is a statement label.", token, v); + } + } + } + } + return this; + }, + led: function () { + error("Expected an operator and instead saw '{a}'.", + nexttoken, nexttoken.value); + } + }; + + type('(regexp)', function () { + return this; + }); + + +// ECMAScript parser + + delim('(endline)'); + delim('(begin)'); + delim('(end)').reach = true; + delim(''); + delim('(error)').reach = true; + delim('}').reach = true; + delim(')'); + delim(']'); + delim('"').reach = true; + delim("'").reach = true; + delim(';'); + delim(':').reach = true; + delim(','); + delim('#'); + delim('@'); + reserve('else'); + reserve('case').reach = true; + reserve('catch'); + reserve('default').reach = true; + reserve('finally'); + reservevar('arguments', function (x) { + if (directive['use strict'] && funct['(global)']) { + warning("Strict violation.", x); + } + }); + reservevar('eval'); + reservevar('false'); + reservevar('Infinity'); + reservevar('NaN'); + reservevar('null'); + reservevar('this', function (x) { + if (directive['use strict'] && !option.validthis && ((funct['(statement)'] && + funct['(name)'].charAt(0) > 'Z') || funct['(global)'])) { + warning("Possible strict violation.", x); + } + }); + reservevar('true'); + reservevar('undefined'); + assignop('=', 'assign', 20); + assignop('+=', 'assignadd', 20); + assignop('-=', 'assignsub', 20); + assignop('*=', 'assignmult', 20); + assignop('/=', 'assigndiv', 20).nud = function () { + error("A regular expression literal can be confused with '/='."); + }; + assignop('%=', 'assignmod', 20); + bitwiseassignop('&=', 'assignbitand', 20); + bitwiseassignop('|=', 'assignbitor', 20); + bitwiseassignop('^=', 'assignbitxor', 20); + bitwiseassignop('<<=', 'assignshiftleft', 20); + bitwiseassignop('>>=', 'assignshiftright', 20); + bitwiseassignop('>>>=', 'assignshiftrightunsigned', 20); + infix('?', function (left, that) { + that.left = left; + that.right = expression(10); + advance(':'); + that['else'] = expression(10); + return that; + }, 30); + + infix('||', 'or', 40); + infix('&&', 'and', 50); + bitwise('|', 'bitor', 70); + bitwise('^', 'bitxor', 80); + bitwise('&', 'bitand', 90); + relation('==', function (left, right) { + var eqnull = option.eqnull && (left.value === 'null' || right.value === 'null'); + + if (!eqnull && option.eqeqeq) + warning("Expected '{a}' and instead saw '{b}'.", this, '===', '=='); + else if (isPoorRelation(left)) + warning("Use '{a}' to compare with '{b}'.", this, '===', left.value); + else if (isPoorRelation(right)) + warning("Use '{a}' to compare with '{b}'.", this, '===', right.value); + + return this; + }); + relation('==='); + relation('!=', function (left, right) { + var eqnull = option.eqnull && + (left.value === 'null' || right.value === 'null'); + + if (!eqnull && option.eqeqeq) { + warning("Expected '{a}' and instead saw '{b}'.", + this, '!==', '!='); + } else if (isPoorRelation(left)) { + warning("Use '{a}' to compare with '{b}'.", + this, '!==', left.value); + } else if (isPoorRelation(right)) { + warning("Use '{a}' to compare with '{b}'.", + this, '!==', right.value); + } + return this; + }); + relation('!=='); + relation('<'); + relation('>'); + relation('<='); + relation('>='); + bitwise('<<', 'shiftleft', 120); + bitwise('>>', 'shiftright', 120); + bitwise('>>>', 'shiftrightunsigned', 120); + infix('in', 'in', 120); + infix('instanceof', 'instanceof', 120); + infix('+', function (left, that) { + var right = expression(130); + if (left && right && left.id === '(string)' && right.id === '(string)') { + left.value += right.value; + left.character = right.character; + if (!option.scripturl && jx.test(left.value)) { + warning("JavaScript URL.", left); + } + return left; + } + that.left = left; + that.right = right; + return that; + }, 130); + prefix('+', 'num'); + prefix('+++', function () { + warning("Confusing pluses."); + this.right = expression(150); + this.arity = 'unary'; + return this; + }); + infix('+++', function (left) { + warning("Confusing pluses."); + this.left = left; + this.right = expression(130); + return this; + }, 130); + infix('-', 'sub', 130); + prefix('-', 'neg'); + prefix('---', function () { + warning("Confusing minuses."); + this.right = expression(150); + this.arity = 'unary'; + return this; + }); + infix('---', function (left) { + warning("Confusing minuses."); + this.left = left; + this.right = expression(130); + return this; + }, 130); + infix('*', 'mult', 140); + infix('/', 'div', 140); + infix('%', 'mod', 140); + + suffix('++', 'postinc'); + prefix('++', 'preinc'); + syntax['++'].exps = true; + + suffix('--', 'postdec'); + prefix('--', 'predec'); + syntax['--'].exps = true; + prefix('delete', function () { + var p = expression(0); + if (!p || (p.id !== '.' && p.id !== '[')) { + warning("Variables should not be deleted."); + } + this.first = p; + return this; + }).exps = true; + + prefix('~', function () { + if (option.bitwise) { + warning("Unexpected '{a}'.", this, '~'); + } + expression(150); + return this; + }); + + prefix('!', function () { + this.right = expression(150); + this.arity = 'unary'; + if (bang[this.right.id] === true) { + warning("Confusing use of '{a}'.", this, '!'); + } + return this; + }); + prefix('typeof', 'typeof'); + prefix('new', function () { + var c = expression(155), i; + if (c && c.id !== 'function') { + if (c.identifier) { + c['new'] = true; + switch (c.value) { + case 'Object': + warning("Use the object literal notation {}.", token); + break; + case 'Number': + case 'String': + case 'Boolean': + case 'Math': + case 'JSON': + warning("Do not use {a} as a constructor.", token, c.value); + break; + case 'Function': + if (!option.evil) { + warning("The Function constructor is eval."); + } + break; + case 'Date': + case 'RegExp': + break; + default: + if (c.id !== 'function') { + i = c.value.substr(0, 1); + if (option.newcap && (i < 'A' || i > 'Z')) { + warning("A constructor name should start with an uppercase letter.", + token); + } + } + } + } else { + if (c.id !== '.' && c.id !== '[' && c.id !== '(') { + warning("Bad constructor.", token); + } + } + } else { + if (!option.supernew) + warning("Weird construction. Delete 'new'.", this); + } + adjacent(token, nexttoken); + if (nexttoken.id !== '(' && !option.supernew) { + warning("Missing '()' invoking a constructor."); + } + this.first = c; + return this; + }); + syntax['new'].exps = true; + + prefix('void').exps = true; + + infix('.', function (left, that) { + adjacent(prevtoken, token); + nobreak(); + var m = identifier(); + if (typeof m === 'string') { + countMember(m); + } + that.left = left; + that.right = m; + if (left && left.value === 'arguments' && (m === 'callee' || m === 'caller')) { + if (option.noarg) + warning("Avoid arguments.{a}.", left, m); + else if (directive['use strict']) + error('Strict violation.'); + } else if (!option.evil && left && left.value === 'document' && + (m === 'write' || m === 'writeln')) { + warning("document.write can be a form of eval.", left); + } + if (!option.evil && (m === 'eval' || m === 'execScript')) { + warning('eval is evil.'); + } + return that; + }, 160, true); + + infix('(', function (left, that) { + if (prevtoken.id !== '}' && prevtoken.id !== ')') { + nobreak(prevtoken, token); + } + nospace(); + if (option.immed && !left.immed && left.id === 'function') { + warning("Wrap an immediate function invocation in parentheses " + + "to assist the reader in understanding that the expression " + + "is the result of a function, and not the function itself."); + } + var n = 0, + p = []; + if (left) { + if (left.type === '(identifier)') { + if (left.value.match(/^[A-Z]([A-Z0-9_$]*[a-z][A-Za-z0-9_$]*)?$/)) { + if (left.value !== 'Number' && left.value !== 'String' && + left.value !== 'Boolean' && + left.value !== 'Date') { + if (left.value === 'Math') { + warning("Math is not a function.", left); + } else if (option.newcap) { + warning( +"Missing 'new' prefix when invoking a constructor.", left); + } + } + } + } + } + if (nexttoken.id !== ')') { + for (;;) { + p[p.length] = expression(10); + n += 1; + if (nexttoken.id !== ',') { + break; + } + comma(); + } + } + advance(')'); + nospace(prevtoken, token); + if (typeof left === 'object') { + if (left.value === 'parseInt' && n === 1) { + warning("Missing radix parameter.", left); + } + if (!option.evil) { + if (left.value === 'eval' || left.value === 'Function' || + left.value === 'execScript') { + warning("eval is evil.", left); + } else if (p[0] && p[0].id === '(string)' && + (left.value === 'setTimeout' || + left.value === 'setInterval')) { + warning( + "Implied eval is evil. Pass a function instead of a string.", left); + } + } + if (!left.identifier && left.id !== '.' && left.id !== '[' && + left.id !== '(' && left.id !== '&&' && left.id !== '||' && + left.id !== '?') { + warning("Bad invocation.", left); + } + } + that.left = left; + return that; + }, 155, true).exps = true; + + prefix('(', function () { + nospace(); + if (nexttoken.id === 'function') { + nexttoken.immed = true; + } + var v = expression(0); + advance(')', this); + nospace(prevtoken, token); + if (option.immed && v.id === 'function') { + if (nexttoken.id === '(' || + (nexttoken.id === '.' && (peek().value === 'call' || peek().value === 'apply'))) { + warning( +"Move the invocation into the parens that contain the function.", nexttoken); + } else { + warning( +"Do not wrap function literals in parens unless they are to be immediately invoked.", + this); + } + } + return v; + }); + + infix('[', function (left, that) { + nobreak(prevtoken, token); + nospace(); + var e = expression(0), s; + if (e && e.type === '(string)') { + if (!option.evil && (e.value === 'eval' || e.value === 'execScript')) { + warning("eval is evil.", that); + } + countMember(e.value); + if (!option.sub && ix.test(e.value)) { + s = syntax[e.value]; + if (!s || !s.reserved) { + warning("['{a}'] is better written in dot notation.", + e, e.value); + } + } + } + advance(']', that); + nospace(prevtoken, token); + that.left = left; + that.right = e; + return that; + }, 160, true); + + prefix('[', function () { + var b = token.line !== nexttoken.line; + this.first = []; + if (b) { + indent += option.indent; + if (nexttoken.from === indent + option.indent) { + indent += option.indent; + } + } + while (nexttoken.id !== '(end)') { + while (nexttoken.id === ',') { + warning("Extra comma."); + advance(','); + } + if (nexttoken.id === ']') { + break; + } + if (b && token.line !== nexttoken.line) { + indentation(); + } + this.first.push(expression(10)); + if (nexttoken.id === ',') { + comma(); + if (nexttoken.id === ']' && !option.es5) { + warning("Extra comma.", token); + break; + } + } else { + break; + } + } + if (b) { + indent -= option.indent; + indentation(); + } + advance(']', this); + return this; + }, 160); + + + function property_name() { + var id = optionalidentifier(true); + if (!id) { + if (nexttoken.id === '(string)') { + id = nexttoken.value; + advance(); + } else if (nexttoken.id === '(number)') { + id = nexttoken.value.toString(); + advance(); + } + } + return id; + } + + + function functionparams() { + var i, t = nexttoken, p = []; + advance('('); + nospace(); + if (nexttoken.id === ')') { + advance(')'); + return; + } + for (;;) { + i = identifier(true); + p.push(i); + addlabel(i, 'parameter'); + if (nexttoken.id === ',') { + comma(); + } else { + advance(')', t); + nospace(prevtoken, token); + return p; + } + } + } + + + function doFunction(i, statement) { + var f, + oldOption = option, + oldScope = scope; + + option = Object.create(option); + scope = Object.create(scope); + + funct = { + '(name)' : i || '"' + anonname + '"', + '(line)' : nexttoken.line, + '(context)' : funct, + '(breakage)' : 0, + '(loopage)' : 0, + '(scope)' : scope, + '(statement)': statement + }; + f = funct; + token.funct = funct; + functions.push(funct); + if (i) { + addlabel(i, 'function'); + } + funct['(params)'] = functionparams(); + + block(false, false, true); + scope = oldScope; + option = oldOption; + funct['(last)'] = token.line; + funct = funct['(context)']; + return f; + } + + + (function (x) { + x.nud = function () { + var b, f, i, j, p, t; + var props = {}; // All properties, including accessors + + function saveProperty(name, token) { + if (props[name] && is_own(props, name)) + warning("Duplicate member '{a}'.", nexttoken, i); + else + props[name] = {}; + + props[name].basic = true; + props[name].basicToken = token; + } + + function saveSetter(name, token) { + if (props[name] && is_own(props, name)) { + if (props[name].basic || props[name].setter) + warning("Duplicate member '{a}'.", nexttoken, i); + } else { + props[name] = {}; + } + + props[name].setter = true; + props[name].setterToken = token; + } + + function saveGetter(name) { + if (props[name] && is_own(props, name)) { + if (props[name].basic || props[name].getter) + warning("Duplicate member '{a}'.", nexttoken, i); + } else { + props[name] = {}; + } + + props[name].getter = true; + props[name].getterToken = token; + } + + b = token.line !== nexttoken.line; + if (b) { + indent += option.indent; + if (nexttoken.from === indent + option.indent) { + indent += option.indent; + } + } + for (;;) { + if (nexttoken.id === '}') { + break; + } + if (b) { + indentation(); + } + if (nexttoken.value === 'get' && peek().id !== ':') { + advance('get'); + if (!option.es5) { + error("get/set are ES5 features."); + } + i = property_name(); + if (!i) { + error("Missing property name."); + } + saveGetter(i); + t = nexttoken; + adjacent(token, nexttoken); + f = doFunction(); + p = f['(params)']; + if (p) { + warning("Unexpected parameter '{a}' in get {b} function.", t, p[0], i); + } + adjacent(token, nexttoken); + } else if (nexttoken.value === 'set' && peek().id !== ':') { + advance('set'); + if (!option.es5) { + error("get/set are ES5 features."); + } + i = property_name(); + if (!i) { + error("Missing property name."); + } + saveSetter(i, nexttoken); + t = nexttoken; + adjacent(token, nexttoken); + f = doFunction(); + p = f['(params)']; + if (!p || p.length !== 1) { + warning("Expected a single parameter in set {a} function.", t, i); + } + } else { + i = property_name(); + saveProperty(i, nexttoken); + if (typeof i !== 'string') { + break; + } + advance(':'); + nonadjacent(token, nexttoken); + expression(10); + } + + countMember(i); + if (nexttoken.id === ',') { + comma(); + if (nexttoken.id === ',') { + warning("Extra comma.", token); + } else if (nexttoken.id === '}' && !option.es5) { + warning("Extra comma.", token); + } + } else { + break; + } + } + if (b) { + indent -= option.indent; + indentation(); + } + advance('}', this); + + // Check for lonely setters if in the ES5 mode. + if (option.es5) { + for (var name in props) { + if (is_own(props, name) && props[name].setter && !props[name].getter) { + warning("Setter is defined without getter.", props[name].setterToken); + } + } + } + return this; + }; + x.fud = function () { + error("Expected to see a statement and instead saw a block.", token); + }; + }(delim('{'))); + +// This Function is called when esnext option is set to true +// it adds the `const` statement to JSHINT + + useESNextSyntax = function () { + var conststatement = stmt('const', function (prefix) { + var id, name, value; + + this.first = []; + for (;;) { + nonadjacent(token, nexttoken); + id = identifier(); + if (funct[id] === "const") { + warning("const '" + id + "' has already been declared"); + } + if (funct['(global)'] && predefined[id] === false) { + warning("Redefinition of '{a}'.", token, id); + } + addlabel(id, 'const'); + if (prefix) { + break; + } + name = token; + this.first.push(token); + + if (nexttoken.id !== "=") { + warning("const " + + "'{a}' is initialized to 'undefined'.", token, id); + } + + if (nexttoken.id === '=') { + nonadjacent(token, nexttoken); + advance('='); + nonadjacent(token, nexttoken); + if (nexttoken.id === 'undefined') { + warning("It is not necessary to initialize " + + "'{a}' to 'undefined'.", token, id); + } + if (peek(0).id === '=' && nexttoken.identifier) { + error("Constant {a} was not declared correctly.", + nexttoken, nexttoken.value); + } + value = expression(0); + name.first = value; + } + + if (nexttoken.id !== ',') { + break; + } + comma(); + } + return this; + }); + conststatement.exps = true; + }; + + var varstatement = stmt('var', function (prefix) { + // JavaScript does not have block scope. It only has function scope. So, + // declaring a variable in a block can have unexpected consequences. + var id, name, value; + + if (funct['(onevar)'] && option.onevar) { + warning("Too many var statements."); + } else if (!funct['(global)']) { + funct['(onevar)'] = true; + } + this.first = []; + for (;;) { + nonadjacent(token, nexttoken); + id = identifier(); + if (option.esnext && funct[id] === "const") { + warning("const '" + id + "' has already been declared"); + } + if (funct['(global)'] && predefined[id] === false) { + warning("Redefinition of '{a}'.", token, id); + } + addlabel(id, 'unused'); + if (prefix) { + break; + } + name = token; + this.first.push(token); + if (nexttoken.id === '=') { + nonadjacent(token, nexttoken); + advance('='); + nonadjacent(token, nexttoken); + if (nexttoken.id === 'undefined') { + warning("It is not necessary to initialize '{a}' to 'undefined'.", token, id); + } + if (peek(0).id === '=' && nexttoken.identifier) { + error("Variable {a} was not declared correctly.", + nexttoken, nexttoken.value); + } + value = expression(0); + name.first = value; + } + if (nexttoken.id !== ',') { + break; + } + comma(); + } + return this; + }); + varstatement.exps = true; + + blockstmt('function', function () { + if (inblock) { + warning("Function declarations should not be placed in blocks. " + + "Use a function expression or move the statement to the top of " + + "the outer function.", token); + + } + var i = identifier(); + if (option.esnext && funct[i] === "const") { + warning("const '" + i + "' has already been declared"); + } + adjacent(token, nexttoken); + addlabel(i, 'unction'); + doFunction(i, true); + if (nexttoken.id === '(' && nexttoken.line === token.line) { + error( +"Function declarations are not invocable. Wrap the whole function invocation in parens."); + } + return this; + }); + + prefix('function', function () { + var i = optionalidentifier(); + if (i) { + adjacent(token, nexttoken); + } else { + nonadjacent(token, nexttoken); + } + doFunction(i); + if (!option.loopfunc && funct['(loopage)']) { + warning("Don't make functions within a loop."); + } + return this; + }); + + blockstmt('if', function () { + var t = nexttoken; + advance('('); + nonadjacent(this, t); + nospace(); + expression(20); + if (nexttoken.id === '=') { + if (!option.boss) + warning("Expected a conditional expression and instead saw an assignment."); + advance('='); + expression(20); + } + advance(')', t); + nospace(prevtoken, token); + block(true, true); + if (nexttoken.id === 'else') { + nonadjacent(token, nexttoken); + advance('else'); + if (nexttoken.id === 'if' || nexttoken.id === 'switch') { + statement(true); + } else { + block(true, true); + } + } + return this; + }); + + blockstmt('try', function () { + var b, e, s; + + block(false); + if (nexttoken.id === 'catch') { + advance('catch'); + nonadjacent(token, nexttoken); + advance('('); + s = scope; + scope = Object.create(s); + e = nexttoken.value; + if (nexttoken.type !== '(identifier)') { + warning("Expected an identifier and instead saw '{a}'.", + nexttoken, e); + } else { + addlabel(e, 'exception'); + } + advance(); + advance(')'); + block(false); + b = true; + scope = s; + } + if (nexttoken.id === 'finally') { + advance('finally'); + block(false); + return; + } else if (!b) { + error("Expected '{a}' and instead saw '{b}'.", + nexttoken, 'catch', nexttoken.value); + } + return this; + }); + + blockstmt('while', function () { + var t = nexttoken; + funct['(breakage)'] += 1; + funct['(loopage)'] += 1; + advance('('); + nonadjacent(this, t); + nospace(); + expression(20); + if (nexttoken.id === '=') { + if (!option.boss) + warning("Expected a conditional expression and instead saw an assignment."); + advance('='); + expression(20); + } + advance(')', t); + nospace(prevtoken, token); + block(true, true); + funct['(breakage)'] -= 1; + funct['(loopage)'] -= 1; + return this; + }).labelled = true; + + reserve('with'); + + blockstmt('switch', function () { + var t = nexttoken, + g = false; + funct['(breakage)'] += 1; + advance('('); + nonadjacent(this, t); + nospace(); + this.condition = expression(20); + advance(')', t); + nospace(prevtoken, token); + nonadjacent(token, nexttoken); + t = nexttoken; + advance('{'); + nonadjacent(token, nexttoken); + indent += option.indent; + this.cases = []; + for (;;) { + switch (nexttoken.id) { + case 'case': + switch (funct['(verb)']) { + case 'break': + case 'case': + case 'continue': + case 'return': + case 'switch': + case 'throw': + break; + default: + // You can tell JSHint that you don't use break intentionally by + // adding a comment /* falls through */ on a line just before + // the next `case`. + if (!ft.test(lines[nexttoken.line - 2])) { + warning( + "Expected a 'break' statement before 'case'.", + token); + } + } + indentation(-option.indent); + advance('case'); + this.cases.push(expression(20)); + g = true; + advance(':'); + funct['(verb)'] = 'case'; + break; + case 'default': + switch (funct['(verb)']) { + case 'break': + case 'continue': + case 'return': + case 'throw': + break; + default: + if (!ft.test(lines[nexttoken.line - 2])) { + warning( + "Expected a 'break' statement before 'default'.", + token); + } + } + indentation(-option.indent); + advance('default'); + g = true; + advance(':'); + break; + case '}': + indent -= option.indent; + indentation(); + advance('}', t); + if (this.cases.length === 1 || this.condition.id === 'true' || + this.condition.id === 'false') { + if (!option.onecase) + warning("This 'switch' should be an 'if'.", this); + } + funct['(breakage)'] -= 1; + funct['(verb)'] = undefined; + return; + case '(end)': + error("Missing '{a}'.", nexttoken, '}'); + return; + default: + if (g) { + switch (token.id) { + case ',': + error("Each value should have its own case label."); + return; + case ':': + g = false; + statements(); + break; + default: + error("Missing ':' on a case clause.", token); + return; + } + } else { + if (token.id === ':') { + advance(':'); + error("Unexpected '{a}'.", token, ':'); + statements(); + } else { + error("Expected '{a}' and instead saw '{b}'.", + nexttoken, 'case', nexttoken.value); + return; + } + } + } + } + }).labelled = true; + + stmt('debugger', function () { + if (!option.debug) { + warning("All 'debugger' statements should be removed."); + } + return this; + }).exps = true; + + (function () { + var x = stmt('do', function () { + funct['(breakage)'] += 1; + funct['(loopage)'] += 1; + this.first = block(true); + advance('while'); + var t = nexttoken; + nonadjacent(token, t); + advance('('); + nospace(); + expression(20); + if (nexttoken.id === '=') { + if (!option.boss) + warning("Expected a conditional expression and instead saw an assignment."); + advance('='); + expression(20); + } + advance(')', t); + nospace(prevtoken, token); + funct['(breakage)'] -= 1; + funct['(loopage)'] -= 1; + return this; + }); + x.labelled = true; + x.exps = true; + }()); + + blockstmt('for', function () { + var s, t = nexttoken; + funct['(breakage)'] += 1; + funct['(loopage)'] += 1; + advance('('); + nonadjacent(this, t); + nospace(); + if (peek(nexttoken.id === 'var' ? 1 : 0).id === 'in') { + if (nexttoken.id === 'var') { + advance('var'); + varstatement.fud.call(varstatement, true); + } else { + switch (funct[nexttoken.value]) { + case 'unused': + funct[nexttoken.value] = 'var'; + break; + case 'var': + break; + default: + warning("Bad for in variable '{a}'.", + nexttoken, nexttoken.value); + } + advance(); + } + advance('in'); + expression(20); + advance(')', t); + s = block(true, true); + if (option.forin && s && (s.length > 1 || typeof s[0] !== 'object' || + s[0].value !== 'if')) { + warning("The body of a for in should be wrapped in an if statement to filter " + + "unwanted properties from the prototype.", this); + } + funct['(breakage)'] -= 1; + funct['(loopage)'] -= 1; + return this; + } else { + if (nexttoken.id !== ';') { + if (nexttoken.id === 'var') { + advance('var'); + varstatement.fud.call(varstatement); + } else { + for (;;) { + expression(0, 'for'); + if (nexttoken.id !== ',') { + break; + } + comma(); + } + } + } + nolinebreak(token); + advance(';'); + if (nexttoken.id !== ';') { + expression(20); + if (nexttoken.id === '=') { + if (!option.boss) + warning("Expected a conditional expression and instead saw an assignment."); + advance('='); + expression(20); + } + } + nolinebreak(token); + advance(';'); + if (nexttoken.id === ';') { + error("Expected '{a}' and instead saw '{b}'.", + nexttoken, ')', ';'); + } + if (nexttoken.id !== ')') { + for (;;) { + expression(0, 'for'); + if (nexttoken.id !== ',') { + break; + } + comma(); + } + } + advance(')', t); + nospace(prevtoken, token); + block(true, true); + funct['(breakage)'] -= 1; + funct['(loopage)'] -= 1; + return this; + } + }).labelled = true; + + + stmt('break', function () { + var v = nexttoken.value; + + if (funct['(breakage)'] === 0) + warning("Unexpected '{a}'.", nexttoken, this.value); + + if (!option.asi) + nolinebreak(this); + + if (nexttoken.id !== ';') { + if (token.line === nexttoken.line) { + if (funct[v] !== 'label') { + warning("'{a}' is not a statement label.", nexttoken, v); + } else if (scope[v] !== funct) { + warning("'{a}' is out of scope.", nexttoken, v); + } + this.first = nexttoken; + advance(); + } + } + reachable('break'); + return this; + }).exps = true; + + + stmt('continue', function () { + var v = nexttoken.value; + + if (funct['(breakage)'] === 0) + warning("Unexpected '{a}'.", nexttoken, this.value); + + if (!option.asi) + nolinebreak(this); + + if (nexttoken.id !== ';') { + if (token.line === nexttoken.line) { + if (funct[v] !== 'label') { + warning("'{a}' is not a statement label.", nexttoken, v); + } else if (scope[v] !== funct) { + warning("'{a}' is out of scope.", nexttoken, v); + } + this.first = nexttoken; + advance(); + } + } else if (!funct['(loopage)']) { + warning("Unexpected '{a}'.", nexttoken, this.value); + } + reachable('continue'); + return this; + }).exps = true; + + + stmt('return', function () { + if (this.line === nexttoken.line) { + if (nexttoken.id === '(regexp)') + warning("Wrap the /regexp/ literal in parens to disambiguate the slash operator."); + + if (nexttoken.id !== ';' && !nexttoken.reach) { + nonadjacent(token, nexttoken); + if (peek().value === "=" && !option.boss) { + warningAt("Did you mean to return a conditional instead of an assignment?", + token.line, token.character + 1); + } + this.first = expression(0); + } + } else if (!option.asi) { + nolinebreak(this); // always warn (Line breaking error) + } + reachable('return'); + return this; + }).exps = true; + + + stmt('throw', function () { + nolinebreak(this); + nonadjacent(token, nexttoken); + this.first = expression(20); + reachable('throw'); + return this; + }).exps = true; + +// Superfluous reserved words + + reserve('class'); + reserve('const'); + reserve('enum'); + reserve('export'); + reserve('extends'); + reserve('import'); + reserve('super'); + + reserve('let'); + reserve('yield'); + reserve('implements'); + reserve('interface'); + reserve('package'); + reserve('private'); + reserve('protected'); + reserve('public'); + reserve('static'); + + +// Parse JSON + + function jsonValue() { + + function jsonObject() { + var o = {}, t = nexttoken; + advance('{'); + if (nexttoken.id !== '}') { + for (;;) { + if (nexttoken.id === '(end)') { + error("Missing '}' to match '{' from line {a}.", + nexttoken, t.line); + } else if (nexttoken.id === '}') { + warning("Unexpected comma.", token); + break; + } else if (nexttoken.id === ',') { + error("Unexpected comma.", nexttoken); + } else if (nexttoken.id !== '(string)') { + warning("Expected a string and instead saw {a}.", + nexttoken, nexttoken.value); + } + if (o[nexttoken.value] === true) { + warning("Duplicate key '{a}'.", + nexttoken, nexttoken.value); + } else if ((nexttoken.value === '__proto__' && + !option.proto) || (nexttoken.value === '__iterator__' && + !option.iterator)) { + warning("The '{a}' key may produce unexpected results.", + nexttoken, nexttoken.value); + } else { + o[nexttoken.value] = true; + } + advance(); + advance(':'); + jsonValue(); + if (nexttoken.id !== ',') { + break; + } + advance(','); + } + } + advance('}'); + } + + function jsonArray() { + var t = nexttoken; + advance('['); + if (nexttoken.id !== ']') { + for (;;) { + if (nexttoken.id === '(end)') { + error("Missing ']' to match '[' from line {a}.", + nexttoken, t.line); + } else if (nexttoken.id === ']') { + warning("Unexpected comma.", token); + break; + } else if (nexttoken.id === ',') { + error("Unexpected comma.", nexttoken); + } + jsonValue(); + if (nexttoken.id !== ',') { + break; + } + advance(','); + } + } + advance(']'); + } + + switch (nexttoken.id) { + case '{': + jsonObject(); + break; + case '[': + jsonArray(); + break; + case 'true': + case 'false': + case 'null': + case '(number)': + case '(string)': + advance(); + break; + case '-': + advance('-'); + if (token.character !== nexttoken.from) { + warning("Unexpected space after '-'.", token); + } + adjacent(token, nexttoken); + advance('(number)'); + break; + default: + error("Expected a JSON value.", nexttoken); + } + } + + +// The actual JSHINT function itself. + + var itself = function (s, o, g) { + var a, i, k; + JSHINT.errors = []; + JSHINT.undefs = []; + predefined = Object.create(standard); + combine(predefined, g || {}); + if (o) { + a = o.predef; + if (a) { + if (Array.isArray(a)) { + for (i = 0; i < a.length; i += 1) { + predefined[a[i]] = true; + } + } else if (typeof a === 'object') { + k = Object.keys(a); + for (i = 0; i < k.length; i += 1) { + predefined[k[i]] = !!a[k[i]]; + } + } + } + option = o; + } else { + option = {}; + } + option.indent = option.indent || 4; + option.maxerr = option.maxerr || 50; + + tab = ''; + for (i = 0; i < option.indent; i += 1) { + tab += ' '; + } + indent = 1; + global = Object.create(predefined); + scope = global; + funct = { + '(global)': true, + '(name)': '(global)', + '(scope)': scope, + '(breakage)': 0, + '(loopage)': 0 + }; + functions = [funct]; + urls = []; + stack = null; + member = {}; + membersOnly = null; + implied = {}; + inblock = false; + lookahead = []; + jsonmode = false; + warnings = 0; + lex.init(s); + prereg = true; + directive = {}; + + prevtoken = token = nexttoken = syntax['(begin)']; + assume(); + + // combine the passed globals after we've assumed all our options + combine(predefined, g || {}); + + try { + advance(); + switch (nexttoken.id) { + case '{': + case '[': + option.laxbreak = true; + jsonmode = true; + jsonValue(); + break; + default: + directives(); + if (directive["use strict"] && !option.globalstrict) { + warning("Use the function form of \"use strict\".", prevtoken); + } + + statements(); + } + advance('(end)'); + + var markDefined = function (name, context) { + do { + if (typeof context[name] === 'string') { + // JSHINT marks unused variables as 'unused' and + // unused function declaration as 'unction'. This + // code changes such instances back 'var' and + // 'closure' so that the code in JSHINT.data() + // doesn't think they're unused. + + if (context[name] === 'unused') + context[name] = 'var'; + else if (context[name] === 'unction') + context[name] = 'closure'; + + return true; + } + + context = context['(context)']; + } while (context); + + return false; + }; + + var clearImplied = function (name, line) { + if (!implied[name]) + return; + + var newImplied = []; + for (var i = 0; i < implied[name].length; i += 1) { + if (implied[name][i] !== line) + newImplied.push(implied[name][i]); + } + + if (newImplied.length === 0) + delete implied[name]; + else + implied[name] = newImplied; + }; + + // Check queued 'x is not defined' instances to see if they're still undefined. + for (i = 0; i < JSHINT.undefs.length; i += 1) { + k = JSHINT.undefs[i].slice(0); + + if (markDefined(k[2].value, k[0])) { + clearImplied(k[2].value, k[2].line); + } else { + warning.apply(warning, k.slice(1)); + } + } + } catch (e) { + if (e) { + var nt = nexttoken || {}; + JSHINT.errors.push({ + raw : e.raw, + reason : e.message, + line : e.line || nt.line, + character : e.character || nt.from + }, null); + } + } + + return JSHINT.errors.length === 0; + }; + + // Data summary. + itself.data = function () { + + var data = { functions: [], options: option }, fu, globals, implieds = [], f, i, j, + members = [], n, unused = [], v; + if (itself.errors.length) { + data.errors = itself.errors; + } + + if (jsonmode) { + data.json = true; + } + + for (n in implied) { + if (is_own(implied, n)) { + implieds.push({ + name: n, + line: implied[n] + }); + } + } + if (implieds.length > 0) { + data.implieds = implieds; + } + + if (urls.length > 0) { + data.urls = urls; + } + + globals = Object.keys(scope); + if (globals.length > 0) { + data.globals = globals; + } + for (i = 1; i < functions.length; i += 1) { + f = functions[i]; + fu = {}; + for (j = 0; j < functionicity.length; j += 1) { + fu[functionicity[j]] = []; + } + for (n in f) { + if (is_own(f, n) && n.charAt(0) !== '(') { + v = f[n]; + if (v === 'unction') { + v = 'unused'; + } + if (Array.isArray(fu[v])) { + fu[v].push(n); + if (v === 'unused') { + unused.push({ + name: n, + line: f['(line)'], + 'function': f['(name)'] + }); + } + } + } + } + for (j = 0; j < functionicity.length; j += 1) { + if (fu[functionicity[j]].length === 0) { + delete fu[functionicity[j]]; + } + } + fu.name = f['(name)']; + fu.param = f['(params)']; + fu.line = f['(line)']; + fu.last = f['(last)']; + data.functions.push(fu); + } + + if (unused.length > 0) { + data.unused = unused; + } + + members = []; + for (n in member) { + if (typeof member[n] === 'number') { + data.member = member; + break; + } + } + + return data; + }; + + itself.report = function (option) { + var data = itself.data(); + + var a = [], c, e, err, f, i, k, l, m = '', n, o = [], s; + + function detail(h, array) { + var b, i, singularity; + if (array) { + o.push('
    ' + h + ' '); + array = array.sort(); + for (i = 0; i < array.length; i += 1) { + if (array[i] !== singularity) { + singularity = array[i]; + o.push((b ? ', ' : '') + singularity); + b = true; + } + } + o.push('
    '); + } + } + + + if (data.errors || data.implieds || data.unused) { + err = true; + o.push('
    Error:'); + if (data.errors) { + for (i = 0; i < data.errors.length; i += 1) { + c = data.errors[i]; + if (c) { + e = c.evidence || ''; + o.push('

    Problem' + (isFinite(c.line) ? ' at line ' + + c.line + ' character ' + c.character : '') + + ': ' + c.reason.entityify() + + '

    ' + + (e && (e.length > 80 ? e.slice(0, 77) + '...' : + e).entityify()) + '

    '); + } + } + } + + if (data.implieds) { + s = []; + for (i = 0; i < data.implieds.length; i += 1) { + s[i] = '' + data.implieds[i].name + ' ' + + data.implieds[i].line + ''; + } + o.push('

    Implied global: ' + s.join(', ') + '

    '); + } + + if (data.unused) { + s = []; + for (i = 0; i < data.unused.length; i += 1) { + s[i] = '' + data.unused[i].name + ' ' + + data.unused[i].line + ' ' + + data.unused[i]['function'] + ''; + } + o.push('

    Unused variable: ' + s.join(', ') + '

    '); + } + if (data.json) { + o.push('

    JSON: bad.

    '); + } + o.push('
    '); + } + + if (!option) { + + o.push('
    '); + + if (data.urls) { + detail("URLs
    ", data.urls, '
    '); + } + + if (data.json && !err) { + o.push('

    JSON: good.

    '); + } else if (data.globals) { + o.push('
    Global ' + + data.globals.sort().join(', ') + '
    '); + } else { + o.push('
    No new global variables introduced.
    '); + } + + for (i = 0; i < data.functions.length; i += 1) { + f = data.functions[i]; + + o.push('
    ' + f.line + '-' + + f.last + ' ' + (f.name || '') + '(' + + (f.param ? f.param.join(', ') : '') + ')
    '); + detail('Unused', f.unused); + detail('Closure', f.closure); + detail('Variable', f['var']); + detail('Exception', f.exception); + detail('Outer', f.outer); + detail('Global', f.global); + detail('Label', f.label); + } + + if (data.member) { + a = Object.keys(data.member); + if (a.length) { + a = a.sort(); + m = '
    /*members ';
    +                    l = 10;
    +                    for (i = 0; i < a.length; i += 1) {
    +                        k = a[i];
    +                        n = k.name();
    +                        if (l + n.length > 72) {
    +                            o.push(m + '
    '); + m = ' '; + l = 1; + } + l += n.length + 2; + if (data.member[k] === 1) { + n = '' + n + ''; + } + if (i < a.length - 1) { + n += ', '; + } + m += n; + } + o.push(m + '
    */
    '); + } + o.push('
    '); + } + } + return o.join(''); + }; + + itself.jshint = itself; + + return itself; +}()); + +// Make JSHINT a Node module, if possible. +if (typeof exports === 'object' && exports) + exports.JSHINT = JSHINT; diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/external/qunit.css b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/external/qunit.css new file mode 100755 index 000000000..55970e006 --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/external/qunit.css @@ -0,0 +1,235 @@ +/** + * QUnit v1.10.0 - A JavaScript Unit Testing Framework + * + * http://qunitjs.com + * + * Copyright 2012 jQuery Foundation and other contributors + * Released under the MIT license. + * http://jquery.org/license + */ + +/** Font Family and Sizes */ + +#qunit-tests, #qunit-header, #qunit-banner, #qunit-testrunner-toolbar, #qunit-userAgent, #qunit-testresult { + font-family: "Helvetica Neue Light", "HelveticaNeue-Light", "Helvetica Neue", Calibri, Helvetica, Arial, sans-serif; +} + +#qunit-testrunner-toolbar, #qunit-userAgent, #qunit-testresult, #qunit-tests li { font-size: small; } +#qunit-tests { font-size: smaller; } + + +/** Resets */ + +#qunit-tests, #qunit-tests ol, #qunit-header, #qunit-banner, #qunit-userAgent, #qunit-testresult, #qunit-modulefilter { + margin: 0; + padding: 0; +} + + +/** Header */ + +#qunit-header { + padding: 0.5em 0 0.5em 1em; + + color: #8699a4; + background-color: #0d3349; + + font-size: 1.5em; + line-height: 1em; + font-weight: normal; + + border-radius: 5px 5px 0 0; + -moz-border-radius: 5px 5px 0 0; + -webkit-border-top-right-radius: 5px; + -webkit-border-top-left-radius: 5px; +} + +#qunit-header a { + text-decoration: none; + color: #c2ccd1; +} + +#qunit-header a:hover, +#qunit-header a:focus { + color: #fff; +} + +#qunit-testrunner-toolbar label { + display: inline-block; + padding: 0 .5em 0 .1em; +} + +#qunit-banner { + height: 5px; +} + +#qunit-testrunner-toolbar { + padding: 0.5em 0 0.5em 2em; + color: #5E740B; + background-color: #eee; + overflow: hidden; +} + +#qunit-userAgent { + padding: 0.5em 0 0.5em 2.5em; + background-color: #2b81af; + color: #fff; + text-shadow: rgba(0, 0, 0, 0.5) 2px 2px 1px; +} + +#qunit-modulefilter-container { + float: right; +} + +/** Tests: Pass/Fail */ + +#qunit-tests { + list-style-position: inside; +} + +#qunit-tests li { + padding: 0.4em 0.5em 0.4em 2.5em; + border-bottom: 1px solid #fff; + list-style-position: inside; +} + +#qunit-tests.hidepass li.pass, #qunit-tests.hidepass li.running { + display: none; +} + +#qunit-tests li strong { + cursor: pointer; +} + +#qunit-tests li a { + padding: 0.5em; + color: #c2ccd1; + text-decoration: none; +} +#qunit-tests li a:hover, +#qunit-tests li a:focus { + color: #000; +} + +#qunit-tests ol { + margin-top: 0.5em; + padding: 0.5em; + + background-color: #fff; + + border-radius: 5px; + -moz-border-radius: 5px; + -webkit-border-radius: 5px; +} + +#qunit-tests table { + border-collapse: collapse; + margin-top: .2em; +} + +#qunit-tests th { + text-align: right; + vertical-align: top; + padding: 0 .5em 0 0; +} + +#qunit-tests td { + vertical-align: top; +} + +#qunit-tests pre { + margin: 0; + white-space: pre-wrap; + word-wrap: break-word; +} + +#qunit-tests del { + background-color: #e0f2be; + color: #374e0c; + text-decoration: none; +} + +#qunit-tests ins { + background-color: #ffcaca; + color: #500; + text-decoration: none; +} + +/*** Test Counts */ + +#qunit-tests b.counts { color: black; } +#qunit-tests b.passed { color: #5E740B; } +#qunit-tests b.failed { color: #710909; } + +#qunit-tests li li { + padding: 5px; + background-color: #fff; + border-bottom: none; + list-style-position: inside; +} + +/*** Passing Styles */ + +#qunit-tests li li.pass { + color: #3c510c; + background-color: #fff; + border-left: 10px solid #C6E746; +} + +#qunit-tests .pass { color: #528CE0; background-color: #D2E0E6; } +#qunit-tests .pass .test-name { color: #366097; } + +#qunit-tests .pass .test-actual, +#qunit-tests .pass .test-expected { color: #999999; } + +#qunit-banner.qunit-pass { background-color: #C6E746; } + +/*** Failing Styles */ + +#qunit-tests li li.fail { + color: #710909; + background-color: #fff; + border-left: 10px solid #EE5757; + white-space: pre; +} + +#qunit-tests > li:last-child { + border-radius: 0 0 5px 5px; + -moz-border-radius: 0 0 5px 5px; + -webkit-border-bottom-right-radius: 5px; + -webkit-border-bottom-left-radius: 5px; +} + +#qunit-tests .fail { color: #000000; background-color: #EE5757; } +#qunit-tests .fail .test-name, +#qunit-tests .fail .module-name { color: #000000; } + +#qunit-tests .fail .test-actual { color: #EE5757; } +#qunit-tests .fail .test-expected { color: green; } + +#qunit-banner.qunit-fail { background-color: #EE5757; } + + +/** Result */ + +#qunit-testresult { + padding: 0.5em 0.5em 0.5em 2.5em; + + color: #2b81af; + background-color: #D2E0E6; + + border-bottom: 1px solid white; +} +#qunit-testresult .module-name { + font-weight: bold; +} + +/** Fixture */ + +#qunit-fixture { + position: absolute; + top: -10000px; + left: -10000px; + width: 1000px; + height: 1000px; +} diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/external/qunit.js b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/external/qunit.js new file mode 100755 index 000000000..d4f17b5ae --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/external/qunit.js @@ -0,0 +1,1977 @@ +/** + * QUnit v1.10.0 - A JavaScript Unit Testing Framework + * + * http://qunitjs.com + * + * Copyright 2012 jQuery Foundation and other contributors + * Released under the MIT license. + * http://jquery.org/license + */ + +(function( window ) { + +var QUnit, + config, + onErrorFnPrev, + testId = 0, + fileName = (sourceFromStacktrace( 0 ) || "" ).replace(/(:\d+)+\)?/, "").replace(/.+\//, ""), + toString = Object.prototype.toString, + hasOwn = Object.prototype.hasOwnProperty, + // Keep a local reference to Date (GH-283) + Date = window.Date, + defined = { + setTimeout: typeof window.setTimeout !== "undefined", + sessionStorage: (function() { + var x = "qunit-test-string"; + try { + sessionStorage.setItem( x, x ); + sessionStorage.removeItem( x ); + return true; + } catch( e ) { + return false; + } + }()) +}; + +function Test( settings ) { + extend( this, settings ); + this.assertions = []; + this.testNumber = ++Test.count; +} + +Test.count = 0; + +Test.prototype = { + init: function() { + var a, b, li, + tests = id( "qunit-tests" ); + + if ( tests ) { + b = document.createElement( "strong" ); + b.innerHTML = this.name; + + // `a` initialized at top of scope + a = document.createElement( "a" ); + a.innerHTML = "Rerun"; + a.href = QUnit.url({ testNumber: this.testNumber }); + + li = document.createElement( "li" ); + li.appendChild( b ); + li.appendChild( a ); + li.className = "running"; + li.id = this.id = "qunit-test-output" + testId++; + + tests.appendChild( li ); + } + }, + setup: function() { + if ( this.module !== config.previousModule ) { + if ( config.previousModule ) { + runLoggingCallbacks( "moduleDone", QUnit, { + name: config.previousModule, + failed: config.moduleStats.bad, + passed: config.moduleStats.all - config.moduleStats.bad, + total: config.moduleStats.all + }); + } + config.previousModule = this.module; + config.moduleStats = { all: 0, bad: 0 }; + runLoggingCallbacks( "moduleStart", QUnit, { + name: this.module + }); + } else if ( config.autorun ) { + runLoggingCallbacks( "moduleStart", QUnit, { + name: this.module + }); + } + + config.current = this; + + this.testEnvironment = extend({ + setup: function() {}, + teardown: function() {} + }, this.moduleTestEnvironment ); + + runLoggingCallbacks( "testStart", QUnit, { + name: this.testName, + module: this.module + }); + + // allow utility functions to access the current test environment + // TODO why?? + QUnit.current_testEnvironment = this.testEnvironment; + + if ( !config.pollution ) { + saveGlobal(); + } + if ( config.notrycatch ) { + this.testEnvironment.setup.call( this.testEnvironment ); + return; + } + try { + this.testEnvironment.setup.call( this.testEnvironment ); + } catch( e ) { + QUnit.pushFailure( "Setup failed on " + this.testName + ": " + e.message, extractStacktrace( e, 1 ) ); + } + }, + run: function() { + config.current = this; + + var running = id( "qunit-testresult" ); + + if ( running ) { + running.innerHTML = "Running:
    " + this.name; + } + + if ( this.async ) { + QUnit.stop(); + } + + if ( config.notrycatch ) { + this.callback.call( this.testEnvironment, QUnit.assert ); + return; + } + + try { + this.callback.call( this.testEnvironment, QUnit.assert ); + } catch( e ) { + QUnit.pushFailure( "Died on test #" + (this.assertions.length + 1) + " " + this.stack + ": " + e.message, extractStacktrace( e, 0 ) ); + // else next test will carry the responsibility + saveGlobal(); + + // Restart the tests if they're blocking + if ( config.blocking ) { + QUnit.start(); + } + } + }, + teardown: function() { + config.current = this; + if ( config.notrycatch ) { + this.testEnvironment.teardown.call( this.testEnvironment ); + return; + } else { + try { + this.testEnvironment.teardown.call( this.testEnvironment ); + } catch( e ) { + QUnit.pushFailure( "Teardown failed on " + this.testName + ": " + e.message, extractStacktrace( e, 1 ) ); + } + } + checkPollution(); + }, + finish: function() { + config.current = this; + if ( config.requireExpects && this.expected == null ) { + QUnit.pushFailure( "Expected number of assertions to be defined, but expect() was not called.", this.stack ); + } else if ( this.expected != null && this.expected != this.assertions.length ) { + QUnit.pushFailure( "Expected " + this.expected + " assertions, but " + this.assertions.length + " were run", this.stack ); + } else if ( this.expected == null && !this.assertions.length ) { + QUnit.pushFailure( "Expected at least one assertion, but none were run - call expect(0) to accept zero assertions.", this.stack ); + } + + var assertion, a, b, i, li, ol, + test = this, + good = 0, + bad = 0, + tests = id( "qunit-tests" ); + + config.stats.all += this.assertions.length; + config.moduleStats.all += this.assertions.length; + + if ( tests ) { + ol = document.createElement( "ol" ); + + for ( i = 0; i < this.assertions.length; i++ ) { + assertion = this.assertions[i]; + + li = document.createElement( "li" ); + li.className = assertion.result ? "pass" : "fail"; + li.innerHTML = assertion.message || ( assertion.result ? "okay" : "failed" ); + ol.appendChild( li ); + + if ( assertion.result ) { + good++; + } else { + bad++; + config.stats.bad++; + config.moduleStats.bad++; + } + } + + // store result when possible + if ( QUnit.config.reorder && defined.sessionStorage ) { + if ( bad ) { + sessionStorage.setItem( "qunit-test-" + this.module + "-" + this.testName, bad ); + } else { + sessionStorage.removeItem( "qunit-test-" + this.module + "-" + this.testName ); + } + } + + if ( bad === 0 ) { + ol.style.display = "none"; + } + + // `b` initialized at top of scope + b = document.createElement( "strong" ); + b.innerHTML = this.name + " (" + bad + ", " + good + ", " + this.assertions.length + ")"; + + addEvent(b, "click", function() { + var next = b.nextSibling.nextSibling, + display = next.style.display; + next.style.display = display === "none" ? "block" : "none"; + }); + + addEvent(b, "dblclick", function( e ) { + var target = e && e.target ? e.target : window.event.srcElement; + if ( target.nodeName.toLowerCase() == "span" || target.nodeName.toLowerCase() == "b" ) { + target = target.parentNode; + } + if ( window.location && target.nodeName.toLowerCase() === "strong" ) { + window.location = QUnit.url({ testNumber: test.testNumber }); + } + }); + + // `li` initialized at top of scope + li = id( this.id ); + li.className = bad ? "fail" : "pass"; + li.removeChild( li.firstChild ); + a = li.firstChild; + li.appendChild( b ); + li.appendChild ( a ); + li.appendChild( ol ); + + } else { + for ( i = 0; i < this.assertions.length; i++ ) { + if ( !this.assertions[i].result ) { + bad++; + config.stats.bad++; + config.moduleStats.bad++; + } + } + } + + runLoggingCallbacks( "testDone", QUnit, { + name: this.testName, + module: this.module, + failed: bad, + passed: this.assertions.length - bad, + total: this.assertions.length + }); + + QUnit.reset(); + + config.current = undefined; + }, + + queue: function() { + var bad, + test = this; + + synchronize(function() { + test.init(); + }); + function run() { + // each of these can by async + synchronize(function() { + test.setup(); + }); + synchronize(function() { + test.run(); + }); + synchronize(function() { + test.teardown(); + }); + synchronize(function() { + test.finish(); + }); + } + + // `bad` initialized at top of scope + // defer when previous test run passed, if storage is available + bad = QUnit.config.reorder && defined.sessionStorage && + +sessionStorage.getItem( "qunit-test-" + this.module + "-" + this.testName ); + + if ( bad ) { + run(); + } else { + synchronize( run, true ); + } + } +}; + +// Root QUnit object. +// `QUnit` initialized at top of scope +QUnit = { + + // call on start of module test to prepend name to all tests + module: function( name, testEnvironment ) { + config.currentModule = name; + config.currentModuleTestEnvironment = testEnvironment; + config.modules[name] = true; + }, + + asyncTest: function( testName, expected, callback ) { + if ( arguments.length === 2 ) { + callback = expected; + expected = null; + } + + QUnit.test( testName, expected, callback, true ); + }, + + test: function( testName, expected, callback, async ) { + var test, + name = "" + escapeInnerText( testName ) + ""; + + if ( arguments.length === 2 ) { + callback = expected; + expected = null; + } + + if ( config.currentModule ) { + name = "" + config.currentModule + ": " + name; + } + + test = new Test({ + name: name, + testName: testName, + expected: expected, + async: async, + callback: callback, + module: config.currentModule, + moduleTestEnvironment: config.currentModuleTestEnvironment, + stack: sourceFromStacktrace( 2 ) + }); + + if ( !validTest( test ) ) { + return; + } + + test.queue(); + }, + + // Specify the number of expected assertions to gurantee that failed test (no assertions are run at all) don't slip through. + expect: function( asserts ) { + if (arguments.length === 1) { + config.current.expected = asserts; + } else { + return config.current.expected; + } + }, + + start: function( count ) { + config.semaphore -= count || 1; + // don't start until equal number of stop-calls + if ( config.semaphore > 0 ) { + return; + } + // ignore if start is called more often then stop + if ( config.semaphore < 0 ) { + config.semaphore = 0; + } + // A slight delay, to avoid any current callbacks + if ( defined.setTimeout ) { + window.setTimeout(function() { + if ( config.semaphore > 0 ) { + return; + } + if ( config.timeout ) { + clearTimeout( config.timeout ); + } + + config.blocking = false; + process( true ); + }, 13); + } else { + config.blocking = false; + process( true ); + } + }, + + stop: function( count ) { + config.semaphore += count || 1; + config.blocking = true; + + if ( config.testTimeout && defined.setTimeout ) { + clearTimeout( config.timeout ); + config.timeout = window.setTimeout(function() { + QUnit.ok( false, "Test timed out" ); + config.semaphore = 1; + QUnit.start(); + }, config.testTimeout ); + } + } +}; + +// Asssert helpers +// All of these must call either QUnit.push() or manually do: +// - runLoggingCallbacks( "log", .. ); +// - config.current.assertions.push({ .. }); +QUnit.assert = { + /** + * Asserts rough true-ish result. + * @name ok + * @function + * @example ok( "asdfasdf".length > 5, "There must be at least 5 chars" ); + */ + ok: function( result, msg ) { + if ( !config.current ) { + throw new Error( "ok() assertion outside test context, was " + sourceFromStacktrace(2) ); + } + result = !!result; + + var source, + details = { + module: config.current.module, + name: config.current.testName, + result: result, + message: msg + }; + + msg = escapeInnerText( msg || (result ? "okay" : "failed" ) ); + msg = "" + msg + ""; + + if ( !result ) { + source = sourceFromStacktrace( 2 ); + if ( source ) { + details.source = source; + msg += "
    Source:
    " + escapeInnerText( source ) + "
    "; + } + } + runLoggingCallbacks( "log", QUnit, details ); + config.current.assertions.push({ + result: result, + message: msg + }); + }, + + /** + * Assert that the first two arguments are equal, with an optional message. + * Prints out both actual and expected values. + * @name equal + * @function + * @example equal( format( "Received {0} bytes.", 2), "Received 2 bytes.", "format() replaces {0} with next argument" ); + */ + equal: function( actual, expected, message ) { + QUnit.push( expected == actual, actual, expected, message ); + }, + + /** + * @name notEqual + * @function + */ + notEqual: function( actual, expected, message ) { + QUnit.push( expected != actual, actual, expected, message ); + }, + + /** + * @name deepEqual + * @function + */ + deepEqual: function( actual, expected, message ) { + QUnit.push( QUnit.equiv(actual, expected), actual, expected, message ); + }, + + /** + * @name notDeepEqual + * @function + */ + notDeepEqual: function( actual, expected, message ) { + QUnit.push( !QUnit.equiv(actual, expected), actual, expected, message ); + }, + + /** + * @name strictEqual + * @function + */ + strictEqual: function( actual, expected, message ) { + QUnit.push( expected === actual, actual, expected, message ); + }, + + /** + * @name notStrictEqual + * @function + */ + notStrictEqual: function( actual, expected, message ) { + QUnit.push( expected !== actual, actual, expected, message ); + }, + + throws: function( block, expected, message ) { + var actual, + ok = false; + + // 'expected' is optional + if ( typeof expected === "string" ) { + message = expected; + expected = null; + } + + config.current.ignoreGlobalErrors = true; + try { + block.call( config.current.testEnvironment ); + } catch (e) { + actual = e; + } + config.current.ignoreGlobalErrors = false; + + if ( actual ) { + // we don't want to validate thrown error + if ( !expected ) { + ok = true; + // expected is a regexp + } else if ( QUnit.objectType( expected ) === "regexp" ) { + ok = expected.test( actual ); + // expected is a constructor + } else if ( actual instanceof expected ) { + ok = true; + // expected is a validation function which returns true is validation passed + } else if ( expected.call( {}, actual ) === true ) { + ok = true; + } + + QUnit.push( ok, actual, null, message ); + } else { + QUnit.pushFailure( message, null, 'No exception was thrown.' ); + } + } +}; + +/** + * @deprecate since 1.8.0 + * Kept assertion helpers in root for backwards compatibility + */ +extend( QUnit, QUnit.assert ); + +/** + * @deprecated since 1.9.0 + * Kept global "raises()" for backwards compatibility + */ +QUnit.raises = QUnit.assert.throws; + +/** + * @deprecated since 1.0.0, replaced with error pushes since 1.3.0 + * Kept to avoid TypeErrors for undefined methods. + */ +QUnit.equals = function() { + QUnit.push( false, false, false, "QUnit.equals has been deprecated since 2009 (e88049a0), use QUnit.equal instead" ); +}; +QUnit.same = function() { + QUnit.push( false, false, false, "QUnit.same has been deprecated since 2009 (e88049a0), use QUnit.deepEqual instead" ); +}; + +// We want access to the constructor's prototype +(function() { + function F() {} + F.prototype = QUnit; + QUnit = new F(); + // Make F QUnit's constructor so that we can add to the prototype later + QUnit.constructor = F; +}()); + +/** + * Config object: Maintain internal state + * Later exposed as QUnit.config + * `config` initialized at top of scope + */ +config = { + // The queue of tests to run + queue: [], + + // block until document ready + blocking: true, + + // when enabled, show only failing tests + // gets persisted through sessionStorage and can be changed in UI via checkbox + hidepassed: false, + + // by default, run previously failed tests first + // very useful in combination with "Hide passed tests" checked + reorder: true, + + // by default, modify document.title when suite is done + altertitle: true, + + // when enabled, all tests must call expect() + requireExpects: false, + + // add checkboxes that are persisted in the query-string + // when enabled, the id is set to `true` as a `QUnit.config` property + urlConfig: [ + { + id: "noglobals", + label: "Check for Globals", + tooltip: "Enabling this will test if any test introduces new properties on the `window` object. Stored as query-strings." + }, + { + id: "notrycatch", + label: "No try-catch", + tooltip: "Enabling this will run tests outside of a try-catch block. Makes debugging exceptions in IE reasonable. Stored as query-strings." + } + ], + + // Set of all modules. + modules: {}, + + // logging callback queues + begin: [], + done: [], + log: [], + testStart: [], + testDone: [], + moduleStart: [], + moduleDone: [] +}; + +// Initialize more QUnit.config and QUnit.urlParams +(function() { + var i, + location = window.location || { search: "", protocol: "file:" }, + params = location.search.slice( 1 ).split( "&" ), + length = params.length, + urlParams = {}, + current; + + if ( params[ 0 ] ) { + for ( i = 0; i < length; i++ ) { + current = params[ i ].split( "=" ); + current[ 0 ] = decodeURIComponent( current[ 0 ] ); + // allow just a key to turn on a flag, e.g., test.html?noglobals + current[ 1 ] = current[ 1 ] ? decodeURIComponent( current[ 1 ] ) : true; + urlParams[ current[ 0 ] ] = current[ 1 ]; + } + } + + QUnit.urlParams = urlParams; + + // String search anywhere in moduleName+testName + config.filter = urlParams.filter; + + // Exact match of the module name + config.module = urlParams.module; + + config.testNumber = parseInt( urlParams.testNumber, 10 ) || null; + + // Figure out if we're running the tests from a server or not + QUnit.isLocal = location.protocol === "file:"; +}()); + +// Export global variables, unless an 'exports' object exists, +// in that case we assume we're in CommonJS (dealt with on the bottom of the script) +if ( typeof exports === "undefined" ) { + extend( window, QUnit ); + + // Expose QUnit object + window.QUnit = QUnit; +} + +// Extend QUnit object, +// these after set here because they should not be exposed as global functions +extend( QUnit, { + config: config, + + // Initialize the configuration options + init: function() { + extend( config, { + stats: { all: 0, bad: 0 }, + moduleStats: { all: 0, bad: 0 }, + started: +new Date(), + updateRate: 1000, + blocking: false, + autostart: true, + autorun: false, + filter: "", + queue: [], + semaphore: 0 + }); + + var tests, banner, result, + qunit = id( "qunit" ); + + if ( qunit ) { + qunit.innerHTML = + "

    " + escapeInnerText( document.title ) + "

    " + + "

    " + + "
    " + + "

    " + + "
      "; + } + + tests = id( "qunit-tests" ); + banner = id( "qunit-banner" ); + result = id( "qunit-testresult" ); + + if ( tests ) { + tests.innerHTML = ""; + } + + if ( banner ) { + banner.className = ""; + } + + if ( result ) { + result.parentNode.removeChild( result ); + } + + if ( tests ) { + result = document.createElement( "p" ); + result.id = "qunit-testresult"; + result.className = "result"; + tests.parentNode.insertBefore( result, tests ); + result.innerHTML = "Running...
       "; + } + }, + + // Resets the test setup. Useful for tests that modify the DOM. + reset: function() { + var fixture = id( "qunit-fixture" ); + if ( fixture ) { + fixture.innerHTML = config.fixture; + } + }, + + // Trigger an event on an element. + // @example triggerEvent( document.body, "click" ); + triggerEvent: function( elem, type, event ) { + if ( document.createEvent ) { + event = document.createEvent( "MouseEvents" ); + event.initMouseEvent(type, true, true, elem.ownerDocument.defaultView, + 0, 0, 0, 0, 0, false, false, false, false, 0, null); + + elem.dispatchEvent( event ); + } else if ( elem.fireEvent ) { + elem.fireEvent( "on" + type ); + } + }, + + // Safe object type checking + is: function( type, obj ) { + return QUnit.objectType( obj ) == type; + }, + + objectType: function( obj ) { + if ( typeof obj === "undefined" ) { + return "undefined"; + // consider: typeof null === object + } + if ( obj === null ) { + return "null"; + } + + var type = toString.call( obj ).match(/^\[object\s(.*)\]$/)[1] || ""; + + switch ( type ) { + case "Number": + if ( isNaN(obj) ) { + return "nan"; + } + return "number"; + case "String": + case "Boolean": + case "Array": + case "Date": + case "RegExp": + case "Function": + return type.toLowerCase(); + } + if ( typeof obj === "object" ) { + return "object"; + } + return undefined; + }, + + push: function( result, actual, expected, message ) { + if ( !config.current ) { + throw new Error( "assertion outside test context, was " + sourceFromStacktrace() ); + } + + var output, source, + details = { + module: config.current.module, + name: config.current.testName, + result: result, + message: message, + actual: actual, + expected: expected + }; + + message = escapeInnerText( message ) || ( result ? "okay" : "failed" ); + message = "" + message + ""; + output = message; + + if ( !result ) { + expected = escapeInnerText( QUnit.jsDump.parse(expected) ); + actual = escapeInnerText( QUnit.jsDump.parse(actual) ); + output += ""; + + if ( actual != expected ) { + output += ""; + output += ""; + } + + source = sourceFromStacktrace(); + + if ( source ) { + details.source = source; + output += ""; + } + + output += "
      Expected:
      " + expected + "
      Result:
      " + actual + "
      Diff:
      " + QUnit.diff( expected, actual ) + "
      Source:
      " + escapeInnerText( source ) + "
      "; + } + + runLoggingCallbacks( "log", QUnit, details ); + + config.current.assertions.push({ + result: !!result, + message: output + }); + }, + + pushFailure: function( message, source, actual ) { + if ( !config.current ) { + throw new Error( "pushFailure() assertion outside test context, was " + sourceFromStacktrace(2) ); + } + + var output, + details = { + module: config.current.module, + name: config.current.testName, + result: false, + message: message + }; + + message = escapeInnerText( message ) || "error"; + message = "" + message + ""; + output = message; + + output += ""; + + if ( actual ) { + output += ""; + } + + if ( source ) { + details.source = source; + output += ""; + } + + output += "
      Result:
      " + escapeInnerText( actual ) + "
      Source:
      " + escapeInnerText( source ) + "
      "; + + runLoggingCallbacks( "log", QUnit, details ); + + config.current.assertions.push({ + result: false, + message: output + }); + }, + + url: function( params ) { + params = extend( extend( {}, QUnit.urlParams ), params ); + var key, + querystring = "?"; + + for ( key in params ) { + if ( !hasOwn.call( params, key ) ) { + continue; + } + querystring += encodeURIComponent( key ) + "=" + + encodeURIComponent( params[ key ] ) + "&"; + } + return window.location.pathname + querystring.slice( 0, -1 ); + }, + + extend: extend, + id: id, + addEvent: addEvent + // load, equiv, jsDump, diff: Attached later +}); + +/** + * @deprecated: Created for backwards compatibility with test runner that set the hook function + * into QUnit.{hook}, instead of invoking it and passing the hook function. + * QUnit.constructor is set to the empty F() above so that we can add to it's prototype here. + * Doing this allows us to tell if the following methods have been overwritten on the actual + * QUnit object. + */ +extend( QUnit.constructor.prototype, { + + // Logging callbacks; all receive a single argument with the listed properties + // run test/logs.html for any related changes + begin: registerLoggingCallback( "begin" ), + + // done: { failed, passed, total, runtime } + done: registerLoggingCallback( "done" ), + + // log: { result, actual, expected, message } + log: registerLoggingCallback( "log" ), + + // testStart: { name } + testStart: registerLoggingCallback( "testStart" ), + + // testDone: { name, failed, passed, total } + testDone: registerLoggingCallback( "testDone" ), + + // moduleStart: { name } + moduleStart: registerLoggingCallback( "moduleStart" ), + + // moduleDone: { name, failed, passed, total } + moduleDone: registerLoggingCallback( "moduleDone" ) +}); + +if ( typeof document === "undefined" || document.readyState === "complete" ) { + config.autorun = true; +} + +QUnit.load = function() { + runLoggingCallbacks( "begin", QUnit, {} ); + + // Initialize the config, saving the execution queue + var banner, filter, i, label, len, main, ol, toolbar, userAgent, val, urlConfigCheckboxes, moduleFilter, + numModules = 0, + moduleFilterHtml = "", + urlConfigHtml = "", + oldconfig = extend( {}, config ); + + QUnit.init(); + extend(config, oldconfig); + + config.blocking = false; + + len = config.urlConfig.length; + + for ( i = 0; i < len; i++ ) { + val = config.urlConfig[i]; + if ( typeof val === "string" ) { + val = { + id: val, + label: val, + tooltip: "[no tooltip available]" + }; + } + config[ val.id ] = QUnit.urlParams[ val.id ]; + urlConfigHtml += ""; + } + + moduleFilterHtml += ""; + + // `userAgent` initialized at top of scope + userAgent = id( "qunit-userAgent" ); + if ( userAgent ) { + userAgent.innerHTML = navigator.userAgent; + } + + // `banner` initialized at top of scope + banner = id( "qunit-header" ); + if ( banner ) { + banner.innerHTML = "" + banner.innerHTML + " "; + } + + // `toolbar` initialized at top of scope + toolbar = id( "qunit-testrunner-toolbar" ); + if ( toolbar ) { + // `filter` initialized at top of scope + filter = document.createElement( "input" ); + filter.type = "checkbox"; + filter.id = "qunit-filter-pass"; + + addEvent( filter, "click", function() { + var tmp, + ol = document.getElementById( "qunit-tests" ); + + if ( filter.checked ) { + ol.className = ol.className + " hidepass"; + } else { + tmp = " " + ol.className.replace( /[\n\t\r]/g, " " ) + " "; + ol.className = tmp.replace( / hidepass /, " " ); + } + if ( defined.sessionStorage ) { + if (filter.checked) { + sessionStorage.setItem( "qunit-filter-passed-tests", "true" ); + } else { + sessionStorage.removeItem( "qunit-filter-passed-tests" ); + } + } + }); + + if ( config.hidepassed || defined.sessionStorage && sessionStorage.getItem( "qunit-filter-passed-tests" ) ) { + filter.checked = true; + // `ol` initialized at top of scope + ol = document.getElementById( "qunit-tests" ); + ol.className = ol.className + " hidepass"; + } + toolbar.appendChild( filter ); + + // `label` initialized at top of scope + label = document.createElement( "label" ); + label.setAttribute( "for", "qunit-filter-pass" ); + label.setAttribute( "title", "Only show tests and assertons that fail. Stored in sessionStorage." ); + label.innerHTML = "Hide passed tests"; + toolbar.appendChild( label ); + + urlConfigCheckboxes = document.createElement( 'span' ); + urlConfigCheckboxes.innerHTML = urlConfigHtml; + addEvent( urlConfigCheckboxes, "change", function( event ) { + var params = {}; + params[ event.target.name ] = event.target.checked ? true : undefined; + window.location = QUnit.url( params ); + }); + toolbar.appendChild( urlConfigCheckboxes ); + + if (numModules > 1) { + moduleFilter = document.createElement( 'span' ); + moduleFilter.setAttribute( 'id', 'qunit-modulefilter-container' ); + moduleFilter.innerHTML = moduleFilterHtml; + addEvent( moduleFilter, "change", function() { + var selectBox = moduleFilter.getElementsByTagName("select")[0], + selectedModule = decodeURIComponent(selectBox.options[selectBox.selectedIndex].value); + + window.location = QUnit.url( { module: ( selectedModule === "" ) ? undefined : selectedModule } ); + }); + toolbar.appendChild(moduleFilter); + } + } + + // `main` initialized at top of scope + main = id( "qunit-fixture" ); + if ( main ) { + config.fixture = main.innerHTML; + } + + if ( config.autostart ) { + QUnit.start(); + } +}; + +addEvent( window, "load", QUnit.load ); + +// `onErrorFnPrev` initialized at top of scope +// Preserve other handlers +onErrorFnPrev = window.onerror; + +// Cover uncaught exceptions +// Returning true will surpress the default browser handler, +// returning false will let it run. +window.onerror = function ( error, filePath, linerNr ) { + var ret = false; + if ( onErrorFnPrev ) { + ret = onErrorFnPrev( error, filePath, linerNr ); + } + + // Treat return value as window.onerror itself does, + // Only do our handling if not surpressed. + if ( ret !== true ) { + if ( QUnit.config.current ) { + if ( QUnit.config.current.ignoreGlobalErrors ) { + return true; + } + QUnit.pushFailure( error, filePath + ":" + linerNr ); + } else { + QUnit.test( "global failure", extend( function() { + QUnit.pushFailure( error, filePath + ":" + linerNr ); + }, { validTest: validTest } ) ); + } + return false; + } + + return ret; +}; + +function done() { + config.autorun = true; + + // Log the last module results + if ( config.currentModule ) { + runLoggingCallbacks( "moduleDone", QUnit, { + name: config.currentModule, + failed: config.moduleStats.bad, + passed: config.moduleStats.all - config.moduleStats.bad, + total: config.moduleStats.all + }); + } + + var i, key, + banner = id( "qunit-banner" ), + tests = id( "qunit-tests" ), + runtime = +new Date() - config.started, + passed = config.stats.all - config.stats.bad, + html = [ + "Tests completed in ", + runtime, + " milliseconds.
      ", + "", + passed, + " tests of ", + config.stats.all, + " passed, ", + config.stats.bad, + " failed." + ].join( "" ); + + if ( banner ) { + banner.className = ( config.stats.bad ? "qunit-fail" : "qunit-pass" ); + } + + if ( tests ) { + id( "qunit-testresult" ).innerHTML = html; + } + + if ( config.altertitle && typeof document !== "undefined" && document.title ) { + // show ✖ for good, ✔ for bad suite result in title + // use escape sequences in case file gets loaded with non-utf-8-charset + document.title = [ + ( config.stats.bad ? "\u2716" : "\u2714" ), + document.title.replace( /^[\u2714\u2716] /i, "" ) + ].join( " " ); + } + + // clear own sessionStorage items if all tests passed + if ( config.reorder && defined.sessionStorage && config.stats.bad === 0 ) { + // `key` & `i` initialized at top of scope + for ( i = 0; i < sessionStorage.length; i++ ) { + key = sessionStorage.key( i++ ); + if ( key.indexOf( "qunit-test-" ) === 0 ) { + sessionStorage.removeItem( key ); + } + } + } + + // scroll back to top to show results + if ( window.scrollTo ) { + window.scrollTo(0, 0); + } + + runLoggingCallbacks( "done", QUnit, { + failed: config.stats.bad, + passed: passed, + total: config.stats.all, + runtime: runtime + }); +} + +/** @return Boolean: true if this test should be ran */ +function validTest( test ) { + var include, + filter = config.filter && config.filter.toLowerCase(), + module = config.module && config.module.toLowerCase(), + fullName = (test.module + ": " + test.testName).toLowerCase(); + + // Internally-generated tests are always valid + if ( test.callback && test.callback.validTest === validTest ) { + delete test.callback.validTest; + return true; + } + + if ( config.testNumber ) { + return test.testNumber === config.testNumber; + } + + if ( module && ( !test.module || test.module.toLowerCase() !== module ) ) { + return false; + } + + if ( !filter ) { + return true; + } + + include = filter.charAt( 0 ) !== "!"; + if ( !include ) { + filter = filter.slice( 1 ); + } + + // If the filter matches, we need to honour include + if ( fullName.indexOf( filter ) !== -1 ) { + return include; + } + + // Otherwise, do the opposite + return !include; +} + +// so far supports only Firefox, Chrome and Opera (buggy), Safari (for real exceptions) +// Later Safari and IE10 are supposed to support error.stack as well +// See also https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Error/Stack +function extractStacktrace( e, offset ) { + offset = offset === undefined ? 3 : offset; + + var stack, include, i, regex; + + if ( e.stacktrace ) { + // Opera + return e.stacktrace.split( "\n" )[ offset + 3 ]; + } else if ( e.stack ) { + // Firefox, Chrome + stack = e.stack.split( "\n" ); + if (/^error$/i.test( stack[0] ) ) { + stack.shift(); + } + if ( fileName ) { + include = []; + for ( i = offset; i < stack.length; i++ ) { + if ( stack[ i ].indexOf( fileName ) != -1 ) { + break; + } + include.push( stack[ i ] ); + } + if ( include.length ) { + return include.join( "\n" ); + } + } + return stack[ offset ]; + } else if ( e.sourceURL ) { + // Safari, PhantomJS + // hopefully one day Safari provides actual stacktraces + // exclude useless self-reference for generated Error objects + if ( /qunit.js$/.test( e.sourceURL ) ) { + return; + } + // for actual exceptions, this is useful + return e.sourceURL + ":" + e.line; + } +} +function sourceFromStacktrace( offset ) { + try { + throw new Error(); + } catch ( e ) { + return extractStacktrace( e, offset ); + } +} + +function escapeInnerText( s ) { + if ( !s ) { + return ""; + } + s = s + ""; + return s.replace( /[\&<>]/g, function( s ) { + switch( s ) { + case "&": return "&"; + case "<": return "<"; + case ">": return ">"; + default: return s; + } + }); +} + +function synchronize( callback, last ) { + config.queue.push( callback ); + + if ( config.autorun && !config.blocking ) { + process( last ); + } +} + +function process( last ) { + function next() { + process( last ); + } + var start = new Date().getTime(); + config.depth = config.depth ? config.depth + 1 : 1; + + while ( config.queue.length && !config.blocking ) { + if ( !defined.setTimeout || config.updateRate <= 0 || ( ( new Date().getTime() - start ) < config.updateRate ) ) { + config.queue.shift()(); + } else { + window.setTimeout( next, 13 ); + break; + } + } + config.depth--; + if ( last && !config.blocking && !config.queue.length && config.depth === 0 ) { + done(); + } +} + +function saveGlobal() { + config.pollution = []; + + if ( config.noglobals ) { + for ( var key in window ) { + // in Opera sometimes DOM element ids show up here, ignore them + if ( !hasOwn.call( window, key ) || /^qunit-test-output/.test( key ) ) { + continue; + } + config.pollution.push( key ); + } + } +} + +function checkPollution( name ) { + var newGlobals, + deletedGlobals, + old = config.pollution; + + saveGlobal(); + + newGlobals = diff( config.pollution, old ); + if ( newGlobals.length > 0 ) { + QUnit.pushFailure( "Introduced global variable(s): " + newGlobals.join(", ") ); + } + + deletedGlobals = diff( old, config.pollution ); + if ( deletedGlobals.length > 0 ) { + QUnit.pushFailure( "Deleted global variable(s): " + deletedGlobals.join(", ") ); + } +} + +// returns a new Array with the elements that are in a but not in b +function diff( a, b ) { + var i, j, + result = a.slice(); + + for ( i = 0; i < result.length; i++ ) { + for ( j = 0; j < b.length; j++ ) { + if ( result[i] === b[j] ) { + result.splice( i, 1 ); + i--; + break; + } + } + } + return result; +} + +function extend( a, b ) { + for ( var prop in b ) { + if ( b[ prop ] === undefined ) { + delete a[ prop ]; + + // Avoid "Member not found" error in IE8 caused by setting window.constructor + } else if ( prop !== "constructor" || a !== window ) { + a[ prop ] = b[ prop ]; + } + } + + return a; +} + +function addEvent( elem, type, fn ) { + if ( elem.addEventListener ) { + elem.addEventListener( type, fn, false ); + } else if ( elem.attachEvent ) { + elem.attachEvent( "on" + type, fn ); + } else { + fn(); + } +} + +function id( name ) { + return !!( typeof document !== "undefined" && document && document.getElementById ) && + document.getElementById( name ); +} + +function registerLoggingCallback( key ) { + return function( callback ) { + config[key].push( callback ); + }; +} + +// Supports deprecated method of completely overwriting logging callbacks +function runLoggingCallbacks( key, scope, args ) { + //debugger; + var i, callbacks; + if ( QUnit.hasOwnProperty( key ) ) { + QUnit[ key ].call(scope, args ); + } else { + callbacks = config[ key ]; + for ( i = 0; i < callbacks.length; i++ ) { + callbacks[ i ].call( scope, args ); + } + } +} + +// Test for equality any JavaScript type. +// Author: Philippe Rathé +QUnit.equiv = (function() { + + // Call the o related callback with the given arguments. + function bindCallbacks( o, callbacks, args ) { + var prop = QUnit.objectType( o ); + if ( prop ) { + if ( QUnit.objectType( callbacks[ prop ] ) === "function" ) { + return callbacks[ prop ].apply( callbacks, args ); + } else { + return callbacks[ prop ]; // or undefined + } + } + } + + // the real equiv function + var innerEquiv, + // stack to decide between skip/abort functions + callers = [], + // stack to avoiding loops from circular referencing + parents = [], + + getProto = Object.getPrototypeOf || function ( obj ) { + return obj.__proto__; + }, + callbacks = (function () { + + // for string, boolean, number and null + function useStrictEquality( b, a ) { + if ( b instanceof a.constructor || a instanceof b.constructor ) { + // to catch short annotaion VS 'new' annotation of a + // declaration + // e.g. var i = 1; + // var j = new Number(1); + return a == b; + } else { + return a === b; + } + } + + return { + "string": useStrictEquality, + "boolean": useStrictEquality, + "number": useStrictEquality, + "null": useStrictEquality, + "undefined": useStrictEquality, + + "nan": function( b ) { + return isNaN( b ); + }, + + "date": function( b, a ) { + return QUnit.objectType( b ) === "date" && a.valueOf() === b.valueOf(); + }, + + "regexp": function( b, a ) { + return QUnit.objectType( b ) === "regexp" && + // the regex itself + a.source === b.source && + // and its modifers + a.global === b.global && + // (gmi) ... + a.ignoreCase === b.ignoreCase && + a.multiline === b.multiline && + a.sticky === b.sticky; + }, + + // - skip when the property is a method of an instance (OOP) + // - abort otherwise, + // initial === would have catch identical references anyway + "function": function() { + var caller = callers[callers.length - 1]; + return caller !== Object && typeof caller !== "undefined"; + }, + + "array": function( b, a ) { + var i, j, len, loop; + + // b could be an object literal here + if ( QUnit.objectType( b ) !== "array" ) { + return false; + } + + len = a.length; + if ( len !== b.length ) { + // safe and faster + return false; + } + + // track reference to avoid circular references + parents.push( a ); + for ( i = 0; i < len; i++ ) { + loop = false; + for ( j = 0; j < parents.length; j++ ) { + if ( parents[j] === a[i] ) { + loop = true;// dont rewalk array + } + } + if ( !loop && !innerEquiv(a[i], b[i]) ) { + parents.pop(); + return false; + } + } + parents.pop(); + return true; + }, + + "object": function( b, a ) { + var i, j, loop, + // Default to true + eq = true, + aProperties = [], + bProperties = []; + + // comparing constructors is more strict than using + // instanceof + if ( a.constructor !== b.constructor ) { + // Allow objects with no prototype to be equivalent to + // objects with Object as their constructor. + if ( !(( getProto(a) === null && getProto(b) === Object.prototype ) || + ( getProto(b) === null && getProto(a) === Object.prototype ) ) ) { + return false; + } + } + + // stack constructor before traversing properties + callers.push( a.constructor ); + // track reference to avoid circular references + parents.push( a ); + + for ( i in a ) { // be strict: don't ensures hasOwnProperty + // and go deep + loop = false; + for ( j = 0; j < parents.length; j++ ) { + if ( parents[j] === a[i] ) { + // don't go down the same path twice + loop = true; + } + } + aProperties.push(i); // collect a's properties + + if (!loop && !innerEquiv( a[i], b[i] ) ) { + eq = false; + break; + } + } + + callers.pop(); // unstack, we are done + parents.pop(); + + for ( i in b ) { + bProperties.push( i ); // collect b's properties + } + + // Ensures identical properties name + return eq && innerEquiv( aProperties.sort(), bProperties.sort() ); + } + }; + }()); + + innerEquiv = function() { // can take multiple arguments + var args = [].slice.apply( arguments ); + if ( args.length < 2 ) { + return true; // end transition + } + + return (function( a, b ) { + if ( a === b ) { + return true; // catch the most you can + } else if ( a === null || b === null || typeof a === "undefined" || + typeof b === "undefined" || + QUnit.objectType(a) !== QUnit.objectType(b) ) { + return false; // don't lose time with error prone cases + } else { + return bindCallbacks(a, callbacks, [ b, a ]); + } + + // apply transition with (1..n) arguments + }( args[0], args[1] ) && arguments.callee.apply( this, args.splice(1, args.length - 1 )) ); + }; + + return innerEquiv; +}()); + +/** + * jsDump Copyright (c) 2008 Ariel Flesler - aflesler(at)gmail(dot)com | + * http://flesler.blogspot.com Licensed under BSD + * (http://www.opensource.org/licenses/bsd-license.php) Date: 5/15/2008 + * + * @projectDescription Advanced and extensible data dumping for Javascript. + * @version 1.0.0 + * @author Ariel Flesler + * @link {http://flesler.blogspot.com/2008/05/jsdump-pretty-dump-of-any-javascript.html} + */ +QUnit.jsDump = (function() { + function quote( str ) { + return '"' + str.toString().replace( /"/g, '\\"' ) + '"'; + } + function literal( o ) { + return o + ""; + } + function join( pre, arr, post ) { + var s = jsDump.separator(), + base = jsDump.indent(), + inner = jsDump.indent(1); + if ( arr.join ) { + arr = arr.join( "," + s + inner ); + } + if ( !arr ) { + return pre + post; + } + return [ pre, inner + arr, base + post ].join(s); + } + function array( arr, stack ) { + var i = arr.length, ret = new Array(i); + this.up(); + while ( i-- ) { + ret[i] = this.parse( arr[i] , undefined , stack); + } + this.down(); + return join( "[", ret, "]" ); + } + + var reName = /^function (\w+)/, + jsDump = { + parse: function( obj, type, stack ) { //type is used mostly internally, you can fix a (custom)type in advance + stack = stack || [ ]; + var inStack, res, + parser = this.parsers[ type || this.typeOf(obj) ]; + + type = typeof parser; + inStack = inArray( obj, stack ); + + if ( inStack != -1 ) { + return "recursion(" + (inStack - stack.length) + ")"; + } + //else + if ( type == "function" ) { + stack.push( obj ); + res = parser.call( this, obj, stack ); + stack.pop(); + return res; + } + // else + return ( type == "string" ) ? parser : this.parsers.error; + }, + typeOf: function( obj ) { + var type; + if ( obj === null ) { + type = "null"; + } else if ( typeof obj === "undefined" ) { + type = "undefined"; + } else if ( QUnit.is( "regexp", obj) ) { + type = "regexp"; + } else if ( QUnit.is( "date", obj) ) { + type = "date"; + } else if ( QUnit.is( "function", obj) ) { + type = "function"; + } else if ( typeof obj.setInterval !== undefined && typeof obj.document !== "undefined" && typeof obj.nodeType === "undefined" ) { + type = "window"; + } else if ( obj.nodeType === 9 ) { + type = "document"; + } else if ( obj.nodeType ) { + type = "node"; + } else if ( + // native arrays + toString.call( obj ) === "[object Array]" || + // NodeList objects + ( typeof obj.length === "number" && typeof obj.item !== "undefined" && ( obj.length ? obj.item(0) === obj[0] : ( obj.item( 0 ) === null && typeof obj[0] === "undefined" ) ) ) + ) { + type = "array"; + } else { + type = typeof obj; + } + return type; + }, + separator: function() { + return this.multiline ? this.HTML ? "
      " : "\n" : this.HTML ? " " : " "; + }, + indent: function( extra ) {// extra can be a number, shortcut for increasing-calling-decreasing + if ( !this.multiline ) { + return ""; + } + var chr = this.indentChar; + if ( this.HTML ) { + chr = chr.replace( /\t/g, " " ).replace( / /g, " " ); + } + return new Array( this._depth_ + (extra||0) ).join(chr); + }, + up: function( a ) { + this._depth_ += a || 1; + }, + down: function( a ) { + this._depth_ -= a || 1; + }, + setParser: function( name, parser ) { + this.parsers[name] = parser; + }, + // The next 3 are exposed so you can use them + quote: quote, + literal: literal, + join: join, + // + _depth_: 1, + // This is the list of parsers, to modify them, use jsDump.setParser + parsers: { + window: "[Window]", + document: "[Document]", + error: "[ERROR]", //when no parser is found, shouldn"t happen + unknown: "[Unknown]", + "null": "null", + "undefined": "undefined", + "function": function( fn ) { + var ret = "function", + name = "name" in fn ? fn.name : (reName.exec(fn) || [])[1];//functions never have name in IE + + if ( name ) { + ret += " " + name; + } + ret += "( "; + + ret = [ ret, QUnit.jsDump.parse( fn, "functionArgs" ), "){" ].join( "" ); + return join( ret, QUnit.jsDump.parse(fn,"functionCode" ), "}" ); + }, + array: array, + nodelist: array, + "arguments": array, + object: function( map, stack ) { + var ret = [ ], keys, key, val, i; + QUnit.jsDump.up(); + if ( Object.keys ) { + keys = Object.keys( map ); + } else { + keys = []; + for ( key in map ) { + keys.push( key ); + } + } + keys.sort(); + for ( i = 0; i < keys.length; i++ ) { + key = keys[ i ]; + val = map[ key ]; + ret.push( QUnit.jsDump.parse( key, "key" ) + ": " + QUnit.jsDump.parse( val, undefined, stack ) ); + } + QUnit.jsDump.down(); + return join( "{", ret, "}" ); + }, + node: function( node ) { + var a, val, + open = QUnit.jsDump.HTML ? "<" : "<", + close = QUnit.jsDump.HTML ? ">" : ">", + tag = node.nodeName.toLowerCase(), + ret = open + tag; + + for ( a in QUnit.jsDump.DOMAttrs ) { + val = node[ QUnit.jsDump.DOMAttrs[a] ]; + if ( val ) { + ret += " " + a + "=" + QUnit.jsDump.parse( val, "attribute" ); + } + } + return ret + close + open + "/" + tag + close; + }, + functionArgs: function( fn ) {//function calls it internally, it's the arguments part of the function + var args, + l = fn.length; + + if ( !l ) { + return ""; + } + + args = new Array(l); + while ( l-- ) { + args[l] = String.fromCharCode(97+l);//97 is 'a' + } + return " " + args.join( ", " ) + " "; + }, + key: quote, //object calls it internally, the key part of an item in a map + functionCode: "[code]", //function calls it internally, it's the content of the function + attribute: quote, //node calls it internally, it's an html attribute value + string: quote, + date: quote, + regexp: literal, //regex + number: literal, + "boolean": literal + }, + DOMAttrs: { + //attributes to dump from nodes, name=>realName + id: "id", + name: "name", + "class": "className" + }, + HTML: false,//if true, entities are escaped ( <, >, \t, space and \n ) + indentChar: " ",//indentation unit + multiline: true //if true, items in a collection, are separated by a \n, else just a space. + }; + + return jsDump; +}()); + +// from Sizzle.js +function getText( elems ) { + var i, elem, + ret = ""; + + for ( 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 += getText( elem.childNodes ); + } + } + + return ret; +} + +// from jquery.js +function inArray( elem, array ) { + if ( array.indexOf ) { + return array.indexOf( elem ); + } + + for ( var i = 0, length = array.length; i < length; i++ ) { + if ( array[ i ] === elem ) { + return i; + } + } + + return -1; +} + +/* + * Javascript Diff Algorithm + * By John Resig (http://ejohn.org/) + * Modified by Chu Alan "sprite" + * + * Released under the MIT license. + * + * More Info: + * http://ejohn.org/projects/javascript-diff-algorithm/ + * + * Usage: QUnit.diff(expected, actual) + * + * QUnit.diff( "the quick brown fox jumped over", "the quick fox jumps over" ) == "the quick brown fox jumped jumps over" + */ +QUnit.diff = (function() { + function diff( o, n ) { + var i, + ns = {}, + os = {}; + + for ( i = 0; i < n.length; i++ ) { + if ( ns[ n[i] ] == null ) { + ns[ n[i] ] = { + rows: [], + o: null + }; + } + ns[ n[i] ].rows.push( i ); + } + + for ( i = 0; i < o.length; i++ ) { + if ( os[ o[i] ] == null ) { + os[ o[i] ] = { + rows: [], + n: null + }; + } + os[ o[i] ].rows.push( i ); + } + + for ( i in ns ) { + if ( !hasOwn.call( ns, i ) ) { + continue; + } + if ( ns[i].rows.length == 1 && typeof os[i] != "undefined" && os[i].rows.length == 1 ) { + n[ ns[i].rows[0] ] = { + text: n[ ns[i].rows[0] ], + row: os[i].rows[0] + }; + o[ os[i].rows[0] ] = { + text: o[ os[i].rows[0] ], + row: ns[i].rows[0] + }; + } + } + + for ( i = 0; i < n.length - 1; i++ ) { + if ( n[i].text != null && n[ i + 1 ].text == null && n[i].row + 1 < o.length && o[ n[i].row + 1 ].text == null && + n[ i + 1 ] == o[ n[i].row + 1 ] ) { + + n[ i + 1 ] = { + text: n[ i + 1 ], + row: n[i].row + 1 + }; + o[ n[i].row + 1 ] = { + text: o[ n[i].row + 1 ], + row: i + 1 + }; + } + } + + for ( i = n.length - 1; i > 0; i-- ) { + if ( n[i].text != null && n[ i - 1 ].text == null && n[i].row > 0 && o[ n[i].row - 1 ].text == null && + n[ i - 1 ] == o[ n[i].row - 1 ]) { + + n[ i - 1 ] = { + text: n[ i - 1 ], + row: n[i].row - 1 + }; + o[ n[i].row - 1 ] = { + text: o[ n[i].row - 1 ], + row: i - 1 + }; + } + } + + return { + o: o, + n: n + }; + } + + return function( o, n ) { + o = o.replace( /\s+$/, "" ); + n = n.replace( /\s+$/, "" ); + + var i, pre, + str = "", + out = diff( o === "" ? [] : o.split(/\s+/), n === "" ? [] : n.split(/\s+/) ), + oSpace = o.match(/\s+/g), + nSpace = n.match(/\s+/g); + + if ( oSpace == null ) { + oSpace = [ " " ]; + } + else { + oSpace.push( " " ); + } + + if ( nSpace == null ) { + nSpace = [ " " ]; + } + else { + nSpace.push( " " ); + } + + if ( out.n.length === 0 ) { + for ( i = 0; i < out.o.length; i++ ) { + str += "" + out.o[i] + oSpace[i] + ""; + } + } + else { + if ( out.n[0].text == null ) { + for ( n = 0; n < out.o.length && out.o[n].text == null; n++ ) { + str += "" + out.o[n] + oSpace[n] + ""; + } + } + + for ( i = 0; i < out.n.length; i++ ) { + if (out.n[i].text == null) { + str += "" + out.n[i] + nSpace[i] + ""; + } + else { + // `pre` initialized at top of scope + pre = ""; + + for ( n = out.n[i].row + 1; n < out.o.length && out.o[n].text == null; n++ ) { + pre += "" + out.o[n] + oSpace[n] + ""; + } + str += " " + out.n[i].text + nSpace[i] + pre; + } + } + } + + return str; + }; +}()); + +// for CommonJS enviroments, export everything +if ( typeof exports !== "undefined" ) { + extend(exports, QUnit); +} + +// get at whatever the global object is, like window in browsers +}( (function() {return this;}.call()) )); diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/grunt.js b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/grunt.js new file mode 100755 index 000000000..08647a7a1 --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/grunt.js @@ -0,0 +1,347 @@ +/*jshint node: true */ +module.exports = function( grunt ) { + +var + // files + coreFiles = [ + "jquery.ui.core.js", + "jquery.ui.widget.js", + "jquery.ui.mouse.js", + "jquery.ui.draggable.js", + "jquery.ui.droppable.js", + "jquery.ui.resizable.js", + "jquery.ui.selectable.js", + "jquery.ui.sortable.js", + "jquery.ui.effect.js" + ], + + uiFiles = coreFiles.map(function( file ) { + return "ui/" + file; + }).concat( grunt.file.expandFiles( "ui/*.js" ).filter(function( file ) { + return coreFiles.indexOf( file.substring(3) ) === -1; + })), + + allI18nFiles = grunt.file.expandFiles( "ui/i18n/*.js" ), + + cssFiles = [ + "core", + "accordion", + "autocomplete", + "button", + "datepicker", + "dialog", + "menu", + "progressbar", + "resizable", + "selectable", + "slider", + "spinner", + "tabs", + "tooltip", + "theme" + ].map(function( component ) { + return "themes/base/jquery.ui." + component + ".css"; + }), + + // minified files + minify = { + "dist/jquery-ui.min.js": [ "", "dist/jquery-ui.js" ], + "dist/i18n/jquery-ui-i18n.min.js": [ "", "dist/i18n/jquery-ui-i18n.js" ] + }, + + minifyCSS = { + "dist/jquery-ui.min.css": "dist/jquery-ui.css" + }, + + compareFiles = { + all: [ + "dist/jquery-ui.js", + "dist/jquery-ui.min.js" + ] + }; + +function mapMinFile( file ) { + return "dist/" + file.replace( /\.js$/, ".min.js" ).replace( /ui\//, "minified/" ); +} + +uiFiles.concat( allI18nFiles ).forEach(function( file ) { + minify[ mapMinFile( file ) ] = [ "", file ]; +}); + +cssFiles.forEach(function( file ) { + minifyCSS[ "dist/" + file.replace( /\.css$/, ".min.css" ).replace( /themes\/base\//, "themes/base/minified/" ) ] = [ "", "" ]; +}); + +uiFiles.forEach(function( file ) { + compareFiles[ file ] = [ file, mapMinFile( file ) ]; +}); + +// grunt plugins +grunt.loadNpmTasks( "grunt-css" ); +grunt.loadNpmTasks( "grunt-html" ); +grunt.loadNpmTasks( "grunt-compare-size" ); +grunt.loadNpmTasks( "grunt-junit" ); +grunt.loadNpmTasks( "grunt-git-authors" ); +// local testswarm and build tasks +grunt.loadTasks( "build/tasks" ); + +grunt.registerHelper( "strip_all_banners", function( filepath ) { + return grunt.file.read( filepath ).replace( /^\s*\/\*[\s\S]*?\*\/\s*/g, "" ); +}); + +function stripBanner( files ) { + return files.map(function( file ) { + return ""; + }); +} + +function stripDirectory( file ) { + // TODO: we're receiving the directive, so we need to strip the trailing > + // we should be receving a clean path without the directive + return file.replace( /.+\/(.+?)>?$/, "$1" ); +} +// allow access from banner template +global.stripDirectory = stripDirectory; + +function createBanner( files ) { + // strip folders + var fileNames = files && files.map( stripDirectory ); + return "/*! <%= pkg.title || pkg.name %> - v<%= pkg.version %> - " + + "<%= grunt.template.today('isoDate') %>\n" + + "<%= pkg.homepage ? '* ' + pkg.homepage + '\n' : '' %>" + + "* Includes: " + (files ? fileNames.join(", ") : "<%= stripDirectory(grunt.task.current.file.src[1]) %>") + "\n" + + "* Copyright <%= grunt.template.today('yyyy') %> <%= pkg.author.name %>;" + + " Licensed <%= _.pluck(pkg.licenses, 'type').join(', ') %> */"; +} + +grunt.initConfig({ + pkg: "", + files: { + dist: "<%= pkg.name %>-<%= pkg.version %>", + cdn: "<%= pkg.name %>-<%= pkg.version %>-cdn", + themes: "<%= pkg.name %>-themes-<%= pkg.version %>" + }, + meta: { + banner: createBanner(), + bannerAll: createBanner( uiFiles ), + bannerI18n: createBanner( allI18nFiles ), + bannerCSS: createBanner( cssFiles ) + }, + compare_size: compareFiles, + concat: { + ui: { + src: [ "", stripBanner( uiFiles ) ], + dest: "dist/jquery-ui.js" + }, + i18n: { + src: [ "", allI18nFiles ], + dest: "dist/i18n/jquery-ui-i18n.js" + }, + css: { + src: [ "", stripBanner( cssFiles ) ], + dest: "dist/jquery-ui.css" + } + }, + min: minify, + cssmin: minifyCSS, + htmllint: { + // ignore files that contain invalid html, used only for ajax content testing + all: grunt.file.expand( [ "demos/**/*.html", "tests/**/*.html" ] ).filter(function( file ) { + return !/(?:ajax\/content\d\.html|tabs\/data\/test\.html|tests\/unit\/core\/core\.html)/.test( file ); + }) + }, + copy: { + dist: { + src: [ + "AUTHORS.txt", + "jquery-*.js", + "MIT-LICENSE.txt", + "README.md", + "grunt.js", + "package.json", + "*.jquery.json", + "ui/**/*", + "demos/**/*", + "themes/**/*", + "external/**/*", + "tests/**/*" + ], + renames: { + "dist/jquery-ui.js": "ui/jquery-ui.js", + "dist/jquery-ui.min.js": "ui/minified/jquery-ui.min.js", + "dist/i18n/jquery-ui-i18n.js": "ui/i18n/jquery-ui-i18n.js", + "dist/i18n/jquery-ui-i18n.min.js": "ui/minified/i18n/jquery-ui-i18n.min.js", + "dist/jquery-ui.css": "themes/base/jquery-ui.css", + "dist/jquery-ui.min.css": "themes/base/minified/jquery-ui.min.css" + }, + dest: "dist/<%= files.dist %>" + }, + dist_min: { + src: "dist/minified/**/*", + strip: /^dist/, + dest: "dist/<%= files.dist %>/ui" + }, + dist_css_min: { + src: "dist/themes/base/minified/*.css", + strip: /^dist/, + dest: "dist/<%= files.dist %>" + }, + dist_units_images: { + src: "themes/base/images/*", + strip: /^themes\/base\//, + dest: "dist/" + }, + dist_min_images: { + src: "themes/base/images/*", + strip: /^themes\/base\//, + dest: "dist/<%= files.dist %>/themes/base/minified" + }, + cdn: { + src: [ + "AUTHORS.txt", + "MIT-LICENSE.txt", + "ui/*.js", + "package.json" + ], + renames: { + "dist/jquery-ui.js": "jquery-ui.js", + "dist/jquery-ui.min.js": "jquery-ui.min.js", + "dist/i18n/jquery-ui-i18n.js": "i18n/jquery-ui-i18n.js", + "dist/i18n/jquery-ui-i18n.min.js": "i18n/jquery-ui-i18n.min.js", + "dist/jquery-ui.css": "themes/base/jquery-ui.css", + "dist/jquery-ui.min.css": "themes/base/minified/jquery-ui.min.css" + }, + dest: "dist/<%= files.cdn %>" + }, + cdn_i18n: { + src: "ui/i18n/jquery.ui.datepicker-*.js", + strip: "ui/", + dest: "dist/<%= files.cdn %>" + }, + cdn_i18n_min: { + src: "dist/minified/i18n/jquery.ui.datepicker-*.js", + strip: "dist/minified", + dest: "dist/<%= files.cdn %>" + }, + cdn_min: { + src: "dist/minified/*.js", + strip: /^dist\/minified/, + dest: "dist/<%= files.cdn %>/ui" + }, + cdn_min_images: { + src: "themes/base/images/*", + strip: /^themes\/base\//, + dest: "dist/<%= files.cdn %>/themes/base/minified" + }, + cdn_themes: { + src: "dist/<%= files.themes %>/themes/**/*", + strip: "dist/<%= files.themes %>", + dest: "dist/<%= files.cdn %>" + }, + themes: { + src: [ + "AUTHORS.txt", + "MIT-LICENSE.txt", + "package.json" + ], + dest: "dist/<%= files.themes %>" + } + }, + zip: { + dist: { + src: "<%= files.dist %>", + dest: "<%= files.dist %>.zip" + }, + cdn: { + src: "<%= files.cdn %>", + dest: "<%= files.cdn %>.zip" + }, + themes: { + src: "<%= files.themes %>", + dest: "<%= files.themes %>.zip" + } + }, + md5: { + dist: { + src: "dist/<%= files.dist %>", + dest: "dist/<%= files.dist %>/MANIFEST" + }, + cdn: { + src: "dist/<%= files.cdn %>", + dest: "dist/<%= files.cdn %>/MANIFEST" + }, + themes: { + src: "dist/<%= files.themes %>", + dest: "dist/<%= files.themes %>/MANIFEST" + } + }, + qunit: { + files: grunt.file.expandFiles( "tests/unit/**/*.html" ).filter(function( file ) { + // disabling everything that doesn't (quite) work with PhantomJS for now + // TODO except for all|index|test, try to include more as we go + return !( /(all|all-active|index|test|draggable|droppable|selectable|resizable|sortable|dialog|slider|datepicker|tabs|tabs_deprecated)\.html$/ ).test( file ); + }) + }, + lint: { + ui: grunt.file.expandFiles( "ui/*.js" ).filter(function( file ) { + // TODO remove items from this list once rewritten + return !( /(mouse|datepicker|draggable|droppable|resizable|selectable|sortable)\.js$/ ).test( file ); + }), + grunt: [ "grunt.js", "build/**/*.js" ], + tests: "tests/unit/**/*.js" + }, + csslint: { + // nothing: [] + // TODO figure out what to check for, then fix and enable + base_theme: { + src: grunt.file.expandFiles( "themes/base/*.css" ).filter(function( file ) { + // TODO remove items from this list once rewritten + return !( /(button|datepicker|core|dialog|theme)\.css$/ ).test( file ); + }), + // TODO consider reenabling some of these rules + rules: { + "import": false, + "important": false, + "outline-none": false, + // especially this one + "overqualified-elements": false + } + } + }, + jshint: (function() { + function parserc( path ) { + var rc = grunt.file.readJSON( (path || "") + ".jshintrc" ), + settings = { + options: rc, + globals: {} + }; + + (rc.predef || []).forEach(function( prop ) { + settings.globals[ prop ] = true; + }); + delete rc.predef; + + return settings; + } + + return { + // TODO: use "faux strict mode" https://github.com/jshint/jshint/issues/504 + // TODO: limit `smarttabs` to multi-line comments https://github.com/jshint/jshint/issues/503 + options: parserc(), + ui: parserc( "ui/" ), + // TODO: `evil: true` is only for document.write() https://github.com/jshint/jshint/issues/519 + // TODO: don't create so many globals in tests + tests: parserc( "tests/" ) + }; + })() +}); + +grunt.registerTask( "default", "lint csslint htmllint qunit" ); +grunt.registerTask( "sizer", "concat:ui min:dist/jquery-ui.min.js compare_size:all" ); +grunt.registerTask( "sizer_all", "concat:ui min compare_size" ); +grunt.registerTask( "build", "concat min cssmin copy:dist_units_images" ); +grunt.registerTask( "release", "clean build copy:dist copy:dist_min copy:dist_min_images copy:dist_css_min md5:dist zip:dist" ); +grunt.registerTask( "release_themes", "release generate_themes copy:themes md5:themes zip:themes" ); +grunt.registerTask( "release_cdn", "release_themes copy:cdn copy:cdn_min copy:cdn_i18n copy:cdn_i18n_min copy:cdn_min_images copy:cdn_themes md5:cdn zip:cdn" ); + +}; diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/jquery-1.8.2.js b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/jquery-1.8.2.js new file mode 100755 index 000000000..d4f3bb38c --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/jquery-1.8.2.js @@ -0,0 +1,9440 @@ +/*! + * jQuery JavaScript Library v1.8.2 + * http://jquery.com/ + * + * Includes Sizzle.js + * http://sizzlejs.com/ + * + * Copyright 2012 jQuery Foundation and other contributors + * Released under the MIT license + * http://jquery.org/license + * + * Date: Thu Sep 20 2012 21:13:05 GMT-0400 (Eastern Daylight Time) + */ +(function( window, undefined ) { +var + // A central reference to the root jQuery(document) + rootjQuery, + + // The deferred used on DOM ready + readyList, + + // Use the correct document accordingly with window argument (sandbox) + document = window.document, + location = window.location, + navigator = window.navigator, + + // Map over jQuery in case of overwrite + _jQuery = window.jQuery, + + // Map over the $ in case of overwrite + _$ = window.$, + + // Save a reference to some core methods + core_push = Array.prototype.push, + core_slice = Array.prototype.slice, + core_indexOf = Array.prototype.indexOf, + core_toString = Object.prototype.toString, + core_hasOwn = Object.prototype.hasOwnProperty, + core_trim = String.prototype.trim, + + // Define a local copy of jQuery + jQuery = function( selector, context ) { + // The jQuery object is actually just the init constructor 'enhanced' + return new jQuery.fn.init( selector, context, rootjQuery ); + }, + + // Used for matching numbers + core_pnum = /[\-+]?(?:\d*\.|)\d+(?:[eE][\-+]?\d+|)/.source, + + // Used for detecting and trimming whitespace + core_rnotwhite = /\S/, + core_rspace = /\s+/, + + // Make sure we trim BOM and NBSP (here's looking at you, Safari 5.0 and IE) + rtrim = /^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g, + + // A simple way to check for HTML strings + // Prioritize #id over to avoid XSS via location.hash (#9521) + rquickExpr = /^(?:[^#<]*(<[\w\W]+>)[^>]*$|#([\w\-]*)$)/, + + // Match a standalone tag + rsingleTag = /^<(\w+)\s*\/?>(?:<\/\1>|)$/, + + // JSON RegExp + rvalidchars = /^[\],:{}\s]*$/, + rvalidbraces = /(?:^|:|,)(?:\s*\[)+/g, + rvalidescape = /\\(?:["\\\/bfnrt]|u[\da-fA-F]{4})/g, + rvalidtokens = /"[^"\\\r\n]*"|true|false|null|-?(?:\d\d*\.|)\d+(?:[eE][\-+]?\d+|)/g, + + // Matches dashed string for camelizing + rmsPrefix = /^-ms-/, + rdashAlpha = /-([\da-z])/gi, + + // Used by jQuery.camelCase as callback to replace() + fcamelCase = function( all, letter ) { + return ( letter + "" ).toUpperCase(); + }, + + // The ready event handler and self cleanup method + DOMContentLoaded = function() { + if ( document.addEventListener ) { + document.removeEventListener( "DOMContentLoaded", DOMContentLoaded, false ); + jQuery.ready(); + } else if ( document.readyState === "complete" ) { + // we're here because readyState === "complete" in oldIE + // which is good enough for us to call the dom ready! + document.detachEvent( "onreadystatechange", DOMContentLoaded ); + jQuery.ready(); + } + }, + + // [[Class]] -> type pairs + class2type = {}; + +jQuery.fn = jQuery.prototype = { + constructor: jQuery, + init: function( selector, context, rootjQuery ) { + var match, elem, ret, doc; + + // Handle $(""), $(null), $(undefined), $(false) + if ( !selector ) { + return this; + } + + // Handle $(DOMElement) + if ( selector.nodeType ) { + this.context = this[0] = selector; + this.length = 1; + return this; + } + + // Handle HTML strings + if ( typeof selector === "string" ) { + 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 = rquickExpr.exec( selector ); + } + + // Match html or make sure no context is specified for #id + if ( match && (match[1] || !context) ) { + + // HANDLE: $(html) -> $(array) + if ( match[1] ) { + context = context instanceof jQuery ? context[0] : context; + doc = ( context && context.nodeType ? context.ownerDocument || context : document ); + + // scripts is true for back-compat + selector = jQuery.parseHTML( match[1], doc, true ); + if ( rsingleTag.test( match[1] ) && jQuery.isPlainObject( context ) ) { + this.attr.call( selector, context, true ); + } + + 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.8.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 core_slice.call( this ); + }, + + // 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 = jQuery.merge( this.constructor(), 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 ) { + // Add the callback + jQuery.ready.promise().done( fn ); + + return this; + }, + + eq: function( i ) { + i = +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( core_slice.apply( this, arguments ), + "slice", core_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: core_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 ) { + + // Abort if there are pending holds or we're already ready + if ( wait === true ? --jQuery.readyWait : jQuery.isReady ) { + return; + } + + // 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").off("ready"); + } + }, + + // 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"; + }, + + isWindow: function( obj ) { + return obj != null && obj == obj.window; + }, + + isNumeric: function( obj ) { + return !isNaN( parseFloat(obj) ) && isFinite( obj ); + }, + + type: function( obj ) { + return obj == null ? + String( obj ) : + class2type[ core_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; + } + + try { + // Not own constructor property must be Object + if ( obj.constructor && + !core_hasOwn.call(obj, "constructor") && + !core_hasOwn.call(obj.constructor.prototype, "isPrototypeOf") ) { + return false; + } + } catch ( e ) { + // IE8,9 Will throw exceptions on certain host objects #9897 + 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 || core_hasOwn.call( obj, key ); + }, + + isEmptyObject: function( obj ) { + var name; + for ( name in obj ) { + return false; + } + return true; + }, + + error: function( msg ) { + throw new Error( msg ); + }, + + // data: string of html + // context (optional): If specified, the fragment will be created in this context, defaults to document + // scripts (optional): If true, will include scripts passed in the html string + parseHTML: function( data, context, scripts ) { + var parsed; + if ( !data || typeof data !== "string" ) { + return null; + } + if ( typeof context === "boolean" ) { + scripts = context; + context = 0; + } + context = context || document; + + // Single tag + if ( (parsed = rsingleTag.exec( data )) ) { + return [ context.createElement( parsed[1] ) ]; + } + + parsed = jQuery.buildFragment( [ data ], context, scripts ? null : [] ); + return jQuery.merge( [], + (parsed.cacheable ? jQuery.clone( parsed.fragment ) : parsed.fragment).childNodes ); + }, + + parseJSON: function( data ) { + if ( !data || typeof data !== "string") { + 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 + parseXML: function( data ) { + var xml, tmp; + if ( !data || typeof data !== "string" ) { + return null; + } + try { + 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 ); + } + } catch( e ) { + xml = undefined; + } + if ( !xml || !xml.documentElement || xml.getElementsByTagName( "parsererror" ).length ) { + 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 && core_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 ); + } + }, + + // Convert dashed to camelCase; used by the css and data modules + // Microsoft forgot to hump their vendor prefix (#9572) + camelCase: function( string ) { + return string.replace( rmsPrefix, "ms-" ).replace( rdashAlpha, fcamelCase ); + }, + + nodeName: function( elem, name ) { + return elem.nodeName && elem.nodeName.toLowerCase() === name.toLowerCase(); + }, + + // args is for internal usage only + each: function( obj, callback, args ) { + var name, + i = 0, + length = obj.length, + isObj = length === undefined || jQuery.isFunction( obj ); + + if ( args ) { + if ( isObj ) { + for ( name in obj ) { + if ( callback.apply( obj[ name ], args ) === false ) { + break; + } + } + } else { + for ( ; i < length; ) { + if ( callback.apply( obj[ i++ ], args ) === false ) { + break; + } + } + } + + // A special, fast, case for the most common use of each + } else { + if ( isObj ) { + for ( name in obj ) { + if ( callback.call( obj[ name ], name, obj[ name ] ) === false ) { + break; + } + } + } else { + for ( ; i < length; ) { + if ( callback.call( obj[ i ], i, obj[ i++ ] ) === false ) { + break; + } + } + } + } + + return obj; + }, + + // Use native String.trim function wherever possible + trim: core_trim && !core_trim.call("\uFEFF\xA0") ? + function( text ) { + return text == null ? + "" : + core_trim.call( text ); + } : + + // Otherwise use our own trimming functionality + function( text ) { + return text == null ? + "" : + ( text + "" ).replace( rtrim, "" ); + }, + + // results is for internal usage only + makeArray: function( arr, results ) { + var type, + ret = results || []; + + if ( arr != null ) { + // The window, strings (and functions) also have 'length' + // Tweaked logic slightly to handle Blackberry 4.7 RegExp issues #6930 + type = jQuery.type( arr ); + + if ( arr.length == null || type === "string" || type === "function" || type === "regexp" || jQuery.isWindow( arr ) ) { + core_push.call( ret, arr ); + } else { + jQuery.merge( ret, arr ); + } + } + + return ret; + }, + + inArray: function( elem, arr, i ) { + var len; + + if ( arr ) { + if ( core_indexOf ) { + return core_indexOf.call( arr, elem, i ); + } + + len = arr.length; + i = i ? i < 0 ? Math.max( 0, len + i ) : i : 0; + + for ( ; i < len; i++ ) { + // Skip accessing in sparse arrays + if ( i in arr && arr[ i ] === elem ) { + return i; + } + } + } + + return -1; + }, + + merge: function( first, second ) { + var l = second.length, + i = first.length, + j = 0; + + if ( typeof l === "number" ) { + for ( ; 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 retVal, + ret = [], + i = 0, + length = elems.length; + inv = !!inv; + + // Go through the array, only saving the items + // that pass the validator function + for ( ; 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 ) { + var tmp, args, proxy; + + if ( typeof context === "string" ) { + 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 + args = core_slice.call( arguments, 2 ); + proxy = function() { + return fn.apply( context, args.concat( core_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 || jQuery.guid++; + + return proxy; + }, + + // Multifunctional method to get and set values of a collection + // The value/s can optionally be executed if it's a function + access: function( elems, fn, key, value, chainable, emptyGet, pass ) { + var exec, + bulk = key == null, + i = 0, + length = elems.length; + + // Sets many values + if ( key && typeof key === "object" ) { + for ( i in key ) { + jQuery.access( elems, fn, i, key[i], 1, emptyGet, value ); + } + chainable = 1; + + // Sets one value + } else if ( value !== undefined ) { + // Optionally, function values get executed if exec is true + exec = pass === undefined && jQuery.isFunction( value ); + + if ( bulk ) { + // Bulk operations only iterate when executing function values + if ( exec ) { + exec = fn; + fn = function( elem, key, value ) { + return exec.call( jQuery( elem ), value ); + }; + + // Otherwise they run against the entire set + } else { + fn.call( elems, value ); + fn = null; + } + } + + if ( fn ) { + for (; i < length; i++ ) { + fn( elems[i], key, exec ? value.call( elems[i], i, fn( elems[i], key ) ) : value, pass ); + } + } + + chainable = 1; + } + + return chainable ? + elems : + + // Gets + bulk ? + fn.call( elems ) : + length ? fn( elems[0], key ) : emptyGet; + }, + + now: function() { + return ( new Date() ).getTime(); + } +}); + +jQuery.ready.promise = function( obj ) { + if ( !readyList ) { + + readyList = jQuery.Deferred(); + + // Catch cases where $(document).ready() is called after the browser event has already occurred. + // we once tried to use readyState "interactive" here, but it caused issues like the one + // discovered by ChrisS here: http://bugs.jquery.com/ticket/12282#comment:15 + if ( document.readyState === "complete" ) { + // Handle it asynchronously to allow scripts the opportunity to delay ready + setTimeout( jQuery.ready, 1 ); + + // Standards-based browsers support DOMContentLoaded + } else 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 { + // 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 top = false; + + try { + top = window.frameElement == null && document.documentElement; + } catch(e) {} + + if ( top && top.doScroll ) { + (function doScrollCheck() { + if ( !jQuery.isReady ) { + + try { + // Use the trick by Diego Perini + // http://javascript.nwbox.com/IEContentLoaded/ + top.doScroll("left"); + } catch(e) { + return setTimeout( doScrollCheck, 50 ); + } + + // and execute any waiting functions + jQuery.ready(); + } + })(); + } + } + } + return readyList.promise( obj ); +}; + +// Populate the class2type map +jQuery.each("Boolean Number String Function Array Date RegExp Object".split(" "), function(i, name) { + class2type[ "[object " + name + "]" ] = name.toLowerCase(); +}); + +// All jQuery objects should point back to these +rootjQuery = jQuery(document); +// String to Object options format cache +var optionsCache = {}; + +// Convert String-formatted options into Object-formatted ones and store in cache +function createOptions( options ) { + var object = optionsCache[ options ] = {}; + jQuery.each( options.split( core_rspace ), function( _, flag ) { + object[ flag ] = true; + }); + return object; +} + +/* + * Create a callback list using the following parameters: + * + * options: an optional list of space-separated options that will change how + * the callback list behaves or a more traditional option object + * + * By default a callback list will act like an event callback list and can be + * "fired" multiple times. + * + * Possible options: + * + * once: will ensure the callback list can only be fired once (like a Deferred) + * + * memory: will keep track of previous values and will call any callback added + * after the list has been fired right away with the latest "memorized" + * values (like a Deferred) + * + * unique: will ensure a callback can only be added once (no duplicate in the list) + * + * stopOnFalse: interrupt callings when a callback returns false + * + */ +jQuery.Callbacks = function( options ) { + + // Convert options from String-formatted to Object-formatted if needed + // (we check in cache first) + options = typeof options === "string" ? + ( optionsCache[ options ] || createOptions( options ) ) : + jQuery.extend( {}, options ); + + var // Last fire value (for non-forgettable lists) + memory, + // Flag to know if list was already fired + fired, + // Flag to know if list is currently firing + firing, + // First callback to fire (used internally by add and fireWith) + firingStart, + // End of the loop when firing + firingLength, + // Index of currently firing callback (modified by remove if needed) + firingIndex, + // Actual callback list + list = [], + // Stack of fire calls for repeatable lists + stack = !options.once && [], + // Fire callbacks + fire = function( data ) { + memory = options.memory && data; + fired = true; + firingIndex = firingStart || 0; + firingStart = 0; + firingLength = list.length; + firing = true; + for ( ; list && firingIndex < firingLength; firingIndex++ ) { + if ( list[ firingIndex ].apply( data[ 0 ], data[ 1 ] ) === false && options.stopOnFalse ) { + memory = false; // To prevent further calls using add + break; + } + } + firing = false; + if ( list ) { + if ( stack ) { + if ( stack.length ) { + fire( stack.shift() ); + } + } else if ( memory ) { + list = []; + } else { + self.disable(); + } + } + }, + // Actual Callbacks object + self = { + // Add a callback or a collection of callbacks to the list + add: function() { + if ( list ) { + // First, we save the current length + var start = list.length; + (function add( args ) { + jQuery.each( args, function( _, arg ) { + var type = jQuery.type( arg ); + if ( type === "function" && ( !options.unique || !self.has( arg ) ) ) { + list.push( arg ); + } else if ( arg && arg.length && type !== "string" ) { + // Inspect recursively + add( arg ); + } + }); + })( arguments ); + // Do we need to add the callbacks to the + // current firing batch? + if ( firing ) { + firingLength = list.length; + // With memory, if we're not firing then + // we should call right away + } else if ( memory ) { + firingStart = start; + fire( memory ); + } + } + return this; + }, + // Remove a callback from the list + remove: function() { + if ( list ) { + jQuery.each( arguments, function( _, arg ) { + var index; + while( ( index = jQuery.inArray( arg, list, index ) ) > -1 ) { + list.splice( index, 1 ); + // Handle firing indexes + if ( firing ) { + if ( index <= firingLength ) { + firingLength--; + } + if ( index <= firingIndex ) { + firingIndex--; + } + } + } + }); + } + return this; + }, + // Control if a given callback is in the list + has: function( fn ) { + return jQuery.inArray( fn, list ) > -1; + }, + // Remove all callbacks from the list + empty: function() { + list = []; + return this; + }, + // Have the list do nothing anymore + disable: function() { + list = stack = memory = undefined; + return this; + }, + // Is it disabled? + disabled: function() { + return !list; + }, + // Lock the list in its current state + lock: function() { + stack = undefined; + if ( !memory ) { + self.disable(); + } + return this; + }, + // Is it locked? + locked: function() { + return !stack; + }, + // Call all callbacks with the given context and arguments + fireWith: function( context, args ) { + args = args || []; + args = [ context, args.slice ? args.slice() : args ]; + if ( list && ( !fired || stack ) ) { + if ( firing ) { + stack.push( args ); + } else { + fire( args ); + } + } + return this; + }, + // Call all the callbacks with the given arguments + fire: function() { + self.fireWith( this, arguments ); + return this; + }, + // To know if the callbacks have already been called at least once + fired: function() { + return !!fired; + } + }; + + return self; +}; +jQuery.extend({ + + Deferred: function( func ) { + var tuples = [ + // action, add listener, listener list, final state + [ "resolve", "done", jQuery.Callbacks("once memory"), "resolved" ], + [ "reject", "fail", jQuery.Callbacks("once memory"), "rejected" ], + [ "notify", "progress", jQuery.Callbacks("memory") ] + ], + state = "pending", + promise = { + state: function() { + return state; + }, + always: function() { + deferred.done( arguments ).fail( arguments ); + return this; + }, + then: function( /* fnDone, fnFail, fnProgress */ ) { + var fns = arguments; + return jQuery.Deferred(function( newDefer ) { + jQuery.each( tuples, function( i, tuple ) { + var action = tuple[ 0 ], + fn = fns[ i ]; + // deferred[ done | fail | progress ] for forwarding actions to newDefer + deferred[ tuple[1] ]( jQuery.isFunction( fn ) ? + function() { + var returned = fn.apply( this, arguments ); + if ( returned && jQuery.isFunction( returned.promise ) ) { + returned.promise() + .done( newDefer.resolve ) + .fail( newDefer.reject ) + .progress( newDefer.notify ); + } else { + newDefer[ action + "With" ]( this === deferred ? newDefer : this, [ returned ] ); + } + } : + newDefer[ action ] + ); + }); + fns = null; + }).promise(); + }, + // Get a promise for this deferred + // If obj is provided, the promise aspect is added to the object + promise: function( obj ) { + return obj != null ? jQuery.extend( obj, promise ) : promise; + } + }, + deferred = {}; + + // Keep pipe for back-compat + promise.pipe = promise.then; + + // Add list-specific methods + jQuery.each( tuples, function( i, tuple ) { + var list = tuple[ 2 ], + stateString = tuple[ 3 ]; + + // promise[ done | fail | progress ] = list.add + promise[ tuple[1] ] = list.add; + + // Handle state + if ( stateString ) { + list.add(function() { + // state = [ resolved | rejected ] + state = stateString; + + // [ reject_list | resolve_list ].disable; progress_list.lock + }, tuples[ i ^ 1 ][ 2 ].disable, tuples[ 2 ][ 2 ].lock ); + } + + // deferred[ resolve | reject | notify ] = list.fire + deferred[ tuple[0] ] = list.fire; + deferred[ tuple[0] + "With" ] = list.fireWith; + }); + + // Make the deferred a promise + promise.promise( deferred ); + + // Call given func if any + if ( func ) { + func.call( deferred, deferred ); + } + + // All done! + return deferred; + }, + + // Deferred helper + when: function( subordinate /* , ..., subordinateN */ ) { + var i = 0, + resolveValues = core_slice.call( arguments ), + length = resolveValues.length, + + // the count of uncompleted subordinates + remaining = length !== 1 || ( subordinate && jQuery.isFunction( subordinate.promise ) ) ? length : 0, + + // the master Deferred. If resolveValues consist of only a single Deferred, just use that. + deferred = remaining === 1 ? subordinate : jQuery.Deferred(), + + // Update function for both resolve and progress values + updateFunc = function( i, contexts, values ) { + return function( value ) { + contexts[ i ] = this; + values[ i ] = arguments.length > 1 ? core_slice.call( arguments ) : value; + if( values === progressValues ) { + deferred.notifyWith( contexts, values ); + } else if ( !( --remaining ) ) { + deferred.resolveWith( contexts, values ); + } + }; + }, + + progressValues, progressContexts, resolveContexts; + + // add listeners to Deferred subordinates; treat others as resolved + if ( length > 1 ) { + progressValues = new Array( length ); + progressContexts = new Array( length ); + resolveContexts = new Array( length ); + for ( ; i < length; i++ ) { + if ( resolveValues[ i ] && jQuery.isFunction( resolveValues[ i ].promise ) ) { + resolveValues[ i ].promise() + .done( updateFunc( i, resolveContexts, resolveValues ) ) + .fail( deferred.reject ) + .progress( updateFunc( i, progressContexts, progressValues ) ); + } else { + --remaining; + } + } + } + + // if we're not waiting on anything, resolve the master + if ( !remaining ) { + deferred.resolveWith( resolveContexts, resolveValues ); + } + + return deferred.promise(); + } +}); +jQuery.support = (function() { + + var support, + all, + a, + select, + opt, + input, + fragment, + eventName, + i, + isSupported, + clickFn, + div = document.createElement("div"); + + // Preliminary tests + div.setAttribute( "className", "t" ); + div.innerHTML = "
      a"; + + all = div.getElementsByTagName("*"); + a = div.getElementsByTagName("a")[ 0 ]; + a.style.cssText = "top:1px;float:left;opacity:.5"; + + // Can't get basic test support + if ( !all || !all.length ) { + 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.5/.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", + + // Tests for enctype support on a form(#6743) + enctype: !!document.createElement("form").enctype, + + // Makes sure cloning an html5 element does not cause problems + // Where outerHTML is undefined, this still works + html5Clone: document.createElement("nav").cloneNode( true ).outerHTML !== "<:nav>", + + // jQuery.support.boxModel DEPRECATED in 1.8 since we don't support Quirks Mode + boxModel: ( document.compatMode === "CSS1Compat" ), + + // Will be defined later + submitBubbles: true, + changeBubbles: true, + focusinBubbles: false, + deleteExpando: true, + noCloneEvent: true, + inlineBlockNeedsLayout: false, + shrinkWrapBlocks: false, + reliableMarginRight: true, + boxSizingReliable: true, + pixelPosition: false + }; + + // 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", clickFn = function() { + // Cloning a node shouldn't copy over any + // bound event handlers (IE does this) + support.noCloneEvent = false; + }); + div.cloneNode( true ).fireEvent("onclick"); + div.detachEvent( "onclick", clickFn ); + } + + // Check if a radio maintains its 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" ); + + // #11217 - WebKit loses check when the name is after the checked attribute + input.setAttribute( "name", "t" ); + + div.appendChild( input ); + fragment = document.createDocumentFragment(); + fragment.appendChild( div.lastChild ); + + // WebKit doesn't clone checked state correctly in fragments + support.checkClone = fragment.cloneNode( true ).cloneNode( true ).lastChild.checked; + + // Check if a disconnected checkbox will retain its checked + // value of true after appended to the DOM (IE6/7) + support.appendChecked = input.checked; + + fragment.removeChild( input ); + fragment.appendChild( div ); + + // Technique from Juriy Zaytsev + // http://perfectionkills.com/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: true, + change: true, + focusin: true + }) { + eventName = "on" + i; + isSupported = ( eventName in div ); + if ( !isSupported ) { + div.setAttribute( eventName, "return;" ); + isSupported = ( typeof div[ eventName ] === "function" ); + } + support[ i + "Bubbles" ] = isSupported; + } + } + + // Run tests that need a body at doc ready + jQuery(function() { + var container, div, tds, marginDiv, + divReset = "padding:0;margin:0;border:0;display:block;overflow:hidden;", + body = document.getElementsByTagName("body")[0]; + + if ( !body ) { + // Return for frameset docs that don't have a body + return; + } + + container = document.createElement("div"); + container.style.cssText = "visibility:hidden;border:0;width:0;height:0;position:static;top:0;margin-top:1px"; + body.insertBefore( container, body.firstChild ); + + // Construct the test element + div = document.createElement("div"); + container.appendChild( div ); + + // 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) + div.innerHTML = "
      t
      "; + tds = div.getElementsByTagName("td"); + tds[ 0 ].style.cssText = "padding:0;margin:0;border:0;display:none"; + 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 ); + + // Check box-sizing and margin behavior + div.innerHTML = ""; + div.style.cssText = "box-sizing:border-box;-moz-box-sizing:border-box;-webkit-box-sizing:border-box;padding:1px;border:1px;display:block;width:4px;margin-top:1%;position:absolute;top:1%;"; + support.boxSizing = ( div.offsetWidth === 4 ); + support.doesNotIncludeMarginInBodyOffset = ( body.offsetTop !== 1 ); + + // NOTE: To any future maintainer, we've window.getComputedStyle + // because jsdom on node.js will break without it. + if ( window.getComputedStyle ) { + support.pixelPosition = ( window.getComputedStyle( div, null ) || {} ).top !== "1%"; + support.boxSizingReliable = ( window.getComputedStyle( div, null ) || { width: "4px" } ).width === "4px"; + + // 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 + marginDiv = document.createElement("div"); + marginDiv.style.cssText = div.style.cssText = divReset; + marginDiv.style.marginRight = marginDiv.style.width = "0"; + div.style.width = "1px"; + div.appendChild( marginDiv ); + support.reliableMarginRight = + !parseFloat( ( window.getComputedStyle( marginDiv, null ) || {} ).marginRight ); + } + + if ( typeof div.style.zoom !== "undefined" ) { + // 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.innerHTML = ""; + div.style.cssText = divReset + "width:1px;padding:1px;display:inline;zoom:1"; + support.inlineBlockNeedsLayout = ( div.offsetWidth === 3 ); + + // Check if elements with layout shrink-wrap their children + // (IE 6 does this) + div.style.display = "block"; + div.style.overflow = "visible"; + div.innerHTML = "
      "; + div.firstChild.style.width = "5px"; + support.shrinkWrapBlocks = ( div.offsetWidth !== 3 ); + + container.style.zoom = 1; + } + + // Null elements to avoid leaks in IE + body.removeChild( container ); + container = div = tds = marginDiv = null; + }); + + // Null elements to avoid leaks in IE + fragment.removeChild( div ); + all = a = select = opt = input = fragment = div = null; + + return support; +})(); +var rbrace = /(?:\{[\s\S]*\}|\[[\s\S]*\])$/, + rmultiDash = /([A-Z])/g; + +jQuery.extend({ + cache: {}, + + deletedIds: [], + + // Remove at next major release (1.9/2.0) + 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 thisCache, ret, + internalKey = jQuery.expando, + getByName = typeof name === "string", + + // 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[ internalKey ] : elem[ internalKey ] && internalKey; + + // 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 || !cache[id] || (!pvt && !cache[id].data)) && 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[ internalKey ] = id = jQuery.deletedIds.pop() || jQuery.guid++; + } else { + id = internalKey; + } + } + + if ( !cache[ id ] ) { + cache[ id ] = {}; + + // 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 ] = jQuery.extend( cache[ id ], name ); + } else { + cache[ id ].data = jQuery.extend( cache[ id ].data, name ); + } + } + + thisCache = cache[ id ]; + + // jQuery data() is stored in a separate object inside the object's internal data + // cache in order to avoid key collisions between internal data and user-defined + // data. + if ( !pvt ) { + if ( !thisCache.data ) { + thisCache.data = {}; + } + + thisCache = thisCache.data; + } + + if ( data !== undefined ) { + thisCache[ jQuery.camelCase( name ) ] = data; + } + + // Check for both converted-to-camel and non-converted data property names + // If a data property was specified + if ( getByName ) { + + // First Try to find as-is property data + ret = thisCache[ name ]; + + // Test for null|undefined property data + if ( ret == null ) { + + // Try to find the camelCased property + ret = thisCache[ jQuery.camelCase( name ) ]; + } + } else { + ret = thisCache; + } + + return ret; + }, + + removeData: function( elem, name, pvt /* Internal Use Only */ ) { + if ( !jQuery.acceptData( elem ) ) { + return; + } + + var thisCache, i, l, + + isNode = elem.nodeType, + + // See jQuery.data for more information + cache = isNode ? jQuery.cache : elem, + 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 ) { + + thisCache = pvt ? cache[ id ] : cache[ id ].data; + + if ( thisCache ) { + + // Support array or space separated string names for data keys + if ( !jQuery.isArray( name ) ) { + + // try the string as a key before any manipulation + if ( name in thisCache ) { + name = [ name ]; + } else { + + // split the camel cased version by spaces unless a key with the spaces exists + name = jQuery.camelCase( name ); + if ( name in thisCache ) { + name = [ name ]; + } else { + name = name.split(" "); + } + } + } + + for ( i = 0, l = name.length; i < l; i++ ) { + delete thisCache[ name[i] ]; + } + + // If there is no data left in the cache, we want to continue + // and let the cache object itself get destroyed + if ( !( pvt ? isEmptyDataObject : jQuery.isEmptyObject )( thisCache ) ) { + return; + } + } + } + + // See jQuery.data for more information + if ( !pvt ) { + delete cache[ id ].data; + + // Don't destroy the parent cache unless the internal data object + // had been the only thing left in it + if ( !isEmptyDataObject( cache[ id ] ) ) { + return; + } + } + + // Destroy the cache + if ( isNode ) { + jQuery.cleanData( [ elem ], true ); + + // Use delete when supported for expandos or `cache` is not a window per isWindow (#10080) + } else if ( jQuery.support.deleteExpando || cache != cache.window ) { + delete cache[ id ]; + + // When all else fails, null + } else { + cache[ id ] = 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 ) { + var noData = elem.nodeName && jQuery.noData[ elem.nodeName.toLowerCase() ]; + + // nodes accept data unless otherwise specified; rejection can be conditional + return !noData || noData !== true && elem.getAttribute("classid") === noData; + } +}); + +jQuery.fn.extend({ + data: function( key, value ) { + var parts, part, attr, name, l, + elem = this[0], + i = 0, + data = null; + + // Gets all values + if ( key === undefined ) { + if ( this.length ) { + data = jQuery.data( elem ); + + if ( elem.nodeType === 1 && !jQuery._data( elem, "parsedAttrs" ) ) { + attr = elem.attributes; + for ( l = attr.length; i < l; i++ ) { + name = attr[i].name; + + if ( !name.indexOf( "data-" ) ) { + name = jQuery.camelCase( name.substring(5) ); + + dataAttr( elem, name, data[ name ] ); + } + } + jQuery._data( elem, "parsedAttrs", true ); + } + } + + return data; + } + + // Sets multiple values + if ( typeof key === "object" ) { + return this.each(function() { + jQuery.data( this, key ); + }); + } + + parts = key.split( ".", 2 ); + parts[1] = parts[1] ? "." + parts[1] : ""; + part = parts[1] + "!"; + + return jQuery.access( this, function( value ) { + + if ( value === undefined ) { + data = this.triggerHandler( "getData" + part, [ parts[0] ] ); + + // Try to fetch any internally stored data first + if ( data === undefined && elem ) { + data = jQuery.data( elem, key ); + data = dataAttr( elem, key, data ); + } + + return data === undefined && parts[1] ? + this.data( parts[0] ) : + data; + } + + parts[1] = value; + this.each(function() { + var self = jQuery( this ); + + self.triggerHandler( "setData" + part, parts ); + jQuery.data( this, key, value ); + self.triggerHandler( "changeData" + part, parts ); + }); + }, null, value, arguments.length > 1, null, false ); + }, + + 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" ).toLowerCase(); + + data = elem.getAttribute( name ); + + if ( typeof data === "string" ) { + try { + data = data === "true" ? true : + data === "false" ? false : + data === "null" ? null : + // Only convert to a number if it doesn't change the string + +data + "" === data ? +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; +} + +// checks a cache object for emptiness +function isEmptyDataObject( obj ) { + var name; + for ( name in obj ) { + + // if the public data object is empty, the private is still empty + if ( name === "data" && jQuery.isEmptyObject( obj[name] ) ) { + continue; + } + if ( name !== "toJSON" ) { + return false; + } + } + + return true; +} +jQuery.extend({ + queue: function( elem, type, data ) { + var queue; + + if ( elem ) { + type = ( type || "fx" ) + "queue"; + queue = jQuery._data( elem, type ); + + // Speed up dequeue by getting out quickly if this is just a lookup + if ( data ) { + if ( !queue || jQuery.isArray(data) ) { + queue = jQuery._data( elem, type, jQuery.makeArray(data) ); + } else { + queue.push( data ); + } + } + return queue || []; + } + }, + + dequeue: function( elem, type ) { + type = type || "fx"; + + var queue = jQuery.queue( elem, type ), + startLength = queue.length, + fn = queue.shift(), + hooks = jQuery._queueHooks( elem, type ), + next = function() { + jQuery.dequeue( elem, type ); + }; + + // If the fx queue is dequeued, always remove the progress sentinel + if ( fn === "inprogress" ) { + fn = queue.shift(); + startLength--; + } + + if ( fn ) { + + // Add a progress sentinel to prevent the fx queue from being + // automatically dequeued + if ( type === "fx" ) { + queue.unshift( "inprogress" ); + } + + // clear up the last queue stop function + delete hooks.stop; + fn.call( elem, next, hooks ); + } + + if ( !startLength && hooks ) { + hooks.empty.fire(); + } + }, + + // not intended for public consumption - generates a queueHooks object, or returns the current one + _queueHooks: function( elem, type ) { + var key = type + "queueHooks"; + return jQuery._data( elem, key ) || jQuery._data( elem, key, { + empty: jQuery.Callbacks("once memory").add(function() { + jQuery.removeData( elem, type + "queue", true ); + jQuery.removeData( elem, key, true ); + }) + }); + } +}); + +jQuery.fn.extend({ + queue: function( type, data ) { + var setter = 2; + + if ( typeof type !== "string" ) { + data = type; + type = "fx"; + setter--; + } + + if ( arguments.length < setter ) { + return jQuery.queue( this[0], type ); + } + + return data === undefined ? + this : + this.each(function() { + var queue = jQuery.queue( this, type, data ); + + // ensure a hooks for this queue + jQuery._queueHooks( this, type ); + + 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( next, hooks ) { + var timeout = setTimeout( next, time ); + hooks.stop = function() { + clearTimeout( timeout ); + }; + }); + }, + 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, obj ) { + var tmp, + count = 1, + defer = jQuery.Deferred(), + elements = this, + i = this.length, + resolve = function() { + if ( !( --count ) ) { + defer.resolveWith( elements, [ elements ] ); + } + }; + + if ( typeof type !== "string" ) { + obj = type; + type = undefined; + } + type = type || "fx"; + + while( i-- ) { + tmp = jQuery._data( elements[ i ], type + "queueHooks" ); + if ( tmp && tmp.empty ) { + count++; + tmp.empty.add( resolve ); + } + } + resolve(); + return defer.promise( obj ); + } +}); +var nodeHook, boolHook, fixSpecified, + rclass = /[\t\r\n]/g, + 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, + getSetAttribute = jQuery.support.getSetAttribute; + +jQuery.fn.extend({ + attr: function( name, value ) { + return jQuery.access( this, jQuery.attr, name, value, arguments.length > 1 ); + }, + + removeAttr: function( name ) { + return this.each(function() { + jQuery.removeAttr( this, name ); + }); + }, + + prop: function( name, value ) { + return jQuery.access( this, jQuery.prop, name, value, arguments.length > 1 ); + }, + + 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( core_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 ] + " " ) < 0 ) { + setClass += classNames[ c ] + " "; + } + } + elem.className = jQuery.trim( setClass ); + } + } + } + } + + return this; + }, + + removeClass: function( value ) { + var removes, className, elem, c, cl, i, l; + + 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 ) { + removes = ( value || "" ).split( core_rspace ); + + for ( i = 0, l = this.length; i < l; i++ ) { + elem = this[ i ]; + if ( elem.nodeType === 1 && elem.className ) { + + className = (" " + elem.className + " ").replace( rclass, " " ); + + // loop over each item in the removal list + for ( c = 0, cl = removes.length; c < cl; c++ ) { + // Remove until there is nothing to remove, + while ( className.indexOf(" " + removes[ c ] + " ") >= 0 ) { + className = className.replace( " " + removes[ c ] + " " , " " ); + } + } + elem.className = value ? jQuery.trim( 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( core_rspace ); + + while ( (className = classNames[ i++ ]) ) { + // check each className given, space separated 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 + " ", + i = 0, + l = this.length; + for ( ; i < l; i++ ) { + if ( this[i].nodeType === 1 && (" " + this[i].className + " ").replace(rclass, " ").indexOf( className ) >= 0 ) { + return true; + } + } + + return false; + }, + + val: function( value ) { + var hooks, ret, isFunction, + elem = this[0]; + + if ( !arguments.length ) { + if ( elem ) { + hooks = jQuery.valHooks[ elem.type ] || jQuery.valHooks[ elem.nodeName.toLowerCase() ]; + + 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; + } + + isFunction = jQuery.isFunction( value ); + + return this.each(function( i ) { + var val, + self = jQuery(this); + + 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.type ] || jQuery.valHooks[ this.nodeName.toLowerCase() ]; + + // 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, i, max, option, + 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 + i = one ? index : 0; + max = one ? index + 1 : options.length; + for ( ; i < max; i++ ) { + 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; + } + } + }, + + // Unused in 1.8, left in so attrFn-stabbers won't die; remove in 1.9 + attrFn: {}, + + attr: function( elem, name, value, pass ) { + var ret, hooks, notxml, + nType = elem.nodeType; + + // don't get/set attributes on text, comment and attribute nodes + if ( !elem || nType === 3 || nType === 8 || nType === 2 ) { + return; + } + + if ( pass && jQuery.isFunction( jQuery.fn[ name ] ) ) { + return jQuery( elem )[ name ]( value ); + } + + // Fallback to prop when attributes are not supported + if ( typeof elem.getAttribute === "undefined" ) { + return jQuery.prop( elem, name, value ); + } + + notxml = nType !== 1 || !jQuery.isXMLDoc( elem ); + + // All attributes are lowercase + // Grab necessary hook if one is defined + if ( notxml ) { + name = name.toLowerCase(); + hooks = jQuery.attrHooks[ name ] || ( rboolean.test( name ) ? boolHook : nodeHook ); + } + + if ( value !== undefined ) { + + if ( value === null ) { + jQuery.removeAttr( elem, name ); + return; + + } 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, value ) { + var propName, attrNames, name, isBool, + i = 0; + + if ( value && elem.nodeType === 1 ) { + + attrNames = value.split( core_rspace ); + + for ( ; i < attrNames.length; i++ ) { + name = attrNames[ i ]; + + if ( name ) { + propName = jQuery.propFix[ name ] || name; + isBool = rboolean.test( name ); + + // See #9699 for explanation of this approach (setting first, then removal) + // Do not do this for boolean attributes (see #10870) + if ( !isBool ) { + jQuery.attr( elem, name, "" ); + } + elem.removeAttribute( getSetAttribute ? name : propName ); + + // Set corresponding property to false for boolean attributes + if ( isBool && propName 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; + } + } + }, + // Use the value property for back compat + // Use the nodeHook for button elements in IE6/7 (#1954) + value: { + get: function( elem, name ) { + if ( nodeHook && jQuery.nodeName( elem, "button" ) ) { + return nodeHook.get( elem, name ); + } + return name in elem ? + elem.value : + null; + }, + set: function( elem, value, name ) { + if ( nodeHook && jQuery.nodeName( elem, "button" ) ) { + return nodeHook.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 ret, hooks, notxml, + nType = elem.nodeType; + + // don't get/set properties on text, comment and attribute nodes + if ( !elem || nType === 3 || nType === 8 || nType === 2 ) { + return; + } + + 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 )) !== null ) { + return ret; + + } else { + return elem[ name ]; + } + } + }, + + propHooks: { + 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; + } + } + } +}); + +// Hook for boolean attributes +boolHook = { + get: function( elem, name ) { + // Align boolean attributes with corresponding properties + // Fall back to attribute presence where some booleans are not supported + var attrNode, + property = jQuery.prop( elem, name ); + return property === true || typeof property !== "boolean" && ( attrNode = elem.getAttributeNode(name) ) && attrNode.nodeValue !== false ? + 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 ( !getSetAttribute ) { + + fixSpecified = { + name: true, + id: true, + coords: true + }; + + // Use this for any attribute in IE6/7 + // This fixes almost every IE6/7 issue + nodeHook = jQuery.valHooks.button = { + get: function( elem, name ) { + var ret; + ret = elem.getAttributeNode( name ); + return ret && ( fixSpecified[ name ] ? ret.value !== "" : ret.specified ) ? + ret.value : + undefined; + }, + set: function( elem, value, name ) { + // Set the existing or create a new attribute node + var ret = elem.getAttributeNode( name ); + if ( !ret ) { + ret = document.createAttribute( name ); + elem.setAttributeNode( ret ); + } + return ( ret.value = 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; + } + } + }); + }); + + // Set contenteditable to false on removals(#10429) + // Setting to empty string throws an error as an invalid value + jQuery.attrHooks.contenteditable = { + get: nodeHook.get, + set: function( elem, value, name ) { + if ( value === "" ) { + value = "false"; + } + nodeHook.set( elem, value, name ); + } + }; +} + + +// 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; + } + } + return null; + } + }); +} + +// IE6/7 call enctype encoding +if ( !jQuery.support.enctype ) { + jQuery.propFix.enctype = "encoding"; +} + +// 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 rformElems = /^(?:textarea|input|select)$/i, + rtypenamespace = /^([^\.]*|)(?:\.(.+)|)$/, + rhoverHack = /(?:^|\s)hover(\.\S+|)\b/, + rkeyEvent = /^key/, + rmouseEvent = /^(?:mouse|contextmenu)|click/, + rfocusMorph = /^(?:focusinfocus|focusoutblur)$/, + hoverHack = function( events ) { + return jQuery.event.special.hover ? events : events.replace( rhoverHack, "mouseenter$1 mouseleave$1" ); + }; + +/* + * Helper functions for managing events -- not part of the public interface. + * Props to Dean Edwards' addEvent library for many of the ideas. + */ +jQuery.event = { + + add: function( elem, types, handler, data, selector ) { + + var elemData, eventHandle, events, + t, tns, type, namespaces, handleObj, + handleObjIn, handlers, special; + + // Don't attach events to noData or text/comment nodes (allow plain objects tho) + if ( elem.nodeType === 3 || elem.nodeType === 8 || !types || !handler || !(elemData = jQuery._data( elem )) ) { + return; + } + + // Caller can pass in an object of custom data in lieu of the handler + if ( handler.handler ) { + handleObjIn = handler; + handler = handleObjIn.handler; + selector = handleObjIn.selector; + } + + // Make sure that the handler has a unique ID, used to find/remove it later + if ( !handler.guid ) { + handler.guid = jQuery.guid++; + } + + // Init the element's event structure and main handler, if this is the first + events = elemData.events; + if ( !events ) { + elemData.events = events = {}; + } + eventHandle = elemData.handle; + 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.dispatch.apply( eventHandle.elem, arguments ) : + undefined; + }; + // Add elem as a property of the handle fn to prevent a memory leak with IE non-native events + eventHandle.elem = elem; + } + + // Handle multiple events separated by a space + // jQuery(...).bind("mouseover mouseout", fn); + types = jQuery.trim( hoverHack(types) ).split( " " ); + for ( t = 0; t < types.length; t++ ) { + + tns = rtypenamespace.exec( types[t] ) || []; + type = tns[1]; + namespaces = ( tns[2] || "" ).split( "." ).sort(); + + // If event changes its type, use the special event handlers for the changed type + special = jQuery.event.special[ type ] || {}; + + // If selector defined, determine special event api type, otherwise given type + type = ( selector ? special.delegateType : special.bindType ) || type; + + // Update special based on newly reset type + special = jQuery.event.special[ type ] || {}; + + // handleObj is passed to all event handlers + handleObj = jQuery.extend({ + type: type, + origType: tns[1], + data: data, + handler: handler, + guid: handler.guid, + selector: selector, + needsContext: selector && jQuery.expr.match.needsContext.test( selector ), + namespace: namespaces.join(".") + }, handleObjIn ); + + // Init the event handler queue if we're the first + handlers = events[ type ]; + if ( !handlers ) { + handlers = events[ type ] = []; + handlers.delegateCount = 0; + + // 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 to the element's handler list, delegates in front + if ( selector ) { + handlers.splice( handlers.delegateCount++, 0, handleObj ); + } else { + handlers.push( handleObj ); + } + + // Keep track of which events have ever 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, selector, mappedTypes ) { + + var t, tns, type, origType, namespaces, origCount, + j, events, special, eventType, handleObj, + elemData = jQuery.hasData( elem ) && jQuery._data( elem ); + + if ( !elemData || !(events = elemData.events) ) { + return; + } + + // Once for each type.namespace in types; type may be omitted + types = jQuery.trim( hoverHack( types || "" ) ).split(" "); + for ( t = 0; t < types.length; t++ ) { + tns = rtypenamespace.exec( types[t] ) || []; + type = origType = tns[1]; + namespaces = tns[2]; + + // Unbind all events (on this namespace, if provided) for the element + if ( !type ) { + for ( type in events ) { + jQuery.event.remove( elem, type + types[ t ], handler, selector, true ); + } + continue; + } + + special = jQuery.event.special[ type ] || {}; + type = ( selector? special.delegateType : special.bindType ) || type; + eventType = events[ type ] || []; + origCount = eventType.length; + namespaces = namespaces ? new RegExp("(^|\\.)" + namespaces.split(".").sort().join("\\.(?:.*\\.|)") + "(\\.|$)") : null; + + // Remove matching events + for ( j = 0; j < eventType.length; j++ ) { + handleObj = eventType[ j ]; + + if ( ( mappedTypes || origType === handleObj.origType ) && + ( !handler || handler.guid === handleObj.guid ) && + ( !namespaces || namespaces.test( handleObj.namespace ) ) && + ( !selector || selector === handleObj.selector || selector === "**" && handleObj.selector ) ) { + eventType.splice( j--, 1 ); + + if ( handleObj.selector ) { + eventType.delegateCount--; + } + if ( special.remove ) { + special.remove.call( elem, handleObj ); + } + } + } + + // Remove generic event handler if we removed something and no more handlers exist + // (avoids potential for endless recursion during removal of special event handlers) + if ( eventType.length === 0 && origCount !== eventType.length ) { + if ( !special.teardown || special.teardown.call( elem, namespaces, elemData.handle ) === false ) { + jQuery.removeEvent( elem, type, elemData.handle ); + } + + delete events[ type ]; + } + } + + // Remove the expando if it's no longer used + if ( jQuery.isEmptyObject( events ) ) { + delete elemData.handle; + + // removeData also checks for emptiness and clears the expando if empty + // so use it instead of delete + jQuery.removeData( elem, "events", 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 ) { + // Don't do events on text and comment nodes + if ( elem && (elem.nodeType === 3 || elem.nodeType === 8) ) { + return; + } + + // Event object or event type + var cache, exclusive, i, cur, old, ontype, special, handle, eventPath, bubbleType, + type = event.type || event, + namespaces = []; + + // focus/blur morphs to focusin/out; ensure we're not firing them right now + if ( rfocusMorph.test( type + jQuery.event.triggered ) ) { + return; + } + + 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.isTrigger = true; + event.exclusive = exclusive; + event.namespace = namespaces.join( "." ); + event.namespace_re = event.namespace? new RegExp("(^|\\.)" + namespaces.join("\\.(?:.*\\.|)") + "(\\.|$)") : null; + ontype = type.indexOf( ":" ) < 0 ? "on" + type : ""; + + // Handle a global trigger + if ( !elem ) { + + // TODO: Stop taunting the data cache; remove global events and always attach to document + cache = jQuery.cache; + for ( i in cache ) { + if ( cache[ i ].events && cache[ i ].events[ type ] ) { + jQuery.event.trigger( event, data, cache[ i ].handle.elem, true ); + } + } + return; + } + + // Clean up the event in case it is being reused + event.result = undefined; + if ( !event.target ) { + 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 ); + + // Allow special events to draw outside the lines + special = jQuery.event.special[ type ] || {}; + if ( special.trigger && special.trigger.apply( elem, data ) === false ) { + return; + } + + // Determine event propagation path in advance, per W3C events spec (#9951) + // Bubble up to document, then to window; watch for a global ownerDocument var (#9724) + eventPath = [[ elem, special.bindType || type ]]; + if ( !onlyHandlers && !special.noBubble && !jQuery.isWindow( elem ) ) { + + bubbleType = special.delegateType || type; + cur = rfocusMorph.test( bubbleType + type ) ? elem : elem.parentNode; + for ( old = elem; cur; cur = cur.parentNode ) { + eventPath.push([ cur, bubbleType ]); + old = cur; + } + + // Only add window if we got to document (e.g., not plain obj or detached DOM) + if ( old === (elem.ownerDocument || document) ) { + eventPath.push([ old.defaultView || old.parentWindow || window, bubbleType ]); + } + } + + // Fire handlers on the event path + for ( i = 0; i < eventPath.length && !event.isPropagationStopped(); i++ ) { + + cur = eventPath[i][0]; + event.type = eventPath[i][1]; + + handle = ( jQuery._data( cur, "events" ) || {} )[ event.type ] && jQuery._data( cur, "handle" ); + if ( handle ) { + handle.apply( cur, data ); + } + // Note that this is a bare JS function and not a jQuery handler + handle = ontype && cur[ ontype ]; + if ( handle && jQuery.acceptData( cur ) && handle.apply && handle.apply( cur, data ) === false ) { + event.preventDefault(); + } + } + event.type = type; + + // If nobody prevented the default action, do it now + if ( !onlyHandlers && !event.isDefaultPrevented() ) { + + if ( (!special._default || special._default.apply( elem.ownerDocument, data ) === 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. + // Don't do default actions on window, that's where global variables be (#6170) + // IE<9 dies on focus/blur to hidden element (#1486) + if ( ontype && elem[ type ] && ((type !== "focus" && type !== "blur") || event.target.offsetWidth !== 0) && !jQuery.isWindow( elem ) ) { + + // Don't re-trigger an onFOO event when we call its FOO() method + old = elem[ ontype ]; + + if ( old ) { + elem[ ontype ] = null; + } + + // Prevent re-triggering of the same event, since we already bubbled it above + jQuery.event.triggered = type; + elem[ type ](); + jQuery.event.triggered = undefined; + + if ( old ) { + elem[ ontype ] = old; + } + } + } + } + + return event.result; + }, + + dispatch: function( event ) { + + // Make a writable jQuery.Event from the native event object + event = jQuery.event.fix( event || window.event ); + + var i, j, cur, ret, selMatch, matched, matches, handleObj, sel, related, + handlers = ( (jQuery._data( this, "events" ) || {} )[ event.type ] || []), + delegateCount = handlers.delegateCount, + args = core_slice.call( arguments ), + run_all = !event.exclusive && !event.namespace, + special = jQuery.event.special[ event.type ] || {}, + handlerQueue = []; + + // Use the fix-ed jQuery.Event rather than the (read-only) native event + args[0] = event; + event.delegateTarget = this; + + // Call the preDispatch hook for the mapped type, and let it bail if desired + if ( special.preDispatch && special.preDispatch.call( this, event ) === false ) { + return; + } + + // Determine handlers that should run if there are delegated events + // Avoid non-left-click bubbling in Firefox (#3861) + if ( delegateCount && !(event.button && event.type === "click") ) { + + for ( cur = event.target; cur != this; cur = cur.parentNode || this ) { + + // Don't process clicks (ONLY) on disabled elements (#6911, #8165, #11382, #11764) + if ( cur.disabled !== true || event.type !== "click" ) { + selMatch = {}; + matches = []; + for ( i = 0; i < delegateCount; i++ ) { + handleObj = handlers[ i ]; + sel = handleObj.selector; + + if ( selMatch[ sel ] === undefined ) { + selMatch[ sel ] = handleObj.needsContext ? + jQuery( sel, this ).index( cur ) >= 0 : + jQuery.find( sel, this, null, [ cur ] ).length; + } + if ( selMatch[ sel ] ) { + matches.push( handleObj ); + } + } + if ( matches.length ) { + handlerQueue.push({ elem: cur, matches: matches }); + } + } + } + } + + // Add the remaining (directly-bound) handlers + if ( handlers.length > delegateCount ) { + handlerQueue.push({ elem: this, matches: handlers.slice( delegateCount ) }); + } + + // Run delegates first; they may want to stop propagation beneath us + for ( i = 0; i < handlerQueue.length && !event.isPropagationStopped(); i++ ) { + matched = handlerQueue[ i ]; + event.currentTarget = matched.elem; + + for ( j = 0; j < matched.matches.length && !event.isImmediatePropagationStopped(); j++ ) { + handleObj = matched.matches[ j ]; + + // Triggered event must either 1) be non-exclusive and have no namespace, or + // 2) have namespace(s) a subset or equal to those in the bound event (both can have no namespace). + if ( run_all || (!event.namespace && !handleObj.namespace) || event.namespace_re && event.namespace_re.test( handleObj.namespace ) ) { + + event.data = handleObj.data; + event.handleObj = handleObj; + + ret = ( (jQuery.event.special[ handleObj.origType ] || {}).handle || handleObj.handler ) + .apply( matched.elem, args ); + + if ( ret !== undefined ) { + event.result = ret; + if ( ret === false ) { + event.preventDefault(); + event.stopPropagation(); + } + } + } + } + } + + // Call the postDispatch hook for the mapped type + if ( special.postDispatch ) { + special.postDispatch.call( this, event ); + } + + return event.result; + }, + + // Includes some event props shared by KeyEvent and MouseEvent + // *** attrChange attrName relatedNode srcElement are not normalized, non-W3C, deprecated, will be removed in 1.8 *** + props: "attrChange attrName relatedNode srcElement altKey bubbles cancelable ctrlKey currentTarget eventPhase metaKey relatedTarget shiftKey target timeStamp view which".split(" "), + + fixHooks: {}, + + keyHooks: { + props: "char charCode key keyCode".split(" "), + filter: function( event, original ) { + + // Add which for key events + if ( event.which == null ) { + event.which = original.charCode != null ? original.charCode : original.keyCode; + } + + return event; + } + }, + + mouseHooks: { + props: "button buttons clientX clientY fromElement offsetX offsetY pageX pageY screenX screenY toElement".split(" "), + filter: function( event, original ) { + var eventDoc, doc, body, + button = original.button, + fromElement = original.fromElement; + + // Calculate pageX/Y if missing and clientX/Y available + if ( event.pageX == null && original.clientX != null ) { + eventDoc = event.target.ownerDocument || document; + doc = eventDoc.documentElement; + body = eventDoc.body; + + event.pageX = original.clientX + ( doc && doc.scrollLeft || body && body.scrollLeft || 0 ) - ( doc && doc.clientLeft || body && body.clientLeft || 0 ); + event.pageY = original.clientY + ( doc && doc.scrollTop || body && body.scrollTop || 0 ) - ( doc && doc.clientTop || body && body.clientTop || 0 ); + } + + // Add relatedTarget, if necessary + if ( !event.relatedTarget && fromElement ) { + event.relatedTarget = fromElement === event.target ? original.toElement : fromElement; + } + + // Add which for click: 1 === left; 2 === middle; 3 === right + // Note: button is not normalized, so don't use it + if ( !event.which && button !== undefined ) { + event.which = ( button & 1 ? 1 : ( button & 2 ? 3 : ( button & 4 ? 2 : 0 ) ) ); + } + + return event; + } + }, + + fix: function( event ) { + if ( event[ jQuery.expando ] ) { + return event; + } + + // Create a writable copy of the event object and normalize some properties + var i, prop, + originalEvent = event, + fixHook = jQuery.event.fixHooks[ event.type ] || {}, + copy = fixHook.props ? this.props.concat( fixHook.props ) : this.props; + + event = jQuery.Event( originalEvent ); + + for ( i = copy.length; i; ) { + prop = copy[ --i ]; + event[ prop ] = originalEvent[ prop ]; + } + + // Fix target property, if necessary (#1925, IE 6/7/8 & Safari2) + if ( !event.target ) { + event.target = originalEvent.srcElement || document; + } + + // Target should not be a text node (#504, Safari) + if ( event.target.nodeType === 3 ) { + event.target = event.target.parentNode; + } + + // For mouse/key events, metaKey==false if it's undefined (#3368, #11328; IE6/7/8) + event.metaKey = !!event.metaKey; + + return fixHook.filter? fixHook.filter( event, originalEvent ) : event; + }, + + special: { + load: { + // Prevent triggered image.load events from bubbling to window.load + noBubble: true + }, + + focus: { + delegateType: "focusin" + }, + blur: { + delegateType: "focusout" + }, + + 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; + } + } + } + }, + + simulate: function( type, elem, event, bubble ) { + // 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. + var e = jQuery.extend( + new jQuery.Event(), + event, + { type: type, + isSimulated: true, + originalEvent: {} + } + ); + if ( bubble ) { + jQuery.event.trigger( e, null, elem ); + } else { + jQuery.event.dispatch.call( elem, e ); + } + if ( e.isDefaultPrevented() ) { + event.preventDefault(); + } + } +}; + +// Some plugins are using, but it's undocumented/deprecated and will be removed. +// The 1.7 special event interface should provide all the hooks needed now. +jQuery.event.handle = jQuery.event.dispatch; + +jQuery.removeEvent = document.removeEventListener ? + function( elem, type, handle ) { + if ( elem.removeEventListener ) { + elem.removeEventListener( type, handle, false ); + } + } : + function( elem, type, handle ) { + var name = "on" + type; + + if ( elem.detachEvent ) { + + // #8545, #7054, preventing memory leaks for custom events in IE6-8 – + // detachEvent needed property on element, by name of that event, to properly expose it to GC + if ( typeof elem[ name ] === "undefined" ) { + elem[ name ] = null; + } + + elem.detachEvent( name, handle ); + } + }; + +jQuery.Event = function( src, props ) { + // Allow instantiation without the 'new' keyword + if ( !(this instanceof jQuery.Event) ) { + 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 ); + } + + // Create a timestamp if incoming event doesn't have one + this.timeStamp = src && src.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 +}; + +// Create mouseenter/leave events using mouseover/out and event-time checks +jQuery.each({ + mouseenter: "mouseover", + mouseleave: "mouseout" +}, function( orig, fix ) { + jQuery.event.special[ orig ] = { + delegateType: fix, + bindType: fix, + + handle: function( event ) { + var ret, + target = this, + related = event.relatedTarget, + handleObj = event.handleObj, + selector = handleObj.selector; + + // For mousenter/leave call the handler if related is outside the target. + // NB: No relatedTarget if the mouse left/entered the browser window + if ( !related || (related !== target && !jQuery.contains( target, related )) ) { + event.type = handleObj.origType; + ret = handleObj.handler.apply( this, arguments ); + event.type = fix; + } + return ret; + } + }; +}); + +// IE submit delegation +if ( !jQuery.support.submitBubbles ) { + + jQuery.event.special.submit = { + setup: function() { + // Only need this for delegated form submit events + if ( jQuery.nodeName( this, "form" ) ) { + return false; + } + + // Lazy-add a submit handler when a descendant form may potentially be submitted + jQuery.event.add( this, "click._submit keypress._submit", function( e ) { + // Node name check avoids a VML-related crash in IE (#9807) + var elem = e.target, + form = jQuery.nodeName( elem, "input" ) || jQuery.nodeName( elem, "button" ) ? elem.form : undefined; + if ( form && !jQuery._data( form, "_submit_attached" ) ) { + jQuery.event.add( form, "submit._submit", function( event ) { + event._submit_bubble = true; + }); + jQuery._data( form, "_submit_attached", true ); + } + }); + // return undefined since we don't need an event listener + }, + + postDispatch: function( event ) { + // If form was submitted by the user, bubble the event up the tree + if ( event._submit_bubble ) { + delete event._submit_bubble; + if ( this.parentNode && !event.isTrigger ) { + jQuery.event.simulate( "submit", this.parentNode, event, true ); + } + } + }, + + teardown: function() { + // Only need this for delegated form submit events + if ( jQuery.nodeName( this, "form" ) ) { + return false; + } + + // Remove delegated handlers; cleanData eventually reaps submit handlers attached above + jQuery.event.remove( this, "._submit" ); + } + }; +} + +// IE change delegation and checkbox/radio fix +if ( !jQuery.support.changeBubbles ) { + + jQuery.event.special.change = { + + setup: function() { + + if ( rformElems.test( this.nodeName ) ) { + // IE doesn't fire change on a check/radio until blur; trigger it on click + // after a propertychange. Eat the blur-change in special.change.handle. + // This still fires onchange a second time for check/radio after blur. + if ( this.type === "checkbox" || this.type === "radio" ) { + jQuery.event.add( this, "propertychange._change", function( event ) { + if ( event.originalEvent.propertyName === "checked" ) { + this._just_changed = true; + } + }); + jQuery.event.add( this, "click._change", function( event ) { + if ( this._just_changed && !event.isTrigger ) { + this._just_changed = false; + } + // Allow triggered, simulated change events (#11500) + jQuery.event.simulate( "change", this, event, true ); + }); + } + return false; + } + // Delegated event; lazy-add a change handler on descendant inputs + jQuery.event.add( this, "beforeactivate._change", function( e ) { + var elem = e.target; + + if ( rformElems.test( elem.nodeName ) && !jQuery._data( elem, "_change_attached" ) ) { + jQuery.event.add( elem, "change._change", function( event ) { + if ( this.parentNode && !event.isSimulated && !event.isTrigger ) { + jQuery.event.simulate( "change", this.parentNode, event, true ); + } + }); + jQuery._data( elem, "_change_attached", true ); + } + }); + }, + + handle: function( event ) { + var elem = event.target; + + // Swallow native change events from checkbox/radio, we already triggered them above + if ( this !== elem || event.isSimulated || event.isTrigger || (elem.type !== "radio" && elem.type !== "checkbox") ) { + return event.handleObj.handler.apply( this, arguments ); + } + }, + + teardown: function() { + jQuery.event.remove( this, "._change" ); + + return !rformElems.test( this.nodeName ); + } + }; +} + +// 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, + handler = function( event ) { + jQuery.event.simulate( fix, event.target, jQuery.event.fix( event ), true ); + }; + + jQuery.event.special[ fix ] = { + setup: function() { + if ( attaches++ === 0 ) { + document.addEventListener( orig, handler, true ); + } + }, + teardown: function() { + if ( --attaches === 0 ) { + document.removeEventListener( orig, handler, true ); + } + } + }; + }); +} + +jQuery.fn.extend({ + + on: function( types, selector, data, fn, /*INTERNAL*/ one ) { + var origFn, type; + + // Types can be a map of types/handlers + if ( typeof types === "object" ) { + // ( types-Object, selector, data ) + if ( typeof selector !== "string" ) { // && selector != null + // ( types-Object, data ) + data = data || selector; + selector = undefined; + } + for ( type in types ) { + this.on( type, selector, data, types[ type ], one ); + } + return this; + } + + if ( data == null && fn == null ) { + // ( types, fn ) + fn = selector; + data = selector = undefined; + } else if ( fn == null ) { + if ( typeof selector === "string" ) { + // ( types, selector, fn ) + fn = data; + data = undefined; + } else { + // ( types, data, fn ) + fn = data; + data = selector; + selector = undefined; + } + } + if ( fn === false ) { + fn = returnFalse; + } else if ( !fn ) { + return this; + } + + if ( one === 1 ) { + origFn = fn; + fn = function( event ) { + // Can use an empty set, since event contains the info + jQuery().off( event ); + return origFn.apply( this, arguments ); + }; + // Use same guid so caller can remove using origFn + fn.guid = origFn.guid || ( origFn.guid = jQuery.guid++ ); + } + return this.each( function() { + jQuery.event.add( this, types, fn, data, selector ); + }); + }, + one: function( types, selector, data, fn ) { + return this.on( types, selector, data, fn, 1 ); + }, + off: function( types, selector, fn ) { + var handleObj, type; + if ( types && types.preventDefault && types.handleObj ) { + // ( event ) dispatched jQuery.Event + handleObj = types.handleObj; + jQuery( types.delegateTarget ).off( + handleObj.namespace ? handleObj.origType + "." + handleObj.namespace : handleObj.origType, + handleObj.selector, + handleObj.handler + ); + return this; + } + if ( typeof types === "object" ) { + // ( types-object [, selector] ) + for ( type in types ) { + this.off( type, selector, types[ type ] ); + } + return this; + } + if ( selector === false || typeof selector === "function" ) { + // ( types [, fn] ) + fn = selector; + selector = undefined; + } + if ( fn === false ) { + fn = returnFalse; + } + return this.each(function() { + jQuery.event.remove( this, types, fn, selector ); + }); + }, + + bind: function( types, data, fn ) { + return this.on( types, null, data, fn ); + }, + unbind: function( types, fn ) { + return this.off( types, null, fn ); + }, + + live: function( types, data, fn ) { + jQuery( this.context ).on( types, this.selector, data, fn ); + return this; + }, + die: function( types, fn ) { + jQuery( this.context ).off( types, this.selector || "**", fn ); + return this; + }, + + delegate: function( selector, types, data, fn ) { + return this.on( types, selector, data, fn ); + }, + undelegate: function( selector, types, fn ) { + // ( namespace ) or ( selector, types [, fn] ) + return arguments.length === 1 ? this.off( selector, "**" ) : this.off( types, selector || "**", fn ); + }, + + 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 ); + } +}); + +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 contextmenu").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.on( name, null, data, fn ) : + this.trigger( name ); + }; + + if ( rkeyEvent.test( name ) ) { + jQuery.event.fixHooks[ name ] = jQuery.event.keyHooks; + } + + if ( rmouseEvent.test( name ) ) { + jQuery.event.fixHooks[ name ] = jQuery.event.mouseHooks; + } +}); +/*! + * Sizzle CSS Selector Engine + * Copyright 2012 jQuery Foundation and other contributors + * Released under the MIT license + * http://sizzlejs.com/ + */ +(function( window, undefined ) { + +var cachedruns, + assertGetIdNotName, + Expr, + getText, + isXML, + contains, + compile, + sortOrder, + hasDuplicate, + outermostContext, + + baseHasDuplicate = true, + strundefined = "undefined", + + expando = ( "sizcache" + Math.random() ).replace( ".", "" ), + + Token = String, + document = window.document, + docElem = document.documentElement, + dirruns = 0, + done = 0, + pop = [].pop, + push = [].push, + slice = [].slice, + // Use a stripped-down indexOf if a native one is unavailable + indexOf = [].indexOf || function( elem ) { + var i = 0, + len = this.length; + for ( ; i < len; i++ ) { + if ( this[i] === elem ) { + return i; + } + } + return -1; + }, + + // Augment a function for special use by Sizzle + markFunction = function( fn, value ) { + fn[ expando ] = value == null || value; + return fn; + }, + + createCache = function() { + var cache = {}, + keys = []; + + return markFunction(function( key, value ) { + // Only keep the most recent entries + if ( keys.push( key ) > Expr.cacheLength ) { + delete cache[ keys.shift() ]; + } + + return (cache[ key ] = value); + }, cache ); + }, + + classCache = createCache(), + tokenCache = createCache(), + compilerCache = createCache(), + + // Regex + + // Whitespace characters http://www.w3.org/TR/css3-selectors/#whitespace + whitespace = "[\\x20\\t\\r\\n\\f]", + // http://www.w3.org/TR/css3-syntax/#characters + characterEncoding = "(?:\\\\.|[-\\w]|[^\\x00-\\xa0])+", + + // Loosely modeled on CSS identifier characters + // An unquoted value should be a CSS identifier (http://www.w3.org/TR/css3-selectors/#attribute-selectors) + // Proper syntax: http://www.w3.org/TR/CSS21/syndata.html#value-def-identifier + identifier = characterEncoding.replace( "w", "w#" ), + + // Acceptable operators http://www.w3.org/TR/selectors/#attribute-selectors + operators = "([*^$|!~]?=)", + attributes = "\\[" + whitespace + "*(" + characterEncoding + ")" + whitespace + + "*(?:" + operators + whitespace + "*(?:(['\"])((?:\\\\.|[^\\\\])*?)\\3|(" + identifier + ")|)|)" + whitespace + "*\\]", + + // Prefer arguments not in parens/brackets, + // then attribute selectors and non-pseudos (denoted by :), + // then anything else + // These preferences are here to reduce the number of selectors + // needing tokenize in the PSEUDO preFilter + pseudos = ":(" + characterEncoding + ")(?:\\((?:(['\"])((?:\\\\.|[^\\\\])*?)\\2|([^()[\\]]*|(?:(?:" + attributes + ")|[^:]|\\\\.)*|.*))\\)|)", + + // For matchExpr.POS and matchExpr.needsContext + pos = ":(even|odd|eq|gt|lt|nth|first|last)(?:\\(" + whitespace + + "*((?:-\\d)?\\d*)" + whitespace + "*\\)|)(?=[^-]|$)", + + // Leading and non-escaped trailing whitespace, capturing some non-whitespace characters preceding the latter + rtrim = new RegExp( "^" + whitespace + "+|((?:^|[^\\\\])(?:\\\\.)*)" + whitespace + "+$", "g" ), + + rcomma = new RegExp( "^" + whitespace + "*," + whitespace + "*" ), + rcombinators = new RegExp( "^" + whitespace + "*([\\x20\\t\\r\\n\\f>+~])" + whitespace + "*" ), + rpseudo = new RegExp( pseudos ), + + // Easily-parseable/retrievable ID or TAG or CLASS selectors + rquickExpr = /^(?:#([\w\-]+)|(\w+)|\.([\w\-]+))$/, + + rnot = /^:not/, + rsibling = /[\x20\t\r\n\f]*[+~]/, + rendsWithNot = /:not\($/, + + rheader = /h\d/i, + rinputs = /input|select|textarea|button/i, + + rbackslash = /\\(?!\\)/g, + + matchExpr = { + "ID": new RegExp( "^#(" + characterEncoding + ")" ), + "CLASS": new RegExp( "^\\.(" + characterEncoding + ")" ), + "NAME": new RegExp( "^\\[name=['\"]?(" + characterEncoding + ")['\"]?\\]" ), + "TAG": new RegExp( "^(" + characterEncoding.replace( "w", "w*" ) + ")" ), + "ATTR": new RegExp( "^" + attributes ), + "PSEUDO": new RegExp( "^" + pseudos ), + "POS": new RegExp( pos, "i" ), + "CHILD": new RegExp( "^:(only|nth|first|last)-child(?:\\(" + whitespace + + "*(even|odd|(([+-]|)(\\d*)n|)" + whitespace + "*(?:([+-]|)" + whitespace + + "*(\\d+)|))" + whitespace + "*\\)|)", "i" ), + // For use in libraries implementing .is() + "needsContext": new RegExp( "^" + whitespace + "*[>+~]|" + pos, "i" ) + }, + + // Support + + // Used for testing something on an element + assert = function( fn ) { + var div = document.createElement("div"); + + try { + return fn( div ); + } catch (e) { + return false; + } finally { + // release memory in IE + div = null; + } + }, + + // Check if getElementsByTagName("*") returns only elements + assertTagNameNoComments = assert(function( div ) { + div.appendChild( document.createComment("") ); + return !div.getElementsByTagName("*").length; + }), + + // Check if getAttribute returns normalized href attributes + assertHrefNotNormalized = assert(function( div ) { + div.innerHTML = ""; + return div.firstChild && typeof div.firstChild.getAttribute !== strundefined && + div.firstChild.getAttribute("href") === "#"; + }), + + // Check if attributes should be retrieved by attribute nodes + assertAttributes = assert(function( div ) { + div.innerHTML = ""; + var type = typeof div.lastChild.getAttribute("multiple"); + // IE8 returns a string for some attributes even when not present + return type !== "boolean" && type !== "string"; + }), + + // Check if getElementsByClassName can be trusted + assertUsableClassName = assert(function( div ) { + // Opera can't find a second classname (in 9.6) + div.innerHTML = ""; + if ( !div.getElementsByClassName || !div.getElementsByClassName("e").length ) { + return false; + } + + // Safari 3.2 caches class attributes and doesn't catch changes + div.lastChild.className = "e"; + return div.getElementsByClassName("e").length === 2; + }), + + // Check if getElementById returns elements by name + // Check if getElementsByName privileges form controls or returns elements by ID + assertUsableName = assert(function( div ) { + // Inject content + div.id = expando + 0; + div.innerHTML = "
      "; + docElem.insertBefore( div, docElem.firstChild ); + + // Test + var pass = document.getElementsByName && + // buggy browsers will return fewer than the correct 2 + document.getElementsByName( expando ).length === 2 + + // buggy browsers will return more than the correct 0 + document.getElementsByName( expando + 0 ).length; + assertGetIdNotName = !document.getElementById( expando ); + + // Cleanup + docElem.removeChild( div ); + + return pass; + }); + +// If slice is not available, provide a backup +try { + slice.call( docElem.childNodes, 0 )[0].nodeType; +} catch ( e ) { + slice = function( i ) { + var elem, + results = []; + for ( ; (elem = this[i]); i++ ) { + results.push( elem ); + } + return results; + }; +} + +function Sizzle( selector, context, results, seed ) { + results = results || []; + context = context || document; + var match, elem, xml, m, + nodeType = context.nodeType; + + if ( !selector || typeof selector !== "string" ) { + return results; + } + + if ( nodeType !== 1 && nodeType !== 9 ) { + return []; + } + + xml = isXML( context ); + + if ( !xml && !seed ) { + if ( (match = rquickExpr.exec( selector )) ) { + // Speed-up: Sizzle("#ID") + if ( (m = match[1]) ) { + if ( nodeType === 9 ) { + elem = context.getElementById( m ); + // 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, Opera, and Webkit return items + // by name instead of ID + if ( elem.id === m ) { + results.push( elem ); + return results; + } + } else { + return results; + } + } else { + // Context is not a document + if ( context.ownerDocument && (elem = context.ownerDocument.getElementById( m )) && + contains( context, elem ) && elem.id === m ) { + results.push( elem ); + return results; + } + } + + // Speed-up: Sizzle("TAG") + } else if ( match[2] ) { + push.apply( results, slice.call(context.getElementsByTagName( selector ), 0) ); + return results; + + // Speed-up: Sizzle(".CLASS") + } else if ( (m = match[3]) && assertUsableClassName && context.getElementsByClassName ) { + push.apply( results, slice.call(context.getElementsByClassName( m ), 0) ); + return results; + } + } + } + + // All others + return select( selector.replace( rtrim, "$1" ), context, results, seed, xml ); +} + +Sizzle.matches = function( expr, elements ) { + return Sizzle( expr, null, null, elements ); +}; + +Sizzle.matchesSelector = function( elem, expr ) { + return Sizzle( expr, null, null, [ elem ] ).length > 0; +}; + +// Returns a function to use in pseudos for input types +function createInputPseudo( type ) { + return function( elem ) { + var name = elem.nodeName.toLowerCase(); + return name === "input" && elem.type === type; + }; +} + +// Returns a function to use in pseudos for buttons +function createButtonPseudo( type ) { + return function( elem ) { + var name = elem.nodeName.toLowerCase(); + return (name === "input" || name === "button") && elem.type === type; + }; +} + +// Returns a function to use in pseudos for positionals +function createPositionalPseudo( fn ) { + return markFunction(function( argument ) { + argument = +argument; + return markFunction(function( seed, matches ) { + var j, + matchIndexes = fn( [], seed.length, argument ), + i = matchIndexes.length; + + // Match elements found at the specified indexes + while ( i-- ) { + if ( seed[ (j = matchIndexes[i]) ] ) { + seed[j] = !(matches[j] = seed[j]); + } + } + }); + }); +} + +/** + * Utility function for retrieving the text value of an array of DOM nodes + * @param {Array|Element} elem + */ +getText = Sizzle.getText = function( elem ) { + var node, + ret = "", + i = 0, + nodeType = elem.nodeType; + + if ( nodeType ) { + if ( nodeType === 1 || nodeType === 9 || nodeType === 11 ) { + // Use textContent for elements + // innerText usage removed for consistency of new lines (see #11153) + if ( typeof elem.textContent === "string" ) { + return elem.textContent; + } else { + // Traverse its children + for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) { + ret += getText( elem ); + } + } + } else if ( nodeType === 3 || nodeType === 4 ) { + return elem.nodeValue; + } + // Do not include comment or processing instruction nodes + } else { + + // If no nodeType, this is expected to be an array + for ( ; (node = elem[i]); i++ ) { + // Do not traverse comment nodes + ret += getText( node ); + } + } + return ret; +}; + +isXML = 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).documentElement; + return documentElement ? documentElement.nodeName !== "HTML" : false; +}; + +// Element contains another +contains = Sizzle.contains = docElem.contains ? + function( a, b ) { + var adown = a.nodeType === 9 ? a.documentElement : a, + bup = b && b.parentNode; + return a === bup || !!( bup && bup.nodeType === 1 && adown.contains && adown.contains(bup) ); + } : + docElem.compareDocumentPosition ? + function( a, b ) { + return b && !!( a.compareDocumentPosition( b ) & 16 ); + } : + function( a, b ) { + while ( (b = b.parentNode) ) { + if ( b === a ) { + return true; + } + } + return false; + }; + +Sizzle.attr = function( elem, name ) { + var val, + xml = isXML( elem ); + + if ( !xml ) { + name = name.toLowerCase(); + } + if ( (val = Expr.attrHandle[ name ]) ) { + return val( elem ); + } + if ( xml || assertAttributes ) { + return elem.getAttribute( name ); + } + val = elem.getAttributeNode( name ); + return val ? + typeof elem[ name ] === "boolean" ? + elem[ name ] ? name : null : + val.specified ? val.value : null : + null; +}; + +Expr = Sizzle.selectors = { + + // Can be adjusted by the user + cacheLength: 50, + + createPseudo: markFunction, + + match: matchExpr, + + // IE6/7 return a modified href + attrHandle: assertHrefNotNormalized ? + {} : + { + "href": function( elem ) { + return elem.getAttribute( "href", 2 ); + }, + "type": function( elem ) { + return elem.getAttribute("type"); + } + }, + + find: { + "ID": assertGetIdNotName ? + function( id, context, xml ) { + if ( typeof context.getElementById !== strundefined && !xml ) { + var m = context.getElementById( id ); + // Check parentNode to catch when Blackberry 4.6 returns + // nodes that are no longer in the document #6963 + return m && m.parentNode ? [m] : []; + } + } : + function( id, context, xml ) { + if ( typeof context.getElementById !== strundefined && !xml ) { + var m = context.getElementById( id ); + + return m ? + m.id === id || typeof m.getAttributeNode !== strundefined && m.getAttributeNode("id").value === id ? + [m] : + undefined : + []; + } + }, + + "TAG": assertTagNameNoComments ? + function( tag, context ) { + if ( typeof context.getElementsByTagName !== strundefined ) { + return context.getElementsByTagName( tag ); + } + } : + function( tag, context ) { + var results = context.getElementsByTagName( tag ); + + // Filter out possible comments + if ( tag === "*" ) { + var elem, + tmp = [], + i = 0; + + for ( ; (elem = results[i]); i++ ) { + if ( elem.nodeType === 1 ) { + tmp.push( elem ); + } + } + + return tmp; + } + return results; + }, + + "NAME": assertUsableName && function( tag, context ) { + if ( typeof context.getElementsByName !== strundefined ) { + return context.getElementsByName( name ); + } + }, + + "CLASS": assertUsableClassName && function( className, context, xml ) { + if ( typeof context.getElementsByClassName !== strundefined && !xml ) { + return context.getElementsByClassName( className ); + } + } + }, + + relative: { + ">": { dir: "parentNode", first: true }, + " ": { dir: "parentNode" }, + "+": { dir: "previousSibling", first: true }, + "~": { dir: "previousSibling" } + }, + + preFilter: { + "ATTR": function( match ) { + match[1] = match[1].replace( rbackslash, "" ); + + // Move the given value to match[3] whether quoted or unquoted + match[3] = ( match[4] || match[5] || "" ).replace( rbackslash, "" ); + + if ( match[2] === "~=" ) { + match[3] = " " + match[3] + " "; + } + + return match.slice( 0, 4 ); + }, + + "CHILD": function( match ) { + /* matches from matchExpr["CHILD"] + 1 type (only|nth|...) + 2 argument (even|odd|\d*|\d*n([+-]\d+)?|...) + 3 xn-component of xn+y argument ([+-]?\d*n|) + 4 sign of xn-component + 5 x of xn-component + 6 sign of y-component + 7 y of y-component + */ + match[1] = match[1].toLowerCase(); + + if ( match[1] === "nth" ) { + // nth-child requires argument + if ( !match[2] ) { + Sizzle.error( match[0] ); + } + + // numeric x and y parameters for Expr.filter.CHILD + // remember that false/true cast respectively to 0/1 + match[3] = +( match[3] ? match[4] + (match[5] || 1) : 2 * ( match[2] === "even" || match[2] === "odd" ) ); + match[4] = +( ( match[6] + match[7] ) || match[2] === "odd" ); + + // other types prohibit arguments + } else if ( match[2] ) { + Sizzle.error( match[0] ); + } + + return match; + }, + + "PSEUDO": function( match ) { + var unquoted, excess; + if ( matchExpr["CHILD"].test( match[0] ) ) { + return null; + } + + if ( match[3] ) { + match[2] = match[3]; + } else if ( (unquoted = match[4]) ) { + // Only check arguments that contain a pseudo + if ( rpseudo.test(unquoted) && + // Get excess from tokenize (recursively) + (excess = tokenize( unquoted, true )) && + // advance to the next closing parenthesis + (excess = unquoted.indexOf( ")", unquoted.length - excess ) - unquoted.length) ) { + + // excess is a negative index + unquoted = unquoted.slice( 0, excess ); + match[0] = match[0].slice( 0, excess ); + } + match[2] = unquoted; + } + + // Return only captures needed by the pseudo filter method (type and argument) + return match.slice( 0, 3 ); + } + }, + + filter: { + "ID": assertGetIdNotName ? + function( id ) { + id = id.replace( rbackslash, "" ); + return function( elem ) { + return elem.getAttribute("id") === id; + }; + } : + function( id ) { + id = id.replace( rbackslash, "" ); + return function( elem ) { + var node = typeof elem.getAttributeNode !== strundefined && elem.getAttributeNode("id"); + return node && node.value === id; + }; + }, + + "TAG": function( nodeName ) { + if ( nodeName === "*" ) { + return function() { return true; }; + } + nodeName = nodeName.replace( rbackslash, "" ).toLowerCase(); + + return function( elem ) { + return elem.nodeName && elem.nodeName.toLowerCase() === nodeName; + }; + }, + + "CLASS": function( className ) { + var pattern = classCache[ expando ][ className ]; + if ( !pattern ) { + pattern = classCache( className, new RegExp("(^|" + whitespace + ")" + className + "(" + whitespace + "|$)") ); + } + return function( elem ) { + return pattern.test( elem.className || (typeof elem.getAttribute !== strundefined && elem.getAttribute("class")) || "" ); + }; + }, + + "ATTR": function( name, operator, check ) { + return function( elem, context ) { + var result = Sizzle.attr( elem, name ); + + if ( result == null ) { + return operator === "!="; + } + if ( !operator ) { + return true; + } + + result += ""; + + return operator === "=" ? result === check : + operator === "!=" ? result !== check : + operator === "^=" ? check && result.indexOf( check ) === 0 : + operator === "*=" ? check && result.indexOf( check ) > -1 : + operator === "$=" ? check && result.substr( result.length - check.length ) === check : + operator === "~=" ? ( " " + result + " " ).indexOf( check ) > -1 : + operator === "|=" ? result === check || result.substr( 0, check.length + 1 ) === check + "-" : + false; + }; + }, + + "CHILD": function( type, argument, first, last ) { + + if ( type === "nth" ) { + return function( elem ) { + var node, diff, + parent = elem.parentNode; + + if ( first === 1 && last === 0 ) { + return true; + } + + if ( parent ) { + diff = 0; + for ( node = parent.firstChild; node; node = node.nextSibling ) { + if ( node.nodeType === 1 ) { + diff++; + if ( elem === node ) { + break; + } + } + } + } + + // Incorporate the offset (or cast to NaN), then check against cycle size + diff -= last; + return diff === first || ( diff % first === 0 && diff / first >= 0 ); + }; + } + + return function( elem ) { + var 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; + + /* falls through */ + case "last": + while ( (node = node.nextSibling) ) { + if ( node.nodeType === 1 ) { + return false; + } + } + + return true; + } + }; + }, + + "PSEUDO": function( pseudo, argument ) { + // pseudo-class names are case-insensitive + // http://www.w3.org/TR/selectors/#pseudo-classes + // Prioritize by case sensitivity in case custom pseudos are added with uppercase letters + // Remember that setFilters inherits from pseudos + var args, + fn = Expr.pseudos[ pseudo ] || Expr.setFilters[ pseudo.toLowerCase() ] || + Sizzle.error( "unsupported pseudo: " + pseudo ); + + // The user may use createPseudo to indicate that + // arguments are needed to create the filter function + // just as Sizzle does + if ( fn[ expando ] ) { + return fn( argument ); + } + + // But maintain support for old signatures + if ( fn.length > 1 ) { + args = [ pseudo, pseudo, "", argument ]; + return Expr.setFilters.hasOwnProperty( pseudo.toLowerCase() ) ? + markFunction(function( seed, matches ) { + var idx, + matched = fn( seed, argument ), + i = matched.length; + while ( i-- ) { + idx = indexOf.call( seed, matched[i] ); + seed[ idx ] = !( matches[ idx ] = matched[i] ); + } + }) : + function( elem ) { + return fn( elem, 0, args ); + }; + } + + return fn; + } + }, + + pseudos: { + "not": markFunction(function( selector ) { + // Trim the selector passed to compile + // to avoid treating leading and trailing + // spaces as combinators + var input = [], + results = [], + matcher = compile( selector.replace( rtrim, "$1" ) ); + + return matcher[ expando ] ? + markFunction(function( seed, matches, context, xml ) { + var elem, + unmatched = matcher( seed, null, xml, [] ), + i = seed.length; + + // Match elements unmatched by `matcher` + while ( i-- ) { + if ( (elem = unmatched[i]) ) { + seed[i] = !(matches[i] = elem); + } + } + }) : + function( elem, context, xml ) { + input[0] = elem; + matcher( input, null, xml, results ); + return !results.pop(); + }; + }), + + "has": markFunction(function( selector ) { + return function( elem ) { + return Sizzle( selector, elem ).length > 0; + }; + }), + + "contains": markFunction(function( text ) { + return function( elem ) { + return ( elem.textContent || elem.innerText || getText( elem ) ).indexOf( text ) > -1; + }; + }), + + "enabled": function( elem ) { + return elem.disabled === false; + }, + + "disabled": function( elem ) { + return elem.disabled === true; + }, + + "checked": function( elem ) { + // In CSS3, :checked should return both checked and selected elements + // http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked + var nodeName = elem.nodeName.toLowerCase(); + return (nodeName === "input" && !!elem.checked) || (nodeName === "option" && !!elem.selected); + }, + + "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 !Expr.pseudos["empty"]( elem ); + }, + + "empty": function( elem ) { + // http://www.w3.org/TR/selectors/#empty-pseudo + // :empty is only affected by element nodes and content nodes(including text(3), cdata(4)), + // not comment, processing instructions, or others + // Thanks to Diego Perini for the nodeName shortcut + // Greater than "@" means alpha characters (specifically not starting with "#" or "?") + var nodeType; + elem = elem.firstChild; + while ( elem ) { + if ( elem.nodeName > "@" || (nodeType = elem.nodeType) === 3 || nodeType === 4 ) { + return false; + } + elem = elem.nextSibling; + } + return true; + }, + + "header": function( elem ) { + return rheader.test( elem.nodeName ); + }, + + "text": function( elem ) { + var type, attr; + // 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" && + (type = elem.type) === "text" && + ( (attr = elem.getAttribute("type")) == null || attr.toLowerCase() === type ); + }, + + // Input types + "radio": createInputPseudo("radio"), + "checkbox": createInputPseudo("checkbox"), + "file": createInputPseudo("file"), + "password": createInputPseudo("password"), + "image": createInputPseudo("image"), + + "submit": createButtonPseudo("submit"), + "reset": createButtonPseudo("reset"), + + "button": function( elem ) { + var name = elem.nodeName.toLowerCase(); + return name === "input" && elem.type === "button" || name === "button"; + }, + + "input": function( elem ) { + return rinputs.test( elem.nodeName ); + }, + + "focus": function( elem ) { + var doc = elem.ownerDocument; + return elem === doc.activeElement && (!doc.hasFocus || doc.hasFocus()) && !!(elem.type || elem.href); + }, + + "active": function( elem ) { + return elem === elem.ownerDocument.activeElement; + }, + + // Positional types + "first": createPositionalPseudo(function( matchIndexes, length, argument ) { + return [ 0 ]; + }), + + "last": createPositionalPseudo(function( matchIndexes, length, argument ) { + return [ length - 1 ]; + }), + + "eq": createPositionalPseudo(function( matchIndexes, length, argument ) { + return [ argument < 0 ? argument + length : argument ]; + }), + + "even": createPositionalPseudo(function( matchIndexes, length, argument ) { + for ( var i = 0; i < length; i += 2 ) { + matchIndexes.push( i ); + } + return matchIndexes; + }), + + "odd": createPositionalPseudo(function( matchIndexes, length, argument ) { + for ( var i = 1; i < length; i += 2 ) { + matchIndexes.push( i ); + } + return matchIndexes; + }), + + "lt": createPositionalPseudo(function( matchIndexes, length, argument ) { + for ( var i = argument < 0 ? argument + length : argument; --i >= 0; ) { + matchIndexes.push( i ); + } + return matchIndexes; + }), + + "gt": createPositionalPseudo(function( matchIndexes, length, argument ) { + for ( var i = argument < 0 ? argument + length : argument; ++i < length; ) { + matchIndexes.push( i ); + } + return matchIndexes; + }) + } +}; + +function siblingCheck( a, b, ret ) { + if ( a === b ) { + return ret; + } + + var cur = a.nextSibling; + + while ( cur ) { + if ( cur === b ) { + return -1; + } + + cur = cur.nextSibling; + } + + return 1; +} + +sortOrder = docElem.compareDocumentPosition ? + function( a, b ) { + if ( a === b ) { + hasDuplicate = true; + return 0; + } + + return ( !a.compareDocumentPosition || !b.compareDocumentPosition ? + a.compareDocumentPosition : + a.compareDocumentPosition(b) & 4 + ) ? -1 : 1; + } : + 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 ); + }; + +// Always assume the presence of duplicates if sort doesn't +// pass them to our comparison function (as in Google Chrome). +[0, 0].sort( sortOrder ); +baseHasDuplicate = !hasDuplicate; + +// Document sorting and removing duplicates +Sizzle.uniqueSort = function( results ) { + var elem, + i = 1; + + hasDuplicate = baseHasDuplicate; + results.sort( sortOrder ); + + if ( hasDuplicate ) { + for ( ; (elem = results[i]); i++ ) { + if ( elem === results[ i - 1 ] ) { + results.splice( i--, 1 ); + } + } + } + + return results; +}; + +Sizzle.error = function( msg ) { + throw new Error( "Syntax error, unrecognized expression: " + msg ); +}; + +function tokenize( selector, parseOnly ) { + var matched, match, tokens, type, soFar, groups, preFilters, + cached = tokenCache[ expando ][ selector ]; + + if ( cached ) { + return parseOnly ? 0 : cached.slice( 0 ); + } + + soFar = selector; + groups = []; + preFilters = Expr.preFilter; + + while ( soFar ) { + + // Comma and first run + if ( !matched || (match = rcomma.exec( soFar )) ) { + if ( match ) { + soFar = soFar.slice( match[0].length ); + } + groups.push( tokens = [] ); + } + + matched = false; + + // Combinators + if ( (match = rcombinators.exec( soFar )) ) { + tokens.push( matched = new Token( match.shift() ) ); + soFar = soFar.slice( matched.length ); + + // Cast descendant combinators to space + matched.type = match[0].replace( rtrim, " " ); + } + + // Filters + for ( type in Expr.filter ) { + if ( (match = matchExpr[ type ].exec( soFar )) && (!preFilters[ type ] || + // The last two arguments here are (context, xml) for backCompat + (match = preFilters[ type ]( match, document, true ))) ) { + + tokens.push( matched = new Token( match.shift() ) ); + soFar = soFar.slice( matched.length ); + matched.type = type; + matched.matches = match; + } + } + + if ( !matched ) { + break; + } + } + + // Return the length of the invalid excess + // if we're just parsing + // Otherwise, throw an error or return tokens + return parseOnly ? + soFar.length : + soFar ? + Sizzle.error( selector ) : + // Cache the tokens + tokenCache( selector, groups ).slice( 0 ); +} + +function addCombinator( matcher, combinator, base ) { + var dir = combinator.dir, + checkNonElements = base && combinator.dir === "parentNode", + doneName = done++; + + return combinator.first ? + // Check against closest ancestor/preceding element + function( elem, context, xml ) { + while ( (elem = elem[ dir ]) ) { + if ( checkNonElements || elem.nodeType === 1 ) { + return matcher( elem, context, xml ); + } + } + } : + + // Check against all ancestor/preceding elements + function( elem, context, xml ) { + // We can't set arbitrary data on XML nodes, so they don't benefit from dir caching + if ( !xml ) { + var cache, + dirkey = dirruns + " " + doneName + " ", + cachedkey = dirkey + cachedruns; + while ( (elem = elem[ dir ]) ) { + if ( checkNonElements || elem.nodeType === 1 ) { + if ( (cache = elem[ expando ]) === cachedkey ) { + return elem.sizset; + } else if ( typeof cache === "string" && cache.indexOf(dirkey) === 0 ) { + if ( elem.sizset ) { + return elem; + } + } else { + elem[ expando ] = cachedkey; + if ( matcher( elem, context, xml ) ) { + elem.sizset = true; + return elem; + } + elem.sizset = false; + } + } + } + } else { + while ( (elem = elem[ dir ]) ) { + if ( checkNonElements || elem.nodeType === 1 ) { + if ( matcher( elem, context, xml ) ) { + return elem; + } + } + } + } + }; +} + +function elementMatcher( matchers ) { + return matchers.length > 1 ? + function( elem, context, xml ) { + var i = matchers.length; + while ( i-- ) { + if ( !matchers[i]( elem, context, xml ) ) { + return false; + } + } + return true; + } : + matchers[0]; +} + +function condense( unmatched, map, filter, context, xml ) { + var elem, + newUnmatched = [], + i = 0, + len = unmatched.length, + mapped = map != null; + + for ( ; i < len; i++ ) { + if ( (elem = unmatched[i]) ) { + if ( !filter || filter( elem, context, xml ) ) { + newUnmatched.push( elem ); + if ( mapped ) { + map.push( i ); + } + } + } + } + + return newUnmatched; +} + +function setMatcher( preFilter, selector, matcher, postFilter, postFinder, postSelector ) { + if ( postFilter && !postFilter[ expando ] ) { + postFilter = setMatcher( postFilter ); + } + if ( postFinder && !postFinder[ expando ] ) { + postFinder = setMatcher( postFinder, postSelector ); + } + return markFunction(function( seed, results, context, xml ) { + // Positional selectors apply to seed elements, so it is invalid to follow them with relative ones + if ( seed && postFinder ) { + return; + } + + var i, elem, postFilterIn, + preMap = [], + postMap = [], + preexisting = results.length, + + // Get initial elements from seed or context + elems = seed || multipleContexts( selector || "*", context.nodeType ? [ context ] : context, [], seed ), + + // Prefilter to get matcher input, preserving a map for seed-results synchronization + matcherIn = preFilter && ( seed || !selector ) ? + condense( elems, preMap, preFilter, context, xml ) : + elems, + + matcherOut = matcher ? + // If we have a postFinder, or filtered seed, or non-seed postFilter or preexisting results, + postFinder || ( seed ? preFilter : preexisting || postFilter ) ? + + // ...intermediate processing is necessary + [] : + + // ...otherwise use results directly + results : + matcherIn; + + // Find primary matches + if ( matcher ) { + matcher( matcherIn, matcherOut, context, xml ); + } + + // Apply postFilter + if ( postFilter ) { + postFilterIn = condense( matcherOut, postMap ); + postFilter( postFilterIn, [], context, xml ); + + // Un-match failing elements by moving them back to matcherIn + i = postFilterIn.length; + while ( i-- ) { + if ( (elem = postFilterIn[i]) ) { + matcherOut[ postMap[i] ] = !(matcherIn[ postMap[i] ] = elem); + } + } + } + + // Keep seed and results synchronized + if ( seed ) { + // Ignore postFinder because it can't coexist with seed + i = preFilter && matcherOut.length; + while ( i-- ) { + if ( (elem = matcherOut[i]) ) { + seed[ preMap[i] ] = !(results[ preMap[i] ] = elem); + } + } + } else { + matcherOut = condense( + matcherOut === results ? + matcherOut.splice( preexisting, matcherOut.length ) : + matcherOut + ); + if ( postFinder ) { + postFinder( null, results, matcherOut, xml ); + } else { + push.apply( results, matcherOut ); + } + } + }); +} + +function matcherFromTokens( tokens ) { + var checkContext, matcher, j, + len = tokens.length, + leadingRelative = Expr.relative[ tokens[0].type ], + implicitRelative = leadingRelative || Expr.relative[" "], + i = leadingRelative ? 1 : 0, + + // The foundational matcher ensures that elements are reachable from top-level context(s) + matchContext = addCombinator( function( elem ) { + return elem === checkContext; + }, implicitRelative, true ), + matchAnyContext = addCombinator( function( elem ) { + return indexOf.call( checkContext, elem ) > -1; + }, implicitRelative, true ), + matchers = [ function( elem, context, xml ) { + return ( !leadingRelative && ( xml || context !== outermostContext ) ) || ( + (checkContext = context).nodeType ? + matchContext( elem, context, xml ) : + matchAnyContext( elem, context, xml ) ); + } ]; + + for ( ; i < len; i++ ) { + if ( (matcher = Expr.relative[ tokens[i].type ]) ) { + matchers = [ addCombinator( elementMatcher( matchers ), matcher ) ]; + } else { + // The concatenated values are (context, xml) for backCompat + matcher = Expr.filter[ tokens[i].type ].apply( null, tokens[i].matches ); + + // Return special upon seeing a positional matcher + if ( matcher[ expando ] ) { + // Find the next relative operator (if any) for proper handling + j = ++i; + for ( ; j < len; j++ ) { + if ( Expr.relative[ tokens[j].type ] ) { + break; + } + } + return setMatcher( + i > 1 && elementMatcher( matchers ), + i > 1 && tokens.slice( 0, i - 1 ).join("").replace( rtrim, "$1" ), + matcher, + i < j && matcherFromTokens( tokens.slice( i, j ) ), + j < len && matcherFromTokens( (tokens = tokens.slice( j )) ), + j < len && tokens.join("") + ); + } + matchers.push( matcher ); + } + } + + return elementMatcher( matchers ); +} + +function matcherFromGroupMatchers( elementMatchers, setMatchers ) { + var bySet = setMatchers.length > 0, + byElement = elementMatchers.length > 0, + superMatcher = function( seed, context, xml, results, expandContext ) { + var elem, j, matcher, + setMatched = [], + matchedCount = 0, + i = "0", + unmatched = seed && [], + outermost = expandContext != null, + contextBackup = outermostContext, + // We must always have either seed elements or context + elems = seed || byElement && Expr.find["TAG"]( "*", expandContext && context.parentNode || context ), + // Nested matchers should use non-integer dirruns + dirrunsUnique = (dirruns += contextBackup == null ? 1 : Math.E); + + if ( outermost ) { + outermostContext = context !== document && context; + cachedruns = superMatcher.el; + } + + // Add elements passing elementMatchers directly to results + for ( ; (elem = elems[i]) != null; i++ ) { + if ( byElement && elem ) { + for ( j = 0; (matcher = elementMatchers[j]); j++ ) { + if ( matcher( elem, context, xml ) ) { + results.push( elem ); + break; + } + } + if ( outermost ) { + dirruns = dirrunsUnique; + cachedruns = ++superMatcher.el; + } + } + + // Track unmatched elements for set filters + if ( bySet ) { + // They will have gone through all possible matchers + if ( (elem = !matcher && elem) ) { + matchedCount--; + } + + // Lengthen the array for every element, matched or not + if ( seed ) { + unmatched.push( elem ); + } + } + } + + // Apply set filters to unmatched elements + matchedCount += i; + if ( bySet && i !== matchedCount ) { + for ( j = 0; (matcher = setMatchers[j]); j++ ) { + matcher( unmatched, setMatched, context, xml ); + } + + if ( seed ) { + // Reintegrate element matches to eliminate the need for sorting + if ( matchedCount > 0 ) { + while ( i-- ) { + if ( !(unmatched[i] || setMatched[i]) ) { + setMatched[i] = pop.call( results ); + } + } + } + + // Discard index placeholder values to get only actual matches + setMatched = condense( setMatched ); + } + + // Add matches to results + push.apply( results, setMatched ); + + // Seedless set matches succeeding multiple successful matchers stipulate sorting + if ( outermost && !seed && setMatched.length > 0 && + ( matchedCount + setMatchers.length ) > 1 ) { + + Sizzle.uniqueSort( results ); + } + } + + // Override manipulation of globals by nested matchers + if ( outermost ) { + dirruns = dirrunsUnique; + outermostContext = contextBackup; + } + + return unmatched; + }; + + superMatcher.el = 0; + return bySet ? + markFunction( superMatcher ) : + superMatcher; +} + +compile = Sizzle.compile = function( selector, group /* Internal Use Only */ ) { + var i, + setMatchers = [], + elementMatchers = [], + cached = compilerCache[ expando ][ selector ]; + + if ( !cached ) { + // Generate a function of recursive functions that can be used to check each element + if ( !group ) { + group = tokenize( selector ); + } + i = group.length; + while ( i-- ) { + cached = matcherFromTokens( group[i] ); + if ( cached[ expando ] ) { + setMatchers.push( cached ); + } else { + elementMatchers.push( cached ); + } + } + + // Cache the compiled function + cached = compilerCache( selector, matcherFromGroupMatchers( elementMatchers, setMatchers ) ); + } + return cached; +}; + +function multipleContexts( selector, contexts, results, seed ) { + var i = 0, + len = contexts.length; + for ( ; i < len; i++ ) { + Sizzle( selector, contexts[i], results, seed ); + } + return results; +} + +function select( selector, context, results, seed, xml ) { + var i, tokens, token, type, find, + match = tokenize( selector ), + j = match.length; + + if ( !seed ) { + // Try to minimize operations if there is only one group + if ( match.length === 1 ) { + + // Take a shortcut and set the context if the root selector is an ID + tokens = match[0] = match[0].slice( 0 ); + if ( tokens.length > 2 && (token = tokens[0]).type === "ID" && + context.nodeType === 9 && !xml && + Expr.relative[ tokens[1].type ] ) { + + context = Expr.find["ID"]( token.matches[0].replace( rbackslash, "" ), context, xml )[0]; + if ( !context ) { + return results; + } + + selector = selector.slice( tokens.shift().length ); + } + + // Fetch a seed set for right-to-left matching + for ( i = matchExpr["POS"].test( selector ) ? -1 : tokens.length - 1; i >= 0; i-- ) { + token = tokens[i]; + + // Abort if we hit a combinator + if ( Expr.relative[ (type = token.type) ] ) { + break; + } + if ( (find = Expr.find[ type ]) ) { + // Search, expanding context for leading sibling combinators + if ( (seed = find( + token.matches[0].replace( rbackslash, "" ), + rsibling.test( tokens[0].type ) && context.parentNode || context, + xml + )) ) { + + // If seed is empty or no tokens remain, we can return early + tokens.splice( i, 1 ); + selector = seed.length && tokens.join(""); + if ( !selector ) { + push.apply( results, slice.call( seed, 0 ) ); + return results; + } + + break; + } + } + } + } + } + + // Compile and execute a filtering function + // Provide `match` to avoid retokenization if we modified the selector above + compile( selector, match )( + seed, + context, + xml, + results, + rsibling.test( selector ) + ); + return results; +} + +if ( document.querySelectorAll ) { + (function() { + var disconnectedMatch, + oldSelect = select, + rescape = /'|\\/g, + rattributeQuotes = /\=[\x20\t\r\n\f]*([^'"\]]*)[\x20\t\r\n\f]*\]/g, + + // qSa(:focus) reports false when true (Chrome 21), + // A support test would require too much code (would include document ready) + rbuggyQSA = [":focus"], + + // matchesSelector(:focus) reports false when true (Chrome 21), + // matchesSelector(:active) reports false when true (IE9/Opera 11.5) + // A support test would require too much code (would include document ready) + // just skip matchesSelector for :active + rbuggyMatches = [ ":active", ":focus" ], + matches = docElem.matchesSelector || + docElem.mozMatchesSelector || + docElem.webkitMatchesSelector || + docElem.oMatchesSelector || + docElem.msMatchesSelector; + + // Build QSA regex + // Regex strategy adopted from Diego Perini + assert(function( div ) { + // Select is set to empty string on purpose + // This is to test IE's treatment of not explictly + // setting a boolean content attribute, + // since its presence should be enough + // http://bugs.jquery.com/ticket/12359 + div.innerHTML = ""; + + // IE8 - Some boolean attributes are not treated correctly + if ( !div.querySelectorAll("[selected]").length ) { + rbuggyQSA.push( "\\[" + whitespace + "*(?:checked|disabled|ismap|multiple|readonly|selected|value)" ); + } + + // Webkit/Opera - :checked should return selected option elements + // http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked + // IE8 throws error here (do not put tests after this one) + if ( !div.querySelectorAll(":checked").length ) { + rbuggyQSA.push(":checked"); + } + }); + + assert(function( div ) { + + // Opera 10-12/IE9 - ^= $= *= and empty values + // Should not select anything + div.innerHTML = "

      "; + if ( div.querySelectorAll("[test^='']").length ) { + rbuggyQSA.push( "[*^$]=" + whitespace + "*(?:\"\"|'')" ); + } + + // FF 3.5 - :enabled/:disabled and hidden elements (hidden elements are still enabled) + // IE8 throws error here (do not put tests after this one) + div.innerHTML = ""; + if ( !div.querySelectorAll(":enabled").length ) { + rbuggyQSA.push(":enabled", ":disabled"); + } + }); + + // rbuggyQSA always contains :focus, so no need for a length check + rbuggyQSA = /* rbuggyQSA.length && */ new RegExp( rbuggyQSA.join("|") ); + + select = function( selector, context, results, seed, xml ) { + // Only use querySelectorAll when not filtering, + // when this is not xml, + // and when no QSA bugs apply + if ( !seed && !xml && (!rbuggyQSA || !rbuggyQSA.test( selector )) ) { + var groups, i, + old = true, + nid = expando, + newContext = context, + newSelector = context.nodeType === 9 && selector; + + // 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 + if ( context.nodeType === 1 && context.nodeName.toLowerCase() !== "object" ) { + groups = tokenize( selector ); + + if ( (old = context.getAttribute("id")) ) { + nid = old.replace( rescape, "\\$&" ); + } else { + context.setAttribute( "id", nid ); + } + nid = "[id='" + nid + "'] "; + + i = groups.length; + while ( i-- ) { + groups[i] = nid + groups[i].join(""); + } + newContext = rsibling.test( selector ) && context.parentNode || context; + newSelector = groups.join(","); + } + + if ( newSelector ) { + try { + push.apply( results, slice.call( newContext.querySelectorAll( + newSelector + ), 0 ) ); + return results; + } catch(qsaError) { + } finally { + if ( !old ) { + context.removeAttribute("id"); + } + } + } + } + + return oldSelect( selector, context, results, seed, xml ); + }; + + if ( matches ) { + assert(function( div ) { + // Check to see if it's possible to do matchesSelector + // on a disconnected node (IE 9) + disconnectedMatch = matches.call( div, "div" ); + + // This should fail with an exception + // Gecko does not error, returns false instead + try { + matches.call( div, "[test!='']:sizzle" ); + rbuggyMatches.push( "!=", pseudos ); + } catch ( e ) {} + }); + + // rbuggyMatches always contains :active and :focus, so no need for a length check + rbuggyMatches = /* rbuggyMatches.length && */ new RegExp( rbuggyMatches.join("|") ); + + Sizzle.matchesSelector = function( elem, expr ) { + // Make sure that attribute selectors are quoted + expr = expr.replace( rattributeQuotes, "='$1']" ); + + // rbuggyMatches always contains :active, so no need for an existence check + if ( !isXML( elem ) && !rbuggyMatches.test( expr ) && (!rbuggyQSA || !rbuggyQSA.test( expr )) ) { + try { + var ret = matches.call( elem, 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 + elem.document && elem.document.nodeType !== 11 ) { + return ret; + } + } catch(e) {} + } + + return Sizzle( expr, null, null, [ elem ] ).length > 0; + }; + } + })(); +} + +// Deprecated +Expr.pseudos["nth"] = Expr.pseudos["eq"]; + +// Back-compat +function setFilters() {} +Expr.filters = setFilters.prototype = Expr.pseudos; +Expr.setFilters = new setFilters(); + +// Override sizzle attribute retrieval +Sizzle.attr = jQuery.attr; +jQuery.find = Sizzle; +jQuery.expr = Sizzle.selectors; +jQuery.expr[":"] = jQuery.expr.pseudos; +jQuery.unique = Sizzle.uniqueSort; +jQuery.text = Sizzle.getText; +jQuery.isXMLDoc = Sizzle.isXML; +jQuery.contains = Sizzle.contains; + + +})( window ); +var runtil = /Until$/, + rparentsprev = /^(?:parents|prev(?:Until|All))/, + isSimple = /^.[^:#\[\.,]*$/, + rneedsContext = jQuery.expr.match.needsContext, + // 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 i, l, length, n, r, ret, + self = this; + + 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; + } + } + }); + } + + ret = this.pushStack( "", "find", selector ); + + 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 i, + targets = jQuery( target, this ), + len = targets.length; + + return this.filter(function() { + for ( i = 0; i < len; 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" ? + // If this is a positional/relative selector, check membership in the returned set + // so $("p:first").is("p:last") won't return true for a doc with two "p". + rneedsContext.test( selector ) ? + jQuery( selector, this.context ).index( this[0] ) >= 0 : + jQuery.filter( selector, this ).length > 0 : + this.filter( selector ).length > 0 ); + }, + + closest: function( selectors, context ) { + var cur, + i = 0, + l = this.length, + ret = [], + pos = rneedsContext.test( selectors ) || typeof selectors !== "string" ? + jQuery( selectors, context || this.context ) : + 0; + + for ( ; i < l; i++ ) { + cur = this[i]; + + while ( cur && cur.ownerDocument && cur !== context && cur.nodeType !== 11 ) { + if ( pos ? pos.index(cur) > -1 : jQuery.find.matchesSelector(cur, selectors) ) { + ret.push( cur ); + break; + } + cur = cur.parentNode; + } + } + + 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 ) { + + // No argument, return index in parent + if ( !elem ) { + return ( this[0] && this[0].parentNode ) ? this.prevAll().length : -1; + } + + // index in selector + if ( typeof elem === "string" ) { + return jQuery.inArray( this[0], jQuery( elem ) ); + } + + // 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 ) ); + }, + + addBack: function( selector ) { + return this.add( selector == null ? + this.prevObject : this.prevObject.filter(selector) + ); + } +}); + +jQuery.fn.andSelf = jQuery.fn.addBack; + +// 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; +} + +function sibling( cur, dir ) { + do { + cur = cur[ dir ]; + } while ( cur && cur.nodeType !== 1 ); + + return cur; +} + +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 sibling( elem, "nextSibling" ); + }, + prev: function( elem ) { + return sibling( elem, "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.merge( [], elem.childNodes ); + } +}, function( name, fn ) { + jQuery.fn[ name ] = function( until, selector ) { + var ret = jQuery.map( this, fn, until ); + + 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 && rparentsprev.test( name ) ) { + ret = ret.reverse(); + } + + return this.pushStack( ret, name, core_slice.call( arguments ).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; + }, + + 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; + }); +} +function createSafeFragment( document ) { + var list = nodeNames.split( "|" ), + safeFrag = document.createDocumentFragment(); + + if ( safeFrag.createElement ) { + while ( list.length ) { + safeFrag.createElement( + list.pop() + ); + } + } + return safeFrag; +} + +var nodeNames = "abbr|article|aside|audio|bdi|canvas|data|datalist|details|figcaption|figure|footer|" + + "header|hgroup|mark|meter|nav|output|progress|section|summary|time|video", + rinlinejQuery = / jQuery\d+="(?:null|\d+)"/g, + rleadingWhitespace = /^\s+/, + rxhtmlTag = /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/gi, + rtagName = /<([\w:]+)/, + rtbody = /]", "i"), + rcheckableType = /^(?:checkbox|radio)$/, + // checked="checked" or checked + rchecked = /checked\s*(?:[^=]|=\s*.checked.)/i, + rscriptType = /\/(java|ecma)script/i, + rcleanScript = /^\s*\s*$/g, + wrapMap = { + option: [ 1, "" ], + legend: [ 1, "
      ", "
      " ], + thead: [ 1, "", "
      " ], + tr: [ 2, "", "
      " ], + td: [ 3, "", "
      " ], + col: [ 2, "", "
      " ], + area: [ 1, "", "" ], + _default: [ 0, "", "" ] + }, + safeFragment = createSafeFragment( document ), + fragmentDiv = safeFragment.appendChild( document.createElement("div") ); + +wrapMap.optgroup = wrapMap.option; +wrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead; +wrapMap.th = wrapMap.td; + +// IE6-8 can't serialize link, script, style, or any html5 (NoScope) tags, +// unless wrapped in a div with non-breaking characters in front of it. +if ( !jQuery.support.htmlSerialize ) { + wrapMap._default = [ 1, "X
      ", "
      " ]; +} + +jQuery.fn.extend({ + text: function( value ) { + return jQuery.access( this, function( value ) { + return value === undefined ? + jQuery.text( this ) : + this.empty().append( ( this[0] && this[0].ownerDocument || document ).createTextNode( value ) ); + }, null, value, arguments.length ); + }, + + wrapAll: function( html ) { + if ( jQuery.isFunction( html ) ) { + return this.each(function(i) { + jQuery(this).wrapAll( html.call(this, i) ); + }); + } + + if ( this[0] ) { + // The elements to wrap the target around + var wrap = jQuery( html, this[0].ownerDocument ).eq(0).clone(true); + + if ( this[0].parentNode ) { + wrap.insertBefore( this[0] ); + } + + wrap.map(function() { + var elem = this; + + while ( elem.firstChild && elem.firstChild.nodeType === 1 ) { + elem = elem.firstChild; + } + + return elem; + }).append( this ); + } + + return this; + }, + + wrapInner: function( html ) { + if ( jQuery.isFunction( html ) ) { + return this.each(function(i) { + jQuery(this).wrapInner( html.call(this, i) ); + }); + } + + return this.each(function() { + var self = jQuery( this ), + contents = self.contents(); + + if ( contents.length ) { + contents.wrapAll( html ); + + } else { + self.append( html ); + } + }); + }, + + wrap: function( html ) { + var isFunction = jQuery.isFunction( html ); + + return this.each(function(i) { + jQuery( this ).wrapAll( isFunction ? html.call(this, i) : html ); + }); + }, + + unwrap: function() { + return this.parent().each(function() { + if ( !jQuery.nodeName( this, "body" ) ) { + jQuery( this ).replaceWith( this.childNodes ); + } + }).end(); + }, + + append: function() { + return this.domManip(arguments, true, function( elem ) { + if ( this.nodeType === 1 || this.nodeType === 11 ) { + this.appendChild( elem ); + } + }); + }, + + prepend: function() { + return this.domManip(arguments, true, function( elem ) { + if ( this.nodeType === 1 || this.nodeType === 11 ) { + this.insertBefore( elem, this.firstChild ); + } + }); + }, + + before: function() { + if ( !isDisconnected( this[0] ) ) { + return this.domManip(arguments, false, function( elem ) { + this.parentNode.insertBefore( elem, this ); + }); + } + + if ( arguments.length ) { + var set = jQuery.clean( arguments ); + return this.pushStack( jQuery.merge( set, this ), "before", this.selector ); + } + }, + + after: function() { + if ( !isDisconnected( this[0] ) ) { + return this.domManip(arguments, false, function( elem ) { + this.parentNode.insertBefore( elem, this.nextSibling ); + }); + } + + if ( arguments.length ) { + var set = jQuery.clean( arguments ); + return this.pushStack( jQuery.merge( this, set ), "after", this.selector ); + } + }, + + // keepData is for internal use only--do not document + remove: function( selector, keepData ) { + var elem, + i = 0; + + for ( ; (elem = this[i]) != null; i++ ) { + if ( !selector || jQuery.filter( selector, [ elem ] ).length ) { + if ( !keepData && elem.nodeType === 1 ) { + jQuery.cleanData( elem.getElementsByTagName("*") ); + jQuery.cleanData( [ elem ] ); + } + + if ( elem.parentNode ) { + elem.parentNode.removeChild( elem ); + } + } + } + + return this; + }, + + empty: function() { + var elem, + i = 0; + + for ( ; (elem = this[i]) != null; i++ ) { + // Remove element nodes and prevent memory leaks + if ( elem.nodeType === 1 ) { + jQuery.cleanData( elem.getElementsByTagName("*") ); + } + + // Remove any remaining nodes + while ( elem.firstChild ) { + elem.removeChild( elem.firstChild ); + } + } + + return this; + }, + + clone: function( dataAndEvents, deepDataAndEvents ) { + dataAndEvents = dataAndEvents == null ? false : dataAndEvents; + deepDataAndEvents = deepDataAndEvents == null ? dataAndEvents : deepDataAndEvents; + + return this.map( function () { + return jQuery.clone( this, dataAndEvents, deepDataAndEvents ); + }); + }, + + html: function( value ) { + return jQuery.access( this, function( value ) { + var elem = this[0] || {}, + i = 0, + l = this.length; + + if ( value === undefined ) { + return elem.nodeType === 1 ? + elem.innerHTML.replace( rinlinejQuery, "" ) : + undefined; + } + + // See if we can take a shortcut and just use innerHTML + if ( typeof value === "string" && !rnoInnerhtml.test( value ) && + ( jQuery.support.htmlSerialize || !rnoshimcache.test( value ) ) && + ( jQuery.support.leadingWhitespace || !rleadingWhitespace.test( value ) ) && + !wrapMap[ ( rtagName.exec( value ) || ["", ""] )[1].toLowerCase() ] ) { + + value = value.replace( rxhtmlTag, "<$1>" ); + + try { + for (; i < l; i++ ) { + // Remove element nodes and prevent memory leaks + elem = this[i] || {}; + if ( elem.nodeType === 1 ) { + jQuery.cleanData( elem.getElementsByTagName( "*" ) ); + elem.innerHTML = value; + } + } + + elem = 0; + + // If using innerHTML throws an exception, use the fallback method + } catch(e) {} + } + + if ( elem ) { + this.empty().append( value ); + } + }, null, value, arguments.length ); + }, + + replaceWith: function( value ) { + if ( !isDisconnected( this[0] ) ) { + // Make sure that the elements are removed from the DOM before they are inserted + // this can help fix replacing a parent with child elements + if ( jQuery.isFunction( value ) ) { + return this.each(function(i) { + var self = jQuery(this), old = self.html(); + self.replaceWith( value.call( this, i, old ) ); + }); + } + + if ( typeof value !== "string" ) { + value = jQuery( value ).detach(); + } + + return this.each(function() { + var next = this.nextSibling, + parent = this.parentNode; + + jQuery( this ).remove(); + + if ( next ) { + jQuery(next).before( value ); + } else { + jQuery(parent).append( value ); + } + }); + } + + return this.length ? + this.pushStack( jQuery(jQuery.isFunction(value) ? value() : value), "replaceWith", value ) : + this; + }, + + detach: function( selector ) { + return this.remove( selector, true ); + }, + + domManip: function( args, table, callback ) { + + // Flatten any nested arrays + args = [].concat.apply( [], args ); + + var results, first, fragment, iNoClone, + i = 0, + value = args[0], + scripts = [], + l = this.length; + + // We can't cloneNode fragments that contain checked, in WebKit + if ( !jQuery.support.checkClone && l > 1 && typeof value === "string" && rchecked.test( value ) ) { + return this.each(function() { + jQuery(this).domManip( args, table, callback ); + }); + } + + if ( jQuery.isFunction(value) ) { + return this.each(function(i) { + var self = jQuery(this); + args[0] = value.call( this, i, table ? self.html() : undefined ); + self.domManip( args, table, callback ); + }); + } + + if ( this[0] ) { + results = jQuery.buildFragment( args, this, scripts ); + fragment = results.fragment; + first = fragment.firstChild; + + if ( fragment.childNodes.length === 1 ) { + fragment = first; + } + + if ( first ) { + table = table && jQuery.nodeName( first, "tr" ); + + // Use the original fragment for the last item instead of the first because it can end up + // being emptied incorrectly in certain situations (#8070). + // Fragments from the fragment cache must always be cloned and never used in place. + for ( iNoClone = results.cacheable || l - 1; i < l; i++ ) { + callback.call( + table && jQuery.nodeName( this[i], "table" ) ? + findOrAppend( this[i], "tbody" ) : + this[i], + i === iNoClone ? + fragment : + jQuery.clone( fragment, true, true ) + ); + } + } + + // Fix #11809: Avoid leaking memory + fragment = first = null; + + if ( scripts.length ) { + jQuery.each( scripts, function( i, elem ) { + if ( elem.src ) { + if ( jQuery.ajax ) { + jQuery.ajax({ + url: elem.src, + type: "GET", + dataType: "script", + async: false, + global: false, + "throws": true + }); + } else { + jQuery.error("no ajax"); + } + } else { + jQuery.globalEval( ( elem.text || elem.textContent || elem.innerHTML || "" ).replace( rcleanScript, "" ) ); + } + + if ( elem.parentNode ) { + elem.parentNode.removeChild( elem ); + } + }); + } + } + + return this; + } +}); + +function findOrAppend( elem, tag ) { + return elem.getElementsByTagName( tag )[0] || elem.appendChild( elem.ownerDocument.createElement( tag ) ); +} + +function cloneCopyEvent( src, dest ) { + + if ( dest.nodeType !== 1 || !jQuery.hasData( src ) ) { + return; + } + + var type, i, l, + oldData = jQuery._data( src ), + curData = jQuery._data( dest, oldData ), + events = oldData.events; + + if ( events ) { + delete curData.handle; + curData.events = {}; + + for ( type in events ) { + for ( i = 0, l = events[ type ].length; i < l; i++ ) { + jQuery.event.add( dest, type, events[ type ][ i ] ); + } + } + } + + // make the cloned public data object a copy from the original + if ( curData.data ) { + curData.data = jQuery.extend( {}, curData.data ); + } +} + +function cloneFixAttributes( src, dest ) { + var nodeName; + + // We do not need to do anything for non-Elements + if ( dest.nodeType !== 1 ) { + return; + } + + // clearAttributes removes the attributes, which we don't want, + // but also removes the attachEvent events, which we *do* want + if ( dest.clearAttributes ) { + dest.clearAttributes(); + } + + // mergeAttributes, in contrast, only merges back on the + // original attributes, not the events + if ( dest.mergeAttributes ) { + dest.mergeAttributes( src ); + } + + nodeName = dest.nodeName.toLowerCase(); + + if ( nodeName === "object" ) { + // IE6-10 improperly clones children of object elements using classid. + // IE10 throws NoModificationAllowedError if parent is null, #12132. + if ( dest.parentNode ) { + dest.outerHTML = src.outerHTML; + } + + // This path appears unavoidable for IE9. When cloning an object + // element in IE9, the outerHTML strategy above is not sufficient. + // If the src has innerHTML and the destination does not, + // copy the src.innerHTML into the dest.innerHTML. #10324 + if ( jQuery.support.html5Clone && (src.innerHTML && !jQuery.trim(dest.innerHTML)) ) { + dest.innerHTML = src.innerHTML; + } + + } else if ( nodeName === "input" && rcheckableType.test( src.type ) ) { + // IE6-8 fails to persist the checked state of a cloned checkbox + // or radio button. Worse, IE6-7 fail to give the cloned element + // a checked appearance if the defaultChecked value isn't also set + + dest.defaultChecked = dest.checked = src.checked; + + // IE6-7 get confused and end up setting the value of a cloned + // checkbox/radio button to an empty string instead of "on" + if ( dest.value !== src.value ) { + dest.value = src.value; + } + + // IE6-8 fails to return the selected option to the default selected + // state when cloning options + } else if ( nodeName === "option" ) { + dest.selected = src.defaultSelected; + + // IE6-8 fails to set the defaultValue to the correct value when + // cloning other types of input fields + } else if ( nodeName === "input" || nodeName === "textarea" ) { + dest.defaultValue = src.defaultValue; + + // IE blanks contents when cloning scripts + } else if ( nodeName === "script" && dest.text !== src.text ) { + dest.text = src.text; + } + + // Event data gets referenced instead of copied if the expando + // gets copied too + dest.removeAttribute( jQuery.expando ); +} + +jQuery.buildFragment = function( args, context, scripts ) { + var fragment, cacheable, cachehit, + first = args[ 0 ]; + + // Set context from what may come in as undefined or a jQuery collection or a node + // Updated to fix #12266 where accessing context[0] could throw an exception in IE9/10 & + // also doubles as fix for #8950 where plain objects caused createDocumentFragment exception + context = context || document; + context = !context.nodeType && context[0] || context; + context = context.ownerDocument || context; + + // Only cache "small" (1/2 KB) HTML strings that are associated with the main document + // Cloning options loses the selected state, so don't cache them + // IE 6 doesn't like it when you put or elements in a fragment + // Also, WebKit does not clone 'checked' attributes on cloneNode, so don't cache + // Lastly, IE6,7,8 will not correctly reuse cached fragments that were created from unknown elems #10501 + if ( args.length === 1 && typeof first === "string" && first.length < 512 && context === document && + first.charAt(0) === "<" && !rnocache.test( first ) && + (jQuery.support.checkClone || !rchecked.test( first )) && + (jQuery.support.html5Clone || !rnoshimcache.test( first )) ) { + + // Mark cacheable and look for a hit + cacheable = true; + fragment = jQuery.fragments[ first ]; + cachehit = fragment !== undefined; + } + + if ( !fragment ) { + fragment = context.createDocumentFragment(); + jQuery.clean( args, context, fragment, scripts ); + + // Update the cache, but only store false + // unless this is a second parsing of the same content + if ( cacheable ) { + jQuery.fragments[ first ] = cachehit && fragment; + } + } + + return { fragment: fragment, cacheable: cacheable }; +}; + +jQuery.fragments = {}; + +jQuery.each({ + appendTo: "append", + prependTo: "prepend", + insertBefore: "before", + insertAfter: "after", + replaceAll: "replaceWith" +}, function( name, original ) { + jQuery.fn[ name ] = function( selector ) { + var elems, + i = 0, + ret = [], + insert = jQuery( selector ), + l = insert.length, + parent = this.length === 1 && this[0].parentNode; + + if ( (parent == null || parent && parent.nodeType === 11 && parent.childNodes.length === 1) && l === 1 ) { + insert[ original ]( this[0] ); + return this; + } else { + for ( ; i < l; i++ ) { + elems = ( i > 0 ? this.clone(true) : this ).get(); + jQuery( insert[i] )[ original ]( elems ); + ret = ret.concat( elems ); + } + + return this.pushStack( ret, name, insert.selector ); + } + }; +}); + +function getAll( elem ) { + if ( typeof elem.getElementsByTagName !== "undefined" ) { + return elem.getElementsByTagName( "*" ); + + } else if ( typeof elem.querySelectorAll !== "undefined" ) { + return elem.querySelectorAll( "*" ); + + } else { + return []; + } +} + +// Used in clean, fixes the defaultChecked property +function fixDefaultChecked( elem ) { + if ( rcheckableType.test( elem.type ) ) { + elem.defaultChecked = elem.checked; + } +} + +jQuery.extend({ + clone: function( elem, dataAndEvents, deepDataAndEvents ) { + var srcElements, + destElements, + i, + clone; + + if ( jQuery.support.html5Clone || jQuery.isXMLDoc(elem) || !rnoshimcache.test( "<" + elem.nodeName + ">" ) ) { + clone = elem.cloneNode( true ); + + // IE<=8 does not properly clone detached, unknown element nodes + } else { + fragmentDiv.innerHTML = elem.outerHTML; + fragmentDiv.removeChild( clone = fragmentDiv.firstChild ); + } + + if ( (!jQuery.support.noCloneEvent || !jQuery.support.noCloneChecked) && + (elem.nodeType === 1 || elem.nodeType === 11) && !jQuery.isXMLDoc(elem) ) { + // IE copies events bound via attachEvent when using cloneNode. + // Calling detachEvent on the clone will also remove the events + // from the original. In order to get around this, we use some + // proprietary methods to clear the events. Thanks to MooTools + // guys for this hotness. + + cloneFixAttributes( elem, clone ); + + // Using Sizzle here is crazy slow, so we use getElementsByTagName instead + srcElements = getAll( elem ); + destElements = getAll( clone ); + + // Weird iteration because IE will replace the length property + // with an element if you are cloning the body and one of the + // elements on the page has a name or id of "length" + for ( i = 0; srcElements[i]; ++i ) { + // Ensure that the destination node is not null; Fixes #9587 + if ( destElements[i] ) { + cloneFixAttributes( srcElements[i], destElements[i] ); + } + } + } + + // Copy the events from the original to the clone + if ( dataAndEvents ) { + cloneCopyEvent( elem, clone ); + + if ( deepDataAndEvents ) { + srcElements = getAll( elem ); + destElements = getAll( clone ); + + for ( i = 0; srcElements[i]; ++i ) { + cloneCopyEvent( srcElements[i], destElements[i] ); + } + } + } + + srcElements = destElements = null; + + // Return the cloned set + return clone; + }, + + clean: function( elems, context, fragment, scripts ) { + var i, j, elem, tag, wrap, depth, div, hasBody, tbody, len, handleScript, jsTags, + safe = context === document && safeFragment, + ret = []; + + // Ensure that context is a document + if ( !context || typeof context.createDocumentFragment === "undefined" ) { + context = document; + } + + // Use the already-created safe fragment if context permits + for ( i = 0; (elem = elems[i]) != null; i++ ) { + if ( typeof elem === "number" ) { + elem += ""; + } + + if ( !elem ) { + continue; + } + + // Convert html string into DOM nodes + if ( typeof elem === "string" ) { + if ( !rhtml.test( elem ) ) { + elem = context.createTextNode( elem ); + } else { + // Ensure a safe container in which to render the html + safe = safe || createSafeFragment( context ); + div = context.createElement("div"); + safe.appendChild( div ); + + // Fix "XHTML"-style tags in all browsers + elem = elem.replace(rxhtmlTag, "<$1>"); + + // Go to html and back, then peel off extra wrappers + tag = ( rtagName.exec( elem ) || ["", ""] )[1].toLowerCase(); + wrap = wrapMap[ tag ] || wrapMap._default; + depth = wrap[0]; + div.innerHTML = wrap[1] + elem + wrap[2]; + + // Move to the right depth + while ( depth-- ) { + div = div.lastChild; + } + + // Remove IE's autoinserted from table fragments + if ( !jQuery.support.tbody ) { + + // String was a , *may* have spurious + hasBody = rtbody.test(elem); + tbody = tag === "table" && !hasBody ? + div.firstChild && div.firstChild.childNodes : + + // String was a bare or + wrap[1] === "
      " && !hasBody ? + div.childNodes : + []; + + for ( j = tbody.length - 1; j >= 0 ; --j ) { + if ( jQuery.nodeName( tbody[ j ], "tbody" ) && !tbody[ j ].childNodes.length ) { + tbody[ j ].parentNode.removeChild( tbody[ j ] ); + } + } + } + + // IE completely kills leading whitespace when innerHTML is used + if ( !jQuery.support.leadingWhitespace && rleadingWhitespace.test( elem ) ) { + div.insertBefore( context.createTextNode( rleadingWhitespace.exec(elem)[0] ), div.firstChild ); + } + + elem = div.childNodes; + + // Take out of fragment container (we need a fresh div each time) + div.parentNode.removeChild( div ); + } + } + + if ( elem.nodeType ) { + ret.push( elem ); + } else { + jQuery.merge( ret, elem ); + } + } + + // Fix #11356: Clear elements from safeFragment + if ( div ) { + elem = div = safe = null; + } + + // Reset defaultChecked for any radios and checkboxes + // about to be appended to the DOM in IE 6/7 (#8060) + if ( !jQuery.support.appendChecked ) { + for ( i = 0; (elem = ret[i]) != null; i++ ) { + if ( jQuery.nodeName( elem, "input" ) ) { + fixDefaultChecked( elem ); + } else if ( typeof elem.getElementsByTagName !== "undefined" ) { + jQuery.grep( elem.getElementsByTagName("input"), fixDefaultChecked ); + } + } + } + + // Append elements to a provided document fragment + if ( fragment ) { + // Special handling of each script element + handleScript = function( elem ) { + // Check if we consider it executable + if ( !elem.type || rscriptType.test( elem.type ) ) { + // Detach the script and store it in the scripts array (if provided) or the fragment + // Return truthy to indicate that it has been handled + return scripts ? + scripts.push( elem.parentNode ? elem.parentNode.removeChild( elem ) : elem ) : + fragment.appendChild( elem ); + } + }; + + for ( i = 0; (elem = ret[i]) != null; i++ ) { + // Check if we're done after handling an executable script + if ( !( jQuery.nodeName( elem, "script" ) && handleScript( elem ) ) ) { + // Append to fragment and handle embedded scripts + fragment.appendChild( elem ); + if ( typeof elem.getElementsByTagName !== "undefined" ) { + // handleScript alters the DOM, so use jQuery.merge to ensure snapshot iteration + jsTags = jQuery.grep( jQuery.merge( [], elem.getElementsByTagName("script") ), handleScript ); + + // Splice the scripts into ret after their former ancestor and advance our index beyond them + ret.splice.apply( ret, [i + 1, 0].concat( jsTags ) ); + i += jsTags.length; + } + } + } + } + + return ret; + }, + + cleanData: function( elems, /* internal */ acceptData ) { + var data, id, elem, type, + i = 0, + internalKey = jQuery.expando, + cache = jQuery.cache, + deleteExpando = jQuery.support.deleteExpando, + special = jQuery.event.special; + + for ( ; (elem = elems[i]) != null; i++ ) { + + if ( acceptData || jQuery.acceptData( elem ) ) { + + id = elem[ internalKey ]; + data = id && cache[ id ]; + + if ( data ) { + if ( data.events ) { + for ( type in data.events ) { + if ( special[ type ] ) { + jQuery.event.remove( elem, type ); + + // This is a shortcut to avoid jQuery.event.remove's overhead + } else { + jQuery.removeEvent( elem, type, data.handle ); + } + } + } + + // Remove cache only if it was not already removed by jQuery.event.remove + if ( cache[ id ] ) { + + delete cache[ id ]; + + // 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 ( deleteExpando ) { + delete elem[ internalKey ]; + + } else if ( elem.removeAttribute ) { + elem.removeAttribute( internalKey ); + + } else { + elem[ internalKey ] = null; + } + + jQuery.deletedIds.push( id ); + } + } + } + } + } +}); +// Limit scope pollution from any deprecated API +(function() { + +var matched, browser; + +// Use of jQuery.browser is frowned upon. +// More details: http://api.jquery.com/jQuery.browser +// jQuery.uaMatch maintained for back-compat +jQuery.uaMatch = function( ua ) { + ua = ua.toLowerCase(); + + var match = /(chrome)[ \/]([\w.]+)/.exec( ua ) || + /(webkit)[ \/]([\w.]+)/.exec( ua ) || + /(opera)(?:.*version|)[ \/]([\w.]+)/.exec( ua ) || + /(msie) ([\w.]+)/.exec( ua ) || + ua.indexOf("compatible") < 0 && /(mozilla)(?:.*? rv:([\w.]+)|)/.exec( ua ) || + []; + + return { + browser: match[ 1 ] || "", + version: match[ 2 ] || "0" + }; +}; + +matched = jQuery.uaMatch( navigator.userAgent ); +browser = {}; + +if ( matched.browser ) { + browser[ matched.browser ] = true; + browser.version = matched.version; +} + +// Chrome is Webkit, but Webkit is also Safari. +if ( browser.chrome ) { + browser.webkit = true; +} else if ( browser.webkit ) { + browser.safari = true; +} + +jQuery.browser = browser; + +jQuery.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; +}; + +})(); +var curCSS, iframe, iframeDoc, + ralpha = /alpha\([^)]*\)/i, + ropacity = /opacity=([^)]*)/, + rposition = /^(top|right|bottom|left)$/, + // swappable if display is none or starts with table except "table", "table-cell", or "table-caption" + // see here for display values: https://developer.mozilla.org/en-US/docs/CSS/display + rdisplayswap = /^(none|table(?!-c[ea]).+)/, + rmargin = /^margin/, + rnumsplit = new RegExp( "^(" + core_pnum + ")(.*)$", "i" ), + rnumnonpx = new RegExp( "^(" + core_pnum + ")(?!px)[a-z%]+$", "i" ), + rrelNum = new RegExp( "^([-+])=(" + core_pnum + ")", "i" ), + elemdisplay = {}, + + cssShow = { position: "absolute", visibility: "hidden", display: "block" }, + cssNormalTransform = { + letterSpacing: 0, + fontWeight: 400 + }, + + cssExpand = [ "Top", "Right", "Bottom", "Left" ], + cssPrefixes = [ "Webkit", "O", "Moz", "ms" ], + + eventsToggle = jQuery.fn.toggle; + +// return a css property mapped to a potentially vendor prefixed property +function vendorPropName( style, name ) { + + // shortcut for names that are not vendor prefixed + if ( name in style ) { + return name; + } + + // check for vendor prefixed names + var capName = name.charAt(0).toUpperCase() + name.slice(1), + origName = name, + i = cssPrefixes.length; + + while ( i-- ) { + name = cssPrefixes[ i ] + capName; + if ( name in style ) { + return name; + } + } + + return origName; +} + +function isHidden( elem, el ) { + elem = el || elem; + return jQuery.css( elem, "display" ) === "none" || !jQuery.contains( elem.ownerDocument, elem ); +} + +function showHide( elements, show ) { + var elem, display, + values = [], + index = 0, + length = elements.length; + + for ( ; index < length; index++ ) { + elem = elements[ index ]; + if ( !elem.style ) { + continue; + } + values[ index ] = jQuery._data( elem, "olddisplay" ); + if ( show ) { + // Reset the inline display of this element to learn if it is + // being hidden by cascaded rules or not + if ( !values[ index ] && elem.style.display === "none" ) { + elem.style.display = ""; + } + + // Set elements which have been overridden with display: none + // in a stylesheet to whatever the default browser style is + // for such an element + if ( elem.style.display === "" && isHidden( elem ) ) { + values[ index ] = jQuery._data( elem, "olddisplay", css_defaultDisplay(elem.nodeName) ); + } + } else { + display = curCSS( elem, "display" ); + + if ( !values[ index ] && display !== "none" ) { + jQuery._data( elem, "olddisplay", display ); + } + } + } + + // Set the display of most of the elements in a second loop + // to avoid the constant reflow + for ( index = 0; index < length; index++ ) { + elem = elements[ index ]; + if ( !elem.style ) { + continue; + } + if ( !show || elem.style.display === "none" || elem.style.display === "" ) { + elem.style.display = show ? values[ index ] || "" : "none"; + } + } + + return elements; +} + +jQuery.fn.extend({ + css: function( name, value ) { + return jQuery.access( this, function( elem, name, value ) { + return value !== undefined ? + jQuery.style( elem, name, value ) : + jQuery.css( elem, name ); + }, name, value, arguments.length > 1 ); + }, + show: function() { + return showHide( this, true ); + }, + hide: function() { + return showHide( this ); + }, + toggle: function( state, fn2 ) { + var bool = typeof state === "boolean"; + + if ( jQuery.isFunction( state ) && jQuery.isFunction( fn2 ) ) { + return eventsToggle.apply( this, arguments ); + } + + return this.each(function() { + if ( bool ? state : isHidden( this ) ) { + jQuery( this ).show(); + } else { + jQuery( this ).hide(); + } + }); + } +}); + +jQuery.extend({ + // Add in style property hooks for overriding the default + // behavior of getting and setting a style property + cssHooks: { + opacity: { + get: function( elem, computed ) { + if ( computed ) { + // We should always get a number back from opacity + var ret = curCSS( elem, "opacity" ); + return ret === "" ? "1" : ret; + + } + } + } + }, + + // Exclude the following css properties to add px + cssNumber: { + "fillOpacity": true, + "fontWeight": true, + "lineHeight": true, + "opacity": true, + "orphans": true, + "widows": true, + "zIndex": true, + "zoom": true + }, + + // Add in properties whose names you wish to fix before + // setting or getting the value + cssProps: { + // normalize float css property + "float": jQuery.support.cssFloat ? "cssFloat" : "styleFloat" + }, + + // Get and set the style property on a DOM Node + style: function( elem, name, value, extra ) { + // Don't set styles on text and comment nodes + if ( !elem || elem.nodeType === 3 || elem.nodeType === 8 || !elem.style ) { + return; + } + + // Make sure that we're working with the right name + var ret, type, hooks, + origName = jQuery.camelCase( name ), + style = elem.style; + + name = jQuery.cssProps[ origName ] || ( jQuery.cssProps[ origName ] = vendorPropName( style, origName ) ); + + // gets hook for the prefixed version + // followed by the unprefixed version + hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ]; + + // Check if we're setting a value + if ( value !== undefined ) { + type = typeof value; + + // convert relative number strings (+= or -=) to relative numbers. #7345 + if ( type === "string" && (ret = rrelNum.exec( value )) ) { + value = ( ret[1] + 1 ) * ret[2] + parseFloat( jQuery.css( elem, name ) ); + // Fixes bug #9237 + type = "number"; + } + + // Make sure that NaN and null values aren't set. See: #7116 + if ( value == null || type === "number" && isNaN( value ) ) { + return; + } + + // If a number was passed in, add 'px' to the (except for certain CSS properties) + if ( type === "number" && !jQuery.cssNumber[ origName ] ) { + value += "px"; + } + + // If a hook was provided, use that value, otherwise just set the specified value + if ( !hooks || !("set" in hooks) || (value = hooks.set( elem, value, extra )) !== undefined ) { + // Wrapped to prevent IE from throwing errors when 'invalid' values are provided + // Fixes bug #5509 + try { + style[ name ] = value; + } catch(e) {} + } + + } else { + // If a hook was provided get the non-computed value from there + if ( hooks && "get" in hooks && (ret = hooks.get( elem, false, extra )) !== undefined ) { + return ret; + } + + // Otherwise just get the value from the style object + return style[ name ]; + } + }, + + css: function( elem, name, numeric, extra ) { + var val, num, hooks, + origName = jQuery.camelCase( name ); + + // Make sure that we're working with the right name + name = jQuery.cssProps[ origName ] || ( jQuery.cssProps[ origName ] = vendorPropName( elem.style, origName ) ); + + // gets hook for the prefixed version + // followed by the unprefixed version + hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ]; + + // If a hook was provided get the computed value from there + if ( hooks && "get" in hooks ) { + val = hooks.get( elem, true, extra ); + } + + // Otherwise, if a way to get the computed value exists, use that + if ( val === undefined ) { + val = curCSS( elem, name ); + } + + //convert "normal" to computed value + if ( val === "normal" && name in cssNormalTransform ) { + val = cssNormalTransform[ name ]; + } + + // Return, converting to number if forced or a qualifier was provided and val looks numeric + if ( numeric || extra !== undefined ) { + num = parseFloat( val ); + return numeric || jQuery.isNumeric( num ) ? num || 0 : val; + } + return val; + }, + + // A method for quickly swapping in/out CSS properties to get correct calculations + swap: function( elem, options, callback ) { + var ret, name, + old = {}; + + // Remember the old values, and insert the new ones + for ( name in options ) { + old[ name ] = elem.style[ name ]; + elem.style[ name ] = options[ name ]; + } + + ret = callback.call( elem ); + + // Revert the old values + for ( name in options ) { + elem.style[ name ] = old[ name ]; + } + + return ret; + } +}); + +// NOTE: To any future maintainer, we've window.getComputedStyle +// because jsdom on node.js will break without it. +if ( window.getComputedStyle ) { + curCSS = function( elem, name ) { + var ret, width, minWidth, maxWidth, + computed = window.getComputedStyle( elem, null ), + style = elem.style; + + if ( computed ) { + + ret = computed[ name ]; + if ( ret === "" && !jQuery.contains( elem.ownerDocument, elem ) ) { + ret = jQuery.style( elem, name ); + } + + // A tribute to the "awesome hack by Dean Edwards" + // Chrome < 17 and Safari 5.0 uses "computed value" instead of "used value" for margin-right + // Safari 5.1.7 (at least) returns percentage for a larger set of values, but width seems to be reliably pixels + // this is against the CSSOM draft spec: http://dev.w3.org/csswg/cssom/#resolved-values + if ( rnumnonpx.test( ret ) && rmargin.test( name ) ) { + width = style.width; + minWidth = style.minWidth; + maxWidth = style.maxWidth; + + style.minWidth = style.maxWidth = style.width = ret; + ret = computed.width; + + style.width = width; + style.minWidth = minWidth; + style.maxWidth = maxWidth; + } + } + + return ret; + }; +} else if ( document.documentElement.currentStyle ) { + curCSS = function( elem, name ) { + var left, rsLeft, + ret = elem.currentStyle && elem.currentStyle[ name ], + style = elem.style; + + // Avoid setting ret to empty string here + // so we don't default to auto + if ( ret == null && style && style[ name ] ) { + ret = style[ name ]; + } + + // From the awesome hack by Dean Edwards + // http://erik.eae.net/archives/2007/07/27/18.54.15/#comment-102291 + + // If we're not dealing with a regular pixel number + // but a number that has a weird ending, we need to convert it to pixels + // but not position css attributes, as those are proportional to the parent element instead + // and we can't measure the parent instead because it might trigger a "stacking dolls" problem + if ( rnumnonpx.test( ret ) && !rposition.test( name ) ) { + + // Remember the original values + left = style.left; + rsLeft = elem.runtimeStyle && elem.runtimeStyle.left; + + // Put in the new values to get a computed value out + if ( rsLeft ) { + elem.runtimeStyle.left = elem.currentStyle.left; + } + style.left = name === "fontSize" ? "1em" : ret; + ret = style.pixelLeft + "px"; + + // Revert the changed values + style.left = left; + if ( rsLeft ) { + elem.runtimeStyle.left = rsLeft; + } + } + + return ret === "" ? "auto" : ret; + }; +} + +function setPositiveNumber( elem, value, subtract ) { + var matches = rnumsplit.exec( value ); + return matches ? + Math.max( 0, matches[ 1 ] - ( subtract || 0 ) ) + ( matches[ 2 ] || "px" ) : + value; +} + +function augmentWidthOrHeight( elem, name, extra, isBorderBox ) { + var i = extra === ( isBorderBox ? "border" : "content" ) ? + // If we already have the right measurement, avoid augmentation + 4 : + // Otherwise initialize for horizontal or vertical properties + name === "width" ? 1 : 0, + + val = 0; + + for ( ; i < 4; i += 2 ) { + // both box models exclude margin, so add it if we want it + if ( extra === "margin" ) { + // we use jQuery.css instead of curCSS here + // because of the reliableMarginRight CSS hook! + val += jQuery.css( elem, extra + cssExpand[ i ], true ); + } + + // From this point on we use curCSS for maximum performance (relevant in animations) + if ( isBorderBox ) { + // border-box includes padding, so remove it if we want content + if ( extra === "content" ) { + val -= parseFloat( curCSS( elem, "padding" + cssExpand[ i ] ) ) || 0; + } + + // at this point, extra isn't border nor margin, so remove border + if ( extra !== "margin" ) { + val -= parseFloat( curCSS( elem, "border" + cssExpand[ i ] + "Width" ) ) || 0; + } + } else { + // at this point, extra isn't content, so add padding + val += parseFloat( curCSS( elem, "padding" + cssExpand[ i ] ) ) || 0; + + // at this point, extra isn't content nor padding, so add border + if ( extra !== "padding" ) { + val += parseFloat( curCSS( elem, "border" + cssExpand[ i ] + "Width" ) ) || 0; + } + } + } + + return val; +} + +function getWidthOrHeight( elem, name, extra ) { + + // Start with offset property, which is equivalent to the border-box value + var val = name === "width" ? elem.offsetWidth : elem.offsetHeight, + valueIsBorderBox = true, + isBorderBox = jQuery.support.boxSizing && jQuery.css( elem, "boxSizing" ) === "border-box"; + + // some non-html elements return undefined for offsetWidth, so check for null/undefined + // svg - https://bugzilla.mozilla.org/show_bug.cgi?id=649285 + // MathML - https://bugzilla.mozilla.org/show_bug.cgi?id=491668 + if ( val <= 0 || val == null ) { + // Fall back to computed then uncomputed css if necessary + val = curCSS( elem, name ); + if ( val < 0 || val == null ) { + val = elem.style[ name ]; + } + + // Computed unit is not pixels. Stop here and return. + if ( rnumnonpx.test(val) ) { + return val; + } + + // we need the check for style in case a browser which returns unreliable values + // for getComputedStyle silently falls back to the reliable elem.style + valueIsBorderBox = isBorderBox && ( jQuery.support.boxSizingReliable || val === elem.style[ name ] ); + + // Normalize "", auto, and prepare for extra + val = parseFloat( val ) || 0; + } + + // use the active box-sizing model to add/subtract irrelevant styles + return ( val + + augmentWidthOrHeight( + elem, + name, + extra || ( isBorderBox ? "border" : "content" ), + valueIsBorderBox + ) + ) + "px"; +} + + +// Try to determine the default display value of an element +function css_defaultDisplay( nodeName ) { + if ( elemdisplay[ nodeName ] ) { + return elemdisplay[ nodeName ]; + } + + var elem = jQuery( "<" + nodeName + ">" ).appendTo( document.body ), + display = elem.css("display"); + elem.remove(); + + // If the simple way fails, + // get element's real default display by attaching it to a temp iframe + if ( display === "none" || display === "" ) { + // Use the already-created iframe if possible + iframe = document.body.appendChild( + iframe || jQuery.extend( document.createElement("iframe"), { + frameBorder: 0, + width: 0, + height: 0 + }) + ); + + // Create a cacheable copy of the iframe document on first call. + // IE and Opera will allow us to reuse the iframeDoc without re-writing the fake HTML + // document to it; WebKit & Firefox won't allow reusing the iframe document. + if ( !iframeDoc || !iframe.createElement ) { + iframeDoc = ( iframe.contentWindow || iframe.contentDocument ).document; + iframeDoc.write(""); + iframeDoc.close(); + } + + elem = iframeDoc.body.appendChild( iframeDoc.createElement(nodeName) ); + + display = curCSS( elem, "display" ); + document.body.removeChild( iframe ); + } + + // Store the correct default display + elemdisplay[ nodeName ] = display; + + return display; +} + +jQuery.each([ "height", "width" ], function( i, name ) { + jQuery.cssHooks[ name ] = { + get: function( elem, computed, extra ) { + if ( computed ) { + // certain elements can have dimension info if we invisibly show them + // however, it must have a current display style that would benefit from this + if ( elem.offsetWidth === 0 && rdisplayswap.test( curCSS( elem, "display" ) ) ) { + return jQuery.swap( elem, cssShow, function() { + return getWidthOrHeight( elem, name, extra ); + }); + } else { + return getWidthOrHeight( elem, name, extra ); + } + } + }, + + set: function( elem, value, extra ) { + return setPositiveNumber( elem, value, extra ? + augmentWidthOrHeight( + elem, + name, + extra, + jQuery.support.boxSizing && jQuery.css( elem, "boxSizing" ) === "border-box" + ) : 0 + ); + } + }; +}); + +if ( !jQuery.support.opacity ) { + jQuery.cssHooks.opacity = { + get: function( elem, computed ) { + // IE uses filters for opacity + return ropacity.test( (computed && elem.currentStyle ? elem.currentStyle.filter : elem.style.filter) || "" ) ? + ( 0.01 * parseFloat( RegExp.$1 ) ) + "" : + computed ? "1" : ""; + }, + + set: function( elem, value ) { + var style = elem.style, + currentStyle = elem.currentStyle, + opacity = jQuery.isNumeric( value ) ? "alpha(opacity=" + value * 100 + ")" : "", + filter = currentStyle && currentStyle.filter || style.filter || ""; + + // IE has trouble with opacity if it does not have layout + // Force it by setting the zoom level + style.zoom = 1; + + // if setting opacity to 1, and no other filters exist - attempt to remove filter attribute #6652 + if ( value >= 1 && jQuery.trim( filter.replace( ralpha, "" ) ) === "" && + style.removeAttribute ) { + + // Setting style.filter to null, "" & " " still leave "filter:" in the cssText + // if "filter:" is present at all, clearType is disabled, we want to avoid this + // style.removeAttribute is IE Only, but so apparently is this code path... + style.removeAttribute( "filter" ); + + // if there there is no filter style applied in a css rule, we are done + if ( currentStyle && !currentStyle.filter ) { + return; + } + } + + // otherwise, set new filter values + style.filter = ralpha.test( filter ) ? + filter.replace( ralpha, opacity ) : + filter + " " + opacity; + } + }; +} + +// These hooks cannot be added until DOM ready because the support test +// for it is not run until after DOM ready +jQuery(function() { + if ( !jQuery.support.reliableMarginRight ) { + jQuery.cssHooks.marginRight = { + get: function( elem, computed ) { + // WebKit Bug 13343 - getComputedStyle returns wrong value for margin-right + // Work around by temporarily setting element display to inline-block + return jQuery.swap( elem, { "display": "inline-block" }, function() { + if ( computed ) { + return curCSS( elem, "marginRight" ); + } + }); + } + }; + } + + // Webkit bug: https://bugs.webkit.org/show_bug.cgi?id=29084 + // getComputedStyle returns percent when specified for top/left/bottom/right + // rather than make the css module depend on the offset module, we just check for it here + if ( !jQuery.support.pixelPosition && jQuery.fn.position ) { + jQuery.each( [ "top", "left" ], function( i, prop ) { + jQuery.cssHooks[ prop ] = { + get: function( elem, computed ) { + if ( computed ) { + var ret = curCSS( elem, prop ); + // if curCSS returns percentage, fallback to offset + return rnumnonpx.test( ret ) ? jQuery( elem ).position()[ prop ] + "px" : ret; + } + } + }; + }); + } + +}); + +if ( jQuery.expr && jQuery.expr.filters ) { + jQuery.expr.filters.hidden = function( elem ) { + return ( elem.offsetWidth === 0 && elem.offsetHeight === 0 ) || (!jQuery.support.reliableHiddenOffsets && ((elem.style && elem.style.display) || curCSS( elem, "display" )) === "none"); + }; + + jQuery.expr.filters.visible = function( elem ) { + return !jQuery.expr.filters.hidden( elem ); + }; +} + +// These hooks are used by animate to expand properties +jQuery.each({ + margin: "", + padding: "", + border: "Width" +}, function( prefix, suffix ) { + jQuery.cssHooks[ prefix + suffix ] = { + expand: function( value ) { + var i, + + // assumes a single number if not a string + parts = typeof value === "string" ? value.split(" ") : [ value ], + expanded = {}; + + for ( i = 0; i < 4; i++ ) { + expanded[ prefix + cssExpand[ i ] + suffix ] = + parts[ i ] || parts[ i - 2 ] || parts[ 0 ]; + } + + return expanded; + } + }; + + if ( !rmargin.test( prefix ) ) { + jQuery.cssHooks[ prefix + suffix ].set = setPositiveNumber; + } +}); +var r20 = /%20/g, + rbracket = /\[\]$/, + rCRLF = /\r?\n/g, + rinput = /^(?:color|date|datetime|datetime-local|email|hidden|month|number|password|range|search|tel|text|time|url|week)$/i, + rselectTextarea = /^(?:select|textarea)/i; + +jQuery.fn.extend({ + serialize: function() { + return jQuery.param( this.serializeArray() ); + }, + serializeArray: function() { + return this.map(function(){ + return this.elements ? jQuery.makeArray( this.elements ) : this; + }) + .filter(function(){ + return this.name && !this.disabled && + ( this.checked || rselectTextarea.test( this.nodeName ) || + rinput.test( this.type ) ); + }) + .map(function( i, elem ){ + var val = jQuery( this ).val(); + + return val == null ? + null : + jQuery.isArray( val ) ? + jQuery.map( val, function( val, i ){ + return { name: elem.name, value: val.replace( rCRLF, "\r\n" ) }; + }) : + { name: elem.name, value: val.replace( rCRLF, "\r\n" ) }; + }).get(); + } +}); + +//Serialize an array of form elements or a set of +//key/values into a query string +jQuery.param = function( a, traditional ) { + var prefix, + s = [], + add = function( key, value ) { + // If value is a function, invoke it and return its value + value = jQuery.isFunction( value ) ? value() : ( value == null ? "" : value ); + s[ s.length ] = encodeURIComponent( key ) + "=" + encodeURIComponent( value ); + }; + + // Set traditional to true for jQuery <= 1.3.2 behavior. + if ( traditional === undefined ) { + traditional = jQuery.ajaxSettings && jQuery.ajaxSettings.traditional; + } + + // If an array was passed in, assume that it is an array of form elements. + if ( jQuery.isArray( a ) || ( a.jquery && !jQuery.isPlainObject( a ) ) ) { + // Serialize the form elements + jQuery.each( a, function() { + add( this.name, this.value ); + }); + + } else { + // If traditional, encode the "old" way (the way 1.3.2 or older + // did it), otherwise encode params recursively. + for ( prefix in a ) { + buildParams( prefix, a[ prefix ], traditional, add ); + } + } + + // Return the resulting serialization + return s.join( "&" ).replace( r20, "+" ); +}; + +function buildParams( prefix, obj, traditional, add ) { + var name; + + if ( jQuery.isArray( obj ) ) { + // Serialize array item. + jQuery.each( obj, function( i, v ) { + if ( traditional || rbracket.test( prefix ) ) { + // Treat each array item as a scalar. + add( prefix, v ); + + } else { + // If array item is non-scalar (array or object), encode its + // numeric index to resolve deserialization ambiguity issues. + // Note that rack (as of 1.0.0) can't currently deserialize + // nested arrays properly, and attempting to do so may cause + // a server error. Possible fixes are to modify rack's + // deserialization algorithm or to provide an option or flag + // to force array serialization to be shallow. + buildParams( prefix + "[" + ( typeof v === "object" ? i : "" ) + "]", v, traditional, add ); + } + }); + + } else if ( !traditional && jQuery.type( obj ) === "object" ) { + // Serialize object item. + for ( name in obj ) { + buildParams( prefix + "[" + name + "]", obj[ name ], traditional, add ); + } + + } else { + // Serialize scalar item. + add( prefix, obj ); + } +} +var + // Document location + ajaxLocParts, + ajaxLocation, + + rhash = /#.*$/, + rheaders = /^(.*?):[ \t]*([^\r\n]*)\r?$/mg, // IE leaves an \r character at EOL + // #7653, #8125, #8152: local protocol detection + rlocalProtocol = /^(?:about|app|app\-storage|.+\-extension|file|res|widget):$/, + rnoContent = /^(?:GET|HEAD)$/, + rprotocol = /^\/\//, + rquery = /\?/, + rscript = /)<[^<]*)*<\/script>/gi, + rts = /([?&])_=[^&]*/, + rurl = /^([\w\+\.\-]+:)(?:\/\/([^\/?#:]*)(?::(\d+)|)|)/, + + // Keep a copy of the old load method + _load = jQuery.fn.load, + + /* Prefilters + * 1) They are useful to introduce custom dataTypes (see ajax/jsonp.js for an example) + * 2) These are called: + * - BEFORE asking for a transport + * - AFTER param serialization (s.data is a string if s.processData is true) + * 3) key is the dataType + * 4) the catchall symbol "*" can be used + * 5) execution will start with transport dataType and THEN continue down to "*" if needed + */ + prefilters = {}, + + /* Transports bindings + * 1) key is the dataType + * 2) the catchall symbol "*" can be used + * 3) selection will start with transport dataType and THEN go to "*" if needed + */ + transports = {}, + + // Avoid comment-prolog char sequence (#10098); must appease lint and evade compression + allTypes = ["*/"] + ["*"]; + +// #8138, IE may throw an exception when accessing +// a field from window.location if document.domain has been set +try { + ajaxLocation = location.href; +} catch( e ) { + // Use the href attribute of an A element + // since IE will modify it given document.location + ajaxLocation = document.createElement( "a" ); + ajaxLocation.href = ""; + ajaxLocation = ajaxLocation.href; +} + +// Segment location into parts +ajaxLocParts = rurl.exec( ajaxLocation.toLowerCase() ) || []; + +// Base "constructor" for jQuery.ajaxPrefilter and jQuery.ajaxTransport +function addToPrefiltersOrTransports( structure ) { + + // dataTypeExpression is optional and defaults to "*" + return function( dataTypeExpression, func ) { + + if ( typeof dataTypeExpression !== "string" ) { + func = dataTypeExpression; + dataTypeExpression = "*"; + } + + var dataType, list, placeBefore, + dataTypes = dataTypeExpression.toLowerCase().split( core_rspace ), + i = 0, + length = dataTypes.length; + + if ( jQuery.isFunction( func ) ) { + // For each dataType in the dataTypeExpression + for ( ; i < length; i++ ) { + dataType = dataTypes[ i ]; + // We control if we're asked to add before + // any existing element + placeBefore = /^\+/.test( dataType ); + if ( placeBefore ) { + dataType = dataType.substr( 1 ) || "*"; + } + list = structure[ dataType ] = structure[ dataType ] || []; + // then we add to the structure accordingly + list[ placeBefore ? "unshift" : "push" ]( func ); + } + } + }; +} + +// Base inspection function for prefilters and transports +function inspectPrefiltersOrTransports( structure, options, originalOptions, jqXHR, + dataType /* internal */, inspected /* internal */ ) { + + dataType = dataType || options.dataTypes[ 0 ]; + inspected = inspected || {}; + + inspected[ dataType ] = true; + + var selection, + list = structure[ dataType ], + i = 0, + length = list ? list.length : 0, + executeOnly = ( structure === prefilters ); + + for ( ; i < length && ( executeOnly || !selection ); i++ ) { + selection = list[ i ]( options, originalOptions, jqXHR ); + // If we got redirected to another dataType + // we try there if executing only and not done already + if ( typeof selection === "string" ) { + if ( !executeOnly || inspected[ selection ] ) { + selection = undefined; + } else { + options.dataTypes.unshift( selection ); + selection = inspectPrefiltersOrTransports( + structure, options, originalOptions, jqXHR, selection, inspected ); + } + } + } + // If we're only executing or nothing was selected + // we try the catchall dataType if not done already + if ( ( executeOnly || !selection ) && !inspected[ "*" ] ) { + selection = inspectPrefiltersOrTransports( + structure, options, originalOptions, jqXHR, "*", inspected ); + } + // unnecessary when only executing (prefilters) + // but it'll be ignored by the caller in that case + return selection; +} + +// A special extend for ajax options +// that takes "flat" options (not to be deep extended) +// Fixes #9887 +function ajaxExtend( target, src ) { + var key, deep, + flatOptions = jQuery.ajaxSettings.flatOptions || {}; + for ( key in src ) { + if ( src[ key ] !== undefined ) { + ( flatOptions[ key ] ? target : ( deep || ( deep = {} ) ) )[ key ] = src[ key ]; + } + } + if ( deep ) { + jQuery.extend( true, target, deep ); + } +} + +jQuery.fn.load = function( url, params, callback ) { + if ( typeof url !== "string" && _load ) { + return _load.apply( this, arguments ); + } + + // Don't do a request if no elements are being requested + if ( !this.length ) { + return this; + } + + var selector, type, response, + self = this, + off = url.indexOf(" "); + + if ( off >= 0 ) { + selector = url.slice( off, url.length ); + url = url.slice( 0, off ); + } + + // If it's a function + if ( jQuery.isFunction( params ) ) { + + // We assume that it's the callback + callback = params; + params = undefined; + + // Otherwise, build a param string + } else if ( params && typeof params === "object" ) { + type = "POST"; + } + + // Request the remote document + jQuery.ajax({ + url: url, + + // if "type" variable is undefined, then "GET" method will be used + type: type, + dataType: "html", + data: params, + complete: function( jqXHR, status ) { + if ( callback ) { + self.each( callback, response || [ jqXHR.responseText, status, jqXHR ] ); + } + } + }).done(function( responseText ) { + + // Save response for use in complete callback + response = arguments; + + // See if a selector was specified + self.html( selector ? + + // Create a dummy div to hold the results + jQuery("
      ") + + // inject the contents of the document in, removing the scripts + // to avoid any 'Permission Denied' errors in IE + .append( responseText.replace( rscript, "" ) ) + + // Locate the specified elements + .find( selector ) : + + // If not, just inject the full result + responseText ); + + }); + + return this; +}; + +// Attach a bunch of functions for handling common AJAX events +jQuery.each( "ajaxStart ajaxStop ajaxComplete ajaxError ajaxSuccess ajaxSend".split( " " ), function( i, o ){ + jQuery.fn[ o ] = function( f ){ + return this.on( o, f ); + }; +}); + +jQuery.each( [ "get", "post" ], function( i, method ) { + jQuery[ method ] = function( url, data, callback, type ) { + // shift arguments if data argument was omitted + if ( jQuery.isFunction( data ) ) { + type = type || callback; + callback = data; + data = undefined; + } + + return jQuery.ajax({ + type: method, + url: url, + data: data, + success: callback, + dataType: type + }); + }; +}); + +jQuery.extend({ + + getScript: function( url, callback ) { + return jQuery.get( url, undefined, callback, "script" ); + }, + + getJSON: function( url, data, callback ) { + return jQuery.get( url, data, callback, "json" ); + }, + + // Creates a full fledged settings object into target + // with both ajaxSettings and settings fields. + // If target is omitted, writes into ajaxSettings. + ajaxSetup: function( target, settings ) { + if ( settings ) { + // Building a settings object + ajaxExtend( target, jQuery.ajaxSettings ); + } else { + // Extending ajaxSettings + settings = target; + target = jQuery.ajaxSettings; + } + ajaxExtend( target, settings ); + return target; + }, + + ajaxSettings: { + url: ajaxLocation, + isLocal: rlocalProtocol.test( ajaxLocParts[ 1 ] ), + global: true, + type: "GET", + contentType: "application/x-www-form-urlencoded; charset=UTF-8", + processData: true, + async: true, + /* + timeout: 0, + data: null, + dataType: null, + username: null, + password: null, + cache: null, + throws: false, + traditional: false, + headers: {}, + */ + + accepts: { + xml: "application/xml, text/xml", + html: "text/html", + text: "text/plain", + json: "application/json, text/javascript", + "*": allTypes + }, + + contents: { + xml: /xml/, + html: /html/, + json: /json/ + }, + + responseFields: { + xml: "responseXML", + text: "responseText" + }, + + // List of data converters + // 1) key format is "source_type destination_type" (a single space in-between) + // 2) the catchall symbol "*" can be used for source_type + converters: { + + // Convert anything to text + "* text": window.String, + + // Text to html (true = no transformation) + "text html": true, + + // Evaluate text as a json expression + "text json": jQuery.parseJSON, + + // Parse text as xml + "text xml": jQuery.parseXML + }, + + // For options that shouldn't be deep extended: + // you can add your own custom options here if + // and when you create one that shouldn't be + // deep extended (see ajaxExtend) + flatOptions: { + context: true, + url: true + } + }, + + ajaxPrefilter: addToPrefiltersOrTransports( prefilters ), + ajaxTransport: addToPrefiltersOrTransports( transports ), + + // Main method + ajax: function( url, options ) { + + // If url is an object, simulate pre-1.5 signature + if ( typeof url === "object" ) { + options = url; + url = undefined; + } + + // Force options to be an object + options = options || {}; + + var // ifModified key + ifModifiedKey, + // Response headers + responseHeadersString, + responseHeaders, + // transport + transport, + // timeout handle + timeoutTimer, + // Cross-domain detection vars + parts, + // To know if global events are to be dispatched + fireGlobals, + // Loop variable + i, + // Create the final options object + s = jQuery.ajaxSetup( {}, options ), + // Callbacks context + callbackContext = s.context || s, + // Context for global events + // It's the callbackContext if one was provided in the options + // and if it's a DOM node or a jQuery collection + globalEventContext = callbackContext !== s && + ( callbackContext.nodeType || callbackContext instanceof jQuery ) ? + jQuery( callbackContext ) : jQuery.event, + // Deferreds + deferred = jQuery.Deferred(), + completeDeferred = jQuery.Callbacks( "once memory" ), + // Status-dependent callbacks + statusCode = s.statusCode || {}, + // Headers (they are sent all at once) + requestHeaders = {}, + requestHeadersNames = {}, + // The jqXHR state + state = 0, + // Default abort message + strAbort = "canceled", + // Fake xhr + jqXHR = { + + readyState: 0, + + // Caches the header + setRequestHeader: function( name, value ) { + if ( !state ) { + var lname = name.toLowerCase(); + name = requestHeadersNames[ lname ] = requestHeadersNames[ lname ] || name; + requestHeaders[ name ] = value; + } + return this; + }, + + // Raw string + getAllResponseHeaders: function() { + return state === 2 ? responseHeadersString : null; + }, + + // Builds headers hashtable if needed + getResponseHeader: function( key ) { + var match; + if ( state === 2 ) { + if ( !responseHeaders ) { + responseHeaders = {}; + while( ( match = rheaders.exec( responseHeadersString ) ) ) { + responseHeaders[ match[1].toLowerCase() ] = match[ 2 ]; + } + } + match = responseHeaders[ key.toLowerCase() ]; + } + return match === undefined ? null : match; + }, + + // Overrides response content-type header + overrideMimeType: function( type ) { + if ( !state ) { + s.mimeType = type; + } + return this; + }, + + // Cancel the request + abort: function( statusText ) { + statusText = statusText || strAbort; + if ( transport ) { + transport.abort( statusText ); + } + done( 0, statusText ); + return this; + } + }; + + // Callback for when everything is done + // It is defined here because jslint complains if it is declared + // at the end of the function (which would be more logical and readable) + function done( status, nativeStatusText, responses, headers ) { + var isSuccess, success, error, response, modified, + statusText = nativeStatusText; + + // Called once + if ( state === 2 ) { + return; + } + + // State is "done" now + state = 2; + + // Clear timeout if it exists + if ( timeoutTimer ) { + clearTimeout( timeoutTimer ); + } + + // Dereference transport for early garbage collection + // (no matter how long the jqXHR object will be used) + transport = undefined; + + // Cache response headers + responseHeadersString = headers || ""; + + // Set readyState + jqXHR.readyState = status > 0 ? 4 : 0; + + // Get response data + if ( responses ) { + response = ajaxHandleResponses( s, jqXHR, responses ); + } + + // If successful, handle type chaining + if ( status >= 200 && status < 300 || status === 304 ) { + + // Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode. + if ( s.ifModified ) { + + modified = jqXHR.getResponseHeader("Last-Modified"); + if ( modified ) { + jQuery.lastModified[ ifModifiedKey ] = modified; + } + modified = jqXHR.getResponseHeader("Etag"); + if ( modified ) { + jQuery.etag[ ifModifiedKey ] = modified; + } + } + + // If not modified + if ( status === 304 ) { + + statusText = "notmodified"; + isSuccess = true; + + // If we have data + } else { + + isSuccess = ajaxConvert( s, response ); + statusText = isSuccess.state; + success = isSuccess.data; + error = isSuccess.error; + isSuccess = !error; + } + } else { + // We extract error from statusText + // then normalize statusText and status for non-aborts + error = statusText; + if ( !statusText || status ) { + statusText = "error"; + if ( status < 0 ) { + status = 0; + } + } + } + + // Set data for the fake xhr object + jqXHR.status = status; + jqXHR.statusText = ( nativeStatusText || statusText ) + ""; + + // Success/Error + if ( isSuccess ) { + deferred.resolveWith( callbackContext, [ success, statusText, jqXHR ] ); + } else { + deferred.rejectWith( callbackContext, [ jqXHR, statusText, error ] ); + } + + // Status-dependent callbacks + jqXHR.statusCode( statusCode ); + statusCode = undefined; + + if ( fireGlobals ) { + globalEventContext.trigger( "ajax" + ( isSuccess ? "Success" : "Error" ), + [ jqXHR, s, isSuccess ? success : error ] ); + } + + // Complete + completeDeferred.fireWith( callbackContext, [ jqXHR, statusText ] ); + + if ( fireGlobals ) { + globalEventContext.trigger( "ajaxComplete", [ jqXHR, s ] ); + // Handle the global AJAX counter + if ( !( --jQuery.active ) ) { + jQuery.event.trigger( "ajaxStop" ); + } + } + } + + // Attach deferreds + deferred.promise( jqXHR ); + jqXHR.success = jqXHR.done; + jqXHR.error = jqXHR.fail; + jqXHR.complete = completeDeferred.add; + + // Status-dependent callbacks + jqXHR.statusCode = function( map ) { + if ( map ) { + var tmp; + if ( state < 2 ) { + for ( tmp in map ) { + statusCode[ tmp ] = [ statusCode[tmp], map[tmp] ]; + } + } else { + tmp = map[ jqXHR.status ]; + jqXHR.always( tmp ); + } + } + return this; + }; + + // Remove hash character (#7531: and string promotion) + // Add protocol if not provided (#5866: IE7 issue with protocol-less urls) + // We also use the url parameter if available + s.url = ( ( url || s.url ) + "" ).replace( rhash, "" ).replace( rprotocol, ajaxLocParts[ 1 ] + "//" ); + + // Extract dataTypes list + s.dataTypes = jQuery.trim( s.dataType || "*" ).toLowerCase().split( core_rspace ); + + // A cross-domain request is in order when we have a protocol:host:port mismatch + if ( s.crossDomain == null ) { + parts = rurl.exec( s.url.toLowerCase() ) || false; + s.crossDomain = parts && ( parts.join(":") + ( parts[ 3 ] ? "" : parts[ 1 ] === "http:" ? 80 : 443 ) ) !== + ( ajaxLocParts.join(":") + ( ajaxLocParts[ 3 ] ? "" : ajaxLocParts[ 1 ] === "http:" ? 80 : 443 ) ); + } + + // Convert data if not already a string + if ( s.data && s.processData && typeof s.data !== "string" ) { + s.data = jQuery.param( s.data, s.traditional ); + } + + // Apply prefilters + inspectPrefiltersOrTransports( prefilters, s, options, jqXHR ); + + // If request was aborted inside a prefilter, stop there + if ( state === 2 ) { + return jqXHR; + } + + // We can fire global events as of now if asked to + fireGlobals = s.global; + + // Uppercase the type + s.type = s.type.toUpperCase(); + + // Determine if request has content + s.hasContent = !rnoContent.test( s.type ); + + // Watch for a new set of requests + if ( fireGlobals && jQuery.active++ === 0 ) { + jQuery.event.trigger( "ajaxStart" ); + } + + // More options handling for requests with no content + if ( !s.hasContent ) { + + // If data is available, append data to url + if ( s.data ) { + s.url += ( rquery.test( s.url ) ? "&" : "?" ) + s.data; + // #9682: remove data so that it's not used in an eventual retry + delete s.data; + } + + // Get ifModifiedKey before adding the anti-cache parameter + ifModifiedKey = s.url; + + // Add anti-cache in url if needed + if ( s.cache === false ) { + + var ts = jQuery.now(), + // try replacing _= if it is there + ret = s.url.replace( rts, "$1_=" + ts ); + + // if nothing was replaced, add timestamp to the end + s.url = ret + ( ( ret === s.url ) ? ( rquery.test( s.url ) ? "&" : "?" ) + "_=" + ts : "" ); + } + } + + // Set the correct header, if data is being sent + if ( s.data && s.hasContent && s.contentType !== false || options.contentType ) { + jqXHR.setRequestHeader( "Content-Type", s.contentType ); + } + + // Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode. + if ( s.ifModified ) { + ifModifiedKey = ifModifiedKey || s.url; + if ( jQuery.lastModified[ ifModifiedKey ] ) { + jqXHR.setRequestHeader( "If-Modified-Since", jQuery.lastModified[ ifModifiedKey ] ); + } + if ( jQuery.etag[ ifModifiedKey ] ) { + jqXHR.setRequestHeader( "If-None-Match", jQuery.etag[ ifModifiedKey ] ); + } + } + + // Set the Accepts header for the server, depending on the dataType + jqXHR.setRequestHeader( + "Accept", + s.dataTypes[ 0 ] && s.accepts[ s.dataTypes[0] ] ? + s.accepts[ s.dataTypes[0] ] + ( s.dataTypes[ 0 ] !== "*" ? ", " + allTypes + "; q=0.01" : "" ) : + s.accepts[ "*" ] + ); + + // Check for headers option + for ( i in s.headers ) { + jqXHR.setRequestHeader( i, s.headers[ i ] ); + } + + // Allow custom headers/mimetypes and early abort + if ( s.beforeSend && ( s.beforeSend.call( callbackContext, jqXHR, s ) === false || state === 2 ) ) { + // Abort if not done already and return + return jqXHR.abort(); + + } + + // aborting is no longer a cancellation + strAbort = "abort"; + + // Install callbacks on deferreds + for ( i in { success: 1, error: 1, complete: 1 } ) { + jqXHR[ i ]( s[ i ] ); + } + + // Get transport + transport = inspectPrefiltersOrTransports( transports, s, options, jqXHR ); + + // If no transport, we auto-abort + if ( !transport ) { + done( -1, "No Transport" ); + } else { + jqXHR.readyState = 1; + // Send global event + if ( fireGlobals ) { + globalEventContext.trigger( "ajaxSend", [ jqXHR, s ] ); + } + // Timeout + if ( s.async && s.timeout > 0 ) { + timeoutTimer = setTimeout( function(){ + jqXHR.abort( "timeout" ); + }, s.timeout ); + } + + try { + state = 1; + transport.send( requestHeaders, done ); + } catch (e) { + // Propagate exception as error if not done + if ( state < 2 ) { + done( -1, e ); + // Simply rethrow otherwise + } else { + throw e; + } + } + } + + return jqXHR; + }, + + // Counter for holding the number of active queries + active: 0, + + // Last-Modified header cache for next request + lastModified: {}, + etag: {} + +}); + +/* Handles responses to an ajax request: + * - sets all responseXXX fields accordingly + * - finds the right dataType (mediates between content-type and expected dataType) + * - returns the corresponding response + */ +function ajaxHandleResponses( s, jqXHR, responses ) { + + var ct, type, finalDataType, firstDataType, + contents = s.contents, + dataTypes = s.dataTypes, + responseFields = s.responseFields; + + // Fill responseXXX fields + for ( type in responseFields ) { + if ( type in responses ) { + jqXHR[ responseFields[type] ] = responses[ type ]; + } + } + + // Remove auto dataType and get content-type in the process + while( dataTypes[ 0 ] === "*" ) { + dataTypes.shift(); + if ( ct === undefined ) { + ct = s.mimeType || jqXHR.getResponseHeader( "content-type" ); + } + } + + // Check if we're dealing with a known content-type + if ( ct ) { + for ( type in contents ) { + if ( contents[ type ] && contents[ type ].test( ct ) ) { + dataTypes.unshift( type ); + break; + } + } + } + + // Check to see if we have a response for the expected dataType + if ( dataTypes[ 0 ] in responses ) { + finalDataType = dataTypes[ 0 ]; + } else { + // Try convertible dataTypes + for ( type in responses ) { + if ( !dataTypes[ 0 ] || s.converters[ type + " " + dataTypes[0] ] ) { + finalDataType = type; + break; + } + if ( !firstDataType ) { + firstDataType = type; + } + } + // Or just use first one + finalDataType = finalDataType || firstDataType; + } + + // If we found a dataType + // We add the dataType to the list if needed + // and return the corresponding response + if ( finalDataType ) { + if ( finalDataType !== dataTypes[ 0 ] ) { + dataTypes.unshift( finalDataType ); + } + return responses[ finalDataType ]; + } +} + +// Chain conversions given the request and the original response +function ajaxConvert( s, response ) { + + var conv, conv2, current, tmp, + // Work with a copy of dataTypes in case we need to modify it for conversion + dataTypes = s.dataTypes.slice(), + prev = dataTypes[ 0 ], + converters = {}, + i = 0; + + // Apply the dataFilter if provided + if ( s.dataFilter ) { + response = s.dataFilter( response, s.dataType ); + } + + // Create converters map with lowercased keys + if ( dataTypes[ 1 ] ) { + for ( conv in s.converters ) { + converters[ conv.toLowerCase() ] = s.converters[ conv ]; + } + } + + // Convert to each sequential dataType, tolerating list modification + for ( ; (current = dataTypes[++i]); ) { + + // There's only work to do if current dataType is non-auto + if ( current !== "*" ) { + + // Convert response if prev dataType is non-auto and differs from current + if ( prev !== "*" && prev !== current ) { + + // Seek a direct converter + conv = converters[ prev + " " + current ] || converters[ "* " + current ]; + + // If none found, seek a pair + if ( !conv ) { + for ( conv2 in converters ) { + + // If conv2 outputs current + tmp = conv2.split(" "); + if ( tmp[ 1 ] === current ) { + + // If prev can be converted to accepted input + conv = converters[ prev + " " + tmp[ 0 ] ] || + converters[ "* " + tmp[ 0 ] ]; + if ( conv ) { + // Condense equivalence converters + if ( conv === true ) { + conv = converters[ conv2 ]; + + // Otherwise, insert the intermediate dataType + } else if ( converters[ conv2 ] !== true ) { + current = tmp[ 0 ]; + dataTypes.splice( i--, 0, current ); + } + + break; + } + } + } + } + + // Apply converter (if not an equivalence) + if ( conv !== true ) { + + // Unless errors are allowed to bubble, catch and return them + if ( conv && s["throws"] ) { + response = conv( response ); + } else { + try { + response = conv( response ); + } catch ( e ) { + return { state: "parsererror", error: conv ? e : "No conversion from " + prev + " to " + current }; + } + } + } + } + + // Update prev for next iteration + prev = current; + } + } + + return { state: "success", data: response }; +} +var oldCallbacks = [], + rquestion = /\?/, + rjsonp = /(=)\?(?=&|$)|\?\?/, + nonce = jQuery.now(); + +// Default jsonp settings +jQuery.ajaxSetup({ + jsonp: "callback", + jsonpCallback: function() { + var callback = oldCallbacks.pop() || ( jQuery.expando + "_" + ( nonce++ ) ); + this[ callback ] = true; + return callback; + } +}); + +// Detect, normalize options and install callbacks for jsonp requests +jQuery.ajaxPrefilter( "json jsonp", function( s, originalSettings, jqXHR ) { + + var callbackName, overwritten, responseContainer, + data = s.data, + url = s.url, + hasCallback = s.jsonp !== false, + replaceInUrl = hasCallback && rjsonp.test( url ), + replaceInData = hasCallback && !replaceInUrl && typeof data === "string" && + !( s.contentType || "" ).indexOf("application/x-www-form-urlencoded") && + rjsonp.test( data ); + + // Handle iff the expected data type is "jsonp" or we have a parameter to set + if ( s.dataTypes[ 0 ] === "jsonp" || replaceInUrl || replaceInData ) { + + // Get callback name, remembering preexisting value associated with it + callbackName = s.jsonpCallback = jQuery.isFunction( s.jsonpCallback ) ? + s.jsonpCallback() : + s.jsonpCallback; + overwritten = window[ callbackName ]; + + // Insert callback into url or form data + if ( replaceInUrl ) { + s.url = url.replace( rjsonp, "$1" + callbackName ); + } else if ( replaceInData ) { + s.data = data.replace( rjsonp, "$1" + callbackName ); + } else if ( hasCallback ) { + s.url += ( rquestion.test( url ) ? "&" : "?" ) + s.jsonp + "=" + callbackName; + } + + // Use data converter to retrieve json after script execution + s.converters["script json"] = function() { + if ( !responseContainer ) { + jQuery.error( callbackName + " was not called" ); + } + return responseContainer[ 0 ]; + }; + + // force json dataType + s.dataTypes[ 0 ] = "json"; + + // Install callback + window[ callbackName ] = function() { + responseContainer = arguments; + }; + + // Clean-up function (fires after converters) + jqXHR.always(function() { + // Restore preexisting value + window[ callbackName ] = overwritten; + + // Save back as free + if ( s[ callbackName ] ) { + // make sure that re-using the options doesn't screw things around + s.jsonpCallback = originalSettings.jsonpCallback; + + // save the callback name for future use + oldCallbacks.push( callbackName ); + } + + // Call if it was a function and we have a response + if ( responseContainer && jQuery.isFunction( overwritten ) ) { + overwritten( responseContainer[ 0 ] ); + } + + responseContainer = overwritten = undefined; + }); + + // Delegate to script + return "script"; + } +}); +// Install script dataType +jQuery.ajaxSetup({ + accepts: { + script: "text/javascript, application/javascript, application/ecmascript, application/x-ecmascript" + }, + contents: { + script: /javascript|ecmascript/ + }, + converters: { + "text script": function( text ) { + jQuery.globalEval( text ); + return text; + } + } +}); + +// Handle cache's special case and global +jQuery.ajaxPrefilter( "script", function( s ) { + if ( s.cache === undefined ) { + s.cache = false; + } + if ( s.crossDomain ) { + s.type = "GET"; + s.global = false; + } +}); + +// Bind script tag hack transport +jQuery.ajaxTransport( "script", function(s) { + + // This transport only deals with cross domain requests + if ( s.crossDomain ) { + + var script, + head = document.head || document.getElementsByTagName( "head" )[0] || document.documentElement; + + return { + + send: function( _, callback ) { + + script = document.createElement( "script" ); + + script.async = "async"; + + if ( s.scriptCharset ) { + script.charset = s.scriptCharset; + } + + script.src = s.url; + + // Attach handlers for all browsers + script.onload = script.onreadystatechange = function( _, isAbort ) { + + if ( isAbort || !script.readyState || /loaded|complete/.test( script.readyState ) ) { + + // Handle memory leak in IE + script.onload = script.onreadystatechange = null; + + // Remove the script + if ( head && script.parentNode ) { + head.removeChild( script ); + } + + // Dereference the script + script = undefined; + + // Callback if not abort + if ( !isAbort ) { + callback( 200, "success" ); + } + } + }; + // Use insertBefore instead of appendChild to circumvent an IE6 bug. + // This arises when a base node is used (#2709 and #4378). + head.insertBefore( script, head.firstChild ); + }, + + abort: function() { + if ( script ) { + script.onload( 0, 1 ); + } + } + }; + } +}); +var xhrCallbacks, + // #5280: Internet Explorer will keep connections alive if we don't abort on unload + xhrOnUnloadAbort = window.ActiveXObject ? function() { + // Abort all pending requests + for ( var key in xhrCallbacks ) { + xhrCallbacks[ key ]( 0, 1 ); + } + } : false, + xhrId = 0; + +// Functions to create xhrs +function createStandardXHR() { + try { + return new window.XMLHttpRequest(); + } catch( e ) {} +} + +function createActiveXHR() { + try { + return new window.ActiveXObject( "Microsoft.XMLHTTP" ); + } catch( e ) {} +} + +// Create the request object +// (This is still attached to ajaxSettings for backward compatibility) +jQuery.ajaxSettings.xhr = window.ActiveXObject ? + /* Microsoft failed to properly + * implement the XMLHttpRequest in IE7 (can't request local files), + * so we use the ActiveXObject when it is available + * Additionally XMLHttpRequest can be disabled in IE7/IE8 so + * we need a fallback. + */ + function() { + return !this.isLocal && createStandardXHR() || createActiveXHR(); + } : + // For all other browsers, use the standard XMLHttpRequest object + createStandardXHR; + +// Determine support properties +(function( xhr ) { + jQuery.extend( jQuery.support, { + ajax: !!xhr, + cors: !!xhr && ( "withCredentials" in xhr ) + }); +})( jQuery.ajaxSettings.xhr() ); + +// Create transport if the browser can provide an xhr +if ( jQuery.support.ajax ) { + + jQuery.ajaxTransport(function( s ) { + // Cross domain only allowed if supported through XMLHttpRequest + if ( !s.crossDomain || jQuery.support.cors ) { + + var callback; + + return { + send: function( headers, complete ) { + + // Get a new xhr + var handle, i, + xhr = s.xhr(); + + // Open the socket + // Passing null username, generates a login popup on Opera (#2865) + if ( s.username ) { + xhr.open( s.type, s.url, s.async, s.username, s.password ); + } else { + xhr.open( s.type, s.url, s.async ); + } + + // Apply custom fields if provided + if ( s.xhrFields ) { + for ( i in s.xhrFields ) { + xhr[ i ] = s.xhrFields[ i ]; + } + } + + // Override mime type if needed + if ( s.mimeType && xhr.overrideMimeType ) { + xhr.overrideMimeType( s.mimeType ); + } + + // X-Requested-With header + // For cross-domain requests, seeing as conditions for a preflight are + // akin to a jigsaw puzzle, we simply never set it to be sure. + // (it can always be set on a per-request basis or even using ajaxSetup) + // For same-domain requests, won't change header if already provided. + if ( !s.crossDomain && !headers["X-Requested-With"] ) { + headers[ "X-Requested-With" ] = "XMLHttpRequest"; + } + + // Need an extra try/catch for cross domain requests in Firefox 3 + try { + for ( i in headers ) { + xhr.setRequestHeader( i, headers[ i ] ); + } + } catch( _ ) {} + + // Do send the request + // This may raise an exception which is actually + // handled in jQuery.ajax (so no try/catch here) + xhr.send( ( s.hasContent && s.data ) || null ); + + // Listener + callback = function( _, isAbort ) { + + var status, + statusText, + responseHeaders, + responses, + xml; + + // Firefox throws exceptions when accessing properties + // of an xhr when a network error occurred + // http://helpful.knobs-dials.com/index.php/Component_returned_failure_code:_0x80040111_(NS_ERROR_NOT_AVAILABLE) + try { + + // Was never called and is aborted or complete + if ( callback && ( isAbort || xhr.readyState === 4 ) ) { + + // Only called once + callback = undefined; + + // Do not keep as active anymore + if ( handle ) { + xhr.onreadystatechange = jQuery.noop; + if ( xhrOnUnloadAbort ) { + delete xhrCallbacks[ handle ]; + } + } + + // If it's an abort + if ( isAbort ) { + // Abort it manually if needed + if ( xhr.readyState !== 4 ) { + xhr.abort(); + } + } else { + status = xhr.status; + responseHeaders = xhr.getAllResponseHeaders(); + responses = {}; + xml = xhr.responseXML; + + // Construct response list + if ( xml && xml.documentElement /* #4958 */ ) { + responses.xml = xml; + } + + // When requesting binary data, IE6-9 will throw an exception + // on any attempt to access responseText (#11426) + try { + responses.text = xhr.responseText; + } catch( _ ) { + } + + // Firefox throws an exception when accessing + // statusText for faulty cross-domain requests + try { + statusText = xhr.statusText; + } catch( e ) { + // We normalize with Webkit giving an empty statusText + statusText = ""; + } + + // Filter status for non standard behaviors + + // If the request is local and we have data: assume a success + // (success with no data won't get notified, that's the best we + // can do given current implementations) + if ( !status && s.isLocal && !s.crossDomain ) { + status = responses.text ? 200 : 404; + // IE - #1450: sometimes returns 1223 when it should be 204 + } else if ( status === 1223 ) { + status = 204; + } + } + } + } catch( firefoxAccessException ) { + if ( !isAbort ) { + complete( -1, firefoxAccessException ); + } + } + + // Call complete if needed + if ( responses ) { + complete( status, statusText, responses, responseHeaders ); + } + }; + + if ( !s.async ) { + // if we're in sync mode we fire the callback + callback(); + } else if ( xhr.readyState === 4 ) { + // (IE6 & IE7) if it's in cache and has been + // retrieved directly we need to fire the callback + setTimeout( callback, 0 ); + } else { + handle = ++xhrId; + if ( xhrOnUnloadAbort ) { + // Create the active xhrs callbacks list if needed + // and attach the unload handler + if ( !xhrCallbacks ) { + xhrCallbacks = {}; + jQuery( window ).unload( xhrOnUnloadAbort ); + } + // Add to list of active xhrs callbacks + xhrCallbacks[ handle ] = callback; + } + xhr.onreadystatechange = callback; + } + }, + + abort: function() { + if ( callback ) { + callback(0,1); + } + } + }; + } + }); +} +var fxNow, timerId, + rfxtypes = /^(?:toggle|show|hide)$/, + rfxnum = new RegExp( "^(?:([-+])=|)(" + core_pnum + ")([a-z%]*)$", "i" ), + rrun = /queueHooks$/, + animationPrefilters = [ defaultPrefilter ], + tweeners = { + "*": [function( prop, value ) { + var end, unit, + tween = this.createTween( prop, value ), + parts = rfxnum.exec( value ), + target = tween.cur(), + start = +target || 0, + scale = 1, + maxIterations = 20; + + if ( parts ) { + end = +parts[2]; + unit = parts[3] || ( jQuery.cssNumber[ prop ] ? "" : "px" ); + + // We need to compute starting value + if ( unit !== "px" && start ) { + // Iteratively approximate from a nonzero starting point + // Prefer the current property, because this process will be trivial if it uses the same units + // Fallback to end or a simple constant + start = jQuery.css( tween.elem, prop, true ) || end || 1; + + do { + // If previous iteration zeroed out, double until we get *something* + // Use a string for doubling factor so we don't accidentally see scale as unchanged below + scale = scale || ".5"; + + // Adjust and apply + start = start / scale; + jQuery.style( tween.elem, prop, start + unit ); + + // Update scale, tolerating zero or NaN from tween.cur() + // And breaking the loop if scale is unchanged or perfect, or if we've just had enough + } while ( scale !== (scale = tween.cur() / target) && scale !== 1 && --maxIterations ); + } + + tween.unit = unit; + tween.start = start; + // If a +=/-= token was provided, we're doing a relative animation + tween.end = parts[1] ? start + ( parts[1] + 1 ) * end : end; + } + return tween; + }] + }; + +// Animations created synchronously will run synchronously +function createFxNow() { + setTimeout(function() { + fxNow = undefined; + }, 0 ); + return ( fxNow = jQuery.now() ); +} + +function createTweens( animation, props ) { + jQuery.each( props, function( prop, value ) { + var collection = ( tweeners[ prop ] || [] ).concat( tweeners[ "*" ] ), + index = 0, + length = collection.length; + for ( ; index < length; index++ ) { + if ( collection[ index ].call( animation, prop, value ) ) { + + // we're done with this property + return; + } + } + }); +} + +function Animation( elem, properties, options ) { + var result, + index = 0, + tweenerIndex = 0, + length = animationPrefilters.length, + deferred = jQuery.Deferred().always( function() { + // don't match elem in the :animated selector + delete tick.elem; + }), + tick = function() { + var currentTime = fxNow || createFxNow(), + remaining = Math.max( 0, animation.startTime + animation.duration - currentTime ), + percent = 1 - ( remaining / animation.duration || 0 ), + index = 0, + length = animation.tweens.length; + + for ( ; index < length ; index++ ) { + animation.tweens[ index ].run( percent ); + } + + deferred.notifyWith( elem, [ animation, percent, remaining ]); + + if ( percent < 1 && length ) { + return remaining; + } else { + deferred.resolveWith( elem, [ animation ] ); + return false; + } + }, + animation = deferred.promise({ + elem: elem, + props: jQuery.extend( {}, properties ), + opts: jQuery.extend( true, { specialEasing: {} }, options ), + originalProperties: properties, + originalOptions: options, + startTime: fxNow || createFxNow(), + duration: options.duration, + tweens: [], + createTween: function( prop, end, easing ) { + var tween = jQuery.Tween( elem, animation.opts, prop, end, + animation.opts.specialEasing[ prop ] || animation.opts.easing ); + animation.tweens.push( tween ); + return tween; + }, + stop: function( gotoEnd ) { + var index = 0, + // if we are going to the end, we want to run all the tweens + // otherwise we skip this part + length = gotoEnd ? animation.tweens.length : 0; + + for ( ; index < length ; index++ ) { + animation.tweens[ index ].run( 1 ); + } + + // resolve when we played the last frame + // otherwise, reject + if ( gotoEnd ) { + deferred.resolveWith( elem, [ animation, gotoEnd ] ); + } else { + deferred.rejectWith( elem, [ animation, gotoEnd ] ); + } + return this; + } + }), + props = animation.props; + + propFilter( props, animation.opts.specialEasing ); + + for ( ; index < length ; index++ ) { + result = animationPrefilters[ index ].call( animation, elem, props, animation.opts ); + if ( result ) { + return result; + } + } + + createTweens( animation, props ); + + if ( jQuery.isFunction( animation.opts.start ) ) { + animation.opts.start.call( elem, animation ); + } + + jQuery.fx.timer( + jQuery.extend( tick, { + anim: animation, + queue: animation.opts.queue, + elem: elem + }) + ); + + // attach callbacks from options + return animation.progress( animation.opts.progress ) + .done( animation.opts.done, animation.opts.complete ) + .fail( animation.opts.fail ) + .always( animation.opts.always ); +} + +function propFilter( props, specialEasing ) { + var index, name, easing, value, hooks; + + // camelCase, specialEasing and expand cssHook pass + for ( index in props ) { + name = jQuery.camelCase( index ); + easing = specialEasing[ name ]; + value = props[ index ]; + if ( jQuery.isArray( value ) ) { + easing = value[ 1 ]; + value = props[ index ] = value[ 0 ]; + } + + if ( index !== name ) { + props[ name ] = value; + delete props[ index ]; + } + + hooks = jQuery.cssHooks[ name ]; + if ( hooks && "expand" in hooks ) { + value = hooks.expand( value ); + delete props[ name ]; + + // not quite $.extend, this wont overwrite keys already present. + // also - reusing 'index' from above because we have the correct "name" + for ( index in value ) { + if ( !( index in props ) ) { + props[ index ] = value[ index ]; + specialEasing[ index ] = easing; + } + } + } else { + specialEasing[ name ] = easing; + } + } +} + +jQuery.Animation = jQuery.extend( Animation, { + + tweener: function( props, callback ) { + if ( jQuery.isFunction( props ) ) { + callback = props; + props = [ "*" ]; + } else { + props = props.split(" "); + } + + var prop, + index = 0, + length = props.length; + + for ( ; index < length ; index++ ) { + prop = props[ index ]; + tweeners[ prop ] = tweeners[ prop ] || []; + tweeners[ prop ].unshift( callback ); + } + }, + + prefilter: function( callback, prepend ) { + if ( prepend ) { + animationPrefilters.unshift( callback ); + } else { + animationPrefilters.push( callback ); + } + } +}); + +function defaultPrefilter( elem, props, opts ) { + var index, prop, value, length, dataShow, tween, hooks, oldfire, + anim = this, + style = elem.style, + orig = {}, + handled = [], + hidden = elem.nodeType && isHidden( elem ); + + // handle queue: false promises + if ( !opts.queue ) { + hooks = jQuery._queueHooks( elem, "fx" ); + if ( hooks.unqueued == null ) { + hooks.unqueued = 0; + oldfire = hooks.empty.fire; + hooks.empty.fire = function() { + if ( !hooks.unqueued ) { + oldfire(); + } + }; + } + hooks.unqueued++; + + anim.always(function() { + // doing this makes sure that the complete handler will be called + // before this completes + anim.always(function() { + hooks.unqueued--; + if ( !jQuery.queue( elem, "fx" ).length ) { + hooks.empty.fire(); + } + }); + }); + } + + // height/width overflow pass + if ( elem.nodeType === 1 && ( "height" in props || "width" in props ) ) { + // Make sure that nothing sneaks out + // Record all 3 overflow attributes because IE does not + // change the overflow attribute when overflowX and + // overflowY are set to the same value + opts.overflow = [ style.overflow, style.overflowX, style.overflowY ]; + + // Set display property to inline-block for height/width + // animations on inline elements that are having width/height animated + if ( jQuery.css( elem, "display" ) === "inline" && + jQuery.css( elem, "float" ) === "none" ) { + + // inline-level elements accept inline-block; + // block-level elements need to be inline with layout + if ( !jQuery.support.inlineBlockNeedsLayout || css_defaultDisplay( elem.nodeName ) === "inline" ) { + style.display = "inline-block"; + + } else { + style.zoom = 1; + } + } + } + + if ( opts.overflow ) { + style.overflow = "hidden"; + if ( !jQuery.support.shrinkWrapBlocks ) { + anim.done(function() { + style.overflow = opts.overflow[ 0 ]; + style.overflowX = opts.overflow[ 1 ]; + style.overflowY = opts.overflow[ 2 ]; + }); + } + } + + + // show/hide pass + for ( index in props ) { + value = props[ index ]; + if ( rfxtypes.exec( value ) ) { + delete props[ index ]; + if ( value === ( hidden ? "hide" : "show" ) ) { + continue; + } + handled.push( index ); + } + } + + length = handled.length; + if ( length ) { + dataShow = jQuery._data( elem, "fxshow" ) || jQuery._data( elem, "fxshow", {} ); + if ( hidden ) { + jQuery( elem ).show(); + } else { + anim.done(function() { + jQuery( elem ).hide(); + }); + } + anim.done(function() { + var prop; + jQuery.removeData( elem, "fxshow", true ); + for ( prop in orig ) { + jQuery.style( elem, prop, orig[ prop ] ); + } + }); + for ( index = 0 ; index < length ; index++ ) { + prop = handled[ index ]; + tween = anim.createTween( prop, hidden ? dataShow[ prop ] : 0 ); + orig[ prop ] = dataShow[ prop ] || jQuery.style( elem, prop ); + + if ( !( prop in dataShow ) ) { + dataShow[ prop ] = tween.start; + if ( hidden ) { + tween.end = tween.start; + tween.start = prop === "width" || prop === "height" ? 1 : 0; + } + } + } + } +} + +function Tween( elem, options, prop, end, easing ) { + return new Tween.prototype.init( elem, options, prop, end, easing ); +} +jQuery.Tween = Tween; + +Tween.prototype = { + constructor: Tween, + init: function( elem, options, prop, end, easing, unit ) { + this.elem = elem; + this.prop = prop; + this.easing = easing || "swing"; + this.options = options; + this.start = this.now = this.cur(); + this.end = end; + this.unit = unit || ( jQuery.cssNumber[ prop ] ? "" : "px" ); + }, + cur: function() { + var hooks = Tween.propHooks[ this.prop ]; + + return hooks && hooks.get ? + hooks.get( this ) : + Tween.propHooks._default.get( this ); + }, + run: function( percent ) { + var eased, + hooks = Tween.propHooks[ this.prop ]; + + if ( this.options.duration ) { + this.pos = eased = jQuery.easing[ this.easing ]( + percent, this.options.duration * percent, 0, 1, this.options.duration + ); + } else { + this.pos = eased = percent; + } + this.now = ( this.end - this.start ) * eased + this.start; + + if ( this.options.step ) { + this.options.step.call( this.elem, this.now, this ); + } + + if ( hooks && hooks.set ) { + hooks.set( this ); + } else { + Tween.propHooks._default.set( this ); + } + return this; + } +}; + +Tween.prototype.init.prototype = Tween.prototype; + +Tween.propHooks = { + _default: { + get: function( tween ) { + var result; + + if ( tween.elem[ tween.prop ] != null && + (!tween.elem.style || tween.elem.style[ tween.prop ] == null) ) { + return tween.elem[ tween.prop ]; + } + + // passing any value as a 4th parameter to .css will automatically + // attempt a parseFloat and fallback to a string if the parse fails + // so, simple values such as "10px" are parsed to Float. + // complex values such as "rotate(1rad)" are returned as is. + result = jQuery.css( tween.elem, tween.prop, false, "" ); + // Empty strings, null, undefined and "auto" are converted to 0. + return !result || result === "auto" ? 0 : result; + }, + set: function( tween ) { + // use step hook for back compat - use cssHook if its there - use .style if its + // available and use plain properties where available + if ( jQuery.fx.step[ tween.prop ] ) { + jQuery.fx.step[ tween.prop ]( tween ); + } else if ( tween.elem.style && ( tween.elem.style[ jQuery.cssProps[ tween.prop ] ] != null || jQuery.cssHooks[ tween.prop ] ) ) { + jQuery.style( tween.elem, tween.prop, tween.now + tween.unit ); + } else { + tween.elem[ tween.prop ] = tween.now; + } + } + } +}; + +// Remove in 2.0 - this supports IE8's panic based approach +// to setting things on disconnected nodes + +Tween.propHooks.scrollTop = Tween.propHooks.scrollLeft = { + set: function( tween ) { + if ( tween.elem.nodeType && tween.elem.parentNode ) { + tween.elem[ tween.prop ] = tween.now; + } + } +}; + +jQuery.each([ "toggle", "show", "hide" ], function( i, name ) { + var cssFn = jQuery.fn[ name ]; + jQuery.fn[ name ] = function( speed, easing, callback ) { + return speed == null || typeof speed === "boolean" || + // special check for .toggle( handler, handler, ... ) + ( !i && jQuery.isFunction( speed ) && jQuery.isFunction( easing ) ) ? + cssFn.apply( this, arguments ) : + this.animate( genFx( name, true ), speed, easing, callback ); + }; +}); + +jQuery.fn.extend({ + fadeTo: function( speed, to, easing, callback ) { + + // show any hidden elements after setting opacity to 0 + return this.filter( isHidden ).css( "opacity", 0 ).show() + + // animate to the value specified + .end().animate({ opacity: to }, speed, easing, callback ); + }, + animate: function( prop, speed, easing, callback ) { + var empty = jQuery.isEmptyObject( prop ), + optall = jQuery.speed( speed, easing, callback ), + doAnimation = function() { + // Operate on a copy of prop so per-property easing won't be lost + var anim = Animation( this, jQuery.extend( {}, prop ), optall ); + + // Empty animations resolve immediately + if ( empty ) { + anim.stop( true ); + } + }; + + return empty || optall.queue === false ? + this.each( doAnimation ) : + this.queue( optall.queue, doAnimation ); + }, + stop: function( type, clearQueue, gotoEnd ) { + var stopQueue = function( hooks ) { + var stop = hooks.stop; + delete hooks.stop; + stop( gotoEnd ); + }; + + if ( typeof type !== "string" ) { + gotoEnd = clearQueue; + clearQueue = type; + type = undefined; + } + if ( clearQueue && type !== false ) { + this.queue( type || "fx", [] ); + } + + return this.each(function() { + var dequeue = true, + index = type != null && type + "queueHooks", + timers = jQuery.timers, + data = jQuery._data( this ); + + if ( index ) { + if ( data[ index ] && data[ index ].stop ) { + stopQueue( data[ index ] ); + } + } else { + for ( index in data ) { + if ( data[ index ] && data[ index ].stop && rrun.test( index ) ) { + stopQueue( data[ index ] ); + } + } + } + + for ( index = timers.length; index--; ) { + if ( timers[ index ].elem === this && (type == null || timers[ index ].queue === type) ) { + timers[ index ].anim.stop( gotoEnd ); + dequeue = false; + timers.splice( index, 1 ); + } + } + + // start the next in the queue if the last step wasn't forced + // timers currently will call their complete callbacks, which will dequeue + // but only if they were gotoEnd + if ( dequeue || !gotoEnd ) { + jQuery.dequeue( this, type ); + } + }); + } +}); + +// Generate parameters to create a standard animation +function genFx( type, includeWidth ) { + var which, + attrs = { height: type }, + i = 0; + + // if we include width, step value is 1 to do all cssExpand values, + // if we don't include width, step value is 2 to skip over Left and Right + includeWidth = includeWidth? 1 : 0; + for( ; i < 4 ; i += 2 - includeWidth ) { + which = cssExpand[ i ]; + attrs[ "margin" + which ] = attrs[ "padding" + which ] = type; + } + + if ( includeWidth ) { + attrs.opacity = attrs.width = type; + } + + return attrs; +} + +// Generate shortcuts for custom animations +jQuery.each({ + slideDown: genFx("show"), + slideUp: genFx("hide"), + slideToggle: genFx("toggle"), + fadeIn: { opacity: "show" }, + fadeOut: { opacity: "hide" }, + fadeToggle: { opacity: "toggle" } +}, function( name, props ) { + jQuery.fn[ name ] = function( speed, easing, callback ) { + return this.animate( props, speed, easing, callback ); + }; +}); + +jQuery.speed = function( speed, easing, fn ) { + var opt = speed && typeof speed === "object" ? jQuery.extend( {}, speed ) : { + complete: fn || !fn && easing || + jQuery.isFunction( speed ) && speed, + duration: speed, + easing: fn && easing || easing && !jQuery.isFunction( easing ) && easing + }; + + opt.duration = jQuery.fx.off ? 0 : typeof opt.duration === "number" ? opt.duration : + opt.duration in jQuery.fx.speeds ? jQuery.fx.speeds[ opt.duration ] : jQuery.fx.speeds._default; + + // normalize opt.queue - true/undefined/null -> "fx" + if ( opt.queue == null || opt.queue === true ) { + opt.queue = "fx"; + } + + // Queueing + opt.old = opt.complete; + + opt.complete = function() { + if ( jQuery.isFunction( opt.old ) ) { + opt.old.call( this ); + } + + if ( opt.queue ) { + jQuery.dequeue( this, opt.queue ); + } + }; + + return opt; +}; + +jQuery.easing = { + linear: function( p ) { + return p; + }, + swing: function( p ) { + return 0.5 - Math.cos( p*Math.PI ) / 2; + } +}; + +jQuery.timers = []; +jQuery.fx = Tween.prototype.init; +jQuery.fx.tick = function() { + var timer, + timers = jQuery.timers, + i = 0; + + for ( ; i < timers.length; i++ ) { + timer = timers[ i ]; + // Checks the timer has not already been removed + if ( !timer() && timers[ i ] === timer ) { + timers.splice( i--, 1 ); + } + } + + if ( !timers.length ) { + jQuery.fx.stop(); + } +}; + +jQuery.fx.timer = function( timer ) { + if ( timer() && jQuery.timers.push( timer ) && !timerId ) { + timerId = setInterval( jQuery.fx.tick, jQuery.fx.interval ); + } +}; + +jQuery.fx.interval = 13; + +jQuery.fx.stop = function() { + clearInterval( timerId ); + timerId = null; +}; + +jQuery.fx.speeds = { + slow: 600, + fast: 200, + // Default speed + _default: 400 +}; + +// Back Compat <1.8 extension point +jQuery.fx.step = {}; + +if ( jQuery.expr && jQuery.expr.filters ) { + jQuery.expr.filters.animated = function( elem ) { + return jQuery.grep(jQuery.timers, function( fn ) { + return elem === fn.elem; + }).length; + }; +} +var rroot = /^(?:body|html)$/i; + +jQuery.fn.offset = function( options ) { + if ( arguments.length ) { + return options === undefined ? + this : + this.each(function( i ) { + jQuery.offset.setOffset( this, options, i ); + }); + } + + var docElem, body, win, clientTop, clientLeft, scrollTop, scrollLeft, + box = { top: 0, left: 0 }, + elem = this[ 0 ], + doc = elem && elem.ownerDocument; + + if ( !doc ) { + return; + } + + if ( (body = doc.body) === elem ) { + return jQuery.offset.bodyOffset( elem ); + } + + docElem = doc.documentElement; + + // Make sure it's not a disconnected DOM node + if ( !jQuery.contains( docElem, elem ) ) { + return box; + } + + // If we don't have gBCR, just use 0,0 rather than error + // BlackBerry 5, iOS 3 (original iPhone) + if ( typeof elem.getBoundingClientRect !== "undefined" ) { + box = elem.getBoundingClientRect(); + } + win = getWindow( doc ); + clientTop = docElem.clientTop || body.clientTop || 0; + clientLeft = docElem.clientLeft || body.clientLeft || 0; + scrollTop = win.pageYOffset || docElem.scrollTop; + scrollLeft = win.pageXOffset || docElem.scrollLeft; + return { + top: box.top + scrollTop - clientTop, + left: box.left + scrollLeft - clientLeft + }; +}; + +jQuery.offset = { + + bodyOffset: function( body ) { + var top = body.offsetTop, + left = body.offsetLeft; + + if ( jQuery.support.doesNotIncludeMarginInBodyOffset ) { + top += parseFloat( jQuery.css(body, "marginTop") ) || 0; + left += parseFloat( jQuery.css(body, "marginLeft") ) || 0; + } + + return { top: top, left: left }; + }, + + setOffset: function( elem, options, i ) { + var position = jQuery.css( elem, "position" ); + + // set position first, in-case top/left are set even on static elem + if ( position === "static" ) { + elem.style.position = "relative"; + } + + var curElem = jQuery( elem ), + curOffset = curElem.offset(), + curCSSTop = jQuery.css( elem, "top" ), + curCSSLeft = jQuery.css( elem, "left" ), + calculatePosition = ( position === "absolute" || position === "fixed" ) && jQuery.inArray("auto", [curCSSTop, curCSSLeft]) > -1, + props = {}, curPosition = {}, curTop, curLeft; + + // need to be able to calculate position if either top or left is auto and position is either absolute or fixed + if ( calculatePosition ) { + curPosition = curElem.position(); + curTop = curPosition.top; + curLeft = curPosition.left; + } else { + curTop = parseFloat( curCSSTop ) || 0; + curLeft = parseFloat( curCSSLeft ) || 0; + } + + if ( jQuery.isFunction( options ) ) { + options = options.call( elem, i, curOffset ); + } + + if ( options.top != null ) { + props.top = ( options.top - curOffset.top ) + curTop; + } + if ( options.left != null ) { + props.left = ( options.left - curOffset.left ) + curLeft; + } + + if ( "using" in options ) { + options.using.call( elem, props ); + } else { + curElem.css( props ); + } + } +}; + + +jQuery.fn.extend({ + + position: function() { + if ( !this[0] ) { + return; + } + + var elem = this[0], + + // Get *real* offsetParent + offsetParent = this.offsetParent(), + + // Get correct offsets + offset = this.offset(), + parentOffset = rroot.test(offsetParent[0].nodeName) ? { top: 0, left: 0 } : offsetParent.offset(); + + // Subtract element margins + // note: when an element has margin: auto the offsetLeft and marginLeft + // are the same in Safari causing offset.left to incorrectly be 0 + offset.top -= parseFloat( jQuery.css(elem, "marginTop") ) || 0; + offset.left -= parseFloat( jQuery.css(elem, "marginLeft") ) || 0; + + // Add offsetParent borders + parentOffset.top += parseFloat( jQuery.css(offsetParent[0], "borderTopWidth") ) || 0; + parentOffset.left += parseFloat( jQuery.css(offsetParent[0], "borderLeftWidth") ) || 0; + + // Subtract the two offsets + return { + top: offset.top - parentOffset.top, + left: offset.left - parentOffset.left + }; + }, + + offsetParent: function() { + return this.map(function() { + var offsetParent = this.offsetParent || document.body; + while ( offsetParent && (!rroot.test(offsetParent.nodeName) && jQuery.css(offsetParent, "position") === "static") ) { + offsetParent = offsetParent.offsetParent; + } + return offsetParent || document.body; + }); + } +}); + + +// Create scrollLeft and scrollTop methods +jQuery.each( {scrollLeft: "pageXOffset", scrollTop: "pageYOffset"}, function( method, prop ) { + var top = /Y/.test( prop ); + + jQuery.fn[ method ] = function( val ) { + return jQuery.access( this, function( elem, method, val ) { + var win = getWindow( elem ); + + if ( val === undefined ) { + return win ? (prop in win) ? win[ prop ] : + win.document.documentElement[ method ] : + elem[ method ]; + } + + if ( win ) { + win.scrollTo( + !top ? val : jQuery( win ).scrollLeft(), + top ? val : jQuery( win ).scrollTop() + ); + + } else { + elem[ method ] = val; + } + }, method, val, arguments.length, null ); + }; +}); + +function getWindow( elem ) { + return jQuery.isWindow( elem ) ? + elem : + elem.nodeType === 9 ? + elem.defaultView || elem.parentWindow : + false; +} +// Create innerHeight, innerWidth, height, width, outerHeight and outerWidth methods +jQuery.each( { Height: "height", Width: "width" }, function( name, type ) { + jQuery.each( { padding: "inner" + name, content: type, "": "outer" + name }, function( defaultExtra, funcName ) { + // margin is only for outerHeight, outerWidth + jQuery.fn[ funcName ] = function( margin, value ) { + var chainable = arguments.length && ( defaultExtra || typeof margin !== "boolean" ), + extra = defaultExtra || ( margin === true || value === true ? "margin" : "border" ); + + return jQuery.access( this, function( elem, type, value ) { + var doc; + + if ( jQuery.isWindow( elem ) ) { + // As of 5/8/2012 this will yield incorrect results for Mobile Safari, but there + // isn't a whole lot we can do. See pull request at this URL for discussion: + // https://github.com/jquery/jquery/pull/764 + return elem.document.documentElement[ "client" + name ]; + } + + // Get document width or height + if ( elem.nodeType === 9 ) { + doc = elem.documentElement; + + // Either scroll[Width/Height] or offset[Width/Height] or client[Width/Height], whichever is greatest + // unfortunately, this causes bug #3838 in IE6/8 only, but there is currently no good, small way to fix it. + return Math.max( + elem.body[ "scroll" + name ], doc[ "scroll" + name ], + elem.body[ "offset" + name ], doc[ "offset" + name ], + doc[ "client" + name ] + ); + } + + return value === undefined ? + // Get width or height on the element, requesting but not forcing parseFloat + jQuery.css( elem, type, value, extra ) : + + // Set width or height on the element + jQuery.style( elem, type, value, extra ); + }, type, chainable ? margin : undefined, chainable, null ); + }; + }); +}); +// Expose jQuery to the global object +window.jQuery = window.$ = jQuery; + +// Expose jQuery as an AMD module, but only for AMD loaders that +// understand the issues with loading multiple versions of jQuery +// in a page that all might call define(). The loader will indicate +// they have special allowances for multiple jQuery versions by +// specifying define.amd.jQuery = true. Register as a named module, +// since jQuery can be concatenated with other files that may use define, +// but not use a proper concatenation script that understands anonymous +// AMD modules. A named AMD is safest and most robust way to register. +// Lowercase jquery is used because AMD module names are derived from +// file names, and jQuery is normally delivered in a lowercase file name. +// Do this after creating the global so that if an AMD module wants to call +// noConflict to hide this version of jQuery, it will work. +if ( typeof define === "function" && define.amd && define.amd.jQuery ) { + define( "jquery", [], function () { return jQuery; } ); +} + +})( window ); diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/package.json b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/package.json new file mode 100755 index 000000000..36679fd10 --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/package.json @@ -0,0 +1,61 @@ +{ + "name": "jquery-ui", + "title": "jQuery UI", + "description": "A curated set of user interface interactions, effects, widgets, and themes built on top of the jQuery JavaScript Library.", + "version": "1.9.0", + "homepage": "http://jqueryui.com", + "author": { + "name": "jQuery Foundation and other contributors", + "url": "https://github.com/jquery/jquery-ui/blob/1.9.0/AUTHORS.txt" + }, + "maintainers": [ + { + "name": "Scott González", + "email": "scott.gonzalez@gmail.com", + "url": "http://scottgonzalez.com" + }, + { + "name": "Jörn Zaefferer", + "email": "joern.zaefferer@gmail.com", + "url": "http://bassistance.de" + }, + { + "name": "Richard D. Worth", + "email": "rdworth@gmail.com", + "url": "http://rdworth.org" + }, + { + "name": "Kris Borchers", + "email": "kris.borchers@gmail.com", + "url": "http://krisborchers.com" + }, + { + "name": "Corey Frang", + "email": "gnarf37@gmail.com", + "url": "http://gnarf.net" + } + ], + "repository": { + "type": "git", + "url": "git://github.com/jquery/jquery-ui.git" + }, + "bugs": "http://bugs.jqueryui.com/", + "licenses": [ + { + "type": "MIT", + "url": "https://github.com/jquery/jquery-ui/blob/1.9.0/MIT-LICENSE.txt" + } + ], + "dependencies": {}, + "devDependencies": { + "grunt": "~0.3.9", + "grunt-css": "0.2.0", + "grunt-compare-size": "0.1.4", + "grunt-html": "0.1.1", + "grunt-junit": "0.1.4", + "grunt-git-authors": "1.0.0", + "rimraf": "2.0.1", + "testswarm": "0.2.3" + }, + "keywords": [] +} diff --git a/htdocs/js/lib/vendor/jquery-ui-for-classlist3/development-bundle/themes/base/images/ui-bg_flat_0_aaaaaa_40x100.png b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/themes/base/images/ui-bg_flat_0_aaaaaa_40x100.png similarity index 100% rename from htdocs/js/lib/vendor/jquery-ui-for-classlist3/development-bundle/themes/base/images/ui-bg_flat_0_aaaaaa_40x100.png rename to htdocs/js/jquery-ui-1.9.0.custom/development-bundle/themes/base/images/ui-bg_flat_0_aaaaaa_40x100.png diff --git a/htdocs/js/lib/vendor/jquery-ui-for-classlist3/development-bundle/themes/base/images/ui-bg_flat_75_ffffff_40x100.png b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/themes/base/images/ui-bg_flat_75_ffffff_40x100.png similarity index 100% rename from htdocs/js/lib/vendor/jquery-ui-for-classlist3/development-bundle/themes/base/images/ui-bg_flat_75_ffffff_40x100.png rename to htdocs/js/jquery-ui-1.9.0.custom/development-bundle/themes/base/images/ui-bg_flat_75_ffffff_40x100.png diff --git a/htdocs/js/lib/vendor/jquery-ui-for-classlist3/development-bundle/themes/base/images/ui-bg_glass_55_fbf9ee_1x400.png b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/themes/base/images/ui-bg_glass_55_fbf9ee_1x400.png similarity index 100% rename from htdocs/js/lib/vendor/jquery-ui-for-classlist3/development-bundle/themes/base/images/ui-bg_glass_55_fbf9ee_1x400.png rename to htdocs/js/jquery-ui-1.9.0.custom/development-bundle/themes/base/images/ui-bg_glass_55_fbf9ee_1x400.png diff --git a/htdocs/js/lib/vendor/jquery-ui-for-classlist3/development-bundle/themes/base/images/ui-bg_glass_65_ffffff_1x400.png b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/themes/base/images/ui-bg_glass_65_ffffff_1x400.png similarity index 100% rename from htdocs/js/lib/vendor/jquery-ui-for-classlist3/development-bundle/themes/base/images/ui-bg_glass_65_ffffff_1x400.png rename to htdocs/js/jquery-ui-1.9.0.custom/development-bundle/themes/base/images/ui-bg_glass_65_ffffff_1x400.png diff --git a/htdocs/js/lib/vendor/jquery-ui-for-classlist3/development-bundle/themes/base/images/ui-bg_glass_75_dadada_1x400.png b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/themes/base/images/ui-bg_glass_75_dadada_1x400.png similarity index 100% rename from htdocs/js/lib/vendor/jquery-ui-for-classlist3/development-bundle/themes/base/images/ui-bg_glass_75_dadada_1x400.png rename to htdocs/js/jquery-ui-1.9.0.custom/development-bundle/themes/base/images/ui-bg_glass_75_dadada_1x400.png diff --git a/htdocs/js/lib/vendor/jquery-ui-for-classlist3/development-bundle/themes/base/images/ui-bg_glass_75_e6e6e6_1x400.png b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/themes/base/images/ui-bg_glass_75_e6e6e6_1x400.png similarity index 100% rename from htdocs/js/lib/vendor/jquery-ui-for-classlist3/development-bundle/themes/base/images/ui-bg_glass_75_e6e6e6_1x400.png rename to htdocs/js/jquery-ui-1.9.0.custom/development-bundle/themes/base/images/ui-bg_glass_75_e6e6e6_1x400.png diff --git a/htdocs/js/lib/vendor/jquery-ui-for-classlist3/development-bundle/themes/base/images/ui-bg_glass_95_fef1ec_1x400.png b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/themes/base/images/ui-bg_glass_95_fef1ec_1x400.png similarity index 100% rename from htdocs/js/lib/vendor/jquery-ui-for-classlist3/development-bundle/themes/base/images/ui-bg_glass_95_fef1ec_1x400.png rename to htdocs/js/jquery-ui-1.9.0.custom/development-bundle/themes/base/images/ui-bg_glass_95_fef1ec_1x400.png diff --git a/htdocs/js/lib/vendor/jquery-ui-for-classlist3/development-bundle/themes/base/images/ui-bg_highlight-soft_75_cccccc_1x100.png b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/themes/base/images/ui-bg_highlight-soft_75_cccccc_1x100.png similarity index 100% rename from htdocs/js/lib/vendor/jquery-ui-for-classlist3/development-bundle/themes/base/images/ui-bg_highlight-soft_75_cccccc_1x100.png rename to htdocs/js/jquery-ui-1.9.0.custom/development-bundle/themes/base/images/ui-bg_highlight-soft_75_cccccc_1x100.png diff --git a/htdocs/js/lib/vendor/jquery-ui-for-classlist3/development-bundle/themes/base/images/ui-icons_222222_256x240.png b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/themes/base/images/ui-icons_222222_256x240.png similarity index 100% rename from htdocs/js/lib/vendor/jquery-ui-for-classlist3/development-bundle/themes/base/images/ui-icons_222222_256x240.png rename to htdocs/js/jquery-ui-1.9.0.custom/development-bundle/themes/base/images/ui-icons_222222_256x240.png diff --git a/htdocs/js/lib/vendor/jquery-ui-for-classlist3/development-bundle/themes/base/images/ui-icons_2e83ff_256x240.png b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/themes/base/images/ui-icons_2e83ff_256x240.png similarity index 100% rename from htdocs/js/lib/vendor/jquery-ui-for-classlist3/development-bundle/themes/base/images/ui-icons_2e83ff_256x240.png rename to htdocs/js/jquery-ui-1.9.0.custom/development-bundle/themes/base/images/ui-icons_2e83ff_256x240.png diff --git a/htdocs/js/lib/vendor/jquery-ui-for-classlist3/development-bundle/themes/base/images/ui-icons_454545_256x240.png b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/themes/base/images/ui-icons_454545_256x240.png similarity index 100% rename from htdocs/js/lib/vendor/jquery-ui-for-classlist3/development-bundle/themes/base/images/ui-icons_454545_256x240.png rename to htdocs/js/jquery-ui-1.9.0.custom/development-bundle/themes/base/images/ui-icons_454545_256x240.png diff --git a/htdocs/js/lib/vendor/jquery-ui-for-classlist3/development-bundle/themes/base/images/ui-icons_888888_256x240.png b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/themes/base/images/ui-icons_888888_256x240.png similarity index 100% rename from htdocs/js/lib/vendor/jquery-ui-for-classlist3/development-bundle/themes/base/images/ui-icons_888888_256x240.png rename to htdocs/js/jquery-ui-1.9.0.custom/development-bundle/themes/base/images/ui-icons_888888_256x240.png diff --git a/htdocs/js/lib/vendor/jquery-ui-for-classlist3/development-bundle/themes/base/images/ui-icons_cd0a0a_256x240.png b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/themes/base/images/ui-icons_cd0a0a_256x240.png similarity index 100% rename from htdocs/js/lib/vendor/jquery-ui-for-classlist3/development-bundle/themes/base/images/ui-icons_cd0a0a_256x240.png rename to htdocs/js/jquery-ui-1.9.0.custom/development-bundle/themes/base/images/ui-icons_cd0a0a_256x240.png diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/themes/base/jquery-ui.css b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/themes/base/jquery-ui.css new file mode 100755 index 000000000..28c6bee41 --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/themes/base/jquery-ui.css @@ -0,0 +1,457 @@ +/*! jQuery UI - v1.9.0 - 2012-10-13 +* http://jqueryui.com +* Includes: jquery.ui.core.css, jquery.ui.resizable.css, jquery.ui.selectable.css, jquery.ui.accordion.css, jquery.ui.autocomplete.css, jquery.ui.button.css, jquery.ui.datepicker.css, jquery.ui.dialog.css, jquery.ui.menu.css, jquery.ui.progressbar.css, jquery.ui.slider.css, jquery.ui.spinner.css, jquery.ui.tabs.css, jquery.ui.tooltip.css +* Copyright (c) 2012 jQuery Foundation and other contributors Licensed MIT */ + +/* Layout helpers +----------------------------------*/ +.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:before, .ui-helper-clearfix:after { content: ""; display: table; } +.ui-helper-clearfix:after { clear: both; } +.ui-helper-clearfix { zoom: 1; } +.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%; } +.ui-resizable { position: relative;} +.ui-resizable-handle { position: absolute;font-size: 0.1px; 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;}.ui-selectable-helper { position: absolute; z-index: 100; border:1px dotted black; } +.ui-accordion .ui-accordion-header { display: block; cursor: pointer; position: relative; margin-top: 2px; padding: .5em .5em .5em .7em; zoom: 1; } +.ui-accordion .ui-accordion-icons { padding-left: 2.2em; } +.ui-accordion .ui-accordion-noicons { padding-left: .7em; } +.ui-accordion .ui-accordion-icons .ui-accordion-icons { padding-left: 2.2em; } +.ui-accordion .ui-accordion-header .ui-accordion-header-icon { position: absolute; left: .5em; top: 50%; margin-top: -8px; } +.ui-accordion .ui-accordion-content { padding: 1em 2.2em; border-top: 0; overflow: auto; zoom: 1; } +.ui-autocomplete { position: absolute; cursor: default; } + +/* workarounds */ +* html .ui-autocomplete { width:1px; } /* without this, the menu expands to 100% in IE6 */ +.ui-button { display: inline-block; position: relative; padding: 0; margin-right: .1em; cursor: pointer; text-align: center; zoom: 1; overflow: visible; } /* the overflow property removes extra width in IE */ +.ui-button, .ui-button:link, .ui-button:visited, .ui-button:hover, .ui-button:active { text-decoration: none; } +.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 */ +.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 { + 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*/ +}.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; } +.ui-menu { list-style:none; padding: 2px; margin: 0; display:block; outline: none; } +.ui-menu .ui-menu { margin-top: -3px; position: absolute; } +.ui-menu .ui-menu-item { margin: 0; padding: 0; zoom: 1; width: 100%; } +.ui-menu .ui-menu-divider { margin: 5px -2px 5px -2px; height: 0; font-size: 0; line-height: 0; border-width: 1px 0 0 0; } +.ui-menu .ui-menu-item a { text-decoration: none; display: block; padding: 2px .4em; line-height: 1.5; zoom: 1; font-weight: normal; } +.ui-menu .ui-menu-item a.ui-state-focus, +.ui-menu .ui-menu-item a.ui-state-active { font-weight: normal; margin: -1px; } + +.ui-menu .ui-state-disabled { font-weight: normal; margin: .4em 0 .2em; line-height: 1.5; } +.ui-menu .ui-state-disabled a { cursor: default; } + +/* icon support */ +.ui-menu-icons { position: relative; } +.ui-menu-icons .ui-menu-item a { position: relative; padding-left: 2em; } + +/* left-aligned */ +.ui-menu .ui-icon { position: absolute; top: .2em; left: .2em; } + +/* right-aligned */ +.ui-menu .ui-menu-icon { position: static; float: right; } +.ui-progressbar { height:2em; text-align: left; overflow: hidden; } +.ui-progressbar .ui-progressbar-value {margin: -1px; height:100%; }.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; }.ui-spinner { position:relative; display: inline-block; overflow: hidden; padding: 0; vertical-align: middle; } +.ui-spinner-input { border: none; background: none; padding: 0; margin: .2em 0; vertical-align: middle; margin-left: .4em; margin-right: 22px; } +.ui-spinner-button { width: 16px; height: 50%; font-size: .5em; padding: 0; margin: 0; z-index: 100; text-align: center; position: absolute; cursor: default; display: block; overflow: hidden; right: 0; } +.ui-spinner a.ui-spinner-button { border-top: none; border-bottom: none; border-right: none; } /* more specificity required here to overide default borders */ +.ui-spinner .ui-icon { position: absolute; margin-top: -8px; top: 50%; left: 0; } /* vertical centre icon */ +.ui-spinner-up { top: 0; } +.ui-spinner-down { bottom: 0; } + +/* TR overrides */ +span.ui-spinner { background: none; } +.ui-spinner .ui-icon-triangle-1-s { + /* need to fix icons sprite */ + background-position:-65px -16px; +} +.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: 0; margin: 1px .2em 0 0; border-bottom: 0; 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-active { margin-bottom: -1px; padding-bottom: 1px; } +.ui-tabs .ui-tabs-nav li.ui-tabs-active a, .ui-tabs .ui-tabs-nav li.ui-state-disabled a, .ui-tabs .ui-tabs-nav li.ui-tabs-loading a { cursor: text; } +.ui-tabs .ui-tabs-nav li a, .ui-tabs-collapsible .ui-tabs-nav li.ui-tabs-active 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-tooltip { + padding:8px; + position:absolute; + z-index:9999; + -o-box-shadow: 0 0 5px #aaa; + -moz-box-shadow: 0 0 5px #aaa; + -webkit-box-shadow: 0 0 5px #aaa; + box-shadow: 0 0 5px #aaa; +} +/* Fades and background-images don't work well together in IE6, drop the image */ +* html .ui-tooltip { + background-image: none; +} +body .ui-tooltip { border-width:2px; } + +/* Component containers +----------------------------------*/ +.ui-widget { font-family: Verdana,Arial,sans-serif/*{ffDefault}*/; font-size: 1.1em/*{fsDefault}*/; } +.ui-widget .ui-widget { font-size: 1em; } +.ui-widget input, .ui-widget select, .ui-widget textarea, .ui-widget button { font-family: Verdana,Arial,sans-serif/*{ffDefault}*/; font-size: 1em; } +.ui-widget-content { border: 1px solid #aaaaaa/*{borderColorContent}*/; background: #ffffff/*{bgColorContent}*/ url(images/ui-bg_flat_75_ffffff_40x100.png)/*{bgImgUrlContent}*/ 50%/*{bgContentXPos}*/ 50%/*{bgContentYPos}*/ repeat-x/*{bgContentRepeat}*/; color: #222222/*{fcContent}*/; } +.ui-widget-content a { color: #222222/*{fcContent}*/; } +.ui-widget-header { border: 1px solid #aaaaaa/*{borderColorHeader}*/; background: #cccccc/*{bgColorHeader}*/ url(images/ui-bg_highlight-soft_75_cccccc_1x100.png)/*{bgImgUrlHeader}*/ 50%/*{bgHeaderXPos}*/ 50%/*{bgHeaderYPos}*/ repeat-x/*{bgHeaderRepeat}*/; color: #222222/*{fcHeader}*/; font-weight: bold; } +.ui-widget-header a { color: #222222/*{fcHeader}*/; } + +/* Interaction states +----------------------------------*/ +.ui-state-default, .ui-widget-content .ui-state-default, .ui-widget-header .ui-state-default { border: 1px solid #d3d3d3/*{borderColorDefault}*/; background: #e6e6e6/*{bgColorDefault}*/ url(images/ui-bg_glass_75_e6e6e6_1x400.png)/*{bgImgUrlDefault}*/ 50%/*{bgDefaultXPos}*/ 50%/*{bgDefaultYPos}*/ repeat-x/*{bgDefaultRepeat}*/; font-weight: normal/*{fwDefault}*/; color: #555555/*{fcDefault}*/; } +.ui-state-default a, .ui-state-default a:link, .ui-state-default a:visited { color: #555555/*{fcDefault}*/; 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 #999999/*{borderColorHover}*/; background: #dadada/*{bgColorHover}*/ url(images/ui-bg_glass_75_dadada_1x400.png)/*{bgImgUrlHover}*/ 50%/*{bgHoverXPos}*/ 50%/*{bgHoverYPos}*/ repeat-x/*{bgHoverRepeat}*/; font-weight: normal/*{fwDefault}*/; color: #212121/*{fcHover}*/; } +.ui-state-hover a, .ui-state-hover a:hover { color: #212121/*{fcHover}*/; text-decoration: none; } +.ui-state-active, .ui-widget-content .ui-state-active, .ui-widget-header .ui-state-active { border: 1px solid #aaaaaa/*{borderColorActive}*/; background: #ffffff/*{bgColorActive}*/ url(images/ui-bg_glass_65_ffffff_1x400.png)/*{bgImgUrlActive}*/ 50%/*{bgActiveXPos}*/ 50%/*{bgActiveYPos}*/ repeat-x/*{bgActiveRepeat}*/; font-weight: normal/*{fwDefault}*/; color: #212121/*{fcActive}*/; } +.ui-state-active a, .ui-state-active a:link, .ui-state-active a:visited { color: #212121/*{fcActive}*/; text-decoration: none; } + +/* Interaction Cues +----------------------------------*/ +.ui-state-highlight, .ui-widget-content .ui-state-highlight, .ui-widget-header .ui-state-highlight {border: 1px solid #fcefa1/*{borderColorHighlight}*/; background: #fbf9ee/*{bgColorHighlight}*/ url(images/ui-bg_glass_55_fbf9ee_1x400.png)/*{bgImgUrlHighlight}*/ 50%/*{bgHighlightXPos}*/ 50%/*{bgHighlightYPos}*/ repeat-x/*{bgHighlightRepeat}*/; color: #363636/*{fcHighlight}*/; } +.ui-state-highlight a, .ui-widget-content .ui-state-highlight a,.ui-widget-header .ui-state-highlight a { color: #363636/*{fcHighlight}*/; } +.ui-state-error, .ui-widget-content .ui-state-error, .ui-widget-header .ui-state-error {border: 1px solid #cd0a0a/*{borderColorError}*/; background: #fef1ec/*{bgColorError}*/ url(images/ui-bg_glass_95_fef1ec_1x400.png)/*{bgImgUrlError}*/ 50%/*{bgErrorXPos}*/ 50%/*{bgErrorYPos}*/ repeat-x/*{bgErrorRepeat}*/; color: #cd0a0a/*{fcError}*/; } +.ui-state-error a, .ui-widget-content .ui-state-error a, .ui-widget-header .ui-state-error a { color: #cd0a0a/*{fcError}*/; } +.ui-state-error-text, .ui-widget-content .ui-state-error-text, .ui-widget-header .ui-state-error-text { color: #cd0a0a/*{fcError}*/; } +.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)/*{iconsContent}*/; } +.ui-widget-content .ui-icon {background-image: url(images/ui-icons_222222_256x240.png)/*{iconsContent}*/; } +.ui-widget-header .ui-icon {background-image: url(images/ui-icons_222222_256x240.png)/*{iconsHeader}*/; } +.ui-state-default .ui-icon { background-image: url(images/ui-icons_888888_256x240.png)/*{iconsDefault}*/; } +.ui-state-hover .ui-icon, .ui-state-focus .ui-icon {background-image: url(images/ui-icons_454545_256x240.png)/*{iconsHover}*/; } +.ui-state-active .ui-icon {background-image: url(images/ui-icons_454545_256x240.png)/*{iconsActive}*/; } +.ui-state-highlight .ui-icon {background-image: url(images/ui-icons_2e83ff_256x240.png)/*{iconsHighlight}*/; } +.ui-state-error .ui-icon, .ui-state-error-text .ui-icon {background-image: url(images/ui-icons_cd0a0a_256x240.png)/*{iconsError}*/; } + +/* 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-on { background-position: -96px -144px; } +.ui-icon-radio-off { 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/*{cornerRadius}*/; -webkit-border-top-left-radius: 4px/*{cornerRadius}*/; -khtml-border-top-left-radius: 4px/*{cornerRadius}*/; border-top-left-radius: 4px/*{cornerRadius}*/; } +.ui-corner-all, .ui-corner-top, .ui-corner-right, .ui-corner-tr { -moz-border-radius-topright: 4px/*{cornerRadius}*/; -webkit-border-top-right-radius: 4px/*{cornerRadius}*/; -khtml-border-top-right-radius: 4px/*{cornerRadius}*/; border-top-right-radius: 4px/*{cornerRadius}*/; } +.ui-corner-all, .ui-corner-bottom, .ui-corner-left, .ui-corner-bl { -moz-border-radius-bottomleft: 4px/*{cornerRadius}*/; -webkit-border-bottom-left-radius: 4px/*{cornerRadius}*/; -khtml-border-bottom-left-radius: 4px/*{cornerRadius}*/; border-bottom-left-radius: 4px/*{cornerRadius}*/; } +.ui-corner-all, .ui-corner-bottom, .ui-corner-right, .ui-corner-br { -moz-border-radius-bottomright: 4px/*{cornerRadius}*/; -webkit-border-bottom-right-radius: 4px/*{cornerRadius}*/; -khtml-border-bottom-right-radius: 4px/*{cornerRadius}*/; border-bottom-right-radius: 4px/*{cornerRadius}*/; } + +/* Overlays */ +.ui-widget-overlay { background: #aaaaaa/*{bgColorOverlay}*/ url(images/ui-bg_flat_0_aaaaaa_40x100.png)/*{bgImgUrlOverlay}*/ 50%/*{bgOverlayXPos}*/ 50%/*{bgOverlayYPos}*/ repeat-x/*{bgOverlayRepeat}*/; opacity: .3;filter:Alpha(Opacity=30)/*{opacityOverlay}*/; } +.ui-widget-shadow { margin: -8px/*{offsetTopShadow}*/ 0 0 -8px/*{offsetLeftShadow}*/; padding: 8px/*{thicknessShadow}*/; background: #aaaaaa/*{bgColorShadow}*/ url(images/ui-bg_flat_0_aaaaaa_40x100.png)/*{bgImgUrlShadow}*/ 50%/*{bgShadowXPos}*/ 50%/*{bgShadowYPos}*/ repeat-x/*{bgShadowRepeat}*/; opacity: .3;filter:Alpha(Opacity=30)/*{opacityShadow}*/; -moz-border-radius: 8px/*{cornerRadiusShadow}*/; -khtml-border-radius: 8px/*{cornerRadiusShadow}*/; -webkit-border-radius: 8px/*{cornerRadiusShadow}*/; border-radius: 8px/*{cornerRadiusShadow}*/; } \ No newline at end of file diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/themes/base/jquery.ui.accordion.css b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/themes/base/jquery.ui.accordion.css new file mode 100755 index 000000000..608e04677 --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/themes/base/jquery.ui.accordion.css @@ -0,0 +1,16 @@ +/*! + * jQuery UI Accordion 1.9.0 + * http://jqueryui.com + * + * Copyright 2012 jQuery Foundation and other contributors + * Released under the MIT license. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Accordion#theming + */ +.ui-accordion .ui-accordion-header { display: block; cursor: pointer; position: relative; margin-top: 2px; padding: .5em .5em .5em .7em; zoom: 1; } +.ui-accordion .ui-accordion-icons { padding-left: 2.2em; } +.ui-accordion .ui-accordion-noicons { padding-left: .7em; } +.ui-accordion .ui-accordion-icons .ui-accordion-icons { padding-left: 2.2em; } +.ui-accordion .ui-accordion-header .ui-accordion-header-icon { position: absolute; left: .5em; top: 50%; margin-top: -8px; } +.ui-accordion .ui-accordion-content { padding: 1em 2.2em; border-top: 0; overflow: auto; zoom: 1; } diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/themes/base/jquery.ui.all.css b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/themes/base/jquery.ui.all.css new file mode 100755 index 000000000..04f10a9da --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/themes/base/jquery.ui.all.css @@ -0,0 +1,12 @@ +/*! + * jQuery UI CSS Framework 1.9.0 + * http://jqueryui.com + * + * Copyright 2012 jQuery Foundation and other contributors + * Released under the MIT license. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Theming + */ +@import "jquery.ui.base.css"; +@import "jquery.ui.theme.css"; diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/themes/base/jquery.ui.autocomplete.css b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/themes/base/jquery.ui.autocomplete.css new file mode 100755 index 000000000..e52e6feda --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/themes/base/jquery.ui.autocomplete.css @@ -0,0 +1,14 @@ +/*! + * jQuery UI Autocomplete 1.9.0 + * http://jqueryui.com + * + * Copyright 2012 jQuery Foundation and other contributors + * Released under the MIT license. + * 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 */ diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/themes/base/jquery.ui.base.css b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/themes/base/jquery.ui.base.css new file mode 100755 index 000000000..061b058ba --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/themes/base/jquery.ui.base.css @@ -0,0 +1,25 @@ +/*! + * jQuery UI CSS Framework 1.9.0 + * http://jqueryui.com + * + * Copyright 2012 jQuery Foundation and other contributors + * Released under the MIT license. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Theming + */ +@import url("jquery.ui.core.css"); + +@import url("jquery.ui.accordion.css"); +@import url("jquery.ui.autocomplete.css"); +@import url("jquery.ui.button.css"); +@import url("jquery.ui.datepicker.css"); +@import url("jquery.ui.dialog.css"); +@import url("jquery.ui.menu.css"); +@import url("jquery.ui.progressbar.css"); +@import url("jquery.ui.resizable.css"); +@import url("jquery.ui.selectable.css"); +@import url("jquery.ui.slider.css"); +@import url("jquery.ui.spinner.css"); +@import url("jquery.ui.tabs.css"); +@import url("jquery.ui.tooltip.css"); diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/themes/base/jquery.ui.button.css b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/themes/base/jquery.ui.button.css new file mode 100755 index 000000000..e24ce54aa --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/themes/base/jquery.ui.button.css @@ -0,0 +1,40 @@ +/*! + * jQuery UI Button 1.9.0 + * http://jqueryui.com + * + * Copyright 2012 jQuery Foundation and other contributors + * Released under the MIT license. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Button#theming + */ +.ui-button { display: inline-block; position: relative; padding: 0; margin-right: .1em; cursor: pointer; text-align: center; zoom: 1; overflow: visible; } /* the overflow property removes extra width in IE */ +.ui-button, .ui-button:link, .ui-button:visited, .ui-button:hover, .ui-button:active { text-decoration: none; } +.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 */ diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/themes/base/jquery.ui.core.css b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/themes/base/jquery.ui.core.css new file mode 100755 index 000000000..988c6a4f6 --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/themes/base/jquery.ui.core.css @@ -0,0 +1,39 @@ +/*! + * jQuery UI CSS Framework 1.9.0 + * http://jqueryui.com + * + * Copyright 2012 jQuery Foundation and other contributors + * Released under the MIT license. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Theming/API + */ + +/* Layout helpers +----------------------------------*/ +.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:before, .ui-helper-clearfix:after { content: ""; display: table; } +.ui-helper-clearfix:after { clear: both; } +.ui-helper-clearfix { zoom: 1; } +.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%; } diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/themes/base/jquery.ui.datepicker.css b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/themes/base/jquery.ui.datepicker.css new file mode 100755 index 000000000..9918aa1fe --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/themes/base/jquery.ui.datepicker.css @@ -0,0 +1,67 @@ +/*! + * jQuery UI Datepicker 1.9.0 + * http://jqueryui.com + * + * Copyright 2012 jQuery Foundation and other contributors + * Released under the MIT license. + * 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 { + 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*/ +} \ No newline at end of file diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/themes/base/jquery.ui.dialog.css b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/themes/base/jquery.ui.dialog.css new file mode 100755 index 000000000..528527ba6 --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/themes/base/jquery.ui.dialog.css @@ -0,0 +1,22 @@ +/*! + * jQuery UI Dialog 1.9.0 + * http://jqueryui.com + * + * Copyright 2012 jQuery Foundation and other contributors + * Released under the MIT license. + * 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; } diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/themes/base/jquery.ui.menu.css b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/themes/base/jquery.ui.menu.css new file mode 100755 index 000000000..4c69487c8 --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/themes/base/jquery.ui.menu.css @@ -0,0 +1,30 @@ +/*! + * jQuery UI Menu 1.9.0 + * http://jqueryui.com + * + * Copyright 2012 jQuery Foundation and other contributors + * Released under the MIT license. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Menu#theming + */ +.ui-menu { list-style:none; padding: 2px; margin: 0; display:block; outline: none; } +.ui-menu .ui-menu { margin-top: -3px; position: absolute; } +.ui-menu .ui-menu-item { margin: 0; padding: 0; zoom: 1; width: 100%; } +.ui-menu .ui-menu-divider { margin: 5px -2px 5px -2px; height: 0; font-size: 0; line-height: 0; border-width: 1px 0 0 0; } +.ui-menu .ui-menu-item a { text-decoration: none; display: block; padding: 2px .4em; line-height: 1.5; zoom: 1; font-weight: normal; } +.ui-menu .ui-menu-item a.ui-state-focus, +.ui-menu .ui-menu-item a.ui-state-active { font-weight: normal; margin: -1px; } + +.ui-menu .ui-state-disabled { font-weight: normal; margin: .4em 0 .2em; line-height: 1.5; } +.ui-menu .ui-state-disabled a { cursor: default; } + +/* icon support */ +.ui-menu-icons { position: relative; } +.ui-menu-icons .ui-menu-item a { position: relative; padding-left: 2em; } + +/* left-aligned */ +.ui-menu .ui-icon { position: absolute; top: .2em; left: .2em; } + +/* right-aligned */ +.ui-menu .ui-menu-icon { position: static; float: right; } diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/themes/base/jquery.ui.progressbar.css b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/themes/base/jquery.ui.progressbar.css new file mode 100755 index 000000000..7bf1ab62f --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/themes/base/jquery.ui.progressbar.css @@ -0,0 +1,12 @@ +/*! + * jQuery UI Progressbar 1.9.0 + * http://jqueryui.com + * + * Copyright 2012 jQuery Foundation and other contributors + * Released under the MIT license. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Progressbar#theming + */ +.ui-progressbar { height:2em; text-align: left; overflow: hidden; } +.ui-progressbar .ui-progressbar-value {margin: -1px; height:100%; } \ No newline at end of file diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/themes/base/jquery.ui.resizable.css b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/themes/base/jquery.ui.resizable.css new file mode 100755 index 000000000..d3bf451a6 --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/themes/base/jquery.ui.resizable.css @@ -0,0 +1,21 @@ +/*! + * jQuery UI Resizable 1.9.0 + * http://jqueryui.com + * + * Copyright 2012 jQuery Foundation and other contributors + * Released under the MIT license. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Resizable#theming + */ +.ui-resizable { position: relative;} +.ui-resizable-handle { position: absolute;font-size: 0.1px; 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;} \ No newline at end of file diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/themes/base/jquery.ui.selectable.css b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/themes/base/jquery.ui.selectable.css new file mode 100755 index 000000000..65063cf2f --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/themes/base/jquery.ui.selectable.css @@ -0,0 +1,11 @@ +/*! + * jQuery UI Selectable 1.9.0 + * http://jqueryui.com + * + * Copyright 2012 jQuery Foundation and other contributors + * Released under the MIT license. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Selectable#theming + */ +.ui-selectable-helper { position: absolute; z-index: 100; border:1px dotted black; } diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/themes/base/jquery.ui.slider.css b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/themes/base/jquery.ui.slider.css new file mode 100755 index 000000000..c645a303d --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/themes/base/jquery.ui.slider.css @@ -0,0 +1,25 @@ +/*! + * jQuery UI Slider 1.9.0 + * http://jqueryui.com + * + * Copyright 2012 jQuery Foundation and other contributors + * Released under the MIT license. + * 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; } \ No newline at end of file diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/themes/base/jquery.ui.spinner.css b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/themes/base/jquery.ui.spinner.css new file mode 100755 index 000000000..82223c27e --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/themes/base/jquery.ui.spinner.css @@ -0,0 +1,24 @@ +/*! + * jQuery UI Spinner 1.9.0 + * http://jqueryui.com + * + * Copyright 2012 jQuery Foundation and other contributors + * Released under the MIT license. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Spinner#theming + */ +.ui-spinner { position:relative; display: inline-block; overflow: hidden; padding: 0; vertical-align: middle; } +.ui-spinner-input { border: none; background: none; padding: 0; margin: .2em 0; vertical-align: middle; margin-left: .4em; margin-right: 22px; } +.ui-spinner-button { width: 16px; height: 50%; font-size: .5em; padding: 0; margin: 0; z-index: 100; text-align: center; position: absolute; cursor: default; display: block; overflow: hidden; right: 0; } +.ui-spinner a.ui-spinner-button { border-top: none; border-bottom: none; border-right: none; } /* more specificity required here to overide default borders */ +.ui-spinner .ui-icon { position: absolute; margin-top: -8px; top: 50%; left: 0; } /* vertical centre icon */ +.ui-spinner-up { top: 0; } +.ui-spinner-down { bottom: 0; } + +/* TR overrides */ +span.ui-spinner { background: none; } +.ui-spinner .ui-icon-triangle-1-s { + /* need to fix icons sprite */ + background-position:-65px -16px; +} diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/themes/base/jquery.ui.tabs.css b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/themes/base/jquery.ui.tabs.css new file mode 100755 index 000000000..6936f86b6 --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/themes/base/jquery.ui.tabs.css @@ -0,0 +1,18 @@ +/*! + * jQuery UI Tabs 1.9.0 + * http://jqueryui.com + * + * Copyright 2012 jQuery Foundation and other contributors + * Released under the MIT license. + * 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: 0; margin: 1px .2em 0 0; border-bottom: 0; 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-active { margin-bottom: -1px; padding-bottom: 1px; } +.ui-tabs .ui-tabs-nav li.ui-tabs-active a, .ui-tabs .ui-tabs-nav li.ui-state-disabled a, .ui-tabs .ui-tabs-nav li.ui-tabs-loading a { cursor: text; } +.ui-tabs .ui-tabs-nav li a, .ui-tabs-collapsible .ui-tabs-nav li.ui-tabs-active 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; } diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/themes/base/jquery.ui.theme.css b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/themes/base/jquery.ui.theme.css new file mode 100755 index 000000000..3d226fa44 --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/themes/base/jquery.ui.theme.css @@ -0,0 +1,247 @@ +/*! + * jQuery UI CSS Framework 1.9.0 + * http://jqueryui.com + * + * Copyright 2012 jQuery Foundation and other contributors + * Released under the MIT license. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Theming/API + * + * To view and modify this theme, visit http://jqueryui.com/themeroller/ + */ + + +/* Component containers +----------------------------------*/ +.ui-widget { font-family: Verdana,Arial,sans-serif/*{ffDefault}*/; font-size: 1.1em/*{fsDefault}*/; } +.ui-widget .ui-widget { font-size: 1em; } +.ui-widget input, .ui-widget select, .ui-widget textarea, .ui-widget button { font-family: Verdana,Arial,sans-serif/*{ffDefault}*/; font-size: 1em; } +.ui-widget-content { border: 1px solid #aaaaaa/*{borderColorContent}*/; background: #ffffff/*{bgColorContent}*/ url(images/ui-bg_flat_75_ffffff_40x100.png)/*{bgImgUrlContent}*/ 50%/*{bgContentXPos}*/ 50%/*{bgContentYPos}*/ repeat-x/*{bgContentRepeat}*/; color: #222222/*{fcContent}*/; } +.ui-widget-content a { color: #222222/*{fcContent}*/; } +.ui-widget-header { border: 1px solid #aaaaaa/*{borderColorHeader}*/; background: #cccccc/*{bgColorHeader}*/ url(images/ui-bg_highlight-soft_75_cccccc_1x100.png)/*{bgImgUrlHeader}*/ 50%/*{bgHeaderXPos}*/ 50%/*{bgHeaderYPos}*/ repeat-x/*{bgHeaderRepeat}*/; color: #222222/*{fcHeader}*/; font-weight: bold; } +.ui-widget-header a { color: #222222/*{fcHeader}*/; } + +/* Interaction states +----------------------------------*/ +.ui-state-default, .ui-widget-content .ui-state-default, .ui-widget-header .ui-state-default { border: 1px solid #d3d3d3/*{borderColorDefault}*/; background: #e6e6e6/*{bgColorDefault}*/ url(images/ui-bg_glass_75_e6e6e6_1x400.png)/*{bgImgUrlDefault}*/ 50%/*{bgDefaultXPos}*/ 50%/*{bgDefaultYPos}*/ repeat-x/*{bgDefaultRepeat}*/; font-weight: normal/*{fwDefault}*/; color: #555555/*{fcDefault}*/; } +.ui-state-default a, .ui-state-default a:link, .ui-state-default a:visited { color: #555555/*{fcDefault}*/; 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 #999999/*{borderColorHover}*/; background: #dadada/*{bgColorHover}*/ url(images/ui-bg_glass_75_dadada_1x400.png)/*{bgImgUrlHover}*/ 50%/*{bgHoverXPos}*/ 50%/*{bgHoverYPos}*/ repeat-x/*{bgHoverRepeat}*/; font-weight: normal/*{fwDefault}*/; color: #212121/*{fcHover}*/; } +.ui-state-hover a, .ui-state-hover a:hover { color: #212121/*{fcHover}*/; text-decoration: none; } +.ui-state-active, .ui-widget-content .ui-state-active, .ui-widget-header .ui-state-active { border: 1px solid #aaaaaa/*{borderColorActive}*/; background: #ffffff/*{bgColorActive}*/ url(images/ui-bg_glass_65_ffffff_1x400.png)/*{bgImgUrlActive}*/ 50%/*{bgActiveXPos}*/ 50%/*{bgActiveYPos}*/ repeat-x/*{bgActiveRepeat}*/; font-weight: normal/*{fwDefault}*/; color: #212121/*{fcActive}*/; } +.ui-state-active a, .ui-state-active a:link, .ui-state-active a:visited { color: #212121/*{fcActive}*/; text-decoration: none; } + +/* Interaction Cues +----------------------------------*/ +.ui-state-highlight, .ui-widget-content .ui-state-highlight, .ui-widget-header .ui-state-highlight {border: 1px solid #fcefa1/*{borderColorHighlight}*/; background: #fbf9ee/*{bgColorHighlight}*/ url(images/ui-bg_glass_55_fbf9ee_1x400.png)/*{bgImgUrlHighlight}*/ 50%/*{bgHighlightXPos}*/ 50%/*{bgHighlightYPos}*/ repeat-x/*{bgHighlightRepeat}*/; color: #363636/*{fcHighlight}*/; } +.ui-state-highlight a, .ui-widget-content .ui-state-highlight a,.ui-widget-header .ui-state-highlight a { color: #363636/*{fcHighlight}*/; } +.ui-state-error, .ui-widget-content .ui-state-error, .ui-widget-header .ui-state-error {border: 1px solid #cd0a0a/*{borderColorError}*/; background: #fef1ec/*{bgColorError}*/ url(images/ui-bg_glass_95_fef1ec_1x400.png)/*{bgImgUrlError}*/ 50%/*{bgErrorXPos}*/ 50%/*{bgErrorYPos}*/ repeat-x/*{bgErrorRepeat}*/; color: #cd0a0a/*{fcError}*/; } +.ui-state-error a, .ui-widget-content .ui-state-error a, .ui-widget-header .ui-state-error a { color: #cd0a0a/*{fcError}*/; } +.ui-state-error-text, .ui-widget-content .ui-state-error-text, .ui-widget-header .ui-state-error-text { color: #cd0a0a/*{fcError}*/; } +.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)/*{iconsContent}*/; } +.ui-widget-content .ui-icon {background-image: url(images/ui-icons_222222_256x240.png)/*{iconsContent}*/; } +.ui-widget-header .ui-icon {background-image: url(images/ui-icons_222222_256x240.png)/*{iconsHeader}*/; } +.ui-state-default .ui-icon { background-image: url(images/ui-icons_888888_256x240.png)/*{iconsDefault}*/; } +.ui-state-hover .ui-icon, .ui-state-focus .ui-icon {background-image: url(images/ui-icons_454545_256x240.png)/*{iconsHover}*/; } +.ui-state-active .ui-icon {background-image: url(images/ui-icons_454545_256x240.png)/*{iconsActive}*/; } +.ui-state-highlight .ui-icon {background-image: url(images/ui-icons_2e83ff_256x240.png)/*{iconsHighlight}*/; } +.ui-state-error .ui-icon, .ui-state-error-text .ui-icon {background-image: url(images/ui-icons_cd0a0a_256x240.png)/*{iconsError}*/; } + +/* 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-on { background-position: -96px -144px; } +.ui-icon-radio-off { 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/*{cornerRadius}*/; -webkit-border-top-left-radius: 4px/*{cornerRadius}*/; -khtml-border-top-left-radius: 4px/*{cornerRadius}*/; border-top-left-radius: 4px/*{cornerRadius}*/; } +.ui-corner-all, .ui-corner-top, .ui-corner-right, .ui-corner-tr { -moz-border-radius-topright: 4px/*{cornerRadius}*/; -webkit-border-top-right-radius: 4px/*{cornerRadius}*/; -khtml-border-top-right-radius: 4px/*{cornerRadius}*/; border-top-right-radius: 4px/*{cornerRadius}*/; } +.ui-corner-all, .ui-corner-bottom, .ui-corner-left, .ui-corner-bl { -moz-border-radius-bottomleft: 4px/*{cornerRadius}*/; -webkit-border-bottom-left-radius: 4px/*{cornerRadius}*/; -khtml-border-bottom-left-radius: 4px/*{cornerRadius}*/; border-bottom-left-radius: 4px/*{cornerRadius}*/; } +.ui-corner-all, .ui-corner-bottom, .ui-corner-right, .ui-corner-br { -moz-border-radius-bottomright: 4px/*{cornerRadius}*/; -webkit-border-bottom-right-radius: 4px/*{cornerRadius}*/; -khtml-border-bottom-right-radius: 4px/*{cornerRadius}*/; border-bottom-right-radius: 4px/*{cornerRadius}*/; } + +/* Overlays */ +.ui-widget-overlay { background: #aaaaaa/*{bgColorOverlay}*/ url(images/ui-bg_flat_0_aaaaaa_40x100.png)/*{bgImgUrlOverlay}*/ 50%/*{bgOverlayXPos}*/ 50%/*{bgOverlayYPos}*/ repeat-x/*{bgOverlayRepeat}*/; opacity: .3;filter:Alpha(Opacity=30)/*{opacityOverlay}*/; } +.ui-widget-shadow { margin: -8px/*{offsetTopShadow}*/ 0 0 -8px/*{offsetLeftShadow}*/; padding: 8px/*{thicknessShadow}*/; background: #aaaaaa/*{bgColorShadow}*/ url(images/ui-bg_flat_0_aaaaaa_40x100.png)/*{bgImgUrlShadow}*/ 50%/*{bgShadowXPos}*/ 50%/*{bgShadowYPos}*/ repeat-x/*{bgShadowRepeat}*/; opacity: .3;filter:Alpha(Opacity=30)/*{opacityShadow}*/; -moz-border-radius: 8px/*{cornerRadiusShadow}*/; -khtml-border-radius: 8px/*{cornerRadiusShadow}*/; -webkit-border-radius: 8px/*{cornerRadiusShadow}*/; border-radius: 8px/*{cornerRadiusShadow}*/; } \ No newline at end of file diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/themes/base/jquery.ui.tooltip.css b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/themes/base/jquery.ui.tooltip.css new file mode 100755 index 000000000..d32438590 --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/themes/base/jquery.ui.tooltip.css @@ -0,0 +1,22 @@ +/*! + * jQuery UI Tooltip 1.9.0 + * http://jqueryui.com + * + * Copyright 2012 jQuery Foundation and other contributors + * Released under the MIT license. + * http://jquery.org/license + */ +.ui-tooltip { + padding:8px; + position:absolute; + z-index:9999; + -o-box-shadow: 0 0 5px #aaa; + -moz-box-shadow: 0 0 5px #aaa; + -webkit-box-shadow: 0 0 5px #aaa; + box-shadow: 0 0 5px #aaa; +} +/* Fades and background-images don't work well together in IE6, drop the image */ +* html .ui-tooltip { + background-image: none; +} +body .ui-tooltip { border-width:2px; } diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/themes/base/minified/images/ui-bg_flat_0_aaaaaa_40x100.png b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/themes/base/minified/images/ui-bg_flat_0_aaaaaa_40x100.png new file mode 100755 index 000000000..5b5dab2ab Binary files /dev/null and b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/themes/base/minified/images/ui-bg_flat_0_aaaaaa_40x100.png differ diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/themes/base/minified/images/ui-bg_flat_75_ffffff_40x100.png b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/themes/base/minified/images/ui-bg_flat_75_ffffff_40x100.png new file mode 100755 index 000000000..ac8b229af Binary files /dev/null and b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/themes/base/minified/images/ui-bg_flat_75_ffffff_40x100.png differ diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/themes/base/minified/images/ui-bg_glass_55_fbf9ee_1x400.png b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/themes/base/minified/images/ui-bg_glass_55_fbf9ee_1x400.png new file mode 100755 index 000000000..ad3d6346e Binary files /dev/null and b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/themes/base/minified/images/ui-bg_glass_55_fbf9ee_1x400.png differ diff --git a/htdocs/js/lib/vendor/jquery-ui-for-classlist3/development-bundle/themes/ui-lightness/images/ui-bg_glass_65_ffffff_1x400.png b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/themes/base/minified/images/ui-bg_glass_65_ffffff_1x400.png similarity index 100% rename from htdocs/js/lib/vendor/jquery-ui-for-classlist3/development-bundle/themes/ui-lightness/images/ui-bg_glass_65_ffffff_1x400.png rename to htdocs/js/jquery-ui-1.9.0.custom/development-bundle/themes/base/minified/images/ui-bg_glass_65_ffffff_1x400.png diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/themes/base/minified/images/ui-bg_glass_75_dadada_1x400.png b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/themes/base/minified/images/ui-bg_glass_75_dadada_1x400.png new file mode 100755 index 000000000..5a46b47cb Binary files /dev/null and b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/themes/base/minified/images/ui-bg_glass_75_dadada_1x400.png differ diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/themes/base/minified/images/ui-bg_glass_75_e6e6e6_1x400.png b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/themes/base/minified/images/ui-bg_glass_75_e6e6e6_1x400.png new file mode 100755 index 000000000..86c2baa65 Binary files /dev/null and b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/themes/base/minified/images/ui-bg_glass_75_e6e6e6_1x400.png differ diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/themes/base/minified/images/ui-bg_glass_95_fef1ec_1x400.png b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/themes/base/minified/images/ui-bg_glass_95_fef1ec_1x400.png new file mode 100755 index 000000000..4443fdc1a Binary files /dev/null and b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/themes/base/minified/images/ui-bg_glass_95_fef1ec_1x400.png differ diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/themes/base/minified/images/ui-bg_highlight-soft_75_cccccc_1x100.png b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/themes/base/minified/images/ui-bg_highlight-soft_75_cccccc_1x100.png new file mode 100755 index 000000000..7c9fa6c6e Binary files /dev/null and b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/themes/base/minified/images/ui-bg_highlight-soft_75_cccccc_1x100.png differ diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/themes/base/minified/images/ui-icons_222222_256x240.png b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/themes/base/minified/images/ui-icons_222222_256x240.png new file mode 100755 index 000000000..ee039dc09 Binary files /dev/null and b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/themes/base/minified/images/ui-icons_222222_256x240.png differ diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/themes/base/minified/images/ui-icons_2e83ff_256x240.png b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/themes/base/minified/images/ui-icons_2e83ff_256x240.png new file mode 100755 index 000000000..45e8928e5 Binary files /dev/null and b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/themes/base/minified/images/ui-icons_2e83ff_256x240.png differ diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/themes/base/minified/images/ui-icons_454545_256x240.png b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/themes/base/minified/images/ui-icons_454545_256x240.png new file mode 100755 index 000000000..7ec70d11b Binary files /dev/null and b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/themes/base/minified/images/ui-icons_454545_256x240.png differ diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/themes/base/minified/images/ui-icons_888888_256x240.png b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/themes/base/minified/images/ui-icons_888888_256x240.png new file mode 100755 index 000000000..5ba708c39 Binary files /dev/null and b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/themes/base/minified/images/ui-icons_888888_256x240.png differ diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/themes/base/minified/images/ui-icons_cd0a0a_256x240.png b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/themes/base/minified/images/ui-icons_cd0a0a_256x240.png new file mode 100755 index 000000000..7930a5580 Binary files /dev/null and b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/themes/base/minified/images/ui-icons_cd0a0a_256x240.png differ diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/themes/base/minified/jquery-ui.min.css b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/themes/base/minified/jquery-ui.min.css new file mode 100755 index 000000000..1ef9a7801 --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/themes/base/minified/jquery-ui.min.css @@ -0,0 +1,10 @@ +/*! jQuery UI - v1.9.0 - 2012-10-13 +* http://jqueryui.com +* Includes: jquery.ui.core.css, jquery.ui.resizable.css, jquery.ui.selectable.css, jquery.ui.accordion.css, jquery.ui.autocomplete.css, jquery.ui.button.css, jquery.ui.datepicker.css, jquery.ui.dialog.css, jquery.ui.menu.css, jquery.ui.progressbar.css, jquery.ui.slider.css, jquery.ui.spinner.css, jquery.ui.tabs.css, jquery.ui.tooltip.css +* Copyright (c) 2012 jQuery Foundation and other contributors Licensed MIT */ + +.ui-helper-hidden{display:none}.ui-helper-hidden-accessible{position:absolute!important;clip:rect(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:before,.ui-helper-clearfix:after{content:"";display:table}.ui-helper-clearfix:after{clear:both}.ui-helper-clearfix{zoom:1}.ui-helper-zfix{width:100%;height:100%;top:0;left:0;position:absolute;opacity:0;filter:Alpha(Opacity=0)}.ui-state-disabled{cursor:default!important}.ui-icon{display:block;text-indent:-99999px;overflow:hidden;background-repeat:no-repeat}.ui-widget-overlay{position:absolute;top:0;left:0;width:100%;height:100%}.ui-resizable{position:relative}.ui-resizable-handle{position:absolute;font-size:0.1px;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}.ui-selectable-helper{position:absolute;z-index:100;border:1px dotted black}.ui-accordion .ui-accordion-header{display:block;cursor:pointer;position:relative;margin-top:2px;padding:.5em .5em .5em .7em;zoom:1}.ui-accordion .ui-accordion-icons{padding-left:2.2em}.ui-accordion .ui-accordion-noicons{padding-left:.7em}.ui-accordion .ui-accordion-icons .ui-accordion-icons{padding-left:2.2em}.ui-accordion .ui-accordion-header .ui-accordion-header-icon{position:absolute;left:.5em;top:50%;margin-top:-8px}.ui-accordion .ui-accordion-content{padding:1em 2.2em;border-top:0;overflow:auto;zoom:1}.ui-autocomplete{position:absolute;cursor:default}* html .ui-autocomplete{width:1px}.ui-button{display:inline-block;position:relative;padding:0;margin-right:.1em;cursor:pointer;text-align:center;zoom:1;overflow:visible}.ui-button,.ui-button:link,.ui-button:visited,.ui-button:hover,.ui-button:active{text-decoration:none}.ui-button-icon-only{width:2.2em}button.ui-button-icon-only{width:2.4em}.ui-button-icons-only{width:3.4em}button.ui-button-icons-only{width:3.7em}.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}input.ui-button{padding:.4em 1em}.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}.ui-buttonset{margin-right:7px}.ui-buttonset .ui-button{margin-left:0;margin-right:-.3em}button.ui-button::-moz-focus-inner{border:0;padding:0}.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}.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}.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}.ui-datepicker-cover{position:absolute;z-index:-1;filter:mask();top:-4px;left:-4px;width:200px;height:200px}.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}.ui-menu{list-style:none;padding:2px;margin:0;display:block;outline:none}.ui-menu .ui-menu{margin-top:-3px;position:absolute}.ui-menu .ui-menu-item{margin:0;padding:0;zoom:1;width:100%}.ui-menu .ui-menu-divider{margin:5px -2px 5px -2px;height:0;font-size:0;line-height:0;border-width:1px 0 0 0}.ui-menu .ui-menu-item a{text-decoration:none;display:block;padding:2px .4em;line-height:1.5;zoom:1;font-weight:normal}.ui-menu .ui-menu-item a.ui-state-focus,.ui-menu .ui-menu-item a.ui-state-active{font-weight:normal;margin:-1px}.ui-menu .ui-state-disabled{font-weight:normal;margin:.4em 0 .2em;line-height:1.5}.ui-menu .ui-state-disabled a{cursor:default}.ui-menu-icons{position:relative}.ui-menu-icons .ui-menu-item a{position:relative;padding-left:2em}.ui-menu .ui-icon{position:absolute;top:.2em;left:.2em}.ui-menu .ui-menu-icon{position:static;float:right}.ui-progressbar{height:2em;text-align:left;overflow:hidden}.ui-progressbar .ui-progressbar-value{margin:-1px;height:100%}.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}.ui-spinner{position:relative;display:inline-block;overflow:hidden;padding:0;vertical-align:middle}.ui-spinner-input{border:none;background:none;padding:0;margin:.2em 0;vertical-align:middle;margin-left:.4em;margin-right:22px}.ui-spinner-button{width:16px;height:50%;font-size:.5em;padding:0;margin:0;z-index:100;text-align:center;position:absolute;cursor:default;display:block;overflow:hidden;right:0}.ui-spinner a.ui-spinner-button{border-top:none;border-bottom:none;border-right:none}.ui-spinner .ui-icon{position:absolute;margin-top:-8px;top:50%;left:0}.ui-spinner-up{top:0}.ui-spinner-down{bottom:0}span.ui-spinner{background:none}.ui-spinner .ui-icon-triangle-1-s{background-position:-65px -16px}.ui-tabs{position:relative;padding:.2em;zoom:1}.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:0;margin:1px .2em 0 0;border-bottom:0;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-active{margin-bottom:-1px;padding-bottom:1px}.ui-tabs .ui-tabs-nav li.ui-tabs-active a,.ui-tabs .ui-tabs-nav li.ui-state-disabled a,.ui-tabs .ui-tabs-nav li.ui-tabs-loading a{cursor:text}.ui-tabs .ui-tabs-nav li a,.ui-tabs-collapsible .ui-tabs-nav li.ui-tabs-active a{cursor:pointer}.ui-tabs .ui-tabs-panel{display:block;border-width:0;padding:1em 1.4em;background:none}.ui-tooltip{padding:8px;position:absolute;z-index:9999;-o-box-shadow:0 0 5px #aaa;-moz-box-shadow:0 0 5px #aaa;-webkit-box-shadow:0 0 5px #aaa;box-shadow:0 0 5px #aaa}* html .ui-tooltip{background-image:none}body .ui-tooltip{border-width:2px}/*! jQuery UI - v1.9.0 - 2012-10-08 +* http://jqueryui.com +* Includes: jquery.ui.theme.css +* Copyright 2012 jQuery Foundation and other contributors; Licensed MIT */ +.ui-widget{font-family: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:Verdana,Arial,sans-serif;font-size:1em}.ui-widget-content{border:1px solid #aaa;background:#fff url(images/ui-bg_flat_75_ffffff_40x100.png) 50% 50% repeat-x;color:#222}.ui-widget-content a{color:#222}.ui-widget-header{border:1px solid #aaa;background:#ccc url(images/ui-bg_highlight-soft_75_cccccc_1x100.png) 50% 50% repeat-x;color:#222;font-weight:bold}.ui-widget-header a{color:#222}.ui-state-default,.ui-widget-content .ui-state-default,.ui-widget-header .ui-state-default{border:1px solid #d3d3d3;background:#e6e6e6 url(images/ui-bg_glass_75_e6e6e6_1x400.png) 50% 50% repeat-x;font-weight:normal;color:#555}.ui-state-default a,.ui-state-default a:link,.ui-state-default a:visited{color:#555;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 #999;background:#dadada url(images/ui-bg_glass_75_dadada_1x400.png) 50% 50% repeat-x;font-weight:normal;color:#212121}.ui-state-hover a,.ui-state-hover a:hover{color:#212121;text-decoration:none}.ui-state-active,.ui-widget-content .ui-state-active,.ui-widget-header .ui-state-active{border:1px solid #aaa;background:#fff url(images/ui-bg_glass_65_ffffff_1x400.png) 50% 50% repeat-x;font-weight:normal;color:#212121}.ui-state-active a,.ui-state-active a:link,.ui-state-active a:visited{color:#212121;text-decoration:none}.ui-state-highlight,.ui-widget-content .ui-state-highlight,.ui-widget-header .ui-state-highlight{border:1px solid #fcefa1;background:#fbf9ee url(images/ui-bg_glass_55_fbf9ee_1x400.png) 50% 50% 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:#fef1ec url(images/ui-bg_glass_95_fef1ec_1x400.png) 50% 50% repeat-x;color:#cd0a0a}.ui-state-error a,.ui-widget-content .ui-state-error a,.ui-widget-header .ui-state-error a{color:#cd0a0a}.ui-state-error-text,.ui-widget-content .ui-state-error-text,.ui-widget-header .ui-state-error-text{color:#cd0a0a}.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}.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_222222_256x240.png)}.ui-state-default .ui-icon{background-image:url(images/ui-icons_888888_256x240.png)}.ui-state-hover .ui-icon,.ui-state-focus .ui-icon{background-image:url(images/ui-icons_454545_256x240.png)}.ui-state-active .ui-icon{background-image:url(images/ui-icons_454545_256x240.png)}.ui-state-highlight .ui-icon{background-image:url(images/ui-icons_2e83ff_256x240.png)}.ui-state-error .ui-icon,.ui-state-error-text .ui-icon{background-image:url(images/ui-icons_cd0a0a_256x240.png)}.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-on{background-position:-96px -144px}.ui-icon-radio-off{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{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}.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}.ui-widget-overlay{background:#aaa url(images/ui-bg_flat_0_aaaaaa_40x100.png) 50% 50% repeat-x;opacity:.3;filter:Alpha(Opacity=30)}.ui-widget-shadow{margin:-8px 0 0 -8px;padding:8px;background:#aaa url(images/ui-bg_flat_0_aaaaaa_40x100.png) 50% 50% repeat-x;opacity:.3;filter:Alpha(Opacity=30);-moz-border-radius:8px;-khtml-border-radius:8px;-webkit-border-radius:8px;border-radius:8px} \ No newline at end of file diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/themes/base/minified/jquery.ui.accordion.min.css b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/themes/base/minified/jquery.ui.accordion.min.css new file mode 100755 index 000000000..34928c9fe --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/themes/base/minified/jquery.ui.accordion.min.css @@ -0,0 +1,5 @@ +/*! jQuery UI - v1.9.0 - 2012-10-08 +* http://jqueryui.com +* Includes: jquery.ui.accordion.css +* Copyright 2012 jQuery Foundation and other contributors; Licensed MIT */ +.ui-accordion .ui-accordion-header{display:block;cursor:pointer;position:relative;margin-top:2px;padding:.5em .5em .5em .7em;zoom:1}.ui-accordion .ui-accordion-icons{padding-left:2.2em}.ui-accordion .ui-accordion-noicons{padding-left:.7em}.ui-accordion .ui-accordion-icons .ui-accordion-icons{padding-left:2.2em}.ui-accordion .ui-accordion-header .ui-accordion-header-icon{position:absolute;left:.5em;top:50%;margin-top:-8px}.ui-accordion .ui-accordion-content{padding:1em 2.2em;border-top:0;overflow:auto;zoom:1} \ No newline at end of file diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/themes/base/minified/jquery.ui.autocomplete.min.css b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/themes/base/minified/jquery.ui.autocomplete.min.css new file mode 100755 index 000000000..087cc3db1 --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/themes/base/minified/jquery.ui.autocomplete.min.css @@ -0,0 +1,5 @@ +/*! jQuery UI - v1.9.0 - 2012-10-08 +* http://jqueryui.com +* Includes: jquery.ui.autocomplete.css +* Copyright 2012 jQuery Foundation and other contributors; Licensed MIT */ +.ui-autocomplete{position:absolute;cursor:default}* html .ui-autocomplete{width:1px} \ No newline at end of file diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/themes/base/minified/jquery.ui.button.min.css b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/themes/base/minified/jquery.ui.button.min.css new file mode 100755 index 000000000..df7c1c591 --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/themes/base/minified/jquery.ui.button.min.css @@ -0,0 +1,5 @@ +/*! jQuery UI - v1.9.0 - 2012-10-08 +* http://jqueryui.com +* Includes: jquery.ui.button.css +* Copyright 2012 jQuery Foundation and other contributors; Licensed MIT */ +.ui-button{display:inline-block;position:relative;padding:0;margin-right:.1em;cursor:pointer;text-align:center;zoom:1;overflow:visible}.ui-button,.ui-button:link,.ui-button:visited,.ui-button:hover,.ui-button:active{text-decoration:none}.ui-button-icon-only{width:2.2em}button.ui-button-icon-only{width:2.4em}.ui-button-icons-only{width:3.4em}button.ui-button-icons-only{width:3.7em}.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}input.ui-button{padding:.4em 1em}.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}.ui-buttonset{margin-right:7px}.ui-buttonset .ui-button{margin-left:0;margin-right:-.3em}button.ui-button::-moz-focus-inner{border:0;padding:0} \ No newline at end of file diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/themes/base/minified/jquery.ui.core.min.css b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/themes/base/minified/jquery.ui.core.min.css new file mode 100755 index 000000000..54f38a56d --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/themes/base/minified/jquery.ui.core.min.css @@ -0,0 +1,5 @@ +/*! jQuery UI - v1.9.0 - 2012-10-08 +* http://jqueryui.com +* Includes: jquery.ui.core.css +* Copyright 2012 jQuery Foundation and other contributors; Licensed MIT */ +.ui-helper-hidden{display:none}.ui-helper-hidden-accessible{position:absolute!important;clip:rect(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:before,.ui-helper-clearfix:after{content:"";display:table}.ui-helper-clearfix:after{clear:both}.ui-helper-clearfix{zoom:1}.ui-helper-zfix{width:100%;height:100%;top:0;left:0;position:absolute;opacity:0;filter:Alpha(Opacity=0)}.ui-state-disabled{cursor:default!important}.ui-icon{display:block;text-indent:-99999px;overflow:hidden;background-repeat:no-repeat}.ui-widget-overlay{position:absolute;top:0;left:0;width:100%;height:100%} \ No newline at end of file diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/themes/base/minified/jquery.ui.datepicker.min.css b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/themes/base/minified/jquery.ui.datepicker.min.css new file mode 100755 index 000000000..0438fbf71 --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/themes/base/minified/jquery.ui.datepicker.min.css @@ -0,0 +1,5 @@ +/*! jQuery UI - v1.9.0 - 2012-10-08 +* http://jqueryui.com +* Includes: jquery.ui.datepicker.css +* Copyright 2012 jQuery Foundation and other contributors; Licensed MIT */ +.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}.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}.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}.ui-datepicker-cover{position:absolute;z-index:-1;filter:mask();top:-4px;left:-4px;width:200px;height:200px} \ No newline at end of file diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/themes/base/minified/jquery.ui.dialog.min.css b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/themes/base/minified/jquery.ui.dialog.min.css new file mode 100755 index 000000000..4efbf5c07 --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/themes/base/minified/jquery.ui.dialog.min.css @@ -0,0 +1,5 @@ +/*! jQuery UI - v1.9.0 - 2012-10-08 +* http://jqueryui.com +* Includes: jquery.ui.dialog.css +* Copyright 2012 jQuery Foundation and other contributors; Licensed MIT */ +.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} \ No newline at end of file diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/themes/base/minified/jquery.ui.menu.min.css b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/themes/base/minified/jquery.ui.menu.min.css new file mode 100755 index 000000000..db00f4bcf --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/themes/base/minified/jquery.ui.menu.min.css @@ -0,0 +1,5 @@ +/*! jQuery UI - v1.9.0 - 2012-10-08 +* http://jqueryui.com +* Includes: jquery.ui.menu.css +* Copyright 2012 jQuery Foundation and other contributors; Licensed MIT */ +.ui-menu{list-style:none;padding:2px;margin:0;display:block;outline:none}.ui-menu .ui-menu{margin-top:-3px;position:absolute}.ui-menu .ui-menu-item{margin:0;padding:0;zoom:1;width:100%}.ui-menu .ui-menu-divider{margin:5px -2px 5px -2px;height:0;font-size:0;line-height:0;border-width:1px 0 0 0}.ui-menu .ui-menu-item a{text-decoration:none;display:block;padding:2px .4em;line-height:1.5;zoom:1;font-weight:normal}.ui-menu .ui-menu-item a.ui-state-focus,.ui-menu .ui-menu-item a.ui-state-active{font-weight:normal;margin:-1px}.ui-menu .ui-state-disabled{font-weight:normal;margin:.4em 0 .2em;line-height:1.5}.ui-menu .ui-state-disabled a{cursor:default}.ui-menu-icons{position:relative}.ui-menu-icons .ui-menu-item a{position:relative;padding-left:2em}.ui-menu .ui-icon{position:absolute;top:.2em;left:.2em}.ui-menu .ui-menu-icon{position:static;float:right} \ No newline at end of file diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/themes/base/minified/jquery.ui.progressbar.min.css b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/themes/base/minified/jquery.ui.progressbar.min.css new file mode 100755 index 000000000..be5490b14 --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/themes/base/minified/jquery.ui.progressbar.min.css @@ -0,0 +1,5 @@ +/*! jQuery UI - v1.9.0 - 2012-10-08 +* http://jqueryui.com +* Includes: jquery.ui.progressbar.css +* Copyright 2012 jQuery Foundation and other contributors; Licensed MIT */ +.ui-progressbar{height:2em;text-align:left;overflow:hidden}.ui-progressbar .ui-progressbar-value{margin:-1px;height:100%} \ No newline at end of file diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/themes/base/minified/jquery.ui.resizable.min.css b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/themes/base/minified/jquery.ui.resizable.min.css new file mode 100755 index 000000000..b6426bcf6 --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/themes/base/minified/jquery.ui.resizable.min.css @@ -0,0 +1,5 @@ +/*! jQuery UI - v1.9.0 - 2012-10-08 +* http://jqueryui.com +* Includes: jquery.ui.resizable.css +* Copyright 2012 jQuery Foundation and other contributors; Licensed MIT */ +.ui-resizable{position:relative}.ui-resizable-handle{position:absolute;font-size:0.1px;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} \ No newline at end of file diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/themes/base/minified/jquery.ui.selectable.min.css b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/themes/base/minified/jquery.ui.selectable.min.css new file mode 100755 index 000000000..b5a5ecbbb --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/themes/base/minified/jquery.ui.selectable.min.css @@ -0,0 +1,5 @@ +/*! jQuery UI - v1.9.0 - 2012-10-08 +* http://jqueryui.com +* Includes: jquery.ui.selectable.css +* Copyright 2012 jQuery Foundation and other contributors; Licensed MIT */ +.ui-selectable-helper{position:absolute;z-index:100;border:1px dotted black} \ No newline at end of file diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/themes/base/minified/jquery.ui.slider.min.css b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/themes/base/minified/jquery.ui.slider.min.css new file mode 100755 index 000000000..b6a02ecf2 --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/themes/base/minified/jquery.ui.slider.min.css @@ -0,0 +1,5 @@ +/*! jQuery UI - v1.9.0 - 2012-10-08 +* http://jqueryui.com +* Includes: jquery.ui.slider.css +* Copyright 2012 jQuery Foundation and other contributors; Licensed MIT */ +.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} \ No newline at end of file diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/themes/base/minified/jquery.ui.spinner.min.css b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/themes/base/minified/jquery.ui.spinner.min.css new file mode 100755 index 000000000..7666e81fd --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/themes/base/minified/jquery.ui.spinner.min.css @@ -0,0 +1,5 @@ +/*! jQuery UI - v1.9.0 - 2012-10-08 +* http://jqueryui.com +* Includes: jquery.ui.spinner.css +* Copyright 2012 jQuery Foundation and other contributors; Licensed MIT */ +.ui-spinner{position:relative;display:inline-block;overflow:hidden;padding:0;vertical-align:middle}.ui-spinner-input{border:none;background:none;padding:0;margin:.2em 0;vertical-align:middle;margin-left:.4em;margin-right:22px}.ui-spinner-button{width:16px;height:50%;font-size:.5em;padding:0;margin:0;z-index:100;text-align:center;position:absolute;cursor:default;display:block;overflow:hidden;right:0}.ui-spinner a.ui-spinner-button{border-top:none;border-bottom:none;border-right:none}.ui-spinner .ui-icon{position:absolute;margin-top:-8px;top:50%;left:0}.ui-spinner-up{top:0}.ui-spinner-down{bottom:0}span.ui-spinner{background:none}.ui-spinner .ui-icon-triangle-1-s{background-position:-65px -16px} \ No newline at end of file diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/themes/base/minified/jquery.ui.tabs.min.css b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/themes/base/minified/jquery.ui.tabs.min.css new file mode 100755 index 000000000..9a67b002a --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/themes/base/minified/jquery.ui.tabs.min.css @@ -0,0 +1,5 @@ +/*! jQuery UI - v1.9.0 - 2012-10-08 +* http://jqueryui.com +* Includes: jquery.ui.tabs.css +* Copyright 2012 jQuery Foundation and other contributors; Licensed MIT */ +.ui-tabs{position:relative;padding:.2em;zoom:1}.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:0;margin:1px .2em 0 0;border-bottom:0;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-active{margin-bottom:-1px;padding-bottom:1px}.ui-tabs .ui-tabs-nav li.ui-tabs-active a,.ui-tabs .ui-tabs-nav li.ui-state-disabled a,.ui-tabs .ui-tabs-nav li.ui-tabs-loading a{cursor:text}.ui-tabs .ui-tabs-nav li a,.ui-tabs-collapsible .ui-tabs-nav li.ui-tabs-active a{cursor:pointer}.ui-tabs .ui-tabs-panel{display:block;border-width:0;padding:1em 1.4em;background:none} \ No newline at end of file diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/themes/base/minified/jquery.ui.theme.min.css b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/themes/base/minified/jquery.ui.theme.min.css new file mode 100755 index 000000000..6785173ef --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/themes/base/minified/jquery.ui.theme.min.css @@ -0,0 +1,5 @@ +/*! jQuery UI - v1.9.0 - 2012-10-08 +* http://jqueryui.com +* Includes: jquery.ui.theme.css +* Copyright 2012 jQuery Foundation and other contributors; Licensed MIT */ +.ui-widget{font-family: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:Verdana,Arial,sans-serif;font-size:1em}.ui-widget-content{border:1px solid #aaa;background:#fff url(images/ui-bg_flat_75_ffffff_40x100.png) 50% 50% repeat-x;color:#222}.ui-widget-content a{color:#222}.ui-widget-header{border:1px solid #aaa;background:#ccc url(images/ui-bg_highlight-soft_75_cccccc_1x100.png) 50% 50% repeat-x;color:#222;font-weight:bold}.ui-widget-header a{color:#222}.ui-state-default,.ui-widget-content .ui-state-default,.ui-widget-header .ui-state-default{border:1px solid #d3d3d3;background:#e6e6e6 url(images/ui-bg_glass_75_e6e6e6_1x400.png) 50% 50% repeat-x;font-weight:normal;color:#555}.ui-state-default a,.ui-state-default a:link,.ui-state-default a:visited{color:#555;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 #999;background:#dadada url(images/ui-bg_glass_75_dadada_1x400.png) 50% 50% repeat-x;font-weight:normal;color:#212121}.ui-state-hover a,.ui-state-hover a:hover{color:#212121;text-decoration:none}.ui-state-active,.ui-widget-content .ui-state-active,.ui-widget-header .ui-state-active{border:1px solid #aaa;background:#fff url(images/ui-bg_glass_65_ffffff_1x400.png) 50% 50% repeat-x;font-weight:normal;color:#212121}.ui-state-active a,.ui-state-active a:link,.ui-state-active a:visited{color:#212121;text-decoration:none}.ui-state-highlight,.ui-widget-content .ui-state-highlight,.ui-widget-header .ui-state-highlight{border:1px solid #fcefa1;background:#fbf9ee url(images/ui-bg_glass_55_fbf9ee_1x400.png) 50% 50% 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:#fef1ec url(images/ui-bg_glass_95_fef1ec_1x400.png) 50% 50% repeat-x;color:#cd0a0a}.ui-state-error a,.ui-widget-content .ui-state-error a,.ui-widget-header .ui-state-error a{color:#cd0a0a}.ui-state-error-text,.ui-widget-content .ui-state-error-text,.ui-widget-header .ui-state-error-text{color:#cd0a0a}.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}.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_222222_256x240.png)}.ui-state-default .ui-icon{background-image:url(images/ui-icons_888888_256x240.png)}.ui-state-hover .ui-icon,.ui-state-focus .ui-icon{background-image:url(images/ui-icons_454545_256x240.png)}.ui-state-active .ui-icon{background-image:url(images/ui-icons_454545_256x240.png)}.ui-state-highlight .ui-icon{background-image:url(images/ui-icons_2e83ff_256x240.png)}.ui-state-error .ui-icon,.ui-state-error-text .ui-icon{background-image:url(images/ui-icons_cd0a0a_256x240.png)}.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-on{background-position:-96px -144px}.ui-icon-radio-off{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{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}.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}.ui-widget-overlay{background:#aaa url(images/ui-bg_flat_0_aaaaaa_40x100.png) 50% 50% repeat-x;opacity:.3;filter:Alpha(Opacity=30)}.ui-widget-shadow{margin:-8px 0 0 -8px;padding:8px;background:#aaa url(images/ui-bg_flat_0_aaaaaa_40x100.png) 50% 50% repeat-x;opacity:.3;filter:Alpha(Opacity=30);-moz-border-radius:8px;-khtml-border-radius:8px;-webkit-border-radius:8px;border-radius:8px} \ No newline at end of file diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/themes/base/minified/jquery.ui.tooltip.min.css b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/themes/base/minified/jquery.ui.tooltip.min.css new file mode 100755 index 000000000..8e18709fe --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/themes/base/minified/jquery.ui.tooltip.min.css @@ -0,0 +1,5 @@ +/*! jQuery UI - v1.9.0 - 2012-10-08 +* http://jqueryui.com +* Includes: jquery.ui.tooltip.css +* Copyright 2012 jQuery Foundation and other contributors; Licensed MIT */ +.ui-tooltip{padding:8px;position:absolute;z-index:9999;-o-box-shadow:0 0 5px #aaa;-moz-box-shadow:0 0 5px #aaa;-webkit-box-shadow:0 0 5px #aaa;box-shadow:0 0 5px #aaa}* html .ui-tooltip{background-image:none}body .ui-tooltip{border-width:2px} \ No newline at end of file diff --git a/htdocs/js/lib/vendor/jquery-ui-for-classlist3/development-bundle/themes/ui-lightness/images/ui-bg_diagonals-thick_18_b81900_40x40.png b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/themes/ui-lightness/images/ui-bg_diagonals-thick_18_b81900_40x40.png similarity index 100% rename from htdocs/js/lib/vendor/jquery-ui-for-classlist3/development-bundle/themes/ui-lightness/images/ui-bg_diagonals-thick_18_b81900_40x40.png rename to htdocs/js/jquery-ui-1.9.0.custom/development-bundle/themes/ui-lightness/images/ui-bg_diagonals-thick_18_b81900_40x40.png diff --git a/htdocs/js/lib/vendor/jquery-ui-for-classlist3/development-bundle/themes/ui-lightness/images/ui-bg_diagonals-thick_20_666666_40x40.png b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/themes/ui-lightness/images/ui-bg_diagonals-thick_20_666666_40x40.png similarity index 100% rename from htdocs/js/lib/vendor/jquery-ui-for-classlist3/development-bundle/themes/ui-lightness/images/ui-bg_diagonals-thick_20_666666_40x40.png rename to htdocs/js/jquery-ui-1.9.0.custom/development-bundle/themes/ui-lightness/images/ui-bg_diagonals-thick_20_666666_40x40.png diff --git a/htdocs/js/lib/vendor/jquery-ui-for-classlist3/development-bundle/themes/ui-lightness/images/ui-bg_flat_10_000000_40x100.png b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/themes/ui-lightness/images/ui-bg_flat_10_000000_40x100.png similarity index 100% rename from htdocs/js/lib/vendor/jquery-ui-for-classlist3/development-bundle/themes/ui-lightness/images/ui-bg_flat_10_000000_40x100.png rename to htdocs/js/jquery-ui-1.9.0.custom/development-bundle/themes/ui-lightness/images/ui-bg_flat_10_000000_40x100.png diff --git a/htdocs/js/lib/vendor/jquery-ui-for-classlist3/development-bundle/themes/ui-lightness/images/ui-bg_glass_100_f6f6f6_1x400.png b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/themes/ui-lightness/images/ui-bg_glass_100_f6f6f6_1x400.png similarity index 100% rename from htdocs/js/lib/vendor/jquery-ui-for-classlist3/development-bundle/themes/ui-lightness/images/ui-bg_glass_100_f6f6f6_1x400.png rename to htdocs/js/jquery-ui-1.9.0.custom/development-bundle/themes/ui-lightness/images/ui-bg_glass_100_f6f6f6_1x400.png diff --git a/htdocs/js/lib/vendor/jquery-ui-for-classlist3/development-bundle/themes/ui-lightness/images/ui-bg_glass_100_fdf5ce_1x400.png b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/themes/ui-lightness/images/ui-bg_glass_100_fdf5ce_1x400.png similarity index 100% rename from htdocs/js/lib/vendor/jquery-ui-for-classlist3/development-bundle/themes/ui-lightness/images/ui-bg_glass_100_fdf5ce_1x400.png rename to htdocs/js/jquery-ui-1.9.0.custom/development-bundle/themes/ui-lightness/images/ui-bg_glass_100_fdf5ce_1x400.png diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/themes/ui-lightness/images/ui-bg_glass_65_ffffff_1x400.png b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/themes/ui-lightness/images/ui-bg_glass_65_ffffff_1x400.png new file mode 100755 index 000000000..42ccba269 Binary files /dev/null and b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/themes/ui-lightness/images/ui-bg_glass_65_ffffff_1x400.png differ diff --git a/htdocs/js/lib/vendor/jquery-ui-for-classlist3/development-bundle/themes/ui-lightness/images/ui-bg_gloss-wave_35_f6a828_500x100.png b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/themes/ui-lightness/images/ui-bg_gloss-wave_35_f6a828_500x100.png similarity index 100% rename from htdocs/js/lib/vendor/jquery-ui-for-classlist3/development-bundle/themes/ui-lightness/images/ui-bg_gloss-wave_35_f6a828_500x100.png rename to htdocs/js/jquery-ui-1.9.0.custom/development-bundle/themes/ui-lightness/images/ui-bg_gloss-wave_35_f6a828_500x100.png diff --git a/htdocs/js/lib/vendor/jquery-ui-for-classlist3/development-bundle/themes/ui-lightness/images/ui-bg_highlight-soft_100_eeeeee_1x100.png b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/themes/ui-lightness/images/ui-bg_highlight-soft_100_eeeeee_1x100.png similarity index 100% rename from htdocs/js/lib/vendor/jquery-ui-for-classlist3/development-bundle/themes/ui-lightness/images/ui-bg_highlight-soft_100_eeeeee_1x100.png rename to htdocs/js/jquery-ui-1.9.0.custom/development-bundle/themes/ui-lightness/images/ui-bg_highlight-soft_100_eeeeee_1x100.png diff --git a/htdocs/js/lib/vendor/jquery-ui-for-classlist3/development-bundle/themes/ui-lightness/images/ui-bg_highlight-soft_75_ffe45c_1x100.png b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/themes/ui-lightness/images/ui-bg_highlight-soft_75_ffe45c_1x100.png similarity index 100% rename from htdocs/js/lib/vendor/jquery-ui-for-classlist3/development-bundle/themes/ui-lightness/images/ui-bg_highlight-soft_75_ffe45c_1x100.png rename to htdocs/js/jquery-ui-1.9.0.custom/development-bundle/themes/ui-lightness/images/ui-bg_highlight-soft_75_ffe45c_1x100.png diff --git a/htdocs/js/lib/vendor/jquery-ui-for-classlist3/development-bundle/themes/ui-lightness/images/ui-icons_222222_256x240.png b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/themes/ui-lightness/images/ui-icons_222222_256x240.png similarity index 100% rename from htdocs/js/lib/vendor/jquery-ui-for-classlist3/development-bundle/themes/ui-lightness/images/ui-icons_222222_256x240.png rename to htdocs/js/jquery-ui-1.9.0.custom/development-bundle/themes/ui-lightness/images/ui-icons_222222_256x240.png diff --git a/htdocs/js/lib/vendor/jquery-ui-for-classlist3/development-bundle/themes/ui-lightness/images/ui-icons_228ef1_256x240.png b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/themes/ui-lightness/images/ui-icons_228ef1_256x240.png similarity index 100% rename from htdocs/js/lib/vendor/jquery-ui-for-classlist3/development-bundle/themes/ui-lightness/images/ui-icons_228ef1_256x240.png rename to htdocs/js/jquery-ui-1.9.0.custom/development-bundle/themes/ui-lightness/images/ui-icons_228ef1_256x240.png diff --git a/htdocs/js/lib/vendor/jquery-ui-for-classlist3/development-bundle/themes/ui-lightness/images/ui-icons_ef8c08_256x240.png b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/themes/ui-lightness/images/ui-icons_ef8c08_256x240.png similarity index 100% rename from htdocs/js/lib/vendor/jquery-ui-for-classlist3/development-bundle/themes/ui-lightness/images/ui-icons_ef8c08_256x240.png rename to htdocs/js/jquery-ui-1.9.0.custom/development-bundle/themes/ui-lightness/images/ui-icons_ef8c08_256x240.png diff --git a/htdocs/js/lib/vendor/jquery-ui-for-classlist3/development-bundle/themes/ui-lightness/images/ui-icons_ffd27a_256x240.png b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/themes/ui-lightness/images/ui-icons_ffd27a_256x240.png similarity index 100% rename from htdocs/js/lib/vendor/jquery-ui-for-classlist3/development-bundle/themes/ui-lightness/images/ui-icons_ffd27a_256x240.png rename to htdocs/js/jquery-ui-1.9.0.custom/development-bundle/themes/ui-lightness/images/ui-icons_ffd27a_256x240.png diff --git a/htdocs/js/lib/vendor/jquery-ui-for-classlist3/development-bundle/themes/ui-lightness/images/ui-icons_ffffff_256x240.png b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/themes/ui-lightness/images/ui-icons_ffffff_256x240.png similarity index 100% rename from htdocs/js/lib/vendor/jquery-ui-for-classlist3/development-bundle/themes/ui-lightness/images/ui-icons_ffffff_256x240.png rename to htdocs/js/jquery-ui-1.9.0.custom/development-bundle/themes/ui-lightness/images/ui-icons_ffffff_256x240.png diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/themes/ui-lightness/jquery-ui.css b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/themes/ui-lightness/jquery-ui.css new file mode 100755 index 000000000..12b99b1be --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/themes/ui-lightness/jquery-ui.css @@ -0,0 +1,458 @@ +/*! jQuery UI - v1.9.0 - 2012-10-13 +* http://jqueryui.com +* Includes: jquery.ui.core.css, jquery.ui.resizable.css, jquery.ui.selectable.css, jquery.ui.accordion.css, jquery.ui.autocomplete.css, jquery.ui.button.css, jquery.ui.datepicker.css, jquery.ui.dialog.css, jquery.ui.menu.css, jquery.ui.progressbar.css, jquery.ui.slider.css, jquery.ui.spinner.css, jquery.ui.tabs.css, jquery.ui.tooltip.css +* To view and modify this theme, visit http://jqueryui.com/themeroller/?ffDefault=Trebuchet%20MS%2CTahoma%2CVerdana%2CArial%2Csans-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 +* Copyright (c) 2012 jQuery Foundation and other contributors Licensed MIT */ + +/* Layout helpers +----------------------------------*/ +.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:before, .ui-helper-clearfix:after { content: ""; display: table; } +.ui-helper-clearfix:after { clear: both; } +.ui-helper-clearfix { zoom: 1; } +.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%; } +.ui-resizable { position: relative;} +.ui-resizable-handle { position: absolute;font-size: 0.1px; 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;}.ui-selectable-helper { position: absolute; z-index: 100; border:1px dotted black; } +.ui-accordion .ui-accordion-header { display: block; cursor: pointer; position: relative; margin-top: 2px; padding: .5em .5em .5em .7em; zoom: 1; } +.ui-accordion .ui-accordion-icons { padding-left: 2.2em; } +.ui-accordion .ui-accordion-noicons { padding-left: .7em; } +.ui-accordion .ui-accordion-icons .ui-accordion-icons { padding-left: 2.2em; } +.ui-accordion .ui-accordion-header .ui-accordion-header-icon { position: absolute; left: .5em; top: 50%; margin-top: -8px; } +.ui-accordion .ui-accordion-content { padding: 1em 2.2em; border-top: 0; overflow: auto; zoom: 1; } +.ui-autocomplete { position: absolute; cursor: default; } + +/* workarounds */ +* html .ui-autocomplete { width:1px; } /* without this, the menu expands to 100% in IE6 */ +.ui-button { display: inline-block; position: relative; padding: 0; margin-right: .1em; cursor: pointer; text-align: center; zoom: 1; overflow: visible; } /* the overflow property removes extra width in IE */ +.ui-button, .ui-button:link, .ui-button:visited, .ui-button:hover, .ui-button:active { text-decoration: none; } +.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 */ +.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 { + 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*/ +}.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; } +.ui-menu { list-style:none; padding: 2px; margin: 0; display:block; outline: none; } +.ui-menu .ui-menu { margin-top: -3px; position: absolute; } +.ui-menu .ui-menu-item { margin: 0; padding: 0; zoom: 1; width: 100%; } +.ui-menu .ui-menu-divider { margin: 5px -2px 5px -2px; height: 0; font-size: 0; line-height: 0; border-width: 1px 0 0 0; } +.ui-menu .ui-menu-item a { text-decoration: none; display: block; padding: 2px .4em; line-height: 1.5; zoom: 1; font-weight: normal; } +.ui-menu .ui-menu-item a.ui-state-focus, +.ui-menu .ui-menu-item a.ui-state-active { font-weight: normal; margin: -1px; } + +.ui-menu .ui-state-disabled { font-weight: normal; margin: .4em 0 .2em; line-height: 1.5; } +.ui-menu .ui-state-disabled a { cursor: default; } + +/* icon support */ +.ui-menu-icons { position: relative; } +.ui-menu-icons .ui-menu-item a { position: relative; padding-left: 2em; } + +/* left-aligned */ +.ui-menu .ui-icon { position: absolute; top: .2em; left: .2em; } + +/* right-aligned */ +.ui-menu .ui-menu-icon { position: static; float: right; } +.ui-progressbar { height:2em; text-align: left; overflow: hidden; } +.ui-progressbar .ui-progressbar-value {margin: -1px; height:100%; }.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; }.ui-spinner { position:relative; display: inline-block; overflow: hidden; padding: 0; vertical-align: middle; } +.ui-spinner-input { border: none; background: none; padding: 0; margin: .2em 0; vertical-align: middle; margin-left: .4em; margin-right: 22px; } +.ui-spinner-button { width: 16px; height: 50%; font-size: .5em; padding: 0; margin: 0; z-index: 100; text-align: center; position: absolute; cursor: default; display: block; overflow: hidden; right: 0; } +.ui-spinner a.ui-spinner-button { border-top: none; border-bottom: none; border-right: none; } /* more specificity required here to overide default borders */ +.ui-spinner .ui-icon { position: absolute; margin-top: -8px; top: 50%; left: 0; } /* vertical centre icon */ +.ui-spinner-up { top: 0; } +.ui-spinner-down { bottom: 0; } + +/* TR overrides */ +span.ui-spinner { background: none; } +.ui-spinner .ui-icon-triangle-1-s { + /* need to fix icons sprite */ + background-position:-65px -16px; +} +.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: 0; margin: 1px .2em 0 0; border-bottom: 0; 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-active { margin-bottom: -1px; padding-bottom: 1px; } +.ui-tabs .ui-tabs-nav li.ui-tabs-active a, .ui-tabs .ui-tabs-nav li.ui-state-disabled a, .ui-tabs .ui-tabs-nav li.ui-tabs-loading a { cursor: text; } +.ui-tabs .ui-tabs-nav li a, .ui-tabs-collapsible .ui-tabs-nav li.ui-tabs-active 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-tooltip { + padding:8px; + position:absolute; + z-index:9999; + -o-box-shadow: 0 0 5px #aaa; + -moz-box-shadow: 0 0 5px #aaa; + -webkit-box-shadow: 0 0 5px #aaa; + box-shadow: 0 0 5px #aaa; +} +/* Fades and background-images don't work well together in IE6, drop the image */ +* html .ui-tooltip { + background-image: none; +} +body .ui-tooltip { border-width:2px; } + +/* 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; } + +/* 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-on { background-position: -96px -144px; } +.ui-icon-radio-off { 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: .5;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: .2;filter:Alpha(Opacity=20); -moz-border-radius: 5px; -khtml-border-radius: 5px; -webkit-border-radius: 5px; border-radius: 5px; } \ No newline at end of file diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/themes/ui-lightness/jquery.ui.accordion.css b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/themes/ui-lightness/jquery.ui.accordion.css new file mode 100755 index 000000000..608e04677 --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/themes/ui-lightness/jquery.ui.accordion.css @@ -0,0 +1,16 @@ +/*! + * jQuery UI Accordion 1.9.0 + * http://jqueryui.com + * + * Copyright 2012 jQuery Foundation and other contributors + * Released under the MIT license. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Accordion#theming + */ +.ui-accordion .ui-accordion-header { display: block; cursor: pointer; position: relative; margin-top: 2px; padding: .5em .5em .5em .7em; zoom: 1; } +.ui-accordion .ui-accordion-icons { padding-left: 2.2em; } +.ui-accordion .ui-accordion-noicons { padding-left: .7em; } +.ui-accordion .ui-accordion-icons .ui-accordion-icons { padding-left: 2.2em; } +.ui-accordion .ui-accordion-header .ui-accordion-header-icon { position: absolute; left: .5em; top: 50%; margin-top: -8px; } +.ui-accordion .ui-accordion-content { padding: 1em 2.2em; border-top: 0; overflow: auto; zoom: 1; } diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/themes/ui-lightness/jquery.ui.all.css b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/themes/ui-lightness/jquery.ui.all.css new file mode 100755 index 000000000..04f10a9da --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/themes/ui-lightness/jquery.ui.all.css @@ -0,0 +1,12 @@ +/*! + * jQuery UI CSS Framework 1.9.0 + * http://jqueryui.com + * + * Copyright 2012 jQuery Foundation and other contributors + * Released under the MIT license. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Theming + */ +@import "jquery.ui.base.css"; +@import "jquery.ui.theme.css"; diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/themes/ui-lightness/jquery.ui.autocomplete.css b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/themes/ui-lightness/jquery.ui.autocomplete.css new file mode 100755 index 000000000..e52e6feda --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/themes/ui-lightness/jquery.ui.autocomplete.css @@ -0,0 +1,14 @@ +/*! + * jQuery UI Autocomplete 1.9.0 + * http://jqueryui.com + * + * Copyright 2012 jQuery Foundation and other contributors + * Released under the MIT license. + * 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 */ diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/themes/ui-lightness/jquery.ui.base.css b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/themes/ui-lightness/jquery.ui.base.css new file mode 100755 index 000000000..061b058ba --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/themes/ui-lightness/jquery.ui.base.css @@ -0,0 +1,25 @@ +/*! + * jQuery UI CSS Framework 1.9.0 + * http://jqueryui.com + * + * Copyright 2012 jQuery Foundation and other contributors + * Released under the MIT license. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Theming + */ +@import url("jquery.ui.core.css"); + +@import url("jquery.ui.accordion.css"); +@import url("jquery.ui.autocomplete.css"); +@import url("jquery.ui.button.css"); +@import url("jquery.ui.datepicker.css"); +@import url("jquery.ui.dialog.css"); +@import url("jquery.ui.menu.css"); +@import url("jquery.ui.progressbar.css"); +@import url("jquery.ui.resizable.css"); +@import url("jquery.ui.selectable.css"); +@import url("jquery.ui.slider.css"); +@import url("jquery.ui.spinner.css"); +@import url("jquery.ui.tabs.css"); +@import url("jquery.ui.tooltip.css"); diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/themes/ui-lightness/jquery.ui.button.css b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/themes/ui-lightness/jquery.ui.button.css new file mode 100755 index 000000000..e24ce54aa --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/themes/ui-lightness/jquery.ui.button.css @@ -0,0 +1,40 @@ +/*! + * jQuery UI Button 1.9.0 + * http://jqueryui.com + * + * Copyright 2012 jQuery Foundation and other contributors + * Released under the MIT license. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Button#theming + */ +.ui-button { display: inline-block; position: relative; padding: 0; margin-right: .1em; cursor: pointer; text-align: center; zoom: 1; overflow: visible; } /* the overflow property removes extra width in IE */ +.ui-button, .ui-button:link, .ui-button:visited, .ui-button:hover, .ui-button:active { text-decoration: none; } +.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 */ diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/themes/ui-lightness/jquery.ui.core.css b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/themes/ui-lightness/jquery.ui.core.css new file mode 100755 index 000000000..988c6a4f6 --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/themes/ui-lightness/jquery.ui.core.css @@ -0,0 +1,39 @@ +/*! + * jQuery UI CSS Framework 1.9.0 + * http://jqueryui.com + * + * Copyright 2012 jQuery Foundation and other contributors + * Released under the MIT license. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Theming/API + */ + +/* Layout helpers +----------------------------------*/ +.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:before, .ui-helper-clearfix:after { content: ""; display: table; } +.ui-helper-clearfix:after { clear: both; } +.ui-helper-clearfix { zoom: 1; } +.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%; } diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/themes/ui-lightness/jquery.ui.datepicker.css b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/themes/ui-lightness/jquery.ui.datepicker.css new file mode 100755 index 000000000..9918aa1fe --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/themes/ui-lightness/jquery.ui.datepicker.css @@ -0,0 +1,67 @@ +/*! + * jQuery UI Datepicker 1.9.0 + * http://jqueryui.com + * + * Copyright 2012 jQuery Foundation and other contributors + * Released under the MIT license. + * 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 { + 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*/ +} \ No newline at end of file diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/themes/ui-lightness/jquery.ui.dialog.css b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/themes/ui-lightness/jquery.ui.dialog.css new file mode 100755 index 000000000..528527ba6 --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/themes/ui-lightness/jquery.ui.dialog.css @@ -0,0 +1,22 @@ +/*! + * jQuery UI Dialog 1.9.0 + * http://jqueryui.com + * + * Copyright 2012 jQuery Foundation and other contributors + * Released under the MIT license. + * 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; } diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/themes/ui-lightness/jquery.ui.menu.css b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/themes/ui-lightness/jquery.ui.menu.css new file mode 100755 index 000000000..4c69487c8 --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/themes/ui-lightness/jquery.ui.menu.css @@ -0,0 +1,30 @@ +/*! + * jQuery UI Menu 1.9.0 + * http://jqueryui.com + * + * Copyright 2012 jQuery Foundation and other contributors + * Released under the MIT license. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Menu#theming + */ +.ui-menu { list-style:none; padding: 2px; margin: 0; display:block; outline: none; } +.ui-menu .ui-menu { margin-top: -3px; position: absolute; } +.ui-menu .ui-menu-item { margin: 0; padding: 0; zoom: 1; width: 100%; } +.ui-menu .ui-menu-divider { margin: 5px -2px 5px -2px; height: 0; font-size: 0; line-height: 0; border-width: 1px 0 0 0; } +.ui-menu .ui-menu-item a { text-decoration: none; display: block; padding: 2px .4em; line-height: 1.5; zoom: 1; font-weight: normal; } +.ui-menu .ui-menu-item a.ui-state-focus, +.ui-menu .ui-menu-item a.ui-state-active { font-weight: normal; margin: -1px; } + +.ui-menu .ui-state-disabled { font-weight: normal; margin: .4em 0 .2em; line-height: 1.5; } +.ui-menu .ui-state-disabled a { cursor: default; } + +/* icon support */ +.ui-menu-icons { position: relative; } +.ui-menu-icons .ui-menu-item a { position: relative; padding-left: 2em; } + +/* left-aligned */ +.ui-menu .ui-icon { position: absolute; top: .2em; left: .2em; } + +/* right-aligned */ +.ui-menu .ui-menu-icon { position: static; float: right; } diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/themes/ui-lightness/jquery.ui.progressbar.css b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/themes/ui-lightness/jquery.ui.progressbar.css new file mode 100755 index 000000000..7bf1ab62f --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/themes/ui-lightness/jquery.ui.progressbar.css @@ -0,0 +1,12 @@ +/*! + * jQuery UI Progressbar 1.9.0 + * http://jqueryui.com + * + * Copyright 2012 jQuery Foundation and other contributors + * Released under the MIT license. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Progressbar#theming + */ +.ui-progressbar { height:2em; text-align: left; overflow: hidden; } +.ui-progressbar .ui-progressbar-value {margin: -1px; height:100%; } \ No newline at end of file diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/themes/ui-lightness/jquery.ui.resizable.css b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/themes/ui-lightness/jquery.ui.resizable.css new file mode 100755 index 000000000..d3bf451a6 --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/themes/ui-lightness/jquery.ui.resizable.css @@ -0,0 +1,21 @@ +/*! + * jQuery UI Resizable 1.9.0 + * http://jqueryui.com + * + * Copyright 2012 jQuery Foundation and other contributors + * Released under the MIT license. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Resizable#theming + */ +.ui-resizable { position: relative;} +.ui-resizable-handle { position: absolute;font-size: 0.1px; 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;} \ No newline at end of file diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/themes/ui-lightness/jquery.ui.selectable.css b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/themes/ui-lightness/jquery.ui.selectable.css new file mode 100755 index 000000000..65063cf2f --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/themes/ui-lightness/jquery.ui.selectable.css @@ -0,0 +1,11 @@ +/*! + * jQuery UI Selectable 1.9.0 + * http://jqueryui.com + * + * Copyright 2012 jQuery Foundation and other contributors + * Released under the MIT license. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Selectable#theming + */ +.ui-selectable-helper { position: absolute; z-index: 100; border:1px dotted black; } diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/themes/ui-lightness/jquery.ui.slider.css b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/themes/ui-lightness/jquery.ui.slider.css new file mode 100755 index 000000000..c645a303d --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/themes/ui-lightness/jquery.ui.slider.css @@ -0,0 +1,25 @@ +/*! + * jQuery UI Slider 1.9.0 + * http://jqueryui.com + * + * Copyright 2012 jQuery Foundation and other contributors + * Released under the MIT license. + * 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; } \ No newline at end of file diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/themes/ui-lightness/jquery.ui.spinner.css b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/themes/ui-lightness/jquery.ui.spinner.css new file mode 100755 index 000000000..82223c27e --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/themes/ui-lightness/jquery.ui.spinner.css @@ -0,0 +1,24 @@ +/*! + * jQuery UI Spinner 1.9.0 + * http://jqueryui.com + * + * Copyright 2012 jQuery Foundation and other contributors + * Released under the MIT license. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Spinner#theming + */ +.ui-spinner { position:relative; display: inline-block; overflow: hidden; padding: 0; vertical-align: middle; } +.ui-spinner-input { border: none; background: none; padding: 0; margin: .2em 0; vertical-align: middle; margin-left: .4em; margin-right: 22px; } +.ui-spinner-button { width: 16px; height: 50%; font-size: .5em; padding: 0; margin: 0; z-index: 100; text-align: center; position: absolute; cursor: default; display: block; overflow: hidden; right: 0; } +.ui-spinner a.ui-spinner-button { border-top: none; border-bottom: none; border-right: none; } /* more specificity required here to overide default borders */ +.ui-spinner .ui-icon { position: absolute; margin-top: -8px; top: 50%; left: 0; } /* vertical centre icon */ +.ui-spinner-up { top: 0; } +.ui-spinner-down { bottom: 0; } + +/* TR overrides */ +span.ui-spinner { background: none; } +.ui-spinner .ui-icon-triangle-1-s { + /* need to fix icons sprite */ + background-position:-65px -16px; +} diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/themes/ui-lightness/jquery.ui.tabs.css b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/themes/ui-lightness/jquery.ui.tabs.css new file mode 100755 index 000000000..6936f86b6 --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/themes/ui-lightness/jquery.ui.tabs.css @@ -0,0 +1,18 @@ +/*! + * jQuery UI Tabs 1.9.0 + * http://jqueryui.com + * + * Copyright 2012 jQuery Foundation and other contributors + * Released under the MIT license. + * 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: 0; margin: 1px .2em 0 0; border-bottom: 0; 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-active { margin-bottom: -1px; padding-bottom: 1px; } +.ui-tabs .ui-tabs-nav li.ui-tabs-active a, .ui-tabs .ui-tabs-nav li.ui-state-disabled a, .ui-tabs .ui-tabs-nav li.ui-tabs-loading a { cursor: text; } +.ui-tabs .ui-tabs-nav li a, .ui-tabs-collapsible .ui-tabs-nav li.ui-tabs-active 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; } diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/themes/ui-lightness/jquery.ui.theme.css b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/themes/ui-lightness/jquery.ui.theme.css new file mode 100755 index 000000000..5d9c2faf3 --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/themes/ui-lightness/jquery.ui.theme.css @@ -0,0 +1,247 @@ +/*! + * jQuery UI CSS Framework 1.9.0 + * http://jqueryui.com + * + * Copyright 2012 jQuery Foundation and other contributors + * Released under the MIT license. + * 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%2CTahoma%2CVerdana%2CArial%2Csans-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; } + +/* 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-on { background-position: -96px -144px; } +.ui-icon-radio-off { 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: .5;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: .2;filter:Alpha(Opacity=20); -moz-border-radius: 5px; -khtml-border-radius: 5px; -webkit-border-radius: 5px; border-radius: 5px; } \ No newline at end of file diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/themes/ui-lightness/jquery.ui.tooltip.css b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/themes/ui-lightness/jquery.ui.tooltip.css new file mode 100755 index 000000000..d32438590 --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/themes/ui-lightness/jquery.ui.tooltip.css @@ -0,0 +1,22 @@ +/*! + * jQuery UI Tooltip 1.9.0 + * http://jqueryui.com + * + * Copyright 2012 jQuery Foundation and other contributors + * Released under the MIT license. + * http://jquery.org/license + */ +.ui-tooltip { + padding:8px; + position:absolute; + z-index:9999; + -o-box-shadow: 0 0 5px #aaa; + -moz-box-shadow: 0 0 5px #aaa; + -webkit-box-shadow: 0 0 5px #aaa; + box-shadow: 0 0 5px #aaa; +} +/* Fades and background-images don't work well together in IE6, drop the image */ +* html .ui-tooltip { + background-image: none; +} +body .ui-tooltip { border-width:2px; } diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/themes/ui-lightness/minified/images/ui-bg_diagonals-thick_18_b81900_40x40.png b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/themes/ui-lightness/minified/images/ui-bg_diagonals-thick_18_b81900_40x40.png new file mode 100755 index 000000000..954e22dbd Binary files /dev/null and b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/themes/ui-lightness/minified/images/ui-bg_diagonals-thick_18_b81900_40x40.png differ diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/themes/ui-lightness/minified/images/ui-bg_diagonals-thick_20_666666_40x40.png b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/themes/ui-lightness/minified/images/ui-bg_diagonals-thick_20_666666_40x40.png new file mode 100755 index 000000000..64ece5707 Binary files /dev/null and b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/themes/ui-lightness/minified/images/ui-bg_diagonals-thick_20_666666_40x40.png differ diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/themes/ui-lightness/minified/images/ui-bg_flat_10_000000_40x100.png b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/themes/ui-lightness/minified/images/ui-bg_flat_10_000000_40x100.png new file mode 100755 index 000000000..abdc01082 Binary files /dev/null and b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/themes/ui-lightness/minified/images/ui-bg_flat_10_000000_40x100.png differ diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/themes/ui-lightness/minified/images/ui-bg_glass_100_f6f6f6_1x400.png b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/themes/ui-lightness/minified/images/ui-bg_glass_100_f6f6f6_1x400.png new file mode 100755 index 000000000..9b383f4d2 Binary files /dev/null and b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/themes/ui-lightness/minified/images/ui-bg_glass_100_f6f6f6_1x400.png differ diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/themes/ui-lightness/minified/images/ui-bg_glass_100_fdf5ce_1x400.png b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/themes/ui-lightness/minified/images/ui-bg_glass_100_fdf5ce_1x400.png new file mode 100755 index 000000000..a23baad25 Binary files /dev/null and b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/themes/ui-lightness/minified/images/ui-bg_glass_100_fdf5ce_1x400.png differ diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/themes/ui-lightness/minified/images/ui-bg_glass_65_ffffff_1x400.png b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/themes/ui-lightness/minified/images/ui-bg_glass_65_ffffff_1x400.png new file mode 100755 index 000000000..42ccba269 Binary files /dev/null and b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/themes/ui-lightness/minified/images/ui-bg_glass_65_ffffff_1x400.png differ diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/themes/ui-lightness/minified/images/ui-bg_gloss-wave_35_f6a828_500x100.png b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/themes/ui-lightness/minified/images/ui-bg_gloss-wave_35_f6a828_500x100.png new file mode 100755 index 000000000..39d5824d6 Binary files /dev/null and b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/themes/ui-lightness/minified/images/ui-bg_gloss-wave_35_f6a828_500x100.png differ diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/themes/ui-lightness/minified/images/ui-bg_highlight-soft_100_eeeeee_1x100.png b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/themes/ui-lightness/minified/images/ui-bg_highlight-soft_100_eeeeee_1x100.png new file mode 100755 index 000000000..f1273672d Binary files /dev/null and b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/themes/ui-lightness/minified/images/ui-bg_highlight-soft_100_eeeeee_1x100.png differ diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/themes/ui-lightness/minified/images/ui-bg_highlight-soft_75_ffe45c_1x100.png b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/themes/ui-lightness/minified/images/ui-bg_highlight-soft_75_ffe45c_1x100.png new file mode 100755 index 000000000..359397acf Binary files /dev/null and b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/themes/ui-lightness/minified/images/ui-bg_highlight-soft_75_ffe45c_1x100.png differ diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/themes/ui-lightness/minified/images/ui-icons_222222_256x240.png b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/themes/ui-lightness/minified/images/ui-icons_222222_256x240.png new file mode 100755 index 000000000..b273ff111 Binary files /dev/null and b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/themes/ui-lightness/minified/images/ui-icons_222222_256x240.png differ diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/themes/ui-lightness/minified/images/ui-icons_228ef1_256x240.png b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/themes/ui-lightness/minified/images/ui-icons_228ef1_256x240.png new file mode 100755 index 000000000..a641a371a Binary files /dev/null and b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/themes/ui-lightness/minified/images/ui-icons_228ef1_256x240.png differ diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/themes/ui-lightness/minified/images/ui-icons_ef8c08_256x240.png b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/themes/ui-lightness/minified/images/ui-icons_ef8c08_256x240.png new file mode 100755 index 000000000..85e63e9f6 Binary files /dev/null and b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/themes/ui-lightness/minified/images/ui-icons_ef8c08_256x240.png differ diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/themes/ui-lightness/minified/images/ui-icons_ffd27a_256x240.png b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/themes/ui-lightness/minified/images/ui-icons_ffd27a_256x240.png new file mode 100755 index 000000000..e117effa3 Binary files /dev/null and b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/themes/ui-lightness/minified/images/ui-icons_ffd27a_256x240.png differ diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/themes/ui-lightness/minified/images/ui-icons_ffffff_256x240.png b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/themes/ui-lightness/minified/images/ui-icons_ffffff_256x240.png new file mode 100755 index 000000000..42f8f992c Binary files /dev/null and b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/themes/ui-lightness/minified/images/ui-icons_ffffff_256x240.png differ diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/themes/ui-lightness/minified/jquery-ui.min.css b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/themes/ui-lightness/minified/jquery-ui.min.css new file mode 100755 index 000000000..ed3003d5e --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/themes/ui-lightness/minified/jquery-ui.min.css @@ -0,0 +1,5 @@ +/*! jQuery UI - v1.9.0 - 2012-10-13 +* http://jqueryui.com +* Includes: jquery.ui.core.css, jquery.ui.resizable.css, jquery.ui.selectable.css, jquery.ui.accordion.css, jquery.ui.autocomplete.css, jquery.ui.button.css, jquery.ui.datepicker.css, jquery.ui.dialog.css, jquery.ui.menu.css, jquery.ui.progressbar.css, jquery.ui.slider.css, jquery.ui.spinner.css, jquery.ui.tabs.css, jquery.ui.tooltip.css +* To view and modify this theme, visit http://jqueryui.com/themeroller/?ffDefault=Trebuchet%20MS%2CTahoma%2CVerdana%2CArial%2Csans-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 +* Copyright (c) 2012 jQuery Foundation and other contributors Licensed MIT */.ui-helper-hidden{display:none}.ui-helper-hidden-accessible{position:absolute!important;clip:rect(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:before,.ui-helper-clearfix:after{content:"";display:table}.ui-helper-clearfix:after{clear:both}.ui-helper-clearfix{zoom:1}.ui-helper-zfix{width:100%;height:100%;top:0;left:0;position:absolute;opacity:0;filter:Alpha(Opacity=0)}.ui-state-disabled{cursor:default!important}.ui-icon{display:block;text-indent:-99999px;overflow:hidden;background-repeat:no-repeat}.ui-widget-overlay{position:absolute;top:0;left:0;width:100%;height:100%}.ui-resizable{position:relative}.ui-resizable-handle{position:absolute;font-size:0.1px;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}.ui-selectable-helper{position:absolute;z-index:100;border:1px dotted black}.ui-accordion .ui-accordion-header{display:block;cursor:pointer;position:relative;margin-top:2px;padding:.5em .5em .5em .7em;zoom:1}.ui-accordion .ui-accordion-icons{padding-left:2.2em}.ui-accordion .ui-accordion-noicons{padding-left:.7em}.ui-accordion .ui-accordion-icons .ui-accordion-icons{padding-left:2.2em}.ui-accordion .ui-accordion-header .ui-accordion-header-icon{position:absolute;left:.5em;top:50%;margin-top:-8px}.ui-accordion .ui-accordion-content{padding:1em 2.2em;border-top:0;overflow:auto;zoom:1}.ui-autocomplete{position:absolute;cursor:default}* html .ui-autocomplete{width:1px}.ui-button{display:inline-block;position:relative;padding:0;margin-right:.1em;cursor:pointer;text-align:center;zoom:1;overflow:visible}.ui-button,.ui-button:link,.ui-button:visited,.ui-button:hover,.ui-button:active{text-decoration:none}.ui-button-icon-only{width:2.2em}button.ui-button-icon-only{width:2.4em}.ui-button-icons-only{width:3.4em}button.ui-button-icons-only{width:3.7em}.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}input.ui-button{padding:.4em 1em}.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}.ui-buttonset{margin-right:7px}.ui-buttonset .ui-button{margin-left:0;margin-right:-.3em}button.ui-button::-moz-focus-inner{border:0;padding:0}.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}.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}.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}.ui-datepicker-cover{position:absolute;z-index:-1;filter:mask();top:-4px;left:-4px;width:200px;height:200px}.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}.ui-menu{list-style:none;padding:2px;margin:0;display:block;outline:none}.ui-menu .ui-menu{margin-top:-3px;position:absolute}.ui-menu .ui-menu-item{margin:0;padding:0;zoom:1;width:100%}.ui-menu .ui-menu-divider{margin:5px -2px 5px -2px;height:0;font-size:0;line-height:0;border-width:1px 0 0 0}.ui-menu .ui-menu-item a{text-decoration:none;display:block;padding:2px .4em;line-height:1.5;zoom:1;font-weight:normal}.ui-menu .ui-menu-item a.ui-state-focus,.ui-menu .ui-menu-item a.ui-state-active{font-weight:normal;margin:-1px}.ui-menu .ui-state-disabled{font-weight:normal;margin:.4em 0 .2em;line-height:1.5}.ui-menu .ui-state-disabled a{cursor:default}.ui-menu-icons{position:relative}.ui-menu-icons .ui-menu-item a{position:relative;padding-left:2em}.ui-menu .ui-icon{position:absolute;top:.2em;left:.2em}.ui-menu .ui-menu-icon{position:static;float:right}.ui-progressbar{height:2em;text-align:left;overflow:hidden}.ui-progressbar .ui-progressbar-value{margin:-1px;height:100%}.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}.ui-spinner{position:relative;display:inline-block;overflow:hidden;padding:0;vertical-align:middle}.ui-spinner-input{border:none;background:none;padding:0;margin:.2em 0;vertical-align:middle;margin-left:.4em;margin-right:22px}.ui-spinner-button{width:16px;height:50%;font-size:.5em;padding:0;margin:0;z-index:100;text-align:center;position:absolute;cursor:default;display:block;overflow:hidden;right:0}.ui-spinner a.ui-spinner-button{border-top:none;border-bottom:none;border-right:none}.ui-spinner .ui-icon{position:absolute;margin-top:-8px;top:50%;left:0}.ui-spinner-up{top:0}.ui-spinner-down{bottom:0}span.ui-spinner{background:none}.ui-spinner .ui-icon-triangle-1-s{background-position:-65px -16px}.ui-tabs{position:relative;padding:.2em;zoom:1}.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:0;margin:1px .2em 0 0;border-bottom:0;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-active{margin-bottom:-1px;padding-bottom:1px}.ui-tabs .ui-tabs-nav li.ui-tabs-active a,.ui-tabs .ui-tabs-nav li.ui-state-disabled a,.ui-tabs .ui-tabs-nav li.ui-tabs-loading a{cursor:text}.ui-tabs .ui-tabs-nav li a,.ui-tabs-collapsible .ui-tabs-nav li.ui-tabs-active a{cursor:pointer}.ui-tabs .ui-tabs-panel{display:block;border-width:0;padding:1em 1.4em;background:none}.ui-tooltip{padding:8px;position:absolute;z-index:9999;-o-box-shadow:0 0 5px #aaa;-moz-box-shadow:0 0 5px #aaa;-webkit-box-shadow:0 0 5px #aaa;box-shadow:0 0 5px #aaa}* html .ui-tooltip{background-image:none}body .ui-tooltip{border-width:2px}.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 #ddd;background:#eee url(images/ui-bg_highlight-soft_100_eeeeee_1x100.png) 50% top repeat-x;color:#333}.ui-widget-content a{color:#333}.ui-widget-header{border:1px solid #e78f08;background:#f6a828 url(images/ui-bg_gloss-wave_35_f6a828_500x100.png) 50% 50% repeat-x;color:#fff;font-weight:bold}.ui-widget-header a{color:#fff}.ui-state-default,.ui-widget-content .ui-state-default,.ui-widget-header .ui-state-default{border:1px solid #ccc;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:#fff 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-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:#fff}.ui-state-error a,.ui-widget-content .ui-state-error a,.ui-widget-header .ui-state-error a{color:#fff}.ui-state-error-text,.ui-widget-content .ui-state-error-text,.ui-widget-header .ui-state-error-text{color:#fff}.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}.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)}.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-on{background-position:-96px -144px}.ui-icon-radio-off{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{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}.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}.ui-widget-overlay{background:#666 url(images/ui-bg_diagonals-thick_20_666666_40x40.png) 50% 50% repeat;opacity:.5;filter:Alpha(Opacity=50)}.ui-widget-shadow{margin:-5px 0 0 -5px;padding:5px;background:#000 url(images/ui-bg_flat_10_000000_40x100.png) 50% 50% repeat-x;opacity:.2;filter:Alpha(Opacity=20);-moz-border-radius:5px;-khtml-border-radius:5px;-webkit-border-radius:5px;border-radius:5px} \ No newline at end of file diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/themes/ui-lightness/minified/jquery.ui.accordion.min.css b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/themes/ui-lightness/minified/jquery.ui.accordion.min.css new file mode 100755 index 000000000..34928c9fe --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/themes/ui-lightness/minified/jquery.ui.accordion.min.css @@ -0,0 +1,5 @@ +/*! jQuery UI - v1.9.0 - 2012-10-08 +* http://jqueryui.com +* Includes: jquery.ui.accordion.css +* Copyright 2012 jQuery Foundation and other contributors; Licensed MIT */ +.ui-accordion .ui-accordion-header{display:block;cursor:pointer;position:relative;margin-top:2px;padding:.5em .5em .5em .7em;zoom:1}.ui-accordion .ui-accordion-icons{padding-left:2.2em}.ui-accordion .ui-accordion-noicons{padding-left:.7em}.ui-accordion .ui-accordion-icons .ui-accordion-icons{padding-left:2.2em}.ui-accordion .ui-accordion-header .ui-accordion-header-icon{position:absolute;left:.5em;top:50%;margin-top:-8px}.ui-accordion .ui-accordion-content{padding:1em 2.2em;border-top:0;overflow:auto;zoom:1} \ No newline at end of file diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/themes/ui-lightness/minified/jquery.ui.autocomplete.min.css b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/themes/ui-lightness/minified/jquery.ui.autocomplete.min.css new file mode 100755 index 000000000..087cc3db1 --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/themes/ui-lightness/minified/jquery.ui.autocomplete.min.css @@ -0,0 +1,5 @@ +/*! jQuery UI - v1.9.0 - 2012-10-08 +* http://jqueryui.com +* Includes: jquery.ui.autocomplete.css +* Copyright 2012 jQuery Foundation and other contributors; Licensed MIT */ +.ui-autocomplete{position:absolute;cursor:default}* html .ui-autocomplete{width:1px} \ No newline at end of file diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/themes/ui-lightness/minified/jquery.ui.button.min.css b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/themes/ui-lightness/minified/jquery.ui.button.min.css new file mode 100755 index 000000000..df7c1c591 --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/themes/ui-lightness/minified/jquery.ui.button.min.css @@ -0,0 +1,5 @@ +/*! jQuery UI - v1.9.0 - 2012-10-08 +* http://jqueryui.com +* Includes: jquery.ui.button.css +* Copyright 2012 jQuery Foundation and other contributors; Licensed MIT */ +.ui-button{display:inline-block;position:relative;padding:0;margin-right:.1em;cursor:pointer;text-align:center;zoom:1;overflow:visible}.ui-button,.ui-button:link,.ui-button:visited,.ui-button:hover,.ui-button:active{text-decoration:none}.ui-button-icon-only{width:2.2em}button.ui-button-icon-only{width:2.4em}.ui-button-icons-only{width:3.4em}button.ui-button-icons-only{width:3.7em}.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}input.ui-button{padding:.4em 1em}.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}.ui-buttonset{margin-right:7px}.ui-buttonset .ui-button{margin-left:0;margin-right:-.3em}button.ui-button::-moz-focus-inner{border:0;padding:0} \ No newline at end of file diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/themes/ui-lightness/minified/jquery.ui.core.min.css b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/themes/ui-lightness/minified/jquery.ui.core.min.css new file mode 100755 index 000000000..54f38a56d --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/themes/ui-lightness/minified/jquery.ui.core.min.css @@ -0,0 +1,5 @@ +/*! jQuery UI - v1.9.0 - 2012-10-08 +* http://jqueryui.com +* Includes: jquery.ui.core.css +* Copyright 2012 jQuery Foundation and other contributors; Licensed MIT */ +.ui-helper-hidden{display:none}.ui-helper-hidden-accessible{position:absolute!important;clip:rect(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:before,.ui-helper-clearfix:after{content:"";display:table}.ui-helper-clearfix:after{clear:both}.ui-helper-clearfix{zoom:1}.ui-helper-zfix{width:100%;height:100%;top:0;left:0;position:absolute;opacity:0;filter:Alpha(Opacity=0)}.ui-state-disabled{cursor:default!important}.ui-icon{display:block;text-indent:-99999px;overflow:hidden;background-repeat:no-repeat}.ui-widget-overlay{position:absolute;top:0;left:0;width:100%;height:100%} \ No newline at end of file diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/themes/ui-lightness/minified/jquery.ui.datepicker.min.css b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/themes/ui-lightness/minified/jquery.ui.datepicker.min.css new file mode 100755 index 000000000..0438fbf71 --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/themes/ui-lightness/minified/jquery.ui.datepicker.min.css @@ -0,0 +1,5 @@ +/*! jQuery UI - v1.9.0 - 2012-10-08 +* http://jqueryui.com +* Includes: jquery.ui.datepicker.css +* Copyright 2012 jQuery Foundation and other contributors; Licensed MIT */ +.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}.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}.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}.ui-datepicker-cover{position:absolute;z-index:-1;filter:mask();top:-4px;left:-4px;width:200px;height:200px} \ No newline at end of file diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/themes/ui-lightness/minified/jquery.ui.dialog.min.css b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/themes/ui-lightness/minified/jquery.ui.dialog.min.css new file mode 100755 index 000000000..4efbf5c07 --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/themes/ui-lightness/minified/jquery.ui.dialog.min.css @@ -0,0 +1,5 @@ +/*! jQuery UI - v1.9.0 - 2012-10-08 +* http://jqueryui.com +* Includes: jquery.ui.dialog.css +* Copyright 2012 jQuery Foundation and other contributors; Licensed MIT */ +.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} \ No newline at end of file diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/themes/ui-lightness/minified/jquery.ui.menu.min.css b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/themes/ui-lightness/minified/jquery.ui.menu.min.css new file mode 100755 index 000000000..db00f4bcf --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/themes/ui-lightness/minified/jquery.ui.menu.min.css @@ -0,0 +1,5 @@ +/*! jQuery UI - v1.9.0 - 2012-10-08 +* http://jqueryui.com +* Includes: jquery.ui.menu.css +* Copyright 2012 jQuery Foundation and other contributors; Licensed MIT */ +.ui-menu{list-style:none;padding:2px;margin:0;display:block;outline:none}.ui-menu .ui-menu{margin-top:-3px;position:absolute}.ui-menu .ui-menu-item{margin:0;padding:0;zoom:1;width:100%}.ui-menu .ui-menu-divider{margin:5px -2px 5px -2px;height:0;font-size:0;line-height:0;border-width:1px 0 0 0}.ui-menu .ui-menu-item a{text-decoration:none;display:block;padding:2px .4em;line-height:1.5;zoom:1;font-weight:normal}.ui-menu .ui-menu-item a.ui-state-focus,.ui-menu .ui-menu-item a.ui-state-active{font-weight:normal;margin:-1px}.ui-menu .ui-state-disabled{font-weight:normal;margin:.4em 0 .2em;line-height:1.5}.ui-menu .ui-state-disabled a{cursor:default}.ui-menu-icons{position:relative}.ui-menu-icons .ui-menu-item a{position:relative;padding-left:2em}.ui-menu .ui-icon{position:absolute;top:.2em;left:.2em}.ui-menu .ui-menu-icon{position:static;float:right} \ No newline at end of file diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/themes/ui-lightness/minified/jquery.ui.progressbar.min.css b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/themes/ui-lightness/minified/jquery.ui.progressbar.min.css new file mode 100755 index 000000000..be5490b14 --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/themes/ui-lightness/minified/jquery.ui.progressbar.min.css @@ -0,0 +1,5 @@ +/*! jQuery UI - v1.9.0 - 2012-10-08 +* http://jqueryui.com +* Includes: jquery.ui.progressbar.css +* Copyright 2012 jQuery Foundation and other contributors; Licensed MIT */ +.ui-progressbar{height:2em;text-align:left;overflow:hidden}.ui-progressbar .ui-progressbar-value{margin:-1px;height:100%} \ No newline at end of file diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/themes/ui-lightness/minified/jquery.ui.resizable.min.css b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/themes/ui-lightness/minified/jquery.ui.resizable.min.css new file mode 100755 index 000000000..b6426bcf6 --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/themes/ui-lightness/minified/jquery.ui.resizable.min.css @@ -0,0 +1,5 @@ +/*! jQuery UI - v1.9.0 - 2012-10-08 +* http://jqueryui.com +* Includes: jquery.ui.resizable.css +* Copyright 2012 jQuery Foundation and other contributors; Licensed MIT */ +.ui-resizable{position:relative}.ui-resizable-handle{position:absolute;font-size:0.1px;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} \ No newline at end of file diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/themes/ui-lightness/minified/jquery.ui.selectable.min.css b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/themes/ui-lightness/minified/jquery.ui.selectable.min.css new file mode 100755 index 000000000..b5a5ecbbb --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/themes/ui-lightness/minified/jquery.ui.selectable.min.css @@ -0,0 +1,5 @@ +/*! jQuery UI - v1.9.0 - 2012-10-08 +* http://jqueryui.com +* Includes: jquery.ui.selectable.css +* Copyright 2012 jQuery Foundation and other contributors; Licensed MIT */ +.ui-selectable-helper{position:absolute;z-index:100;border:1px dotted black} \ No newline at end of file diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/themes/ui-lightness/minified/jquery.ui.slider.min.css b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/themes/ui-lightness/minified/jquery.ui.slider.min.css new file mode 100755 index 000000000..b6a02ecf2 --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/themes/ui-lightness/minified/jquery.ui.slider.min.css @@ -0,0 +1,5 @@ +/*! jQuery UI - v1.9.0 - 2012-10-08 +* http://jqueryui.com +* Includes: jquery.ui.slider.css +* Copyright 2012 jQuery Foundation and other contributors; Licensed MIT */ +.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} \ No newline at end of file diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/themes/ui-lightness/minified/jquery.ui.spinner.min.css b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/themes/ui-lightness/minified/jquery.ui.spinner.min.css new file mode 100755 index 000000000..7666e81fd --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/themes/ui-lightness/minified/jquery.ui.spinner.min.css @@ -0,0 +1,5 @@ +/*! jQuery UI - v1.9.0 - 2012-10-08 +* http://jqueryui.com +* Includes: jquery.ui.spinner.css +* Copyright 2012 jQuery Foundation and other contributors; Licensed MIT */ +.ui-spinner{position:relative;display:inline-block;overflow:hidden;padding:0;vertical-align:middle}.ui-spinner-input{border:none;background:none;padding:0;margin:.2em 0;vertical-align:middle;margin-left:.4em;margin-right:22px}.ui-spinner-button{width:16px;height:50%;font-size:.5em;padding:0;margin:0;z-index:100;text-align:center;position:absolute;cursor:default;display:block;overflow:hidden;right:0}.ui-spinner a.ui-spinner-button{border-top:none;border-bottom:none;border-right:none}.ui-spinner .ui-icon{position:absolute;margin-top:-8px;top:50%;left:0}.ui-spinner-up{top:0}.ui-spinner-down{bottom:0}span.ui-spinner{background:none}.ui-spinner .ui-icon-triangle-1-s{background-position:-65px -16px} \ No newline at end of file diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/themes/ui-lightness/minified/jquery.ui.tabs.min.css b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/themes/ui-lightness/minified/jquery.ui.tabs.min.css new file mode 100755 index 000000000..9a67b002a --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/themes/ui-lightness/minified/jquery.ui.tabs.min.css @@ -0,0 +1,5 @@ +/*! jQuery UI - v1.9.0 - 2012-10-08 +* http://jqueryui.com +* Includes: jquery.ui.tabs.css +* Copyright 2012 jQuery Foundation and other contributors; Licensed MIT */ +.ui-tabs{position:relative;padding:.2em;zoom:1}.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:0;margin:1px .2em 0 0;border-bottom:0;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-active{margin-bottom:-1px;padding-bottom:1px}.ui-tabs .ui-tabs-nav li.ui-tabs-active a,.ui-tabs .ui-tabs-nav li.ui-state-disabled a,.ui-tabs .ui-tabs-nav li.ui-tabs-loading a{cursor:text}.ui-tabs .ui-tabs-nav li a,.ui-tabs-collapsible .ui-tabs-nav li.ui-tabs-active a{cursor:pointer}.ui-tabs .ui-tabs-panel{display:block;border-width:0;padding:1em 1.4em;background:none} \ No newline at end of file diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/themes/ui-lightness/minified/jquery.ui.theme.min.css b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/themes/ui-lightness/minified/jquery.ui.theme.min.css new file mode 100755 index 000000000..9f2fe3620 --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/themes/ui-lightness/minified/jquery.ui.theme.min.css @@ -0,0 +1,5 @@ +/*! jQuery UI - v1.9.0 - 2012-10-13 +* http://jqueryui.com +* Includes: jquery.ui.theme.css +* Copyright (c) 2012 jQuery Foundation and other contributors Licensed MIT */ +.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 #ddd;background:#eee url(images/ui-bg_highlight-soft_100_eeeeee_1x100.png) 50% top repeat-x;color:#333}.ui-widget-content a{color:#333}.ui-widget-header{border:1px solid #e78f08;background:#f6a828 url(images/ui-bg_gloss-wave_35_f6a828_500x100.png) 50% 50% repeat-x;color:#fff;font-weight:bold}.ui-widget-header a{color:#fff}.ui-state-default,.ui-widget-content .ui-state-default,.ui-widget-header .ui-state-default{border:1px solid #ccc;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:#fff 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-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:#fff}.ui-state-error a,.ui-widget-content .ui-state-error a,.ui-widget-header .ui-state-error a{color:#fff}.ui-state-error-text,.ui-widget-content .ui-state-error-text,.ui-widget-header .ui-state-error-text{color:#fff}.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}.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)}.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-on{background-position:-96px -144px}.ui-icon-radio-off{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{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}.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}.ui-widget-overlay{background:#666 url(images/ui-bg_diagonals-thick_20_666666_40x40.png) 50% 50% repeat;opacity:.5;filter:Alpha(Opacity=50)}.ui-widget-shadow{margin:-5px 0 0 -5px;padding:5px;background:#000 url(images/ui-bg_flat_10_000000_40x100.png) 50% 50% repeat-x;opacity:.2;filter:Alpha(Opacity=20);-moz-border-radius:5px;-khtml-border-radius:5px;-webkit-border-radius:5px;border-radius:5px} \ No newline at end of file diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/themes/ui-lightness/minified/jquery.ui.tooltip.min.css b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/themes/ui-lightness/minified/jquery.ui.tooltip.min.css new file mode 100755 index 000000000..8e18709fe --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/themes/ui-lightness/minified/jquery.ui.tooltip.min.css @@ -0,0 +1,5 @@ +/*! jQuery UI - v1.9.0 - 2012-10-08 +* http://jqueryui.com +* Includes: jquery.ui.tooltip.css +* Copyright 2012 jQuery Foundation and other contributors; Licensed MIT */ +.ui-tooltip{padding:8px;position:absolute;z-index:9999;-o-box-shadow:0 0 5px #aaa;-moz-box-shadow:0 0 5px #aaa;-webkit-box-shadow:0 0 5px #aaa;box-shadow:0 0 5px #aaa}* html .ui-tooltip{background-image:none}body .ui-tooltip{border-width:2px} \ No newline at end of file diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/ui.accordion.jquery.json b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/ui.accordion.jquery.json new file mode 100755 index 000000000..33b3100d2 --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/ui.accordion.jquery.json @@ -0,0 +1,62 @@ +{ + "name": "ui.accordion", + "title": "jQuery UI Accordion", + "description": "Displays collapsible content panels for presenting information in a limited amount of space.", + "keywords": [ + "ui", + "accordion", + "navigation", + "panel", + "collapse", + "expand" + ], + "version": "1.9.0", + "author": { + "name": "jQuery Foundation and other contributors", + "url": "https://github.com/jquery/jquery-ui/blob/1.9.0/AUTHORS.txt" + }, + "maintainers": [ + { + "name": "Scott González", + "email": "scott.gonzalez@gmail.com", + "url": "http://scottgonzalez.com" + }, + { + "name": "Jörn Zaefferer", + "email": "joern.zaefferer@gmail.com", + "url": "http://bassistance.de" + }, + { + "name": "Richard D. Worth", + "email": "rdworth@gmail.com", + "url": "http://rdworth.org" + }, + { + "name": "Kris Borchers", + "email": "kris.borchers@gmail.com", + "url": "http://krisborchers.com" + }, + { + "name": "Corey Frang", + "email": "gnarf37@gmail.com", + "url": "http://gnarf.net" + } + ], + "licenses": [ + { + "type": "MIT", + "url": "https://github.com/jquery/jquery-ui/blob/1.9.0/MIT-LICENSE.txt" + } + ], + "bugs": "http://bugs.jqueryui.com/", + "homepage": "http://jqueryui.com/accordion/", + "demo": "http://jqueryui.com/accordion/", + "docs": "http://api.jqueryui.com/accordion/", + "download": "http://jqueryui.com/download/", + "dependencies": { + "jquery": ">=1.6", + "ui.core": "1.9.0", + "ui.widget": "1.9.0" + }, + "category": "widget" +} diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/ui.autocomplete.jquery.json b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/ui.autocomplete.jquery.json new file mode 100755 index 000000000..569a6bff1 --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/ui.autocomplete.jquery.json @@ -0,0 +1,64 @@ +{ + "name": "ui.autocomplete", + "title": "jQuery UI Autocomplete", + "description": "Lists suggested words as the user is typing.", + "keywords": [ + "ui", + "autocomplete", + "form", + "word", + "predict", + "suggest" + ], + "version": "1.9.0", + "author": { + "name": "jQuery Foundation and other contributors", + "url": "https://github.com/jquery/jquery-ui/blob/1.9.0/AUTHORS.txt" + }, + "maintainers": [ + { + "name": "Scott González", + "email": "scott.gonzalez@gmail.com", + "url": "http://scottgonzalez.com" + }, + { + "name": "Jörn Zaefferer", + "email": "joern.zaefferer@gmail.com", + "url": "http://bassistance.de" + }, + { + "name": "Richard D. Worth", + "email": "rdworth@gmail.com", + "url": "http://rdworth.org" + }, + { + "name": "Kris Borchers", + "email": "kris.borchers@gmail.com", + "url": "http://krisborchers.com" + }, + { + "name": "Corey Frang", + "email": "gnarf37@gmail.com", + "url": "http://gnarf.net" + } + ], + "licenses": [ + { + "type": "MIT", + "url": "https://github.com/jquery/jquery-ui/blob/1.9.0/MIT-LICENSE.txt" + } + ], + "bugs": "http://bugs.jqueryui.com/", + "homepage": "http://jqueryui.com/autocomplete/", + "demo": "http://jqueryui.com/autocomplete/", + "docs": "http://api.jqueryui.com/autocomplete/", + "download": "http://jqueryui.com/download/", + "dependencies": { + "jquery": ">=1.6", + "ui.core": "1.9.0", + "ui.widget": "1.9.0", + "ui.menu": "1.9.0", + "ui.position": "1.9.0" + }, + "category": "widget" +} diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/ui.button.jquery.json b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/ui.button.jquery.json new file mode 100755 index 000000000..33b5384a7 --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/ui.button.jquery.json @@ -0,0 +1,61 @@ +{ + "name": "ui.button", + "title": "jQuery UI Button", + "description": "Enhances a form with themable buttons.", + "keywords": [ + "ui", + "button", + "form", + "radio", + "checkbox" + ], + "version": "1.9.0", + "author": { + "name": "jQuery Foundation and other contributors", + "url": "https://github.com/jquery/jquery-ui/blob/1.9.0/AUTHORS.txt" + }, + "maintainers": [ + { + "name": "Scott González", + "email": "scott.gonzalez@gmail.com", + "url": "http://scottgonzalez.com" + }, + { + "name": "Jörn Zaefferer", + "email": "joern.zaefferer@gmail.com", + "url": "http://bassistance.de" + }, + { + "name": "Richard D. Worth", + "email": "rdworth@gmail.com", + "url": "http://rdworth.org" + }, + { + "name": "Kris Borchers", + "email": "kris.borchers@gmail.com", + "url": "http://krisborchers.com" + }, + { + "name": "Corey Frang", + "email": "gnarf37@gmail.com", + "url": "http://gnarf.net" + } + ], + "licenses": [ + { + "type": "MIT", + "url": "https://github.com/jquery/jquery-ui/blob/1.9.0/MIT-LICENSE.txt" + } + ], + "bugs": "http://bugs.jqueryui.com/", + "homepage": "http://jqueryui.com/button/", + "demo": "http://jqueryui.com/button/", + "docs": "http://api.jqueryui.com/button/", + "download": "http://jqueryui.com/download/", + "dependencies": { + "jquery": ">=1.6", + "ui.core": "1.9.0", + "ui.widget": "1.9.0" + }, + "category": "widget" +} diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/ui.core.jquery.json b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/ui.core.jquery.json new file mode 100755 index 000000000..c87aa05bc --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/ui.core.jquery.json @@ -0,0 +1,56 @@ +{ + "name": "ui.core", + "title": "jQuery UI Core", + "description": "The core of jQuery UI, required for all interactions and widgets.", + "keywords": [ + "ui", + "core" + ], + "version": "1.9.0", + "author": { + "name": "jQuery Foundation and other contributors", + "url": "https://github.com/jquery/jquery-ui/blob/1.9.0/AUTHORS.txt" + }, + "maintainers": [ + { + "name": "Scott González", + "email": "scott.gonzalez@gmail.com", + "url": "http://scottgonzalez.com" + }, + { + "name": "Jörn Zaefferer", + "email": "joern.zaefferer@gmail.com", + "url": "http://bassistance.de" + }, + { + "name": "Richard D. Worth", + "email": "rdworth@gmail.com", + "url": "http://rdworth.org" + }, + { + "name": "Kris Borchers", + "email": "kris.borchers@gmail.com", + "url": "http://krisborchers.com" + }, + { + "name": "Corey Frang", + "email": "gnarf37@gmail.com", + "url": "http://gnarf.net" + } + ], + "licenses": [ + { + "type": "MIT", + "url": "https://github.com/jquery/jquery-ui/blob/1.9.0/MIT-LICENSE.txt" + } + ], + "bugs": "http://bugs.jqueryui.com/", + "homepage": "http://jqueryui.com/", + "demo": "http://jqueryui.com/", + "docs": "http://api.jqueryui.com/category/ui-core/", + "download": "http://jqueryui.com/download/", + "dependencies": { + "jquery": ">=1.6" + }, + "category": "core" +} diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/ui.datepicker.jquery.json b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/ui.datepicker.jquery.json new file mode 100755 index 000000000..b4120ce2a --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/ui.datepicker.jquery.json @@ -0,0 +1,61 @@ +{ + "name": "ui.datepicker", + "title": "jQuery UI Datepicker", + "description": "Displays a calendar from an input or inline for selecting dates.", + "keywords": [ + "ui", + "datepicker", + "form", + "calendar", + "date", + "i18n" + ], + "version": "1.9.0", + "author": { + "name": "jQuery Foundation and other contributors", + "url": "https://github.com/jquery/jquery-ui/blob/1.9.0/AUTHORS.txt" + }, + "maintainers": [ + { + "name": "Scott González", + "email": "scott.gonzalez@gmail.com", + "url": "http://scottgonzalez.com" + }, + { + "name": "Jörn Zaefferer", + "email": "joern.zaefferer@gmail.com", + "url": "http://bassistance.de" + }, + { + "name": "Richard D. Worth", + "email": "rdworth@gmail.com", + "url": "http://rdworth.org" + }, + { + "name": "Kris Borchers", + "email": "kris.borchers@gmail.com", + "url": "http://krisborchers.com" + }, + { + "name": "Corey Frang", + "email": "gnarf37@gmail.com", + "url": "http://gnarf.net" + } + ], + "licenses": [ + { + "type": "MIT", + "url": "https://github.com/jquery/jquery-ui/blob/1.9.0/MIT-LICENSE.txt" + } + ], + "bugs": "http://bugs.jqueryui.com/", + "homepage": "http://jqueryui.com/datepicker/", + "demo": "http://jqueryui.com/datepicker/", + "docs": "http://api.jqueryui.com/datepicker/", + "download": "http://jqueryui.com/download/", + "dependencies": { + "jquery": ">=1.6", + "ui.core": "1.9.0" + }, + "category": "widget" +} diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/ui.dialog.jquery.json b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/ui.dialog.jquery.json new file mode 100755 index 000000000..2752e4066 --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/ui.dialog.jquery.json @@ -0,0 +1,65 @@ +{ + "name": "ui.dialog", + "title": "jQuery UI Dialog", + "description": "Displays customizable dialog windows.", + "keywords": [ + "ui", + "dialog", + "modal", + "alert", + "popup" + ], + "version": "1.9.0", + "author": { + "name": "jQuery Foundation and other contributors", + "url": "https://github.com/jquery/jquery-ui/blob/1.9.0/AUTHORS.txt" + }, + "maintainers": [ + { + "name": "Scott González", + "email": "scott.gonzalez@gmail.com", + "url": "http://scottgonzalez.com" + }, + { + "name": "Jörn Zaefferer", + "email": "joern.zaefferer@gmail.com", + "url": "http://bassistance.de" + }, + { + "name": "Richard D. Worth", + "email": "rdworth@gmail.com", + "url": "http://rdworth.org" + }, + { + "name": "Kris Borchers", + "email": "kris.borchers@gmail.com", + "url": "http://krisborchers.com" + }, + { + "name": "Corey Frang", + "email": "gnarf37@gmail.com", + "url": "http://gnarf.net" + } + ], + "licenses": [ + { + "type": "MIT", + "url": "https://github.com/jquery/jquery-ui/blob/1.9.0/MIT-LICENSE.txt" + } + ], + "bugs": "http://bugs.jqueryui.com/", + "homepage": "http://jqueryui.com/dialog/", + "demo": "http://jqueryui.com/dialog/", + "docs": "http://api.jqueryui.com/dialog/", + "download": "http://jqueryui.com/download/", + "dependencies": { + "jquery": ">=1.6", + "ui.core": "1.9.0", + "ui.widget": "1.9.0", + "ui.button": "1.9.0", + "ui.draggable": "1.9.0", + "ui.position": "1.9.0", + "ui.resizable": "1.9.0" + }, + "category": "widget" +} diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/ui.draggable.jquery.json b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/ui.draggable.jquery.json new file mode 100755 index 000000000..23056b0a1 --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/ui.draggable.jquery.json @@ -0,0 +1,61 @@ +{ + "name": "ui.draggable", + "title": "jQuery UI Draggable", + "description": "Enables dragging functionality for any element.", + "keywords": [ + "ui", + "draggable", + "drag", + "drop" + ], + "version": "1.9.0", + "author": { + "name": "jQuery Foundation and other contributors", + "url": "https://github.com/jquery/jquery-ui/blob/1.9.0/AUTHORS.txt" + }, + "maintainers": [ + { + "name": "Scott González", + "email": "scott.gonzalez@gmail.com", + "url": "http://scottgonzalez.com" + }, + { + "name": "Jörn Zaefferer", + "email": "joern.zaefferer@gmail.com", + "url": "http://bassistance.de" + }, + { + "name": "Richard D. Worth", + "email": "rdworth@gmail.com", + "url": "http://rdworth.org" + }, + { + "name": "Kris Borchers", + "email": "kris.borchers@gmail.com", + "url": "http://krisborchers.com" + }, + { + "name": "Corey Frang", + "email": "gnarf37@gmail.com", + "url": "http://gnarf.net" + } + ], + "licenses": [ + { + "type": "MIT", + "url": "https://github.com/jquery/jquery-ui/blob/1.9.0/MIT-LICENSE.txt" + } + ], + "bugs": "http://bugs.jqueryui.com/", + "homepage": "http://jqueryui.com/draggable/", + "demo": "http://jqueryui.com/draggable/", + "docs": "http://api.jqueryui.com/draggable/", + "download": "http://jqueryui.com/download/", + "dependencies": { + "jquery": ">=1.6", + "ui.core": "1.9.0", + "ui.widget": "1.9.0", + "ui.mouse": "1.9.0" + }, + "category": "interaction" +} diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/ui.droppable.jquery.json b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/ui.droppable.jquery.json new file mode 100755 index 000000000..fe682f150 --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/ui.droppable.jquery.json @@ -0,0 +1,62 @@ +{ + "name": "ui.droppable", + "title": "jQuery UI Droppable", + "description": "Enables drop targets for draggable elements.", + "keywords": [ + "ui", + "droppable", + "drag", + "drop" + ], + "version": "1.9.0", + "author": { + "name": "jQuery Foundation and other contributors", + "url": "https://github.com/jquery/jquery-ui/blob/1.9.0/AUTHORS.txt" + }, + "maintainers": [ + { + "name": "Scott González", + "email": "scott.gonzalez@gmail.com", + "url": "http://scottgonzalez.com" + }, + { + "name": "Jörn Zaefferer", + "email": "joern.zaefferer@gmail.com", + "url": "http://bassistance.de" + }, + { + "name": "Richard D. Worth", + "email": "rdworth@gmail.com", + "url": "http://rdworth.org" + }, + { + "name": "Kris Borchers", + "email": "kris.borchers@gmail.com", + "url": "http://krisborchers.com" + }, + { + "name": "Corey Frang", + "email": "gnarf37@gmail.com", + "url": "http://gnarf.net" + } + ], + "licenses": [ + { + "type": "MIT", + "url": "https://github.com/jquery/jquery-ui/blob/1.9.0/MIT-LICENSE.txt" + } + ], + "bugs": "http://bugs.jqueryui.com/", + "homepage": "http://jqueryui.com/droppable/", + "demo": "http://jqueryui.com/droppable/", + "docs": "http://api.jqueryui.com/droppable/", + "download": "http://jqueryui.com/download/", + "dependencies": { + "jquery": ">=1.6", + "ui.core": "1.9.0", + "ui.widget": "1.9.0", + "ui.mouse": "1.9.0", + "ui.draggable": "1.9.0" + }, + "category": "interaction" +} diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/ui.effect-blind.jquery.json b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/ui.effect-blind.jquery.json new file mode 100755 index 000000000..45a5fb38c --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/ui.effect-blind.jquery.json @@ -0,0 +1,60 @@ +{ + "name": "ui.effect-blind", + "title": "jQuery UI Blind Effect", + "description": "Blinds the element.", + "keywords": [ + "ui", + "blind", + "effect", + "show", + "hide" + ], + "version": "1.9.0", + "author": { + "name": "jQuery Foundation and other contributors", + "url": "https://github.com/jquery/jquery-ui/blob/1.9.0/AUTHORS.txt" + }, + "maintainers": [ + { + "name": "Scott González", + "email": "scott.gonzalez@gmail.com", + "url": "http://scottgonzalez.com" + }, + { + "name": "Jörn Zaefferer", + "email": "joern.zaefferer@gmail.com", + "url": "http://bassistance.de" + }, + { + "name": "Richard D. Worth", + "email": "rdworth@gmail.com", + "url": "http://rdworth.org" + }, + { + "name": "Kris Borchers", + "email": "kris.borchers@gmail.com", + "url": "http://krisborchers.com" + }, + { + "name": "Corey Frang", + "email": "gnarf37@gmail.com", + "url": "http://gnarf.net" + } + ], + "licenses": [ + { + "type": "MIT", + "url": "https://github.com/jquery/jquery-ui/blob/1.9.0/MIT-LICENSE.txt" + } + ], + "bugs": "http://bugs.jqueryui.com/", + "homepage": "http://jqueryui.com/blind-effect/", + "demo": "http://jqueryui.com/blind-effect/", + "docs": "http://api.jqueryui.com/blind-effect/", + "download": "http://jqueryui.com/download/", + "dependencies": { + "jquery": ">=1.6", + "ui.effect": "1.9.0" + }, + "category": "effect" +} diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/ui.effect-bounce.jquery.json b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/ui.effect-bounce.jquery.json new file mode 100755 index 000000000..8806e835d --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/ui.effect-bounce.jquery.json @@ -0,0 +1,60 @@ +{ + "name": "ui.effect-bounce", + "title": "jQuery UI Bounce Effect", + "description": "Bounces an element horizontally or vertically n times.", + "keywords": [ + "ui", + "bounce", + "effect", + "show", + "hide" + ], + "version": "1.9.0", + "author": { + "name": "jQuery Foundation and other contributors", + "url": "https://github.com/jquery/jquery-ui/blob/1.9.0/AUTHORS.txt" + }, + "maintainers": [ + { + "name": "Scott González", + "email": "scott.gonzalez@gmail.com", + "url": "http://scottgonzalez.com" + }, + { + "name": "Jörn Zaefferer", + "email": "joern.zaefferer@gmail.com", + "url": "http://bassistance.de" + }, + { + "name": "Richard D. Worth", + "email": "rdworth@gmail.com", + "url": "http://rdworth.org" + }, + { + "name": "Kris Borchers", + "email": "kris.borchers@gmail.com", + "url": "http://krisborchers.com" + }, + { + "name": "Corey Frang", + "email": "gnarf37@gmail.com", + "url": "http://gnarf.net" + } + ], + "licenses": [ + { + "type": "MIT", + "url": "https://github.com/jquery/jquery-ui/blob/1.9.0/MIT-LICENSE.txt" + } + ], + "bugs": "http://bugs.jqueryui.com/", + "homepage": "http://jqueryui.com/bounce-effect/", + "demo": "http://jqueryui.com/bounce-effect/", + "docs": "http://api.jqueryui.com/bounce-effect/", + "download": "http://jqueryui.com/download/", + "dependencies": { + "jquery": ">=1.6", + "ui.effect": "1.9.0" + }, + "category": "effect" +} diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/ui.effect-clip.jquery.json b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/ui.effect-clip.jquery.json new file mode 100755 index 000000000..77acea9cc --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/ui.effect-clip.jquery.json @@ -0,0 +1,60 @@ +{ + "name": "ui.effect-clip", + "title": "jQuery UI Clip Effect", + "description": "Clips the element on and off like an old TV.", + "keywords": [ + "ui", + "clip", + "effect", + "show", + "hide" + ], + "version": "1.9.0", + "author": { + "name": "jQuery Foundation and other contributors", + "url": "https://github.com/jquery/jquery-ui/blob/1.9.0/AUTHORS.txt" + }, + "maintainers": [ + { + "name": "Scott González", + "email": "scott.gonzalez@gmail.com", + "url": "http://scottgonzalez.com" + }, + { + "name": "Jörn Zaefferer", + "email": "joern.zaefferer@gmail.com", + "url": "http://bassistance.de" + }, + { + "name": "Richard D. Worth", + "email": "rdworth@gmail.com", + "url": "http://rdworth.org" + }, + { + "name": "Kris Borchers", + "email": "kris.borchers@gmail.com", + "url": "http://krisborchers.com" + }, + { + "name": "Corey Frang", + "email": "gnarf37@gmail.com", + "url": "http://gnarf.net" + } + ], + "licenses": [ + { + "type": "MIT", + "url": "https://github.com/jquery/jquery-ui/blob/1.9.0/MIT-LICENSE.txt" + } + ], + "bugs": "http://bugs.jqueryui.com/", + "homepage": "http://jqueryui.com/clip-effect/", + "demo": "http://jqueryui.com/clip-effect/", + "docs": "http://api.jqueryui.com/clip-effect/", + "download": "http://jqueryui.com/download/", + "dependencies": { + "jquery": ">=1.6", + "ui.effect": "1.9.0" + }, + "category": "effect" +} diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/ui.effect-drop.jquery.json b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/ui.effect-drop.jquery.json new file mode 100755 index 000000000..bb01be476 --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/ui.effect-drop.jquery.json @@ -0,0 +1,60 @@ +{ + "name": "ui.effect-drop", + "title": "jQuery UI Drop Effect", + "description": "Moves an element in one direction and hides it at the same time.", + "keywords": [ + "ui", + "drop", + "effect", + "show", + "hide" + ], + "version": "1.9.0", + "author": { + "name": "jQuery Foundation and other contributors", + "url": "https://github.com/jquery/jquery-ui/blob/1.9.0/AUTHORS.txt" + }, + "maintainers": [ + { + "name": "Scott González", + "email": "scott.gonzalez@gmail.com", + "url": "http://scottgonzalez.com" + }, + { + "name": "Jörn Zaefferer", + "email": "joern.zaefferer@gmail.com", + "url": "http://bassistance.de" + }, + { + "name": "Richard D. Worth", + "email": "rdworth@gmail.com", + "url": "http://rdworth.org" + }, + { + "name": "Kris Borchers", + "email": "kris.borchers@gmail.com", + "url": "http://krisborchers.com" + }, + { + "name": "Corey Frang", + "email": "gnarf37@gmail.com", + "url": "http://gnarf.net" + } + ], + "licenses": [ + { + "type": "MIT", + "url": "https://github.com/jquery/jquery-ui/blob/1.9.0/MIT-LICENSE.txt" + } + ], + "bugs": "http://bugs.jqueryui.com/", + "homepage": "http://jqueryui.com/drop-effect/", + "demo": "http://jqueryui.com/drop-effect/", + "docs": "http://api.jqueryui.com/drop-effect/", + "download": "http://jqueryui.com/download/", + "dependencies": { + "jquery": ">=1.6", + "ui.effect": "1.9.0" + }, + "category": "effect" +} diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/ui.effect-explode.jquery.json b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/ui.effect-explode.jquery.json new file mode 100755 index 000000000..dcd843d3a --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/ui.effect-explode.jquery.json @@ -0,0 +1,60 @@ +{ + "name": "ui.effect-explode", + "title": "jQuery UI Explode Effect", + "description": "Explodes an element in all directions into n pieces. Implodes an element to its original wholeness.", + "keywords": [ + "ui", + "explode", + "effect", + "show", + "hide" + ], + "version": "1.9.0", + "author": { + "name": "jQuery Foundation and other contributors", + "url": "https://github.com/jquery/jquery-ui/blob/1.9.0/AUTHORS.txt" + }, + "maintainers": [ + { + "name": "Scott González", + "email": "scott.gonzalez@gmail.com", + "url": "http://scottgonzalez.com" + }, + { + "name": "Jörn Zaefferer", + "email": "joern.zaefferer@gmail.com", + "url": "http://bassistance.de" + }, + { + "name": "Richard D. Worth", + "email": "rdworth@gmail.com", + "url": "http://rdworth.org" + }, + { + "name": "Kris Borchers", + "email": "kris.borchers@gmail.com", + "url": "http://krisborchers.com" + }, + { + "name": "Corey Frang", + "email": "gnarf37@gmail.com", + "url": "http://gnarf.net" + } + ], + "licenses": [ + { + "type": "MIT", + "url": "https://github.com/jquery/jquery-ui/blob/1.9.0/MIT-LICENSE.txt" + } + ], + "bugs": "http://bugs.jqueryui.com/", + "homepage": "http://jqueryui.com/explode-effect/", + "demo": "http://jqueryui.com/explode-effect/", + "docs": "http://api.jqueryui.com/explode-effect/", + "download": "http://jqueryui.com/download/", + "dependencies": { + "jquery": ">=1.6", + "ui.effect": "1.9.0" + }, + "category": "effect" +} diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/ui.effect-fade.jquery.json b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/ui.effect-fade.jquery.json new file mode 100755 index 000000000..5e3332d3c --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/ui.effect-fade.jquery.json @@ -0,0 +1,60 @@ +{ + "name": "ui.effect-fade", + "title": "jQuery UI Fade Effect", + "description": "Fades an element.", + "keywords": [ + "ui", + "fade", + "effect", + "show", + "hide" + ], + "version": "1.9.0", + "author": { + "name": "jQuery Foundation and other contributors", + "url": "https://github.com/jquery/jquery-ui/blob/1.9.0/AUTHORS.txt" + }, + "maintainers": [ + { + "name": "Scott González", + "email": "scott.gonzalez@gmail.com", + "url": "http://scottgonzalez.com" + }, + { + "name": "Jörn Zaefferer", + "email": "joern.zaefferer@gmail.com", + "url": "http://bassistance.de" + }, + { + "name": "Richard D. Worth", + "email": "rdworth@gmail.com", + "url": "http://rdworth.org" + }, + { + "name": "Kris Borchers", + "email": "kris.borchers@gmail.com", + "url": "http://krisborchers.com" + }, + { + "name": "Corey Frang", + "email": "gnarf37@gmail.com", + "url": "http://gnarf.net" + } + ], + "licenses": [ + { + "type": "MIT", + "url": "https://github.com/jquery/jquery-ui/blob/1.9.0/MIT-LICENSE.txt" + } + ], + "bugs": "http://bugs.jqueryui.com/", + "homepage": "http://jqueryui.com/fade-effect/", + "demo": "http://jqueryui.com/fade-effect/", + "docs": "http://api.jqueryui.com/fade-effect/", + "download": "http://jqueryui.com/download/", + "dependencies": { + "jquery": ">=1.6", + "ui.effect": "1.9.0" + }, + "category": "effect" +} diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/ui.effect-fold.jquery.json b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/ui.effect-fold.jquery.json new file mode 100755 index 000000000..37c7dc278 --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/ui.effect-fold.jquery.json @@ -0,0 +1,60 @@ +{ + "name": "ui.effect-fold", + "title": "jQuery UI Fold Effect", + "description": "Folds an element first horizontally and then vertically.", + "keywords": [ + "ui", + "fold", + "effect", + "show", + "hide" + ], + "version": "1.9.0", + "author": { + "name": "jQuery Foundation and other contributors", + "url": "https://github.com/jquery/jquery-ui/blob/1.9.0/AUTHORS.txt" + }, + "maintainers": [ + { + "name": "Scott González", + "email": "scott.gonzalez@gmail.com", + "url": "http://scottgonzalez.com" + }, + { + "name": "Jörn Zaefferer", + "email": "joern.zaefferer@gmail.com", + "url": "http://bassistance.de" + }, + { + "name": "Richard D. Worth", + "email": "rdworth@gmail.com", + "url": "http://rdworth.org" + }, + { + "name": "Kris Borchers", + "email": "kris.borchers@gmail.com", + "url": "http://krisborchers.com" + }, + { + "name": "Corey Frang", + "email": "gnarf37@gmail.com", + "url": "http://gnarf.net" + } + ], + "licenses": [ + { + "type": "MIT", + "url": "https://github.com/jquery/jquery-ui/blob/1.9.0/MIT-LICENSE.txt" + } + ], + "bugs": "http://bugs.jqueryui.com/", + "homepage": "http://jqueryui.com/fold-effect/", + "demo": "http://jqueryui.com/fold-effect/", + "docs": "http://api.jqueryui.com/fold-effect/", + "download": "http://jqueryui.com/download/", + "dependencies": { + "jquery": ">=1.6", + "ui.effect": "1.9.0" + }, + "category": "effect" +} diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/ui.effect-highlight.jquery.json b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/ui.effect-highlight.jquery.json new file mode 100755 index 000000000..3e409bc91 --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/ui.effect-highlight.jquery.json @@ -0,0 +1,60 @@ +{ + "name": "ui.effect-highlight", + "title": "jQuery UI Highlight Effect", + "description": "Highlights the background of an element in a defined color for a custom duration.", + "keywords": [ + "ui", + "highlight", + "effect", + "show", + "hide" + ], + "version": "1.9.0", + "author": { + "name": "jQuery Foundation and other contributors", + "url": "https://github.com/jquery/jquery-ui/blob/1.9.0/AUTHORS.txt" + }, + "maintainers": [ + { + "name": "Scott González", + "email": "scott.gonzalez@gmail.com", + "url": "http://scottgonzalez.com" + }, + { + "name": "Jörn Zaefferer", + "email": "joern.zaefferer@gmail.com", + "url": "http://bassistance.de" + }, + { + "name": "Richard D. Worth", + "email": "rdworth@gmail.com", + "url": "http://rdworth.org" + }, + { + "name": "Kris Borchers", + "email": "kris.borchers@gmail.com", + "url": "http://krisborchers.com" + }, + { + "name": "Corey Frang", + "email": "gnarf37@gmail.com", + "url": "http://gnarf.net" + } + ], + "licenses": [ + { + "type": "MIT", + "url": "https://github.com/jquery/jquery-ui/blob/1.9.0/MIT-LICENSE.txt" + } + ], + "bugs": "http://bugs.jqueryui.com/", + "homepage": "http://jqueryui.com/highlight-effect/", + "demo": "http://jqueryui.com/highlight-effect/", + "docs": "http://api.jqueryui.com/highlight-effect/", + "download": "http://jqueryui.com/download/", + "dependencies": { + "jquery": ">=1.6", + "ui.effect": "1.9.0" + }, + "category": "effect" +} diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/ui.effect-pulsate.jquery.json b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/ui.effect-pulsate.jquery.json new file mode 100755 index 000000000..6853a5bc1 --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/ui.effect-pulsate.jquery.json @@ -0,0 +1,60 @@ +{ + "name": "ui.effect-pulsate", + "title": "jQuery UI Pulsate Effect", + "description": "Pulsates an element n times by changing the opacity to zero and back.", + "keywords": [ + "ui", + "pulsate", + "effect", + "show", + "hide" + ], + "version": "1.9.0", + "author": { + "name": "jQuery Foundation and other contributors", + "url": "https://github.com/jquery/jquery-ui/blob/1.9.0/AUTHORS.txt" + }, + "maintainers": [ + { + "name": "Scott González", + "email": "scott.gonzalez@gmail.com", + "url": "http://scottgonzalez.com" + }, + { + "name": "Jörn Zaefferer", + "email": "joern.zaefferer@gmail.com", + "url": "http://bassistance.de" + }, + { + "name": "Richard D. Worth", + "email": "rdworth@gmail.com", + "url": "http://rdworth.org" + }, + { + "name": "Kris Borchers", + "email": "kris.borchers@gmail.com", + "url": "http://krisborchers.com" + }, + { + "name": "Corey Frang", + "email": "gnarf37@gmail.com", + "url": "http://gnarf.net" + } + ], + "licenses": [ + { + "type": "MIT", + "url": "https://github.com/jquery/jquery-ui/blob/1.9.0/MIT-LICENSE.txt" + } + ], + "bugs": "http://bugs.jqueryui.com/", + "homepage": "http://jqueryui.com/pulsate-effect/", + "demo": "http://jqueryui.com/pulsate-effect/", + "docs": "http://api.jqueryui.com/pulsate-effect/", + "download": "http://jqueryui.com/download/", + "dependencies": { + "jquery": ">=1.6", + "ui.effect": "1.9.0" + }, + "category": "effect" +} diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/ui.effect-scale.jquery.json b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/ui.effect-scale.jquery.json new file mode 100755 index 000000000..f5355eccb --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/ui.effect-scale.jquery.json @@ -0,0 +1,60 @@ +{ + "name": "ui.effect-scale", + "title": "jQuery UI Scale Effect", + "description": "Grows or shrinks an element and its content. Restores an elemnt to its original size.", + "keywords": [ + "ui", + "scale", + "effect", + "show", + "hide" + ], + "version": "1.9.0", + "author": { + "name": "jQuery Foundation and other contributors", + "url": "https://github.com/jquery/jquery-ui/blob/1.9.0/AUTHORS.txt" + }, + "maintainers": [ + { + "name": "Scott González", + "email": "scott.gonzalez@gmail.com", + "url": "http://scottgonzalez.com" + }, + { + "name": "Jörn Zaefferer", + "email": "joern.zaefferer@gmail.com", + "url": "http://bassistance.de" + }, + { + "name": "Richard D. Worth", + "email": "rdworth@gmail.com", + "url": "http://rdworth.org" + }, + { + "name": "Kris Borchers", + "email": "kris.borchers@gmail.com", + "url": "http://krisborchers.com" + }, + { + "name": "Corey Frang", + "email": "gnarf37@gmail.com", + "url": "http://gnarf.net" + } + ], + "licenses": [ + { + "type": "MIT", + "url": "https://github.com/jquery/jquery-ui/blob/1.9.0/MIT-LICENSE.txt" + } + ], + "bugs": "http://bugs.jqueryui.com/", + "homepage": "http://jqueryui.com/scale-effect/", + "demo": "http://jqueryui.com/scale-effect/", + "docs": "http://api.jqueryui.com/scale-effect/", + "download": "http://jqueryui.com/download/", + "dependencies": { + "jquery": ">=1.6", + "ui.effect": "1.9.0" + }, + "category": "effect" +} diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/ui.effect-shake.jquery.json b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/ui.effect-shake.jquery.json new file mode 100755 index 000000000..faa315b96 --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/ui.effect-shake.jquery.json @@ -0,0 +1,60 @@ +{ + "name": "ui.effect-shake", + "title": "jQuery UI Shake Effect", + "description": "Shakes an element horizontally or vertically n times.", + "keywords": [ + "ui", + "shake", + "effect", + "show", + "hide" + ], + "version": "1.9.0", + "author": { + "name": "jQuery Foundation and other contributors", + "url": "https://github.com/jquery/jquery-ui/blob/1.9.0/AUTHORS.txt" + }, + "maintainers": [ + { + "name": "Scott González", + "email": "scott.gonzalez@gmail.com", + "url": "http://scottgonzalez.com" + }, + { + "name": "Jörn Zaefferer", + "email": "joern.zaefferer@gmail.com", + "url": "http://bassistance.de" + }, + { + "name": "Richard D. Worth", + "email": "rdworth@gmail.com", + "url": "http://rdworth.org" + }, + { + "name": "Kris Borchers", + "email": "kris.borchers@gmail.com", + "url": "http://krisborchers.com" + }, + { + "name": "Corey Frang", + "email": "gnarf37@gmail.com", + "url": "http://gnarf.net" + } + ], + "licenses": [ + { + "type": "MIT", + "url": "https://github.com/jquery/jquery-ui/blob/1.9.0/MIT-LICENSE.txt" + } + ], + "bugs": "http://bugs.jqueryui.com/", + "homepage": "http://jqueryui.com/shake-effect/", + "demo": "http://jqueryui.com/shake-effect/", + "docs": "http://api.jqueryui.com/shake-effect/", + "download": "http://jqueryui.com/download/", + "dependencies": { + "jquery": ">=1.6", + "ui.effect": "1.9.0" + }, + "category": "effect" +} diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/ui.effect-slide.jquery.json b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/ui.effect-slide.jquery.json new file mode 100755 index 000000000..d7b27d0e6 --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/ui.effect-slide.jquery.json @@ -0,0 +1,60 @@ +{ + "name": "ui.effect-slide", + "title": "jQuery UI Slide Effect", + "description": "Slides an element in and out of the viewport.", + "keywords": [ + "ui", + "slide", + "effect", + "show", + "hide" + ], + "version": "1.9.0", + "author": { + "name": "jQuery Foundation and other contributors", + "url": "https://github.com/jquery/jquery-ui/blob/1.9.0/AUTHORS.txt" + }, + "maintainers": [ + { + "name": "Scott González", + "email": "scott.gonzalez@gmail.com", + "url": "http://scottgonzalez.com" + }, + { + "name": "Jörn Zaefferer", + "email": "joern.zaefferer@gmail.com", + "url": "http://bassistance.de" + }, + { + "name": "Richard D. Worth", + "email": "rdworth@gmail.com", + "url": "http://rdworth.org" + }, + { + "name": "Kris Borchers", + "email": "kris.borchers@gmail.com", + "url": "http://krisborchers.com" + }, + { + "name": "Corey Frang", + "email": "gnarf37@gmail.com", + "url": "http://gnarf.net" + } + ], + "licenses": [ + { + "type": "MIT", + "url": "https://github.com/jquery/jquery-ui/blob/1.9.0/MIT-LICENSE.txt" + } + ], + "bugs": "http://bugs.jqueryui.com/", + "homepage": "http://jqueryui.com/slide-effect/", + "demo": "http://jqueryui.com/slide-effect/", + "docs": "http://api.jqueryui.com/slide-effect/", + "download": "http://jqueryui.com/download/", + "dependencies": { + "jquery": ">=1.6", + "ui.effect": "1.9.0" + }, + "category": "effect" +} diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/ui.effect-transfer.jquery.json b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/ui.effect-transfer.jquery.json new file mode 100755 index 000000000..3a8749ac0 --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/ui.effect-transfer.jquery.json @@ -0,0 +1,58 @@ +{ + "name": "ui.effect-transfer", + "title": "jQuery UI Transfer Effect", + "description": "Displays a transfer effect from one element to another.", + "keywords": [ + "ui", + "transfer", + "effect" + ], + "version": "1.9.0", + "author": { + "name": "jQuery Foundation and other contributors", + "url": "https://github.com/jquery/jquery-ui/blob/1.9.0/AUTHORS.txt" + }, + "maintainers": [ + { + "name": "Scott González", + "email": "scott.gonzalez@gmail.com", + "url": "http://scottgonzalez.com" + }, + { + "name": "Jörn Zaefferer", + "email": "joern.zaefferer@gmail.com", + "url": "http://bassistance.de" + }, + { + "name": "Richard D. Worth", + "email": "rdworth@gmail.com", + "url": "http://rdworth.org" + }, + { + "name": "Kris Borchers", + "email": "kris.borchers@gmail.com", + "url": "http://krisborchers.com" + }, + { + "name": "Corey Frang", + "email": "gnarf37@gmail.com", + "url": "http://gnarf.net" + } + ], + "licenses": [ + { + "type": "MIT", + "url": "https://github.com/jquery/jquery-ui/blob/1.9.0/MIT-LICENSE.txt" + } + ], + "bugs": "http://bugs.jqueryui.com/", + "homepage": "http://jqueryui.com/transfer-effect/", + "demo": "http://jqueryui.com/transfer-effect/", + "docs": "http://api.jqueryui.com/transfer-effect/", + "download": "http://jqueryui.com/download/", + "dependencies": { + "jquery": ">=1.6", + "ui.effect": "1.9.0" + }, + "category": "effect" +} diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/ui.effect.jquery.json b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/ui.effect.jquery.json new file mode 100755 index 000000000..4ca346f29 --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/ui.effect.jquery.json @@ -0,0 +1,63 @@ +{ + "name": "ui.effect", + "title": "jQuery UI Effects Core", + "description": "Extends the internal jQuery effects. Includes morphing and easing. Required by all other effects.", + "keywords": [ + "ui", + "effect", + "animation", + "show", + "hide", + "color", + "class", + "transition", + "easing" + ], + "version": "1.9.0", + "author": { + "name": "jQuery Foundation and other contributors", + "url": "https://github.com/jquery/jquery-ui/blob/1.9.0/AUTHORS.txt" + }, + "maintainers": [ + { + "name": "Scott González", + "email": "scott.gonzalez@gmail.com", + "url": "http://scottgonzalez.com" + }, + { + "name": "Jörn Zaefferer", + "email": "joern.zaefferer@gmail.com", + "url": "http://bassistance.de" + }, + { + "name": "Richard D. Worth", + "email": "rdworth@gmail.com", + "url": "http://rdworth.org" + }, + { + "name": "Kris Borchers", + "email": "kris.borchers@gmail.com", + "url": "http://krisborchers.com" + }, + { + "name": "Corey Frang", + "email": "gnarf37@gmail.com", + "url": "http://gnarf.net" + } + ], + "licenses": [ + { + "type": "MIT", + "url": "https://github.com/jquery/jquery-ui/blob/1.9.0/MIT-LICENSE.txt" + } + ], + "bugs": "http://bugs.jqueryui.com/", + "homepage": "http://jqueryui.com/", + "demo": "http://jqueryui.com/effects/", + "docs": "http://api.jqueryui.com/category/effects-core/", + "download": "http://jqueryui.com/download/", + "dependencies": { + "jquery": ">=1.6" + }, + "category": "effect" +} diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/ui.menu.jquery.json b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/ui.menu.jquery.json new file mode 100755 index 000000000..caf4b814c --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/ui.menu.jquery.json @@ -0,0 +1,61 @@ +{ + "name": "ui.menu", + "title": "jQuery UI Menu", + "description": "Creates nestable menus.", + "keywords": [ + "ui", + "menu", + "dropdown", + "flyout" + ], + "version": "1.9.0", + "author": { + "name": "jQuery Foundation and other contributors", + "url": "https://github.com/jquery/jquery-ui/blob/1.9.0/AUTHORS.txt" + }, + "maintainers": [ + { + "name": "Scott González", + "email": "scott.gonzalez@gmail.com", + "url": "http://scottgonzalez.com" + }, + { + "name": "Jörn Zaefferer", + "email": "joern.zaefferer@gmail.com", + "url": "http://bassistance.de" + }, + { + "name": "Richard D. Worth", + "email": "rdworth@gmail.com", + "url": "http://rdworth.org" + }, + { + "name": "Kris Borchers", + "email": "kris.borchers@gmail.com", + "url": "http://krisborchers.com" + }, + { + "name": "Corey Frang", + "email": "gnarf37@gmail.com", + "url": "http://gnarf.net" + } + ], + "licenses": [ + { + "type": "MIT", + "url": "https://github.com/jquery/jquery-ui/blob/1.9.0/MIT-LICENSE.txt" + } + ], + "bugs": "http://bugs.jqueryui.com/", + "homepage": "http://jqueryui.com/menu/", + "demo": "http://jqueryui.com/menu/", + "docs": "http://api.jqueryui.com/menu/", + "download": "http://jqueryui.com/download/", + "dependencies": { + "jquery": ">=1.6", + "ui.core": "1.9.0", + "ui.widget": "1.9.0", + "ui.position": "1.9.0" + }, + "category": "widget" +} diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/ui.mouse.jquery.json b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/ui.mouse.jquery.json new file mode 100755 index 000000000..bc385b74a --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/ui.mouse.jquery.json @@ -0,0 +1,59 @@ +{ + "name": "ui.mouse", + "title": "jQuery UI Mouse", + "description": "Abstracts mouse-based interactions to assist in creating certain widgets.", + "keywords": [ + "ui", + "mouse", + "abstraction" + ], + "version": "1.9.0", + "author": { + "name": "jQuery Foundation and other contributors", + "url": "https://github.com/jquery/jquery-ui/blob/1.9.0/AUTHORS.txt" + }, + "maintainers": [ + { + "name": "Scott González", + "email": "scott.gonzalez@gmail.com", + "url": "http://scottgonzalez.com" + }, + { + "name": "Jörn Zaefferer", + "email": "joern.zaefferer@gmail.com", + "url": "http://bassistance.de" + }, + { + "name": "Richard D. Worth", + "email": "rdworth@gmail.com", + "url": "http://rdworth.org" + }, + { + "name": "Kris Borchers", + "email": "kris.borchers@gmail.com", + "url": "http://krisborchers.com" + }, + { + "name": "Corey Frang", + "email": "gnarf37@gmail.com", + "url": "http://gnarf.net" + } + ], + "licenses": [ + { + "type": "MIT", + "url": "https://github.com/jquery/jquery-ui/blob/1.9.0/MIT-LICENSE.txt" + } + ], + "bugs": "http://bugs.jqueryui.com/", + "homepage": "http://jqueryui.com/mouse/", + "demo": "http://jqueryui.com/mouse/", + "docs": "http://api.jqueryui.com/mouse/", + "download": "http://jqueryui.com/download/", + "dependencies": { + "jquery": ">=1.6", + "ui.core": "1.9.0", + "ui.widget": "1.9.0" + }, + "category": "core" +} diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/ui.position.jquery.json b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/ui.position.jquery.json new file mode 100755 index 000000000..0181de160 --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/ui.position.jquery.json @@ -0,0 +1,61 @@ +{ + "name": "ui.position", + "title": "jQuery UI Position", + "description": "Positions elements relative to other elements.", + "keywords": [ + "ui", + "position", + "offset", + "relative", + "absolute", + "fixed", + "collision" + ], + "version": "1.9.0", + "author": { + "name": "jQuery Foundation and other contributors", + "url": "https://github.com/jquery/jquery-ui/blob/1.9.0/AUTHORS.txt" + }, + "maintainers": [ + { + "name": "Scott González", + "email": "scott.gonzalez@gmail.com", + "url": "http://scottgonzalez.com" + }, + { + "name": "Jörn Zaefferer", + "email": "joern.zaefferer@gmail.com", + "url": "http://bassistance.de" + }, + { + "name": "Richard D. Worth", + "email": "rdworth@gmail.com", + "url": "http://rdworth.org" + }, + { + "name": "Kris Borchers", + "email": "kris.borchers@gmail.com", + "url": "http://krisborchers.com" + }, + { + "name": "Corey Frang", + "email": "gnarf37@gmail.com", + "url": "http://gnarf.net" + } + ], + "licenses": [ + { + "type": "MIT", + "url": "https://github.com/jquery/jquery-ui/blob/1.9.0/MIT-LICENSE.txt" + } + ], + "bugs": "http://bugs.jqueryui.com/", + "homepage": "http://jqueryui.com/position/", + "demo": "http://jqueryui.com/position/", + "docs": "http://api.jqueryui.com/position/", + "download": "http://jqueryui.com/download/", + "dependencies": { + "jquery": ">=1.6" + }, + "category": "core" +} diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/ui.progressbar.jquery.json b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/ui.progressbar.jquery.json new file mode 100755 index 000000000..4b20e613c --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/ui.progressbar.jquery.json @@ -0,0 +1,60 @@ +{ + "name": "ui.progressbar", + "title": "jQuery UI Progressbar", + "description": "Displays a status indicator for loading state, standard percentage, and other progress indicators.", + "keywords": [ + "ui", + "progressbar", + "determinate", + "status" + ], + "version": "1.9.0", + "author": { + "name": "jQuery Foundation and other contributors", + "url": "https://github.com/jquery/jquery-ui/blob/1.9.0/AUTHORS.txt" + }, + "maintainers": [ + { + "name": "Scott González", + "email": "scott.gonzalez@gmail.com", + "url": "http://scottgonzalez.com" + }, + { + "name": "Jörn Zaefferer", + "email": "joern.zaefferer@gmail.com", + "url": "http://bassistance.de" + }, + { + "name": "Richard D. Worth", + "email": "rdworth@gmail.com", + "url": "http://rdworth.org" + }, + { + "name": "Kris Borchers", + "email": "kris.borchers@gmail.com", + "url": "http://krisborchers.com" + }, + { + "name": "Corey Frang", + "email": "gnarf37@gmail.com", + "url": "http://gnarf.net" + } + ], + "licenses": [ + { + "type": "MIT", + "url": "https://github.com/jquery/jquery-ui/blob/1.9.0/MIT-LICENSE.txt" + } + ], + "bugs": "http://bugs.jqueryui.com/", + "homepage": "http://jqueryui.com/progressbar/", + "demo": "http://jqueryui.com/progressbar/", + "docs": "http://api.jqueryui.com/progressbar/", + "download": "http://jqueryui.com/download/", + "dependencies": { + "jquery": ">=1.6", + "ui.core": "1.9.0", + "ui.widget": "1.9.0" + }, + "category": "widget" +} diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/ui.resizable.jquery.json b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/ui.resizable.jquery.json new file mode 100755 index 000000000..ff74c683a --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/ui.resizable.jquery.json @@ -0,0 +1,60 @@ +{ + "name": "ui.resizable", + "title": "jQuery UI Resizable", + "description": "Enables resize functionality for any element.", + "keywords": [ + "ui", + "resizable", + "resize" + ], + "version": "1.9.0", + "author": { + "name": "jQuery Foundation and other contributors", + "url": "https://github.com/jquery/jquery-ui/blob/1.9.0/AUTHORS.txt" + }, + "maintainers": [ + { + "name": "Scott González", + "email": "scott.gonzalez@gmail.com", + "url": "http://scottgonzalez.com" + }, + { + "name": "Jörn Zaefferer", + "email": "joern.zaefferer@gmail.com", + "url": "http://bassistance.de" + }, + { + "name": "Richard D. Worth", + "email": "rdworth@gmail.com", + "url": "http://rdworth.org" + }, + { + "name": "Kris Borchers", + "email": "kris.borchers@gmail.com", + "url": "http://krisborchers.com" + }, + { + "name": "Corey Frang", + "email": "gnarf37@gmail.com", + "url": "http://gnarf.net" + } + ], + "licenses": [ + { + "type": "MIT", + "url": "https://github.com/jquery/jquery-ui/blob/1.9.0/MIT-LICENSE.txt" + } + ], + "bugs": "http://bugs.jqueryui.com/", + "homepage": "http://jqueryui.com/resizable/", + "demo": "http://jqueryui.com/resizable/", + "docs": "http://api.jqueryui.com/resizable/", + "download": "http://jqueryui.com/download/", + "dependencies": { + "jquery": ">=1.6", + "ui.core": "1.9.0", + "ui.widget": "1.9.0", + "ui.mouse": "1.9.0" + }, + "category": "interaction" +} diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/ui.selectable.jquery.json b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/ui.selectable.jquery.json new file mode 100755 index 000000000..37cbceb49 --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/ui.selectable.jquery.json @@ -0,0 +1,60 @@ +{ + "name": "ui.selectable", + "title": "jQuery UI Selectable", + "description": "Allows groups of elements to be selected with the mouse.", + "keywords": [ + "ui", + "selectable", + "selection" + ], + "version": "1.9.0", + "author": { + "name": "jQuery Foundation and other contributors", + "url": "https://github.com/jquery/jquery-ui/blob/1.9.0/AUTHORS.txt" + }, + "maintainers": [ + { + "name": "Scott González", + "email": "scott.gonzalez@gmail.com", + "url": "http://scottgonzalez.com" + }, + { + "name": "Jörn Zaefferer", + "email": "joern.zaefferer@gmail.com", + "url": "http://bassistance.de" + }, + { + "name": "Richard D. Worth", + "email": "rdworth@gmail.com", + "url": "http://rdworth.org" + }, + { + "name": "Kris Borchers", + "email": "kris.borchers@gmail.com", + "url": "http://krisborchers.com" + }, + { + "name": "Corey Frang", + "email": "gnarf37@gmail.com", + "url": "http://gnarf.net" + } + ], + "licenses": [ + { + "type": "MIT", + "url": "https://github.com/jquery/jquery-ui/blob/1.9.0/MIT-LICENSE.txt" + } + ], + "bugs": "http://bugs.jqueryui.com/", + "homepage": "http://jqueryui.com/selectable/", + "demo": "http://jqueryui.com/selectable/", + "docs": "http://api.jqueryui.com/selectable/", + "download": "http://jqueryui.com/download/", + "dependencies": { + "jquery": ">=1.6", + "ui.core": "1.9.0", + "ui.widget": "1.9.0", + "ui.mouse": "1.9.0" + }, + "category": "interaction" +} diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/ui.slider.jquery.json b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/ui.slider.jquery.json new file mode 100755 index 000000000..e29152af4 --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/ui.slider.jquery.json @@ -0,0 +1,62 @@ +{ + "name": "ui.slider", + "title": "jQuery UI Slider", + "description": "Displays a flexible slider with ranges and accessibility via keyboard.", + "keywords": [ + "ui", + "slider", + "form", + "number", + "range" + ], + "version": "1.9.0", + "author": { + "name": "jQuery Foundation and other contributors", + "url": "https://github.com/jquery/jquery-ui/blob/1.9.0/AUTHORS.txt" + }, + "maintainers": [ + { + "name": "Scott González", + "email": "scott.gonzalez@gmail.com", + "url": "http://scottgonzalez.com" + }, + { + "name": "Jörn Zaefferer", + "email": "joern.zaefferer@gmail.com", + "url": "http://bassistance.de" + }, + { + "name": "Richard D. Worth", + "email": "rdworth@gmail.com", + "url": "http://rdworth.org" + }, + { + "name": "Kris Borchers", + "email": "kris.borchers@gmail.com", + "url": "http://krisborchers.com" + }, + { + "name": "Corey Frang", + "email": "gnarf37@gmail.com", + "url": "http://gnarf.net" + } + ], + "licenses": [ + { + "type": "MIT", + "url": "https://github.com/jquery/jquery-ui/blob/1.9.0/MIT-LICENSE.txt" + } + ], + "bugs": "http://bugs.jqueryui.com/", + "homepage": "http://jqueryui.com/slider/", + "demo": "http://jqueryui.com/slider/", + "docs": "http://api.jqueryui.com/slider/", + "download": "http://jqueryui.com/download/", + "dependencies": { + "jquery": ">=1.6", + "ui.core": "1.9.0", + "ui.widget": "1.9.0", + "ui.mouse": "1.9.0" + }, + "category": "widget" +} diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/ui.sortable.jquery.json b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/ui.sortable.jquery.json new file mode 100755 index 000000000..78893d0a8 --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/ui.sortable.jquery.json @@ -0,0 +1,61 @@ +{ + "name": "ui.sortable", + "title": "jQuery UI Sortable", + "description": "Enables items in a list to be sorted using the mouse.", + "keywords": [ + "ui", + "sortable", + "sort", + "list" + ], + "version": "1.9.0", + "author": { + "name": "jQuery Foundation and other contributors", + "url": "https://github.com/jquery/jquery-ui/blob/1.9.0/AUTHORS.txt" + }, + "maintainers": [ + { + "name": "Scott González", + "email": "scott.gonzalez@gmail.com", + "url": "http://scottgonzalez.com" + }, + { + "name": "Jörn Zaefferer", + "email": "joern.zaefferer@gmail.com", + "url": "http://bassistance.de" + }, + { + "name": "Richard D. Worth", + "email": "rdworth@gmail.com", + "url": "http://rdworth.org" + }, + { + "name": "Kris Borchers", + "email": "kris.borchers@gmail.com", + "url": "http://krisborchers.com" + }, + { + "name": "Corey Frang", + "email": "gnarf37@gmail.com", + "url": "http://gnarf.net" + } + ], + "licenses": [ + { + "type": "MIT", + "url": "https://github.com/jquery/jquery-ui/blob/1.9.0/MIT-LICENSE.txt" + } + ], + "bugs": "http://bugs.jqueryui.com/", + "homepage": "http://jqueryui.com/sortable/", + "demo": "http://jqueryui.com/sortable/", + "docs": "http://api.jqueryui.com/sortable/", + "download": "http://jqueryui.com/download/", + "dependencies": { + "jquery": ">=1.6", + "ui.core": "1.9.0", + "ui.widget": "1.9.0", + "ui.mouse": "1.9.0" + }, + "category": "interaction" +} diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/ui.spinner.jquery.json b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/ui.spinner.jquery.json new file mode 100755 index 000000000..8cd5b9b0a --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/ui.spinner.jquery.json @@ -0,0 +1,63 @@ +{ + "name": "ui.spinner", + "title": "jQuery UI Spinner", + "description": "Displays buttons to easily input numbers via the keyboard or mouse.", + "keywords": [ + "ui", + "spinner", + "form", + "number", + "spinbutton", + "stepper" + ], + "version": "1.9.0", + "author": { + "name": "jQuery Foundation and other contributors", + "url": "https://github.com/jquery/jquery-ui/blob/1.9.0/AUTHORS.txt" + }, + "maintainers": [ + { + "name": "Scott González", + "email": "scott.gonzalez@gmail.com", + "url": "http://scottgonzalez.com" + }, + { + "name": "Jörn Zaefferer", + "email": "joern.zaefferer@gmail.com", + "url": "http://bassistance.de" + }, + { + "name": "Richard D. Worth", + "email": "rdworth@gmail.com", + "url": "http://rdworth.org" + }, + { + "name": "Kris Borchers", + "email": "kris.borchers@gmail.com", + "url": "http://krisborchers.com" + }, + { + "name": "Corey Frang", + "email": "gnarf37@gmail.com", + "url": "http://gnarf.net" + } + ], + "licenses": [ + { + "type": "MIT", + "url": "https://github.com/jquery/jquery-ui/blob/1.9.0/MIT-LICENSE.txt" + } + ], + "bugs": "http://bugs.jqueryui.com/", + "homepage": "http://jqueryui.com/spinner/", + "demo": "http://jqueryui.com/spinner/", + "docs": "http://api.jqueryui.com/spinner/", + "download": "http://jqueryui.com/download/", + "dependencies": { + "jquery": ">=1.6", + "ui.core": "1.9.0", + "ui.widget": "1.9.0", + "ui.button": "1.9.0" + }, + "category": "widget" +} diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/ui.tabs.jquery.json b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/ui.tabs.jquery.json new file mode 100755 index 000000000..a2267d869 --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/ui.tabs.jquery.json @@ -0,0 +1,62 @@ +{ + "name": "ui.tabs", + "title": "jQuery UI Tabs", + "description": "Transforms a set of container elements into a tab structure.", + "keywords": [ + "ui", + "tabs", + "navigation", + "panel", + "collapse", + "expand" + ], + "version": "1.9.0", + "author": { + "name": "jQuery Foundation and other contributors", + "url": "https://github.com/jquery/jquery-ui/blob/1.9.0/AUTHORS.txt" + }, + "maintainers": [ + { + "name": "Scott González", + "email": "scott.gonzalez@gmail.com", + "url": "http://scottgonzalez.com" + }, + { + "name": "Jörn Zaefferer", + "email": "joern.zaefferer@gmail.com", + "url": "http://bassistance.de" + }, + { + "name": "Richard D. Worth", + "email": "rdworth@gmail.com", + "url": "http://rdworth.org" + }, + { + "name": "Kris Borchers", + "email": "kris.borchers@gmail.com", + "url": "http://krisborchers.com" + }, + { + "name": "Corey Frang", + "email": "gnarf37@gmail.com", + "url": "http://gnarf.net" + } + ], + "licenses": [ + { + "type": "MIT", + "url": "https://github.com/jquery/jquery-ui/blob/1.9.0/MIT-LICENSE.txt" + } + ], + "bugs": "http://bugs.jqueryui.com/", + "homepage": "http://jqueryui.com/tabs/", + "demo": "http://jqueryui.com/tabs/", + "docs": "http://api.jqueryui.com/tabs/", + "download": "http://jqueryui.com/download/", + "dependencies": { + "jquery": ">=1.6", + "ui.core": "1.9.0", + "ui.widget": "1.9.0" + }, + "category": "widget" +} diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/ui.tooltip.jquery.json b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/ui.tooltip.jquery.json new file mode 100755 index 000000000..e5e3f891d --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/ui.tooltip.jquery.json @@ -0,0 +1,59 @@ +{ + "name": "ui.tooltip", + "title": "jQuery UI Tooltip", + "description": "Shows additional information for any element on hover or focus.", + "keywords": [ + "ui", + "tooltip" + ], + "version": "1.9.0", + "author": { + "name": "jQuery Foundation and other contributors", + "url": "https://github.com/jquery/jquery-ui/blob/1.9.0/AUTHORS.txt" + }, + "maintainers": [ + { + "name": "Scott González", + "email": "scott.gonzalez@gmail.com", + "url": "http://scottgonzalez.com" + }, + { + "name": "Jörn Zaefferer", + "email": "joern.zaefferer@gmail.com", + "url": "http://bassistance.de" + }, + { + "name": "Richard D. Worth", + "email": "rdworth@gmail.com", + "url": "http://rdworth.org" + }, + { + "name": "Kris Borchers", + "email": "kris.borchers@gmail.com", + "url": "http://krisborchers.com" + }, + { + "name": "Corey Frang", + "email": "gnarf37@gmail.com", + "url": "http://gnarf.net" + } + ], + "licenses": [ + { + "type": "MIT", + "url": "https://github.com/jquery/jquery-ui/blob/1.9.0/MIT-LICENSE.txt" + } + ], + "bugs": "http://bugs.jqueryui.com/", + "homepage": "http://jqueryui.com/tooltip/", + "demo": "http://jqueryui.com/tooltip/", + "docs": "http://api.jqueryui.com/tooltip/", + "download": "http://jqueryui.com/download/", + "dependencies": { + "jquery": ">=1.6", + "ui.core": "1.9.0", + "ui.widget": "1.9.0", + "ui.position": "1.9.0" + }, + "category": "widget" +} diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/ui.widget.jquery.json b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/ui.widget.jquery.json new file mode 100755 index 000000000..c90db5c2c --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/ui.widget.jquery.json @@ -0,0 +1,59 @@ +{ + "name": "ui.widget", + "title": "jQuery UI Widget", + "description": "Provides a factory for creating stateful widgets with a common API.", + "keywords": [ + "ui", + "widget", + "abstraction", + "state", + "factory" + ], + "version": "1.9.0", + "author": { + "name": "jQuery Foundation and other contributors", + "url": "https://github.com/jquery/jquery-ui/blob/1.9.0/AUTHORS.txt" + }, + "maintainers": [ + { + "name": "Scott González", + "email": "scott.gonzalez@gmail.com", + "url": "http://scottgonzalez.com" + }, + { + "name": "Jörn Zaefferer", + "email": "joern.zaefferer@gmail.com", + "url": "http://bassistance.de" + }, + { + "name": "Richard D. Worth", + "email": "rdworth@gmail.com", + "url": "http://rdworth.org" + }, + { + "name": "Kris Borchers", + "email": "kris.borchers@gmail.com", + "url": "http://krisborchers.com" + }, + { + "name": "Corey Frang", + "email": "gnarf37@gmail.com", + "url": "http://gnarf.net" + } + ], + "licenses": [ + { + "type": "MIT", + "url": "https://github.com/jquery/jquery-ui/blob/1.9.0/MIT-LICENSE.txt" + } + ], + "bugs": "http://bugs.jqueryui.com/", + "homepage": "http://jqueryui.com/widget/", + "demo": "http://jqueryui.com/widget/", + "docs": "http://api.jqueryui.com/jQuery.widget/", + "download": "http://jqueryui.com/download/", + "dependencies": { + "jquery": ">=1.6" + }, + "category": "core" +} diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/ui/i18n/jquery-ui-i18n.js b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/ui/i18n/jquery-ui-i18n.js new file mode 100755 index 000000000..39333e4df --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/ui/i18n/jquery-ui-i18n.js @@ -0,0 +1,1647 @@ +/*! jQuery UI - v1.9.0 - 2012-10-08 +* http://jqueryui.com +* Includes: jquery.ui.datepicker-af.js, jquery.ui.datepicker-ar-DZ.js, jquery.ui.datepicker-ar.js, jquery.ui.datepicker-az.js, jquery.ui.datepicker-bg.js, jquery.ui.datepicker-bs.js, jquery.ui.datepicker-ca.js, jquery.ui.datepicker-cs.js, jquery.ui.datepicker-cy-GB.js, jquery.ui.datepicker-da.js, jquery.ui.datepicker-de.js, jquery.ui.datepicker-el.js, jquery.ui.datepicker-en-AU.js, jquery.ui.datepicker-en-GB.js, jquery.ui.datepicker-en-NZ.js, jquery.ui.datepicker-eo.js, jquery.ui.datepicker-es.js, jquery.ui.datepicker-et.js, jquery.ui.datepicker-eu.js, jquery.ui.datepicker-fa.js, jquery.ui.datepicker-fi.js, jquery.ui.datepicker-fo.js, jquery.ui.datepicker-fr-CH.js, jquery.ui.datepicker-fr.js, jquery.ui.datepicker-gl.js, jquery.ui.datepicker-he.js, jquery.ui.datepicker-hi.js, jquery.ui.datepicker-hr.js, jquery.ui.datepicker-hu.js, jquery.ui.datepicker-hy.js, jquery.ui.datepicker-id.js, jquery.ui.datepicker-is.js, jquery.ui.datepicker-it.js, jquery.ui.datepicker-ja.js, jquery.ui.datepicker-ka.js, jquery.ui.datepicker-kk.js, jquery.ui.datepicker-km.js, jquery.ui.datepicker-ko.js, jquery.ui.datepicker-lb.js, jquery.ui.datepicker-lt.js, jquery.ui.datepicker-lv.js, jquery.ui.datepicker-mk.js, jquery.ui.datepicker-ml.js, jquery.ui.datepicker-ms.js, jquery.ui.datepicker-nl-BE.js, jquery.ui.datepicker-nl.js, jquery.ui.datepicker-no.js, jquery.ui.datepicker-pl.js, jquery.ui.datepicker-pt-BR.js, jquery.ui.datepicker-pt.js, jquery.ui.datepicker-rm.js, jquery.ui.datepicker-ro.js, jquery.ui.datepicker-ru.js, jquery.ui.datepicker-sk.js, jquery.ui.datepicker-sl.js, jquery.ui.datepicker-sq.js, jquery.ui.datepicker-sr-SR.js, jquery.ui.datepicker-sr.js, jquery.ui.datepicker-sv.js, jquery.ui.datepicker-ta.js, jquery.ui.datepicker-th.js, jquery.ui.datepicker-tj.js, jquery.ui.datepicker-tr.js, jquery.ui.datepicker-uk.js, jquery.ui.datepicker-vi.js, jquery.ui.datepicker-zh-CN.js, jquery.ui.datepicker-zh-HK.js, jquery.ui.datepicker-zh-TW.js +* Copyright 2012 jQuery Foundation and other contributors; Licensed MIT */ + +/* Afrikaans initialisation for the jQuery UI date picker plugin. */ +/* Written by Renier Pretorius. */ +jQuery(function($){ + $.datepicker.regional['af'] = { + closeText: 'Selekteer', + prevText: 'Vorige', + nextText: 'Volgende', + currentText: 'Vandag', + monthNames: ['Januarie','Februarie','Maart','April','Mei','Junie', + 'Julie','Augustus','September','Oktober','November','Desember'], + monthNamesShort: ['Jan', 'Feb', 'Mrt', 'Apr', 'Mei', 'Jun', + 'Jul', 'Aug', 'Sep', 'Okt', 'Nov', 'Des'], + dayNames: ['Sondag', 'Maandag', 'Dinsdag', 'Woensdag', 'Donderdag', 'Vrydag', 'Saterdag'], + dayNamesShort: ['Son', 'Maa', 'Din', 'Woe', 'Don', 'Vry', 'Sat'], + dayNamesMin: ['So','Ma','Di','Wo','Do','Vr','Sa'], + weekHeader: 'Wk', + dateFormat: 'dd/mm/yy', + firstDay: 1, + isRTL: false, + showMonthAfterYear: false, + yearSuffix: ''}; + $.datepicker.setDefaults($.datepicker.regional['af']); +}); + +/* Algerian Arabic Translation for jQuery UI date picker plugin. (can be used for Tunisia)*/ +/* Mohamed Cherif BOUCHELAGHEM -- cherifbouchelaghem@yahoo.fr */ + +jQuery(function($){ + $.datepicker.regional['ar-DZ'] = { + closeText: 'إغلاق', + prevText: '<السابق', + nextText: 'التالي>', + currentText: 'اليوم', + monthNames: ['جانفي', 'فيفري', 'مارس', 'أفريل', 'ماي', 'جوان', + 'جويلية', 'أوت', 'سبتمبر','أكتوبر', 'نوفمبر', 'ديسمبر'], + monthNamesShort: ['1', '2', '3', '4', '5', '6', '7', '8', '9', '10', '11', '12'], + dayNames: ['الأحد', 'الاثنين', 'الثلاثاء', 'الأربعاء', 'الخميس', 'الجمعة', 'السبت'], + dayNamesShort: ['الأحد', 'الاثنين', 'الثلاثاء', 'الأربعاء', 'الخميس', 'الجمعة', 'السبت'], + dayNamesMin: ['الأحد', 'الاثنين', 'الثلاثاء', 'الأربعاء', 'الخميس', 'الجمعة', 'السبت'], + weekHeader: 'أسبوع', + dateFormat: 'dd/mm/yy', + firstDay: 6, + isRTL: true, + showMonthAfterYear: false, + yearSuffix: ''}; + $.datepicker.setDefaults($.datepicker.regional['ar-DZ']); +}); + +/* Arabic Translation for jQuery UI date picker plugin. */ +/* Khaled Alhourani -- me@khaledalhourani.com */ +/* NOTE: monthNames are the original months names and they are the Arabic names, not the new months name فبراير - يناير and there isn't any Arabic roots for these months */ +jQuery(function($){ + $.datepicker.regional['ar'] = { + closeText: 'إغلاق', + prevText: '<السابق', + nextText: 'التالي>', + currentText: 'اليوم', + monthNames: ['كانون الثاني', 'شباط', 'آذار', 'نيسان', 'مايو', 'حزيران', + 'تموز', 'آب', 'أيلول', 'تشرين الأول', 'تشرين الثاني', 'كانون الأول'], + monthNamesShort: ['1', '2', '3', '4', '5', '6', '7', '8', '9', '10', '11', '12'], + dayNames: ['الأحد', 'الاثنين', 'الثلاثاء', 'الأربعاء', 'الخميس', 'الجمعة', 'السبت'], + dayNamesShort: ['الأحد', 'الاثنين', 'الثلاثاء', 'الأربعاء', 'الخميس', 'الجمعة', 'السبت'], + dayNamesMin: ['ح', 'ن', 'ث', 'ر', 'خ', 'ج', 'س'], + weekHeader: 'أسبوع', + dateFormat: 'dd/mm/yy', + firstDay: 6, + isRTL: true, + showMonthAfterYear: false, + yearSuffix: ''}; + $.datepicker.setDefaults($.datepicker.regional['ar']); +}); +/* Azerbaijani (UTF-8) initialisation for the jQuery UI date picker plugin. */ +/* Written by Jamil Najafov (necefov33@gmail.com). */ +jQuery(function($) { + $.datepicker.regional['az'] = { + closeText: 'Bağla', + prevText: '<Geri', + nextText: 'İrəli>', + currentText: 'Bugün', + monthNames: ['Yanvar','Fevral','Mart','Aprel','May','İyun', + 'İyul','Avqust','Sentyabr','Oktyabr','Noyabr','Dekabr'], + monthNamesShort: ['Yan','Fev','Mar','Apr','May','İyun', + 'İyul','Avq','Sen','Okt','Noy','Dek'], + dayNames: ['Bazar','Bazar ertəsi','Çərşənbə axşamı','Çərşənbə','Cümə axşamı','Cümə','Şənbə'], + dayNamesShort: ['B','Be','Ça','Ç','Ca','C','Ş'], + dayNamesMin: ['B','B','Ç','С','Ç','C','Ş'], + weekHeader: 'Hf', + dateFormat: 'dd.mm.yy', + firstDay: 1, + isRTL: false, + showMonthAfterYear: false, + yearSuffix: ''}; + $.datepicker.setDefaults($.datepicker.regional['az']); +}); +/* Bulgarian initialisation for the jQuery UI date picker plugin. */ +/* Written by Stoyan Kyosev (http://svest.org). */ +jQuery(function($){ + $.datepicker.regional['bg'] = { + closeText: 'затвори', + prevText: '<назад', + nextText: 'напред>', + nextBigText: '>>', + currentText: 'днес', + monthNames: ['Януари','Февруари','Март','Април','Май','Юни', + 'Юли','Август','Септември','Октомври','Ноември','Декември'], + monthNamesShort: ['Яну','Фев','Мар','Апр','Май','Юни', + 'Юли','Авг','Сеп','Окт','Нов','Дек'], + dayNames: ['Неделя','Понеделник','Вторник','Сряда','Четвъртък','Петък','Събота'], + dayNamesShort: ['Нед','Пон','Вто','Сря','Чет','Пет','Съб'], + dayNamesMin: ['Не','По','Вт','Ср','Че','Пе','Съ'], + weekHeader: 'Wk', + dateFormat: 'dd.mm.yy', + firstDay: 1, + isRTL: false, + showMonthAfterYear: false, + yearSuffix: ''}; + $.datepicker.setDefaults($.datepicker.regional['bg']); +}); + +/* Bosnian i18n for the jQuery UI date picker plugin. */ +/* Written by Kenan Konjo. */ +jQuery(function($){ + $.datepicker.regional['bs'] = { + closeText: 'Zatvori', + prevText: '<', + nextText: '>', + currentText: 'Danas', + monthNames: ['Januar','Februar','Mart','April','Maj','Juni', + 'Juli','August','Septembar','Oktobar','Novembar','Decembar'], + monthNamesShort: ['Jan','Feb','Mar','Apr','Maj','Jun', + 'Jul','Aug','Sep','Okt','Nov','Dec'], + dayNames: ['Nedelja','Ponedeljak','Utorak','Srijeda','Četvrtak','Petak','Subota'], + dayNamesShort: ['Ned','Pon','Uto','Sri','Čet','Pet','Sub'], + dayNamesMin: ['Ne','Po','Ut','Sr','Če','Pe','Su'], + weekHeader: 'Wk', + dateFormat: 'dd.mm.yy', + firstDay: 1, + isRTL: false, + showMonthAfterYear: false, + yearSuffix: ''}; + $.datepicker.setDefaults($.datepicker.regional['bs']); +}); +/* Inicialització en català per a l'extensió 'UI date picker' per jQuery. */ +/* Writers: (joan.leon@gmail.com). */ +jQuery(function($){ + $.datepicker.regional['ca'] = { + closeText: 'Tanca', + prevText: 'Anterior', + nextText: 'Següent', + currentText: 'Avui', + monthNames: ['gener','febrer','març','abril','maig','juny', + 'juliol','agost','setembre','octubre','novembre','desembre'], + monthNamesShort: ['gen','feb','març','abr','maig','juny', + 'jul','ag','set','oct','nov','des'], + dayNames: ['diumenge','dilluns','dimarts','dimecres','dijous','divendres','dissabte'], + dayNamesShort: ['dg','dl','dt','dc','dj','dv','ds'], + dayNamesMin: ['dg','dl','dt','dc','dj','dv','ds'], + weekHeader: 'Set', + dateFormat: 'dd/mm/yy', + firstDay: 1, + isRTL: false, + showMonthAfterYear: false, + yearSuffix: ''}; + $.datepicker.setDefaults($.datepicker.regional['ca']); +}); + +/* Czech initialisation for the jQuery UI date picker plugin. */ +/* Written by Tomas Muller (tomas@tomas-muller.net). */ +jQuery(function($){ + $.datepicker.regional['cs'] = { + closeText: 'Zavřít', + prevText: '<Dříve', + nextText: 'Později>', + currentText: 'Nyní', + monthNames: ['leden','únor','březen','duben','květen','červen', + 'červenec','srpen','září','říjen','listopad','prosinec'], + monthNamesShort: ['led','úno','bře','dub','kvě','čer', + 'čvc','srp','zář','říj','lis','pro'], + dayNames: ['neděle', 'pondělí', 'úterý', 'středa', 'čtvrtek', 'pátek', 'sobota'], + dayNamesShort: ['ne', 'po', 'út', 'st', 'čt', 'pá', 'so'], + dayNamesMin: ['ne','po','út','st','čt','pá','so'], + weekHeader: 'Týd', + dateFormat: 'dd.mm.yy', + firstDay: 1, + isRTL: false, + showMonthAfterYear: false, + yearSuffix: ''}; + $.datepicker.setDefaults($.datepicker.regional['cs']); +}); + +/* Welsh/UK initialisation for the jQuery UI date picker plugin. */ +/* Written by William Griffiths. */ +jQuery(function($){ + $.datepicker.regional['cy-GB'] = { + closeText: 'Done', + prevText: 'Prev', + nextText: 'Next', + currentText: 'Today', + monthNames: ['Ionawr','Chwefror','Mawrth','Ebrill','Mai','Mehefin', + 'Gorffennaf','Awst','Medi','Hydref','Tachwedd','Rhagfyr'], + monthNamesShort: ['Ion', 'Chw', 'Maw', 'Ebr', 'Mai', 'Meh', + 'Gor', 'Aws', 'Med', 'Hyd', 'Tac', 'Rha'], + dayNames: ['Dydd Sul', 'Dydd Llun', 'Dydd Mawrth', 'Dydd Mercher', 'Dydd Iau', 'Dydd Gwener', 'Dydd Sadwrn'], + dayNamesShort: ['Sul', 'Llu', 'Maw', 'Mer', 'Iau', 'Gwe', 'Sad'], + dayNamesMin: ['Su','Ll','Ma','Me','Ia','Gw','Sa'], + weekHeader: 'Wy', + dateFormat: 'dd/mm/yy', + firstDay: 1, + isRTL: false, + showMonthAfterYear: false, + yearSuffix: ''}; + $.datepicker.setDefaults($.datepicker.regional['cy-GB']); +}); +/* Danish initialisation for the jQuery UI date picker plugin. */ +/* Written by Jan Christensen ( deletestuff@gmail.com). */ +jQuery(function($){ + $.datepicker.regional['da'] = { + closeText: 'Luk', + prevText: '<Forrige', + nextText: 'Næste>', + currentText: 'Idag', + monthNames: ['Januar','Februar','Marts','April','Maj','Juni', + 'Juli','August','September','Oktober','November','December'], + monthNamesShort: ['Jan','Feb','Mar','Apr','Maj','Jun', + 'Jul','Aug','Sep','Okt','Nov','Dec'], + dayNames: ['Søndag','Mandag','Tirsdag','Onsdag','Torsdag','Fredag','Lørdag'], + dayNamesShort: ['Søn','Man','Tir','Ons','Tor','Fre','Lør'], + dayNamesMin: ['Sø','Ma','Ti','On','To','Fr','Lø'], + weekHeader: 'Uge', + dateFormat: 'dd-mm-yy', + firstDay: 1, + isRTL: false, + showMonthAfterYear: false, + yearSuffix: ''}; + $.datepicker.setDefaults($.datepicker.regional['da']); +}); + +/* German initialisation for the jQuery UI date picker plugin. */ +/* Written by Milian Wolff (mail@milianw.de). */ +jQuery(function($){ + $.datepicker.regional['de'] = { + closeText: 'schließen', + prevText: '<zurück', + nextText: 'Vor>', + currentText: 'heute', + monthNames: ['Januar','Februar','März','April','Mai','Juni', + 'Juli','August','September','Oktober','November','Dezember'], + monthNamesShort: ['Jan','Feb','Mär','Apr','Mai','Jun', + 'Jul','Aug','Sep','Okt','Nov','Dez'], + dayNames: ['Sonntag','Montag','Dienstag','Mittwoch','Donnerstag','Freitag','Samstag'], + dayNamesShort: ['So','Mo','Di','Mi','Do','Fr','Sa'], + dayNamesMin: ['So','Mo','Di','Mi','Do','Fr','Sa'], + weekHeader: 'KW', + dateFormat: 'dd.mm.yy', + firstDay: 1, + isRTL: false, + showMonthAfterYear: false, + yearSuffix: ''}; + $.datepicker.setDefaults($.datepicker.regional['de']); +}); + +/* Greek (el) initialisation for the jQuery UI date picker plugin. */ +/* Written by Alex Cicovic (http://www.alexcicovic.com) */ +jQuery(function($){ + $.datepicker.regional['el'] = { + closeText: 'Κλείσιμο', + prevText: 'Προηγούμενος', + nextText: 'Επόμενος', + currentText: 'Τρέχων Μήνας', + monthNames: ['Ιανουάριος','Φεβρουάριος','Μάρτιος','Απρίλιος','Μάιος','Ιούνιος', + 'Ιούλιος','Αύγουστος','Σεπτέμβριος','Οκτώβριος','Νοέμβριος','Δεκέμβριος'], + monthNamesShort: ['Ιαν','Φεβ','Μαρ','Απρ','Μαι','Ιουν', + 'Ιουλ','Αυγ','Σεπ','Οκτ','Νοε','Δεκ'], + dayNames: ['Κυριακή','Δευτέρα','Τρίτη','Τετάρτη','Πέμπτη','Παρασκευή','Σάββατο'], + dayNamesShort: ['Κυρ','Δευ','Τρι','Τετ','Πεμ','Παρ','Σαβ'], + dayNamesMin: ['Κυ','Δε','Τρ','Τε','Πε','Πα','Σα'], + weekHeader: 'Εβδ', + dateFormat: 'dd/mm/yy', + firstDay: 1, + isRTL: false, + showMonthAfterYear: false, + yearSuffix: ''}; + $.datepicker.setDefaults($.datepicker.regional['el']); +}); +/* English/Australia initialisation for the jQuery UI date picker plugin. */ +/* Based on the en-GB initialisation. */ +jQuery(function($){ + $.datepicker.regional['en-AU'] = { + closeText: 'Done', + prevText: 'Prev', + nextText: 'Next', + currentText: 'Today', + monthNames: ['January','February','March','April','May','June', + 'July','August','September','October','November','December'], + monthNamesShort: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', + 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'], + dayNames: ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'], + dayNamesShort: ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'], + dayNamesMin: ['Su','Mo','Tu','We','Th','Fr','Sa'], + weekHeader: 'Wk', + dateFormat: 'dd/mm/yy', + firstDay: 1, + isRTL: false, + showMonthAfterYear: false, + yearSuffix: ''}; + $.datepicker.setDefaults($.datepicker.regional['en-AU']); +}); + +/* English/UK initialisation for the jQuery UI date picker plugin. */ +/* Written by Stuart. */ +jQuery(function($){ + $.datepicker.regional['en-GB'] = { + closeText: 'Done', + prevText: 'Prev', + nextText: 'Next', + currentText: 'Today', + monthNames: ['January','February','March','April','May','June', + 'July','August','September','October','November','December'], + monthNamesShort: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', + 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'], + dayNames: ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'], + dayNamesShort: ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'], + dayNamesMin: ['Su','Mo','Tu','We','Th','Fr','Sa'], + weekHeader: 'Wk', + dateFormat: 'dd/mm/yy', + firstDay: 1, + isRTL: false, + showMonthAfterYear: false, + yearSuffix: ''}; + $.datepicker.setDefaults($.datepicker.regional['en-GB']); +}); + +/* English/New Zealand initialisation for the jQuery UI date picker plugin. */ +/* Based on the en-GB initialisation. */ +jQuery(function($){ + $.datepicker.regional['en-NZ'] = { + closeText: 'Done', + prevText: 'Prev', + nextText: 'Next', + currentText: 'Today', + monthNames: ['January','February','March','April','May','June', + 'July','August','September','October','November','December'], + monthNamesShort: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', + 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'], + dayNames: ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'], + dayNamesShort: ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'], + dayNamesMin: ['Su','Mo','Tu','We','Th','Fr','Sa'], + weekHeader: 'Wk', + dateFormat: 'dd/mm/yy', + firstDay: 1, + isRTL: false, + showMonthAfterYear: false, + yearSuffix: ''}; + $.datepicker.setDefaults($.datepicker.regional['en-NZ']); +}); + +/* Esperanto initialisation for the jQuery UI date picker plugin. */ +/* Written by Olivier M. (olivierweb@ifrance.com). */ +jQuery(function($){ + $.datepicker.regional['eo'] = { + closeText: 'Fermi', + prevText: '<Anta', + nextText: 'Sekv>', + currentText: 'Nuna', + monthNames: ['Januaro','Februaro','Marto','Aprilo','Majo','Junio', + 'Julio','Aŭgusto','Septembro','Oktobro','Novembro','Decembro'], + monthNamesShort: ['Jan','Feb','Mar','Apr','Maj','Jun', + 'Jul','Aŭg','Sep','Okt','Nov','Dec'], + dayNames: ['Dimanĉo','Lundo','Mardo','Merkredo','Ĵaŭdo','Vendredo','Sabato'], + dayNamesShort: ['Dim','Lun','Mar','Mer','Ĵaŭ','Ven','Sab'], + dayNamesMin: ['Di','Lu','Ma','Me','Ĵa','Ve','Sa'], + weekHeader: 'Sb', + dateFormat: 'dd/mm/yy', + firstDay: 0, + isRTL: false, + showMonthAfterYear: false, + yearSuffix: ''}; + $.datepicker.setDefaults($.datepicker.regional['eo']); +}); + +/* Inicialización en español para la extensión 'UI date picker' para jQuery. */ +/* Traducido por Vester (xvester@gmail.com). */ +jQuery(function($){ + $.datepicker.regional['es'] = { + closeText: 'Cerrar', + prevText: '<Ant', + nextText: 'Sig>', + currentText: 'Hoy', + monthNames: ['Enero','Febrero','Marzo','Abril','Mayo','Junio', + 'Julio','Agosto','Septiembre','Octubre','Noviembre','Diciembre'], + monthNamesShort: ['Ene','Feb','Mar','Abr','May','Jun', + 'Jul','Ago','Sep','Oct','Nov','Dic'], + dayNames: ['Domingo','Lunes','Martes','Miércoles','Jueves','Viernes','Sábado'], + dayNamesShort: ['Dom','Lun','Mar','Mié','Juv','Vie','Sáb'], + dayNamesMin: ['Do','Lu','Ma','Mi','Ju','Vi','Sá'], + weekHeader: 'Sm', + dateFormat: 'dd/mm/yy', + firstDay: 1, + isRTL: false, + showMonthAfterYear: false, + yearSuffix: ''}; + $.datepicker.setDefaults($.datepicker.regional['es']); +}); +/* Estonian initialisation for the jQuery UI date picker plugin. */ +/* Written by Mart Sõmermaa (mrts.pydev at gmail com). */ +jQuery(function($){ + $.datepicker.regional['et'] = { + closeText: 'Sulge', + prevText: 'Eelnev', + nextText: 'Järgnev', + currentText: 'Täna', + monthNames: ['Jaanuar','Veebruar','Märts','Aprill','Mai','Juuni', + 'Juuli','August','September','Oktoober','November','Detsember'], + monthNamesShort: ['Jaan', 'Veebr', 'Märts', 'Apr', 'Mai', 'Juuni', + 'Juuli', 'Aug', 'Sept', 'Okt', 'Nov', 'Dets'], + dayNames: ['Pühapäev', 'Esmaspäev', 'Teisipäev', 'Kolmapäev', 'Neljapäev', 'Reede', 'Laupäev'], + dayNamesShort: ['Pühap', 'Esmasp', 'Teisip', 'Kolmap', 'Neljap', 'Reede', 'Laup'], + dayNamesMin: ['P','E','T','K','N','R','L'], + weekHeader: 'näd', + dateFormat: 'dd.mm.yy', + firstDay: 1, + isRTL: false, + showMonthAfterYear: false, + yearSuffix: ''}; + $.datepicker.setDefaults($.datepicker.regional['et']); +}); +/* Euskarako oinarria 'UI date picker' jquery-ko extentsioarentzat */ +/* Karrikas-ek itzulia (karrikas@karrikas.com) */ +jQuery(function($){ + $.datepicker.regional['eu'] = { + closeText: 'Egina', + prevText: '<Aur', + nextText: 'Hur>', + currentText: 'Gaur', + monthNames: ['urtarrila','otsaila','martxoa','apirila','maiatza','ekaina', + 'uztaila','abuztua','iraila','urria','azaroa','abendua'], + monthNamesShort: ['urt.','ots.','mar.','api.','mai.','eka.', + 'uzt.','abu.','ira.','urr.','aza.','abe.'], + dayNames: ['igandea','astelehena','asteartea','asteazkena','osteguna','ostirala','larunbata'], + dayNamesShort: ['ig.','al.','ar.','az.','og.','ol.','lr.'], + dayNamesMin: ['ig','al','ar','az','og','ol','lr'], + weekHeader: 'As', + dateFormat: 'yy-mm-dd', + firstDay: 1, + isRTL: false, + showMonthAfterYear: false, + yearSuffix: ''}; + $.datepicker.setDefaults($.datepicker.regional['eu']); +}); +/* Persian (Farsi) Translation for the jQuery UI date picker plugin. */ +/* Javad Mowlanezhad -- jmowla@gmail.com */ +/* Jalali calendar should supported soon! (Its implemented but I have to test it) */ +jQuery(function($) { + $.datepicker.regional['fa'] = { + closeText: 'بستن', + prevText: '<قبلی', + nextText: 'بعدی>', + currentText: 'امروز', + monthNames: [ + 'فروردين', + 'ارديبهشت', + 'خرداد', + 'تير', + 'مرداد', + 'شهريور', + 'مهر', + 'آبان', + 'آذر', + 'دی', + 'بهمن', + 'اسفند' + ], + monthNamesShort: ['1','2','3','4','5','6','7','8','9','10','11','12'], + dayNames: [ + 'يکشنبه', + 'دوشنبه', + 'سه‌شنبه', + 'چهارشنبه', + 'پنجشنبه', + 'جمعه', + 'شنبه' + ], + dayNamesShort: [ + 'ی', + 'د', + 'س', + 'چ', + 'پ', + 'ج', + 'ش' + ], + dayNamesMin: [ + 'ی', + 'د', + 'س', + 'چ', + 'پ', + 'ج', + 'ش' + ], + weekHeader: 'هف', + dateFormat: 'yy/mm/dd', + firstDay: 6, + isRTL: true, + showMonthAfterYear: false, + yearSuffix: ''}; + $.datepicker.setDefaults($.datepicker.regional['fa']); +}); +/* Finnish initialisation for the jQuery UI date picker plugin. */ +/* Written by Harri Kilpiö (harrikilpio@gmail.com). */ +jQuery(function($){ + $.datepicker.regional['fi'] = { + closeText: 'Sulje', + prevText: '«Edellinen', + nextText: 'Seuraava»', + currentText: 'Tänään', + monthNames: ['Tammikuu','Helmikuu','Maaliskuu','Huhtikuu','Toukokuu','Kesäkuu', + 'Heinäkuu','Elokuu','Syyskuu','Lokakuu','Marraskuu','Joulukuu'], + monthNamesShort: ['Tammi','Helmi','Maalis','Huhti','Touko','Kesä', + 'Heinä','Elo','Syys','Loka','Marras','Joulu'], + dayNamesShort: ['Su','Ma','Ti','Ke','To','Pe','La'], + dayNames: ['Sunnuntai','Maanantai','Tiistai','Keskiviikko','Torstai','Perjantai','Lauantai'], + dayNamesMin: ['Su','Ma','Ti','Ke','To','Pe','La'], + weekHeader: 'Vk', + dateFormat: 'dd.mm.yy', + firstDay: 1, + isRTL: false, + showMonthAfterYear: false, + yearSuffix: ''}; + $.datepicker.setDefaults($.datepicker.regional['fi']); +}); + +/* Faroese initialisation for the jQuery UI date picker plugin */ +/* Written by Sverri Mohr Olsen, sverrimo@gmail.com */ +jQuery(function($){ + $.datepicker.regional['fo'] = { + closeText: 'Lat aftur', + prevText: '<Fyrra', + nextText: 'Næsta>', + currentText: 'Í dag', + monthNames: ['Januar','Februar','Mars','Apríl','Mei','Juni', + 'Juli','August','September','Oktober','November','Desember'], + monthNamesShort: ['Jan','Feb','Mar','Apr','Mei','Jun', + 'Jul','Aug','Sep','Okt','Nov','Des'], + dayNames: ['Sunnudagur','Mánadagur','Týsdagur','Mikudagur','Hósdagur','Fríggjadagur','Leyardagur'], + dayNamesShort: ['Sun','Mán','Týs','Mik','Hós','Frí','Ley'], + dayNamesMin: ['Su','Má','Tý','Mi','Hó','Fr','Le'], + weekHeader: 'Vk', + dateFormat: 'dd-mm-yy', + firstDay: 0, + isRTL: false, + showMonthAfterYear: false, + yearSuffix: ''}; + $.datepicker.setDefaults($.datepicker.regional['fo']); +}); + +/* Swiss-French initialisation for the jQuery UI date picker plugin. */ +/* Written Martin Voelkle (martin.voelkle@e-tc.ch). */ +jQuery(function($){ + $.datepicker.regional['fr-CH'] = { + closeText: 'Fermer', + prevText: '<Préc', + nextText: 'Suiv>', + currentText: 'Courant', + monthNames: ['Janvier','Février','Mars','Avril','Mai','Juin', + 'Juillet','Août','Septembre','Octobre','Novembre','Décembre'], + monthNamesShort: ['Jan','Fév','Mar','Avr','Mai','Jun', + 'Jul','Aoû','Sep','Oct','Nov','Déc'], + dayNames: ['Dimanche','Lundi','Mardi','Mercredi','Jeudi','Vendredi','Samedi'], + dayNamesShort: ['Dim','Lun','Mar','Mer','Jeu','Ven','Sam'], + dayNamesMin: ['Di','Lu','Ma','Me','Je','Ve','Sa'], + weekHeader: 'Sm', + dateFormat: 'dd.mm.yy', + firstDay: 1, + isRTL: false, + showMonthAfterYear: false, + yearSuffix: ''}; + $.datepicker.setDefaults($.datepicker.regional['fr-CH']); +}); +/* French initialisation for the jQuery UI date picker plugin. */ +/* Written by Keith Wood (kbwood{at}iinet.com.au), + Stéphane Nahmani (sholby@sholby.net), + Stéphane Raimbault */ +jQuery(function($){ + $.datepicker.regional['fr'] = { + closeText: 'Fermer', + prevText: 'Précédent', + nextText: 'Suivant', + currentText: 'Aujourd\'hui', + monthNames: ['Janvier','Février','Mars','Avril','Mai','Juin', + 'Juillet','Août','Septembre','Octobre','Novembre','Décembre'], + monthNamesShort: ['Janv.','Févr.','Mars','Avril','Mai','Juin', + 'Juil.','Août','Sept.','Oct.','Nov.','Déc.'], + dayNames: ['Dimanche','Lundi','Mardi','Mercredi','Jeudi','Vendredi','Samedi'], + dayNamesShort: ['Dim.','Lun.','Mar.','Mer.','Jeu.','Ven.','Sam.'], + dayNamesMin: ['D','L','M','M','J','V','S'], + weekHeader: 'Sem.', + dateFormat: 'dd/mm/yy', + firstDay: 1, + isRTL: false, + showMonthAfterYear: false, + yearSuffix: ''}; + $.datepicker.setDefaults($.datepicker.regional['fr']); +}); + +/* Galician localization for 'UI date picker' jQuery extension. */ +/* Translated by Jorge Barreiro . */ +jQuery(function($){ + $.datepicker.regional['gl'] = { + closeText: 'Pechar', + prevText: '<Ant', + nextText: 'Seg>', + currentText: 'Hoxe', + monthNames: ['Xaneiro','Febreiro','Marzo','Abril','Maio','Xuño', + 'Xullo','Agosto','Setembro','Outubro','Novembro','Decembro'], + monthNamesShort: ['Xan','Feb','Mar','Abr','Mai','Xuñ', + 'Xul','Ago','Set','Out','Nov','Dec'], + dayNames: ['Domingo','Luns','Martes','Mércores','Xoves','Venres','Sábado'], + dayNamesShort: ['Dom','Lun','Mar','Mér','Xov','Ven','Sáb'], + dayNamesMin: ['Do','Lu','Ma','Mé','Xo','Ve','Sá'], + weekHeader: 'Sm', + dateFormat: 'dd/mm/yy', + firstDay: 1, + isRTL: false, + showMonthAfterYear: false, + yearSuffix: ''}; + $.datepicker.setDefaults($.datepicker.regional['gl']); +}); +/* Hebrew initialisation for the UI Datepicker extension. */ +/* Written by Amir Hardon (ahardon at gmail dot com). */ +jQuery(function($){ + $.datepicker.regional['he'] = { + closeText: 'סגור', + prevText: '<הקודם', + nextText: 'הבא>', + currentText: 'היום', + monthNames: ['ינואר','פברואר','מרץ','אפריל','מאי','יוני', + 'יולי','אוגוסט','ספטמבר','אוקטובר','נובמבר','דצמבר'], + monthNamesShort: ['ינו','פבר','מרץ','אפר','מאי','יוני', + 'יולי','אוג','ספט','אוק','נוב','דצמ'], + dayNames: ['ראשון','שני','שלישי','רביעי','חמישי','שישי','שבת'], + dayNamesShort: ['א\'','ב\'','ג\'','ד\'','ה\'','ו\'','שבת'], + dayNamesMin: ['א\'','ב\'','ג\'','ד\'','ה\'','ו\'','שבת'], + weekHeader: 'Wk', + dateFormat: 'dd/mm/yy', + firstDay: 0, + isRTL: true, + showMonthAfterYear: false, + yearSuffix: ''}; + $.datepicker.setDefaults($.datepicker.regional['he']); +}); + +/* Hindi initialisation for the jQuery UI date picker plugin. */ +/* Written by Michael Dawart. */ +jQuery(function($){ + $.datepicker.regional['hi'] = { + closeText: 'बंद', + prevText: 'पिछला', + nextText: 'अगला', + currentText: 'आज', + monthNames: ['जनवरी ','फरवरी','मार्च','अप्रेल','मई','जून', + 'जूलाई','अगस्त ','सितम्बर','अक्टूबर','नवम्बर','दिसम्बर'], + monthNamesShort: ['जन', 'फर', 'मार्च', 'अप्रेल', 'मई', 'जून', + 'जूलाई', 'अग', 'सित', 'अक्ट', 'नव', 'दि'], + dayNames: ['रविवार', 'सोमवार', 'मंगलवार', 'बुधवार', 'गुरुवार', 'शुक्रवार', 'शनिवार'], + dayNamesShort: ['रवि', 'सोम', 'मंगल', 'बुध', 'गुरु', 'शुक्र', 'शनि'], + dayNamesMin: ['रवि', 'सोम', 'मंगल', 'बुध', 'गुरु', 'शुक्र', 'शनि'], + weekHeader: 'हफ्ता', + dateFormat: 'dd/mm/yy', + firstDay: 1, + isRTL: false, + showMonthAfterYear: false, + yearSuffix: ''}; + $.datepicker.setDefaults($.datepicker.regional['hi']); +}); + +/* Croatian i18n for the jQuery UI date picker plugin. */ +/* Written by Vjekoslav Nesek. */ +jQuery(function($){ + $.datepicker.regional['hr'] = { + closeText: 'Zatvori', + prevText: '<', + nextText: '>', + currentText: 'Danas', + monthNames: ['Siječanj','Veljača','Ožujak','Travanj','Svibanj','Lipanj', + 'Srpanj','Kolovoz','Rujan','Listopad','Studeni','Prosinac'], + monthNamesShort: ['Sij','Velj','Ožu','Tra','Svi','Lip', + 'Srp','Kol','Ruj','Lis','Stu','Pro'], + dayNames: ['Nedjelja','Ponedjeljak','Utorak','Srijeda','Četvrtak','Petak','Subota'], + dayNamesShort: ['Ned','Pon','Uto','Sri','Čet','Pet','Sub'], + dayNamesMin: ['Ne','Po','Ut','Sr','Če','Pe','Su'], + weekHeader: 'Tje', + dateFormat: 'dd.mm.yy.', + firstDay: 1, + isRTL: false, + showMonthAfterYear: false, + yearSuffix: ''}; + $.datepicker.setDefaults($.datepicker.regional['hr']); +}); +/* Hungarian initialisation for the jQuery UI date picker plugin. */ +/* Written by Istvan Karaszi (jquery@spam.raszi.hu). */ +jQuery(function($){ + $.datepicker.regional['hu'] = { + closeText: 'bezár', + prevText: 'vissza', + nextText: 'előre', + currentText: 'ma', + monthNames: ['Január', 'Február', 'Március', 'Április', 'Május', 'Június', + 'Július', 'Augusztus', 'Szeptember', 'Október', 'November', 'December'], + monthNamesShort: ['Jan', 'Feb', 'Már', 'Ápr', 'Máj', 'Jún', + 'Júl', 'Aug', 'Szep', 'Okt', 'Nov', 'Dec'], + dayNames: ['Vasárnap', 'Hétfő', 'Kedd', 'Szerda', 'Csütörtök', 'Péntek', 'Szombat'], + dayNamesShort: ['Vas', 'Hét', 'Ked', 'Sze', 'Csü', 'Pén', 'Szo'], + dayNamesMin: ['V', 'H', 'K', 'Sze', 'Cs', 'P', 'Szo'], + weekHeader: 'Hét', + dateFormat: 'yy.mm.dd.', + firstDay: 1, + isRTL: false, + showMonthAfterYear: true, + yearSuffix: ''}; + $.datepicker.setDefaults($.datepicker.regional['hu']); +}); + +/* Armenian(UTF-8) initialisation for the jQuery UI date picker plugin. */ +/* Written by Levon Zakaryan (levon.zakaryan@gmail.com)*/ +jQuery(function($){ + $.datepicker.regional['hy'] = { + closeText: 'Փակել', + prevText: '<Նախ.', + nextText: 'Հաջ.>', + currentText: 'Այսօր', + monthNames: ['Հունվար','Փետրվար','Մարտ','Ապրիլ','Մայիս','Հունիս', + 'Հուլիս','Օգոստոս','Սեպտեմբեր','Հոկտեմբեր','Նոյեմբեր','Դեկտեմբեր'], + monthNamesShort: ['Հունվ','Փետր','Մարտ','Ապր','Մայիս','Հունիս', + 'Հուլ','Օգս','Սեպ','Հոկ','Նոյ','Դեկ'], + dayNames: ['կիրակի','եկուշաբթի','երեքշաբթի','չորեքշաբթի','հինգշաբթի','ուրբաթ','շաբաթ'], + dayNamesShort: ['կիր','երկ','երք','չրք','հնգ','ուրբ','շբթ'], + dayNamesMin: ['կիր','երկ','երք','չրք','հնգ','ուրբ','շբթ'], + weekHeader: 'ՇԲՏ', + dateFormat: 'dd.mm.yy', + firstDay: 1, + isRTL: false, + showMonthAfterYear: false, + yearSuffix: ''}; + $.datepicker.setDefaults($.datepicker.regional['hy']); +}); +/* Indonesian initialisation for the jQuery UI date picker plugin. */ +/* Written by Deden Fathurahman (dedenf@gmail.com). */ +jQuery(function($){ + $.datepicker.regional['id'] = { + closeText: 'Tutup', + prevText: '<mundur', + nextText: 'maju>', + currentText: 'hari ini', + monthNames: ['Januari','Februari','Maret','April','Mei','Juni', + 'Juli','Agustus','September','Oktober','Nopember','Desember'], + monthNamesShort: ['Jan','Feb','Mar','Apr','Mei','Jun', + 'Jul','Agus','Sep','Okt','Nop','Des'], + dayNames: ['Minggu','Senin','Selasa','Rabu','Kamis','Jumat','Sabtu'], + dayNamesShort: ['Min','Sen','Sel','Rab','kam','Jum','Sab'], + dayNamesMin: ['Mg','Sn','Sl','Rb','Km','jm','Sb'], + weekHeader: 'Mg', + dateFormat: 'dd/mm/yy', + firstDay: 0, + isRTL: false, + showMonthAfterYear: false, + yearSuffix: ''}; + $.datepicker.setDefaults($.datepicker.regional['id']); +}); +/* Icelandic initialisation for the jQuery UI date picker plugin. */ +/* Written by Haukur H. Thorsson (haukur@eskill.is). */ +jQuery(function($){ + $.datepicker.regional['is'] = { + closeText: 'Loka', + prevText: '< Fyrri', + nextText: 'Næsti >', + currentText: 'Í dag', + monthNames: ['Janúar','Febrúar','Mars','Apríl','Maí','Júní', + 'Júlí','Ágúst','September','Október','Nóvember','Desember'], + monthNamesShort: ['Jan','Feb','Mar','Apr','Maí','Jún', + 'Júl','Ágú','Sep','Okt','Nóv','Des'], + dayNames: ['Sunnudagur','Mánudagur','Þriðjudagur','Miðvikudagur','Fimmtudagur','Föstudagur','Laugardagur'], + dayNamesShort: ['Sun','Mán','Þri','Mið','Fim','Fös','Lau'], + dayNamesMin: ['Su','Má','Þr','Mi','Fi','Fö','La'], + weekHeader: 'Vika', + dateFormat: 'dd/mm/yy', + firstDay: 0, + isRTL: false, + showMonthAfterYear: false, + yearSuffix: ''}; + $.datepicker.setDefaults($.datepicker.regional['is']); +}); +/* Italian initialisation for the jQuery UI date picker plugin. */ +/* Written by Antonello Pasella (antonello.pasella@gmail.com). */ +jQuery(function($){ + $.datepicker.regional['it'] = { + closeText: 'Chiudi', + prevText: '<Prec', + nextText: 'Succ>', + currentText: 'Oggi', + monthNames: ['Gennaio','Febbraio','Marzo','Aprile','Maggio','Giugno', + 'Luglio','Agosto','Settembre','Ottobre','Novembre','Dicembre'], + monthNamesShort: ['Gen','Feb','Mar','Apr','Mag','Giu', + 'Lug','Ago','Set','Ott','Nov','Dic'], + dayNames: ['Domenica','Lunedì','Martedì','Mercoledì','Giovedì','Venerdì','Sabato'], + dayNamesShort: ['Dom','Lun','Mar','Mer','Gio','Ven','Sab'], + dayNamesMin: ['Do','Lu','Ma','Me','Gi','Ve','Sa'], + weekHeader: 'Sm', + dateFormat: 'dd/mm/yy', + firstDay: 1, + isRTL: false, + showMonthAfterYear: false, + yearSuffix: ''}; + $.datepicker.setDefaults($.datepicker.regional['it']); +}); + +/* Japanese initialisation for the jQuery UI date picker plugin. */ +/* Written by Kentaro SATO (kentaro@ranvis.com). */ +jQuery(function($){ + $.datepicker.regional['ja'] = { + closeText: '閉じる', + prevText: '<前', + nextText: '次>', + currentText: '今日', + monthNames: ['1月','2月','3月','4月','5月','6月', + '7月','8月','9月','10月','11月','12月'], + monthNamesShort: ['1月','2月','3月','4月','5月','6月', + '7月','8月','9月','10月','11月','12月'], + dayNames: ['日曜日','月曜日','火曜日','水曜日','木曜日','金曜日','土曜日'], + dayNamesShort: ['日','月','火','水','木','金','土'], + dayNamesMin: ['日','月','火','水','木','金','土'], + weekHeader: '週', + dateFormat: 'yy/mm/dd', + firstDay: 0, + isRTL: false, + showMonthAfterYear: true, + yearSuffix: '年'}; + $.datepicker.setDefaults($.datepicker.regional['ja']); +}); +/* Georgian (UTF-8) initialisation for the jQuery UI date picker plugin. */ +/* Written by Lado Lomidze (lado.lomidze@gmail.com). */ +jQuery(function($){ + $.datepicker.regional['ka'] = { + closeText: 'დახურვა', + prevText: '< წინა', + nextText: 'შემდეგი >', + currentText: 'დღეს', + monthNames: ['იანვარი','თებერვალი','მარტი','აპრილი','მაისი','ივნისი', 'ივლისი','აგვისტო','სექტემბერი','ოქტომბერი','ნოემბერი','დეკემბერი'], + monthNamesShort: ['იან','თებ','მარ','აპრ','მაი','ივნ', 'ივლ','აგვ','სექ','ოქტ','ნოე','დეკ'], + dayNames: ['კვირა','ორშაბათი','სამშაბათი','ოთხშაბათი','ხუთშაბათი','პარასკევი','შაბათი'], + dayNamesShort: ['კვ','ორშ','სამ','ოთხ','ხუთ','პარ','შაბ'], + dayNamesMin: ['კვ','ორშ','სამ','ოთხ','ხუთ','პარ','შაბ'], + weekHeader: 'კვირა', + dateFormat: 'dd-mm-yy', + firstDay: 1, + isRTL: false, + showMonthAfterYear: false, + yearSuffix: ''}; + $.datepicker.setDefaults($.datepicker.regional['ka']); +}); + +/* Kazakh (UTF-8) initialisation for the jQuery UI date picker plugin. */ +/* Written by Dmitriy Karasyov (dmitriy.karasyov@gmail.com). */ +jQuery(function($){ + $.datepicker.regional['kk'] = { + closeText: 'Жабу', + prevText: '<Алдыңғы', + nextText: 'Келесі>', + currentText: 'Бүгін', + monthNames: ['Қаңтар','Ақпан','Наурыз','Сәуір','Мамыр','Маусым', + 'Шілде','Тамыз','Қыркүйек','Қазан','Қараша','Желтоқсан'], + monthNamesShort: ['Қаң','Ақп','Нау','Сәу','Мам','Мау', + 'Шіл','Там','Қыр','Қаз','Қар','Жел'], + dayNames: ['Жексенбі','Дүйсенбі','Сейсенбі','Сәрсенбі','Бейсенбі','Жұма','Сенбі'], + dayNamesShort: ['жкс','дсн','ссн','срс','бсн','жма','снб'], + dayNamesMin: ['Жк','Дс','Сс','Ср','Бс','Жм','Сн'], + weekHeader: 'Не', + dateFormat: 'dd.mm.yy', + firstDay: 1, + isRTL: false, + showMonthAfterYear: false, + yearSuffix: ''}; + $.datepicker.setDefaults($.datepicker.regional['kk']); +}); + +/* Khmer initialisation for the jQuery calendar extension. */ +/* Written by Chandara Om (chandara.teacher@gmail.com). */ +jQuery(function($){ + $.datepicker.regional['km'] = { + closeText: 'ធ្វើ​រួច', + prevText: 'មុន', + nextText: 'បន្ទាប់', + currentText: 'ថ្ងៃ​នេះ', + monthNames: ['មករា','កុម្ភៈ','មីនា','មេសា','ឧសភា','មិថុនា', + 'កក្កដា','សីហា','កញ្ញា','តុលា','វិច្ឆិកា','ធ្នូ'], + monthNamesShort: ['មករា','កុម្ភៈ','មីនា','មេសា','ឧសភា','មិថុនា', + 'កក្កដា','សីហា','កញ្ញា','តុលា','វិច្ឆិកា','ធ្នូ'], + dayNames: ['អាទិត្យ', 'ចន្ទ', 'អង្គារ', 'ពុធ', 'ព្រហស្បតិ៍', 'សុក្រ', 'សៅរ៍'], + dayNamesShort: ['អា', 'ច', 'អ', 'ពុ', 'ព្រហ', 'សុ', 'សៅ'], + dayNamesMin: ['អា', 'ច', 'អ', 'ពុ', 'ព្រហ', 'សុ', 'សៅ'], + weekHeader: 'សប្ដាហ៍', + dateFormat: 'dd-mm-yy', + firstDay: 1, + isRTL: false, + showMonthAfterYear: false, + yearSuffix: ''}; + $.datepicker.setDefaults($.datepicker.regional['km']); +}); + +/* Korean initialisation for the jQuery calendar extension. */ +/* Written by DaeKwon Kang (ncrash.dk@gmail.com), Edited by Genie. */ +jQuery(function($){ + $.datepicker.regional['ko'] = { + closeText: '닫기', + prevText: '이전달', + nextText: '다음달', + currentText: '오늘', + monthNames: ['1월','2월','3월','4월','5월','6월', + '7월','8월','9월','10월','11월','12월'], + monthNamesShort: ['1월','2월','3월','4월','5월','6월', + '7월','8월','9월','10월','11월','12월'], + dayNames: ['일요일','월요일','화요일','수요일','목요일','금요일','토요일'], + dayNamesShort: ['일','월','화','수','목','금','토'], + dayNamesMin: ['일','월','화','수','목','금','토'], + weekHeader: 'Wk', + dateFormat: 'yy-mm-dd', + firstDay: 0, + isRTL: false, + showMonthAfterYear: true, + yearSuffix: '년'}; + $.datepicker.setDefaults($.datepicker.regional['ko']); +}); +/* Luxembourgish initialisation for the jQuery UI date picker plugin. */ +/* Written by Michel Weimerskirch */ +jQuery(function($){ + $.datepicker.regional['lb'] = { + closeText: 'Fäerdeg', + prevText: 'Zréck', + nextText: 'Weider', + currentText: 'Haut', + monthNames: ['Januar','Februar','Mäerz','Abrëll','Mee','Juni', + 'Juli','August','September','Oktober','November','Dezember'], + monthNamesShort: ['Jan', 'Feb', 'Mäe', 'Abr', 'Mee', 'Jun', + 'Jul', 'Aug', 'Sep', 'Okt', 'Nov', 'Dez'], + dayNames: ['Sonndeg', 'Méindeg', 'Dënschdeg', 'Mëttwoch', 'Donneschdeg', 'Freideg', 'Samschdeg'], + dayNamesShort: ['Son', 'Méi', 'Dën', 'Mët', 'Don', 'Fre', 'Sam'], + dayNamesMin: ['So','Mé','Dë','Më','Do','Fr','Sa'], + weekHeader: 'W', + dateFormat: 'dd.mm.yy', + firstDay: 1, + isRTL: false, + showMonthAfterYear: false, + yearSuffix: ''}; + $.datepicker.setDefaults($.datepicker.regional['lb']); +}); + +/* Lithuanian (UTF-8) initialisation for the jQuery UI date picker plugin. */ +/* @author Arturas Paleicikas */ +jQuery(function($){ + $.datepicker.regional['lt'] = { + closeText: 'Uždaryti', + prevText: '<Atgal', + nextText: 'Pirmyn>', + currentText: 'Šiandien', + monthNames: ['Sausis','Vasaris','Kovas','Balandis','Gegužė','Birželis', + 'Liepa','Rugpjūtis','Rugsėjis','Spalis','Lapkritis','Gruodis'], + monthNamesShort: ['Sau','Vas','Kov','Bal','Geg','Bir', + 'Lie','Rugp','Rugs','Spa','Lap','Gru'], + dayNames: ['sekmadienis','pirmadienis','antradienis','trečiadienis','ketvirtadienis','penktadienis','šeštadienis'], + dayNamesShort: ['sek','pir','ant','tre','ket','pen','šeš'], + dayNamesMin: ['Se','Pr','An','Tr','Ke','Pe','Še'], + weekHeader: 'Wk', + dateFormat: 'yy-mm-dd', + firstDay: 1, + isRTL: false, + showMonthAfterYear: false, + yearSuffix: ''}; + $.datepicker.setDefaults($.datepicker.regional['lt']); +}); +/* Latvian (UTF-8) initialisation for the jQuery UI date picker plugin. */ +/* @author Arturas Paleicikas */ +jQuery(function($){ + $.datepicker.regional['lv'] = { + closeText: 'Aizvērt', + prevText: 'Iepr', + nextText: 'Nāka', + currentText: 'Šodien', + monthNames: ['Janvāris','Februāris','Marts','Aprīlis','Maijs','Jūnijs', + 'Jūlijs','Augusts','Septembris','Oktobris','Novembris','Decembris'], + monthNamesShort: ['Jan','Feb','Mar','Apr','Mai','Jūn', + 'Jūl','Aug','Sep','Okt','Nov','Dec'], + dayNames: ['svētdiena','pirmdiena','otrdiena','trešdiena','ceturtdiena','piektdiena','sestdiena'], + dayNamesShort: ['svt','prm','otr','tre','ctr','pkt','sst'], + dayNamesMin: ['Sv','Pr','Ot','Tr','Ct','Pk','Ss'], + weekHeader: 'Nav', + dateFormat: 'dd-mm-yy', + firstDay: 1, + isRTL: false, + showMonthAfterYear: false, + yearSuffix: ''}; + $.datepicker.setDefaults($.datepicker.regional['lv']); +}); +/* Macedonian i18n for the jQuery UI date picker plugin. */ +/* Written by Stojce Slavkovski. */ +jQuery(function($){ + $.datepicker.regional['mk'] = { + closeText: 'Затвори', + prevText: '<', + nextText: '>', + currentText: 'Денес', + monthNames: ['Јануари','Февруари','Март','Април','Мај','Јуни', + 'Јули','Август','Септември','Октомври','Ноември','Декември'], + monthNamesShort: ['Јан','Фев','Мар','Апр','Мај','Јун', + 'Јул','Авг','Сеп','Окт','Ное','Дек'], + dayNames: ['Недела','Понеделник','Вторник','Среда','Четврток','Петок','Сабота'], + dayNamesShort: ['Нед','Пон','Вто','Сре','Чет','Пет','Саб'], + dayNamesMin: ['Не','По','Вт','Ср','Че','Пе','Са'], + weekHeader: 'Сед', + dateFormat: 'dd.mm.yy', + firstDay: 1, + isRTL: false, + showMonthAfterYear: false, + yearSuffix: ''}; + $.datepicker.setDefaults($.datepicker.regional['mk']); +}); + +/* Malayalam (UTF-8) initialisation for the jQuery UI date picker plugin. */ +/* Written by Saji Nediyanchath (saji89@gmail.com). */ +jQuery(function($){ + $.datepicker.regional['ml'] = { + closeText: 'ശരി', + prevText: 'മുന്നത്തെ', + nextText: 'അടുത്തത് ', + currentText: 'ഇന്ന്', + monthNames: ['ജനുവരി','ഫെബ്രുവരി','മാര്‍ച്ച്','ഏപ്രില്‍','മേയ്','ജൂണ്‍', + 'ജൂലൈ','ആഗസ്റ്റ്','സെപ്റ്റംബര്‍','ഒക്ടോബര്‍','നവംബര്‍','ഡിസംബര്‍'], + monthNamesShort: ['ജനു', 'ഫെബ്', 'മാര്‍', 'ഏപ്രി', 'മേയ്', 'ജൂണ്‍', + 'ജൂലാ', 'ആഗ', 'സെപ്', 'ഒക്ടോ', 'നവം', 'ഡിസ'], + dayNames: ['ഞായര്‍', 'തിങ്കള്‍', 'ചൊവ്വ', 'ബുധന്‍', 'വ്യാഴം', 'വെള്ളി', 'ശനി'], + dayNamesShort: ['ഞായ', 'തിങ്ക', 'ചൊവ്വ', 'ബുധ', 'വ്യാഴം', 'വെള്ളി', 'ശനി'], + dayNamesMin: ['ഞാ','തി','ചൊ','ബു','വ്യാ','വെ','ശ'], + weekHeader: 'ആ', + dateFormat: 'dd/mm/yy', + firstDay: 1, + isRTL: false, + showMonthAfterYear: false, + yearSuffix: ''}; + $.datepicker.setDefaults($.datepicker.regional['ml']); +}); + +/* Malaysian initialisation for the jQuery UI date picker plugin. */ +/* Written by Mohd Nawawi Mohamad Jamili (nawawi@ronggeng.net). */ +jQuery(function($){ + $.datepicker.regional['ms'] = { + closeText: 'Tutup', + prevText: '<Sebelum', + nextText: 'Selepas>', + currentText: 'hari ini', + monthNames: ['Januari','Februari','Mac','April','Mei','Jun', + 'Julai','Ogos','September','Oktober','November','Disember'], + monthNamesShort: ['Jan','Feb','Mac','Apr','Mei','Jun', + 'Jul','Ogo','Sep','Okt','Nov','Dis'], + dayNames: ['Ahad','Isnin','Selasa','Rabu','Khamis','Jumaat','Sabtu'], + dayNamesShort: ['Aha','Isn','Sel','Rab','kha','Jum','Sab'], + dayNamesMin: ['Ah','Is','Se','Ra','Kh','Ju','Sa'], + weekHeader: 'Mg', + dateFormat: 'dd/mm/yy', + firstDay: 0, + isRTL: false, + showMonthAfterYear: false, + yearSuffix: ''}; + $.datepicker.setDefaults($.datepicker.regional['ms']); +}); +/* Dutch (Belgium) initialisation for the jQuery UI date picker plugin. */ +/* David De Sloovere @DavidDeSloovere */ +jQuery(function($){ + $.datepicker.regional['nl-BE'] = { + closeText: 'Sluiten', + prevText: '←', + nextText: '→', + currentText: 'Vandaag', + monthNames: ['januari', 'februari', 'maart', 'april', 'mei', 'juni', + 'juli', 'augustus', 'september', 'oktober', 'november', 'december'], + monthNamesShort: ['jan', 'feb', 'mrt', 'apr', 'mei', 'jun', + 'jul', 'aug', 'sep', 'okt', 'nov', 'dec'], + dayNames: ['zondag', 'maandag', 'dinsdag', 'woensdag', 'donderdag', 'vrijdag', 'zaterdag'], + dayNamesShort: ['zon', 'maa', 'din', 'woe', 'don', 'vri', 'zat'], + dayNamesMin: ['zo', 'ma', 'di', 'wo', 'do', 'vr', 'za'], + weekHeader: 'Wk', + dateFormat: 'dd/mm/yy', + firstDay: 1, + isRTL: false, + showMonthAfterYear: false, + yearSuffix: ''}; + $.datepicker.setDefaults($.datepicker.regional['nl-BE']); +}); + +/* Dutch (UTF-8) initialisation for the jQuery UI date picker plugin. */ +/* Written by Mathias Bynens */ +jQuery(function($){ + $.datepicker.regional.nl = { + closeText: 'Sluiten', + prevText: '←', + nextText: '→', + currentText: 'Vandaag', + monthNames: ['januari', 'februari', 'maart', 'april', 'mei', 'juni', + 'juli', 'augustus', 'september', 'oktober', 'november', 'december'], + monthNamesShort: ['jan', 'feb', 'mrt', 'apr', 'mei', 'jun', + 'jul', 'aug', 'sep', 'okt', 'nov', 'dec'], + dayNames: ['zondag', 'maandag', 'dinsdag', 'woensdag', 'donderdag', 'vrijdag', 'zaterdag'], + dayNamesShort: ['zon', 'maa', 'din', 'woe', 'don', 'vri', 'zat'], + dayNamesMin: ['zo', 'ma', 'di', 'wo', 'do', 'vr', 'za'], + weekHeader: 'Wk', + dateFormat: 'dd-mm-yy', + firstDay: 1, + isRTL: false, + showMonthAfterYear: false, + yearSuffix: ''}; + $.datepicker.setDefaults($.datepicker.regional.nl); +}); +/* Norwegian initialisation for the jQuery UI date picker plugin. */ +/* Written by Naimdjon Takhirov (naimdjon@gmail.com). */ + +jQuery(function($){ + $.datepicker.regional['no'] = { + closeText: 'Lukk', + prevText: '«Forrige', + nextText: 'Neste»', + currentText: 'I dag', + monthNames: ['januar','februar','mars','april','mai','juni','juli','august','september','oktober','november','desember'], + monthNamesShort: ['jan','feb','mar','apr','mai','jun','jul','aug','sep','okt','nov','des'], + dayNamesShort: ['søn','man','tir','ons','tor','fre','lør'], + dayNames: ['søndag','mandag','tirsdag','onsdag','torsdag','fredag','lørdag'], + dayNamesMin: ['sø','ma','ti','on','to','fr','lø'], + weekHeader: 'Uke', + dateFormat: 'dd.mm.yy', + firstDay: 1, + isRTL: false, + showMonthAfterYear: false, + yearSuffix: '' + }; + $.datepicker.setDefaults($.datepicker.regional['no']); +}); + +/* Polish initialisation for the jQuery UI date picker plugin. */ +/* Written by Jacek Wysocki (jacek.wysocki@gmail.com). */ +jQuery(function($){ + $.datepicker.regional['pl'] = { + closeText: 'Zamknij', + prevText: '<Poprzedni', + nextText: 'Następny>', + currentText: 'Dziś', + monthNames: ['Styczeń','Luty','Marzec','Kwiecień','Maj','Czerwiec', + 'Lipiec','Sierpień','Wrzesień','Październik','Listopad','Grudzień'], + monthNamesShort: ['Sty','Lu','Mar','Kw','Maj','Cze', + 'Lip','Sie','Wrz','Pa','Lis','Gru'], + dayNames: ['Niedziela','Poniedziałek','Wtorek','Środa','Czwartek','Piątek','Sobota'], + dayNamesShort: ['Nie','Pn','Wt','Śr','Czw','Pt','So'], + dayNamesMin: ['N','Pn','Wt','Śr','Cz','Pt','So'], + weekHeader: 'Tydz', + dateFormat: 'dd.mm.yy', + firstDay: 1, + isRTL: false, + showMonthAfterYear: false, + yearSuffix: ''}; + $.datepicker.setDefaults($.datepicker.regional['pl']); +}); + +/* Brazilian initialisation for the jQuery UI date picker plugin. */ +/* Written by Leonildo Costa Silva (leocsilva@gmail.com). */ +jQuery(function($){ + $.datepicker.regional['pt-BR'] = { + closeText: 'Fechar', + prevText: '<Anterior', + nextText: 'Próximo>', + currentText: 'Hoje', + monthNames: ['Janeiro','Fevereiro','Março','Abril','Maio','Junho', + 'Julho','Agosto','Setembro','Outubro','Novembro','Dezembro'], + monthNamesShort: ['Jan','Fev','Mar','Abr','Mai','Jun', + 'Jul','Ago','Set','Out','Nov','Dez'], + dayNames: ['Domingo','Segunda-feira','Terça-feira','Quarta-feira','Quinta-feira','Sexta-feira','Sábado'], + dayNamesShort: ['Dom','Seg','Ter','Qua','Qui','Sex','Sáb'], + dayNamesMin: ['Dom','Seg','Ter','Qua','Qui','Sex','Sáb'], + weekHeader: 'Sm', + dateFormat: 'dd/mm/yy', + firstDay: 0, + isRTL: false, + showMonthAfterYear: false, + yearSuffix: ''}; + $.datepicker.setDefaults($.datepicker.regional['pt-BR']); +}); +/* Portuguese initialisation for the jQuery UI date picker plugin. */ +jQuery(function($){ + $.datepicker.regional['pt'] = { + closeText: 'Fechar', + prevText: '<Anterior', + nextText: 'Seguinte', + currentText: 'Hoje', + monthNames: ['Janeiro','Fevereiro','Março','Abril','Maio','Junho', + 'Julho','Agosto','Setembro','Outubro','Novembro','Dezembro'], + monthNamesShort: ['Jan','Fev','Mar','Abr','Mai','Jun', + 'Jul','Ago','Set','Out','Nov','Dez'], + dayNames: ['Domingo','Segunda-feira','Terça-feira','Quarta-feira','Quinta-feira','Sexta-feira','Sábado'], + dayNamesShort: ['Dom','Seg','Ter','Qua','Qui','Sex','Sáb'], + dayNamesMin: ['Dom','Seg','Ter','Qua','Qui','Sex','Sáb'], + weekHeader: 'Sem', + dateFormat: 'dd/mm/yy', + firstDay: 0, + isRTL: false, + showMonthAfterYear: false, + yearSuffix: ''}; + $.datepicker.setDefaults($.datepicker.regional['pt']); +}); +/* Romansh initialisation for the jQuery UI date picker plugin. */ +/* Written by Yvonne Gienal (yvonne.gienal@educa.ch). */ +jQuery(function($){ + $.datepicker.regional['rm'] = { + closeText: 'Serrar', + prevText: '<Suandant', + nextText: 'Precedent>', + currentText: 'Actual', + monthNames: ['Schaner','Favrer','Mars','Avrigl','Matg','Zercladur', 'Fanadur','Avust','Settember','October','November','December'], + monthNamesShort: ['Scha','Fev','Mar','Avr','Matg','Zer', 'Fan','Avu','Sett','Oct','Nov','Dec'], + dayNames: ['Dumengia','Glindesdi','Mardi','Mesemna','Gievgia','Venderdi','Sonda'], + dayNamesShort: ['Dum','Gli','Mar','Mes','Gie','Ven','Som'], + dayNamesMin: ['Du','Gl','Ma','Me','Gi','Ve','So'], + weekHeader: 'emna', + dateFormat: 'dd/mm/yy', + firstDay: 1, + isRTL: false, + showMonthAfterYear: false, + yearSuffix: ''}; + $.datepicker.setDefaults($.datepicker.regional['rm']); +}); + +/* Romanian initialisation for the jQuery UI date picker plugin. + * + * Written by Edmond L. (ll_edmond@walla.com) + * and Ionut G. Stan (ionut.g.stan@gmail.com) + */ +jQuery(function($){ + $.datepicker.regional['ro'] = { + closeText: 'Închide', + prevText: '« Luna precedentă', + nextText: 'Luna următoare »', + currentText: 'Azi', + monthNames: ['Ianuarie','Februarie','Martie','Aprilie','Mai','Iunie', + 'Iulie','August','Septembrie','Octombrie','Noiembrie','Decembrie'], + monthNamesShort: ['Ian', 'Feb', 'Mar', 'Apr', 'Mai', 'Iun', + 'Iul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'], + dayNames: ['Duminică', 'Luni', 'Marţi', 'Miercuri', 'Joi', 'Vineri', 'Sâmbătă'], + dayNamesShort: ['Dum', 'Lun', 'Mar', 'Mie', 'Joi', 'Vin', 'Sâm'], + dayNamesMin: ['Du','Lu','Ma','Mi','Jo','Vi','Sâ'], + weekHeader: 'Săpt', + dateFormat: 'dd.mm.yy', + firstDay: 1, + isRTL: false, + showMonthAfterYear: false, + yearSuffix: ''}; + $.datepicker.setDefaults($.datepicker.regional['ro']); +}); + +/* Russian (UTF-8) initialisation for the jQuery UI date picker plugin. */ +/* Written by Andrew Stromnov (stromnov@gmail.com). */ +jQuery(function($){ + $.datepicker.regional['ru'] = { + closeText: 'Закрыть', + prevText: '<Пред', + nextText: 'След>', + currentText: 'Сегодня', + monthNames: ['Январь','Февраль','Март','Апрель','Май','Июнь', + 'Июль','Август','Сентябрь','Октябрь','Ноябрь','Декабрь'], + monthNamesShort: ['Янв','Фев','Мар','Апр','Май','Июн', + 'Июл','Авг','Сен','Окт','Ноя','Дек'], + dayNames: ['воскресенье','понедельник','вторник','среда','четверг','пятница','суббота'], + dayNamesShort: ['вск','пнд','втр','срд','чтв','птн','сбт'], + dayNamesMin: ['Вс','Пн','Вт','Ср','Чт','Пт','Сб'], + weekHeader: 'Нед', + dateFormat: 'dd.mm.yy', + firstDay: 1, + isRTL: false, + showMonthAfterYear: false, + yearSuffix: ''}; + $.datepicker.setDefaults($.datepicker.regional['ru']); +}); +/* Slovak initialisation for the jQuery UI date picker plugin. */ +/* Written by Vojtech Rinik (vojto@hmm.sk). */ +jQuery(function($){ + $.datepicker.regional['sk'] = { + closeText: 'Zavrieť', + prevText: '<Predchádzajúci', + nextText: 'Nasledujúci>', + currentText: 'Dnes', + monthNames: ['Január','Február','Marec','Apríl','Máj','Jún', + 'Júl','August','September','Október','November','December'], + monthNamesShort: ['Jan','Feb','Mar','Apr','Máj','Jún', + 'Júl','Aug','Sep','Okt','Nov','Dec'], + dayNames: ['Nedeľa','Pondelok','Utorok','Streda','Štvrtok','Piatok','Sobota'], + dayNamesShort: ['Ned','Pon','Uto','Str','Štv','Pia','Sob'], + dayNamesMin: ['Ne','Po','Ut','St','Št','Pia','So'], + weekHeader: 'Ty', + dateFormat: 'dd.mm.yy', + firstDay: 1, + isRTL: false, + showMonthAfterYear: false, + yearSuffix: ''}; + $.datepicker.setDefaults($.datepicker.regional['sk']); +}); + +/* Slovenian initialisation for the jQuery UI date picker plugin. */ +/* Written by Jaka Jancar (jaka@kubje.org). */ +/* c = č, s = š z = ž C = Č S = Š Z = Ž */ +jQuery(function($){ + $.datepicker.regional['sl'] = { + closeText: 'Zapri', + prevText: '<Prejšnji', + nextText: 'Naslednji>', + currentText: 'Trenutni', + monthNames: ['Januar','Februar','Marec','April','Maj','Junij', + 'Julij','Avgust','September','Oktober','November','December'], + monthNamesShort: ['Jan','Feb','Mar','Apr','Maj','Jun', + 'Jul','Avg','Sep','Okt','Nov','Dec'], + dayNames: ['Nedelja','Ponedeljek','Torek','Sreda','Četrtek','Petek','Sobota'], + dayNamesShort: ['Ned','Pon','Tor','Sre','Čet','Pet','Sob'], + dayNamesMin: ['Ne','Po','To','Sr','Če','Pe','So'], + weekHeader: 'Teden', + dateFormat: 'dd.mm.yy', + firstDay: 1, + isRTL: false, + showMonthAfterYear: false, + yearSuffix: ''}; + $.datepicker.setDefaults($.datepicker.regional['sl']); +}); + +/* Albanian initialisation for the jQuery UI date picker plugin. */ +/* Written by Flakron Bytyqi (flakron@gmail.com). */ +jQuery(function($){ + $.datepicker.regional['sq'] = { + closeText: 'mbylle', + prevText: '<mbrapa', + nextText: 'Përpara>', + currentText: 'sot', + monthNames: ['Janar','Shkurt','Mars','Prill','Maj','Qershor', + 'Korrik','Gusht','Shtator','Tetor','Nëntor','Dhjetor'], + monthNamesShort: ['Jan','Shk','Mar','Pri','Maj','Qer', + 'Kor','Gus','Sht','Tet','Nën','Dhj'], + dayNames: ['E Diel','E Hënë','E Martë','E Mërkurë','E Enjte','E Premte','E Shtune'], + dayNamesShort: ['Di','Hë','Ma','Më','En','Pr','Sh'], + dayNamesMin: ['Di','Hë','Ma','Më','En','Pr','Sh'], + weekHeader: 'Ja', + dateFormat: 'dd.mm.yy', + firstDay: 1, + isRTL: false, + showMonthAfterYear: false, + yearSuffix: ''}; + $.datepicker.setDefaults($.datepicker.regional['sq']); +}); + +/* Serbian i18n for the jQuery UI date picker plugin. */ +/* Written by Dejan Dimić. */ +jQuery(function($){ + $.datepicker.regional['sr-SR'] = { + closeText: 'Zatvori', + prevText: '<', + nextText: '>', + currentText: 'Danas', + monthNames: ['Januar','Februar','Mart','April','Maj','Jun', + 'Jul','Avgust','Septembar','Oktobar','Novembar','Decembar'], + monthNamesShort: ['Jan','Feb','Mar','Apr','Maj','Jun', + 'Jul','Avg','Sep','Okt','Nov','Dec'], + dayNames: ['Nedelja','Ponedeljak','Utorak','Sreda','Četvrtak','Petak','Subota'], + dayNamesShort: ['Ned','Pon','Uto','Sre','Čet','Pet','Sub'], + dayNamesMin: ['Ne','Po','Ut','Sr','Če','Pe','Su'], + weekHeader: 'Sed', + dateFormat: 'dd/mm/yy', + firstDay: 1, + isRTL: false, + showMonthAfterYear: false, + yearSuffix: ''}; + $.datepicker.setDefaults($.datepicker.regional['sr-SR']); +}); + +/* Serbian i18n for the jQuery UI date picker plugin. */ +/* Written by Dejan Dimić. */ +jQuery(function($){ + $.datepicker.regional['sr'] = { + closeText: 'Затвори', + prevText: '<', + nextText: '>', + currentText: 'Данас', + monthNames: ['Јануар','Фебруар','Март','Април','Мај','Јун', + 'Јул','Август','Септембар','Октобар','Новембар','Децембар'], + monthNamesShort: ['Јан','Феб','Мар','Апр','Мај','Јун', + 'Јул','Авг','Сеп','Окт','Нов','Дец'], + dayNames: ['Недеља','Понедељак','Уторак','Среда','Четвртак','Петак','Субота'], + dayNamesShort: ['Нед','Пон','Уто','Сре','Чет','Пет','Суб'], + dayNamesMin: ['Не','По','Ут','Ср','Че','Пе','Су'], + weekHeader: 'Сед', + dateFormat: 'dd/mm/yy', + firstDay: 1, + isRTL: false, + showMonthAfterYear: false, + yearSuffix: ''}; + $.datepicker.setDefaults($.datepicker.regional['sr']); +}); + +/* Swedish initialisation for the jQuery UI date picker plugin. */ +/* Written by Anders Ekdahl ( anders@nomadiz.se). */ +jQuery(function($){ + $.datepicker.regional['sv'] = { + closeText: 'Stäng', + prevText: '«Förra', + nextText: 'Nästa»', + currentText: 'Idag', + monthNames: ['Januari','Februari','Mars','April','Maj','Juni', + 'Juli','Augusti','September','Oktober','November','December'], + monthNamesShort: ['Jan','Feb','Mar','Apr','Maj','Jun', + 'Jul','Aug','Sep','Okt','Nov','Dec'], + dayNamesShort: ['Sön','Mån','Tis','Ons','Tor','Fre','Lör'], + dayNames: ['Söndag','Måndag','Tisdag','Onsdag','Torsdag','Fredag','Lördag'], + dayNamesMin: ['Sö','Må','Ti','On','To','Fr','Lö'], + weekHeader: 'Ve', + dateFormat: 'yy-mm-dd', + firstDay: 1, + isRTL: false, + showMonthAfterYear: false, + yearSuffix: ''}; + $.datepicker.setDefaults($.datepicker.regional['sv']); +}); + +/* Tamil (UTF-8) initialisation for the jQuery UI date picker plugin. */ +/* Written by S A Sureshkumar (saskumar@live.com). */ +jQuery(function($){ + $.datepicker.regional['ta'] = { + closeText: 'மூடு', + prevText: 'முன்னையது', + nextText: 'அடுத்தது', + currentText: 'இன்று', + monthNames: ['தை','மாசி','பங்குனி','சித்திரை','வைகாசி','ஆனி', + 'ஆடி','ஆவணி','புரட்டாசி','ஐப்பசி','கார்த்திகை','மார்கழி'], + monthNamesShort: ['தை','மாசி','பங்','சித்','வைகா','ஆனி', + 'ஆடி','ஆவ','புர','ஐப்','கார்','மார்'], + dayNames: ['ஞாயிற்றுக்கிழமை','திங்கட்கிழமை','செவ்வாய்க்கிழமை','புதன்கிழமை','வியாழக்கிழமை','வெள்ளிக்கிழமை','சனிக்கிழமை'], + dayNamesShort: ['ஞாயிறு','திங்கள்','செவ்வாய்','புதன்','வியாழன்','வெள்ளி','சனி'], + dayNamesMin: ['ஞா','தி','செ','பு','வி','வெ','ச'], + weekHeader: 'Не', + dateFormat: 'dd/mm/yy', + firstDay: 1, + isRTL: false, + showMonthAfterYear: false, + yearSuffix: ''}; + $.datepicker.setDefaults($.datepicker.regional['ta']); +}); + +/* Thai initialisation for the jQuery UI date picker plugin. */ +/* Written by pipo (pipo@sixhead.com). */ +jQuery(function($){ + $.datepicker.regional['th'] = { + closeText: 'ปิด', + prevText: '« ย้อน', + nextText: 'ถัดไป »', + currentText: 'วันนี้', + monthNames: ['มกราคม','กุมภาพันธ์','มีนาคม','เมษายน','พฤษภาคม','มิถุนายน', + 'กรกฎาคม','สิงหาคม','กันยายน','ตุลาคม','พฤศจิกายน','ธันวาคม'], + monthNamesShort: ['ม.ค.','ก.พ.','มี.ค.','เม.ย.','พ.ค.','มิ.ย.', + 'ก.ค.','ส.ค.','ก.ย.','ต.ค.','พ.ย.','ธ.ค.'], + dayNames: ['อาทิตย์','จันทร์','อังคาร','พุธ','พฤหัสบดี','ศุกร์','เสาร์'], + dayNamesShort: ['อา.','จ.','อ.','พ.','พฤ.','ศ.','ส.'], + dayNamesMin: ['อา.','จ.','อ.','พ.','พฤ.','ศ.','ส.'], + weekHeader: 'Wk', + dateFormat: 'dd/mm/yy', + firstDay: 0, + isRTL: false, + showMonthAfterYear: false, + yearSuffix: ''}; + $.datepicker.setDefaults($.datepicker.regional['th']); +}); +/* Tajiki (UTF-8) initialisation for the jQuery UI date picker plugin. */ +/* Written by Abdurahmon Saidov (saidovab@gmail.com). */ +jQuery(function($){ + $.datepicker.regional['tj'] = { + closeText: 'Идома', + prevText: '<Қафо', + nextText: 'Пеш>', + currentText: 'Имрӯз', + monthNames: ['Январ','Феврал','Март','Апрел','Май','Июн', + 'Июл','Август','Сентябр','Октябр','Ноябр','Декабр'], + monthNamesShort: ['Янв','Фев','Мар','Апр','Май','Июн', + 'Июл','Авг','Сен','Окт','Ноя','Дек'], + dayNames: ['якшанбе','душанбе','сешанбе','чоршанбе','панҷшанбе','ҷумъа','шанбе'], + dayNamesShort: ['якш','душ','сеш','чор','пан','ҷум','шан'], + dayNamesMin: ['Як','Дш','Сш','Чш','Пш','Ҷм','Шн'], + weekHeader: 'Хф', + dateFormat: 'dd.mm.yy', + firstDay: 1, + isRTL: false, + showMonthAfterYear: false, + yearSuffix: ''}; + $.datepicker.setDefaults($.datepicker.regional['tj']); +}); +/* Turkish initialisation for the jQuery UI date picker plugin. */ +/* Written by Izzet Emre Erkan (kara@karalamalar.net). */ +jQuery(function($){ + $.datepicker.regional['tr'] = { + closeText: 'kapat', + prevText: '<geri', + nextText: 'ileri>', + currentText: 'bugün', + monthNames: ['Ocak','Şubat','Mart','Nisan','Mayıs','Haziran', + 'Temmuz','Ağustos','Eylül','Ekim','Kasım','Aralık'], + monthNamesShort: ['Oca','Şub','Mar','Nis','May','Haz', + 'Tem','Ağu','Eyl','Eki','Kas','Ara'], + dayNames: ['Pazar','Pazartesi','Salı','Çarşamba','Perşembe','Cuma','Cumartesi'], + dayNamesShort: ['Pz','Pt','Sa','Ça','Pe','Cu','Ct'], + dayNamesMin: ['Pz','Pt','Sa','Ça','Pe','Cu','Ct'], + weekHeader: 'Hf', + dateFormat: 'dd.mm.yy', + firstDay: 1, + isRTL: false, + showMonthAfterYear: false, + yearSuffix: ''}; + $.datepicker.setDefaults($.datepicker.regional['tr']); +}); +/* Ukrainian (UTF-8) initialisation for the jQuery UI date picker plugin. */ +/* Written by Maxim Drogobitskiy (maxdao@gmail.com). */ +/* Corrected by Igor Milla (igor.fsp.milla@gmail.com). */ +jQuery(function($){ + $.datepicker.regional['uk'] = { + closeText: 'Закрити', + prevText: '<', + nextText: '>', + currentText: 'Сьогодні', + monthNames: ['Січень','Лютий','Березень','Квітень','Травень','Червень', + 'Липень','Серпень','Вересень','Жовтень','Листопад','Грудень'], + monthNamesShort: ['Січ','Лют','Бер','Кві','Тра','Чер', + 'Лип','Сер','Вер','Жов','Лис','Гру'], + dayNames: ['неділя','понеділок','вівторок','середа','четвер','п’ятниця','субота'], + dayNamesShort: ['нед','пнд','вів','срд','чтв','птн','сбт'], + dayNamesMin: ['Нд','Пн','Вт','Ср','Чт','Пт','Сб'], + weekHeader: 'Тиж', + dateFormat: 'dd/mm/yy', + firstDay: 1, + isRTL: false, + showMonthAfterYear: false, + yearSuffix: ''}; + $.datepicker.setDefaults($.datepicker.regional['uk']); +}); +/* Vietnamese initialisation for the jQuery UI date picker plugin. */ +/* Translated by Le Thanh Huy (lthanhhuy@cit.ctu.edu.vn). */ +jQuery(function($){ + $.datepicker.regional['vi'] = { + closeText: 'Đóng', + prevText: '<Trước', + nextText: 'Tiếp>', + currentText: 'Hôm nay', + monthNames: ['Tháng Một', 'Tháng Hai', 'Tháng Ba', 'Tháng Tư', 'Tháng Năm', 'Tháng Sáu', + 'Tháng Bảy', 'Tháng Tám', 'Tháng Chín', 'Tháng Mười', 'Tháng Mười Một', 'Tháng Mười Hai'], + monthNamesShort: ['Tháng 1', 'Tháng 2', 'Tháng 3', 'Tháng 4', 'Tháng 5', 'Tháng 6', + 'Tháng 7', 'Tháng 8', 'Tháng 9', 'Tháng 10', 'Tháng 11', 'Tháng 12'], + dayNames: ['Chủ Nhật', 'Thứ Hai', 'Thứ Ba', 'Thứ Tư', 'Thứ Năm', 'Thứ Sáu', 'Thứ Bảy'], + dayNamesShort: ['CN', 'T2', 'T3', 'T4', 'T5', 'T6', 'T7'], + dayNamesMin: ['CN', 'T2', 'T3', 'T4', 'T5', 'T6', 'T7'], + weekHeader: 'Tu', + dateFormat: 'dd/mm/yy', + firstDay: 0, + isRTL: false, + showMonthAfterYear: false, + yearSuffix: ''}; + $.datepicker.setDefaults($.datepicker.regional['vi']); +}); + +/* Chinese initialisation for the jQuery UI date picker plugin. */ +/* Written by Cloudream (cloudream@gmail.com). */ +jQuery(function($){ + $.datepicker.regional['zh-CN'] = { + closeText: '关闭', + prevText: '<上月', + nextText: '下月>', + currentText: '今天', + monthNames: ['一月','二月','三月','四月','五月','六月', + '七月','八月','九月','十月','十一月','十二月'], + monthNamesShort: ['一月','二月','三月','四月','五月','六月', + '七月','八月','九月','十月','十一月','十二月'], + dayNames: ['星期日','星期一','星期二','星期三','星期四','星期五','星期六'], + dayNamesShort: ['周日','周一','周二','周三','周四','周五','周六'], + dayNamesMin: ['日','一','二','三','四','五','六'], + weekHeader: '周', + dateFormat: 'yy-mm-dd', + firstDay: 1, + isRTL: false, + showMonthAfterYear: true, + yearSuffix: '年'}; + $.datepicker.setDefaults($.datepicker.regional['zh-CN']); +}); + +/* Chinese initialisation for the jQuery UI date picker plugin. */ +/* Written by SCCY (samuelcychan@gmail.com). */ +jQuery(function($){ + $.datepicker.regional['zh-HK'] = { + closeText: '關閉', + prevText: '<上月', + nextText: '下月>', + currentText: '今天', + monthNames: ['一月','二月','三月','四月','五月','六月', + '七月','八月','九月','十月','十一月','十二月'], + monthNamesShort: ['一月','二月','三月','四月','五月','六月', + '七月','八月','九月','十月','十一月','十二月'], + dayNames: ['星期日','星期一','星期二','星期三','星期四','星期五','星期六'], + dayNamesShort: ['周日','周一','周二','周三','周四','周五','周六'], + dayNamesMin: ['日','一','二','三','四','五','六'], + weekHeader: '周', + dateFormat: 'dd-mm-yy', + firstDay: 0, + isRTL: false, + showMonthAfterYear: true, + yearSuffix: '年'}; + $.datepicker.setDefaults($.datepicker.regional['zh-HK']); +}); + +/* Chinese initialisation for the jQuery UI date picker plugin. */ +/* Written by Ressol (ressol@gmail.com). */ +jQuery(function($){ + $.datepicker.regional['zh-TW'] = { + closeText: '關閉', + prevText: '<上月', + nextText: '下月>', + currentText: '今天', + monthNames: ['一月','二月','三月','四月','五月','六月', + '七月','八月','九月','十月','十一月','十二月'], + monthNamesShort: ['一月','二月','三月','四月','五月','六月', + '七月','八月','九月','十月','十一月','十二月'], + dayNames: ['星期日','星期一','星期二','星期三','星期四','星期五','星期六'], + dayNamesShort: ['周日','周一','周二','周三','周四','周五','周六'], + dayNamesMin: ['日','一','二','三','四','五','六'], + weekHeader: '周', + dateFormat: 'yy/mm/dd', + firstDay: 1, + isRTL: false, + showMonthAfterYear: true, + yearSuffix: '年'}; + $.datepicker.setDefaults($.datepicker.regional['zh-TW']); +}); diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/ui/i18n/jquery.ui.datepicker-af.js b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/ui/i18n/jquery.ui.datepicker-af.js new file mode 100755 index 000000000..0922ef7a1 --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/ui/i18n/jquery.ui.datepicker-af.js @@ -0,0 +1,23 @@ +/* Afrikaans initialisation for the jQuery UI date picker plugin. */ +/* Written by Renier Pretorius. */ +jQuery(function($){ + $.datepicker.regional['af'] = { + closeText: 'Selekteer', + prevText: 'Vorige', + nextText: 'Volgende', + currentText: 'Vandag', + monthNames: ['Januarie','Februarie','Maart','April','Mei','Junie', + 'Julie','Augustus','September','Oktober','November','Desember'], + monthNamesShort: ['Jan', 'Feb', 'Mrt', 'Apr', 'Mei', 'Jun', + 'Jul', 'Aug', 'Sep', 'Okt', 'Nov', 'Des'], + dayNames: ['Sondag', 'Maandag', 'Dinsdag', 'Woensdag', 'Donderdag', 'Vrydag', 'Saterdag'], + dayNamesShort: ['Son', 'Maa', 'Din', 'Woe', 'Don', 'Vry', 'Sat'], + dayNamesMin: ['So','Ma','Di','Wo','Do','Vr','Sa'], + weekHeader: 'Wk', + dateFormat: 'dd/mm/yy', + firstDay: 1, + isRTL: false, + showMonthAfterYear: false, + yearSuffix: ''}; + $.datepicker.setDefaults($.datepicker.regional['af']); +}); diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/ui/i18n/jquery.ui.datepicker-ar-DZ.js b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/ui/i18n/jquery.ui.datepicker-ar-DZ.js new file mode 100755 index 000000000..7b175af40 --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/ui/i18n/jquery.ui.datepicker-ar-DZ.js @@ -0,0 +1,23 @@ +/* Algerian Arabic Translation for jQuery UI date picker plugin. (can be used for Tunisia)*/ +/* Mohamed Cherif BOUCHELAGHEM -- cherifbouchelaghem@yahoo.fr */ + +jQuery(function($){ + $.datepicker.regional['ar-DZ'] = { + closeText: 'إغلاق', + prevText: '<السابق', + nextText: 'التالي>', + currentText: 'اليوم', + monthNames: ['جانفي', 'فيفري', 'مارس', 'أفريل', 'ماي', 'جوان', + 'جويلية', 'أوت', 'سبتمبر','أكتوبر', 'نوفمبر', 'ديسمبر'], + monthNamesShort: ['1', '2', '3', '4', '5', '6', '7', '8', '9', '10', '11', '12'], + dayNames: ['الأحد', 'الاثنين', 'الثلاثاء', 'الأربعاء', 'الخميس', 'الجمعة', 'السبت'], + dayNamesShort: ['الأحد', 'الاثنين', 'الثلاثاء', 'الأربعاء', 'الخميس', 'الجمعة', 'السبت'], + dayNamesMin: ['الأحد', 'الاثنين', 'الثلاثاء', 'الأربعاء', 'الخميس', 'الجمعة', 'السبت'], + weekHeader: 'أسبوع', + dateFormat: 'dd/mm/yy', + firstDay: 6, + isRTL: true, + showMonthAfterYear: false, + yearSuffix: ''}; + $.datepicker.setDefaults($.datepicker.regional['ar-DZ']); +}); diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/ui/i18n/jquery.ui.datepicker-ar.js b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/ui/i18n/jquery.ui.datepicker-ar.js new file mode 100755 index 000000000..f0d009667 --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/ui/i18n/jquery.ui.datepicker-ar.js @@ -0,0 +1,23 @@ +/* Arabic Translation for jQuery UI date picker plugin. */ +/* Khaled Alhourani -- me@khaledalhourani.com */ +/* NOTE: monthNames are the original months names and they are the Arabic names, not the new months name فبراير - يناير and there isn't any Arabic roots for these months */ +jQuery(function($){ + $.datepicker.regional['ar'] = { + closeText: 'إغلاق', + prevText: '<السابق', + nextText: 'التالي>', + currentText: 'اليوم', + monthNames: ['كانون الثاني', 'شباط', 'آذار', 'نيسان', 'مايو', 'حزيران', + 'تموز', 'آب', 'أيلول', 'تشرين الأول', 'تشرين الثاني', 'كانون الأول'], + monthNamesShort: ['1', '2', '3', '4', '5', '6', '7', '8', '9', '10', '11', '12'], + dayNames: ['الأحد', 'الاثنين', 'الثلاثاء', 'الأربعاء', 'الخميس', 'الجمعة', 'السبت'], + dayNamesShort: ['الأحد', 'الاثنين', 'الثلاثاء', 'الأربعاء', 'الخميس', 'الجمعة', 'السبت'], + dayNamesMin: ['ح', 'ن', 'ث', 'ر', 'خ', 'ج', 'س'], + weekHeader: 'أسبوع', + dateFormat: 'dd/mm/yy', + firstDay: 6, + isRTL: true, + showMonthAfterYear: false, + yearSuffix: ''}; + $.datepicker.setDefaults($.datepicker.regional['ar']); +}); \ No newline at end of file diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/ui/i18n/jquery.ui.datepicker-az.js b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/ui/i18n/jquery.ui.datepicker-az.js new file mode 100755 index 000000000..1101c8b91 --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/ui/i18n/jquery.ui.datepicker-az.js @@ -0,0 +1,23 @@ +/* Azerbaijani (UTF-8) initialisation for the jQuery UI date picker plugin. */ +/* Written by Jamil Najafov (necefov33@gmail.com). */ +jQuery(function($) { + $.datepicker.regional['az'] = { + closeText: 'Bağla', + prevText: '<Geri', + nextText: 'İrəli>', + currentText: 'Bugün', + monthNames: ['Yanvar','Fevral','Mart','Aprel','May','İyun', + 'İyul','Avqust','Sentyabr','Oktyabr','Noyabr','Dekabr'], + monthNamesShort: ['Yan','Fev','Mar','Apr','May','İyun', + 'İyul','Avq','Sen','Okt','Noy','Dek'], + dayNames: ['Bazar','Bazar ertəsi','Çərşənbə axşamı','Çərşənbə','Cümə axşamı','Cümə','Şənbə'], + dayNamesShort: ['B','Be','Ça','Ç','Ca','C','Ş'], + dayNamesMin: ['B','B','Ç','С','Ç','C','Ş'], + weekHeader: 'Hf', + dateFormat: 'dd.mm.yy', + firstDay: 1, + isRTL: false, + showMonthAfterYear: false, + yearSuffix: ''}; + $.datepicker.setDefaults($.datepicker.regional['az']); +}); \ No newline at end of file diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/ui/i18n/jquery.ui.datepicker-bg.js b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/ui/i18n/jquery.ui.datepicker-bg.js new file mode 100755 index 000000000..86ab88582 --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/ui/i18n/jquery.ui.datepicker-bg.js @@ -0,0 +1,24 @@ +/* Bulgarian initialisation for the jQuery UI date picker plugin. */ +/* Written by Stoyan Kyosev (http://svest.org). */ +jQuery(function($){ + $.datepicker.regional['bg'] = { + closeText: 'затвори', + prevText: '<назад', + nextText: 'напред>', + nextBigText: '>>', + currentText: 'днес', + monthNames: ['Януари','Февруари','Март','Април','Май','Юни', + 'Юли','Август','Септември','Октомври','Ноември','Декември'], + monthNamesShort: ['Яну','Фев','Мар','Апр','Май','Юни', + 'Юли','Авг','Сеп','Окт','Нов','Дек'], + dayNames: ['Неделя','Понеделник','Вторник','Сряда','Четвъртък','Петък','Събота'], + dayNamesShort: ['Нед','Пон','Вто','Сря','Чет','Пет','Съб'], + dayNamesMin: ['Не','По','Вт','Ср','Че','Пе','Съ'], + weekHeader: 'Wk', + dateFormat: 'dd.mm.yy', + firstDay: 1, + isRTL: false, + showMonthAfterYear: false, + yearSuffix: ''}; + $.datepicker.setDefaults($.datepicker.regional['bg']); +}); diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/ui/i18n/jquery.ui.datepicker-bs.js b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/ui/i18n/jquery.ui.datepicker-bs.js new file mode 100755 index 000000000..d64573755 --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/ui/i18n/jquery.ui.datepicker-bs.js @@ -0,0 +1,23 @@ +/* Bosnian i18n for the jQuery UI date picker plugin. */ +/* Written by Kenan Konjo. */ +jQuery(function($){ + $.datepicker.regional['bs'] = { + closeText: 'Zatvori', + prevText: '<', + nextText: '>', + currentText: 'Danas', + monthNames: ['Januar','Februar','Mart','April','Maj','Juni', + 'Juli','August','Septembar','Oktobar','Novembar','Decembar'], + monthNamesShort: ['Jan','Feb','Mar','Apr','Maj','Jun', + 'Jul','Aug','Sep','Okt','Nov','Dec'], + dayNames: ['Nedelja','Ponedeljak','Utorak','Srijeda','Četvrtak','Petak','Subota'], + dayNamesShort: ['Ned','Pon','Uto','Sri','Čet','Pet','Sub'], + dayNamesMin: ['Ne','Po','Ut','Sr','Če','Pe','Su'], + weekHeader: 'Wk', + dateFormat: 'dd.mm.yy', + firstDay: 1, + isRTL: false, + showMonthAfterYear: false, + yearSuffix: ''}; + $.datepicker.setDefaults($.datepicker.regional['bs']); +}); \ No newline at end of file diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/ui/i18n/jquery.ui.datepicker-ca.js b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/ui/i18n/jquery.ui.datepicker-ca.js new file mode 100755 index 000000000..a10b549c2 --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/ui/i18n/jquery.ui.datepicker-ca.js @@ -0,0 +1,23 @@ +/* Inicialització en català per a l'extensió 'UI date picker' per jQuery. */ +/* Writers: (joan.leon@gmail.com). */ +jQuery(function($){ + $.datepicker.regional['ca'] = { + closeText: 'Tanca', + prevText: 'Anterior', + nextText: 'Següent', + currentText: 'Avui', + monthNames: ['gener','febrer','març','abril','maig','juny', + 'juliol','agost','setembre','octubre','novembre','desembre'], + monthNamesShort: ['gen','feb','març','abr','maig','juny', + 'jul','ag','set','oct','nov','des'], + dayNames: ['diumenge','dilluns','dimarts','dimecres','dijous','divendres','dissabte'], + dayNamesShort: ['dg','dl','dt','dc','dj','dv','ds'], + dayNamesMin: ['dg','dl','dt','dc','dj','dv','ds'], + weekHeader: 'Set', + dateFormat: 'dd/mm/yy', + firstDay: 1, + isRTL: false, + showMonthAfterYear: false, + yearSuffix: ''}; + $.datepicker.setDefaults($.datepicker.regional['ca']); +}); diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/ui/i18n/jquery.ui.datepicker-cs.js b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/ui/i18n/jquery.ui.datepicker-cs.js new file mode 100755 index 000000000..b96b1a51c --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/ui/i18n/jquery.ui.datepicker-cs.js @@ -0,0 +1,23 @@ +/* Czech initialisation for the jQuery UI date picker plugin. */ +/* Written by Tomas Muller (tomas@tomas-muller.net). */ +jQuery(function($){ + $.datepicker.regional['cs'] = { + closeText: 'Zavřít', + prevText: '<Dříve', + nextText: 'Později>', + currentText: 'Nyní', + monthNames: ['leden','únor','březen','duben','květen','červen', + 'červenec','srpen','září','říjen','listopad','prosinec'], + monthNamesShort: ['led','úno','bře','dub','kvě','čer', + 'čvc','srp','zář','říj','lis','pro'], + dayNames: ['neděle', 'pondělí', 'úterý', 'středa', 'čtvrtek', 'pátek', 'sobota'], + dayNamesShort: ['ne', 'po', 'út', 'st', 'čt', 'pá', 'so'], + dayNamesMin: ['ne','po','út','st','čt','pá','so'], + weekHeader: 'Týd', + dateFormat: 'dd.mm.yy', + firstDay: 1, + isRTL: false, + showMonthAfterYear: false, + yearSuffix: ''}; + $.datepicker.setDefaults($.datepicker.regional['cs']); +}); diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/ui/i18n/jquery.ui.datepicker-cy-GB.js b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/ui/i18n/jquery.ui.datepicker-cy-GB.js new file mode 100755 index 000000000..dfee2f9d4 --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/ui/i18n/jquery.ui.datepicker-cy-GB.js @@ -0,0 +1,23 @@ +/* Welsh/UK initialisation for the jQuery UI date picker plugin. */ +/* Written by William Griffiths. */ +jQuery(function($){ + $.datepicker.regional['cy-GB'] = { + closeText: 'Done', + prevText: 'Prev', + nextText: 'Next', + currentText: 'Today', + monthNames: ['Ionawr','Chwefror','Mawrth','Ebrill','Mai','Mehefin', + 'Gorffennaf','Awst','Medi','Hydref','Tachwedd','Rhagfyr'], + monthNamesShort: ['Ion', 'Chw', 'Maw', 'Ebr', 'Mai', 'Meh', + 'Gor', 'Aws', 'Med', 'Hyd', 'Tac', 'Rha'], + dayNames: ['Dydd Sul', 'Dydd Llun', 'Dydd Mawrth', 'Dydd Mercher', 'Dydd Iau', 'Dydd Gwener', 'Dydd Sadwrn'], + dayNamesShort: ['Sul', 'Llu', 'Maw', 'Mer', 'Iau', 'Gwe', 'Sad'], + dayNamesMin: ['Su','Ll','Ma','Me','Ia','Gw','Sa'], + weekHeader: 'Wy', + dateFormat: 'dd/mm/yy', + firstDay: 1, + isRTL: false, + showMonthAfterYear: false, + yearSuffix: ''}; + $.datepicker.setDefaults($.datepicker.regional['cy-GB']); +}); \ No newline at end of file diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/ui/i18n/jquery.ui.datepicker-da.js b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/ui/i18n/jquery.ui.datepicker-da.js new file mode 100755 index 000000000..7e42948b3 --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/ui/i18n/jquery.ui.datepicker-da.js @@ -0,0 +1,23 @@ +/* Danish initialisation for the jQuery UI date picker plugin. */ +/* Written by Jan Christensen ( deletestuff@gmail.com). */ +jQuery(function($){ + $.datepicker.regional['da'] = { + closeText: 'Luk', + prevText: '<Forrige', + nextText: 'Næste>', + currentText: 'Idag', + monthNames: ['Januar','Februar','Marts','April','Maj','Juni', + 'Juli','August','September','Oktober','November','December'], + monthNamesShort: ['Jan','Feb','Mar','Apr','Maj','Jun', + 'Jul','Aug','Sep','Okt','Nov','Dec'], + dayNames: ['Søndag','Mandag','Tirsdag','Onsdag','Torsdag','Fredag','Lørdag'], + dayNamesShort: ['Søn','Man','Tir','Ons','Tor','Fre','Lør'], + dayNamesMin: ['Sø','Ma','Ti','On','To','Fr','Lø'], + weekHeader: 'Uge', + dateFormat: 'dd-mm-yy', + firstDay: 1, + isRTL: false, + showMonthAfterYear: false, + yearSuffix: ''}; + $.datepicker.setDefaults($.datepicker.regional['da']); +}); diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/ui/i18n/jquery.ui.datepicker-de.js b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/ui/i18n/jquery.ui.datepicker-de.js new file mode 100755 index 000000000..cfe91759b --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/ui/i18n/jquery.ui.datepicker-de.js @@ -0,0 +1,23 @@ +/* German initialisation for the jQuery UI date picker plugin. */ +/* Written by Milian Wolff (mail@milianw.de). */ +jQuery(function($){ + $.datepicker.regional['de'] = { + closeText: 'schließen', + prevText: '<zurück', + nextText: 'Vor>', + currentText: 'heute', + monthNames: ['Januar','Februar','März','April','Mai','Juni', + 'Juli','August','September','Oktober','November','Dezember'], + monthNamesShort: ['Jan','Feb','Mär','Apr','Mai','Jun', + 'Jul','Aug','Sep','Okt','Nov','Dez'], + dayNames: ['Sonntag','Montag','Dienstag','Mittwoch','Donnerstag','Freitag','Samstag'], + dayNamesShort: ['So','Mo','Di','Mi','Do','Fr','Sa'], + dayNamesMin: ['So','Mo','Di','Mi','Do','Fr','Sa'], + weekHeader: 'KW', + dateFormat: 'dd.mm.yy', + firstDay: 1, + isRTL: false, + showMonthAfterYear: false, + yearSuffix: ''}; + $.datepicker.setDefaults($.datepicker.regional['de']); +}); diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/ui/i18n/jquery.ui.datepicker-el.js b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/ui/i18n/jquery.ui.datepicker-el.js new file mode 100755 index 000000000..6d775f995 --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/ui/i18n/jquery.ui.datepicker-el.js @@ -0,0 +1,23 @@ +/* Greek (el) initialisation for the jQuery UI date picker plugin. */ +/* Written by Alex Cicovic (http://www.alexcicovic.com) */ +jQuery(function($){ + $.datepicker.regional['el'] = { + closeText: 'Κλείσιμο', + prevText: 'Προηγούμενος', + nextText: 'Επόμενος', + currentText: 'Τρέχων Μήνας', + monthNames: ['Ιανουάριος','Φεβρουάριος','Μάρτιος','Απρίλιος','Μάιος','Ιούνιος', + 'Ιούλιος','Αύγουστος','Σεπτέμβριος','Οκτώβριος','Νοέμβριος','Δεκέμβριος'], + monthNamesShort: ['Ιαν','Φεβ','Μαρ','Απρ','Μαι','Ιουν', + 'Ιουλ','Αυγ','Σεπ','Οκτ','Νοε','Δεκ'], + dayNames: ['Κυριακή','Δευτέρα','Τρίτη','Τετάρτη','Πέμπτη','Παρασκευή','Σάββατο'], + dayNamesShort: ['Κυρ','Δευ','Τρι','Τετ','Πεμ','Παρ','Σαβ'], + dayNamesMin: ['Κυ','Δε','Τρ','Τε','Πε','Πα','Σα'], + weekHeader: 'Εβδ', + dateFormat: 'dd/mm/yy', + firstDay: 1, + isRTL: false, + showMonthAfterYear: false, + yearSuffix: ''}; + $.datepicker.setDefaults($.datepicker.regional['el']); +}); \ No newline at end of file diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/ui/i18n/jquery.ui.datepicker-en-AU.js b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/ui/i18n/jquery.ui.datepicker-en-AU.js new file mode 100755 index 000000000..c1a1020a1 --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/ui/i18n/jquery.ui.datepicker-en-AU.js @@ -0,0 +1,23 @@ +/* English/Australia initialisation for the jQuery UI date picker plugin. */ +/* Based on the en-GB initialisation. */ +jQuery(function($){ + $.datepicker.regional['en-AU'] = { + closeText: 'Done', + prevText: 'Prev', + nextText: 'Next', + currentText: 'Today', + monthNames: ['January','February','March','April','May','June', + 'July','August','September','October','November','December'], + monthNamesShort: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', + 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'], + dayNames: ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'], + dayNamesShort: ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'], + dayNamesMin: ['Su','Mo','Tu','We','Th','Fr','Sa'], + weekHeader: 'Wk', + dateFormat: 'dd/mm/yy', + firstDay: 1, + isRTL: false, + showMonthAfterYear: false, + yearSuffix: ''}; + $.datepicker.setDefaults($.datepicker.regional['en-AU']); +}); diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/ui/i18n/jquery.ui.datepicker-en-GB.js b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/ui/i18n/jquery.ui.datepicker-en-GB.js new file mode 100755 index 000000000..16a096e75 --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/ui/i18n/jquery.ui.datepicker-en-GB.js @@ -0,0 +1,23 @@ +/* English/UK initialisation for the jQuery UI date picker plugin. */ +/* Written by Stuart. */ +jQuery(function($){ + $.datepicker.regional['en-GB'] = { + closeText: 'Done', + prevText: 'Prev', + nextText: 'Next', + currentText: 'Today', + monthNames: ['January','February','March','April','May','June', + 'July','August','September','October','November','December'], + monthNamesShort: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', + 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'], + dayNames: ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'], + dayNamesShort: ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'], + dayNamesMin: ['Su','Mo','Tu','We','Th','Fr','Sa'], + weekHeader: 'Wk', + dateFormat: 'dd/mm/yy', + firstDay: 1, + isRTL: false, + showMonthAfterYear: false, + yearSuffix: ''}; + $.datepicker.setDefaults($.datepicker.regional['en-GB']); +}); diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/ui/i18n/jquery.ui.datepicker-en-NZ.js b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/ui/i18n/jquery.ui.datepicker-en-NZ.js new file mode 100755 index 000000000..7819df052 --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/ui/i18n/jquery.ui.datepicker-en-NZ.js @@ -0,0 +1,23 @@ +/* English/New Zealand initialisation for the jQuery UI date picker plugin. */ +/* Based on the en-GB initialisation. */ +jQuery(function($){ + $.datepicker.regional['en-NZ'] = { + closeText: 'Done', + prevText: 'Prev', + nextText: 'Next', + currentText: 'Today', + monthNames: ['January','February','March','April','May','June', + 'July','August','September','October','November','December'], + monthNamesShort: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', + 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'], + dayNames: ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'], + dayNamesShort: ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'], + dayNamesMin: ['Su','Mo','Tu','We','Th','Fr','Sa'], + weekHeader: 'Wk', + dateFormat: 'dd/mm/yy', + firstDay: 1, + isRTL: false, + showMonthAfterYear: false, + yearSuffix: ''}; + $.datepicker.setDefaults($.datepicker.regional['en-NZ']); +}); diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/ui/i18n/jquery.ui.datepicker-eo.js b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/ui/i18n/jquery.ui.datepicker-eo.js new file mode 100755 index 000000000..39e44fc57 --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/ui/i18n/jquery.ui.datepicker-eo.js @@ -0,0 +1,23 @@ +/* Esperanto initialisation for the jQuery UI date picker plugin. */ +/* Written by Olivier M. (olivierweb@ifrance.com). */ +jQuery(function($){ + $.datepicker.regional['eo'] = { + closeText: 'Fermi', + prevText: '<Anta', + nextText: 'Sekv>', + currentText: 'Nuna', + monthNames: ['Januaro','Februaro','Marto','Aprilo','Majo','Junio', + 'Julio','Aŭgusto','Septembro','Oktobro','Novembro','Decembro'], + monthNamesShort: ['Jan','Feb','Mar','Apr','Maj','Jun', + 'Jul','Aŭg','Sep','Okt','Nov','Dec'], + dayNames: ['Dimanĉo','Lundo','Mardo','Merkredo','Ĵaŭdo','Vendredo','Sabato'], + dayNamesShort: ['Dim','Lun','Mar','Mer','Ĵaŭ','Ven','Sab'], + dayNamesMin: ['Di','Lu','Ma','Me','Ĵa','Ve','Sa'], + weekHeader: 'Sb', + dateFormat: 'dd/mm/yy', + firstDay: 0, + isRTL: false, + showMonthAfterYear: false, + yearSuffix: ''}; + $.datepicker.setDefaults($.datepicker.regional['eo']); +}); diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/ui/i18n/jquery.ui.datepicker-es.js b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/ui/i18n/jquery.ui.datepicker-es.js new file mode 100755 index 000000000..63368aecc --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/ui/i18n/jquery.ui.datepicker-es.js @@ -0,0 +1,23 @@ +/* Inicialización en español para la extensión 'UI date picker' para jQuery. */ +/* Traducido por Vester (xvester@gmail.com). */ +jQuery(function($){ + $.datepicker.regional['es'] = { + closeText: 'Cerrar', + prevText: '<Ant', + nextText: 'Sig>', + currentText: 'Hoy', + monthNames: ['Enero','Febrero','Marzo','Abril','Mayo','Junio', + 'Julio','Agosto','Septiembre','Octubre','Noviembre','Diciembre'], + monthNamesShort: ['Ene','Feb','Mar','Abr','May','Jun', + 'Jul','Ago','Sep','Oct','Nov','Dic'], + dayNames: ['Domingo','Lunes','Martes','Miércoles','Jueves','Viernes','Sábado'], + dayNamesShort: ['Dom','Lun','Mar','Mié','Juv','Vie','Sáb'], + dayNamesMin: ['Do','Lu','Ma','Mi','Ju','Vi','Sá'], + weekHeader: 'Sm', + dateFormat: 'dd/mm/yy', + firstDay: 1, + isRTL: false, + showMonthAfterYear: false, + yearSuffix: ''}; + $.datepicker.setDefaults($.datepicker.regional['es']); +}); \ No newline at end of file diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/ui/i18n/jquery.ui.datepicker-et.js b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/ui/i18n/jquery.ui.datepicker-et.js new file mode 100755 index 000000000..32702b243 --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/ui/i18n/jquery.ui.datepicker-et.js @@ -0,0 +1,23 @@ +/* Estonian initialisation for the jQuery UI date picker plugin. */ +/* Written by Mart Sõmermaa (mrts.pydev at gmail com). */ +jQuery(function($){ + $.datepicker.regional['et'] = { + closeText: 'Sulge', + prevText: 'Eelnev', + nextText: 'Järgnev', + currentText: 'Täna', + monthNames: ['Jaanuar','Veebruar','Märts','Aprill','Mai','Juuni', + 'Juuli','August','September','Oktoober','November','Detsember'], + monthNamesShort: ['Jaan', 'Veebr', 'Märts', 'Apr', 'Mai', 'Juuni', + 'Juuli', 'Aug', 'Sept', 'Okt', 'Nov', 'Dets'], + dayNames: ['Pühapäev', 'Esmaspäev', 'Teisipäev', 'Kolmapäev', 'Neljapäev', 'Reede', 'Laupäev'], + dayNamesShort: ['Pühap', 'Esmasp', 'Teisip', 'Kolmap', 'Neljap', 'Reede', 'Laup'], + dayNamesMin: ['P','E','T','K','N','R','L'], + weekHeader: 'näd', + dateFormat: 'dd.mm.yy', + firstDay: 1, + isRTL: false, + showMonthAfterYear: false, + yearSuffix: ''}; + $.datepicker.setDefaults($.datepicker.regional['et']); +}); \ No newline at end of file diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/ui/i18n/jquery.ui.datepicker-eu.js b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/ui/i18n/jquery.ui.datepicker-eu.js new file mode 100755 index 000000000..846ce3abc --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/ui/i18n/jquery.ui.datepicker-eu.js @@ -0,0 +1,23 @@ +/* Euskarako oinarria 'UI date picker' jquery-ko extentsioarentzat */ +/* Karrikas-ek itzulia (karrikas@karrikas.com) */ +jQuery(function($){ + $.datepicker.regional['eu'] = { + closeText: 'Egina', + prevText: '<Aur', + nextText: 'Hur>', + currentText: 'Gaur', + monthNames: ['urtarrila','otsaila','martxoa','apirila','maiatza','ekaina', + 'uztaila','abuztua','iraila','urria','azaroa','abendua'], + monthNamesShort: ['urt.','ots.','mar.','api.','mai.','eka.', + 'uzt.','abu.','ira.','urr.','aza.','abe.'], + dayNames: ['igandea','astelehena','asteartea','asteazkena','osteguna','ostirala','larunbata'], + dayNamesShort: ['ig.','al.','ar.','az.','og.','ol.','lr.'], + dayNamesMin: ['ig','al','ar','az','og','ol','lr'], + weekHeader: 'As', + dateFormat: 'yy-mm-dd', + firstDay: 1, + isRTL: false, + showMonthAfterYear: false, + yearSuffix: ''}; + $.datepicker.setDefaults($.datepicker.regional['eu']); +}); \ No newline at end of file diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/ui/i18n/jquery.ui.datepicker-fa.js b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/ui/i18n/jquery.ui.datepicker-fa.js new file mode 100755 index 000000000..be8acd2a5 --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/ui/i18n/jquery.ui.datepicker-fa.js @@ -0,0 +1,59 @@ +/* Persian (Farsi) Translation for the jQuery UI date picker plugin. */ +/* Javad Mowlanezhad -- jmowla@gmail.com */ +/* Jalali calendar should supported soon! (Its implemented but I have to test it) */ +jQuery(function($) { + $.datepicker.regional['fa'] = { + closeText: 'بستن', + prevText: '<قبلی', + nextText: 'بعدی>', + currentText: 'امروز', + monthNames: [ + 'فروردين', + 'ارديبهشت', + 'خرداد', + 'تير', + 'مرداد', + 'شهريور', + 'مهر', + 'آبان', + 'آذر', + 'دی', + 'بهمن', + 'اسفند' + ], + monthNamesShort: ['1','2','3','4','5','6','7','8','9','10','11','12'], + dayNames: [ + 'يکشنبه', + 'دوشنبه', + 'سه‌شنبه', + 'چهارشنبه', + 'پنجشنبه', + 'جمعه', + 'شنبه' + ], + dayNamesShort: [ + 'ی', + 'د', + 'س', + 'چ', + 'پ', + 'ج', + 'ش' + ], + dayNamesMin: [ + 'ی', + 'د', + 'س', + 'چ', + 'پ', + 'ج', + 'ش' + ], + weekHeader: 'هف', + dateFormat: 'yy/mm/dd', + firstDay: 6, + isRTL: true, + showMonthAfterYear: false, + yearSuffix: ''}; + $.datepicker.setDefaults($.datepicker.regional['fa']); +}); \ No newline at end of file diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/ui/i18n/jquery.ui.datepicker-fi.js b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/ui/i18n/jquery.ui.datepicker-fi.js new file mode 100755 index 000000000..bd6d99498 --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/ui/i18n/jquery.ui.datepicker-fi.js @@ -0,0 +1,23 @@ +/* Finnish initialisation for the jQuery UI date picker plugin. */ +/* Written by Harri Kilpiö (harrikilpio@gmail.com). */ +jQuery(function($){ + $.datepicker.regional['fi'] = { + closeText: 'Sulje', + prevText: '«Edellinen', + nextText: 'Seuraava»', + currentText: 'Tänään', + monthNames: ['Tammikuu','Helmikuu','Maaliskuu','Huhtikuu','Toukokuu','Kesäkuu', + 'Heinäkuu','Elokuu','Syyskuu','Lokakuu','Marraskuu','Joulukuu'], + monthNamesShort: ['Tammi','Helmi','Maalis','Huhti','Touko','Kesä', + 'Heinä','Elo','Syys','Loka','Marras','Joulu'], + dayNamesShort: ['Su','Ma','Ti','Ke','To','Pe','La'], + dayNames: ['Sunnuntai','Maanantai','Tiistai','Keskiviikko','Torstai','Perjantai','Lauantai'], + dayNamesMin: ['Su','Ma','Ti','Ke','To','Pe','La'], + weekHeader: 'Vk', + dateFormat: 'dd.mm.yy', + firstDay: 1, + isRTL: false, + showMonthAfterYear: false, + yearSuffix: ''}; + $.datepicker.setDefaults($.datepicker.regional['fi']); +}); diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/ui/i18n/jquery.ui.datepicker-fo.js b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/ui/i18n/jquery.ui.datepicker-fo.js new file mode 100755 index 000000000..9c848a04b --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/ui/i18n/jquery.ui.datepicker-fo.js @@ -0,0 +1,23 @@ +/* Faroese initialisation for the jQuery UI date picker plugin */ +/* Written by Sverri Mohr Olsen, sverrimo@gmail.com */ +jQuery(function($){ + $.datepicker.regional['fo'] = { + closeText: 'Lat aftur', + prevText: '<Fyrra', + nextText: 'Næsta>', + currentText: 'Í dag', + monthNames: ['Januar','Februar','Mars','Apríl','Mei','Juni', + 'Juli','August','September','Oktober','November','Desember'], + monthNamesShort: ['Jan','Feb','Mar','Apr','Mei','Jun', + 'Jul','Aug','Sep','Okt','Nov','Des'], + dayNames: ['Sunnudagur','Mánadagur','Týsdagur','Mikudagur','Hósdagur','Fríggjadagur','Leyardagur'], + dayNamesShort: ['Sun','Mán','Týs','Mik','Hós','Frí','Ley'], + dayNamesMin: ['Su','Má','Tý','Mi','Hó','Fr','Le'], + weekHeader: 'Vk', + dateFormat: 'dd-mm-yy', + firstDay: 0, + isRTL: false, + showMonthAfterYear: false, + yearSuffix: ''}; + $.datepicker.setDefaults($.datepicker.regional['fo']); +}); diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/ui/i18n/jquery.ui.datepicker-fr-CH.js b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/ui/i18n/jquery.ui.datepicker-fr-CH.js new file mode 100755 index 000000000..fec03a042 --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/ui/i18n/jquery.ui.datepicker-fr-CH.js @@ -0,0 +1,23 @@ +/* Swiss-French initialisation for the jQuery UI date picker plugin. */ +/* Written Martin Voelkle (martin.voelkle@e-tc.ch). */ +jQuery(function($){ + $.datepicker.regional['fr-CH'] = { + closeText: 'Fermer', + prevText: '<Préc', + nextText: 'Suiv>', + currentText: 'Courant', + monthNames: ['Janvier','Février','Mars','Avril','Mai','Juin', + 'Juillet','Août','Septembre','Octobre','Novembre','Décembre'], + monthNamesShort: ['Jan','Fév','Mar','Avr','Mai','Jun', + 'Jul','Aoû','Sep','Oct','Nov','Déc'], + dayNames: ['Dimanche','Lundi','Mardi','Mercredi','Jeudi','Vendredi','Samedi'], + dayNamesShort: ['Dim','Lun','Mar','Mer','Jeu','Ven','Sam'], + dayNamesMin: ['Di','Lu','Ma','Me','Je','Ve','Sa'], + weekHeader: 'Sm', + dateFormat: 'dd.mm.yy', + firstDay: 1, + isRTL: false, + showMonthAfterYear: false, + yearSuffix: ''}; + $.datepicker.setDefaults($.datepicker.regional['fr-CH']); +}); \ No newline at end of file diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/ui/i18n/jquery.ui.datepicker-fr.js b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/ui/i18n/jquery.ui.datepicker-fr.js new file mode 100755 index 000000000..934afd1d0 --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/ui/i18n/jquery.ui.datepicker-fr.js @@ -0,0 +1,25 @@ +/* French initialisation for the jQuery UI date picker plugin. */ +/* Written by Keith Wood (kbwood{at}iinet.com.au), + Stéphane Nahmani (sholby@sholby.net), + Stéphane Raimbault */ +jQuery(function($){ + $.datepicker.regional['fr'] = { + closeText: 'Fermer', + prevText: 'Précédent', + nextText: 'Suivant', + currentText: 'Aujourd\'hui', + monthNames: ['Janvier','Février','Mars','Avril','Mai','Juin', + 'Juillet','Août','Septembre','Octobre','Novembre','Décembre'], + monthNamesShort: ['Janv.','Févr.','Mars','Avril','Mai','Juin', + 'Juil.','Août','Sept.','Oct.','Nov.','Déc.'], + dayNames: ['Dimanche','Lundi','Mardi','Mercredi','Jeudi','Vendredi','Samedi'], + dayNamesShort: ['Dim.','Lun.','Mar.','Mer.','Jeu.','Ven.','Sam.'], + dayNamesMin: ['D','L','M','M','J','V','S'], + weekHeader: 'Sem.', + dateFormat: 'dd/mm/yy', + firstDay: 1, + isRTL: false, + showMonthAfterYear: false, + yearSuffix: ''}; + $.datepicker.setDefaults($.datepicker.regional['fr']); +}); diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/ui/i18n/jquery.ui.datepicker-gl.js b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/ui/i18n/jquery.ui.datepicker-gl.js new file mode 100755 index 000000000..0de64968f --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/ui/i18n/jquery.ui.datepicker-gl.js @@ -0,0 +1,23 @@ +/* Galician localization for 'UI date picker' jQuery extension. */ +/* Translated by Jorge Barreiro . */ +jQuery(function($){ + $.datepicker.regional['gl'] = { + closeText: 'Pechar', + prevText: '<Ant', + nextText: 'Seg>', + currentText: 'Hoxe', + monthNames: ['Xaneiro','Febreiro','Marzo','Abril','Maio','Xuño', + 'Xullo','Agosto','Setembro','Outubro','Novembro','Decembro'], + monthNamesShort: ['Xan','Feb','Mar','Abr','Mai','Xuñ', + 'Xul','Ago','Set','Out','Nov','Dec'], + dayNames: ['Domingo','Luns','Martes','Mércores','Xoves','Venres','Sábado'], + dayNamesShort: ['Dom','Lun','Mar','Mér','Xov','Ven','Sáb'], + dayNamesMin: ['Do','Lu','Ma','Mé','Xo','Ve','Sá'], + weekHeader: 'Sm', + dateFormat: 'dd/mm/yy', + firstDay: 1, + isRTL: false, + showMonthAfterYear: false, + yearSuffix: ''}; + $.datepicker.setDefaults($.datepicker.regional['gl']); +}); \ No newline at end of file diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/ui/i18n/jquery.ui.datepicker-he.js b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/ui/i18n/jquery.ui.datepicker-he.js new file mode 100755 index 000000000..b9e8deec5 --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/ui/i18n/jquery.ui.datepicker-he.js @@ -0,0 +1,23 @@ +/* Hebrew initialisation for the UI Datepicker extension. */ +/* Written by Amir Hardon (ahardon at gmail dot com). */ +jQuery(function($){ + $.datepicker.regional['he'] = { + closeText: 'סגור', + prevText: '<הקודם', + nextText: 'הבא>', + currentText: 'היום', + monthNames: ['ינואר','פברואר','מרץ','אפריל','מאי','יוני', + 'יולי','אוגוסט','ספטמבר','אוקטובר','נובמבר','דצמבר'], + monthNamesShort: ['ינו','פבר','מרץ','אפר','מאי','יוני', + 'יולי','אוג','ספט','אוק','נוב','דצמ'], + dayNames: ['ראשון','שני','שלישי','רביעי','חמישי','שישי','שבת'], + dayNamesShort: ['א\'','ב\'','ג\'','ד\'','ה\'','ו\'','שבת'], + dayNamesMin: ['א\'','ב\'','ג\'','ד\'','ה\'','ו\'','שבת'], + weekHeader: 'Wk', + dateFormat: 'dd/mm/yy', + firstDay: 0, + isRTL: true, + showMonthAfterYear: false, + yearSuffix: ''}; + $.datepicker.setDefaults($.datepicker.regional['he']); +}); diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/ui/i18n/jquery.ui.datepicker-hi.js b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/ui/i18n/jquery.ui.datepicker-hi.js new file mode 100755 index 000000000..6c563b997 --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/ui/i18n/jquery.ui.datepicker-hi.js @@ -0,0 +1,23 @@ +/* Hindi initialisation for the jQuery UI date picker plugin. */ +/* Written by Michael Dawart. */ +jQuery(function($){ + $.datepicker.regional['hi'] = { + closeText: 'बंद', + prevText: 'पिछला', + nextText: 'अगला', + currentText: 'आज', + monthNames: ['जनवरी ','फरवरी','मार्च','अप्रेल','मई','जून', + 'जूलाई','अगस्त ','सितम्बर','अक्टूबर','नवम्बर','दिसम्बर'], + monthNamesShort: ['जन', 'फर', 'मार्च', 'अप्रेल', 'मई', 'जून', + 'जूलाई', 'अग', 'सित', 'अक्ट', 'नव', 'दि'], + dayNames: ['रविवार', 'सोमवार', 'मंगलवार', 'बुधवार', 'गुरुवार', 'शुक्रवार', 'शनिवार'], + dayNamesShort: ['रवि', 'सोम', 'मंगल', 'बुध', 'गुरु', 'शुक्र', 'शनि'], + dayNamesMin: ['रवि', 'सोम', 'मंगल', 'बुध', 'गुरु', 'शुक्र', 'शनि'], + weekHeader: 'हफ्ता', + dateFormat: 'dd/mm/yy', + firstDay: 1, + isRTL: false, + showMonthAfterYear: false, + yearSuffix: ''}; + $.datepicker.setDefaults($.datepicker.regional['hi']); +}); diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/ui/i18n/jquery.ui.datepicker-hr.js b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/ui/i18n/jquery.ui.datepicker-hr.js new file mode 100755 index 000000000..6bc5aade1 --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/ui/i18n/jquery.ui.datepicker-hr.js @@ -0,0 +1,23 @@ +/* Croatian i18n for the jQuery UI date picker plugin. */ +/* Written by Vjekoslav Nesek. */ +jQuery(function($){ + $.datepicker.regional['hr'] = { + closeText: 'Zatvori', + prevText: '<', + nextText: '>', + currentText: 'Danas', + monthNames: ['Siječanj','Veljača','Ožujak','Travanj','Svibanj','Lipanj', + 'Srpanj','Kolovoz','Rujan','Listopad','Studeni','Prosinac'], + monthNamesShort: ['Sij','Velj','Ožu','Tra','Svi','Lip', + 'Srp','Kol','Ruj','Lis','Stu','Pro'], + dayNames: ['Nedjelja','Ponedjeljak','Utorak','Srijeda','Četvrtak','Petak','Subota'], + dayNamesShort: ['Ned','Pon','Uto','Sri','Čet','Pet','Sub'], + dayNamesMin: ['Ne','Po','Ut','Sr','Če','Pe','Su'], + weekHeader: 'Tje', + dateFormat: 'dd.mm.yy.', + firstDay: 1, + isRTL: false, + showMonthAfterYear: false, + yearSuffix: ''}; + $.datepicker.setDefaults($.datepicker.regional['hr']); +}); \ No newline at end of file diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/ui/i18n/jquery.ui.datepicker-hu.js b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/ui/i18n/jquery.ui.datepicker-hu.js new file mode 100755 index 000000000..b28c268c1 --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/ui/i18n/jquery.ui.datepicker-hu.js @@ -0,0 +1,23 @@ +/* Hungarian initialisation for the jQuery UI date picker plugin. */ +/* Written by Istvan Karaszi (jquery@spam.raszi.hu). */ +jQuery(function($){ + $.datepicker.regional['hu'] = { + closeText: 'bezár', + prevText: 'vissza', + nextText: 'előre', + currentText: 'ma', + monthNames: ['Január', 'Február', 'Március', 'Április', 'Május', 'Június', + 'Július', 'Augusztus', 'Szeptember', 'Október', 'November', 'December'], + monthNamesShort: ['Jan', 'Feb', 'Már', 'Ápr', 'Máj', 'Jún', + 'Júl', 'Aug', 'Szep', 'Okt', 'Nov', 'Dec'], + dayNames: ['Vasárnap', 'Hétfő', 'Kedd', 'Szerda', 'Csütörtök', 'Péntek', 'Szombat'], + dayNamesShort: ['Vas', 'Hét', 'Ked', 'Sze', 'Csü', 'Pén', 'Szo'], + dayNamesMin: ['V', 'H', 'K', 'Sze', 'Cs', 'P', 'Szo'], + weekHeader: 'Hét', + dateFormat: 'yy.mm.dd.', + firstDay: 1, + isRTL: false, + showMonthAfterYear: true, + yearSuffix: ''}; + $.datepicker.setDefaults($.datepicker.regional['hu']); +}); diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/ui/i18n/jquery.ui.datepicker-hy.js b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/ui/i18n/jquery.ui.datepicker-hy.js new file mode 100755 index 000000000..b42851596 --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/ui/i18n/jquery.ui.datepicker-hy.js @@ -0,0 +1,23 @@ +/* Armenian(UTF-8) initialisation for the jQuery UI date picker plugin. */ +/* Written by Levon Zakaryan (levon.zakaryan@gmail.com)*/ +jQuery(function($){ + $.datepicker.regional['hy'] = { + closeText: 'Փակել', + prevText: '<Նախ.', + nextText: 'Հաջ.>', + currentText: 'Այսօր', + monthNames: ['Հունվար','Փետրվար','Մարտ','Ապրիլ','Մայիս','Հունիս', + 'Հուլիս','Օգոստոս','Սեպտեմբեր','Հոկտեմբեր','Նոյեմբեր','Դեկտեմբեր'], + monthNamesShort: ['Հունվ','Փետր','Մարտ','Ապր','Մայիս','Հունիս', + 'Հուլ','Օգս','Սեպ','Հոկ','Նոյ','Դեկ'], + dayNames: ['կիրակի','եկուշաբթի','երեքշաբթի','չորեքշաբթի','հինգշաբթի','ուրբաթ','շաբաթ'], + dayNamesShort: ['կիր','երկ','երք','չրք','հնգ','ուրբ','շբթ'], + dayNamesMin: ['կիր','երկ','երք','չրք','հնգ','ուրբ','շբթ'], + weekHeader: 'ՇԲՏ', + dateFormat: 'dd.mm.yy', + firstDay: 1, + isRTL: false, + showMonthAfterYear: false, + yearSuffix: ''}; + $.datepicker.setDefaults($.datepicker.regional['hy']); +}); \ No newline at end of file diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/ui/i18n/jquery.ui.datepicker-id.js b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/ui/i18n/jquery.ui.datepicker-id.js new file mode 100755 index 000000000..4ad46f640 --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/ui/i18n/jquery.ui.datepicker-id.js @@ -0,0 +1,23 @@ +/* Indonesian initialisation for the jQuery UI date picker plugin. */ +/* Written by Deden Fathurahman (dedenf@gmail.com). */ +jQuery(function($){ + $.datepicker.regional['id'] = { + closeText: 'Tutup', + prevText: '<mundur', + nextText: 'maju>', + currentText: 'hari ini', + monthNames: ['Januari','Februari','Maret','April','Mei','Juni', + 'Juli','Agustus','September','Oktober','Nopember','Desember'], + monthNamesShort: ['Jan','Feb','Mar','Apr','Mei','Jun', + 'Jul','Agus','Sep','Okt','Nop','Des'], + dayNames: ['Minggu','Senin','Selasa','Rabu','Kamis','Jumat','Sabtu'], + dayNamesShort: ['Min','Sen','Sel','Rab','kam','Jum','Sab'], + dayNamesMin: ['Mg','Sn','Sl','Rb','Km','jm','Sb'], + weekHeader: 'Mg', + dateFormat: 'dd/mm/yy', + firstDay: 0, + isRTL: false, + showMonthAfterYear: false, + yearSuffix: ''}; + $.datepicker.setDefaults($.datepicker.regional['id']); +}); \ No newline at end of file diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/ui/i18n/jquery.ui.datepicker-is.js b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/ui/i18n/jquery.ui.datepicker-is.js new file mode 100755 index 000000000..f1b067ebf --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/ui/i18n/jquery.ui.datepicker-is.js @@ -0,0 +1,23 @@ +/* Icelandic initialisation for the jQuery UI date picker plugin. */ +/* Written by Haukur H. Thorsson (haukur@eskill.is). */ +jQuery(function($){ + $.datepicker.regional['is'] = { + closeText: 'Loka', + prevText: '< Fyrri', + nextText: 'Næsti >', + currentText: 'Í dag', + monthNames: ['Janúar','Febrúar','Mars','Apríl','Maí','Júní', + 'Júlí','Ágúst','September','Október','Nóvember','Desember'], + monthNamesShort: ['Jan','Feb','Mar','Apr','Maí','Jún', + 'Júl','Ágú','Sep','Okt','Nóv','Des'], + dayNames: ['Sunnudagur','Mánudagur','Þriðjudagur','Miðvikudagur','Fimmtudagur','Föstudagur','Laugardagur'], + dayNamesShort: ['Sun','Mán','Þri','Mið','Fim','Fös','Lau'], + dayNamesMin: ['Su','Má','Þr','Mi','Fi','Fö','La'], + weekHeader: 'Vika', + dateFormat: 'dd/mm/yy', + firstDay: 0, + isRTL: false, + showMonthAfterYear: false, + yearSuffix: ''}; + $.datepicker.setDefaults($.datepicker.regional['is']); +}); \ No newline at end of file diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/ui/i18n/jquery.ui.datepicker-it.js b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/ui/i18n/jquery.ui.datepicker-it.js new file mode 100755 index 000000000..a01f043f8 --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/ui/i18n/jquery.ui.datepicker-it.js @@ -0,0 +1,23 @@ +/* Italian initialisation for the jQuery UI date picker plugin. */ +/* Written by Antonello Pasella (antonello.pasella@gmail.com). */ +jQuery(function($){ + $.datepicker.regional['it'] = { + closeText: 'Chiudi', + prevText: '<Prec', + nextText: 'Succ>', + currentText: 'Oggi', + monthNames: ['Gennaio','Febbraio','Marzo','Aprile','Maggio','Giugno', + 'Luglio','Agosto','Settembre','Ottobre','Novembre','Dicembre'], + monthNamesShort: ['Gen','Feb','Mar','Apr','Mag','Giu', + 'Lug','Ago','Set','Ott','Nov','Dic'], + dayNames: ['Domenica','Lunedì','Martedì','Mercoledì','Giovedì','Venerdì','Sabato'], + dayNamesShort: ['Dom','Lun','Mar','Mer','Gio','Ven','Sab'], + dayNamesMin: ['Do','Lu','Ma','Me','Gi','Ve','Sa'], + weekHeader: 'Sm', + dateFormat: 'dd/mm/yy', + firstDay: 1, + isRTL: false, + showMonthAfterYear: false, + yearSuffix: ''}; + $.datepicker.setDefaults($.datepicker.regional['it']); +}); diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/ui/i18n/jquery.ui.datepicker-ja.js b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/ui/i18n/jquery.ui.datepicker-ja.js new file mode 100755 index 000000000..afd298315 --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/ui/i18n/jquery.ui.datepicker-ja.js @@ -0,0 +1,23 @@ +/* Japanese initialisation for the jQuery UI date picker plugin. */ +/* Written by Kentaro SATO (kentaro@ranvis.com). */ +jQuery(function($){ + $.datepicker.regional['ja'] = { + closeText: '閉じる', + prevText: '<前', + nextText: '次>', + currentText: '今日', + monthNames: ['1月','2月','3月','4月','5月','6月', + '7月','8月','9月','10月','11月','12月'], + monthNamesShort: ['1月','2月','3月','4月','5月','6月', + '7月','8月','9月','10月','11月','12月'], + dayNames: ['日曜日','月曜日','火曜日','水曜日','木曜日','金曜日','土曜日'], + dayNamesShort: ['日','月','火','水','木','金','土'], + dayNamesMin: ['日','月','火','水','木','金','土'], + weekHeader: '週', + dateFormat: 'yy/mm/dd', + firstDay: 0, + isRTL: false, + showMonthAfterYear: true, + yearSuffix: '年'}; + $.datepicker.setDefaults($.datepicker.regional['ja']); +}); \ No newline at end of file diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/ui/i18n/jquery.ui.datepicker-ka.js b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/ui/i18n/jquery.ui.datepicker-ka.js new file mode 100755 index 000000000..c10658d79 --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/ui/i18n/jquery.ui.datepicker-ka.js @@ -0,0 +1,21 @@ +/* Georgian (UTF-8) initialisation for the jQuery UI date picker plugin. */ +/* Written by Lado Lomidze (lado.lomidze@gmail.com). */ +jQuery(function($){ + $.datepicker.regional['ka'] = { + closeText: 'დახურვა', + prevText: '< წინა', + nextText: 'შემდეგი >', + currentText: 'დღეს', + monthNames: ['იანვარი','თებერვალი','მარტი','აპრილი','მაისი','ივნისი', 'ივლისი','აგვისტო','სექტემბერი','ოქტომბერი','ნოემბერი','დეკემბერი'], + monthNamesShort: ['იან','თებ','მარ','აპრ','მაი','ივნ', 'ივლ','აგვ','სექ','ოქტ','ნოე','დეკ'], + dayNames: ['კვირა','ორშაბათი','სამშაბათი','ოთხშაბათი','ხუთშაბათი','პარასკევი','შაბათი'], + dayNamesShort: ['კვ','ორშ','სამ','ოთხ','ხუთ','პარ','შაბ'], + dayNamesMin: ['კვ','ორშ','სამ','ოთხ','ხუთ','პარ','შაბ'], + weekHeader: 'კვირა', + dateFormat: 'dd-mm-yy', + firstDay: 1, + isRTL: false, + showMonthAfterYear: false, + yearSuffix: ''}; + $.datepicker.setDefaults($.datepicker.regional['ka']); +}); diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/ui/i18n/jquery.ui.datepicker-kk.js b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/ui/i18n/jquery.ui.datepicker-kk.js new file mode 100755 index 000000000..dcd6a65df --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/ui/i18n/jquery.ui.datepicker-kk.js @@ -0,0 +1,23 @@ +/* Kazakh (UTF-8) initialisation for the jQuery UI date picker plugin. */ +/* Written by Dmitriy Karasyov (dmitriy.karasyov@gmail.com). */ +jQuery(function($){ + $.datepicker.regional['kk'] = { + closeText: 'Жабу', + prevText: '<Алдыңғы', + nextText: 'Келесі>', + currentText: 'Бүгін', + monthNames: ['Қаңтар','Ақпан','Наурыз','Сәуір','Мамыр','Маусым', + 'Шілде','Тамыз','Қыркүйек','Қазан','Қараша','Желтоқсан'], + monthNamesShort: ['Қаң','Ақп','Нау','Сәу','Мам','Мау', + 'Шіл','Там','Қыр','Қаз','Қар','Жел'], + dayNames: ['Жексенбі','Дүйсенбі','Сейсенбі','Сәрсенбі','Бейсенбі','Жұма','Сенбі'], + dayNamesShort: ['жкс','дсн','ссн','срс','бсн','жма','снб'], + dayNamesMin: ['Жк','Дс','Сс','Ср','Бс','Жм','Сн'], + weekHeader: 'Не', + dateFormat: 'dd.mm.yy', + firstDay: 1, + isRTL: false, + showMonthAfterYear: false, + yearSuffix: ''}; + $.datepicker.setDefaults($.datepicker.regional['kk']); +}); diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/ui/i18n/jquery.ui.datepicker-km.js b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/ui/i18n/jquery.ui.datepicker-km.js new file mode 100755 index 000000000..f9c4e3a02 --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/ui/i18n/jquery.ui.datepicker-km.js @@ -0,0 +1,23 @@ +/* Khmer initialisation for the jQuery calendar extension. */ +/* Written by Chandara Om (chandara.teacher@gmail.com). */ +jQuery(function($){ + $.datepicker.regional['km'] = { + closeText: 'ធ្វើ​រួច', + prevText: 'មុន', + nextText: 'បន្ទាប់', + currentText: 'ថ្ងៃ​នេះ', + monthNames: ['មករា','កុម្ភៈ','មីនា','មេសា','ឧសភា','មិថុនា', + 'កក្កដា','សីហា','កញ្ញា','តុលា','វិច្ឆិកា','ធ្នូ'], + monthNamesShort: ['មករា','កុម្ភៈ','មីនា','មេសា','ឧសភា','មិថុនា', + 'កក្កដា','សីហា','កញ្ញា','តុលា','វិច្ឆិកា','ធ្នូ'], + dayNames: ['អាទិត្យ', 'ចន្ទ', 'អង្គារ', 'ពុធ', 'ព្រហស្បតិ៍', 'សុក្រ', 'សៅរ៍'], + dayNamesShort: ['អា', 'ច', 'អ', 'ពុ', 'ព្រហ', 'សុ', 'សៅ'], + dayNamesMin: ['អា', 'ច', 'អ', 'ពុ', 'ព្រហ', 'សុ', 'សៅ'], + weekHeader: 'សប្ដាហ៍', + dateFormat: 'dd-mm-yy', + firstDay: 1, + isRTL: false, + showMonthAfterYear: false, + yearSuffix: ''}; + $.datepicker.setDefaults($.datepicker.regional['km']); +}); diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/ui/i18n/jquery.ui.datepicker-ko.js b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/ui/i18n/jquery.ui.datepicker-ko.js new file mode 100755 index 000000000..04112424d --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/ui/i18n/jquery.ui.datepicker-ko.js @@ -0,0 +1,23 @@ +/* Korean initialisation for the jQuery calendar extension. */ +/* Written by DaeKwon Kang (ncrash.dk@gmail.com), Edited by Genie. */ +jQuery(function($){ + $.datepicker.regional['ko'] = { + closeText: '닫기', + prevText: '이전달', + nextText: '다음달', + currentText: '오늘', + monthNames: ['1월','2월','3월','4월','5월','6월', + '7월','8월','9월','10월','11월','12월'], + monthNamesShort: ['1월','2월','3월','4월','5월','6월', + '7월','8월','9월','10월','11월','12월'], + dayNames: ['일요일','월요일','화요일','수요일','목요일','금요일','토요일'], + dayNamesShort: ['일','월','화','수','목','금','토'], + dayNamesMin: ['일','월','화','수','목','금','토'], + weekHeader: 'Wk', + dateFormat: 'yy-mm-dd', + firstDay: 0, + isRTL: false, + showMonthAfterYear: true, + yearSuffix: '년'}; + $.datepicker.setDefaults($.datepicker.regional['ko']); +}); \ No newline at end of file diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/ui/i18n/jquery.ui.datepicker-lb.js b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/ui/i18n/jquery.ui.datepicker-lb.js new file mode 100755 index 000000000..87c79d594 --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/ui/i18n/jquery.ui.datepicker-lb.js @@ -0,0 +1,23 @@ +/* Luxembourgish initialisation for the jQuery UI date picker plugin. */ +/* Written by Michel Weimerskirch */ +jQuery(function($){ + $.datepicker.regional['lb'] = { + closeText: 'Fäerdeg', + prevText: 'Zréck', + nextText: 'Weider', + currentText: 'Haut', + monthNames: ['Januar','Februar','Mäerz','Abrëll','Mee','Juni', + 'Juli','August','September','Oktober','November','Dezember'], + monthNamesShort: ['Jan', 'Feb', 'Mäe', 'Abr', 'Mee', 'Jun', + 'Jul', 'Aug', 'Sep', 'Okt', 'Nov', 'Dez'], + dayNames: ['Sonndeg', 'Méindeg', 'Dënschdeg', 'Mëttwoch', 'Donneschdeg', 'Freideg', 'Samschdeg'], + dayNamesShort: ['Son', 'Méi', 'Dën', 'Mët', 'Don', 'Fre', 'Sam'], + dayNamesMin: ['So','Mé','Dë','Më','Do','Fr','Sa'], + weekHeader: 'W', + dateFormat: 'dd.mm.yy', + firstDay: 1, + isRTL: false, + showMonthAfterYear: false, + yearSuffix: ''}; + $.datepicker.setDefaults($.datepicker.regional['lb']); +}); diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/ui/i18n/jquery.ui.datepicker-lt.js b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/ui/i18n/jquery.ui.datepicker-lt.js new file mode 100755 index 000000000..2970f8f37 --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/ui/i18n/jquery.ui.datepicker-lt.js @@ -0,0 +1,23 @@ +/* Lithuanian (UTF-8) initialisation for the jQuery UI date picker plugin. */ +/* @author Arturas Paleicikas */ +jQuery(function($){ + $.datepicker.regional['lt'] = { + closeText: 'Uždaryti', + prevText: '<Atgal', + nextText: 'Pirmyn>', + currentText: 'Šiandien', + monthNames: ['Sausis','Vasaris','Kovas','Balandis','Gegužė','Birželis', + 'Liepa','Rugpjūtis','Rugsėjis','Spalis','Lapkritis','Gruodis'], + monthNamesShort: ['Sau','Vas','Kov','Bal','Geg','Bir', + 'Lie','Rugp','Rugs','Spa','Lap','Gru'], + dayNames: ['sekmadienis','pirmadienis','antradienis','trečiadienis','ketvirtadienis','penktadienis','šeštadienis'], + dayNamesShort: ['sek','pir','ant','tre','ket','pen','šeš'], + dayNamesMin: ['Se','Pr','An','Tr','Ke','Pe','Še'], + weekHeader: 'Wk', + dateFormat: 'yy-mm-dd', + firstDay: 1, + isRTL: false, + showMonthAfterYear: false, + yearSuffix: ''}; + $.datepicker.setDefaults($.datepicker.regional['lt']); +}); \ No newline at end of file diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/ui/i18n/jquery.ui.datepicker-lv.js b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/ui/i18n/jquery.ui.datepicker-lv.js new file mode 100755 index 000000000..003934e72 --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/ui/i18n/jquery.ui.datepicker-lv.js @@ -0,0 +1,23 @@ +/* Latvian (UTF-8) initialisation for the jQuery UI date picker plugin. */ +/* @author Arturas Paleicikas */ +jQuery(function($){ + $.datepicker.regional['lv'] = { + closeText: 'Aizvērt', + prevText: 'Iepr', + nextText: 'Nāka', + currentText: 'Šodien', + monthNames: ['Janvāris','Februāris','Marts','Aprīlis','Maijs','Jūnijs', + 'Jūlijs','Augusts','Septembris','Oktobris','Novembris','Decembris'], + monthNamesShort: ['Jan','Feb','Mar','Apr','Mai','Jūn', + 'Jūl','Aug','Sep','Okt','Nov','Dec'], + dayNames: ['svētdiena','pirmdiena','otrdiena','trešdiena','ceturtdiena','piektdiena','sestdiena'], + dayNamesShort: ['svt','prm','otr','tre','ctr','pkt','sst'], + dayNamesMin: ['Sv','Pr','Ot','Tr','Ct','Pk','Ss'], + weekHeader: 'Nav', + dateFormat: 'dd-mm-yy', + firstDay: 1, + isRTL: false, + showMonthAfterYear: false, + yearSuffix: ''}; + $.datepicker.setDefaults($.datepicker.regional['lv']); +}); \ No newline at end of file diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/ui/i18n/jquery.ui.datepicker-mk.js b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/ui/i18n/jquery.ui.datepicker-mk.js new file mode 100755 index 000000000..028532551 --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/ui/i18n/jquery.ui.datepicker-mk.js @@ -0,0 +1,23 @@ +/* Macedonian i18n for the jQuery UI date picker plugin. */ +/* Written by Stojce Slavkovski. */ +jQuery(function($){ + $.datepicker.regional['mk'] = { + closeText: 'Затвори', + prevText: '<', + nextText: '>', + currentText: 'Денес', + monthNames: ['Јануари','Февруари','Март','Април','Мај','Јуни', + 'Јули','Август','Септември','Октомври','Ноември','Декември'], + monthNamesShort: ['Јан','Фев','Мар','Апр','Мај','Јун', + 'Јул','Авг','Сеп','Окт','Ное','Дек'], + dayNames: ['Недела','Понеделник','Вторник','Среда','Четврток','Петок','Сабота'], + dayNamesShort: ['Нед','Пон','Вто','Сре','Чет','Пет','Саб'], + dayNamesMin: ['Не','По','Вт','Ср','Че','Пе','Са'], + weekHeader: 'Сед', + dateFormat: 'dd.mm.yy', + firstDay: 1, + isRTL: false, + showMonthAfterYear: false, + yearSuffix: ''}; + $.datepicker.setDefaults($.datepicker.regional['mk']); +}); diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/ui/i18n/jquery.ui.datepicker-ml.js b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/ui/i18n/jquery.ui.datepicker-ml.js new file mode 100755 index 000000000..1e3432c0a --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/ui/i18n/jquery.ui.datepicker-ml.js @@ -0,0 +1,23 @@ +/* Malayalam (UTF-8) initialisation for the jQuery UI date picker plugin. */ +/* Written by Saji Nediyanchath (saji89@gmail.com). */ +jQuery(function($){ + $.datepicker.regional['ml'] = { + closeText: 'ശരി', + prevText: 'മുന്നത്തെ', + nextText: 'അടുത്തത് ', + currentText: 'ഇന്ന്', + monthNames: ['ജനുവരി','ഫെബ്രുവരി','മാര്‍ച്ച്','ഏപ്രില്‍','മേയ്','ജൂണ്‍', + 'ജൂലൈ','ആഗസ്റ്റ്','സെപ്റ്റംബര്‍','ഒക്ടോബര്‍','നവംബര്‍','ഡിസംബര്‍'], + monthNamesShort: ['ജനു', 'ഫെബ്', 'മാര്‍', 'ഏപ്രി', 'മേയ്', 'ജൂണ്‍', + 'ജൂലാ', 'ആഗ', 'സെപ്', 'ഒക്ടോ', 'നവം', 'ഡിസ'], + dayNames: ['ഞായര്‍', 'തിങ്കള്‍', 'ചൊവ്വ', 'ബുധന്‍', 'വ്യാഴം', 'വെള്ളി', 'ശനി'], + dayNamesShort: ['ഞായ', 'തിങ്ക', 'ചൊവ്വ', 'ബുധ', 'വ്യാഴം', 'വെള്ളി', 'ശനി'], + dayNamesMin: ['ഞാ','തി','ചൊ','ബു','വ്യാ','വെ','ശ'], + weekHeader: 'ആ', + dateFormat: 'dd/mm/yy', + firstDay: 1, + isRTL: false, + showMonthAfterYear: false, + yearSuffix: ''}; + $.datepicker.setDefaults($.datepicker.regional['ml']); +}); diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/ui/i18n/jquery.ui.datepicker-ms.js b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/ui/i18n/jquery.ui.datepicker-ms.js new file mode 100755 index 000000000..c290af10a --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/ui/i18n/jquery.ui.datepicker-ms.js @@ -0,0 +1,23 @@ +/* Malaysian initialisation for the jQuery UI date picker plugin. */ +/* Written by Mohd Nawawi Mohamad Jamili (nawawi@ronggeng.net). */ +jQuery(function($){ + $.datepicker.regional['ms'] = { + closeText: 'Tutup', + prevText: '<Sebelum', + nextText: 'Selepas>', + currentText: 'hari ini', + monthNames: ['Januari','Februari','Mac','April','Mei','Jun', + 'Julai','Ogos','September','Oktober','November','Disember'], + monthNamesShort: ['Jan','Feb','Mac','Apr','Mei','Jun', + 'Jul','Ogo','Sep','Okt','Nov','Dis'], + dayNames: ['Ahad','Isnin','Selasa','Rabu','Khamis','Jumaat','Sabtu'], + dayNamesShort: ['Aha','Isn','Sel','Rab','kha','Jum','Sab'], + dayNamesMin: ['Ah','Is','Se','Ra','Kh','Ju','Sa'], + weekHeader: 'Mg', + dateFormat: 'dd/mm/yy', + firstDay: 0, + isRTL: false, + showMonthAfterYear: false, + yearSuffix: ''}; + $.datepicker.setDefaults($.datepicker.regional['ms']); +}); \ No newline at end of file diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/ui/i18n/jquery.ui.datepicker-nl-BE.js b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/ui/i18n/jquery.ui.datepicker-nl-BE.js new file mode 100755 index 000000000..7b3cdf425 --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/ui/i18n/jquery.ui.datepicker-nl-BE.js @@ -0,0 +1,23 @@ +/* Dutch (Belgium) initialisation for the jQuery UI date picker plugin. */ +/* David De Sloovere @DavidDeSloovere */ +jQuery(function($){ + $.datepicker.regional['nl-BE'] = { + closeText: 'Sluiten', + prevText: '←', + nextText: '→', + currentText: 'Vandaag', + monthNames: ['januari', 'februari', 'maart', 'april', 'mei', 'juni', + 'juli', 'augustus', 'september', 'oktober', 'november', 'december'], + monthNamesShort: ['jan', 'feb', 'mrt', 'apr', 'mei', 'jun', + 'jul', 'aug', 'sep', 'okt', 'nov', 'dec'], + dayNames: ['zondag', 'maandag', 'dinsdag', 'woensdag', 'donderdag', 'vrijdag', 'zaterdag'], + dayNamesShort: ['zon', 'maa', 'din', 'woe', 'don', 'vri', 'zat'], + dayNamesMin: ['zo', 'ma', 'di', 'wo', 'do', 'vr', 'za'], + weekHeader: 'Wk', + dateFormat: 'dd/mm/yy', + firstDay: 1, + isRTL: false, + showMonthAfterYear: false, + yearSuffix: ''}; + $.datepicker.setDefaults($.datepicker.regional['nl-BE']); +}); diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/ui/i18n/jquery.ui.datepicker-nl.js b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/ui/i18n/jquery.ui.datepicker-nl.js new file mode 100755 index 000000000..781fe6191 --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/ui/i18n/jquery.ui.datepicker-nl.js @@ -0,0 +1,23 @@ +/* Dutch (UTF-8) initialisation for the jQuery UI date picker plugin. */ +/* Written by Mathias Bynens */ +jQuery(function($){ + $.datepicker.regional.nl = { + closeText: 'Sluiten', + prevText: '←', + nextText: '→', + currentText: 'Vandaag', + monthNames: ['januari', 'februari', 'maart', 'april', 'mei', 'juni', + 'juli', 'augustus', 'september', 'oktober', 'november', 'december'], + monthNamesShort: ['jan', 'feb', 'mrt', 'apr', 'mei', 'jun', + 'jul', 'aug', 'sep', 'okt', 'nov', 'dec'], + dayNames: ['zondag', 'maandag', 'dinsdag', 'woensdag', 'donderdag', 'vrijdag', 'zaterdag'], + dayNamesShort: ['zon', 'maa', 'din', 'woe', 'don', 'vri', 'zat'], + dayNamesMin: ['zo', 'ma', 'di', 'wo', 'do', 'vr', 'za'], + weekHeader: 'Wk', + dateFormat: 'dd-mm-yy', + firstDay: 1, + isRTL: false, + showMonthAfterYear: false, + yearSuffix: ''}; + $.datepicker.setDefaults($.datepicker.regional.nl); +}); \ No newline at end of file diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/ui/i18n/jquery.ui.datepicker-no.js b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/ui/i18n/jquery.ui.datepicker-no.js new file mode 100755 index 000000000..d36e430be --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/ui/i18n/jquery.ui.datepicker-no.js @@ -0,0 +1,23 @@ +/* Norwegian initialisation for the jQuery UI date picker plugin. */ +/* Written by Naimdjon Takhirov (naimdjon@gmail.com). */ + +jQuery(function($){ + $.datepicker.regional['no'] = { + closeText: 'Lukk', + prevText: '«Forrige', + nextText: 'Neste»', + currentText: 'I dag', + monthNames: ['januar','februar','mars','april','mai','juni','juli','august','september','oktober','november','desember'], + monthNamesShort: ['jan','feb','mar','apr','mai','jun','jul','aug','sep','okt','nov','des'], + dayNamesShort: ['søn','man','tir','ons','tor','fre','lør'], + dayNames: ['søndag','mandag','tirsdag','onsdag','torsdag','fredag','lørdag'], + dayNamesMin: ['sø','ma','ti','on','to','fr','lø'], + weekHeader: 'Uke', + dateFormat: 'dd.mm.yy', + firstDay: 1, + isRTL: false, + showMonthAfterYear: false, + yearSuffix: '' + }; + $.datepicker.setDefaults($.datepicker.regional['no']); +}); diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/ui/i18n/jquery.ui.datepicker-pl.js b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/ui/i18n/jquery.ui.datepicker-pl.js new file mode 100755 index 000000000..0ffc515b9 --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/ui/i18n/jquery.ui.datepicker-pl.js @@ -0,0 +1,23 @@ +/* Polish initialisation for the jQuery UI date picker plugin. */ +/* Written by Jacek Wysocki (jacek.wysocki@gmail.com). */ +jQuery(function($){ + $.datepicker.regional['pl'] = { + closeText: 'Zamknij', + prevText: '<Poprzedni', + nextText: 'Następny>', + currentText: 'Dziś', + monthNames: ['Styczeń','Luty','Marzec','Kwiecień','Maj','Czerwiec', + 'Lipiec','Sierpień','Wrzesień','Październik','Listopad','Grudzień'], + monthNamesShort: ['Sty','Lu','Mar','Kw','Maj','Cze', + 'Lip','Sie','Wrz','Pa','Lis','Gru'], + dayNames: ['Niedziela','Poniedziałek','Wtorek','Środa','Czwartek','Piątek','Sobota'], + dayNamesShort: ['Nie','Pn','Wt','Śr','Czw','Pt','So'], + dayNamesMin: ['N','Pn','Wt','Śr','Cz','Pt','So'], + weekHeader: 'Tydz', + dateFormat: 'dd.mm.yy', + firstDay: 1, + isRTL: false, + showMonthAfterYear: false, + yearSuffix: ''}; + $.datepicker.setDefaults($.datepicker.regional['pl']); +}); diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/ui/i18n/jquery.ui.datepicker-pt-BR.js b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/ui/i18n/jquery.ui.datepicker-pt-BR.js new file mode 100755 index 000000000..0741892ab --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/ui/i18n/jquery.ui.datepicker-pt-BR.js @@ -0,0 +1,23 @@ +/* Brazilian initialisation for the jQuery UI date picker plugin. */ +/* Written by Leonildo Costa Silva (leocsilva@gmail.com). */ +jQuery(function($){ + $.datepicker.regional['pt-BR'] = { + closeText: 'Fechar', + prevText: '<Anterior', + nextText: 'Próximo>', + currentText: 'Hoje', + monthNames: ['Janeiro','Fevereiro','Março','Abril','Maio','Junho', + 'Julho','Agosto','Setembro','Outubro','Novembro','Dezembro'], + monthNamesShort: ['Jan','Fev','Mar','Abr','Mai','Jun', + 'Jul','Ago','Set','Out','Nov','Dez'], + dayNames: ['Domingo','Segunda-feira','Terça-feira','Quarta-feira','Quinta-feira','Sexta-feira','Sábado'], + dayNamesShort: ['Dom','Seg','Ter','Qua','Qui','Sex','Sáb'], + dayNamesMin: ['Dom','Seg','Ter','Qua','Qui','Sex','Sáb'], + weekHeader: 'Sm', + dateFormat: 'dd/mm/yy', + firstDay: 0, + isRTL: false, + showMonthAfterYear: false, + yearSuffix: ''}; + $.datepicker.setDefaults($.datepicker.regional['pt-BR']); +}); \ No newline at end of file diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/ui/i18n/jquery.ui.datepicker-pt.js b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/ui/i18n/jquery.ui.datepicker-pt.js new file mode 100755 index 000000000..98925b455 --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/ui/i18n/jquery.ui.datepicker-pt.js @@ -0,0 +1,22 @@ +/* Portuguese initialisation for the jQuery UI date picker plugin. */ +jQuery(function($){ + $.datepicker.regional['pt'] = { + closeText: 'Fechar', + prevText: '<Anterior', + nextText: 'Seguinte', + currentText: 'Hoje', + monthNames: ['Janeiro','Fevereiro','Março','Abril','Maio','Junho', + 'Julho','Agosto','Setembro','Outubro','Novembro','Dezembro'], + monthNamesShort: ['Jan','Fev','Mar','Abr','Mai','Jun', + 'Jul','Ago','Set','Out','Nov','Dez'], + dayNames: ['Domingo','Segunda-feira','Terça-feira','Quarta-feira','Quinta-feira','Sexta-feira','Sábado'], + dayNamesShort: ['Dom','Seg','Ter','Qua','Qui','Sex','Sáb'], + dayNamesMin: ['Dom','Seg','Ter','Qua','Qui','Sex','Sáb'], + weekHeader: 'Sem', + dateFormat: 'dd/mm/yy', + firstDay: 0, + isRTL: false, + showMonthAfterYear: false, + yearSuffix: ''}; + $.datepicker.setDefaults($.datepicker.regional['pt']); +}); \ No newline at end of file diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/ui/i18n/jquery.ui.datepicker-rm.js b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/ui/i18n/jquery.ui.datepicker-rm.js new file mode 100755 index 000000000..22ed21685 --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/ui/i18n/jquery.ui.datepicker-rm.js @@ -0,0 +1,21 @@ +/* Romansh initialisation for the jQuery UI date picker plugin. */ +/* Written by Yvonne Gienal (yvonne.gienal@educa.ch). */ +jQuery(function($){ + $.datepicker.regional['rm'] = { + closeText: 'Serrar', + prevText: '<Suandant', + nextText: 'Precedent>', + currentText: 'Actual', + monthNames: ['Schaner','Favrer','Mars','Avrigl','Matg','Zercladur', 'Fanadur','Avust','Settember','October','November','December'], + monthNamesShort: ['Scha','Fev','Mar','Avr','Matg','Zer', 'Fan','Avu','Sett','Oct','Nov','Dec'], + dayNames: ['Dumengia','Glindesdi','Mardi','Mesemna','Gievgia','Venderdi','Sonda'], + dayNamesShort: ['Dum','Gli','Mar','Mes','Gie','Ven','Som'], + dayNamesMin: ['Du','Gl','Ma','Me','Gi','Ve','So'], + weekHeader: 'emna', + dateFormat: 'dd/mm/yy', + firstDay: 1, + isRTL: false, + showMonthAfterYear: false, + yearSuffix: ''}; + $.datepicker.setDefaults($.datepicker.regional['rm']); +}); diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/ui/i18n/jquery.ui.datepicker-ro.js b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/ui/i18n/jquery.ui.datepicker-ro.js new file mode 100755 index 000000000..a988270d7 --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/ui/i18n/jquery.ui.datepicker-ro.js @@ -0,0 +1,26 @@ +/* Romanian initialisation for the jQuery UI date picker plugin. + * + * Written by Edmond L. (ll_edmond@walla.com) + * and Ionut G. Stan (ionut.g.stan@gmail.com) + */ +jQuery(function($){ + $.datepicker.regional['ro'] = { + closeText: 'Închide', + prevText: '« Luna precedentă', + nextText: 'Luna următoare »', + currentText: 'Azi', + monthNames: ['Ianuarie','Februarie','Martie','Aprilie','Mai','Iunie', + 'Iulie','August','Septembrie','Octombrie','Noiembrie','Decembrie'], + monthNamesShort: ['Ian', 'Feb', 'Mar', 'Apr', 'Mai', 'Iun', + 'Iul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'], + dayNames: ['Duminică', 'Luni', 'Marţi', 'Miercuri', 'Joi', 'Vineri', 'Sâmbătă'], + dayNamesShort: ['Dum', 'Lun', 'Mar', 'Mie', 'Joi', 'Vin', 'Sâm'], + dayNamesMin: ['Du','Lu','Ma','Mi','Jo','Vi','Sâ'], + weekHeader: 'Săpt', + dateFormat: 'dd.mm.yy', + firstDay: 1, + isRTL: false, + showMonthAfterYear: false, + yearSuffix: ''}; + $.datepicker.setDefaults($.datepicker.regional['ro']); +}); diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/ui/i18n/jquery.ui.datepicker-ru.js b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/ui/i18n/jquery.ui.datepicker-ru.js new file mode 100755 index 000000000..2017e0537 --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/ui/i18n/jquery.ui.datepicker-ru.js @@ -0,0 +1,23 @@ +/* Russian (UTF-8) initialisation for the jQuery UI date picker plugin. */ +/* Written by Andrew Stromnov (stromnov@gmail.com). */ +jQuery(function($){ + $.datepicker.regional['ru'] = { + closeText: 'Закрыть', + prevText: '<Пред', + nextText: 'След>', + currentText: 'Сегодня', + monthNames: ['Январь','Февраль','Март','Апрель','Май','Июнь', + 'Июль','Август','Сентябрь','Октябрь','Ноябрь','Декабрь'], + monthNamesShort: ['Янв','Фев','Мар','Апр','Май','Июн', + 'Июл','Авг','Сен','Окт','Ноя','Дек'], + dayNames: ['воскресенье','понедельник','вторник','среда','четверг','пятница','суббота'], + dayNamesShort: ['вск','пнд','втр','срд','чтв','птн','сбт'], + dayNamesMin: ['Вс','Пн','Вт','Ср','Чт','Пт','Сб'], + weekHeader: 'Нед', + dateFormat: 'dd.mm.yy', + firstDay: 1, + isRTL: false, + showMonthAfterYear: false, + yearSuffix: ''}; + $.datepicker.setDefaults($.datepicker.regional['ru']); +}); \ No newline at end of file diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/ui/i18n/jquery.ui.datepicker-sk.js b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/ui/i18n/jquery.ui.datepicker-sk.js new file mode 100755 index 000000000..83ae8e811 --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/ui/i18n/jquery.ui.datepicker-sk.js @@ -0,0 +1,23 @@ +/* Slovak initialisation for the jQuery UI date picker plugin. */ +/* Written by Vojtech Rinik (vojto@hmm.sk). */ +jQuery(function($){ + $.datepicker.regional['sk'] = { + closeText: 'Zavrieť', + prevText: '<Predchádzajúci', + nextText: 'Nasledujúci>', + currentText: 'Dnes', + monthNames: ['Január','Február','Marec','Apríl','Máj','Jún', + 'Júl','August','September','Október','November','December'], + monthNamesShort: ['Jan','Feb','Mar','Apr','Máj','Jún', + 'Júl','Aug','Sep','Okt','Nov','Dec'], + dayNames: ['Nedeľa','Pondelok','Utorok','Streda','Štvrtok','Piatok','Sobota'], + dayNamesShort: ['Ned','Pon','Uto','Str','Štv','Pia','Sob'], + dayNamesMin: ['Ne','Po','Ut','St','Št','Pia','So'], + weekHeader: 'Ty', + dateFormat: 'dd.mm.yy', + firstDay: 1, + isRTL: false, + showMonthAfterYear: false, + yearSuffix: ''}; + $.datepicker.setDefaults($.datepicker.regional['sk']); +}); diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/ui/i18n/jquery.ui.datepicker-sl.js b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/ui/i18n/jquery.ui.datepicker-sl.js new file mode 100755 index 000000000..048a47af7 --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/ui/i18n/jquery.ui.datepicker-sl.js @@ -0,0 +1,24 @@ +/* Slovenian initialisation for the jQuery UI date picker plugin. */ +/* Written by Jaka Jancar (jaka@kubje.org). */ +/* c = č, s = š z = ž C = Č S = Š Z = Ž */ +jQuery(function($){ + $.datepicker.regional['sl'] = { + closeText: 'Zapri', + prevText: '<Prejšnji', + nextText: 'Naslednji>', + currentText: 'Trenutni', + monthNames: ['Januar','Februar','Marec','April','Maj','Junij', + 'Julij','Avgust','September','Oktober','November','December'], + monthNamesShort: ['Jan','Feb','Mar','Apr','Maj','Jun', + 'Jul','Avg','Sep','Okt','Nov','Dec'], + dayNames: ['Nedelja','Ponedeljek','Torek','Sreda','Četrtek','Petek','Sobota'], + dayNamesShort: ['Ned','Pon','Tor','Sre','Čet','Pet','Sob'], + dayNamesMin: ['Ne','Po','To','Sr','Če','Pe','So'], + weekHeader: 'Teden', + dateFormat: 'dd.mm.yy', + firstDay: 1, + isRTL: false, + showMonthAfterYear: false, + yearSuffix: ''}; + $.datepicker.setDefaults($.datepicker.regional['sl']); +}); diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/ui/i18n/jquery.ui.datepicker-sq.js b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/ui/i18n/jquery.ui.datepicker-sq.js new file mode 100755 index 000000000..d6086a789 --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/ui/i18n/jquery.ui.datepicker-sq.js @@ -0,0 +1,23 @@ +/* Albanian initialisation for the jQuery UI date picker plugin. */ +/* Written by Flakron Bytyqi (flakron@gmail.com). */ +jQuery(function($){ + $.datepicker.regional['sq'] = { + closeText: 'mbylle', + prevText: '<mbrapa', + nextText: 'Përpara>', + currentText: 'sot', + monthNames: ['Janar','Shkurt','Mars','Prill','Maj','Qershor', + 'Korrik','Gusht','Shtator','Tetor','Nëntor','Dhjetor'], + monthNamesShort: ['Jan','Shk','Mar','Pri','Maj','Qer', + 'Kor','Gus','Sht','Tet','Nën','Dhj'], + dayNames: ['E Diel','E Hënë','E Martë','E Mërkurë','E Enjte','E Premte','E Shtune'], + dayNamesShort: ['Di','Hë','Ma','Më','En','Pr','Sh'], + dayNamesMin: ['Di','Hë','Ma','Më','En','Pr','Sh'], + weekHeader: 'Ja', + dateFormat: 'dd.mm.yy', + firstDay: 1, + isRTL: false, + showMonthAfterYear: false, + yearSuffix: ''}; + $.datepicker.setDefaults($.datepicker.regional['sq']); +}); diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/ui/i18n/jquery.ui.datepicker-sr-SR.js b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/ui/i18n/jquery.ui.datepicker-sr-SR.js new file mode 100755 index 000000000..6d5d04211 --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/ui/i18n/jquery.ui.datepicker-sr-SR.js @@ -0,0 +1,23 @@ +/* Serbian i18n for the jQuery UI date picker plugin. */ +/* Written by Dejan Dimić. */ +jQuery(function($){ + $.datepicker.regional['sr-SR'] = { + closeText: 'Zatvori', + prevText: '<', + nextText: '>', + currentText: 'Danas', + monthNames: ['Januar','Februar','Mart','April','Maj','Jun', + 'Jul','Avgust','Septembar','Oktobar','Novembar','Decembar'], + monthNamesShort: ['Jan','Feb','Mar','Apr','Maj','Jun', + 'Jul','Avg','Sep','Okt','Nov','Dec'], + dayNames: ['Nedelja','Ponedeljak','Utorak','Sreda','Četvrtak','Petak','Subota'], + dayNamesShort: ['Ned','Pon','Uto','Sre','Čet','Pet','Sub'], + dayNamesMin: ['Ne','Po','Ut','Sr','Če','Pe','Su'], + weekHeader: 'Sed', + dateFormat: 'dd/mm/yy', + firstDay: 1, + isRTL: false, + showMonthAfterYear: false, + yearSuffix: ''}; + $.datepicker.setDefaults($.datepicker.regional['sr-SR']); +}); diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/ui/i18n/jquery.ui.datepicker-sr.js b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/ui/i18n/jquery.ui.datepicker-sr.js new file mode 100755 index 000000000..d4e1d9af0 --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/ui/i18n/jquery.ui.datepicker-sr.js @@ -0,0 +1,23 @@ +/* Serbian i18n for the jQuery UI date picker plugin. */ +/* Written by Dejan Dimić. */ +jQuery(function($){ + $.datepicker.regional['sr'] = { + closeText: 'Затвори', + prevText: '<', + nextText: '>', + currentText: 'Данас', + monthNames: ['Јануар','Фебруар','Март','Април','Мај','Јун', + 'Јул','Август','Септембар','Октобар','Новембар','Децембар'], + monthNamesShort: ['Јан','Феб','Мар','Апр','Мај','Јун', + 'Јул','Авг','Сеп','Окт','Нов','Дец'], + dayNames: ['Недеља','Понедељак','Уторак','Среда','Четвртак','Петак','Субота'], + dayNamesShort: ['Нед','Пон','Уто','Сре','Чет','Пет','Суб'], + dayNamesMin: ['Не','По','Ут','Ср','Че','Пе','Су'], + weekHeader: 'Сед', + dateFormat: 'dd/mm/yy', + firstDay: 1, + isRTL: false, + showMonthAfterYear: false, + yearSuffix: ''}; + $.datepicker.setDefaults($.datepicker.regional['sr']); +}); diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/ui/i18n/jquery.ui.datepicker-sv.js b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/ui/i18n/jquery.ui.datepicker-sv.js new file mode 100755 index 000000000..cbb5ad135 --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/ui/i18n/jquery.ui.datepicker-sv.js @@ -0,0 +1,23 @@ +/* Swedish initialisation for the jQuery UI date picker plugin. */ +/* Written by Anders Ekdahl ( anders@nomadiz.se). */ +jQuery(function($){ + $.datepicker.regional['sv'] = { + closeText: 'Stäng', + prevText: '«Förra', + nextText: 'Nästa»', + currentText: 'Idag', + monthNames: ['Januari','Februari','Mars','April','Maj','Juni', + 'Juli','Augusti','September','Oktober','November','December'], + monthNamesShort: ['Jan','Feb','Mar','Apr','Maj','Jun', + 'Jul','Aug','Sep','Okt','Nov','Dec'], + dayNamesShort: ['Sön','Mån','Tis','Ons','Tor','Fre','Lör'], + dayNames: ['Söndag','Måndag','Tisdag','Onsdag','Torsdag','Fredag','Lördag'], + dayNamesMin: ['Sö','Må','Ti','On','To','Fr','Lö'], + weekHeader: 'Ve', + dateFormat: 'yy-mm-dd', + firstDay: 1, + isRTL: false, + showMonthAfterYear: false, + yearSuffix: ''}; + $.datepicker.setDefaults($.datepicker.regional['sv']); +}); diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/ui/i18n/jquery.ui.datepicker-ta.js b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/ui/i18n/jquery.ui.datepicker-ta.js new file mode 100755 index 000000000..40431ed8e --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/ui/i18n/jquery.ui.datepicker-ta.js @@ -0,0 +1,23 @@ +/* Tamil (UTF-8) initialisation for the jQuery UI date picker plugin. */ +/* Written by S A Sureshkumar (saskumar@live.com). */ +jQuery(function($){ + $.datepicker.regional['ta'] = { + closeText: 'மூடு', + prevText: 'முன்னையது', + nextText: 'அடுத்தது', + currentText: 'இன்று', + monthNames: ['தை','மாசி','பங்குனி','சித்திரை','வைகாசி','ஆனி', + 'ஆடி','ஆவணி','புரட்டாசி','ஐப்பசி','கார்த்திகை','மார்கழி'], + monthNamesShort: ['தை','மாசி','பங்','சித்','வைகா','ஆனி', + 'ஆடி','ஆவ','புர','ஐப்','கார்','மார்'], + dayNames: ['ஞாயிற்றுக்கிழமை','திங்கட்கிழமை','செவ்வாய்க்கிழமை','புதன்கிழமை','வியாழக்கிழமை','வெள்ளிக்கிழமை','சனிக்கிழமை'], + dayNamesShort: ['ஞாயிறு','திங்கள்','செவ்வாய்','புதன்','வியாழன்','வெள்ளி','சனி'], + dayNamesMin: ['ஞா','தி','செ','பு','வி','வெ','ச'], + weekHeader: 'Не', + dateFormat: 'dd/mm/yy', + firstDay: 1, + isRTL: false, + showMonthAfterYear: false, + yearSuffix: ''}; + $.datepicker.setDefaults($.datepicker.regional['ta']); +}); diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/ui/i18n/jquery.ui.datepicker-th.js b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/ui/i18n/jquery.ui.datepicker-th.js new file mode 100755 index 000000000..d57541f64 --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/ui/i18n/jquery.ui.datepicker-th.js @@ -0,0 +1,23 @@ +/* Thai initialisation for the jQuery UI date picker plugin. */ +/* Written by pipo (pipo@sixhead.com). */ +jQuery(function($){ + $.datepicker.regional['th'] = { + closeText: 'ปิด', + prevText: '« ย้อน', + nextText: 'ถัดไป »', + currentText: 'วันนี้', + monthNames: ['มกราคม','กุมภาพันธ์','มีนาคม','เมษายน','พฤษภาคม','มิถุนายน', + 'กรกฎาคม','สิงหาคม','กันยายน','ตุลาคม','พฤศจิกายน','ธันวาคม'], + monthNamesShort: ['ม.ค.','ก.พ.','มี.ค.','เม.ย.','พ.ค.','มิ.ย.', + 'ก.ค.','ส.ค.','ก.ย.','ต.ค.','พ.ย.','ธ.ค.'], + dayNames: ['อาทิตย์','จันทร์','อังคาร','พุธ','พฤหัสบดี','ศุกร์','เสาร์'], + dayNamesShort: ['อา.','จ.','อ.','พ.','พฤ.','ศ.','ส.'], + dayNamesMin: ['อา.','จ.','อ.','พ.','พฤ.','ศ.','ส.'], + weekHeader: 'Wk', + dateFormat: 'dd/mm/yy', + firstDay: 0, + isRTL: false, + showMonthAfterYear: false, + yearSuffix: ''}; + $.datepicker.setDefaults($.datepicker.regional['th']); +}); \ No newline at end of file diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/ui/i18n/jquery.ui.datepicker-tj.js b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/ui/i18n/jquery.ui.datepicker-tj.js new file mode 100755 index 000000000..ed662392c --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/ui/i18n/jquery.ui.datepicker-tj.js @@ -0,0 +1,23 @@ +/* Tajiki (UTF-8) initialisation for the jQuery UI date picker plugin. */ +/* Written by Abdurahmon Saidov (saidovab@gmail.com). */ +jQuery(function($){ + $.datepicker.regional['tj'] = { + closeText: 'Идома', + prevText: '<Қафо', + nextText: 'Пеш>', + currentText: 'Имрӯз', + monthNames: ['Январ','Феврал','Март','Апрел','Май','Июн', + 'Июл','Август','Сентябр','Октябр','Ноябр','Декабр'], + monthNamesShort: ['Янв','Фев','Мар','Апр','Май','Июн', + 'Июл','Авг','Сен','Окт','Ноя','Дек'], + dayNames: ['якшанбе','душанбе','сешанбе','чоршанбе','панҷшанбе','ҷумъа','шанбе'], + dayNamesShort: ['якш','душ','сеш','чор','пан','ҷум','шан'], + dayNamesMin: ['Як','Дш','Сш','Чш','Пш','Ҷм','Шн'], + weekHeader: 'Хф', + dateFormat: 'dd.mm.yy', + firstDay: 1, + isRTL: false, + showMonthAfterYear: false, + yearSuffix: ''}; + $.datepicker.setDefaults($.datepicker.regional['tj']); +}); \ No newline at end of file diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/ui/i18n/jquery.ui.datepicker-tr.js b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/ui/i18n/jquery.ui.datepicker-tr.js new file mode 100755 index 000000000..1b5cafc39 --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/ui/i18n/jquery.ui.datepicker-tr.js @@ -0,0 +1,23 @@ +/* Turkish initialisation for the jQuery UI date picker plugin. */ +/* Written by Izzet Emre Erkan (kara@karalamalar.net). */ +jQuery(function($){ + $.datepicker.regional['tr'] = { + closeText: 'kapat', + prevText: '<geri', + nextText: 'ileri>', + currentText: 'bugün', + monthNames: ['Ocak','Şubat','Mart','Nisan','Mayıs','Haziran', + 'Temmuz','Ağustos','Eylül','Ekim','Kasım','Aralık'], + monthNamesShort: ['Oca','Şub','Mar','Nis','May','Haz', + 'Tem','Ağu','Eyl','Eki','Kas','Ara'], + dayNames: ['Pazar','Pazartesi','Salı','Çarşamba','Perşembe','Cuma','Cumartesi'], + dayNamesShort: ['Pz','Pt','Sa','Ça','Pe','Cu','Ct'], + dayNamesMin: ['Pz','Pt','Sa','Ça','Pe','Cu','Ct'], + weekHeader: 'Hf', + dateFormat: 'dd.mm.yy', + firstDay: 1, + isRTL: false, + showMonthAfterYear: false, + yearSuffix: ''}; + $.datepicker.setDefaults($.datepicker.regional['tr']); +}); \ No newline at end of file diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/ui/i18n/jquery.ui.datepicker-uk.js b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/ui/i18n/jquery.ui.datepicker-uk.js new file mode 100755 index 000000000..31964af44 --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/ui/i18n/jquery.ui.datepicker-uk.js @@ -0,0 +1,24 @@ +/* Ukrainian (UTF-8) initialisation for the jQuery UI date picker plugin. */ +/* Written by Maxim Drogobitskiy (maxdao@gmail.com). */ +/* Corrected by Igor Milla (igor.fsp.milla@gmail.com). */ +jQuery(function($){ + $.datepicker.regional['uk'] = { + closeText: 'Закрити', + prevText: '<', + nextText: '>', + currentText: 'Сьогодні', + monthNames: ['Січень','Лютий','Березень','Квітень','Травень','Червень', + 'Липень','Серпень','Вересень','Жовтень','Листопад','Грудень'], + monthNamesShort: ['Січ','Лют','Бер','Кві','Тра','Чер', + 'Лип','Сер','Вер','Жов','Лис','Гру'], + dayNames: ['неділя','понеділок','вівторок','середа','четвер','п’ятниця','субота'], + dayNamesShort: ['нед','пнд','вів','срд','чтв','птн','сбт'], + dayNamesMin: ['Нд','Пн','Вт','Ср','Чт','Пт','Сб'], + weekHeader: 'Тиж', + dateFormat: 'dd/mm/yy', + firstDay: 1, + isRTL: false, + showMonthAfterYear: false, + yearSuffix: ''}; + $.datepicker.setDefaults($.datepicker.regional['uk']); +}); \ No newline at end of file diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/ui/i18n/jquery.ui.datepicker-vi.js b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/ui/i18n/jquery.ui.datepicker-vi.js new file mode 100755 index 000000000..b49e7eb13 --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/ui/i18n/jquery.ui.datepicker-vi.js @@ -0,0 +1,23 @@ +/* Vietnamese initialisation for the jQuery UI date picker plugin. */ +/* Translated by Le Thanh Huy (lthanhhuy@cit.ctu.edu.vn). */ +jQuery(function($){ + $.datepicker.regional['vi'] = { + closeText: 'Đóng', + prevText: '<Trước', + nextText: 'Tiếp>', + currentText: 'Hôm nay', + monthNames: ['Tháng Một', 'Tháng Hai', 'Tháng Ba', 'Tháng Tư', 'Tháng Năm', 'Tháng Sáu', + 'Tháng Bảy', 'Tháng Tám', 'Tháng Chín', 'Tháng Mười', 'Tháng Mười Một', 'Tháng Mười Hai'], + monthNamesShort: ['Tháng 1', 'Tháng 2', 'Tháng 3', 'Tháng 4', 'Tháng 5', 'Tháng 6', + 'Tháng 7', 'Tháng 8', 'Tháng 9', 'Tháng 10', 'Tháng 11', 'Tháng 12'], + dayNames: ['Chủ Nhật', 'Thứ Hai', 'Thứ Ba', 'Thứ Tư', 'Thứ Năm', 'Thứ Sáu', 'Thứ Bảy'], + dayNamesShort: ['CN', 'T2', 'T3', 'T4', 'T5', 'T6', 'T7'], + dayNamesMin: ['CN', 'T2', 'T3', 'T4', 'T5', 'T6', 'T7'], + weekHeader: 'Tu', + dateFormat: 'dd/mm/yy', + firstDay: 0, + isRTL: false, + showMonthAfterYear: false, + yearSuffix: ''}; + $.datepicker.setDefaults($.datepicker.regional['vi']); +}); diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/ui/i18n/jquery.ui.datepicker-zh-CN.js b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/ui/i18n/jquery.ui.datepicker-zh-CN.js new file mode 100755 index 000000000..d337e4a99 --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/ui/i18n/jquery.ui.datepicker-zh-CN.js @@ -0,0 +1,23 @@ +/* Chinese initialisation for the jQuery UI date picker plugin. */ +/* Written by Cloudream (cloudream@gmail.com). */ +jQuery(function($){ + $.datepicker.regional['zh-CN'] = { + closeText: '关闭', + prevText: '<上月', + nextText: '下月>', + currentText: '今天', + monthNames: ['一月','二月','三月','四月','五月','六月', + '七月','八月','九月','十月','十一月','十二月'], + monthNamesShort: ['一月','二月','三月','四月','五月','六月', + '七月','八月','九月','十月','十一月','十二月'], + dayNames: ['星期日','星期一','星期二','星期三','星期四','星期五','星期六'], + dayNamesShort: ['周日','周一','周二','周三','周四','周五','周六'], + dayNamesMin: ['日','一','二','三','四','五','六'], + weekHeader: '周', + dateFormat: 'yy-mm-dd', + firstDay: 1, + isRTL: false, + showMonthAfterYear: true, + yearSuffix: '年'}; + $.datepicker.setDefaults($.datepicker.regional['zh-CN']); +}); diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/ui/i18n/jquery.ui.datepicker-zh-HK.js b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/ui/i18n/jquery.ui.datepicker-zh-HK.js new file mode 100755 index 000000000..ef6f4e715 --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/ui/i18n/jquery.ui.datepicker-zh-HK.js @@ -0,0 +1,23 @@ +/* Chinese initialisation for the jQuery UI date picker plugin. */ +/* Written by SCCY (samuelcychan@gmail.com). */ +jQuery(function($){ + $.datepicker.regional['zh-HK'] = { + closeText: '關閉', + prevText: '<上月', + nextText: '下月>', + currentText: '今天', + monthNames: ['一月','二月','三月','四月','五月','六月', + '七月','八月','九月','十月','十一月','十二月'], + monthNamesShort: ['一月','二月','三月','四月','五月','六月', + '七月','八月','九月','十月','十一月','十二月'], + dayNames: ['星期日','星期一','星期二','星期三','星期四','星期五','星期六'], + dayNamesShort: ['周日','周一','周二','周三','周四','周五','周六'], + dayNamesMin: ['日','一','二','三','四','五','六'], + weekHeader: '周', + dateFormat: 'dd-mm-yy', + firstDay: 0, + isRTL: false, + showMonthAfterYear: true, + yearSuffix: '年'}; + $.datepicker.setDefaults($.datepicker.regional['zh-HK']); +}); diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/ui/i18n/jquery.ui.datepicker-zh-TW.js b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/ui/i18n/jquery.ui.datepicker-zh-TW.js new file mode 100755 index 000000000..b9105ea50 --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/ui/i18n/jquery.ui.datepicker-zh-TW.js @@ -0,0 +1,23 @@ +/* Chinese initialisation for the jQuery UI date picker plugin. */ +/* Written by Ressol (ressol@gmail.com). */ +jQuery(function($){ + $.datepicker.regional['zh-TW'] = { + closeText: '關閉', + prevText: '<上月', + nextText: '下月>', + currentText: '今天', + monthNames: ['一月','二月','三月','四月','五月','六月', + '七月','八月','九月','十月','十一月','十二月'], + monthNamesShort: ['一月','二月','三月','四月','五月','六月', + '七月','八月','九月','十月','十一月','十二月'], + dayNames: ['星期日','星期一','星期二','星期三','星期四','星期五','星期六'], + dayNamesShort: ['周日','周一','周二','周三','周四','周五','周六'], + dayNamesMin: ['日','一','二','三','四','五','六'], + weekHeader: '周', + dateFormat: 'yy/mm/dd', + firstDay: 1, + isRTL: false, + showMonthAfterYear: true, + yearSuffix: '年'}; + $.datepicker.setDefaults($.datepicker.regional['zh-TW']); +}); diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/ui/jquery-ui.custom.js b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/ui/jquery-ui.custom.js new file mode 100755 index 000000000..dbaa85e86 --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/ui/jquery-ui.custom.js @@ -0,0 +1,14709 @@ +/*! jQuery UI - v1.9.0 - 2012-10-13 +* http://jqueryui.com +* Includes: jquery.ui.core.js, jquery.ui.widget.js, jquery.ui.mouse.js, jquery.ui.position.js, jquery.ui.draggable.js, jquery.ui.droppable.js, jquery.ui.resizable.js, jquery.ui.selectable.js, jquery.ui.sortable.js, jquery.ui.accordion.js, jquery.ui.autocomplete.js, jquery.ui.button.js, jquery.ui.datepicker.js, jquery.ui.dialog.js, jquery.ui.menu.js, jquery.ui.progressbar.js, jquery.ui.slider.js, jquery.ui.spinner.js, jquery.ui.tabs.js, jquery.ui.tooltip.js, jquery.ui.effect.js, jquery.ui.effect-blind.js, jquery.ui.effect-bounce.js, jquery.ui.effect-clip.js, jquery.ui.effect-drop.js, jquery.ui.effect-explode.js, jquery.ui.effect-fade.js, jquery.ui.effect-fold.js, jquery.ui.effect-highlight.js, jquery.ui.effect-pulsate.js, jquery.ui.effect-scale.js, jquery.ui.effect-shake.js, jquery.ui.effect-slide.js, jquery.ui.effect-transfer.js +* Copyright (c) 2012 jQuery Foundation and other contributors Licensed MIT */ + +(function( $, undefined ) { + +var uuid = 0, + runiqueId = /^ui-id-\d+$/; + +// prevent duplicate loading +// this is only a problem because we proxy existing functions +// and we don't want to double proxy them +$.ui = $.ui || {}; +if ( $.ui.version ) { + return; +} + +$.extend( $.ui, { + version: "1.9.0", + + keyCode: { + BACKSPACE: 8, + COMMA: 188, + DELETE: 46, + DOWN: 40, + END: 35, + ENTER: 13, + ESCAPE: 27, + HOME: 36, + LEFT: 37, + NUMPAD_ADD: 107, + NUMPAD_DECIMAL: 110, + NUMPAD_DIVIDE: 111, + NUMPAD_ENTER: 108, + NUMPAD_MULTIPLY: 106, + NUMPAD_SUBTRACT: 109, + PAGE_DOWN: 34, + PAGE_UP: 33, + PERIOD: 190, + RIGHT: 39, + SPACE: 32, + TAB: 9, + UP: 38 + } +}); + +// plugins +$.fn.extend({ + _focus: $.fn.focus, + focus: function( delay, fn ) { + return typeof delay === "number" ? + this.each(function() { + var elem = this; + setTimeout(function() { + $( elem ).focus(); + if ( fn ) { + fn.call( elem ); + } + }, delay ); + }) : + this._focus.apply( this, arguments ); + }, + + scrollParent: function() { + var scrollParent; + if (($.browser.msie && (/(static|relative)/).test(this.css('position'))) || (/absolute/).test(this.css('position'))) { + scrollParent = this.parents().filter(function() { + return (/(relative|absolute|fixed)/).test($.css(this,'position')) && (/(auto|scroll)/).test($.css(this,'overflow')+$.css(this,'overflow-y')+$.css(this,'overflow-x')); + }).eq(0); + } else { + scrollParent = this.parents().filter(function() { + return (/(auto|scroll)/).test($.css(this,'overflow')+$.css(this,'overflow-y')+$.css(this,'overflow-x')); + }).eq(0); + } + + return (/fixed/).test(this.css('position')) || !scrollParent.length ? $(document) : scrollParent; + }, + + zIndex: function( zIndex ) { + if ( zIndex !== undefined ) { + return this.css( "zIndex", zIndex ); + } + + if ( this.length ) { + var elem = $( this[ 0 ] ), position, value; + while ( elem.length && elem[ 0 ] !== document ) { + // Ignore z-index if position is set to a value where z-index is ignored by the browser + // This makes behavior of this function consistent across browsers + // WebKit always returns auto if the element is positioned + position = elem.css( "position" ); + if ( position === "absolute" || position === "relative" || position === "fixed" ) { + // IE returns 0 when zIndex is not specified + // other browsers return a string + // we ignore the case of nested elements with an explicit value of 0 + //
      + value = parseInt( elem.css( "zIndex" ), 10 ); + if ( !isNaN( value ) && value !== 0 ) { + return value; + } + } + elem = elem.parent(); + } + } + + return 0; + }, + + uniqueId: function() { + return this.each(function() { + if ( !this.id ) { + this.id = "ui-id-" + (++uuid); + } + }); + }, + + removeUniqueId: function() { + return this.each(function() { + if ( runiqueId.test( this.id ) ) { + $( this ).removeAttr( "id" ); + } + }); + } +}); + +// support: jQuery <1.8 +if ( !$( "" ).outerWidth( 1 ).jquery ) { + $.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( $.css( elem, "padding" + this ) ) || 0; + if ( border ) { + size -= parseFloat( $.css( elem, "border" + this + "Width" ) ) || 0; + } + if ( margin ) { + size -= parseFloat( $.css( elem, "margin" + this ) ) || 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 map, mapName, img, + nodeName = element.nodeName.toLowerCase(); + if ( "area" === nodeName ) { + map = element.parentNode; + mapName = map.name; + 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 $.css( this, "visibility" ) === "hidden" || + $.expr.filters.hidden( this ); + }).length; +} + +$.extend( $.expr[ ":" ], { + data: $.expr.createPseudo ? + $.expr.createPseudo(function( dataName ) { + return function( elem ) { + return !!$.data( elem, dataName ); + }; + }) : + // support: jQuery <1.8 + 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" ) ); + + // access offsetHeight before setting the style to prevent a layout bug + // in IE 9 which causes the element to continue to take up space even + // after it is removed from the DOM (#8026) + div.offsetHeight; + + $.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 + +$.fn.extend({ + disableSelection: function() { + return this.bind( ( $.support.selectstart ? "selectstart" : "mousedown" ) + + ".ui-disableSelection", function( event ) { + event.preventDefault(); + }); + }, + + enableSelection: function() { + return this.unbind( ".ui-disableSelection" ); + } +}); + +$.extend( $.ui, { + // $.ui.plugin is deprecated. Use the proxy pattern instead. + plugin: { + add: function( module, option, set ) { + var i, + proto = $.ui[ module ].prototype; + for ( i in set ) { + proto.plugins[ i ] = proto.plugins[ i ] || []; + proto.plugins[ i ].push( [ option, set[ i ] ] ); + } + }, + call: function( instance, name, args ) { + var i, + set = instance.plugins[ name ]; + if ( !set || !instance.element[ 0 ].parentNode || instance.element[ 0 ].parentNode.nodeType === 11 ) { + return; + } + + for ( i = 0; i < set.length; i++ ) { + if ( instance.options[ set[ i ][ 0 ] ] ) { + set[ i ][ 1 ].apply( instance.element, args ); + } + } + } + }, + + contains: $.contains, + + // 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 ); +(function( $, undefined ) { + +var uuid = 0, + slice = Array.prototype.slice, + _cleanData = $.cleanData; +$.cleanData = function( elems ) { + for ( var i = 0, elem; (elem = elems[i]) != null; i++ ) { + try { + $( elem ).triggerHandler( "remove" ); + // http://bugs.jquery.com/ticket/8235 + } catch( e ) {} + } + _cleanData( elems ); +}; + +$.widget = function( name, base, prototype ) { + var fullName, existingConstructor, constructor, basePrototype, + namespace = name.split( "." )[ 0 ]; + + name = name.split( "." )[ 1 ]; + fullName = namespace + "-" + name; + + if ( !prototype ) { + prototype = base; + base = $.Widget; + } + + // create selector for plugin + $.expr[ ":" ][ fullName.toLowerCase() ] = function( elem ) { + return !!$.data( elem, fullName ); + }; + + $[ namespace ] = $[ namespace ] || {}; + existingConstructor = $[ namespace ][ name ]; + constructor = $[ namespace ][ name ] = function( options, element ) { + // allow instantiation without "new" keyword + if ( !this._createWidget ) { + return new constructor( options, element ); + } + + // allow instantiation without initializing for simple inheritance + // must use "new" keyword (the code above always passes args) + if ( arguments.length ) { + this._createWidget( options, element ); + } + }; + // extend with the existing constructor to carry over any static properties + $.extend( constructor, existingConstructor, { + version: prototype.version, + // copy the object used to create the prototype in case we need to + // redefine the widget later + _proto: $.extend( {}, prototype ), + // track widgets that inherit from this widget in case this widget is + // redefined after a widget inherits from it + _childConstructors: [] + }); + + 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 + basePrototype.options = $.widget.extend( {}, basePrototype.options ); + $.each( prototype, function( prop, value ) { + if ( $.isFunction( value ) ) { + prototype[ prop ] = (function() { + var _super = function() { + return base.prototype[ prop ].apply( this, arguments ); + }, + _superApply = function( args ) { + return base.prototype[ prop ].apply( this, args ); + }; + return function() { + var __super = this._super, + __superApply = this._superApply, + returnValue; + + this._super = _super; + this._superApply = _superApply; + + returnValue = value.apply( this, arguments ); + + this._super = __super; + this._superApply = __superApply; + + return returnValue; + }; + })(); + } + }); + constructor.prototype = $.widget.extend( basePrototype, { + // TODO: remove support for widgetEventPrefix + // always use the name + a colon as the prefix, e.g., draggable:start + // don't prefix for widgets that aren't DOM-based + widgetEventPrefix: name + }, prototype, { + constructor: constructor, + namespace: namespace, + widgetName: name, + // TODO remove widgetBaseClass, see #8155 + widgetBaseClass: fullName, + widgetFullName: fullName + }); + + // If this widget is being redefined then we need to find all widgets that + // are inheriting from it and redefine all of them so that they inherit from + // the new version of this widget. We're essentially trying to replace one + // level in the prototype chain. + if ( existingConstructor ) { + $.each( existingConstructor._childConstructors, function( i, child ) { + var childPrototype = child.prototype; + + // redefine the child widget using the same prototype that was + // originally used, but inherit from the new version of the base + $.widget( childPrototype.namespace + "." + childPrototype.widgetName, constructor, child._proto ); + }); + // remove the list of existing child constructors from the old constructor + // so the old child constructors can be garbage collected + delete existingConstructor._childConstructors; + } else { + base._childConstructors.push( constructor ); + } + + $.widget.bridge( name, constructor ); +}; + +$.widget.extend = function( target ) { + var input = slice.call( arguments, 1 ), + inputIndex = 0, + inputLength = input.length, + key, + value; + for ( ; inputIndex < inputLength; inputIndex++ ) { + for ( key in input[ inputIndex ] ) { + value = input[ inputIndex ][ key ]; + if (input[ inputIndex ].hasOwnProperty( key ) && value !== undefined ) { + target[ key ] = $.isPlainObject( value ) ? $.widget.extend( {}, target[ key ], value ) : value; + } + } + } + return target; +}; + +$.widget.bridge = function( name, object ) { + var fullName = object.prototype.widgetFullName; + $.fn[ name ] = function( options ) { + var isMethodCall = typeof options === "string", + args = slice.call( arguments, 1 ), + returnValue = this; + + // allow multiple hashes to be passed on init + options = !isMethodCall && args.length ? + $.widget.extend.apply( null, [ options ].concat(args) ) : + options; + + if ( isMethodCall ) { + this.each(function() { + var methodValue, + instance = $.data( this, fullName ); + if ( !instance ) { + return $.error( "cannot call methods on " + name + " prior to initialization; " + + "attempted to call method '" + options + "'" ); + } + if ( !$.isFunction( instance[options] ) || options.charAt( 0 ) === "_" ) { + return $.error( "no such method '" + options + "' for " + name + " widget instance" ); + } + methodValue = instance[ options ].apply( instance, args ); + if ( methodValue !== instance && methodValue !== undefined ) { + returnValue = methodValue && methodValue.jquery ? + returnValue.pushStack( methodValue.get() ) : + methodValue; + return false; + } + }); + } else { + this.each(function() { + var instance = $.data( this, fullName ); + if ( instance ) { + instance.option( options || {} )._init(); + } else { + new object( options, this ); + } + }); + } + + return returnValue; + }; +}; + +$.Widget = function( options, element ) {}; +$.Widget._childConstructors = []; + +$.Widget.prototype = { + widgetName: "widget", + widgetEventPrefix: "", + defaultElement: "
      ", + options: { + disabled: false, + + // callbacks + create: null + }, + _createWidget: function( options, element ) { + element = $( element || this.defaultElement || this )[ 0 ]; + this.element = $( element ); + this.uuid = uuid++; + this.eventNamespace = "." + this.widgetName + this.uuid; + this.options = $.widget.extend( {}, + this.options, + this._getCreateOptions(), + options ); + + this.bindings = $(); + this.hoverable = $(); + this.focusable = $(); + + if ( element !== this ) { + // 1.9 BC for #7810 + // TODO remove dual storage + $.data( element, this.widgetName, this ); + $.data( element, this.widgetFullName, this ); + this._on({ remove: "destroy" }); + this.document = $( element.style ? + // element within the document + element.ownerDocument : + // element is window or document + element.document || element ); + this.window = $( this.document[0].defaultView || this.document[0].parentWindow ); + } + + this._create(); + this._trigger( "create", null, this._getCreateEventData() ); + this._init(); + }, + _getCreateOptions: $.noop, + _getCreateEventData: $.noop, + _create: $.noop, + _init: $.noop, + + destroy: function() { + this._destroy(); + // we can probably remove the unbind calls in 2.0 + // all event bindings should go through this._on() + this.element + .unbind( this.eventNamespace ) + // 1.9 BC for #7810 + // TODO remove dual storage + .removeData( this.widgetName ) + .removeData( this.widgetFullName ) + // support: jquery <1.6.3 + // http://bugs.jquery.com/ticket/9413 + .removeData( $.camelCase( this.widgetFullName ) ); + this.widget() + .unbind( this.eventNamespace ) + .removeAttr( "aria-disabled" ) + .removeClass( + this.widgetFullName + "-disabled " + + "ui-state-disabled" ); + + // clean up events and states + this.bindings.unbind( this.eventNamespace ); + this.hoverable.removeClass( "ui-state-hover" ); + this.focusable.removeClass( "ui-state-focus" ); + }, + _destroy: $.noop, + + widget: function() { + return this.element; + }, + + option: function( key, value ) { + var options = key, + parts, + curOption, + i; + + if ( arguments.length === 0 ) { + // don't return a reference to the internal hash + return $.widget.extend( {}, this.options ); + } + + if ( typeof key === "string" ) { + // handle nested keys, e.g., "foo.bar" => { foo: { bar: ___ } } + options = {}; + parts = key.split( "." ); + key = parts.shift(); + if ( parts.length ) { + curOption = options[ key ] = $.widget.extend( {}, this.options[ key ] ); + for ( i = 0; i < parts.length - 1; i++ ) { + curOption[ parts[ i ] ] = curOption[ parts[ i ] ] || {}; + curOption = curOption[ parts[ i ] ]; + } + key = parts.pop(); + if ( value === undefined ) { + return curOption[ key ] === undefined ? null : curOption[ key ]; + } + curOption[ key ] = value; + } else { + if ( value === undefined ) { + return this.options[ key ] === undefined ? null : this.options[ key ]; + } + options[ key ] = value; + } + } + + this._setOptions( options ); + + return this; + }, + _setOptions: function( options ) { + var key; + + for ( key in options ) { + this._setOption( key, options[ key ] ); + } + + return this; + }, + _setOption: function( key, value ) { + this.options[ key ] = value; + + if ( key === "disabled" ) { + this.widget() + .toggleClass( this.widgetFullName + "-disabled ui-state-disabled", !!value ) + .attr( "aria-disabled", value ); + this.hoverable.removeClass( "ui-state-hover" ); + this.focusable.removeClass( "ui-state-focus" ); + } + + return this; + }, + + enable: function() { + return this._setOption( "disabled", false ); + }, + disable: function() { + return this._setOption( "disabled", true ); + }, + + _on: function( element, handlers ) { + // no element argument, shuffle and use this.element + if ( !handlers ) { + handlers = element; + element = this.element; + } else { + // accept selectors, DOM elements + element = $( element ); + this.bindings = this.bindings.add( element ); + } + + var instance = this; + $.each( handlers, function( event, handler ) { + function handlerProxy() { + // allow widgets to customize the disabled handling + // - disabled as an array instead of boolean + // - disabled class as method for disabling individual parts + if ( instance.options.disabled === true || + $( this ).hasClass( "ui-state-disabled" ) ) { + return; + } + return ( typeof handler === "string" ? instance[ handler ] : handler ) + .apply( instance, arguments ); + } + + // copy the guid so direct unbinding works + if ( typeof handler !== "string" ) { + handlerProxy.guid = handler.guid = + handler.guid || handlerProxy.guid || $.guid++; + } + + var match = event.match( /^(\w+)\s*(.*)$/ ), + eventName = match[1] + instance.eventNamespace, + selector = match[2]; + if ( selector ) { + instance.widget().delegate( selector, eventName, handlerProxy ); + } else { + element.bind( eventName, handlerProxy ); + } + }); + }, + + _off: function( element, eventName ) { + eventName = (eventName || "").split( " " ).join( this.eventNamespace + " " ) + this.eventNamespace; + element.unbind( eventName ).undelegate( eventName ); + }, + + _delay: function( handler, delay ) { + function handlerProxy() { + return ( typeof handler === "string" ? instance[ handler ] : handler ) + .apply( instance, arguments ); + } + var instance = this; + return setTimeout( handlerProxy, delay || 0 ); + }, + + _hoverable: function( element ) { + this.hoverable = this.hoverable.add( element ); + this._on( element, { + mouseenter: function( event ) { + $( event.currentTarget ).addClass( "ui-state-hover" ); + }, + mouseleave: function( event ) { + $( event.currentTarget ).removeClass( "ui-state-hover" ); + } + }); + }, + + _focusable: function( element ) { + this.focusable = this.focusable.add( element ); + this._on( element, { + focusin: function( event ) { + $( event.currentTarget ).addClass( "ui-state-focus" ); + }, + focusout: function( event ) { + $( event.currentTarget ).removeClass( "ui-state-focus" ); + } + }); + }, + + _trigger: function( type, event, data ) { + var prop, orig, + callback = this.options[ type ]; + + data = data || {}; + event = $.Event( event ); + event.type = ( type === this.widgetEventPrefix ? + type : + this.widgetEventPrefix + type ).toLowerCase(); + // the original event may come from any element + // so we need to reset the target on the new event + event.target = this.element[ 0 ]; + + // copy original event properties over to the new event + orig = event.originalEvent; + if ( orig ) { + for ( prop in orig ) { + if ( !( prop in event ) ) { + event[ prop ] = orig[ prop ]; + } + } + } + + this.element.trigger( event, data ); + return !( $.isFunction( callback ) && + callback.apply( this.element[0], [ event ].concat( data ) ) === false || + event.isDefaultPrevented() ); + } +}; + +$.each( { show: "fadeIn", hide: "fadeOut" }, function( method, defaultEffect ) { + $.Widget.prototype[ "_" + method ] = function( element, options, callback ) { + if ( typeof options === "string" ) { + options = { effect: options }; + } + var hasOptions, + effectName = !options ? + method : + options === true || typeof options === "number" ? + defaultEffect : + options.effect || defaultEffect; + options = options || {}; + if ( typeof options === "number" ) { + options = { duration: options }; + } + hasOptions = !$.isEmptyObject( options ); + options.complete = callback; + if ( options.delay ) { + element.delay( options.delay ); + } + if ( hasOptions && $.effects && ( $.effects.effect[ effectName ] || $.uiBackCompat !== false && $.effects[ effectName ] ) ) { + element[ method ]( options ); + } else if ( effectName !== method && element[ effectName ] ) { + element[ effectName ]( options.duration, options.easing, callback ); + } else { + element.queue(function( next ) { + $( this )[ method ](); + if ( callback ) { + callback.call( element[ 0 ] ); + } + next(); + }); + } + }; +}); + +// DEPRECATED +if ( $.uiBackCompat !== false ) { + $.Widget.prototype._getCreateOptions = function() { + return $.metadata && $.metadata.get( this.element[0] )[ this.widgetName ]; + }; +} + +})( jQuery ); +(function( $, undefined ) { + +var mouseHandled = false; +$( document ).mouseup( function( e ) { + mouseHandled = false; +}); + +$.widget("ui.mouse", { + version: "1.9.0", + options: { + cancel: 'input,textarea,button,select,option', + distance: 1, + delay: 0 + }, + _mouseInit: function() { + var that = this; + + this.element + .bind('mousedown.'+this.widgetName, function(event) { + return that._mouseDown(event); + }) + .bind('click.'+this.widgetName, function(event) { + if (true === $.data(event.target, that.widgetName + '.preventClickEvent')) { + $.removeData(event.target, that.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); + if ( this._mouseMoveDelegate ) { + $(document) + .unbind('mousemove.'+this.widgetName, this._mouseMoveDelegate) + .unbind('mouseup.'+this.widgetName, this._mouseUpDelegate); + } + }, + + _mouseDown: function(event) { + // don't let more than one widget handle mouseStart + if( mouseHandled ) { return; } + + // we may have missed mouseup (out of window) + (this._mouseStarted && this._mouseUp(event)); + + this._mouseDownEvent = event; + + var that = this, + btnIsLeft = (event.which === 1), + // event.target.nodeName works around a bug in IE 8 with + // disabled inputs (#7620) + elIsCancel = (typeof this.options.cancel === "string" && event.target.nodeName ? $(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() { + that.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 that._mouseMove(event); + }; + this._mouseUpDelegate = function(event) { + return that._mouseUp(event); + }; + $(document) + .bind('mousemove.'+this.widgetName, this._mouseMoveDelegate) + .bind('mouseup.'+this.widgetName, this._mouseUpDelegate); + + event.preventDefault(); + + 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); +(function( $, undefined ) { + +$.ui = $.ui || {}; + +var cachedScrollbarWidth, + max = Math.max, + abs = Math.abs, + round = Math.round, + rhorizontal = /left|center|right/, + rvertical = /top|center|bottom/, + roffset = /[\+\-]\d+%?/, + rposition = /^\w+/, + rpercent = /%$/, + _position = $.fn.position; + +function getOffsets( offsets, width, height ) { + return [ + parseInt( offsets[ 0 ], 10 ) * ( rpercent.test( offsets[ 0 ] ) ? width / 100 : 1 ), + parseInt( offsets[ 1 ], 10 ) * ( rpercent.test( offsets[ 1 ] ) ? height / 100 : 1 ) + ]; +} +function parseCss( element, property ) { + return parseInt( $.css( element, property ), 10 ) || 0; +} + +$.position = { + scrollbarWidth: function() { + if ( cachedScrollbarWidth !== undefined ) { + return cachedScrollbarWidth; + } + var w1, w2, + div = $( "
      " ), + innerDiv = div.children()[0]; + + $( "body" ).append( div ); + w1 = innerDiv.offsetWidth; + div.css( "overflow", "scroll" ); + + w2 = innerDiv.offsetWidth; + + if ( w1 === w2 ) { + w2 = div[0].clientWidth; + } + + div.remove(); + + return (cachedScrollbarWidth = w1 - w2); + }, + getScrollInfo: function( within ) { + var overflowX = within.isWindow ? "" : within.element.css( "overflow-x" ), + overflowY = within.isWindow ? "" : within.element.css( "overflow-y" ), + hasOverflowX = overflowX === "scroll" || + ( overflowX === "auto" && within.width < within.element[0].scrollWidth ), + hasOverflowY = overflowY === "scroll" || + ( overflowY === "auto" && within.height < within.element[0].scrollHeight ); + return { + width: hasOverflowX ? $.position.scrollbarWidth() : 0, + height: hasOverflowY ? $.position.scrollbarWidth() : 0 + }; + }, + getWithinInfo: function( element ) { + var withinElement = $( element || window ), + isWindow = $.isWindow( withinElement[0] ); + return { + element: withinElement, + isWindow: isWindow, + offset: withinElement.offset() || { left: 0, top: 0 }, + scrollLeft: withinElement.scrollLeft(), + scrollTop: withinElement.scrollTop(), + width: isWindow ? withinElement.width() : withinElement.outerWidth(), + height: isWindow ? withinElement.height() : withinElement.outerHeight() + }; + } +}; + +$.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 atOffset, targetWidth, targetHeight, targetOffset, basePosition, + target = $( options.of ), + within = $.position.getWithinInfo( options.within ), + scrollInfo = $.position.getScrollInfo( within ), + targetElem = target[0], + collision = ( options.collision || "flip" ).split( " " ), + offsets = {}; + + if ( targetElem.nodeType === 9 ) { + targetWidth = target.width(); + targetHeight = target.height(); + targetOffset = { top: 0, left: 0 }; + } else if ( $.isWindow( targetElem ) ) { + targetWidth = target.width(); + targetHeight = target.height(); + targetOffset = { top: target.scrollTop(), left: target.scrollLeft() }; + } else if ( targetElem.preventDefault ) { + // force left top to allow flipping + options.at = "left top"; + targetWidth = targetHeight = 0; + targetOffset = { top: targetElem.pageY, left: targetElem.pageX }; + } else { + targetWidth = target.outerWidth(); + targetHeight = target.outerHeight(); + targetOffset = target.offset(); + } + // clone to reuse original targetOffset later + basePosition = $.extend( {}, targetOffset ); + + // force my and at to have valid horizontal and vertical positions + // if a value is missing or invalid, it will be converted to center + $.each( [ "my", "at" ], function() { + var pos = ( options[ this ] || "" ).split( " " ), + horizontalOffset, + verticalOffset; + + if ( pos.length === 1) { + pos = rhorizontal.test( pos[ 0 ] ) ? + pos.concat( [ "center" ] ) : + rvertical.test( pos[ 0 ] ) ? + [ "center" ].concat( pos ) : + [ "center", "center" ]; + } + pos[ 0 ] = rhorizontal.test( pos[ 0 ] ) ? pos[ 0 ] : "center"; + pos[ 1 ] = rvertical.test( pos[ 1 ] ) ? pos[ 1 ] : "center"; + + // calculate offsets + horizontalOffset = roffset.exec( pos[ 0 ] ); + verticalOffset = roffset.exec( pos[ 1 ] ); + offsets[ this ] = [ + horizontalOffset ? horizontalOffset[ 0 ] : 0, + verticalOffset ? verticalOffset[ 0 ] : 0 + ]; + + // reduce to just the positions without the offsets + options[ this ] = [ + rposition.exec( pos[ 0 ] )[ 0 ], + rposition.exec( pos[ 1 ] )[ 0 ] + ]; + }); + + // normalize collision option + if ( collision.length === 1 ) { + collision[ 1 ] = collision[ 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; + } + + atOffset = getOffsets( offsets.at, targetWidth, targetHeight ); + basePosition.left += atOffset[ 0 ]; + basePosition.top += atOffset[ 1 ]; + + return this.each(function() { + var collisionPosition, using, + elem = $( this ), + elemWidth = elem.outerWidth(), + elemHeight = elem.outerHeight(), + marginLeft = parseCss( this, "marginLeft" ), + marginTop = parseCss( this, "marginTop" ), + collisionWidth = elemWidth + marginLeft + parseCss( this, "marginRight" ) + scrollInfo.width, + collisionHeight = elemHeight + marginTop + parseCss( this, "marginBottom" ) + scrollInfo.height, + position = $.extend( {}, basePosition ), + myOffset = getOffsets( offsets.my, elem.outerWidth(), elem.outerHeight() ); + + 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; + } + + position.left += myOffset[ 0 ]; + position.top += myOffset[ 1 ]; + + // if the browser doesn't support fractions, then round for consistent results + if ( !$.support.offsetFractions ) { + position.left = round( position.left ); + position.top = round( position.top ); + } + + collisionPosition = { + marginLeft: marginLeft, + marginTop: 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: [ atOffset[ 0 ] + myOffset[ 0 ], atOffset [ 1 ] + myOffset[ 1 ] ], + my: options.my, + at: options.at, + within: within, + elem : elem + }); + } + }); + + if ( $.fn.bgiframe ) { + elem.bgiframe(); + } + + if ( options.using ) { + // adds feedback as second argument to using callback, if present + using = function( props ) { + var left = targetOffset.left - position.left, + right = left + targetWidth - elemWidth, + top = targetOffset.top - position.top, + bottom = top + targetHeight - elemHeight, + feedback = { + target: { + element: target, + left: targetOffset.left, + top: targetOffset.top, + width: targetWidth, + height: targetHeight + }, + element: { + element: elem, + left: position.left, + top: position.top, + width: elemWidth, + height: elemHeight + }, + horizontal: right < 0 ? "left" : left > 0 ? "right" : "center", + vertical: bottom < 0 ? "top" : top > 0 ? "bottom" : "middle" + }; + if ( targetWidth < elemWidth && abs( left + right ) < targetWidth ) { + feedback.horizontal = "center"; + } + if ( targetHeight < elemHeight && abs( top + bottom ) < targetHeight ) { + feedback.vertical = "middle"; + } + if ( max( abs( left ), abs( right ) ) > max( abs( top ), abs( bottom ) ) ) { + feedback.important = "horizontal"; + } else { + feedback.important = "vertical"; + } + options.using.call( this, props, feedback ); + }; + } + + elem.offset( $.extend( position, { using: using } ) ); + }); +}; + +$.ui.position = { + fit: { + left: function( position, data ) { + var within = data.within, + withinOffset = within.isWindow ? within.scrollLeft : within.offset.left, + outerWidth = within.width, + collisionPosLeft = position.left - data.collisionPosition.marginLeft, + overLeft = withinOffset - collisionPosLeft, + overRight = collisionPosLeft + data.collisionWidth - outerWidth - withinOffset, + newOverRight; + + // element is wider than within + if ( data.collisionWidth > outerWidth ) { + // element is initially over the left side of within + if ( overLeft > 0 && overRight <= 0 ) { + newOverRight = position.left + overLeft + data.collisionWidth - outerWidth - withinOffset; + position.left += overLeft - newOverRight; + // element is initially over right side of within + } else if ( overRight > 0 && overLeft <= 0 ) { + position.left = withinOffset; + // element is initially over both left and right sides of within + } else { + if ( overLeft > overRight ) { + position.left = withinOffset + outerWidth - data.collisionWidth; + } else { + position.left = withinOffset; + } + } + // too far left -> align with left edge + } else if ( overLeft > 0 ) { + position.left += overLeft; + // too far right -> align with right edge + } else if ( overRight > 0 ) { + position.left -= overRight; + // adjust based on position and margin + } else { + position.left = max( position.left - collisionPosLeft, position.left ); + } + }, + top: function( position, data ) { + var within = data.within, + withinOffset = within.isWindow ? within.scrollTop : within.offset.top, + outerHeight = data.within.height, + collisionPosTop = position.top - data.collisionPosition.marginTop, + overTop = withinOffset - collisionPosTop, + overBottom = collisionPosTop + data.collisionHeight - outerHeight - withinOffset, + newOverBottom; + + // element is taller than within + if ( data.collisionHeight > outerHeight ) { + // element is initially over the top of within + if ( overTop > 0 && overBottom <= 0 ) { + newOverBottom = position.top + overTop + data.collisionHeight - outerHeight - withinOffset; + position.top += overTop - newOverBottom; + // element is initially over bottom of within + } else if ( overBottom > 0 && overTop <= 0 ) { + position.top = withinOffset; + // element is initially over both top and bottom of within + } else { + if ( overTop > overBottom ) { + position.top = withinOffset + outerHeight - data.collisionHeight; + } else { + position.top = withinOffset; + } + } + // too far up -> align with top + } else if ( overTop > 0 ) { + position.top += overTop; + // too far down -> align with bottom edge + } else if ( overBottom > 0 ) { + position.top -= overBottom; + // adjust based on position and margin + } else { + position.top = max( position.top - collisionPosTop, position.top ); + } + } + }, + flip: { + left: function( position, data ) { + var within = data.within, + withinOffset = within.offset.left + within.scrollLeft, + outerWidth = within.width, + offsetLeft = within.isWindow ? within.scrollLeft : within.offset.left, + collisionPosLeft = position.left - data.collisionPosition.marginLeft, + overLeft = collisionPosLeft - offsetLeft, + overRight = collisionPosLeft + data.collisionWidth - outerWidth - offsetLeft, + myOffset = data.my[ 0 ] === "left" ? + -data.elemWidth : + data.my[ 0 ] === "right" ? + data.elemWidth : + 0, + atOffset = data.at[ 0 ] === "left" ? + data.targetWidth : + data.at[ 0 ] === "right" ? + -data.targetWidth : + 0, + offset = -2 * data.offset[ 0 ], + newOverRight, + newOverLeft; + + if ( overLeft < 0 ) { + newOverRight = position.left + myOffset + atOffset + offset + data.collisionWidth - outerWidth - withinOffset; + if ( newOverRight < 0 || newOverRight < abs( overLeft ) ) { + position.left += myOffset + atOffset + offset; + } + } + else if ( overRight > 0 ) { + newOverLeft = position.left - data.collisionPosition.marginLeft + myOffset + atOffset + offset - offsetLeft; + if ( newOverLeft > 0 || abs( newOverLeft ) < overRight ) { + position.left += myOffset + atOffset + offset; + } + } + }, + top: function( position, data ) { + var within = data.within, + withinOffset = within.offset.top + within.scrollTop, + outerHeight = within.height, + offsetTop = within.isWindow ? within.scrollTop : within.offset.top, + collisionPosTop = position.top - data.collisionPosition.marginTop, + overTop = collisionPosTop - offsetTop, + overBottom = collisionPosTop + data.collisionHeight - outerHeight - offsetTop, + top = data.my[ 1 ] === "top", + myOffset = top ? + -data.elemHeight : + data.my[ 1 ] === "bottom" ? + data.elemHeight : + 0, + atOffset = data.at[ 1 ] === "top" ? + data.targetHeight : + data.at[ 1 ] === "bottom" ? + -data.targetHeight : + 0, + offset = -2 * data.offset[ 1 ], + newOverTop, + newOverBottom; + if ( overTop < 0 ) { + newOverBottom = position.top + myOffset + atOffset + offset + data.collisionHeight - outerHeight - withinOffset; + if ( ( position.top + myOffset + atOffset + offset) > overTop && ( newOverBottom < 0 || newOverBottom < abs( overTop ) ) ) { + position.top += myOffset + atOffset + offset; + } + } + else if ( overBottom > 0 ) { + newOverTop = position.top - data.collisionPosition.marginTop + myOffset + atOffset + offset - offsetTop; + if ( ( position.top + myOffset + atOffset + offset) > overBottom && ( newOverTop > 0 || abs( newOverTop ) < overBottom ) ) { + position.top += myOffset + atOffset + offset; + } + } + } + }, + flipfit: { + left: function() { + $.ui.position.flip.left.apply( this, arguments ); + $.ui.position.fit.left.apply( this, arguments ); + }, + top: function() { + $.ui.position.flip.top.apply( this, arguments ); + $.ui.position.fit.top.apply( this, arguments ); + } + } +}; + +// fraction support test +(function () { + var testElement, testElementParent, testElementStyle, offsetLeft, i, + body = document.getElementsByTagName( "body" )[ 0 ], + div = document.createElement( "div" ); + + //Create a "fake body" for testing based on method used in jQuery.support + testElement = document.createElement( body ? "div" : "body" ); + testElementStyle = { + visibility: "hidden", + width: 0, + height: 0, + border: 0, + margin: 0, + background: "none" + }; + if ( body ) { + $.extend( testElementStyle, { + position: "absolute", + left: "-1000px", + top: "-1000px" + }); + } + for ( i in testElementStyle ) { + testElement.style[ i ] = testElementStyle[ i ]; + } + testElement.appendChild( div ); + testElementParent = body || document.documentElement; + testElementParent.insertBefore( testElement, testElementParent.firstChild ); + + div.style.cssText = "position: absolute; left: 10.7432222px;"; + + offsetLeft = $( div ).offset().left; + $.support.offsetFractions = offsetLeft > 10 && offsetLeft < 11; + + testElement.innerHTML = ""; + testElementParent.removeChild( testElement ); +})(); + +// DEPRECATED +if ( $.uiBackCompat !== false ) { + // offset option + (function( $ ) { + var _position = $.fn.position; + $.fn.position = function( options ) { + if ( !options || !options.offset ) { + return _position.call( this, options ); + } + var offset = options.offset.split( " " ), + at = options.at.split( " " ); + if ( offset.length === 1 ) { + offset[ 1 ] = offset[ 0 ]; + } + if ( /^\d/.test( offset[ 0 ] ) ) { + offset[ 0 ] = "+" + offset[ 0 ]; + } + if ( /^\d/.test( offset[ 1 ] ) ) { + offset[ 1 ] = "+" + offset[ 1 ]; + } + if ( at.length === 1 ) { + if ( /left|center|right/.test( at[ 0 ] ) ) { + at[ 1 ] = "center"; + } else { + at[ 1 ] = at[ 0 ]; + at[ 0 ] = "center"; + } + } + return _position.call( this, $.extend( options, { + at: at[ 0 ] + offset[ 0 ] + " " + at[ 1 ] + offset[ 1 ], + offset: undefined + } ) ); + }; + }( jQuery ) ); +} + +}( jQuery ) ); +(function( $, undefined ) { + +$.widget("ui.draggable", $.ui.mouse, { + version: "1.9.0", + 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() { + this.element.removeClass( "ui-draggable ui-draggable-dragging ui-draggable-disabled" ); + this._mouseDestroy(); + }, + + _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); + + this.helper.addClass("ui-draggable-dragging"); + + //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._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 no longer in the DOM don't bother to continue (see #8269) + var element = this.element[0], elementInDom = false; + while ( element && (element = element.parentNode) ) { + if (element == document ) { + elementInDom = true; + } + } + if ( !elementInDom && 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 that = this; + $(this.helper).animate(this.originalPosition, parseInt(this.options.revertDuration, 10), function() { + if(that._trigger("stop", event) !== false) { + that._clear(); + } + }); + } else { + if(this._trigger("stop", event) !== false) { + this._clear(); + } + } + + return false; + }, + + _mouseUp: function(event) { + //Remove frame helpers + $("div.ui-draggable-iframeFix").each(function() { + this.parentNode.removeChild(this); + }); + + //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 && $.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 && $.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) + - ( ( 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) + - ( ( 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 && $.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) + + ( ( 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) + + ( ( 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 + }; + } + +}); + +$.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"), that = 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 = $(that).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); +(function( $, undefined ) { + +$.widget("ui.droppable", { + version: "1.9.0", + 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"); + }, + + _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 + }; + } + +}); + +$.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 = this._drop.call(this, event) || dropped; + + 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) { + // find droppable parents with same scope + var scope = this.options.scope; + var parent = this.element.parents(':data(droppable)').filter(function () { + return $.data(this, 'droppable').options.scope === scope; + }); + + 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); +(function( $, undefined ) { + +$.widget("ui.resizable", $.ui.mouse, { + version: "1.9.0", + 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 that = 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)) { + + //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 = $('
      '); + + // Apply zIndex to all handles - see #7960 + 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 (!that.resizing) { + if (this.className) + var axis = this.className.match(/ui-resizable-(se|sw|ne|nw|n|e|s|w)/i); + //Axis, default = se + that.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") + .mouseenter(function() { + if (o.disabled) return; + $(this).removeClass("ui-resizable-autohide"); + that._handles.show(); + }) + .mouseleave(function(){ + if (o.disabled) return; + if (!that.resizing) { + $(this).addClass("ui-resizable-autohide"); + that._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").removeData("ui-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 }); + } + + 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 = {}, + that = 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]); + + // 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, that = 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 : that.sizeDiff.height, + soffsetw = ista ? 0 : that.sizeDiff.width; + + var s = { width: (that.helper.width() - soffsetw), height: (that.helper.height() - soffseth) }, + left = (parseInt(that.element.css('left'), 10) + (that.position.left - that.originalPosition.left)) || null, + top = (parseInt(that.element.css('top'), 10) + (that.position.top - that.originalPosition.top)) || null; + + if (!o.animate) + this.element.css($.extend(s, { top: top, left: left })); + + that.helper.height(that.size.height); + that.helper.width(that.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; + }); + } + + 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 + }; + } + +}); + +/* + * Resizable Extensions + */ + +$.ui.plugin.add("resizable", "alsoResize", { + + start: function (event, ui) { + var that = $(this).data("resizable"), o = that.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) + }); + }); + }; + + 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 that = $(this).data("resizable"), o = that.options, os = that.originalSize, op = that.originalPosition; + + var delta = { + height: (that.size.height - os.height) || 0, width: (that.size.width - os.width) || 0, + top: (that.position.top - op.top) || 0, left: (that.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; + }); + + 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) { + $(this).removeData("resizable-alsoresize"); + } +}); + +$.ui.plugin.add("resizable", "animate", { + + stop: function(event, ui) { + var that = $(this).data("resizable"), o = that.options; + + var pr = that._proportionallyResizeElements, ista = pr.length && (/textarea/i).test(pr[0].nodeName), + soffseth = ista && $.ui.hasScroll(pr[0], 'left') /* TODO - jump height */ ? 0 : that.sizeDiff.height, + soffsetw = ista ? 0 : that.sizeDiff.width; + + var style = { width: (that.size.width - soffsetw), height: (that.size.height - soffseth) }, + left = (parseInt(that.element.css('left'), 10) + (that.position.left - that.originalPosition.left)) || null, + top = (parseInt(that.element.css('top'), 10) + (that.position.top - that.originalPosition.top)) || null; + + that.element.animate( + $.extend(style, top && left ? { top: top, left: left } : {}), { + duration: o.animateDuration, + easing: o.animateEasing, + step: function() { + + var data = { + width: parseInt(that.element.css('width'), 10), + height: parseInt(that.element.css('height'), 10), + top: parseInt(that.element.css('top'), 10), + left: parseInt(that.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 + that._updateCache(data); + that._propagate("resize", event); + + } + } + ); + } + +}); + +$.ui.plugin.add("resizable", "containment", { + + start: function(event, ui) { + var that = $(this).data("resizable"), o = that.options, el = that.element; + var oc = o.containment, ce = (oc instanceof $) ? oc.get(0) : (/parent/.test(oc)) ? el.parent().get(0) : oc; + if (!ce) return; + + that.containerElement = $(ce); + + if (/document/.test(oc) || oc == document) { + that.containerOffset = { left: 0, top: 0 }; + that.containerPosition = { left: 0, top: 0 }; + + that.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)); }); + + that.containerOffset = element.offset(); + that.containerPosition = element.position(); + that.containerSize = { height: (element.innerHeight() - p[3]), width: (element.innerWidth() - p[1]) }; + + var co = that.containerOffset, ch = that.containerSize.height, cw = that.containerSize.width, + width = ($.ui.hasScroll(ce, "left") ? ce.scrollWidth : cw ), height = ($.ui.hasScroll(ce) ? ce.scrollHeight : ch); + + that.parentData = { + element: ce, left: co.left, top: co.top, width: width, height: height + }; + } + }, + + resize: function(event, ui) { + var that = $(this).data("resizable"), o = that.options, + ps = that.containerSize, co = that.containerOffset, cs = that.size, cp = that.position, + pRatio = that._aspectRatio || event.shiftKey, cop = { top:0, left:0 }, ce = that.containerElement; + + if (ce[0] != document && (/static/).test(ce.css('position'))) cop = co; + + if (cp.left < (that._helper ? co.left : 0)) { + that.size.width = that.size.width + (that._helper ? (that.position.left - co.left) : (that.position.left - cop.left)); + if (pRatio) that.size.height = that.size.width / that.aspectRatio; + that.position.left = o.helper ? co.left : 0; + } + + if (cp.top < (that._helper ? co.top : 0)) { + that.size.height = that.size.height + (that._helper ? (that.position.top - co.top) : that.position.top); + if (pRatio) that.size.width = that.size.height * that.aspectRatio; + that.position.top = that._helper ? co.top : 0; + } + + that.offset.left = that.parentData.left+that.position.left; + that.offset.top = that.parentData.top+that.position.top; + + var woset = Math.abs( (that._helper ? that.offset.left - cop.left : (that.offset.left - cop.left)) + that.sizeDiff.width ), + hoset = Math.abs( (that._helper ? that.offset.top - cop.top : (that.offset.top - co.top)) + that.sizeDiff.height ); + + var isParent = that.containerElement.get(0) == that.element.parent().get(0), + isOffsetRelative = /relative|absolute/.test(that.containerElement.css('position')); + + if(isParent && isOffsetRelative) woset -= that.parentData.left; + + if (woset + that.size.width >= that.parentData.width) { + that.size.width = that.parentData.width - woset; + if (pRatio) that.size.height = that.size.width / that.aspectRatio; + } + + if (hoset + that.size.height >= that.parentData.height) { + that.size.height = that.parentData.height - hoset; + if (pRatio) that.size.width = that.size.height * that.aspectRatio; + } + }, + + stop: function(event, ui){ + var that = $(this).data("resizable"), o = that.options, cp = that.position, + co = that.containerOffset, cop = that.containerPosition, ce = that.containerElement; + + var helper = $(that.helper), ho = helper.offset(), w = helper.outerWidth() - that.sizeDiff.width, h = helper.outerHeight() - that.sizeDiff.height; + + if (that._helper && !o.animate && (/relative/).test(ce.css('position'))) + $(this).css({ left: ho.left - cop.left - co.left, width: w, height: h }); + + if (that._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 that = $(this).data("resizable"), o = that.options, cs = that.size; + + that.ghost = that.originalElement.clone(); + that.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 : ''); + + that.ghost.appendTo(that.helper); + + }, + + resize: function(event, ui){ + var that = $(this).data("resizable"), o = that.options; + if (that.ghost) that.ghost.css({ position: 'relative', height: that.size.height, width: that.size.width }); + }, + + stop: function(event, ui){ + var that = $(this).data("resizable"), o = that.options; + if (that.ghost && that.helper) that.helper.get(0).removeChild(that.ghost.get(0)); + } + +}); + +$.ui.plugin.add("resizable", "grid", { + + resize: function(event, ui) { + var that = $(this).data("resizable"), o = that.options, cs = that.size, os = that.originalSize, op = that.originalPosition, a = that.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)) { + that.size.width = os.width + ox; + that.size.height = os.height + oy; + } + else if (/^(ne)$/.test(a)) { + that.size.width = os.width + ox; + that.size.height = os.height + oy; + that.position.top = op.top - oy; + } + else if (/^(sw)$/.test(a)) { + that.size.width = os.width + ox; + that.size.height = os.height + oy; + that.position.left = op.left - ox; + } + else { + that.size.width = os.width + ox; + that.size.height = os.height + oy; + that.position.top = op.top - oy; + that.position.left = op.left - ox; + } + } + +}); + +var num = function(v) { + return parseInt(v, 10) || 0; +}; + +var isNumber = function(value) { + return !isNaN(parseInt(value, 10)); +}; + +})(jQuery); +(function( $, undefined ) { + +$.widget("ui.selectable", $.ui.mouse, { + version: "1.9.0", + options: { + appendTo: 'body', + autoRefresh: true, + distance: 0, + filter: '*', + tolerance: 'touch' + }, + _create: function() { + var that = this; + + this.element.addClass("ui-selectable"); + + this.dragged = false; + + // cache selectee children based on filter + var selectees; + this.refresh = function() { + selectees = $(that.options.filter, that.element[0]); + selectees.addClass("ui-selectee"); + 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"); + this._mouseDestroy(); + }, + + _mouseStart: function(event) { + var that = 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 && !event.ctrlKey) { + selectee.$element.removeClass('ui-selected'); + selectee.selected = false; + selectee.$element.addClass('ui-unselecting'); + selectee.unselecting = true; + // selectable UNSELECTING callback + that._trigger("unselecting", event, { + unselecting: selectee.element + }); + } + }); + + $(event.target).parents().andSelf().each(function() { + var selectee = $.data(this, "selectable-item"); + if (selectee) { + var doSelect = (!event.metaKey && !event.ctrlKey) || !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) { + that._trigger("selecting", event, { + selecting: selectee.element + }); + } else { + that._trigger("unselecting", event, { + unselecting: selectee.element + }); + } + return false; + } + }); + + }, + + _mouseDrag: function(event) { + var that = 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 == that.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 + that._trigger("selecting", event, { + selecting: selectee.element + }); + } + } else { + // UNSELECT + if (selectee.selecting) { + if ((event.metaKey || event.ctrlKey) && 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 + that._trigger("unselecting", event, { + unselecting: selectee.element + }); + } + } + if (selectee.selected) { + if (!event.metaKey && !event.ctrlKey && !selectee.startselected) { + selectee.$element.removeClass('ui-selected'); + selectee.selected = false; + + selectee.$element.addClass('ui-unselecting'); + selectee.unselecting = true; + // selectable UNSELECTING callback + that._trigger("unselecting", event, { + unselecting: selectee.element + }); + } + } + } + }); + + return false; + }, + + _mouseStop: function(event) { + var that = 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; + that._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; + that._trigger("selected", event, { + selected: selectee.element + }); + }); + this._trigger("stop", event); + + this.helper.remove(); + + return false; + } + +}); + +})(jQuery); +(function( $, undefined ) { + +$.widget("ui.sortable", $.ui.mouse, { + version: "1.9.0", + widgetEventPrefix: "sort", + ready: false, + 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(); + + //We're ready to go + this.ready = true + + }, + + _destroy: function() { + this.element + .removeClass("ui-sortable ui-sortable-disabled"); + this._mouseDestroy(); + + for ( var i = this.items.length - 1; i >= 0; i-- ) + this.items[i].item.removeData(this.widgetName + "-item"); + + return this; + }, + + _setOption: function(key, value){ + if ( key === "disabled" ) { + this.options[ key ] = value; + + this.widget().toggleClass( "ui-sortable-disabled", !!value ); + } 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) { + var that = this; + + 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, nodes = $(event.target).parents().each(function() { + if($.data(this, that.widgetName + '-item') == that) { + currentItem = $(this); + return false; + } + }); + if($.data(event.target, that.widgetName + '-item') == that) 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; + 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 + }; + + $.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 + }); + + // 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"); + + //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, this._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; + + // Only put the placeholder inside the current Container, skip all + // items form other containers. This works because when moving + // an item from one container to another the + // currentContainer is switched before the placeholder is moved. + // + // Without this moving items in "sub-sortables" can cause the placeholder to jitter + // beetween the outer and inner container. + if (item.instance !== this.currentContainer) 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 + && !$.contains(this.placeholder[0], itemElement) //no action if the item moved is the parent of the item checked + && (this.options.type == 'semi-dynamic' ? !$.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 that = this; + var cur = this.placeholder.offset(); + + this.reverting = true; + + $(this.helper).animate({ + left: cur.left - this.offset.parent.left - this.margins.left + (this.offsetParent[0] == document.body ? 0 : this.offsetParent[0].scrollLeft), + top: cur.top - this.offset.parent.top - this.margins.top + (this.offsetParent[0] == document.body ? 0 : this.offsetParent[0].scrollTop) + }, parseInt(this.options.revert, 10) || 500, function() { + that._clear(event); + }); + } else { + this._clear(event, noPropagation); + } + + return false; + + }, + + cancel: function() { + + 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, this._uiHash(this)); + if(this.containers[i].containerCache.over) { + this.containers[i]._trigger("out", null, this._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 = (this.options.axis === 'x') || $.ui.isOverAxis(this.positionAbs.top + this.offset.click.top, item.top, item.height), + isOverElementWidth = (this.options.axis === 'y') || $.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 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], this.widgetName); + 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(" + this.widgetName + "-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 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 && this.ready) { //Shouldn't be run the first time through due to massive slow-down + 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], this.widgetName); + 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(this.widgetName + '-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) { + that = that || this; + var o = that.options; + + if(!o.placeholder || o.placeholder.constructor == String) { + var className = o.placeholder; + o.placeholder = { + element: function() { + + var el = $(document.createElement(that.currentItem[0].nodeName)) + .addClass(className || that.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(that.currentItem.innerHeight() - parseInt(that.currentItem.css('paddingTop')||0, 10) - parseInt(that.currentItem.css('paddingBottom')||0, 10)); }; + if(!p.width()) { p.width(that.currentItem.innerWidth() - parseInt(that.currentItem.css('paddingLeft')||0, 10) - parseInt(that.currentItem.css('paddingRight')||0, 10)); }; + } + }; + } + + //Create the placeholder + that.placeholder = $(o.placeholder.element.call(that.element, that.currentItem)); + + //Append it after the actual current item + that.currentItem.after(that.placeholder); + + //Update the size of the placeholder (TODO: Logic to fuzzy, see line 316/317) + o.placeholder.update(that, that.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($.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 && $.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(!$.contains(this.containers[innermostIndex].element[0], this.items[j].item[0])) continue; + var cur = this.containers[innermostIndex].floating ? this.items[j].item.offset().left : this.items[j].item.offset().top; + if(Math.abs(cur - base) < dist) { + dist = Math.abs(cur - base); itemWithLeastDistance = this.items[j]; + this.direction = (cur - base > 0) ? 'down' : 'up'; + } + } + + 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 && $.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 && $.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) + - ( ( 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) + - ( ( 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 && $.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) + + ( ( 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) + + ( ( 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 counter = this.counter; + + this._delay(function() { + if(counter == this.counter) this.refreshPositions(!hardRefresh); //Precompute after each DOM insertion, NOT on mousemove + }); + + }, + + _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 = []; + + // 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 + + // Check if the items Container has Changed and trigger appropriate + // events. + if (this !== this.currentContainer) { + if(!noPropagation) { + delayedTriggers.push(function(event) { this._trigger("remove", event, this._uiHash()); }); + delayedTriggers.push((function(c) { return function(event) { c._trigger("receive", event, this._uiHash(this)); }; }).call(this, this.currentContainer)); + delayedTriggers.push((function(c) { return function(event) { c._trigger("update", event, this._uiHash(this)); }; }).call(this, this.currentContainer)); + } + } + + + //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()); + } + + this.fromOutside = false; + 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 inst = _inst || this; + return { + helper: inst.helper, + placeholder: inst.placeholder || $([]), + position: inst.position, + originalPosition: inst.originalPosition, + offset: inst.positionAbs, + item: inst.currentItem, + sender: _inst ? _inst.element : null + }; + } + +}); + +})(jQuery); +(function( $, undefined ) { + +var uid = 0, + hideProps = {}, + showProps = {}; + +hideProps.height = hideProps.paddingTop = hideProps.paddingBottom = + hideProps.borderTopWidth = hideProps.borderBottomWidth = "hide"; +showProps.height = showProps.paddingTop = showProps.paddingBottom = + showProps.borderTopWidth = showProps.borderBottomWidth = "show"; + +$.widget( "ui.accordion", { + version: "1.9.0", + options: { + active: 0, + animate: {}, + collapsible: false, + event: "click", + header: "> li > :first-child,> :not(li):even", + heightStyle: "auto", + icons: { + activeHeader: "ui-icon-triangle-1-s", + header: "ui-icon-triangle-1-e" + }, + + // callbacks + activate: null, + beforeActivate: null + }, + + _create: function() { + var accordionId = this.accordionId = "ui-accordion-" + + (this.element.attr( "id" ) || ++uid), + options = this.options; + + this.prevShow = this.prevHide = $(); + this.element.addClass( "ui-accordion ui-widget ui-helper-reset" ); + + this.headers = this.element.find( options.header ) + .addClass( "ui-accordion-header ui-helper-reset ui-state-default ui-corner-all" ); + this._hoverable( this.headers ); + this._focusable( this.headers ); + + this.headers.next() + .addClass( "ui-accordion-content ui-helper-reset ui-widget-content ui-corner-bottom" ) + .hide(); + + // don't allow collapsible: false and active: false + if ( !options.collapsible && options.active === false ) { + options.active = 0; + } + // handle negative values + if ( options.active < 0 ) { + options.active += this.headers.length; + } + this.active = this._findActive( options.active ) + .addClass( "ui-accordion-header-active ui-state-active" ) + .toggleClass( "ui-corner-all ui-corner-top" ); + this.active.next() + .addClass( "ui-accordion-content-active" ) + .show(); + + this._createIcons(); + this.originalHeight = this.element[0].style.height; + this.refresh(); + + // ARIA + this.element.attr( "role", "tablist" ); + + this.headers + .attr( "role", "tab" ) + .each(function( i ) { + var header = $( this ), + headerId = header.attr( "id" ), + panel = header.next(), + panelId = panel.attr( "id" ); + if ( !headerId ) { + headerId = accordionId + "-header-" + i; + header.attr( "id", headerId ); + } + if ( !panelId ) { + panelId = accordionId + "-panel-" + i; + panel.attr( "id", panelId ); + } + header.attr( "aria-controls", panelId ); + panel.attr( "aria-labelledby", headerId ); + }) + .next() + .attr( "role", "tabpanel" ); + + this.headers + .not( this.active ) + .attr({ + "aria-selected": "false", + tabIndex: -1 + }) + .next() + .attr({ + "aria-expanded": "false", + "aria-hidden": "true" + }) + .hide(); + + // make sure at least one header is in the tab order + if ( !this.active.length ) { + this.headers.eq( 0 ).attr( "tabIndex", 0 ); + } else { + this.active.attr({ + "aria-selected": "true", + tabIndex: 0 + }) + .next() + .attr({ + "aria-expanded": "true", + "aria-hidden": "false" + }); + } + + this._on( this.headers, { keydown: "_keydown" }); + this._on( this.headers.next(), { keydown: "_panelKeyDown" }); + this._setupEvents( options.event ); + }, + + _getCreateEventData: function() { + return { + header: this.active, + content: !this.active.length ? $() : this.active.next() + }; + }, + + _createIcons: function() { + var icons = this.options.icons; + if ( icons ) { + $( "" ) + .addClass( "ui-accordion-header-icon ui-icon " + icons.header ) + .prependTo( this.headers ); + this.active.children( ".ui-accordion-header-icon" ) + .removeClass( icons.header ) + .addClass( icons.activeHeader ); + this.headers.addClass( "ui-accordion-icons" ); + } + }, + + _destroyIcons: function() { + this.headers + .removeClass( "ui-accordion-icons" ) + .children( ".ui-accordion-header-icon" ) + .remove(); + }, + + _destroy: function() { + var contents; + + // clean up main element + this.element + .removeClass( "ui-accordion ui-widget ui-helper-reset" ) + .removeAttr( "role" ); + + // clean up headers + this.headers + .removeClass( "ui-accordion-header ui-accordion-header-active ui-helper-reset ui-state-default ui-corner-all ui-state-active ui-state-disabled ui-corner-top" ) + .removeAttr( "role" ) + .removeAttr( "aria-selected" ) + .removeAttr( "aria-controls" ) + .removeAttr( "tabIndex" ) + .each(function() { + if ( /^ui-accordion/.test( this.id ) ) { + this.removeAttribute( "id" ); + } + }); + this._destroyIcons(); + + // clean up content panels + contents = this.headers.next() + .css( "display", "" ) + .removeAttr( "role" ) + .removeAttr( "aria-expanded" ) + .removeAttr( "aria-hidden" ) + .removeAttr( "aria-labelledby" ) + .removeClass( "ui-helper-reset ui-widget-content ui-corner-bottom ui-accordion-content ui-accordion-content-active ui-state-disabled" ) + .each(function() { + if ( /^ui-accordion/.test( this.id ) ) { + this.removeAttribute( "id" ); + } + }); + if ( this.options.heightStyle !== "content" ) { + this.element.css( "height", this.originalHeight ); + contents.css( "height", "" ); + } + }, + + _setOption: function( key, value ) { + if ( key === "active" ) { + // _activate() will handle invalid values and update this.options + this._activate( value ); + return; + } + + if ( key === "event" ) { + if ( this.options.event ) { + this._off( this.headers, this.options.event ); + } + this._setupEvents( value ); + } + + this._super( key, value ); + + // setting collapsible: false while collapsed; open first panel + if ( key === "collapsible" && !value && this.options.active === false ) { + this._activate( 0 ); + } + + 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() ) + .toggleClass( "ui-state-disabled", !!value ); + } + }, + + _keydown: function( event ) { + if ( 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._eventHandler( event ); + break; + case keyCode.HOME: + toFocus = this.headers[ 0 ]; + break; + case keyCode.END: + toFocus = this.headers[ length - 1 ]; + break; + } + + if ( toFocus ) { + $( event.target ).attr( "tabIndex", -1 ); + $( toFocus ).attr( "tabIndex", 0 ); + toFocus.focus(); + event.preventDefault(); + } + }, + + _panelKeyDown : function( event ) { + if ( event.keyCode === $.ui.keyCode.UP && event.ctrlKey ) { + $( event.currentTarget ).prev().focus(); + } + }, + + refresh: function() { + var maxHeight, overflow, + heightStyle = this.options.heightStyle, + parent = this.element.parent(); + + this.element.css( "height", this.originalHeight ); + + if ( heightStyle === "fill" ) { + // IE 6 treats height like minHeight, so we need to turn off overflow + // in order to get a reliable height + // we use the minHeight support test because we assume that only + // browsers that don't support minHeight will treat height as minHeight + if ( !$.support.minHeight ) { + overflow = parent.css( "overflow" ); + parent.css( "overflow", "hidden"); + } + maxHeight = parent.height(); + this.element.siblings( ":visible" ).each(function() { + var elem = $( this ), + position = elem.css( "position" ); + + if ( position === "absolute" || position === "fixed" ) { + return; + } + maxHeight -= elem.outerHeight( true ); + }); + if ( overflow ) { + parent.css( "overflow", overflow ); + } + + 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 ( heightStyle === "auto" ) { + maxHeight = 0; + this.headers.next() + .each(function() { + maxHeight = Math.max( maxHeight, $( this ).height( "" ).height() ); + }) + .height( maxHeight ); + } + + if ( heightStyle !== "content" ) { + this.element.height( this.element.height() ); + } + }, + + _activate: function( index ) { + var active = this._findActive( index )[ 0 ]; + + // trying to activate the already active panel + if ( active === this.active[ 0 ] ) { + return; + } + + // trying to collapse, simulate a click on the currently active header + active = active || this.active[ 0 ]; + + this._eventHandler({ + target: active, + currentTarget: active, + preventDefault: $.noop + }); + }, + + _findActive: function( selector ) { + return typeof selector === "number" ? this.headers.eq( selector ) : $(); + }, + + _setupEvents: function( event ) { + var events = {}; + if ( !event ) { + return; + } + $.each( event.split(" "), function( index, eventName ) { + events[ eventName ] = "_eventHandler"; + }); + this._on( this.headers, events ); + }, + + _eventHandler: function( event ) { + var options = this.options, + active = this.active, + clicked = $( event.currentTarget ), + clickedIsActive = clicked[ 0 ] === active[ 0 ], + collapsing = clickedIsActive && options.collapsible, + toShow = collapsing ? $() : clicked.next(), + toHide = active.next(), + eventData = { + oldHeader: active, + oldPanel: toHide, + newHeader: collapsing ? $() : clicked, + newPanel: toShow + }; + + event.preventDefault(); + + if ( + // click on active header, but not collapsible + ( clickedIsActive && !options.collapsible ) || + // allow canceling activation + ( this._trigger( "beforeActivate", event, eventData ) === false ) ) { + return; + } + + options.active = collapsing ? false : this.headers.index( clicked ); + + // 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( eventData ); + + // switch classes + // corner classes on the previously active header stay after the animation + active.removeClass( "ui-accordion-header-active ui-state-active" ); + if ( options.icons ) { + active.children( ".ui-accordion-header-icon" ) + .removeClass( options.icons.activeHeader ) + .addClass( options.icons.header ); + } + + if ( !clickedIsActive ) { + clicked + .removeClass( "ui-corner-all" ) + .addClass( "ui-accordion-header-active ui-state-active ui-corner-top" ); + if ( options.icons ) { + clicked.children( ".ui-accordion-header-icon" ) + .removeClass( options.icons.header ) + .addClass( options.icons.activeHeader ); + } + + clicked + .next() + .addClass( "ui-accordion-content-active" ); + } + }, + + _toggle: function( data ) { + var toShow = data.newPanel, + toHide = this.prevShow.length ? this.prevShow : data.oldPanel; + + // handle activating a panel during the animation for another activation + this.prevShow.add( this.prevHide ).stop( true, true ); + this.prevShow = toShow; + this.prevHide = toHide; + + if ( this.options.animate ) { + this._animate( toShow, toHide, data ); + } else { + toHide.hide(); + toShow.show(); + this._toggleComplete( data ); + } + + toHide.attr({ + "aria-expanded": "false", + "aria-hidden": "true" + }); + toHide.prev().attr( "aria-selected", "false" ); + // if we're switching panels, remove the old header from the tab order + // if we're opening from collapsed state, remove the previous header from the tab order + // if we're collapsing, then keep the collapsing header in the tab order + if ( toShow.length && toHide.length ) { + toHide.prev().attr( "tabIndex", -1 ); + } else if ( toShow.length ) { + this.headers.filter(function() { + return $( this ).attr( "tabIndex" ) === 0; + }) + .attr( "tabIndex", -1 ); + } + + toShow + .attr({ + "aria-expanded": "true", + "aria-hidden": "false" + }) + .prev() + .attr({ + "aria-selected": "true", + tabIndex: 0 + }); + }, + + _animate: function( toShow, toHide, data ) { + var total, easing, duration, + that = this, + adjust = 0, + down = toShow.length && + ( !toHide.length || ( toShow.index() < toHide.index() ) ), + animate = this.options.animate || {}, + options = down && animate.down || animate, + complete = function() { + that._toggleComplete( data ); + }; + + if ( typeof options === "number" ) { + duration = options; + } + if ( typeof options === "string" ) { + easing = options; + } + // fall back from options to animation in case of partial down settings + easing = easing || options.easing || animate.easing; + duration = duration || options.duration || animate.duration; + + if ( !toHide.length ) { + return toShow.animate( showProps, duration, easing, complete ); + } + if ( !toShow.length ) { + return toHide.animate( hideProps, duration, easing, complete ); + } + + total = toShow.show().outerHeight(); + toHide.animate( hideProps, { + duration: duration, + easing: easing, + step: function( now, fx ) { + fx.now = Math.round( now ); + } + }); + toShow + .hide() + .animate( showProps, { + duration: duration, + easing: easing, + complete: complete, + step: function( now, fx ) { + fx.now = Math.round( now ); + if ( fx.prop !== "height" ) { + adjust += fx.now; + } else if ( that.options.heightStyle !== "content" ) { + fx.now = Math.round( total - toHide.outerHeight() - adjust ); + adjust = 0; + } + } + }); + }, + + _toggleComplete: function( data ) { + var toHide = data.oldPanel; + + toHide + .removeClass( "ui-accordion-content-active" ) + .prev() + .removeClass( "ui-corner-top" ) + .addClass( "ui-corner-all" ); + + // Work around for rendering bug in IE (#5421) + if ( toHide.length ) { + toHide.parent()[0].className = toHide.parent()[0].className; + } + + this._trigger( "activate", null, data ); + } +}); + + + +// DEPRECATED +if ( $.uiBackCompat !== false ) { + // navigation options + (function( $, prototype ) { + $.extend( prototype.options, { + navigation: false, + navigationFilter: function() { + return this.href.toLowerCase() === location.href.toLowerCase(); + } + }); + + var _create = prototype._create; + prototype._create = function() { + if ( this.options.navigation ) { + var that = this, + headers = this.element.find( this.options.header ), + content = headers.next(), + current = headers.add( content ) + .find( "a" ) + .filter( this.options.navigationFilter ) + [ 0 ]; + if ( current ) { + headers.add( content ).each( function( index ) { + if ( $.contains( this, current ) ) { + that.options.active = Math.floor( index / 2 ); + return false; + } + }); + } + } + _create.call( this ); + }; + }( jQuery, jQuery.ui.accordion.prototype ) ); + + // height options + (function( $, prototype ) { + $.extend( prototype.options, { + heightStyle: null, // remove default so we fall back to old values + autoHeight: true, // use heightStyle: "auto" + clearStyle: false, // use heightStyle: "content" + fillSpace: false // use heightStyle: "fill" + }); + + var _create = prototype._create, + _setOption = prototype._setOption; + + $.extend( prototype, { + _create: function() { + this.options.heightStyle = this.options.heightStyle || + this._mergeHeightStyle(); + + _create.call( this ); + }, + + _setOption: function( key, value ) { + if ( key === "autoHeight" || key === "clearStyle" || key === "fillSpace" ) { + this.options.heightStyle = this._mergeHeightStyle(); + } + _setOption.apply( this, arguments ); + }, + + _mergeHeightStyle: function() { + var options = this.options; + + if ( options.fillSpace ) { + return "fill"; + } + + if ( options.clearStyle ) { + return "content"; + } + + if ( options.autoHeight ) { + return "auto"; + } + } + }); + }( jQuery, jQuery.ui.accordion.prototype ) ); + + // icon options + (function( $, prototype ) { + $.extend( prototype.options.icons, { + activeHeader: null, // remove default so we fall back to old values + headerSelected: "ui-icon-triangle-1-s" + }); + + var _createIcons = prototype._createIcons; + prototype._createIcons = function() { + if ( this.options.icons ) { + this.options.icons.activeHeader = this.options.icons.activeHeader || + this.options.icons.headerSelected; + } + _createIcons.call( this ); + }; + }( jQuery, jQuery.ui.accordion.prototype ) ); + + // expanded active option, activate method + (function( $, prototype ) { + prototype.activate = prototype._activate; + + var _findActive = prototype._findActive; + prototype._findActive = function( index ) { + if ( index === -1 ) { + index = false; + } + if ( index && typeof index !== "number" ) { + index = this.headers.index( this.headers.filter( index ) ); + if ( index === -1 ) { + index = false; + } + } + return _findActive.call( this, index ); + }; + }( jQuery, jQuery.ui.accordion.prototype ) ); + + // resize method + jQuery.ui.accordion.prototype.resize = jQuery.ui.accordion.prototype.refresh; + + // change events + (function( $, prototype ) { + $.extend( prototype.options, { + change: null, + changestart: null + }); + + var _trigger = prototype._trigger; + prototype._trigger = function( type, event, data ) { + var ret = _trigger.apply( this, arguments ); + if ( !ret ) { + return false; + } + + if ( type === "beforeActivate" ) { + ret = _trigger.call( this, "changestart", event, { + oldHeader: data.oldHeader, + oldContent: data.oldPanel, + newHeader: data.newHeader, + newContent: data.newPanel + }); + } else if ( type === "activate" ) { + ret = _trigger.call( this, "change", event, { + oldHeader: data.oldHeader, + oldContent: data.oldPanel, + newHeader: data.newHeader, + newContent: data.newPanel + }); + } + return ret; + }; + }( jQuery, jQuery.ui.accordion.prototype ) ); + + // animated option + // NOTE: this only provides support for "slide", "bounceslide", and easings + // not the full $.ui.accordion.animations API + (function( $, prototype ) { + $.extend( prototype.options, { + animate: null, + animated: "slide" + }); + + var _create = prototype._create; + prototype._create = function() { + var options = this.options; + if ( options.animate === null ) { + if ( !options.animated ) { + options.animate = false; + } else if ( options.animated === "slide" ) { + options.animate = 300; + } else if ( options.animated === "bounceslide" ) { + options.animate = { + duration: 200, + down: { + easing: "easeOutBounce", + duration: 1000 + } + }; + } else { + options.animate = options.animated; + } + } + + _create.call( this ); + }; + }( jQuery, jQuery.ui.accordion.prototype ) ); +} + +})( jQuery ); +(function( $, undefined ) { + +// used to prevent race conditions with remote data sources +var requestIndex = 0; + +$.widget( "ui.autocomplete", { + version: "1.9.0", + defaultElement: "", + options: { + appendTo: "body", + autoFocus: false, + delay: 300, + minLength: 1, + position: { + my: "left top", + at: "left bottom", + collision: "none" + }, + source: null, + + // callbacks + change: null, + close: null, + focus: null, + open: null, + response: null, + search: null, + select: null + }, + + pending: 0, + + _create: function() { + // Some browsers only repeat keydown events, not keypress events, + // so we use the suppressKeyPress flag to determine if we've already + // handled the keydown event. #7269 + // Unfortunately the code for & in keypress is the same as the up arrow, + // so we use the suppressKeyPressRepeat flag to avoid handling keypress + // events when we know the keydown event was used to modify the + // search term. #7799 + var suppressKeyPress, suppressKeyPressRepeat, suppressInput; + + this.isMultiLine = this._isMultiLine(); + this.valueMethod = this.element[ this.element.is( "input,textarea" ) ? "val" : "text" ]; + this.isNewMenu = true; + + this.element + .addClass( "ui-autocomplete-input" ) + .attr( "autocomplete", "off" ); + + this._on({ + keydown: function( event ) { + if ( this.element.prop( "readOnly" ) ) { + suppressKeyPress = true; + suppressInput = true; + suppressKeyPressRepeat = true; + return; + } + + suppressKeyPress = false; + suppressInput = false; + suppressKeyPressRepeat = false; + var keyCode = $.ui.keyCode; + switch( event.keyCode ) { + case keyCode.PAGE_UP: + suppressKeyPress = true; + this._move( "previousPage", event ); + break; + case keyCode.PAGE_DOWN: + suppressKeyPress = true; + this._move( "nextPage", event ); + break; + case keyCode.UP: + suppressKeyPress = true; + this._keyEvent( "previous", event ); + break; + case keyCode.DOWN: + suppressKeyPress = true; + this._keyEvent( "next", event ); + break; + case keyCode.ENTER: + case keyCode.NUMPAD_ENTER: + // when menu is open and has focus + if ( this.menu.active ) { + // #6055 - Opera still allows the keypress to occur + // which causes forms to submit + suppressKeyPress = true; + event.preventDefault(); + this.menu.select( event ); + } + break; + case keyCode.TAB: + if ( this.menu.active ) { + this.menu.select( event ); + } + break; + case keyCode.ESCAPE: + if ( this.menu.element.is( ":visible" ) ) { + this._value( this.term ); + this.close( event ); + // Different browsers have different default behavior for escape + // Single press can mean undo or clear + // Double press in IE means clear the whole form + event.preventDefault(); + } + break; + default: + suppressKeyPressRepeat = true; + // search timeout should be triggered before the input value is changed + this._searchTimeout( event ); + break; + } + }, + keypress: function( event ) { + if ( suppressKeyPress ) { + suppressKeyPress = false; + event.preventDefault(); + return; + } + if ( suppressKeyPressRepeat ) { + return; + } + + // replicate some key handlers to allow them to repeat in Firefox and Opera + var keyCode = $.ui.keyCode; + switch( event.keyCode ) { + case keyCode.PAGE_UP: + this._move( "previousPage", event ); + break; + case keyCode.PAGE_DOWN: + this._move( "nextPage", event ); + break; + case keyCode.UP: + this._keyEvent( "previous", event ); + break; + case keyCode.DOWN: + this._keyEvent( "next", event ); + break; + } + }, + input: function( event ) { + if ( suppressInput ) { + suppressInput = false; + event.preventDefault(); + return; + } + this._searchTimeout( event ); + }, + focus: function() { + this.selectedItem = null; + this.previous = this._value(); + }, + blur: function( event ) { + if ( this.cancelBlur ) { + delete this.cancelBlur; + return; + } + + clearTimeout( this.searching ); + this.close( event ); + this._change( event ); + } + }); + + this._initSource(); + this.menu = $( "
      ' + + ''; + 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.delegate(selector, 'mouseout', function() { + $(this).removeClass('ui-state-hover'); + if (this.className.indexOf('ui-datepicker-prev') != -1) $(this).removeClass('ui-datepicker-prev-hover'); + if (this.className.indexOf('ui-datepicker-next') != -1) $(this).removeClass('ui-datepicker-next-hover'); + }) + .delegate(selector, 'mouseover', function(){ + if (!$.datepicker._isDisabledDatepicker( instActive.inline ? dpDiv.parent()[0] : instActive.input[0])) { + $(this).parents('.ui-datepicker-calendar').find('a').removeClass('ui-state-hover'); + $(this).addClass('ui-state-hover'); + if (this.className.indexOf('ui-datepicker-prev') != -1) $(this).addClass('ui-datepicker-prev-hover'); + if (this.className.indexOf('ui-datepicker-next') != -1) $(this).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; +}; + +/* 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(document.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.9.0"; + +// Workaround for #4055 +// Add another global to avoid noConflict issues with inline event handlers +window['DP_jQuery_' + dpuuid] = $; + +})(jQuery); +(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 + }; + +$.widget("ui.dialog", { + version: "1.9.0", + 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", + of: window, + 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.oldPosition = { + parent: this.element.parent(), + index: this.element.parent().children().index( this.element ) + }; + this.options.title = this.options.title || this.originalTitle; + var that = this, + options = this.options, + + title = options.title || " ", + + uiDialog = ( this.uiDialog = $( "
      " ) ) + .addClass( uiDialogClasses + options.dialogClass ) + .css({ + display: "none", + outline: 0, // TODO: move to stylesheet + zIndex: options.zIndex + }) + // setting tabIndex makes the div focusable + .attr( "tabIndex", -1) + .keydown(function( event ) { + if ( options.closeOnEscape && !event.isDefaultPrevented() && event.keyCode && + event.keyCode === $.ui.keyCode.ESCAPE ) { + that.close( event ); + event.preventDefault(); + } + }) + .mousedown(function( event ) { + that.moveToTop( false, event ); + }) + .appendTo( "body" ), + + uiDialogContent = this.element + .show() + .removeAttr( "title" ) + .addClass( "ui-dialog-content ui-widget-content" ) + .appendTo( uiDialog ), + + uiDialogTitlebar = ( this.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" ) + .click(function( event ) { + event.preventDefault(); + that.close( event ); + }) + .appendTo( uiDialogTitlebar ), + + uiDialogTitlebarCloseText = ( this.uiDialogTitlebarCloseText = $( "" ) ) + .addClass( "ui-icon ui-icon-closethick" ) + .text( options.closeText ) + .appendTo( uiDialogTitlebarClose ), + + uiDialogTitle = $( "" ) + .uniqueId() + .addClass( "ui-dialog-title" ) + .html( title ) + .prependTo( uiDialogTitlebar ), + + uiDialogButtonPane = ( this.uiDialogButtonPane = $( "
      " ) ) + .addClass( "ui-dialog-buttonpane ui-widget-content ui-helper-clearfix" ), + + uiButtonSet = ( this.uiButtonSet = $( "
      " ) ) + .addClass( "ui-dialog-buttonset" ) + .appendTo( uiDialogButtonPane ); + + uiDialog.attr({ + role: "dialog", + "aria-labelledby": uiDialogTitle.attr( "id" ) + }); + + uiDialogTitlebar.find( "*" ).add( uiDialogTitlebar ).disableSelection(); + this._hoverable( uiDialogTitlebarClose ); + this._focusable( uiDialogTitlebarClose ); + + if ( options.draggable && $.fn.draggable ) { + this._makeDraggable(); + } + if ( options.resizable && $.fn.resizable ) { + this._makeResizable(); + } + + this._createButtons( options.buttons ); + this._isOpen = false; + + if ( $.fn.bgiframe ) { + uiDialog.bgiframe(); + } + + // prevent tabbing out of modal dialogs + this._on( uiDialog, { keydown: function( event ) { + if ( !options.modal || event.keyCode !== $.ui.keyCode.TAB ) { + return; + } + + var tabbables = $( ":tabbable", uiDialog ), + 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; + } + }}); + }, + + _init: function() { + if ( this.options.autoOpen ) { + this.open(); + } + }, + + _destroy: function() { + var next, + oldPosition = this.oldPosition; + + if ( this.overlay ) { + this.overlay.destroy(); + } + this.uiDialog.hide(); + this.element + .removeClass( "ui-dialog-content ui-widget-content" ) + .hide() + .appendTo( "body" ); + this.uiDialog.remove(); + + if ( this.originalTitle ) { + this.element.attr( "title", this.originalTitle ); + } + + next = oldPosition.parent.children().eq( oldPosition.index ); + // Don't try to place the dialog next to itself (#8613) + if ( next.length && next[ 0 ] !== this.element[ 0 ] ) { + next.before( this.element ); + } else { + oldPosition.parent.append( this.element ); + } + }, + + widget: function() { + return this.uiDialog; + }, + + close: function( event ) { + var that = this, + maxZ, thisZ; + + if ( !this._isOpen ) { + return; + } + + if ( false === this._trigger( "beforeClose", event ) ) { + return; + } + + this._isOpen = false; + + if ( this.overlay ) { + this.overlay.destroy(); + } + + if ( this.options.hide ) { + this.uiDialog.hide( this.options.hide, function() { + that._trigger( "close", event ); + }); + } else { + this.uiDialog.hide(); + this._trigger( "close", event ); + } + + $.ui.dialog.overlay.resize(); + + // adjust the maxZ to allow other modal dialogs to continue to work (see #4309) + if ( this.options.modal ) { + maxZ = 0; + $( ".ui-dialog" ).each(function() { + if ( this !== that.uiDialog[0] ) { + thisZ = $( this ).css( "z-index" ); + if ( !isNaN( thisZ ) ) { + maxZ = Math.max( maxZ, thisZ ); + } + } + }); + $.ui.dialog.maxZ = maxZ; + } + + return this; + }, + + 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 options = this.options, + saveScroll; + + if ( ( options.modal && !force ) || + ( !options.stack && !options.modal ) ) { + return this._trigger( "focus", event ); + } + + if ( options.zIndex > $.ui.dialog.maxZ ) { + $.ui.dialog.maxZ = options.zIndex; + } + if ( this.overlay ) { + $.ui.dialog.maxZ += 1; + $.ui.dialog.overlay.maxZ = $.ui.dialog.maxZ; + this.overlay.$el.css( "z-index", $.ui.dialog.overlay.maxZ ); + } + + // Save and then restore scroll + // Opera 9.5+ resets when parent z-index is changed. + // http://bugs.jqueryui.com/ticket/3193 + saveScroll = { + scrollTop: this.element.scrollTop(), + scrollLeft: this.element.scrollLeft() + }; + $.ui.dialog.maxZ += 1; + this.uiDialog.css( "z-index", $.ui.dialog.maxZ ); + this.element.attr( saveScroll ); + this._trigger( "focus", event ); + + return this; + }, + + open: function() { + if ( this._isOpen ) { + return; + } + + var hasFocus, + options = this.options, + uiDialog = this.uiDialog; + + this._size(); + this._position( options.position ); + uiDialog.show( options.show ); + this.overlay = options.modal ? new $.ui.dialog.overlay( this ) : null; + this.moveToTop( true ); + + // 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 + hasFocus = this.element.find( ":tabbable" ); + if ( !hasFocus.length ) { + hasFocus = this.uiDialogButtonPane.find( ":tabbable" ); + if ( !hasFocus.length ) { + hasFocus = uiDialog; + } + } + hasFocus.eq( 0 ).focus(); + + this._isOpen = true; + this._trigger( "open" ); + + return this; + }, + + _createButtons: function( buttons ) { + var uiDialogButtonPane, uiButtonSet, + that = this, + hasButtons = false; + + // if we already have a button pane, remove it + this.uiDialogButtonPane.remove(); + this.uiButtonSet.empty(); + + 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 = $( "').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 if ($.datepicker._datepickerShowing && $.datepicker._lastInput != input[0]) { + $.datepicker._hideDatepicker(); + $.datepicker._showDatepicker(input[0]); + } 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"). + prop("disabled", false); + } + 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"). + prop("disabled", true); + } + 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 (err) { + $.datepicker.log(err); + } + } + return true; + }, + + /* Pop-up the date picker for a given input field. + If false returned from beforeShow event handler do not show. + @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) { + $.datepicker._curInst.dpDiv.stop(true, true); + if ( inst && $.datepicker._datepickerShowing ) { + $.datepicker._hideDatepicker( $.datepicker._curInst.input[0] ); + } + } + var beforeShow = $.datepicker._get(inst, 'beforeShow'); + var beforeShowSettings = beforeShow ? beforeShow.apply(input, [input, inst]) : {}; + if(beforeShowSettings === false){ + //false + return; + } + extendRemove(inst.settings, beforeShowSettings); + 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; + }); + 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; + + // DEPRECATED: after BC for 1.8.x $.effects[ showAnim ] is not needed + if ( $.effects && ( $.effects.effect[ showAnim ] || $.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) { + this.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)); + this._attachHandlers(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 + (isFixed ? 0 : $(document).scrollLeft()); + var viewHeight = document.documentElement.clientHeight + (isFixed ? 0 : $(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]; + }, + + /* 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); + }; + + // DEPRECATED: after BC for 1.8.x $.effects[ showAnim ] is not needed + if ( $.effects && ( $.effects.effect[ showAnim ] || $.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(); + this._datepickerShowing = false; + var onClose = this._get(inst, 'onClose'); + if (onClose) + onClose.apply((inst.input ? inst.input[0] : null), + [(inst.input ? inst.input.val() : ''), inst]); + 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), + inst = $.datepicker._getInst($target[0]); + + if ( ( ( $target[0].id != $.datepicker._mainDivId && + $target.parents('#' + $.datepicker._mainDivId).length == 0 && + !$target.hasClass($.datepicker.markerClassName) && + !$target.closest("." + $.datepicker._triggerClass).length && + $.datepicker._datepickerShowing && !($.datepicker._inDialog && $.blockUI) ) ) || + ( $target.hasClass($.datepicker.markerClassName) && $.datepicker._curInst != inst ) ) + $.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]; + if (typeof(inst.input[0]) != 'object') + 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){ + var extra = value.substr(iValue); + if (!/^\s+/.test(extra)) { + throw "Extra/unparsed characters found in date: " + extra; + } + } + 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)); + } + }, + + /* 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; + }, + + /* Attach the onxxx handlers. These are declared statically so + * they work with static code transformers like Caja. + */ + _attachHandlers: function(inst) { + var stepMonths = this._get(inst, 'stepMonths'); + var id = '#' + inst.id.replace( /\\\\/g, "\\" ); + inst.dpDiv.find('[data-handler]').map(function () { + var handler = { + prev: function () { + window['DP_jQuery_' + dpuuid].datepicker._adjustDate(id, -stepMonths, 'M'); + }, + next: function () { + window['DP_jQuery_' + dpuuid].datepicker._adjustDate(id, +stepMonths, 'M'); + }, + hide: function () { + window['DP_jQuery_' + dpuuid].datepicker._hideDatepicker(); + }, + today: function () { + window['DP_jQuery_' + dpuuid].datepicker._gotoToday(id); + }, + selectDay: function () { + window['DP_jQuery_' + dpuuid].datepicker._selectDay(id, +this.getAttribute('data-month'), +this.getAttribute('data-year'), this); + return false; + }, + selectMonth: function () { + window['DP_jQuery_' + dpuuid].datepicker._selectMonthYear(id, this, 'M'); + return false; + }, + selectYear: function () { + window['DP_jQuery_' + dpuuid].datepicker._selectMonthYear(id, this, 'Y'); + return false; + } + }; + $(this).bind(this.getAttribute('data-event'), handler[this.getAttribute('data-handler')]); + }); + }, + + /* 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.delegate(selector, 'mouseout', function() { + $(this).removeClass('ui-state-hover'); + if (this.className.indexOf('ui-datepicker-prev') != -1) $(this).removeClass('ui-datepicker-prev-hover'); + if (this.className.indexOf('ui-datepicker-next') != -1) $(this).removeClass('ui-datepicker-next-hover'); + }) + .delegate(selector, 'mouseover', function(){ + if (!$.datepicker._isDisabledDatepicker( instActive.inline ? dpDiv.parent()[0] : instActive.input[0])) { + $(this).parents('.ui-datepicker-calendar').find('a').removeClass('ui-state-hover'); + $(this).addClass('ui-state-hover'); + if (this.className.indexOf('ui-datepicker-prev') != -1) $(this).addClass('ui-datepicker-prev-hover'); + if (this.className.indexOf('ui-datepicker-next') != -1) $(this).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; +}; + +/* 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(document.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.9.0"; + +// Workaround for #4055 +// Add another global to avoid noConflict issues with inline event handlers +window['DP_jQuery_' + dpuuid] = $; + +})(jQuery); diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/ui/jquery.ui.dialog.js b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/ui/jquery.ui.dialog.js new file mode 100755 index 000000000..f9923d27b --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/ui/jquery.ui.dialog.js @@ -0,0 +1,847 @@ +/*! + * jQuery UI Dialog 1.9.0 + * http://jqueryui.com + * + * Copyright 2012 jQuery Foundation and other contributors + * Released under the MIT license. + * http://jquery.org/license + * + * http://api.jqueryui.com/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 + }; + +$.widget("ui.dialog", { + version: "1.9.0", + 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", + of: window, + 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.oldPosition = { + parent: this.element.parent(), + index: this.element.parent().children().index( this.element ) + }; + this.options.title = this.options.title || this.originalTitle; + var that = this, + options = this.options, + + title = options.title || " ", + + uiDialog = ( this.uiDialog = $( "
      " ) ) + .addClass( uiDialogClasses + options.dialogClass ) + .css({ + display: "none", + outline: 0, // TODO: move to stylesheet + zIndex: options.zIndex + }) + // setting tabIndex makes the div focusable + .attr( "tabIndex", -1) + .keydown(function( event ) { + if ( options.closeOnEscape && !event.isDefaultPrevented() && event.keyCode && + event.keyCode === $.ui.keyCode.ESCAPE ) { + that.close( event ); + event.preventDefault(); + } + }) + .mousedown(function( event ) { + that.moveToTop( false, event ); + }) + .appendTo( "body" ), + + uiDialogContent = this.element + .show() + .removeAttr( "title" ) + .addClass( "ui-dialog-content ui-widget-content" ) + .appendTo( uiDialog ), + + uiDialogTitlebar = ( this.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" ) + .click(function( event ) { + event.preventDefault(); + that.close( event ); + }) + .appendTo( uiDialogTitlebar ), + + uiDialogTitlebarCloseText = ( this.uiDialogTitlebarCloseText = $( "" ) ) + .addClass( "ui-icon ui-icon-closethick" ) + .text( options.closeText ) + .appendTo( uiDialogTitlebarClose ), + + uiDialogTitle = $( "" ) + .uniqueId() + .addClass( "ui-dialog-title" ) + .html( title ) + .prependTo( uiDialogTitlebar ), + + uiDialogButtonPane = ( this.uiDialogButtonPane = $( "
      " ) ) + .addClass( "ui-dialog-buttonpane ui-widget-content ui-helper-clearfix" ), + + uiButtonSet = ( this.uiButtonSet = $( "
      " ) ) + .addClass( "ui-dialog-buttonset" ) + .appendTo( uiDialogButtonPane ); + + uiDialog.attr({ + role: "dialog", + "aria-labelledby": uiDialogTitle.attr( "id" ) + }); + + uiDialogTitlebar.find( "*" ).add( uiDialogTitlebar ).disableSelection(); + this._hoverable( uiDialogTitlebarClose ); + this._focusable( uiDialogTitlebarClose ); + + if ( options.draggable && $.fn.draggable ) { + this._makeDraggable(); + } + if ( options.resizable && $.fn.resizable ) { + this._makeResizable(); + } + + this._createButtons( options.buttons ); + this._isOpen = false; + + if ( $.fn.bgiframe ) { + uiDialog.bgiframe(); + } + + // prevent tabbing out of modal dialogs + this._on( uiDialog, { keydown: function( event ) { + if ( !options.modal || event.keyCode !== $.ui.keyCode.TAB ) { + return; + } + + var tabbables = $( ":tabbable", uiDialog ), + 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; + } + }}); + }, + + _init: function() { + if ( this.options.autoOpen ) { + this.open(); + } + }, + + _destroy: function() { + var next, + oldPosition = this.oldPosition; + + if ( this.overlay ) { + this.overlay.destroy(); + } + this.uiDialog.hide(); + this.element + .removeClass( "ui-dialog-content ui-widget-content" ) + .hide() + .appendTo( "body" ); + this.uiDialog.remove(); + + if ( this.originalTitle ) { + this.element.attr( "title", this.originalTitle ); + } + + next = oldPosition.parent.children().eq( oldPosition.index ); + // Don't try to place the dialog next to itself (#8613) + if ( next.length && next[ 0 ] !== this.element[ 0 ] ) { + next.before( this.element ); + } else { + oldPosition.parent.append( this.element ); + } + }, + + widget: function() { + return this.uiDialog; + }, + + close: function( event ) { + var that = this, + maxZ, thisZ; + + if ( !this._isOpen ) { + return; + } + + if ( false === this._trigger( "beforeClose", event ) ) { + return; + } + + this._isOpen = false; + + if ( this.overlay ) { + this.overlay.destroy(); + } + + if ( this.options.hide ) { + this.uiDialog.hide( this.options.hide, function() { + that._trigger( "close", event ); + }); + } else { + this.uiDialog.hide(); + this._trigger( "close", event ); + } + + $.ui.dialog.overlay.resize(); + + // adjust the maxZ to allow other modal dialogs to continue to work (see #4309) + if ( this.options.modal ) { + maxZ = 0; + $( ".ui-dialog" ).each(function() { + if ( this !== that.uiDialog[0] ) { + thisZ = $( this ).css( "z-index" ); + if ( !isNaN( thisZ ) ) { + maxZ = Math.max( maxZ, thisZ ); + } + } + }); + $.ui.dialog.maxZ = maxZ; + } + + return this; + }, + + 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 options = this.options, + saveScroll; + + if ( ( options.modal && !force ) || + ( !options.stack && !options.modal ) ) { + return this._trigger( "focus", event ); + } + + if ( options.zIndex > $.ui.dialog.maxZ ) { + $.ui.dialog.maxZ = options.zIndex; + } + if ( this.overlay ) { + $.ui.dialog.maxZ += 1; + $.ui.dialog.overlay.maxZ = $.ui.dialog.maxZ; + this.overlay.$el.css( "z-index", $.ui.dialog.overlay.maxZ ); + } + + // Save and then restore scroll + // Opera 9.5+ resets when parent z-index is changed. + // http://bugs.jqueryui.com/ticket/3193 + saveScroll = { + scrollTop: this.element.scrollTop(), + scrollLeft: this.element.scrollLeft() + }; + $.ui.dialog.maxZ += 1; + this.uiDialog.css( "z-index", $.ui.dialog.maxZ ); + this.element.attr( saveScroll ); + this._trigger( "focus", event ); + + return this; + }, + + open: function() { + if ( this._isOpen ) { + return; + } + + var hasFocus, + options = this.options, + uiDialog = this.uiDialog; + + this._size(); + this._position( options.position ); + uiDialog.show( options.show ); + this.overlay = options.modal ? new $.ui.dialog.overlay( this ) : null; + this.moveToTop( true ); + + // 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 + hasFocus = this.element.find( ":tabbable" ); + if ( !hasFocus.length ) { + hasFocus = this.uiDialogButtonPane.find( ":tabbable" ); + if ( !hasFocus.length ) { + hasFocus = uiDialog; + } + } + hasFocus.eq( 0 ).focus(); + + this._isOpen = true; + this._trigger( "open" ); + + return this; + }, + + _createButtons: function( buttons ) { + var uiDialogButtonPane, uiButtonSet, + that = this, + hasButtons = false; + + // if we already have a button pane, remove it + this.uiDialogButtonPane.remove(); + this.uiButtonSet.empty(); + + 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 = $( "').addClass(this._triggerClass).html(o==""?s:$("").attr({src:o,alt:s,title:s}))),e[r?"before":"after"](t.trigger),t.trigger.click(function(){return $.datepicker._datepickerShowing&&$.datepicker._lastInput==e[0]?$.datepicker._hideDatepicker():$.datepicker._datepickerShowing&&$.datepicker._lastInput!=e[0]?($.datepicker._hideDatepicker(),$.datepicker._showDatepicker(e[0])):$.datepicker._showDatepicker(e[0]),!1})}},_autoSize:function(e){if(this._get(e,"autoSize")&&!e.inline){var t=new Date(2009,11,20),n=this._get(e,"dateFormat");if(n.match(/[DM]/)){var r=function(e){var t=0,n=0;for(var r=0;rt&&(t=e[r].length,n=r);return n};t.setMonth(r(this._get(e,n.match(/MM/)?"monthNames":"monthNamesShort"))),t.setDate(r(this._get(e,n.match(/DD/)?"dayNames":"dayNamesShort"))+20-t.getDay())}e.input.attr("size",this._formatDate(e,t).length)}},_inlineDatepicker:function(e,t){var n=$(e);if(n.hasClass(this.markerClassName))return;n.addClass(this.markerClassName).append(t.dpDiv).bind("setData.datepicker",function(e,n,r){t.settings[n]=r}).bind("getData.datepicker",function(e,n){return this._get(t,n)}),$.data(e,PROP_NAME,t),this._setDate(t,this._getDefaultDate(t),!0),this._updateDatepicker(t),this._updateAlternate(t),t.settings.disabled&&this._disableDatepicker(e),t.dpDiv.css("display","block")},_dialogDatepicker:function(e,t,n,r,i){var s=this._dialogInst;if(!s){this.uuid+=1;var o="dp"+this.uuid;this._dialogInput=$(''),this._dialogInput.keydown(this._doKeyDown),$("body").append(this._dialogInput),s=this._dialogInst=this._newInst(this._dialogInput,!1),s.settings={},$.data(this._dialogInput[0],PROP_NAME,s)}extendRemove(s.settings,r||{}),t=t&&t.constructor==Date?this._formatDate(s,t):t,this._dialogInput.val(t),this._pos=i?i.length?i:[i.pageX,i.pageY]:null;if(!this._pos){var u=document.documentElement.clientWidth,a=document.documentElement.clientHeight,f=document.documentElement.scrollLeft||document.body.scrollLeft,l=document.documentElement.scrollTop||document.body.scrollTop;this._pos=[u/2-100+f,a/2-150+l]}return this._dialogInput.css("left",this._pos[0]+20+"px").css("top",this._pos[1]+"px"),s.settings.onSelect=n,this._inDialog=!0,this.dpDiv.addClass(this._dialogClass),this._showDatepicker(this._dialogInput[0]),$.blockUI&&$.blockUI(this.dpDiv),$.data(this._dialogInput[0],PROP_NAME,s),this},_destroyDatepicker:function(e){var t=$(e),n=$.data(e,PROP_NAME);if(!t.hasClass(this.markerClassName))return;var r=e.nodeName.toLowerCase();$.removeData(e,PROP_NAME),r=="input"?(n.append.remove(),n.trigger.remove(),t.removeClass(this.markerClassName).unbind("focus",this._showDatepicker).unbind("keydown",this._doKeyDown).unbind("keypress",this._doKeyPress).unbind("keyup",this._doKeyUp)):(r=="div"||r=="span")&&t.removeClass(this.markerClassName).empty()},_enableDatepicker:function(e){var t=$(e),n=$.data(e,PROP_NAME);if(!t.hasClass(this.markerClassName))return;var r=e.nodeName.toLowerCase();if(r=="input")e.disabled=!1,n.trigger.filter("button").each(function(){this.disabled=!1}).end().filter("img").css({opacity:"1.0",cursor:""});else if(r=="div"||r=="span"){var i=t.children("."+this._inlineClass);i.children().removeClass("ui-state-disabled"),i.find("select.ui-datepicker-month, select.ui-datepicker-year").prop("disabled",!1)}this._disabledInputs=$.map(this._disabledInputs,function(t){return t==e?null:t})},_disableDatepicker:function(e){var t=$(e),n=$.data(e,PROP_NAME);if(!t.hasClass(this.markerClassName))return;var r=e.nodeName.toLowerCase();if(r=="input")e.disabled=!0,n.trigger.filter("button").each(function(){this.disabled=!0}).end().filter("img").css({opacity:"0.5",cursor:"default"});else if(r=="div"||r=="span"){var i=t.children("."+this._inlineClass);i.children().addClass("ui-state-disabled"),i.find("select.ui-datepicker-month, select.ui-datepicker-year").prop("disabled",!0)}this._disabledInputs=$.map(this._disabledInputs,function(t){return t==e?null:t}),this._disabledInputs[this._disabledInputs.length]=e},_isDisabledDatepicker:function(e){if(!e)return!1;for(var t=0;t-1}},_doKeyUp:function(e){var t=$.datepicker._getInst(e.target);if(t.input.val()!=t.lastVal)try{var n=$.datepicker.parseDate($.datepicker._get(t,"dateFormat"),t.input?t.input.val():null,$.datepicker._getFormatConfig(t));n&&($.datepicker._setDateFromField(t),$.datepicker._updateAlternate(t),$.datepicker._updateDatepicker(t))}catch(r){$.datepicker.log(r)}return!0},_showDatepicker:function(e){e=e.target||e,e.nodeName.toLowerCase()!="input"&&(e=$("input",e.parentNode)[0]);if($.datepicker._isDisabledDatepicker(e)||$.datepicker._lastInput==e)return;var t=$.datepicker._getInst(e);$.datepicker._curInst&&$.datepicker._curInst!=t&&($.datepicker._curInst.dpDiv.stop(!0,!0),t&&$.datepicker._datepickerShowing&&$.datepicker._hideDatepicker($.datepicker._curInst.input[0]));var n=$.datepicker._get(t,"beforeShow"),r=n?n.apply(e,[e,t]):{};if(r===!1)return;extendRemove(t.settings,r),t.lastVal=null,$.datepicker._lastInput=e,$.datepicker._setDateFromField(t),$.datepicker._inDialog&&(e.value=""),$.datepicker._pos||($.datepicker._pos=$.datepicker._findPos(e),$.datepicker._pos[1]+=e.offsetHeight);var i=!1;$(e).parents().each(function(){return i|=$(this).css("position")=="fixed",!i});var s={left:$.datepicker._pos[0],top:$.datepicker._pos[1]};$.datepicker._pos=null,t.dpDiv.empty(),t.dpDiv.css({position:"absolute",display:"block",top:"-1000px"}),$.datepicker._updateDatepicker(t),s=$.datepicker._checkOffset(t,s,i),t.dpDiv.css({position:$.datepicker._inDialog&&$.blockUI?"static":i?"fixed":"absolute",display:"none",left:s.left+"px",top:s.top+"px"});if(!t.inline){var o=$.datepicker._get(t,"showAnim"),u=$.datepicker._get(t,"duration"),a=function(){var e=t.dpDiv.find("iframe.ui-datepicker-cover");if(!!e.length){var n=$.datepicker._getBorders(t.dpDiv);e.css({left:-n[0],top:-n[1],width:t.dpDiv.outerWidth(),height:t.dpDiv.outerHeight()})}};t.dpDiv.zIndex($(e).zIndex()+1),$.datepicker._datepickerShowing=!0,$.effects&&($.effects.effect[o]||$.effects[o])?t.dpDiv.show(o,$.datepicker._get(t,"showOptions"),u,a):t.dpDiv[o||"show"](o?u:null,a),(!o||!u)&&a(),t.input.is(":visible")&&!t.input.is(":disabled")&&t.input.focus(),$.datepicker._curInst=t}},_updateDatepicker:function(e){this.maxRows=4;var t=$.datepicker._getBorders(e.dpDiv);instActive=e,e.dpDiv.empty().append(this._generateHTML(e)),this._attachHandlers(e);var n=e.dpDiv.find("iframe.ui-datepicker-cover");!n.length||n.css({left:-t[0],top:-t[1],width:e.dpDiv.outerWidth(),height:e.dpDiv.outerHeight()}),e.dpDiv.find("."+this._dayOverClass+" a").mouseover();var r=this._getNumberOfMonths(e),i=r[1],s=17;e.dpDiv.removeClass("ui-datepicker-multi-2 ui-datepicker-multi-3 ui-datepicker-multi-4").width(""),i>1&&e.dpDiv.addClass("ui-datepicker-multi-"+i).css("width",s*i+"em"),e.dpDiv[(r[0]!=1||r[1]!=1?"add":"remove")+"Class"]("ui-datepicker-multi"),e.dpDiv[(this._get(e,"isRTL")?"add":"remove")+"Class"]("ui-datepicker-rtl"),e==$.datepicker._curInst&&$.datepicker._datepickerShowing&&e.input&&e.input.is(":visible")&&!e.input.is(":disabled")&&e.input[0]!=document.activeElement&&e.input.focus();if(e.yearshtml){var o=e.yearshtml;setTimeout(function(){o===e.yearshtml&&e.yearshtml&&e.dpDiv.find("select.ui-datepicker-year:first").replaceWith(e.yearshtml),o=e.yearshtml=null},0)}},_getBorders:function(e){var t=function(e){return{thin:1,medium:2,thick:3}[e]||e};return[parseFloat(t(e.css("border-left-width"))),parseFloat(t(e.css("border-top-width")))]},_checkOffset:function(e,t,n){var r=e.dpDiv.outerWidth(),i=e.dpDiv.outerHeight(),s=e.input?e.input.outerWidth():0,o=e.input?e.input.outerHeight():0,u=document.documentElement.clientWidth+(n?0:$(document).scrollLeft()),a=document.documentElement.clientHeight+(n?0:$(document).scrollTop());return t.left-=this._get(e,"isRTL")?r-s:0,t.left-=n&&t.left==e.input.offset().left?$(document).scrollLeft():0,t.top-=n&&t.top==e.input.offset().top+o?$(document).scrollTop():0,t.left-=Math.min(t.left,t.left+r>u&&u>r?Math.abs(t.left+r-u):0),t.top-=Math.min(t.top,t.top+i>a&&a>i?Math.abs(i+o):0),t},_findPos:function(e){var t=this._getInst(e),n=this._get(t,"isRTL");while(e&&(e.type=="hidden"||e.nodeType!=1||$.expr.filters.hidden(e)))e=e[n?"previousSibling":"nextSibling"];var r=$(e).offset();return[r.left,r.top]},_hideDatepicker:function(e){var t=this._curInst;if(!t||e&&t!=$.data(e,PROP_NAME))return;if(this._datepickerShowing){var n=this._get(t,"showAnim"),r=this._get(t,"duration"),i=function(){$.datepicker._tidyDialog(t)};$.effects&&($.effects.effect[n]||$.effects[n])?t.dpDiv.hide(n,$.datepicker._get(t,"showOptions"),r,i):t.dpDiv[n=="slideDown"?"slideUp":n=="fadeIn"?"fadeOut":"hide"](n?r:null,i),n||i(),this._datepickerShowing=!1;var s=this._get(t,"onClose");s&&s.apply(t.input?t.input[0]:null,[t.input?t.input.val():"",t]),this._lastInput=null,this._inDialog&&(this._dialogInput.css({position:"absolute",left:"0",top:"-100px"}),$.blockUI&&($.unblockUI(),$("body").append(this.dpDiv))),this._inDialog=!1}},_tidyDialog:function(e){e.dpDiv.removeClass(this._dialogClass).unbind(".ui-datepicker-calendar")},_checkExternalClick:function(e){if(!$.datepicker._curInst)return;var t=$(e.target),n=$.datepicker._getInst(t[0]);(t[0].id!=$.datepicker._mainDivId&&t.parents("#"+$.datepicker._mainDivId).length==0&&!t.hasClass($.datepicker.markerClassName)&&!t.closest("."+$.datepicker._triggerClass).length&&$.datepicker._datepickerShowing&&(!$.datepicker._inDialog||!$.blockUI)||t.hasClass($.datepicker.markerClassName)&&$.datepicker._curInst!=n)&&$.datepicker._hideDatepicker()},_adjustDate:function(e,t,n){var r=$(e),i=this._getInst(r[0]);if(this._isDisabledDatepicker(r[0]))return;this._adjustInstDate(i,t+(n=="M"?this._get(i,"showCurrentAtPos"):0),n),this._updateDatepicker(i)},_gotoToday:function(e){var t=$(e),n=this._getInst(t[0]);if(this._get(n,"gotoCurrent")&&n.currentDay)n.selectedDay=n.currentDay,n.drawMonth=n.selectedMonth=n.currentMonth,n.drawYear=n.selectedYear=n.currentYear;else{var r=new Date;n.selectedDay=r.getDate(),n.drawMonth=n.selectedMonth=r.getMonth(),n.drawYear=n.selectedYear=r.getFullYear()}this._notifyChange(n),this._adjustDate(t)},_selectMonthYear:function(e,t,n){var r=$(e),i=this._getInst(r[0]);i["selected"+(n=="M"?"Month":"Year")]=i["draw"+(n=="M"?"Month":"Year")]=parseInt(t.options[t.selectedIndex].value,10),this._notifyChange(i),this._adjustDate(r)},_selectDay:function(e,t,n,r){var i=$(e);if($(r).hasClass(this._unselectableClass)||this._isDisabledDatepicker(i[0]))return;var s=this._getInst(i[0]);s.selectedDay=s.currentDay=$("a",r).html(),s.selectedMonth=s.currentMonth=t,s.selectedYear=s.currentYear=n,this._selectDate(e,this._formatDate(s,s.currentDay,s.currentMonth,s.currentYear))},_clearDate:function(e){var t=$(e),n=this._getInst(t[0]);this._selectDate(t,"")},_selectDate:function(e,t){var n=$(e),r=this._getInst(n[0]);t=t!=null?t:this._formatDate(r),r.input&&r.input.val(t),this._updateAlternate(r);var i=this._get(r,"onSelect");i?i.apply(r.input?r.input[0]:null,[t,r]):r.input&&r.input.trigger("change"),r.inline?this._updateDatepicker(r):(this._hideDatepicker(),this._lastInput=r.input[0],typeof r.input[0]!="object"&&r.input.focus(),this._lastInput=null)},_updateAlternate:function(e){var t=this._get(e,"altField");if(t){var n=this._get(e,"altFormat")||this._get(e,"dateFormat"),r=this._getDate(e),i=this.formatDate(n,r,this._getFormatConfig(e));$(t).each(function(){$(this).val(i)})}},noWeekends:function(e){var t=e.getDay();return[t>0&&t<6,""]},iso8601Week:function(e){var t=new Date(e.getTime());t.setDate(t.getDate()+4-(t.getDay()||7));var n=t.getTime();return t.setMonth(0),t.setDate(1),Math.floor(Math.round((n-t)/864e5)/7)+1},parseDate:function(e,t,n){if(e==null||t==null)throw"Invalid arguments";t=typeof t=="object"?t.toString():t+"";if(t=="")return null;var r=(n?n.shortYearCutoff:null)||this._defaults.shortYearCutoff;r=typeof r!="string"?r:(new Date).getFullYear()%100+parseInt(r,10);var i=(n?n.dayNamesShort:null)||this._defaults.dayNamesShort,s=(n?n.dayNames:null)||this._defaults.dayNames,o=(n?n.monthNamesShort:null)||this._defaults.monthNamesShort,u=(n?n.monthNames:null)||this._defaults.monthNames,a=-1,f=-1,l=-1,c=-1,h=!1,p=function(t){var n=y+1-1){f=1,l=c;do{var E=this._getDaysInMonth(a,f-1);if(l<=E)break;f++,l-=E}while(!0)}var b=this._daylightSavingAdjust(new Date(a,f-1,l));if(b.getFullYear()!=a||b.getMonth()+1!=f||b.getDate()!=l)throw"Invalid date";return b},ATOM:"yy-mm-dd",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",TICKS:"!",TIMESTAMP:"@",W3C:"yy-mm-dd",_ticksTo1970:(718685+Math.floor(492.5)-Math.floor(19.7)+Math.floor(4.925))*24*60*60*1e7,formatDate:function(e,t,n){if(!t)return"";var r=(n?n.dayNamesShort:null)||this._defaults.dayNamesShort,i=(n?n.dayNames:null)||this._defaults.dayNames,s=(n?n.monthNamesShort:null)||this._defaults.monthNamesShort,o=(n?n.monthNames:null)||this._defaults.monthNames,u=function(t){var n=h+112?e.getHours()+2:0),e):null},_setDate:function(e,t,n){var r=!t,i=e.selectedMonth,s=e.selectedYear,o=this._restrictMinMax(e,this._determineDate(e,t,new Date));e.selectedDay=e.currentDay=o.getDate(),e.drawMonth=e.selectedMonth=e.currentMonth=o.getMonth(),e.drawYear=e.selectedYear=e.currentYear=o.getFullYear(),(i!=e.selectedMonth||s!=e.selectedYear)&&!n&&this._notifyChange(e),this._adjustInstDate(e),e.input&&e.input.val(r?"":this._formatDate(e))},_getDate:function(e){var t=!e.currentYear||e.input&&e.input.val()==""?null:this._daylightSavingAdjust(new Date(e.currentYear,e.currentMonth,e.currentDay));return t},_attachHandlers:function(e){var t=this._get(e,"stepMonths"),n="#"+e.id.replace(/\\\\/g,"\\");e.dpDiv.find("[data-handler]").map(function(){var e={prev:function(){window["DP_jQuery_"+dpuuid].datepicker._adjustDate(n,-t,"M")},next:function(){window["DP_jQuery_"+dpuuid].datepicker._adjustDate(n,+t,"M")},hide:function(){window["DP_jQuery_"+dpuuid].datepicker._hideDatepicker()},today:function(){window["DP_jQuery_"+dpuuid].datepicker._gotoToday(n)},selectDay:function(){return window["DP_jQuery_"+dpuuid].datepicker._selectDay(n,+this.getAttribute("data-month"),+this.getAttribute("data-year"),this),!1},selectMonth:function(){return window["DP_jQuery_"+dpuuid].datepicker._selectMonthYear(n,this,"M"),!1},selectYear:function(){return window["DP_jQuery_"+dpuuid].datepicker._selectMonthYear(n,this,"Y"),!1}};$(this).bind(this.getAttribute("data-event"),e[this.getAttribute("data-handler")])})},_generateHTML:function(e){var t=new Date;t=this._daylightSavingAdjust(new Date(t.getFullYear(),t.getMonth(),t.getDate()));var n=this._get(e,"isRTL"),r=this._get(e,"showButtonPanel"),i=this._get(e,"hideIfNoPrevNext"),s=this._get(e,"navigationAsDateFormat"),o=this._getNumberOfMonths(e),u=this._get(e,"showCurrentAtPos"),a=this._get(e,"stepMonths"),f=o[0]!=1||o[1]!=1,l=this._daylightSavingAdjust(e.currentDay?new Date(e.currentYear,e.currentMonth,e.currentDay):new Date(9999,9,9)),c=this._getMinMaxDate(e,"min"),h=this._getMinMaxDate(e,"max"),p=e.drawMonth-u,d=e.drawYear;p<0&&(p+=12,d--);if(h){var v=this._daylightSavingAdjust(new Date(h.getFullYear(),h.getMonth()-o[0]*o[1]+1,h.getDate()));v=c&&vv)p--,p<0&&(p=11,d--)}e.drawMonth=p,e.drawYear=d;var m=this._get(e,"prevText");m=s?this.formatDate(m,this._daylightSavingAdjust(new Date(d,p-a,1)),this._getFormatConfig(e)):m;var g=this._canAdjustMonth(e,-1,d,p)?''+m+"":i?"":''+m+"",y=this._get(e,"nextText");y=s?this.formatDate(y,this._daylightSavingAdjust(new Date(d,p+a,1)),this._getFormatConfig(e)):y;var b=this._canAdjustMonth(e,1,d,p)?''+y+"":i?"":''+y+"",w=this._get(e,"currentText"),E=this._get(e,"gotoCurrent")&&e.currentDay?l:t;w=s?this.formatDate(w,E,this._getFormatConfig(e)):w;var S=e.inline?"":'",x=r?'
      '+(n?S:"")+(this._isInRange(e,E)?'":"")+(n?"":S)+"
      ":"",T=parseInt(this._get(e,"firstDay"),10);T=isNaN(T)?0:T;var N=this._get(e,"showWeek"),C=this._get(e,"dayNames"),k=this._get(e,"dayNamesShort"),L=this._get(e,"dayNamesMin"),A=this._get(e,"monthNames"),O=this._get(e,"monthNamesShort"),M=this._get(e,"beforeShowDay"),_=this._get(e,"showOtherMonths"),D=this._get(e,"selectOtherMonths"),P=this._get(e,"calculateWeek")||this.iso8601Week,H=this._getDefaultDate(e),B="";for(var j=0;j1)switch(I){case 0:U+=" ui-datepicker-group-first",R=" ui-corner-"+(n?"right":"left");break;case o[1]-1:U+=" ui-datepicker-group-last",R=" ui-corner-"+(n?"left":"right");break;default:U+=" ui-datepicker-group-middle",R=""}U+='">'}U+='
      '+(/all|left/.test(R)&&j==0?n?b:g:"")+(/all|right/.test(R)&&j==0?n?g:b:"")+this._generateMonthYearHeader(e,p,d,c,h,j>0||I>0,A,O)+'
      '+"";var z=N?'":"";for(var W=0;W<7;W++){var X=(W+T)%7;z+="=5?' class="ui-datepicker-week-end"':"")+">"+''+L[X]+""}U+=z+"";var V=this._getDaysInMonth(d,p);d==e.selectedYear&&p==e.selectedMonth&&(e.selectedDay=Math.min(e.selectedDay,V));var J=(this._getFirstDayOfMonth(d,p)-T+7)%7,K=Math.ceil((J+V)/7),Q=f?this.maxRows>K?this.maxRows:K:K;this.maxRows=Q;var G=this._daylightSavingAdjust(new Date(d,p,1-J));for(var Y=0;Y";var Z=N?'":"";for(var W=0;W<7;W++){var et=M?M.apply(e.input?e.input[0]:null,[G]):[!0,""],tt=G.getMonth()!=p,nt=tt&&!D||!et[0]||c&&Gh;Z+='",G.setDate(G.getDate()+1),G=this._daylightSavingAdjust(G)}U+=Z+""}p++,p>11&&(p=0,d++),U+="
      '+this._get(e,"weekHeader")+"
      '+this._get(e,"calculateWeek")(G)+""+(tt&&!_?" ":nt?''+G.getDate()+"":''+G.getDate()+"")+"
      "+(f?"
      "+(o[0]>0&&I==o[1]-1?'
      ':""):""),F+=U}B+=F}return B+=x+($.browser.msie&&parseInt($.browser.version,10)<7&&!e.inline?'':""),e._keyEvent=!1,B},_generateMonthYearHeader:function(e,t,n,r,i,s,o,u){var a=this._get(e,"changeMonth"),f=this._get(e,"changeYear"),l=this._get(e,"showMonthAfterYear"),c='
      ',h="";if(s||!a)h+=''+o[t]+"";else{var p=r&&r.getFullYear()==n,d=i&&i.getFullYear()==n;h+='"}l||(c+=h+(s||!a||!f?" ":""));if(!e.yearshtml){e.yearshtml="";if(s||!f)c+=''+n+"";else{var m=this._get(e,"yearRange").split(":"),g=(new Date).getFullYear(),y=function(e){var t=e.match(/c[+-].*/)?n+parseInt(e.substring(1),10):e.match(/[+-].*/)?g+parseInt(e,10):parseInt(e,10);return isNaN(t)?g:t},b=y(m[0]),w=Math.max(b,y(m[1]||""));b=r?Math.max(b,r.getFullYear()):b,w=i?Math.min(w,i.getFullYear()):w,e.yearshtml+='",c+=e.yearshtml,e.yearshtml=null}}return c+=this._get(e,"yearSuffix"),l&&(c+=(s||!a||!f?" ":"")+h),c+="
      ",c},_adjustInstDate:function(e,t,n){var r=e.drawYear+(n=="Y"?t:0),i=e.drawMonth+(n=="M"?t:0),s=Math.min(e.selectedDay,this._getDaysInMonth(r,i))+(n=="D"?t:0),o=this._restrictMinMax(e,this._daylightSavingAdjust(new Date(r,i,s)));e.selectedDay=o.getDate(),e.drawMonth=e.selectedMonth=o.getMonth(),e.drawYear=e.selectedYear=o.getFullYear(),(n=="M"||n=="Y")&&this._notifyChange(e)},_restrictMinMax:function(e,t){var n=this._getMinMaxDate(e,"min"),r=this._getMinMaxDate(e,"max"),i=n&&tr?r:i,i},_notifyChange:function(e){var t=this._get(e,"onChangeMonthYear");t&&t.apply(e.input?e.input[0]:null,[e.selectedYear,e.selectedMonth+1,e])},_getNumberOfMonths:function(e){var t=this._get(e,"numberOfMonths");return t==null?[1,1]:typeof t=="number"?[1,t]:t},_getMinMaxDate:function(e,t){return this._determineDate(e,this._get(e,t+"Date"),null)},_getDaysInMonth:function(e,t){return 32-this._daylightSavingAdjust(new Date(e,t,32)).getDate()},_getFirstDayOfMonth:function(e,t){return(new Date(e,t,1)).getDay()},_canAdjustMonth:function(e,t,n,r){var i=this._getNumberOfMonths(e),s=this._daylightSavingAdjust(new Date(n,r+(t<0?t:i[0]*i[1]),1));return t<0&&s.setDate(this._getDaysInMonth(s.getFullYear(),s.getMonth())),this._isInRange(e,s)},_isInRange:function(e,t){var n=this._getMinMaxDate(e,"min"),r=this._getMinMaxDate(e,"max");return(!n||t.getTime()>=n.getTime())&&(!r||t.getTime()<=r.getTime())},_getFormatConfig:function(e){var t=this._get(e,"shortYearCutoff");return t=typeof t!="string"?t:(new Date).getFullYear()%100+parseInt(t,10),{shortYearCutoff:t,dayNamesShort:this._get(e,"dayNamesShort"),dayNames:this._get(e,"dayNames"),monthNamesShort:this._get(e,"monthNamesShort"),monthNames:this._get(e,"monthNames")}},_formatDate:function(e,t,n,r){t||(e.currentDay=e.selectedDay,e.currentMonth=e.selectedMonth,e.currentYear=e.selectedYear);var i=t?typeof t=="object"?t:this._daylightSavingAdjust(new Date(r,n,t)):this._daylightSavingAdjust(new Date(e.currentYear,e.currentMonth,e.currentDay));return this.formatDate(this._get(e,"dateFormat"),i,this._getFormatConfig(e))}}),$.fn.datepicker=function(e){if(!this.length)return this;$.datepicker.initialized||($(document).mousedown($.datepicker._checkExternalClick).find(document.body).append($.datepicker.dpDiv),$.datepicker.initialized=!0);var t=Array.prototype.slice.call(arguments,1);return typeof e!="string"||e!="isDisabled"&&e!="getDate"&&e!="widget"?e=="option"&&arguments.length==2&&typeof arguments[1]=="string"?$.datepicker["_"+e+"Datepicker"].apply($.datepicker,[this[0]].concat(t)):this.each(function(){typeof e=="string"?$.datepicker["_"+e+"Datepicker"].apply($.datepicker,[this].concat(t)):$.datepicker._attachDatepicker(this,e)}):$.datepicker["_"+e+"Datepicker"].apply($.datepicker,[this[0]].concat(t))},$.datepicker=new Datepicker,$.datepicker.initialized=!1,$.datepicker.uuid=(new Date).getTime(),$.datepicker.version="1.9.0",window["DP_jQuery_"+dpuuid]=$})(jQuery);(function(e,t){var n="ui-dialog ui-widget ui-widget-content ui-corner-all ",r={buttons:!0,height:!0,maxHeight:!0,maxWidth:!0,minHeight:!0,minWidth:!0,width:!0},i={maxHeight:!0,maxWidth:!0,minHeight:!0,minWidth:!0};e.widget("ui.dialog",{version:"1.9.0",options:{autoOpen:!0,buttons:{},closeOnEscape:!0,closeText:"close",dialogClass:"",draggable:!0,hide:null,height:"auto",maxHeight:!1,maxWidth:!1,minHeight:150,minWidth:150,modal:!1,position:{my:"center",at:"center",of:window,collision:"fit",using:function(t){var n=e(this).css(t).offset().top;n<0&&e(this).css("top",t.top-n)}},resizable:!0,show:null,stack:!0,title:"",width:300,zIndex:1e3},_create:function(){this.originalTitle=this.element.attr("title"),typeof this.originalTitle!="string"&&(this.originalTitle=""),this.oldPosition={parent:this.element.parent(),index:this.element.parent().children().index(this.element)},this.options.title=this.options.title||this.originalTitle;var t=this,r=this.options,i=r.title||" ",s=(this.uiDialog=e("
      ")).addClass(n+r.dialogClass).css({display:"none",outline:0,zIndex:r.zIndex}).attr("tabIndex",-1).keydown(function(n){r.closeOnEscape&&!n.isDefaultPrevented()&&n.keyCode&&n.keyCode===e.ui.keyCode.ESCAPE&&(t.close(n),n.preventDefault())}).mousedown(function(e){t.moveToTop(!1,e)}).appendTo("body"),o=this.element.show().removeAttr("title").addClass("ui-dialog-content ui-widget-content").appendTo(s),u=(this.uiDialogTitlebar=e("
      ")).addClass("ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix").prependTo(s),a=e("").addClass("ui-dialog-titlebar-close ui-corner-all").attr("role","button").click(function(e){e.preventDefault(),t.close(e)}).appendTo(u),f=(this.uiDialogTitlebarCloseText=e("")).addClass("ui-icon ui-icon-closethick").text(r.closeText).appendTo(a),l=e("").uniqueId().addClass("ui-dialog-title").html(i).prependTo(u),c=(this.uiDialogButtonPane=e("
      ")).addClass("ui-dialog-buttonpane ui-widget-content ui-helper-clearfix"),h=(this.uiButtonSet=e("
      ")).addClass("ui-dialog-buttonset").appendTo(c);s.attr({role:"dialog","aria-labelledby":l.attr("id")}),u.find("*").add(u).disableSelection(),this._hoverable(a),this._focusable(a),r.draggable&&e.fn.draggable&&this._makeDraggable(),r.resizable&&e.fn.resizable&&this._makeResizable(),this._createButtons(r.buttons),this._isOpen=!1,e.fn.bgiframe&&s.bgiframe(),this._on(s,{keydown:function(t){if(!r.modal||t.keyCode!==e.ui.keyCode.TAB)return;var n=e(":tabbable",s),i=n.filter(":first"),o=n.filter(":last");if(t.target===o[0]&&!t.shiftKey)return i.focus(1),!1;if(t.target===i[0]&&t.shiftKey)return o.focus(1),!1}})},_init:function(){this.options.autoOpen&&this.open()},_destroy:function(){var e,t=this.oldPosition;this.overlay&&this.overlay.destroy(),this.uiDialog.hide(),this.element.removeClass("ui-dialog-content ui-widget-content").hide().appendTo("body"),this.uiDialog.remove(),this.originalTitle&&this.element.attr("title",this.originalTitle),e=t.parent.children().eq(t.index),e.length&&e[0]!==this.element[0]?e.before(this.element):t.parent.append(this.element)},widget:function(){return this.uiDialog},close:function(t){var n=this,r,i;if(!this._isOpen)return;if(!1===this._trigger("beforeClose",t))return;return this._isOpen=!1,this.overlay&&this.overlay.destroy(),this.options.hide?this.uiDialog.hide(this.options.hide,function(){n._trigger("close",t)}):(this.uiDialog.hide(),this._trigger("close",t)),e.ui.dialog.overlay.resize(),this.options.modal&&(r=0,e(".ui-dialog").each(function(){this!==n.uiDialog[0]&&(i=e(this).css("z-index"),isNaN(i)||(r=Math.max(r,i)))}),e.ui.dialog.maxZ=r),this},isOpen:function(){return this._isOpen},moveToTop:function(t,n){var r=this.options,i;return r.modal&&!t||!r.stack&&!r.modal?this._trigger("focus",n):(r.zIndex>e.ui.dialog.maxZ&&(e.ui.dialog.maxZ=r.zIndex),this.overlay&&(e.ui.dialog.maxZ+=1,e.ui.dialog.overlay.maxZ=e.ui.dialog.maxZ,this.overlay.$el.css("z-index",e.ui.dialog.overlay.maxZ)),i={scrollTop:this.element.scrollTop(),scrollLeft:this.element.scrollLeft()},e.ui.dialog.maxZ+=1,this.uiDialog.css("z-index",e.ui.dialog.maxZ),this.element.attr(i),this._trigger("focus",n),this)},open:function(){if(this._isOpen)return;var t,n=this.options,r=this.uiDialog;return this._size(),this._position(n.position),r.show(n.show),this.overlay=n.modal?new e.ui.dialog.overlay(this):null,this.moveToTop(!0),t=this.element.find(":tabbable"),t.length||(t=this.uiDialogButtonPane.find(":tabbable"),t.length||(t=r)),t.eq(0).focus(),this._isOpen=!0,this._trigger("open"),this},_createButtons:function(t){var n,r,i=this,s=!1;this.uiDialogButtonPane.remove(),this.uiButtonSet.empty(),typeof t=="object"&&t!==null&&e.each(t,function(){return!(s=!0)}),s?(e.each(t,function(t,n){n=e.isFunction(n)?{click:n,text:t}:n;var r=e("
      ").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()},value:function(e){return e===t?this._value():(this._setOption("value",e),this)},_setOption:function(e,t){e==="value"&&(this.options.value=t,this._refreshValue(),this._value()===this.options.max&&this._trigger("complete")),this._super(e,t)},_value:function(){var e=this.options.value;return typeof e!="number"&&(e=0),Math.min(this.options.max,Math.max(this.min,e))},_percentage:function(){return 100*this._value()/this.options.max},_refreshValue:function(){var e=this.value(),t=this._percentage();this.oldValue!==e&&(this.oldValue=e,this._trigger("change")),this.valueDiv.toggle(e>this.min).toggleClass("ui-corner-right",e===this.options.max).width(t.toFixed(0)+"%"),this.element.attr("aria-valuenow",e)}})})(jQuery);(function(e,t){var n=5;e.widget("ui.slider",e.ui.mouse,{version:"1.9.0",widgetEventPrefix:"slide",options:{animate:!1,distance:0,max:100,min:0,orientation:"horizontal",range:!1,step:1,value:0,values:null},_create:function(){var t,r=this.options,i=this.element.find(".ui-slider-handle").addClass("ui-state-default ui-corner-all"),s="",o=r.values&&r.values.length||1,u=[];this._keySliding=!1,this._mouseSliding=!1,this._animateOff=!0,this._handleIndex=null,this._detectOrientation(),this._mouseInit(),this.element.addClass("ui-slider ui-slider-"+this.orientation+" ui-widget"+" ui-widget-content"+" ui-corner-all"+(r.disabled?" ui-slider-disabled ui-disabled":"")),this.range=e([]),r.range&&(r.range===!0&&(r.values||(r.values=[this._valueMin(),this._valueMin()]),r.values.length&&r.values.length!==2&&(r.values=[r.values[0],r.values[0]])),this.range=e("
      ").appendTo(this.element).addClass("ui-slider-range ui-widget-header"+(r.range==="min"||r.range==="max"?" ui-slider-range-"+r.range:"")));for(t=i.length;tn&&(i=n,s=e(this),o=t)}),c.range===!0&&this.values(1)===c.min&&(o+=1,s=e(this.handles[o])),u=this._start(t,o),u===!1?!1:(this._mouseSliding=!0,this._handleIndex=o,s.addClass("ui-state-active").focus(),a=s.offset(),f=!e(t.target).parents().andSelf().is(".ui-slider-handle"),this._clickOffset=f?{left:0,top:0}:{left:t.pageX-a.left-s.width()/2,top:t.pageY-a.top-s.height()/2-(parseInt(s.css("borderTopWidth"),10)||0)-(parseInt(s.css("borderBottomWidth"),10)||0)+(parseInt(s.css("marginTop"),10)||0)},this.handles.hasClass("ui-state-hover")||this._slide(t,o,r),this._animateOff=!0,!0))},_mouseStart:function(e){return!0},_mouseDrag:function(e){var t={x:e.pageX,y:e.pageY},n=this._normValueFromMouse(t);return this._slide(e,this._handleIndex,n),!1},_mouseStop:function(e){return this.handles.removeClass("ui-state-active"),this._mouseSliding=!1,this._stop(e,this._handleIndex),this._change(e,this._handleIndex),this._handleIndex=null,this._clickOffset=null,this._animateOff=!1,!1},_detectOrientation:function(){this.orientation=this.options.orientation==="vertical"?"vertical":"horizontal"},_normValueFromMouse:function(e){var t,n,r,i,s;return this.orientation==="horizontal"?(t=this.elementSize.width,n=e.x-this.elementOffset.left-(this._clickOffset?this._clickOffset.left:0)):(t=this.elementSize.height,n=e.y-this.elementOffset.top-(this._clickOffset?this._clickOffset.top:0)),r=n/t,r>1&&(r=1),r<0&&(r=0),this.orientation==="vertical"&&(r=1-r),i=this._valueMax()-this._valueMin(),s=this._valueMin()+r*i,this._trimAlignValue(s)},_start:function(e,t){var n={handle:this.handles[t],value:this.value()};return this.options.values&&this.options.values.length&&(n.value=this.values(t),n.values=this.values()),this._trigger("start",e,n)},_slide:function(e,t,n){var r,i,s;this.options.values&&this.options.values.length?(r=this.values(t?0:1),this.options.values.length===2&&this.options.range===!0&&(t===0&&n>r||t===1&&n1){this.options.values[t]=this._trimAlignValue(n),this._refreshValue(),this._change(null,t);return}if(!arguments.length)return this._values();if(!e.isArray(arguments[0]))return this.options.values&&this.options.values.length?this._values(t):this.value();r=this.options.values,i=arguments[0];for(s=0;s=this._valueMax())return this._valueMax();var t=this.options.step>0?this.options.step:1,n=(e-this._valueMin())%t,r=e-n;return Math.abs(n)*2>=t&&(r+=n>0?t:-t),parseFloat(r.toFixed(5))},_valueMin:function(){return this.options.min},_valueMax:function(){return this.options.max},_refreshValue:function(){var t,n,r,i,s,o=this.options.range,u=this.options,a=this,f=this._animateOff?!1:u.animate,l={};this.options.values&&this.options.values.length?this.handles.each(function(r,i){n=(a.values(r)-a._valueMin())/(a._valueMax()-a._valueMin())*100,l[a.orientation==="horizontal"?"left":"bottom"]=n+"%",e(this).stop(1,1)[f?"animate":"css"](l,u.animate),a.options.range===!0&&(a.orientation==="horizontal"?(r===0&&a.range.stop(1,1)[f?"animate":"css"]({left:n+"%"},u.animate),r===1&&a.range[f?"animate":"css"]({width:n-t+"%"},{queue:!1,duration:u.animate})):(r===0&&a.range.stop(1,1)[f?"animate":"css"]({bottom:n+"%"},u.animate),r===1&&a.range[f?"animate":"css"]({height:n-t+"%"},{queue:!1,duration:u.animate}))),t=n}):(r=this.value(),i=this._valueMin(),s=this._valueMax(),n=s!==i?(r-i)/(s-i)*100:0,l[this.orientation==="horizontal"?"left":"bottom"]=n+"%",this.handle.stop(1,1)[f?"animate":"css"](l,u.animate),o==="min"&&this.orientation==="horizontal"&&this.range.stop(1,1)[f?"animate":"css"]({width:n+"%"},u.animate),o==="max"&&this.orientation==="horizontal"&&this.range[f?"animate":"css"]({width:100-n+"%"},{queue:!1,duration:u.animate}),o==="min"&&this.orientation==="vertical"&&this.range.stop(1,1)[f?"animate":"css"]({height:n+"%"},u.animate),o==="max"&&this.orientation==="vertical"&&this.range[f?"animate":"css"]({height:100-n+"%"},{queue:!1,duration:u.animate}))}})})(jQuery);(function(e){function t(e){return function(){var t=this.element.val();e.apply(this,arguments),this._refresh(),t!==this.element.val()&&this._trigger("change")}}e.widget("ui.spinner",{version:"1.9.0",defaultElement:"",widgetEventPrefix:"spin",options:{culture:null,icons:{down:"ui-icon-triangle-1-s",up:"ui-icon-triangle-1-n"},incremental:!0,max:null,min:null,numberFormat:null,page:10,step:1,change:null,spin:null,start:null,stop:null},_create:function(){this._setOption("max",this.options.max),this._setOption("min",this.options.min),this._setOption("step",this.options.step),this._value(this.element.val(),!0),this._draw(),this._on(this._events),this._refresh(),this._on(this.window,{beforeunload:function(){this.element.removeAttr("autocomplete")}})},_getCreateOptions:function(){var t={},n=this.element;return e.each(["min","max","step"],function(e,r){var i=n.attr(r);i!==undefined&&i.length&&(t[r]=i)}),t},_events:{keydown:function(e){this._start(e)&&this._keydown(e)&&e.preventDefault()},keyup:"_stop",focus:function(){this.uiSpinner.addClass("ui-state-active"),this.previous=this.element.val()},blur:function(e){if(this.cancelBlur){delete this.cancelBlur;return}this._refresh(),this.uiSpinner.removeClass("ui-state-active"),this.previous!==this.element.val()&&this._trigger("change",e)},mousewheel:function(e,t){if(!t)return;if(!this.spinning&&!this._start(e))return!1;this._spin((t>0?1:-1)*this.options.step,e),clearTimeout(this.mousewheelTimer),this.mousewheelTimer=this._delay(function(){this.spinning&&this._stop(e)},100),e.preventDefault()},"mousedown .ui-spinner-button":function(t){function r(){var e=this.element[0]===this.document[0].activeElement;e||(this.element.focus(),this.previous=n,this._delay(function(){this.previous=n}))}var n;n=this.element[0]===this.document[0].activeElement?this.previous:this.element.val(),t.preventDefault(),r.call(this),this.cancelBlur=!0,this._delay(function(){delete this.cancelBlur,r.call(this)});if(this._start(t)===!1)return;this._repeat(null,e(t.currentTarget).hasClass("ui-spinner-up")?1:-1,t)},"mouseup .ui-spinner-button":"_stop","mouseenter .ui-spinner-button":function(t){if(!e(t.currentTarget).hasClass("ui-state-active"))return;if(this._start(t)===!1)return!1;this._repeat(null,e(t.currentTarget).hasClass("ui-spinner-up")?1:-1,t)},"mouseleave .ui-spinner-button":"_stop"},_draw:function(){var e=this.uiSpinner=this.element.addClass("ui-spinner-input").attr("autocomplete","off").wrap(this._uiSpinnerHtml()).parent().append(this._buttonHtml());this._hoverable(e),this.element.attr("role","spinbutton"),this.buttons=e.find(".ui-spinner-button").attr("tabIndex",-1).button().removeClass("ui-corner-all"),this.buttons.height()>Math.ceil(e.height()*.5)&&e.height()>0&&e.height(e.height()),this.options.disabled&&this.disable()},_keydown:function(t){var n=this.options,r=e.ui.keyCode;switch(t.keyCode){case r.UP:return this._repeat(null,1,t),!0;case r.DOWN:return this._repeat(null,-1,t),!0;case r.PAGE_UP:return this._repeat(null,n.page,t),!0;case r.PAGE_DOWN:return this._repeat(null,-n.page,t),!0}return!1},_uiSpinnerHtml:function(){return""},_buttonHtml:function(){return""+""+""+""+""},_start:function(e){return!this.spinning&&this._trigger("start",e)===!1?!1:(this.counter||(this.counter=1),this.spinning=!0,!0)},_repeat:function(e,t,n){e=e||500,clearTimeout(this.timer),this.timer=this._delay(function(){this._repeat(40,t,n)},e),this._spin(t*this.options.step,n)},_spin:function(e,t){var n=this.value()||0;this.counter||(this.counter=1),n=this._adjustValue(n+e*this._increment(this.counter));if(!this.spinning||this._trigger("spin",t,{value:n})!==!1)this._value(n),this.counter++},_increment:function(t){var n=this.options.incremental;return n?e.isFunction(n)?n(t):Math.floor(t*t*t/5e4-t*t/500+17*t/200+1):1},_precision:function(){var e=this._precisionOf(this.options.step);return this.options.min!==null&&(e=Math.max(e,this._precisionOf(this.options.min))),e},_precisionOf:function(e){var t=e.toString(),n=t.indexOf(".");return n===-1?0:t.length-n-1},_adjustValue:function(e){var t,n,r=this.options;return t=r.min!==null?r.min:0,n=e-t,n=Math.round(n/r.step)*r.step,e=t+n,e=parseFloat(e.toFixed(this._precision())),r.max!==null&&e>r.max?r.max:r.min!==null&&e1&&e.href.replace(r,"")===location.href.replace(r,"")}var n=0,r=/#.*$/;e.widget("ui.tabs",{version:"1.9.0",delay:300,options:{active:null,collapsible:!1,event:"click",heightStyle:"content",hide:null,show:null,activate:null,beforeActivate:null,beforeLoad:null,load:null},_create:function(){var t,n=this,r=this.options,i=r.active;this.running=!1,this.element.addClass("ui-tabs ui-widget ui-widget-content ui-corner-all").toggleClass("ui-tabs-collapsible",r.collapsible).delegate(".ui-tabs-nav > li","mousedown"+this.eventNamespace,function(t){e(this).is(".ui-state-disabled")&&t.preventDefault()}).delegate(".ui-tabs-anchor","focus"+this.eventNamespace,function(){e(this).closest("li").is(".ui-state-disabled")&&this.blur()}),this._processTabs();if(i===null){location.hash&&this.anchors.each(function(e,t){if(t.hash===location.hash)return i=e,!1}),i===null&&(i=this.tabs.filter(".ui-tabs-active").index());if(i===null||i===-1)i=this.tabs.length?0:!1}i!==!1&&(i=this.tabs.index(this.tabs.eq(i)),i===-1&&(i=r.collapsible?!1:0)),r.active=i,!r.collapsible&&r.active===!1&&this.anchors.length&&(r.active=0),e.isArray(r.disabled)&&(r.disabled=e.unique(r.disabled.concat(e.map(this.tabs.filter(".ui-state-disabled"),function(e){return n.tabs.index(e)}))).sort()),this.options.active!==!1&&this.anchors.length?this.active=this._findActive(this.options.active):this.active=e(),this._refresh(),this.active.length&&this.load(r.active)},_getCreateEventData:function(){return{tab:this.active,panel:this.active.length?this._getPanelForTab(this.active):e()}},_tabKeydown:function(t){var n=e(this.document[0].activeElement).closest("li"),r=this.tabs.index(n),i=!0;if(this._handlePageNav(t))return;switch(t.keyCode){case e.ui.keyCode.RIGHT:case e.ui.keyCode.DOWN:r++;break;case e.ui.keyCode.UP:case e.ui.keyCode.LEFT:i=!1,r--;break;case e.ui.keyCode.END:r=this.anchors.length-1;break;case e.ui.keyCode.HOME:r=0;break;case e.ui.keyCode.SPACE:t.preventDefault(),clearTimeout(this.activating),this._activate(r);return;case e.ui.keyCode.ENTER:t.preventDefault(),clearTimeout(this.activating),this._activate(r===this.options.active?!1:r);return;default:return}t.preventDefault(),clearTimeout(this.activating),r=this._focusNextTab(r,i),t.ctrlKey||(n.attr("aria-selected","false"),this.tabs.eq(r).attr("aria-selected","true"),this.activating=this._delay(function(){this.option("active",r)},this.delay))},_panelKeydown:function(t){if(this._handlePageNav(t))return;t.ctrlKey&&t.keyCode===e.ui.keyCode.UP&&(t.preventDefault(),this.active.focus())},_handlePageNav:function(t){if(t.altKey&&t.keyCode===e.ui.keyCode.PAGE_UP)return this._activate(this._focusNextTab(this.options.active-1,!1)),!0;if(t.altKey&&t.keyCode===e.ui.keyCode.PAGE_DOWN)return this._activate(this._focusNextTab(this.options.active+1,!0)),!0},_findNextTab:function(t,n){function i(){return t>r&&(t=0),t<0&&(t=r),t}var r=this.tabs.length-1;while(e.inArray(i(),this.options.disabled)!==-1)t=n?t+1:t-1;return t},_focusNextTab:function(e,t){return e=this._findNextTab(e,t),this.tabs.eq(e).focus(),e},_setOption:function(e,t){if(e==="active"){this._activate(t);return}if(e==="disabled"){this._setupDisabled(t);return}this._super(e,t),e==="collapsible"&&(this.element.toggleClass("ui-tabs-collapsible",t),!t&&this.options.active===!1&&this._activate(0)),e==="event"&&this._setupEvents(t),e==="heightStyle"&&this._setupHeightStyle(t)},_tabId:function(e){return e.attr("aria-controls")||"ui-tabs-"+i()},_sanitizeSelector:function(e){return e?e.replace(/[!"$%&'()*+,.\/:;<=>?@\[\]\^`{|}~]/g,"\\$&"):""},refresh:function(){var t,n=this.options,r=this.tablist.children(":has(a[href])");n.disabled=e.map(r.filter(".ui-state-disabled"),function(e){return r.index(e)}),this._processTabs(),n.active===!1||!this.anchors.length?(n.active=!1,this.active=e()):this.active.length&&!e.contains(this.tablist[0],this.active[0])?this.tabs.length===n.disabled.length?(n.active=!1,this.active=e()):this._activate(this._findNextTab(Math.max(0,n.active-1),!1)):n.active=this.tabs.index(this.active),this._refresh()},_refresh:function(){this._setupDisabled(this.options.disabled),this._setupEvents(this.options.event),this._setupHeightStyle(this.options.heightStyle),this.tabs.not(this.active).attr({"aria-selected":"false",tabIndex:-1}),this.panels.not(this._getPanelForTab(this.active)).hide().attr({"aria-expanded":"false","aria-hidden":"true"}),this.active.length?(this.active.addClass("ui-tabs-active ui-state-active").attr({"aria-selected":"true",tabIndex:0}),this._getPanelForTab(this.active).show().attr({"aria-expanded":"true","aria-hidden":"false"})):this.tabs.eq(0).attr("tabIndex",0)},_processTabs:function(){var t=this;this.tablist=this._getList().addClass("ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all").attr("role","tablist"),this.tabs=this.tablist.find("> li:has(a[href])").addClass("ui-state-default ui-corner-top").attr({role:"tab",tabIndex:-1}),this.anchors=this.tabs.map(function(){return e("a",this)[0]}).addClass("ui-tabs-anchor").attr({role:"presentation",tabIndex:-1}),this.panels=e(),this.anchors.each(function(n,r){var i,o,u,a=e(r).uniqueId().attr("id"),f=e(r).closest("li"),l=f.attr("aria-controls");s(r)?(i=r.hash,o=t.element.find(t._sanitizeSelector(i))):(u=t._tabId(f),i="#"+u,o=t.element.find(i),o.length||(o=t._createPanel(u),o.insertAfter(t.panels[n-1]||t.tablist)),o.attr("aria-live","polite")),o.length&&(t.panels=t.panels.add(o)),l&&f.data("ui-tabs-aria-controls",l),f.attr({"aria-controls":i.substring(1),"aria-labelledby":a}),o.attr("aria-labelledby",a)}),this.panels.addClass("ui-tabs-panel ui-widget-content ui-corner-bottom").attr("role","tabpanel")},_getList:function(){return this.element.find("ol,ul").eq(0)},_createPanel:function(t){return e("
      ").attr("id",t).addClass("ui-tabs-panel ui-widget-content ui-corner-bottom").data("ui-tabs-destroy",!0)},_setupDisabled:function(t){e.isArray(t)&&(t.length?t.length===this.anchors.length&&(t=!0):t=!1);for(var n=0,r;r=this.tabs[n];n++)t===!0||e.inArray(n,t)!==-1?e(r).addClass("ui-state-disabled").attr("aria-disabled","true"):e(r).removeClass("ui-state-disabled").removeAttr("aria-disabled");this.options.disabled=t},_setupEvents:function(t){var n={click:function(e){e.preventDefault()}};t&&e.each(t.split(" "),function(e,t){n[t]="_eventHandler"}),this._off(this.anchors.add(this.tabs).add(this.panels)),this._on(this.anchors,n),this._on(this.tabs,{keydown:"_tabKeydown"}),this._on(this.panels,{keydown:"_panelKeydown"}),this._focusable(this.tabs),this._hoverable(this.tabs)},_setupHeightStyle:function(t){var n,r,i=this.element.parent();t==="fill"?(e.support.minHeight||(r=i.css("overflow"),i.css("overflow","hidden")),n=i.height(),this.element.siblings(":visible").each(function(){var t=e(this),r=t.css("position");if(r==="absolute"||r==="fixed")return;n-=t.outerHeight(!0)}),r&&i.css("overflow",r),this.element.children().not(this.panels).each(function(){n-=e(this).outerHeight(!0)}),this.panels.each(function(){e(this).height(Math.max(0,n-e(this).innerHeight()+e(this).height()))}).css("overflow","auto")):t==="auto"&&(n=0,this.panels.each(function(){n=Math.max(n,e(this).height("").height())}).height(n))},_eventHandler:function(t){var n=this.options,r=this.active,i=e(t.currentTarget),s=i.closest("li"),o=s[0]===r[0],u=o&&n.collapsible,a=u?e():this._getPanelForTab(s),f=r.length?this._getPanelForTab(r):e(),l={oldTab:r,oldPanel:f,newTab:u?e():s,newPanel:a};t.preventDefault();if(s.hasClass("ui-state-disabled")||s.hasClass("ui-tabs-loading")||this.running||o&&!n.collapsible||this._trigger("beforeActivate",t,l)===!1)return;n.active=u?!1:this.tabs.index(s),this.active=o?e():s,this.xhr&&this.xhr.abort(),!f.length&&!a.length&&e.error("jQuery UI Tabs: Mismatching fragment identifier."),a.length&&this.load(this.tabs.index(s),t),this._toggle(t,l)},_toggle:function(t,n){function o(){r.running=!1,r._trigger("activate",t,n)}function u(){n.newTab.closest("li").addClass("ui-tabs-active ui-state-active"),i.length&&r.options.show?r._show(i,r.options.show,o):(i.show(),o())}var r=this,i=n.newPanel,s=n.oldPanel;this.running=!0,s.length&&this.options.hide?this._hide(s,this.options.hide,function(){n.oldTab.closest("li").removeClass("ui-tabs-active ui-state-active"),u()}):(n.oldTab.closest("li").removeClass("ui-tabs-active ui-state-active"),s.hide(),u()),s.attr({"aria-expanded":"false","aria-hidden":"true"}),n.oldTab.attr("aria-selected","false"),i.length&&s.length?n.oldTab.attr("tabIndex",-1):i.length&&this.tabs.filter(function(){return e(this).attr("tabIndex")===0}).attr("tabIndex",-1),i.attr({"aria-expanded":"true","aria-hidden":"false"}),n.newTab.attr({"aria-selected":"true",tabIndex:0})},_activate:function(t){var n,r=this._findActive(t);if(r[0]===this.active[0])return;r.length||(r=this.active),n=r.find(".ui-tabs-anchor")[0],this._eventHandler({target:n,currentTarget:n,preventDefault:e.noop})},_findActive:function(t){return t===!1?e():this.tabs.eq(t)},_getIndex:function(e){return typeof e=="string"&&(e=this.anchors.index(this.anchors.filter("[href$='"+e+"']"))),e},_destroy:function(){this.xhr&&this.xhr.abort(),this.element.removeClass("ui-tabs ui-widget ui-widget-content ui-corner-all ui-tabs-collapsible"),this.tablist.removeClass("ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all").removeAttr("role"),this.anchors.removeClass("ui-tabs-anchor").removeAttr("role").removeAttr("tabIndex").removeData("href.tabs").removeData("load.tabs").removeUniqueId(),this.tabs.add(this.panels).each(function(){e.data(this,"ui-tabs-destroy")?e(this).remove():e(this).removeClass("ui-state-default ui-state-active ui-state-disabled ui-corner-top ui-corner-bottom ui-widget-content ui-tabs-active ui-tabs-panel").removeAttr("tabIndex").removeAttr("aria-live").removeAttr("aria-busy").removeAttr("aria-selected").removeAttr("aria-labelledby").removeAttr("aria-hidden").removeAttr("aria-expanded").removeAttr("role")}),this.tabs.each(function(){var t=e(this),n=t.data("ui-tabs-aria-controls");n?t.attr("aria-controls",n):t.removeAttr("aria-controls")}),this.options.heightStyle!=="content"&&this.panels.css("height","")},enable:function(n){var r=this.options.disabled;if(r===!1)return;n===t?r=!1:(n=this._getIndex(n),e.isArray(r)?r=e.map(r,function(e){return e!==n?e:null}):r=e.map(this.tabs,function(e,t){return t!==n?t:null})),this._setupDisabled(r)},disable:function(n){var r=this.options.disabled;if(r===!0)return;if(n===t)r=!0;else{n=this._getIndex(n);if(e.inArray(n,r)!==-1)return;e.isArray(r)?r=e.merge([n],r).sort():r=[n]}this._setupDisabled(r)},load:function(t,n){t=this._getIndex(t);var r=this,i=this.tabs.eq(t),o=i.find(".ui-tabs-anchor"),u=this._getPanelForTab(i),a={tab:i,panel:u};if(s(o[0]))return;this.xhr=e.ajax(this._ajaxSettings(o,n,a)),this.xhr&&this.xhr.statusText!=="canceled"&&(i.addClass("ui-tabs-loading"),u.attr("aria-busy","true"),this.xhr.success(function(e){setTimeout(function(){u.html(e),r._trigger("load",n,a)},1)}).complete(function(e,t){setTimeout(function(){t==="abort"&&r.panels.stop(!1,!0),i.removeClass("ui-tabs-loading"),u.removeAttr("aria-busy"),e===r.xhr&&delete r.xhr},1)}))},_ajaxSettings:function(t,n,r){var i=this;return{url:t.attr("href"),beforeSend:function(t,s){return i._trigger("beforeLoad",n,e.extend({jqXHR:t,ajaxSettings:s},r))}}},_getPanelForTab:function(t){var n=e(t).attr("aria-controls");return this.element.find(this._sanitizeSelector("#"+n))}}),e.uiBackCompat!==!1&&(e.ui.tabs.prototype._ui=function(e,t){return{tab:e,panel:t,index:this.anchors.index(e)}},e.widget("ui.tabs",e.ui.tabs,{url:function(e,t){this.anchors.eq(e).attr("href",t)}}),e.widget("ui.tabs",e.ui.tabs,{options:{ajaxOptions:null,cache:!1},_create:function(){this._super();var t=this;this._on({tabsbeforeload:function(n,r){if(e.data(r.tab[0],"cache.tabs")){n.preventDefault();return}r.jqXHR.success(function(){t.options.cache&&e.data(r.tab[0],"cache.tabs",!0)})}})},_ajaxSettings:function(t,n,r){var i=this.options.ajaxOptions;return e.extend({},i,{error:function(e,t,n){try{i.error(e,t,r.tab.closest("li").index(),r.tab[0])}catch(n){}}},this._superApply(arguments))},_setOption:function(e,t){e==="cache"&&t===!1&&this.anchors.removeData("cache.tabs"),this._super(e,t)},_destroy:function(){this.anchors.removeData("cache.tabs"),this._super()},url:function(e,t){this.anchors.eq(e).removeData("cache.tabs"),this._superApply(arguments)}}),e.widget("ui.tabs",e.ui.tabs,{abort:function(){this.xhr&&this.xhr.abort()}}),e.widget("ui.tabs",e.ui.tabs,{options:{spinner:"Loading…"},_create:function(){this._super(),this._on({tabsbeforeload:function(e,t){if(e.target!==this.element[0]||!this.options.spinner)return;var n=t.tab.find("span"),r=n.html();n.html(this.options.spinner),t.jqXHR.complete(function(){n.html(r)})}})}}),e.widget("ui.tabs",e.ui.tabs,{options:{enable:null,disable:null},enable:function(t){var n=this.options,r;if(t&&n.disabled===!0||e.isArray(n.disabled)&&e.inArray(t,n.disabled)!==-1)r=!0;this._superApply(arguments),r&&this._trigger("enable",null,this._ui(this.anchors[t],this.panels[t]))},disable:function(t){var n=this.options,r;if(t&&n.disabled===!1||e.isArray(n.disabled)&&e.inArray(t,n.disabled)===-1)r=!0;this._superApply(arguments),r&&this._trigger("disable",null,this._ui(this.anchors[t],this.panels[t]))}}),e.widget("ui.tabs",e.ui.tabs,{options:{add:null,remove:null,tabTemplate:"
    1. #{label}
    2. "},add:function(n,r,i){i===t&&(i=this.anchors.length);var s,o,u=this.options,a=e(u.tabTemplate.replace(/#\{href\}/g,n).replace(/#\{label\}/g,r)),f=n.indexOf("#")?this._tabId(a):n.replace("#","");return a.addClass("ui-state-default ui-corner-top").data("ui-tabs-destroy",!0),a.attr("aria-controls",f),s=i>=this.tabs.length,o=this.element.find("#"+f),o.length||(o=this._createPanel(f),s?i>0?o.insertAfter(this.panels.eq(-1)):o.appendTo(this.element):o.insertBefore(this.panels[i])),o.addClass("ui-tabs-panel ui-widget-content ui-corner-bottom").hide(),s?a.appendTo(this.tablist):a.insertBefore(this.tabs[i]),u.disabled=e.map(u.disabled,function(e){return e>=i?++e:e}),this.refresh(),this.tabs.length===1&&u.active===!1&&this.option("active",0),this._trigger("add",null,this._ui(this.anchors[i],this.panels[i])),this},remove:function(t){t=this._getIndex(t);var n=this.options,r=this.tabs.eq(t).remove(),i=this._getPanelForTab(r).remove();return r.hasClass("ui-tabs-active")&&this.anchors.length>2&&this._activate(t+(t+1=t?--e:e}),this.refresh(),this._trigger("remove",null,this._ui(r.find("a")[0],i[0])),this}}),e.widget("ui.tabs",e.ui.tabs,{length:function(){return this.anchors.length}}),e.widget("ui.tabs",e.ui.tabs,{options:{idPrefix:"ui-tabs-"},_tabId:function(t){var n=t.is("li")?t.find("a[href]"):t;return n=n[0],e(n).closest("li").attr("aria-controls")||n.title&&n.title.replace(/\s/g,"_").replace(/[^\w\u00c0-\uFFFF\-]/g,"")||this.options.idPrefix+i()}}),e.widget("ui.tabs",e.ui.tabs,{options:{panelTemplate:"
      "},_createPanel:function(t){return e(this.options.panelTemplate).attr("id",t).addClass("ui-tabs-panel ui-widget-content ui-corner-bottom").data("ui-tabs-destroy",!0)}}),e.widget("ui.tabs",e.ui.tabs,{_create:function(){var e=this.options;e.active===null&&e.selected!==t&&(e.active=e.selected===-1?!1:e.selected),this._super(),e.selected=e.active,e.selected===!1&&(e.selected=-1)},_setOption:function(e,t){if(e!=="selected")return this._super(e,t);var n=this.options;this._super("active",t===-1?!1:t),n.selected=n.active,n.selected===!1&&(n.selected=-1)},_eventHandler:function(e){this._superApply(arguments),this.options.selected=this.options.active,this.options.selected===!1&&(this.options.selected=-1)}}),e.widget("ui.tabs",e.ui.tabs,{options:{show:null,select:null},_create:function(){this._super(),this.options.active!==!1&&this._trigger("show",null,this._ui(this.active.find(".ui-tabs-anchor")[0],this._getPanelForTab(this.active)[0]))},_trigger:function(e,t,n){var r=this._superApply(arguments);return r?(e==="beforeActivate"&&n.newTab.length?r=this._super("select",t,{tab:n.newTab.find(".ui-tabs-anchor")[0],panel:n.newPanel[0],index:n.newTab.closest("li").index()}):e==="activate"&&n.newTab.length&&(r=this._super("show",t,{tab:n.newTab.find(".ui-tabs-anchor")[0],panel:n.newPanel[0],index:n.newTab.closest("li").index()})),r):!1}}),e.widget("ui.tabs",e.ui.tabs,{select:function(e){e=this._getIndex(e);if(e===-1){if(!this.options.collapsible||this.options.selected===-1)return;e=this.options.selected}this.anchors.eq(e).trigger(this.options.event+this.eventNamespace)}}),function(){var t=0;e.widget("ui.tabs",e.ui.tabs,{options:{cookie:null},_create:function(){var e=this.options,t;e.active==null&&e.cookie&&(t=parseInt(this._cookie(),10),t===-1&&(t=!1),e.active=t),this._super()},_cookie:function(n){var r=[this.cookie||(this.cookie=this.options.cookie.name||"ui-tabs-"+ ++t)];return arguments.length&&(r.push(n===!1?-1:n),r.push(this.options.cookie)),e.cookie.apply(null,r)},_refresh:function(){this._super(),this.options.cookie&&this._cookie(this.options.active,this.options.cookie)},_eventHandler:function(e){this._superApply(arguments),this.options.cookie&&this._cookie(this.options.active,this.options.cookie)},_destroy:function(){this._super(),this.options.cookie&&this._cookie(null,this.options.cookie)}})}(),e.widget("ui.tabs",e.ui.tabs,{_trigger:function(t,n,r){var i=e.extend({},r);return t==="load"&&(i.panel=i.panel[0],i.tab=i.tab.find(".ui-tabs-anchor")[0]),this._super(t,n,i)}}),e.widget("ui.tabs",e.ui.tabs,{options:{fx:null},_getFx:function(){var t,n,r=this.options.fx;return r&&(e.isArray(r)?(t=r[0],n=r[1]):t=n=r),r?{show:n,hide:t}:null},_toggle:function(e,t){function o(){n.running=!1,n._trigger("activate",e,t)}function u(){t.newTab.closest("li").addClass("ui-tabs-active ui-state-active"),r.length&&s.show?r.animate(s.show,s.show.duration,function(){o()}):(r.show(),o())}var n=this,r=t.newPanel,i=t.oldPanel,s=this._getFx();if(!s)return this._super(e,t);n.running=!0,i.length&&s.hide?i.animate(s.hide,s.hide.duration,function(){t.oldTab.closest("li").removeClass("ui-tabs-active ui-state-active"),u()}):(t.oldTab.closest("li").removeClass("ui-tabs-active ui-state-active"),i.hide(),u())}}))})(jQuery);(function(e){function n(t,n){var r=(t.attr("aria-describedby")||"").split(/\s+/);r.push(n),t.data("ui-tooltip-id",n).attr("aria-describedby",e.trim(r.join(" ")))}function r(t){var n=t.data("ui-tooltip-id"),r=(t.attr("aria-describedby")||"").split(/\s+/),i=e.inArray(n,r);i!==-1&&r.splice(i,1),t.removeData("ui-tooltip-id"),r=e.trim(r.join(" ")),r?t.attr("aria-describedby",r):t.removeAttr("aria-describedby")}var t=0;e.widget("ui.tooltip",{version:"1.9.0",options:{content:function(){return e(this).attr("title")},hide:!0,items:"[title]",position:{my:"left+15 center",at:"right center",collision:"flipfit flipfit"},show:!0,tooltipClass:null,track:!1,close:null,open:null},_create:function(){this._on({mouseover:"open",focusin:"open"}),this.tooltips={}},_setOption:function(t,n){var r=this;if(t==="disabled"){this[n?"_disable":"_enable"](),this.options[t]=n;return}this._super(t,n),t==="content"&&e.each(this.tooltips,function(e,t){r._updateContent(t)})},_disable:function(){var t=this;e.each(this.tooltips,function(n,r){var i=e.Event("blur");i.target=i.currentTarget=r[0],t.close(i,!0)}),this.element.find(this.options.items).andSelf().each(function(){var t=e(this);t.is("[title]")&&t.data("ui-tooltip-title",t.attr("title")).attr("title","")})},_enable:function(){this.element.find(this.options.items).andSelf().each(function(){var t=e(this);t.data("ui-tooltip-title")&&t.attr("title",t.data("ui-tooltip-title"))})},open:function(t){var n=e(t?t.target:this.element).closest(this.options.items);if(!n.length)return;if(this.options.track&&n.data("ui-tooltip-id")){this._find(n).position(e.extend({of:n},this.options.position)),this._off(this.document,"mousemove");return}n.attr("title")&&n.data("ui-tooltip-title",n.attr("title")),n.data("tooltip-open",!0),this._updateContent(n,t)},_updateContent:function(e,t){var n,r=this.options.content,i=this;if(typeof r=="string")return this._open(t,e,r);n=r.call(e[0],function(n){if(!e.data("tooltip-open"))return;i._delay(function(){this._open(t,e,n)})}),n&&this._open(t,e,n)},_open:function(t,r,i){function u(e){o.of=e,s.position(o)}var s,o;if(!i)return;s=this._find(r);if(s.length){s.find(".ui-tooltip-content").html(i);return}r.is("[title]")&&(t&&t.type==="mouseover"?r.attr("title",""):r.removeAttr("title")),s=this._tooltip(r),n(r,s.attr("id")),s.find(".ui-tooltip-content").html(i),this.options.track&&t&&/^mouse/.test(t.originalEvent.type)?(o=e.extend({},this.options.position),this._on(this.document,{mousemove:u}),u(t)):s.position(e.extend({of:r},this.options.position)),s.hide(),this._show(s,this.options.show),this._trigger("open",t,{tooltip:s}),this._on(r,{mouseleave:"close",focusout:"close",keyup:function(t){if(t.keyCode===e.ui.keyCode.ESCAPE){var n=e.Event(t);n.currentTarget=r[0],this.close(n,!0)}}})},close:function(t,n){var i=this,s=e(t?t.currentTarget:this.element),o=this._find(s);if(this.closing)return;if(!n&&t&&t.type!=="focusout"&&this.document[0].activeElement===s[0])return;s.data("ui-tooltip-title")&&s.attr("title",s.data("ui-tooltip-title")),r(s),o.stop(!0),this._hide(o,this.options.hide,function(){e(this).remove(),delete i.tooltips[this.id]}),s.removeData("tooltip-open"),this._off(s,"mouseleave focusout keyup"),this._off(this.document,"mousemove"),this.closing=!0,this._trigger("close",t,{tooltip:o}),this.closing=!1},_tooltip:function(n){var r="ui-tooltip-"+t++,i=e("
      ").attr({id:r,role:"tooltip"}).addClass("ui-tooltip ui-widget ui-corner-all ui-widget-content "+(this.options.tooltipClass||""));return e("
      ").addClass("ui-tooltip-content").appendTo(i),i.appendTo(this.document[0].body),e.fn.bgiframe&&i.bgiframe(),this.tooltips[r]=n,i},_find:function(t){var n=t.data("ui-tooltip-id");return n?e("#"+n):e()},_destroy:function(){var t=this;e.each(this.tooltips,function(n,r){var i=e.Event("blur");i.target=i.currentTarget=r[0],t.close(i,!0),e("#"+n).remove(),r.data("ui-tooltip-title")&&(r.attr("title",r.data("ui-tooltip-title")),r.removeData("ui-tooltip-title"))})}})})(jQuery);jQuery.effects||function(e,t){var n=e.uiBackCompat!==!1,r="ui-effects-";e.effects={effect:{}},function(t,n){function p(e,t,n){var r=a[t.type]||{};return e==null?n||!t.def?null:t.def:(e=r.floor?~~e:parseFloat(e),isNaN(e)?t.def:r.mod?(e+r.mod)%r.mod:0>e?0:r.max")[0],c,h=t.each;l.style.cssText="background-color:rgba(1,1,1,.5)",f.rgba=l.style.backgroundColor.indexOf("rgba")>-1,h(u,function(e,t){t.cache="_"+e,t.props.alpha={idx:3,type:"percent",def:1}}),o.fn=t.extend(o.prototype,{parse:function(r,i,s,a){if(r===n)return this._rgba=[null,null,null,null],this;if(r.jquery||r.nodeType)r=t(r).css(i),i=n;var f=this,l=t.type(r),v=this._rgba=[],m;i!==n&&(r=[r,i,s,a],l="array");if(l==="string")return this.parse(d(r)||c._default);if(l==="array")return h(u.rgba.props,function(e,t){v[t.idx]=p(r[t.idx],t)}),this;if(l==="object")return r instanceof o?h(u,function(e,t){r[t.cache]&&(f[t.cache]=r[t.cache].slice())}):h(u,function(t,n){var i=n.cache;h(n.props,function(e,t){if(!f[i]&&n.to){if(e==="alpha"||r[e]==null)return;f[i]=n.to(f._rgba)}f[i][t.idx]=p(r[e],t,!0)}),f[i]&&e.inArray(null,f[i].slice(0,3))<0&&(f[i][3]=1,n.from&&(f._rgba=n.from(f[i])))}),this},is:function(e){var t=o(e),n=!0,r=this;return h(u,function(e,i){var s,o=t[i.cache];return o&&(s=r[i.cache]||i.to&&i.to(r._rgba)||[],h(i.props,function(e,t){if(o[t.idx]!=null)return n=o[t.idx]===s[t.idx],n})),n}),n},_space:function(){var e=[],t=this;return h(u,function(n,r){t[r.cache]&&e.push(n)}),e.pop()},transition:function(e,t){var n=o(e),r=n._space(),i=u[r],s=this.alpha()===0?o("transparent"):this,f=s[i.cache]||i.to(s._rgba),l=f.slice();return n=n[i.cache],h(i.props,function(e,r){var i=r.idx,s=f[i],o=n[i],u=a[r.type]||{};if(o===null)return;s===null?l[i]=o:(u.mod&&(o-s>u.mod/2?s+=u.mod:s-o>u.mod/2&&(s-=u.mod)),l[i]=p((o-s)*t+s,r))}),this[r](l)},blend:function(e){if(this._rgba[3]===1)return this;var n=this._rgba.slice(),r=n.pop(),i=o(e)._rgba;return o(t.map(n,function(e,t){return(1-r)*i[t]+r*e}))},toRgbaString:function(){var e="rgba(",n=t.map(this._rgba,function(e,t){return e==null?t>2?1:0:e});return n[3]===1&&(n.pop(),e="rgb("),e+n.join()+")"},toHslaString:function(){var e="hsla(",n=t.map(this.hsla(),function(e,t){return e==null&&(e=t>2?1:0),t&&t<3&&(e=Math.round(e*100)+"%"),e});return n[3]===1&&(n.pop(),e="hsl("),e+n.join()+")"},toHexString:function(e){var n=this._rgba.slice(),r=n.pop();return e&&n.push(~~(r*255)),"#"+t.map(n,function(e,t){return e=(e||0).toString(16),e.length===1?"0"+e:e}).join("")},toString:function(){return this._rgba[3]===0?"transparent":this.toRgbaString()}}),o.fn.parse.prototype=o.fn,u.hsla.to=function(e){if(e[0]==null||e[1]==null||e[2]==null)return[null,null,null,e[3]];var t=e[0]/255,n=e[1]/255,r=e[2]/255,i=e[3],s=Math.max(t,n,r),o=Math.min(t,n,r),u=s-o,a=s+o,f=a*.5,l,c;return o===s?l=0:t===s?l=60*(n-r)/u+360:n===s?l=60*(r-t)/u+120:l=60*(t-n)/u+240,f===0||f===1?c=f:f<=.5?c=u/a:c=u/(2-a),[Math.round(l)%360,c,f,i==null?1:i]},u.hsla.from=function(e){if(e[0]==null||e[1]==null||e[2]==null)return[null,null,null,e[3]];var t=e[0]/360,n=e[1],r=e[2],i=e[3],s=r<=.5?r*(1+n):r+n-r*n,o=2*r-s,u,a,f;return[Math.round(v(o,s,t+1/3)*255),Math.round(v(o,s,t)*255),Math.round(v(o,s,t-1/3)*255),i]},h(u,function(e,r){var s=r.props,u=r.cache,a=r.to,f=r.from;o.fn[e]=function(e){a&&!this[u]&&(this[u]=a(this._rgba));if(e===n)return this[u].slice();var r,i=t.type(e),l=i==="array"||i==="object"?e:arguments,c=this[u].slice();return h(s,function(e,t){var n=l[i==="object"?e:t.idx];n==null&&(n=c[t.idx]),c[t.idx]=p(n,t)}),f?(r=o(f(c)),r[u]=c,r):o(c)},h(s,function(n,r){if(o.fn[n])return;o.fn[n]=function(s){var o=t.type(s),u=n==="alpha"?this._hsla?"hsla":"rgba":e,a=this[u](),f=a[r.idx],l;return o==="undefined"?f:(o==="function"&&(s=s.call(this,f),o=t.type(s)),s==null&&r.empty?this:(o==="string"&&(l=i.exec(s),l&&(s=f+parseFloat(l[2])*(l[1]==="+"?1:-1))),a[r.idx]=s,this[u](a)))}})}),h(r,function(e,n){t.cssHooks[n]={set:function(e,r){var i,s,u="";if(t.type(r)!=="string"||(i=d(r))){r=o(i||r);if(!f.rgba&&r._rgba[3]!==1){s=n==="backgroundColor"?e.parentNode:e;while((u===""||u==="transparent")&&s&&s.style)try{u=t.css(s,"backgroundColor"),s=s.parentNode}catch(a){}r=r.blend(u&&u!=="transparent"?u:"_default")}r=r.toRgbaString()}try{e.style[n]=r}catch(r){}}},t.fx.step[n]=function(e){e.colorInit||(e.start=o(e.elem,n),e.end=o(e.end),e.colorInit=!0),t.cssHooks[n].set(e.elem,e.start.transition(e.end,e.pos))}}),t.cssHooks.borderColor={expand:function(e){var t={};return h(["Top","Right","Bottom","Left"],function(n,r){t["border"+r+"Color"]=e}),t}},c=t.Color.names={aqua:"#00ffff",black:"#000000",blue:"#0000ff",fuchsia:"#ff00ff",gray:"#808080",green:"#008000",lime:"#00ff00",maroon:"#800000",navy:"#000080",olive:"#808000",purple:"#800080",red:"#ff0000",silver:"#c0c0c0",teal:"#008080",white:"#ffffff",yellow:"#ffff00",transparent:[null,null,null,0],_default:"#ffffff"}}(jQuery),function(){function i(){var t=this.ownerDocument.defaultView?this.ownerDocument.defaultView.getComputedStyle(this,null):this.currentStyle,n={},r,i,s;if(t&&t.length&&t[0]&&t[t[0]]){s=t.length;while(s--)r=t[s],typeof t[r]=="string"&&(n[e.camelCase(r)]=t[r])}else for(r in t)typeof t[r]=="string"&&(n[r]=t[r]);return n}function s(t,n){var i={},s,o;for(s in n)o=n[s],t[s]!==o&&!r[s]&&(e.fx.step[s]||!isNaN(parseFloat(o)))&&(i[s]=o);return i}var n=["add","remove","toggle"],r={border:1,borderBottom:1,borderColor:1,borderLeft:1,borderRight:1,borderTop:1,borderWidth:1,margin:1,padding:1};e.each(["borderLeftStyle","borderRightStyle","borderBottomStyle","borderTopStyle"],function(t,n){e.fx.step[n]=function(e){if(e.end!=="none"&&!e.setAttr||e.pos===1&&!e.setAttr)jQuery.style(e.elem,n,e.end),e.setAttr=!0}}),e.effects.animateClass=function(t,r,o,u){var a=e.speed(r,o,u);return this.queue(function(){var r=e(this),o=r.attr("class")||"",u,f=a.children?r.find("*").andSelf():r;f=f.map(function(){var t=e(this);return{el:t,start:i.call(this)}}),u=function(){e.each(n,function(e,n){t[n]&&r[n+"Class"](t[n])})},u(),f=f.map(function(){return this.end=i.call(this.el[0]),this.diff=s(this.start,this.end),this}),r.attr("class",o),f=f.map(function(){var t=this,n=e.Deferred(),r=jQuery.extend({},a,{queue:!1,complete:function(){n.resolve(t)}});return this.el.animate(this.diff,r),n.promise()}),e.when.apply(e,f.get()).done(function(){u(),e.each(arguments,function(){var t=this.el;e.each(this.diff,function(e){t.css(e,"")})}),a.complete.call(r[0])})})},e.fn.extend({_addClass:e.fn.addClass,addClass:function(t,n,r,i){return n?e.effects.animateClass.call(this,{add:t},n,r,i):this._addClass(t)},_removeClass:e.fn.removeClass,removeClass:function(t,n,r,i){return n?e.effects.animateClass.call(this,{remove:t},n,r,i):this._removeClass(t)},_toggleClass:e.fn.toggleClass,toggleClass:function(n,r,i,s,o){return typeof r=="boolean"||r===t?i?e.effects.animateClass.call(this,r?{add:n}:{remove:n},i,s,o):this._toggleClass(n,r):e.effects.animateClass.call(this,{toggle:n},r,i,s)},switchClass:function(t,n,r,i,s){return e.effects.animateClass.call(this,{add:n,remove:t},r,i,s)}})}(),function(){function i(n,r,i,s){e.isPlainObject(n)&&(r=n,n=n.effect),n={effect:n},r===t&&(r={}),e.isFunction(r)&&(s=r,i=null,r={});if(typeof r=="number"||e.fx.speeds[r])s=i,i=r,r={};return e.isFunction(i)&&(s=i,i=null),r&&e.extend(n,r),i=i||r.duration,n.duration=e.fx.off?0:typeof i=="number"?i:i in e.fx.speeds?e.fx.speeds[i]:e.fx.speeds._default,n.complete=s||r.complete,n}function s(t){return!t||typeof t=="number"||e.fx.speeds[t]?!0:typeof t=="string"&&!e.effects.effect[t]?n&&e.effects[t]?!1:!0:!1}e.extend(e.effects,{version:"1.9.0",save:function(e,t){for(var n=0;n
      ").addClass("ui-effects-wrapper").css({fontSize:"100%",background:"transparent",border:"none",margin:0,padding:0}),i={width:t.width(),height:t.height()},s=document.activeElement;try{s.id}catch(o){s=document.body}return t.wrap(r),(t[0]===s||e.contains(t[0],s))&&e(s).focus(),r=t.parent(),t.css("position")==="static"?(r.css({position:"relative"}),t.css({position:"relative"})):(e.extend(n,{position:t.css("position"),zIndex:t.css("z-index")}),e.each(["top","left","bottom","right"],function(e,r){n[r]=t.css(r),isNaN(parseInt(n[r],10))&&(n[r]="auto")}),t.css({position:"relative",top:0,left:0,right:"auto",bottom:"auto"})),t.css(i),r.css(n).show()},removeWrapper:function(t){var n=document.activeElement;return t.parent().is(".ui-effects-wrapper")&&(t.parent().replaceWith(t),(t[0]===n||e.contains(t[0],n))&&e(n).focus()),t},setTransition:function(t,n,r,i){return i=i||{},e.each(n,function(e,n){var s=t.cssUnit(n);s[0]>0&&(i[n]=s[0]*r+s[1])}),i}}),e.fn.extend({effect:function(t,r,s,o){function h(t){function s(){e.isFunction(r)&&r.call(n[0]),e.isFunction(t)&&t()}var n=e(this),r=u.complete,i=u.mode;(n.is(":hidden")?i==="hide":i==="show")?s():l.call(n[0],u,s)}var u=i.apply(this,arguments),a=u.mode,f=u.queue,l=e.effects.effect[u.effect],c=!l&&n&&e.effects[u.effect];return e.fx.off||!l&&!c?a?this[a](u.duration,u.complete):this.each(function(){u.complete&&u.complete.call(this)}):l?f===!1?this.each(h):this.queue(f||"fx",h):c.call(this,{options:u,duration:u.duration,callback:u.complete,mode:u.mode})},_show:e.fn.show,show:function(e){if(s(e))return this._show.apply(this,arguments);var t=i.apply(this,arguments);return t.mode="show",this.effect.call(this,t)},_hide:e.fn.hide,hide:function(e){if(s(e))return this._hide.apply(this,arguments);var t=i.apply(this,arguments);return t.mode="hide",this.effect.call(this,t)},__toggle:e.fn.toggle,toggle:function(t){if(s(t)||typeof t=="boolean"||e.isFunction(t))return this.__toggle.apply(this,arguments);var n=i.apply(this,arguments);return n.mode="toggle",this.effect.call(this,n)},cssUnit:function(t){var n=this.css(t),r=[];return e.each(["em","px","%","pt"],function(e,t){n.indexOf(t)>0&&(r=[parseFloat(n),t])}),r}})}(),function(){var t={};e.each(["Quad","Cubic","Quart","Quint","Expo"],function(e,n){t[n]=function(t){return Math.pow(t,e+2)}}),e.extend(t,{Sine:function(e){return 1-Math.cos(e*Math.PI/2)},Circ:function(e){return 1-Math.sqrt(1-e*e)},Elastic:function(e){return e===0||e===1?e:-Math.pow(2,8*(e-1))*Math.sin(((e-1)*80-7.5)*Math.PI/15)},Back:function(e){return e*e*(3*e-2)},Bounce:function(e){var t,n=4;while(e<((t=Math.pow(2,--n))-1)/11);return 1/Math.pow(4,3-n)-7.5625*Math.pow((t*3-2)/22-e,2)}}),e.each(t,function(t,n){e.easing["easeIn"+t]=n,e.easing["easeOut"+t]=function(e){return 1-n(1-e)},e.easing["easeInOut"+t]=function(e){return e<.5?n(e*2)/2:1-n(e*-2+2)/2}})}()}(jQuery);(function(e,t){var n=/up|down|vertical/,r=/up|left|vertical|horizontal/;e.effects.effect.blind=function(t,i){var s=e(this),o=["position","top","bottom","left","right","height","width"],u=e.effects.setMode(s,t.mode||"hide"),a=t.direction||"up",f=n.test(a),l=f?"height":"width",c=f?"top":"left",h=r.test(a),p={},d=u==="show",v,m,g;s.parent().is(".ui-effects-wrapper")?e.effects.save(s.parent(),o):e.effects.save(s,o),s.show(),v=e.effects.createWrapper(s).css({overflow:"hidden"}),m=v[l](),g=parseFloat(v.css(c))||0,p[l]=d?m:0,h||(s.css(f?"bottom":"right",0).css(f?"top":"left","auto").css({position:"absolute"}),p[c]=d?g:m+g),d&&(v.css(l,0),h||v.css(c,g+m)),v.animate(p,{duration:t.duration,easing:t.easing,queue:!1,complete:function(){u==="hide"&&s.hide(),e.effects.restore(s,o),e.effects.removeWrapper(s),i()}})}})(jQuery);(function(e,t){e.effects.effect.bounce=function(t,n){var r=e(this),i=["position","top","bottom","left","right","height","width"],s=e.effects.setMode(r,t.mode||"effect"),o=s==="hide",u=s==="show",a=t.direction||"up",f=t.distance,l=t.times||5,c=l*2+(u||o?1:0),h=t.duration/c,p=t.easing,d=a==="up"||a==="down"?"top":"left",v=a==="up"||a==="left",m,g,y,b=r.queue(),w=b.length;(u||o)&&i.push("opacity"),e.effects.save(r,i),r.show(),e.effects.createWrapper(r),f||(f=r[d==="top"?"outerHeight":"outerWidth"]()/3),u&&(y={opacity:1},y[d]=0,r.css("opacity",0).css(d,v?-f*2:f*2).animate(y,h,p)),o&&(f/=Math.pow(2,l-1)),y={},y[d]=0;for(m=0;m1&&b.splice.apply(b,[1,0].concat(b.splice(w,c+1))),r.dequeue()}})(jQuery);(function(e,t){e.effects.effect.clip=function(t,n){var r=e(this),i=["position","top","bottom","left","right","height","width"],s=e.effects.setMode(r,t.mode||"hide"),o=s==="show",u=t.direction||"vertical",a=u==="vertical",f=a?"height":"width",l=a?"top":"left",c={},h,p,d;e.effects.save(r,i),r.show(),h=e.effects.createWrapper(r).css({overflow:"hidden"}),p=r[0].tagName==="IMG"?h:r,d=p[f](),o&&(p.css(f,0),p.css(l,d/2)),c[f]=o?d:0,c[l]=o?0:d/2,p.animate(c,{queue:!1,duration:t.duration,easing:t.easing,complete:function(){o||r.hide(),e.effects.restore(r,i),e.effects.removeWrapper(r),n()}})}})(jQuery);(function(e,t){e.effects.effect.drop=function(t,n){var r=e(this),i=["position","top","bottom","left","right","opacity","height","width"],s=e.effects.setMode(r,t.mode||"hide"),o=s==="show",u=t.direction||"left",a=u==="up"||u==="down"?"top":"left",f=u==="up"||u==="left"?"pos":"neg",l={opacity:o?1:0},c;e.effects.save(r,i),r.show(),e.effects.createWrapper(r),c=t.distance||r[a==="top"?"outerHeight":"outerWidth"](!0)/2,o&&r.css("opacity",0).css(a,f==="pos"?-c:c),l[a]=(o?f==="pos"?"+=":"-=":f==="pos"?"-=":"+=")+c,r.animate(l,{queue:!1,duration:t.duration,easing:t.easing,complete:function(){s==="hide"&&r.hide(),e.effects.restore(r,i),e.effects.removeWrapper(r),n()}})}})(jQuery);(function(e,t){e.effects.effect.explode=function(t,n){function y(){c.push(this),c.length===r*i&&b()}function b(){s.css({visibility:"visible"}),e(c).remove(),u||s.hide(),n()}var r=t.pieces?Math.round(Math.sqrt(t.pieces)):3,i=r,s=e(this),o=e.effects.setMode(s,t.mode||"hide"),u=o==="show",a=s.show().css("visibility","hidden").offset(),f=Math.ceil(s.outerWidth()/i),l=Math.ceil(s.outerHeight()/r),c=[],h,p,d,v,m,g;for(h=0;h
      ").css({position:"absolute",visibility:"visible",left:-p*f,top:-h*l}).parent().addClass("ui-effects-explode").css({position:"absolute",overflow:"hidden",width:f,height:l,left:d+(u?m*f:0),top:v+(u?g*l:0),opacity:u?0:1}).animate({left:d+(u?0:m*f),top:v+(u?0:g*l),opacity:u?1:0},t.duration||500,t.easing,y)}}})(jQuery);(function(e,t){e.effects.effect.fade=function(t,n){var r=e(this),i=e.effects.setMode(r,t.mode||"toggle");r.animate({opacity:i},{queue:!1,duration:t.duration,easing:t.easing,complete:n})}})(jQuery);(function(e,t){e.effects.effect.fold=function(t,n){var r=e(this),i=["position","top","bottom","left","right","height","width"],s=e.effects.setMode(r,t.mode||"hide"),o=s==="show",u=s==="hide",a=t.size||15,f=/([0-9]+)%/.exec(a),l=!!t.horizFirst,c=o!==l,h=c?["width","height"]:["height","width"],p=t.duration/2,d,v,m={},g={};e.effects.save(r,i),r.show(),d=e.effects.createWrapper(r).css({overflow:"hidden"}),v=c?[d.width(),d.height()]:[d.height(),d.width()],f&&(a=parseInt(f[1],10)/100*v[u?0:1]),o&&d.css(l?{height:0,width:a}:{height:a,width:0}),m[h[0]]=o?v[0]:a,g[h[1]]=o?v[1]:0,d.animate(m,p,t.easing).animate(g,p,t.easing,function(){u&&r.hide(),e.effects.restore(r,i),e.effects.removeWrapper(r),n()})}})(jQuery);(function(e,t){e.effects.effect.highlight=function(t,n){var r=e(this),i=["backgroundImage","backgroundColor","opacity"],s=e.effects.setMode(r,t.mode||"show"),o={backgroundColor:r.css("backgroundColor")};s==="hide"&&(o.opacity=0),e.effects.save(r,i),r.show().css({backgroundImage:"none",backgroundColor:t.color||"#ffff99"}).animate(o,{queue:!1,duration:t.duration,easing:t.easing,complete:function(){s==="hide"&&r.hide(),e.effects.restore(r,i),n()}})}})(jQuery);(function(e,t){e.effects.effect.pulsate=function(t,n){var r=e(this),i=e.effects.setMode(r,t.mode||"show"),s=i==="show",o=i==="hide",u=s||i==="hide",a=(t.times||5)*2+(u?1:0),f=t.duration/a,l=0,c=r.queue(),h=c.length,p;if(s||!r.is(":visible"))r.css("opacity",0).show(),l=1;for(p=1;p1&&c.splice.apply(c,[1,0].concat(c.splice(h,a+1))),r.dequeue()}})(jQuery);(function(e,t){e.effects.effect.puff=function(t,n){var r=e(this),i=e.effects.setMode(r,t.mode||"hide"),s=i==="hide",o=parseInt(t.percent,10)||150,u=o/100,a={height:r.height(),width:r.width()};e.extend(t,{effect:"scale",queue:!1,fade:!0,mode:i,complete:n,percent:s?o:100,from:s?a:{height:a.height*u,width:a.width*u}}),r.effect(t)},e.effects.effect.scale=function(t,n){var r=e(this),i=e.extend(!0,{},t),s=e.effects.setMode(r,t.mode||"effect"),o=parseInt(t.percent,10)||(parseInt(t.percent,10)===0?0:s==="hide"?0:100),u=t.direction||"both",a=t.origin,f={height:r.height(),width:r.width(),outerHeight:r.outerHeight(),outerWidth:r.outerWidth()},l={y:u!=="horizontal"?o/100:1,x:u!=="vertical"?o/100:1};i.effect="size",i.queue=!1,i.complete=n,s!=="effect"&&(i.origin=a||["middle","center"],i.restore=!0),i.from=t.from||(s==="show"?{height:0,width:0}:f),i.to={height:f.height*l.y,width:f.width*l.x,outerHeight:f.outerHeight*l.y,outerWidth:f.outerWidth*l.x},i.fade&&(s==="show"&&(i.from.opacity=0,i.to.opacity=1),s==="hide"&&(i.from.opacity=1,i.to.opacity=0)),r.effect(i)},e.effects.effect.size=function(t,n){var r=e(this),i=["position","top","bottom","left","right","width","height","overflow","opacity"],s=["position","top","bottom","left","right","overflow","opacity"],o=["width","height","overflow"],u=["fontSize"],a=["borderTopWidth","borderBottomWidth","paddingTop","paddingBottom"],f=["borderLeftWidth","borderRightWidth","paddingLeft","paddingRight"],l=e.effects.setMode(r,t.mode||"effect"),c=t.restore||l!=="effect",h=t.scale||"both",p=t.origin||["middle","center"],d,v,m,g=r.css("position");l==="show"&&r.show(),d={height:r.height(),width:r.width(),outerHeight:r.outerHeight(),outerWidth:r.outerWidth()},r.from=t.from||d,r.to=t.to||d,m={from:{y:r.from.height/d.height,x:r.from.width/d.width},to:{y:r.to.height/d.height,x:r.to.width/d.width}};if(h==="box"||h==="both")m.from.y!==m.to.y&&(i=i.concat(a),r.from=e.effects.setTransition(r,a,m.from.y,r.from),r.to=e.effects.setTransition(r,a,m.to.y,r.to)),m.from.x!==m.to.x&&(i=i.concat(f),r.from=e.effects.setTransition(r,f,m.from.x,r.from),r.to=e.effects.setTransition(r,f,m.to.x,r.to));(h==="content"||h==="both")&&m.from.y!==m.to.y&&(i=i.concat(u),r.from=e.effects.setTransition(r,u,m.from.y,r.from),r.to=e.effects.setTransition(r,u,m.to.y,r.to)),e.effects.save(r,c?i:s),r.show(),e.effects.createWrapper(r),r.css("overflow","hidden").css(r.from),p&&(v=e.effects.getBaseline(p,d),r.from.top=(d.outerHeight-r.outerHeight())*v.y,r.from.left=(d.outerWidth-r.outerWidth())*v.x,r.to.top=(d.outerHeight-r.to.outerHeight)*v.y,r.to.left=(d.outerWidth-r.to.outerWidth)*v.x),r.css(r.from);if(h==="content"||h==="both")a=a.concat(["marginTop","marginBottom"]).concat(u),f=f.concat(["marginLeft","marginRight"]),o=i.concat(a).concat(f),r.find("*[width]").each(function(){var n=e(this),r={height:n.height(),width:n.width()};c&&e.effects.save(n,o),n.from={height:r.height*m.from.y,width:r.width*m.from.x},n.to={height:r.height*m.to.y,width:r.width*m.to.x},m.from.y!==m.to.y&&(n.from=e.effects.setTransition(n,a,m.from.y,n.from),n.to=e.effects.setTransition(n,a,m.to.y,n.to)),m.from.x!==m.to.x&&(n.from=e.effects.setTransition(n,f,m.from.x,n.from),n.to=e.effects.setTransition(n,f,m.to.x,n.to)),n.css(n.from),n.animate(n.to,t.duration,t.easing,function(){c&&e.effects.restore(n,o)})});r.animate(r.to,{queue:!1,duration:t.duration,easing:t.easing,complete:function(){r.to.opacity===0&&r.css("opacity",r.from.opacity),l==="hide"&&r.hide(),e.effects.restore(r,c?i:s),c||(g==="static"?r.css({position:"relative",top:r.to.top,left:r.to.left}):e.each(["top","left"],function(e,t){r.css(t,function(t,n){var i=parseInt(n,10),s=e?r.to.left:r.to.top;return n==="auto"?s+"px":i+s+"px"})})),e.effects.removeWrapper(r),n()}})}})(jQuery);(function(e,t){e.effects.effect.shake=function(t,n){var r=e(this),i=["position","top","bottom","left","right","height","width"],s=e.effects.setMode(r,t.mode||"effect"),o=t.direction||"left",u=t.distance||20,a=t.times||3,f=a*2+1,l=Math.round(t.duration/f),c=o==="up"||o==="down"?"top":"left",h=o==="up"||o==="left",p={},d={},v={},m,g=r.queue(),y=g.length;e.effects.save(r,i),r.show(),e.effects.createWrapper(r),p[c]=(h?"-=":"+=")+u,d[c]=(h?"+=":"-=")+u*2,v[c]=(h?"-=":"+=")+u*2,r.animate(p,l,t.easing);for(m=1;m1&&g.splice.apply(g,[1,0].concat(g.splice(y,f+1))),r.dequeue()}})(jQuery);(function(e,t){e.effects.effect.slide=function(t,n){var r=e(this),i=["position","top","bottom","left","right","width","height"],s=e.effects.setMode(r,t.mode||"show"),o=s==="show",u=t.direction||"left",a=u==="up"||u==="down"?"top":"left",f=u==="up"||u==="left",l,c={};e.effects.save(r,i),r.show(),l=t.distance||r[a==="top"?"outerHeight":"outerWidth"](!0),e.effects.createWrapper(r).css({overflow:"hidden"}),o&&r.css(a,f?isNaN(l)?"-"+l:-l:l),c[a]=(o?f?"+=":"-=":f?"-=":"+=")+l,r.animate(c,{queue:!1,duration:t.duration,easing:t.easing,complete:function(){s==="hide"&&r.hide(),e.effects.restore(r,i),e.effects.removeWrapper(r),n()}})}})(jQuery);(function(e,t){e.effects.effect.transfer=function(t,n){var r=e(this),i=e(t.to),s=i.css("position")==="fixed",o=e("body"),u=s?o.scrollTop():0,a=s?o.scrollLeft():0,f=i.offset(),l={top:f.top-u,left:f.left-a,height:i.innerHeight(),width:i.innerWidth()},c=r.offset(),h=e('
      ').appendTo(document.body).addClass(t.className).css({top:c.top-u,left:c.left-a,height:r.innerHeight(),width:r.innerWidth(),position:s?"fixed":"absolute"}).animate(l,t.duration,t.easing,function(){h.remove(),n()})}})(jQuery); \ No newline at end of file diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/ui/minified/jquery.ui.accordion.min.js b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/ui/minified/jquery.ui.accordion.min.js new file mode 100755 index 000000000..f375e56dc --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/ui/minified/jquery.ui.accordion.min.js @@ -0,0 +1,5 @@ +/*! jQuery UI - v1.9.0 - 2012-10-08 +* http://jqueryui.com +* Includes: jquery.ui.accordion.js +* Copyright 2012 jQuery Foundation and other contributors; Licensed MIT */ +(function(e,t){var n=0,r={},i={};r.height=r.paddingTop=r.paddingBottom=r.borderTopWidth=r.borderBottomWidth="hide",i.height=i.paddingTop=i.paddingBottom=i.borderTopWidth=i.borderBottomWidth="show",e.widget("ui.accordion",{version:"1.9.0",options:{active:0,animate:{},collapsible:!1,event:"click",header:"> li > :first-child,> :not(li):even",heightStyle:"auto",icons:{activeHeader:"ui-icon-triangle-1-s",header:"ui-icon-triangle-1-e"},activate:null,beforeActivate:null},_create:function(){var t=this.accordionId="ui-accordion-"+(this.element.attr("id")||++n),r=this.options;this.prevShow=this.prevHide=e(),this.element.addClass("ui-accordion ui-widget ui-helper-reset"),this.headers=this.element.find(r.header).addClass("ui-accordion-header ui-helper-reset ui-state-default ui-corner-all"),this._hoverable(this.headers),this._focusable(this.headers),this.headers.next().addClass("ui-accordion-content ui-helper-reset ui-widget-content ui-corner-bottom").hide(),!r.collapsible&&r.active===!1&&(r.active=0),r.active<0&&(r.active+=this.headers.length),this.active=this._findActive(r.active).addClass("ui-accordion-header-active ui-state-active").toggleClass("ui-corner-all ui-corner-top"),this.active.next().addClass("ui-accordion-content-active").show(),this._createIcons(),this.originalHeight=this.element[0].style.height,this.refresh(),this.element.attr("role","tablist"),this.headers.attr("role","tab").each(function(n){var r=e(this),i=r.attr("id"),s=r.next(),o=s.attr("id");i||(i=t+"-header-"+n,r.attr("id",i)),o||(o=t+"-panel-"+n,s.attr("id",o)),r.attr("aria-controls",o),s.attr("aria-labelledby",i)}).next().attr("role","tabpanel"),this.headers.not(this.active).attr({"aria-selected":"false",tabIndex:-1}).next().attr({"aria-expanded":"false","aria-hidden":"true"}).hide(),this.active.length?this.active.attr({"aria-selected":"true",tabIndex:0}).next().attr({"aria-expanded":"true","aria-hidden":"false"}):this.headers.eq(0).attr("tabIndex",0),this._on(this.headers,{keydown:"_keydown"}),this._on(this.headers.next(),{keydown:"_panelKeyDown"}),this._setupEvents(r.event)},_getCreateEventData:function(){return{header:this.active,content:this.active.length?this.active.next():e()}},_createIcons:function(){var t=this.options.icons;t&&(e("").addClass("ui-accordion-header-icon ui-icon "+t.header).prependTo(this.headers),this.active.children(".ui-accordion-header-icon").removeClass(t.header).addClass(t.activeHeader),this.headers.addClass("ui-accordion-icons"))},_destroyIcons:function(){this.headers.removeClass("ui-accordion-icons").children(".ui-accordion-header-icon").remove()},_destroy:function(){var e;this.element.removeClass("ui-accordion ui-widget ui-helper-reset").removeAttr("role"),this.headers.removeClass("ui-accordion-header ui-accordion-header-active ui-helper-reset ui-state-default ui-corner-all ui-state-active ui-state-disabled ui-corner-top").removeAttr("role").removeAttr("aria-selected").removeAttr("aria-controls").removeAttr("tabIndex").each(function(){/^ui-accordion/.test(this.id)&&this.removeAttribute("id")}),this._destroyIcons(),e=this.headers.next().css("display","").removeAttr("role").removeAttr("aria-expanded").removeAttr("aria-hidden").removeAttr("aria-labelledby").removeClass("ui-helper-reset ui-widget-content ui-corner-bottom ui-accordion-content ui-accordion-content-active ui-state-disabled").each(function(){/^ui-accordion/.test(this.id)&&this.removeAttribute("id")}),this.options.heightStyle!=="content"&&(this.element.css("height",this.originalHeight),e.css("height",""))},_setOption:function(e,t){if(e==="active"){this._activate(t);return}e==="event"&&(this.options.event&&this._off(this.headers,this.options.event),this._setupEvents(t)),this._super(e,t),e==="collapsible"&&!t&&this.options.active===!1&&this._activate(0),e==="icons"&&(this._destroyIcons(),t&&this._createIcons()),e==="disabled"&&this.headers.add(this.headers.next()).toggleClass("ui-state-disabled",!!t)},_keydown:function(t){if(t.altKey||t.ctrlKey)return;var n=e.ui.keyCode,r=this.headers.length,i=this.headers.index(t.target),s=!1;switch(t.keyCode){case n.RIGHT:case n.DOWN:s=this.headers[(i+1)%r];break;case n.LEFT:case n.UP:s=this.headers[(i-1+r)%r];break;case n.SPACE:case n.ENTER:this._eventHandler(t);break;case n.HOME:s=this.headers[0];break;case n.END:s=this.headers[r-1]}s&&(e(t.target).attr("tabIndex",-1),e(s).attr("tabIndex",0),s.focus(),t.preventDefault())},_panelKeyDown:function(t){t.keyCode===e.ui.keyCode.UP&&t.ctrlKey&&e(t.currentTarget).prev().focus()},refresh:function(){var t,n,r=this.options.heightStyle,i=this.element.parent();this.element.css("height",this.originalHeight),r==="fill"?(e.support.minHeight||(n=i.css("overflow"),i.css("overflow","hidden")),t=i.height(),this.element.siblings(":visible").each(function(){var n=e(this),r=n.css("position");if(r==="absolute"||r==="fixed")return;t-=n.outerHeight(!0)}),n&&i.css("overflow",n),this.headers.each(function(){t-=e(this).outerHeight(!0)}),this.headers.next().each(function(){e(this).height(Math.max(0,t-e(this).innerHeight()+e(this).height()))}).css("overflow","auto")):r==="auto"&&(t=0,this.headers.next().each(function(){t=Math.max(t,e(this).height("").height())}).height(t)),r!=="content"&&this.element.height(this.element.height())},_activate:function(t){var n=this._findActive(t)[0];if(n===this.active[0])return;n=n||this.active[0],this._eventHandler({target:n,currentTarget:n,preventDefault:e.noop})},_findActive:function(t){return typeof t=="number"?this.headers.eq(t):e()},_setupEvents:function(t){var n={};if(!t)return;e.each(t.split(" "),function(e,t){n[t]="_eventHandler"}),this._on(this.headers,n)},_eventHandler:function(t){var n=this.options,r=this.active,i=e(t.currentTarget),s=i[0]===r[0],o=s&&n.collapsible,u=o?e():i.next(),a=r.next(),f={oldHeader:r,oldPanel:a,newHeader:o?e():i,newPanel:u};t.preventDefault();if(s&&!n.collapsible||this._trigger("beforeActivate",t,f)===!1)return;n.active=o?!1:this.headers.index(i),this.active=s?e():i,this._toggle(f),r.removeClass("ui-accordion-header-active ui-state-active"),n.icons&&r.children(".ui-accordion-header-icon").removeClass(n.icons.activeHeader).addClass(n.icons.header),s||(i.removeClass("ui-corner-all").addClass("ui-accordion-header-active ui-state-active ui-corner-top"),n.icons&&i.children(".ui-accordion-header-icon").removeClass(n.icons.header).addClass(n.icons.activeHeader),i.next().addClass("ui-accordion-content-active"))},_toggle:function(t){var n=t.newPanel,r=this.prevShow.length?this.prevShow:t.oldPanel;this.prevShow.add(this.prevHide).stop(!0,!0),this.prevShow=n,this.prevHide=r,this.options.animate?this._animate(n,r,t):(r.hide(),n.show(),this._toggleComplete(t)),r.attr({"aria-expanded":"false","aria-hidden":"true"}),r.prev().attr("aria-selected","false"),n.length&&r.length?r.prev().attr("tabIndex",-1):n.length&&this.headers.filter(function(){return e(this).attr("tabIndex")===0}).attr("tabIndex",-1),n.attr({"aria-expanded":"true","aria-hidden":"false"}).prev().attr({"aria-selected":"true",tabIndex:0})},_animate:function(e,t,n){var s,o,u,a=this,f=0,l=e.length&&(!t.length||e.index()",options:{appendTo:"body",autoFocus:!1,delay:300,minLength:1,position:{my:"left top",at:"left bottom",collision:"none"},source:null,change:null,close:null,focus:null,open:null,response:null,search:null,select:null},pending:0,_create:function(){var t,n,r;this.isMultiLine=this._isMultiLine(),this.valueMethod=this.element[this.element.is("input,textarea")?"val":"text"],this.isNewMenu=!0,this.element.addClass("ui-autocomplete-input").attr("autocomplete","off"),this._on({keydown:function(i){if(this.element.prop("readOnly")){t=!0,r=!0,n=!0;return}t=!1,r=!1,n=!1;var s=e.ui.keyCode;switch(i.keyCode){case s.PAGE_UP:t=!0,this._move("previousPage",i);break;case s.PAGE_DOWN:t=!0,this._move("nextPage",i);break;case s.UP:t=!0,this._keyEvent("previous",i);break;case s.DOWN:t=!0,this._keyEvent("next",i);break;case s.ENTER:case s.NUMPAD_ENTER:this.menu.active&&(t=!0,i.preventDefault(),this.menu.select(i));break;case s.TAB:this.menu.active&&this.menu.select(i);break;case s.ESCAPE:this.menu.element.is(":visible")&&(this._value(this.term),this.close(i),i.preventDefault());break;default:n=!0,this._searchTimeout(i)}},keypress:function(r){if(t){t=!1,r.preventDefault();return}if(n)return;var i=e.ui.keyCode;switch(r.keyCode){case i.PAGE_UP:this._move("previousPage",r);break;case i.PAGE_DOWN:this._move("nextPage",r);break;case i.UP:this._keyEvent("previous",r);break;case i.DOWN:this._keyEvent("next",r)}},input:function(e){if(r){r=!1,e.preventDefault();return}this._searchTimeout(e)},focus:function(){this.selectedItem=null,this.previous=this._value()},blur:function(e){if(this.cancelBlur){delete this.cancelBlur;return}clearTimeout(this.searching),this.close(e),this._change(e)}}),this._initSource(),this.menu=e("
      '))}function bindHover(e){var t="button, .ui-datepicker-prev, .ui-datepicker-next, .ui-datepicker-calendar td a";return e.delegate(t,"mouseout",function(){$(this).removeClass("ui-state-hover"),this.className.indexOf("ui-datepicker-prev")!=-1&&$(this).removeClass("ui-datepicker-prev-hover"),this.className.indexOf("ui-datepicker-next")!=-1&&$(this).removeClass("ui-datepicker-next-hover")}).delegate(t,"mouseover",function(){$.datepicker._isDisabledDatepicker(instActive.inline?e.parent()[0]:instActive.input[0])||($(this).parents(".ui-datepicker-calendar").find("a").removeClass("ui-state-hover"),$(this).addClass("ui-state-hover"),this.className.indexOf("ui-datepicker-prev")!=-1&&$(this).addClass("ui-datepicker-prev-hover"),this.className.indexOf("ui-datepicker-next")!=-1&&$(this).addClass("ui-datepicker-next-hover"))})}function extendRemove(e,t){$.extend(e,t);for(var n in t)if(t[n]==null||t[n]==undefined)e[n]=t[n];return e}$.extend($.ui,{datepicker:{version:"1.9.0"}});var PROP_NAME="datepicker",dpuuid=(new Date).getTime(),instActive;$.extend(Datepicker.prototype,{markerClassName:"hasDatepicker",maxRows:4,log:function(){this.debug&&console.log.apply("",arguments)},_widgetDatepicker:function(){return this.dpDiv},setDefaults:function(e){return extendRemove(this._defaults,e||{}),this},_attachDatepicker:function(target,settings){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(),inline=nodeName=="div"||nodeName=="span";target.id||(this.uuid+=1,target.id="dp"+this.uuid);var inst=this._newInst($(target),inline);inst.settings=$.extend({},settings||{},inlineSettings||{}),nodeName=="input"?this._connectDatepicker(target,inst):inline&&this._inlineDatepicker(target,inst)},_newInst:function(e,t){var n=e[0].id.replace(/([^A-Za-z0-9_-])/g,"\\\\$1");return{id:n,input:e,selectedDay:0,selectedMonth:0,selectedYear:0,drawMonth:0,drawYear:0,inline:t,dpDiv:t?bindHover($('
      ')):this.dpDiv}},_connectDatepicker:function(e,t){var n=$(e);t.append=$([]),t.trigger=$([]);if(n.hasClass(this.markerClassName))return;this._attachments(n,t),n.addClass(this.markerClassName).keydown(this._doKeyDown).keypress(this._doKeyPress).keyup(this._doKeyUp).bind("setData.datepicker",function(e,n,r){t.settings[n]=r}).bind("getData.datepicker",function(e,n){return this._get(t,n)}),this._autoSize(t),$.data(e,PROP_NAME,t),t.settings.disabled&&this._disableDatepicker(e)},_attachments:function(e,t){var n=this._get(t,"appendText"),r=this._get(t,"isRTL");t.append&&t.append.remove(),n&&(t.append=$(''+n+""),e[r?"before":"after"](t.append)),e.unbind("focus",this._showDatepicker),t.trigger&&t.trigger.remove();var i=this._get(t,"showOn");(i=="focus"||i=="both")&&e.focus(this._showDatepicker);if(i=="button"||i=="both"){var s=this._get(t,"buttonText"),o=this._get(t,"buttonImage");t.trigger=$(this._get(t,"buttonImageOnly")?$("").addClass(this._triggerClass).attr({src:o,alt:s,title:s}):$('').addClass(this._triggerClass).html(o==""?s:$("").attr({src:o,alt:s,title:s}))),e[r?"before":"after"](t.trigger),t.trigger.click(function(){return $.datepicker._datepickerShowing&&$.datepicker._lastInput==e[0]?$.datepicker._hideDatepicker():$.datepicker._datepickerShowing&&$.datepicker._lastInput!=e[0]?($.datepicker._hideDatepicker(),$.datepicker._showDatepicker(e[0])):$.datepicker._showDatepicker(e[0]),!1})}},_autoSize:function(e){if(this._get(e,"autoSize")&&!e.inline){var t=new Date(2009,11,20),n=this._get(e,"dateFormat");if(n.match(/[DM]/)){var r=function(e){var t=0,n=0;for(var r=0;rt&&(t=e[r].length,n=r);return n};t.setMonth(r(this._get(e,n.match(/MM/)?"monthNames":"monthNamesShort"))),t.setDate(r(this._get(e,n.match(/DD/)?"dayNames":"dayNamesShort"))+20-t.getDay())}e.input.attr("size",this._formatDate(e,t).length)}},_inlineDatepicker:function(e,t){var n=$(e);if(n.hasClass(this.markerClassName))return;n.addClass(this.markerClassName).append(t.dpDiv).bind("setData.datepicker",function(e,n,r){t.settings[n]=r}).bind("getData.datepicker",function(e,n){return this._get(t,n)}),$.data(e,PROP_NAME,t),this._setDate(t,this._getDefaultDate(t),!0),this._updateDatepicker(t),this._updateAlternate(t),t.settings.disabled&&this._disableDatepicker(e),t.dpDiv.css("display","block")},_dialogDatepicker:function(e,t,n,r,i){var s=this._dialogInst;if(!s){this.uuid+=1;var o="dp"+this.uuid;this._dialogInput=$(''),this._dialogInput.keydown(this._doKeyDown),$("body").append(this._dialogInput),s=this._dialogInst=this._newInst(this._dialogInput,!1),s.settings={},$.data(this._dialogInput[0],PROP_NAME,s)}extendRemove(s.settings,r||{}),t=t&&t.constructor==Date?this._formatDate(s,t):t,this._dialogInput.val(t),this._pos=i?i.length?i:[i.pageX,i.pageY]:null;if(!this._pos){var u=document.documentElement.clientWidth,a=document.documentElement.clientHeight,f=document.documentElement.scrollLeft||document.body.scrollLeft,l=document.documentElement.scrollTop||document.body.scrollTop;this._pos=[u/2-100+f,a/2-150+l]}return this._dialogInput.css("left",this._pos[0]+20+"px").css("top",this._pos[1]+"px"),s.settings.onSelect=n,this._inDialog=!0,this.dpDiv.addClass(this._dialogClass),this._showDatepicker(this._dialogInput[0]),$.blockUI&&$.blockUI(this.dpDiv),$.data(this._dialogInput[0],PROP_NAME,s),this},_destroyDatepicker:function(e){var t=$(e),n=$.data(e,PROP_NAME);if(!t.hasClass(this.markerClassName))return;var r=e.nodeName.toLowerCase();$.removeData(e,PROP_NAME),r=="input"?(n.append.remove(),n.trigger.remove(),t.removeClass(this.markerClassName).unbind("focus",this._showDatepicker).unbind("keydown",this._doKeyDown).unbind("keypress",this._doKeyPress).unbind("keyup",this._doKeyUp)):(r=="div"||r=="span")&&t.removeClass(this.markerClassName).empty()},_enableDatepicker:function(e){var t=$(e),n=$.data(e,PROP_NAME);if(!t.hasClass(this.markerClassName))return;var r=e.nodeName.toLowerCase();if(r=="input")e.disabled=!1,n.trigger.filter("button").each(function(){this.disabled=!1}).end().filter("img").css({opacity:"1.0",cursor:""});else if(r=="div"||r=="span"){var i=t.children("."+this._inlineClass);i.children().removeClass("ui-state-disabled"),i.find("select.ui-datepicker-month, select.ui-datepicker-year").prop("disabled",!1)}this._disabledInputs=$.map(this._disabledInputs,function(t){return t==e?null:t})},_disableDatepicker:function(e){var t=$(e),n=$.data(e,PROP_NAME);if(!t.hasClass(this.markerClassName))return;var r=e.nodeName.toLowerCase();if(r=="input")e.disabled=!0,n.trigger.filter("button").each(function(){this.disabled=!0}).end().filter("img").css({opacity:"0.5",cursor:"default"});else if(r=="div"||r=="span"){var i=t.children("."+this._inlineClass);i.children().addClass("ui-state-disabled"),i.find("select.ui-datepicker-month, select.ui-datepicker-year").prop("disabled",!0)}this._disabledInputs=$.map(this._disabledInputs,function(t){return t==e?null:t}),this._disabledInputs[this._disabledInputs.length]=e},_isDisabledDatepicker:function(e){if(!e)return!1;for(var t=0;t-1}},_doKeyUp:function(e){var t=$.datepicker._getInst(e.target);if(t.input.val()!=t.lastVal)try{var n=$.datepicker.parseDate($.datepicker._get(t,"dateFormat"),t.input?t.input.val():null,$.datepicker._getFormatConfig(t));n&&($.datepicker._setDateFromField(t),$.datepicker._updateAlternate(t),$.datepicker._updateDatepicker(t))}catch(r){$.datepicker.log(r)}return!0},_showDatepicker:function(e){e=e.target||e,e.nodeName.toLowerCase()!="input"&&(e=$("input",e.parentNode)[0]);if($.datepicker._isDisabledDatepicker(e)||$.datepicker._lastInput==e)return;var t=$.datepicker._getInst(e);$.datepicker._curInst&&$.datepicker._curInst!=t&&($.datepicker._curInst.dpDiv.stop(!0,!0),t&&$.datepicker._datepickerShowing&&$.datepicker._hideDatepicker($.datepicker._curInst.input[0]));var n=$.datepicker._get(t,"beforeShow"),r=n?n.apply(e,[e,t]):{};if(r===!1)return;extendRemove(t.settings,r),t.lastVal=null,$.datepicker._lastInput=e,$.datepicker._setDateFromField(t),$.datepicker._inDialog&&(e.value=""),$.datepicker._pos||($.datepicker._pos=$.datepicker._findPos(e),$.datepicker._pos[1]+=e.offsetHeight);var i=!1;$(e).parents().each(function(){return i|=$(this).css("position")=="fixed",!i});var s={left:$.datepicker._pos[0],top:$.datepicker._pos[1]};$.datepicker._pos=null,t.dpDiv.empty(),t.dpDiv.css({position:"absolute",display:"block",top:"-1000px"}),$.datepicker._updateDatepicker(t),s=$.datepicker._checkOffset(t,s,i),t.dpDiv.css({position:$.datepicker._inDialog&&$.blockUI?"static":i?"fixed":"absolute",display:"none",left:s.left+"px",top:s.top+"px"});if(!t.inline){var o=$.datepicker._get(t,"showAnim"),u=$.datepicker._get(t,"duration"),a=function(){var e=t.dpDiv.find("iframe.ui-datepicker-cover");if(!!e.length){var n=$.datepicker._getBorders(t.dpDiv);e.css({left:-n[0],top:-n[1],width:t.dpDiv.outerWidth(),height:t.dpDiv.outerHeight()})}};t.dpDiv.zIndex($(e).zIndex()+1),$.datepicker._datepickerShowing=!0,$.effects&&($.effects.effect[o]||$.effects[o])?t.dpDiv.show(o,$.datepicker._get(t,"showOptions"),u,a):t.dpDiv[o||"show"](o?u:null,a),(!o||!u)&&a(),t.input.is(":visible")&&!t.input.is(":disabled")&&t.input.focus(),$.datepicker._curInst=t}},_updateDatepicker:function(e){this.maxRows=4;var t=$.datepicker._getBorders(e.dpDiv);instActive=e,e.dpDiv.empty().append(this._generateHTML(e)),this._attachHandlers(e);var n=e.dpDiv.find("iframe.ui-datepicker-cover");!n.length||n.css({left:-t[0],top:-t[1],width:e.dpDiv.outerWidth(),height:e.dpDiv.outerHeight()}),e.dpDiv.find("."+this._dayOverClass+" a").mouseover();var r=this._getNumberOfMonths(e),i=r[1],s=17;e.dpDiv.removeClass("ui-datepicker-multi-2 ui-datepicker-multi-3 ui-datepicker-multi-4").width(""),i>1&&e.dpDiv.addClass("ui-datepicker-multi-"+i).css("width",s*i+"em"),e.dpDiv[(r[0]!=1||r[1]!=1?"add":"remove")+"Class"]("ui-datepicker-multi"),e.dpDiv[(this._get(e,"isRTL")?"add":"remove")+"Class"]("ui-datepicker-rtl"),e==$.datepicker._curInst&&$.datepicker._datepickerShowing&&e.input&&e.input.is(":visible")&&!e.input.is(":disabled")&&e.input[0]!=document.activeElement&&e.input.focus();if(e.yearshtml){var o=e.yearshtml;setTimeout(function(){o===e.yearshtml&&e.yearshtml&&e.dpDiv.find("select.ui-datepicker-year:first").replaceWith(e.yearshtml),o=e.yearshtml=null},0)}},_getBorders:function(e){var t=function(e){return{thin:1,medium:2,thick:3}[e]||e};return[parseFloat(t(e.css("border-left-width"))),parseFloat(t(e.css("border-top-width")))]},_checkOffset:function(e,t,n){var r=e.dpDiv.outerWidth(),i=e.dpDiv.outerHeight(),s=e.input?e.input.outerWidth():0,o=e.input?e.input.outerHeight():0,u=document.documentElement.clientWidth+(n?0:$(document).scrollLeft()),a=document.documentElement.clientHeight+(n?0:$(document).scrollTop());return t.left-=this._get(e,"isRTL")?r-s:0,t.left-=n&&t.left==e.input.offset().left?$(document).scrollLeft():0,t.top-=n&&t.top==e.input.offset().top+o?$(document).scrollTop():0,t.left-=Math.min(t.left,t.left+r>u&&u>r?Math.abs(t.left+r-u):0),t.top-=Math.min(t.top,t.top+i>a&&a>i?Math.abs(i+o):0),t},_findPos:function(e){var t=this._getInst(e),n=this._get(t,"isRTL");while(e&&(e.type=="hidden"||e.nodeType!=1||$.expr.filters.hidden(e)))e=e[n?"previousSibling":"nextSibling"];var r=$(e).offset();return[r.left,r.top]},_hideDatepicker:function(e){var t=this._curInst;if(!t||e&&t!=$.data(e,PROP_NAME))return;if(this._datepickerShowing){var n=this._get(t,"showAnim"),r=this._get(t,"duration"),i=function(){$.datepicker._tidyDialog(t)};$.effects&&($.effects.effect[n]||$.effects[n])?t.dpDiv.hide(n,$.datepicker._get(t,"showOptions"),r,i):t.dpDiv[n=="slideDown"?"slideUp":n=="fadeIn"?"fadeOut":"hide"](n?r:null,i),n||i(),this._datepickerShowing=!1;var s=this._get(t,"onClose");s&&s.apply(t.input?t.input[0]:null,[t.input?t.input.val():"",t]),this._lastInput=null,this._inDialog&&(this._dialogInput.css({position:"absolute",left:"0",top:"-100px"}),$.blockUI&&($.unblockUI(),$("body").append(this.dpDiv))),this._inDialog=!1}},_tidyDialog:function(e){e.dpDiv.removeClass(this._dialogClass).unbind(".ui-datepicker-calendar")},_checkExternalClick:function(e){if(!$.datepicker._curInst)return;var t=$(e.target),n=$.datepicker._getInst(t[0]);(t[0].id!=$.datepicker._mainDivId&&t.parents("#"+$.datepicker._mainDivId).length==0&&!t.hasClass($.datepicker.markerClassName)&&!t.closest("."+$.datepicker._triggerClass).length&&$.datepicker._datepickerShowing&&(!$.datepicker._inDialog||!$.blockUI)||t.hasClass($.datepicker.markerClassName)&&$.datepicker._curInst!=n)&&$.datepicker._hideDatepicker()},_adjustDate:function(e,t,n){var r=$(e),i=this._getInst(r[0]);if(this._isDisabledDatepicker(r[0]))return;this._adjustInstDate(i,t+(n=="M"?this._get(i,"showCurrentAtPos"):0),n),this._updateDatepicker(i)},_gotoToday:function(e){var t=$(e),n=this._getInst(t[0]);if(this._get(n,"gotoCurrent")&&n.currentDay)n.selectedDay=n.currentDay,n.drawMonth=n.selectedMonth=n.currentMonth,n.drawYear=n.selectedYear=n.currentYear;else{var r=new Date;n.selectedDay=r.getDate(),n.drawMonth=n.selectedMonth=r.getMonth(),n.drawYear=n.selectedYear=r.getFullYear()}this._notifyChange(n),this._adjustDate(t)},_selectMonthYear:function(e,t,n){var r=$(e),i=this._getInst(r[0]);i["selected"+(n=="M"?"Month":"Year")]=i["draw"+(n=="M"?"Month":"Year")]=parseInt(t.options[t.selectedIndex].value,10),this._notifyChange(i),this._adjustDate(r)},_selectDay:function(e,t,n,r){var i=$(e);if($(r).hasClass(this._unselectableClass)||this._isDisabledDatepicker(i[0]))return;var s=this._getInst(i[0]);s.selectedDay=s.currentDay=$("a",r).html(),s.selectedMonth=s.currentMonth=t,s.selectedYear=s.currentYear=n,this._selectDate(e,this._formatDate(s,s.currentDay,s.currentMonth,s.currentYear))},_clearDate:function(e){var t=$(e),n=this._getInst(t[0]);this._selectDate(t,"")},_selectDate:function(e,t){var n=$(e),r=this._getInst(n[0]);t=t!=null?t:this._formatDate(r),r.input&&r.input.val(t),this._updateAlternate(r);var i=this._get(r,"onSelect");i?i.apply(r.input?r.input[0]:null,[t,r]):r.input&&r.input.trigger("change"),r.inline?this._updateDatepicker(r):(this._hideDatepicker(),this._lastInput=r.input[0],typeof r.input[0]!="object"&&r.input.focus(),this._lastInput=null)},_updateAlternate:function(e){var t=this._get(e,"altField");if(t){var n=this._get(e,"altFormat")||this._get(e,"dateFormat"),r=this._getDate(e),i=this.formatDate(n,r,this._getFormatConfig(e));$(t).each(function(){$(this).val(i)})}},noWeekends:function(e){var t=e.getDay();return[t>0&&t<6,""]},iso8601Week:function(e){var t=new Date(e.getTime());t.setDate(t.getDate()+4-(t.getDay()||7));var n=t.getTime();return t.setMonth(0),t.setDate(1),Math.floor(Math.round((n-t)/864e5)/7)+1},parseDate:function(e,t,n){if(e==null||t==null)throw"Invalid arguments";t=typeof t=="object"?t.toString():t+"";if(t=="")return null;var r=(n?n.shortYearCutoff:null)||this._defaults.shortYearCutoff;r=typeof r!="string"?r:(new Date).getFullYear()%100+parseInt(r,10);var i=(n?n.dayNamesShort:null)||this._defaults.dayNamesShort,s=(n?n.dayNames:null)||this._defaults.dayNames,o=(n?n.monthNamesShort:null)||this._defaults.monthNamesShort,u=(n?n.monthNames:null)||this._defaults.monthNames,a=-1,f=-1,l=-1,c=-1,h=!1,p=function(t){var n=y+1-1){f=1,l=c;do{var E=this._getDaysInMonth(a,f-1);if(l<=E)break;f++,l-=E}while(!0)}var b=this._daylightSavingAdjust(new Date(a,f-1,l));if(b.getFullYear()!=a||b.getMonth()+1!=f||b.getDate()!=l)throw"Invalid date";return b},ATOM:"yy-mm-dd",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",TICKS:"!",TIMESTAMP:"@",W3C:"yy-mm-dd",_ticksTo1970:(718685+Math.floor(492.5)-Math.floor(19.7)+Math.floor(4.925))*24*60*60*1e7,formatDate:function(e,t,n){if(!t)return"";var r=(n?n.dayNamesShort:null)||this._defaults.dayNamesShort,i=(n?n.dayNames:null)||this._defaults.dayNames,s=(n?n.monthNamesShort:null)||this._defaults.monthNamesShort,o=(n?n.monthNames:null)||this._defaults.monthNames,u=function(t){var n=h+112?e.getHours()+2:0),e):null},_setDate:function(e,t,n){var r=!t,i=e.selectedMonth,s=e.selectedYear,o=this._restrictMinMax(e,this._determineDate(e,t,new Date));e.selectedDay=e.currentDay=o.getDate(),e.drawMonth=e.selectedMonth=e.currentMonth=o.getMonth(),e.drawYear=e.selectedYear=e.currentYear=o.getFullYear(),(i!=e.selectedMonth||s!=e.selectedYear)&&!n&&this._notifyChange(e),this._adjustInstDate(e),e.input&&e.input.val(r?"":this._formatDate(e))},_getDate:function(e){var t=!e.currentYear||e.input&&e.input.val()==""?null:this._daylightSavingAdjust(new Date(e.currentYear,e.currentMonth,e.currentDay));return t},_attachHandlers:function(e){var t=this._get(e,"stepMonths"),n="#"+e.id.replace(/\\\\/g,"\\");e.dpDiv.find("[data-handler]").map(function(){var e={prev:function(){window["DP_jQuery_"+dpuuid].datepicker._adjustDate(n,-t,"M")},next:function(){window["DP_jQuery_"+dpuuid].datepicker._adjustDate(n,+t,"M")},hide:function(){window["DP_jQuery_"+dpuuid].datepicker._hideDatepicker()},today:function(){window["DP_jQuery_"+dpuuid].datepicker._gotoToday(n)},selectDay:function(){return window["DP_jQuery_"+dpuuid].datepicker._selectDay(n,+this.getAttribute("data-month"),+this.getAttribute("data-year"),this),!1},selectMonth:function(){return window["DP_jQuery_"+dpuuid].datepicker._selectMonthYear(n,this,"M"),!1},selectYear:function(){return window["DP_jQuery_"+dpuuid].datepicker._selectMonthYear(n,this,"Y"),!1}};$(this).bind(this.getAttribute("data-event"),e[this.getAttribute("data-handler")])})},_generateHTML:function(e){var t=new Date;t=this._daylightSavingAdjust(new Date(t.getFullYear(),t.getMonth(),t.getDate()));var n=this._get(e,"isRTL"),r=this._get(e,"showButtonPanel"),i=this._get(e,"hideIfNoPrevNext"),s=this._get(e,"navigationAsDateFormat"),o=this._getNumberOfMonths(e),u=this._get(e,"showCurrentAtPos"),a=this._get(e,"stepMonths"),f=o[0]!=1||o[1]!=1,l=this._daylightSavingAdjust(e.currentDay?new Date(e.currentYear,e.currentMonth,e.currentDay):new Date(9999,9,9)),c=this._getMinMaxDate(e,"min"),h=this._getMinMaxDate(e,"max"),p=e.drawMonth-u,d=e.drawYear;p<0&&(p+=12,d--);if(h){var v=this._daylightSavingAdjust(new Date(h.getFullYear(),h.getMonth()-o[0]*o[1]+1,h.getDate()));v=c&&vv)p--,p<0&&(p=11,d--)}e.drawMonth=p,e.drawYear=d;var m=this._get(e,"prevText");m=s?this.formatDate(m,this._daylightSavingAdjust(new Date(d,p-a,1)),this._getFormatConfig(e)):m;var g=this._canAdjustMonth(e,-1,d,p)?'
      '+m+"":i?"":''+m+"",y=this._get(e,"nextText");y=s?this.formatDate(y,this._daylightSavingAdjust(new Date(d,p+a,1)),this._getFormatConfig(e)):y;var b=this._canAdjustMonth(e,1,d,p)?''+y+"":i?"":''+y+"",w=this._get(e,"currentText"),E=this._get(e,"gotoCurrent")&&e.currentDay?l:t;w=s?this.formatDate(w,E,this._getFormatConfig(e)):w;var S=e.inline?"":'",x=r?'
      '+(n?S:"")+(this._isInRange(e,E)?'":"")+(n?"":S)+"
      ":"",T=parseInt(this._get(e,"firstDay"),10);T=isNaN(T)?0:T;var N=this._get(e,"showWeek"),C=this._get(e,"dayNames"),k=this._get(e,"dayNamesShort"),L=this._get(e,"dayNamesMin"),A=this._get(e,"monthNames"),O=this._get(e,"monthNamesShort"),M=this._get(e,"beforeShowDay"),_=this._get(e,"showOtherMonths"),D=this._get(e,"selectOtherMonths"),P=this._get(e,"calculateWeek")||this.iso8601Week,H=this._getDefaultDate(e),B="";for(var j=0;j1)switch(I){case 0:U+=" ui-datepicker-group-first",R=" ui-corner-"+(n?"right":"left");break;case o[1]-1:U+=" ui-datepicker-group-last",R=" ui-corner-"+(n?"left":"right");break;default:U+=" ui-datepicker-group-middle",R=""}U+='">'}U+='
      '+(/all|left/.test(R)&&j==0?n?b:g:"")+(/all|right/.test(R)&&j==0?n?g:b:"")+this._generateMonthYearHeader(e,p,d,c,h,j>0||I>0,A,O)+'
      '+"";var z=N?'":"";for(var W=0;W<7;W++){var X=(W+T)%7;z+="=5?' class="ui-datepicker-week-end"':"")+">"+''+L[X]+""}U+=z+"";var V=this._getDaysInMonth(d,p);d==e.selectedYear&&p==e.selectedMonth&&(e.selectedDay=Math.min(e.selectedDay,V));var J=(this._getFirstDayOfMonth(d,p)-T+7)%7,K=Math.ceil((J+V)/7),Q=f?this.maxRows>K?this.maxRows:K:K;this.maxRows=Q;var G=this._daylightSavingAdjust(new Date(d,p,1-J));for(var Y=0;Y";var Z=N?'":"";for(var W=0;W<7;W++){var et=M?M.apply(e.input?e.input[0]:null,[G]):[!0,""],tt=G.getMonth()!=p,nt=tt&&!D||!et[0]||c&&Gh;Z+='",G.setDate(G.getDate()+1),G=this._daylightSavingAdjust(G)}U+=Z+""}p++,p>11&&(p=0,d++),U+="
      '+this._get(e,"weekHeader")+"
      '+this._get(e,"calculateWeek")(G)+""+(tt&&!_?" ":nt?''+G.getDate()+"":''+G.getDate()+"")+"
      "+(f?"
      "+(o[0]>0&&I==o[1]-1?'
      ':""):""),F+=U}B+=F}return B+=x+($.browser.msie&&parseInt($.browser.version,10)<7&&!e.inline?'':""),e._keyEvent=!1,B},_generateMonthYearHeader:function(e,t,n,r,i,s,o,u){var a=this._get(e,"changeMonth"),f=this._get(e,"changeYear"),l=this._get(e,"showMonthAfterYear"),c='
      ',h="";if(s||!a)h+=''+o[t]+"";else{var p=r&&r.getFullYear()==n,d=i&&i.getFullYear()==n;h+='"}l||(c+=h+(s||!a||!f?" ":""));if(!e.yearshtml){e.yearshtml="";if(s||!f)c+=''+n+"";else{var m=this._get(e,"yearRange").split(":"),g=(new Date).getFullYear(),y=function(e){var t=e.match(/c[+-].*/)?n+parseInt(e.substring(1),10):e.match(/[+-].*/)?g+parseInt(e,10):parseInt(e,10);return isNaN(t)?g:t},b=y(m[0]),w=Math.max(b,y(m[1]||""));b=r?Math.max(b,r.getFullYear()):b,w=i?Math.min(w,i.getFullYear()):w,e.yearshtml+='",c+=e.yearshtml,e.yearshtml=null}}return c+=this._get(e,"yearSuffix"),l&&(c+=(s||!a||!f?" ":"")+h),c+="
      ",c},_adjustInstDate:function(e,t,n){var r=e.drawYear+(n=="Y"?t:0),i=e.drawMonth+(n=="M"?t:0),s=Math.min(e.selectedDay,this._getDaysInMonth(r,i))+(n=="D"?t:0),o=this._restrictMinMax(e,this._daylightSavingAdjust(new Date(r,i,s)));e.selectedDay=o.getDate(),e.drawMonth=e.selectedMonth=o.getMonth(),e.drawYear=e.selectedYear=o.getFullYear(),(n=="M"||n=="Y")&&this._notifyChange(e)},_restrictMinMax:function(e,t){var n=this._getMinMaxDate(e,"min"),r=this._getMinMaxDate(e,"max"),i=n&&tr?r:i,i},_notifyChange:function(e){var t=this._get(e,"onChangeMonthYear");t&&t.apply(e.input?e.input[0]:null,[e.selectedYear,e.selectedMonth+1,e])},_getNumberOfMonths:function(e){var t=this._get(e,"numberOfMonths");return t==null?[1,1]:typeof t=="number"?[1,t]:t},_getMinMaxDate:function(e,t){return this._determineDate(e,this._get(e,t+"Date"),null)},_getDaysInMonth:function(e,t){return 32-this._daylightSavingAdjust(new Date(e,t,32)).getDate()},_getFirstDayOfMonth:function(e,t){return(new Date(e,t,1)).getDay()},_canAdjustMonth:function(e,t,n,r){var i=this._getNumberOfMonths(e),s=this._daylightSavingAdjust(new Date(n,r+(t<0?t:i[0]*i[1]),1));return t<0&&s.setDate(this._getDaysInMonth(s.getFullYear(),s.getMonth())),this._isInRange(e,s)},_isInRange:function(e,t){var n=this._getMinMaxDate(e,"min"),r=this._getMinMaxDate(e,"max");return(!n||t.getTime()>=n.getTime())&&(!r||t.getTime()<=r.getTime())},_getFormatConfig:function(e){var t=this._get(e,"shortYearCutoff");return t=typeof t!="string"?t:(new Date).getFullYear()%100+parseInt(t,10),{shortYearCutoff:t,dayNamesShort:this._get(e,"dayNamesShort"),dayNames:this._get(e,"dayNames"),monthNamesShort:this._get(e,"monthNamesShort"),monthNames:this._get(e,"monthNames")}},_formatDate:function(e,t,n,r){t||(e.currentDay=e.selectedDay,e.currentMonth=e.selectedMonth,e.currentYear=e.selectedYear);var i=t?typeof t=="object"?t:this._daylightSavingAdjust(new Date(r,n,t)):this._daylightSavingAdjust(new Date(e.currentYear,e.currentMonth,e.currentDay));return this.formatDate(this._get(e,"dateFormat"),i,this._getFormatConfig(e))}}),$.fn.datepicker=function(e){if(!this.length)return this;$.datepicker.initialized||($(document).mousedown($.datepicker._checkExternalClick).find(document.body).append($.datepicker.dpDiv),$.datepicker.initialized=!0);var t=Array.prototype.slice.call(arguments,1);return typeof e!="string"||e!="isDisabled"&&e!="getDate"&&e!="widget"?e=="option"&&arguments.length==2&&typeof arguments[1]=="string"?$.datepicker["_"+e+"Datepicker"].apply($.datepicker,[this[0]].concat(t)):this.each(function(){typeof e=="string"?$.datepicker["_"+e+"Datepicker"].apply($.datepicker,[this].concat(t)):$.datepicker._attachDatepicker(this,e)}):$.datepicker["_"+e+"Datepicker"].apply($.datepicker,[this[0]].concat(t))},$.datepicker=new Datepicker,$.datepicker.initialized=!1,$.datepicker.uuid=(new Date).getTime(),$.datepicker.version="1.9.0",window["DP_jQuery_"+dpuuid]=$})(jQuery); \ No newline at end of file diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/ui/minified/jquery.ui.dialog.min.js b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/ui/minified/jquery.ui.dialog.min.js new file mode 100755 index 000000000..aa3837c3b --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/ui/minified/jquery.ui.dialog.min.js @@ -0,0 +1,5 @@ +/*! jQuery UI - v1.9.0 - 2012-10-08 +* http://jqueryui.com +* Includes: jquery.ui.dialog.js +* Copyright 2012 jQuery Foundation and other contributors; Licensed MIT */ +(function(e,t){var n="ui-dialog ui-widget ui-widget-content ui-corner-all ",r={buttons:!0,height:!0,maxHeight:!0,maxWidth:!0,minHeight:!0,minWidth:!0,width:!0},i={maxHeight:!0,maxWidth:!0,minHeight:!0,minWidth:!0};e.widget("ui.dialog",{version:"1.9.0",options:{autoOpen:!0,buttons:{},closeOnEscape:!0,closeText:"close",dialogClass:"",draggable:!0,hide:null,height:"auto",maxHeight:!1,maxWidth:!1,minHeight:150,minWidth:150,modal:!1,position:{my:"center",at:"center",of:window,collision:"fit",using:function(t){var n=e(this).css(t).offset().top;n<0&&e(this).css("top",t.top-n)}},resizable:!0,show:null,stack:!0,title:"",width:300,zIndex:1e3},_create:function(){this.originalTitle=this.element.attr("title"),typeof this.originalTitle!="string"&&(this.originalTitle=""),this.oldPosition={parent:this.element.parent(),index:this.element.parent().children().index(this.element)},this.options.title=this.options.title||this.originalTitle;var t=this,r=this.options,i=r.title||" ",s=(this.uiDialog=e("
      ")).addClass(n+r.dialogClass).css({display:"none",outline:0,zIndex:r.zIndex}).attr("tabIndex",-1).keydown(function(n){r.closeOnEscape&&!n.isDefaultPrevented()&&n.keyCode&&n.keyCode===e.ui.keyCode.ESCAPE&&(t.close(n),n.preventDefault())}).mousedown(function(e){t.moveToTop(!1,e)}).appendTo("body"),o=this.element.show().removeAttr("title").addClass("ui-dialog-content ui-widget-content").appendTo(s),u=(this.uiDialogTitlebar=e("
      ")).addClass("ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix").prependTo(s),a=e("").addClass("ui-dialog-titlebar-close ui-corner-all").attr("role","button").click(function(e){e.preventDefault(),t.close(e)}).appendTo(u),f=(this.uiDialogTitlebarCloseText=e("")).addClass("ui-icon ui-icon-closethick").text(r.closeText).appendTo(a),l=e("").uniqueId().addClass("ui-dialog-title").html(i).prependTo(u),c=(this.uiDialogButtonPane=e("
      ")).addClass("ui-dialog-buttonpane ui-widget-content ui-helper-clearfix"),h=(this.uiButtonSet=e("
      ")).addClass("ui-dialog-buttonset").appendTo(c);s.attr({role:"dialog","aria-labelledby":l.attr("id")}),u.find("*").add(u).disableSelection(),this._hoverable(a),this._focusable(a),r.draggable&&e.fn.draggable&&this._makeDraggable(),r.resizable&&e.fn.resizable&&this._makeResizable(),this._createButtons(r.buttons),this._isOpen=!1,e.fn.bgiframe&&s.bgiframe(),this._on(s,{keydown:function(t){if(!r.modal||t.keyCode!==e.ui.keyCode.TAB)return;var n=e(":tabbable",s),i=n.filter(":first"),o=n.filter(":last");if(t.target===o[0]&&!t.shiftKey)return i.focus(1),!1;if(t.target===i[0]&&t.shiftKey)return o.focus(1),!1}})},_init:function(){this.options.autoOpen&&this.open()},_destroy:function(){var e,t=this.oldPosition;this.overlay&&this.overlay.destroy(),this.uiDialog.hide(),this.element.removeClass("ui-dialog-content ui-widget-content").hide().appendTo("body"),this.uiDialog.remove(),this.originalTitle&&this.element.attr("title",this.originalTitle),e=t.parent.children().eq(t.index),e.length&&e[0]!==this.element[0]?e.before(this.element):t.parent.append(this.element)},widget:function(){return this.uiDialog},close:function(t){var n=this,r,i;if(!this._isOpen)return;if(!1===this._trigger("beforeClose",t))return;return this._isOpen=!1,this.overlay&&this.overlay.destroy(),this.options.hide?this.uiDialog.hide(this.options.hide,function(){n._trigger("close",t)}):(this.uiDialog.hide(),this._trigger("close",t)),e.ui.dialog.overlay.resize(),this.options.modal&&(r=0,e(".ui-dialog").each(function(){this!==n.uiDialog[0]&&(i=e(this).css("z-index"),isNaN(i)||(r=Math.max(r,i)))}),e.ui.dialog.maxZ=r),this},isOpen:function(){return this._isOpen},moveToTop:function(t,n){var r=this.options,i;return r.modal&&!t||!r.stack&&!r.modal?this._trigger("focus",n):(r.zIndex>e.ui.dialog.maxZ&&(e.ui.dialog.maxZ=r.zIndex),this.overlay&&(e.ui.dialog.maxZ+=1,e.ui.dialog.overlay.maxZ=e.ui.dialog.maxZ,this.overlay.$el.css("z-index",e.ui.dialog.overlay.maxZ)),i={scrollTop:this.element.scrollTop(),scrollLeft:this.element.scrollLeft()},e.ui.dialog.maxZ+=1,this.uiDialog.css("z-index",e.ui.dialog.maxZ),this.element.attr(i),this._trigger("focus",n),this)},open:function(){if(this._isOpen)return;var t,n=this.options,r=this.uiDialog;return this._size(),this._position(n.position),r.show(n.show),this.overlay=n.modal?new e.ui.dialog.overlay(this):null,this.moveToTop(!0),t=this.element.find(":tabbable"),t.length||(t=this.uiDialogButtonPane.find(":tabbable"),t.length||(t=r)),t.eq(0).focus(),this._isOpen=!0,this._trigger("open"),this},_createButtons:function(t){var n,r,i=this,s=!1;this.uiDialogButtonPane.remove(),this.uiButtonSet.empty(),typeof t=="object"&&t!==null&&e.each(t,function(){return!(s=!0)}),s?(e.each(t,function(t,n){n=e.isFunction(n)?{click:n,text:t}:n;var r=e("
      ').css({width:this.offsetWidth+"px",height:this.offsetHeight+"px",position:"absolute",opacity:"0.001",zIndex:1e3}).css(e(this).offset()).appendTo("body")}),!0):!1)},_mouseStart:function(t){var n=this.options;return this.helper=this._createHelper(t),this.helper.addClass("ui-draggable-dragging"),this._cacheHelperProportions(),e.ui.ddmanager&&(e.ui.ddmanager.current=this),this._cacheMargins(),this.cssPosition=this.helper.css("position"),this.scrollParent=this.helper.scrollParent(),this.offset=this.positionAbs=this.element.offset(),this.offset={top:this.offset.top-this.margins.top,left:this.offset.left-this.margins.left},e.extend(this.offset,{click:{left:t.pageX-this.offset.left,top:t.pageY-this.offset.top},parent:this._getParentOffset(),relative:this._getRelativeOffset()}),this.originalPosition=this.position=this._generatePosition(t),this.originalPageX=t.pageX,this.originalPageY=t.pageY,n.cursorAt&&this._adjustOffsetFromHelper(n.cursorAt),n.containment&&this._setContainment(),this._trigger("start",t)===!1?(this._clear(),!1):(this._cacheHelperProportions(),e.ui.ddmanager&&!n.dropBehaviour&&e.ui.ddmanager.prepareOffsets(this,t),this._mouseDrag(t,!0),e.ui.ddmanager&&e.ui.ddmanager.dragStart(this,t),!0)},_mouseDrag:function(t,n){this.position=this._generatePosition(t),this.positionAbs=this._convertPositionTo("absolute");if(!n){var r=this._uiHash();if(this._trigger("drag",t,r)===!1)return this._mouseUp({}),!1;this.position=r.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";return e.ui.ddmanager&&e.ui.ddmanager.drag(this,t),!1},_mouseStop:function(t){var n=!1;e.ui.ddmanager&&!this.options.dropBehaviour&&(n=e.ui.ddmanager.drop(this,t)),this.dropped&&(n=this.dropped,this.dropped=!1);var r=this.element[0],i=!1;while(r&&(r=r.parentNode))r==document&&(i=!0);if(!i&&this.options.helper==="original")return!1;if(this.options.revert=="invalid"&&!n||this.options.revert=="valid"&&n||this.options.revert===!0||e.isFunction(this.options.revert)&&this.options.revert.call(this.element,n)){var s=this;e(this.helper).animate(this.originalPosition,parseInt(this.options.revertDuration,10),function(){s._trigger("stop",t)!==!1&&s._clear()})}else this._trigger("stop",t)!==!1&&this._clear();return!1},_mouseUp:function(t){return e("div.ui-draggable-iframeFix").each(function(){this.parentNode.removeChild(this)}),e.ui.ddmanager&&e.ui.ddmanager.dragStop(this,t),e.ui.mouse.prototype._mouseUp.call(this,t)},cancel:function(){return this.helper.is(".ui-draggable-dragging")?this._mouseUp({}):this._clear(),this},_getHandle:function(t){var n=!this.options.handle||!e(this.options.handle,this.element).length?!0:!1;return e(this.options.handle,this.element).find("*").andSelf().each(function(){this==t.target&&(n=!0)}),n},_createHelper:function(t){var n=this.options,r=e.isFunction(n.helper)?e(n.helper.apply(this.element[0],[t])):n.helper=="clone"?this.element.clone().removeAttr("id"):this.element;return r.parents("body").length||r.appendTo(n.appendTo=="parent"?this.element[0].parentNode:n.appendTo),r[0]!=this.element[0]&&!/(fixed|absolute)/.test(r.css("position"))&&r.css("position","absolute"),r},_adjustOffsetFromHelper:function(t){typeof t=="string"&&(t=t.split(" ")),e.isArray(t)&&(t={left:+t[0],top:+t[1]||0}),"left"in t&&(this.offset.click.left=t.left+this.margins.left),"right"in t&&(this.offset.click.left=this.helperProportions.width-t.right+this.margins.left),"top"in t&&(this.offset.click.top=t.top+this.margins.top),"bottom"in t&&(this.offset.click.top=this.helperProportions.height-t.bottom+this.margins.top)},_getParentOffset:function(){this.offsetParent=this.helper.offsetParent();var t=this.offsetParent.offset();this.cssPosition=="absolute"&&this.scrollParent[0]!=document&&e.contains(this.scrollParent[0],this.offsetParent[0])&&(t.left+=this.scrollParent.scrollLeft(),t.top+=this.scrollParent.scrollTop());if(this.offsetParent[0]==document.body||this.offsetParent[0].tagName&&this.offsetParent[0].tagName.toLowerCase()=="html"&&e.browser.msie)t={top:0,left:0};return{top:t.top+(parseInt(this.offsetParent.css("borderTopWidth"),10)||0),left:t.left+(parseInt(this.offsetParent.css("borderLeftWidth"),10)||0)}},_getRelativeOffset:function(){if(this.cssPosition=="relative"){var e=this.element.position();return{top:e.top-(parseInt(this.helper.css("top"),10)||0)+this.scrollParent.scrollTop(),left:e.left-(parseInt(this.helper.css("left"),10)||0)+this.scrollParent.scrollLeft()}}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 t=this.options;t.containment=="parent"&&(t.containment=this.helper[0].parentNode);if(t.containment=="document"||t.containment=="window")this.containment=[t.containment=="document"?0:e(window).scrollLeft()-this.offset.relative.left-this.offset.parent.left,t.containment=="document"?0:e(window).scrollTop()-this.offset.relative.top-this.offset.parent.top,(t.containment=="document"?0:e(window).scrollLeft())+e(t.containment=="document"?document:window).width()-this.helperProportions.width-this.margins.left,(t.containment=="document"?0:e(window).scrollTop())+(e(t.containment=="document"?document:window).height()||document.body.parentNode.scrollHeight)-this.helperProportions.height-this.margins.top];if(!/^(document|window|parent)$/.test(t.containment)&&t.containment.constructor!=Array){var n=e(t.containment),r=n[0];if(!r)return;var i=n.offset(),s=e(r).css("overflow")!="hidden";this.containment=[(parseInt(e(r).css("borderLeftWidth"),10)||0)+(parseInt(e(r).css("paddingLeft"),10)||0),(parseInt(e(r).css("borderTopWidth"),10)||0)+(parseInt(e(r).css("paddingTop"),10)||0),(s?Math.max(r.scrollWidth,r.offsetWidth):r.offsetWidth)-(parseInt(e(r).css("borderLeftWidth"),10)||0)-(parseInt(e(r).css("paddingRight"),10)||0)-this.helperProportions.width-this.margins.left-this.margins.right,(s?Math.max(r.scrollHeight,r.offsetHeight):r.offsetHeight)-(parseInt(e(r).css("borderTopWidth"),10)||0)-(parseInt(e(r).css("paddingBottom"),10)||0)-this.helperProportions.height-this.margins.top-this.margins.bottom],this.relative_container=n}else t.containment.constructor==Array&&(this.containment=t.containment)},_convertPositionTo:function(t,n){n||(n=this.position);var r=t=="absolute"?1:-1,i=this.options,s=this.cssPosition!="absolute"||this.scrollParent[0]!=document&&!!e.contains(this.scrollParent[0],this.offsetParent[0])?this.scrollParent:this.offsetParent,o=/(html|body)/i.test(s[0].tagName);return{top:n.top+this.offset.relative.top*r+this.offset.parent.top*r-(this.cssPosition=="fixed"?-this.scrollParent.scrollTop():o?0:s.scrollTop())*r,left:n.left+this.offset.relative.left*r+this.offset.parent.left*r-(this.cssPosition=="fixed"?-this.scrollParent.scrollLeft():o?0:s.scrollLeft())*r}},_generatePosition:function(t){var n=this.options,r=this.cssPosition!="absolute"||this.scrollParent[0]!=document&&!!e.contains(this.scrollParent[0],this.offsetParent[0])?this.scrollParent:this.offsetParent,i=/(html|body)/i.test(r[0].tagName),s=t.pageX,o=t.pageY;if(this.originalPosition){var u;if(this.containment){if(this.relative_container){var a=this.relative_container.offset();u=[this.containment[0]+a.left,this.containment[1]+a.top,this.containment[2]+a.left,this.containment[3]+a.top]}else u=this.containment;t.pageX-this.offset.click.leftu[2]&&(s=u[2]+this.offset.click.left),t.pageY-this.offset.click.top>u[3]&&(o=u[3]+this.offset.click.top)}if(n.grid){var f=n.grid[1]?this.originalPageY+Math.round((o-this.originalPageY)/n.grid[1])*n.grid[1]:this.originalPageY;o=u?f-this.offset.click.topu[3]?f-this.offset.click.topu[2]?l-this.offset.click.left=0;l--){var c=r.snapElements[l].left,h=c+r.snapElements[l].width,p=r.snapElements[l].top,d=p+r.snapElements[l].height;if(!(c-s=l&&o<=c||u>=l&&u<=c||oc)&&(i>=a&&i<=f||s>=a&&s<=f||if);default:return!1}},e.ui.ddmanager={current:null,droppables:{"default":[]},prepareOffsets:function(t,n){var r=e.ui.ddmanager.droppables[t.options.scope]||[],i=n?n.type:null,s=(t.currentItem||t.element).find(":data(droppable)").andSelf();e:for(var o=0;o1&&b.splice.apply(b,[1,0].concat(b.splice(w,c+1))),r.dequeue()}})(jQuery); \ No newline at end of file diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/ui/minified/jquery.ui.effect-clip.min.js b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/ui/minified/jquery.ui.effect-clip.min.js new file mode 100755 index 000000000..dc92fb4f8 --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/ui/minified/jquery.ui.effect-clip.min.js @@ -0,0 +1,5 @@ +/*! jQuery UI - v1.9.0 - 2012-10-08 +* http://jqueryui.com +* Includes: jquery.ui.effect-clip.js +* Copyright 2012 jQuery Foundation and other contributors; Licensed MIT */ +(function(e,t){e.effects.effect.clip=function(t,n){var r=e(this),i=["position","top","bottom","left","right","height","width"],s=e.effects.setMode(r,t.mode||"hide"),o=s==="show",u=t.direction||"vertical",a=u==="vertical",f=a?"height":"width",l=a?"top":"left",c={},h,p,d;e.effects.save(r,i),r.show(),h=e.effects.createWrapper(r).css({overflow:"hidden"}),p=r[0].tagName==="IMG"?h:r,d=p[f](),o&&(p.css(f,0),p.css(l,d/2)),c[f]=o?d:0,c[l]=o?0:d/2,p.animate(c,{queue:!1,duration:t.duration,easing:t.easing,complete:function(){o||r.hide(),e.effects.restore(r,i),e.effects.removeWrapper(r),n()}})}})(jQuery); \ No newline at end of file diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/ui/minified/jquery.ui.effect-drop.min.js b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/ui/minified/jquery.ui.effect-drop.min.js new file mode 100755 index 000000000..1d1bcbbf9 --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/ui/minified/jquery.ui.effect-drop.min.js @@ -0,0 +1,5 @@ +/*! jQuery UI - v1.9.0 - 2012-10-08 +* http://jqueryui.com +* Includes: jquery.ui.effect-drop.js +* Copyright 2012 jQuery Foundation and other contributors; Licensed MIT */ +(function(e,t){e.effects.effect.drop=function(t,n){var r=e(this),i=["position","top","bottom","left","right","opacity","height","width"],s=e.effects.setMode(r,t.mode||"hide"),o=s==="show",u=t.direction||"left",a=u==="up"||u==="down"?"top":"left",f=u==="up"||u==="left"?"pos":"neg",l={opacity:o?1:0},c;e.effects.save(r,i),r.show(),e.effects.createWrapper(r),c=t.distance||r[a==="top"?"outerHeight":"outerWidth"](!0)/2,o&&r.css("opacity",0).css(a,f==="pos"?-c:c),l[a]=(o?f==="pos"?"+=":"-=":f==="pos"?"-=":"+=")+c,r.animate(l,{queue:!1,duration:t.duration,easing:t.easing,complete:function(){s==="hide"&&r.hide(),e.effects.restore(r,i),e.effects.removeWrapper(r),n()}})}})(jQuery); \ No newline at end of file diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/ui/minified/jquery.ui.effect-explode.min.js b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/ui/minified/jquery.ui.effect-explode.min.js new file mode 100755 index 000000000..7b78ffd41 --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/ui/minified/jquery.ui.effect-explode.min.js @@ -0,0 +1,5 @@ +/*! jQuery UI - v1.9.0 - 2012-10-08 +* http://jqueryui.com +* Includes: jquery.ui.effect-explode.js +* Copyright 2012 jQuery Foundation and other contributors; Licensed MIT */ +(function(e,t){e.effects.effect.explode=function(t,n){function y(){c.push(this),c.length===r*i&&b()}function b(){s.css({visibility:"visible"}),e(c).remove(),u||s.hide(),n()}var r=t.pieces?Math.round(Math.sqrt(t.pieces)):3,i=r,s=e(this),o=e.effects.setMode(s,t.mode||"hide"),u=o==="show",a=s.show().css("visibility","hidden").offset(),f=Math.ceil(s.outerWidth()/i),l=Math.ceil(s.outerHeight()/r),c=[],h,p,d,v,m,g;for(h=0;h
      ").css({position:"absolute",visibility:"visible",left:-p*f,top:-h*l}).parent().addClass("ui-effects-explode").css({position:"absolute",overflow:"hidden",width:f,height:l,left:d+(u?m*f:0),top:v+(u?g*l:0),opacity:u?0:1}).animate({left:d+(u?0:m*f),top:v+(u?0:g*l),opacity:u?1:0},t.duration||500,t.easing,y)}}})(jQuery); \ No newline at end of file diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/ui/minified/jquery.ui.effect-fade.min.js b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/ui/minified/jquery.ui.effect-fade.min.js new file mode 100755 index 000000000..c636b3898 --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/ui/minified/jquery.ui.effect-fade.min.js @@ -0,0 +1,5 @@ +/*! jQuery UI - v1.9.0 - 2012-10-08 +* http://jqueryui.com +* Includes: jquery.ui.effect-fade.js +* Copyright 2012 jQuery Foundation and other contributors; Licensed MIT */ +(function(e,t){e.effects.effect.fade=function(t,n){var r=e(this),i=e.effects.setMode(r,t.mode||"toggle");r.animate({opacity:i},{queue:!1,duration:t.duration,easing:t.easing,complete:n})}})(jQuery); \ No newline at end of file diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/ui/minified/jquery.ui.effect-fold.min.js b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/ui/minified/jquery.ui.effect-fold.min.js new file mode 100755 index 000000000..0d6275a78 --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/ui/minified/jquery.ui.effect-fold.min.js @@ -0,0 +1,5 @@ +/*! jQuery UI - v1.9.0 - 2012-10-08 +* http://jqueryui.com +* Includes: jquery.ui.effect-fold.js +* Copyright 2012 jQuery Foundation and other contributors; Licensed MIT */ +(function(e,t){e.effects.effect.fold=function(t,n){var r=e(this),i=["position","top","bottom","left","right","height","width"],s=e.effects.setMode(r,t.mode||"hide"),o=s==="show",u=s==="hide",a=t.size||15,f=/([0-9]+)%/.exec(a),l=!!t.horizFirst,c=o!==l,h=c?["width","height"]:["height","width"],p=t.duration/2,d,v,m={},g={};e.effects.save(r,i),r.show(),d=e.effects.createWrapper(r).css({overflow:"hidden"}),v=c?[d.width(),d.height()]:[d.height(),d.width()],f&&(a=parseInt(f[1],10)/100*v[u?0:1]),o&&d.css(l?{height:0,width:a}:{height:a,width:0}),m[h[0]]=o?v[0]:a,g[h[1]]=o?v[1]:0,d.animate(m,p,t.easing).animate(g,p,t.easing,function(){u&&r.hide(),e.effects.restore(r,i),e.effects.removeWrapper(r),n()})}})(jQuery); \ No newline at end of file diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/ui/minified/jquery.ui.effect-highlight.min.js b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/ui/minified/jquery.ui.effect-highlight.min.js new file mode 100755 index 000000000..b0c3abb8d --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/ui/minified/jquery.ui.effect-highlight.min.js @@ -0,0 +1,5 @@ +/*! jQuery UI - v1.9.0 - 2012-10-08 +* http://jqueryui.com +* Includes: jquery.ui.effect-highlight.js +* Copyright 2012 jQuery Foundation and other contributors; Licensed MIT */ +(function(e,t){e.effects.effect.highlight=function(t,n){var r=e(this),i=["backgroundImage","backgroundColor","opacity"],s=e.effects.setMode(r,t.mode||"show"),o={backgroundColor:r.css("backgroundColor")};s==="hide"&&(o.opacity=0),e.effects.save(r,i),r.show().css({backgroundImage:"none",backgroundColor:t.color||"#ffff99"}).animate(o,{queue:!1,duration:t.duration,easing:t.easing,complete:function(){s==="hide"&&r.hide(),e.effects.restore(r,i),n()}})}})(jQuery); \ No newline at end of file diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/ui/minified/jquery.ui.effect-pulsate.min.js b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/ui/minified/jquery.ui.effect-pulsate.min.js new file mode 100755 index 000000000..d39cd6a27 --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/ui/minified/jquery.ui.effect-pulsate.min.js @@ -0,0 +1,5 @@ +/*! jQuery UI - v1.9.0 - 2012-10-08 +* http://jqueryui.com +* Includes: jquery.ui.effect-pulsate.js +* Copyright 2012 jQuery Foundation and other contributors; Licensed MIT */ +(function(e,t){e.effects.effect.pulsate=function(t,n){var r=e(this),i=e.effects.setMode(r,t.mode||"show"),s=i==="show",o=i==="hide",u=s||i==="hide",a=(t.times||5)*2+(u?1:0),f=t.duration/a,l=0,c=r.queue(),h=c.length,p;if(s||!r.is(":visible"))r.css("opacity",0).show(),l=1;for(p=1;p1&&c.splice.apply(c,[1,0].concat(c.splice(h,a+1))),r.dequeue()}})(jQuery); \ No newline at end of file diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/ui/minified/jquery.ui.effect-scale.min.js b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/ui/minified/jquery.ui.effect-scale.min.js new file mode 100755 index 000000000..6058b5f6c --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/ui/minified/jquery.ui.effect-scale.min.js @@ -0,0 +1,5 @@ +/*! jQuery UI - v1.9.0 - 2012-10-08 +* http://jqueryui.com +* Includes: jquery.ui.effect-scale.js +* Copyright 2012 jQuery Foundation and other contributors; Licensed MIT */ +(function(e,t){e.effects.effect.puff=function(t,n){var r=e(this),i=e.effects.setMode(r,t.mode||"hide"),s=i==="hide",o=parseInt(t.percent,10)||150,u=o/100,a={height:r.height(),width:r.width()};e.extend(t,{effect:"scale",queue:!1,fade:!0,mode:i,complete:n,percent:s?o:100,from:s?a:{height:a.height*u,width:a.width*u}}),r.effect(t)},e.effects.effect.scale=function(t,n){var r=e(this),i=e.extend(!0,{},t),s=e.effects.setMode(r,t.mode||"effect"),o=parseInt(t.percent,10)||(parseInt(t.percent,10)===0?0:s==="hide"?0:100),u=t.direction||"both",a=t.origin,f={height:r.height(),width:r.width(),outerHeight:r.outerHeight(),outerWidth:r.outerWidth()},l={y:u!=="horizontal"?o/100:1,x:u!=="vertical"?o/100:1};i.effect="size",i.queue=!1,i.complete=n,s!=="effect"&&(i.origin=a||["middle","center"],i.restore=!0),i.from=t.from||(s==="show"?{height:0,width:0}:f),i.to={height:f.height*l.y,width:f.width*l.x,outerHeight:f.outerHeight*l.y,outerWidth:f.outerWidth*l.x},i.fade&&(s==="show"&&(i.from.opacity=0,i.to.opacity=1),s==="hide"&&(i.from.opacity=1,i.to.opacity=0)),r.effect(i)},e.effects.effect.size=function(t,n){var r=e(this),i=["position","top","bottom","left","right","width","height","overflow","opacity"],s=["position","top","bottom","left","right","overflow","opacity"],o=["width","height","overflow"],u=["fontSize"],a=["borderTopWidth","borderBottomWidth","paddingTop","paddingBottom"],f=["borderLeftWidth","borderRightWidth","paddingLeft","paddingRight"],l=e.effects.setMode(r,t.mode||"effect"),c=t.restore||l!=="effect",h=t.scale||"both",p=t.origin||["middle","center"],d,v,m,g=r.css("position");l==="show"&&r.show(),d={height:r.height(),width:r.width(),outerHeight:r.outerHeight(),outerWidth:r.outerWidth()},r.from=t.from||d,r.to=t.to||d,m={from:{y:r.from.height/d.height,x:r.from.width/d.width},to:{y:r.to.height/d.height,x:r.to.width/d.width}};if(h==="box"||h==="both")m.from.y!==m.to.y&&(i=i.concat(a),r.from=e.effects.setTransition(r,a,m.from.y,r.from),r.to=e.effects.setTransition(r,a,m.to.y,r.to)),m.from.x!==m.to.x&&(i=i.concat(f),r.from=e.effects.setTransition(r,f,m.from.x,r.from),r.to=e.effects.setTransition(r,f,m.to.x,r.to));(h==="content"||h==="both")&&m.from.y!==m.to.y&&(i=i.concat(u),r.from=e.effects.setTransition(r,u,m.from.y,r.from),r.to=e.effects.setTransition(r,u,m.to.y,r.to)),e.effects.save(r,c?i:s),r.show(),e.effects.createWrapper(r),r.css("overflow","hidden").css(r.from),p&&(v=e.effects.getBaseline(p,d),r.from.top=(d.outerHeight-r.outerHeight())*v.y,r.from.left=(d.outerWidth-r.outerWidth())*v.x,r.to.top=(d.outerHeight-r.to.outerHeight)*v.y,r.to.left=(d.outerWidth-r.to.outerWidth)*v.x),r.css(r.from);if(h==="content"||h==="both")a=a.concat(["marginTop","marginBottom"]).concat(u),f=f.concat(["marginLeft","marginRight"]),o=i.concat(a).concat(f),r.find("*[width]").each(function(){var n=e(this),r={height:n.height(),width:n.width()};c&&e.effects.save(n,o),n.from={height:r.height*m.from.y,width:r.width*m.from.x},n.to={height:r.height*m.to.y,width:r.width*m.to.x},m.from.y!==m.to.y&&(n.from=e.effects.setTransition(n,a,m.from.y,n.from),n.to=e.effects.setTransition(n,a,m.to.y,n.to)),m.from.x!==m.to.x&&(n.from=e.effects.setTransition(n,f,m.from.x,n.from),n.to=e.effects.setTransition(n,f,m.to.x,n.to)),n.css(n.from),n.animate(n.to,t.duration,t.easing,function(){c&&e.effects.restore(n,o)})});r.animate(r.to,{queue:!1,duration:t.duration,easing:t.easing,complete:function(){r.to.opacity===0&&r.css("opacity",r.from.opacity),l==="hide"&&r.hide(),e.effects.restore(r,c?i:s),c||(g==="static"?r.css({position:"relative",top:r.to.top,left:r.to.left}):e.each(["top","left"],function(e,t){r.css(t,function(t,n){var i=parseInt(n,10),s=e?r.to.left:r.to.top;return n==="auto"?s+"px":i+s+"px"})})),e.effects.removeWrapper(r),n()}})}})(jQuery); \ No newline at end of file diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/ui/minified/jquery.ui.effect-shake.min.js b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/ui/minified/jquery.ui.effect-shake.min.js new file mode 100755 index 000000000..ec6e5d46f --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/ui/minified/jquery.ui.effect-shake.min.js @@ -0,0 +1,5 @@ +/*! jQuery UI - v1.9.0 - 2012-10-08 +* http://jqueryui.com +* Includes: jquery.ui.effect-shake.js +* Copyright 2012 jQuery Foundation and other contributors; Licensed MIT */ +(function(e,t){e.effects.effect.shake=function(t,n){var r=e(this),i=["position","top","bottom","left","right","height","width"],s=e.effects.setMode(r,t.mode||"effect"),o=t.direction||"left",u=t.distance||20,a=t.times||3,f=a*2+1,l=Math.round(t.duration/f),c=o==="up"||o==="down"?"top":"left",h=o==="up"||o==="left",p={},d={},v={},m,g=r.queue(),y=g.length;e.effects.save(r,i),r.show(),e.effects.createWrapper(r),p[c]=(h?"-=":"+=")+u,d[c]=(h?"+=":"-=")+u*2,v[c]=(h?"-=":"+=")+u*2,r.animate(p,l,t.easing);for(m=1;m1&&g.splice.apply(g,[1,0].concat(g.splice(y,f+1))),r.dequeue()}})(jQuery); \ No newline at end of file diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/ui/minified/jquery.ui.effect-slide.min.js b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/ui/minified/jquery.ui.effect-slide.min.js new file mode 100755 index 000000000..8b78baad5 --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/ui/minified/jquery.ui.effect-slide.min.js @@ -0,0 +1,5 @@ +/*! jQuery UI - v1.9.0 - 2012-10-08 +* http://jqueryui.com +* Includes: jquery.ui.effect-slide.js +* Copyright 2012 jQuery Foundation and other contributors; Licensed MIT */ +(function(e,t){e.effects.effect.slide=function(t,n){var r=e(this),i=["position","top","bottom","left","right","width","height"],s=e.effects.setMode(r,t.mode||"show"),o=s==="show",u=t.direction||"left",a=u==="up"||u==="down"?"top":"left",f=u==="up"||u==="left",l,c={};e.effects.save(r,i),r.show(),l=t.distance||r[a==="top"?"outerHeight":"outerWidth"](!0),e.effects.createWrapper(r).css({overflow:"hidden"}),o&&r.css(a,f?isNaN(l)?"-"+l:-l:l),c[a]=(o?f?"+=":"-=":f?"-=":"+=")+l,r.animate(c,{queue:!1,duration:t.duration,easing:t.easing,complete:function(){s==="hide"&&r.hide(),e.effects.restore(r,i),e.effects.removeWrapper(r),n()}})}})(jQuery); \ No newline at end of file diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/ui/minified/jquery.ui.effect-transfer.min.js b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/ui/minified/jquery.ui.effect-transfer.min.js new file mode 100755 index 000000000..1d118233d --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/ui/minified/jquery.ui.effect-transfer.min.js @@ -0,0 +1,5 @@ +/*! jQuery UI - v1.9.0 - 2012-10-08 +* http://jqueryui.com +* Includes: jquery.ui.effect-transfer.js +* Copyright 2012 jQuery Foundation and other contributors; Licensed MIT */ +(function(e,t){e.effects.effect.transfer=function(t,n){var r=e(this),i=e(t.to),s=i.css("position")==="fixed",o=e("body"),u=s?o.scrollTop():0,a=s?o.scrollLeft():0,f=i.offset(),l={top:f.top-u,left:f.left-a,height:i.innerHeight(),width:i.innerWidth()},c=r.offset(),h=e('
      ').appendTo(document.body).addClass(t.className).css({top:c.top-u,left:c.left-a,height:r.innerHeight(),width:r.innerWidth(),position:s?"fixed":"absolute"}).animate(l,t.duration,t.easing,function(){h.remove(),n()})}})(jQuery); \ No newline at end of file diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/ui/minified/jquery.ui.effect.min.js b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/ui/minified/jquery.ui.effect.min.js new file mode 100755 index 000000000..e66a8ef98 --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/ui/minified/jquery.ui.effect.min.js @@ -0,0 +1,5 @@ +/*! jQuery UI - v1.9.0 - 2012-10-08 +* http://jqueryui.com +* Includes: jquery.ui.effect.js +* Copyright 2012 jQuery Foundation and other contributors; Licensed MIT */ +jQuery.effects||function(e,t){var n=e.uiBackCompat!==!1,r="ui-effects-";e.effects={effect:{}},function(t,n){function p(e,t,n){var r=a[t.type]||{};return e==null?n||!t.def?null:t.def:(e=r.floor?~~e:parseFloat(e),isNaN(e)?t.def:r.mod?(e+r.mod)%r.mod:0>e?0:r.max")[0],c,h=t.each;l.style.cssText="background-color:rgba(1,1,1,.5)",f.rgba=l.style.backgroundColor.indexOf("rgba")>-1,h(u,function(e,t){t.cache="_"+e,t.props.alpha={idx:3,type:"percent",def:1}}),o.fn=t.extend(o.prototype,{parse:function(r,i,s,a){if(r===n)return this._rgba=[null,null,null,null],this;if(r.jquery||r.nodeType)r=t(r).css(i),i=n;var f=this,l=t.type(r),v=this._rgba=[],m;i!==n&&(r=[r,i,s,a],l="array");if(l==="string")return this.parse(d(r)||c._default);if(l==="array")return h(u.rgba.props,function(e,t){v[t.idx]=p(r[t.idx],t)}),this;if(l==="object")return r instanceof o?h(u,function(e,t){r[t.cache]&&(f[t.cache]=r[t.cache].slice())}):h(u,function(t,n){var i=n.cache;h(n.props,function(e,t){if(!f[i]&&n.to){if(e==="alpha"||r[e]==null)return;f[i]=n.to(f._rgba)}f[i][t.idx]=p(r[e],t,!0)}),f[i]&&e.inArray(null,f[i].slice(0,3))<0&&(f[i][3]=1,n.from&&(f._rgba=n.from(f[i])))}),this},is:function(e){var t=o(e),n=!0,r=this;return h(u,function(e,i){var s,o=t[i.cache];return o&&(s=r[i.cache]||i.to&&i.to(r._rgba)||[],h(i.props,function(e,t){if(o[t.idx]!=null)return n=o[t.idx]===s[t.idx],n})),n}),n},_space:function(){var e=[],t=this;return h(u,function(n,r){t[r.cache]&&e.push(n)}),e.pop()},transition:function(e,t){var n=o(e),r=n._space(),i=u[r],s=this.alpha()===0?o("transparent"):this,f=s[i.cache]||i.to(s._rgba),l=f.slice();return n=n[i.cache],h(i.props,function(e,r){var i=r.idx,s=f[i],o=n[i],u=a[r.type]||{};if(o===null)return;s===null?l[i]=o:(u.mod&&(o-s>u.mod/2?s+=u.mod:s-o>u.mod/2&&(s-=u.mod)),l[i]=p((o-s)*t+s,r))}),this[r](l)},blend:function(e){if(this._rgba[3]===1)return this;var n=this._rgba.slice(),r=n.pop(),i=o(e)._rgba;return o(t.map(n,function(e,t){return(1-r)*i[t]+r*e}))},toRgbaString:function(){var e="rgba(",n=t.map(this._rgba,function(e,t){return e==null?t>2?1:0:e});return n[3]===1&&(n.pop(),e="rgb("),e+n.join()+")"},toHslaString:function(){var e="hsla(",n=t.map(this.hsla(),function(e,t){return e==null&&(e=t>2?1:0),t&&t<3&&(e=Math.round(e*100)+"%"),e});return n[3]===1&&(n.pop(),e="hsl("),e+n.join()+")"},toHexString:function(e){var n=this._rgba.slice(),r=n.pop();return e&&n.push(~~(r*255)),"#"+t.map(n,function(e,t){return e=(e||0).toString(16),e.length===1?"0"+e:e}).join("")},toString:function(){return this._rgba[3]===0?"transparent":this.toRgbaString()}}),o.fn.parse.prototype=o.fn,u.hsla.to=function(e){if(e[0]==null||e[1]==null||e[2]==null)return[null,null,null,e[3]];var t=e[0]/255,n=e[1]/255,r=e[2]/255,i=e[3],s=Math.max(t,n,r),o=Math.min(t,n,r),u=s-o,a=s+o,f=a*.5,l,c;return o===s?l=0:t===s?l=60*(n-r)/u+360:n===s?l=60*(r-t)/u+120:l=60*(t-n)/u+240,f===0||f===1?c=f:f<=.5?c=u/a:c=u/(2-a),[Math.round(l)%360,c,f,i==null?1:i]},u.hsla.from=function(e){if(e[0]==null||e[1]==null||e[2]==null)return[null,null,null,e[3]];var t=e[0]/360,n=e[1],r=e[2],i=e[3],s=r<=.5?r*(1+n):r+n-r*n,o=2*r-s,u,a,f;return[Math.round(v(o,s,t+1/3)*255),Math.round(v(o,s,t)*255),Math.round(v(o,s,t-1/3)*255),i]},h(u,function(e,r){var s=r.props,u=r.cache,a=r.to,f=r.from;o.fn[e]=function(e){a&&!this[u]&&(this[u]=a(this._rgba));if(e===n)return this[u].slice();var r,i=t.type(e),l=i==="array"||i==="object"?e:arguments,c=this[u].slice();return h(s,function(e,t){var n=l[i==="object"?e:t.idx];n==null&&(n=c[t.idx]),c[t.idx]=p(n,t)}),f?(r=o(f(c)),r[u]=c,r):o(c)},h(s,function(n,r){if(o.fn[n])return;o.fn[n]=function(s){var o=t.type(s),u=n==="alpha"?this._hsla?"hsla":"rgba":e,a=this[u](),f=a[r.idx],l;return o==="undefined"?f:(o==="function"&&(s=s.call(this,f),o=t.type(s)),s==null&&r.empty?this:(o==="string"&&(l=i.exec(s),l&&(s=f+parseFloat(l[2])*(l[1]==="+"?1:-1))),a[r.idx]=s,this[u](a)))}})}),h(r,function(e,n){t.cssHooks[n]={set:function(e,r){var i,s,u="";if(t.type(r)!=="string"||(i=d(r))){r=o(i||r);if(!f.rgba&&r._rgba[3]!==1){s=n==="backgroundColor"?e.parentNode:e;while((u===""||u==="transparent")&&s&&s.style)try{u=t.css(s,"backgroundColor"),s=s.parentNode}catch(a){}r=r.blend(u&&u!=="transparent"?u:"_default")}r=r.toRgbaString()}try{e.style[n]=r}catch(r){}}},t.fx.step[n]=function(e){e.colorInit||(e.start=o(e.elem,n),e.end=o(e.end),e.colorInit=!0),t.cssHooks[n].set(e.elem,e.start.transition(e.end,e.pos))}}),t.cssHooks.borderColor={expand:function(e){var t={};return h(["Top","Right","Bottom","Left"],function(n,r){t["border"+r+"Color"]=e}),t}},c=t.Color.names={aqua:"#00ffff",black:"#000000",blue:"#0000ff",fuchsia:"#ff00ff",gray:"#808080",green:"#008000",lime:"#00ff00",maroon:"#800000",navy:"#000080",olive:"#808000",purple:"#800080",red:"#ff0000",silver:"#c0c0c0",teal:"#008080",white:"#ffffff",yellow:"#ffff00",transparent:[null,null,null,0],_default:"#ffffff"}}(jQuery),function(){function i(){var t=this.ownerDocument.defaultView?this.ownerDocument.defaultView.getComputedStyle(this,null):this.currentStyle,n={},r,i,s;if(t&&t.length&&t[0]&&t[t[0]]){s=t.length;while(s--)r=t[s],typeof t[r]=="string"&&(n[e.camelCase(r)]=t[r])}else for(r in t)typeof t[r]=="string"&&(n[r]=t[r]);return n}function s(t,n){var i={},s,o;for(s in n)o=n[s],t[s]!==o&&!r[s]&&(e.fx.step[s]||!isNaN(parseFloat(o)))&&(i[s]=o);return i}var n=["add","remove","toggle"],r={border:1,borderBottom:1,borderColor:1,borderLeft:1,borderRight:1,borderTop:1,borderWidth:1,margin:1,padding:1};e.each(["borderLeftStyle","borderRightStyle","borderBottomStyle","borderTopStyle"],function(t,n){e.fx.step[n]=function(e){if(e.end!=="none"&&!e.setAttr||e.pos===1&&!e.setAttr)jQuery.style(e.elem,n,e.end),e.setAttr=!0}}),e.effects.animateClass=function(t,r,o,u){var a=e.speed(r,o,u);return this.queue(function(){var r=e(this),o=r.attr("class")||"",u,f=a.children?r.find("*").andSelf():r;f=f.map(function(){var t=e(this);return{el:t,start:i.call(this)}}),u=function(){e.each(n,function(e,n){t[n]&&r[n+"Class"](t[n])})},u(),f=f.map(function(){return this.end=i.call(this.el[0]),this.diff=s(this.start,this.end),this}),r.attr("class",o),f=f.map(function(){var t=this,n=e.Deferred(),r=jQuery.extend({},a,{queue:!1,complete:function(){n.resolve(t)}});return this.el.animate(this.diff,r),n.promise()}),e.when.apply(e,f.get()).done(function(){u(),e.each(arguments,function(){var t=this.el;e.each(this.diff,function(e){t.css(e,"")})}),a.complete.call(r[0])})})},e.fn.extend({_addClass:e.fn.addClass,addClass:function(t,n,r,i){return n?e.effects.animateClass.call(this,{add:t},n,r,i):this._addClass(t)},_removeClass:e.fn.removeClass,removeClass:function(t,n,r,i){return n?e.effects.animateClass.call(this,{remove:t},n,r,i):this._removeClass(t)},_toggleClass:e.fn.toggleClass,toggleClass:function(n,r,i,s,o){return typeof r=="boolean"||r===t?i?e.effects.animateClass.call(this,r?{add:n}:{remove:n},i,s,o):this._toggleClass(n,r):e.effects.animateClass.call(this,{toggle:n},r,i,s)},switchClass:function(t,n,r,i,s){return e.effects.animateClass.call(this,{add:n,remove:t},r,i,s)}})}(),function(){function i(n,r,i,s){e.isPlainObject(n)&&(r=n,n=n.effect),n={effect:n},r===t&&(r={}),e.isFunction(r)&&(s=r,i=null,r={});if(typeof r=="number"||e.fx.speeds[r])s=i,i=r,r={};return e.isFunction(i)&&(s=i,i=null),r&&e.extend(n,r),i=i||r.duration,n.duration=e.fx.off?0:typeof i=="number"?i:i in e.fx.speeds?e.fx.speeds[i]:e.fx.speeds._default,n.complete=s||r.complete,n}function s(t){return!t||typeof t=="number"||e.fx.speeds[t]?!0:typeof t=="string"&&!e.effects.effect[t]?n&&e.effects[t]?!1:!0:!1}e.extend(e.effects,{version:"1.9.0",save:function(e,t){for(var n=0;n
      ").addClass("ui-effects-wrapper").css({fontSize:"100%",background:"transparent",border:"none",margin:0,padding:0}),i={width:t.width(),height:t.height()},s=document.activeElement;try{s.id}catch(o){s=document.body}return t.wrap(r),(t[0]===s||e.contains(t[0],s))&&e(s).focus(),r=t.parent(),t.css("position")==="static"?(r.css({position:"relative"}),t.css({position:"relative"})):(e.extend(n,{position:t.css("position"),zIndex:t.css("z-index")}),e.each(["top","left","bottom","right"],function(e,r){n[r]=t.css(r),isNaN(parseInt(n[r],10))&&(n[r]="auto")}),t.css({position:"relative",top:0,left:0,right:"auto",bottom:"auto"})),t.css(i),r.css(n).show()},removeWrapper:function(t){var n=document.activeElement;return t.parent().is(".ui-effects-wrapper")&&(t.parent().replaceWith(t),(t[0]===n||e.contains(t[0],n))&&e(n).focus()),t},setTransition:function(t,n,r,i){return i=i||{},e.each(n,function(e,n){var s=t.cssUnit(n);s[0]>0&&(i[n]=s[0]*r+s[1])}),i}}),e.fn.extend({effect:function(t,r,s,o){function h(t){function s(){e.isFunction(r)&&r.call(n[0]),e.isFunction(t)&&t()}var n=e(this),r=u.complete,i=u.mode;(n.is(":hidden")?i==="hide":i==="show")?s():l.call(n[0],u,s)}var u=i.apply(this,arguments),a=u.mode,f=u.queue,l=e.effects.effect[u.effect],c=!l&&n&&e.effects[u.effect];return e.fx.off||!l&&!c?a?this[a](u.duration,u.complete):this.each(function(){u.complete&&u.complete.call(this)}):l?f===!1?this.each(h):this.queue(f||"fx",h):c.call(this,{options:u,duration:u.duration,callback:u.complete,mode:u.mode})},_show:e.fn.show,show:function(e){if(s(e))return this._show.apply(this,arguments);var t=i.apply(this,arguments);return t.mode="show",this.effect.call(this,t)},_hide:e.fn.hide,hide:function(e){if(s(e))return this._hide.apply(this,arguments);var t=i.apply(this,arguments);return t.mode="hide",this.effect.call(this,t)},__toggle:e.fn.toggle,toggle:function(t){if(s(t)||typeof t=="boolean"||e.isFunction(t))return this.__toggle.apply(this,arguments);var n=i.apply(this,arguments);return n.mode="toggle",this.effect.call(this,n)},cssUnit:function(t){var n=this.css(t),r=[];return e.each(["em","px","%","pt"],function(e,t){n.indexOf(t)>0&&(r=[parseFloat(n),t])}),r}})}(),function(){var t={};e.each(["Quad","Cubic","Quart","Quint","Expo"],function(e,n){t[n]=function(t){return Math.pow(t,e+2)}}),e.extend(t,{Sine:function(e){return 1-Math.cos(e*Math.PI/2)},Circ:function(e){return 1-Math.sqrt(1-e*e)},Elastic:function(e){return e===0||e===1?e:-Math.pow(2,8*(e-1))*Math.sin(((e-1)*80-7.5)*Math.PI/15)},Back:function(e){return e*e*(3*e-2)},Bounce:function(e){var t,n=4;while(e<((t=Math.pow(2,--n))-1)/11);return 1/Math.pow(4,3-n)-7.5625*Math.pow((t*3-2)/22-e,2)}}),e.each(t,function(t,n){e.easing["easeIn"+t]=n,e.easing["easeOut"+t]=function(e){return 1-n(1-e)},e.easing["easeInOut"+t]=function(e){return e<.5?n(e*2)/2:1-n(e*-2+2)/2}})}()}(jQuery); \ No newline at end of file diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/ui/minified/jquery.ui.menu.min.js b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/ui/minified/jquery.ui.menu.min.js new file mode 100755 index 000000000..abc114a07 --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/ui/minified/jquery.ui.menu.min.js @@ -0,0 +1,5 @@ +/*! jQuery UI - v1.9.0 - 2012-10-08 +* http://jqueryui.com +* Includes: jquery.ui.menu.js +* Copyright 2012 jQuery Foundation and other contributors; Licensed MIT */ +(function(e,t){var n=!1;e.widget("ui.menu",{version:"1.9.0",defaultElement:"
        ",delay:300,options:{icons:{submenu:"ui-icon-carat-1-e"},menus:"ul",position:{my:"left top",at:"right top"},role:"menu",blur:null,focus:null,select:null},_create:function(){this.activeMenu=this.element,this.element.uniqueId().addClass("ui-menu ui-widget ui-widget-content ui-corner-all").toggleClass("ui-menu-icons",!!this.element.find(".ui-icon").length).attr({role:this.options.role,tabIndex:0}).bind("click"+this.eventNamespace,e.proxy(function(e){this.options.disabled&&e.preventDefault()},this)),this.options.disabled&&this.element.addClass("ui-state-disabled").attr("aria-disabled","true"),this._on({"mousedown .ui-menu-item > a":function(e){e.preventDefault()},"click .ui-state-disabled > a":function(e){e.preventDefault()},"click .ui-menu-item:has(a)":function(t){var r=e(t.target).closest(".ui-menu-item");!n&&r.not(".ui-state-disabled").length&&(n=!0,this.select(t),r.has(".ui-menu").length?this.expand(t):this.element.is(":focus")||(this.element.trigger("focus",[!0]),this.active&&this.active.parents(".ui-menu").length===1&&clearTimeout(this.timer)))},"mouseenter .ui-menu-item":function(t){var n=e(t.currentTarget);n.siblings().children(".ui-state-active").removeClass("ui-state-active"),this.focus(t,n)},mouseleave:"collapseAll","mouseleave .ui-menu":"collapseAll",focus:function(e,t){var n=this.active||this.element.children(".ui-menu-item").eq(0);t||this.focus(e,n)},blur:function(t){this._delay(function(){e.contains(this.element[0],this.document[0].activeElement)||this.collapseAll(t)})},keydown:"_keydown"}),this.refresh(),this._on(this.document,{click:function(t){e(t.target).closest(".ui-menu").length||this.collapseAll(t),n=!1}})},_destroy:function(){this.element.removeAttr("aria-activedescendant").find(".ui-menu").andSelf().removeClass("ui-menu ui-widget ui-widget-content ui-corner-all ui-menu-icons").removeAttr("role").removeAttr("tabIndex").removeAttr("aria-labelledby").removeAttr("aria-expanded").removeAttr("aria-hidden").removeAttr("aria-disabled").removeUniqueId().show(),this.element.find(".ui-menu-item").removeClass("ui-menu-item").removeAttr("role").removeAttr("aria-disabled").children("a").removeUniqueId().removeClass("ui-corner-all ui-state-hover").removeAttr("tabIndex").removeAttr("role").removeAttr("aria-haspopup").children().each(function(){var t=e(this);t.data("ui-menu-submenu-carat")&&t.remove()}),this.element.find(".ui-menu-divider").removeClass("ui-menu-divider ui-widget-content")},_keydown:function(t){function a(e){return e.replace(/[\-\[\]{}()*+?.,\\\^$|#\s]/g,"\\$&")}var n,r,i,s,o,u=!0;switch(t.keyCode){case e.ui.keyCode.PAGE_UP:this.previousPage(t);break;case e.ui.keyCode.PAGE_DOWN:this.nextPage(t);break;case e.ui.keyCode.HOME:this._move("first","first",t);break;case e.ui.keyCode.END:this._move("last","last",t);break;case e.ui.keyCode.UP:this.previous(t);break;case e.ui.keyCode.DOWN:this.next(t);break;case e.ui.keyCode.LEFT:this.collapse(t);break;case e.ui.keyCode.RIGHT:this.active&&!this.active.is(".ui-state-disabled")&&this.expand(t);break;case e.ui.keyCode.ENTER:case e.ui.keyCode.SPACE:this._activate(t);break;case e.ui.keyCode.ESCAPE:this.collapse(t);break;default:u=!1,r=this.previousFilter||"",i=String.fromCharCode(t.keyCode),s=!1,clearTimeout(this.filterTimer),i===r?s=!0:i=r+i,o=new RegExp("^"+a(i),"i"),n=this.activeMenu.children(".ui-menu-item").filter(function(){return o.test(e(this).children("a").text())}),n=s&&n.index(this.active.next())!==-1?this.active.nextAll(".ui-menu-item"):n,n.length||(i=String.fromCharCode(t.keyCode),o=new RegExp("^"+a(i),"i"),n=this.activeMenu.children(".ui-menu-item").filter(function(){return o.test(e(this).children("a").text())})),n.length?(this.focus(t,n),n.length>1?(this.previousFilter=i,this.filterTimer=this._delay(function(){delete this.previousFilter},1e3)):delete this.previousFilter):delete this.previousFilter}u&&t.preventDefault()},_activate:function(e){this.active.is(".ui-state-disabled")||(this.active.children("a[aria-haspopup='true']").length?this.expand(e):this.select(e))},refresh:function(){var t,n=this.options.icons.submenu,r=this.element.find(this.options.menus+":not(.ui-menu)").addClass("ui-menu ui-widget ui-widget-content ui-corner-all").hide().attr({role:this.options.role,"aria-hidden":"true","aria-expanded":"false"});t=r.add(this.element),t.children(":not(.ui-menu-item):has(a)").addClass("ui-menu-item").attr("role","presentation").children("a").uniqueId().addClass("ui-corner-all").attr({tabIndex:-1,role:this._itemRole()}),t.children(":not(.ui-menu-item)").each(function(){var t=e(this);/[^\-—–\s]/.test(t.text())||t.addClass("ui-widget-content ui-menu-divider")}),t.children(".ui-state-disabled").attr("aria-disabled","true"),r.each(function(){var t=e(this),r=t.prev("a"),i=e("").addClass("ui-menu-icon ui-icon "+n).data("ui-menu-submenu-carat",!0);r.attr("aria-haspopup","true").prepend(i),t.attr("aria-labelledby",r.attr("id"))}),this.active&&!e.contains(this.element[0],this.active[0])&&this.blur()},_itemRole:function(){return{menu:"menuitem",listbox:"option"}[this.options.role]},focus:function(e,t){var n,r;this.blur(e,e&&e.type==="focus"),this._scrollIntoView(t),this.active=t.first(),r=this.active.children("a").addClass("ui-state-focus"),this.options.role&&this.element.attr("aria-activedescendant",r.attr("id")),this.active.parent().closest(".ui-menu-item").children("a:first").addClass("ui-state-active"),e&&e.type==="keydown"?this._close():this.timer=this._delay(function(){this._close()},this.delay),n=t.children(".ui-menu"),n.length&&/^mouse/.test(e.type)&&this._startOpening(n),this.activeMenu=t.parent(),this._trigger("focus",e,{item:t})},_scrollIntoView:function(t){var n,r,i,s,o,u;this._hasScroll()&&(n=parseFloat(e.css(this.activeMenu[0],"borderTopWidth"))||0,r=parseFloat(e.css(this.activeMenu[0],"paddingTop"))||0,i=t.offset().top-this.activeMenu.offset().top-n-r,s=this.activeMenu.scrollTop(),o=this.activeMenu.height(),u=t.height(),i<0?this.activeMenu.scrollTop(s+i):i+u>o&&this.activeMenu.scrollTop(s+i-o+u))},blur:function(e,t){t||clearTimeout(this.timer);if(!this.active)return;this.active.children("a").removeClass("ui-state-focus"),this.active=null,this._trigger("blur",e,{item:this.active})},_startOpening:function(e){clearTimeout(this.timer);if(e.attr("aria-hidden")!=="true")return;this.timer=this._delay(function(){this._close(),this._open(e)},this.delay)},_open:function(t){var n=e.extend({of:this.active},this.options.position);clearTimeout(this.timer),this.element.find(".ui-menu").not(t.parents(".ui-menu")).hide().attr("aria-hidden","true"),t.show().removeAttr("aria-hidden").attr("aria-expanded","true").position(n)},collapseAll:function(t,n){clearTimeout(this.timer),this.timer=this._delay(function(){var r=n?this.element:e(t&&t.target).closest(this.element.find(".ui-menu"));r.length||(r=this.element),this._close(r),this.blur(t),this.activeMenu=r},this.delay)},_close:function(e){e||(e=this.active?this.active.parent():this.element),e.find(".ui-menu").hide().attr("aria-hidden","true").attr("aria-expanded","false").end().find("a.ui-state-active").removeClass("ui-state-active")},collapse:function(e){var t=this.active&&this.active.parent().closest(".ui-menu-item",this.element);t&&t.length&&(this._close(),this.focus(e,t))},expand:function(e){var t=this.active&&this.active.children(".ui-menu ").children(".ui-menu-item").first();t&&t.length&&(this._open(t.parent()),this._delay(function(){this.focus(e,t)}))},next:function(e){this._move("next","first",e)},previous:function(e){this._move("prev","last",e)},isFirstItem:function(){return this.active&&!this.active.prevAll(".ui-menu-item").length},isLastItem:function(){return this.active&&!this.active.nextAll(".ui-menu-item").length},_move:function(e,t,n){var r;this.active&&(e==="first"||e==="last"?r=this.active[e==="first"?"prevAll":"nextAll"](".ui-menu-item").eq(-1):r=this.active[e+"All"](".ui-menu-item").eq(0));if(!r||!r.length||!this.active)r=this.activeMenu.children(".ui-menu-item")[t]();this.focus(n,r)},nextPage:function(t){var n,r,i;if(!this.active){this.next(t);return}if(this.isLastItem())return;this._hasScroll()?(r=this.active.offset().top,i=this.element.height(),this.active.nextAll(".ui-menu-item").each(function(){return n=e(this),n.offset().top-r-i<0}),this.focus(t,n)):this.focus(t,this.activeMenu.children(".ui-menu-item")[this.active?"last":"first"]())},previousPage:function(t){var n,r,i;if(!this.active){this.next(t);return}if(this.isFirstItem())return;this._hasScroll()?(r=this.active.offset().top,i=this.element.height(),this.active.prevAll(".ui-menu-item").each(function(){return n=e(this),n.offset().top-r+i>0}),this.focus(t,n)):this.focus(t,this.activeMenu.children(".ui-menu-item").first())},_hasScroll:function(){return this.element.outerHeight()=9||!!t.button?this._mouseStarted?(this._mouseDrag(t),t.preventDefault()):(this._mouseDistanceMet(t)&&this._mouseDelayMet(t)&&(this._mouseStarted=this._mouseStart(this._mouseDownEvent,t)!==!1,this._mouseStarted?this._mouseDrag(t):this._mouseUp(t)),!this._mouseStarted):this._mouseUp(t)},_mouseUp:function(t){return e(document).unbind("mousemove."+this.widgetName,this._mouseMoveDelegate).unbind("mouseup."+this.widgetName,this._mouseUpDelegate),this._mouseStarted&&(this._mouseStarted=!1,t.target===this._mouseDownEvent.target&&e.data(t.target,this.widgetName+".preventClickEvent",!0),this._mouseStop(t)),!1},_mouseDistanceMet:function(e){return Math.max(Math.abs(this._mouseDownEvent.pageX-e.pageX),Math.abs(this._mouseDownEvent.pageY-e.pageY))>=this.options.distance},_mouseDelayMet:function(e){return this.mouseDelayMet},_mouseStart:function(e){},_mouseDrag:function(e){},_mouseStop:function(e){},_mouseCapture:function(e){return!0}})})(jQuery); \ No newline at end of file diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/ui/minified/jquery.ui.position.min.js b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/ui/minified/jquery.ui.position.min.js new file mode 100755 index 000000000..988093842 --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/ui/minified/jquery.ui.position.min.js @@ -0,0 +1,5 @@ +/*! jQuery UI - v1.9.0 - 2012-10-08 +* http://jqueryui.com +* Includes: jquery.ui.position.js +* Copyright 2012 jQuery Foundation and other contributors; Licensed MIT */ +(function(e,t){function h(e,t,n){return[parseInt(e[0],10)*(l.test(e[0])?t/100:1),parseInt(e[1],10)*(l.test(e[1])?n/100:1)]}function p(t,n){return parseInt(e.css(t,n),10)||0}e.ui=e.ui||{};var n,r=Math.max,i=Math.abs,s=Math.round,o=/left|center|right/,u=/top|center|bottom/,a=/[\+\-]\d+%?/,f=/^\w+/,l=/%$/,c=e.fn.position;e.position={scrollbarWidth:function(){if(n!==t)return n;var r,i,s=e("
        "),o=s.children()[0];return e("body").append(s),r=o.offsetWidth,s.css("overflow","scroll"),i=o.offsetWidth,r===i&&(i=s[0].clientWidth),s.remove(),n=r-i},getScrollInfo:function(t){var n=t.isWindow?"":t.element.css("overflow-x"),r=t.isWindow?"":t.element.css("overflow-y"),i=n==="scroll"||n==="auto"&&t.width0?"right":"center",vertical:u<0?"top":o>0?"bottom":"middle"};lr(i(o),i(u))?h.important="horizontal":h.important="vertical",t.using.call(this,e,h)}),a.offset(e.extend(C,{using:u}))})},e.ui.position={fit:{left:function(e,t){var n=t.within,i=n.isWindow?n.scrollLeft:n.offset.left,s=n.width,o=e.left-t.collisionPosition.marginLeft,u=i-o,a=o+t.collisionWidth-s-i,f;t.collisionWidth>s?u>0&&a<=0?(f=e.left+u+t.collisionWidth-s-i,e.left+=u-f):a>0&&u<=0?e.left=i:u>a?e.left=i+s-t.collisionWidth:e.left=i:u>0?e.left+=u:a>0?e.left-=a:e.left=r(e.left-o,e.left)},top:function(e,t){var n=t.within,i=n.isWindow?n.scrollTop:n.offset.top,s=t.within.height,o=e.top-t.collisionPosition.marginTop,u=i-o,a=o+t.collisionHeight-s-i,f;t.collisionHeight>s?u>0&&a<=0?(f=e.top+u+t.collisionHeight-s-i,e.top+=u-f):a>0&&u<=0?e.top=i:u>a?e.top=i+s-t.collisionHeight:e.top=i:u>0?e.top+=u:a>0?e.top-=a:e.top=r(e.top-o,e.top)}},flip:{left:function(e,t){var n=t.within,r=n.offset.left+n.scrollLeft,s=n.width,o=n.isWindow?n.scrollLeft:n.offset.left,u=e.left-t.collisionPosition.marginLeft,a=u-o,f=u+t.collisionWidth-s-o,l=t.my[0]==="left"?-t.elemWidth:t.my[0]==="right"?t.elemWidth:0,c=t.at[0]==="left"?t.targetWidth:t.at[0]==="right"?-t.targetWidth:0,h=-2*t.offset[0],p,d;if(a<0){p=e.left+l+c+h+t.collisionWidth-s-r;if(p<0||p0){d=e.left-t.collisionPosition.marginLeft+l+c+h-o;if(d>0||i(d)a&&(v<0||v0&&(d=e.top-t.collisionPosition.marginTop+c+h+p-o,e.top+c+h+p>f&&(d>0||i(d)10&&i<11,t.innerHTML="",n.removeChild(t)}(),e.uiBackCompat!==!1&&function(e){var n=e.fn.position;e.fn.position=function(r){if(!r||!r.offset)return n.call(this,r);var i=r.offset.split(" "),s=r.at.split(" ");return i.length===1&&(i[1]=i[0]),/^\d/.test(i[0])&&(i[0]="+"+i[0]),/^\d/.test(i[1])&&(i[1]="+"+i[1]),s.length===1&&(/left|center|right/.test(s[0])?s[1]="center":(s[1]=s[0],s[0]="center")),n.call(this,e.extend(r,{at:s[0]+i[0]+" "+s[1]+i[1],offset:t}))}}(jQuery)})(jQuery); \ No newline at end of file diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/ui/minified/jquery.ui.progressbar.min.js b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/ui/minified/jquery.ui.progressbar.min.js new file mode 100755 index 000000000..a7fced431 --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/ui/minified/jquery.ui.progressbar.min.js @@ -0,0 +1,5 @@ +/*! jQuery UI - v1.9.0 - 2012-10-08 +* http://jqueryui.com +* Includes: jquery.ui.progressbar.js +* Copyright 2012 jQuery Foundation and other contributors; Licensed MIT */ +(function(e,t){e.widget("ui.progressbar",{version:"1.9.0",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=e("
        ").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()},value:function(e){return e===t?this._value():(this._setOption("value",e),this)},_setOption:function(e,t){e==="value"&&(this.options.value=t,this._refreshValue(),this._value()===this.options.max&&this._trigger("complete")),this._super(e,t)},_value:function(){var e=this.options.value;return typeof e!="number"&&(e=0),Math.min(this.options.max,Math.max(this.min,e))},_percentage:function(){return 100*this._value()/this.options.max},_refreshValue:function(){var e=this.value(),t=this._percentage();this.oldValue!==e&&(this.oldValue=e,this._trigger("change")),this.valueDiv.toggle(e>this.min).toggleClass("ui-corner-right",e===this.options.max).width(t.toFixed(0)+"%"),this.element.attr("aria-valuenow",e)}})})(jQuery); \ No newline at end of file diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/ui/minified/jquery.ui.resizable.min.js b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/ui/minified/jquery.ui.resizable.min.js new file mode 100755 index 000000000..44caa7a86 --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/ui/minified/jquery.ui.resizable.min.js @@ -0,0 +1,5 @@ +/*! jQuery UI - v1.9.0 - 2012-10-08 +* http://jqueryui.com +* Includes: jquery.ui.resizable.js +* Copyright 2012 jQuery Foundation and other contributors; Licensed MIT */ +(function(e,t){e.widget("ui.resizable",e.ui.mouse,{version:"1.9.0",widgetEventPrefix:"resize",options:{alsoResize:!1,animate:!1,animateDuration:"slow",animateEasing:"swing",aspectRatio:!1,autoHide:!1,containment:!1,ghost:!1,grid:!1,handles:"e,s,se",helper:!1,maxHeight:null,maxWidth:null,minHeight:10,minWidth:10,zIndex:1e3},_create:function(){var t=this,n=this.options;this.element.addClass("ui-resizable"),e.extend(this,{_aspectRatio:!!n.aspectRatio,aspectRatio:n.aspectRatio,originalElement:this.element,_proportionallyResizeElements:[],_helper:n.helper||n.ghost||n.animate?n.helper||"ui-resizable-helper":null}),this.element[0].nodeName.match(/canvas|textarea|input|select|button|img/i)&&(this.element.wrap(e('
        ').css({position:this.element.css("position"),width:this.element.outerWidth(),height:this.element.outerHeight(),top:this.element.css("top"),left:this.element.css("left")})),this.element=this.element.parent().data("resizable",this.element.data("resizable")),this.elementIsWrapper=!0,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}),this.originalResizeStyle=this.originalElement.css("resize"),this.originalElement.css("resize","none"),this._proportionallyResizeElements.push(this.originalElement.css({position:"static",zoom:1,display:"block"})),this.originalElement.css({margin:this.originalElement.css("margin")}),this._proportionallyResize()),this.handles=n.handles||(e(".ui-resizable-handle",this.element).length?{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"}:"e,s,se");if(this.handles.constructor==String){this.handles=="all"&&(this.handles="n,e,s,w,se,sw,ne,nw");var r=this.handles.split(",");this.handles={};for(var i=0;i
      ');u.css({zIndex:n.zIndex}),"se"==s&&u.addClass("ui-icon ui-icon-gripsmall-diagonal-se"),this.handles[s]=".ui-resizable-"+s,this.element.append(u)}}this._renderAxis=function(t){t=t||this.element;for(var n in this.handles){this.handles[n].constructor==String&&(this.handles[n]=e(this.handles[n],this.element).show());if(this.elementIsWrapper&&this.originalElement[0].nodeName.match(/textarea|input|select|button/i)){var r=e(this.handles[n],this.element),i=0;i=/sw|ne|nw|se|n|s/.test(n)?r.outerHeight():r.outerWidth();var s=["padding",/ne|nw|n/.test(n)?"Top":/se|sw|s/.test(n)?"Bottom":/^e$/.test(n)?"Right":"Left"].join("");t.css(s,i),this._proportionallyResize()}if(!e(this.handles[n]).length)continue}},this._renderAxis(this.element),this._handles=e(".ui-resizable-handle",this.element).disableSelection(),this._handles.mouseover(function(){if(!t.resizing){if(this.className)var e=this.className.match(/ui-resizable-(se|sw|ne|nw|n|e|s|w)/i);t.axis=e&&e[1]?e[1]:"se"}}),n.autoHide&&(this._handles.hide(),e(this.element).addClass("ui-resizable-autohide").mouseenter(function(){if(n.disabled)return;e(this).removeClass("ui-resizable-autohide"),t._handles.show()}).mouseleave(function(){if(n.disabled)return;t.resizing||(e(this).addClass("ui-resizable-autohide"),t._handles.hide())})),this._mouseInit()},_destroy:function(){this._mouseDestroy();var t=function(t){e(t).removeClass("ui-resizable ui-resizable-disabled ui-resizable-resizing").removeData("resizable").removeData("ui-resizable").unbind(".resizable").find(".ui-resizable-handle").remove()};if(this.elementIsWrapper){t(this.element);var n=this.element;n.after(this.originalElement.css({position:n.css("position"),width:n.outerWidth(),height:n.outerHeight(),top:n.css("top"),left:n.css("left")})).remove()}return this.originalElement.css("resize",this.originalResizeStyle),t(this.originalElement),this},_mouseCapture:function(t){var n=!1;for(var r in this.handles)e(this.handles[r])[0]==t.target&&(n=!0);return!this.options.disabled&&n},_mouseStart:function(t){var r=this.options,i=this.element.position(),s=this.element;this.resizing=!0,this.documentScroll={top:e(document).scrollTop(),left:e(document).scrollLeft()},(s.is(".ui-draggable")||/absolute/.test(s.css("position")))&&s.css({position:"absolute",top:i.top,left:i.left}),this._renderProxy();var o=n(this.helper.css("left")),u=n(this.helper.css("top"));r.containment&&(o+=e(r.containment).scrollLeft()||0,u+=e(r.containment).scrollTop()||0),this.offset=this.helper.offset(),this.position={left:o,top:u},this.size=this._helper?{width:s.outerWidth(),height:s.outerHeight()}:{width:s.width(),height:s.height()},this.originalSize=this._helper?{width:s.outerWidth(),height:s.outerHeight()}:{width:s.width(),height:s.height()},this.originalPosition={left:o,top:u},this.sizeDiff={width:s.outerWidth()-s.width(),height:s.outerHeight()-s.height()},this.originalMousePosition={left:t.pageX,top:t.pageY},this.aspectRatio=typeof r.aspectRatio=="number"?r.aspectRatio:this.originalSize.width/this.originalSize.height||1;var a=e(".ui-resizable-"+this.axis).css("cursor");return e("body").css("cursor",a=="auto"?this.axis+"-resize":a),s.addClass("ui-resizable-resizing"),this._propagate("start",t),!0},_mouseDrag:function(e){var t=this.helper,n=this.options,r={},i=this,s=this.originalMousePosition,o=this.axis,u=e.pageX-s.left||0,a=e.pageY-s.top||0,f=this._change[o];if(!f)return!1;var l=f.apply(this,[e,u,a]);this._updateVirtualBoundaries(e.shiftKey);if(this._aspectRatio||e.shiftKey)l=this._updateRatio(l,e);return l=this._respectSize(l,e),this._propagate("resize",e),t.css({top:this.position.top+"px",left:this.position.left+"px",width:this.size.width+"px",height:this.size.height+"px"}),!this._helper&&this._proportionallyResizeElements.length&&this._proportionallyResize(),this._updateCache(l),this._trigger("resize",e,this.ui()),!1},_mouseStop:function(t){this.resizing=!1;var n=this.options,r=this;if(this._helper){var i=this._proportionallyResizeElements,s=i.length&&/textarea/i.test(i[0].nodeName),o=s&&e.ui.hasScroll(i[0],"left")?0:r.sizeDiff.height,u=s?0:r.sizeDiff.width,a={width:r.helper.width()-u,height:r.helper.height()-o},f=parseInt(r.element.css("left"),10)+(r.position.left-r.originalPosition.left)||null,l=parseInt(r.element.css("top"),10)+(r.position.top-r.originalPosition.top)||null;n.animate||this.element.css(e.extend(a,{top:l,left:f})),r.helper.height(r.size.height),r.helper.width(r.size.width),this._helper&&!n.animate&&this._proportionallyResize()}return e("body").css("cursor","auto"),this.element.removeClass("ui-resizable-resizing"),this._propagate("stop",t),this._helper&&this.helper.remove(),!1},_updateVirtualBoundaries:function(e){var t=this.options,n,i,s,o,u;u={minWidth:r(t.minWidth)?t.minWidth:0,maxWidth:r(t.maxWidth)?t.maxWidth:Infinity,minHeight:r(t.minHeight)?t.minHeight:0,maxHeight:r(t.maxHeight)?t.maxHeight:Infinity};if(this._aspectRatio||e)n=u.minHeight*this.aspectRatio,s=u.minWidth/this.aspectRatio,i=u.maxHeight*this.aspectRatio,o=u.maxWidth/this.aspectRatio,n>u.minWidth&&(u.minWidth=n),s>u.minHeight&&(u.minHeight=s),ie.width,l=r(e.height)&&i.minHeight&&i.minHeight>e.height;f&&(e.width=i.minWidth),l&&(e.height=i.minHeight),u&&(e.width=i.maxWidth),a&&(e.height=i.maxHeight);var c=this.originalPosition.left+this.originalSize.width,h=this.position.top+this.size.height,p=/sw|nw|w/.test(o),d=/nw|ne|n/.test(o);f&&p&&(e.left=c-i.minWidth),u&&p&&(e.left=c-i.maxWidth),l&&d&&(e.top=h-i.minHeight),a&&d&&(e.top=h-i.maxHeight);var v=!e.width&&!e.height;return v&&!e.left&&e.top?e.top=null:v&&!e.top&&e.left&&(e.left=null),e},_proportionallyResize:function(){var t=this.options;if(!this._proportionallyResizeElements.length)return;var n=this.helper||this.element;for(var r=0;r
      ');var r=e.browser.msie&&e.browser.version<7,i=r?1:0,s=r?2:-1;this.helper.addClass(this._helper).css({width:this.element.outerWidth()+s,height:this.element.outerHeight()+s,position:"absolute",left:this.elementOffset.left-i+"px",top:this.elementOffset.top-i+"px",zIndex:++n.zIndex}),this.helper.appendTo("body").disableSelection()}else this.helper=this.element},_change:{e:function(e,t,n){return{width:this.originalSize.width+t}},w:function(e,t,n){var r=this.options,i=this.originalSize,s=this.originalPosition;return{left:s.left+t,width:i.width-t}},n:function(e,t,n){var r=this.options,i=this.originalSize,s=this.originalPosition;return{top:s.top+n,height:i.height-n}},s:function(e,t,n){return{height:this.originalSize.height+n}},se:function(t,n,r){return e.extend(this._change.s.apply(this,arguments),this._change.e.apply(this,[t,n,r]))},sw:function(t,n,r){return e.extend(this._change.s.apply(this,arguments),this._change.w.apply(this,[t,n,r]))},ne:function(t,n,r){return e.extend(this._change.n.apply(this,arguments),this._change.e.apply(this,[t,n,r]))},nw:function(t,n,r){return e.extend(this._change.n.apply(this,arguments),this._change.w.apply(this,[t,n,r]))}},_propagate:function(t,n){e.ui.plugin.call(this,t,[n,this.ui()]),t!="resize"&&this._trigger(t,n,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}}}),e.ui.plugin.add("resizable","alsoResize",{start:function(t,n){var r=e(this).data("resizable"),i=r.options,s=function(t){e(t).each(function(){var t=e(this);t.data("resizable-alsoresize",{width:parseInt(t.width(),10),height:parseInt(t.height(),10),left:parseInt(t.css("left"),10),top:parseInt(t.css("top"),10)})})};typeof i.alsoResize=="object"&&!i.alsoResize.parentNode?i.alsoResize.length?(i.alsoResize=i.alsoResize[0],s(i.alsoResize)):e.each(i.alsoResize,function(e){s(e)}):s(i.alsoResize)},resize:function(t,n){var r=e(this).data("resizable"),i=r.options,s=r.originalSize,o=r.originalPosition,u={height:r.size.height-s.height||0,width:r.size.width-s.width||0,top:r.position.top-o.top||0,left:r.position.left-o.left||0},a=function(t,r){e(t).each(function(){var t=e(this),i=e(this).data("resizable-alsoresize"),s={},o=r&&r.length?r:t.parents(n.originalElement[0]).length?["width","height"]:["width","height","top","left"];e.each(o,function(e,t){var n=(i[t]||0)+(u[t]||0);n&&n>=0&&(s[t]=n||null)}),t.css(s)})};typeof i.alsoResize=="object"&&!i.alsoResize.nodeType?e.each(i.alsoResize,function(e,t){a(e,t)}):a(i.alsoResize)},stop:function(t,n){e(this).removeData("resizable-alsoresize")}}),e.ui.plugin.add("resizable","animate",{stop:function(t,n){var r=e(this).data("resizable"),i=r.options,s=r._proportionallyResizeElements,o=s.length&&/textarea/i.test(s[0].nodeName),u=o&&e.ui.hasScroll(s[0],"left")?0:r.sizeDiff.height,a=o?0:r.sizeDiff.width,f={width:r.size.width-a,height:r.size.height-u},l=parseInt(r.element.css("left"),10)+(r.position.left-r.originalPosition.left)||null,c=parseInt(r.element.css("top"),10)+(r.position.top-r.originalPosition.top)||null;r.element.animate(e.extend(f,c&&l?{top:c,left:l}:{}),{duration:i.animateDuration,easing:i.animateEasing,step:function(){var n={width:parseInt(r.element.css("width"),10),height:parseInt(r.element.css("height"),10),top:parseInt(r.element.css("top"),10),left:parseInt(r.element.css("left"),10)};s&&s.length&&e(s[0]).css({width:n.width,height:n.height}),r._updateCache(n),r._propagate("resize",t)}})}}),e.ui.plugin.add("resizable","containment",{start:function(t,r){var i=e(this).data("resizable"),s=i.options,o=i.element,u=s.containment,a=u instanceof e?u.get(0):/parent/.test(u)?o.parent().get(0):u;if(!a)return;i.containerElement=e(a);if(/document/.test(u)||u==document)i.containerOffset={left:0,top:0},i.containerPosition={left:0,top:0},i.parentData={element:e(document),left:0,top:0,width:e(document).width(),height:e(document).height()||document.body.parentNode.scrollHeight};else{var f=e(a),l=[];e(["Top","Right","Left","Bottom"]).each(function(e,t){l[e]=n(f.css("padding"+t))}),i.containerOffset=f.offset(),i.containerPosition=f.position(),i.containerSize={height:f.innerHeight()-l[3],width:f.innerWidth()-l[1]};var c=i.containerOffset,h=i.containerSize.height,p=i.containerSize.width,d=e.ui.hasScroll(a,"left")?a.scrollWidth:p,v=e.ui.hasScroll(a)?a.scrollHeight:h;i.parentData={element:a,left:c.left,top:c.top,width:d,height:v}}},resize:function(t,n){var r=e(this).data("resizable"),i=r.options,s=r.containerSize,o=r.containerOffset,u=r.size,a=r.position,f=r._aspectRatio||t.shiftKey,l={top:0,left:0},c=r.containerElement;c[0]!=document&&/static/.test(c.css("position"))&&(l=o),a.left<(r._helper?o.left:0)&&(r.size.width=r.size.width+(r._helper?r.position.left-o.left:r.position.left-l.left),f&&(r.size.height=r.size.width/r.aspectRatio),r.position.left=i.helper?o.left:0),a.top<(r._helper?o.top:0)&&(r.size.height=r.size.height+(r._helper?r.position.top-o.top:r.position.top),f&&(r.size.width=r.size.height*r.aspectRatio),r.position.top=r._helper?o.top:0),r.offset.left=r.parentData.left+r.position.left,r.offset.top=r.parentData.top+r.position.top;var h=Math.abs((r._helper?r.offset.left-l.left:r.offset.left-l.left)+r.sizeDiff.width),p=Math.abs((r._helper?r.offset.top-l.top:r.offset.top-o.top)+r.sizeDiff.height),d=r.containerElement.get(0)==r.element.parent().get(0),v=/relative|absolute/.test(r.containerElement.css("position"));d&&v&&(h-=r.parentData.left),h+r.size.width>=r.parentData.width&&(r.size.width=r.parentData.width-h,f&&(r.size.height=r.size.width/r.aspectRatio)),p+r.size.height>=r.parentData.height&&(r.size.height=r.parentData.height-p,f&&(r.size.width=r.size.height*r.aspectRatio))},stop:function(t,n){var r=e(this).data("resizable"),i=r.options,s=r.position,o=r.containerOffset,u=r.containerPosition,a=r.containerElement,f=e(r.helper),l=f.offset(),c=f.outerWidth()-r.sizeDiff.width,h=f.outerHeight()-r.sizeDiff.height;r._helper&&!i.animate&&/relative/.test(a.css("position"))&&e(this).css({left:l.left-u.left-o.left,width:c,height:h}),r._helper&&!i.animate&&/static/.test(a.css("position"))&&e(this).css({left:l.left-u.left-o.left,width:c,height:h})}}),e.ui.plugin.add("resizable","ghost",{start:function(t,n){var r=e(this).data("resizable"),i=r.options,s=r.size;r.ghost=r.originalElement.clone(),r.ghost.css({opacity:.25,display:"block",position:"relative",height:s.height,width:s.width,margin:0,left:0,top:0}).addClass("ui-resizable-ghost").addClass(typeof i.ghost=="string"?i.ghost:""),r.ghost.appendTo(r.helper)},resize:function(t,n){var r=e(this).data("resizable"),i=r.options;r.ghost&&r.ghost.css({position:"relative",height:r.size.height,width:r.size.width})},stop:function(t,n){var r=e(this).data("resizable"),i=r.options;r.ghost&&r.helper&&r.helper.get(0).removeChild(r.ghost.get(0))}}),e.ui.plugin.add("resizable","grid",{resize:function(t,n){var r=e(this).data("resizable"),i=r.options,s=r.size,o=r.originalSize,u=r.originalPosition,a=r.axis,f=i._aspectRatio||t.shiftKey;i.grid=typeof i.grid=="number"?[i.grid,i.grid]:i.grid;var l=Math.round((s.width-o.width)/(i.grid[0]||1))*(i.grid[0]||1),c=Math.round((s.height-o.height)/(i.grid[1]||1))*(i.grid[1]||1);/^(se|s|e)$/.test(a)?(r.size.width=o.width+l,r.size.height=o.height+c):/^(ne)$/.test(a)?(r.size.width=o.width+l,r.size.height=o.height+c,r.position.top=u.top-c):/^(sw)$/.test(a)?(r.size.width=o.width+l,r.size.height=o.height+c,r.position.left=u.left-l):(r.size.width=o.width+l,r.size.height=o.height+c,r.position.top=u.top-c,r.position.left=u.left-l)}});var n=function(e){return parseInt(e,10)||0},r=function(e){return!isNaN(parseInt(e,10))}})(jQuery); \ No newline at end of file diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/ui/minified/jquery.ui.selectable.min.js b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/ui/minified/jquery.ui.selectable.min.js new file mode 100755 index 000000000..36ce6a4d4 --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/ui/minified/jquery.ui.selectable.min.js @@ -0,0 +1,5 @@ +/*! jQuery UI - v1.9.0 - 2012-10-08 +* http://jqueryui.com +* Includes: jquery.ui.selectable.js +* Copyright 2012 jQuery Foundation and other contributors; Licensed MIT */ +(function(e,t){e.widget("ui.selectable",e.ui.mouse,{version:"1.9.0",options:{appendTo:"body",autoRefresh:!0,distance:0,filter:"*",tolerance:"touch"},_create:function(){var t=this;this.element.addClass("ui-selectable"),this.dragged=!1;var n;this.refresh=function(){n=e(t.options.filter,t.element[0]),n.addClass("ui-selectee"),n.each(function(){var t=e(this),n=t.offset();e.data(this,"selectable-item",{element:this,$element:t,left:n.left,top:n.top,right:n.left+t.outerWidth(),bottom:n.top+t.outerHeight(),startselected:!1,selected:t.hasClass("ui-selected"),selecting:t.hasClass("ui-selecting"),unselecting:t.hasClass("ui-unselecting")})})},this.refresh(),this.selectees=n.addClass("ui-selectee"),this._mouseInit(),this.helper=e("
      ")},_destroy:function(){this.selectees.removeClass("ui-selectee").removeData("selectable-item"),this.element.removeClass("ui-selectable ui-selectable-disabled"),this._mouseDestroy()},_mouseStart:function(t){var n=this;this.opos=[t.pageX,t.pageY];if(this.options.disabled)return;var r=this.options;this.selectees=e(r.filter,this.element[0]),this._trigger("start",t),e(r.appendTo).append(this.helper),this.helper.css({left:t.clientX,top:t.clientY,width:0,height:0}),r.autoRefresh&&this.refresh(),this.selectees.filter(".ui-selected").each(function(){var r=e.data(this,"selectable-item");r.startselected=!0,!t.metaKey&&!t.ctrlKey&&(r.$element.removeClass("ui-selected"),r.selected=!1,r.$element.addClass("ui-unselecting"),r.unselecting=!0,n._trigger("unselecting",t,{unselecting:r.element}))}),e(t.target).parents().andSelf().each(function(){var r=e.data(this,"selectable-item");if(r){var i=!t.metaKey&&!t.ctrlKey||!r.$element.hasClass("ui-selected");return r.$element.removeClass(i?"ui-unselecting":"ui-selected").addClass(i?"ui-selecting":"ui-unselecting"),r.unselecting=!i,r.selecting=i,r.selected=i,i?n._trigger("selecting",t,{selecting:r.element}):n._trigger("unselecting",t,{unselecting:r.element}),!1}})},_mouseDrag:function(t){var n=this;this.dragged=!0;if(this.options.disabled)return;var r=this.options,i=this.opos[0],s=this.opos[1],o=t.pageX,u=t.pageY;if(i>o){var a=o;o=i,i=a}if(s>u){var a=u;u=s,s=a}return this.helper.css({left:i,top:s,width:o-i,height:u-s}),this.selectees.each(function(){var a=e.data(this,"selectable-item");if(!a||a.element==n.element[0])return;var f=!1;r.tolerance=="touch"?f=!(a.left>o||a.rightu||a.bottomi&&a.rights&&a.bottom
      ").appendTo(this.element).addClass("ui-slider-range ui-widget-header"+(r.range==="min"||r.range==="max"?" ui-slider-range-"+r.range:"")));for(t=i.length;tn&&(i=n,s=e(this),o=t)}),c.range===!0&&this.values(1)===c.min&&(o+=1,s=e(this.handles[o])),u=this._start(t,o),u===!1?!1:(this._mouseSliding=!0,this._handleIndex=o,s.addClass("ui-state-active").focus(),a=s.offset(),f=!e(t.target).parents().andSelf().is(".ui-slider-handle"),this._clickOffset=f?{left:0,top:0}:{left:t.pageX-a.left-s.width()/2,top:t.pageY-a.top-s.height()/2-(parseInt(s.css("borderTopWidth"),10)||0)-(parseInt(s.css("borderBottomWidth"),10)||0)+(parseInt(s.css("marginTop"),10)||0)},this.handles.hasClass("ui-state-hover")||this._slide(t,o,r),this._animateOff=!0,!0))},_mouseStart:function(e){return!0},_mouseDrag:function(e){var t={x:e.pageX,y:e.pageY},n=this._normValueFromMouse(t);return this._slide(e,this._handleIndex,n),!1},_mouseStop:function(e){return this.handles.removeClass("ui-state-active"),this._mouseSliding=!1,this._stop(e,this._handleIndex),this._change(e,this._handleIndex),this._handleIndex=null,this._clickOffset=null,this._animateOff=!1,!1},_detectOrientation:function(){this.orientation=this.options.orientation==="vertical"?"vertical":"horizontal"},_normValueFromMouse:function(e){var t,n,r,i,s;return this.orientation==="horizontal"?(t=this.elementSize.width,n=e.x-this.elementOffset.left-(this._clickOffset?this._clickOffset.left:0)):(t=this.elementSize.height,n=e.y-this.elementOffset.top-(this._clickOffset?this._clickOffset.top:0)),r=n/t,r>1&&(r=1),r<0&&(r=0),this.orientation==="vertical"&&(r=1-r),i=this._valueMax()-this._valueMin(),s=this._valueMin()+r*i,this._trimAlignValue(s)},_start:function(e,t){var n={handle:this.handles[t],value:this.value()};return this.options.values&&this.options.values.length&&(n.value=this.values(t),n.values=this.values()),this._trigger("start",e,n)},_slide:function(e,t,n){var r,i,s;this.options.values&&this.options.values.length?(r=this.values(t?0:1),this.options.values.length===2&&this.options.range===!0&&(t===0&&n>r||t===1&&n1){this.options.values[t]=this._trimAlignValue(n),this._refreshValue(),this._change(null,t);return}if(!arguments.length)return this._values();if(!e.isArray(arguments[0]))return this.options.values&&this.options.values.length?this._values(t):this.value();r=this.options.values,i=arguments[0];for(s=0;s=this._valueMax())return this._valueMax();var t=this.options.step>0?this.options.step:1,n=(e-this._valueMin())%t,r=e-n;return Math.abs(n)*2>=t&&(r+=n>0?t:-t),parseFloat(r.toFixed(5))},_valueMin:function(){return this.options.min},_valueMax:function(){return this.options.max},_refreshValue:function(){var t,n,r,i,s,o=this.options.range,u=this.options,a=this,f=this._animateOff?!1:u.animate,l={};this.options.values&&this.options.values.length?this.handles.each(function(r,i){n=(a.values(r)-a._valueMin())/(a._valueMax()-a._valueMin())*100,l[a.orientation==="horizontal"?"left":"bottom"]=n+"%",e(this).stop(1,1)[f?"animate":"css"](l,u.animate),a.options.range===!0&&(a.orientation==="horizontal"?(r===0&&a.range.stop(1,1)[f?"animate":"css"]({left:n+"%"},u.animate),r===1&&a.range[f?"animate":"css"]({width:n-t+"%"},{queue:!1,duration:u.animate})):(r===0&&a.range.stop(1,1)[f?"animate":"css"]({bottom:n+"%"},u.animate),r===1&&a.range[f?"animate":"css"]({height:n-t+"%"},{queue:!1,duration:u.animate}))),t=n}):(r=this.value(),i=this._valueMin(),s=this._valueMax(),n=s!==i?(r-i)/(s-i)*100:0,l[this.orientation==="horizontal"?"left":"bottom"]=n+"%",this.handle.stop(1,1)[f?"animate":"css"](l,u.animate),o==="min"&&this.orientation==="horizontal"&&this.range.stop(1,1)[f?"animate":"css"]({width:n+"%"},u.animate),o==="max"&&this.orientation==="horizontal"&&this.range[f?"animate":"css"]({width:100-n+"%"},{queue:!1,duration:u.animate}),o==="min"&&this.orientation==="vertical"&&this.range.stop(1,1)[f?"animate":"css"]({height:n+"%"},u.animate),o==="max"&&this.orientation==="vertical"&&this.range[f?"animate":"css"]({height:100-n+"%"},{queue:!1,duration:u.animate}))}})})(jQuery); \ No newline at end of file diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/ui/minified/jquery.ui.sortable.min.js b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/ui/minified/jquery.ui.sortable.min.js new file mode 100755 index 000000000..d7cc35480 --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/ui/minified/jquery.ui.sortable.min.js @@ -0,0 +1,5 @@ +/*! jQuery UI - v1.9.0 - 2012-10-08 +* http://jqueryui.com +* Includes: jquery.ui.sortable.js +* Copyright 2012 jQuery Foundation and other contributors; Licensed MIT */ +(function(e,t){e.widget("ui.sortable",e.ui.mouse,{version:"1.9.0",widgetEventPrefix:"sort",ready:!1,options:{appendTo:"parent",axis:!1,connectWith:!1,containment:!1,cursor:"auto",cursorAt:!1,dropOnEmpty:!0,forcePlaceholderSize:!1,forceHelperSize:!1,grid:!1,handle:!1,helper:"original",items:"> *",opacity:!1,placeholder:!1,revert:!1,scroll:!0,scrollSensitivity:20,scrollSpeed:20,scope:"default",tolerance:"intersect",zIndex:1e3},_create:function(){var e=this.options;this.containerCache={},this.element.addClass("ui-sortable"),this.refresh(),this.floating=this.items.length?e.axis==="x"||/left|right/.test(this.items[0].item.css("float"))||/inline|table-cell/.test(this.items[0].item.css("display")):!1,this.offset=this.element.offset(),this._mouseInit(),this.ready=!0},_destroy:function(){this.element.removeClass("ui-sortable ui-sortable-disabled"),this._mouseDestroy();for(var e=this.items.length-1;e>=0;e--)this.items[e].item.removeData(this.widgetName+"-item");return this},_setOption:function(t,n){t==="disabled"?(this.options[t]=n,this.widget().toggleClass("ui-sortable-disabled",!!n)):e.Widget.prototype._setOption.apply(this,arguments)},_mouseCapture:function(t,n){var r=this;if(this.reverting)return!1;if(this.options.disabled||this.options.type=="static")return!1;this._refreshItems(t);var i=null,s=e(t.target).parents().each(function(){if(e.data(this,r.widgetName+"-item")==r)return i=e(this),!1});e.data(t.target,r.widgetName+"-item")==r&&(i=e(t.target));if(!i)return!1;if(this.options.handle&&!n){var o=!1;e(this.options.handle,i).find("*").andSelf().each(function(){this==t.target&&(o=!0)});if(!o)return!1}return this.currentItem=i,this._removeCurrentsFromItems(),!0},_mouseStart:function(t,n,r){var i=this.options;this.currentContainer=this,this.refreshPositions(),this.helper=this._createHelper(t),this._cacheHelperProportions(),this._cacheMargins(),this.scrollParent=this.helper.scrollParent(),this.offset=this.currentItem.offset(),this.offset={top:this.offset.top-this.margins.top,left:this.offset.left-this.margins.left},e.extend(this.offset,{click:{left:t.pageX-this.offset.left,top:t.pageY-this.offset.top},parent:this._getParentOffset(),relative:this._getRelativeOffset()}),this.helper.css("position","absolute"),this.cssPosition=this.helper.css("position"),this.originalPosition=this._generatePosition(t),this.originalPageX=t.pageX,this.originalPageY=t.pageY,i.cursorAt&&this._adjustOffsetFromHelper(i.cursorAt),this.domPosition={prev:this.currentItem.prev()[0],parent:this.currentItem.parent()[0]},this.helper[0]!=this.currentItem[0]&&this.currentItem.hide(),this._createPlaceholder(),i.containment&&this._setContainment(),i.cursor&&(e("body").css("cursor")&&(this._storedCursor=e("body").css("cursor")),e("body").css("cursor",i.cursor)),i.opacity&&(this.helper.css("opacity")&&(this._storedOpacity=this.helper.css("opacity")),this.helper.css("opacity",i.opacity)),i.zIndex&&(this.helper.css("zIndex")&&(this._storedZIndex=this.helper.css("zIndex")),this.helper.css("zIndex",i.zIndex)),this.scrollParent[0]!=document&&this.scrollParent[0].tagName!="HTML"&&(this.overflowOffset=this.scrollParent.offset()),this._trigger("start",t,this._uiHash()),this._preserveHelperProportions||this._cacheHelperProportions();if(!r)for(var s=this.containers.length-1;s>=0;s--)this.containers[s]._trigger("activate",t,this._uiHash(this));return e.ui.ddmanager&&(e.ui.ddmanager.current=this),e.ui.ddmanager&&!i.dropBehaviour&&e.ui.ddmanager.prepareOffsets(this,t),this.dragging=!0,this.helper.addClass("ui-sortable-helper"),this._mouseDrag(t),!0},_mouseDrag:function(t){this.position=this._generatePosition(t),this.positionAbs=this._convertPositionTo("absolute"),this.lastPositionAbs||(this.lastPositionAbs=this.positionAbs);if(this.options.scroll){var n=this.options,r=!1;this.scrollParent[0]!=document&&this.scrollParent[0].tagName!="HTML"?(this.overflowOffset.top+this.scrollParent[0].offsetHeight-t.pageY=0;i--){var s=this.items[i],o=s.item[0],u=this._intersectsWithPointer(s);if(!u)continue;if(s.instance!==this.currentContainer)continue;if(o!=this.currentItem[0]&&this.placeholder[u==1?"next":"prev"]()[0]!=o&&!e.contains(this.placeholder[0],o)&&(this.options.type=="semi-dynamic"?!e.contains(this.element[0],o):!0)){this.direction=u==1?"down":"up";if(this.options.tolerance!="pointer"&&!this._intersectsWithSides(s))break;this._rearrange(t,s),this._trigger("change",t,this._uiHash());break}}return this._contactContainers(t),e.ui.ddmanager&&e.ui.ddmanager.drag(this,t),this._trigger("sort",t,this._uiHash()),this.lastPositionAbs=this.positionAbs,!1},_mouseStop:function(t,n){if(!t)return;e.ui.ddmanager&&!this.options.dropBehaviour&&e.ui.ddmanager.drop(this,t);if(this.options.revert){var r=this,i=this.placeholder.offset();this.reverting=!0,e(this.helper).animate({left:i.left-this.offset.parent.left-this.margins.left+(this.offsetParent[0]==document.body?0:this.offsetParent[0].scrollLeft),top:i.top-this.offset.parent.top-this.margins.top+(this.offsetParent[0]==document.body?0:this.offsetParent[0].scrollTop)},parseInt(this.options.revert,10)||500,function(){r._clear(t)})}else this._clear(t,n);return!1},cancel:function(){if(this.dragging){this._mouseUp({target:null}),this.options.helper=="original"?this.currentItem.css(this._storedCSS).removeClass("ui-sortable-helper"):this.currentItem.show();for(var t=this.containers.length-1;t>=0;t--)this.containers[t]._trigger("deactivate",null,this._uiHash(this)),this.containers[t].containerCache.over&&(this.containers[t]._trigger("out",null,this._uiHash(this)),this.containers[t].containerCache.over=0)}return this.placeholder&&(this.placeholder[0].parentNode&&this.placeholder[0].parentNode.removeChild(this.placeholder[0]),this.options.helper!="original"&&this.helper&&this.helper[0].parentNode&&this.helper.remove(),e.extend(this,{helper:null,dragging:!1,reverting:!1,_noFinalSort:null}),this.domPosition.prev?e(this.domPosition.prev).after(this.currentItem):e(this.domPosition.parent).prepend(this.currentItem)),this},serialize:function(t){var n=this._getItemsAsjQuery(t&&t.connected),r=[];return t=t||{},e(n).each(function(){var n=(e(t.item||this).attr(t.attribute||"id")||"").match(t.expression||/(.+)[-=_](.+)/);n&&r.push((t.key||n[1]+"[]")+"="+(t.key&&t.expression?n[1]:n[2]))}),!r.length&&t.key&&r.push(t.key+"="),r.join("&")},toArray:function(t){var n=this._getItemsAsjQuery(t&&t.connected),r=[];return t=t||{},n.each(function(){r.push(e(t.item||this).attr(t.attribute||"id")||"")}),r},_intersectsWith:function(e){var t=this.positionAbs.left,n=t+this.helperProportions.width,r=this.positionAbs.top,i=r+this.helperProportions.height,s=e.left,o=s+e.width,u=e.top,a=u+e.height,f=this.offset.click.top,l=this.offset.click.left,c=r+f>u&&r+fs&&t+le[this.floating?"width":"height"]?c:s0?"down":"up")},_getDragHorizontalDirection:function(){var e=this.positionAbs.left-this.lastPositionAbs.left;return e!=0&&(e>0?"right":"left")},refresh:function(e){return this._refreshItems(e),this.refreshPositions(),this},_connectWith:function(){var e=this.options;return e.connectWith.constructor==String?[e.connectWith]:e.connectWith},_getItemsAsjQuery:function(t){var n=[],r=[],i=this._connectWith();if(i&&t)for(var s=i.length-1;s>=0;s--){var o=e(i[s]);for(var u=o.length-1;u>=0;u--){var a=e.data(o[u],this.widgetName);a&&a!=this&&!a.options.disabled&&r.push([e.isFunction(a.options.items)?a.options.items.call(a.element):e(a.options.items,a.element).not(".ui-sortable-helper").not(".ui-sortable-placeholder"),a])}}r.push([e.isFunction(this.options.items)?this.options.items.call(this.element,null,{options:this.options,item:this.currentItem}):e(this.options.items,this.element).not(".ui-sortable-helper").not(".ui-sortable-placeholder"),this]);for(var s=r.length-1;s>=0;s--)r[s][0].each(function(){n.push(this)});return e(n)},_removeCurrentsFromItems:function(){var e=this.currentItem.find(":data("+this.widgetName+"-item)");for(var t=0;t=0;s--){var o=e(i[s]);for(var u=o.length-1;u>=0;u--){var a=e.data(o[u],this.widgetName);a&&a!=this&&!a.options.disabled&&(r.push([e.isFunction(a.options.items)?a.options.items.call(a.element[0],t,{item:this.currentItem}):e(a.options.items,a.element),a]),this.containers.push(a))}}for(var s=r.length-1;s>=0;s--){var f=r[s][1],l=r[s][0];for(var u=0,c=l.length;u=0;n--){var r=this.items[n];if(r.instance!=this.currentContainer&&this.currentContainer&&r.item[0]!=this.currentItem[0])continue;var i=this.options.toleranceElement?e(this.options.toleranceElement,r.item):r.item;t||(r.width=i.outerWidth(),r.height=i.outerHeight());var s=i.offset();r.left=s.left,r.top=s.top}if(this.options.custom&&this.options.custom.refreshContainers)this.options.custom.refreshContainers.call(this);else for(var n=this.containers.length-1;n>=0;n--){var s=this.containers[n].element.offset();this.containers[n].containerCache.left=s.left,this.containers[n].containerCache.top=s.top,this.containers[n].containerCache.width=this.containers[n].element.outerWidth(),this.containers[n].containerCache.height=this.containers[n].element.outerHeight()}return this},_createPlaceholder:function(t){t=t||this;var n=t.options;if(!n.placeholder||n.placeholder.constructor==String){var r=n.placeholder;n.placeholder={element:function(){var n=e(document.createElement(t.currentItem[0].nodeName)).addClass(r||t.currentItem[0].className+" ui-sortable-placeholder").removeClass("ui-sortable-helper")[0];return r||(n.style.visibility="hidden"),n},update:function(e,i){if(r&&!n.forcePlaceholderSize)return;i.height()||i.height(t.currentItem.innerHeight()-parseInt(t.currentItem.css("paddingTop")||0,10)-parseInt(t.currentItem.css("paddingBottom")||0,10)),i.width()||i.width(t.currentItem.innerWidth()-parseInt(t.currentItem.css("paddingLeft")||0,10)-parseInt(t.currentItem.css("paddingRight")||0,10))}}}t.placeholder=e(n.placeholder.element.call(t.element,t.currentItem)),t.currentItem.after(t.placeholder),n.placeholder.update(t,t.placeholder)},_contactContainers:function(t){var n=null,r=null;for(var i=this.containers.length-1;i>=0;i--){if(e.contains(this.currentItem[0],this.containers[i].element[0]))continue;if(this._intersectsWith(this.containers[i].containerCache)){if(n&&e.contains(this.containers[i].element[0],n.element[0]))continue;n=this.containers[i],r=i}else this.containers[i].containerCache.over&&(this.containers[i]._trigger("out",t,this._uiHash(this)),this.containers[i].containerCache.over=0)}if(!n)return;if(this.containers.length===1)this.containers[r]._trigger("over",t,this._uiHash(this)),this.containers[r].containerCache.over=1;else if(this.currentContainer!=this.containers[r]){var s=1e4,o=null,u=this.positionAbs[this.containers[r].floating?"left":"top"];for(var a=this.items.length-1;a>=0;a--){if(!e.contains(this.containers[r].element[0],this.items[a].item[0]))continue;var f=this.containers[r].floating?this.items[a].item.offset().left:this.items[a].item.offset().top;Math.abs(f-u)0?"down":"up")}if(!o&&!this.options.dropOnEmpty)return;this.currentContainer=this.containers[r],o?this._rearrange(t,o,null,!0):this._rearrange(t,null,this.containers[r].element,!0),this._trigger("change",t,this._uiHash()),this.containers[r]._trigger("change",t,this._uiHash(this)),this.options.placeholder.update(this.currentContainer,this.placeholder),this.containers[r]._trigger("over",t,this._uiHash(this)),this.containers[r].containerCache.over=1}},_createHelper:function(t){var n=this.options,r=e.isFunction(n.helper)?e(n.helper.apply(this.element[0],[t,this.currentItem])):n.helper=="clone"?this.currentItem.clone():this.currentItem;return r.parents("body").length||e(n.appendTo!="parent"?n.appendTo:this.currentItem[0].parentNode)[0].appendChild(r[0]),r[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")}),(r[0].style.width==""||n.forceHelperSize)&&r.width(this.currentItem.width()),(r[0].style.height==""||n.forceHelperSize)&&r.height(this.currentItem.height()),r},_adjustOffsetFromHelper:function(t){typeof t=="string"&&(t=t.split(" ")),e.isArray(t)&&(t={left:+t[0],top:+t[1]||0}),"left"in t&&(this.offset.click.left=t.left+this.margins.left),"right"in t&&(this.offset.click.left=this.helperProportions.width-t.right+this.margins.left),"top"in t&&(this.offset.click.top=t.top+this.margins.top),"bottom"in t&&(this.offset.click.top=this.helperProportions.height-t.bottom+this.margins.top)},_getParentOffset:function(){this.offsetParent=this.helper.offsetParent();var t=this.offsetParent.offset();this.cssPosition=="absolute"&&this.scrollParent[0]!=document&&e.contains(this.scrollParent[0],this.offsetParent[0])&&(t.left+=this.scrollParent.scrollLeft(),t.top+=this.scrollParent.scrollTop());if(this.offsetParent[0]==document.body||this.offsetParent[0].tagName&&this.offsetParent[0].tagName.toLowerCase()=="html"&&e.browser.msie)t={top:0,left:0};return{top:t.top+(parseInt(this.offsetParent.css("borderTopWidth"),10)||0),left:t.left+(parseInt(this.offsetParent.css("borderLeftWidth"),10)||0)}},_getRelativeOffset:function(){if(this.cssPosition=="relative"){var e=this.currentItem.position();return{top:e.top-(parseInt(this.helper.css("top"),10)||0)+this.scrollParent.scrollTop(),left:e.left-(parseInt(this.helper.css("left"),10)||0)+this.scrollParent.scrollLeft()}}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 t=this.options;t.containment=="parent"&&(t.containment=this.helper[0].parentNode);if(t.containment=="document"||t.containment=="window")this.containment=[0-this.offset.relative.left-this.offset.parent.left,0-this.offset.relative.top-this.offset.parent.top,e(t.containment=="document"?document:window).width()-this.helperProportions.width-this.margins.left,(e(t.containment=="document"?document:window).height()||document.body.parentNode.scrollHeight)-this.helperProportions.height-this.margins.top];if(!/^(document|window|parent)$/.test(t.containment)){var n=e(t.containment)[0],r=e(t.containment).offset(),i=e(n).css("overflow")!="hidden";this.containment=[r.left+(parseInt(e(n).css("borderLeftWidth"),10)||0)+(parseInt(e(n).css("paddingLeft"),10)||0)-this.margins.left,r.top+(parseInt(e(n).css("borderTopWidth"),10)||0)+(parseInt(e(n).css("paddingTop"),10)||0)-this.margins.top,r.left+(i?Math.max(n.scrollWidth,n.offsetWidth):n.offsetWidth)-(parseInt(e(n).css("borderLeftWidth"),10)||0)-(parseInt(e(n).css("paddingRight"),10)||0)-this.helperProportions.width-this.margins.left,r.top+(i?Math.max(n.scrollHeight,n.offsetHeight):n.offsetHeight)-(parseInt(e(n).css("borderTopWidth"),10)||0)-(parseInt(e(n).css("paddingBottom"),10)||0)-this.helperProportions.height-this.margins.top]}},_convertPositionTo:function(t,n){n||(n=this.position);var r=t=="absolute"?1:-1,i=this.options,s=this.cssPosition!="absolute"||this.scrollParent[0]!=document&&!!e.contains(this.scrollParent[0],this.offsetParent[0])?this.scrollParent:this.offsetParent,o=/(html|body)/i.test(s[0].tagName);return{top:n.top+this.offset.relative.top*r+this.offset.parent.top*r-(this.cssPosition=="fixed"?-this.scrollParent.scrollTop():o?0:s.scrollTop())*r,left:n.left+this.offset.relative.left*r+this.offset.parent.left*r-(this.cssPosition=="fixed"?-this.scrollParent.scrollLeft():o?0:s.scrollLeft())*r}},_generatePosition:function(t){var n=this.options,r=this.cssPosition!="absolute"||this.scrollParent[0]!=document&&!!e.contains(this.scrollParent[0],this.offsetParent[0])?this.scrollParent:this.offsetParent,i=/(html|body)/i.test(r[0].tagName);this.cssPosition=="relative"&&(this.scrollParent[0]==document||this.scrollParent[0]==this.offsetParent[0])&&(this.offset.relative=this._getRelativeOffset());var s=t.pageX,o=t.pageY;if(this.originalPosition){this.containment&&(t.pageX-this.offset.click.leftthis.containment[2]&&(s=this.containment[2]+this.offset.click.left),t.pageY-this.offset.click.top>this.containment[3]&&(o=this.containment[3]+this.offset.click.top));if(n.grid){var u=this.originalPageY+Math.round((o-this.originalPageY)/n.grid[1])*n.grid[1];o=this.containment?u-this.offset.click.topthis.containment[3]?u-this.offset.click.topthis.containment[2]?a-this.offset.click.left=0;i--)n||r.push(function(e){return function(t){e._trigger("deactivate",t,this._uiHash(this))}}.call(this,this.containers[i])),this.containers[i].containerCache.over&&(r.push(function(e){return function(t){e._trigger("out",t,this._uiHash(this))}}.call(this,this.containers[i])),this.containers[i].containerCache.over=0);this._storedCursor&&e("body").css("cursor",this._storedCursor),this._storedOpacity&&this.helper.css("opacity",this._storedOpacity),this._storedZIndex&&this.helper.css("zIndex",this._storedZIndex=="auto"?"":this._storedZIndex),this.dragging=!1;if(this.cancelHelperRemoval){if(!n){this._trigger("beforeStop",t,this._uiHash());for(var i=0;i",widgetEventPrefix:"spin",options:{culture:null,icons:{down:"ui-icon-triangle-1-s",up:"ui-icon-triangle-1-n"},incremental:!0,max:null,min:null,numberFormat:null,page:10,step:1,change:null,spin:null,start:null,stop:null},_create:function(){this._setOption("max",this.options.max),this._setOption("min",this.options.min),this._setOption("step",this.options.step),this._value(this.element.val(),!0),this._draw(),this._on(this._events),this._refresh(),this._on(this.window,{beforeunload:function(){this.element.removeAttr("autocomplete")}})},_getCreateOptions:function(){var t={},n=this.element;return e.each(["min","max","step"],function(e,r){var i=n.attr(r);i!==undefined&&i.length&&(t[r]=i)}),t},_events:{keydown:function(e){this._start(e)&&this._keydown(e)&&e.preventDefault()},keyup:"_stop",focus:function(){this.uiSpinner.addClass("ui-state-active"),this.previous=this.element.val()},blur:function(e){if(this.cancelBlur){delete this.cancelBlur;return}this._refresh(),this.uiSpinner.removeClass("ui-state-active"),this.previous!==this.element.val()&&this._trigger("change",e)},mousewheel:function(e,t){if(!t)return;if(!this.spinning&&!this._start(e))return!1;this._spin((t>0?1:-1)*this.options.step,e),clearTimeout(this.mousewheelTimer),this.mousewheelTimer=this._delay(function(){this.spinning&&this._stop(e)},100),e.preventDefault()},"mousedown .ui-spinner-button":function(t){function r(){var e=this.element[0]===this.document[0].activeElement;e||(this.element.focus(),this.previous=n,this._delay(function(){this.previous=n}))}var n;n=this.element[0]===this.document[0].activeElement?this.previous:this.element.val(),t.preventDefault(),r.call(this),this.cancelBlur=!0,this._delay(function(){delete this.cancelBlur,r.call(this)});if(this._start(t)===!1)return;this._repeat(null,e(t.currentTarget).hasClass("ui-spinner-up")?1:-1,t)},"mouseup .ui-spinner-button":"_stop","mouseenter .ui-spinner-button":function(t){if(!e(t.currentTarget).hasClass("ui-state-active"))return;if(this._start(t)===!1)return!1;this._repeat(null,e(t.currentTarget).hasClass("ui-spinner-up")?1:-1,t)},"mouseleave .ui-spinner-button":"_stop"},_draw:function(){var e=this.uiSpinner=this.element.addClass("ui-spinner-input").attr("autocomplete","off").wrap(this._uiSpinnerHtml()).parent().append(this._buttonHtml());this._hoverable(e),this.element.attr("role","spinbutton"),this.buttons=e.find(".ui-spinner-button").attr("tabIndex",-1).button().removeClass("ui-corner-all"),this.buttons.height()>Math.ceil(e.height()*.5)&&e.height()>0&&e.height(e.height()),this.options.disabled&&this.disable()},_keydown:function(t){var n=this.options,r=e.ui.keyCode;switch(t.keyCode){case r.UP:return this._repeat(null,1,t),!0;case r.DOWN:return this._repeat(null,-1,t),!0;case r.PAGE_UP:return this._repeat(null,n.page,t),!0;case r.PAGE_DOWN:return this._repeat(null,-n.page,t),!0}return!1},_uiSpinnerHtml:function(){return""},_buttonHtml:function(){return""+""+""+""+""},_start:function(e){return!this.spinning&&this._trigger("start",e)===!1?!1:(this.counter||(this.counter=1),this.spinning=!0,!0)},_repeat:function(e,t,n){e=e||500,clearTimeout(this.timer),this.timer=this._delay(function(){this._repeat(40,t,n)},e),this._spin(t*this.options.step,n)},_spin:function(e,t){var n=this.value()||0;this.counter||(this.counter=1),n=this._adjustValue(n+e*this._increment(this.counter));if(!this.spinning||this._trigger("spin",t,{value:n})!==!1)this._value(n),this.counter++},_increment:function(t){var n=this.options.incremental;return n?e.isFunction(n)?n(t):Math.floor(t*t*t/5e4-t*t/500+17*t/200+1):1},_precision:function(){var e=this._precisionOf(this.options.step);return this.options.min!==null&&(e=Math.max(e,this._precisionOf(this.options.min))),e},_precisionOf:function(e){var t=e.toString(),n=t.indexOf(".");return n===-1?0:t.length-n-1},_adjustValue:function(e){var t,n,r=this.options;return t=r.min!==null?r.min:0,n=e-t,n=Math.round(n/r.step)*r.step,e=t+n,e=parseFloat(e.toFixed(this._precision())),r.max!==null&&e>r.max?r.max:r.min!==null&&e1&&e.href.replace(r,"")===location.href.replace(r,"")}var n=0,r=/#.*$/;e.widget("ui.tabs",{version:"1.9.0",delay:300,options:{active:null,collapsible:!1,event:"click",heightStyle:"content",hide:null,show:null,activate:null,beforeActivate:null,beforeLoad:null,load:null},_create:function(){var t,n=this,r=this.options,i=r.active;this.running=!1,this.element.addClass("ui-tabs ui-widget ui-widget-content ui-corner-all").toggleClass("ui-tabs-collapsible",r.collapsible).delegate(".ui-tabs-nav > li","mousedown"+this.eventNamespace,function(t){e(this).is(".ui-state-disabled")&&t.preventDefault()}).delegate(".ui-tabs-anchor","focus"+this.eventNamespace,function(){e(this).closest("li").is(".ui-state-disabled")&&this.blur()}),this._processTabs();if(i===null){location.hash&&this.anchors.each(function(e,t){if(t.hash===location.hash)return i=e,!1}),i===null&&(i=this.tabs.filter(".ui-tabs-active").index());if(i===null||i===-1)i=this.tabs.length?0:!1}i!==!1&&(i=this.tabs.index(this.tabs.eq(i)),i===-1&&(i=r.collapsible?!1:0)),r.active=i,!r.collapsible&&r.active===!1&&this.anchors.length&&(r.active=0),e.isArray(r.disabled)&&(r.disabled=e.unique(r.disabled.concat(e.map(this.tabs.filter(".ui-state-disabled"),function(e){return n.tabs.index(e)}))).sort()),this.options.active!==!1&&this.anchors.length?this.active=this._findActive(this.options.active):this.active=e(),this._refresh(),this.active.length&&this.load(r.active)},_getCreateEventData:function(){return{tab:this.active,panel:this.active.length?this._getPanelForTab(this.active):e()}},_tabKeydown:function(t){var n=e(this.document[0].activeElement).closest("li"),r=this.tabs.index(n),i=!0;if(this._handlePageNav(t))return;switch(t.keyCode){case e.ui.keyCode.RIGHT:case e.ui.keyCode.DOWN:r++;break;case e.ui.keyCode.UP:case e.ui.keyCode.LEFT:i=!1,r--;break;case e.ui.keyCode.END:r=this.anchors.length-1;break;case e.ui.keyCode.HOME:r=0;break;case e.ui.keyCode.SPACE:t.preventDefault(),clearTimeout(this.activating),this._activate(r);return;case e.ui.keyCode.ENTER:t.preventDefault(),clearTimeout(this.activating),this._activate(r===this.options.active?!1:r);return;default:return}t.preventDefault(),clearTimeout(this.activating),r=this._focusNextTab(r,i),t.ctrlKey||(n.attr("aria-selected","false"),this.tabs.eq(r).attr("aria-selected","true"),this.activating=this._delay(function(){this.option("active",r)},this.delay))},_panelKeydown:function(t){if(this._handlePageNav(t))return;t.ctrlKey&&t.keyCode===e.ui.keyCode.UP&&(t.preventDefault(),this.active.focus())},_handlePageNav:function(t){if(t.altKey&&t.keyCode===e.ui.keyCode.PAGE_UP)return this._activate(this._focusNextTab(this.options.active-1,!1)),!0;if(t.altKey&&t.keyCode===e.ui.keyCode.PAGE_DOWN)return this._activate(this._focusNextTab(this.options.active+1,!0)),!0},_findNextTab:function(t,n){function i(){return t>r&&(t=0),t<0&&(t=r),t}var r=this.tabs.length-1;while(e.inArray(i(),this.options.disabled)!==-1)t=n?t+1:t-1;return t},_focusNextTab:function(e,t){return e=this._findNextTab(e,t),this.tabs.eq(e).focus(),e},_setOption:function(e,t){if(e==="active"){this._activate(t);return}if(e==="disabled"){this._setupDisabled(t);return}this._super(e,t),e==="collapsible"&&(this.element.toggleClass("ui-tabs-collapsible",t),!t&&this.options.active===!1&&this._activate(0)),e==="event"&&this._setupEvents(t),e==="heightStyle"&&this._setupHeightStyle(t)},_tabId:function(e){return e.attr("aria-controls")||"ui-tabs-"+i()},_sanitizeSelector:function(e){return e?e.replace(/[!"$%&'()*+,.\/:;<=>?@\[\]\^`{|}~]/g,"\\$&"):""},refresh:function(){var t,n=this.options,r=this.tablist.children(":has(a[href])");n.disabled=e.map(r.filter(".ui-state-disabled"),function(e){return r.index(e)}),this._processTabs(),n.active===!1||!this.anchors.length?(n.active=!1,this.active=e()):this.active.length&&!e.contains(this.tablist[0],this.active[0])?this.tabs.length===n.disabled.length?(n.active=!1,this.active=e()):this._activate(this._findNextTab(Math.max(0,n.active-1),!1)):n.active=this.tabs.index(this.active),this._refresh()},_refresh:function(){this._setupDisabled(this.options.disabled),this._setupEvents(this.options.event),this._setupHeightStyle(this.options.heightStyle),this.tabs.not(this.active).attr({"aria-selected":"false",tabIndex:-1}),this.panels.not(this._getPanelForTab(this.active)).hide().attr({"aria-expanded":"false","aria-hidden":"true"}),this.active.length?(this.active.addClass("ui-tabs-active ui-state-active").attr({"aria-selected":"true",tabIndex:0}),this._getPanelForTab(this.active).show().attr({"aria-expanded":"true","aria-hidden":"false"})):this.tabs.eq(0).attr("tabIndex",0)},_processTabs:function(){var t=this;this.tablist=this._getList().addClass("ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all").attr("role","tablist"),this.tabs=this.tablist.find("> li:has(a[href])").addClass("ui-state-default ui-corner-top").attr({role:"tab",tabIndex:-1}),this.anchors=this.tabs.map(function(){return e("a",this)[0]}).addClass("ui-tabs-anchor").attr({role:"presentation",tabIndex:-1}),this.panels=e(),this.anchors.each(function(n,r){var i,o,u,a=e(r).uniqueId().attr("id"),f=e(r).closest("li"),l=f.attr("aria-controls");s(r)?(i=r.hash,o=t.element.find(t._sanitizeSelector(i))):(u=t._tabId(f),i="#"+u,o=t.element.find(i),o.length||(o=t._createPanel(u),o.insertAfter(t.panels[n-1]||t.tablist)),o.attr("aria-live","polite")),o.length&&(t.panels=t.panels.add(o)),l&&f.data("ui-tabs-aria-controls",l),f.attr({"aria-controls":i.substring(1),"aria-labelledby":a}),o.attr("aria-labelledby",a)}),this.panels.addClass("ui-tabs-panel ui-widget-content ui-corner-bottom").attr("role","tabpanel")},_getList:function(){return this.element.find("ol,ul").eq(0)},_createPanel:function(t){return e("
      ").attr("id",t).addClass("ui-tabs-panel ui-widget-content ui-corner-bottom").data("ui-tabs-destroy",!0)},_setupDisabled:function(t){e.isArray(t)&&(t.length?t.length===this.anchors.length&&(t=!0):t=!1);for(var n=0,r;r=this.tabs[n];n++)t===!0||e.inArray(n,t)!==-1?e(r).addClass("ui-state-disabled").attr("aria-disabled","true"):e(r).removeClass("ui-state-disabled").removeAttr("aria-disabled");this.options.disabled=t},_setupEvents:function(t){var n={click:function(e){e.preventDefault()}};t&&e.each(t.split(" "),function(e,t){n[t]="_eventHandler"}),this._off(this.anchors.add(this.tabs).add(this.panels)),this._on(this.anchors,n),this._on(this.tabs,{keydown:"_tabKeydown"}),this._on(this.panels,{keydown:"_panelKeydown"}),this._focusable(this.tabs),this._hoverable(this.tabs)},_setupHeightStyle:function(t){var n,r,i=this.element.parent();t==="fill"?(e.support.minHeight||(r=i.css("overflow"),i.css("overflow","hidden")),n=i.height(),this.element.siblings(":visible").each(function(){var t=e(this),r=t.css("position");if(r==="absolute"||r==="fixed")return;n-=t.outerHeight(!0)}),r&&i.css("overflow",r),this.element.children().not(this.panels).each(function(){n-=e(this).outerHeight(!0)}),this.panels.each(function(){e(this).height(Math.max(0,n-e(this).innerHeight()+e(this).height()))}).css("overflow","auto")):t==="auto"&&(n=0,this.panels.each(function(){n=Math.max(n,e(this).height("").height())}).height(n))},_eventHandler:function(t){var n=this.options,r=this.active,i=e(t.currentTarget),s=i.closest("li"),o=s[0]===r[0],u=o&&n.collapsible,a=u?e():this._getPanelForTab(s),f=r.length?this._getPanelForTab(r):e(),l={oldTab:r,oldPanel:f,newTab:u?e():s,newPanel:a};t.preventDefault();if(s.hasClass("ui-state-disabled")||s.hasClass("ui-tabs-loading")||this.running||o&&!n.collapsible||this._trigger("beforeActivate",t,l)===!1)return;n.active=u?!1:this.tabs.index(s),this.active=o?e():s,this.xhr&&this.xhr.abort(),!f.length&&!a.length&&e.error("jQuery UI Tabs: Mismatching fragment identifier."),a.length&&this.load(this.tabs.index(s),t),this._toggle(t,l)},_toggle:function(t,n){function o(){r.running=!1,r._trigger("activate",t,n)}function u(){n.newTab.closest("li").addClass("ui-tabs-active ui-state-active"),i.length&&r.options.show?r._show(i,r.options.show,o):(i.show(),o())}var r=this,i=n.newPanel,s=n.oldPanel;this.running=!0,s.length&&this.options.hide?this._hide(s,this.options.hide,function(){n.oldTab.closest("li").removeClass("ui-tabs-active ui-state-active"),u()}):(n.oldTab.closest("li").removeClass("ui-tabs-active ui-state-active"),s.hide(),u()),s.attr({"aria-expanded":"false","aria-hidden":"true"}),n.oldTab.attr("aria-selected","false"),i.length&&s.length?n.oldTab.attr("tabIndex",-1):i.length&&this.tabs.filter(function(){return e(this).attr("tabIndex")===0}).attr("tabIndex",-1),i.attr({"aria-expanded":"true","aria-hidden":"false"}),n.newTab.attr({"aria-selected":"true",tabIndex:0})},_activate:function(t){var n,r=this._findActive(t);if(r[0]===this.active[0])return;r.length||(r=this.active),n=r.find(".ui-tabs-anchor")[0],this._eventHandler({target:n,currentTarget:n,preventDefault:e.noop})},_findActive:function(t){return t===!1?e():this.tabs.eq(t)},_getIndex:function(e){return typeof e=="string"&&(e=this.anchors.index(this.anchors.filter("[href$='"+e+"']"))),e},_destroy:function(){this.xhr&&this.xhr.abort(),this.element.removeClass("ui-tabs ui-widget ui-widget-content ui-corner-all ui-tabs-collapsible"),this.tablist.removeClass("ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all").removeAttr("role"),this.anchors.removeClass("ui-tabs-anchor").removeAttr("role").removeAttr("tabIndex").removeData("href.tabs").removeData("load.tabs").removeUniqueId(),this.tabs.add(this.panels).each(function(){e.data(this,"ui-tabs-destroy")?e(this).remove():e(this).removeClass("ui-state-default ui-state-active ui-state-disabled ui-corner-top ui-corner-bottom ui-widget-content ui-tabs-active ui-tabs-panel").removeAttr("tabIndex").removeAttr("aria-live").removeAttr("aria-busy").removeAttr("aria-selected").removeAttr("aria-labelledby").removeAttr("aria-hidden").removeAttr("aria-expanded").removeAttr("role")}),this.tabs.each(function(){var t=e(this),n=t.data("ui-tabs-aria-controls");n?t.attr("aria-controls",n):t.removeAttr("aria-controls")}),this.options.heightStyle!=="content"&&this.panels.css("height","")},enable:function(n){var r=this.options.disabled;if(r===!1)return;n===t?r=!1:(n=this._getIndex(n),e.isArray(r)?r=e.map(r,function(e){return e!==n?e:null}):r=e.map(this.tabs,function(e,t){return t!==n?t:null})),this._setupDisabled(r)},disable:function(n){var r=this.options.disabled;if(r===!0)return;if(n===t)r=!0;else{n=this._getIndex(n);if(e.inArray(n,r)!==-1)return;e.isArray(r)?r=e.merge([n],r).sort():r=[n]}this._setupDisabled(r)},load:function(t,n){t=this._getIndex(t);var r=this,i=this.tabs.eq(t),o=i.find(".ui-tabs-anchor"),u=this._getPanelForTab(i),a={tab:i,panel:u};if(s(o[0]))return;this.xhr=e.ajax(this._ajaxSettings(o,n,a)),this.xhr&&this.xhr.statusText!=="canceled"&&(i.addClass("ui-tabs-loading"),u.attr("aria-busy","true"),this.xhr.success(function(e){setTimeout(function(){u.html(e),r._trigger("load",n,a)},1)}).complete(function(e,t){setTimeout(function(){t==="abort"&&r.panels.stop(!1,!0),i.removeClass("ui-tabs-loading"),u.removeAttr("aria-busy"),e===r.xhr&&delete r.xhr},1)}))},_ajaxSettings:function(t,n,r){var i=this;return{url:t.attr("href"),beforeSend:function(t,s){return i._trigger("beforeLoad",n,e.extend({jqXHR:t,ajaxSettings:s},r))}}},_getPanelForTab:function(t){var n=e(t).attr("aria-controls");return this.element.find(this._sanitizeSelector("#"+n))}}),e.uiBackCompat!==!1&&(e.ui.tabs.prototype._ui=function(e,t){return{tab:e,panel:t,index:this.anchors.index(e)}},e.widget("ui.tabs",e.ui.tabs,{url:function(e,t){this.anchors.eq(e).attr("href",t)}}),e.widget("ui.tabs",e.ui.tabs,{options:{ajaxOptions:null,cache:!1},_create:function(){this._super();var t=this;this._on({tabsbeforeload:function(n,r){if(e.data(r.tab[0],"cache.tabs")){n.preventDefault();return}r.jqXHR.success(function(){t.options.cache&&e.data(r.tab[0],"cache.tabs",!0)})}})},_ajaxSettings:function(t,n,r){var i=this.options.ajaxOptions;return e.extend({},i,{error:function(e,t,n){try{i.error(e,t,r.tab.closest("li").index(),r.tab[0])}catch(n){}}},this._superApply(arguments))},_setOption:function(e,t){e==="cache"&&t===!1&&this.anchors.removeData("cache.tabs"),this._super(e,t)},_destroy:function(){this.anchors.removeData("cache.tabs"),this._super()},url:function(e,t){this.anchors.eq(e).removeData("cache.tabs"),this._superApply(arguments)}}),e.widget("ui.tabs",e.ui.tabs,{abort:function(){this.xhr&&this.xhr.abort()}}),e.widget("ui.tabs",e.ui.tabs,{options:{spinner:"Loading…"},_create:function(){this._super(),this._on({tabsbeforeload:function(e,t){if(e.target!==this.element[0]||!this.options.spinner)return;var n=t.tab.find("span"),r=n.html();n.html(this.options.spinner),t.jqXHR.complete(function(){n.html(r)})}})}}),e.widget("ui.tabs",e.ui.tabs,{options:{enable:null,disable:null},enable:function(t){var n=this.options,r;if(t&&n.disabled===!0||e.isArray(n.disabled)&&e.inArray(t,n.disabled)!==-1)r=!0;this._superApply(arguments),r&&this._trigger("enable",null,this._ui(this.anchors[t],this.panels[t]))},disable:function(t){var n=this.options,r;if(t&&n.disabled===!1||e.isArray(n.disabled)&&e.inArray(t,n.disabled)===-1)r=!0;this._superApply(arguments),r&&this._trigger("disable",null,this._ui(this.anchors[t],this.panels[t]))}}),e.widget("ui.tabs",e.ui.tabs,{options:{add:null,remove:null,tabTemplate:"
    3. #{label}
    4. "},add:function(n,r,i){i===t&&(i=this.anchors.length);var s,o,u=this.options,a=e(u.tabTemplate.replace(/#\{href\}/g,n).replace(/#\{label\}/g,r)),f=n.indexOf("#")?this._tabId(a):n.replace("#","");return a.addClass("ui-state-default ui-corner-top").data("ui-tabs-destroy",!0),a.attr("aria-controls",f),s=i>=this.tabs.length,o=this.element.find("#"+f),o.length||(o=this._createPanel(f),s?i>0?o.insertAfter(this.panels.eq(-1)):o.appendTo(this.element):o.insertBefore(this.panels[i])),o.addClass("ui-tabs-panel ui-widget-content ui-corner-bottom").hide(),s?a.appendTo(this.tablist):a.insertBefore(this.tabs[i]),u.disabled=e.map(u.disabled,function(e){return e>=i?++e:e}),this.refresh(),this.tabs.length===1&&u.active===!1&&this.option("active",0),this._trigger("add",null,this._ui(this.anchors[i],this.panels[i])),this},remove:function(t){t=this._getIndex(t);var n=this.options,r=this.tabs.eq(t).remove(),i=this._getPanelForTab(r).remove();return r.hasClass("ui-tabs-active")&&this.anchors.length>2&&this._activate(t+(t+1=t?--e:e}),this.refresh(),this._trigger("remove",null,this._ui(r.find("a")[0],i[0])),this}}),e.widget("ui.tabs",e.ui.tabs,{length:function(){return this.anchors.length}}),e.widget("ui.tabs",e.ui.tabs,{options:{idPrefix:"ui-tabs-"},_tabId:function(t){var n=t.is("li")?t.find("a[href]"):t;return n=n[0],e(n).closest("li").attr("aria-controls")||n.title&&n.title.replace(/\s/g,"_").replace(/[^\w\u00c0-\uFFFF\-]/g,"")||this.options.idPrefix+i()}}),e.widget("ui.tabs",e.ui.tabs,{options:{panelTemplate:"
      "},_createPanel:function(t){return e(this.options.panelTemplate).attr("id",t).addClass("ui-tabs-panel ui-widget-content ui-corner-bottom").data("ui-tabs-destroy",!0)}}),e.widget("ui.tabs",e.ui.tabs,{_create:function(){var e=this.options;e.active===null&&e.selected!==t&&(e.active=e.selected===-1?!1:e.selected),this._super(),e.selected=e.active,e.selected===!1&&(e.selected=-1)},_setOption:function(e,t){if(e!=="selected")return this._super(e,t);var n=this.options;this._super("active",t===-1?!1:t),n.selected=n.active,n.selected===!1&&(n.selected=-1)},_eventHandler:function(e){this._superApply(arguments),this.options.selected=this.options.active,this.options.selected===!1&&(this.options.selected=-1)}}),e.widget("ui.tabs",e.ui.tabs,{options:{show:null,select:null},_create:function(){this._super(),this.options.active!==!1&&this._trigger("show",null,this._ui(this.active.find(".ui-tabs-anchor")[0],this._getPanelForTab(this.active)[0]))},_trigger:function(e,t,n){var r=this._superApply(arguments);return r?(e==="beforeActivate"&&n.newTab.length?r=this._super("select",t,{tab:n.newTab.find(".ui-tabs-anchor")[0],panel:n.newPanel[0],index:n.newTab.closest("li").index()}):e==="activate"&&n.newTab.length&&(r=this._super("show",t,{tab:n.newTab.find(".ui-tabs-anchor")[0],panel:n.newPanel[0],index:n.newTab.closest("li").index()})),r):!1}}),e.widget("ui.tabs",e.ui.tabs,{select:function(e){e=this._getIndex(e);if(e===-1){if(!this.options.collapsible||this.options.selected===-1)return;e=this.options.selected}this.anchors.eq(e).trigger(this.options.event+this.eventNamespace)}}),function(){var t=0;e.widget("ui.tabs",e.ui.tabs,{options:{cookie:null},_create:function(){var e=this.options,t;e.active==null&&e.cookie&&(t=parseInt(this._cookie(),10),t===-1&&(t=!1),e.active=t),this._super()},_cookie:function(n){var r=[this.cookie||(this.cookie=this.options.cookie.name||"ui-tabs-"+ ++t)];return arguments.length&&(r.push(n===!1?-1:n),r.push(this.options.cookie)),e.cookie.apply(null,r)},_refresh:function(){this._super(),this.options.cookie&&this._cookie(this.options.active,this.options.cookie)},_eventHandler:function(e){this._superApply(arguments),this.options.cookie&&this._cookie(this.options.active,this.options.cookie)},_destroy:function(){this._super(),this.options.cookie&&this._cookie(null,this.options.cookie)}})}(),e.widget("ui.tabs",e.ui.tabs,{_trigger:function(t,n,r){var i=e.extend({},r);return t==="load"&&(i.panel=i.panel[0],i.tab=i.tab.find(".ui-tabs-anchor")[0]),this._super(t,n,i)}}),e.widget("ui.tabs",e.ui.tabs,{options:{fx:null},_getFx:function(){var t,n,r=this.options.fx;return r&&(e.isArray(r)?(t=r[0],n=r[1]):t=n=r),r?{show:n,hide:t}:null},_toggle:function(e,t){function o(){n.running=!1,n._trigger("activate",e,t)}function u(){t.newTab.closest("li").addClass("ui-tabs-active ui-state-active"),r.length&&s.show?r.animate(s.show,s.show.duration,function(){o()}):(r.show(),o())}var n=this,r=t.newPanel,i=t.oldPanel,s=this._getFx();if(!s)return this._super(e,t);n.running=!0,i.length&&s.hide?i.animate(s.hide,s.hide.duration,function(){t.oldTab.closest("li").removeClass("ui-tabs-active ui-state-active"),u()}):(t.oldTab.closest("li").removeClass("ui-tabs-active ui-state-active"),i.hide(),u())}}))})(jQuery); \ No newline at end of file diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/ui/minified/jquery.ui.tooltip.min.js b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/ui/minified/jquery.ui.tooltip.min.js new file mode 100755 index 000000000..c5c55d8b6 --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/ui/minified/jquery.ui.tooltip.min.js @@ -0,0 +1,5 @@ +/*! jQuery UI - v1.9.0 - 2012-10-08 +* http://jqueryui.com +* Includes: jquery.ui.tooltip.js +* Copyright 2012 jQuery Foundation and other contributors; Licensed MIT */ +(function(e){function n(t,n){var r=(t.attr("aria-describedby")||"").split(/\s+/);r.push(n),t.data("ui-tooltip-id",n).attr("aria-describedby",e.trim(r.join(" ")))}function r(t){var n=t.data("ui-tooltip-id"),r=(t.attr("aria-describedby")||"").split(/\s+/),i=e.inArray(n,r);i!==-1&&r.splice(i,1),t.removeData("ui-tooltip-id"),r=e.trim(r.join(" ")),r?t.attr("aria-describedby",r):t.removeAttr("aria-describedby")}var t=0;e.widget("ui.tooltip",{version:"1.9.0",options:{content:function(){return e(this).attr("title")},hide:!0,items:"[title]",position:{my:"left+15 center",at:"right center",collision:"flipfit flipfit"},show:!0,tooltipClass:null,track:!1,close:null,open:null},_create:function(){this._on({mouseover:"open",focusin:"open"}),this.tooltips={}},_setOption:function(t,n){var r=this;if(t==="disabled"){this[n?"_disable":"_enable"](),this.options[t]=n;return}this._super(t,n),t==="content"&&e.each(this.tooltips,function(e,t){r._updateContent(t)})},_disable:function(){var t=this;e.each(this.tooltips,function(n,r){var i=e.Event("blur");i.target=i.currentTarget=r[0],t.close(i,!0)}),this.element.find(this.options.items).andSelf().each(function(){var t=e(this);t.is("[title]")&&t.data("ui-tooltip-title",t.attr("title")).attr("title","")})},_enable:function(){this.element.find(this.options.items).andSelf().each(function(){var t=e(this);t.data("ui-tooltip-title")&&t.attr("title",t.data("ui-tooltip-title"))})},open:function(t){var n=e(t?t.target:this.element).closest(this.options.items);if(!n.length)return;if(this.options.track&&n.data("ui-tooltip-id")){this._find(n).position(e.extend({of:n},this.options.position)),this._off(this.document,"mousemove");return}n.attr("title")&&n.data("ui-tooltip-title",n.attr("title")),n.data("tooltip-open",!0),this._updateContent(n,t)},_updateContent:function(e,t){var n,r=this.options.content,i=this;if(typeof r=="string")return this._open(t,e,r);n=r.call(e[0],function(n){if(!e.data("tooltip-open"))return;i._delay(function(){this._open(t,e,n)})}),n&&this._open(t,e,n)},_open:function(t,r,i){function u(e){o.of=e,s.position(o)}var s,o;if(!i)return;s=this._find(r);if(s.length){s.find(".ui-tooltip-content").html(i);return}r.is("[title]")&&(t&&t.type==="mouseover"?r.attr("title",""):r.removeAttr("title")),s=this._tooltip(r),n(r,s.attr("id")),s.find(".ui-tooltip-content").html(i),this.options.track&&t&&/^mouse/.test(t.originalEvent.type)?(o=e.extend({},this.options.position),this._on(this.document,{mousemove:u}),u(t)):s.position(e.extend({of:r},this.options.position)),s.hide(),this._show(s,this.options.show),this._trigger("open",t,{tooltip:s}),this._on(r,{mouseleave:"close",focusout:"close",keyup:function(t){if(t.keyCode===e.ui.keyCode.ESCAPE){var n=e.Event(t);n.currentTarget=r[0],this.close(n,!0)}}})},close:function(t,n){var i=this,s=e(t?t.currentTarget:this.element),o=this._find(s);if(this.closing)return;if(!n&&t&&t.type!=="focusout"&&this.document[0].activeElement===s[0])return;s.data("ui-tooltip-title")&&s.attr("title",s.data("ui-tooltip-title")),r(s),o.stop(!0),this._hide(o,this.options.hide,function(){e(this).remove(),delete i.tooltips[this.id]}),s.removeData("tooltip-open"),this._off(s,"mouseleave focusout keyup"),this._off(this.document,"mousemove"),this.closing=!0,this._trigger("close",t,{tooltip:o}),this.closing=!1},_tooltip:function(n){var r="ui-tooltip-"+t++,i=e("
      ").attr({id:r,role:"tooltip"}).addClass("ui-tooltip ui-widget ui-corner-all ui-widget-content "+(this.options.tooltipClass||""));return e("
      ").addClass("ui-tooltip-content").appendTo(i),i.appendTo(this.document[0].body),e.fn.bgiframe&&i.bgiframe(),this.tooltips[r]=n,i},_find:function(t){var n=t.data("ui-tooltip-id");return n?e("#"+n):e()},_destroy:function(){var t=this;e.each(this.tooltips,function(n,r){var i=e.Event("blur");i.target=i.currentTarget=r[0],t.close(i,!0),e("#"+n).remove(),r.data("ui-tooltip-title")&&(r.attr("title",r.data("ui-tooltip-title")),r.removeData("ui-tooltip-title"))})}})})(jQuery); \ No newline at end of file diff --git a/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/ui/minified/jquery.ui.widget.min.js b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/ui/minified/jquery.ui.widget.min.js new file mode 100755 index 000000000..e0f10cdd5 --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/development-bundle/ui/minified/jquery.ui.widget.min.js @@ -0,0 +1,5 @@ +/*! jQuery UI - v1.9.0 - 2012-10-08 +* http://jqueryui.com +* Includes: jquery.ui.widget.js +* Copyright 2012 jQuery Foundation and other contributors; Licensed MIT */ +(function(e,t){var n=0,r=Array.prototype.slice,i=e.cleanData;e.cleanData=function(t){for(var n=0,r;(r=t[n])!=null;n++)try{e(r).triggerHandler("remove")}catch(s){}i(t)},e.widget=function(t,n,r){var i,s,o,u,a=t.split(".")[0];t=t.split(".")[1],i=a+"-"+t,r||(r=n,n=e.Widget),e.expr[":"][i.toLowerCase()]=function(t){return!!e.data(t,i)},e[a]=e[a]||{},s=e[a][t],o=e[a][t]=function(e,t){if(!this._createWidget)return new o(e,t);arguments.length&&this._createWidget(e,t)},e.extend(o,s,{version:r.version,_proto:e.extend({},r),_childConstructors:[]}),u=new n,u.options=e.widget.extend({},u.options),e.each(r,function(t,i){e.isFunction(i)&&(r[t]=function(){var e=function(){return n.prototype[t].apply(this,arguments)},r=function(e){return n.prototype[t].apply(this,e)};return function(){var t=this._super,n=this._superApply,s;return this._super=e,this._superApply=r,s=i.apply(this,arguments),this._super=t,this._superApply=n,s}}())}),o.prototype=e.widget.extend(u,{widgetEventPrefix:t},r,{constructor:o,namespace:a,widgetName:t,widgetBaseClass:i,widgetFullName:i}),s?(e.each(s._childConstructors,function(t,n){var r=n.prototype;e.widget(r.namespace+"."+r.widgetName,o,n._proto)}),delete s._childConstructors):n._childConstructors.push(o),e.widget.bridge(t,o)},e.widget.extend=function(n){var i=r.call(arguments,1),s=0,o=i.length,u,a;for(;s",options:{disabled:!1,create:null},_createWidget:function(t,r){r=e(r||this.defaultElement||this)[0],this.element=e(r),this.uuid=n++,this.eventNamespace="."+this.widgetName+this.uuid,this.options=e.widget.extend({},this.options,this._getCreateOptions(),t),this.bindings=e(),this.hoverable=e(),this.focusable=e(),r!==this&&(e.data(r,this.widgetName,this),e.data(r,this.widgetFullName,this),this._on({remove:"destroy"}),this.document=e(r.style?r.ownerDocument:r.document||r),this.window=e(this.document[0].defaultView||this.document[0].parentWindow)),this._create(),this._trigger("create",null,this._getCreateEventData()),this._init()},_getCreateOptions:e.noop,_getCreateEventData:e.noop,_create:e.noop,_init:e.noop,destroy:function(){this._destroy(),this.element.unbind(this.eventNamespace).removeData(this.widgetName).removeData(this.widgetFullName).removeData(e.camelCase(this.widgetFullName)),this.widget().unbind(this.eventNamespace).removeAttr("aria-disabled").removeClass(this.widgetFullName+"-disabled "+"ui-state-disabled"),this.bindings.unbind(this.eventNamespace),this.hoverable.removeClass("ui-state-hover"),this.focusable.removeClass("ui-state-focus")},_destroy:e.noop,widget:function(){return this.element},option:function(n,r){var i=n,s,o,u;if(arguments.length===0)return e.widget.extend({},this.options);if(typeof n=="string"){i={},s=n.split("."),n=s.shift();if(s.length){o=i[n]=e.widget.extend({},this.options[n]);for(u=0;u + + + + jQuery UI Example Page + + + + + + + + +

      Welcome to jQuery UI!

      + +
      +

      This page demonstrates the widgets you downloaded using the theme you selected in the download builder. We've included and linked to minified versions of jQuery, your personalized copy of jQuery UI (js/jquery-ui-1.9.0.custom.min.js), and css/ui-lightness/jquery-ui-1.9.0.custom.min.css which imports the entire jQuery UI CSS Framework. You can choose to link a subset of the CSS Framework depending on your needs.

      +

      You've downloaded components and a theme that are compatible with jQuery 1.6+. Please make sure you are using jQuery 1.6+ in your production environment.

      +
      + +

      YOUR COMPONENTS:

      + + + +

      Accordion

      +
      +

      First

      +
      Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet.
      +

      Second

      +
      Phasellus mattis tincidunt nibh.
      +

      Third

      +
      Nam dui erat, auctor a, dignissim quis.
      +
      + + + + +

      Autocomplete

      +
      + +
      + + + + +

      Button

      + +
      +
      + + + +
      +
      + + + + +

      Tabs

      +
      + +
      Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.
      +
      Phasellus mattis tincidunt nibh. Cras orci urna, blandit id, pretium vel, aliquet ornare, felis. Maecenas scelerisque sem non nisl. Fusce sed lorem in enim dictum bibendum.
      +
      Nam dui erat, auctor a, dignissim quis, sollicitudin eu, felis. Pellentesque nisi urna, interdum eget, sagittis et, consequat vestibulum, lacus. Mauris porttitor ullamcorper augue.
      +
      + + + + +

      Dialog

      +

      Open Dialog

      + +

      Overlay and Shadow Classes (not currently used in UI widgets)

      +
      +

      Lorem ipsum dolor sit amet, Nulla nec tortor. Donec id elit quis purus consectetur consequat.

      Nam congue semper tellus. Sed erat dolor, dapibus sit amet, venenatis ornare, ultrices ut, nisi. Aliquam ante. Suspendisse scelerisque dui nec velit. Duis augue augue, gravida euismod, vulputate ac, facilisis id, sem. Morbi in orci.

      Nulla purus lacus, pulvinar vel, malesuada ac, mattis nec, quam. Nam molestie scelerisque quam. Nullam feugiat cursus lacus.orem ipsum dolor sit amet, consectetur adipiscing elit. Donec libero risus, commodo vitae, pharetra mollis, posuere eu, pede. Nulla nec tortor. Donec id elit quis purus consectetur consequat.

      Nam congue semper tellus. Sed erat dolor, dapibus sit amet, venenatis ornare, ultrices ut, nisi. Aliquam ante. Suspendisse scelerisque dui nec velit. Duis augue augue, gravida euismod, vulputate ac, facilisis id, sem. Morbi in orci. Nulla purus lacus, pulvinar vel, malesuada ac, mattis nec, quam. Nam molestie scelerisque quam.

      Nullam feugiat cursus lacus.orem ipsum dolor sit amet, consectetur adipiscing elit. Donec libero risus, commodo vitae, pharetra mollis, posuere eu, pede. Nulla nec tortor. Donec id elit quis purus consectetur consequat. Nam congue semper tellus. Sed erat dolor, dapibus sit amet, venenatis ornare, ultrices ut, nisi. Aliquam ante.

      Suspendisse scelerisque dui nec velit. Duis augue augue, gravida euismod, vulputate ac, facilisis id, sem. Morbi in orci. Nulla purus lacus, pulvinar vel, malesuada ac, mattis nec, quam. Nam molestie scelerisque quam. Nullam feugiat cursus lacus.orem ipsum dolor sit amet, consectetur adipiscing elit. Donec libero risus, commodo vitae, pharetra mollis, posuere eu, pede. Nulla nec tortor. Donec id elit quis purus consectetur consequat. Nam congue semper tellus. Sed erat dolor, dapibus sit amet, venenatis ornare, ultrices ut, nisi.

      + + +
      +
      +
      +

      Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.

      +
      +
      + +
      + + +
      +

      Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.

      +
      + + + +

      Framework Icons (content color preview)

      +
        +
      • +
      • +
      • +
      • +
      • +
      • +
      • +
      • +
      • +
      • +
      • +
      • +
      • +
      • +
      • +
      • +
      • +
      • +
      • +
      • +
      • +
      • +
      • +
      • +
      • +
      • +
      • +
      • +
      • +
      • +
      • +
      • +
      • +
      • +
      • +
      • +
      • +
      • +
      • +
      • +
      • +
      • +
      • +
      • +
      • +
      • +
      • +
      • +
      • +
      • +
      • +
      • +
      • +
      • +
      • +
      • +
      • +
      • +
      • +
      • +
      • +
      • +
      • +
      • +
      • +
      • +
      • +
      • +
      • +
      • +
      • +
      • +
      • +
      • +
      • +
      • +
      • +
      • +
      • +
      • +
      • +
      • +
      • +
      • +
      • +
      • +
      • +
      • +
      • +
      • +
      • +
      • +
      • +
      • +
      • +
      • +
      • +
      • +
      • +
      • +
      • +
      • +
      • +
      • +
      • +
      • +
      • +
      • +
      • +
      • +
      • +
      • +
      • +
      • +
      • +
      • +
      • +
      • +
      • +
      • +
      • +
      • +
      • +
      • +
      • +
      • +
      • +
      • +
      • +
      • +
      • +
      • +
      • +
      • +
      • +
      • +
      • +
      • +
      • +
      • +
      • +
      • +
      • +
      • +
      • +
      • +
      • +
      • +
      • +
      • +
      • +
      • +
      • +
      • +
      • +
      • +
      • +
      • +
      • +
      • +
      • +
      • +
      • +
      • +
      • +
      • +
      • +
      • +
      • +
      • +
      • +
      • +
      • +
      + + + +

      Slider

      +
      + + + + +

      Datepicker

      +
      + + + + +

      Progressbar

      +
      + + + +

      Highlight / Error

      +
      +
      +

      + Hey! Sample ui-state-highlight style.

      +
      +
      +
      +
      +
      +

      + Alert: Sample ui-state-error style.

      +
      +
      + + + diff --git a/htdocs/js/jquery-ui-1.9.0.custom/js/jquery-1.8.2.js b/htdocs/js/jquery-ui-1.9.0.custom/js/jquery-1.8.2.js new file mode 100755 index 000000000..d4f3bb38c --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/js/jquery-1.8.2.js @@ -0,0 +1,9440 @@ +/*! + * jQuery JavaScript Library v1.8.2 + * http://jquery.com/ + * + * Includes Sizzle.js + * http://sizzlejs.com/ + * + * Copyright 2012 jQuery Foundation and other contributors + * Released under the MIT license + * http://jquery.org/license + * + * Date: Thu Sep 20 2012 21:13:05 GMT-0400 (Eastern Daylight Time) + */ +(function( window, undefined ) { +var + // A central reference to the root jQuery(document) + rootjQuery, + + // The deferred used on DOM ready + readyList, + + // Use the correct document accordingly with window argument (sandbox) + document = window.document, + location = window.location, + navigator = window.navigator, + + // Map over jQuery in case of overwrite + _jQuery = window.jQuery, + + // Map over the $ in case of overwrite + _$ = window.$, + + // Save a reference to some core methods + core_push = Array.prototype.push, + core_slice = Array.prototype.slice, + core_indexOf = Array.prototype.indexOf, + core_toString = Object.prototype.toString, + core_hasOwn = Object.prototype.hasOwnProperty, + core_trim = String.prototype.trim, + + // Define a local copy of jQuery + jQuery = function( selector, context ) { + // The jQuery object is actually just the init constructor 'enhanced' + return new jQuery.fn.init( selector, context, rootjQuery ); + }, + + // Used for matching numbers + core_pnum = /[\-+]?(?:\d*\.|)\d+(?:[eE][\-+]?\d+|)/.source, + + // Used for detecting and trimming whitespace + core_rnotwhite = /\S/, + core_rspace = /\s+/, + + // Make sure we trim BOM and NBSP (here's looking at you, Safari 5.0 and IE) + rtrim = /^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g, + + // A simple way to check for HTML strings + // Prioritize #id over to avoid XSS via location.hash (#9521) + rquickExpr = /^(?:[^#<]*(<[\w\W]+>)[^>]*$|#([\w\-]*)$)/, + + // Match a standalone tag + rsingleTag = /^<(\w+)\s*\/?>(?:<\/\1>|)$/, + + // JSON RegExp + rvalidchars = /^[\],:{}\s]*$/, + rvalidbraces = /(?:^|:|,)(?:\s*\[)+/g, + rvalidescape = /\\(?:["\\\/bfnrt]|u[\da-fA-F]{4})/g, + rvalidtokens = /"[^"\\\r\n]*"|true|false|null|-?(?:\d\d*\.|)\d+(?:[eE][\-+]?\d+|)/g, + + // Matches dashed string for camelizing + rmsPrefix = /^-ms-/, + rdashAlpha = /-([\da-z])/gi, + + // Used by jQuery.camelCase as callback to replace() + fcamelCase = function( all, letter ) { + return ( letter + "" ).toUpperCase(); + }, + + // The ready event handler and self cleanup method + DOMContentLoaded = function() { + if ( document.addEventListener ) { + document.removeEventListener( "DOMContentLoaded", DOMContentLoaded, false ); + jQuery.ready(); + } else if ( document.readyState === "complete" ) { + // we're here because readyState === "complete" in oldIE + // which is good enough for us to call the dom ready! + document.detachEvent( "onreadystatechange", DOMContentLoaded ); + jQuery.ready(); + } + }, + + // [[Class]] -> type pairs + class2type = {}; + +jQuery.fn = jQuery.prototype = { + constructor: jQuery, + init: function( selector, context, rootjQuery ) { + var match, elem, ret, doc; + + // Handle $(""), $(null), $(undefined), $(false) + if ( !selector ) { + return this; + } + + // Handle $(DOMElement) + if ( selector.nodeType ) { + this.context = this[0] = selector; + this.length = 1; + return this; + } + + // Handle HTML strings + if ( typeof selector === "string" ) { + 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 = rquickExpr.exec( selector ); + } + + // Match html or make sure no context is specified for #id + if ( match && (match[1] || !context) ) { + + // HANDLE: $(html) -> $(array) + if ( match[1] ) { + context = context instanceof jQuery ? context[0] : context; + doc = ( context && context.nodeType ? context.ownerDocument || context : document ); + + // scripts is true for back-compat + selector = jQuery.parseHTML( match[1], doc, true ); + if ( rsingleTag.test( match[1] ) && jQuery.isPlainObject( context ) ) { + this.attr.call( selector, context, true ); + } + + 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.8.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 core_slice.call( this ); + }, + + // 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 = jQuery.merge( this.constructor(), 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 ) { + // Add the callback + jQuery.ready.promise().done( fn ); + + return this; + }, + + eq: function( i ) { + i = +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( core_slice.apply( this, arguments ), + "slice", core_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: core_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 ) { + + // Abort if there are pending holds or we're already ready + if ( wait === true ? --jQuery.readyWait : jQuery.isReady ) { + return; + } + + // 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").off("ready"); + } + }, + + // 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"; + }, + + isWindow: function( obj ) { + return obj != null && obj == obj.window; + }, + + isNumeric: function( obj ) { + return !isNaN( parseFloat(obj) ) && isFinite( obj ); + }, + + type: function( obj ) { + return obj == null ? + String( obj ) : + class2type[ core_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; + } + + try { + // Not own constructor property must be Object + if ( obj.constructor && + !core_hasOwn.call(obj, "constructor") && + !core_hasOwn.call(obj.constructor.prototype, "isPrototypeOf") ) { + return false; + } + } catch ( e ) { + // IE8,9 Will throw exceptions on certain host objects #9897 + 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 || core_hasOwn.call( obj, key ); + }, + + isEmptyObject: function( obj ) { + var name; + for ( name in obj ) { + return false; + } + return true; + }, + + error: function( msg ) { + throw new Error( msg ); + }, + + // data: string of html + // context (optional): If specified, the fragment will be created in this context, defaults to document + // scripts (optional): If true, will include scripts passed in the html string + parseHTML: function( data, context, scripts ) { + var parsed; + if ( !data || typeof data !== "string" ) { + return null; + } + if ( typeof context === "boolean" ) { + scripts = context; + context = 0; + } + context = context || document; + + // Single tag + if ( (parsed = rsingleTag.exec( data )) ) { + return [ context.createElement( parsed[1] ) ]; + } + + parsed = jQuery.buildFragment( [ data ], context, scripts ? null : [] ); + return jQuery.merge( [], + (parsed.cacheable ? jQuery.clone( parsed.fragment ) : parsed.fragment).childNodes ); + }, + + parseJSON: function( data ) { + if ( !data || typeof data !== "string") { + 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 + parseXML: function( data ) { + var xml, tmp; + if ( !data || typeof data !== "string" ) { + return null; + } + try { + 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 ); + } + } catch( e ) { + xml = undefined; + } + if ( !xml || !xml.documentElement || xml.getElementsByTagName( "parsererror" ).length ) { + 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 && core_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 ); + } + }, + + // Convert dashed to camelCase; used by the css and data modules + // Microsoft forgot to hump their vendor prefix (#9572) + camelCase: function( string ) { + return string.replace( rmsPrefix, "ms-" ).replace( rdashAlpha, fcamelCase ); + }, + + nodeName: function( elem, name ) { + return elem.nodeName && elem.nodeName.toLowerCase() === name.toLowerCase(); + }, + + // args is for internal usage only + each: function( obj, callback, args ) { + var name, + i = 0, + length = obj.length, + isObj = length === undefined || jQuery.isFunction( obj ); + + if ( args ) { + if ( isObj ) { + for ( name in obj ) { + if ( callback.apply( obj[ name ], args ) === false ) { + break; + } + } + } else { + for ( ; i < length; ) { + if ( callback.apply( obj[ i++ ], args ) === false ) { + break; + } + } + } + + // A special, fast, case for the most common use of each + } else { + if ( isObj ) { + for ( name in obj ) { + if ( callback.call( obj[ name ], name, obj[ name ] ) === false ) { + break; + } + } + } else { + for ( ; i < length; ) { + if ( callback.call( obj[ i ], i, obj[ i++ ] ) === false ) { + break; + } + } + } + } + + return obj; + }, + + // Use native String.trim function wherever possible + trim: core_trim && !core_trim.call("\uFEFF\xA0") ? + function( text ) { + return text == null ? + "" : + core_trim.call( text ); + } : + + // Otherwise use our own trimming functionality + function( text ) { + return text == null ? + "" : + ( text + "" ).replace( rtrim, "" ); + }, + + // results is for internal usage only + makeArray: function( arr, results ) { + var type, + ret = results || []; + + if ( arr != null ) { + // The window, strings (and functions) also have 'length' + // Tweaked logic slightly to handle Blackberry 4.7 RegExp issues #6930 + type = jQuery.type( arr ); + + if ( arr.length == null || type === "string" || type === "function" || type === "regexp" || jQuery.isWindow( arr ) ) { + core_push.call( ret, arr ); + } else { + jQuery.merge( ret, arr ); + } + } + + return ret; + }, + + inArray: function( elem, arr, i ) { + var len; + + if ( arr ) { + if ( core_indexOf ) { + return core_indexOf.call( arr, elem, i ); + } + + len = arr.length; + i = i ? i < 0 ? Math.max( 0, len + i ) : i : 0; + + for ( ; i < len; i++ ) { + // Skip accessing in sparse arrays + if ( i in arr && arr[ i ] === elem ) { + return i; + } + } + } + + return -1; + }, + + merge: function( first, second ) { + var l = second.length, + i = first.length, + j = 0; + + if ( typeof l === "number" ) { + for ( ; 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 retVal, + ret = [], + i = 0, + length = elems.length; + inv = !!inv; + + // Go through the array, only saving the items + // that pass the validator function + for ( ; 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 ) { + var tmp, args, proxy; + + if ( typeof context === "string" ) { + 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 + args = core_slice.call( arguments, 2 ); + proxy = function() { + return fn.apply( context, args.concat( core_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 || jQuery.guid++; + + return proxy; + }, + + // Multifunctional method to get and set values of a collection + // The value/s can optionally be executed if it's a function + access: function( elems, fn, key, value, chainable, emptyGet, pass ) { + var exec, + bulk = key == null, + i = 0, + length = elems.length; + + // Sets many values + if ( key && typeof key === "object" ) { + for ( i in key ) { + jQuery.access( elems, fn, i, key[i], 1, emptyGet, value ); + } + chainable = 1; + + // Sets one value + } else if ( value !== undefined ) { + // Optionally, function values get executed if exec is true + exec = pass === undefined && jQuery.isFunction( value ); + + if ( bulk ) { + // Bulk operations only iterate when executing function values + if ( exec ) { + exec = fn; + fn = function( elem, key, value ) { + return exec.call( jQuery( elem ), value ); + }; + + // Otherwise they run against the entire set + } else { + fn.call( elems, value ); + fn = null; + } + } + + if ( fn ) { + for (; i < length; i++ ) { + fn( elems[i], key, exec ? value.call( elems[i], i, fn( elems[i], key ) ) : value, pass ); + } + } + + chainable = 1; + } + + return chainable ? + elems : + + // Gets + bulk ? + fn.call( elems ) : + length ? fn( elems[0], key ) : emptyGet; + }, + + now: function() { + return ( new Date() ).getTime(); + } +}); + +jQuery.ready.promise = function( obj ) { + if ( !readyList ) { + + readyList = jQuery.Deferred(); + + // Catch cases where $(document).ready() is called after the browser event has already occurred. + // we once tried to use readyState "interactive" here, but it caused issues like the one + // discovered by ChrisS here: http://bugs.jquery.com/ticket/12282#comment:15 + if ( document.readyState === "complete" ) { + // Handle it asynchronously to allow scripts the opportunity to delay ready + setTimeout( jQuery.ready, 1 ); + + // Standards-based browsers support DOMContentLoaded + } else 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 { + // 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 top = false; + + try { + top = window.frameElement == null && document.documentElement; + } catch(e) {} + + if ( top && top.doScroll ) { + (function doScrollCheck() { + if ( !jQuery.isReady ) { + + try { + // Use the trick by Diego Perini + // http://javascript.nwbox.com/IEContentLoaded/ + top.doScroll("left"); + } catch(e) { + return setTimeout( doScrollCheck, 50 ); + } + + // and execute any waiting functions + jQuery.ready(); + } + })(); + } + } + } + return readyList.promise( obj ); +}; + +// Populate the class2type map +jQuery.each("Boolean Number String Function Array Date RegExp Object".split(" "), function(i, name) { + class2type[ "[object " + name + "]" ] = name.toLowerCase(); +}); + +// All jQuery objects should point back to these +rootjQuery = jQuery(document); +// String to Object options format cache +var optionsCache = {}; + +// Convert String-formatted options into Object-formatted ones and store in cache +function createOptions( options ) { + var object = optionsCache[ options ] = {}; + jQuery.each( options.split( core_rspace ), function( _, flag ) { + object[ flag ] = true; + }); + return object; +} + +/* + * Create a callback list using the following parameters: + * + * options: an optional list of space-separated options that will change how + * the callback list behaves or a more traditional option object + * + * By default a callback list will act like an event callback list and can be + * "fired" multiple times. + * + * Possible options: + * + * once: will ensure the callback list can only be fired once (like a Deferred) + * + * memory: will keep track of previous values and will call any callback added + * after the list has been fired right away with the latest "memorized" + * values (like a Deferred) + * + * unique: will ensure a callback can only be added once (no duplicate in the list) + * + * stopOnFalse: interrupt callings when a callback returns false + * + */ +jQuery.Callbacks = function( options ) { + + // Convert options from String-formatted to Object-formatted if needed + // (we check in cache first) + options = typeof options === "string" ? + ( optionsCache[ options ] || createOptions( options ) ) : + jQuery.extend( {}, options ); + + var // Last fire value (for non-forgettable lists) + memory, + // Flag to know if list was already fired + fired, + // Flag to know if list is currently firing + firing, + // First callback to fire (used internally by add and fireWith) + firingStart, + // End of the loop when firing + firingLength, + // Index of currently firing callback (modified by remove if needed) + firingIndex, + // Actual callback list + list = [], + // Stack of fire calls for repeatable lists + stack = !options.once && [], + // Fire callbacks + fire = function( data ) { + memory = options.memory && data; + fired = true; + firingIndex = firingStart || 0; + firingStart = 0; + firingLength = list.length; + firing = true; + for ( ; list && firingIndex < firingLength; firingIndex++ ) { + if ( list[ firingIndex ].apply( data[ 0 ], data[ 1 ] ) === false && options.stopOnFalse ) { + memory = false; // To prevent further calls using add + break; + } + } + firing = false; + if ( list ) { + if ( stack ) { + if ( stack.length ) { + fire( stack.shift() ); + } + } else if ( memory ) { + list = []; + } else { + self.disable(); + } + } + }, + // Actual Callbacks object + self = { + // Add a callback or a collection of callbacks to the list + add: function() { + if ( list ) { + // First, we save the current length + var start = list.length; + (function add( args ) { + jQuery.each( args, function( _, arg ) { + var type = jQuery.type( arg ); + if ( type === "function" && ( !options.unique || !self.has( arg ) ) ) { + list.push( arg ); + } else if ( arg && arg.length && type !== "string" ) { + // Inspect recursively + add( arg ); + } + }); + })( arguments ); + // Do we need to add the callbacks to the + // current firing batch? + if ( firing ) { + firingLength = list.length; + // With memory, if we're not firing then + // we should call right away + } else if ( memory ) { + firingStart = start; + fire( memory ); + } + } + return this; + }, + // Remove a callback from the list + remove: function() { + if ( list ) { + jQuery.each( arguments, function( _, arg ) { + var index; + while( ( index = jQuery.inArray( arg, list, index ) ) > -1 ) { + list.splice( index, 1 ); + // Handle firing indexes + if ( firing ) { + if ( index <= firingLength ) { + firingLength--; + } + if ( index <= firingIndex ) { + firingIndex--; + } + } + } + }); + } + return this; + }, + // Control if a given callback is in the list + has: function( fn ) { + return jQuery.inArray( fn, list ) > -1; + }, + // Remove all callbacks from the list + empty: function() { + list = []; + return this; + }, + // Have the list do nothing anymore + disable: function() { + list = stack = memory = undefined; + return this; + }, + // Is it disabled? + disabled: function() { + return !list; + }, + // Lock the list in its current state + lock: function() { + stack = undefined; + if ( !memory ) { + self.disable(); + } + return this; + }, + // Is it locked? + locked: function() { + return !stack; + }, + // Call all callbacks with the given context and arguments + fireWith: function( context, args ) { + args = args || []; + args = [ context, args.slice ? args.slice() : args ]; + if ( list && ( !fired || stack ) ) { + if ( firing ) { + stack.push( args ); + } else { + fire( args ); + } + } + return this; + }, + // Call all the callbacks with the given arguments + fire: function() { + self.fireWith( this, arguments ); + return this; + }, + // To know if the callbacks have already been called at least once + fired: function() { + return !!fired; + } + }; + + return self; +}; +jQuery.extend({ + + Deferred: function( func ) { + var tuples = [ + // action, add listener, listener list, final state + [ "resolve", "done", jQuery.Callbacks("once memory"), "resolved" ], + [ "reject", "fail", jQuery.Callbacks("once memory"), "rejected" ], + [ "notify", "progress", jQuery.Callbacks("memory") ] + ], + state = "pending", + promise = { + state: function() { + return state; + }, + always: function() { + deferred.done( arguments ).fail( arguments ); + return this; + }, + then: function( /* fnDone, fnFail, fnProgress */ ) { + var fns = arguments; + return jQuery.Deferred(function( newDefer ) { + jQuery.each( tuples, function( i, tuple ) { + var action = tuple[ 0 ], + fn = fns[ i ]; + // deferred[ done | fail | progress ] for forwarding actions to newDefer + deferred[ tuple[1] ]( jQuery.isFunction( fn ) ? + function() { + var returned = fn.apply( this, arguments ); + if ( returned && jQuery.isFunction( returned.promise ) ) { + returned.promise() + .done( newDefer.resolve ) + .fail( newDefer.reject ) + .progress( newDefer.notify ); + } else { + newDefer[ action + "With" ]( this === deferred ? newDefer : this, [ returned ] ); + } + } : + newDefer[ action ] + ); + }); + fns = null; + }).promise(); + }, + // Get a promise for this deferred + // If obj is provided, the promise aspect is added to the object + promise: function( obj ) { + return obj != null ? jQuery.extend( obj, promise ) : promise; + } + }, + deferred = {}; + + // Keep pipe for back-compat + promise.pipe = promise.then; + + // Add list-specific methods + jQuery.each( tuples, function( i, tuple ) { + var list = tuple[ 2 ], + stateString = tuple[ 3 ]; + + // promise[ done | fail | progress ] = list.add + promise[ tuple[1] ] = list.add; + + // Handle state + if ( stateString ) { + list.add(function() { + // state = [ resolved | rejected ] + state = stateString; + + // [ reject_list | resolve_list ].disable; progress_list.lock + }, tuples[ i ^ 1 ][ 2 ].disable, tuples[ 2 ][ 2 ].lock ); + } + + // deferred[ resolve | reject | notify ] = list.fire + deferred[ tuple[0] ] = list.fire; + deferred[ tuple[0] + "With" ] = list.fireWith; + }); + + // Make the deferred a promise + promise.promise( deferred ); + + // Call given func if any + if ( func ) { + func.call( deferred, deferred ); + } + + // All done! + return deferred; + }, + + // Deferred helper + when: function( subordinate /* , ..., subordinateN */ ) { + var i = 0, + resolveValues = core_slice.call( arguments ), + length = resolveValues.length, + + // the count of uncompleted subordinates + remaining = length !== 1 || ( subordinate && jQuery.isFunction( subordinate.promise ) ) ? length : 0, + + // the master Deferred. If resolveValues consist of only a single Deferred, just use that. + deferred = remaining === 1 ? subordinate : jQuery.Deferred(), + + // Update function for both resolve and progress values + updateFunc = function( i, contexts, values ) { + return function( value ) { + contexts[ i ] = this; + values[ i ] = arguments.length > 1 ? core_slice.call( arguments ) : value; + if( values === progressValues ) { + deferred.notifyWith( contexts, values ); + } else if ( !( --remaining ) ) { + deferred.resolveWith( contexts, values ); + } + }; + }, + + progressValues, progressContexts, resolveContexts; + + // add listeners to Deferred subordinates; treat others as resolved + if ( length > 1 ) { + progressValues = new Array( length ); + progressContexts = new Array( length ); + resolveContexts = new Array( length ); + for ( ; i < length; i++ ) { + if ( resolveValues[ i ] && jQuery.isFunction( resolveValues[ i ].promise ) ) { + resolveValues[ i ].promise() + .done( updateFunc( i, resolveContexts, resolveValues ) ) + .fail( deferred.reject ) + .progress( updateFunc( i, progressContexts, progressValues ) ); + } else { + --remaining; + } + } + } + + // if we're not waiting on anything, resolve the master + if ( !remaining ) { + deferred.resolveWith( resolveContexts, resolveValues ); + } + + return deferred.promise(); + } +}); +jQuery.support = (function() { + + var support, + all, + a, + select, + opt, + input, + fragment, + eventName, + i, + isSupported, + clickFn, + div = document.createElement("div"); + + // Preliminary tests + div.setAttribute( "className", "t" ); + div.innerHTML = "
      a"; + + all = div.getElementsByTagName("*"); + a = div.getElementsByTagName("a")[ 0 ]; + a.style.cssText = "top:1px;float:left;opacity:.5"; + + // Can't get basic test support + if ( !all || !all.length ) { + 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.5/.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", + + // Tests for enctype support on a form(#6743) + enctype: !!document.createElement("form").enctype, + + // Makes sure cloning an html5 element does not cause problems + // Where outerHTML is undefined, this still works + html5Clone: document.createElement("nav").cloneNode( true ).outerHTML !== "<:nav>", + + // jQuery.support.boxModel DEPRECATED in 1.8 since we don't support Quirks Mode + boxModel: ( document.compatMode === "CSS1Compat" ), + + // Will be defined later + submitBubbles: true, + changeBubbles: true, + focusinBubbles: false, + deleteExpando: true, + noCloneEvent: true, + inlineBlockNeedsLayout: false, + shrinkWrapBlocks: false, + reliableMarginRight: true, + boxSizingReliable: true, + pixelPosition: false + }; + + // 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", clickFn = function() { + // Cloning a node shouldn't copy over any + // bound event handlers (IE does this) + support.noCloneEvent = false; + }); + div.cloneNode( true ).fireEvent("onclick"); + div.detachEvent( "onclick", clickFn ); + } + + // Check if a radio maintains its 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" ); + + // #11217 - WebKit loses check when the name is after the checked attribute + input.setAttribute( "name", "t" ); + + div.appendChild( input ); + fragment = document.createDocumentFragment(); + fragment.appendChild( div.lastChild ); + + // WebKit doesn't clone checked state correctly in fragments + support.checkClone = fragment.cloneNode( true ).cloneNode( true ).lastChild.checked; + + // Check if a disconnected checkbox will retain its checked + // value of true after appended to the DOM (IE6/7) + support.appendChecked = input.checked; + + fragment.removeChild( input ); + fragment.appendChild( div ); + + // Technique from Juriy Zaytsev + // http://perfectionkills.com/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: true, + change: true, + focusin: true + }) { + eventName = "on" + i; + isSupported = ( eventName in div ); + if ( !isSupported ) { + div.setAttribute( eventName, "return;" ); + isSupported = ( typeof div[ eventName ] === "function" ); + } + support[ i + "Bubbles" ] = isSupported; + } + } + + // Run tests that need a body at doc ready + jQuery(function() { + var container, div, tds, marginDiv, + divReset = "padding:0;margin:0;border:0;display:block;overflow:hidden;", + body = document.getElementsByTagName("body")[0]; + + if ( !body ) { + // Return for frameset docs that don't have a body + return; + } + + container = document.createElement("div"); + container.style.cssText = "visibility:hidden;border:0;width:0;height:0;position:static;top:0;margin-top:1px"; + body.insertBefore( container, body.firstChild ); + + // Construct the test element + div = document.createElement("div"); + container.appendChild( div ); + + // 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) + div.innerHTML = "
      t
      "; + tds = div.getElementsByTagName("td"); + tds[ 0 ].style.cssText = "padding:0;margin:0;border:0;display:none"; + 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 ); + + // Check box-sizing and margin behavior + div.innerHTML = ""; + div.style.cssText = "box-sizing:border-box;-moz-box-sizing:border-box;-webkit-box-sizing:border-box;padding:1px;border:1px;display:block;width:4px;margin-top:1%;position:absolute;top:1%;"; + support.boxSizing = ( div.offsetWidth === 4 ); + support.doesNotIncludeMarginInBodyOffset = ( body.offsetTop !== 1 ); + + // NOTE: To any future maintainer, we've window.getComputedStyle + // because jsdom on node.js will break without it. + if ( window.getComputedStyle ) { + support.pixelPosition = ( window.getComputedStyle( div, null ) || {} ).top !== "1%"; + support.boxSizingReliable = ( window.getComputedStyle( div, null ) || { width: "4px" } ).width === "4px"; + + // 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 + marginDiv = document.createElement("div"); + marginDiv.style.cssText = div.style.cssText = divReset; + marginDiv.style.marginRight = marginDiv.style.width = "0"; + div.style.width = "1px"; + div.appendChild( marginDiv ); + support.reliableMarginRight = + !parseFloat( ( window.getComputedStyle( marginDiv, null ) || {} ).marginRight ); + } + + if ( typeof div.style.zoom !== "undefined" ) { + // 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.innerHTML = ""; + div.style.cssText = divReset + "width:1px;padding:1px;display:inline;zoom:1"; + support.inlineBlockNeedsLayout = ( div.offsetWidth === 3 ); + + // Check if elements with layout shrink-wrap their children + // (IE 6 does this) + div.style.display = "block"; + div.style.overflow = "visible"; + div.innerHTML = "
      "; + div.firstChild.style.width = "5px"; + support.shrinkWrapBlocks = ( div.offsetWidth !== 3 ); + + container.style.zoom = 1; + } + + // Null elements to avoid leaks in IE + body.removeChild( container ); + container = div = tds = marginDiv = null; + }); + + // Null elements to avoid leaks in IE + fragment.removeChild( div ); + all = a = select = opt = input = fragment = div = null; + + return support; +})(); +var rbrace = /(?:\{[\s\S]*\}|\[[\s\S]*\])$/, + rmultiDash = /([A-Z])/g; + +jQuery.extend({ + cache: {}, + + deletedIds: [], + + // Remove at next major release (1.9/2.0) + 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 thisCache, ret, + internalKey = jQuery.expando, + getByName = typeof name === "string", + + // 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[ internalKey ] : elem[ internalKey ] && internalKey; + + // 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 || !cache[id] || (!pvt && !cache[id].data)) && 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[ internalKey ] = id = jQuery.deletedIds.pop() || jQuery.guid++; + } else { + id = internalKey; + } + } + + if ( !cache[ id ] ) { + cache[ id ] = {}; + + // 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 ] = jQuery.extend( cache[ id ], name ); + } else { + cache[ id ].data = jQuery.extend( cache[ id ].data, name ); + } + } + + thisCache = cache[ id ]; + + // jQuery data() is stored in a separate object inside the object's internal data + // cache in order to avoid key collisions between internal data and user-defined + // data. + if ( !pvt ) { + if ( !thisCache.data ) { + thisCache.data = {}; + } + + thisCache = thisCache.data; + } + + if ( data !== undefined ) { + thisCache[ jQuery.camelCase( name ) ] = data; + } + + // Check for both converted-to-camel and non-converted data property names + // If a data property was specified + if ( getByName ) { + + // First Try to find as-is property data + ret = thisCache[ name ]; + + // Test for null|undefined property data + if ( ret == null ) { + + // Try to find the camelCased property + ret = thisCache[ jQuery.camelCase( name ) ]; + } + } else { + ret = thisCache; + } + + return ret; + }, + + removeData: function( elem, name, pvt /* Internal Use Only */ ) { + if ( !jQuery.acceptData( elem ) ) { + return; + } + + var thisCache, i, l, + + isNode = elem.nodeType, + + // See jQuery.data for more information + cache = isNode ? jQuery.cache : elem, + 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 ) { + + thisCache = pvt ? cache[ id ] : cache[ id ].data; + + if ( thisCache ) { + + // Support array or space separated string names for data keys + if ( !jQuery.isArray( name ) ) { + + // try the string as a key before any manipulation + if ( name in thisCache ) { + name = [ name ]; + } else { + + // split the camel cased version by spaces unless a key with the spaces exists + name = jQuery.camelCase( name ); + if ( name in thisCache ) { + name = [ name ]; + } else { + name = name.split(" "); + } + } + } + + for ( i = 0, l = name.length; i < l; i++ ) { + delete thisCache[ name[i] ]; + } + + // If there is no data left in the cache, we want to continue + // and let the cache object itself get destroyed + if ( !( pvt ? isEmptyDataObject : jQuery.isEmptyObject )( thisCache ) ) { + return; + } + } + } + + // See jQuery.data for more information + if ( !pvt ) { + delete cache[ id ].data; + + // Don't destroy the parent cache unless the internal data object + // had been the only thing left in it + if ( !isEmptyDataObject( cache[ id ] ) ) { + return; + } + } + + // Destroy the cache + if ( isNode ) { + jQuery.cleanData( [ elem ], true ); + + // Use delete when supported for expandos or `cache` is not a window per isWindow (#10080) + } else if ( jQuery.support.deleteExpando || cache != cache.window ) { + delete cache[ id ]; + + // When all else fails, null + } else { + cache[ id ] = 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 ) { + var noData = elem.nodeName && jQuery.noData[ elem.nodeName.toLowerCase() ]; + + // nodes accept data unless otherwise specified; rejection can be conditional + return !noData || noData !== true && elem.getAttribute("classid") === noData; + } +}); + +jQuery.fn.extend({ + data: function( key, value ) { + var parts, part, attr, name, l, + elem = this[0], + i = 0, + data = null; + + // Gets all values + if ( key === undefined ) { + if ( this.length ) { + data = jQuery.data( elem ); + + if ( elem.nodeType === 1 && !jQuery._data( elem, "parsedAttrs" ) ) { + attr = elem.attributes; + for ( l = attr.length; i < l; i++ ) { + name = attr[i].name; + + if ( !name.indexOf( "data-" ) ) { + name = jQuery.camelCase( name.substring(5) ); + + dataAttr( elem, name, data[ name ] ); + } + } + jQuery._data( elem, "parsedAttrs", true ); + } + } + + return data; + } + + // Sets multiple values + if ( typeof key === "object" ) { + return this.each(function() { + jQuery.data( this, key ); + }); + } + + parts = key.split( ".", 2 ); + parts[1] = parts[1] ? "." + parts[1] : ""; + part = parts[1] + "!"; + + return jQuery.access( this, function( value ) { + + if ( value === undefined ) { + data = this.triggerHandler( "getData" + part, [ parts[0] ] ); + + // Try to fetch any internally stored data first + if ( data === undefined && elem ) { + data = jQuery.data( elem, key ); + data = dataAttr( elem, key, data ); + } + + return data === undefined && parts[1] ? + this.data( parts[0] ) : + data; + } + + parts[1] = value; + this.each(function() { + var self = jQuery( this ); + + self.triggerHandler( "setData" + part, parts ); + jQuery.data( this, key, value ); + self.triggerHandler( "changeData" + part, parts ); + }); + }, null, value, arguments.length > 1, null, false ); + }, + + 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" ).toLowerCase(); + + data = elem.getAttribute( name ); + + if ( typeof data === "string" ) { + try { + data = data === "true" ? true : + data === "false" ? false : + data === "null" ? null : + // Only convert to a number if it doesn't change the string + +data + "" === data ? +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; +} + +// checks a cache object for emptiness +function isEmptyDataObject( obj ) { + var name; + for ( name in obj ) { + + // if the public data object is empty, the private is still empty + if ( name === "data" && jQuery.isEmptyObject( obj[name] ) ) { + continue; + } + if ( name !== "toJSON" ) { + return false; + } + } + + return true; +} +jQuery.extend({ + queue: function( elem, type, data ) { + var queue; + + if ( elem ) { + type = ( type || "fx" ) + "queue"; + queue = jQuery._data( elem, type ); + + // Speed up dequeue by getting out quickly if this is just a lookup + if ( data ) { + if ( !queue || jQuery.isArray(data) ) { + queue = jQuery._data( elem, type, jQuery.makeArray(data) ); + } else { + queue.push( data ); + } + } + return queue || []; + } + }, + + dequeue: function( elem, type ) { + type = type || "fx"; + + var queue = jQuery.queue( elem, type ), + startLength = queue.length, + fn = queue.shift(), + hooks = jQuery._queueHooks( elem, type ), + next = function() { + jQuery.dequeue( elem, type ); + }; + + // If the fx queue is dequeued, always remove the progress sentinel + if ( fn === "inprogress" ) { + fn = queue.shift(); + startLength--; + } + + if ( fn ) { + + // Add a progress sentinel to prevent the fx queue from being + // automatically dequeued + if ( type === "fx" ) { + queue.unshift( "inprogress" ); + } + + // clear up the last queue stop function + delete hooks.stop; + fn.call( elem, next, hooks ); + } + + if ( !startLength && hooks ) { + hooks.empty.fire(); + } + }, + + // not intended for public consumption - generates a queueHooks object, or returns the current one + _queueHooks: function( elem, type ) { + var key = type + "queueHooks"; + return jQuery._data( elem, key ) || jQuery._data( elem, key, { + empty: jQuery.Callbacks("once memory").add(function() { + jQuery.removeData( elem, type + "queue", true ); + jQuery.removeData( elem, key, true ); + }) + }); + } +}); + +jQuery.fn.extend({ + queue: function( type, data ) { + var setter = 2; + + if ( typeof type !== "string" ) { + data = type; + type = "fx"; + setter--; + } + + if ( arguments.length < setter ) { + return jQuery.queue( this[0], type ); + } + + return data === undefined ? + this : + this.each(function() { + var queue = jQuery.queue( this, type, data ); + + // ensure a hooks for this queue + jQuery._queueHooks( this, type ); + + 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( next, hooks ) { + var timeout = setTimeout( next, time ); + hooks.stop = function() { + clearTimeout( timeout ); + }; + }); + }, + 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, obj ) { + var tmp, + count = 1, + defer = jQuery.Deferred(), + elements = this, + i = this.length, + resolve = function() { + if ( !( --count ) ) { + defer.resolveWith( elements, [ elements ] ); + } + }; + + if ( typeof type !== "string" ) { + obj = type; + type = undefined; + } + type = type || "fx"; + + while( i-- ) { + tmp = jQuery._data( elements[ i ], type + "queueHooks" ); + if ( tmp && tmp.empty ) { + count++; + tmp.empty.add( resolve ); + } + } + resolve(); + return defer.promise( obj ); + } +}); +var nodeHook, boolHook, fixSpecified, + rclass = /[\t\r\n]/g, + 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, + getSetAttribute = jQuery.support.getSetAttribute; + +jQuery.fn.extend({ + attr: function( name, value ) { + return jQuery.access( this, jQuery.attr, name, value, arguments.length > 1 ); + }, + + removeAttr: function( name ) { + return this.each(function() { + jQuery.removeAttr( this, name ); + }); + }, + + prop: function( name, value ) { + return jQuery.access( this, jQuery.prop, name, value, arguments.length > 1 ); + }, + + 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( core_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 ] + " " ) < 0 ) { + setClass += classNames[ c ] + " "; + } + } + elem.className = jQuery.trim( setClass ); + } + } + } + } + + return this; + }, + + removeClass: function( value ) { + var removes, className, elem, c, cl, i, l; + + 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 ) { + removes = ( value || "" ).split( core_rspace ); + + for ( i = 0, l = this.length; i < l; i++ ) { + elem = this[ i ]; + if ( elem.nodeType === 1 && elem.className ) { + + className = (" " + elem.className + " ").replace( rclass, " " ); + + // loop over each item in the removal list + for ( c = 0, cl = removes.length; c < cl; c++ ) { + // Remove until there is nothing to remove, + while ( className.indexOf(" " + removes[ c ] + " ") >= 0 ) { + className = className.replace( " " + removes[ c ] + " " , " " ); + } + } + elem.className = value ? jQuery.trim( 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( core_rspace ); + + while ( (className = classNames[ i++ ]) ) { + // check each className given, space separated 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 + " ", + i = 0, + l = this.length; + for ( ; i < l; i++ ) { + if ( this[i].nodeType === 1 && (" " + this[i].className + " ").replace(rclass, " ").indexOf( className ) >= 0 ) { + return true; + } + } + + return false; + }, + + val: function( value ) { + var hooks, ret, isFunction, + elem = this[0]; + + if ( !arguments.length ) { + if ( elem ) { + hooks = jQuery.valHooks[ elem.type ] || jQuery.valHooks[ elem.nodeName.toLowerCase() ]; + + 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; + } + + isFunction = jQuery.isFunction( value ); + + return this.each(function( i ) { + var val, + self = jQuery(this); + + 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.type ] || jQuery.valHooks[ this.nodeName.toLowerCase() ]; + + // 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, i, max, option, + 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 + i = one ? index : 0; + max = one ? index + 1 : options.length; + for ( ; i < max; i++ ) { + 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; + } + } + }, + + // Unused in 1.8, left in so attrFn-stabbers won't die; remove in 1.9 + attrFn: {}, + + attr: function( elem, name, value, pass ) { + var ret, hooks, notxml, + nType = elem.nodeType; + + // don't get/set attributes on text, comment and attribute nodes + if ( !elem || nType === 3 || nType === 8 || nType === 2 ) { + return; + } + + if ( pass && jQuery.isFunction( jQuery.fn[ name ] ) ) { + return jQuery( elem )[ name ]( value ); + } + + // Fallback to prop when attributes are not supported + if ( typeof elem.getAttribute === "undefined" ) { + return jQuery.prop( elem, name, value ); + } + + notxml = nType !== 1 || !jQuery.isXMLDoc( elem ); + + // All attributes are lowercase + // Grab necessary hook if one is defined + if ( notxml ) { + name = name.toLowerCase(); + hooks = jQuery.attrHooks[ name ] || ( rboolean.test( name ) ? boolHook : nodeHook ); + } + + if ( value !== undefined ) { + + if ( value === null ) { + jQuery.removeAttr( elem, name ); + return; + + } 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, value ) { + var propName, attrNames, name, isBool, + i = 0; + + if ( value && elem.nodeType === 1 ) { + + attrNames = value.split( core_rspace ); + + for ( ; i < attrNames.length; i++ ) { + name = attrNames[ i ]; + + if ( name ) { + propName = jQuery.propFix[ name ] || name; + isBool = rboolean.test( name ); + + // See #9699 for explanation of this approach (setting first, then removal) + // Do not do this for boolean attributes (see #10870) + if ( !isBool ) { + jQuery.attr( elem, name, "" ); + } + elem.removeAttribute( getSetAttribute ? name : propName ); + + // Set corresponding property to false for boolean attributes + if ( isBool && propName 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; + } + } + }, + // Use the value property for back compat + // Use the nodeHook for button elements in IE6/7 (#1954) + value: { + get: function( elem, name ) { + if ( nodeHook && jQuery.nodeName( elem, "button" ) ) { + return nodeHook.get( elem, name ); + } + return name in elem ? + elem.value : + null; + }, + set: function( elem, value, name ) { + if ( nodeHook && jQuery.nodeName( elem, "button" ) ) { + return nodeHook.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 ret, hooks, notxml, + nType = elem.nodeType; + + // don't get/set properties on text, comment and attribute nodes + if ( !elem || nType === 3 || nType === 8 || nType === 2 ) { + return; + } + + 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 )) !== null ) { + return ret; + + } else { + return elem[ name ]; + } + } + }, + + propHooks: { + 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; + } + } + } +}); + +// Hook for boolean attributes +boolHook = { + get: function( elem, name ) { + // Align boolean attributes with corresponding properties + // Fall back to attribute presence where some booleans are not supported + var attrNode, + property = jQuery.prop( elem, name ); + return property === true || typeof property !== "boolean" && ( attrNode = elem.getAttributeNode(name) ) && attrNode.nodeValue !== false ? + 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 ( !getSetAttribute ) { + + fixSpecified = { + name: true, + id: true, + coords: true + }; + + // Use this for any attribute in IE6/7 + // This fixes almost every IE6/7 issue + nodeHook = jQuery.valHooks.button = { + get: function( elem, name ) { + var ret; + ret = elem.getAttributeNode( name ); + return ret && ( fixSpecified[ name ] ? ret.value !== "" : ret.specified ) ? + ret.value : + undefined; + }, + set: function( elem, value, name ) { + // Set the existing or create a new attribute node + var ret = elem.getAttributeNode( name ); + if ( !ret ) { + ret = document.createAttribute( name ); + elem.setAttributeNode( ret ); + } + return ( ret.value = 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; + } + } + }); + }); + + // Set contenteditable to false on removals(#10429) + // Setting to empty string throws an error as an invalid value + jQuery.attrHooks.contenteditable = { + get: nodeHook.get, + set: function( elem, value, name ) { + if ( value === "" ) { + value = "false"; + } + nodeHook.set( elem, value, name ); + } + }; +} + + +// 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; + } + } + return null; + } + }); +} + +// IE6/7 call enctype encoding +if ( !jQuery.support.enctype ) { + jQuery.propFix.enctype = "encoding"; +} + +// 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 rformElems = /^(?:textarea|input|select)$/i, + rtypenamespace = /^([^\.]*|)(?:\.(.+)|)$/, + rhoverHack = /(?:^|\s)hover(\.\S+|)\b/, + rkeyEvent = /^key/, + rmouseEvent = /^(?:mouse|contextmenu)|click/, + rfocusMorph = /^(?:focusinfocus|focusoutblur)$/, + hoverHack = function( events ) { + return jQuery.event.special.hover ? events : events.replace( rhoverHack, "mouseenter$1 mouseleave$1" ); + }; + +/* + * Helper functions for managing events -- not part of the public interface. + * Props to Dean Edwards' addEvent library for many of the ideas. + */ +jQuery.event = { + + add: function( elem, types, handler, data, selector ) { + + var elemData, eventHandle, events, + t, tns, type, namespaces, handleObj, + handleObjIn, handlers, special; + + // Don't attach events to noData or text/comment nodes (allow plain objects tho) + if ( elem.nodeType === 3 || elem.nodeType === 8 || !types || !handler || !(elemData = jQuery._data( elem )) ) { + return; + } + + // Caller can pass in an object of custom data in lieu of the handler + if ( handler.handler ) { + handleObjIn = handler; + handler = handleObjIn.handler; + selector = handleObjIn.selector; + } + + // Make sure that the handler has a unique ID, used to find/remove it later + if ( !handler.guid ) { + handler.guid = jQuery.guid++; + } + + // Init the element's event structure and main handler, if this is the first + events = elemData.events; + if ( !events ) { + elemData.events = events = {}; + } + eventHandle = elemData.handle; + 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.dispatch.apply( eventHandle.elem, arguments ) : + undefined; + }; + // Add elem as a property of the handle fn to prevent a memory leak with IE non-native events + eventHandle.elem = elem; + } + + // Handle multiple events separated by a space + // jQuery(...).bind("mouseover mouseout", fn); + types = jQuery.trim( hoverHack(types) ).split( " " ); + for ( t = 0; t < types.length; t++ ) { + + tns = rtypenamespace.exec( types[t] ) || []; + type = tns[1]; + namespaces = ( tns[2] || "" ).split( "." ).sort(); + + // If event changes its type, use the special event handlers for the changed type + special = jQuery.event.special[ type ] || {}; + + // If selector defined, determine special event api type, otherwise given type + type = ( selector ? special.delegateType : special.bindType ) || type; + + // Update special based on newly reset type + special = jQuery.event.special[ type ] || {}; + + // handleObj is passed to all event handlers + handleObj = jQuery.extend({ + type: type, + origType: tns[1], + data: data, + handler: handler, + guid: handler.guid, + selector: selector, + needsContext: selector && jQuery.expr.match.needsContext.test( selector ), + namespace: namespaces.join(".") + }, handleObjIn ); + + // Init the event handler queue if we're the first + handlers = events[ type ]; + if ( !handlers ) { + handlers = events[ type ] = []; + handlers.delegateCount = 0; + + // 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 to the element's handler list, delegates in front + if ( selector ) { + handlers.splice( handlers.delegateCount++, 0, handleObj ); + } else { + handlers.push( handleObj ); + } + + // Keep track of which events have ever 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, selector, mappedTypes ) { + + var t, tns, type, origType, namespaces, origCount, + j, events, special, eventType, handleObj, + elemData = jQuery.hasData( elem ) && jQuery._data( elem ); + + if ( !elemData || !(events = elemData.events) ) { + return; + } + + // Once for each type.namespace in types; type may be omitted + types = jQuery.trim( hoverHack( types || "" ) ).split(" "); + for ( t = 0; t < types.length; t++ ) { + tns = rtypenamespace.exec( types[t] ) || []; + type = origType = tns[1]; + namespaces = tns[2]; + + // Unbind all events (on this namespace, if provided) for the element + if ( !type ) { + for ( type in events ) { + jQuery.event.remove( elem, type + types[ t ], handler, selector, true ); + } + continue; + } + + special = jQuery.event.special[ type ] || {}; + type = ( selector? special.delegateType : special.bindType ) || type; + eventType = events[ type ] || []; + origCount = eventType.length; + namespaces = namespaces ? new RegExp("(^|\\.)" + namespaces.split(".").sort().join("\\.(?:.*\\.|)") + "(\\.|$)") : null; + + // Remove matching events + for ( j = 0; j < eventType.length; j++ ) { + handleObj = eventType[ j ]; + + if ( ( mappedTypes || origType === handleObj.origType ) && + ( !handler || handler.guid === handleObj.guid ) && + ( !namespaces || namespaces.test( handleObj.namespace ) ) && + ( !selector || selector === handleObj.selector || selector === "**" && handleObj.selector ) ) { + eventType.splice( j--, 1 ); + + if ( handleObj.selector ) { + eventType.delegateCount--; + } + if ( special.remove ) { + special.remove.call( elem, handleObj ); + } + } + } + + // Remove generic event handler if we removed something and no more handlers exist + // (avoids potential for endless recursion during removal of special event handlers) + if ( eventType.length === 0 && origCount !== eventType.length ) { + if ( !special.teardown || special.teardown.call( elem, namespaces, elemData.handle ) === false ) { + jQuery.removeEvent( elem, type, elemData.handle ); + } + + delete events[ type ]; + } + } + + // Remove the expando if it's no longer used + if ( jQuery.isEmptyObject( events ) ) { + delete elemData.handle; + + // removeData also checks for emptiness and clears the expando if empty + // so use it instead of delete + jQuery.removeData( elem, "events", 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 ) { + // Don't do events on text and comment nodes + if ( elem && (elem.nodeType === 3 || elem.nodeType === 8) ) { + return; + } + + // Event object or event type + var cache, exclusive, i, cur, old, ontype, special, handle, eventPath, bubbleType, + type = event.type || event, + namespaces = []; + + // focus/blur morphs to focusin/out; ensure we're not firing them right now + if ( rfocusMorph.test( type + jQuery.event.triggered ) ) { + return; + } + + 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.isTrigger = true; + event.exclusive = exclusive; + event.namespace = namespaces.join( "." ); + event.namespace_re = event.namespace? new RegExp("(^|\\.)" + namespaces.join("\\.(?:.*\\.|)") + "(\\.|$)") : null; + ontype = type.indexOf( ":" ) < 0 ? "on" + type : ""; + + // Handle a global trigger + if ( !elem ) { + + // TODO: Stop taunting the data cache; remove global events and always attach to document + cache = jQuery.cache; + for ( i in cache ) { + if ( cache[ i ].events && cache[ i ].events[ type ] ) { + jQuery.event.trigger( event, data, cache[ i ].handle.elem, true ); + } + } + return; + } + + // Clean up the event in case it is being reused + event.result = undefined; + if ( !event.target ) { + 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 ); + + // Allow special events to draw outside the lines + special = jQuery.event.special[ type ] || {}; + if ( special.trigger && special.trigger.apply( elem, data ) === false ) { + return; + } + + // Determine event propagation path in advance, per W3C events spec (#9951) + // Bubble up to document, then to window; watch for a global ownerDocument var (#9724) + eventPath = [[ elem, special.bindType || type ]]; + if ( !onlyHandlers && !special.noBubble && !jQuery.isWindow( elem ) ) { + + bubbleType = special.delegateType || type; + cur = rfocusMorph.test( bubbleType + type ) ? elem : elem.parentNode; + for ( old = elem; cur; cur = cur.parentNode ) { + eventPath.push([ cur, bubbleType ]); + old = cur; + } + + // Only add window if we got to document (e.g., not plain obj or detached DOM) + if ( old === (elem.ownerDocument || document) ) { + eventPath.push([ old.defaultView || old.parentWindow || window, bubbleType ]); + } + } + + // Fire handlers on the event path + for ( i = 0; i < eventPath.length && !event.isPropagationStopped(); i++ ) { + + cur = eventPath[i][0]; + event.type = eventPath[i][1]; + + handle = ( jQuery._data( cur, "events" ) || {} )[ event.type ] && jQuery._data( cur, "handle" ); + if ( handle ) { + handle.apply( cur, data ); + } + // Note that this is a bare JS function and not a jQuery handler + handle = ontype && cur[ ontype ]; + if ( handle && jQuery.acceptData( cur ) && handle.apply && handle.apply( cur, data ) === false ) { + event.preventDefault(); + } + } + event.type = type; + + // If nobody prevented the default action, do it now + if ( !onlyHandlers && !event.isDefaultPrevented() ) { + + if ( (!special._default || special._default.apply( elem.ownerDocument, data ) === 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. + // Don't do default actions on window, that's where global variables be (#6170) + // IE<9 dies on focus/blur to hidden element (#1486) + if ( ontype && elem[ type ] && ((type !== "focus" && type !== "blur") || event.target.offsetWidth !== 0) && !jQuery.isWindow( elem ) ) { + + // Don't re-trigger an onFOO event when we call its FOO() method + old = elem[ ontype ]; + + if ( old ) { + elem[ ontype ] = null; + } + + // Prevent re-triggering of the same event, since we already bubbled it above + jQuery.event.triggered = type; + elem[ type ](); + jQuery.event.triggered = undefined; + + if ( old ) { + elem[ ontype ] = old; + } + } + } + } + + return event.result; + }, + + dispatch: function( event ) { + + // Make a writable jQuery.Event from the native event object + event = jQuery.event.fix( event || window.event ); + + var i, j, cur, ret, selMatch, matched, matches, handleObj, sel, related, + handlers = ( (jQuery._data( this, "events" ) || {} )[ event.type ] || []), + delegateCount = handlers.delegateCount, + args = core_slice.call( arguments ), + run_all = !event.exclusive && !event.namespace, + special = jQuery.event.special[ event.type ] || {}, + handlerQueue = []; + + // Use the fix-ed jQuery.Event rather than the (read-only) native event + args[0] = event; + event.delegateTarget = this; + + // Call the preDispatch hook for the mapped type, and let it bail if desired + if ( special.preDispatch && special.preDispatch.call( this, event ) === false ) { + return; + } + + // Determine handlers that should run if there are delegated events + // Avoid non-left-click bubbling in Firefox (#3861) + if ( delegateCount && !(event.button && event.type === "click") ) { + + for ( cur = event.target; cur != this; cur = cur.parentNode || this ) { + + // Don't process clicks (ONLY) on disabled elements (#6911, #8165, #11382, #11764) + if ( cur.disabled !== true || event.type !== "click" ) { + selMatch = {}; + matches = []; + for ( i = 0; i < delegateCount; i++ ) { + handleObj = handlers[ i ]; + sel = handleObj.selector; + + if ( selMatch[ sel ] === undefined ) { + selMatch[ sel ] = handleObj.needsContext ? + jQuery( sel, this ).index( cur ) >= 0 : + jQuery.find( sel, this, null, [ cur ] ).length; + } + if ( selMatch[ sel ] ) { + matches.push( handleObj ); + } + } + if ( matches.length ) { + handlerQueue.push({ elem: cur, matches: matches }); + } + } + } + } + + // Add the remaining (directly-bound) handlers + if ( handlers.length > delegateCount ) { + handlerQueue.push({ elem: this, matches: handlers.slice( delegateCount ) }); + } + + // Run delegates first; they may want to stop propagation beneath us + for ( i = 0; i < handlerQueue.length && !event.isPropagationStopped(); i++ ) { + matched = handlerQueue[ i ]; + event.currentTarget = matched.elem; + + for ( j = 0; j < matched.matches.length && !event.isImmediatePropagationStopped(); j++ ) { + handleObj = matched.matches[ j ]; + + // Triggered event must either 1) be non-exclusive and have no namespace, or + // 2) have namespace(s) a subset or equal to those in the bound event (both can have no namespace). + if ( run_all || (!event.namespace && !handleObj.namespace) || event.namespace_re && event.namespace_re.test( handleObj.namespace ) ) { + + event.data = handleObj.data; + event.handleObj = handleObj; + + ret = ( (jQuery.event.special[ handleObj.origType ] || {}).handle || handleObj.handler ) + .apply( matched.elem, args ); + + if ( ret !== undefined ) { + event.result = ret; + if ( ret === false ) { + event.preventDefault(); + event.stopPropagation(); + } + } + } + } + } + + // Call the postDispatch hook for the mapped type + if ( special.postDispatch ) { + special.postDispatch.call( this, event ); + } + + return event.result; + }, + + // Includes some event props shared by KeyEvent and MouseEvent + // *** attrChange attrName relatedNode srcElement are not normalized, non-W3C, deprecated, will be removed in 1.8 *** + props: "attrChange attrName relatedNode srcElement altKey bubbles cancelable ctrlKey currentTarget eventPhase metaKey relatedTarget shiftKey target timeStamp view which".split(" "), + + fixHooks: {}, + + keyHooks: { + props: "char charCode key keyCode".split(" "), + filter: function( event, original ) { + + // Add which for key events + if ( event.which == null ) { + event.which = original.charCode != null ? original.charCode : original.keyCode; + } + + return event; + } + }, + + mouseHooks: { + props: "button buttons clientX clientY fromElement offsetX offsetY pageX pageY screenX screenY toElement".split(" "), + filter: function( event, original ) { + var eventDoc, doc, body, + button = original.button, + fromElement = original.fromElement; + + // Calculate pageX/Y if missing and clientX/Y available + if ( event.pageX == null && original.clientX != null ) { + eventDoc = event.target.ownerDocument || document; + doc = eventDoc.documentElement; + body = eventDoc.body; + + event.pageX = original.clientX + ( doc && doc.scrollLeft || body && body.scrollLeft || 0 ) - ( doc && doc.clientLeft || body && body.clientLeft || 0 ); + event.pageY = original.clientY + ( doc && doc.scrollTop || body && body.scrollTop || 0 ) - ( doc && doc.clientTop || body && body.clientTop || 0 ); + } + + // Add relatedTarget, if necessary + if ( !event.relatedTarget && fromElement ) { + event.relatedTarget = fromElement === event.target ? original.toElement : fromElement; + } + + // Add which for click: 1 === left; 2 === middle; 3 === right + // Note: button is not normalized, so don't use it + if ( !event.which && button !== undefined ) { + event.which = ( button & 1 ? 1 : ( button & 2 ? 3 : ( button & 4 ? 2 : 0 ) ) ); + } + + return event; + } + }, + + fix: function( event ) { + if ( event[ jQuery.expando ] ) { + return event; + } + + // Create a writable copy of the event object and normalize some properties + var i, prop, + originalEvent = event, + fixHook = jQuery.event.fixHooks[ event.type ] || {}, + copy = fixHook.props ? this.props.concat( fixHook.props ) : this.props; + + event = jQuery.Event( originalEvent ); + + for ( i = copy.length; i; ) { + prop = copy[ --i ]; + event[ prop ] = originalEvent[ prop ]; + } + + // Fix target property, if necessary (#1925, IE 6/7/8 & Safari2) + if ( !event.target ) { + event.target = originalEvent.srcElement || document; + } + + // Target should not be a text node (#504, Safari) + if ( event.target.nodeType === 3 ) { + event.target = event.target.parentNode; + } + + // For mouse/key events, metaKey==false if it's undefined (#3368, #11328; IE6/7/8) + event.metaKey = !!event.metaKey; + + return fixHook.filter? fixHook.filter( event, originalEvent ) : event; + }, + + special: { + load: { + // Prevent triggered image.load events from bubbling to window.load + noBubble: true + }, + + focus: { + delegateType: "focusin" + }, + blur: { + delegateType: "focusout" + }, + + 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; + } + } + } + }, + + simulate: function( type, elem, event, bubble ) { + // 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. + var e = jQuery.extend( + new jQuery.Event(), + event, + { type: type, + isSimulated: true, + originalEvent: {} + } + ); + if ( bubble ) { + jQuery.event.trigger( e, null, elem ); + } else { + jQuery.event.dispatch.call( elem, e ); + } + if ( e.isDefaultPrevented() ) { + event.preventDefault(); + } + } +}; + +// Some plugins are using, but it's undocumented/deprecated and will be removed. +// The 1.7 special event interface should provide all the hooks needed now. +jQuery.event.handle = jQuery.event.dispatch; + +jQuery.removeEvent = document.removeEventListener ? + function( elem, type, handle ) { + if ( elem.removeEventListener ) { + elem.removeEventListener( type, handle, false ); + } + } : + function( elem, type, handle ) { + var name = "on" + type; + + if ( elem.detachEvent ) { + + // #8545, #7054, preventing memory leaks for custom events in IE6-8 – + // detachEvent needed property on element, by name of that event, to properly expose it to GC + if ( typeof elem[ name ] === "undefined" ) { + elem[ name ] = null; + } + + elem.detachEvent( name, handle ); + } + }; + +jQuery.Event = function( src, props ) { + // Allow instantiation without the 'new' keyword + if ( !(this instanceof jQuery.Event) ) { + 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 ); + } + + // Create a timestamp if incoming event doesn't have one + this.timeStamp = src && src.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 +}; + +// Create mouseenter/leave events using mouseover/out and event-time checks +jQuery.each({ + mouseenter: "mouseover", + mouseleave: "mouseout" +}, function( orig, fix ) { + jQuery.event.special[ orig ] = { + delegateType: fix, + bindType: fix, + + handle: function( event ) { + var ret, + target = this, + related = event.relatedTarget, + handleObj = event.handleObj, + selector = handleObj.selector; + + // For mousenter/leave call the handler if related is outside the target. + // NB: No relatedTarget if the mouse left/entered the browser window + if ( !related || (related !== target && !jQuery.contains( target, related )) ) { + event.type = handleObj.origType; + ret = handleObj.handler.apply( this, arguments ); + event.type = fix; + } + return ret; + } + }; +}); + +// IE submit delegation +if ( !jQuery.support.submitBubbles ) { + + jQuery.event.special.submit = { + setup: function() { + // Only need this for delegated form submit events + if ( jQuery.nodeName( this, "form" ) ) { + return false; + } + + // Lazy-add a submit handler when a descendant form may potentially be submitted + jQuery.event.add( this, "click._submit keypress._submit", function( e ) { + // Node name check avoids a VML-related crash in IE (#9807) + var elem = e.target, + form = jQuery.nodeName( elem, "input" ) || jQuery.nodeName( elem, "button" ) ? elem.form : undefined; + if ( form && !jQuery._data( form, "_submit_attached" ) ) { + jQuery.event.add( form, "submit._submit", function( event ) { + event._submit_bubble = true; + }); + jQuery._data( form, "_submit_attached", true ); + } + }); + // return undefined since we don't need an event listener + }, + + postDispatch: function( event ) { + // If form was submitted by the user, bubble the event up the tree + if ( event._submit_bubble ) { + delete event._submit_bubble; + if ( this.parentNode && !event.isTrigger ) { + jQuery.event.simulate( "submit", this.parentNode, event, true ); + } + } + }, + + teardown: function() { + // Only need this for delegated form submit events + if ( jQuery.nodeName( this, "form" ) ) { + return false; + } + + // Remove delegated handlers; cleanData eventually reaps submit handlers attached above + jQuery.event.remove( this, "._submit" ); + } + }; +} + +// IE change delegation and checkbox/radio fix +if ( !jQuery.support.changeBubbles ) { + + jQuery.event.special.change = { + + setup: function() { + + if ( rformElems.test( this.nodeName ) ) { + // IE doesn't fire change on a check/radio until blur; trigger it on click + // after a propertychange. Eat the blur-change in special.change.handle. + // This still fires onchange a second time for check/radio after blur. + if ( this.type === "checkbox" || this.type === "radio" ) { + jQuery.event.add( this, "propertychange._change", function( event ) { + if ( event.originalEvent.propertyName === "checked" ) { + this._just_changed = true; + } + }); + jQuery.event.add( this, "click._change", function( event ) { + if ( this._just_changed && !event.isTrigger ) { + this._just_changed = false; + } + // Allow triggered, simulated change events (#11500) + jQuery.event.simulate( "change", this, event, true ); + }); + } + return false; + } + // Delegated event; lazy-add a change handler on descendant inputs + jQuery.event.add( this, "beforeactivate._change", function( e ) { + var elem = e.target; + + if ( rformElems.test( elem.nodeName ) && !jQuery._data( elem, "_change_attached" ) ) { + jQuery.event.add( elem, "change._change", function( event ) { + if ( this.parentNode && !event.isSimulated && !event.isTrigger ) { + jQuery.event.simulate( "change", this.parentNode, event, true ); + } + }); + jQuery._data( elem, "_change_attached", true ); + } + }); + }, + + handle: function( event ) { + var elem = event.target; + + // Swallow native change events from checkbox/radio, we already triggered them above + if ( this !== elem || event.isSimulated || event.isTrigger || (elem.type !== "radio" && elem.type !== "checkbox") ) { + return event.handleObj.handler.apply( this, arguments ); + } + }, + + teardown: function() { + jQuery.event.remove( this, "._change" ); + + return !rformElems.test( this.nodeName ); + } + }; +} + +// 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, + handler = function( event ) { + jQuery.event.simulate( fix, event.target, jQuery.event.fix( event ), true ); + }; + + jQuery.event.special[ fix ] = { + setup: function() { + if ( attaches++ === 0 ) { + document.addEventListener( orig, handler, true ); + } + }, + teardown: function() { + if ( --attaches === 0 ) { + document.removeEventListener( orig, handler, true ); + } + } + }; + }); +} + +jQuery.fn.extend({ + + on: function( types, selector, data, fn, /*INTERNAL*/ one ) { + var origFn, type; + + // Types can be a map of types/handlers + if ( typeof types === "object" ) { + // ( types-Object, selector, data ) + if ( typeof selector !== "string" ) { // && selector != null + // ( types-Object, data ) + data = data || selector; + selector = undefined; + } + for ( type in types ) { + this.on( type, selector, data, types[ type ], one ); + } + return this; + } + + if ( data == null && fn == null ) { + // ( types, fn ) + fn = selector; + data = selector = undefined; + } else if ( fn == null ) { + if ( typeof selector === "string" ) { + // ( types, selector, fn ) + fn = data; + data = undefined; + } else { + // ( types, data, fn ) + fn = data; + data = selector; + selector = undefined; + } + } + if ( fn === false ) { + fn = returnFalse; + } else if ( !fn ) { + return this; + } + + if ( one === 1 ) { + origFn = fn; + fn = function( event ) { + // Can use an empty set, since event contains the info + jQuery().off( event ); + return origFn.apply( this, arguments ); + }; + // Use same guid so caller can remove using origFn + fn.guid = origFn.guid || ( origFn.guid = jQuery.guid++ ); + } + return this.each( function() { + jQuery.event.add( this, types, fn, data, selector ); + }); + }, + one: function( types, selector, data, fn ) { + return this.on( types, selector, data, fn, 1 ); + }, + off: function( types, selector, fn ) { + var handleObj, type; + if ( types && types.preventDefault && types.handleObj ) { + // ( event ) dispatched jQuery.Event + handleObj = types.handleObj; + jQuery( types.delegateTarget ).off( + handleObj.namespace ? handleObj.origType + "." + handleObj.namespace : handleObj.origType, + handleObj.selector, + handleObj.handler + ); + return this; + } + if ( typeof types === "object" ) { + // ( types-object [, selector] ) + for ( type in types ) { + this.off( type, selector, types[ type ] ); + } + return this; + } + if ( selector === false || typeof selector === "function" ) { + // ( types [, fn] ) + fn = selector; + selector = undefined; + } + if ( fn === false ) { + fn = returnFalse; + } + return this.each(function() { + jQuery.event.remove( this, types, fn, selector ); + }); + }, + + bind: function( types, data, fn ) { + return this.on( types, null, data, fn ); + }, + unbind: function( types, fn ) { + return this.off( types, null, fn ); + }, + + live: function( types, data, fn ) { + jQuery( this.context ).on( types, this.selector, data, fn ); + return this; + }, + die: function( types, fn ) { + jQuery( this.context ).off( types, this.selector || "**", fn ); + return this; + }, + + delegate: function( selector, types, data, fn ) { + return this.on( types, selector, data, fn ); + }, + undelegate: function( selector, types, fn ) { + // ( namespace ) or ( selector, types [, fn] ) + return arguments.length === 1 ? this.off( selector, "**" ) : this.off( types, selector || "**", fn ); + }, + + 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 ); + } +}); + +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 contextmenu").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.on( name, null, data, fn ) : + this.trigger( name ); + }; + + if ( rkeyEvent.test( name ) ) { + jQuery.event.fixHooks[ name ] = jQuery.event.keyHooks; + } + + if ( rmouseEvent.test( name ) ) { + jQuery.event.fixHooks[ name ] = jQuery.event.mouseHooks; + } +}); +/*! + * Sizzle CSS Selector Engine + * Copyright 2012 jQuery Foundation and other contributors + * Released under the MIT license + * http://sizzlejs.com/ + */ +(function( window, undefined ) { + +var cachedruns, + assertGetIdNotName, + Expr, + getText, + isXML, + contains, + compile, + sortOrder, + hasDuplicate, + outermostContext, + + baseHasDuplicate = true, + strundefined = "undefined", + + expando = ( "sizcache" + Math.random() ).replace( ".", "" ), + + Token = String, + document = window.document, + docElem = document.documentElement, + dirruns = 0, + done = 0, + pop = [].pop, + push = [].push, + slice = [].slice, + // Use a stripped-down indexOf if a native one is unavailable + indexOf = [].indexOf || function( elem ) { + var i = 0, + len = this.length; + for ( ; i < len; i++ ) { + if ( this[i] === elem ) { + return i; + } + } + return -1; + }, + + // Augment a function for special use by Sizzle + markFunction = function( fn, value ) { + fn[ expando ] = value == null || value; + return fn; + }, + + createCache = function() { + var cache = {}, + keys = []; + + return markFunction(function( key, value ) { + // Only keep the most recent entries + if ( keys.push( key ) > Expr.cacheLength ) { + delete cache[ keys.shift() ]; + } + + return (cache[ key ] = value); + }, cache ); + }, + + classCache = createCache(), + tokenCache = createCache(), + compilerCache = createCache(), + + // Regex + + // Whitespace characters http://www.w3.org/TR/css3-selectors/#whitespace + whitespace = "[\\x20\\t\\r\\n\\f]", + // http://www.w3.org/TR/css3-syntax/#characters + characterEncoding = "(?:\\\\.|[-\\w]|[^\\x00-\\xa0])+", + + // Loosely modeled on CSS identifier characters + // An unquoted value should be a CSS identifier (http://www.w3.org/TR/css3-selectors/#attribute-selectors) + // Proper syntax: http://www.w3.org/TR/CSS21/syndata.html#value-def-identifier + identifier = characterEncoding.replace( "w", "w#" ), + + // Acceptable operators http://www.w3.org/TR/selectors/#attribute-selectors + operators = "([*^$|!~]?=)", + attributes = "\\[" + whitespace + "*(" + characterEncoding + ")" + whitespace + + "*(?:" + operators + whitespace + "*(?:(['\"])((?:\\\\.|[^\\\\])*?)\\3|(" + identifier + ")|)|)" + whitespace + "*\\]", + + // Prefer arguments not in parens/brackets, + // then attribute selectors and non-pseudos (denoted by :), + // then anything else + // These preferences are here to reduce the number of selectors + // needing tokenize in the PSEUDO preFilter + pseudos = ":(" + characterEncoding + ")(?:\\((?:(['\"])((?:\\\\.|[^\\\\])*?)\\2|([^()[\\]]*|(?:(?:" + attributes + ")|[^:]|\\\\.)*|.*))\\)|)", + + // For matchExpr.POS and matchExpr.needsContext + pos = ":(even|odd|eq|gt|lt|nth|first|last)(?:\\(" + whitespace + + "*((?:-\\d)?\\d*)" + whitespace + "*\\)|)(?=[^-]|$)", + + // Leading and non-escaped trailing whitespace, capturing some non-whitespace characters preceding the latter + rtrim = new RegExp( "^" + whitespace + "+|((?:^|[^\\\\])(?:\\\\.)*)" + whitespace + "+$", "g" ), + + rcomma = new RegExp( "^" + whitespace + "*," + whitespace + "*" ), + rcombinators = new RegExp( "^" + whitespace + "*([\\x20\\t\\r\\n\\f>+~])" + whitespace + "*" ), + rpseudo = new RegExp( pseudos ), + + // Easily-parseable/retrievable ID or TAG or CLASS selectors + rquickExpr = /^(?:#([\w\-]+)|(\w+)|\.([\w\-]+))$/, + + rnot = /^:not/, + rsibling = /[\x20\t\r\n\f]*[+~]/, + rendsWithNot = /:not\($/, + + rheader = /h\d/i, + rinputs = /input|select|textarea|button/i, + + rbackslash = /\\(?!\\)/g, + + matchExpr = { + "ID": new RegExp( "^#(" + characterEncoding + ")" ), + "CLASS": new RegExp( "^\\.(" + characterEncoding + ")" ), + "NAME": new RegExp( "^\\[name=['\"]?(" + characterEncoding + ")['\"]?\\]" ), + "TAG": new RegExp( "^(" + characterEncoding.replace( "w", "w*" ) + ")" ), + "ATTR": new RegExp( "^" + attributes ), + "PSEUDO": new RegExp( "^" + pseudos ), + "POS": new RegExp( pos, "i" ), + "CHILD": new RegExp( "^:(only|nth|first|last)-child(?:\\(" + whitespace + + "*(even|odd|(([+-]|)(\\d*)n|)" + whitespace + "*(?:([+-]|)" + whitespace + + "*(\\d+)|))" + whitespace + "*\\)|)", "i" ), + // For use in libraries implementing .is() + "needsContext": new RegExp( "^" + whitespace + "*[>+~]|" + pos, "i" ) + }, + + // Support + + // Used for testing something on an element + assert = function( fn ) { + var div = document.createElement("div"); + + try { + return fn( div ); + } catch (e) { + return false; + } finally { + // release memory in IE + div = null; + } + }, + + // Check if getElementsByTagName("*") returns only elements + assertTagNameNoComments = assert(function( div ) { + div.appendChild( document.createComment("") ); + return !div.getElementsByTagName("*").length; + }), + + // Check if getAttribute returns normalized href attributes + assertHrefNotNormalized = assert(function( div ) { + div.innerHTML = ""; + return div.firstChild && typeof div.firstChild.getAttribute !== strundefined && + div.firstChild.getAttribute("href") === "#"; + }), + + // Check if attributes should be retrieved by attribute nodes + assertAttributes = assert(function( div ) { + div.innerHTML = ""; + var type = typeof div.lastChild.getAttribute("multiple"); + // IE8 returns a string for some attributes even when not present + return type !== "boolean" && type !== "string"; + }), + + // Check if getElementsByClassName can be trusted + assertUsableClassName = assert(function( div ) { + // Opera can't find a second classname (in 9.6) + div.innerHTML = ""; + if ( !div.getElementsByClassName || !div.getElementsByClassName("e").length ) { + return false; + } + + // Safari 3.2 caches class attributes and doesn't catch changes + div.lastChild.className = "e"; + return div.getElementsByClassName("e").length === 2; + }), + + // Check if getElementById returns elements by name + // Check if getElementsByName privileges form controls or returns elements by ID + assertUsableName = assert(function( div ) { + // Inject content + div.id = expando + 0; + div.innerHTML = "
      "; + docElem.insertBefore( div, docElem.firstChild ); + + // Test + var pass = document.getElementsByName && + // buggy browsers will return fewer than the correct 2 + document.getElementsByName( expando ).length === 2 + + // buggy browsers will return more than the correct 0 + document.getElementsByName( expando + 0 ).length; + assertGetIdNotName = !document.getElementById( expando ); + + // Cleanup + docElem.removeChild( div ); + + return pass; + }); + +// If slice is not available, provide a backup +try { + slice.call( docElem.childNodes, 0 )[0].nodeType; +} catch ( e ) { + slice = function( i ) { + var elem, + results = []; + for ( ; (elem = this[i]); i++ ) { + results.push( elem ); + } + return results; + }; +} + +function Sizzle( selector, context, results, seed ) { + results = results || []; + context = context || document; + var match, elem, xml, m, + nodeType = context.nodeType; + + if ( !selector || typeof selector !== "string" ) { + return results; + } + + if ( nodeType !== 1 && nodeType !== 9 ) { + return []; + } + + xml = isXML( context ); + + if ( !xml && !seed ) { + if ( (match = rquickExpr.exec( selector )) ) { + // Speed-up: Sizzle("#ID") + if ( (m = match[1]) ) { + if ( nodeType === 9 ) { + elem = context.getElementById( m ); + // 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, Opera, and Webkit return items + // by name instead of ID + if ( elem.id === m ) { + results.push( elem ); + return results; + } + } else { + return results; + } + } else { + // Context is not a document + if ( context.ownerDocument && (elem = context.ownerDocument.getElementById( m )) && + contains( context, elem ) && elem.id === m ) { + results.push( elem ); + return results; + } + } + + // Speed-up: Sizzle("TAG") + } else if ( match[2] ) { + push.apply( results, slice.call(context.getElementsByTagName( selector ), 0) ); + return results; + + // Speed-up: Sizzle(".CLASS") + } else if ( (m = match[3]) && assertUsableClassName && context.getElementsByClassName ) { + push.apply( results, slice.call(context.getElementsByClassName( m ), 0) ); + return results; + } + } + } + + // All others + return select( selector.replace( rtrim, "$1" ), context, results, seed, xml ); +} + +Sizzle.matches = function( expr, elements ) { + return Sizzle( expr, null, null, elements ); +}; + +Sizzle.matchesSelector = function( elem, expr ) { + return Sizzle( expr, null, null, [ elem ] ).length > 0; +}; + +// Returns a function to use in pseudos for input types +function createInputPseudo( type ) { + return function( elem ) { + var name = elem.nodeName.toLowerCase(); + return name === "input" && elem.type === type; + }; +} + +// Returns a function to use in pseudos for buttons +function createButtonPseudo( type ) { + return function( elem ) { + var name = elem.nodeName.toLowerCase(); + return (name === "input" || name === "button") && elem.type === type; + }; +} + +// Returns a function to use in pseudos for positionals +function createPositionalPseudo( fn ) { + return markFunction(function( argument ) { + argument = +argument; + return markFunction(function( seed, matches ) { + var j, + matchIndexes = fn( [], seed.length, argument ), + i = matchIndexes.length; + + // Match elements found at the specified indexes + while ( i-- ) { + if ( seed[ (j = matchIndexes[i]) ] ) { + seed[j] = !(matches[j] = seed[j]); + } + } + }); + }); +} + +/** + * Utility function for retrieving the text value of an array of DOM nodes + * @param {Array|Element} elem + */ +getText = Sizzle.getText = function( elem ) { + var node, + ret = "", + i = 0, + nodeType = elem.nodeType; + + if ( nodeType ) { + if ( nodeType === 1 || nodeType === 9 || nodeType === 11 ) { + // Use textContent for elements + // innerText usage removed for consistency of new lines (see #11153) + if ( typeof elem.textContent === "string" ) { + return elem.textContent; + } else { + // Traverse its children + for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) { + ret += getText( elem ); + } + } + } else if ( nodeType === 3 || nodeType === 4 ) { + return elem.nodeValue; + } + // Do not include comment or processing instruction nodes + } else { + + // If no nodeType, this is expected to be an array + for ( ; (node = elem[i]); i++ ) { + // Do not traverse comment nodes + ret += getText( node ); + } + } + return ret; +}; + +isXML = 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).documentElement; + return documentElement ? documentElement.nodeName !== "HTML" : false; +}; + +// Element contains another +contains = Sizzle.contains = docElem.contains ? + function( a, b ) { + var adown = a.nodeType === 9 ? a.documentElement : a, + bup = b && b.parentNode; + return a === bup || !!( bup && bup.nodeType === 1 && adown.contains && adown.contains(bup) ); + } : + docElem.compareDocumentPosition ? + function( a, b ) { + return b && !!( a.compareDocumentPosition( b ) & 16 ); + } : + function( a, b ) { + while ( (b = b.parentNode) ) { + if ( b === a ) { + return true; + } + } + return false; + }; + +Sizzle.attr = function( elem, name ) { + var val, + xml = isXML( elem ); + + if ( !xml ) { + name = name.toLowerCase(); + } + if ( (val = Expr.attrHandle[ name ]) ) { + return val( elem ); + } + if ( xml || assertAttributes ) { + return elem.getAttribute( name ); + } + val = elem.getAttributeNode( name ); + return val ? + typeof elem[ name ] === "boolean" ? + elem[ name ] ? name : null : + val.specified ? val.value : null : + null; +}; + +Expr = Sizzle.selectors = { + + // Can be adjusted by the user + cacheLength: 50, + + createPseudo: markFunction, + + match: matchExpr, + + // IE6/7 return a modified href + attrHandle: assertHrefNotNormalized ? + {} : + { + "href": function( elem ) { + return elem.getAttribute( "href", 2 ); + }, + "type": function( elem ) { + return elem.getAttribute("type"); + } + }, + + find: { + "ID": assertGetIdNotName ? + function( id, context, xml ) { + if ( typeof context.getElementById !== strundefined && !xml ) { + var m = context.getElementById( id ); + // Check parentNode to catch when Blackberry 4.6 returns + // nodes that are no longer in the document #6963 + return m && m.parentNode ? [m] : []; + } + } : + function( id, context, xml ) { + if ( typeof context.getElementById !== strundefined && !xml ) { + var m = context.getElementById( id ); + + return m ? + m.id === id || typeof m.getAttributeNode !== strundefined && m.getAttributeNode("id").value === id ? + [m] : + undefined : + []; + } + }, + + "TAG": assertTagNameNoComments ? + function( tag, context ) { + if ( typeof context.getElementsByTagName !== strundefined ) { + return context.getElementsByTagName( tag ); + } + } : + function( tag, context ) { + var results = context.getElementsByTagName( tag ); + + // Filter out possible comments + if ( tag === "*" ) { + var elem, + tmp = [], + i = 0; + + for ( ; (elem = results[i]); i++ ) { + if ( elem.nodeType === 1 ) { + tmp.push( elem ); + } + } + + return tmp; + } + return results; + }, + + "NAME": assertUsableName && function( tag, context ) { + if ( typeof context.getElementsByName !== strundefined ) { + return context.getElementsByName( name ); + } + }, + + "CLASS": assertUsableClassName && function( className, context, xml ) { + if ( typeof context.getElementsByClassName !== strundefined && !xml ) { + return context.getElementsByClassName( className ); + } + } + }, + + relative: { + ">": { dir: "parentNode", first: true }, + " ": { dir: "parentNode" }, + "+": { dir: "previousSibling", first: true }, + "~": { dir: "previousSibling" } + }, + + preFilter: { + "ATTR": function( match ) { + match[1] = match[1].replace( rbackslash, "" ); + + // Move the given value to match[3] whether quoted or unquoted + match[3] = ( match[4] || match[5] || "" ).replace( rbackslash, "" ); + + if ( match[2] === "~=" ) { + match[3] = " " + match[3] + " "; + } + + return match.slice( 0, 4 ); + }, + + "CHILD": function( match ) { + /* matches from matchExpr["CHILD"] + 1 type (only|nth|...) + 2 argument (even|odd|\d*|\d*n([+-]\d+)?|...) + 3 xn-component of xn+y argument ([+-]?\d*n|) + 4 sign of xn-component + 5 x of xn-component + 6 sign of y-component + 7 y of y-component + */ + match[1] = match[1].toLowerCase(); + + if ( match[1] === "nth" ) { + // nth-child requires argument + if ( !match[2] ) { + Sizzle.error( match[0] ); + } + + // numeric x and y parameters for Expr.filter.CHILD + // remember that false/true cast respectively to 0/1 + match[3] = +( match[3] ? match[4] + (match[5] || 1) : 2 * ( match[2] === "even" || match[2] === "odd" ) ); + match[4] = +( ( match[6] + match[7] ) || match[2] === "odd" ); + + // other types prohibit arguments + } else if ( match[2] ) { + Sizzle.error( match[0] ); + } + + return match; + }, + + "PSEUDO": function( match ) { + var unquoted, excess; + if ( matchExpr["CHILD"].test( match[0] ) ) { + return null; + } + + if ( match[3] ) { + match[2] = match[3]; + } else if ( (unquoted = match[4]) ) { + // Only check arguments that contain a pseudo + if ( rpseudo.test(unquoted) && + // Get excess from tokenize (recursively) + (excess = tokenize( unquoted, true )) && + // advance to the next closing parenthesis + (excess = unquoted.indexOf( ")", unquoted.length - excess ) - unquoted.length) ) { + + // excess is a negative index + unquoted = unquoted.slice( 0, excess ); + match[0] = match[0].slice( 0, excess ); + } + match[2] = unquoted; + } + + // Return only captures needed by the pseudo filter method (type and argument) + return match.slice( 0, 3 ); + } + }, + + filter: { + "ID": assertGetIdNotName ? + function( id ) { + id = id.replace( rbackslash, "" ); + return function( elem ) { + return elem.getAttribute("id") === id; + }; + } : + function( id ) { + id = id.replace( rbackslash, "" ); + return function( elem ) { + var node = typeof elem.getAttributeNode !== strundefined && elem.getAttributeNode("id"); + return node && node.value === id; + }; + }, + + "TAG": function( nodeName ) { + if ( nodeName === "*" ) { + return function() { return true; }; + } + nodeName = nodeName.replace( rbackslash, "" ).toLowerCase(); + + return function( elem ) { + return elem.nodeName && elem.nodeName.toLowerCase() === nodeName; + }; + }, + + "CLASS": function( className ) { + var pattern = classCache[ expando ][ className ]; + if ( !pattern ) { + pattern = classCache( className, new RegExp("(^|" + whitespace + ")" + className + "(" + whitespace + "|$)") ); + } + return function( elem ) { + return pattern.test( elem.className || (typeof elem.getAttribute !== strundefined && elem.getAttribute("class")) || "" ); + }; + }, + + "ATTR": function( name, operator, check ) { + return function( elem, context ) { + var result = Sizzle.attr( elem, name ); + + if ( result == null ) { + return operator === "!="; + } + if ( !operator ) { + return true; + } + + result += ""; + + return operator === "=" ? result === check : + operator === "!=" ? result !== check : + operator === "^=" ? check && result.indexOf( check ) === 0 : + operator === "*=" ? check && result.indexOf( check ) > -1 : + operator === "$=" ? check && result.substr( result.length - check.length ) === check : + operator === "~=" ? ( " " + result + " " ).indexOf( check ) > -1 : + operator === "|=" ? result === check || result.substr( 0, check.length + 1 ) === check + "-" : + false; + }; + }, + + "CHILD": function( type, argument, first, last ) { + + if ( type === "nth" ) { + return function( elem ) { + var node, diff, + parent = elem.parentNode; + + if ( first === 1 && last === 0 ) { + return true; + } + + if ( parent ) { + diff = 0; + for ( node = parent.firstChild; node; node = node.nextSibling ) { + if ( node.nodeType === 1 ) { + diff++; + if ( elem === node ) { + break; + } + } + } + } + + // Incorporate the offset (or cast to NaN), then check against cycle size + diff -= last; + return diff === first || ( diff % first === 0 && diff / first >= 0 ); + }; + } + + return function( elem ) { + var 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; + + /* falls through */ + case "last": + while ( (node = node.nextSibling) ) { + if ( node.nodeType === 1 ) { + return false; + } + } + + return true; + } + }; + }, + + "PSEUDO": function( pseudo, argument ) { + // pseudo-class names are case-insensitive + // http://www.w3.org/TR/selectors/#pseudo-classes + // Prioritize by case sensitivity in case custom pseudos are added with uppercase letters + // Remember that setFilters inherits from pseudos + var args, + fn = Expr.pseudos[ pseudo ] || Expr.setFilters[ pseudo.toLowerCase() ] || + Sizzle.error( "unsupported pseudo: " + pseudo ); + + // The user may use createPseudo to indicate that + // arguments are needed to create the filter function + // just as Sizzle does + if ( fn[ expando ] ) { + return fn( argument ); + } + + // But maintain support for old signatures + if ( fn.length > 1 ) { + args = [ pseudo, pseudo, "", argument ]; + return Expr.setFilters.hasOwnProperty( pseudo.toLowerCase() ) ? + markFunction(function( seed, matches ) { + var idx, + matched = fn( seed, argument ), + i = matched.length; + while ( i-- ) { + idx = indexOf.call( seed, matched[i] ); + seed[ idx ] = !( matches[ idx ] = matched[i] ); + } + }) : + function( elem ) { + return fn( elem, 0, args ); + }; + } + + return fn; + } + }, + + pseudos: { + "not": markFunction(function( selector ) { + // Trim the selector passed to compile + // to avoid treating leading and trailing + // spaces as combinators + var input = [], + results = [], + matcher = compile( selector.replace( rtrim, "$1" ) ); + + return matcher[ expando ] ? + markFunction(function( seed, matches, context, xml ) { + var elem, + unmatched = matcher( seed, null, xml, [] ), + i = seed.length; + + // Match elements unmatched by `matcher` + while ( i-- ) { + if ( (elem = unmatched[i]) ) { + seed[i] = !(matches[i] = elem); + } + } + }) : + function( elem, context, xml ) { + input[0] = elem; + matcher( input, null, xml, results ); + return !results.pop(); + }; + }), + + "has": markFunction(function( selector ) { + return function( elem ) { + return Sizzle( selector, elem ).length > 0; + }; + }), + + "contains": markFunction(function( text ) { + return function( elem ) { + return ( elem.textContent || elem.innerText || getText( elem ) ).indexOf( text ) > -1; + }; + }), + + "enabled": function( elem ) { + return elem.disabled === false; + }, + + "disabled": function( elem ) { + return elem.disabled === true; + }, + + "checked": function( elem ) { + // In CSS3, :checked should return both checked and selected elements + // http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked + var nodeName = elem.nodeName.toLowerCase(); + return (nodeName === "input" && !!elem.checked) || (nodeName === "option" && !!elem.selected); + }, + + "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 !Expr.pseudos["empty"]( elem ); + }, + + "empty": function( elem ) { + // http://www.w3.org/TR/selectors/#empty-pseudo + // :empty is only affected by element nodes and content nodes(including text(3), cdata(4)), + // not comment, processing instructions, or others + // Thanks to Diego Perini for the nodeName shortcut + // Greater than "@" means alpha characters (specifically not starting with "#" or "?") + var nodeType; + elem = elem.firstChild; + while ( elem ) { + if ( elem.nodeName > "@" || (nodeType = elem.nodeType) === 3 || nodeType === 4 ) { + return false; + } + elem = elem.nextSibling; + } + return true; + }, + + "header": function( elem ) { + return rheader.test( elem.nodeName ); + }, + + "text": function( elem ) { + var type, attr; + // 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" && + (type = elem.type) === "text" && + ( (attr = elem.getAttribute("type")) == null || attr.toLowerCase() === type ); + }, + + // Input types + "radio": createInputPseudo("radio"), + "checkbox": createInputPseudo("checkbox"), + "file": createInputPseudo("file"), + "password": createInputPseudo("password"), + "image": createInputPseudo("image"), + + "submit": createButtonPseudo("submit"), + "reset": createButtonPseudo("reset"), + + "button": function( elem ) { + var name = elem.nodeName.toLowerCase(); + return name === "input" && elem.type === "button" || name === "button"; + }, + + "input": function( elem ) { + return rinputs.test( elem.nodeName ); + }, + + "focus": function( elem ) { + var doc = elem.ownerDocument; + return elem === doc.activeElement && (!doc.hasFocus || doc.hasFocus()) && !!(elem.type || elem.href); + }, + + "active": function( elem ) { + return elem === elem.ownerDocument.activeElement; + }, + + // Positional types + "first": createPositionalPseudo(function( matchIndexes, length, argument ) { + return [ 0 ]; + }), + + "last": createPositionalPseudo(function( matchIndexes, length, argument ) { + return [ length - 1 ]; + }), + + "eq": createPositionalPseudo(function( matchIndexes, length, argument ) { + return [ argument < 0 ? argument + length : argument ]; + }), + + "even": createPositionalPseudo(function( matchIndexes, length, argument ) { + for ( var i = 0; i < length; i += 2 ) { + matchIndexes.push( i ); + } + return matchIndexes; + }), + + "odd": createPositionalPseudo(function( matchIndexes, length, argument ) { + for ( var i = 1; i < length; i += 2 ) { + matchIndexes.push( i ); + } + return matchIndexes; + }), + + "lt": createPositionalPseudo(function( matchIndexes, length, argument ) { + for ( var i = argument < 0 ? argument + length : argument; --i >= 0; ) { + matchIndexes.push( i ); + } + return matchIndexes; + }), + + "gt": createPositionalPseudo(function( matchIndexes, length, argument ) { + for ( var i = argument < 0 ? argument + length : argument; ++i < length; ) { + matchIndexes.push( i ); + } + return matchIndexes; + }) + } +}; + +function siblingCheck( a, b, ret ) { + if ( a === b ) { + return ret; + } + + var cur = a.nextSibling; + + while ( cur ) { + if ( cur === b ) { + return -1; + } + + cur = cur.nextSibling; + } + + return 1; +} + +sortOrder = docElem.compareDocumentPosition ? + function( a, b ) { + if ( a === b ) { + hasDuplicate = true; + return 0; + } + + return ( !a.compareDocumentPosition || !b.compareDocumentPosition ? + a.compareDocumentPosition : + a.compareDocumentPosition(b) & 4 + ) ? -1 : 1; + } : + 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 ); + }; + +// Always assume the presence of duplicates if sort doesn't +// pass them to our comparison function (as in Google Chrome). +[0, 0].sort( sortOrder ); +baseHasDuplicate = !hasDuplicate; + +// Document sorting and removing duplicates +Sizzle.uniqueSort = function( results ) { + var elem, + i = 1; + + hasDuplicate = baseHasDuplicate; + results.sort( sortOrder ); + + if ( hasDuplicate ) { + for ( ; (elem = results[i]); i++ ) { + if ( elem === results[ i - 1 ] ) { + results.splice( i--, 1 ); + } + } + } + + return results; +}; + +Sizzle.error = function( msg ) { + throw new Error( "Syntax error, unrecognized expression: " + msg ); +}; + +function tokenize( selector, parseOnly ) { + var matched, match, tokens, type, soFar, groups, preFilters, + cached = tokenCache[ expando ][ selector ]; + + if ( cached ) { + return parseOnly ? 0 : cached.slice( 0 ); + } + + soFar = selector; + groups = []; + preFilters = Expr.preFilter; + + while ( soFar ) { + + // Comma and first run + if ( !matched || (match = rcomma.exec( soFar )) ) { + if ( match ) { + soFar = soFar.slice( match[0].length ); + } + groups.push( tokens = [] ); + } + + matched = false; + + // Combinators + if ( (match = rcombinators.exec( soFar )) ) { + tokens.push( matched = new Token( match.shift() ) ); + soFar = soFar.slice( matched.length ); + + // Cast descendant combinators to space + matched.type = match[0].replace( rtrim, " " ); + } + + // Filters + for ( type in Expr.filter ) { + if ( (match = matchExpr[ type ].exec( soFar )) && (!preFilters[ type ] || + // The last two arguments here are (context, xml) for backCompat + (match = preFilters[ type ]( match, document, true ))) ) { + + tokens.push( matched = new Token( match.shift() ) ); + soFar = soFar.slice( matched.length ); + matched.type = type; + matched.matches = match; + } + } + + if ( !matched ) { + break; + } + } + + // Return the length of the invalid excess + // if we're just parsing + // Otherwise, throw an error or return tokens + return parseOnly ? + soFar.length : + soFar ? + Sizzle.error( selector ) : + // Cache the tokens + tokenCache( selector, groups ).slice( 0 ); +} + +function addCombinator( matcher, combinator, base ) { + var dir = combinator.dir, + checkNonElements = base && combinator.dir === "parentNode", + doneName = done++; + + return combinator.first ? + // Check against closest ancestor/preceding element + function( elem, context, xml ) { + while ( (elem = elem[ dir ]) ) { + if ( checkNonElements || elem.nodeType === 1 ) { + return matcher( elem, context, xml ); + } + } + } : + + // Check against all ancestor/preceding elements + function( elem, context, xml ) { + // We can't set arbitrary data on XML nodes, so they don't benefit from dir caching + if ( !xml ) { + var cache, + dirkey = dirruns + " " + doneName + " ", + cachedkey = dirkey + cachedruns; + while ( (elem = elem[ dir ]) ) { + if ( checkNonElements || elem.nodeType === 1 ) { + if ( (cache = elem[ expando ]) === cachedkey ) { + return elem.sizset; + } else if ( typeof cache === "string" && cache.indexOf(dirkey) === 0 ) { + if ( elem.sizset ) { + return elem; + } + } else { + elem[ expando ] = cachedkey; + if ( matcher( elem, context, xml ) ) { + elem.sizset = true; + return elem; + } + elem.sizset = false; + } + } + } + } else { + while ( (elem = elem[ dir ]) ) { + if ( checkNonElements || elem.nodeType === 1 ) { + if ( matcher( elem, context, xml ) ) { + return elem; + } + } + } + } + }; +} + +function elementMatcher( matchers ) { + return matchers.length > 1 ? + function( elem, context, xml ) { + var i = matchers.length; + while ( i-- ) { + if ( !matchers[i]( elem, context, xml ) ) { + return false; + } + } + return true; + } : + matchers[0]; +} + +function condense( unmatched, map, filter, context, xml ) { + var elem, + newUnmatched = [], + i = 0, + len = unmatched.length, + mapped = map != null; + + for ( ; i < len; i++ ) { + if ( (elem = unmatched[i]) ) { + if ( !filter || filter( elem, context, xml ) ) { + newUnmatched.push( elem ); + if ( mapped ) { + map.push( i ); + } + } + } + } + + return newUnmatched; +} + +function setMatcher( preFilter, selector, matcher, postFilter, postFinder, postSelector ) { + if ( postFilter && !postFilter[ expando ] ) { + postFilter = setMatcher( postFilter ); + } + if ( postFinder && !postFinder[ expando ] ) { + postFinder = setMatcher( postFinder, postSelector ); + } + return markFunction(function( seed, results, context, xml ) { + // Positional selectors apply to seed elements, so it is invalid to follow them with relative ones + if ( seed && postFinder ) { + return; + } + + var i, elem, postFilterIn, + preMap = [], + postMap = [], + preexisting = results.length, + + // Get initial elements from seed or context + elems = seed || multipleContexts( selector || "*", context.nodeType ? [ context ] : context, [], seed ), + + // Prefilter to get matcher input, preserving a map for seed-results synchronization + matcherIn = preFilter && ( seed || !selector ) ? + condense( elems, preMap, preFilter, context, xml ) : + elems, + + matcherOut = matcher ? + // If we have a postFinder, or filtered seed, or non-seed postFilter or preexisting results, + postFinder || ( seed ? preFilter : preexisting || postFilter ) ? + + // ...intermediate processing is necessary + [] : + + // ...otherwise use results directly + results : + matcherIn; + + // Find primary matches + if ( matcher ) { + matcher( matcherIn, matcherOut, context, xml ); + } + + // Apply postFilter + if ( postFilter ) { + postFilterIn = condense( matcherOut, postMap ); + postFilter( postFilterIn, [], context, xml ); + + // Un-match failing elements by moving them back to matcherIn + i = postFilterIn.length; + while ( i-- ) { + if ( (elem = postFilterIn[i]) ) { + matcherOut[ postMap[i] ] = !(matcherIn[ postMap[i] ] = elem); + } + } + } + + // Keep seed and results synchronized + if ( seed ) { + // Ignore postFinder because it can't coexist with seed + i = preFilter && matcherOut.length; + while ( i-- ) { + if ( (elem = matcherOut[i]) ) { + seed[ preMap[i] ] = !(results[ preMap[i] ] = elem); + } + } + } else { + matcherOut = condense( + matcherOut === results ? + matcherOut.splice( preexisting, matcherOut.length ) : + matcherOut + ); + if ( postFinder ) { + postFinder( null, results, matcherOut, xml ); + } else { + push.apply( results, matcherOut ); + } + } + }); +} + +function matcherFromTokens( tokens ) { + var checkContext, matcher, j, + len = tokens.length, + leadingRelative = Expr.relative[ tokens[0].type ], + implicitRelative = leadingRelative || Expr.relative[" "], + i = leadingRelative ? 1 : 0, + + // The foundational matcher ensures that elements are reachable from top-level context(s) + matchContext = addCombinator( function( elem ) { + return elem === checkContext; + }, implicitRelative, true ), + matchAnyContext = addCombinator( function( elem ) { + return indexOf.call( checkContext, elem ) > -1; + }, implicitRelative, true ), + matchers = [ function( elem, context, xml ) { + return ( !leadingRelative && ( xml || context !== outermostContext ) ) || ( + (checkContext = context).nodeType ? + matchContext( elem, context, xml ) : + matchAnyContext( elem, context, xml ) ); + } ]; + + for ( ; i < len; i++ ) { + if ( (matcher = Expr.relative[ tokens[i].type ]) ) { + matchers = [ addCombinator( elementMatcher( matchers ), matcher ) ]; + } else { + // The concatenated values are (context, xml) for backCompat + matcher = Expr.filter[ tokens[i].type ].apply( null, tokens[i].matches ); + + // Return special upon seeing a positional matcher + if ( matcher[ expando ] ) { + // Find the next relative operator (if any) for proper handling + j = ++i; + for ( ; j < len; j++ ) { + if ( Expr.relative[ tokens[j].type ] ) { + break; + } + } + return setMatcher( + i > 1 && elementMatcher( matchers ), + i > 1 && tokens.slice( 0, i - 1 ).join("").replace( rtrim, "$1" ), + matcher, + i < j && matcherFromTokens( tokens.slice( i, j ) ), + j < len && matcherFromTokens( (tokens = tokens.slice( j )) ), + j < len && tokens.join("") + ); + } + matchers.push( matcher ); + } + } + + return elementMatcher( matchers ); +} + +function matcherFromGroupMatchers( elementMatchers, setMatchers ) { + var bySet = setMatchers.length > 0, + byElement = elementMatchers.length > 0, + superMatcher = function( seed, context, xml, results, expandContext ) { + var elem, j, matcher, + setMatched = [], + matchedCount = 0, + i = "0", + unmatched = seed && [], + outermost = expandContext != null, + contextBackup = outermostContext, + // We must always have either seed elements or context + elems = seed || byElement && Expr.find["TAG"]( "*", expandContext && context.parentNode || context ), + // Nested matchers should use non-integer dirruns + dirrunsUnique = (dirruns += contextBackup == null ? 1 : Math.E); + + if ( outermost ) { + outermostContext = context !== document && context; + cachedruns = superMatcher.el; + } + + // Add elements passing elementMatchers directly to results + for ( ; (elem = elems[i]) != null; i++ ) { + if ( byElement && elem ) { + for ( j = 0; (matcher = elementMatchers[j]); j++ ) { + if ( matcher( elem, context, xml ) ) { + results.push( elem ); + break; + } + } + if ( outermost ) { + dirruns = dirrunsUnique; + cachedruns = ++superMatcher.el; + } + } + + // Track unmatched elements for set filters + if ( bySet ) { + // They will have gone through all possible matchers + if ( (elem = !matcher && elem) ) { + matchedCount--; + } + + // Lengthen the array for every element, matched or not + if ( seed ) { + unmatched.push( elem ); + } + } + } + + // Apply set filters to unmatched elements + matchedCount += i; + if ( bySet && i !== matchedCount ) { + for ( j = 0; (matcher = setMatchers[j]); j++ ) { + matcher( unmatched, setMatched, context, xml ); + } + + if ( seed ) { + // Reintegrate element matches to eliminate the need for sorting + if ( matchedCount > 0 ) { + while ( i-- ) { + if ( !(unmatched[i] || setMatched[i]) ) { + setMatched[i] = pop.call( results ); + } + } + } + + // Discard index placeholder values to get only actual matches + setMatched = condense( setMatched ); + } + + // Add matches to results + push.apply( results, setMatched ); + + // Seedless set matches succeeding multiple successful matchers stipulate sorting + if ( outermost && !seed && setMatched.length > 0 && + ( matchedCount + setMatchers.length ) > 1 ) { + + Sizzle.uniqueSort( results ); + } + } + + // Override manipulation of globals by nested matchers + if ( outermost ) { + dirruns = dirrunsUnique; + outermostContext = contextBackup; + } + + return unmatched; + }; + + superMatcher.el = 0; + return bySet ? + markFunction( superMatcher ) : + superMatcher; +} + +compile = Sizzle.compile = function( selector, group /* Internal Use Only */ ) { + var i, + setMatchers = [], + elementMatchers = [], + cached = compilerCache[ expando ][ selector ]; + + if ( !cached ) { + // Generate a function of recursive functions that can be used to check each element + if ( !group ) { + group = tokenize( selector ); + } + i = group.length; + while ( i-- ) { + cached = matcherFromTokens( group[i] ); + if ( cached[ expando ] ) { + setMatchers.push( cached ); + } else { + elementMatchers.push( cached ); + } + } + + // Cache the compiled function + cached = compilerCache( selector, matcherFromGroupMatchers( elementMatchers, setMatchers ) ); + } + return cached; +}; + +function multipleContexts( selector, contexts, results, seed ) { + var i = 0, + len = contexts.length; + for ( ; i < len; i++ ) { + Sizzle( selector, contexts[i], results, seed ); + } + return results; +} + +function select( selector, context, results, seed, xml ) { + var i, tokens, token, type, find, + match = tokenize( selector ), + j = match.length; + + if ( !seed ) { + // Try to minimize operations if there is only one group + if ( match.length === 1 ) { + + // Take a shortcut and set the context if the root selector is an ID + tokens = match[0] = match[0].slice( 0 ); + if ( tokens.length > 2 && (token = tokens[0]).type === "ID" && + context.nodeType === 9 && !xml && + Expr.relative[ tokens[1].type ] ) { + + context = Expr.find["ID"]( token.matches[0].replace( rbackslash, "" ), context, xml )[0]; + if ( !context ) { + return results; + } + + selector = selector.slice( tokens.shift().length ); + } + + // Fetch a seed set for right-to-left matching + for ( i = matchExpr["POS"].test( selector ) ? -1 : tokens.length - 1; i >= 0; i-- ) { + token = tokens[i]; + + // Abort if we hit a combinator + if ( Expr.relative[ (type = token.type) ] ) { + break; + } + if ( (find = Expr.find[ type ]) ) { + // Search, expanding context for leading sibling combinators + if ( (seed = find( + token.matches[0].replace( rbackslash, "" ), + rsibling.test( tokens[0].type ) && context.parentNode || context, + xml + )) ) { + + // If seed is empty or no tokens remain, we can return early + tokens.splice( i, 1 ); + selector = seed.length && tokens.join(""); + if ( !selector ) { + push.apply( results, slice.call( seed, 0 ) ); + return results; + } + + break; + } + } + } + } + } + + // Compile and execute a filtering function + // Provide `match` to avoid retokenization if we modified the selector above + compile( selector, match )( + seed, + context, + xml, + results, + rsibling.test( selector ) + ); + return results; +} + +if ( document.querySelectorAll ) { + (function() { + var disconnectedMatch, + oldSelect = select, + rescape = /'|\\/g, + rattributeQuotes = /\=[\x20\t\r\n\f]*([^'"\]]*)[\x20\t\r\n\f]*\]/g, + + // qSa(:focus) reports false when true (Chrome 21), + // A support test would require too much code (would include document ready) + rbuggyQSA = [":focus"], + + // matchesSelector(:focus) reports false when true (Chrome 21), + // matchesSelector(:active) reports false when true (IE9/Opera 11.5) + // A support test would require too much code (would include document ready) + // just skip matchesSelector for :active + rbuggyMatches = [ ":active", ":focus" ], + matches = docElem.matchesSelector || + docElem.mozMatchesSelector || + docElem.webkitMatchesSelector || + docElem.oMatchesSelector || + docElem.msMatchesSelector; + + // Build QSA regex + // Regex strategy adopted from Diego Perini + assert(function( div ) { + // Select is set to empty string on purpose + // This is to test IE's treatment of not explictly + // setting a boolean content attribute, + // since its presence should be enough + // http://bugs.jquery.com/ticket/12359 + div.innerHTML = ""; + + // IE8 - Some boolean attributes are not treated correctly + if ( !div.querySelectorAll("[selected]").length ) { + rbuggyQSA.push( "\\[" + whitespace + "*(?:checked|disabled|ismap|multiple|readonly|selected|value)" ); + } + + // Webkit/Opera - :checked should return selected option elements + // http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked + // IE8 throws error here (do not put tests after this one) + if ( !div.querySelectorAll(":checked").length ) { + rbuggyQSA.push(":checked"); + } + }); + + assert(function( div ) { + + // Opera 10-12/IE9 - ^= $= *= and empty values + // Should not select anything + div.innerHTML = "

      "; + if ( div.querySelectorAll("[test^='']").length ) { + rbuggyQSA.push( "[*^$]=" + whitespace + "*(?:\"\"|'')" ); + } + + // FF 3.5 - :enabled/:disabled and hidden elements (hidden elements are still enabled) + // IE8 throws error here (do not put tests after this one) + div.innerHTML = ""; + if ( !div.querySelectorAll(":enabled").length ) { + rbuggyQSA.push(":enabled", ":disabled"); + } + }); + + // rbuggyQSA always contains :focus, so no need for a length check + rbuggyQSA = /* rbuggyQSA.length && */ new RegExp( rbuggyQSA.join("|") ); + + select = function( selector, context, results, seed, xml ) { + // Only use querySelectorAll when not filtering, + // when this is not xml, + // and when no QSA bugs apply + if ( !seed && !xml && (!rbuggyQSA || !rbuggyQSA.test( selector )) ) { + var groups, i, + old = true, + nid = expando, + newContext = context, + newSelector = context.nodeType === 9 && selector; + + // 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 + if ( context.nodeType === 1 && context.nodeName.toLowerCase() !== "object" ) { + groups = tokenize( selector ); + + if ( (old = context.getAttribute("id")) ) { + nid = old.replace( rescape, "\\$&" ); + } else { + context.setAttribute( "id", nid ); + } + nid = "[id='" + nid + "'] "; + + i = groups.length; + while ( i-- ) { + groups[i] = nid + groups[i].join(""); + } + newContext = rsibling.test( selector ) && context.parentNode || context; + newSelector = groups.join(","); + } + + if ( newSelector ) { + try { + push.apply( results, slice.call( newContext.querySelectorAll( + newSelector + ), 0 ) ); + return results; + } catch(qsaError) { + } finally { + if ( !old ) { + context.removeAttribute("id"); + } + } + } + } + + return oldSelect( selector, context, results, seed, xml ); + }; + + if ( matches ) { + assert(function( div ) { + // Check to see if it's possible to do matchesSelector + // on a disconnected node (IE 9) + disconnectedMatch = matches.call( div, "div" ); + + // This should fail with an exception + // Gecko does not error, returns false instead + try { + matches.call( div, "[test!='']:sizzle" ); + rbuggyMatches.push( "!=", pseudos ); + } catch ( e ) {} + }); + + // rbuggyMatches always contains :active and :focus, so no need for a length check + rbuggyMatches = /* rbuggyMatches.length && */ new RegExp( rbuggyMatches.join("|") ); + + Sizzle.matchesSelector = function( elem, expr ) { + // Make sure that attribute selectors are quoted + expr = expr.replace( rattributeQuotes, "='$1']" ); + + // rbuggyMatches always contains :active, so no need for an existence check + if ( !isXML( elem ) && !rbuggyMatches.test( expr ) && (!rbuggyQSA || !rbuggyQSA.test( expr )) ) { + try { + var ret = matches.call( elem, 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 + elem.document && elem.document.nodeType !== 11 ) { + return ret; + } + } catch(e) {} + } + + return Sizzle( expr, null, null, [ elem ] ).length > 0; + }; + } + })(); +} + +// Deprecated +Expr.pseudos["nth"] = Expr.pseudos["eq"]; + +// Back-compat +function setFilters() {} +Expr.filters = setFilters.prototype = Expr.pseudos; +Expr.setFilters = new setFilters(); + +// Override sizzle attribute retrieval +Sizzle.attr = jQuery.attr; +jQuery.find = Sizzle; +jQuery.expr = Sizzle.selectors; +jQuery.expr[":"] = jQuery.expr.pseudos; +jQuery.unique = Sizzle.uniqueSort; +jQuery.text = Sizzle.getText; +jQuery.isXMLDoc = Sizzle.isXML; +jQuery.contains = Sizzle.contains; + + +})( window ); +var runtil = /Until$/, + rparentsprev = /^(?:parents|prev(?:Until|All))/, + isSimple = /^.[^:#\[\.,]*$/, + rneedsContext = jQuery.expr.match.needsContext, + // 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 i, l, length, n, r, ret, + self = this; + + 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; + } + } + }); + } + + ret = this.pushStack( "", "find", selector ); + + 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 i, + targets = jQuery( target, this ), + len = targets.length; + + return this.filter(function() { + for ( i = 0; i < len; 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" ? + // If this is a positional/relative selector, check membership in the returned set + // so $("p:first").is("p:last") won't return true for a doc with two "p". + rneedsContext.test( selector ) ? + jQuery( selector, this.context ).index( this[0] ) >= 0 : + jQuery.filter( selector, this ).length > 0 : + this.filter( selector ).length > 0 ); + }, + + closest: function( selectors, context ) { + var cur, + i = 0, + l = this.length, + ret = [], + pos = rneedsContext.test( selectors ) || typeof selectors !== "string" ? + jQuery( selectors, context || this.context ) : + 0; + + for ( ; i < l; i++ ) { + cur = this[i]; + + while ( cur && cur.ownerDocument && cur !== context && cur.nodeType !== 11 ) { + if ( pos ? pos.index(cur) > -1 : jQuery.find.matchesSelector(cur, selectors) ) { + ret.push( cur ); + break; + } + cur = cur.parentNode; + } + } + + 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 ) { + + // No argument, return index in parent + if ( !elem ) { + return ( this[0] && this[0].parentNode ) ? this.prevAll().length : -1; + } + + // index in selector + if ( typeof elem === "string" ) { + return jQuery.inArray( this[0], jQuery( elem ) ); + } + + // 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 ) ); + }, + + addBack: function( selector ) { + return this.add( selector == null ? + this.prevObject : this.prevObject.filter(selector) + ); + } +}); + +jQuery.fn.andSelf = jQuery.fn.addBack; + +// 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; +} + +function sibling( cur, dir ) { + do { + cur = cur[ dir ]; + } while ( cur && cur.nodeType !== 1 ); + + return cur; +} + +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 sibling( elem, "nextSibling" ); + }, + prev: function( elem ) { + return sibling( elem, "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.merge( [], elem.childNodes ); + } +}, function( name, fn ) { + jQuery.fn[ name ] = function( until, selector ) { + var ret = jQuery.map( this, fn, until ); + + 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 && rparentsprev.test( name ) ) { + ret = ret.reverse(); + } + + return this.pushStack( ret, name, core_slice.call( arguments ).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; + }, + + 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; + }); +} +function createSafeFragment( document ) { + var list = nodeNames.split( "|" ), + safeFrag = document.createDocumentFragment(); + + if ( safeFrag.createElement ) { + while ( list.length ) { + safeFrag.createElement( + list.pop() + ); + } + } + return safeFrag; +} + +var nodeNames = "abbr|article|aside|audio|bdi|canvas|data|datalist|details|figcaption|figure|footer|" + + "header|hgroup|mark|meter|nav|output|progress|section|summary|time|video", + rinlinejQuery = / jQuery\d+="(?:null|\d+)"/g, + rleadingWhitespace = /^\s+/, + rxhtmlTag = /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/gi, + rtagName = /<([\w:]+)/, + rtbody = /]", "i"), + rcheckableType = /^(?:checkbox|radio)$/, + // checked="checked" or checked + rchecked = /checked\s*(?:[^=]|=\s*.checked.)/i, + rscriptType = /\/(java|ecma)script/i, + rcleanScript = /^\s*\s*$/g, + wrapMap = { + option: [ 1, "" ], + legend: [ 1, "
      ", "
      " ], + thead: [ 1, "", "
      " ], + tr: [ 2, "", "
      " ], + td: [ 3, "", "
      " ], + col: [ 2, "", "
      " ], + area: [ 1, "", "" ], + _default: [ 0, "", "" ] + }, + safeFragment = createSafeFragment( document ), + fragmentDiv = safeFragment.appendChild( document.createElement("div") ); + +wrapMap.optgroup = wrapMap.option; +wrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead; +wrapMap.th = wrapMap.td; + +// IE6-8 can't serialize link, script, style, or any html5 (NoScope) tags, +// unless wrapped in a div with non-breaking characters in front of it. +if ( !jQuery.support.htmlSerialize ) { + wrapMap._default = [ 1, "X
      ", "
      " ]; +} + +jQuery.fn.extend({ + text: function( value ) { + return jQuery.access( this, function( value ) { + return value === undefined ? + jQuery.text( this ) : + this.empty().append( ( this[0] && this[0].ownerDocument || document ).createTextNode( value ) ); + }, null, value, arguments.length ); + }, + + wrapAll: function( html ) { + if ( jQuery.isFunction( html ) ) { + return this.each(function(i) { + jQuery(this).wrapAll( html.call(this, i) ); + }); + } + + if ( this[0] ) { + // The elements to wrap the target around + var wrap = jQuery( html, this[0].ownerDocument ).eq(0).clone(true); + + if ( this[0].parentNode ) { + wrap.insertBefore( this[0] ); + } + + wrap.map(function() { + var elem = this; + + while ( elem.firstChild && elem.firstChild.nodeType === 1 ) { + elem = elem.firstChild; + } + + return elem; + }).append( this ); + } + + return this; + }, + + wrapInner: function( html ) { + if ( jQuery.isFunction( html ) ) { + return this.each(function(i) { + jQuery(this).wrapInner( html.call(this, i) ); + }); + } + + return this.each(function() { + var self = jQuery( this ), + contents = self.contents(); + + if ( contents.length ) { + contents.wrapAll( html ); + + } else { + self.append( html ); + } + }); + }, + + wrap: function( html ) { + var isFunction = jQuery.isFunction( html ); + + return this.each(function(i) { + jQuery( this ).wrapAll( isFunction ? html.call(this, i) : html ); + }); + }, + + unwrap: function() { + return this.parent().each(function() { + if ( !jQuery.nodeName( this, "body" ) ) { + jQuery( this ).replaceWith( this.childNodes ); + } + }).end(); + }, + + append: function() { + return this.domManip(arguments, true, function( elem ) { + if ( this.nodeType === 1 || this.nodeType === 11 ) { + this.appendChild( elem ); + } + }); + }, + + prepend: function() { + return this.domManip(arguments, true, function( elem ) { + if ( this.nodeType === 1 || this.nodeType === 11 ) { + this.insertBefore( elem, this.firstChild ); + } + }); + }, + + before: function() { + if ( !isDisconnected( this[0] ) ) { + return this.domManip(arguments, false, function( elem ) { + this.parentNode.insertBefore( elem, this ); + }); + } + + if ( arguments.length ) { + var set = jQuery.clean( arguments ); + return this.pushStack( jQuery.merge( set, this ), "before", this.selector ); + } + }, + + after: function() { + if ( !isDisconnected( this[0] ) ) { + return this.domManip(arguments, false, function( elem ) { + this.parentNode.insertBefore( elem, this.nextSibling ); + }); + } + + if ( arguments.length ) { + var set = jQuery.clean( arguments ); + return this.pushStack( jQuery.merge( this, set ), "after", this.selector ); + } + }, + + // keepData is for internal use only--do not document + remove: function( selector, keepData ) { + var elem, + i = 0; + + for ( ; (elem = this[i]) != null; i++ ) { + if ( !selector || jQuery.filter( selector, [ elem ] ).length ) { + if ( !keepData && elem.nodeType === 1 ) { + jQuery.cleanData( elem.getElementsByTagName("*") ); + jQuery.cleanData( [ elem ] ); + } + + if ( elem.parentNode ) { + elem.parentNode.removeChild( elem ); + } + } + } + + return this; + }, + + empty: function() { + var elem, + i = 0; + + for ( ; (elem = this[i]) != null; i++ ) { + // Remove element nodes and prevent memory leaks + if ( elem.nodeType === 1 ) { + jQuery.cleanData( elem.getElementsByTagName("*") ); + } + + // Remove any remaining nodes + while ( elem.firstChild ) { + elem.removeChild( elem.firstChild ); + } + } + + return this; + }, + + clone: function( dataAndEvents, deepDataAndEvents ) { + dataAndEvents = dataAndEvents == null ? false : dataAndEvents; + deepDataAndEvents = deepDataAndEvents == null ? dataAndEvents : deepDataAndEvents; + + return this.map( function () { + return jQuery.clone( this, dataAndEvents, deepDataAndEvents ); + }); + }, + + html: function( value ) { + return jQuery.access( this, function( value ) { + var elem = this[0] || {}, + i = 0, + l = this.length; + + if ( value === undefined ) { + return elem.nodeType === 1 ? + elem.innerHTML.replace( rinlinejQuery, "" ) : + undefined; + } + + // See if we can take a shortcut and just use innerHTML + if ( typeof value === "string" && !rnoInnerhtml.test( value ) && + ( jQuery.support.htmlSerialize || !rnoshimcache.test( value ) ) && + ( jQuery.support.leadingWhitespace || !rleadingWhitespace.test( value ) ) && + !wrapMap[ ( rtagName.exec( value ) || ["", ""] )[1].toLowerCase() ] ) { + + value = value.replace( rxhtmlTag, "<$1>" ); + + try { + for (; i < l; i++ ) { + // Remove element nodes and prevent memory leaks + elem = this[i] || {}; + if ( elem.nodeType === 1 ) { + jQuery.cleanData( elem.getElementsByTagName( "*" ) ); + elem.innerHTML = value; + } + } + + elem = 0; + + // If using innerHTML throws an exception, use the fallback method + } catch(e) {} + } + + if ( elem ) { + this.empty().append( value ); + } + }, null, value, arguments.length ); + }, + + replaceWith: function( value ) { + if ( !isDisconnected( this[0] ) ) { + // Make sure that the elements are removed from the DOM before they are inserted + // this can help fix replacing a parent with child elements + if ( jQuery.isFunction( value ) ) { + return this.each(function(i) { + var self = jQuery(this), old = self.html(); + self.replaceWith( value.call( this, i, old ) ); + }); + } + + if ( typeof value !== "string" ) { + value = jQuery( value ).detach(); + } + + return this.each(function() { + var next = this.nextSibling, + parent = this.parentNode; + + jQuery( this ).remove(); + + if ( next ) { + jQuery(next).before( value ); + } else { + jQuery(parent).append( value ); + } + }); + } + + return this.length ? + this.pushStack( jQuery(jQuery.isFunction(value) ? value() : value), "replaceWith", value ) : + this; + }, + + detach: function( selector ) { + return this.remove( selector, true ); + }, + + domManip: function( args, table, callback ) { + + // Flatten any nested arrays + args = [].concat.apply( [], args ); + + var results, first, fragment, iNoClone, + i = 0, + value = args[0], + scripts = [], + l = this.length; + + // We can't cloneNode fragments that contain checked, in WebKit + if ( !jQuery.support.checkClone && l > 1 && typeof value === "string" && rchecked.test( value ) ) { + return this.each(function() { + jQuery(this).domManip( args, table, callback ); + }); + } + + if ( jQuery.isFunction(value) ) { + return this.each(function(i) { + var self = jQuery(this); + args[0] = value.call( this, i, table ? self.html() : undefined ); + self.domManip( args, table, callback ); + }); + } + + if ( this[0] ) { + results = jQuery.buildFragment( args, this, scripts ); + fragment = results.fragment; + first = fragment.firstChild; + + if ( fragment.childNodes.length === 1 ) { + fragment = first; + } + + if ( first ) { + table = table && jQuery.nodeName( first, "tr" ); + + // Use the original fragment for the last item instead of the first because it can end up + // being emptied incorrectly in certain situations (#8070). + // Fragments from the fragment cache must always be cloned and never used in place. + for ( iNoClone = results.cacheable || l - 1; i < l; i++ ) { + callback.call( + table && jQuery.nodeName( this[i], "table" ) ? + findOrAppend( this[i], "tbody" ) : + this[i], + i === iNoClone ? + fragment : + jQuery.clone( fragment, true, true ) + ); + } + } + + // Fix #11809: Avoid leaking memory + fragment = first = null; + + if ( scripts.length ) { + jQuery.each( scripts, function( i, elem ) { + if ( elem.src ) { + if ( jQuery.ajax ) { + jQuery.ajax({ + url: elem.src, + type: "GET", + dataType: "script", + async: false, + global: false, + "throws": true + }); + } else { + jQuery.error("no ajax"); + } + } else { + jQuery.globalEval( ( elem.text || elem.textContent || elem.innerHTML || "" ).replace( rcleanScript, "" ) ); + } + + if ( elem.parentNode ) { + elem.parentNode.removeChild( elem ); + } + }); + } + } + + return this; + } +}); + +function findOrAppend( elem, tag ) { + return elem.getElementsByTagName( tag )[0] || elem.appendChild( elem.ownerDocument.createElement( tag ) ); +} + +function cloneCopyEvent( src, dest ) { + + if ( dest.nodeType !== 1 || !jQuery.hasData( src ) ) { + return; + } + + var type, i, l, + oldData = jQuery._data( src ), + curData = jQuery._data( dest, oldData ), + events = oldData.events; + + if ( events ) { + delete curData.handle; + curData.events = {}; + + for ( type in events ) { + for ( i = 0, l = events[ type ].length; i < l; i++ ) { + jQuery.event.add( dest, type, events[ type ][ i ] ); + } + } + } + + // make the cloned public data object a copy from the original + if ( curData.data ) { + curData.data = jQuery.extend( {}, curData.data ); + } +} + +function cloneFixAttributes( src, dest ) { + var nodeName; + + // We do not need to do anything for non-Elements + if ( dest.nodeType !== 1 ) { + return; + } + + // clearAttributes removes the attributes, which we don't want, + // but also removes the attachEvent events, which we *do* want + if ( dest.clearAttributes ) { + dest.clearAttributes(); + } + + // mergeAttributes, in contrast, only merges back on the + // original attributes, not the events + if ( dest.mergeAttributes ) { + dest.mergeAttributes( src ); + } + + nodeName = dest.nodeName.toLowerCase(); + + if ( nodeName === "object" ) { + // IE6-10 improperly clones children of object elements using classid. + // IE10 throws NoModificationAllowedError if parent is null, #12132. + if ( dest.parentNode ) { + dest.outerHTML = src.outerHTML; + } + + // This path appears unavoidable for IE9. When cloning an object + // element in IE9, the outerHTML strategy above is not sufficient. + // If the src has innerHTML and the destination does not, + // copy the src.innerHTML into the dest.innerHTML. #10324 + if ( jQuery.support.html5Clone && (src.innerHTML && !jQuery.trim(dest.innerHTML)) ) { + dest.innerHTML = src.innerHTML; + } + + } else if ( nodeName === "input" && rcheckableType.test( src.type ) ) { + // IE6-8 fails to persist the checked state of a cloned checkbox + // or radio button. Worse, IE6-7 fail to give the cloned element + // a checked appearance if the defaultChecked value isn't also set + + dest.defaultChecked = dest.checked = src.checked; + + // IE6-7 get confused and end up setting the value of a cloned + // checkbox/radio button to an empty string instead of "on" + if ( dest.value !== src.value ) { + dest.value = src.value; + } + + // IE6-8 fails to return the selected option to the default selected + // state when cloning options + } else if ( nodeName === "option" ) { + dest.selected = src.defaultSelected; + + // IE6-8 fails to set the defaultValue to the correct value when + // cloning other types of input fields + } else if ( nodeName === "input" || nodeName === "textarea" ) { + dest.defaultValue = src.defaultValue; + + // IE blanks contents when cloning scripts + } else if ( nodeName === "script" && dest.text !== src.text ) { + dest.text = src.text; + } + + // Event data gets referenced instead of copied if the expando + // gets copied too + dest.removeAttribute( jQuery.expando ); +} + +jQuery.buildFragment = function( args, context, scripts ) { + var fragment, cacheable, cachehit, + first = args[ 0 ]; + + // Set context from what may come in as undefined or a jQuery collection or a node + // Updated to fix #12266 where accessing context[0] could throw an exception in IE9/10 & + // also doubles as fix for #8950 where plain objects caused createDocumentFragment exception + context = context || document; + context = !context.nodeType && context[0] || context; + context = context.ownerDocument || context; + + // Only cache "small" (1/2 KB) HTML strings that are associated with the main document + // Cloning options loses the selected state, so don't cache them + // IE 6 doesn't like it when you put or elements in a fragment + // Also, WebKit does not clone 'checked' attributes on cloneNode, so don't cache + // Lastly, IE6,7,8 will not correctly reuse cached fragments that were created from unknown elems #10501 + if ( args.length === 1 && typeof first === "string" && first.length < 512 && context === document && + first.charAt(0) === "<" && !rnocache.test( first ) && + (jQuery.support.checkClone || !rchecked.test( first )) && + (jQuery.support.html5Clone || !rnoshimcache.test( first )) ) { + + // Mark cacheable and look for a hit + cacheable = true; + fragment = jQuery.fragments[ first ]; + cachehit = fragment !== undefined; + } + + if ( !fragment ) { + fragment = context.createDocumentFragment(); + jQuery.clean( args, context, fragment, scripts ); + + // Update the cache, but only store false + // unless this is a second parsing of the same content + if ( cacheable ) { + jQuery.fragments[ first ] = cachehit && fragment; + } + } + + return { fragment: fragment, cacheable: cacheable }; +}; + +jQuery.fragments = {}; + +jQuery.each({ + appendTo: "append", + prependTo: "prepend", + insertBefore: "before", + insertAfter: "after", + replaceAll: "replaceWith" +}, function( name, original ) { + jQuery.fn[ name ] = function( selector ) { + var elems, + i = 0, + ret = [], + insert = jQuery( selector ), + l = insert.length, + parent = this.length === 1 && this[0].parentNode; + + if ( (parent == null || parent && parent.nodeType === 11 && parent.childNodes.length === 1) && l === 1 ) { + insert[ original ]( this[0] ); + return this; + } else { + for ( ; i < l; i++ ) { + elems = ( i > 0 ? this.clone(true) : this ).get(); + jQuery( insert[i] )[ original ]( elems ); + ret = ret.concat( elems ); + } + + return this.pushStack( ret, name, insert.selector ); + } + }; +}); + +function getAll( elem ) { + if ( typeof elem.getElementsByTagName !== "undefined" ) { + return elem.getElementsByTagName( "*" ); + + } else if ( typeof elem.querySelectorAll !== "undefined" ) { + return elem.querySelectorAll( "*" ); + + } else { + return []; + } +} + +// Used in clean, fixes the defaultChecked property +function fixDefaultChecked( elem ) { + if ( rcheckableType.test( elem.type ) ) { + elem.defaultChecked = elem.checked; + } +} + +jQuery.extend({ + clone: function( elem, dataAndEvents, deepDataAndEvents ) { + var srcElements, + destElements, + i, + clone; + + if ( jQuery.support.html5Clone || jQuery.isXMLDoc(elem) || !rnoshimcache.test( "<" + elem.nodeName + ">" ) ) { + clone = elem.cloneNode( true ); + + // IE<=8 does not properly clone detached, unknown element nodes + } else { + fragmentDiv.innerHTML = elem.outerHTML; + fragmentDiv.removeChild( clone = fragmentDiv.firstChild ); + } + + if ( (!jQuery.support.noCloneEvent || !jQuery.support.noCloneChecked) && + (elem.nodeType === 1 || elem.nodeType === 11) && !jQuery.isXMLDoc(elem) ) { + // IE copies events bound via attachEvent when using cloneNode. + // Calling detachEvent on the clone will also remove the events + // from the original. In order to get around this, we use some + // proprietary methods to clear the events. Thanks to MooTools + // guys for this hotness. + + cloneFixAttributes( elem, clone ); + + // Using Sizzle here is crazy slow, so we use getElementsByTagName instead + srcElements = getAll( elem ); + destElements = getAll( clone ); + + // Weird iteration because IE will replace the length property + // with an element if you are cloning the body and one of the + // elements on the page has a name or id of "length" + for ( i = 0; srcElements[i]; ++i ) { + // Ensure that the destination node is not null; Fixes #9587 + if ( destElements[i] ) { + cloneFixAttributes( srcElements[i], destElements[i] ); + } + } + } + + // Copy the events from the original to the clone + if ( dataAndEvents ) { + cloneCopyEvent( elem, clone ); + + if ( deepDataAndEvents ) { + srcElements = getAll( elem ); + destElements = getAll( clone ); + + for ( i = 0; srcElements[i]; ++i ) { + cloneCopyEvent( srcElements[i], destElements[i] ); + } + } + } + + srcElements = destElements = null; + + // Return the cloned set + return clone; + }, + + clean: function( elems, context, fragment, scripts ) { + var i, j, elem, tag, wrap, depth, div, hasBody, tbody, len, handleScript, jsTags, + safe = context === document && safeFragment, + ret = []; + + // Ensure that context is a document + if ( !context || typeof context.createDocumentFragment === "undefined" ) { + context = document; + } + + // Use the already-created safe fragment if context permits + for ( i = 0; (elem = elems[i]) != null; i++ ) { + if ( typeof elem === "number" ) { + elem += ""; + } + + if ( !elem ) { + continue; + } + + // Convert html string into DOM nodes + if ( typeof elem === "string" ) { + if ( !rhtml.test( elem ) ) { + elem = context.createTextNode( elem ); + } else { + // Ensure a safe container in which to render the html + safe = safe || createSafeFragment( context ); + div = context.createElement("div"); + safe.appendChild( div ); + + // Fix "XHTML"-style tags in all browsers + elem = elem.replace(rxhtmlTag, "<$1>"); + + // Go to html and back, then peel off extra wrappers + tag = ( rtagName.exec( elem ) || ["", ""] )[1].toLowerCase(); + wrap = wrapMap[ tag ] || wrapMap._default; + depth = wrap[0]; + div.innerHTML = wrap[1] + elem + wrap[2]; + + // Move to the right depth + while ( depth-- ) { + div = div.lastChild; + } + + // Remove IE's autoinserted from table fragments + if ( !jQuery.support.tbody ) { + + // String was a , *may* have spurious + hasBody = rtbody.test(elem); + tbody = tag === "table" && !hasBody ? + div.firstChild && div.firstChild.childNodes : + + // String was a bare or + wrap[1] === "
      " && !hasBody ? + div.childNodes : + []; + + for ( j = tbody.length - 1; j >= 0 ; --j ) { + if ( jQuery.nodeName( tbody[ j ], "tbody" ) && !tbody[ j ].childNodes.length ) { + tbody[ j ].parentNode.removeChild( tbody[ j ] ); + } + } + } + + // IE completely kills leading whitespace when innerHTML is used + if ( !jQuery.support.leadingWhitespace && rleadingWhitespace.test( elem ) ) { + div.insertBefore( context.createTextNode( rleadingWhitespace.exec(elem)[0] ), div.firstChild ); + } + + elem = div.childNodes; + + // Take out of fragment container (we need a fresh div each time) + div.parentNode.removeChild( div ); + } + } + + if ( elem.nodeType ) { + ret.push( elem ); + } else { + jQuery.merge( ret, elem ); + } + } + + // Fix #11356: Clear elements from safeFragment + if ( div ) { + elem = div = safe = null; + } + + // Reset defaultChecked for any radios and checkboxes + // about to be appended to the DOM in IE 6/7 (#8060) + if ( !jQuery.support.appendChecked ) { + for ( i = 0; (elem = ret[i]) != null; i++ ) { + if ( jQuery.nodeName( elem, "input" ) ) { + fixDefaultChecked( elem ); + } else if ( typeof elem.getElementsByTagName !== "undefined" ) { + jQuery.grep( elem.getElementsByTagName("input"), fixDefaultChecked ); + } + } + } + + // Append elements to a provided document fragment + if ( fragment ) { + // Special handling of each script element + handleScript = function( elem ) { + // Check if we consider it executable + if ( !elem.type || rscriptType.test( elem.type ) ) { + // Detach the script and store it in the scripts array (if provided) or the fragment + // Return truthy to indicate that it has been handled + return scripts ? + scripts.push( elem.parentNode ? elem.parentNode.removeChild( elem ) : elem ) : + fragment.appendChild( elem ); + } + }; + + for ( i = 0; (elem = ret[i]) != null; i++ ) { + // Check if we're done after handling an executable script + if ( !( jQuery.nodeName( elem, "script" ) && handleScript( elem ) ) ) { + // Append to fragment and handle embedded scripts + fragment.appendChild( elem ); + if ( typeof elem.getElementsByTagName !== "undefined" ) { + // handleScript alters the DOM, so use jQuery.merge to ensure snapshot iteration + jsTags = jQuery.grep( jQuery.merge( [], elem.getElementsByTagName("script") ), handleScript ); + + // Splice the scripts into ret after their former ancestor and advance our index beyond them + ret.splice.apply( ret, [i + 1, 0].concat( jsTags ) ); + i += jsTags.length; + } + } + } + } + + return ret; + }, + + cleanData: function( elems, /* internal */ acceptData ) { + var data, id, elem, type, + i = 0, + internalKey = jQuery.expando, + cache = jQuery.cache, + deleteExpando = jQuery.support.deleteExpando, + special = jQuery.event.special; + + for ( ; (elem = elems[i]) != null; i++ ) { + + if ( acceptData || jQuery.acceptData( elem ) ) { + + id = elem[ internalKey ]; + data = id && cache[ id ]; + + if ( data ) { + if ( data.events ) { + for ( type in data.events ) { + if ( special[ type ] ) { + jQuery.event.remove( elem, type ); + + // This is a shortcut to avoid jQuery.event.remove's overhead + } else { + jQuery.removeEvent( elem, type, data.handle ); + } + } + } + + // Remove cache only if it was not already removed by jQuery.event.remove + if ( cache[ id ] ) { + + delete cache[ id ]; + + // 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 ( deleteExpando ) { + delete elem[ internalKey ]; + + } else if ( elem.removeAttribute ) { + elem.removeAttribute( internalKey ); + + } else { + elem[ internalKey ] = null; + } + + jQuery.deletedIds.push( id ); + } + } + } + } + } +}); +// Limit scope pollution from any deprecated API +(function() { + +var matched, browser; + +// Use of jQuery.browser is frowned upon. +// More details: http://api.jquery.com/jQuery.browser +// jQuery.uaMatch maintained for back-compat +jQuery.uaMatch = function( ua ) { + ua = ua.toLowerCase(); + + var match = /(chrome)[ \/]([\w.]+)/.exec( ua ) || + /(webkit)[ \/]([\w.]+)/.exec( ua ) || + /(opera)(?:.*version|)[ \/]([\w.]+)/.exec( ua ) || + /(msie) ([\w.]+)/.exec( ua ) || + ua.indexOf("compatible") < 0 && /(mozilla)(?:.*? rv:([\w.]+)|)/.exec( ua ) || + []; + + return { + browser: match[ 1 ] || "", + version: match[ 2 ] || "0" + }; +}; + +matched = jQuery.uaMatch( navigator.userAgent ); +browser = {}; + +if ( matched.browser ) { + browser[ matched.browser ] = true; + browser.version = matched.version; +} + +// Chrome is Webkit, but Webkit is also Safari. +if ( browser.chrome ) { + browser.webkit = true; +} else if ( browser.webkit ) { + browser.safari = true; +} + +jQuery.browser = browser; + +jQuery.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; +}; + +})(); +var curCSS, iframe, iframeDoc, + ralpha = /alpha\([^)]*\)/i, + ropacity = /opacity=([^)]*)/, + rposition = /^(top|right|bottom|left)$/, + // swappable if display is none or starts with table except "table", "table-cell", or "table-caption" + // see here for display values: https://developer.mozilla.org/en-US/docs/CSS/display + rdisplayswap = /^(none|table(?!-c[ea]).+)/, + rmargin = /^margin/, + rnumsplit = new RegExp( "^(" + core_pnum + ")(.*)$", "i" ), + rnumnonpx = new RegExp( "^(" + core_pnum + ")(?!px)[a-z%]+$", "i" ), + rrelNum = new RegExp( "^([-+])=(" + core_pnum + ")", "i" ), + elemdisplay = {}, + + cssShow = { position: "absolute", visibility: "hidden", display: "block" }, + cssNormalTransform = { + letterSpacing: 0, + fontWeight: 400 + }, + + cssExpand = [ "Top", "Right", "Bottom", "Left" ], + cssPrefixes = [ "Webkit", "O", "Moz", "ms" ], + + eventsToggle = jQuery.fn.toggle; + +// return a css property mapped to a potentially vendor prefixed property +function vendorPropName( style, name ) { + + // shortcut for names that are not vendor prefixed + if ( name in style ) { + return name; + } + + // check for vendor prefixed names + var capName = name.charAt(0).toUpperCase() + name.slice(1), + origName = name, + i = cssPrefixes.length; + + while ( i-- ) { + name = cssPrefixes[ i ] + capName; + if ( name in style ) { + return name; + } + } + + return origName; +} + +function isHidden( elem, el ) { + elem = el || elem; + return jQuery.css( elem, "display" ) === "none" || !jQuery.contains( elem.ownerDocument, elem ); +} + +function showHide( elements, show ) { + var elem, display, + values = [], + index = 0, + length = elements.length; + + for ( ; index < length; index++ ) { + elem = elements[ index ]; + if ( !elem.style ) { + continue; + } + values[ index ] = jQuery._data( elem, "olddisplay" ); + if ( show ) { + // Reset the inline display of this element to learn if it is + // being hidden by cascaded rules or not + if ( !values[ index ] && elem.style.display === "none" ) { + elem.style.display = ""; + } + + // Set elements which have been overridden with display: none + // in a stylesheet to whatever the default browser style is + // for such an element + if ( elem.style.display === "" && isHidden( elem ) ) { + values[ index ] = jQuery._data( elem, "olddisplay", css_defaultDisplay(elem.nodeName) ); + } + } else { + display = curCSS( elem, "display" ); + + if ( !values[ index ] && display !== "none" ) { + jQuery._data( elem, "olddisplay", display ); + } + } + } + + // Set the display of most of the elements in a second loop + // to avoid the constant reflow + for ( index = 0; index < length; index++ ) { + elem = elements[ index ]; + if ( !elem.style ) { + continue; + } + if ( !show || elem.style.display === "none" || elem.style.display === "" ) { + elem.style.display = show ? values[ index ] || "" : "none"; + } + } + + return elements; +} + +jQuery.fn.extend({ + css: function( name, value ) { + return jQuery.access( this, function( elem, name, value ) { + return value !== undefined ? + jQuery.style( elem, name, value ) : + jQuery.css( elem, name ); + }, name, value, arguments.length > 1 ); + }, + show: function() { + return showHide( this, true ); + }, + hide: function() { + return showHide( this ); + }, + toggle: function( state, fn2 ) { + var bool = typeof state === "boolean"; + + if ( jQuery.isFunction( state ) && jQuery.isFunction( fn2 ) ) { + return eventsToggle.apply( this, arguments ); + } + + return this.each(function() { + if ( bool ? state : isHidden( this ) ) { + jQuery( this ).show(); + } else { + jQuery( this ).hide(); + } + }); + } +}); + +jQuery.extend({ + // Add in style property hooks for overriding the default + // behavior of getting and setting a style property + cssHooks: { + opacity: { + get: function( elem, computed ) { + if ( computed ) { + // We should always get a number back from opacity + var ret = curCSS( elem, "opacity" ); + return ret === "" ? "1" : ret; + + } + } + } + }, + + // Exclude the following css properties to add px + cssNumber: { + "fillOpacity": true, + "fontWeight": true, + "lineHeight": true, + "opacity": true, + "orphans": true, + "widows": true, + "zIndex": true, + "zoom": true + }, + + // Add in properties whose names you wish to fix before + // setting or getting the value + cssProps: { + // normalize float css property + "float": jQuery.support.cssFloat ? "cssFloat" : "styleFloat" + }, + + // Get and set the style property on a DOM Node + style: function( elem, name, value, extra ) { + // Don't set styles on text and comment nodes + if ( !elem || elem.nodeType === 3 || elem.nodeType === 8 || !elem.style ) { + return; + } + + // Make sure that we're working with the right name + var ret, type, hooks, + origName = jQuery.camelCase( name ), + style = elem.style; + + name = jQuery.cssProps[ origName ] || ( jQuery.cssProps[ origName ] = vendorPropName( style, origName ) ); + + // gets hook for the prefixed version + // followed by the unprefixed version + hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ]; + + // Check if we're setting a value + if ( value !== undefined ) { + type = typeof value; + + // convert relative number strings (+= or -=) to relative numbers. #7345 + if ( type === "string" && (ret = rrelNum.exec( value )) ) { + value = ( ret[1] + 1 ) * ret[2] + parseFloat( jQuery.css( elem, name ) ); + // Fixes bug #9237 + type = "number"; + } + + // Make sure that NaN and null values aren't set. See: #7116 + if ( value == null || type === "number" && isNaN( value ) ) { + return; + } + + // If a number was passed in, add 'px' to the (except for certain CSS properties) + if ( type === "number" && !jQuery.cssNumber[ origName ] ) { + value += "px"; + } + + // If a hook was provided, use that value, otherwise just set the specified value + if ( !hooks || !("set" in hooks) || (value = hooks.set( elem, value, extra )) !== undefined ) { + // Wrapped to prevent IE from throwing errors when 'invalid' values are provided + // Fixes bug #5509 + try { + style[ name ] = value; + } catch(e) {} + } + + } else { + // If a hook was provided get the non-computed value from there + if ( hooks && "get" in hooks && (ret = hooks.get( elem, false, extra )) !== undefined ) { + return ret; + } + + // Otherwise just get the value from the style object + return style[ name ]; + } + }, + + css: function( elem, name, numeric, extra ) { + var val, num, hooks, + origName = jQuery.camelCase( name ); + + // Make sure that we're working with the right name + name = jQuery.cssProps[ origName ] || ( jQuery.cssProps[ origName ] = vendorPropName( elem.style, origName ) ); + + // gets hook for the prefixed version + // followed by the unprefixed version + hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ]; + + // If a hook was provided get the computed value from there + if ( hooks && "get" in hooks ) { + val = hooks.get( elem, true, extra ); + } + + // Otherwise, if a way to get the computed value exists, use that + if ( val === undefined ) { + val = curCSS( elem, name ); + } + + //convert "normal" to computed value + if ( val === "normal" && name in cssNormalTransform ) { + val = cssNormalTransform[ name ]; + } + + // Return, converting to number if forced or a qualifier was provided and val looks numeric + if ( numeric || extra !== undefined ) { + num = parseFloat( val ); + return numeric || jQuery.isNumeric( num ) ? num || 0 : val; + } + return val; + }, + + // A method for quickly swapping in/out CSS properties to get correct calculations + swap: function( elem, options, callback ) { + var ret, name, + old = {}; + + // Remember the old values, and insert the new ones + for ( name in options ) { + old[ name ] = elem.style[ name ]; + elem.style[ name ] = options[ name ]; + } + + ret = callback.call( elem ); + + // Revert the old values + for ( name in options ) { + elem.style[ name ] = old[ name ]; + } + + return ret; + } +}); + +// NOTE: To any future maintainer, we've window.getComputedStyle +// because jsdom on node.js will break without it. +if ( window.getComputedStyle ) { + curCSS = function( elem, name ) { + var ret, width, minWidth, maxWidth, + computed = window.getComputedStyle( elem, null ), + style = elem.style; + + if ( computed ) { + + ret = computed[ name ]; + if ( ret === "" && !jQuery.contains( elem.ownerDocument, elem ) ) { + ret = jQuery.style( elem, name ); + } + + // A tribute to the "awesome hack by Dean Edwards" + // Chrome < 17 and Safari 5.0 uses "computed value" instead of "used value" for margin-right + // Safari 5.1.7 (at least) returns percentage for a larger set of values, but width seems to be reliably pixels + // this is against the CSSOM draft spec: http://dev.w3.org/csswg/cssom/#resolved-values + if ( rnumnonpx.test( ret ) && rmargin.test( name ) ) { + width = style.width; + minWidth = style.minWidth; + maxWidth = style.maxWidth; + + style.minWidth = style.maxWidth = style.width = ret; + ret = computed.width; + + style.width = width; + style.minWidth = minWidth; + style.maxWidth = maxWidth; + } + } + + return ret; + }; +} else if ( document.documentElement.currentStyle ) { + curCSS = function( elem, name ) { + var left, rsLeft, + ret = elem.currentStyle && elem.currentStyle[ name ], + style = elem.style; + + // Avoid setting ret to empty string here + // so we don't default to auto + if ( ret == null && style && style[ name ] ) { + ret = style[ name ]; + } + + // From the awesome hack by Dean Edwards + // http://erik.eae.net/archives/2007/07/27/18.54.15/#comment-102291 + + // If we're not dealing with a regular pixel number + // but a number that has a weird ending, we need to convert it to pixels + // but not position css attributes, as those are proportional to the parent element instead + // and we can't measure the parent instead because it might trigger a "stacking dolls" problem + if ( rnumnonpx.test( ret ) && !rposition.test( name ) ) { + + // Remember the original values + left = style.left; + rsLeft = elem.runtimeStyle && elem.runtimeStyle.left; + + // Put in the new values to get a computed value out + if ( rsLeft ) { + elem.runtimeStyle.left = elem.currentStyle.left; + } + style.left = name === "fontSize" ? "1em" : ret; + ret = style.pixelLeft + "px"; + + // Revert the changed values + style.left = left; + if ( rsLeft ) { + elem.runtimeStyle.left = rsLeft; + } + } + + return ret === "" ? "auto" : ret; + }; +} + +function setPositiveNumber( elem, value, subtract ) { + var matches = rnumsplit.exec( value ); + return matches ? + Math.max( 0, matches[ 1 ] - ( subtract || 0 ) ) + ( matches[ 2 ] || "px" ) : + value; +} + +function augmentWidthOrHeight( elem, name, extra, isBorderBox ) { + var i = extra === ( isBorderBox ? "border" : "content" ) ? + // If we already have the right measurement, avoid augmentation + 4 : + // Otherwise initialize for horizontal or vertical properties + name === "width" ? 1 : 0, + + val = 0; + + for ( ; i < 4; i += 2 ) { + // both box models exclude margin, so add it if we want it + if ( extra === "margin" ) { + // we use jQuery.css instead of curCSS here + // because of the reliableMarginRight CSS hook! + val += jQuery.css( elem, extra + cssExpand[ i ], true ); + } + + // From this point on we use curCSS for maximum performance (relevant in animations) + if ( isBorderBox ) { + // border-box includes padding, so remove it if we want content + if ( extra === "content" ) { + val -= parseFloat( curCSS( elem, "padding" + cssExpand[ i ] ) ) || 0; + } + + // at this point, extra isn't border nor margin, so remove border + if ( extra !== "margin" ) { + val -= parseFloat( curCSS( elem, "border" + cssExpand[ i ] + "Width" ) ) || 0; + } + } else { + // at this point, extra isn't content, so add padding + val += parseFloat( curCSS( elem, "padding" + cssExpand[ i ] ) ) || 0; + + // at this point, extra isn't content nor padding, so add border + if ( extra !== "padding" ) { + val += parseFloat( curCSS( elem, "border" + cssExpand[ i ] + "Width" ) ) || 0; + } + } + } + + return val; +} + +function getWidthOrHeight( elem, name, extra ) { + + // Start with offset property, which is equivalent to the border-box value + var val = name === "width" ? elem.offsetWidth : elem.offsetHeight, + valueIsBorderBox = true, + isBorderBox = jQuery.support.boxSizing && jQuery.css( elem, "boxSizing" ) === "border-box"; + + // some non-html elements return undefined for offsetWidth, so check for null/undefined + // svg - https://bugzilla.mozilla.org/show_bug.cgi?id=649285 + // MathML - https://bugzilla.mozilla.org/show_bug.cgi?id=491668 + if ( val <= 0 || val == null ) { + // Fall back to computed then uncomputed css if necessary + val = curCSS( elem, name ); + if ( val < 0 || val == null ) { + val = elem.style[ name ]; + } + + // Computed unit is not pixels. Stop here and return. + if ( rnumnonpx.test(val) ) { + return val; + } + + // we need the check for style in case a browser which returns unreliable values + // for getComputedStyle silently falls back to the reliable elem.style + valueIsBorderBox = isBorderBox && ( jQuery.support.boxSizingReliable || val === elem.style[ name ] ); + + // Normalize "", auto, and prepare for extra + val = parseFloat( val ) || 0; + } + + // use the active box-sizing model to add/subtract irrelevant styles + return ( val + + augmentWidthOrHeight( + elem, + name, + extra || ( isBorderBox ? "border" : "content" ), + valueIsBorderBox + ) + ) + "px"; +} + + +// Try to determine the default display value of an element +function css_defaultDisplay( nodeName ) { + if ( elemdisplay[ nodeName ] ) { + return elemdisplay[ nodeName ]; + } + + var elem = jQuery( "<" + nodeName + ">" ).appendTo( document.body ), + display = elem.css("display"); + elem.remove(); + + // If the simple way fails, + // get element's real default display by attaching it to a temp iframe + if ( display === "none" || display === "" ) { + // Use the already-created iframe if possible + iframe = document.body.appendChild( + iframe || jQuery.extend( document.createElement("iframe"), { + frameBorder: 0, + width: 0, + height: 0 + }) + ); + + // Create a cacheable copy of the iframe document on first call. + // IE and Opera will allow us to reuse the iframeDoc without re-writing the fake HTML + // document to it; WebKit & Firefox won't allow reusing the iframe document. + if ( !iframeDoc || !iframe.createElement ) { + iframeDoc = ( iframe.contentWindow || iframe.contentDocument ).document; + iframeDoc.write(""); + iframeDoc.close(); + } + + elem = iframeDoc.body.appendChild( iframeDoc.createElement(nodeName) ); + + display = curCSS( elem, "display" ); + document.body.removeChild( iframe ); + } + + // Store the correct default display + elemdisplay[ nodeName ] = display; + + return display; +} + +jQuery.each([ "height", "width" ], function( i, name ) { + jQuery.cssHooks[ name ] = { + get: function( elem, computed, extra ) { + if ( computed ) { + // certain elements can have dimension info if we invisibly show them + // however, it must have a current display style that would benefit from this + if ( elem.offsetWidth === 0 && rdisplayswap.test( curCSS( elem, "display" ) ) ) { + return jQuery.swap( elem, cssShow, function() { + return getWidthOrHeight( elem, name, extra ); + }); + } else { + return getWidthOrHeight( elem, name, extra ); + } + } + }, + + set: function( elem, value, extra ) { + return setPositiveNumber( elem, value, extra ? + augmentWidthOrHeight( + elem, + name, + extra, + jQuery.support.boxSizing && jQuery.css( elem, "boxSizing" ) === "border-box" + ) : 0 + ); + } + }; +}); + +if ( !jQuery.support.opacity ) { + jQuery.cssHooks.opacity = { + get: function( elem, computed ) { + // IE uses filters for opacity + return ropacity.test( (computed && elem.currentStyle ? elem.currentStyle.filter : elem.style.filter) || "" ) ? + ( 0.01 * parseFloat( RegExp.$1 ) ) + "" : + computed ? "1" : ""; + }, + + set: function( elem, value ) { + var style = elem.style, + currentStyle = elem.currentStyle, + opacity = jQuery.isNumeric( value ) ? "alpha(opacity=" + value * 100 + ")" : "", + filter = currentStyle && currentStyle.filter || style.filter || ""; + + // IE has trouble with opacity if it does not have layout + // Force it by setting the zoom level + style.zoom = 1; + + // if setting opacity to 1, and no other filters exist - attempt to remove filter attribute #6652 + if ( value >= 1 && jQuery.trim( filter.replace( ralpha, "" ) ) === "" && + style.removeAttribute ) { + + // Setting style.filter to null, "" & " " still leave "filter:" in the cssText + // if "filter:" is present at all, clearType is disabled, we want to avoid this + // style.removeAttribute is IE Only, but so apparently is this code path... + style.removeAttribute( "filter" ); + + // if there there is no filter style applied in a css rule, we are done + if ( currentStyle && !currentStyle.filter ) { + return; + } + } + + // otherwise, set new filter values + style.filter = ralpha.test( filter ) ? + filter.replace( ralpha, opacity ) : + filter + " " + opacity; + } + }; +} + +// These hooks cannot be added until DOM ready because the support test +// for it is not run until after DOM ready +jQuery(function() { + if ( !jQuery.support.reliableMarginRight ) { + jQuery.cssHooks.marginRight = { + get: function( elem, computed ) { + // WebKit Bug 13343 - getComputedStyle returns wrong value for margin-right + // Work around by temporarily setting element display to inline-block + return jQuery.swap( elem, { "display": "inline-block" }, function() { + if ( computed ) { + return curCSS( elem, "marginRight" ); + } + }); + } + }; + } + + // Webkit bug: https://bugs.webkit.org/show_bug.cgi?id=29084 + // getComputedStyle returns percent when specified for top/left/bottom/right + // rather than make the css module depend on the offset module, we just check for it here + if ( !jQuery.support.pixelPosition && jQuery.fn.position ) { + jQuery.each( [ "top", "left" ], function( i, prop ) { + jQuery.cssHooks[ prop ] = { + get: function( elem, computed ) { + if ( computed ) { + var ret = curCSS( elem, prop ); + // if curCSS returns percentage, fallback to offset + return rnumnonpx.test( ret ) ? jQuery( elem ).position()[ prop ] + "px" : ret; + } + } + }; + }); + } + +}); + +if ( jQuery.expr && jQuery.expr.filters ) { + jQuery.expr.filters.hidden = function( elem ) { + return ( elem.offsetWidth === 0 && elem.offsetHeight === 0 ) || (!jQuery.support.reliableHiddenOffsets && ((elem.style && elem.style.display) || curCSS( elem, "display" )) === "none"); + }; + + jQuery.expr.filters.visible = function( elem ) { + return !jQuery.expr.filters.hidden( elem ); + }; +} + +// These hooks are used by animate to expand properties +jQuery.each({ + margin: "", + padding: "", + border: "Width" +}, function( prefix, suffix ) { + jQuery.cssHooks[ prefix + suffix ] = { + expand: function( value ) { + var i, + + // assumes a single number if not a string + parts = typeof value === "string" ? value.split(" ") : [ value ], + expanded = {}; + + for ( i = 0; i < 4; i++ ) { + expanded[ prefix + cssExpand[ i ] + suffix ] = + parts[ i ] || parts[ i - 2 ] || parts[ 0 ]; + } + + return expanded; + } + }; + + if ( !rmargin.test( prefix ) ) { + jQuery.cssHooks[ prefix + suffix ].set = setPositiveNumber; + } +}); +var r20 = /%20/g, + rbracket = /\[\]$/, + rCRLF = /\r?\n/g, + rinput = /^(?:color|date|datetime|datetime-local|email|hidden|month|number|password|range|search|tel|text|time|url|week)$/i, + rselectTextarea = /^(?:select|textarea)/i; + +jQuery.fn.extend({ + serialize: function() { + return jQuery.param( this.serializeArray() ); + }, + serializeArray: function() { + return this.map(function(){ + return this.elements ? jQuery.makeArray( this.elements ) : this; + }) + .filter(function(){ + return this.name && !this.disabled && + ( this.checked || rselectTextarea.test( this.nodeName ) || + rinput.test( this.type ) ); + }) + .map(function( i, elem ){ + var val = jQuery( this ).val(); + + return val == null ? + null : + jQuery.isArray( val ) ? + jQuery.map( val, function( val, i ){ + return { name: elem.name, value: val.replace( rCRLF, "\r\n" ) }; + }) : + { name: elem.name, value: val.replace( rCRLF, "\r\n" ) }; + }).get(); + } +}); + +//Serialize an array of form elements or a set of +//key/values into a query string +jQuery.param = function( a, traditional ) { + var prefix, + s = [], + add = function( key, value ) { + // If value is a function, invoke it and return its value + value = jQuery.isFunction( value ) ? value() : ( value == null ? "" : value ); + s[ s.length ] = encodeURIComponent( key ) + "=" + encodeURIComponent( value ); + }; + + // Set traditional to true for jQuery <= 1.3.2 behavior. + if ( traditional === undefined ) { + traditional = jQuery.ajaxSettings && jQuery.ajaxSettings.traditional; + } + + // If an array was passed in, assume that it is an array of form elements. + if ( jQuery.isArray( a ) || ( a.jquery && !jQuery.isPlainObject( a ) ) ) { + // Serialize the form elements + jQuery.each( a, function() { + add( this.name, this.value ); + }); + + } else { + // If traditional, encode the "old" way (the way 1.3.2 or older + // did it), otherwise encode params recursively. + for ( prefix in a ) { + buildParams( prefix, a[ prefix ], traditional, add ); + } + } + + // Return the resulting serialization + return s.join( "&" ).replace( r20, "+" ); +}; + +function buildParams( prefix, obj, traditional, add ) { + var name; + + if ( jQuery.isArray( obj ) ) { + // Serialize array item. + jQuery.each( obj, function( i, v ) { + if ( traditional || rbracket.test( prefix ) ) { + // Treat each array item as a scalar. + add( prefix, v ); + + } else { + // If array item is non-scalar (array or object), encode its + // numeric index to resolve deserialization ambiguity issues. + // Note that rack (as of 1.0.0) can't currently deserialize + // nested arrays properly, and attempting to do so may cause + // a server error. Possible fixes are to modify rack's + // deserialization algorithm or to provide an option or flag + // to force array serialization to be shallow. + buildParams( prefix + "[" + ( typeof v === "object" ? i : "" ) + "]", v, traditional, add ); + } + }); + + } else if ( !traditional && jQuery.type( obj ) === "object" ) { + // Serialize object item. + for ( name in obj ) { + buildParams( prefix + "[" + name + "]", obj[ name ], traditional, add ); + } + + } else { + // Serialize scalar item. + add( prefix, obj ); + } +} +var + // Document location + ajaxLocParts, + ajaxLocation, + + rhash = /#.*$/, + rheaders = /^(.*?):[ \t]*([^\r\n]*)\r?$/mg, // IE leaves an \r character at EOL + // #7653, #8125, #8152: local protocol detection + rlocalProtocol = /^(?:about|app|app\-storage|.+\-extension|file|res|widget):$/, + rnoContent = /^(?:GET|HEAD)$/, + rprotocol = /^\/\//, + rquery = /\?/, + rscript = /)<[^<]*)*<\/script>/gi, + rts = /([?&])_=[^&]*/, + rurl = /^([\w\+\.\-]+:)(?:\/\/([^\/?#:]*)(?::(\d+)|)|)/, + + // Keep a copy of the old load method + _load = jQuery.fn.load, + + /* Prefilters + * 1) They are useful to introduce custom dataTypes (see ajax/jsonp.js for an example) + * 2) These are called: + * - BEFORE asking for a transport + * - AFTER param serialization (s.data is a string if s.processData is true) + * 3) key is the dataType + * 4) the catchall symbol "*" can be used + * 5) execution will start with transport dataType and THEN continue down to "*" if needed + */ + prefilters = {}, + + /* Transports bindings + * 1) key is the dataType + * 2) the catchall symbol "*" can be used + * 3) selection will start with transport dataType and THEN go to "*" if needed + */ + transports = {}, + + // Avoid comment-prolog char sequence (#10098); must appease lint and evade compression + allTypes = ["*/"] + ["*"]; + +// #8138, IE may throw an exception when accessing +// a field from window.location if document.domain has been set +try { + ajaxLocation = location.href; +} catch( e ) { + // Use the href attribute of an A element + // since IE will modify it given document.location + ajaxLocation = document.createElement( "a" ); + ajaxLocation.href = ""; + ajaxLocation = ajaxLocation.href; +} + +// Segment location into parts +ajaxLocParts = rurl.exec( ajaxLocation.toLowerCase() ) || []; + +// Base "constructor" for jQuery.ajaxPrefilter and jQuery.ajaxTransport +function addToPrefiltersOrTransports( structure ) { + + // dataTypeExpression is optional and defaults to "*" + return function( dataTypeExpression, func ) { + + if ( typeof dataTypeExpression !== "string" ) { + func = dataTypeExpression; + dataTypeExpression = "*"; + } + + var dataType, list, placeBefore, + dataTypes = dataTypeExpression.toLowerCase().split( core_rspace ), + i = 0, + length = dataTypes.length; + + if ( jQuery.isFunction( func ) ) { + // For each dataType in the dataTypeExpression + for ( ; i < length; i++ ) { + dataType = dataTypes[ i ]; + // We control if we're asked to add before + // any existing element + placeBefore = /^\+/.test( dataType ); + if ( placeBefore ) { + dataType = dataType.substr( 1 ) || "*"; + } + list = structure[ dataType ] = structure[ dataType ] || []; + // then we add to the structure accordingly + list[ placeBefore ? "unshift" : "push" ]( func ); + } + } + }; +} + +// Base inspection function for prefilters and transports +function inspectPrefiltersOrTransports( structure, options, originalOptions, jqXHR, + dataType /* internal */, inspected /* internal */ ) { + + dataType = dataType || options.dataTypes[ 0 ]; + inspected = inspected || {}; + + inspected[ dataType ] = true; + + var selection, + list = structure[ dataType ], + i = 0, + length = list ? list.length : 0, + executeOnly = ( structure === prefilters ); + + for ( ; i < length && ( executeOnly || !selection ); i++ ) { + selection = list[ i ]( options, originalOptions, jqXHR ); + // If we got redirected to another dataType + // we try there if executing only and not done already + if ( typeof selection === "string" ) { + if ( !executeOnly || inspected[ selection ] ) { + selection = undefined; + } else { + options.dataTypes.unshift( selection ); + selection = inspectPrefiltersOrTransports( + structure, options, originalOptions, jqXHR, selection, inspected ); + } + } + } + // If we're only executing or nothing was selected + // we try the catchall dataType if not done already + if ( ( executeOnly || !selection ) && !inspected[ "*" ] ) { + selection = inspectPrefiltersOrTransports( + structure, options, originalOptions, jqXHR, "*", inspected ); + } + // unnecessary when only executing (prefilters) + // but it'll be ignored by the caller in that case + return selection; +} + +// A special extend for ajax options +// that takes "flat" options (not to be deep extended) +// Fixes #9887 +function ajaxExtend( target, src ) { + var key, deep, + flatOptions = jQuery.ajaxSettings.flatOptions || {}; + for ( key in src ) { + if ( src[ key ] !== undefined ) { + ( flatOptions[ key ] ? target : ( deep || ( deep = {} ) ) )[ key ] = src[ key ]; + } + } + if ( deep ) { + jQuery.extend( true, target, deep ); + } +} + +jQuery.fn.load = function( url, params, callback ) { + if ( typeof url !== "string" && _load ) { + return _load.apply( this, arguments ); + } + + // Don't do a request if no elements are being requested + if ( !this.length ) { + return this; + } + + var selector, type, response, + self = this, + off = url.indexOf(" "); + + if ( off >= 0 ) { + selector = url.slice( off, url.length ); + url = url.slice( 0, off ); + } + + // If it's a function + if ( jQuery.isFunction( params ) ) { + + // We assume that it's the callback + callback = params; + params = undefined; + + // Otherwise, build a param string + } else if ( params && typeof params === "object" ) { + type = "POST"; + } + + // Request the remote document + jQuery.ajax({ + url: url, + + // if "type" variable is undefined, then "GET" method will be used + type: type, + dataType: "html", + data: params, + complete: function( jqXHR, status ) { + if ( callback ) { + self.each( callback, response || [ jqXHR.responseText, status, jqXHR ] ); + } + } + }).done(function( responseText ) { + + // Save response for use in complete callback + response = arguments; + + // See if a selector was specified + self.html( selector ? + + // Create a dummy div to hold the results + jQuery("
      ") + + // inject the contents of the document in, removing the scripts + // to avoid any 'Permission Denied' errors in IE + .append( responseText.replace( rscript, "" ) ) + + // Locate the specified elements + .find( selector ) : + + // If not, just inject the full result + responseText ); + + }); + + return this; +}; + +// Attach a bunch of functions for handling common AJAX events +jQuery.each( "ajaxStart ajaxStop ajaxComplete ajaxError ajaxSuccess ajaxSend".split( " " ), function( i, o ){ + jQuery.fn[ o ] = function( f ){ + return this.on( o, f ); + }; +}); + +jQuery.each( [ "get", "post" ], function( i, method ) { + jQuery[ method ] = function( url, data, callback, type ) { + // shift arguments if data argument was omitted + if ( jQuery.isFunction( data ) ) { + type = type || callback; + callback = data; + data = undefined; + } + + return jQuery.ajax({ + type: method, + url: url, + data: data, + success: callback, + dataType: type + }); + }; +}); + +jQuery.extend({ + + getScript: function( url, callback ) { + return jQuery.get( url, undefined, callback, "script" ); + }, + + getJSON: function( url, data, callback ) { + return jQuery.get( url, data, callback, "json" ); + }, + + // Creates a full fledged settings object into target + // with both ajaxSettings and settings fields. + // If target is omitted, writes into ajaxSettings. + ajaxSetup: function( target, settings ) { + if ( settings ) { + // Building a settings object + ajaxExtend( target, jQuery.ajaxSettings ); + } else { + // Extending ajaxSettings + settings = target; + target = jQuery.ajaxSettings; + } + ajaxExtend( target, settings ); + return target; + }, + + ajaxSettings: { + url: ajaxLocation, + isLocal: rlocalProtocol.test( ajaxLocParts[ 1 ] ), + global: true, + type: "GET", + contentType: "application/x-www-form-urlencoded; charset=UTF-8", + processData: true, + async: true, + /* + timeout: 0, + data: null, + dataType: null, + username: null, + password: null, + cache: null, + throws: false, + traditional: false, + headers: {}, + */ + + accepts: { + xml: "application/xml, text/xml", + html: "text/html", + text: "text/plain", + json: "application/json, text/javascript", + "*": allTypes + }, + + contents: { + xml: /xml/, + html: /html/, + json: /json/ + }, + + responseFields: { + xml: "responseXML", + text: "responseText" + }, + + // List of data converters + // 1) key format is "source_type destination_type" (a single space in-between) + // 2) the catchall symbol "*" can be used for source_type + converters: { + + // Convert anything to text + "* text": window.String, + + // Text to html (true = no transformation) + "text html": true, + + // Evaluate text as a json expression + "text json": jQuery.parseJSON, + + // Parse text as xml + "text xml": jQuery.parseXML + }, + + // For options that shouldn't be deep extended: + // you can add your own custom options here if + // and when you create one that shouldn't be + // deep extended (see ajaxExtend) + flatOptions: { + context: true, + url: true + } + }, + + ajaxPrefilter: addToPrefiltersOrTransports( prefilters ), + ajaxTransport: addToPrefiltersOrTransports( transports ), + + // Main method + ajax: function( url, options ) { + + // If url is an object, simulate pre-1.5 signature + if ( typeof url === "object" ) { + options = url; + url = undefined; + } + + // Force options to be an object + options = options || {}; + + var // ifModified key + ifModifiedKey, + // Response headers + responseHeadersString, + responseHeaders, + // transport + transport, + // timeout handle + timeoutTimer, + // Cross-domain detection vars + parts, + // To know if global events are to be dispatched + fireGlobals, + // Loop variable + i, + // Create the final options object + s = jQuery.ajaxSetup( {}, options ), + // Callbacks context + callbackContext = s.context || s, + // Context for global events + // It's the callbackContext if one was provided in the options + // and if it's a DOM node or a jQuery collection + globalEventContext = callbackContext !== s && + ( callbackContext.nodeType || callbackContext instanceof jQuery ) ? + jQuery( callbackContext ) : jQuery.event, + // Deferreds + deferred = jQuery.Deferred(), + completeDeferred = jQuery.Callbacks( "once memory" ), + // Status-dependent callbacks + statusCode = s.statusCode || {}, + // Headers (they are sent all at once) + requestHeaders = {}, + requestHeadersNames = {}, + // The jqXHR state + state = 0, + // Default abort message + strAbort = "canceled", + // Fake xhr + jqXHR = { + + readyState: 0, + + // Caches the header + setRequestHeader: function( name, value ) { + if ( !state ) { + var lname = name.toLowerCase(); + name = requestHeadersNames[ lname ] = requestHeadersNames[ lname ] || name; + requestHeaders[ name ] = value; + } + return this; + }, + + // Raw string + getAllResponseHeaders: function() { + return state === 2 ? responseHeadersString : null; + }, + + // Builds headers hashtable if needed + getResponseHeader: function( key ) { + var match; + if ( state === 2 ) { + if ( !responseHeaders ) { + responseHeaders = {}; + while( ( match = rheaders.exec( responseHeadersString ) ) ) { + responseHeaders[ match[1].toLowerCase() ] = match[ 2 ]; + } + } + match = responseHeaders[ key.toLowerCase() ]; + } + return match === undefined ? null : match; + }, + + // Overrides response content-type header + overrideMimeType: function( type ) { + if ( !state ) { + s.mimeType = type; + } + return this; + }, + + // Cancel the request + abort: function( statusText ) { + statusText = statusText || strAbort; + if ( transport ) { + transport.abort( statusText ); + } + done( 0, statusText ); + return this; + } + }; + + // Callback for when everything is done + // It is defined here because jslint complains if it is declared + // at the end of the function (which would be more logical and readable) + function done( status, nativeStatusText, responses, headers ) { + var isSuccess, success, error, response, modified, + statusText = nativeStatusText; + + // Called once + if ( state === 2 ) { + return; + } + + // State is "done" now + state = 2; + + // Clear timeout if it exists + if ( timeoutTimer ) { + clearTimeout( timeoutTimer ); + } + + // Dereference transport for early garbage collection + // (no matter how long the jqXHR object will be used) + transport = undefined; + + // Cache response headers + responseHeadersString = headers || ""; + + // Set readyState + jqXHR.readyState = status > 0 ? 4 : 0; + + // Get response data + if ( responses ) { + response = ajaxHandleResponses( s, jqXHR, responses ); + } + + // If successful, handle type chaining + if ( status >= 200 && status < 300 || status === 304 ) { + + // Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode. + if ( s.ifModified ) { + + modified = jqXHR.getResponseHeader("Last-Modified"); + if ( modified ) { + jQuery.lastModified[ ifModifiedKey ] = modified; + } + modified = jqXHR.getResponseHeader("Etag"); + if ( modified ) { + jQuery.etag[ ifModifiedKey ] = modified; + } + } + + // If not modified + if ( status === 304 ) { + + statusText = "notmodified"; + isSuccess = true; + + // If we have data + } else { + + isSuccess = ajaxConvert( s, response ); + statusText = isSuccess.state; + success = isSuccess.data; + error = isSuccess.error; + isSuccess = !error; + } + } else { + // We extract error from statusText + // then normalize statusText and status for non-aborts + error = statusText; + if ( !statusText || status ) { + statusText = "error"; + if ( status < 0 ) { + status = 0; + } + } + } + + // Set data for the fake xhr object + jqXHR.status = status; + jqXHR.statusText = ( nativeStatusText || statusText ) + ""; + + // Success/Error + if ( isSuccess ) { + deferred.resolveWith( callbackContext, [ success, statusText, jqXHR ] ); + } else { + deferred.rejectWith( callbackContext, [ jqXHR, statusText, error ] ); + } + + // Status-dependent callbacks + jqXHR.statusCode( statusCode ); + statusCode = undefined; + + if ( fireGlobals ) { + globalEventContext.trigger( "ajax" + ( isSuccess ? "Success" : "Error" ), + [ jqXHR, s, isSuccess ? success : error ] ); + } + + // Complete + completeDeferred.fireWith( callbackContext, [ jqXHR, statusText ] ); + + if ( fireGlobals ) { + globalEventContext.trigger( "ajaxComplete", [ jqXHR, s ] ); + // Handle the global AJAX counter + if ( !( --jQuery.active ) ) { + jQuery.event.trigger( "ajaxStop" ); + } + } + } + + // Attach deferreds + deferred.promise( jqXHR ); + jqXHR.success = jqXHR.done; + jqXHR.error = jqXHR.fail; + jqXHR.complete = completeDeferred.add; + + // Status-dependent callbacks + jqXHR.statusCode = function( map ) { + if ( map ) { + var tmp; + if ( state < 2 ) { + for ( tmp in map ) { + statusCode[ tmp ] = [ statusCode[tmp], map[tmp] ]; + } + } else { + tmp = map[ jqXHR.status ]; + jqXHR.always( tmp ); + } + } + return this; + }; + + // Remove hash character (#7531: and string promotion) + // Add protocol if not provided (#5866: IE7 issue with protocol-less urls) + // We also use the url parameter if available + s.url = ( ( url || s.url ) + "" ).replace( rhash, "" ).replace( rprotocol, ajaxLocParts[ 1 ] + "//" ); + + // Extract dataTypes list + s.dataTypes = jQuery.trim( s.dataType || "*" ).toLowerCase().split( core_rspace ); + + // A cross-domain request is in order when we have a protocol:host:port mismatch + if ( s.crossDomain == null ) { + parts = rurl.exec( s.url.toLowerCase() ) || false; + s.crossDomain = parts && ( parts.join(":") + ( parts[ 3 ] ? "" : parts[ 1 ] === "http:" ? 80 : 443 ) ) !== + ( ajaxLocParts.join(":") + ( ajaxLocParts[ 3 ] ? "" : ajaxLocParts[ 1 ] === "http:" ? 80 : 443 ) ); + } + + // Convert data if not already a string + if ( s.data && s.processData && typeof s.data !== "string" ) { + s.data = jQuery.param( s.data, s.traditional ); + } + + // Apply prefilters + inspectPrefiltersOrTransports( prefilters, s, options, jqXHR ); + + // If request was aborted inside a prefilter, stop there + if ( state === 2 ) { + return jqXHR; + } + + // We can fire global events as of now if asked to + fireGlobals = s.global; + + // Uppercase the type + s.type = s.type.toUpperCase(); + + // Determine if request has content + s.hasContent = !rnoContent.test( s.type ); + + // Watch for a new set of requests + if ( fireGlobals && jQuery.active++ === 0 ) { + jQuery.event.trigger( "ajaxStart" ); + } + + // More options handling for requests with no content + if ( !s.hasContent ) { + + // If data is available, append data to url + if ( s.data ) { + s.url += ( rquery.test( s.url ) ? "&" : "?" ) + s.data; + // #9682: remove data so that it's not used in an eventual retry + delete s.data; + } + + // Get ifModifiedKey before adding the anti-cache parameter + ifModifiedKey = s.url; + + // Add anti-cache in url if needed + if ( s.cache === false ) { + + var ts = jQuery.now(), + // try replacing _= if it is there + ret = s.url.replace( rts, "$1_=" + ts ); + + // if nothing was replaced, add timestamp to the end + s.url = ret + ( ( ret === s.url ) ? ( rquery.test( s.url ) ? "&" : "?" ) + "_=" + ts : "" ); + } + } + + // Set the correct header, if data is being sent + if ( s.data && s.hasContent && s.contentType !== false || options.contentType ) { + jqXHR.setRequestHeader( "Content-Type", s.contentType ); + } + + // Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode. + if ( s.ifModified ) { + ifModifiedKey = ifModifiedKey || s.url; + if ( jQuery.lastModified[ ifModifiedKey ] ) { + jqXHR.setRequestHeader( "If-Modified-Since", jQuery.lastModified[ ifModifiedKey ] ); + } + if ( jQuery.etag[ ifModifiedKey ] ) { + jqXHR.setRequestHeader( "If-None-Match", jQuery.etag[ ifModifiedKey ] ); + } + } + + // Set the Accepts header for the server, depending on the dataType + jqXHR.setRequestHeader( + "Accept", + s.dataTypes[ 0 ] && s.accepts[ s.dataTypes[0] ] ? + s.accepts[ s.dataTypes[0] ] + ( s.dataTypes[ 0 ] !== "*" ? ", " + allTypes + "; q=0.01" : "" ) : + s.accepts[ "*" ] + ); + + // Check for headers option + for ( i in s.headers ) { + jqXHR.setRequestHeader( i, s.headers[ i ] ); + } + + // Allow custom headers/mimetypes and early abort + if ( s.beforeSend && ( s.beforeSend.call( callbackContext, jqXHR, s ) === false || state === 2 ) ) { + // Abort if not done already and return + return jqXHR.abort(); + + } + + // aborting is no longer a cancellation + strAbort = "abort"; + + // Install callbacks on deferreds + for ( i in { success: 1, error: 1, complete: 1 } ) { + jqXHR[ i ]( s[ i ] ); + } + + // Get transport + transport = inspectPrefiltersOrTransports( transports, s, options, jqXHR ); + + // If no transport, we auto-abort + if ( !transport ) { + done( -1, "No Transport" ); + } else { + jqXHR.readyState = 1; + // Send global event + if ( fireGlobals ) { + globalEventContext.trigger( "ajaxSend", [ jqXHR, s ] ); + } + // Timeout + if ( s.async && s.timeout > 0 ) { + timeoutTimer = setTimeout( function(){ + jqXHR.abort( "timeout" ); + }, s.timeout ); + } + + try { + state = 1; + transport.send( requestHeaders, done ); + } catch (e) { + // Propagate exception as error if not done + if ( state < 2 ) { + done( -1, e ); + // Simply rethrow otherwise + } else { + throw e; + } + } + } + + return jqXHR; + }, + + // Counter for holding the number of active queries + active: 0, + + // Last-Modified header cache for next request + lastModified: {}, + etag: {} + +}); + +/* Handles responses to an ajax request: + * - sets all responseXXX fields accordingly + * - finds the right dataType (mediates between content-type and expected dataType) + * - returns the corresponding response + */ +function ajaxHandleResponses( s, jqXHR, responses ) { + + var ct, type, finalDataType, firstDataType, + contents = s.contents, + dataTypes = s.dataTypes, + responseFields = s.responseFields; + + // Fill responseXXX fields + for ( type in responseFields ) { + if ( type in responses ) { + jqXHR[ responseFields[type] ] = responses[ type ]; + } + } + + // Remove auto dataType and get content-type in the process + while( dataTypes[ 0 ] === "*" ) { + dataTypes.shift(); + if ( ct === undefined ) { + ct = s.mimeType || jqXHR.getResponseHeader( "content-type" ); + } + } + + // Check if we're dealing with a known content-type + if ( ct ) { + for ( type in contents ) { + if ( contents[ type ] && contents[ type ].test( ct ) ) { + dataTypes.unshift( type ); + break; + } + } + } + + // Check to see if we have a response for the expected dataType + if ( dataTypes[ 0 ] in responses ) { + finalDataType = dataTypes[ 0 ]; + } else { + // Try convertible dataTypes + for ( type in responses ) { + if ( !dataTypes[ 0 ] || s.converters[ type + " " + dataTypes[0] ] ) { + finalDataType = type; + break; + } + if ( !firstDataType ) { + firstDataType = type; + } + } + // Or just use first one + finalDataType = finalDataType || firstDataType; + } + + // If we found a dataType + // We add the dataType to the list if needed + // and return the corresponding response + if ( finalDataType ) { + if ( finalDataType !== dataTypes[ 0 ] ) { + dataTypes.unshift( finalDataType ); + } + return responses[ finalDataType ]; + } +} + +// Chain conversions given the request and the original response +function ajaxConvert( s, response ) { + + var conv, conv2, current, tmp, + // Work with a copy of dataTypes in case we need to modify it for conversion + dataTypes = s.dataTypes.slice(), + prev = dataTypes[ 0 ], + converters = {}, + i = 0; + + // Apply the dataFilter if provided + if ( s.dataFilter ) { + response = s.dataFilter( response, s.dataType ); + } + + // Create converters map with lowercased keys + if ( dataTypes[ 1 ] ) { + for ( conv in s.converters ) { + converters[ conv.toLowerCase() ] = s.converters[ conv ]; + } + } + + // Convert to each sequential dataType, tolerating list modification + for ( ; (current = dataTypes[++i]); ) { + + // There's only work to do if current dataType is non-auto + if ( current !== "*" ) { + + // Convert response if prev dataType is non-auto and differs from current + if ( prev !== "*" && prev !== current ) { + + // Seek a direct converter + conv = converters[ prev + " " + current ] || converters[ "* " + current ]; + + // If none found, seek a pair + if ( !conv ) { + for ( conv2 in converters ) { + + // If conv2 outputs current + tmp = conv2.split(" "); + if ( tmp[ 1 ] === current ) { + + // If prev can be converted to accepted input + conv = converters[ prev + " " + tmp[ 0 ] ] || + converters[ "* " + tmp[ 0 ] ]; + if ( conv ) { + // Condense equivalence converters + if ( conv === true ) { + conv = converters[ conv2 ]; + + // Otherwise, insert the intermediate dataType + } else if ( converters[ conv2 ] !== true ) { + current = tmp[ 0 ]; + dataTypes.splice( i--, 0, current ); + } + + break; + } + } + } + } + + // Apply converter (if not an equivalence) + if ( conv !== true ) { + + // Unless errors are allowed to bubble, catch and return them + if ( conv && s["throws"] ) { + response = conv( response ); + } else { + try { + response = conv( response ); + } catch ( e ) { + return { state: "parsererror", error: conv ? e : "No conversion from " + prev + " to " + current }; + } + } + } + } + + // Update prev for next iteration + prev = current; + } + } + + return { state: "success", data: response }; +} +var oldCallbacks = [], + rquestion = /\?/, + rjsonp = /(=)\?(?=&|$)|\?\?/, + nonce = jQuery.now(); + +// Default jsonp settings +jQuery.ajaxSetup({ + jsonp: "callback", + jsonpCallback: function() { + var callback = oldCallbacks.pop() || ( jQuery.expando + "_" + ( nonce++ ) ); + this[ callback ] = true; + return callback; + } +}); + +// Detect, normalize options and install callbacks for jsonp requests +jQuery.ajaxPrefilter( "json jsonp", function( s, originalSettings, jqXHR ) { + + var callbackName, overwritten, responseContainer, + data = s.data, + url = s.url, + hasCallback = s.jsonp !== false, + replaceInUrl = hasCallback && rjsonp.test( url ), + replaceInData = hasCallback && !replaceInUrl && typeof data === "string" && + !( s.contentType || "" ).indexOf("application/x-www-form-urlencoded") && + rjsonp.test( data ); + + // Handle iff the expected data type is "jsonp" or we have a parameter to set + if ( s.dataTypes[ 0 ] === "jsonp" || replaceInUrl || replaceInData ) { + + // Get callback name, remembering preexisting value associated with it + callbackName = s.jsonpCallback = jQuery.isFunction( s.jsonpCallback ) ? + s.jsonpCallback() : + s.jsonpCallback; + overwritten = window[ callbackName ]; + + // Insert callback into url or form data + if ( replaceInUrl ) { + s.url = url.replace( rjsonp, "$1" + callbackName ); + } else if ( replaceInData ) { + s.data = data.replace( rjsonp, "$1" + callbackName ); + } else if ( hasCallback ) { + s.url += ( rquestion.test( url ) ? "&" : "?" ) + s.jsonp + "=" + callbackName; + } + + // Use data converter to retrieve json after script execution + s.converters["script json"] = function() { + if ( !responseContainer ) { + jQuery.error( callbackName + " was not called" ); + } + return responseContainer[ 0 ]; + }; + + // force json dataType + s.dataTypes[ 0 ] = "json"; + + // Install callback + window[ callbackName ] = function() { + responseContainer = arguments; + }; + + // Clean-up function (fires after converters) + jqXHR.always(function() { + // Restore preexisting value + window[ callbackName ] = overwritten; + + // Save back as free + if ( s[ callbackName ] ) { + // make sure that re-using the options doesn't screw things around + s.jsonpCallback = originalSettings.jsonpCallback; + + // save the callback name for future use + oldCallbacks.push( callbackName ); + } + + // Call if it was a function and we have a response + if ( responseContainer && jQuery.isFunction( overwritten ) ) { + overwritten( responseContainer[ 0 ] ); + } + + responseContainer = overwritten = undefined; + }); + + // Delegate to script + return "script"; + } +}); +// Install script dataType +jQuery.ajaxSetup({ + accepts: { + script: "text/javascript, application/javascript, application/ecmascript, application/x-ecmascript" + }, + contents: { + script: /javascript|ecmascript/ + }, + converters: { + "text script": function( text ) { + jQuery.globalEval( text ); + return text; + } + } +}); + +// Handle cache's special case and global +jQuery.ajaxPrefilter( "script", function( s ) { + if ( s.cache === undefined ) { + s.cache = false; + } + if ( s.crossDomain ) { + s.type = "GET"; + s.global = false; + } +}); + +// Bind script tag hack transport +jQuery.ajaxTransport( "script", function(s) { + + // This transport only deals with cross domain requests + if ( s.crossDomain ) { + + var script, + head = document.head || document.getElementsByTagName( "head" )[0] || document.documentElement; + + return { + + send: function( _, callback ) { + + script = document.createElement( "script" ); + + script.async = "async"; + + if ( s.scriptCharset ) { + script.charset = s.scriptCharset; + } + + script.src = s.url; + + // Attach handlers for all browsers + script.onload = script.onreadystatechange = function( _, isAbort ) { + + if ( isAbort || !script.readyState || /loaded|complete/.test( script.readyState ) ) { + + // Handle memory leak in IE + script.onload = script.onreadystatechange = null; + + // Remove the script + if ( head && script.parentNode ) { + head.removeChild( script ); + } + + // Dereference the script + script = undefined; + + // Callback if not abort + if ( !isAbort ) { + callback( 200, "success" ); + } + } + }; + // Use insertBefore instead of appendChild to circumvent an IE6 bug. + // This arises when a base node is used (#2709 and #4378). + head.insertBefore( script, head.firstChild ); + }, + + abort: function() { + if ( script ) { + script.onload( 0, 1 ); + } + } + }; + } +}); +var xhrCallbacks, + // #5280: Internet Explorer will keep connections alive if we don't abort on unload + xhrOnUnloadAbort = window.ActiveXObject ? function() { + // Abort all pending requests + for ( var key in xhrCallbacks ) { + xhrCallbacks[ key ]( 0, 1 ); + } + } : false, + xhrId = 0; + +// Functions to create xhrs +function createStandardXHR() { + try { + return new window.XMLHttpRequest(); + } catch( e ) {} +} + +function createActiveXHR() { + try { + return new window.ActiveXObject( "Microsoft.XMLHTTP" ); + } catch( e ) {} +} + +// Create the request object +// (This is still attached to ajaxSettings for backward compatibility) +jQuery.ajaxSettings.xhr = window.ActiveXObject ? + /* Microsoft failed to properly + * implement the XMLHttpRequest in IE7 (can't request local files), + * so we use the ActiveXObject when it is available + * Additionally XMLHttpRequest can be disabled in IE7/IE8 so + * we need a fallback. + */ + function() { + return !this.isLocal && createStandardXHR() || createActiveXHR(); + } : + // For all other browsers, use the standard XMLHttpRequest object + createStandardXHR; + +// Determine support properties +(function( xhr ) { + jQuery.extend( jQuery.support, { + ajax: !!xhr, + cors: !!xhr && ( "withCredentials" in xhr ) + }); +})( jQuery.ajaxSettings.xhr() ); + +// Create transport if the browser can provide an xhr +if ( jQuery.support.ajax ) { + + jQuery.ajaxTransport(function( s ) { + // Cross domain only allowed if supported through XMLHttpRequest + if ( !s.crossDomain || jQuery.support.cors ) { + + var callback; + + return { + send: function( headers, complete ) { + + // Get a new xhr + var handle, i, + xhr = s.xhr(); + + // Open the socket + // Passing null username, generates a login popup on Opera (#2865) + if ( s.username ) { + xhr.open( s.type, s.url, s.async, s.username, s.password ); + } else { + xhr.open( s.type, s.url, s.async ); + } + + // Apply custom fields if provided + if ( s.xhrFields ) { + for ( i in s.xhrFields ) { + xhr[ i ] = s.xhrFields[ i ]; + } + } + + // Override mime type if needed + if ( s.mimeType && xhr.overrideMimeType ) { + xhr.overrideMimeType( s.mimeType ); + } + + // X-Requested-With header + // For cross-domain requests, seeing as conditions for a preflight are + // akin to a jigsaw puzzle, we simply never set it to be sure. + // (it can always be set on a per-request basis or even using ajaxSetup) + // For same-domain requests, won't change header if already provided. + if ( !s.crossDomain && !headers["X-Requested-With"] ) { + headers[ "X-Requested-With" ] = "XMLHttpRequest"; + } + + // Need an extra try/catch for cross domain requests in Firefox 3 + try { + for ( i in headers ) { + xhr.setRequestHeader( i, headers[ i ] ); + } + } catch( _ ) {} + + // Do send the request + // This may raise an exception which is actually + // handled in jQuery.ajax (so no try/catch here) + xhr.send( ( s.hasContent && s.data ) || null ); + + // Listener + callback = function( _, isAbort ) { + + var status, + statusText, + responseHeaders, + responses, + xml; + + // Firefox throws exceptions when accessing properties + // of an xhr when a network error occurred + // http://helpful.knobs-dials.com/index.php/Component_returned_failure_code:_0x80040111_(NS_ERROR_NOT_AVAILABLE) + try { + + // Was never called and is aborted or complete + if ( callback && ( isAbort || xhr.readyState === 4 ) ) { + + // Only called once + callback = undefined; + + // Do not keep as active anymore + if ( handle ) { + xhr.onreadystatechange = jQuery.noop; + if ( xhrOnUnloadAbort ) { + delete xhrCallbacks[ handle ]; + } + } + + // If it's an abort + if ( isAbort ) { + // Abort it manually if needed + if ( xhr.readyState !== 4 ) { + xhr.abort(); + } + } else { + status = xhr.status; + responseHeaders = xhr.getAllResponseHeaders(); + responses = {}; + xml = xhr.responseXML; + + // Construct response list + if ( xml && xml.documentElement /* #4958 */ ) { + responses.xml = xml; + } + + // When requesting binary data, IE6-9 will throw an exception + // on any attempt to access responseText (#11426) + try { + responses.text = xhr.responseText; + } catch( _ ) { + } + + // Firefox throws an exception when accessing + // statusText for faulty cross-domain requests + try { + statusText = xhr.statusText; + } catch( e ) { + // We normalize with Webkit giving an empty statusText + statusText = ""; + } + + // Filter status for non standard behaviors + + // If the request is local and we have data: assume a success + // (success with no data won't get notified, that's the best we + // can do given current implementations) + if ( !status && s.isLocal && !s.crossDomain ) { + status = responses.text ? 200 : 404; + // IE - #1450: sometimes returns 1223 when it should be 204 + } else if ( status === 1223 ) { + status = 204; + } + } + } + } catch( firefoxAccessException ) { + if ( !isAbort ) { + complete( -1, firefoxAccessException ); + } + } + + // Call complete if needed + if ( responses ) { + complete( status, statusText, responses, responseHeaders ); + } + }; + + if ( !s.async ) { + // if we're in sync mode we fire the callback + callback(); + } else if ( xhr.readyState === 4 ) { + // (IE6 & IE7) if it's in cache and has been + // retrieved directly we need to fire the callback + setTimeout( callback, 0 ); + } else { + handle = ++xhrId; + if ( xhrOnUnloadAbort ) { + // Create the active xhrs callbacks list if needed + // and attach the unload handler + if ( !xhrCallbacks ) { + xhrCallbacks = {}; + jQuery( window ).unload( xhrOnUnloadAbort ); + } + // Add to list of active xhrs callbacks + xhrCallbacks[ handle ] = callback; + } + xhr.onreadystatechange = callback; + } + }, + + abort: function() { + if ( callback ) { + callback(0,1); + } + } + }; + } + }); +} +var fxNow, timerId, + rfxtypes = /^(?:toggle|show|hide)$/, + rfxnum = new RegExp( "^(?:([-+])=|)(" + core_pnum + ")([a-z%]*)$", "i" ), + rrun = /queueHooks$/, + animationPrefilters = [ defaultPrefilter ], + tweeners = { + "*": [function( prop, value ) { + var end, unit, + tween = this.createTween( prop, value ), + parts = rfxnum.exec( value ), + target = tween.cur(), + start = +target || 0, + scale = 1, + maxIterations = 20; + + if ( parts ) { + end = +parts[2]; + unit = parts[3] || ( jQuery.cssNumber[ prop ] ? "" : "px" ); + + // We need to compute starting value + if ( unit !== "px" && start ) { + // Iteratively approximate from a nonzero starting point + // Prefer the current property, because this process will be trivial if it uses the same units + // Fallback to end or a simple constant + start = jQuery.css( tween.elem, prop, true ) || end || 1; + + do { + // If previous iteration zeroed out, double until we get *something* + // Use a string for doubling factor so we don't accidentally see scale as unchanged below + scale = scale || ".5"; + + // Adjust and apply + start = start / scale; + jQuery.style( tween.elem, prop, start + unit ); + + // Update scale, tolerating zero or NaN from tween.cur() + // And breaking the loop if scale is unchanged or perfect, or if we've just had enough + } while ( scale !== (scale = tween.cur() / target) && scale !== 1 && --maxIterations ); + } + + tween.unit = unit; + tween.start = start; + // If a +=/-= token was provided, we're doing a relative animation + tween.end = parts[1] ? start + ( parts[1] + 1 ) * end : end; + } + return tween; + }] + }; + +// Animations created synchronously will run synchronously +function createFxNow() { + setTimeout(function() { + fxNow = undefined; + }, 0 ); + return ( fxNow = jQuery.now() ); +} + +function createTweens( animation, props ) { + jQuery.each( props, function( prop, value ) { + var collection = ( tweeners[ prop ] || [] ).concat( tweeners[ "*" ] ), + index = 0, + length = collection.length; + for ( ; index < length; index++ ) { + if ( collection[ index ].call( animation, prop, value ) ) { + + // we're done with this property + return; + } + } + }); +} + +function Animation( elem, properties, options ) { + var result, + index = 0, + tweenerIndex = 0, + length = animationPrefilters.length, + deferred = jQuery.Deferred().always( function() { + // don't match elem in the :animated selector + delete tick.elem; + }), + tick = function() { + var currentTime = fxNow || createFxNow(), + remaining = Math.max( 0, animation.startTime + animation.duration - currentTime ), + percent = 1 - ( remaining / animation.duration || 0 ), + index = 0, + length = animation.tweens.length; + + for ( ; index < length ; index++ ) { + animation.tweens[ index ].run( percent ); + } + + deferred.notifyWith( elem, [ animation, percent, remaining ]); + + if ( percent < 1 && length ) { + return remaining; + } else { + deferred.resolveWith( elem, [ animation ] ); + return false; + } + }, + animation = deferred.promise({ + elem: elem, + props: jQuery.extend( {}, properties ), + opts: jQuery.extend( true, { specialEasing: {} }, options ), + originalProperties: properties, + originalOptions: options, + startTime: fxNow || createFxNow(), + duration: options.duration, + tweens: [], + createTween: function( prop, end, easing ) { + var tween = jQuery.Tween( elem, animation.opts, prop, end, + animation.opts.specialEasing[ prop ] || animation.opts.easing ); + animation.tweens.push( tween ); + return tween; + }, + stop: function( gotoEnd ) { + var index = 0, + // if we are going to the end, we want to run all the tweens + // otherwise we skip this part + length = gotoEnd ? animation.tweens.length : 0; + + for ( ; index < length ; index++ ) { + animation.tweens[ index ].run( 1 ); + } + + // resolve when we played the last frame + // otherwise, reject + if ( gotoEnd ) { + deferred.resolveWith( elem, [ animation, gotoEnd ] ); + } else { + deferred.rejectWith( elem, [ animation, gotoEnd ] ); + } + return this; + } + }), + props = animation.props; + + propFilter( props, animation.opts.specialEasing ); + + for ( ; index < length ; index++ ) { + result = animationPrefilters[ index ].call( animation, elem, props, animation.opts ); + if ( result ) { + return result; + } + } + + createTweens( animation, props ); + + if ( jQuery.isFunction( animation.opts.start ) ) { + animation.opts.start.call( elem, animation ); + } + + jQuery.fx.timer( + jQuery.extend( tick, { + anim: animation, + queue: animation.opts.queue, + elem: elem + }) + ); + + // attach callbacks from options + return animation.progress( animation.opts.progress ) + .done( animation.opts.done, animation.opts.complete ) + .fail( animation.opts.fail ) + .always( animation.opts.always ); +} + +function propFilter( props, specialEasing ) { + var index, name, easing, value, hooks; + + // camelCase, specialEasing and expand cssHook pass + for ( index in props ) { + name = jQuery.camelCase( index ); + easing = specialEasing[ name ]; + value = props[ index ]; + if ( jQuery.isArray( value ) ) { + easing = value[ 1 ]; + value = props[ index ] = value[ 0 ]; + } + + if ( index !== name ) { + props[ name ] = value; + delete props[ index ]; + } + + hooks = jQuery.cssHooks[ name ]; + if ( hooks && "expand" in hooks ) { + value = hooks.expand( value ); + delete props[ name ]; + + // not quite $.extend, this wont overwrite keys already present. + // also - reusing 'index' from above because we have the correct "name" + for ( index in value ) { + if ( !( index in props ) ) { + props[ index ] = value[ index ]; + specialEasing[ index ] = easing; + } + } + } else { + specialEasing[ name ] = easing; + } + } +} + +jQuery.Animation = jQuery.extend( Animation, { + + tweener: function( props, callback ) { + if ( jQuery.isFunction( props ) ) { + callback = props; + props = [ "*" ]; + } else { + props = props.split(" "); + } + + var prop, + index = 0, + length = props.length; + + for ( ; index < length ; index++ ) { + prop = props[ index ]; + tweeners[ prop ] = tweeners[ prop ] || []; + tweeners[ prop ].unshift( callback ); + } + }, + + prefilter: function( callback, prepend ) { + if ( prepend ) { + animationPrefilters.unshift( callback ); + } else { + animationPrefilters.push( callback ); + } + } +}); + +function defaultPrefilter( elem, props, opts ) { + var index, prop, value, length, dataShow, tween, hooks, oldfire, + anim = this, + style = elem.style, + orig = {}, + handled = [], + hidden = elem.nodeType && isHidden( elem ); + + // handle queue: false promises + if ( !opts.queue ) { + hooks = jQuery._queueHooks( elem, "fx" ); + if ( hooks.unqueued == null ) { + hooks.unqueued = 0; + oldfire = hooks.empty.fire; + hooks.empty.fire = function() { + if ( !hooks.unqueued ) { + oldfire(); + } + }; + } + hooks.unqueued++; + + anim.always(function() { + // doing this makes sure that the complete handler will be called + // before this completes + anim.always(function() { + hooks.unqueued--; + if ( !jQuery.queue( elem, "fx" ).length ) { + hooks.empty.fire(); + } + }); + }); + } + + // height/width overflow pass + if ( elem.nodeType === 1 && ( "height" in props || "width" in props ) ) { + // Make sure that nothing sneaks out + // Record all 3 overflow attributes because IE does not + // change the overflow attribute when overflowX and + // overflowY are set to the same value + opts.overflow = [ style.overflow, style.overflowX, style.overflowY ]; + + // Set display property to inline-block for height/width + // animations on inline elements that are having width/height animated + if ( jQuery.css( elem, "display" ) === "inline" && + jQuery.css( elem, "float" ) === "none" ) { + + // inline-level elements accept inline-block; + // block-level elements need to be inline with layout + if ( !jQuery.support.inlineBlockNeedsLayout || css_defaultDisplay( elem.nodeName ) === "inline" ) { + style.display = "inline-block"; + + } else { + style.zoom = 1; + } + } + } + + if ( opts.overflow ) { + style.overflow = "hidden"; + if ( !jQuery.support.shrinkWrapBlocks ) { + anim.done(function() { + style.overflow = opts.overflow[ 0 ]; + style.overflowX = opts.overflow[ 1 ]; + style.overflowY = opts.overflow[ 2 ]; + }); + } + } + + + // show/hide pass + for ( index in props ) { + value = props[ index ]; + if ( rfxtypes.exec( value ) ) { + delete props[ index ]; + if ( value === ( hidden ? "hide" : "show" ) ) { + continue; + } + handled.push( index ); + } + } + + length = handled.length; + if ( length ) { + dataShow = jQuery._data( elem, "fxshow" ) || jQuery._data( elem, "fxshow", {} ); + if ( hidden ) { + jQuery( elem ).show(); + } else { + anim.done(function() { + jQuery( elem ).hide(); + }); + } + anim.done(function() { + var prop; + jQuery.removeData( elem, "fxshow", true ); + for ( prop in orig ) { + jQuery.style( elem, prop, orig[ prop ] ); + } + }); + for ( index = 0 ; index < length ; index++ ) { + prop = handled[ index ]; + tween = anim.createTween( prop, hidden ? dataShow[ prop ] : 0 ); + orig[ prop ] = dataShow[ prop ] || jQuery.style( elem, prop ); + + if ( !( prop in dataShow ) ) { + dataShow[ prop ] = tween.start; + if ( hidden ) { + tween.end = tween.start; + tween.start = prop === "width" || prop === "height" ? 1 : 0; + } + } + } + } +} + +function Tween( elem, options, prop, end, easing ) { + return new Tween.prototype.init( elem, options, prop, end, easing ); +} +jQuery.Tween = Tween; + +Tween.prototype = { + constructor: Tween, + init: function( elem, options, prop, end, easing, unit ) { + this.elem = elem; + this.prop = prop; + this.easing = easing || "swing"; + this.options = options; + this.start = this.now = this.cur(); + this.end = end; + this.unit = unit || ( jQuery.cssNumber[ prop ] ? "" : "px" ); + }, + cur: function() { + var hooks = Tween.propHooks[ this.prop ]; + + return hooks && hooks.get ? + hooks.get( this ) : + Tween.propHooks._default.get( this ); + }, + run: function( percent ) { + var eased, + hooks = Tween.propHooks[ this.prop ]; + + if ( this.options.duration ) { + this.pos = eased = jQuery.easing[ this.easing ]( + percent, this.options.duration * percent, 0, 1, this.options.duration + ); + } else { + this.pos = eased = percent; + } + this.now = ( this.end - this.start ) * eased + this.start; + + if ( this.options.step ) { + this.options.step.call( this.elem, this.now, this ); + } + + if ( hooks && hooks.set ) { + hooks.set( this ); + } else { + Tween.propHooks._default.set( this ); + } + return this; + } +}; + +Tween.prototype.init.prototype = Tween.prototype; + +Tween.propHooks = { + _default: { + get: function( tween ) { + var result; + + if ( tween.elem[ tween.prop ] != null && + (!tween.elem.style || tween.elem.style[ tween.prop ] == null) ) { + return tween.elem[ tween.prop ]; + } + + // passing any value as a 4th parameter to .css will automatically + // attempt a parseFloat and fallback to a string if the parse fails + // so, simple values such as "10px" are parsed to Float. + // complex values such as "rotate(1rad)" are returned as is. + result = jQuery.css( tween.elem, tween.prop, false, "" ); + // Empty strings, null, undefined and "auto" are converted to 0. + return !result || result === "auto" ? 0 : result; + }, + set: function( tween ) { + // use step hook for back compat - use cssHook if its there - use .style if its + // available and use plain properties where available + if ( jQuery.fx.step[ tween.prop ] ) { + jQuery.fx.step[ tween.prop ]( tween ); + } else if ( tween.elem.style && ( tween.elem.style[ jQuery.cssProps[ tween.prop ] ] != null || jQuery.cssHooks[ tween.prop ] ) ) { + jQuery.style( tween.elem, tween.prop, tween.now + tween.unit ); + } else { + tween.elem[ tween.prop ] = tween.now; + } + } + } +}; + +// Remove in 2.0 - this supports IE8's panic based approach +// to setting things on disconnected nodes + +Tween.propHooks.scrollTop = Tween.propHooks.scrollLeft = { + set: function( tween ) { + if ( tween.elem.nodeType && tween.elem.parentNode ) { + tween.elem[ tween.prop ] = tween.now; + } + } +}; + +jQuery.each([ "toggle", "show", "hide" ], function( i, name ) { + var cssFn = jQuery.fn[ name ]; + jQuery.fn[ name ] = function( speed, easing, callback ) { + return speed == null || typeof speed === "boolean" || + // special check for .toggle( handler, handler, ... ) + ( !i && jQuery.isFunction( speed ) && jQuery.isFunction( easing ) ) ? + cssFn.apply( this, arguments ) : + this.animate( genFx( name, true ), speed, easing, callback ); + }; +}); + +jQuery.fn.extend({ + fadeTo: function( speed, to, easing, callback ) { + + // show any hidden elements after setting opacity to 0 + return this.filter( isHidden ).css( "opacity", 0 ).show() + + // animate to the value specified + .end().animate({ opacity: to }, speed, easing, callback ); + }, + animate: function( prop, speed, easing, callback ) { + var empty = jQuery.isEmptyObject( prop ), + optall = jQuery.speed( speed, easing, callback ), + doAnimation = function() { + // Operate on a copy of prop so per-property easing won't be lost + var anim = Animation( this, jQuery.extend( {}, prop ), optall ); + + // Empty animations resolve immediately + if ( empty ) { + anim.stop( true ); + } + }; + + return empty || optall.queue === false ? + this.each( doAnimation ) : + this.queue( optall.queue, doAnimation ); + }, + stop: function( type, clearQueue, gotoEnd ) { + var stopQueue = function( hooks ) { + var stop = hooks.stop; + delete hooks.stop; + stop( gotoEnd ); + }; + + if ( typeof type !== "string" ) { + gotoEnd = clearQueue; + clearQueue = type; + type = undefined; + } + if ( clearQueue && type !== false ) { + this.queue( type || "fx", [] ); + } + + return this.each(function() { + var dequeue = true, + index = type != null && type + "queueHooks", + timers = jQuery.timers, + data = jQuery._data( this ); + + if ( index ) { + if ( data[ index ] && data[ index ].stop ) { + stopQueue( data[ index ] ); + } + } else { + for ( index in data ) { + if ( data[ index ] && data[ index ].stop && rrun.test( index ) ) { + stopQueue( data[ index ] ); + } + } + } + + for ( index = timers.length; index--; ) { + if ( timers[ index ].elem === this && (type == null || timers[ index ].queue === type) ) { + timers[ index ].anim.stop( gotoEnd ); + dequeue = false; + timers.splice( index, 1 ); + } + } + + // start the next in the queue if the last step wasn't forced + // timers currently will call their complete callbacks, which will dequeue + // but only if they were gotoEnd + if ( dequeue || !gotoEnd ) { + jQuery.dequeue( this, type ); + } + }); + } +}); + +// Generate parameters to create a standard animation +function genFx( type, includeWidth ) { + var which, + attrs = { height: type }, + i = 0; + + // if we include width, step value is 1 to do all cssExpand values, + // if we don't include width, step value is 2 to skip over Left and Right + includeWidth = includeWidth? 1 : 0; + for( ; i < 4 ; i += 2 - includeWidth ) { + which = cssExpand[ i ]; + attrs[ "margin" + which ] = attrs[ "padding" + which ] = type; + } + + if ( includeWidth ) { + attrs.opacity = attrs.width = type; + } + + return attrs; +} + +// Generate shortcuts for custom animations +jQuery.each({ + slideDown: genFx("show"), + slideUp: genFx("hide"), + slideToggle: genFx("toggle"), + fadeIn: { opacity: "show" }, + fadeOut: { opacity: "hide" }, + fadeToggle: { opacity: "toggle" } +}, function( name, props ) { + jQuery.fn[ name ] = function( speed, easing, callback ) { + return this.animate( props, speed, easing, callback ); + }; +}); + +jQuery.speed = function( speed, easing, fn ) { + var opt = speed && typeof speed === "object" ? jQuery.extend( {}, speed ) : { + complete: fn || !fn && easing || + jQuery.isFunction( speed ) && speed, + duration: speed, + easing: fn && easing || easing && !jQuery.isFunction( easing ) && easing + }; + + opt.duration = jQuery.fx.off ? 0 : typeof opt.duration === "number" ? opt.duration : + opt.duration in jQuery.fx.speeds ? jQuery.fx.speeds[ opt.duration ] : jQuery.fx.speeds._default; + + // normalize opt.queue - true/undefined/null -> "fx" + if ( opt.queue == null || opt.queue === true ) { + opt.queue = "fx"; + } + + // Queueing + opt.old = opt.complete; + + opt.complete = function() { + if ( jQuery.isFunction( opt.old ) ) { + opt.old.call( this ); + } + + if ( opt.queue ) { + jQuery.dequeue( this, opt.queue ); + } + }; + + return opt; +}; + +jQuery.easing = { + linear: function( p ) { + return p; + }, + swing: function( p ) { + return 0.5 - Math.cos( p*Math.PI ) / 2; + } +}; + +jQuery.timers = []; +jQuery.fx = Tween.prototype.init; +jQuery.fx.tick = function() { + var timer, + timers = jQuery.timers, + i = 0; + + for ( ; i < timers.length; i++ ) { + timer = timers[ i ]; + // Checks the timer has not already been removed + if ( !timer() && timers[ i ] === timer ) { + timers.splice( i--, 1 ); + } + } + + if ( !timers.length ) { + jQuery.fx.stop(); + } +}; + +jQuery.fx.timer = function( timer ) { + if ( timer() && jQuery.timers.push( timer ) && !timerId ) { + timerId = setInterval( jQuery.fx.tick, jQuery.fx.interval ); + } +}; + +jQuery.fx.interval = 13; + +jQuery.fx.stop = function() { + clearInterval( timerId ); + timerId = null; +}; + +jQuery.fx.speeds = { + slow: 600, + fast: 200, + // Default speed + _default: 400 +}; + +// Back Compat <1.8 extension point +jQuery.fx.step = {}; + +if ( jQuery.expr && jQuery.expr.filters ) { + jQuery.expr.filters.animated = function( elem ) { + return jQuery.grep(jQuery.timers, function( fn ) { + return elem === fn.elem; + }).length; + }; +} +var rroot = /^(?:body|html)$/i; + +jQuery.fn.offset = function( options ) { + if ( arguments.length ) { + return options === undefined ? + this : + this.each(function( i ) { + jQuery.offset.setOffset( this, options, i ); + }); + } + + var docElem, body, win, clientTop, clientLeft, scrollTop, scrollLeft, + box = { top: 0, left: 0 }, + elem = this[ 0 ], + doc = elem && elem.ownerDocument; + + if ( !doc ) { + return; + } + + if ( (body = doc.body) === elem ) { + return jQuery.offset.bodyOffset( elem ); + } + + docElem = doc.documentElement; + + // Make sure it's not a disconnected DOM node + if ( !jQuery.contains( docElem, elem ) ) { + return box; + } + + // If we don't have gBCR, just use 0,0 rather than error + // BlackBerry 5, iOS 3 (original iPhone) + if ( typeof elem.getBoundingClientRect !== "undefined" ) { + box = elem.getBoundingClientRect(); + } + win = getWindow( doc ); + clientTop = docElem.clientTop || body.clientTop || 0; + clientLeft = docElem.clientLeft || body.clientLeft || 0; + scrollTop = win.pageYOffset || docElem.scrollTop; + scrollLeft = win.pageXOffset || docElem.scrollLeft; + return { + top: box.top + scrollTop - clientTop, + left: box.left + scrollLeft - clientLeft + }; +}; + +jQuery.offset = { + + bodyOffset: function( body ) { + var top = body.offsetTop, + left = body.offsetLeft; + + if ( jQuery.support.doesNotIncludeMarginInBodyOffset ) { + top += parseFloat( jQuery.css(body, "marginTop") ) || 0; + left += parseFloat( jQuery.css(body, "marginLeft") ) || 0; + } + + return { top: top, left: left }; + }, + + setOffset: function( elem, options, i ) { + var position = jQuery.css( elem, "position" ); + + // set position first, in-case top/left are set even on static elem + if ( position === "static" ) { + elem.style.position = "relative"; + } + + var curElem = jQuery( elem ), + curOffset = curElem.offset(), + curCSSTop = jQuery.css( elem, "top" ), + curCSSLeft = jQuery.css( elem, "left" ), + calculatePosition = ( position === "absolute" || position === "fixed" ) && jQuery.inArray("auto", [curCSSTop, curCSSLeft]) > -1, + props = {}, curPosition = {}, curTop, curLeft; + + // need to be able to calculate position if either top or left is auto and position is either absolute or fixed + if ( calculatePosition ) { + curPosition = curElem.position(); + curTop = curPosition.top; + curLeft = curPosition.left; + } else { + curTop = parseFloat( curCSSTop ) || 0; + curLeft = parseFloat( curCSSLeft ) || 0; + } + + if ( jQuery.isFunction( options ) ) { + options = options.call( elem, i, curOffset ); + } + + if ( options.top != null ) { + props.top = ( options.top - curOffset.top ) + curTop; + } + if ( options.left != null ) { + props.left = ( options.left - curOffset.left ) + curLeft; + } + + if ( "using" in options ) { + options.using.call( elem, props ); + } else { + curElem.css( props ); + } + } +}; + + +jQuery.fn.extend({ + + position: function() { + if ( !this[0] ) { + return; + } + + var elem = this[0], + + // Get *real* offsetParent + offsetParent = this.offsetParent(), + + // Get correct offsets + offset = this.offset(), + parentOffset = rroot.test(offsetParent[0].nodeName) ? { top: 0, left: 0 } : offsetParent.offset(); + + // Subtract element margins + // note: when an element has margin: auto the offsetLeft and marginLeft + // are the same in Safari causing offset.left to incorrectly be 0 + offset.top -= parseFloat( jQuery.css(elem, "marginTop") ) || 0; + offset.left -= parseFloat( jQuery.css(elem, "marginLeft") ) || 0; + + // Add offsetParent borders + parentOffset.top += parseFloat( jQuery.css(offsetParent[0], "borderTopWidth") ) || 0; + parentOffset.left += parseFloat( jQuery.css(offsetParent[0], "borderLeftWidth") ) || 0; + + // Subtract the two offsets + return { + top: offset.top - parentOffset.top, + left: offset.left - parentOffset.left + }; + }, + + offsetParent: function() { + return this.map(function() { + var offsetParent = this.offsetParent || document.body; + while ( offsetParent && (!rroot.test(offsetParent.nodeName) && jQuery.css(offsetParent, "position") === "static") ) { + offsetParent = offsetParent.offsetParent; + } + return offsetParent || document.body; + }); + } +}); + + +// Create scrollLeft and scrollTop methods +jQuery.each( {scrollLeft: "pageXOffset", scrollTop: "pageYOffset"}, function( method, prop ) { + var top = /Y/.test( prop ); + + jQuery.fn[ method ] = function( val ) { + return jQuery.access( this, function( elem, method, val ) { + var win = getWindow( elem ); + + if ( val === undefined ) { + return win ? (prop in win) ? win[ prop ] : + win.document.documentElement[ method ] : + elem[ method ]; + } + + if ( win ) { + win.scrollTo( + !top ? val : jQuery( win ).scrollLeft(), + top ? val : jQuery( win ).scrollTop() + ); + + } else { + elem[ method ] = val; + } + }, method, val, arguments.length, null ); + }; +}); + +function getWindow( elem ) { + return jQuery.isWindow( elem ) ? + elem : + elem.nodeType === 9 ? + elem.defaultView || elem.parentWindow : + false; +} +// Create innerHeight, innerWidth, height, width, outerHeight and outerWidth methods +jQuery.each( { Height: "height", Width: "width" }, function( name, type ) { + jQuery.each( { padding: "inner" + name, content: type, "": "outer" + name }, function( defaultExtra, funcName ) { + // margin is only for outerHeight, outerWidth + jQuery.fn[ funcName ] = function( margin, value ) { + var chainable = arguments.length && ( defaultExtra || typeof margin !== "boolean" ), + extra = defaultExtra || ( margin === true || value === true ? "margin" : "border" ); + + return jQuery.access( this, function( elem, type, value ) { + var doc; + + if ( jQuery.isWindow( elem ) ) { + // As of 5/8/2012 this will yield incorrect results for Mobile Safari, but there + // isn't a whole lot we can do. See pull request at this URL for discussion: + // https://github.com/jquery/jquery/pull/764 + return elem.document.documentElement[ "client" + name ]; + } + + // Get document width or height + if ( elem.nodeType === 9 ) { + doc = elem.documentElement; + + // Either scroll[Width/Height] or offset[Width/Height] or client[Width/Height], whichever is greatest + // unfortunately, this causes bug #3838 in IE6/8 only, but there is currently no good, small way to fix it. + return Math.max( + elem.body[ "scroll" + name ], doc[ "scroll" + name ], + elem.body[ "offset" + name ], doc[ "offset" + name ], + doc[ "client" + name ] + ); + } + + return value === undefined ? + // Get width or height on the element, requesting but not forcing parseFloat + jQuery.css( elem, type, value, extra ) : + + // Set width or height on the element + jQuery.style( elem, type, value, extra ); + }, type, chainable ? margin : undefined, chainable, null ); + }; + }); +}); +// Expose jQuery to the global object +window.jQuery = window.$ = jQuery; + +// Expose jQuery as an AMD module, but only for AMD loaders that +// understand the issues with loading multiple versions of jQuery +// in a page that all might call define(). The loader will indicate +// they have special allowances for multiple jQuery versions by +// specifying define.amd.jQuery = true. Register as a named module, +// since jQuery can be concatenated with other files that may use define, +// but not use a proper concatenation script that understands anonymous +// AMD modules. A named AMD is safest and most robust way to register. +// Lowercase jquery is used because AMD module names are derived from +// file names, and jQuery is normally delivered in a lowercase file name. +// Do this after creating the global so that if an AMD module wants to call +// noConflict to hide this version of jQuery, it will work. +if ( typeof define === "function" && define.amd && define.amd.jQuery ) { + define( "jquery", [], function () { return jQuery; } ); +} + +})( window ); diff --git a/htdocs/js/jquery-ui-1.9.0.custom/js/jquery-ui-1.9.0.custom.js b/htdocs/js/jquery-ui-1.9.0.custom/js/jquery-ui-1.9.0.custom.js new file mode 100755 index 000000000..dbaa85e86 --- /dev/null +++ b/htdocs/js/jquery-ui-1.9.0.custom/js/jquery-ui-1.9.0.custom.js @@ -0,0 +1,14709 @@ +/*! jQuery UI - v1.9.0 - 2012-10-13 +* http://jqueryui.com +* Includes: jquery.ui.core.js, jquery.ui.widget.js, jquery.ui.mouse.js, jquery.ui.position.js, jquery.ui.draggable.js, jquery.ui.droppable.js, jquery.ui.resizable.js, jquery.ui.selectable.js, jquery.ui.sortable.js, jquery.ui.accordion.js, jquery.ui.autocomplete.js, jquery.ui.button.js, jquery.ui.datepicker.js, jquery.ui.dialog.js, jquery.ui.menu.js, jquery.ui.progressbar.js, jquery.ui.slider.js, jquery.ui.spinner.js, jquery.ui.tabs.js, jquery.ui.tooltip.js, jquery.ui.effect.js, jquery.ui.effect-blind.js, jquery.ui.effect-bounce.js, jquery.ui.effect-clip.js, jquery.ui.effect-drop.js, jquery.ui.effect-explode.js, jquery.ui.effect-fade.js, jquery.ui.effect-fold.js, jquery.ui.effect-highlight.js, jquery.ui.effect-pulsate.js, jquery.ui.effect-scale.js, jquery.ui.effect-shake.js, jquery.ui.effect-slide.js, jquery.ui.effect-transfer.js +* Copyright (c) 2012 jQuery Foundation and other contributors Licensed MIT */ + +(function( $, undefined ) { + +var uuid = 0, + runiqueId = /^ui-id-\d+$/; + +// prevent duplicate loading +// this is only a problem because we proxy existing functions +// and we don't want to double proxy them +$.ui = $.ui || {}; +if ( $.ui.version ) { + return; +} + +$.extend( $.ui, { + version: "1.9.0", + + keyCode: { + BACKSPACE: 8, + COMMA: 188, + DELETE: 46, + DOWN: 40, + END: 35, + ENTER: 13, + ESCAPE: 27, + HOME: 36, + LEFT: 37, + NUMPAD_ADD: 107, + NUMPAD_DECIMAL: 110, + NUMPAD_DIVIDE: 111, + NUMPAD_ENTER: 108, + NUMPAD_MULTIPLY: 106, + NUMPAD_SUBTRACT: 109, + PAGE_DOWN: 34, + PAGE_UP: 33, + PERIOD: 190, + RIGHT: 39, + SPACE: 32, + TAB: 9, + UP: 38 + } +}); + +// plugins +$.fn.extend({ + _focus: $.fn.focus, + focus: function( delay, fn ) { + return typeof delay === "number" ? + this.each(function() { + var elem = this; + setTimeout(function() { + $( elem ).focus(); + if ( fn ) { + fn.call( elem ); + } + }, delay ); + }) : + this._focus.apply( this, arguments ); + }, + + scrollParent: function() { + var scrollParent; + if (($.browser.msie && (/(static|relative)/).test(this.css('position'))) || (/absolute/).test(this.css('position'))) { + scrollParent = this.parents().filter(function() { + return (/(relative|absolute|fixed)/).test($.css(this,'position')) && (/(auto|scroll)/).test($.css(this,'overflow')+$.css(this,'overflow-y')+$.css(this,'overflow-x')); + }).eq(0); + } else { + scrollParent = this.parents().filter(function() { + return (/(auto|scroll)/).test($.css(this,'overflow')+$.css(this,'overflow-y')+$.css(this,'overflow-x')); + }).eq(0); + } + + return (/fixed/).test(this.css('position')) || !scrollParent.length ? $(document) : scrollParent; + }, + + zIndex: function( zIndex ) { + if ( zIndex !== undefined ) { + return this.css( "zIndex", zIndex ); + } + + if ( this.length ) { + var elem = $( this[ 0 ] ), position, value; + while ( elem.length && elem[ 0 ] !== document ) { + // Ignore z-index if position is set to a value where z-index is ignored by the browser + // This makes behavior of this function consistent across browsers + // WebKit always returns auto if the element is positioned + position = elem.css( "position" ); + if ( position === "absolute" || position === "relative" || position === "fixed" ) { + // IE returns 0 when zIndex is not specified + // other browsers return a string + // we ignore the case of nested elements with an explicit value of 0 + //
      + value = parseInt( elem.css( "zIndex" ), 10 ); + if ( !isNaN( value ) && value !== 0 ) { + return value; + } + } + elem = elem.parent(); + } + } + + return 0; + }, + + uniqueId: function() { + return this.each(function() { + if ( !this.id ) { + this.id = "ui-id-" + (++uuid); + } + }); + }, + + removeUniqueId: function() { + return this.each(function() { + if ( runiqueId.test( this.id ) ) { + $( this ).removeAttr( "id" ); + } + }); + } +}); + +// support: jQuery <1.8 +if ( !$( "" ).outerWidth( 1 ).jquery ) { + $.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( $.css( elem, "padding" + this ) ) || 0; + if ( border ) { + size -= parseFloat( $.css( elem, "border" + this + "Width" ) ) || 0; + } + if ( margin ) { + size -= parseFloat( $.css( elem, "margin" + this ) ) || 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 map, mapName, img, + nodeName = element.nodeName.toLowerCase(); + if ( "area" === nodeName ) { + map = element.parentNode; + mapName = map.name; + 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 $.css( this, "visibility" ) === "hidden" || + $.expr.filters.hidden( this ); + }).length; +} + +$.extend( $.expr[ ":" ], { + data: $.expr.createPseudo ? + $.expr.createPseudo(function( dataName ) { + return function( elem ) { + return !!$.data( elem, dataName ); + }; + }) : + // support: jQuery <1.8 + 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" ) ); + + // access offsetHeight before setting the style to prevent a layout bug + // in IE 9 which causes the element to continue to take up space even + // after it is removed from the DOM (#8026) + div.offsetHeight; + + $.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 + +$.fn.extend({ + disableSelection: function() { + return this.bind( ( $.support.selectstart ? "selectstart" : "mousedown" ) + + ".ui-disableSelection", function( event ) { + event.preventDefault(); + }); + }, + + enableSelection: function() { + return this.unbind( ".ui-disableSelection" ); + } +}); + +$.extend( $.ui, { + // $.ui.plugin is deprecated. Use the proxy pattern instead. + plugin: { + add: function( module, option, set ) { + var i, + proto = $.ui[ module ].prototype; + for ( i in set ) { + proto.plugins[ i ] = proto.plugins[ i ] || []; + proto.plugins[ i ].push( [ option, set[ i ] ] ); + } + }, + call: function( instance, name, args ) { + var i, + set = instance.plugins[ name ]; + if ( !set || !instance.element[ 0 ].parentNode || instance.element[ 0 ].parentNode.nodeType === 11 ) { + return; + } + + for ( i = 0; i < set.length; i++ ) { + if ( instance.options[ set[ i ][ 0 ] ] ) { + set[ i ][ 1 ].apply( instance.element, args ); + } + } + } + }, + + contains: $.contains, + + // 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 ); +(function( $, undefined ) { + +var uuid = 0, + slice = Array.prototype.slice, + _cleanData = $.cleanData; +$.cleanData = function( elems ) { + for ( var i = 0, elem; (elem = elems[i]) != null; i++ ) { + try { + $( elem ).triggerHandler( "remove" ); + // http://bugs.jquery.com/ticket/8235 + } catch( e ) {} + } + _cleanData( elems ); +}; + +$.widget = function( name, base, prototype ) { + var fullName, existingConstructor, constructor, basePrototype, + namespace = name.split( "." )[ 0 ]; + + name = name.split( "." )[ 1 ]; + fullName = namespace + "-" + name; + + if ( !prototype ) { + prototype = base; + base = $.Widget; + } + + // create selector for plugin + $.expr[ ":" ][ fullName.toLowerCase() ] = function( elem ) { + return !!$.data( elem, fullName ); + }; + + $[ namespace ] = $[ namespace ] || {}; + existingConstructor = $[ namespace ][ name ]; + constructor = $[ namespace ][ name ] = function( options, element ) { + // allow instantiation without "new" keyword + if ( !this._createWidget ) { + return new constructor( options, element ); + } + + // allow instantiation without initializing for simple inheritance + // must use "new" keyword (the code above always passes args) + if ( arguments.length ) { + this._createWidget( options, element ); + } + }; + // extend with the existing constructor to carry over any static properties + $.extend( constructor, existingConstructor, { + version: prototype.version, + // copy the object used to create the prototype in case we need to + // redefine the widget later + _proto: $.extend( {}, prototype ), + // track widgets that inherit from this widget in case this widget is + // redefined after a widget inherits from it + _childConstructors: [] + }); + + 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 + basePrototype.options = $.widget.extend( {}, basePrototype.options ); + $.each( prototype, function( prop, value ) { + if ( $.isFunction( value ) ) { + prototype[ prop ] = (function() { + var _super = function() { + return base.prototype[ prop ].apply( this, arguments ); + }, + _superApply = function( args ) { + return base.prototype[ prop ].apply( this, args ); + }; + return function() { + var __super = this._super, + __superApply = this._superApply, + returnValue; + + this._super = _super; + this._superApply = _superApply; + + returnValue = value.apply( this, arguments ); + + this._super = __super; + this._superApply = __superApply; + + return returnValue; + }; + })(); + } + }); + constructor.prototype = $.widget.extend( basePrototype, { + // TODO: remove support for widgetEventPrefix + // always use the name + a colon as the prefix, e.g., draggable:start + // don't prefix for widgets that aren't DOM-based + widgetEventPrefix: name + }, prototype, { + constructor: constructor, + namespace: namespace, + widgetName: name, + // TODO remove widgetBaseClass, see #8155 + widgetBaseClass: fullName, + widgetFullName: fullName + }); + + // If this widget is being redefined then we need to find all widgets that + // are inheriting from it and redefine all of them so that they inherit from + // the new version of this widget. We're essentially trying to replace one + // level in the prototype chain. + if ( existingConstructor ) { + $.each( existingConstructor._childConstructors, function( i, child ) { + var childPrototype = child.prototype; + + // redefine the child widget using the same prototype that was + // originally used, but inherit from the new version of the base + $.widget( childPrototype.namespace + "." + childPrototype.widgetName, constructor, child._proto ); + }); + // remove the list of existing child constructors from the old constructor + // so the old child constructors can be garbage collected + delete existingConstructor._childConstructors; + } else { + base._childConstructors.push( constructor ); + } + + $.widget.bridge( name, constructor ); +}; + +$.widget.extend = function( target ) { + var input = slice.call( arguments, 1 ), + inputIndex = 0, + inputLength = input.length, + key, + value; + for ( ; inputIndex < inputLength; inputIndex++ ) { + for ( key in input[ inputIndex ] ) { + value = input[ inputIndex ][ key ]; + if (input[ inputIndex ].hasOwnProperty( key ) && value !== undefined ) { + target[ key ] = $.isPlainObject( value ) ? $.widget.extend( {}, target[ key ], value ) : value; + } + } + } + return target; +}; + +$.widget.bridge = function( name, object ) { + var fullName = object.prototype.widgetFullName; + $.fn[ name ] = function( options ) { + var isMethodCall = typeof options === "string", + args = slice.call( arguments, 1 ), + returnValue = this; + + // allow multiple hashes to be passed on init + options = !isMethodCall && args.length ? + $.widget.extend.apply( null, [ options ].concat(args) ) : + options; + + if ( isMethodCall ) { + this.each(function() { + var methodValue, + instance = $.data( this, fullName ); + if ( !instance ) { + return $.error( "cannot call methods on " + name + " prior to initialization; " + + "attempted to call method '" + options + "'" ); + } + if ( !$.isFunction( instance[options] ) || options.charAt( 0 ) === "_" ) { + return $.error( "no such method '" + options + "' for " + name + " widget instance" ); + } + methodValue = instance[ options ].apply( instance, args ); + if ( methodValue !== instance && methodValue !== undefined ) { + returnValue = methodValue && methodValue.jquery ? + returnValue.pushStack( methodValue.get() ) : + methodValue; + return false; + } + }); + } else { + this.each(function() { + var instance = $.data( this, fullName ); + if ( instance ) { + instance.option( options || {} )._init(); + } else { + new object( options, this ); + } + }); + } + + return returnValue; + }; +}; + +$.Widget = function( options, element ) {}; +$.Widget._childConstructors = []; + +$.Widget.prototype = { + widgetName: "widget", + widgetEventPrefix: "", + defaultElement: "
      ", + options: { + disabled: false, + + // callbacks + create: null + }, + _createWidget: function( options, element ) { + element = $( element || this.defaultElement || this )[ 0 ]; + this.element = $( element ); + this.uuid = uuid++; + this.eventNamespace = "." + this.widgetName + this.uuid; + this.options = $.widget.extend( {}, + this.options, + this._getCreateOptions(), + options ); + + this.bindings = $(); + this.hoverable = $(); + this.focusable = $(); + + if ( element !== this ) { + // 1.9 BC for #7810 + // TODO remove dual storage + $.data( element, this.widgetName, this ); + $.data( element, this.widgetFullName, this ); + this._on({ remove: "destroy" }); + this.document = $( element.style ? + // element within the document + element.ownerDocument : + // element is window or document + element.document || element ); + this.window = $( this.document[0].defaultView || this.document[0].parentWindow ); + } + + this._create(); + this._trigger( "create", null, this._getCreateEventData() ); + this._init(); + }, + _getCreateOptions: $.noop, + _getCreateEventData: $.noop, + _create: $.noop, + _init: $.noop, + + destroy: function() { + this._destroy(); + // we can probably remove the unbind calls in 2.0 + // all event bindings should go through this._on() + this.element + .unbind( this.eventNamespace ) + // 1.9 BC for #7810 + // TODO remove dual storage + .removeData( this.widgetName ) + .removeData( this.widgetFullName ) + // support: jquery <1.6.3 + // http://bugs.jquery.com/ticket/9413 + .removeData( $.camelCase( this.widgetFullName ) ); + this.widget() + .unbind( this.eventNamespace ) + .removeAttr( "aria-disabled" ) + .removeClass( + this.widgetFullName + "-disabled " + + "ui-state-disabled" ); + + // clean up events and states + this.bindings.unbind( this.eventNamespace ); + this.hoverable.removeClass( "ui-state-hover" ); + this.focusable.removeClass( "ui-state-focus" ); + }, + _destroy: $.noop, + + widget: function() { + return this.element; + }, + + option: function( key, value ) { + var options = key, + parts, + curOption, + i; + + if ( arguments.length === 0 ) { + // don't return a reference to the internal hash + return $.widget.extend( {}, this.options ); + } + + if ( typeof key === "string" ) { + // handle nested keys, e.g., "foo.bar" => { foo: { bar: ___ } } + options = {}; + parts = key.split( "." ); + key = parts.shift(); + if ( parts.length ) { + curOption = options[ key ] = $.widget.extend( {}, this.options[ key ] ); + for ( i = 0; i < parts.length - 1; i++ ) { + curOption[ parts[ i ] ] = curOption[ parts[ i ] ] || {}; + curOption = curOption[ parts[ i ] ]; + } + key = parts.pop(); + if ( value === undefined ) { + return curOption[ key ] === undefined ? null : curOption[ key ]; + } + curOption[ key ] = value; + } else { + if ( value === undefined ) { + return this.options[ key ] === undefined ? null : this.options[ key ]; + } + options[ key ] = value; + } + } + + this._setOptions( options ); + + return this; + }, + _setOptions: function( options ) { + var key; + + for ( key in options ) { + this._setOption( key, options[ key ] ); + } + + return this; + }, + _setOption: function( key, value ) { + this.options[ key ] = value; + + if ( key === "disabled" ) { + this.widget() + .toggleClass( this.widgetFullName + "-disabled ui-state-disabled", !!value ) + .attr( "aria-disabled", value ); + this.hoverable.removeClass( "ui-state-hover" ); + this.focusable.removeClass( "ui-state-focus" ); + } + + return this; + }, + + enable: function() { + return this._setOption( "disabled", false ); + }, + disable: function() { + return this._setOption( "disabled", true ); + }, + + _on: function( element, handlers ) { + // no element argument, shuffle and use this.element + if ( !handlers ) { + handlers = element; + element = this.element; + } else { + // accept selectors, DOM elements + element = $( element ); + this.bindings = this.bindings.add( element ); + } + + var instance = this; + $.each( handlers, function( event, handler ) { + function handlerProxy() { + // allow widgets to customize the disabled handling + // - disabled as an array instead of boolean + // - disabled class as method for disabling individual parts + if ( instance.options.disabled === true || + $( this ).hasClass( "ui-state-disabled" ) ) { + return; + } + return ( typeof handler === "string" ? instance[ handler ] : handler ) + .apply( instance, arguments ); + } + + // copy the guid so direct unbinding works + if ( typeof handler !== "string" ) { + handlerProxy.guid = handler.guid = + handler.guid || handlerProxy.guid || $.guid++; + } + + var match = event.match( /^(\w+)\s*(.*)$/ ), + eventName = match[1] + instance.eventNamespace, + selector = match[2]; + if ( selector ) { + instance.widget().delegate( selector, eventName, handlerProxy ); + } else { + element.bind( eventName, handlerProxy ); + } + }); + }, + + _off: function( element, eventName ) { + eventName = (eventName || "").split( " " ).join( this.eventNamespace + " " ) + this.eventNamespace; + element.unbind( eventName ).undelegate( eventName ); + }, + + _delay: function( handler, delay ) { + function handlerProxy() { + return ( typeof handler === "string" ? instance[ handler ] : handler ) + .apply( instance, arguments ); + } + var instance = this; + return setTimeout( handlerProxy, delay || 0 ); + }, + + _hoverable: function( element ) { + this.hoverable = this.hoverable.add( element ); + this._on( element, { + mouseenter: function( event ) { + $( event.currentTarget ).addClass( "ui-state-hover" ); + }, + mouseleave: function( event ) { + $( event.currentTarget ).removeClass( "ui-state-hover" ); + } + }); + }, + + _focusable: function( element ) { + this.focusable = this.focusable.add( element ); + this._on( element, { + focusin: function( event ) { + $( event.currentTarget ).addClass( "ui-state-focus" ); + }, + focusout: function( event ) { + $( event.currentTarget ).removeClass( "ui-state-focus" ); + } + }); + }, + + _trigger: function( type, event, data ) { + var prop, orig, + callback = this.options[ type ]; + + data = data || {}; + event = $.Event( event ); + event.type = ( type === this.widgetEventPrefix ? + type : + this.widgetEventPrefix + type ).toLowerCase(); + // the original event may come from any element + // so we need to reset the target on the new event + event.target = this.element[ 0 ]; + + // copy original event properties over to the new event + orig = event.originalEvent; + if ( orig ) { + for ( prop in orig ) { + if ( !( prop in event ) ) { + event[ prop ] = orig[ prop ]; + } + } + } + + this.element.trigger( event, data ); + return !( $.isFunction( callback ) && + callback.apply( this.element[0], [ event ].concat( data ) ) === false || + event.isDefaultPrevented() ); + } +}; + +$.each( { show: "fadeIn", hide: "fadeOut" }, function( method, defaultEffect ) { + $.Widget.prototype[ "_" + method ] = function( element, options, callback ) { + if ( typeof options === "string" ) { + options = { effect: options }; + } + var hasOptions, + effectName = !options ? + method : + options === true || typeof options === "number" ? + defaultEffect : + options.effect || defaultEffect; + options = options || {}; + if ( typeof options === "number" ) { + options = { duration: options }; + } + hasOptions = !$.isEmptyObject( options ); + options.complete = callback; + if ( options.delay ) { + element.delay( options.delay ); + } + if ( hasOptions && $.effects && ( $.effects.effect[ effectName ] || $.uiBackCompat !== false && $.effects[ effectName ] ) ) { + element[ method ]( options ); + } else if ( effectName !== method && element[ effectName ] ) { + element[ effectName ]( options.duration, options.easing, callback ); + } else { + element.queue(function( next ) { + $( this )[ method ](); + if ( callback ) { + callback.call( element[ 0 ] ); + } + next(); + }); + } + }; +}); + +// DEPRECATED +if ( $.uiBackCompat !== false ) { + $.Widget.prototype._getCreateOptions = function() { + return $.metadata && $.metadata.get( this.element[0] )[ this.widgetName ]; + }; +} + +})( jQuery ); +(function( $, undefined ) { + +var mouseHandled = false; +$( document ).mouseup( function( e ) { + mouseHandled = false; +}); + +$.widget("ui.mouse", { + version: "1.9.0", + options: { + cancel: 'input,textarea,button,select,option', + distance: 1, + delay: 0 + }, + _mouseInit: function() { + var that = this; + + this.element + .bind('mousedown.'+this.widgetName, function(event) { + return that._mouseDown(event); + }) + .bind('click.'+this.widgetName, function(event) { + if (true === $.data(event.target, that.widgetName + '.preventClickEvent')) { + $.removeData(event.target, that.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); + if ( this._mouseMoveDelegate ) { + $(document) + .unbind('mousemove.'+this.widgetName, this._mouseMoveDelegate) + .unbind('mouseup.'+this.widgetName, this._mouseUpDelegate); + } + }, + + _mouseDown: function(event) { + // don't let more than one widget handle mouseStart + if( mouseHandled ) { return; } + + // we may have missed mouseup (out of window) + (this._mouseStarted && this._mouseUp(event)); + + this._mouseDownEvent = event; + + var that = this, + btnIsLeft = (event.which === 1), + // event.target.nodeName works around a bug in IE 8 with + // disabled inputs (#7620) + elIsCancel = (typeof this.options.cancel === "string" && event.target.nodeName ? $(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() { + that.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 that._mouseMove(event); + }; + this._mouseUpDelegate = function(event) { + return that._mouseUp(event); + }; + $(document) + .bind('mousemove.'+this.widgetName, this._mouseMoveDelegate) + .bind('mouseup.'+this.widgetName, this._mouseUpDelegate); + + event.preventDefault(); + + 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); +(function( $, undefined ) { + +$.ui = $.ui || {}; + +var cachedScrollbarWidth, + max = Math.max, + abs = Math.abs, + round = Math.round, + rhorizontal = /left|center|right/, + rvertical = /top|center|bottom/, + roffset = /[\+\-]\d+%?/, + rposition = /^\w+/, + rpercent = /%$/, + _position = $.fn.position; + +function getOffsets( offsets, width, height ) { + return [ + parseInt( offsets[ 0 ], 10 ) * ( rpercent.test( offsets[ 0 ] ) ? width / 100 : 1 ), + parseInt( offsets[ 1 ], 10 ) * ( rpercent.test( offsets[ 1 ] ) ? height / 100 : 1 ) + ]; +} +function parseCss( element, property ) { + return parseInt( $.css( element, property ), 10 ) || 0; +} + +$.position = { + scrollbarWidth: function() { + if ( cachedScrollbarWidth !== undefined ) { + return cachedScrollbarWidth; + } + var w1, w2, + div = $( "
      " ), + innerDiv = div.children()[0]; + + $( "body" ).append( div ); + w1 = innerDiv.offsetWidth; + div.css( "overflow", "scroll" ); + + w2 = innerDiv.offsetWidth; + + if ( w1 === w2 ) { + w2 = div[0].clientWidth; + } + + div.remove(); + + return (cachedScrollbarWidth = w1 - w2); + }, + getScrollInfo: function( within ) { + var overflowX = within.isWindow ? "" : within.element.css( "overflow-x" ), + overflowY = within.isWindow ? "" : within.element.css( "overflow-y" ), + hasOverflowX = overflowX === "scroll" || + ( overflowX === "auto" && within.width < within.element[0].scrollWidth ), + hasOverflowY = overflowY === "scroll" || + ( overflowY === "auto" && within.height < within.element[0].scrollHeight ); + return { + width: hasOverflowX ? $.position.scrollbarWidth() : 0, + height: hasOverflowY ? $.position.scrollbarWidth() : 0 + }; + }, + getWithinInfo: function( element ) { + var withinElement = $( element || window ), + isWindow = $.isWindow( withinElement[0] ); + return { + element: withinElement, + isWindow: isWindow, + offset: withinElement.offset() || { left: 0, top: 0 }, + scrollLeft: withinElement.scrollLeft(), + scrollTop: withinElement.scrollTop(), + width: isWindow ? withinElement.width() : withinElement.outerWidth(), + height: isWindow ? withinElement.height() : withinElement.outerHeight() + }; + } +}; + +$.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 atOffset, targetWidth, targetHeight, targetOffset, basePosition, + target = $( options.of ), + within = $.position.getWithinInfo( options.within ), + scrollInfo = $.position.getScrollInfo( within ), + targetElem = target[0], + collision = ( options.collision || "flip" ).split( " " ), + offsets = {}; + + if ( targetElem.nodeType === 9 ) { + targetWidth = target.width(); + targetHeight = target.height(); + targetOffset = { top: 0, left: 0 }; + } else if ( $.isWindow( targetElem ) ) { + targetWidth = target.width(); + targetHeight = target.height(); + targetOffset = { top: target.scrollTop(), left: target.scrollLeft() }; + } else if ( targetElem.preventDefault ) { + // force left top to allow flipping + options.at = "left top"; + targetWidth = targetHeight = 0; + targetOffset = { top: targetElem.pageY, left: targetElem.pageX }; + } else { + targetWidth = target.outerWidth(); + targetHeight = target.outerHeight(); + targetOffset = target.offset(); + } + // clone to reuse original targetOffset later + basePosition = $.extend( {}, targetOffset ); + + // force my and at to have valid horizontal and vertical positions + // if a value is missing or invalid, it will be converted to center + $.each( [ "my", "at" ], function() { + var pos = ( options[ this ] || "" ).split( " " ), + horizontalOffset, + verticalOffset; + + if ( pos.length === 1) { + pos = rhorizontal.test( pos[ 0 ] ) ? + pos.concat( [ "center" ] ) : + rvertical.test( pos[ 0 ] ) ? + [ "center" ].concat( pos ) : + [ "center", "center" ]; + } + pos[ 0 ] = rhorizontal.test( pos[ 0 ] ) ? pos[ 0 ] : "center"; + pos[ 1 ] = rvertical.test( pos[ 1 ] ) ? pos[ 1 ] : "center"; + + // calculate offsets + horizontalOffset = roffset.exec( pos[ 0 ] ); + verticalOffset = roffset.exec( pos[ 1 ] ); + offsets[ this ] = [ + horizontalOffset ? horizontalOffset[ 0 ] : 0, + verticalOffset ? verticalOffset[ 0 ] : 0 + ]; + + // reduce to just the positions without the offsets + options[ this ] = [ + rposition.exec( pos[ 0 ] )[ 0 ], + rposition.exec( pos[ 1 ] )[ 0 ] + ]; + }); + + // normalize collision option + if ( collision.length === 1 ) { + collision[ 1 ] = collision[ 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; + } + + atOffset = getOffsets( offsets.at, targetWidth, targetHeight ); + basePosition.left += atOffset[ 0 ]; + basePosition.top += atOffset[ 1 ]; + + return this.each(function() { + var collisionPosition, using, + elem = $( this ), + elemWidth = elem.outerWidth(), + elemHeight = elem.outerHeight(), + marginLeft = parseCss( this, "marginLeft" ), + marginTop = parseCss( this, "marginTop" ), + collisionWidth = elemWidth + marginLeft + parseCss( this, "marginRight" ) + scrollInfo.width, + collisionHeight = elemHeight + marginTop + parseCss( this, "marginBottom" ) + scrollInfo.height, + position = $.extend( {}, basePosition ), + myOffset = getOffsets( offsets.my, elem.outerWidth(), elem.outerHeight() ); + + 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; + } + + position.left += myOffset[ 0 ]; + position.top += myOffset[ 1 ]; + + // if the browser doesn't support fractions, then round for consistent results + if ( !$.support.offsetFractions ) { + position.left = round( position.left ); + position.top = round( position.top ); + } + + collisionPosition = { + marginLeft: marginLeft, + marginTop: 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: [ atOffset[ 0 ] + myOffset[ 0 ], atOffset [ 1 ] + myOffset[ 1 ] ], + my: options.my, + at: options.at, + within: within, + elem : elem + }); + } + }); + + if ( $.fn.bgiframe ) { + elem.bgiframe(); + } + + if ( options.using ) { + // adds feedback as second argument to using callback, if present + using = function( props ) { + var left = targetOffset.left - position.left, + right = left + targetWidth - elemWidth, + top = targetOffset.top - position.top, + bottom = top + targetHeight - elemHeight, + feedback = { + target: { + element: target, + left: targetOffset.left, + top: targetOffset.top, + width: targetWidth, + height: targetHeight + }, + element: { + element: elem, + left: position.left, + top: position.top, + width: elemWidth, + height: elemHeight + }, + horizontal: right < 0 ? "left" : left > 0 ? "right" : "center", + vertical: bottom < 0 ? "top" : top > 0 ? "bottom" : "middle" + }; + if ( targetWidth < elemWidth && abs( left + right ) < targetWidth ) { + feedback.horizontal = "center"; + } + if ( targetHeight < elemHeight && abs( top + bottom ) < targetHeight ) { + feedback.vertical = "middle"; + } + if ( max( abs( left ), abs( right ) ) > max( abs( top ), abs( bottom ) ) ) { + feedback.important = "horizontal"; + } else { + feedback.important = "vertical"; + } + options.using.call( this, props, feedback ); + }; + } + + elem.offset( $.extend( position, { using: using } ) ); + }); +}; + +$.ui.position = { + fit: { + left: function( position, data ) { + var within = data.within, + withinOffset = within.isWindow ? within.scrollLeft : within.offset.left, + outerWidth = within.width, + collisionPosLeft = position.left - data.collisionPosition.marginLeft, + overLeft = withinOffset - collisionPosLeft, + overRight = collisionPosLeft + data.collisionWidth - outerWidth - withinOffset, + newOverRight; + + // element is wider than within + if ( data.collisionWidth > outerWidth ) { + // element is initially over the left side of within + if ( overLeft > 0 && overRight <= 0 ) { + newOverRight = position.left + overLeft + data.collisionWidth - outerWidth - withinOffset; + position.left += overLeft - newOverRight; + // element is initially over right side of within + } else if ( overRight > 0 && overLeft <= 0 ) { + position.left = withinOffset; + // element is initially over both left and right sides of within + } else { + if ( overLeft > overRight ) { + position.left = withinOffset + outerWidth - data.collisionWidth; + } else { + position.left = withinOffset; + } + } + // too far left -> align with left edge + } else if ( overLeft > 0 ) { + position.left += overLeft; + // too far right -> align with right edge + } else if ( overRight > 0 ) { + position.left -= overRight; + // adjust based on position and margin + } else { + position.left = max( position.left - collisionPosLeft, position.left ); + } + }, + top: function( position, data ) { + var within = data.within, + withinOffset = within.isWindow ? within.scrollTop : within.offset.top, + outerHeight = data.within.height, + collisionPosTop = position.top - data.collisionPosition.marginTop, + overTop = withinOffset - collisionPosTop, + overBottom = collisionPosTop + data.collisionHeight - outerHeight - withinOffset, + newOverBottom; + + // element is taller than within + if ( data.collisionHeight > outerHeight ) { + // element is initially over the top of within + if ( overTop > 0 && overBottom <= 0 ) { + newOverBottom = position.top + overTop + data.collisionHeight - outerHeight - withinOffset; + position.top += overTop - newOverBottom; + // element is initially over bottom of within + } else if ( overBottom > 0 && overTop <= 0 ) { + position.top = withinOffset; + // element is initially over both top and bottom of within + } else { + if ( overTop > overBottom ) { + position.top = withinOffset + outerHeight - data.collisionHeight; + } else { + position.top = withinOffset; + } + } + // too far up -> align with top + } else if ( overTop > 0 ) { + position.top += overTop; + // too far down -> align with bottom edge + } else if ( overBottom > 0 ) { + position.top -= overBottom; + // adjust based on position and margin + } else { + position.top = max( position.top - collisionPosTop, position.top ); + } + } + }, + flip: { + left: function( position, data ) { + var within = data.within, + withinOffset = within.offset.left + within.scrollLeft, + outerWidth = within.width, + offsetLeft = within.isWindow ? within.scrollLeft : within.offset.left, + collisionPosLeft = position.left - data.collisionPosition.marginLeft, + overLeft = collisionPosLeft - offsetLeft, + overRight = collisionPosLeft + data.collisionWidth - outerWidth - offsetLeft, + myOffset = data.my[ 0 ] === "left" ? + -data.elemWidth : + data.my[ 0 ] === "right" ? + data.elemWidth : + 0, + atOffset = data.at[ 0 ] === "left" ? + data.targetWidth : + data.at[ 0 ] === "right" ? + -data.targetWidth : + 0, + offset = -2 * data.offset[ 0 ], + newOverRight, + newOverLeft; + + if ( overLeft < 0 ) { + newOverRight = position.left + myOffset + atOffset + offset + data.collisionWidth - outerWidth - withinOffset; + if ( newOverRight < 0 || newOverRight < abs( overLeft ) ) { + position.left += myOffset + atOffset + offset; + } + } + else if ( overRight > 0 ) { + newOverLeft = position.left - data.collisionPosition.marginLeft + myOffset + atOffset + offset - offsetLeft; + if ( newOverLeft > 0 || abs( newOverLeft ) < overRight ) { + position.left += myOffset + atOffset + offset; + } + } + }, + top: function( position, data ) { + var within = data.within, + withinOffset = within.offset.top + within.scrollTop, + outerHeight = within.height, + offsetTop = within.isWindow ? within.scrollTop : within.offset.top, + collisionPosTop = position.top - data.collisionPosition.marginTop, + overTop = collisionPosTop - offsetTop, + overBottom = collisionPosTop + data.collisionHeight - outerHeight - offsetTop, + top = data.my[ 1 ] === "top", + myOffset = top ? + -data.elemHeight : + data.my[ 1 ] === "bottom" ? + data.elemHeight : + 0, + atOffset = data.at[ 1 ] === "top" ? + data.targetHeight : + data.at[ 1 ] === "bottom" ? + -data.targetHeight : + 0, + offset = -2 * data.offset[ 1 ], + newOverTop, + newOverBottom; + if ( overTop < 0 ) { + newOverBottom = position.top + myOffset + atOffset + offset + data.collisionHeight - outerHeight - withinOffset; + if ( ( position.top + myOffset + atOffset + offset) > overTop && ( newOverBottom < 0 || newOverBottom < abs( overTop ) ) ) { + position.top += myOffset + atOffset + offset; + } + } + else if ( overBottom > 0 ) { + newOverTop = position.top - data.collisionPosition.marginTop + myOffset + atOffset + offset - offsetTop; + if ( ( position.top + myOffset + atOffset + offset) > overBottom && ( newOverTop > 0 || abs( newOverTop ) < overBottom ) ) { + position.top += myOffset + atOffset + offset; + } + } + } + }, + flipfit: { + left: function() { + $.ui.position.flip.left.apply( this, arguments ); + $.ui.position.fit.left.apply( this, arguments ); + }, + top: function() { + $.ui.position.flip.top.apply( this, arguments ); + $.ui.position.fit.top.apply( this, arguments ); + } + } +}; + +// fraction support test +(function () { + var testElement, testElementParent, testElementStyle, offsetLeft, i, + body = document.getElementsByTagName( "body" )[ 0 ], + div = document.createElement( "div" ); + + //Create a "fake body" for testing based on method used in jQuery.support + testElement = document.createElement( body ? "div" : "body" ); + testElementStyle = { + visibility: "hidden", + width: 0, + height: 0, + border: 0, + margin: 0, + background: "none" + }; + if ( body ) { + $.extend( testElementStyle, { + position: "absolute", + left: "-1000px", + top: "-1000px" + }); + } + for ( i in testElementStyle ) { + testElement.style[ i ] = testElementStyle[ i ]; + } + testElement.appendChild( div ); + testElementParent = body || document.documentElement; + testElementParent.insertBefore( testElement, testElementParent.firstChild ); + + div.style.cssText = "position: absolute; left: 10.7432222px;"; + + offsetLeft = $( div ).offset().left; + $.support.offsetFractions = offsetLeft > 10 && offsetLeft < 11; + + testElement.innerHTML = ""; + testElementParent.removeChild( testElement ); +})(); + +// DEPRECATED +if ( $.uiBackCompat !== false ) { + // offset option + (function( $ ) { + var _position = $.fn.position; + $.fn.position = function( options ) { + if ( !options || !options.offset ) { + return _position.call( this, options ); + } + var offset = options.offset.split( " " ), + at = options.at.split( " " ); + if ( offset.length === 1 ) { + offset[ 1 ] = offset[ 0 ]; + } + if ( /^\d/.test( offset[ 0 ] ) ) { + offset[ 0 ] = "+" + offset[ 0 ]; + } + if ( /^\d/.test( offset[ 1 ] ) ) { + offset[ 1 ] = "+" + offset[ 1 ]; + } + if ( at.length === 1 ) { + if ( /left|center|right/.test( at[ 0 ] ) ) { + at[ 1 ] = "center"; + } else { + at[ 1 ] = at[ 0 ]; + at[ 0 ] = "center"; + } + } + return _position.call( this, $.extend( options, { + at: at[ 0 ] + offset[ 0 ] + " " + at[ 1 ] + offset[ 1 ], + offset: undefined + } ) ); + }; + }( jQuery ) ); +} + +}( jQuery ) ); +(function( $, undefined ) { + +$.widget("ui.draggable", $.ui.mouse, { + version: "1.9.0", + 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() { + this.element.removeClass( "ui-draggable ui-draggable-dragging ui-draggable-disabled" ); + this._mouseDestroy(); + }, + + _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); + + this.helper.addClass("ui-draggable-dragging"); + + //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._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 no longer in the DOM don't bother to continue (see #8269) + var element = this.element[0], elementInDom = false; + while ( element && (element = element.parentNode) ) { + if (element == document ) { + elementInDom = true; + } + } + if ( !elementInDom && 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 that = this; + $(this.helper).animate(this.originalPosition, parseInt(this.options.revertDuration, 10), function() { + if(that._trigger("stop", event) !== false) { + that._clear(); + } + }); + } else { + if(this._trigger("stop", event) !== false) { + this._clear(); + } + } + + return false; + }, + + _mouseUp: function(event) { + //Remove frame helpers + $("div.ui-draggable-iframeFix").each(function() { + this.parentNode.removeChild(this); + }); + + //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 && $.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 && $.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) + - ( ( 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) + - ( ( 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 && $.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) + + ( ( 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) + + ( ( 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 + }; + } + +}); + +$.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"), that = 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 = $(that).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); +(function( $, undefined ) { + +$.widget("ui.droppable", { + version: "1.9.0", + 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"); + }, + + _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 + }; + } + +}); + +$.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 = this._drop.call(this, event) || dropped; + + 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) { + // find droppable parents with same scope + var scope = this.options.scope; + var parent = this.element.parents(':data(droppable)').filter(function () { + return $.data(this, 'droppable').options.scope === scope; + }); + + 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); +(function( $, undefined ) { + +$.widget("ui.resizable", $.ui.mouse, { + version: "1.9.0", + 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 that = 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)) { + + //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 = $('
      '); + + // Apply zIndex to all handles - see #7960 + 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 (!that.resizing) { + if (this.className) + var axis = this.className.match(/ui-resizable-(se|sw|ne|nw|n|e|s|w)/i); + //Axis, default = se + that.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") + .mouseenter(function() { + if (o.disabled) return; + $(this).removeClass("ui-resizable-autohide"); + that._handles.show(); + }) + .mouseleave(function(){ + if (o.disabled) return; + if (!that.resizing) { + $(this).addClass("ui-resizable-autohide"); + that._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").removeData("ui-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 }); + } + + 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 = {}, + that = 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]); + + // 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, that = 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 : that.sizeDiff.height, + soffsetw = ista ? 0 : that.sizeDiff.width; + + var s = { width: (that.helper.width() - soffsetw), height: (that.helper.height() - soffseth) }, + left = (parseInt(that.element.css('left'), 10) + (that.position.left - that.originalPosition.left)) || null, + top = (parseInt(that.element.css('top'), 10) + (that.position.top - that.originalPosition.top)) || null; + + if (!o.animate) + this.element.css($.extend(s, { top: top, left: left })); + + that.helper.height(that.size.height); + that.helper.width(that.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; + }); + } + + 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 + }; + } + +}); + +/* + * Resizable Extensions + */ + +$.ui.plugin.add("resizable", "alsoResize", { + + start: function (event, ui) { + var that = $(this).data("resizable"), o = that.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) + }); + }); + }; + + 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 that = $(this).data("resizable"), o = that.options, os = that.originalSize, op = that.originalPosition; + + var delta = { + height: (that.size.height - os.height) || 0, width: (that.size.width - os.width) || 0, + top: (that.position.top - op.top) || 0, left: (that.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; + }); + + 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) { + $(this).removeData("resizable-alsoresize"); + } +}); + +$.ui.plugin.add("resizable", "animate", { + + stop: function(event, ui) { + var that = $(this).data("resizable"), o = that.options; + + var pr = that._proportionallyResizeElements, ista = pr.length && (/textarea/i).test(pr[0].nodeName), + soffseth = ista && $.ui.hasScroll(pr[0], 'left') /* TODO - jump height */ ? 0 : that.sizeDiff.height, + soffsetw = ista ? 0 : that.sizeDiff.width; + + var style = { width: (that.size.width - soffsetw), height: (that.size.height - soffseth) }, + left = (parseInt(that.element.css('left'), 10) + (that.position.left - that.originalPosition.left)) || null, + top = (parseInt(that.element.css('top'), 10) + (that.position.top - that.originalPosition.top)) || null; + + that.element.animate( + $.extend(style, top && left ? { top: top, left: left } : {}), { + duration: o.animateDuration, + easing: o.animateEasing, + step: function() { + + var data = { + width: parseInt(that.element.css('width'), 10), + height: parseInt(that.element.css('height'), 10), + top: parseInt(that.element.css('top'), 10), + left: parseInt(that.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 + that._updateCache(data); + that._propagate("resize", event); + + } + } + ); + } + +}); + +$.ui.plugin.add("resizable", "containment", { + + start: function(event, ui) { + var that = $(this).data("resizable"), o = that.options, el = that.element; + var oc = o.containment, ce = (oc instanceof $) ? oc.get(0) : (/parent/.test(oc)) ? el.parent().get(0) : oc; + if (!ce) return; + + that.containerElement = $(ce); + + if (/document/.test(oc) || oc == document) { + that.containerOffset = { left: 0, top: 0 }; + that.containerPosition = { left: 0, top: 0 }; + + that.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)); }); + + that.containerOffset = element.offset(); + that.containerPosition = element.position(); + that.containerSize = { height: (element.innerHeight() - p[3]), width: (element.innerWidth() - p[1]) }; + + var co = that.containerOffset, ch = that.containerSize.height, cw = that.containerSize.width, + width = ($.ui.hasScroll(ce, "left") ? ce.scrollWidth : cw ), height = ($.ui.hasScroll(ce) ? ce.scrollHeight : ch); + + that.parentData = { + element: ce, left: co.left, top: co.top, width: width, height: height + }; + } + }, + + resize: function(event, ui) { + var that = $(this).data("resizable"), o = that.options, + ps = that.containerSize, co = that.containerOffset, cs = that.size, cp = that.position, + pRatio = that._aspectRatio || event.shiftKey, cop = { top:0, left:0 }, ce = that.containerElement; + + if (ce[0] != document && (/static/).test(ce.css('position'))) cop = co; + + if (cp.left < (that._helper ? co.left : 0)) { + that.size.width = that.size.width + (that._helper ? (that.position.left - co.left) : (that.position.left - cop.left)); + if (pRatio) that.size.height = that.size.width / that.aspectRatio; + that.position.left = o.helper ? co.left : 0; + } + + if (cp.top < (that._helper ? co.top : 0)) { + that.size.height = that.size.height + (that._helper ? (that.position.top - co.top) : that.position.top); + if (pRatio) that.size.width = that.size.height * that.aspectRatio; + that.position.top = that._helper ? co.top : 0; + } + + that.offset.left = that.parentData.left+that.position.left; + that.offset.top = that.parentData.top+that.position.top; + + var woset = Math.abs( (that._helper ? that.offset.left - cop.left : (that.offset.left - cop.left)) + that.sizeDiff.width ), + hoset = Math.abs( (that._helper ? that.offset.top - cop.top : (that.offset.top - co.top)) + that.sizeDiff.height ); + + var isParent = that.containerElement.get(0) == that.element.parent().get(0), + isOffsetRelative = /relative|absolute/.test(that.containerElement.css('position')); + + if(isParent && isOffsetRelative) woset -= that.parentData.left; + + if (woset + that.size.width >= that.parentData.width) { + that.size.width = that.parentData.width - woset; + if (pRatio) that.size.height = that.size.width / that.aspectRatio; + } + + if (hoset + that.size.height >= that.parentData.height) { + that.size.height = that.parentData.height - hoset; + if (pRatio) that.size.width = that.size.height * that.aspectRatio; + } + }, + + stop: function(event, ui){ + var that = $(this).data("resizable"), o = that.options, cp = that.position, + co = that.containerOffset, cop = that.containerPosition, ce = that.containerElement; + + var helper = $(that.helper), ho = helper.offset(), w = helper.outerWidth() - that.sizeDiff.width, h = helper.outerHeight() - that.sizeDiff.height; + + if (that._helper && !o.animate && (/relative/).test(ce.css('position'))) + $(this).css({ left: ho.left - cop.left - co.left, width: w, height: h }); + + if (that._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 that = $(this).data("resizable"), o = that.options, cs = that.size; + + that.ghost = that.originalElement.clone(); + that.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 : ''); + + that.ghost.appendTo(that.helper); + + }, + + resize: function(event, ui){ + var that = $(this).data("resizable"), o = that.options; + if (that.ghost) that.ghost.css({ position: 'relative', height: that.size.height, width: that.size.width }); + }, + + stop: function(event, ui){ + var that = $(this).data("resizable"), o = that.options; + if (that.ghost && that.helper) that.helper.get(0).removeChild(that.ghost.get(0)); + } + +}); + +$.ui.plugin.add("resizable", "grid", { + + resize: function(event, ui) { + var that = $(this).data("resizable"), o = that.options, cs = that.size, os = that.originalSize, op = that.originalPosition, a = that.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)) { + that.size.width = os.width + ox; + that.size.height = os.height + oy; + } + else if (/^(ne)$/.test(a)) { + that.size.width = os.width + ox; + that.size.height = os.height + oy; + that.position.top = op.top - oy; + } + else if (/^(sw)$/.test(a)) { + that.size.width = os.width + ox; + that.size.height = os.height + oy; + that.position.left = op.left - ox; + } + else { + that.size.width = os.width + ox; + that.size.height = os.height + oy; + that.position.top = op.top - oy; + that.position.left = op.left - ox; + } + } + +}); + +var num = function(v) { + return parseInt(v, 10) || 0; +}; + +var isNumber = function(value) { + return !isNaN(parseInt(value, 10)); +}; + +})(jQuery); +(function( $, undefined ) { + +$.widget("ui.selectable", $.ui.mouse, { + version: "1.9.0", + options: { + appendTo: 'body', + autoRefresh: true, + distance: 0, + filter: '*', + tolerance: 'touch' + }, + _create: function() { + var that = this; + + this.element.addClass("ui-selectable"); + + this.dragged = false; + + // cache selectee children based on filter + var selectees; + this.refresh = function() { + selectees = $(that.options.filter, that.element[0]); + selectees.addClass("ui-selectee"); + 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"); + this._mouseDestroy(); + }, + + _mouseStart: function(event) { + var that = 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 && !event.ctrlKey) { + selectee.$element.removeClass('ui-selected'); + selectee.selected = false; + selectee.$element.addClass('ui-unselecting'); + selectee.unselecting = true; + // selectable UNSELECTING callback + that._trigger("unselecting", event, { + unselecting: selectee.element + }); + } + }); + + $(event.target).parents().andSelf().each(function() { + var selectee = $.data(this, "selectable-item"); + if (selectee) { + var doSelect = (!event.metaKey && !event.ctrlKey) || !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) { + that._trigger("selecting", event, { + selecting: selectee.element + }); + } else { + that._trigger("unselecting", event, { + unselecting: selectee.element + }); + } + return false; + } + }); + + }, + + _mouseDrag: function(event) { + var that = 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 == that.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 + that._trigger("selecting", event, { + selecting: selectee.element + }); + } + } else { + // UNSELECT + if (selectee.selecting) { + if ((event.metaKey || event.ctrlKey) && 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 + that._trigger("unselecting", event, { + unselecting: selectee.element + }); + } + } + if (selectee.selected) { + if (!event.metaKey && !event.ctrlKey && !selectee.startselected) { + selectee.$element.removeClass('ui-selected'); + selectee.selected = false; + + selectee.$element.addClass('ui-unselecting'); + selectee.unselecting = true; + // selectable UNSELECTING callback + that._trigger("unselecting", event, { + unselecting: selectee.element + }); + } + } + } + }); + + return false; + }, + + _mouseStop: function(event) { + var that = 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; + that._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; + that._trigger("selected", event, { + selected: selectee.element + }); + }); + this._trigger("stop", event); + + this.helper.remove(); + + return false; + } + +}); + +})(jQuery); +(function( $, undefined ) { + +$.widget("ui.sortable", $.ui.mouse, { + version: "1.9.0", + widgetEventPrefix: "sort", + ready: false, + 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(); + + //We're ready to go + this.ready = true + + }, + + _destroy: function() { + this.element + .removeClass("ui-sortable ui-sortable-disabled"); + this._mouseDestroy(); + + for ( var i = this.items.length - 1; i >= 0; i-- ) + this.items[i].item.removeData(this.widgetName + "-item"); + + return this; + }, + + _setOption: function(key, value){ + if ( key === "disabled" ) { + this.options[ key ] = value; + + this.widget().toggleClass( "ui-sortable-disabled", !!value ); + } 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) { + var that = this; + + 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, nodes = $(event.target).parents().each(function() { + if($.data(this, that.widgetName + '-item') == that) { + currentItem = $(this); + return false; + } + }); + if($.data(event.target, that.widgetName + '-item') == that) 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; + 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 + }; + + $.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 + }); + + // 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"); + + //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, this._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; + + // Only put the placeholder inside the current Container, skip all + // items form other containers. This works because when moving + // an item from one container to another the + // currentContainer is switched before the placeholder is moved. + // + // Without this moving items in "sub-sortables" can cause the placeholder to jitter + // beetween the outer and inner container. + if (item.instance !== this.currentContainer) 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 + && !$.contains(this.placeholder[0], itemElement) //no action if the item moved is the parent of the item checked + && (this.options.type == 'semi-dynamic' ? !$.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 that = this; + var cur = this.placeholder.offset(); + + this.reverting = true; + + $(this.helper).animate({ + left: cur.left - this.offset.parent.left - this.margins.left + (this.offsetParent[0] == document.body ? 0 : this.offsetParent[0].scrollLeft), + top: cur.top - this.offset.parent.top - this.margins.top + (this.offsetParent[0] == document.body ? 0 : this.offsetParent[0].scrollTop) + }, parseInt(this.options.revert, 10) || 500, function() { + that._clear(event); + }); + } else { + this._clear(event, noPropagation); + } + + return false; + + }, + + cancel: function() { + + 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, this._uiHash(this)); + if(this.containers[i].containerCache.over) { + this.containers[i]._trigger("out", null, this._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 = (this.options.axis === 'x') || $.ui.isOverAxis(this.positionAbs.top + this.offset.click.top, item.top, item.height), + isOverElementWidth = (this.options.axis === 'y') || $.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 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], this.widgetName); + 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(" + this.widgetName + "-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 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 && this.ready) { //Shouldn't be run the first time through due to massive slow-down + 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], this.widgetName); + 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(this.widgetName + '-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) { + that = that || this; + var o = that.options; + + if(!o.placeholder || o.placeholder.constructor == String) { + var className = o.placeholder; + o.placeholder = { + element: function() { + + var el = $(document.createElement(that.currentItem[0].nodeName)) + .addClass(className || that.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(that.currentItem.innerHeight() - parseInt(that.currentItem.css('paddingTop')||0, 10) - parseInt(that.currentItem.css('paddingBottom')||0, 10)); }; + if(!p.width()) { p.width(that.currentItem.innerWidth() - parseInt(that.currentItem.css('paddingLeft')||0, 10) - parseInt(that.currentItem.css('paddingRight')||0, 10)); }; + } + }; + } + + //Create the placeholder + that.placeholder = $(o.placeholder.element.call(that.element, that.currentItem)); + + //Append it after the actual current item + that.currentItem.after(that.placeholder); + + //Update the size of the placeholder (TODO: Logic to fuzzy, see line 316/317) + o.placeholder.update(that, that.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($.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 && $.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(!$.contains(this.containers[innermostIndex].element[0], this.items[j].item[0])) continue; + var cur = this.containers[innermostIndex].floating ? this.items[j].item.offset().left : this.items[j].item.offset().top; + if(Math.abs(cur - base) < dist) { + dist = Math.abs(cur - base); itemWithLeastDistance = this.items[j]; + this.direction = (cur - base > 0) ? 'down' : 'up'; + } + } + + 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 && $.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 && $.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) + - ( ( 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) + - ( ( 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 && $.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) + + ( ( 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) + + ( ( 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 counter = this.counter; + + this._delay(function() { + if(counter == this.counter) this.refreshPositions(!hardRefresh); //Precompute after each DOM insertion, NOT on mousemove + }); + + }, + + _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 = []; + + // 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 + + // Check if the items Container has Changed and trigger appropriate + // events. + if (this !== this.currentContainer) { + if(!noPropagation) { + delayedTriggers.push(function(event) { this._trigger("remove", event, this._uiHash()); }); + delayedTriggers.push((function(c) { return function(event) { c._trigger("receive", event, this._uiHash(this)); }; }).call(this, this.currentContainer)); + delayedTriggers.push((function(c) { return function(event) { c._trigger("update", event, this._uiHash(this)); }; }).call(this, this.currentContainer)); + } + } + + + //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()); + } + + this.fromOutside = false; + 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 inst = _inst || this; + return { + helper: inst.helper, + placeholder: inst.placeholder || $([]), + position: inst.position, + originalPosition: inst.originalPosition, + offset: inst.positionAbs, + item: inst.currentItem, + sender: _inst ? _inst.element : null + }; + } + +}); + +})(jQuery); +(function( $, undefined ) { + +var uid = 0, + hideProps = {}, + showProps = {}; + +hideProps.height = hideProps.paddingTop = hideProps.paddingBottom = + hideProps.borderTopWidth = hideProps.borderBottomWidth = "hide"; +showProps.height = showProps.paddingTop = showProps.paddingBottom = + showProps.borderTopWidth = showProps.borderBottomWidth = "show"; + +$.widget( "ui.accordion", { + version: "1.9.0", + options: { + active: 0, + animate: {}, + collapsible: false, + event: "click", + header: "> li > :first-child,> :not(li):even", + heightStyle: "auto", + icons: { + activeHeader: "ui-icon-triangle-1-s", + header: "ui-icon-triangle-1-e" + }, + + // callbacks + activate: null, + beforeActivate: null + }, + + _create: function() { + var accordionId = this.accordionId = "ui-accordion-" + + (this.element.attr( "id" ) || ++uid), + options = this.options; + + this.prevShow = this.prevHide = $(); + this.element.addClass( "ui-accordion ui-widget ui-helper-reset" ); + + this.headers = this.element.find( options.header ) + .addClass( "ui-accordion-header ui-helper-reset ui-state-default ui-corner-all" ); + this._hoverable( this.headers ); + this._focusable( this.headers ); + + this.headers.next() + .addClass( "ui-accordion-content ui-helper-reset ui-widget-content ui-corner-bottom" ) + .hide(); + + // don't allow collapsible: false and active: false + if ( !options.collapsible && options.active === false ) { + options.active = 0; + } + // handle negative values + if ( options.active < 0 ) { + options.active += this.headers.length; + } + this.active = this._findActive( options.active ) + .addClass( "ui-accordion-header-active ui-state-active" ) + .toggleClass( "ui-corner-all ui-corner-top" ); + this.active.next() + .addClass( "ui-accordion-content-active" ) + .show(); + + this._createIcons(); + this.originalHeight = this.element[0].style.height; + this.refresh(); + + // ARIA + this.element.attr( "role", "tablist" ); + + this.headers + .attr( "role", "tab" ) + .each(function( i ) { + var header = $( this ), + headerId = header.attr( "id" ), + panel = header.next(), + panelId = panel.attr( "id" ); + if ( !headerId ) { + headerId = accordionId + "-header-" + i; + header.attr( "id", headerId ); + } + if ( !panelId ) { + panelId = accordionId + "-panel-" + i; + panel.attr( "id", panelId ); + } + header.attr( "aria-controls", panelId ); + panel.attr( "aria-labelledby", headerId ); + }) + .next() + .attr( "role", "tabpanel" ); + + this.headers + .not( this.active ) + .attr({ + "aria-selected": "false", + tabIndex: -1 + }) + .next() + .attr({ + "aria-expanded": "false", + "aria-hidden": "true" + }) + .hide(); + + // make sure at least one header is in the tab order + if ( !this.active.length ) { + this.headers.eq( 0 ).attr( "tabIndex", 0 ); + } else { + this.active.attr({ + "aria-selected": "true", + tabIndex: 0 + }) + .next() + .attr({ + "aria-expanded": "true", + "aria-hidden": "false" + }); + } + + this._on( this.headers, { keydown: "_keydown" }); + this._on( this.headers.next(), { keydown: "_panelKeyDown" }); + this._setupEvents( options.event ); + }, + + _getCreateEventData: function() { + return { + header: this.active, + content: !this.active.length ? $() : this.active.next() + }; + }, + + _createIcons: function() { + var icons = this.options.icons; + if ( icons ) { + $( "" ) + .addClass( "ui-accordion-header-icon ui-icon " + icons.header ) + .prependTo( this.headers ); + this.active.children( ".ui-accordion-header-icon" ) + .removeClass( icons.header ) + .addClass( icons.activeHeader ); + this.headers.addClass( "ui-accordion-icons" ); + } + }, + + _destroyIcons: function() { + this.headers + .removeClass( "ui-accordion-icons" ) + .children( ".ui-accordion-header-icon" ) + .remove(); + }, + + _destroy: function() { + var contents; + + // clean up main element + this.element + .removeClass( "ui-accordion ui-widget ui-helper-reset" ) + .removeAttr( "role" ); + + // clean up headers + this.headers + .removeClass( "ui-accordion-header ui-accordion-header-active ui-helper-reset ui-state-default ui-corner-all ui-state-active ui-state-disabled ui-corner-top" ) + .removeAttr( "role" ) + .removeAttr( "aria-selected" ) + .removeAttr( "aria-controls" ) + .removeAttr( "tabIndex" ) + .each(function() { + if ( /^ui-accordion/.test( this.id ) ) { + this.removeAttribute( "id" ); + } + }); + this._destroyIcons(); + + // clean up content panels + contents = this.headers.next() + .css( "display", "" ) + .removeAttr( "role" ) + .removeAttr( "aria-expanded" ) + .removeAttr( "aria-hidden" ) + .removeAttr( "aria-labelledby" ) + .removeClass( "ui-helper-reset ui-widget-content ui-corner-bottom ui-accordion-content ui-accordion-content-active ui-state-disabled" ) + .each(function() { + if ( /^ui-accordion/.test( this.id ) ) { + this.removeAttribute( "id" ); + } + }); + if ( this.options.heightStyle !== "content" ) { + this.element.css( "height", this.originalHeight ); + contents.css( "height", "" ); + } + }, + + _setOption: function( key, value ) { + if ( key === "active" ) { + // _activate() will handle invalid values and update this.options + this._activate( value ); + return; + } + + if ( key === "event" ) { + if ( this.options.event ) { + this._off( this.headers, this.options.event ); + } + this._setupEvents( value ); + } + + this._super( key, value ); + + // setting collapsible: false while collapsed; open first panel + if ( key === "collapsible" && !value && this.options.active === false ) { + this._activate( 0 ); + } + + 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() ) + .toggleClass( "ui-state-disabled", !!value ); + } + }, + + _keydown: function( event ) { + if ( 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._eventHandler( event ); + break; + case keyCode.HOME: + toFocus = this.headers[ 0 ]; + break; + case keyCode.END: + toFocus = this.headers[ length - 1 ]; + break; + } + + if ( toFocus ) { + $( event.target ).attr( "tabIndex", -1 ); + $( toFocus ).attr( "tabIndex", 0 ); + toFocus.focus(); + event.preventDefault(); + } + }, + + _panelKeyDown : function( event ) { + if ( event.keyCode === $.ui.keyCode.UP && event.ctrlKey ) { + $( event.currentTarget ).prev().focus(); + } + }, + + refresh: function() { + var maxHeight, overflow, + heightStyle = this.options.heightStyle, + parent = this.element.parent(); + + this.element.css( "height", this.originalHeight ); + + if ( heightStyle === "fill" ) { + // IE 6 treats height like minHeight, so we need to turn off overflow + // in order to get a reliable height + // we use the minHeight support test because we assume that only + // browsers that don't support minHeight will treat height as minHeight + if ( !$.support.minHeight ) { + overflow = parent.css( "overflow" ); + parent.css( "overflow", "hidden"); + } + maxHeight = parent.height(); + this.element.siblings( ":visible" ).each(function() { + var elem = $( this ), + position = elem.css( "position" ); + + if ( position === "absolute" || position === "fixed" ) { + return; + } + maxHeight -= elem.outerHeight( true ); + }); + if ( overflow ) { + parent.css( "overflow", overflow ); + } + + 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 ( heightStyle === "auto" ) { + maxHeight = 0; + this.headers.next() + .each(function() { + maxHeight = Math.max( maxHeight, $( this ).height( "" ).height() ); + }) + .height( maxHeight ); + } + + if ( heightStyle !== "content" ) { + this.element.height( this.element.height() ); + } + }, + + _activate: function( index ) { + var active = this._findActive( index )[ 0 ]; + + // trying to activate the already active panel + if ( active === this.active[ 0 ] ) { + return; + } + + // trying to collapse, simulate a click on the currently active header + active = active || this.active[ 0 ]; + + this._eventHandler({ + target: active, + currentTarget: active, + preventDefault: $.noop + }); + }, + + _findActive: function( selector ) { + return typeof selector === "number" ? this.headers.eq( selector ) : $(); + }, + + _setupEvents: function( event ) { + var events = {}; + if ( !event ) { + return; + } + $.each( event.split(" "), function( index, eventName ) { + events[ eventName ] = "_eventHandler"; + }); + this._on( this.headers, events ); + }, + + _eventHandler: function( event ) { + var options = this.options, + active = this.active, + clicked = $( event.currentTarget ), + clickedIsActive = clicked[ 0 ] === active[ 0 ], + collapsing = clickedIsActive && options.collapsible, + toShow = collapsing ? $() : clicked.next(), + toHide = active.next(), + eventData = { + oldHeader: active, + oldPanel: toHide, + newHeader: collapsing ? $() : clicked, + newPanel: toShow + }; + + event.preventDefault(); + + if ( + // click on active header, but not collapsible + ( clickedIsActive && !options.collapsible ) || + // allow canceling activation + ( this._trigger( "beforeActivate", event, eventData ) === false ) ) { + return; + } + + options.active = collapsing ? false : this.headers.index( clicked ); + + // 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( eventData ); + + // switch classes + // corner classes on the previously active header stay after the animation + active.removeClass( "ui-accordion-header-active ui-state-active" ); + if ( options.icons ) { + active.children( ".ui-accordion-header-icon" ) + .removeClass( options.icons.activeHeader ) + .addClass( options.icons.header ); + } + + if ( !clickedIsActive ) { + clicked + .removeClass( "ui-corner-all" ) + .addClass( "ui-accordion-header-active ui-state-active ui-corner-top" ); + if ( options.icons ) { + clicked.children( ".ui-accordion-header-icon" ) + .removeClass( options.icons.header ) + .addClass( options.icons.activeHeader ); + } + + clicked + .next() + .addClass( "ui-accordion-content-active" ); + } + }, + + _toggle: function( data ) { + var toShow = data.newPanel, + toHide = this.prevShow.length ? this.prevShow : data.oldPanel; + + // handle activating a panel during the animation for another activation + this.prevShow.add( this.prevHide ).stop( true, true ); + this.prevShow = toShow; + this.prevHide = toHide; + + if ( this.options.animate ) { + this._animate( toShow, toHide, data ); + } else { + toHide.hide(); + toShow.show(); + this._toggleComplete( data ); + } + + toHide.attr({ + "aria-expanded": "false", + "aria-hidden": "true" + }); + toHide.prev().attr( "aria-selected", "false" ); + // if we're switching panels, remove the old header from the tab order + // if we're opening from collapsed state, remove the previous header from the tab order + // if we're collapsing, then keep the collapsing header in the tab order + if ( toShow.length && toHide.length ) { + toHide.prev().attr( "tabIndex", -1 ); + } else if ( toShow.length ) { + this.headers.filter(function() { + return $( this ).attr( "tabIndex" ) === 0; + }) + .attr( "tabIndex", -1 ); + } + + toShow + .attr({ + "aria-expanded": "true", + "aria-hidden": "false" + }) + .prev() + .attr({ + "aria-selected": "true", + tabIndex: 0 + }); + }, + + _animate: function( toShow, toHide, data ) { + var total, easing, duration, + that = this, + adjust = 0, + down = toShow.length && + ( !toHide.length || ( toShow.index() < toHide.index() ) ), + animate = this.options.animate || {}, + options = down && animate.down || animate, + complete = function() { + that._toggleComplete( data ); + }; + + if ( typeof options === "number" ) { + duration = options; + } + if ( typeof options === "string" ) { + easing = options; + } + // fall back from options to animation in case of partial down settings + easing = easing || options.easing || animate.easing; + duration = duration || options.duration || animate.duration; + + if ( !toHide.length ) { + return toShow.animate( showProps, duration, easing, complete ); + } + if ( !toShow.length ) { + return toHide.animate( hideProps, duration, easing, complete ); + } + + total = toShow.show().outerHeight(); + toHide.animate( hideProps, { + duration: duration, + easing: easing, + step: function( now, fx ) { + fx.now = Math.round( now ); + } + }); + toShow + .hide() + .animate( showProps, { + duration: duration, + easing: easing, + complete: complete, + step: function( now, fx ) { + fx.now = Math.round( now ); + if ( fx.prop !== "height" ) { + adjust += fx.now; + } else if ( that.options.heightStyle !== "content" ) { + fx.now = Math.round( total - toHide.outerHeight() - adjust ); + adjust = 0; + } + } + }); + }, + + _toggleComplete: function( data ) { + var toHide = data.oldPanel; + + toHide + .removeClass( "ui-accordion-content-active" ) + .prev() + .removeClass( "ui-corner-top" ) + .addClass( "ui-corner-all" ); + + // Work around for rendering bug in IE (#5421) + if ( toHide.length ) { + toHide.parent()[0].className = toHide.parent()[0].className; + } + + this._trigger( "activate", null, data ); + } +}); + + + +// DEPRECATED +if ( $.uiBackCompat !== false ) { + // navigation options + (function( $, prototype ) { + $.extend( prototype.options, { + navigation: false, + navigationFilter: function() { + return this.href.toLowerCase() === location.href.toLowerCase(); + } + }); + + var _create = prototype._create; + prototype._create = function() { + if ( this.options.navigation ) { + var that = this, + headers = this.element.find( this.options.header ), + content = headers.next(), + current = headers.add( content ) + .find( "a" ) + .filter( this.options.navigationFilter ) + [ 0 ]; + if ( current ) { + headers.add( content ).each( function( index ) { + if ( $.contains( this, current ) ) { + that.options.active = Math.floor( index / 2 ); + return false; + } + }); + } + } + _create.call( this ); + }; + }( jQuery, jQuery.ui.accordion.prototype ) ); + + // height options + (function( $, prototype ) { + $.extend( prototype.options, { + heightStyle: null, // remove default so we fall back to old values + autoHeight: true, // use heightStyle: "auto" + clearStyle: false, // use heightStyle: "content" + fillSpace: false // use heightStyle: "fill" + }); + + var _create = prototype._create, + _setOption = prototype._setOption; + + $.extend( prototype, { + _create: function() { + this.options.heightStyle = this.options.heightStyle || + this._mergeHeightStyle(); + + _create.call( this ); + }, + + _setOption: function( key, value ) { + if ( key === "autoHeight" || key === "clearStyle" || key === "fillSpace" ) { + this.options.heightStyle = this._mergeHeightStyle(); + } + _setOption.apply( this, arguments ); + }, + + _mergeHeightStyle: function() { + var options = this.options; + + if ( options.fillSpace ) { + return "fill"; + } + + if ( options.clearStyle ) { + return "content"; + } + + if ( options.autoHeight ) { + return "auto"; + } + } + }); + }( jQuery, jQuery.ui.accordion.prototype ) ); + + // icon options + (function( $, prototype ) { + $.extend( prototype.options.icons, { + activeHeader: null, // remove default so we fall back to old values + headerSelected: "ui-icon-triangle-1-s" + }); + + var _createIcons = prototype._createIcons; + prototype._createIcons = function() { + if ( this.options.icons ) { + this.options.icons.activeHeader = this.options.icons.activeHeader || + this.options.icons.headerSelected; + } + _createIcons.call( this ); + }; + }( jQuery, jQuery.ui.accordion.prototype ) ); + + // expanded active option, activate method + (function( $, prototype ) { + prototype.activate = prototype._activate; + + var _findActive = prototype._findActive; + prototype._findActive = function( index ) { + if ( index === -1 ) { + index = false; + } + if ( index && typeof index !== "number" ) { + index = this.headers.index( this.headers.filter( index ) ); + if ( index === -1 ) { + index = false; + } + } + return _findActive.call( this, index ); + }; + }( jQuery, jQuery.ui.accordion.prototype ) ); + + // resize method + jQuery.ui.accordion.prototype.resize = jQuery.ui.accordion.prototype.refresh; + + // change events + (function( $, prototype ) { + $.extend( prototype.options, { + change: null, + changestart: null + }); + + var _trigger = prototype._trigger; + prototype._trigger = function( type, event, data ) { + var ret = _trigger.apply( this, arguments ); + if ( !ret ) { + return false; + } + + if ( type === "beforeActivate" ) { + ret = _trigger.call( this, "changestart", event, { + oldHeader: data.oldHeader, + oldContent: data.oldPanel, + newHeader: data.newHeader, + newContent: data.newPanel + }); + } else if ( type === "activate" ) { + ret = _trigger.call( this, "change", event, { + oldHeader: data.oldHeader, + oldContent: data.oldPanel, + newHeader: data.newHeader, + newContent: data.newPanel + }); + } + return ret; + }; + }( jQuery, jQuery.ui.accordion.prototype ) ); + + // animated option + // NOTE: this only provides support for "slide", "bounceslide", and easings + // not the full $.ui.accordion.animations API + (function( $, prototype ) { + $.extend( prototype.options, { + animate: null, + animated: "slide" + }); + + var _create = prototype._create; + prototype._create = function() { + var options = this.options; + if ( options.animate === null ) { + if ( !options.animated ) { + options.animate = false; + } else if ( options.animated === "slide" ) { + options.animate = 300; + } else if ( options.animated === "bounceslide" ) { + options.animate = { + duration: 200, + down: { + easing: "easeOutBounce", + duration: 1000 + } + }; + } else { + options.animate = options.animated; + } + } + + _create.call( this ); + }; + }( jQuery, jQuery.ui.accordion.prototype ) ); +} + +})( jQuery ); +(function( $, undefined ) { + +// used to prevent race conditions with remote data sources +var requestIndex = 0; + +$.widget( "ui.autocomplete", { + version: "1.9.0", + defaultElement: "", + options: { + appendTo: "body", + autoFocus: false, + delay: 300, + minLength: 1, + position: { + my: "left top", + at: "left bottom", + collision: "none" + }, + source: null, + + // callbacks + change: null, + close: null, + focus: null, + open: null, + response: null, + search: null, + select: null + }, + + pending: 0, + + _create: function() { + // Some browsers only repeat keydown events, not keypress events, + // so we use the suppressKeyPress flag to determine if we've already + // handled the keydown event. #7269 + // Unfortunately the code for & in keypress is the same as the up arrow, + // so we use the suppressKeyPressRepeat flag to avoid handling keypress + // events when we know the keydown event was used to modify the + // search term. #7799 + var suppressKeyPress, suppressKeyPressRepeat, suppressInput; + + this.isMultiLine = this._isMultiLine(); + this.valueMethod = this.element[ this.element.is( "input,textarea" ) ? "val" : "text" ]; + this.isNewMenu = true; + + this.element + .addClass( "ui-autocomplete-input" ) + .attr( "autocomplete", "off" ); + + this._on({ + keydown: function( event ) { + if ( this.element.prop( "readOnly" ) ) { + suppressKeyPress = true; + suppressInput = true; + suppressKeyPressRepeat = true; + return; + } + + suppressKeyPress = false; + suppressInput = false; + suppressKeyPressRepeat = false; + var keyCode = $.ui.keyCode; + switch( event.keyCode ) { + case keyCode.PAGE_UP: + suppressKeyPress = true; + this._move( "previousPage", event ); + break; + case keyCode.PAGE_DOWN: + suppressKeyPress = true; + this._move( "nextPage", event ); + break; + case keyCode.UP: + suppressKeyPress = true; + this._keyEvent( "previous", event ); + break; + case keyCode.DOWN: + suppressKeyPress = true; + this._keyEvent( "next", event ); + break; + case keyCode.ENTER: + case keyCode.NUMPAD_ENTER: + // when menu is open and has focus + if ( this.menu.active ) { + // #6055 - Opera still allows the keypress to occur + // which causes forms to submit + suppressKeyPress = true; + event.preventDefault(); + this.menu.select( event ); + } + break; + case keyCode.TAB: + if ( this.menu.active ) { + this.menu.select( event ); + } + break; + case keyCode.ESCAPE: + if ( this.menu.element.is( ":visible" ) ) { + this._value( this.term ); + this.close( event ); + // Different browsers have different default behavior for escape + // Single press can mean undo or clear + // Double press in IE means clear the whole form + event.preventDefault(); + } + break; + default: + suppressKeyPressRepeat = true; + // search timeout should be triggered before the input value is changed + this._searchTimeout( event ); + break; + } + }, + keypress: function( event ) { + if ( suppressKeyPress ) { + suppressKeyPress = false; + event.preventDefault(); + return; + } + if ( suppressKeyPressRepeat ) { + return; + } + + // replicate some key handlers to allow them to repeat in Firefox and Opera + var keyCode = $.ui.keyCode; + switch( event.keyCode ) { + case keyCode.PAGE_UP: + this._move( "previousPage", event ); + break; + case keyCode.PAGE_DOWN: + this._move( "nextPage", event ); + break; + case keyCode.UP: + this._keyEvent( "previous", event ); + break; + case keyCode.DOWN: + this._keyEvent( "next", event ); + break; + } + }, + input: function( event ) { + if ( suppressInput ) { + suppressInput = false; + event.preventDefault(); + return; + } + this._searchTimeout( event ); + }, + focus: function() { + this.selectedItem = null; + this.previous = this._value(); + }, + blur: function( event ) { + if ( this.cancelBlur ) { + delete this.cancelBlur; + return; + } + + clearTimeout( this.searching ); + this.close( event ); + this._change( event ); + } + }); + + this._initSource(); + this.menu = $( "
      ' + + ''; + 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.delegate(selector, 'mouseout', function() { + $(this).removeClass('ui-state-hover'); + if (this.className.indexOf('ui-datepicker-prev') != -1) $(this).removeClass('ui-datepicker-prev-hover'); + if (this.className.indexOf('ui-datepicker-next') != -1) $(this).removeClass('ui-datepicker-next-hover'); + }) + .delegate(selector, 'mouseover', function(){ + if (!$.datepicker._isDisabledDatepicker( instActive.inline ? dpDiv.parent()[0] : instActive.input[0])) { + $(this).parents('.ui-datepicker-calendar').find('a').removeClass('ui-state-hover'); + $(this).addClass('ui-state-hover'); + if (this.className.indexOf('ui-datepicker-prev') != -1) $(this).addClass('ui-datepicker-prev-hover'); + if (this.className.indexOf('ui-datepicker-next') != -1) $(this).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; +}; + +/* 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(document.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.9.0"; + +// Workaround for #4055 +// Add another global to avoid noConflict issues with inline event handlers +window['DP_jQuery_' + dpuuid] = $; + +})(jQuery); +(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 + }; + +$.widget("ui.dialog", { + version: "1.9.0", + 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", + of: window, + 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.oldPosition = { + parent: this.element.parent(), + index: this.element.parent().children().index( this.element ) + }; + this.options.title = this.options.title || this.originalTitle; + var that = this, + options = this.options, + + title = options.title || " ", + + uiDialog = ( this.uiDialog = $( "
      " ) ) + .addClass( uiDialogClasses + options.dialogClass ) + .css({ + display: "none", + outline: 0, // TODO: move to stylesheet + zIndex: options.zIndex + }) + // setting tabIndex makes the div focusable + .attr( "tabIndex", -1) + .keydown(function( event ) { + if ( options.closeOnEscape && !event.isDefaultPrevented() && event.keyCode && + event.keyCode === $.ui.keyCode.ESCAPE ) { + that.close( event ); + event.preventDefault(); + } + }) + .mousedown(function( event ) { + that.moveToTop( false, event ); + }) + .appendTo( "body" ), + + uiDialogContent = this.element + .show() + .removeAttr( "title" ) + .addClass( "ui-dialog-content ui-widget-content" ) + .appendTo( uiDialog ), + + uiDialogTitlebar = ( this.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" ) + .click(function( event ) { + event.preventDefault(); + that.close( event ); + }) + .appendTo( uiDialogTitlebar ), + + uiDialogTitlebarCloseText = ( this.uiDialogTitlebarCloseText = $( "" ) ) + .addClass( "ui-icon ui-icon-closethick" ) + .text( options.closeText ) + .appendTo( uiDialogTitlebarClose ), + + uiDialogTitle = $( "" ) + .uniqueId() + .addClass( "ui-dialog-title" ) + .html( title ) + .prependTo( uiDialogTitlebar ), + + uiDialogButtonPane = ( this.uiDialogButtonPane = $( "
      " ) ) + .addClass( "ui-dialog-buttonpane ui-widget-content ui-helper-clearfix" ), + + uiButtonSet = ( this.uiButtonSet = $( "
      " ) ) + .addClass( "ui-dialog-buttonset" ) + .appendTo( uiDialogButtonPane ); + + uiDialog.attr({ + role: "dialog", + "aria-labelledby": uiDialogTitle.attr( "id" ) + }); + + uiDialogTitlebar.find( "*" ).add( uiDialogTitlebar ).disableSelection(); + this._hoverable( uiDialogTitlebarClose ); + this._focusable( uiDialogTitlebarClose ); + + if ( options.draggable && $.fn.draggable ) { + this._makeDraggable(); + } + if ( options.resizable && $.fn.resizable ) { + this._makeResizable(); + } + + this._createButtons( options.buttons ); + this._isOpen = false; + + if ( $.fn.bgiframe ) { + uiDialog.bgiframe(); + } + + // prevent tabbing out of modal dialogs + this._on( uiDialog, { keydown: function( event ) { + if ( !options.modal || event.keyCode !== $.ui.keyCode.TAB ) { + return; + } + + var tabbables = $( ":tabbable", uiDialog ), + 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; + } + }}); + }, + + _init: function() { + if ( this.options.autoOpen ) { + this.open(); + } + }, + + _destroy: function() { + var next, + oldPosition = this.oldPosition; + + if ( this.overlay ) { + this.overlay.destroy(); + } + this.uiDialog.hide(); + this.element + .removeClass( "ui-dialog-content ui-widget-content" ) + .hide() + .appendTo( "body" ); + this.uiDialog.remove(); + + if ( this.originalTitle ) { + this.element.attr( "title", this.originalTitle ); + } + + next = oldPosition.parent.children().eq( oldPosition.index ); + // Don't try to place the dialog next to itself (#8613) + if ( next.length && next[ 0 ] !== this.element[ 0 ] ) { + next.before( this.element ); + } else { + oldPosition.parent.append( this.element ); + } + }, + + widget: function() { + return this.uiDialog; + }, + + close: function( event ) { + var that = this, + maxZ, thisZ; + + if ( !this._isOpen ) { + return; + } + + if ( false === this._trigger( "beforeClose", event ) ) { + return; + } + + this._isOpen = false; + + if ( this.overlay ) { + this.overlay.destroy(); + } + + if ( this.options.hide ) { + this.uiDialog.hide( this.options.hide, function() { + that._trigger( "close", event ); + }); + } else { + this.uiDialog.hide(); + this._trigger( "close", event ); + } + + $.ui.dialog.overlay.resize(); + + // adjust the maxZ to allow other modal dialogs to continue to work (see #4309) + if ( this.options.modal ) { + maxZ = 0; + $( ".ui-dialog" ).each(function() { + if ( this !== that.uiDialog[0] ) { + thisZ = $( this ).css( "z-index" ); + if ( !isNaN( thisZ ) ) { + maxZ = Math.max( maxZ, thisZ ); + } + } + }); + $.ui.dialog.maxZ = maxZ; + } + + return this; + }, + + 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 options = this.options, + saveScroll; + + if ( ( options.modal && !force ) || + ( !options.stack && !options.modal ) ) { + return this._trigger( "focus", event ); + } + + if ( options.zIndex > $.ui.dialog.maxZ ) { + $.ui.dialog.maxZ = options.zIndex; + } + if ( this.overlay ) { + $.ui.dialog.maxZ += 1; + $.ui.dialog.overlay.maxZ = $.ui.dialog.maxZ; + this.overlay.$el.css( "z-index", $.ui.dialog.overlay.maxZ ); + } + + // Save and then restore scroll + // Opera 9.5+ resets when parent z-index is changed. + // http://bugs.jqueryui.com/ticket/3193 + saveScroll = { + scrollTop: this.element.scrollTop(), + scrollLeft: this.element.scrollLeft() + }; + $.ui.dialog.maxZ += 1; + this.uiDialog.css( "z-index", $.ui.dialog.maxZ ); + this.element.attr( saveScroll ); + this._trigger( "focus", event ); + + return this; + }, + + open: function() { + if ( this._isOpen ) { + return; + } + + var hasFocus, + options = this.options, + uiDialog = this.uiDialog; + + this._size(); + this._position( options.position ); + uiDialog.show( options.show ); + this.overlay = options.modal ? new $.ui.dialog.overlay( this ) : null; + this.moveToTop( true ); + + // 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 + hasFocus = this.element.find( ":tabbable" ); + if ( !hasFocus.length ) { + hasFocus = this.uiDialogButtonPane.find( ":tabbable" ); + if ( !hasFocus.length ) { + hasFocus = uiDialog; + } + } + hasFocus.eq( 0 ).focus(); + + this._isOpen = true; + this._trigger( "open" ); + + return this; + }, + + _createButtons: function( buttons ) { + var uiDialogButtonPane, uiButtonSet, + that = this, + hasButtons = false; + + // if we already have a button pane, remove it + this.uiDialogButtonPane.remove(); + this.uiButtonSet.empty(); + + 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 = $( "').addClass(this._triggerClass).html(o==""?s:$("").attr({src:o,alt:s,title:s}))),e[r?"before":"after"](t.trigger),t.trigger.click(function(){return $.datepicker._datepickerShowing&&$.datepicker._lastInput==e[0]?$.datepicker._hideDatepicker():$.datepicker._datepickerShowing&&$.datepicker._lastInput!=e[0]?($.datepicker._hideDatepicker(),$.datepicker._showDatepicker(e[0])):$.datepicker._showDatepicker(e[0]),!1})}},_autoSize:function(e){if(this._get(e,"autoSize")&&!e.inline){var t=new Date(2009,11,20),n=this._get(e,"dateFormat");if(n.match(/[DM]/)){var r=function(e){var t=0,n=0;for(var r=0;rt&&(t=e[r].length,n=r);return n};t.setMonth(r(this._get(e,n.match(/MM/)?"monthNames":"monthNamesShort"))),t.setDate(r(this._get(e,n.match(/DD/)?"dayNames":"dayNamesShort"))+20-t.getDay())}e.input.attr("size",this._formatDate(e,t).length)}},_inlineDatepicker:function(e,t){var n=$(e);if(n.hasClass(this.markerClassName))return;n.addClass(this.markerClassName).append(t.dpDiv).bind("setData.datepicker",function(e,n,r){t.settings[n]=r}).bind("getData.datepicker",function(e,n){return this._get(t,n)}),$.data(e,PROP_NAME,t),this._setDate(t,this._getDefaultDate(t),!0),this._updateDatepicker(t),this._updateAlternate(t),t.settings.disabled&&this._disableDatepicker(e),t.dpDiv.css("display","block")},_dialogDatepicker:function(e,t,n,r,i){var s=this._dialogInst;if(!s){this.uuid+=1;var o="dp"+this.uuid;this._dialogInput=$(''),this._dialogInput.keydown(this._doKeyDown),$("body").append(this._dialogInput),s=this._dialogInst=this._newInst(this._dialogInput,!1),s.settings={},$.data(this._dialogInput[0],PROP_NAME,s)}extendRemove(s.settings,r||{}),t=t&&t.constructor==Date?this._formatDate(s,t):t,this._dialogInput.val(t),this._pos=i?i.length?i:[i.pageX,i.pageY]:null;if(!this._pos){var u=document.documentElement.clientWidth,a=document.documentElement.clientHeight,f=document.documentElement.scrollLeft||document.body.scrollLeft,l=document.documentElement.scrollTop||document.body.scrollTop;this._pos=[u/2-100+f,a/2-150+l]}return this._dialogInput.css("left",this._pos[0]+20+"px").css("top",this._pos[1]+"px"),s.settings.onSelect=n,this._inDialog=!0,this.dpDiv.addClass(this._dialogClass),this._showDatepicker(this._dialogInput[0]),$.blockUI&&$.blockUI(this.dpDiv),$.data(this._dialogInput[0],PROP_NAME,s),this},_destroyDatepicker:function(e){var t=$(e),n=$.data(e,PROP_NAME);if(!t.hasClass(this.markerClassName))return;var r=e.nodeName.toLowerCase();$.removeData(e,PROP_NAME),r=="input"?(n.append.remove(),n.trigger.remove(),t.removeClass(this.markerClassName).unbind("focus",this._showDatepicker).unbind("keydown",this._doKeyDown).unbind("keypress",this._doKeyPress).unbind("keyup",this._doKeyUp)):(r=="div"||r=="span")&&t.removeClass(this.markerClassName).empty()},_enableDatepicker:function(e){var t=$(e),n=$.data(e,PROP_NAME);if(!t.hasClass(this.markerClassName))return;var r=e.nodeName.toLowerCase();if(r=="input")e.disabled=!1,n.trigger.filter("button").each(function(){this.disabled=!1}).end().filter("img").css({opacity:"1.0",cursor:""});else if(r=="div"||r=="span"){var i=t.children("."+this._inlineClass);i.children().removeClass("ui-state-disabled"),i.find("select.ui-datepicker-month, select.ui-datepicker-year").prop("disabled",!1)}this._disabledInputs=$.map(this._disabledInputs,function(t){return t==e?null:t})},_disableDatepicker:function(e){var t=$(e),n=$.data(e,PROP_NAME);if(!t.hasClass(this.markerClassName))return;var r=e.nodeName.toLowerCase();if(r=="input")e.disabled=!0,n.trigger.filter("button").each(function(){this.disabled=!0}).end().filter("img").css({opacity:"0.5",cursor:"default"});else if(r=="div"||r=="span"){var i=t.children("."+this._inlineClass);i.children().addClass("ui-state-disabled"),i.find("select.ui-datepicker-month, select.ui-datepicker-year").prop("disabled",!0)}this._disabledInputs=$.map(this._disabledInputs,function(t){return t==e?null:t}),this._disabledInputs[this._disabledInputs.length]=e},_isDisabledDatepicker:function(e){if(!e)return!1;for(var t=0;t-1}},_doKeyUp:function(e){var t=$.datepicker._getInst(e.target);if(t.input.val()!=t.lastVal)try{var n=$.datepicker.parseDate($.datepicker._get(t,"dateFormat"),t.input?t.input.val():null,$.datepicker._getFormatConfig(t));n&&($.datepicker._setDateFromField(t),$.datepicker._updateAlternate(t),$.datepicker._updateDatepicker(t))}catch(r){$.datepicker.log(r)}return!0},_showDatepicker:function(e){e=e.target||e,e.nodeName.toLowerCase()!="input"&&(e=$("input",e.parentNode)[0]);if($.datepicker._isDisabledDatepicker(e)||$.datepicker._lastInput==e)return;var t=$.datepicker._getInst(e);$.datepicker._curInst&&$.datepicker._curInst!=t&&($.datepicker._curInst.dpDiv.stop(!0,!0),t&&$.datepicker._datepickerShowing&&$.datepicker._hideDatepicker($.datepicker._curInst.input[0]));var n=$.datepicker._get(t,"beforeShow"),r=n?n.apply(e,[e,t]):{};if(r===!1)return;extendRemove(t.settings,r),t.lastVal=null,$.datepicker._lastInput=e,$.datepicker._setDateFromField(t),$.datepicker._inDialog&&(e.value=""),$.datepicker._pos||($.datepicker._pos=$.datepicker._findPos(e),$.datepicker._pos[1]+=e.offsetHeight);var i=!1;$(e).parents().each(function(){return i|=$(this).css("position")=="fixed",!i});var s={left:$.datepicker._pos[0],top:$.datepicker._pos[1]};$.datepicker._pos=null,t.dpDiv.empty(),t.dpDiv.css({position:"absolute",display:"block",top:"-1000px"}),$.datepicker._updateDatepicker(t),s=$.datepicker._checkOffset(t,s,i),t.dpDiv.css({position:$.datepicker._inDialog&&$.blockUI?"static":i?"fixed":"absolute",display:"none",left:s.left+"px",top:s.top+"px"});if(!t.inline){var o=$.datepicker._get(t,"showAnim"),u=$.datepicker._get(t,"duration"),a=function(){var e=t.dpDiv.find("iframe.ui-datepicker-cover");if(!!e.length){var n=$.datepicker._getBorders(t.dpDiv);e.css({left:-n[0],top:-n[1],width:t.dpDiv.outerWidth(),height:t.dpDiv.outerHeight()})}};t.dpDiv.zIndex($(e).zIndex()+1),$.datepicker._datepickerShowing=!0,$.effects&&($.effects.effect[o]||$.effects[o])?t.dpDiv.show(o,$.datepicker._get(t,"showOptions"),u,a):t.dpDiv[o||"show"](o?u:null,a),(!o||!u)&&a(),t.input.is(":visible")&&!t.input.is(":disabled")&&t.input.focus(),$.datepicker._curInst=t}},_updateDatepicker:function(e){this.maxRows=4;var t=$.datepicker._getBorders(e.dpDiv);instActive=e,e.dpDiv.empty().append(this._generateHTML(e)),this._attachHandlers(e);var n=e.dpDiv.find("iframe.ui-datepicker-cover");!n.length||n.css({left:-t[0],top:-t[1],width:e.dpDiv.outerWidth(),height:e.dpDiv.outerHeight()}),e.dpDiv.find("."+this._dayOverClass+" a").mouseover();var r=this._getNumberOfMonths(e),i=r[1],s=17;e.dpDiv.removeClass("ui-datepicker-multi-2 ui-datepicker-multi-3 ui-datepicker-multi-4").width(""),i>1&&e.dpDiv.addClass("ui-datepicker-multi-"+i).css("width",s*i+"em"),e.dpDiv[(r[0]!=1||r[1]!=1?"add":"remove")+"Class"]("ui-datepicker-multi"),e.dpDiv[(this._get(e,"isRTL")?"add":"remove")+"Class"]("ui-datepicker-rtl"),e==$.datepicker._curInst&&$.datepicker._datepickerShowing&&e.input&&e.input.is(":visible")&&!e.input.is(":disabled")&&e.input[0]!=document.activeElement&&e.input.focus();if(e.yearshtml){var o=e.yearshtml;setTimeout(function(){o===e.yearshtml&&e.yearshtml&&e.dpDiv.find("select.ui-datepicker-year:first").replaceWith(e.yearshtml),o=e.yearshtml=null},0)}},_getBorders:function(e){var t=function(e){return{thin:1,medium:2,thick:3}[e]||e};return[parseFloat(t(e.css("border-left-width"))),parseFloat(t(e.css("border-top-width")))]},_checkOffset:function(e,t,n){var r=e.dpDiv.outerWidth(),i=e.dpDiv.outerHeight(),s=e.input?e.input.outerWidth():0,o=e.input?e.input.outerHeight():0,u=document.documentElement.clientWidth+(n?0:$(document).scrollLeft()),a=document.documentElement.clientHeight+(n?0:$(document).scrollTop());return t.left-=this._get(e,"isRTL")?r-s:0,t.left-=n&&t.left==e.input.offset().left?$(document).scrollLeft():0,t.top-=n&&t.top==e.input.offset().top+o?$(document).scrollTop():0,t.left-=Math.min(t.left,t.left+r>u&&u>r?Math.abs(t.left+r-u):0),t.top-=Math.min(t.top,t.top+i>a&&a>i?Math.abs(i+o):0),t},_findPos:function(e){var t=this._getInst(e),n=this._get(t,"isRTL");while(e&&(e.type=="hidden"||e.nodeType!=1||$.expr.filters.hidden(e)))e=e[n?"previousSibling":"nextSibling"];var r=$(e).offset();return[r.left,r.top]},_hideDatepicker:function(e){var t=this._curInst;if(!t||e&&t!=$.data(e,PROP_NAME))return;if(this._datepickerShowing){var n=this._get(t,"showAnim"),r=this._get(t,"duration"),i=function(){$.datepicker._tidyDialog(t)};$.effects&&($.effects.effect[n]||$.effects[n])?t.dpDiv.hide(n,$.datepicker._get(t,"showOptions"),r,i):t.dpDiv[n=="slideDown"?"slideUp":n=="fadeIn"?"fadeOut":"hide"](n?r:null,i),n||i(),this._datepickerShowing=!1;var s=this._get(t,"onClose");s&&s.apply(t.input?t.input[0]:null,[t.input?t.input.val():"",t]),this._lastInput=null,this._inDialog&&(this._dialogInput.css({position:"absolute",left:"0",top:"-100px"}),$.blockUI&&($.unblockUI(),$("body").append(this.dpDiv))),this._inDialog=!1}},_tidyDialog:function(e){e.dpDiv.removeClass(this._dialogClass).unbind(".ui-datepicker-calendar")},_checkExternalClick:function(e){if(!$.datepicker._curInst)return;var t=$(e.target),n=$.datepicker._getInst(t[0]);(t[0].id!=$.datepicker._mainDivId&&t.parents("#"+$.datepicker._mainDivId).length==0&&!t.hasClass($.datepicker.markerClassName)&&!t.closest("."+$.datepicker._triggerClass).length&&$.datepicker._datepickerShowing&&(!$.datepicker._inDialog||!$.blockUI)||t.hasClass($.datepicker.markerClassName)&&$.datepicker._curInst!=n)&&$.datepicker._hideDatepicker()},_adjustDate:function(e,t,n){var r=$(e),i=this._getInst(r[0]);if(this._isDisabledDatepicker(r[0]))return;this._adjustInstDate(i,t+(n=="M"?this._get(i,"showCurrentAtPos"):0),n),this._updateDatepicker(i)},_gotoToday:function(e){var t=$(e),n=this._getInst(t[0]);if(this._get(n,"gotoCurrent")&&n.currentDay)n.selectedDay=n.currentDay,n.drawMonth=n.selectedMonth=n.currentMonth,n.drawYear=n.selectedYear=n.currentYear;else{var r=new Date;n.selectedDay=r.getDate(),n.drawMonth=n.selectedMonth=r.getMonth(),n.drawYear=n.selectedYear=r.getFullYear()}this._notifyChange(n),this._adjustDate(t)},_selectMonthYear:function(e,t,n){var r=$(e),i=this._getInst(r[0]);i["selected"+(n=="M"?"Month":"Year")]=i["draw"+(n=="M"?"Month":"Year")]=parseInt(t.options[t.selectedIndex].value,10),this._notifyChange(i),this._adjustDate(r)},_selectDay:function(e,t,n,r){var i=$(e);if($(r).hasClass(this._unselectableClass)||this._isDisabledDatepicker(i[0]))return;var s=this._getInst(i[0]);s.selectedDay=s.currentDay=$("a",r).html(),s.selectedMonth=s.currentMonth=t,s.selectedYear=s.currentYear=n,this._selectDate(e,this._formatDate(s,s.currentDay,s.currentMonth,s.currentYear))},_clearDate:function(e){var t=$(e),n=this._getInst(t[0]);this._selectDate(t,"")},_selectDate:function(e,t){var n=$(e),r=this._getInst(n[0]);t=t!=null?t:this._formatDate(r),r.input&&r.input.val(t),this._updateAlternate(r);var i=this._get(r,"onSelect");i?i.apply(r.input?r.input[0]:null,[t,r]):r.input&&r.input.trigger("change"),r.inline?this._updateDatepicker(r):(this._hideDatepicker(),this._lastInput=r.input[0],typeof r.input[0]!="object"&&r.input.focus(),this._lastInput=null)},_updateAlternate:function(e){var t=this._get(e,"altField");if(t){var n=this._get(e,"altFormat")||this._get(e,"dateFormat"),r=this._getDate(e),i=this.formatDate(n,r,this._getFormatConfig(e));$(t).each(function(){$(this).val(i)})}},noWeekends:function(e){var t=e.getDay();return[t>0&&t<6,""]},iso8601Week:function(e){var t=new Date(e.getTime());t.setDate(t.getDate()+4-(t.getDay()||7));var n=t.getTime();return t.setMonth(0),t.setDate(1),Math.floor(Math.round((n-t)/864e5)/7)+1},parseDate:function(e,t,n){if(e==null||t==null)throw"Invalid arguments";t=typeof t=="object"?t.toString():t+"";if(t=="")return null;var r=(n?n.shortYearCutoff:null)||this._defaults.shortYearCutoff;r=typeof r!="string"?r:(new Date).getFullYear()%100+parseInt(r,10);var i=(n?n.dayNamesShort:null)||this._defaults.dayNamesShort,s=(n?n.dayNames:null)||this._defaults.dayNames,o=(n?n.monthNamesShort:null)||this._defaults.monthNamesShort,u=(n?n.monthNames:null)||this._defaults.monthNames,a=-1,f=-1,l=-1,c=-1,h=!1,p=function(t){var n=y+1-1){f=1,l=c;do{var E=this._getDaysInMonth(a,f-1);if(l<=E)break;f++,l-=E}while(!0)}var b=this._daylightSavingAdjust(new Date(a,f-1,l));if(b.getFullYear()!=a||b.getMonth()+1!=f||b.getDate()!=l)throw"Invalid date";return b},ATOM:"yy-mm-dd",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",TICKS:"!",TIMESTAMP:"@",W3C:"yy-mm-dd",_ticksTo1970:(718685+Math.floor(492.5)-Math.floor(19.7)+Math.floor(4.925))*24*60*60*1e7,formatDate:function(e,t,n){if(!t)return"";var r=(n?n.dayNamesShort:null)||this._defaults.dayNamesShort,i=(n?n.dayNames:null)||this._defaults.dayNames,s=(n?n.monthNamesShort:null)||this._defaults.monthNamesShort,o=(n?n.monthNames:null)||this._defaults.monthNames,u=function(t){var n=h+112?e.getHours()+2:0),e):null},_setDate:function(e,t,n){var r=!t,i=e.selectedMonth,s=e.selectedYear,o=this._restrictMinMax(e,this._determineDate(e,t,new Date));e.selectedDay=e.currentDay=o.getDate(),e.drawMonth=e.selectedMonth=e.currentMonth=o.getMonth(),e.drawYear=e.selectedYear=e.currentYear=o.getFullYear(),(i!=e.selectedMonth||s!=e.selectedYear)&&!n&&this._notifyChange(e),this._adjustInstDate(e),e.input&&e.input.val(r?"":this._formatDate(e))},_getDate:function(e){var t=!e.currentYear||e.input&&e.input.val()==""?null:this._daylightSavingAdjust(new Date(e.currentYear,e.currentMonth,e.currentDay));return t},_attachHandlers:function(e){var t=this._get(e,"stepMonths"),n="#"+e.id.replace(/\\\\/g,"\\");e.dpDiv.find("[data-handler]").map(function(){var e={prev:function(){window["DP_jQuery_"+dpuuid].datepicker._adjustDate(n,-t,"M")},next:function(){window["DP_jQuery_"+dpuuid].datepicker._adjustDate(n,+t,"M")},hide:function(){window["DP_jQuery_"+dpuuid].datepicker._hideDatepicker()},today:function(){window["DP_jQuery_"+dpuuid].datepicker._gotoToday(n)},selectDay:function(){return window["DP_jQuery_"+dpuuid].datepicker._selectDay(n,+this.getAttribute("data-month"),+this.getAttribute("data-year"),this),!1},selectMonth:function(){return window["DP_jQuery_"+dpuuid].datepicker._selectMonthYear(n,this,"M"),!1},selectYear:function(){return window["DP_jQuery_"+dpuuid].datepicker._selectMonthYear(n,this,"Y"),!1}};$(this).bind(this.getAttribute("data-event"),e[this.getAttribute("data-handler")])})},_generateHTML:function(e){var t=new Date;t=this._daylightSavingAdjust(new Date(t.getFullYear(),t.getMonth(),t.getDate()));var n=this._get(e,"isRTL"),r=this._get(e,"showButtonPanel"),i=this._get(e,"hideIfNoPrevNext"),s=this._get(e,"navigationAsDateFormat"),o=this._getNumberOfMonths(e),u=this._get(e,"showCurrentAtPos"),a=this._get(e,"stepMonths"),f=o[0]!=1||o[1]!=1,l=this._daylightSavingAdjust(e.currentDay?new Date(e.currentYear,e.currentMonth,e.currentDay):new Date(9999,9,9)),c=this._getMinMaxDate(e,"min"),h=this._getMinMaxDate(e,"max"),p=e.drawMonth-u,d=e.drawYear;p<0&&(p+=12,d--);if(h){var v=this._daylightSavingAdjust(new Date(h.getFullYear(),h.getMonth()-o[0]*o[1]+1,h.getDate()));v=c&&vv)p--,p<0&&(p=11,d--)}e.drawMonth=p,e.drawYear=d;var m=this._get(e,"prevText");m=s?this.formatDate(m,this._daylightSavingAdjust(new Date(d,p-a,1)),this._getFormatConfig(e)):m;var g=this._canAdjustMonth(e,-1,d,p)?''+m+"":i?"":''+m+"",y=this._get(e,"nextText");y=s?this.formatDate(y,this._daylightSavingAdjust(new Date(d,p+a,1)),this._getFormatConfig(e)):y;var b=this._canAdjustMonth(e,1,d,p)?''+y+"":i?"":''+y+"",w=this._get(e,"currentText"),E=this._get(e,"gotoCurrent")&&e.currentDay?l:t;w=s?this.formatDate(w,E,this._getFormatConfig(e)):w;var S=e.inline?"":'",x=r?'
      '+(n?S:"")+(this._isInRange(e,E)?'":"")+(n?"":S)+"
      ":"",T=parseInt(this._get(e,"firstDay"),10);T=isNaN(T)?0:T;var N=this._get(e,"showWeek"),C=this._get(e,"dayNames"),k=this._get(e,"dayNamesShort"),L=this._get(e,"dayNamesMin"),A=this._get(e,"monthNames"),O=this._get(e,"monthNamesShort"),M=this._get(e,"beforeShowDay"),_=this._get(e,"showOtherMonths"),D=this._get(e,"selectOtherMonths"),P=this._get(e,"calculateWeek")||this.iso8601Week,H=this._getDefaultDate(e),B="";for(var j=0;j1)switch(I){case 0:U+=" ui-datepicker-group-first",R=" ui-corner-"+(n?"right":"left");break;case o[1]-1:U+=" ui-datepicker-group-last",R=" ui-corner-"+(n?"left":"right");break;default:U+=" ui-datepicker-group-middle",R=""}U+='">'}U+='
      '+(/all|left/.test(R)&&j==0?n?b:g:"")+(/all|right/.test(R)&&j==0?n?g:b:"")+this._generateMonthYearHeader(e,p,d,c,h,j>0||I>0,A,O)+'
      '+"";var z=N?'":"";for(var W=0;W<7;W++){var X=(W+T)%7;z+="=5?' class="ui-datepicker-week-end"':"")+">"+''+L[X]+""}U+=z+"";var V=this._getDaysInMonth(d,p);d==e.selectedYear&&p==e.selectedMonth&&(e.selectedDay=Math.min(e.selectedDay,V));var J=(this._getFirstDayOfMonth(d,p)-T+7)%7,K=Math.ceil((J+V)/7),Q=f?this.maxRows>K?this.maxRows:K:K;this.maxRows=Q;var G=this._daylightSavingAdjust(new Date(d,p,1-J));for(var Y=0;Y";var Z=N?'":"";for(var W=0;W<7;W++){var et=M?M.apply(e.input?e.input[0]:null,[G]):[!0,""],tt=G.getMonth()!=p,nt=tt&&!D||!et[0]||c&&Gh;Z+='",G.setDate(G.getDate()+1),G=this._daylightSavingAdjust(G)}U+=Z+""}p++,p>11&&(p=0,d++),U+="
      '+this._get(e,"weekHeader")+"
      '+this._get(e,"calculateWeek")(G)+""+(tt&&!_?" ":nt?''+G.getDate()+"":''+G.getDate()+"")+"
      "+(f?"
      "+(o[0]>0&&I==o[1]-1?'
      ':""):""),F+=U}B+=F}return B+=x+($.browser.msie&&parseInt($.browser.version,10)<7&&!e.inline?'':""),e._keyEvent=!1,B},_generateMonthYearHeader:function(e,t,n,r,i,s,o,u){var a=this._get(e,"changeMonth"),f=this._get(e,"changeYear"),l=this._get(e,"showMonthAfterYear"),c='
      ',h="";if(s||!a)h+=''+o[t]+"";else{var p=r&&r.getFullYear()==n,d=i&&i.getFullYear()==n;h+='"}l||(c+=h+(s||!a||!f?" ":""));if(!e.yearshtml){e.yearshtml="";if(s||!f)c+=''+n+"";else{var m=this._get(e,"yearRange").split(":"),g=(new Date).getFullYear(),y=function(e){var t=e.match(/c[+-].*/)?n+parseInt(e.substring(1),10):e.match(/[+-].*/)?g+parseInt(e,10):parseInt(e,10);return isNaN(t)?g:t},b=y(m[0]),w=Math.max(b,y(m[1]||""));b=r?Math.max(b,r.getFullYear()):b,w=i?Math.min(w,i.getFullYear()):w,e.yearshtml+='",c+=e.yearshtml,e.yearshtml=null}}return c+=this._get(e,"yearSuffix"),l&&(c+=(s||!a||!f?" ":"")+h),c+="
      ",c},_adjustInstDate:function(e,t,n){var r=e.drawYear+(n=="Y"?t:0),i=e.drawMonth+(n=="M"?t:0),s=Math.min(e.selectedDay,this._getDaysInMonth(r,i))+(n=="D"?t:0),o=this._restrictMinMax(e,this._daylightSavingAdjust(new Date(r,i,s)));e.selectedDay=o.getDate(),e.drawMonth=e.selectedMonth=o.getMonth(),e.drawYear=e.selectedYear=o.getFullYear(),(n=="M"||n=="Y")&&this._notifyChange(e)},_restrictMinMax:function(e,t){var n=this._getMinMaxDate(e,"min"),r=this._getMinMaxDate(e,"max"),i=n&&tr?r:i,i},_notifyChange:function(e){var t=this._get(e,"onChangeMonthYear");t&&t.apply(e.input?e.input[0]:null,[e.selectedYear,e.selectedMonth+1,e])},_getNumberOfMonths:function(e){var t=this._get(e,"numberOfMonths");return t==null?[1,1]:typeof t=="number"?[1,t]:t},_getMinMaxDate:function(e,t){return this._determineDate(e,this._get(e,t+"Date"),null)},_getDaysInMonth:function(e,t){return 32-this._daylightSavingAdjust(new Date(e,t,32)).getDate()},_getFirstDayOfMonth:function(e,t){return(new Date(e,t,1)).getDay()},_canAdjustMonth:function(e,t,n,r){var i=this._getNumberOfMonths(e),s=this._daylightSavingAdjust(new Date(n,r+(t<0?t:i[0]*i[1]),1));return t<0&&s.setDate(this._getDaysInMonth(s.getFullYear(),s.getMonth())),this._isInRange(e,s)},_isInRange:function(e,t){var n=this._getMinMaxDate(e,"min"),r=this._getMinMaxDate(e,"max");return(!n||t.getTime()>=n.getTime())&&(!r||t.getTime()<=r.getTime())},_getFormatConfig:function(e){var t=this._get(e,"shortYearCutoff");return t=typeof t!="string"?t:(new Date).getFullYear()%100+parseInt(t,10),{shortYearCutoff:t,dayNamesShort:this._get(e,"dayNamesShort"),dayNames:this._get(e,"dayNames"),monthNamesShort:this._get(e,"monthNamesShort"),monthNames:this._get(e,"monthNames")}},_formatDate:function(e,t,n,r){t||(e.currentDay=e.selectedDay,e.currentMonth=e.selectedMonth,e.currentYear=e.selectedYear);var i=t?typeof t=="object"?t:this._daylightSavingAdjust(new Date(r,n,t)):this._daylightSavingAdjust(new Date(e.currentYear,e.currentMonth,e.currentDay));return this.formatDate(this._get(e,"dateFormat"),i,this._getFormatConfig(e))}}),$.fn.datepicker=function(e){if(!this.length)return this;$.datepicker.initialized||($(document).mousedown($.datepicker._checkExternalClick).find(document.body).append($.datepicker.dpDiv),$.datepicker.initialized=!0);var t=Array.prototype.slice.call(arguments,1);return typeof e!="string"||e!="isDisabled"&&e!="getDate"&&e!="widget"?e=="option"&&arguments.length==2&&typeof arguments[1]=="string"?$.datepicker["_"+e+"Datepicker"].apply($.datepicker,[this[0]].concat(t)):this.each(function(){typeof e=="string"?$.datepicker["_"+e+"Datepicker"].apply($.datepicker,[this].concat(t)):$.datepicker._attachDatepicker(this,e)}):$.datepicker["_"+e+"Datepicker"].apply($.datepicker,[this[0]].concat(t))},$.datepicker=new Datepicker,$.datepicker.initialized=!1,$.datepicker.uuid=(new Date).getTime(),$.datepicker.version="1.9.0",window["DP_jQuery_"+dpuuid]=$})(jQuery);(function(e,t){var n="ui-dialog ui-widget ui-widget-content ui-corner-all ",r={buttons:!0,height:!0,maxHeight:!0,maxWidth:!0,minHeight:!0,minWidth:!0,width:!0},i={maxHeight:!0,maxWidth:!0,minHeight:!0,minWidth:!0};e.widget("ui.dialog",{version:"1.9.0",options:{autoOpen:!0,buttons:{},closeOnEscape:!0,closeText:"close",dialogClass:"",draggable:!0,hide:null,height:"auto",maxHeight:!1,maxWidth:!1,minHeight:150,minWidth:150,modal:!1,position:{my:"center",at:"center",of:window,collision:"fit",using:function(t){var n=e(this).css(t).offset().top;n<0&&e(this).css("top",t.top-n)}},resizable:!0,show:null,stack:!0,title:"",width:300,zIndex:1e3},_create:function(){this.originalTitle=this.element.attr("title"),typeof this.originalTitle!="string"&&(this.originalTitle=""),this.oldPosition={parent:this.element.parent(),index:this.element.parent().children().index(this.element)},this.options.title=this.options.title||this.originalTitle;var t=this,r=this.options,i=r.title||" ",s=(this.uiDialog=e("
      ")).addClass(n+r.dialogClass).css({display:"none",outline:0,zIndex:r.zIndex}).attr("tabIndex",-1).keydown(function(n){r.closeOnEscape&&!n.isDefaultPrevented()&&n.keyCode&&n.keyCode===e.ui.keyCode.ESCAPE&&(t.close(n),n.preventDefault())}).mousedown(function(e){t.moveToTop(!1,e)}).appendTo("body"),o=this.element.show().removeAttr("title").addClass("ui-dialog-content ui-widget-content").appendTo(s),u=(this.uiDialogTitlebar=e("
      ")).addClass("ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix").prependTo(s),a=e("").addClass("ui-dialog-titlebar-close ui-corner-all").attr("role","button").click(function(e){e.preventDefault(),t.close(e)}).appendTo(u),f=(this.uiDialogTitlebarCloseText=e("")).addClass("ui-icon ui-icon-closethick").text(r.closeText).appendTo(a),l=e("").uniqueId().addClass("ui-dialog-title").html(i).prependTo(u),c=(this.uiDialogButtonPane=e("
      ")).addClass("ui-dialog-buttonpane ui-widget-content ui-helper-clearfix"),h=(this.uiButtonSet=e("
      ")).addClass("ui-dialog-buttonset").appendTo(c);s.attr({role:"dialog","aria-labelledby":l.attr("id")}),u.find("*").add(u).disableSelection(),this._hoverable(a),this._focusable(a),r.draggable&&e.fn.draggable&&this._makeDraggable(),r.resizable&&e.fn.resizable&&this._makeResizable(),this._createButtons(r.buttons),this._isOpen=!1,e.fn.bgiframe&&s.bgiframe(),this._on(s,{keydown:function(t){if(!r.modal||t.keyCode!==e.ui.keyCode.TAB)return;var n=e(":tabbable",s),i=n.filter(":first"),o=n.filter(":last");if(t.target===o[0]&&!t.shiftKey)return i.focus(1),!1;if(t.target===i[0]&&t.shiftKey)return o.focus(1),!1}})},_init:function(){this.options.autoOpen&&this.open()},_destroy:function(){var e,t=this.oldPosition;this.overlay&&this.overlay.destroy(),this.uiDialog.hide(),this.element.removeClass("ui-dialog-content ui-widget-content").hide().appendTo("body"),this.uiDialog.remove(),this.originalTitle&&this.element.attr("title",this.originalTitle),e=t.parent.children().eq(t.index),e.length&&e[0]!==this.element[0]?e.before(this.element):t.parent.append(this.element)},widget:function(){return this.uiDialog},close:function(t){var n=this,r,i;if(!this._isOpen)return;if(!1===this._trigger("beforeClose",t))return;return this._isOpen=!1,this.overlay&&this.overlay.destroy(),this.options.hide?this.uiDialog.hide(this.options.hide,function(){n._trigger("close",t)}):(this.uiDialog.hide(),this._trigger("close",t)),e.ui.dialog.overlay.resize(),this.options.modal&&(r=0,e(".ui-dialog").each(function(){this!==n.uiDialog[0]&&(i=e(this).css("z-index"),isNaN(i)||(r=Math.max(r,i)))}),e.ui.dialog.maxZ=r),this},isOpen:function(){return this._isOpen},moveToTop:function(t,n){var r=this.options,i;return r.modal&&!t||!r.stack&&!r.modal?this._trigger("focus",n):(r.zIndex>e.ui.dialog.maxZ&&(e.ui.dialog.maxZ=r.zIndex),this.overlay&&(e.ui.dialog.maxZ+=1,e.ui.dialog.overlay.maxZ=e.ui.dialog.maxZ,this.overlay.$el.css("z-index",e.ui.dialog.overlay.maxZ)),i={scrollTop:this.element.scrollTop(),scrollLeft:this.element.scrollLeft()},e.ui.dialog.maxZ+=1,this.uiDialog.css("z-index",e.ui.dialog.maxZ),this.element.attr(i),this._trigger("focus",n),this)},open:function(){if(this._isOpen)return;var t,n=this.options,r=this.uiDialog;return this._size(),this._position(n.position),r.show(n.show),this.overlay=n.modal?new e.ui.dialog.overlay(this):null,this.moveToTop(!0),t=this.element.find(":tabbable"),t.length||(t=this.uiDialogButtonPane.find(":tabbable"),t.length||(t=r)),t.eq(0).focus(),this._isOpen=!0,this._trigger("open"),this},_createButtons:function(t){var n,r,i=this,s=!1;this.uiDialogButtonPane.remove(),this.uiButtonSet.empty(),typeof t=="object"&&t!==null&&e.each(t,function(){return!(s=!0)}),s?(e.each(t,function(t,n){n=e.isFunction(n)?{click:n,text:t}:n;var r=e("
      ").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()},value:function(e){return e===t?this._value():(this._setOption("value",e),this)},_setOption:function(e,t){e==="value"&&(this.options.value=t,this._refreshValue(),this._value()===this.options.max&&this._trigger("complete")),this._super(e,t)},_value:function(){var e=this.options.value;return typeof e!="number"&&(e=0),Math.min(this.options.max,Math.max(this.min,e))},_percentage:function(){return 100*this._value()/this.options.max},_refreshValue:function(){var e=this.value(),t=this._percentage();this.oldValue!==e&&(this.oldValue=e,this._trigger("change")),this.valueDiv.toggle(e>this.min).toggleClass("ui-corner-right",e===this.options.max).width(t.toFixed(0)+"%"),this.element.attr("aria-valuenow",e)}})})(jQuery);(function(e,t){var n=5;e.widget("ui.slider",e.ui.mouse,{version:"1.9.0",widgetEventPrefix:"slide",options:{animate:!1,distance:0,max:100,min:0,orientation:"horizontal",range:!1,step:1,value:0,values:null},_create:function(){var t,r=this.options,i=this.element.find(".ui-slider-handle").addClass("ui-state-default ui-corner-all"),s="",o=r.values&&r.values.length||1,u=[];this._keySliding=!1,this._mouseSliding=!1,this._animateOff=!0,this._handleIndex=null,this._detectOrientation(),this._mouseInit(),this.element.addClass("ui-slider ui-slider-"+this.orientation+" ui-widget"+" ui-widget-content"+" ui-corner-all"+(r.disabled?" ui-slider-disabled ui-disabled":"")),this.range=e([]),r.range&&(r.range===!0&&(r.values||(r.values=[this._valueMin(),this._valueMin()]),r.values.length&&r.values.length!==2&&(r.values=[r.values[0],r.values[0]])),this.range=e("
      ").appendTo(this.element).addClass("ui-slider-range ui-widget-header"+(r.range==="min"||r.range==="max"?" ui-slider-range-"+r.range:"")));for(t=i.length;tn&&(i=n,s=e(this),o=t)}),c.range===!0&&this.values(1)===c.min&&(o+=1,s=e(this.handles[o])),u=this._start(t,o),u===!1?!1:(this._mouseSliding=!0,this._handleIndex=o,s.addClass("ui-state-active").focus(),a=s.offset(),f=!e(t.target).parents().andSelf().is(".ui-slider-handle"),this._clickOffset=f?{left:0,top:0}:{left:t.pageX-a.left-s.width()/2,top:t.pageY-a.top-s.height()/2-(parseInt(s.css("borderTopWidth"),10)||0)-(parseInt(s.css("borderBottomWidth"),10)||0)+(parseInt(s.css("marginTop"),10)||0)},this.handles.hasClass("ui-state-hover")||this._slide(t,o,r),this._animateOff=!0,!0))},_mouseStart:function(e){return!0},_mouseDrag:function(e){var t={x:e.pageX,y:e.pageY},n=this._normValueFromMouse(t);return this._slide(e,this._handleIndex,n),!1},_mouseStop:function(e){return this.handles.removeClass("ui-state-active"),this._mouseSliding=!1,this._stop(e,this._handleIndex),this._change(e,this._handleIndex),this._handleIndex=null,this._clickOffset=null,this._animateOff=!1,!1},_detectOrientation:function(){this.orientation=this.options.orientation==="vertical"?"vertical":"horizontal"},_normValueFromMouse:function(e){var t,n,r,i,s;return this.orientation==="horizontal"?(t=this.elementSize.width,n=e.x-this.elementOffset.left-(this._clickOffset?this._clickOffset.left:0)):(t=this.elementSize.height,n=e.y-this.elementOffset.top-(this._clickOffset?this._clickOffset.top:0)),r=n/t,r>1&&(r=1),r<0&&(r=0),this.orientation==="vertical"&&(r=1-r),i=this._valueMax()-this._valueMin(),s=this._valueMin()+r*i,this._trimAlignValue(s)},_start:function(e,t){var n={handle:this.handles[t],value:this.value()};return this.options.values&&this.options.values.length&&(n.value=this.values(t),n.values=this.values()),this._trigger("start",e,n)},_slide:function(e,t,n){var r,i,s;this.options.values&&this.options.values.length?(r=this.values(t?0:1),this.options.values.length===2&&this.options.range===!0&&(t===0&&n>r||t===1&&n1){this.options.values[t]=this._trimAlignValue(n),this._refreshValue(),this._change(null,t);return}if(!arguments.length)return this._values();if(!e.isArray(arguments[0]))return this.options.values&&this.options.values.length?this._values(t):this.value();r=this.options.values,i=arguments[0];for(s=0;s=this._valueMax())return this._valueMax();var t=this.options.step>0?this.options.step:1,n=(e-this._valueMin())%t,r=e-n;return Math.abs(n)*2>=t&&(r+=n>0?t:-t),parseFloat(r.toFixed(5))},_valueMin:function(){return this.options.min},_valueMax:function(){return this.options.max},_refreshValue:function(){var t,n,r,i,s,o=this.options.range,u=this.options,a=this,f=this._animateOff?!1:u.animate,l={};this.options.values&&this.options.values.length?this.handles.each(function(r,i){n=(a.values(r)-a._valueMin())/(a._valueMax()-a._valueMin())*100,l[a.orientation==="horizontal"?"left":"bottom"]=n+"%",e(this).stop(1,1)[f?"animate":"css"](l,u.animate),a.options.range===!0&&(a.orientation==="horizontal"?(r===0&&a.range.stop(1,1)[f?"animate":"css"]({left:n+"%"},u.animate),r===1&&a.range[f?"animate":"css"]({width:n-t+"%"},{queue:!1,duration:u.animate})):(r===0&&a.range.stop(1,1)[f?"animate":"css"]({bottom:n+"%"},u.animate),r===1&&a.range[f?"animate":"css"]({height:n-t+"%"},{queue:!1,duration:u.animate}))),t=n}):(r=this.value(),i=this._valueMin(),s=this._valueMax(),n=s!==i?(r-i)/(s-i)*100:0,l[this.orientation==="horizontal"?"left":"bottom"]=n+"%",this.handle.stop(1,1)[f?"animate":"css"](l,u.animate),o==="min"&&this.orientation==="horizontal"&&this.range.stop(1,1)[f?"animate":"css"]({width:n+"%"},u.animate),o==="max"&&this.orientation==="horizontal"&&this.range[f?"animate":"css"]({width:100-n+"%"},{queue:!1,duration:u.animate}),o==="min"&&this.orientation==="vertical"&&this.range.stop(1,1)[f?"animate":"css"]({height:n+"%"},u.animate),o==="max"&&this.orientation==="vertical"&&this.range[f?"animate":"css"]({height:100-n+"%"},{queue:!1,duration:u.animate}))}})})(jQuery);(function(e){function t(e){return function(){var t=this.element.val();e.apply(this,arguments),this._refresh(),t!==this.element.val()&&this._trigger("change")}}e.widget("ui.spinner",{version:"1.9.0",defaultElement:"",widgetEventPrefix:"spin",options:{culture:null,icons:{down:"ui-icon-triangle-1-s",up:"ui-icon-triangle-1-n"},incremental:!0,max:null,min:null,numberFormat:null,page:10,step:1,change:null,spin:null,start:null,stop:null},_create:function(){this._setOption("max",this.options.max),this._setOption("min",this.options.min),this._setOption("step",this.options.step),this._value(this.element.val(),!0),this._draw(),this._on(this._events),this._refresh(),this._on(this.window,{beforeunload:function(){this.element.removeAttr("autocomplete")}})},_getCreateOptions:function(){var t={},n=this.element;return e.each(["min","max","step"],function(e,r){var i=n.attr(r);i!==undefined&&i.length&&(t[r]=i)}),t},_events:{keydown:function(e){this._start(e)&&this._keydown(e)&&e.preventDefault()},keyup:"_stop",focus:function(){this.uiSpinner.addClass("ui-state-active"),this.previous=this.element.val()},blur:function(e){if(this.cancelBlur){delete this.cancelBlur;return}this._refresh(),this.uiSpinner.removeClass("ui-state-active"),this.previous!==this.element.val()&&this._trigger("change",e)},mousewheel:function(e,t){if(!t)return;if(!this.spinning&&!this._start(e))return!1;this._spin((t>0?1:-1)*this.options.step,e),clearTimeout(this.mousewheelTimer),this.mousewheelTimer=this._delay(function(){this.spinning&&this._stop(e)},100),e.preventDefault()},"mousedown .ui-spinner-button":function(t){function r(){var e=this.element[0]===this.document[0].activeElement;e||(this.element.focus(),this.previous=n,this._delay(function(){this.previous=n}))}var n;n=this.element[0]===this.document[0].activeElement?this.previous:this.element.val(),t.preventDefault(),r.call(this),this.cancelBlur=!0,this._delay(function(){delete this.cancelBlur,r.call(this)});if(this._start(t)===!1)return;this._repeat(null,e(t.currentTarget).hasClass("ui-spinner-up")?1:-1,t)},"mouseup .ui-spinner-button":"_stop","mouseenter .ui-spinner-button":function(t){if(!e(t.currentTarget).hasClass("ui-state-active"))return;if(this._start(t)===!1)return!1;this._repeat(null,e(t.currentTarget).hasClass("ui-spinner-up")?1:-1,t)},"mouseleave .ui-spinner-button":"_stop"},_draw:function(){var e=this.uiSpinner=this.element.addClass("ui-spinner-input").attr("autocomplete","off").wrap(this._uiSpinnerHtml()).parent().append(this._buttonHtml());this._hoverable(e),this.element.attr("role","spinbutton"),this.buttons=e.find(".ui-spinner-button").attr("tabIndex",-1).button().removeClass("ui-corner-all"),this.buttons.height()>Math.ceil(e.height()*.5)&&e.height()>0&&e.height(e.height()),this.options.disabled&&this.disable()},_keydown:function(t){var n=this.options,r=e.ui.keyCode;switch(t.keyCode){case r.UP:return this._repeat(null,1,t),!0;case r.DOWN:return this._repeat(null,-1,t),!0;case r.PAGE_UP:return this._repeat(null,n.page,t),!0;case r.PAGE_DOWN:return this._repeat(null,-n.page,t),!0}return!1},_uiSpinnerHtml:function(){return""},_buttonHtml:function(){return""+""+""+""+""},_start:function(e){return!this.spinning&&this._trigger("start",e)===!1?!1:(this.counter||(this.counter=1),this.spinning=!0,!0)},_repeat:function(e,t,n){e=e||500,clearTimeout(this.timer),this.timer=this._delay(function(){this._repeat(40,t,n)},e),this._spin(t*this.options.step,n)},_spin:function(e,t){var n=this.value()||0;this.counter||(this.counter=1),n=this._adjustValue(n+e*this._increment(this.counter));if(!this.spinning||this._trigger("spin",t,{value:n})!==!1)this._value(n),this.counter++},_increment:function(t){var n=this.options.incremental;return n?e.isFunction(n)?n(t):Math.floor(t*t*t/5e4-t*t/500+17*t/200+1):1},_precision:function(){var e=this._precisionOf(this.options.step);return this.options.min!==null&&(e=Math.max(e,this._precisionOf(this.options.min))),e},_precisionOf:function(e){var t=e.toString(),n=t.indexOf(".");return n===-1?0:t.length-n-1},_adjustValue:function(e){var t,n,r=this.options;return t=r.min!==null?r.min:0,n=e-t,n=Math.round(n/r.step)*r.step,e=t+n,e=parseFloat(e.toFixed(this._precision())),r.max!==null&&e>r.max?r.max:r.min!==null&&e1&&e.href.replace(r,"")===location.href.replace(r,"")}var n=0,r=/#.*$/;e.widget("ui.tabs",{version:"1.9.0",delay:300,options:{active:null,collapsible:!1,event:"click",heightStyle:"content",hide:null,show:null,activate:null,beforeActivate:null,beforeLoad:null,load:null},_create:function(){var t,n=this,r=this.options,i=r.active;this.running=!1,this.element.addClass("ui-tabs ui-widget ui-widget-content ui-corner-all").toggleClass("ui-tabs-collapsible",r.collapsible).delegate(".ui-tabs-nav > li","mousedown"+this.eventNamespace,function(t){e(this).is(".ui-state-disabled")&&t.preventDefault()}).delegate(".ui-tabs-anchor","focus"+this.eventNamespace,function(){e(this).closest("li").is(".ui-state-disabled")&&this.blur()}),this._processTabs();if(i===null){location.hash&&this.anchors.each(function(e,t){if(t.hash===location.hash)return i=e,!1}),i===null&&(i=this.tabs.filter(".ui-tabs-active").index());if(i===null||i===-1)i=this.tabs.length?0:!1}i!==!1&&(i=this.tabs.index(this.tabs.eq(i)),i===-1&&(i=r.collapsible?!1:0)),r.active=i,!r.collapsible&&r.active===!1&&this.anchors.length&&(r.active=0),e.isArray(r.disabled)&&(r.disabled=e.unique(r.disabled.concat(e.map(this.tabs.filter(".ui-state-disabled"),function(e){return n.tabs.index(e)}))).sort()),this.options.active!==!1&&this.anchors.length?this.active=this._findActive(this.options.active):this.active=e(),this._refresh(),this.active.length&&this.load(r.active)},_getCreateEventData:function(){return{tab:this.active,panel:this.active.length?this._getPanelForTab(this.active):e()}},_tabKeydown:function(t){var n=e(this.document[0].activeElement).closest("li"),r=this.tabs.index(n),i=!0;if(this._handlePageNav(t))return;switch(t.keyCode){case e.ui.keyCode.RIGHT:case e.ui.keyCode.DOWN:r++;break;case e.ui.keyCode.UP:case e.ui.keyCode.LEFT:i=!1,r--;break;case e.ui.keyCode.END:r=this.anchors.length-1;break;case e.ui.keyCode.HOME:r=0;break;case e.ui.keyCode.SPACE:t.preventDefault(),clearTimeout(this.activating),this._activate(r);return;case e.ui.keyCode.ENTER:t.preventDefault(),clearTimeout(this.activating),this._activate(r===this.options.active?!1:r);return;default:return}t.preventDefault(),clearTimeout(this.activating),r=this._focusNextTab(r,i),t.ctrlKey||(n.attr("aria-selected","false"),this.tabs.eq(r).attr("aria-selected","true"),this.activating=this._delay(function(){this.option("active",r)},this.delay))},_panelKeydown:function(t){if(this._handlePageNav(t))return;t.ctrlKey&&t.keyCode===e.ui.keyCode.UP&&(t.preventDefault(),this.active.focus())},_handlePageNav:function(t){if(t.altKey&&t.keyCode===e.ui.keyCode.PAGE_UP)return this._activate(this._focusNextTab(this.options.active-1,!1)),!0;if(t.altKey&&t.keyCode===e.ui.keyCode.PAGE_DOWN)return this._activate(this._focusNextTab(this.options.active+1,!0)),!0},_findNextTab:function(t,n){function i(){return t>r&&(t=0),t<0&&(t=r),t}var r=this.tabs.length-1;while(e.inArray(i(),this.options.disabled)!==-1)t=n?t+1:t-1;return t},_focusNextTab:function(e,t){return e=this._findNextTab(e,t),this.tabs.eq(e).focus(),e},_setOption:function(e,t){if(e==="active"){this._activate(t);return}if(e==="disabled"){this._setupDisabled(t);return}this._super(e,t),e==="collapsible"&&(this.element.toggleClass("ui-tabs-collapsible",t),!t&&this.options.active===!1&&this._activate(0)),e==="event"&&this._setupEvents(t),e==="heightStyle"&&this._setupHeightStyle(t)},_tabId:function(e){return e.attr("aria-controls")||"ui-tabs-"+i()},_sanitizeSelector:function(e){return e?e.replace(/[!"$%&'()*+,.\/:;<=>?@\[\]\^`{|}~]/g,"\\$&"):""},refresh:function(){var t,n=this.options,r=this.tablist.children(":has(a[href])");n.disabled=e.map(r.filter(".ui-state-disabled"),function(e){return r.index(e)}),this._processTabs(),n.active===!1||!this.anchors.length?(n.active=!1,this.active=e()):this.active.length&&!e.contains(this.tablist[0],this.active[0])?this.tabs.length===n.disabled.length?(n.active=!1,this.active=e()):this._activate(this._findNextTab(Math.max(0,n.active-1),!1)):n.active=this.tabs.index(this.active),this._refresh()},_refresh:function(){this._setupDisabled(this.options.disabled),this._setupEvents(this.options.event),this._setupHeightStyle(this.options.heightStyle),this.tabs.not(this.active).attr({"aria-selected":"false",tabIndex:-1}),this.panels.not(this._getPanelForTab(this.active)).hide().attr({"aria-expanded":"false","aria-hidden":"true"}),this.active.length?(this.active.addClass("ui-tabs-active ui-state-active").attr({"aria-selected":"true",tabIndex:0}),this._getPanelForTab(this.active).show().attr({"aria-expanded":"true","aria-hidden":"false"})):this.tabs.eq(0).attr("tabIndex",0)},_processTabs:function(){var t=this;this.tablist=this._getList().addClass("ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all").attr("role","tablist"),this.tabs=this.tablist.find("> li:has(a[href])").addClass("ui-state-default ui-corner-top").attr({role:"tab",tabIndex:-1}),this.anchors=this.tabs.map(function(){return e("a",this)[0]}).addClass("ui-tabs-anchor").attr({role:"presentation",tabIndex:-1}),this.panels=e(),this.anchors.each(function(n,r){var i,o,u,a=e(r).uniqueId().attr("id"),f=e(r).closest("li"),l=f.attr("aria-controls");s(r)?(i=r.hash,o=t.element.find(t._sanitizeSelector(i))):(u=t._tabId(f),i="#"+u,o=t.element.find(i),o.length||(o=t._createPanel(u),o.insertAfter(t.panels[n-1]||t.tablist)),o.attr("aria-live","polite")),o.length&&(t.panels=t.panels.add(o)),l&&f.data("ui-tabs-aria-controls",l),f.attr({"aria-controls":i.substring(1),"aria-labelledby":a}),o.attr("aria-labelledby",a)}),this.panels.addClass("ui-tabs-panel ui-widget-content ui-corner-bottom").attr("role","tabpanel")},_getList:function(){return this.element.find("ol,ul").eq(0)},_createPanel:function(t){return e("
      ").attr("id",t).addClass("ui-tabs-panel ui-widget-content ui-corner-bottom").data("ui-tabs-destroy",!0)},_setupDisabled:function(t){e.isArray(t)&&(t.length?t.length===this.anchors.length&&(t=!0):t=!1);for(var n=0,r;r=this.tabs[n];n++)t===!0||e.inArray(n,t)!==-1?e(r).addClass("ui-state-disabled").attr("aria-disabled","true"):e(r).removeClass("ui-state-disabled").removeAttr("aria-disabled");this.options.disabled=t},_setupEvents:function(t){var n={click:function(e){e.preventDefault()}};t&&e.each(t.split(" "),function(e,t){n[t]="_eventHandler"}),this._off(this.anchors.add(this.tabs).add(this.panels)),this._on(this.anchors,n),this._on(this.tabs,{keydown:"_tabKeydown"}),this._on(this.panels,{keydown:"_panelKeydown"}),this._focusable(this.tabs),this._hoverable(this.tabs)},_setupHeightStyle:function(t){var n,r,i=this.element.parent();t==="fill"?(e.support.minHeight||(r=i.css("overflow"),i.css("overflow","hidden")),n=i.height(),this.element.siblings(":visible").each(function(){var t=e(this),r=t.css("position");if(r==="absolute"||r==="fixed")return;n-=t.outerHeight(!0)}),r&&i.css("overflow",r),this.element.children().not(this.panels).each(function(){n-=e(this).outerHeight(!0)}),this.panels.each(function(){e(this).height(Math.max(0,n-e(this).innerHeight()+e(this).height()))}).css("overflow","auto")):t==="auto"&&(n=0,this.panels.each(function(){n=Math.max(n,e(this).height("").height())}).height(n))},_eventHandler:function(t){var n=this.options,r=this.active,i=e(t.currentTarget),s=i.closest("li"),o=s[0]===r[0],u=o&&n.collapsible,a=u?e():this._getPanelForTab(s),f=r.length?this._getPanelForTab(r):e(),l={oldTab:r,oldPanel:f,newTab:u?e():s,newPanel:a};t.preventDefault();if(s.hasClass("ui-state-disabled")||s.hasClass("ui-tabs-loading")||this.running||o&&!n.collapsible||this._trigger("beforeActivate",t,l)===!1)return;n.active=u?!1:this.tabs.index(s),this.active=o?e():s,this.xhr&&this.xhr.abort(),!f.length&&!a.length&&e.error("jQuery UI Tabs: Mismatching fragment identifier."),a.length&&this.load(this.tabs.index(s),t),this._toggle(t,l)},_toggle:function(t,n){function o(){r.running=!1,r._trigger("activate",t,n)}function u(){n.newTab.closest("li").addClass("ui-tabs-active ui-state-active"),i.length&&r.options.show?r._show(i,r.options.show,o):(i.show(),o())}var r=this,i=n.newPanel,s=n.oldPanel;this.running=!0,s.length&&this.options.hide?this._hide(s,this.options.hide,function(){n.oldTab.closest("li").removeClass("ui-tabs-active ui-state-active"),u()}):(n.oldTab.closest("li").removeClass("ui-tabs-active ui-state-active"),s.hide(),u()),s.attr({"aria-expanded":"false","aria-hidden":"true"}),n.oldTab.attr("aria-selected","false"),i.length&&s.length?n.oldTab.attr("tabIndex",-1):i.length&&this.tabs.filter(function(){return e(this).attr("tabIndex")===0}).attr("tabIndex",-1),i.attr({"aria-expanded":"true","aria-hidden":"false"}),n.newTab.attr({"aria-selected":"true",tabIndex:0})},_activate:function(t){var n,r=this._findActive(t);if(r[0]===this.active[0])return;r.length||(r=this.active),n=r.find(".ui-tabs-anchor")[0],this._eventHandler({target:n,currentTarget:n,preventDefault:e.noop})},_findActive:function(t){return t===!1?e():this.tabs.eq(t)},_getIndex:function(e){return typeof e=="string"&&(e=this.anchors.index(this.anchors.filter("[href$='"+e+"']"))),e},_destroy:function(){this.xhr&&this.xhr.abort(),this.element.removeClass("ui-tabs ui-widget ui-widget-content ui-corner-all ui-tabs-collapsible"),this.tablist.removeClass("ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all").removeAttr("role"),this.anchors.removeClass("ui-tabs-anchor").removeAttr("role").removeAttr("tabIndex").removeData("href.tabs").removeData("load.tabs").removeUniqueId(),this.tabs.add(this.panels).each(function(){e.data(this,"ui-tabs-destroy")?e(this).remove():e(this).removeClass("ui-state-default ui-state-active ui-state-disabled ui-corner-top ui-corner-bottom ui-widget-content ui-tabs-active ui-tabs-panel").removeAttr("tabIndex").removeAttr("aria-live").removeAttr("aria-busy").removeAttr("aria-selected").removeAttr("aria-labelledby").removeAttr("aria-hidden").removeAttr("aria-expanded").removeAttr("role")}),this.tabs.each(function(){var t=e(this),n=t.data("ui-tabs-aria-controls");n?t.attr("aria-controls",n):t.removeAttr("aria-controls")}),this.options.heightStyle!=="content"&&this.panels.css("height","")},enable:function(n){var r=this.options.disabled;if(r===!1)return;n===t?r=!1:(n=this._getIndex(n),e.isArray(r)?r=e.map(r,function(e){return e!==n?e:null}):r=e.map(this.tabs,function(e,t){return t!==n?t:null})),this._setupDisabled(r)},disable:function(n){var r=this.options.disabled;if(r===!0)return;if(n===t)r=!0;else{n=this._getIndex(n);if(e.inArray(n,r)!==-1)return;e.isArray(r)?r=e.merge([n],r).sort():r=[n]}this._setupDisabled(r)},load:function(t,n){t=this._getIndex(t);var r=this,i=this.tabs.eq(t),o=i.find(".ui-tabs-anchor"),u=this._getPanelForTab(i),a={tab:i,panel:u};if(s(o[0]))return;this.xhr=e.ajax(this._ajaxSettings(o,n,a)),this.xhr&&this.xhr.statusText!=="canceled"&&(i.addClass("ui-tabs-loading"),u.attr("aria-busy","true"),this.xhr.success(function(e){setTimeout(function(){u.html(e),r._trigger("load",n,a)},1)}).complete(function(e,t){setTimeout(function(){t==="abort"&&r.panels.stop(!1,!0),i.removeClass("ui-tabs-loading"),u.removeAttr("aria-busy"),e===r.xhr&&delete r.xhr},1)}))},_ajaxSettings:function(t,n,r){var i=this;return{url:t.attr("href"),beforeSend:function(t,s){return i._trigger("beforeLoad",n,e.extend({jqXHR:t,ajaxSettings:s},r))}}},_getPanelForTab:function(t){var n=e(t).attr("aria-controls");return this.element.find(this._sanitizeSelector("#"+n))}}),e.uiBackCompat!==!1&&(e.ui.tabs.prototype._ui=function(e,t){return{tab:e,panel:t,index:this.anchors.index(e)}},e.widget("ui.tabs",e.ui.tabs,{url:function(e,t){this.anchors.eq(e).attr("href",t)}}),e.widget("ui.tabs",e.ui.tabs,{options:{ajaxOptions:null,cache:!1},_create:function(){this._super();var t=this;this._on({tabsbeforeload:function(n,r){if(e.data(r.tab[0],"cache.tabs")){n.preventDefault();return}r.jqXHR.success(function(){t.options.cache&&e.data(r.tab[0],"cache.tabs",!0)})}})},_ajaxSettings:function(t,n,r){var i=this.options.ajaxOptions;return e.extend({},i,{error:function(e,t,n){try{i.error(e,t,r.tab.closest("li").index(),r.tab[0])}catch(n){}}},this._superApply(arguments))},_setOption:function(e,t){e==="cache"&&t===!1&&this.anchors.removeData("cache.tabs"),this._super(e,t)},_destroy:function(){this.anchors.removeData("cache.tabs"),this._super()},url:function(e,t){this.anchors.eq(e).removeData("cache.tabs"),this._superApply(arguments)}}),e.widget("ui.tabs",e.ui.tabs,{abort:function(){this.xhr&&this.xhr.abort()}}),e.widget("ui.tabs",e.ui.tabs,{options:{spinner:"Loading…"},_create:function(){this._super(),this._on({tabsbeforeload:function(e,t){if(e.target!==this.element[0]||!this.options.spinner)return;var n=t.tab.find("span"),r=n.html();n.html(this.options.spinner),t.jqXHR.complete(function(){n.html(r)})}})}}),e.widget("ui.tabs",e.ui.tabs,{options:{enable:null,disable:null},enable:function(t){var n=this.options,r;if(t&&n.disabled===!0||e.isArray(n.disabled)&&e.inArray(t,n.disabled)!==-1)r=!0;this._superApply(arguments),r&&this._trigger("enable",null,this._ui(this.anchors[t],this.panels[t]))},disable:function(t){var n=this.options,r;if(t&&n.disabled===!1||e.isArray(n.disabled)&&e.inArray(t,n.disabled)===-1)r=!0;this._superApply(arguments),r&&this._trigger("disable",null,this._ui(this.anchors[t],this.panels[t]))}}),e.widget("ui.tabs",e.ui.tabs,{options:{add:null,remove:null,tabTemplate:"
    5. #{label}
    6. "},add:function(n,r,i){i===t&&(i=this.anchors.length);var s,o,u=this.options,a=e(u.tabTemplate.replace(/#\{href\}/g,n).replace(/#\{label\}/g,r)),f=n.indexOf("#")?this._tabId(a):n.replace("#","");return a.addClass("ui-state-default ui-corner-top").data("ui-tabs-destroy",!0),a.attr("aria-controls",f),s=i>=this.tabs.length,o=this.element.find("#"+f),o.length||(o=this._createPanel(f),s?i>0?o.insertAfter(this.panels.eq(-1)):o.appendTo(this.element):o.insertBefore(this.panels[i])),o.addClass("ui-tabs-panel ui-widget-content ui-corner-bottom").hide(),s?a.appendTo(this.tablist):a.insertBefore(this.tabs[i]),u.disabled=e.map(u.disabled,function(e){return e>=i?++e:e}),this.refresh(),this.tabs.length===1&&u.active===!1&&this.option("active",0),this._trigger("add",null,this._ui(this.anchors[i],this.panels[i])),this},remove:function(t){t=this._getIndex(t);var n=this.options,r=this.tabs.eq(t).remove(),i=this._getPanelForTab(r).remove();return r.hasClass("ui-tabs-active")&&this.anchors.length>2&&this._activate(t+(t+1=t?--e:e}),this.refresh(),this._trigger("remove",null,this._ui(r.find("a")[0],i[0])),this}}),e.widget("ui.tabs",e.ui.tabs,{length:function(){return this.anchors.length}}),e.widget("ui.tabs",e.ui.tabs,{options:{idPrefix:"ui-tabs-"},_tabId:function(t){var n=t.is("li")?t.find("a[href]"):t;return n=n[0],e(n).closest("li").attr("aria-controls")||n.title&&n.title.replace(/\s/g,"_").replace(/[^\w\u00c0-\uFFFF\-]/g,"")||this.options.idPrefix+i()}}),e.widget("ui.tabs",e.ui.tabs,{options:{panelTemplate:"
      "},_createPanel:function(t){return e(this.options.panelTemplate).attr("id",t).addClass("ui-tabs-panel ui-widget-content ui-corner-bottom").data("ui-tabs-destroy",!0)}}),e.widget("ui.tabs",e.ui.tabs,{_create:function(){var e=this.options;e.active===null&&e.selected!==t&&(e.active=e.selected===-1?!1:e.selected),this._super(),e.selected=e.active,e.selected===!1&&(e.selected=-1)},_setOption:function(e,t){if(e!=="selected")return this._super(e,t);var n=this.options;this._super("active",t===-1?!1:t),n.selected=n.active,n.selected===!1&&(n.selected=-1)},_eventHandler:function(e){this._superApply(arguments),this.options.selected=this.options.active,this.options.selected===!1&&(this.options.selected=-1)}}),e.widget("ui.tabs",e.ui.tabs,{options:{show:null,select:null},_create:function(){this._super(),this.options.active!==!1&&this._trigger("show",null,this._ui(this.active.find(".ui-tabs-anchor")[0],this._getPanelForTab(this.active)[0]))},_trigger:function(e,t,n){var r=this._superApply(arguments);return r?(e==="beforeActivate"&&n.newTab.length?r=this._super("select",t,{tab:n.newTab.find(".ui-tabs-anchor")[0],panel:n.newPanel[0],index:n.newTab.closest("li").index()}):e==="activate"&&n.newTab.length&&(r=this._super("show",t,{tab:n.newTab.find(".ui-tabs-anchor")[0],panel:n.newPanel[0],index:n.newTab.closest("li").index()})),r):!1}}),e.widget("ui.tabs",e.ui.tabs,{select:function(e){e=this._getIndex(e);if(e===-1){if(!this.options.collapsible||this.options.selected===-1)return;e=this.options.selected}this.anchors.eq(e).trigger(this.options.event+this.eventNamespace)}}),function(){var t=0;e.widget("ui.tabs",e.ui.tabs,{options:{cookie:null},_create:function(){var e=this.options,t;e.active==null&&e.cookie&&(t=parseInt(this._cookie(),10),t===-1&&(t=!1),e.active=t),this._super()},_cookie:function(n){var r=[this.cookie||(this.cookie=this.options.cookie.name||"ui-tabs-"+ ++t)];return arguments.length&&(r.push(n===!1?-1:n),r.push(this.options.cookie)),e.cookie.apply(null,r)},_refresh:function(){this._super(),this.options.cookie&&this._cookie(this.options.active,this.options.cookie)},_eventHandler:function(e){this._superApply(arguments),this.options.cookie&&this._cookie(this.options.active,this.options.cookie)},_destroy:function(){this._super(),this.options.cookie&&this._cookie(null,this.options.cookie)}})}(),e.widget("ui.tabs",e.ui.tabs,{_trigger:function(t,n,r){var i=e.extend({},r);return t==="load"&&(i.panel=i.panel[0],i.tab=i.tab.find(".ui-tabs-anchor")[0]),this._super(t,n,i)}}),e.widget("ui.tabs",e.ui.tabs,{options:{fx:null},_getFx:function(){var t,n,r=this.options.fx;return r&&(e.isArray(r)?(t=r[0],n=r[1]):t=n=r),r?{show:n,hide:t}:null},_toggle:function(e,t){function o(){n.running=!1,n._trigger("activate",e,t)}function u(){t.newTab.closest("li").addClass("ui-tabs-active ui-state-active"),r.length&&s.show?r.animate(s.show,s.show.duration,function(){o()}):(r.show(),o())}var n=this,r=t.newPanel,i=t.oldPanel,s=this._getFx();if(!s)return this._super(e,t);n.running=!0,i.length&&s.hide?i.animate(s.hide,s.hide.duration,function(){t.oldTab.closest("li").removeClass("ui-tabs-active ui-state-active"),u()}):(t.oldTab.closest("li").removeClass("ui-tabs-active ui-state-active"),i.hide(),u())}}))})(jQuery);(function(e){function n(t,n){var r=(t.attr("aria-describedby")||"").split(/\s+/);r.push(n),t.data("ui-tooltip-id",n).attr("aria-describedby",e.trim(r.join(" ")))}function r(t){var n=t.data("ui-tooltip-id"),r=(t.attr("aria-describedby")||"").split(/\s+/),i=e.inArray(n,r);i!==-1&&r.splice(i,1),t.removeData("ui-tooltip-id"),r=e.trim(r.join(" ")),r?t.attr("aria-describedby",r):t.removeAttr("aria-describedby")}var t=0;e.widget("ui.tooltip",{version:"1.9.0",options:{content:function(){return e(this).attr("title")},hide:!0,items:"[title]",position:{my:"left+15 center",at:"right center",collision:"flipfit flipfit"},show:!0,tooltipClass:null,track:!1,close:null,open:null},_create:function(){this._on({mouseover:"open",focusin:"open"}),this.tooltips={}},_setOption:function(t,n){var r=this;if(t==="disabled"){this[n?"_disable":"_enable"](),this.options[t]=n;return}this._super(t,n),t==="content"&&e.each(this.tooltips,function(e,t){r._updateContent(t)})},_disable:function(){var t=this;e.each(this.tooltips,function(n,r){var i=e.Event("blur");i.target=i.currentTarget=r[0],t.close(i,!0)}),this.element.find(this.options.items).andSelf().each(function(){var t=e(this);t.is("[title]")&&t.data("ui-tooltip-title",t.attr("title")).attr("title","")})},_enable:function(){this.element.find(this.options.items).andSelf().each(function(){var t=e(this);t.data("ui-tooltip-title")&&t.attr("title",t.data("ui-tooltip-title"))})},open:function(t){var n=e(t?t.target:this.element).closest(this.options.items);if(!n.length)return;if(this.options.track&&n.data("ui-tooltip-id")){this._find(n).position(e.extend({of:n},this.options.position)),this._off(this.document,"mousemove");return}n.attr("title")&&n.data("ui-tooltip-title",n.attr("title")),n.data("tooltip-open",!0),this._updateContent(n,t)},_updateContent:function(e,t){var n,r=this.options.content,i=this;if(typeof r=="string")return this._open(t,e,r);n=r.call(e[0],function(n){if(!e.data("tooltip-open"))return;i._delay(function(){this._open(t,e,n)})}),n&&this._open(t,e,n)},_open:function(t,r,i){function u(e){o.of=e,s.position(o)}var s,o;if(!i)return;s=this._find(r);if(s.length){s.find(".ui-tooltip-content").html(i);return}r.is("[title]")&&(t&&t.type==="mouseover"?r.attr("title",""):r.removeAttr("title")),s=this._tooltip(r),n(r,s.attr("id")),s.find(".ui-tooltip-content").html(i),this.options.track&&t&&/^mouse/.test(t.originalEvent.type)?(o=e.extend({},this.options.position),this._on(this.document,{mousemove:u}),u(t)):s.position(e.extend({of:r},this.options.position)),s.hide(),this._show(s,this.options.show),this._trigger("open",t,{tooltip:s}),this._on(r,{mouseleave:"close",focusout:"close",keyup:function(t){if(t.keyCode===e.ui.keyCode.ESCAPE){var n=e.Event(t);n.currentTarget=r[0],this.close(n,!0)}}})},close:function(t,n){var i=this,s=e(t?t.currentTarget:this.element),o=this._find(s);if(this.closing)return;if(!n&&t&&t.type!=="focusout"&&this.document[0].activeElement===s[0])return;s.data("ui-tooltip-title")&&s.attr("title",s.data("ui-tooltip-title")),r(s),o.stop(!0),this._hide(o,this.options.hide,function(){e(this).remove(),delete i.tooltips[this.id]}),s.removeData("tooltip-open"),this._off(s,"mouseleave focusout keyup"),this._off(this.document,"mousemove"),this.closing=!0,this._trigger("close",t,{tooltip:o}),this.closing=!1},_tooltip:function(n){var r="ui-tooltip-"+t++,i=e("
      ").attr({id:r,role:"tooltip"}).addClass("ui-tooltip ui-widget ui-corner-all ui-widget-content "+(this.options.tooltipClass||""));return e("
      ").addClass("ui-tooltip-content").appendTo(i),i.appendTo(this.document[0].body),e.fn.bgiframe&&i.bgiframe(),this.tooltips[r]=n,i},_find:function(t){var n=t.data("ui-tooltip-id");return n?e("#"+n):e()},_destroy:function(){var t=this;e.each(this.tooltips,function(n,r){var i=e.Event("blur");i.target=i.currentTarget=r[0],t.close(i,!0),e("#"+n).remove(),r.data("ui-tooltip-title")&&(r.attr("title",r.data("ui-tooltip-title")),r.removeData("ui-tooltip-title"))})}})})(jQuery);jQuery.effects||function(e,t){var n=e.uiBackCompat!==!1,r="ui-effects-";e.effects={effect:{}},function(t,n){function p(e,t,n){var r=a[t.type]||{};return e==null?n||!t.def?null:t.def:(e=r.floor?~~e:parseFloat(e),isNaN(e)?t.def:r.mod?(e+r.mod)%r.mod:0>e?0:r.max")[0],c,h=t.each;l.style.cssText="background-color:rgba(1,1,1,.5)",f.rgba=l.style.backgroundColor.indexOf("rgba")>-1,h(u,function(e,t){t.cache="_"+e,t.props.alpha={idx:3,type:"percent",def:1}}),o.fn=t.extend(o.prototype,{parse:function(r,i,s,a){if(r===n)return this._rgba=[null,null,null,null],this;if(r.jquery||r.nodeType)r=t(r).css(i),i=n;var f=this,l=t.type(r),v=this._rgba=[],m;i!==n&&(r=[r,i,s,a],l="array");if(l==="string")return this.parse(d(r)||c._default);if(l==="array")return h(u.rgba.props,function(e,t){v[t.idx]=p(r[t.idx],t)}),this;if(l==="object")return r instanceof o?h(u,function(e,t){r[t.cache]&&(f[t.cache]=r[t.cache].slice())}):h(u,function(t,n){var i=n.cache;h(n.props,function(e,t){if(!f[i]&&n.to){if(e==="alpha"||r[e]==null)return;f[i]=n.to(f._rgba)}f[i][t.idx]=p(r[e],t,!0)}),f[i]&&e.inArray(null,f[i].slice(0,3))<0&&(f[i][3]=1,n.from&&(f._rgba=n.from(f[i])))}),this},is:function(e){var t=o(e),n=!0,r=this;return h(u,function(e,i){var s,o=t[i.cache];return o&&(s=r[i.cache]||i.to&&i.to(r._rgba)||[],h(i.props,function(e,t){if(o[t.idx]!=null)return n=o[t.idx]===s[t.idx],n})),n}),n},_space:function(){var e=[],t=this;return h(u,function(n,r){t[r.cache]&&e.push(n)}),e.pop()},transition:function(e,t){var n=o(e),r=n._space(),i=u[r],s=this.alpha()===0?o("transparent"):this,f=s[i.cache]||i.to(s._rgba),l=f.slice();return n=n[i.cache],h(i.props,function(e,r){var i=r.idx,s=f[i],o=n[i],u=a[r.type]||{};if(o===null)return;s===null?l[i]=o:(u.mod&&(o-s>u.mod/2?s+=u.mod:s-o>u.mod/2&&(s-=u.mod)),l[i]=p((o-s)*t+s,r))}),this[r](l)},blend:function(e){if(this._rgba[3]===1)return this;var n=this._rgba.slice(),r=n.pop(),i=o(e)._rgba;return o(t.map(n,function(e,t){return(1-r)*i[t]+r*e}))},toRgbaString:function(){var e="rgba(",n=t.map(this._rgba,function(e,t){return e==null?t>2?1:0:e});return n[3]===1&&(n.pop(),e="rgb("),e+n.join()+")"},toHslaString:function(){var e="hsla(",n=t.map(this.hsla(),function(e,t){return e==null&&(e=t>2?1:0),t&&t<3&&(e=Math.round(e*100)+"%"),e});return n[3]===1&&(n.pop(),e="hsl("),e+n.join()+")"},toHexString:function(e){var n=this._rgba.slice(),r=n.pop();return e&&n.push(~~(r*255)),"#"+t.map(n,function(e,t){return e=(e||0).toString(16),e.length===1?"0"+e:e}).join("")},toString:function(){return this._rgba[3]===0?"transparent":this.toRgbaString()}}),o.fn.parse.prototype=o.fn,u.hsla.to=function(e){if(e[0]==null||e[1]==null||e[2]==null)return[null,null,null,e[3]];var t=e[0]/255,n=e[1]/255,r=e[2]/255,i=e[3],s=Math.max(t,n,r),o=Math.min(t,n,r),u=s-o,a=s+o,f=a*.5,l,c;return o===s?l=0:t===s?l=60*(n-r)/u+360:n===s?l=60*(r-t)/u+120:l=60*(t-n)/u+240,f===0||f===1?c=f:f<=.5?c=u/a:c=u/(2-a),[Math.round(l)%360,c,f,i==null?1:i]},u.hsla.from=function(e){if(e[0]==null||e[1]==null||e[2]==null)return[null,null,null,e[3]];var t=e[0]/360,n=e[1],r=e[2],i=e[3],s=r<=.5?r*(1+n):r+n-r*n,o=2*r-s,u,a,f;return[Math.round(v(o,s,t+1/3)*255),Math.round(v(o,s,t)*255),Math.round(v(o,s,t-1/3)*255),i]},h(u,function(e,r){var s=r.props,u=r.cache,a=r.to,f=r.from;o.fn[e]=function(e){a&&!this[u]&&(this[u]=a(this._rgba));if(e===n)return this[u].slice();var r,i=t.type(e),l=i==="array"||i==="object"?e:arguments,c=this[u].slice();return h(s,function(e,t){var n=l[i==="object"?e:t.idx];n==null&&(n=c[t.idx]),c[t.idx]=p(n,t)}),f?(r=o(f(c)),r[u]=c,r):o(c)},h(s,function(n,r){if(o.fn[n])return;o.fn[n]=function(s){var o=t.type(s),u=n==="alpha"?this._hsla?"hsla":"rgba":e,a=this[u](),f=a[r.idx],l;return o==="undefined"?f:(o==="function"&&(s=s.call(this,f),o=t.type(s)),s==null&&r.empty?this:(o==="string"&&(l=i.exec(s),l&&(s=f+parseFloat(l[2])*(l[1]==="+"?1:-1))),a[r.idx]=s,this[u](a)))}})}),h(r,function(e,n){t.cssHooks[n]={set:function(e,r){var i,s,u="";if(t.type(r)!=="string"||(i=d(r))){r=o(i||r);if(!f.rgba&&r._rgba[3]!==1){s=n==="backgroundColor"?e.parentNode:e;while((u===""||u==="transparent")&&s&&s.style)try{u=t.css(s,"backgroundColor"),s=s.parentNode}catch(a){}r=r.blend(u&&u!=="transparent"?u:"_default")}r=r.toRgbaString()}try{e.style[n]=r}catch(r){}}},t.fx.step[n]=function(e){e.colorInit||(e.start=o(e.elem,n),e.end=o(e.end),e.colorInit=!0),t.cssHooks[n].set(e.elem,e.start.transition(e.end,e.pos))}}),t.cssHooks.borderColor={expand:function(e){var t={};return h(["Top","Right","Bottom","Left"],function(n,r){t["border"+r+"Color"]=e}),t}},c=t.Color.names={aqua:"#00ffff",black:"#000000",blue:"#0000ff",fuchsia:"#ff00ff",gray:"#808080",green:"#008000",lime:"#00ff00",maroon:"#800000",navy:"#000080",olive:"#808000",purple:"#800080",red:"#ff0000",silver:"#c0c0c0",teal:"#008080",white:"#ffffff",yellow:"#ffff00",transparent:[null,null,null,0],_default:"#ffffff"}}(jQuery),function(){function i(){var t=this.ownerDocument.defaultView?this.ownerDocument.defaultView.getComputedStyle(this,null):this.currentStyle,n={},r,i,s;if(t&&t.length&&t[0]&&t[t[0]]){s=t.length;while(s--)r=t[s],typeof t[r]=="string"&&(n[e.camelCase(r)]=t[r])}else for(r in t)typeof t[r]=="string"&&(n[r]=t[r]);return n}function s(t,n){var i={},s,o;for(s in n)o=n[s],t[s]!==o&&!r[s]&&(e.fx.step[s]||!isNaN(parseFloat(o)))&&(i[s]=o);return i}var n=["add","remove","toggle"],r={border:1,borderBottom:1,borderColor:1,borderLeft:1,borderRight:1,borderTop:1,borderWidth:1,margin:1,padding:1};e.each(["borderLeftStyle","borderRightStyle","borderBottomStyle","borderTopStyle"],function(t,n){e.fx.step[n]=function(e){if(e.end!=="none"&&!e.setAttr||e.pos===1&&!e.setAttr)jQuery.style(e.elem,n,e.end),e.setAttr=!0}}),e.effects.animateClass=function(t,r,o,u){var a=e.speed(r,o,u);return this.queue(function(){var r=e(this),o=r.attr("class")||"",u,f=a.children?r.find("*").andSelf():r;f=f.map(function(){var t=e(this);return{el:t,start:i.call(this)}}),u=function(){e.each(n,function(e,n){t[n]&&r[n+"Class"](t[n])})},u(),f=f.map(function(){return this.end=i.call(this.el[0]),this.diff=s(this.start,this.end),this}),r.attr("class",o),f=f.map(function(){var t=this,n=e.Deferred(),r=jQuery.extend({},a,{queue:!1,complete:function(){n.resolve(t)}});return this.el.animate(this.diff,r),n.promise()}),e.when.apply(e,f.get()).done(function(){u(),e.each(arguments,function(){var t=this.el;e.each(this.diff,function(e){t.css(e,"")})}),a.complete.call(r[0])})})},e.fn.extend({_addClass:e.fn.addClass,addClass:function(t,n,r,i){return n?e.effects.animateClass.call(this,{add:t},n,r,i):this._addClass(t)},_removeClass:e.fn.removeClass,removeClass:function(t,n,r,i){return n?e.effects.animateClass.call(this,{remove:t},n,r,i):this._removeClass(t)},_toggleClass:e.fn.toggleClass,toggleClass:function(n,r,i,s,o){return typeof r=="boolean"||r===t?i?e.effects.animateClass.call(this,r?{add:n}:{remove:n},i,s,o):this._toggleClass(n,r):e.effects.animateClass.call(this,{toggle:n},r,i,s)},switchClass:function(t,n,r,i,s){return e.effects.animateClass.call(this,{add:n,remove:t},r,i,s)}})}(),function(){function i(n,r,i,s){e.isPlainObject(n)&&(r=n,n=n.effect),n={effect:n},r===t&&(r={}),e.isFunction(r)&&(s=r,i=null,r={});if(typeof r=="number"||e.fx.speeds[r])s=i,i=r,r={};return e.isFunction(i)&&(s=i,i=null),r&&e.extend(n,r),i=i||r.duration,n.duration=e.fx.off?0:typeof i=="number"?i:i in e.fx.speeds?e.fx.speeds[i]:e.fx.speeds._default,n.complete=s||r.complete,n}function s(t){return!t||typeof t=="number"||e.fx.speeds[t]?!0:typeof t=="string"&&!e.effects.effect[t]?n&&e.effects[t]?!1:!0:!1}e.extend(e.effects,{version:"1.9.0",save:function(e,t){for(var n=0;n
      ").addClass("ui-effects-wrapper").css({fontSize:"100%",background:"transparent",border:"none",margin:0,padding:0}),i={width:t.width(),height:t.height()},s=document.activeElement;try{s.id}catch(o){s=document.body}return t.wrap(r),(t[0]===s||e.contains(t[0],s))&&e(s).focus(),r=t.parent(),t.css("position")==="static"?(r.css({position:"relative"}),t.css({position:"relative"})):(e.extend(n,{position:t.css("position"),zIndex:t.css("z-index")}),e.each(["top","left","bottom","right"],function(e,r){n[r]=t.css(r),isNaN(parseInt(n[r],10))&&(n[r]="auto")}),t.css({position:"relative",top:0,left:0,right:"auto",bottom:"auto"})),t.css(i),r.css(n).show()},removeWrapper:function(t){var n=document.activeElement;return t.parent().is(".ui-effects-wrapper")&&(t.parent().replaceWith(t),(t[0]===n||e.contains(t[0],n))&&e(n).focus()),t},setTransition:function(t,n,r,i){return i=i||{},e.each(n,function(e,n){var s=t.cssUnit(n);s[0]>0&&(i[n]=s[0]*r+s[1])}),i}}),e.fn.extend({effect:function(t,r,s,o){function h(t){function s(){e.isFunction(r)&&r.call(n[0]),e.isFunction(t)&&t()}var n=e(this),r=u.complete,i=u.mode;(n.is(":hidden")?i==="hide":i==="show")?s():l.call(n[0],u,s)}var u=i.apply(this,arguments),a=u.mode,f=u.queue,l=e.effects.effect[u.effect],c=!l&&n&&e.effects[u.effect];return e.fx.off||!l&&!c?a?this[a](u.duration,u.complete):this.each(function(){u.complete&&u.complete.call(this)}):l?f===!1?this.each(h):this.queue(f||"fx",h):c.call(this,{options:u,duration:u.duration,callback:u.complete,mode:u.mode})},_show:e.fn.show,show:function(e){if(s(e))return this._show.apply(this,arguments);var t=i.apply(this,arguments);return t.mode="show",this.effect.call(this,t)},_hide:e.fn.hide,hide:function(e){if(s(e))return this._hide.apply(this,arguments);var t=i.apply(this,arguments);return t.mode="hide",this.effect.call(this,t)},__toggle:e.fn.toggle,toggle:function(t){if(s(t)||typeof t=="boolean"||e.isFunction(t))return this.__toggle.apply(this,arguments);var n=i.apply(this,arguments);return n.mode="toggle",this.effect.call(this,n)},cssUnit:function(t){var n=this.css(t),r=[];return e.each(["em","px","%","pt"],function(e,t){n.indexOf(t)>0&&(r=[parseFloat(n),t])}),r}})}(),function(){var t={};e.each(["Quad","Cubic","Quart","Quint","Expo"],function(e,n){t[n]=function(t){return Math.pow(t,e+2)}}),e.extend(t,{Sine:function(e){return 1-Math.cos(e*Math.PI/2)},Circ:function(e){return 1-Math.sqrt(1-e*e)},Elastic:function(e){return e===0||e===1?e:-Math.pow(2,8*(e-1))*Math.sin(((e-1)*80-7.5)*Math.PI/15)},Back:function(e){return e*e*(3*e-2)},Bounce:function(e){var t,n=4;while(e<((t=Math.pow(2,--n))-1)/11);return 1/Math.pow(4,3-n)-7.5625*Math.pow((t*3-2)/22-e,2)}}),e.each(t,function(t,n){e.easing["easeIn"+t]=n,e.easing["easeOut"+t]=function(e){return 1-n(1-e)},e.easing["easeInOut"+t]=function(e){return e<.5?n(e*2)/2:1-n(e*-2+2)/2}})}()}(jQuery);(function(e,t){var n=/up|down|vertical/,r=/up|left|vertical|horizontal/;e.effects.effect.blind=function(t,i){var s=e(this),o=["position","top","bottom","left","right","height","width"],u=e.effects.setMode(s,t.mode||"hide"),a=t.direction||"up",f=n.test(a),l=f?"height":"width",c=f?"top":"left",h=r.test(a),p={},d=u==="show",v,m,g;s.parent().is(".ui-effects-wrapper")?e.effects.save(s.parent(),o):e.effects.save(s,o),s.show(),v=e.effects.createWrapper(s).css({overflow:"hidden"}),m=v[l](),g=parseFloat(v.css(c))||0,p[l]=d?m:0,h||(s.css(f?"bottom":"right",0).css(f?"top":"left","auto").css({position:"absolute"}),p[c]=d?g:m+g),d&&(v.css(l,0),h||v.css(c,g+m)),v.animate(p,{duration:t.duration,easing:t.easing,queue:!1,complete:function(){u==="hide"&&s.hide(),e.effects.restore(s,o),e.effects.removeWrapper(s),i()}})}})(jQuery);(function(e,t){e.effects.effect.bounce=function(t,n){var r=e(this),i=["position","top","bottom","left","right","height","width"],s=e.effects.setMode(r,t.mode||"effect"),o=s==="hide",u=s==="show",a=t.direction||"up",f=t.distance,l=t.times||5,c=l*2+(u||o?1:0),h=t.duration/c,p=t.easing,d=a==="up"||a==="down"?"top":"left",v=a==="up"||a==="left",m,g,y,b=r.queue(),w=b.length;(u||o)&&i.push("opacity"),e.effects.save(r,i),r.show(),e.effects.createWrapper(r),f||(f=r[d==="top"?"outerHeight":"outerWidth"]()/3),u&&(y={opacity:1},y[d]=0,r.css("opacity",0).css(d,v?-f*2:f*2).animate(y,h,p)),o&&(f/=Math.pow(2,l-1)),y={},y[d]=0;for(m=0;m1&&b.splice.apply(b,[1,0].concat(b.splice(w,c+1))),r.dequeue()}})(jQuery);(function(e,t){e.effects.effect.clip=function(t,n){var r=e(this),i=["position","top","bottom","left","right","height","width"],s=e.effects.setMode(r,t.mode||"hide"),o=s==="show",u=t.direction||"vertical",a=u==="vertical",f=a?"height":"width",l=a?"top":"left",c={},h,p,d;e.effects.save(r,i),r.show(),h=e.effects.createWrapper(r).css({overflow:"hidden"}),p=r[0].tagName==="IMG"?h:r,d=p[f](),o&&(p.css(f,0),p.css(l,d/2)),c[f]=o?d:0,c[l]=o?0:d/2,p.animate(c,{queue:!1,duration:t.duration,easing:t.easing,complete:function(){o||r.hide(),e.effects.restore(r,i),e.effects.removeWrapper(r),n()}})}})(jQuery);(function(e,t){e.effects.effect.drop=function(t,n){var r=e(this),i=["position","top","bottom","left","right","opacity","height","width"],s=e.effects.setMode(r,t.mode||"hide"),o=s==="show",u=t.direction||"left",a=u==="up"||u==="down"?"top":"left",f=u==="up"||u==="left"?"pos":"neg",l={opacity:o?1:0},c;e.effects.save(r,i),r.show(),e.effects.createWrapper(r),c=t.distance||r[a==="top"?"outerHeight":"outerWidth"](!0)/2,o&&r.css("opacity",0).css(a,f==="pos"?-c:c),l[a]=(o?f==="pos"?"+=":"-=":f==="pos"?"-=":"+=")+c,r.animate(l,{queue:!1,duration:t.duration,easing:t.easing,complete:function(){s==="hide"&&r.hide(),e.effects.restore(r,i),e.effects.removeWrapper(r),n()}})}})(jQuery);(function(e,t){e.effects.effect.explode=function(t,n){function y(){c.push(this),c.length===r*i&&b()}function b(){s.css({visibility:"visible"}),e(c).remove(),u||s.hide(),n()}var r=t.pieces?Math.round(Math.sqrt(t.pieces)):3,i=r,s=e(this),o=e.effects.setMode(s,t.mode||"hide"),u=o==="show",a=s.show().css("visibility","hidden").offset(),f=Math.ceil(s.outerWidth()/i),l=Math.ceil(s.outerHeight()/r),c=[],h,p,d,v,m,g;for(h=0;h
      ").css({position:"absolute",visibility:"visible",left:-p*f,top:-h*l}).parent().addClass("ui-effects-explode").css({position:"absolute",overflow:"hidden",width:f,height:l,left:d+(u?m*f:0),top:v+(u?g*l:0),opacity:u?0:1}).animate({left:d+(u?0:m*f),top:v+(u?0:g*l),opacity:u?1:0},t.duration||500,t.easing,y)}}})(jQuery);(function(e,t){e.effects.effect.fade=function(t,n){var r=e(this),i=e.effects.setMode(r,t.mode||"toggle");r.animate({opacity:i},{queue:!1,duration:t.duration,easing:t.easing,complete:n})}})(jQuery);(function(e,t){e.effects.effect.fold=function(t,n){var r=e(this),i=["position","top","bottom","left","right","height","width"],s=e.effects.setMode(r,t.mode||"hide"),o=s==="show",u=s==="hide",a=t.size||15,f=/([0-9]+)%/.exec(a),l=!!t.horizFirst,c=o!==l,h=c?["width","height"]:["height","width"],p=t.duration/2,d,v,m={},g={};e.effects.save(r,i),r.show(),d=e.effects.createWrapper(r).css({overflow:"hidden"}),v=c?[d.width(),d.height()]:[d.height(),d.width()],f&&(a=parseInt(f[1],10)/100*v[u?0:1]),o&&d.css(l?{height:0,width:a}:{height:a,width:0}),m[h[0]]=o?v[0]:a,g[h[1]]=o?v[1]:0,d.animate(m,p,t.easing).animate(g,p,t.easing,function(){u&&r.hide(),e.effects.restore(r,i),e.effects.removeWrapper(r),n()})}})(jQuery);(function(e,t){e.effects.effect.highlight=function(t,n){var r=e(this),i=["backgroundImage","backgroundColor","opacity"],s=e.effects.setMode(r,t.mode||"show"),o={backgroundColor:r.css("backgroundColor")};s==="hide"&&(o.opacity=0),e.effects.save(r,i),r.show().css({backgroundImage:"none",backgroundColor:t.color||"#ffff99"}).animate(o,{queue:!1,duration:t.duration,easing:t.easing,complete:function(){s==="hide"&&r.hide(),e.effects.restore(r,i),n()}})}})(jQuery);(function(e,t){e.effects.effect.pulsate=function(t,n){var r=e(this),i=e.effects.setMode(r,t.mode||"show"),s=i==="show",o=i==="hide",u=s||i==="hide",a=(t.times||5)*2+(u?1:0),f=t.duration/a,l=0,c=r.queue(),h=c.length,p;if(s||!r.is(":visible"))r.css("opacity",0).show(),l=1;for(p=1;p1&&c.splice.apply(c,[1,0].concat(c.splice(h,a+1))),r.dequeue()}})(jQuery);(function(e,t){e.effects.effect.puff=function(t,n){var r=e(this),i=e.effects.setMode(r,t.mode||"hide"),s=i==="hide",o=parseInt(t.percent,10)||150,u=o/100,a={height:r.height(),width:r.width()};e.extend(t,{effect:"scale",queue:!1,fade:!0,mode:i,complete:n,percent:s?o:100,from:s?a:{height:a.height*u,width:a.width*u}}),r.effect(t)},e.effects.effect.scale=function(t,n){var r=e(this),i=e.extend(!0,{},t),s=e.effects.setMode(r,t.mode||"effect"),o=parseInt(t.percent,10)||(parseInt(t.percent,10)===0?0:s==="hide"?0:100),u=t.direction||"both",a=t.origin,f={height:r.height(),width:r.width(),outerHeight:r.outerHeight(),outerWidth:r.outerWidth()},l={y:u!=="horizontal"?o/100:1,x:u!=="vertical"?o/100:1};i.effect="size",i.queue=!1,i.complete=n,s!=="effect"&&(i.origin=a||["middle","center"],i.restore=!0),i.from=t.from||(s==="show"?{height:0,width:0}:f),i.to={height:f.height*l.y,width:f.width*l.x,outerHeight:f.outerHeight*l.y,outerWidth:f.outerWidth*l.x},i.fade&&(s==="show"&&(i.from.opacity=0,i.to.opacity=1),s==="hide"&&(i.from.opacity=1,i.to.opacity=0)),r.effect(i)},e.effects.effect.size=function(t,n){var r=e(this),i=["position","top","bottom","left","right","width","height","overflow","opacity"],s=["position","top","bottom","left","right","overflow","opacity"],o=["width","height","overflow"],u=["fontSize"],a=["borderTopWidth","borderBottomWidth","paddingTop","paddingBottom"],f=["borderLeftWidth","borderRightWidth","paddingLeft","paddingRight"],l=e.effects.setMode(r,t.mode||"effect"),c=t.restore||l!=="effect",h=t.scale||"both",p=t.origin||["middle","center"],d,v,m,g=r.css("position");l==="show"&&r.show(),d={height:r.height(),width:r.width(),outerHeight:r.outerHeight(),outerWidth:r.outerWidth()},r.from=t.from||d,r.to=t.to||d,m={from:{y:r.from.height/d.height,x:r.from.width/d.width},to:{y:r.to.height/d.height,x:r.to.width/d.width}};if(h==="box"||h==="both")m.from.y!==m.to.y&&(i=i.concat(a),r.from=e.effects.setTransition(r,a,m.from.y,r.from),r.to=e.effects.setTransition(r,a,m.to.y,r.to)),m.from.x!==m.to.x&&(i=i.concat(f),r.from=e.effects.setTransition(r,f,m.from.x,r.from),r.to=e.effects.setTransition(r,f,m.to.x,r.to));(h==="content"||h==="both")&&m.from.y!==m.to.y&&(i=i.concat(u),r.from=e.effects.setTransition(r,u,m.from.y,r.from),r.to=e.effects.setTransition(r,u,m.to.y,r.to)),e.effects.save(r,c?i:s),r.show(),e.effects.createWrapper(r),r.css("overflow","hidden").css(r.from),p&&(v=e.effects.getBaseline(p,d),r.from.top=(d.outerHeight-r.outerHeight())*v.y,r.from.left=(d.outerWidth-r.outerWidth())*v.x,r.to.top=(d.outerHeight-r.to.outerHeight)*v.y,r.to.left=(d.outerWidth-r.to.outerWidth)*v.x),r.css(r.from);if(h==="content"||h==="both")a=a.concat(["marginTop","marginBottom"]).concat(u),f=f.concat(["marginLeft","marginRight"]),o=i.concat(a).concat(f),r.find("*[width]").each(function(){var n=e(this),r={height:n.height(),width:n.width()};c&&e.effects.save(n,o),n.from={height:r.height*m.from.y,width:r.width*m.from.x},n.to={height:r.height*m.to.y,width:r.width*m.to.x},m.from.y!==m.to.y&&(n.from=e.effects.setTransition(n,a,m.from.y,n.from),n.to=e.effects.setTransition(n,a,m.to.y,n.to)),m.from.x!==m.to.x&&(n.from=e.effects.setTransition(n,f,m.from.x,n.from),n.to=e.effects.setTransition(n,f,m.to.x,n.to)),n.css(n.from),n.animate(n.to,t.duration,t.easing,function(){c&&e.effects.restore(n,o)})});r.animate(r.to,{queue:!1,duration:t.duration,easing:t.easing,complete:function(){r.to.opacity===0&&r.css("opacity",r.from.opacity),l==="hide"&&r.hide(),e.effects.restore(r,c?i:s),c||(g==="static"?r.css({position:"relative",top:r.to.top,left:r.to.left}):e.each(["top","left"],function(e,t){r.css(t,function(t,n){var i=parseInt(n,10),s=e?r.to.left:r.to.top;return n==="auto"?s+"px":i+s+"px"})})),e.effects.removeWrapper(r),n()}})}})(jQuery);(function(e,t){e.effects.effect.shake=function(t,n){var r=e(this),i=["position","top","bottom","left","right","height","width"],s=e.effects.setMode(r,t.mode||"effect"),o=t.direction||"left",u=t.distance||20,a=t.times||3,f=a*2+1,l=Math.round(t.duration/f),c=o==="up"||o==="down"?"top":"left",h=o==="up"||o==="left",p={},d={},v={},m,g=r.queue(),y=g.length;e.effects.save(r,i),r.show(),e.effects.createWrapper(r),p[c]=(h?"-=":"+=")+u,d[c]=(h?"+=":"-=")+u*2,v[c]=(h?"-=":"+=")+u*2,r.animate(p,l,t.easing);for(m=1;m1&&g.splice.apply(g,[1,0].concat(g.splice(y,f+1))),r.dequeue()}})(jQuery);(function(e,t){e.effects.effect.slide=function(t,n){var r=e(this),i=["position","top","bottom","left","right","width","height"],s=e.effects.setMode(r,t.mode||"show"),o=s==="show",u=t.direction||"left",a=u==="up"||u==="down"?"top":"left",f=u==="up"||u==="left",l,c={};e.effects.save(r,i),r.show(),l=t.distance||r[a==="top"?"outerHeight":"outerWidth"](!0),e.effects.createWrapper(r).css({overflow:"hidden"}),o&&r.css(a,f?isNaN(l)?"-"+l:-l:l),c[a]=(o?f?"+=":"-=":f?"-=":"+=")+l,r.animate(c,{queue:!1,duration:t.duration,easing:t.easing,complete:function(){s==="hide"&&r.hide(),e.effects.restore(r,i),e.effects.removeWrapper(r),n()}})}})(jQuery);(function(e,t){e.effects.effect.transfer=function(t,n){var r=e(this),i=e(t.to),s=i.css("position")==="fixed",o=e("body"),u=s?o.scrollTop():0,a=s?o.scrollLeft():0,f=i.offset(),l={top:f.top-u,left:f.left-a,height:i.innerHeight(),width:i.innerWidth()},c=r.offset(),h=e('
      ').appendTo(document.body).addClass(t.className).css({top:c.top-u,left:c.left-a,height:r.innerHeight(),width:r.innerWidth(),position:s?"fixed":"absolute"}).animate(l,t.duration,t.easing,function(){h.remove(),n()})}})(jQuery); \ No newline at end of file diff --git a/htdocs/js/lib/vendor/BlobBuilder.js b/htdocs/js/lib/vendor/BlobBuilder.js new file mode 100644 index 000000000..8f8e27050 --- /dev/null +++ b/htdocs/js/lib/vendor/BlobBuilder.js @@ -0,0 +1,161 @@ +/* BlobBuilder.js + * A BlobBuilder implementation. + * 2012-04-21 + * + * By Eli Grey, http://eligrey.com + * License: X11/MIT + * See LICENSE.md + */ + +/*global self, unescape */ +/*jslint bitwise: true, regexp: true, confusion: true, es5: true, vars: true, white: true, + plusplus: true */ + +/*! @source http://purl.eligrey.com/github/BlobBuilder.js/blob/master/BlobBuilder.js */ + +var BlobBuilder = BlobBuilder || self.WebKitBlobBuilder || self.MozBlobBuilder || self.MSBlobBuilder || (function(view) { +"use strict"; +var + get_class = function(object) { + return Object.prototype.toString.call(object).match(/^\[object\s(.*)\]$/)[1]; + } + , FakeBlobBuilder = function(){ + this.data = []; + } + , FakeBlob = function(data, type, encoding) { + this.data = data; + this.size = data.length; + this.type = type; + this.encoding = encoding; + } + , FBB_proto = FakeBlobBuilder.prototype + , FB_proto = FakeBlob.prototype + , FileReaderSync = view.FileReaderSync + , FileException = function(type) { + this.code = this[this.name = type]; + } + , file_ex_codes = ( + "NOT_FOUND_ERR SECURITY_ERR ABORT_ERR NOT_READABLE_ERR ENCODING_ERR " + + "NO_MODIFICATION_ALLOWED_ERR INVALID_STATE_ERR SYNTAX_ERR" + ).split(" ") + , file_ex_code = file_ex_codes.length + , realURL = view.URL || view.webkitURL || view + , real_create_object_URL = realURL.createObjectURL + , real_revoke_object_URL = realURL.revokeObjectURL + , URL = realURL + , btoa = view.btoa + , atob = view.atob + , can_apply_typed_arrays = false + , can_apply_typed_arrays_test = function(pass) { + can_apply_typed_arrays = !pass; + } + + , ArrayBuffer = view.ArrayBuffer + , Uint8Array = view.Uint8Array +; +FakeBlobBuilder.fake = FB_proto.fake = true; +while (file_ex_code--) { + FileException.prototype[file_ex_codes[file_ex_code]] = file_ex_code + 1; +} +try { + if (Uint8Array) { + can_apply_typed_arrays_test.apply(0, new Uint8Array(1)); + } +} catch (ex) {} +if (!realURL.createObjectURL) { + URL = view.URL = {}; +} +URL.createObjectURL = function(blob) { + var + type = blob.type + , data_URI_header + ; + if (type === null) { + type = "application/octet-stream"; + } + if (blob instanceof FakeBlob) { + data_URI_header = "data:" + type; + if (blob.encoding === "base64") { + return data_URI_header + ";base64," + blob.data; + } else if (blob.encoding === "URI") { + return data_URI_header + "," + decodeURIComponent(blob.data); + } if (btoa) { + return data_URI_header + ";base64," + btoa(blob.data); + } else { + return data_URI_header + "," + encodeURIComponent(blob.data); + } + } else if (real_create_object_url) { + return real_create_object_url.call(realURL, blob); + } +}; +URL.revokeObjectURL = function(object_url) { + if (object_url.substring(0, 5) !== "data:" && real_revoke_object_url) { + real_revoke_object_url.call(realURL, object_url); + } +}; +FBB_proto.append = function(data/*, endings*/) { + var bb = this.data; + // decode data to a binary string + if (Uint8Array && data instanceof ArrayBuffer) { + if (can_apply_typed_arrays) { + bb.push(String.fromCharCode.apply(String, new Uint8Array(data))); + } else { + var + str = "" + , buf = new Uint8Array(data) + , i = 0 + , buf_len = buf.length + ; + for (; i < buf_len; i++) { + str += String.fromCharCode(buf[i]); + } + } + } else if (get_class(data) === "Blob" || get_class(data) === "File") { + if (FileReaderSync) { + var fr = new FileReaderSync; + bb.push(fr.readAsBinaryString(data)); + } else { + // async FileReader won't work as BlobBuilder is sync + throw new FileException("NOT_READABLE_ERR"); + } + } else if (data instanceof FakeBlob) { + if (data.encoding === "base64" && atob) { + bb.push(atob(data.data)); + } else if (data.encoding === "URI") { + bb.push(decodeURIComponent(data.data)); + } else if (data.encoding === "raw") { + bb.push(data.data); + } + } else { + if (typeof data !== "string") { + data += ""; // convert unsupported types to strings + } + // decode UTF-16 to binary string + bb.push(unescape(encodeURIComponent(data))); + } +}; +FBB_proto.getBlob = function(type) { + if (!arguments.length) { + type = null; + } + return new FakeBlob(this.data.join(""), type, "raw"); +}; +FBB_proto.toString = function() { + return "[object BlobBuilder]"; +}; +FB_proto.slice = function(start, end, type) { + var args = arguments.length; + if (args < 3) { + type = null; + } + return new FakeBlob( + this.data.slice(start, args > 1 ? end : this.data.length) + , type + , this.encoding + ); +}; +FB_proto.toString = function() { + return "[object Blob]"; +}; +return FakeBlobBuilder; +}(self)); \ No newline at end of file diff --git a/htdocs/js/lib/vendor/FileSaver.js b/htdocs/js/lib/vendor/FileSaver.js new file mode 100644 index 000000000..445c0ae39 --- /dev/null +++ b/htdocs/js/lib/vendor/FileSaver.js @@ -0,0 +1,213 @@ +/* FileSaver.js + * A saveAs() FileSaver implementation. + * 2011-08-02 + * + * By Eli Grey, http://eligrey.com + * License: X11/MIT + * See LICENSE.md + */ + +/*global self */ +/*jslint bitwise: true, regexp: true, confusion: true, es5: true, vars: true, white: true, + plusplus: true */ + +/*! @source http://purl.eligrey.com/github/FileSaver.js/blob/master/FileSaver.js */ + +var saveAs = saveAs || (function(view) { + "use strict"; + var + doc = view.document + // only get URL when necessary in case BlobBuilder.js hasn't overridden it yet + , get_URL = function() { + return view.URL || view.webkitURL || view; + } + , URL = view.URL || view.webkitURL || view + , save_link = doc.createElementNS("http://www.w3.org/1999/xhtml", "a") + , can_use_save_link = "download" in save_link + , click = function(node) { + var event = doc.createEvent("MouseEvents"); + event.initMouseEvent( + "click", true, false, view, 0, 0, 0, 0, 0 + , false, false, false, false, 0, null + ); + return node.dispatchEvent(event); // false if event was cancelled + } + , webkit_req_fs = view.webkitRequestFileSystem + , req_fs = view.requestFileSystem || webkit_req_fs || view.mozRequestFileSystem + , throw_outside = function (ex) { + (view.setImmediate || view.setTimeout)(function() { + throw ex; + }, 0); + } + , force_saveable_type = "application/octet-stream" + , fs_min_size = 0 + , deletion_queue = [] + , process_deletion_queue = function() { + var i = deletion_queue.length; + while (i--) { + var file = deletion_queue[i]; + if (typeof file === "string") { // file is an object URL + URL.revokeObjectURL(file); + } else { // file is a File + file.remove(); + } + } + deletion_queue.length = 0; // clear queue + } + , dispatch = function(filesaver, event_types, event) { + event_types = [].concat(event_types); + var i = event_types.length; + while (i--) { + var listener = filesaver["on" + event_types[i]]; + if (typeof listener === "function") { + try { + listener.call(filesaver, event || filesaver); + } catch (ex) { + throw_outside(ex); + } + } + } + } + , FileSaver = function(blob, name) { + // First try a.download, then web filesystem, then object URLs + var + filesaver = this + , type = blob.type + , blob_changed = false + , object_url + , target_view + , get_object_url = function() { + var object_url = get_URL().createObjectURL(blob); + deletion_queue.push(object_url); + return object_url; + } + , dispatch_all = function() { + dispatch(filesaver, "writestart progress write writeend".split(" ")); + } + // on any filesys errors revert to saving with object URLs + , fs_error = function() { + // don't create more object URLs than needed + if (blob_changed || !object_url) { + object_url = get_object_url(blob); + } + target_view.location.href = object_url; + filesaver.readyState = filesaver.DONE; + dispatch_all(); + } + , abortable = function(func) { + return function() { + if (filesaver.readyState !== filesaver.DONE) { + return func.apply(this, arguments); + } + }; + } + , create_if_not_found = {create: true, exclusive: false} + , slice + ; + filesaver.readyState = filesaver.INIT; + if (!name) { + name = "download"; + } + if (can_use_save_link) { + object_url = get_object_url(blob); + save_link.href = object_url; + save_link.download = name; + if (click(save_link)) { + filesaver.readyState = filesaver.DONE; + dispatch_all(); + return; + } + } + // Object and web filesystem URLs have a problem saving in Google Chrome when + // viewed in a tab, so I force save with application/octet-stream + // http://code.google.com/p/chromium/issues/detail?id=91158 + if (view.chrome && type && type !== force_saveable_type) { + slice = blob.slice || blob.webkitSlice; + blob = slice.call(blob, 0, blob.size, force_saveable_type); + blob_changed = true; + } + // Since I can't be sure that the guessed media type will trigger a download + // in WebKit, I append .download to the filename. + // https://bugs.webkit.org/show_bug.cgi?id=65440 + if (webkit_req_fs && name !== "download") { + name += ".download"; + } + if (type === force_saveable_type || webkit_req_fs) { + target_view = view; + } else { + target_view = view.open(); + } + if (!req_fs) { + fs_error(); + return; + } + fs_min_size += blob.size; + req_fs(view.TEMPORARY, fs_min_size, abortable(function(fs) { + fs.root.getDirectory("saved", create_if_not_found, abortable(function(dir) { + var save = function() { + dir.getFile(name, create_if_not_found, abortable(function(file) { + file.createWriter(abortable(function(writer) { + writer.onwriteend = function(event) { + target_view.location.href = file.toURL(); + deletion_queue.push(file); + filesaver.readyState = filesaver.DONE; + dispatch(filesaver, "writeend", event); + }; + writer.onerror = function() { + var error = writer.error; + if (error.code !== error.ABORT_ERR) { + fs_error(); + } + }; + "writestart progress write abort".split(" ").forEach(function(event) { + writer["on" + event] = filesaver["on" + event]; + }); + writer.write(blob); + filesaver.abort = function() { + writer.abort(); + filesaver.readyState = filesaver.DONE; + }; + filesaver.readyState = filesaver.WRITING; + }), fs_error); + }), fs_error); + }; + dir.getFile(name, {create: false}, abortable(function(file) { + // delete file if it already exists + file.remove(); + save(); + }), abortable(function(ex) { + if (ex.code === ex.NOT_FOUND_ERR) { + save(); + } else { + fs_error(); + } + })); + }), fs_error); + }), fs_error); + } + , FS_proto = FileSaver.prototype + , saveAs = function(blob, name) { + return new FileSaver(blob, name); + } + ; + FS_proto.abort = function() { + var filesaver = this; + filesaver.readyState = filesaver.DONE; + dispatch(filesaver, "abort"); + }; + FS_proto.readyState = FS_proto.INIT = 0; + FS_proto.WRITING = 1; + FS_proto.DONE = 2; + + FS_proto.error = + FS_proto.onwritestart = + FS_proto.onprogress = + FS_proto.onwrite = + FS_proto.onabort = + FS_proto.onerror = + FS_proto.onwriteend = + null; + + view.addEventListener("unload", process_deletion_queue, false); + return saveAs; +}(self)); \ No newline at end of file diff --git a/htdocs/js/lib/vendor/backbone-0.9.9.js b/htdocs/js/lib/vendor/backbone-0.9.9.js new file mode 100644 index 000000000..90e18d4ac --- /dev/null +++ b/htdocs/js/lib/vendor/backbone-0.9.9.js @@ -0,0 +1,1533 @@ +// Backbone.js 0.9.9 + +// (c) 2010-2012 Jeremy Ashkenas, DocumentCloud Inc. +// Backbone may be freely distributed under the MIT license. +// For all details and documentation: +// http://backbonejs.org + +(function(){ + + // Initial Setup + // ------------- + + // Save a reference to the global object (`window` in the browser, `exports` + // on the server). + var root = this; + + // Save the previous value of the `Backbone` variable, so that it can be + // restored later on, if `noConflict` is used. + var previousBackbone = root.Backbone; + + // Create a local reference to array methods. + var array = []; + var push = array.push; + var slice = array.slice; + var splice = array.splice; + + // The top-level namespace. All public Backbone classes and modules will + // be attached to this. Exported for both CommonJS and the browser. + var Backbone; + if (typeof exports !== 'undefined') { + Backbone = exports; + } else { + Backbone = root.Backbone = {}; + } + + // Current version of the library. Keep in sync with `package.json`. + Backbone.VERSION = '0.9.9'; + + // Require Underscore, if we're on the server, and it's not already present. + var _ = root._; + if (!_ && (typeof require !== 'undefined')) _ = require('underscore'); + + // For Backbone's purposes, jQuery, Zepto, or Ender owns the `$` variable. + Backbone.$ = root.jQuery || root.Zepto || root.ender; + + // Runs Backbone.js in *noConflict* mode, returning the `Backbone` variable + // to its previous owner. Returns a reference to this Backbone object. + Backbone.noConflict = function() { + root.Backbone = previousBackbone; + return this; + }; + + // Turn on `emulateHTTP` to support legacy HTTP servers. Setting this option + // will fake `"PUT"` and `"DELETE"` requests via the `_method` parameter and + // set a `X-Http-Method-Override` header. + Backbone.emulateHTTP = false; + + // Turn on `emulateJSON` to support legacy servers that can't deal with direct + // `application/json` requests ... will encode the body as + // `application/x-www-form-urlencoded` instead and will send the model in a + // form param named `model`. + Backbone.emulateJSON = false; + + // Backbone.Events + // --------------- + + // Regular expression used to split event strings. + var eventSplitter = /\s+/; + + // Implement fancy features of the Events API such as multiple event + // names `"change blur"` and jQuery-style event maps `{change: action}` + // in terms of the existing API. + var eventsApi = function(obj, action, name, rest) { + if (!name) return true; + if (typeof name === 'object') { + for (var key in name) { + obj[action].apply(obj, [key, name[key]].concat(rest)); + } + } else if (eventSplitter.test(name)) { + var names = name.split(eventSplitter); + for (var i = 0, l = names.length; i < l; i++) { + obj[action].apply(obj, [names[i]].concat(rest)); + } + } else { + return true; + } + }; + + // Optimized internal dispatch function for triggering events. Tries to + // keep the usual cases speedy (most Backbone events have 3 arguments). + var triggerEvents = function(obj, events, args) { + var ev, i = -1, l = events.length; + switch (args.length) { + case 0: while (++i < l) (ev = events[i]).callback.call(ev.ctx); + return; + case 1: while (++i < l) (ev = events[i]).callback.call(ev.ctx, args[0]); + return; + case 2: while (++i < l) (ev = events[i]).callback.call(ev.ctx, args[0], args[1]); + return; + case 3: while (++i < l) (ev = events[i]).callback.call(ev.ctx, args[0], args[1], args[2]); + return; + default: while (++i < l) (ev = events[i]).callback.apply(ev.ctx, args); + } + }; + + // A module that can be mixed in to *any object* in order to provide it with + // custom events. You may bind with `on` or remove with `off` callback + // functions to an event; `trigger`-ing an event fires all callbacks in + // succession. + // + // var object = {}; + // _.extend(object, Backbone.Events); + // object.on('expand', function(){ alert('expanded'); }); + // object.trigger('expand'); + // + var Events = Backbone.Events = { + + // Bind one or more space separated events, or an events map, + // to a `callback` function. Passing `"all"` will bind the callback to + // all events fired. + on: function(name, callback, context) { + if (!(eventsApi(this, 'on', name, [callback, context]) && callback)) return this; + this._events || (this._events = {}); + var list = this._events[name] || (this._events[name] = []); + list.push({callback: callback, context: context, ctx: context || this}); + return this; + }, + + // Bind events to only be triggered a single time. After the first time + // the callback is invoked, it will be removed. + once: function(name, callback, context) { + if (!(eventsApi(this, 'once', name, [callback, context]) && callback)) return this; + var self = this; + var once = _.once(function() { + self.off(name, once); + callback.apply(this, arguments); + }); + once._callback = callback; + this.on(name, once, context); + return this; + }, + + // Remove one or many callbacks. If `context` is null, removes all + // callbacks with that function. If `callback` is null, removes all + // callbacks for the event. If `events` is null, removes all bound + // callbacks for all events. + off: function(name, callback, context) { + var list, ev, events, names, i, l, j, k; + if (!this._events || !eventsApi(this, 'off', name, [callback, context])) return this; + if (!name && !callback && !context) { + this._events = {}; + return this; + } + + names = name ? [name] : _.keys(this._events); + for (i = 0, l = names.length; i < l; i++) { + name = names[i]; + if (list = this._events[name]) { + events = []; + if (callback || context) { + for (j = 0, k = list.length; j < k; j++) { + ev = list[j]; + if ((callback && callback !== (ev.callback._callback || ev.callback)) || + (context && context !== ev.context)) { + events.push(ev); + } + } + } + this._events[name] = events; + } + } + + return this; + }, + + // Trigger one or many events, firing all bound callbacks. Callbacks are + // passed the same arguments as `trigger` is, apart from the event name + // (unless you're listening on `"all"`, which will cause your callback to + // receive the true name of the event as the first argument). + trigger: function(name) { + if (!this._events) return this; + var args = slice.call(arguments, 1); + if (!eventsApi(this, 'trigger', name, args)) return this; + var events = this._events[name]; + var allEvents = this._events.all; + if (events) triggerEvents(this, events, args); + if (allEvents) triggerEvents(this, allEvents, arguments); + return this; + }, + + // An inversion-of-control version of `on`. Tell *this* object to listen to + // an event in another object ... keeping track of what it's listening to. + listenTo: function(object, events, callback) { + var listeners = this._listeners || (this._listeners = {}); + var id = object._listenerId || (object._listenerId = _.uniqueId('l')); + listeners[id] = object; + object.on(events, callback || this, this); + return this; + }, + + // Tell this object to stop listening to either specific events ... or + // to every object it's currently listening to. + stopListening: function(object, events, callback) { + var listeners = this._listeners; + if (!listeners) return; + if (object) { + object.off(events, callback, this); + if (!events && !callback) delete listeners[object._listenerId]; + } else { + for (var id in listeners) { + listeners[id].off(null, null, this); + } + this._listeners = {}; + } + return this; + } + }; + + // Aliases for backwards compatibility. + Events.bind = Events.on; + Events.unbind = Events.off; + + // Allow the `Backbone` object to serve as a global event bus, for folks who + // want global "pubsub" in a convenient place. + _.extend(Backbone, Events); + + // Backbone.Model + // -------------- + + // Create a new model, with defined attributes. A client id (`cid`) + // is automatically generated and assigned for you. + var Model = Backbone.Model = function(attributes, options) { + var defaults; + var attrs = attributes || {}; + this.cid = _.uniqueId('c'); + this.changed = {}; + this.attributes = {}; + this._changes = []; + if (options && options.collection) this.collection = options.collection; + if (options && options.parse) attrs = this.parse(attrs); + if (defaults = _.result(this, 'defaults')) _.defaults(attrs, defaults); + this.set(attrs, {silent: true}); + this._currentAttributes = _.clone(this.attributes); + this._previousAttributes = _.clone(this.attributes); + this.initialize.apply(this, arguments); + }; + + // Attach all inheritable methods to the Model prototype. + _.extend(Model.prototype, Events, { + + // A hash of attributes whose current and previous value differ. + changed: null, + + // The default name for the JSON `id` attribute is `"id"`. MongoDB and + // CouchDB users may want to set this to `"_id"`. + idAttribute: 'id', + + // Initialize is an empty function by default. Override it with your own + // initialization logic. + initialize: function(){}, + + // Return a copy of the model's `attributes` object. + toJSON: function(options) { + return _.clone(this.attributes); + }, + + // Proxy `Backbone.sync` by default. + sync: function() { + return Backbone.sync.apply(this, arguments); + }, + + // Get the value of an attribute. + get: function(attr) { + return this.attributes[attr]; + }, + + // Get the HTML-escaped value of an attribute. + escape: function(attr) { + return _.escape(this.get(attr)); + }, + + // Returns `true` if the attribute contains a value that is not null + // or undefined. + has: function(attr) { + return this.get(attr) != null; + }, + + // Set a hash of model attributes on the object, firing `"change"` unless + // you choose to silence it. + set: function(key, val, options) { + var attr, attrs; + if (key == null) return this; + + // Handle both `"key", value` and `{key: value}` -style arguments. + if (_.isObject(key)) { + attrs = key; + options = val; + } else { + (attrs = {})[key] = val; + } + + // Extract attributes and options. + var silent = options && options.silent; + var unset = options && options.unset; + + // Run validation. + if (!this._validate(attrs, options)) return false; + + // Check for changes of `id`. + if (this.idAttribute in attrs) this.id = attrs[this.idAttribute]; + + var now = this.attributes; + + // For each `set` attribute... + for (attr in attrs) { + val = attrs[attr]; + + // Update or delete the current value, and track the change. + unset ? delete now[attr] : now[attr] = val; + this._changes.push(attr, val); + } + + // Signal that the model's state has potentially changed, and we need + // to recompute the actual changes. + this._hasComputed = false; + + // Fire the `"change"` events. + if (!silent) this.change(options); + return this; + }, + + // Remove an attribute from the model, firing `"change"` unless you choose + // to silence it. `unset` is a noop if the attribute doesn't exist. + unset: function(attr, options) { + return this.set(attr, void 0, _.extend({}, options, {unset: true})); + }, + + // Clear all attributes on the model, firing `"change"` unless you choose + // to silence it. + clear: function(options) { + var attrs = {}; + for (var key in this.attributes) attrs[key] = void 0; + return this.set(attrs, _.extend({}, options, {unset: true})); + }, + + // Fetch the model from the server. If the server's representation of the + // model differs from its current attributes, they will be overriden, + // triggering a `"change"` event. + fetch: function(options) { + options = options ? _.clone(options) : {}; + if (options.parse === void 0) options.parse = true; + var model = this; + var success = options.success; + options.success = function(resp, status, xhr) { + if (!model.set(model.parse(resp), options)) return false; + if (success) success(model, resp, options); + }; + return this.sync('read', this, options); + }, + + // Set a hash of model attributes, and sync the model to the server. + // If the server returns an attributes hash that differs, the model's + // state will be `set` again. + save: function(key, val, options) { + var attrs, current, done; + + // Handle both `"key", value` and `{key: value}` -style arguments. + if (key == null || _.isObject(key)) { + attrs = key; + options = val; + } else if (key != null) { + (attrs = {})[key] = val; + } + options = options ? _.clone(options) : {}; + + // If we're "wait"-ing to set changed attributes, validate early. + if (options.wait) { + if (attrs && !this._validate(attrs, options)) return false; + current = _.clone(this.attributes); + } + + // Regular saves `set` attributes before persisting to the server. + var silentOptions = _.extend({}, options, {silent: true}); + if (attrs && !this.set(attrs, options.wait ? silentOptions : options)) { + return false; + } + + // Do not persist invalid models. + if (!attrs && !this._validate(null, options)) return false; + + // After a successful server-side save, the client is (optionally) + // updated with the server-side state. + var model = this; + var success = options.success; + options.success = function(resp, status, xhr) { + done = true; + var serverAttrs = model.parse(resp); + if (options.wait) serverAttrs = _.extend(attrs || {}, serverAttrs); + if (!model.set(serverAttrs, options)) return false; + if (success) success(model, resp, options); + }; + + // Finish configuring and sending the Ajax request. + var method = this.isNew() ? 'create' : (options.patch ? 'patch' : 'update'); + if (method == 'patch') options.attrs = attrs; + var xhr = this.sync(method, this, options); + + // When using `wait`, reset attributes to original values unless + // `success` has been called already. + if (!done && options.wait) { + this.clear(silentOptions); + this.set(current, silentOptions); + } + + return xhr; + }, + + // Destroy this model on the server if it was already persisted. + // Optimistically removes the model from its collection, if it has one. + // If `wait: true` is passed, waits for the server to respond before removal. + destroy: function(options) { + options = options ? _.clone(options) : {}; + var model = this; + var success = options.success; + + var destroy = function() { + model.trigger('destroy', model, model.collection, options); + }; + + options.success = function(resp) { + if (options.wait || model.isNew()) destroy(); + if (success) success(model, resp, options); + }; + + if (this.isNew()) { + options.success(); + return false; + } + + var xhr = this.sync('delete', this, options); + if (!options.wait) destroy(); + return xhr; + }, + + // Default URL for the model's representation on the server -- if you're + // using Backbone's restful methods, override this to change the endpoint + // that will be called. + url: function() { + var base = _.result(this, 'urlRoot') || _.result(this.collection, 'url') || urlError(); + if (this.isNew()) return base; + return base + (base.charAt(base.length - 1) === '/' ? '' : '/') + encodeURIComponent(this.id); + }, + + // **parse** converts a response into the hash of attributes to be `set` on + // the model. The default implementation is just to pass the response along. + parse: function(resp) { + return resp; + }, + + // Create a new model with identical attributes to this one. + clone: function() { + return new this.constructor(this.attributes); + }, + + // A model is new if it has never been saved to the server, and lacks an id. + isNew: function() { + return this.id == null; + }, + + // Call this method to manually fire a `"change"` event for this model and + // a `"change:attribute"` event for each changed attribute. + // Calling this will cause all objects observing the model to update. + change: function(options) { + var changing = this._changing; + this._changing = true; + + // Generate the changes to be triggered on the model. + var triggers = this._computeChanges(true); + + this._pending = !!triggers.length; + + for (var i = triggers.length - 2; i >= 0; i -= 2) { + this.trigger('change:' + triggers[i], this, triggers[i + 1], options); + } + + if (changing) return this; + + // Trigger a `change` while there have been changes. + while (this._pending) { + this._pending = false; + this.trigger('change', this, options); + this._previousAttributes = _.clone(this.attributes); + } + + this._changing = false; + return this; + }, + + // Determine if the model has changed since the last `"change"` event. + // If you specify an attribute name, determine if that attribute has changed. + hasChanged: function(attr) { + if (!this._hasComputed) this._computeChanges(); + if (attr == null) return !_.isEmpty(this.changed); + return _.has(this.changed, attr); + }, + + // Return an object containing all the attributes that have changed, or + // false if there are no changed attributes. Useful for determining what + // parts of a view need to be updated and/or what attributes need to be + // persisted to the server. Unset attributes will be set to undefined. + // You can also pass an attributes object to diff against the model, + // determining if there *would be* a change. + changedAttributes: function(diff) { + if (!diff) return this.hasChanged() ? _.clone(this.changed) : false; + var val, changed = false, old = this._previousAttributes; + for (var attr in diff) { + if (_.isEqual(old[attr], (val = diff[attr]))) continue; + (changed || (changed = {}))[attr] = val; + } + return changed; + }, + + // Looking at the built up list of `set` attribute changes, compute how + // many of the attributes have actually changed. If `loud`, return a + // boiled-down list of only the real changes. + _computeChanges: function(loud) { + this.changed = {}; + var already = {}; + var triggers = []; + var current = this._currentAttributes; + var changes = this._changes; + + // Loop through the current queue of potential model changes. + for (var i = changes.length - 2; i >= 0; i -= 2) { + var key = changes[i], val = changes[i + 1]; + if (already[key]) continue; + already[key] = true; + + // Check if the attribute has been modified since the last change, + // and update `this.changed` accordingly. If we're inside of a `change` + // call, also add a trigger to the list. + if (current[key] !== val) { + this.changed[key] = val; + if (!loud) continue; + triggers.push(key, val); + current[key] = val; + } + } + if (loud) this._changes = []; + + // Signals `this.changed` is current to prevent duplicate calls from `this.hasChanged`. + this._hasComputed = true; + return triggers; + }, + + // Get the previous value of an attribute, recorded at the time the last + // `"change"` event was fired. + previous: function(attr) { + if (attr == null || !this._previousAttributes) return null; + return this._previousAttributes[attr]; + }, + + // Get all of the attributes of the model at the time of the previous + // `"change"` event. + previousAttributes: function() { + return _.clone(this._previousAttributes); + }, + + // Run validation against the next complete set of model attributes, + // returning `true` if all is well. If a specific `error` callback has + // been passed, call that instead of firing the general `"error"` event. + _validate: function(attrs, options) { + if (!this.validate) return true; + attrs = _.extend({}, this.attributes, attrs); + var error = this.validate(attrs, options); + if (!error) return true; + if (options && options.error) options.error(this, error, options); + this.trigger('error', this, error, options); + return false; + } + + }); + + // Backbone.Collection + // ------------------- + + // Provides a standard collection class for our sets of models, ordered + // or unordered. If a `comparator` is specified, the Collection will maintain + // its models in sort order, as they're added and removed. + var Collection = Backbone.Collection = function(models, options) { + options || (options = {}); + if (options.model) this.model = options.model; + if (options.comparator !== void 0) this.comparator = options.comparator; + this._reset(); + this.initialize.apply(this, arguments); + if (models) this.reset(models, _.extend({silent: true}, options)); + }; + + // Define the Collection's inheritable methods. + _.extend(Collection.prototype, Events, { + + // The default model for a collection is just a **Backbone.Model**. + // This should be overridden in most cases. + model: Model, + + // Initialize is an empty function by default. Override it with your own + // initialization logic. + initialize: function(){}, + + // The JSON representation of a Collection is an array of the + // models' attributes. + toJSON: function(options) { + return this.map(function(model){ return model.toJSON(options); }); + }, + + // Proxy `Backbone.sync` by default. + sync: function() { + return Backbone.sync.apply(this, arguments); + }, + + // Add a model, or list of models to the set. Pass **silent** to avoid + // firing the `add` event for every new model. + add: function(models, options) { + var i, args, length, model, existing, needsSort; + var at = options && options.at; + var sort = ((options && options.sort) == null ? true : options.sort); + models = _.isArray(models) ? models.slice() : [models]; + + // Turn bare objects into model references, and prevent invalid models + // from being added. + for (i = models.length - 1; i >= 0; i--) { + if(!(model = this._prepareModel(models[i], options))) { + this.trigger("error", this, models[i], options); + models.splice(i, 1); + continue; + } + models[i] = model; + + existing = model.id != null && this._byId[model.id]; + // If a duplicate is found, prevent it from being added and + // optionally merge it into the existing model. + if (existing || this._byCid[model.cid]) { + if (options && options.merge && existing) { + existing.set(model.attributes, options); + needsSort = sort; + } + models.splice(i, 1); + continue; + } + + // Listen to added models' events, and index models for lookup by + // `id` and by `cid`. + model.on('all', this._onModelEvent, this); + this._byCid[model.cid] = model; + if (model.id != null) this._byId[model.id] = model; + } + + // See if sorting is needed, update `length` and splice in new models. + if (models.length) needsSort = sort; + this.length += models.length; + args = [at != null ? at : this.models.length, 0]; + push.apply(args, models); + splice.apply(this.models, args); + + // Sort the collection if appropriate. + if (needsSort && this.comparator && at == null) this.sort({silent: true}); + + if (options && options.silent) return this; + + // Trigger `add` events. + while (model = models.shift()) { + model.trigger('add', model, this, options); + } + + return this; + }, + + // Remove a model, or a list of models from the set. Pass silent to avoid + // firing the `remove` event for every model removed. + remove: function(models, options) { + var i, l, index, model; + options || (options = {}); + models = _.isArray(models) ? models.slice() : [models]; + for (i = 0, l = models.length; i < l; i++) { + model = this.get(models[i]); + if (!model) continue; + delete this._byId[model.id]; + delete this._byCid[model.cid]; + index = this.indexOf(model); + this.models.splice(index, 1); + this.length--; + if (!options.silent) { + options.index = index; + model.trigger('remove', model, this, options); + } + this._removeReference(model); + } + return this; + }, + + // Add a model to the end of the collection. + push: function(model, options) { + model = this._prepareModel(model, options); + this.add(model, _.extend({at: this.length}, options)); + return model; + }, + + // Remove a model from the end of the collection. + pop: function(options) { + var model = this.at(this.length - 1); + this.remove(model, options); + return model; + }, + + // Add a model to the beginning of the collection. + unshift: function(model, options) { + model = this._prepareModel(model, options); + this.add(model, _.extend({at: 0}, options)); + return model; + }, + + // Remove a model from the beginning of the collection. + shift: function(options) { + var model = this.at(0); + this.remove(model, options); + return model; + }, + + // Slice out a sub-array of models from the collection. + slice: function(begin, end) { + return this.models.slice(begin, end); + }, + + // Get a model from the set by id. + get: function(obj) { + if (obj == null) return void 0; + return this._byId[obj.id != null ? obj.id : obj] || this._byCid[obj.cid || obj]; + }, + + // Get the model at the given index. + at: function(index) { + return this.models[index]; + }, + + // Return models with matching attributes. Useful for simple cases of `filter`. + where: function(attrs) { + if (_.isEmpty(attrs)) return []; + return this.filter(function(model) { + for (var key in attrs) { + if (attrs[key] !== model.get(key)) return false; + } + return true; + }); + }, + + // Force the collection to re-sort itself. You don't need to call this under + // normal circumstances, as the set will maintain sort order as each item + // is added. + sort: function(options) { + if (!this.comparator) { + throw new Error('Cannot sort a set without a comparator'); + } + + if (_.isString(this.comparator) || this.comparator.length === 1) { + this.models = this.sortBy(this.comparator, this); + } else { + this.models.sort(_.bind(this.comparator, this)); + } + + if (!options || !options.silent) this.trigger('sort', this, options); + return this; + }, + + // Pluck an attribute from each model in the collection. + pluck: function(attr) { + return _.invoke(this.models, 'get', attr); + }, + + // Smartly update a collection with a change set of models, adding, + // removing, and merging as necessary. + update: function(models, options) { + var model, i, l, existing; + var add = [], remove = [], modelMap = {}; + var idAttr = this.model.prototype.idAttribute; + options = _.extend({add: true, merge: true, remove: true}, options); + if (options.parse) models = this.parse(models); + + // Allow a single model (or no argument) to be passed. + if (!_.isArray(models)) models = models ? [models] : []; + + // Proxy to `add` for this case, no need to iterate... + if (options.add && !options.remove) return this.add(models, options); + + // Determine which models to add and merge, and which to remove. + for (i = 0, l = models.length; i < l; i++) { + model = models[i]; + existing = this.get(model.id || model.cid || model[idAttr]); + if (options.remove && existing) modelMap[existing.cid] = true; + if ((options.add && !existing) || (options.merge && existing)) { + add.push(model); + } + } + if (options.remove) { + for (i = 0, l = this.models.length; i < l; i++) { + model = this.models[i]; + if (!modelMap[model.cid]) remove.push(model); + } + } + + // Remove models (if applicable) before we add and merge the rest. + if (remove.length) this.remove(remove, options); + if (add.length) this.add(add, options); + return this; + }, + + // When you have more items than you want to add or remove individually, + // you can reset the entire set with a new list of models, without firing + // any `add` or `remove` events. Fires `reset` when finished. + reset: function(models, options) { + options || (options = {}); + if (options.parse) models = this.parse(models); + for (var i = 0, l = this.models.length; i < l; i++) { + this._removeReference(this.models[i]); + } + options.previousModels = this.models; + this._reset(); + if (models) this.add(models, _.extend({silent: true}, options)); + if (!options.silent) this.trigger('reset', this, options); + return this; + }, + + // Fetch the default set of models for this collection, resetting the + // collection when they arrive. If `add: true` is passed, appends the + // models to the collection instead of resetting. + fetch: function(options) { + options = options ? _.clone(options) : {}; + if (options.parse === void 0) options.parse = true; + var collection = this; + var success = options.success; + options.success = function(resp, status, xhr) { + var method = options.update ? 'update' : 'reset'; + collection[method](resp, options); + if (success) success(collection, resp, options); + }; + return this.sync('read', this, options); + }, + + // Create a new instance of a model in this collection. Add the model to the + // collection immediately, unless `wait: true` is passed, in which case we + // wait for the server to agree. + create: function(model, options) { + var collection = this; + options = options ? _.clone(options) : {}; + model = this._prepareModel(model, options); + if (!model) return false; + if (!options.wait) collection.add(model, options); + var success = options.success; + options.success = function(model, resp, options) { + if (options.wait) collection.add(model, options); + if (success) success(model, resp, options); + }; + model.save(null, options); + return model; + }, + + // **parse** converts a response into a list of models to be added to the + // collection. The default implementation is just to pass it through. + parse: function(resp) { + return resp; + }, + + // Create a new collection with an identical list of models as this one. + clone: function() { + return new this.constructor(this.models); + }, + + // Proxy to _'s chain. Can't be proxied the same way the rest of the + // underscore methods are proxied because it relies on the underscore + // constructor. + chain: function() { + return _(this.models).chain(); + }, + + // Reset all internal state. Called when the collection is reset. + _reset: function() { + this.length = 0; + this.models = []; + this._byId = {}; + this._byCid = {}; + }, + + // Prepare a model or hash of attributes to be added to this collection. + _prepareModel: function(attrs, options) { + if (attrs instanceof Model) { + if (!attrs.collection) attrs.collection = this; + return attrs; + } + options || (options = {}); + options.collection = this; + var model = new this.model(attrs, options); + if (!model._validate(attrs, options)) return false; + return model; + }, + + // Internal method to remove a model's ties to a collection. + _removeReference: function(model) { + if (this === model.collection) delete model.collection; + model.off('all', this._onModelEvent, this); + }, + + // Internal method called every time a model in the set fires an event. + // Sets need to update their indexes when models change ids. All other + // events simply proxy through. "add" and "remove" events that originate + // in other collections are ignored. + _onModelEvent: function(event, model, collection, options) { + if ((event === 'add' || event === 'remove') && collection !== this) return; + if (event === 'destroy') this.remove(model, options); + if (model && event === 'change:' + model.idAttribute) { + delete this._byId[model.previous(model.idAttribute)]; + if (model.id != null) this._byId[model.id] = model; + } + this.trigger.apply(this, arguments); + } + + }); + + // Underscore methods that we want to implement on the Collection. + var methods = ['forEach', 'each', 'map', 'collect', 'reduce', 'foldl', + 'inject', 'reduceRight', 'foldr', 'find', 'detect', 'filter', 'select', + 'reject', 'every', 'all', 'some', 'any', 'include', 'contains', 'invoke', + 'max', 'min', 'sortedIndex', 'toArray', 'size', 'first', 'head', 'take', + 'initial', 'rest', 'tail', 'last', 'without', 'indexOf', 'shuffle', + 'lastIndexOf', 'isEmpty']; + + // Mix in each Underscore method as a proxy to `Collection#models`. + _.each(methods, function(method) { + Collection.prototype[method] = function() { + var args = slice.call(arguments); + args.unshift(this.models); + return _[method].apply(_, args); + }; + }); + + // Underscore methods that take a property name as an argument. + var attributeMethods = ['groupBy', 'countBy', 'sortBy']; + + // Use attributes instead of properties. + _.each(attributeMethods, function(method) { + Collection.prototype[method] = function(value, context) { + var iterator = _.isFunction(value) ? value : function(model) { + return model.get(value); + }; + return _[method](this.models, iterator, context); + }; + }); + + // Backbone.Router + // --------------- + + // Routers map faux-URLs to actions, and fire events when routes are + // matched. Creating a new one sets its `routes` hash, if not set statically. + var Router = Backbone.Router = function(options) { + options || (options = {}); + if (options.routes) this.routes = options.routes; + this._bindRoutes(); + this.initialize.apply(this, arguments); + }; + + // Cached regular expressions for matching named param parts and splatted + // parts of route strings. + var optionalParam = /\((.*?)\)/g; + var namedParam = /:\w+/g; + var splatParam = /\*\w+/g; + var escapeRegExp = /[\-{}\[\]+?.,\\\^$|#\s]/g; + + // Set up all inheritable **Backbone.Router** properties and methods. + _.extend(Router.prototype, Events, { + + // Initialize is an empty function by default. Override it with your own + // initialization logic. + initialize: function(){}, + + // Manually bind a single named route to a callback. For example: + // + // this.route('search/:query/p:num', 'search', function(query, num) { + // ... + // }); + // + route: function(route, name, callback) { + if (!_.isRegExp(route)) route = this._routeToRegExp(route); + if (!callback) callback = this[name]; + Backbone.history.route(route, _.bind(function(fragment) { + var args = this._extractParameters(route, fragment); + callback && callback.apply(this, args); + this.trigger.apply(this, ['route:' + name].concat(args)); + Backbone.history.trigger('route', this, name, args); + }, this)); + return this; + }, + + // Simple proxy to `Backbone.history` to save a fragment into the history. + navigate: function(fragment, options) { + Backbone.history.navigate(fragment, options); + return this; + }, + + // Bind all defined routes to `Backbone.history`. We have to reverse the + // order of the routes here to support behavior where the most general + // routes can be defined at the bottom of the route map. + _bindRoutes: function() { + if (!this.routes) return; + var route, routes = _.keys(this.routes); + while ((route = routes.pop()) != null) { + this.route(route, this.routes[route]); + } + }, + + // Convert a route string into a regular expression, suitable for matching + // against the current location hash. + _routeToRegExp: function(route) { + route = route.replace(escapeRegExp, '\\$&') + .replace(optionalParam, '(?:$1)?') + .replace(namedParam, '([^\/]+)') + .replace(splatParam, '(.*?)'); + return new RegExp('^' + route + '$'); + }, + + // Given a route, and a URL fragment that it matches, return the array of + // extracted parameters. + _extractParameters: function(route, fragment) { + return route.exec(fragment).slice(1); + } + + }); + + // Backbone.History + // ---------------- + + // Handles cross-browser history management, based on URL fragments. If the + // browser does not support `onhashchange`, falls back to polling. + var History = Backbone.History = function() { + this.handlers = []; + _.bindAll(this, 'checkUrl'); + + // Ensure that `History` can be used outside of the browser. + if (typeof window !== 'undefined') { + this.location = window.location; + this.history = window.history; + } + }; + + // Cached regex for stripping a leading hash/slash and trailing space. + var routeStripper = /^[#\/]|\s+$/g; + + // Cached regex for stripping leading and trailing slashes. + var rootStripper = /^\/+|\/+$/g; + + // Cached regex for detecting MSIE. + var isExplorer = /msie [\w.]+/; + + // Cached regex for removing a trailing slash. + var trailingSlash = /\/$/; + + // Has the history handling already been started? + History.started = false; + + // Set up all inheritable **Backbone.History** properties and methods. + _.extend(History.prototype, Events, { + + // The default interval to poll for hash changes, if necessary, is + // twenty times a second. + interval: 50, + + // Gets the true hash value. Cannot use location.hash directly due to bug + // in Firefox where location.hash will always be decoded. + getHash: function(window) { + var match = (window || this).location.href.match(/#(.*)$/); + return match ? match[1] : ''; + }, + + // Get the cross-browser normalized URL fragment, either from the URL, + // the hash, or the override. + getFragment: function(fragment, forcePushState) { + if (fragment == null) { + if (this._hasPushState || !this._wantsHashChange || forcePushState) { + fragment = this.location.pathname; + var root = this.root.replace(trailingSlash, ''); + if (!fragment.indexOf(root)) fragment = fragment.substr(root.length); + } else { + fragment = this.getHash(); + } + } + return fragment.replace(routeStripper, ''); + }, + + // Start the hash change handling, returning `true` if the current URL matches + // an existing route, and `false` otherwise. + start: function(options) { + if (History.started) throw new Error("Backbone.history has already been started"); + History.started = true; + + // Figure out the initial configuration. Do we need an iframe? + // Is pushState desired ... is it available? + this.options = _.extend({}, {root: '/'}, this.options, options); + this.root = this.options.root; + this._wantsHashChange = this.options.hashChange !== false; + this._wantsPushState = !!this.options.pushState; + this._hasPushState = !!(this.options.pushState && this.history && this.history.pushState); + var fragment = this.getFragment(); + var docMode = document.documentMode; + var oldIE = (isExplorer.exec(navigator.userAgent.toLowerCase()) && (!docMode || docMode <= 7)); + + // Normalize root to always include a leading and trailing slash. + this.root = ('/' + this.root + '/').replace(rootStripper, '/'); + + if (oldIE && this._wantsHashChange) { + this.iframe = Backbone.$(' + +
      + + + + + + diff --git a/htdocs/js/lib/vendor/components/requirejs/tests/doh/runner.js b/htdocs/js/lib/vendor/components/requirejs/tests/doh/runner.js new file mode 100644 index 000000000..2bf12608b --- /dev/null +++ b/htdocs/js/lib/vendor/components/requirejs/tests/doh/runner.js @@ -0,0 +1,1499 @@ +// package system gunk. +//try{ +// dojo.provide("doh.runner"); +//}catch(e){ + if(!this["doh"]){ + doh = {}; + } +//} + +// +// Utility Functions and Classes +// + +doh.selfTest = false; + +doh.global = this; + +doh.hitch = function(/*Object*/thisObject, /*Function|String*/method /*, ...*/){ + var args = []; + for(var x=2; x= 0)) { + this._fire(); + } + }, + + _continue: function(res){ + this._resback(res); + this._unpause(); + }, + + _resback: function(res){ + this.fired = ((res instanceof Error) ? 1 : 0); + this.results[this.fired] = res; + this._fire(); + }, + + _check: function(){ + if(this.fired != -1){ + if(!this.silentlyCancelled){ + throw new Error("already called!"); + } + this.silentlyCancelled = false; + return; + } + }, + + callback: function(res){ + this._check(); + this._resback(res); + }, + + errback: function(res){ + this._check(); + if(!(res instanceof Error)){ + res = new Error(res); + } + this._resback(res); + }, + + addBoth: function(cb, cbfn){ + var enclosed = this.getFunctionFromArgs(cb, cbfn); + if(arguments.length > 2){ + enclosed = doh.hitch(null, enclosed, arguments, 2); + } + return this.addCallbacks(enclosed, enclosed); + }, + + addCallback: function(cb, cbfn){ + var enclosed = this.getFunctionFromArgs(cb, cbfn); + if(arguments.length > 2){ + enclosed = doh.hitch(null, enclosed, arguments, 2); + } + return this.addCallbacks(enclosed, null); + }, + + addErrback: function(cb, cbfn){ + var enclosed = this.getFunctionFromArgs(cb, cbfn); + if(arguments.length > 2){ + enclosed = doh.hitch(null, enclosed, arguments, 2); + } + return this.addCallbacks(null, enclosed); + }, + + addCallbacks: function(cb, eb){ + this.chain.push([cb, eb]); + if(this.fired >= 0){ + this._fire(); + } + return this; + }, + + _fire: function(){ + var chain = this.chain; + var fired = this.fired; + var res = this.results[fired]; + var self = this; + var cb = null; + while(chain.length > 0 && this.paused == 0){ + // Array + var pair = chain.shift(); + var f = pair[fired]; + if(f == null){ + continue; + } + try { + res = f(res); + fired = ((res instanceof Error) ? 1 : 0); + if(res instanceof doh.Deferred){ + cb = function(res){ + self._continue(res); + }; + this._pause(); + } + }catch(err){ + fired = 1; + res = err; + } + } + this.fired = fired; + this.results[fired] = res; + if((cb)&&(this.paused)){ + res.addBoth(cb); + } + } +}); + +// +// State Keeping and Reporting +// + +doh._testCount = 0; +doh._groupCount = 0; +doh._errorCount = 0; +doh._failureCount = 0; +doh._currentGroup = null; +doh._currentTest = null; +doh._paused = true; + +doh._init = function(){ + this._currentGroup = null; + this._currentTest = null; + this._errorCount = 0; + this._failureCount = 0; + this.debug(this._testCount, "tests to run in", this._groupCount, "groups"); +} + +// doh._urls = []; +doh._groups = {}; + +// +// Test Registration +// + +doh.registerTestNs = function(/*String*/ group, /*Object*/ ns){ + // summary: + // adds the passed namespace object to the list of objects to be + // searched for test groups. Only "public" functions (not prefixed + // with "_") will be added as tests to be run. If you'd like to use + // fixtures (setUp(), tearDown(), and runTest()), please use + // registerTest() or registerTests(). + for(var x in ns){ + if( (x.charAt(0) != "_") && + (typeof ns[x] == "function") ){ + this.registerTest(group, ns[x]); + } + } +} + +doh._testRegistered = function(group, fixture){ + // slot to be filled in +} + +doh._groupStarted = function(group){ + // slot to be filled in +} + +doh._groupFinished = function(group, success){ + // slot to be filled in +} + +doh._testStarted = function(group, fixture){ + // slot to be filled in +} + +doh._testFinished = function(group, fixture, success){ + // slot to be filled in +} + +doh.registerGroup = function( /*String*/ group, + /*Array||Function||Object*/ tests, + /*Function*/ setUp, + /*Function*/ tearDown, + /*String*/ type){ + // summary: + // registers an entire group of tests at once and provides a setUp and + // tearDown facility for groups. If you call this method with only + // setUp and tearDown parameters, they will replace previously + // installed setUp or tearDown functions for the group with the new + // methods. + // group: + // string name of the group + // tests: + // either a function or an object or an array of functions/objects. If + // an object, it must contain at *least* a "runTest" method, and may + // also contain "setUp" and "tearDown" methods. These will be invoked + // on either side of the "runTest" method (respectively) when the test + // is run. If an array, it must contain objects matching the above + // description or test functions. + // setUp: a function for initializing the test group + // tearDown: a function for initializing the test group + // type: The type of tests these are, such as a group of performance tests + // null/undefied are standard DOH tests, the valye 'perf' enables + // registering them as performance tests. + if(tests){ + this.register(group, tests, type); + } + if(setUp){ + this._groups[group].setUp = setUp; + } + if(tearDown){ + this._groups[group].tearDown = tearDown; + } +} + +doh._getTestObj = function(group, test, type){ + var tObj = test; + if(typeof test == "string"){ + if(test.substr(0, 4)=="url:"){ + return this.registerUrl(group, test); + }else{ + tObj = { + name: test.replace("/\s/g", "_") // FIXME: bad escapement + }; + tObj.runTest = new Function("t", test); + } + }else if(typeof test == "function"){ + // if we didn't get a fixture, wrap the function + tObj = { "runTest": test }; + if(test["name"]){ + tObj.name = test.name; + }else{ + try{ + var fStr = "function "; + var ts = tObj.runTest+""; + if(0 <= ts.indexOf(fStr)){ + tObj.name = ts.split(fStr)[1].split("(", 1)[0]; + } + // doh.debug(tObj.runTest.toSource()); + }catch(e){ + } + } + // FIXME: try harder to get the test name here + } + + //Augment the test with some specific options to make it identifiable as a + //particular type of test so it can be executed properly. + if(type === "perf" || tObj.testType === "perf"){ + tObj.testType = "perf"; + + //Build an object on the root DOH class to contain all the test results. + //Cache it on the test object for quick lookup later for results storage. + if(!doh.perfTestResults){ + doh.perfTestResults = {}; + doh.perfTestResults[group] = {}; + } + if(!doh.perfTestResults[group]){ + doh.perfTestResults[group] = {}; + } + if(!doh.perfTestResults[group][tObj.name]){ + doh.perfTestResults[group][tObj.name] = {}; + } + tObj.results = doh.perfTestResults[group][tObj.name]; + + //If it's not set, then set the trial duration + //default to 100ms. + if(!("trialDuration" in tObj)){ + tObj.trialDuration = 100; + } + + //If it's not set, then set the delay between trial runs to 100ms + //default to 100ms to allow for GC and to make IE happy. + if(!("trialDelay" in tObj)){ + tObj.trialDelay = 100; + } + + //If it's not set, then set number of times a trial is run to 10. + if(!("trialIterations" in tObj)){ + tObj.trialIterations = 10; + } + } + return tObj; +} + +doh.registerTest = function(/*String*/ group, /*Function||Object*/ test, /*String*/ type){ + // summary: + // add the provided test function or fixture object to the specified + // test group. + // group: + // string name of the group to add the test to + // test: + // either a function or an object. If an object, it must contain at + // *least* a "runTest" method, and may also contain "setUp" and + // "tearDown" methods. These will be invoked on either side of the + // "runTest" method (respectively) when the test is run. + // type: + // An identifier denoting the type of testing that the test performs, such + // as a performance test. If null, defaults to regular DOH test. + if(!this._groups[group]){ + this._groupCount++; + this._groups[group] = []; + this._groups[group].inFlight = 0; + } + var tObj = this._getTestObj(group, test, type); + if(!tObj){ return null; } + this._groups[group].push(tObj); + this._testCount++; + this._testRegistered(group, tObj); + return tObj; +} + +doh.registerTests = function(/*String*/ group, /*Array*/ testArr, /*String*/ type){ + // summary: + // registers a group of tests, treating each element of testArr as + // though it were being (along with group) passed to the registerTest + // method. It also uses the type to decide how the tests should + // behave, by defining the type of tests these are, such as performance tests + for(var x=0; x 1) ? "s" : "")+" to run"); +} + +doh._handleFailure = function(groupName, fixture, e){ + // this.debug("FAILED test:", fixture.name); + // mostly borrowed from JUM + this._groups[groupName].failures++; + var out = ""; + if(e instanceof this._AssertFailure){ + this._failureCount++; + if(e["fileName"]){ out += e.fileName + ':'; } + if(e["lineNumber"]){ out += e.lineNumber + ' '; } + out += e+": "+e.message; + this.debug("\t_AssertFailure:", out); + }else{ + this._errorCount++; + } + this.debug(e); + if(fixture.runTest["toSource"]){ + var ss = fixture.runTest.toSource(); + this.debug("\tERROR IN:\n\t\t", ss); + }else{ + this.debug("\tERROR IN:\n\t\t", fixture.runTest); + } + + if(e.rhinoException){ + e.rhinoException.printStackTrace(); + }else if(e.javaException){ + e.javaException.printStackTrace(); + } +} + +//Assume a setTimeout implementation that is synchronous, so that +//the Node and Rhino envs work similar to each other. Node defines +//a setTimeout, so testing for setTimeout is not enough, each environment +//adapter should set this value accordingly. +doh.setTimeout = function(func){ + return func(); +}; + +doh._runPerfFixture = function(/*String*/groupName, /*Object*/fixture){ + // summary: + // This function handles how to execute a 'performance' test + // which is different from a straight UT style test. These + // will often do numerous iterations of the same operation and + // gather execution statistics about it, like max, min, average, + // etc. It makes use of the already in place DOH deferred test + // handling since it is a good idea to put a pause inbetween each + // iteration to allow for GC cleanup and the like. + // + // groupName: + // The test group that contains this performance test. + // fixture: + // The performance test fixture. + var tg = this._groups[groupName]; + fixture.startTime = new Date(); + + //Perf tests always need to act in an async manner as there is a + //number of iterations to flow through. + var def = new doh.Deferred(); + tg.inFlight++; + def.groupName = groupName; + def.fixture = fixture; + + def.addErrback(function(err){ + doh._handleFailure(groupName, fixture, err); + }); + + //Set up the finalizer. + var retEnd = function(){ + if(fixture["tearDown"]){ fixture.tearDown(doh); } + tg.inFlight--; + if((!tg.inFlight)&&(tg.iterated)){ + doh._groupFinished(groupName, !tg.failures); + } + doh._testFinished(groupName, fixture, def.results[0]); + if(doh._paused){ + doh.run(); + } + }; + + //Since these can take who knows how long, we don't want to timeout + //unless explicitly set + var timer; + var to = fixture.timeout; + if(to > 0) { + timer = doh.setTimeout(function(){ + // ret.cancel(); + // retEnd(); + def.errback(new Error("test timeout in "+fixture.name.toString())); + }, to); + } + + //Set up the end calls to the test into the deferred we'll return. + def.addBoth(function(arg){ + if(timer){ + clearTimeout(timer); + } + retEnd(); + }); + + //Okay, now set up the timing loop for the actual test. + //This is down as an async type test where there is a delay + //between each execution to allow for GC time, etc, so the GC + //has less impact on the tests. + var res = fixture.results; + res.trials = []; + + //Try to figure out how many calls are needed to hit a particular threshold. + var itrDef = doh._calcTrialIterations(groupName, fixture); + itrDef.addErrback(function(err){ + fixture.endTime = new Date(); + def.errback(err); + }); + + //Blah, since tests can be deferred, the actual run has to be deferred until after + //we know how many iterations to run. This is just plain ugly. + itrDef.addCallback(function(iterations){ + if(iterations){ + var countdown = fixture.trialIterations; + doh.debug("TIMING TEST: [" + fixture.name + + "]\n\t\tITERATIONS PER TRIAL: " + + iterations + "\n\tTRIALS: " + + countdown); + + //Figure out how many times we want to run our 'trial'. + //Where each trial consists of 'iterations' of the test. + + var trialRunner = function() { + //Set up our function to execute a block of tests + var start = new Date(); + var tTimer = new doh.Deferred(); + var tCountdown = iterations; + + var tState = { + countdown: iterations + }; + var testRunner = function(state){ + while(state){ + try{ + state.countdown--; + if(state.countdown){ + var ret = fixture.runTest(doh); + if(ret instanceof doh.Deferred){ + //Deferreds have to be handled async, + //otherwise we just keep looping. + var atState = { + countdown: state.countdown + }; + ret.addCallback(function(){ + testRunner(atState); + }); + ret.addErrback(function(err) { + doh._handleFailure(groupName, fixture, err); + fixture.endTime = new Date(); + def.errback(err); + }); + state = null; + } + }else{ + tTimer.callback(new Date()); + state = null; + } + }catch(err){ + fixture.endTime = new Date(); + tTimer.errback(err); + } + } + }; + tTimer.addCallback(function(end){ + //Figure out the results and try to factor out function call costs. + var tResults = { + trial: (fixture.trialIterations - countdown), + testIterations: iterations, + executionTime: (end.getTime() - start.getTime()), + average: (end.getTime() - start.getTime())/iterations + }; + res.trials.push(tResults); + doh.debug("\n\t\tTRIAL #: " + + tResults.trial + "\n\tTIME: " + + tResults.executionTime + "ms.\n\tAVG TEST TIME: " + + (tResults.executionTime/tResults.testIterations) + "ms."); + + //Okay, have we run all the trials yet? + countdown--; + if(countdown){ + doh.setTimeout(trialRunner, fixture.trialDelay); + }else{ + //Okay, we're done, lets compute some final performance results. + var t = res.trials; + + + + //We're done. + fixture.endTime = new Date(); + def.callback(true); + } + }); + tTimer.addErrback(function(err){ + fixture.endTime = new Date(); + def.errback(err); + }); + testRunner(tState); + }; + trialRunner(); + } + }); + + //Set for a pause, returned the deferred. + if(def.fired < 0){ + doh.pause(); + } + return def; +}; + +doh._calcTrialIterations = function(/*String*/ groupName, /*Object*/ fixture){ + // summary: + // This function determines the rough number of iterations to + // use to reach a particular MS threshold. This returns a deferred + // since tests can theoretically by async. Async tests aren't going to + // give great perf #s, though. + // The callback is passed the # of iterations to hit the requested + // threshold. + // + // fixture: + // The test fixture we want to calculate iterations for. + var def = new doh.Deferred(); + var calibrate = function () { + var testFunc = fixture.runTest; + + //Set the initial state. We have to do this as a loop instead + //of a recursive function. Otherwise, it blows the call stack + //on some browsers. + var iState = { + start: new Date(), + curIter: 0, + iterations: 5 + }; + var handleIteration = function(state){ + while(state){ + if(state.curIter < state.iterations){ + try{ + var ret = testFunc(doh); + if(ret instanceof doh.Deferred){ + var aState = { + start: state.start, + curIter: state.curIter + 1, + iterations: state.iterations + }; + ret.addCallback(function(){ + handleIteration(aState); + }); + ret.addErrback(function(err) { + fixture.endTime = new Date(); + def.errback(err); + }); + state = null; + }else{ + state.curIter++; + } + }catch(err){ + fixture.endTime = new Date(); + def.errback(err); + return; + } + }else{ + var end = new Date(); + var totalTime = (end.getTime() - state.start.getTime()); + if(totalTime < fixture.trialDuration){ + var nState = { + iterations: state.iterations * 2, + curIter: 0 + } + state = null; + doh.setTimeout(function(){ + nState.start = new Date(); + handleIteration(nState); + }, 50); + }else{ + var itrs = state.iterations; + doh.setTimeout(function(){def.callback(itrs)}, 50); + state = null; + } + } + } + }; + handleIteration(iState); + }; + doh.setTimeout(calibrate, 10); + return def; +}; + +doh._runRegFixture = function(/*String*/groupName, /*Object*/fixture){ + // summary: + // Function to run a generic doh test. These are not + // specialized tests, like performance groups and such. + // + // groupName: + // The groupName of the test. + // fixture: + // The test fixture to execute. + var tg = this._groups[groupName]; + fixture.startTime = new Date(); + var ret = fixture.runTest(this); + fixture.endTime = new Date(); + // if we get a deferred back from the test runner, we know we're + // gonna wait for an async result. It's up to the test code to trap + // errors and give us an errback or callback. + if(ret instanceof doh.Deferred){ + tg.inFlight++; + ret.groupName = groupName; + ret.fixture = fixture; + + ret.addErrback(function(err){ + doh._handleFailure(groupName, fixture, err); + }); + + var retEnd = function(){ + if(fixture["tearDown"]){ fixture.tearDown(doh); } + tg.inFlight--; + if((!tg.inFlight)&&(tg.iterated)){ + doh._groupFinished(groupName, !tg.failures); + } + doh._testFinished(groupName, fixture, ret.results[0]); + if(doh._paused){ + doh.run(); + } + } + + var timer = doh.setTimeout(function(){ + // ret.cancel(); + // retEnd(); + ret.errback(new Error("test timeout in "+fixture.name.toString())); + }, fixture["timeout"]||1000); + + ret.addBoth(function(arg){ + clearTimeout(timer); + retEnd(); + }); + if(ret.fired < 0){ + doh.pause(); + } + return ret; + } +}; + +doh._runFixture = function(groupName, fixture){ + var tg = this._groups[groupName]; + this._testStarted(groupName, fixture); + var threw = false; + var err = null; + // run it, catching exceptions and reporting them + try{ + // let doh reference "this.group.thinger..." which can be set by + // another test or group-level setUp function + fixture.group = tg; + // only execute the parts of the fixture we've got + + if(fixture["setUp"]){ fixture.setUp(this); } + if(fixture["runTest"]){ // should we error out of a fixture doesn't have a runTest? + if(fixture.testType === "perf"){ + //Always async deferred, so return it. + return doh._runPerfFixture(groupName, fixture); + }else{ + //May or may not by async. + var ret = doh._runRegFixture(groupName, fixture); + if(ret){ + return ret; + } + } + } + if(fixture["tearDown"]){ fixture.tearDown(this); } + }catch(e){ + threw = true; + err = e; + if(!fixture.endTime){ + fixture.endTime = new Date(); + } + } + var d = new doh.Deferred(); + doh.setTimeout(this.hitch(this, function(){ + if(threw){ + this._handleFailure(groupName, fixture, err); + } + this._testFinished(groupName, fixture, !threw); + + if((!tg.inFlight)&&(tg.iterated)){ + doh._groupFinished(groupName, !tg.failures); + }else if(tg.inFlight > 0){ + doh.setTimeout(this.hitch(this, function(){ + doh.runGroup(groupName); // , idx); + }), 100); + this._paused = true; + } + if(doh._paused){ + doh.run(); + } + }), 30); + doh.pause(); + return d; +} + +doh._testId = 0; +doh.runGroup = function(/*String*/ groupName, /*Integer*/ idx){ + // summary: + // runs the specified test group + + // the general structure of the algorithm is to run through the group's + // list of doh, checking before and after each of them to see if we're in + // a paused state. This can be caused by the test returning a deferred or + // the user hitting the pause button. In either case, we want to halt + // execution of the test until something external to us restarts it. This + // means we need to pickle off enough state to pick up where we left off. + + // FIXME: need to make fixture execution async!! + + var tg = this._groups[groupName]; + if(tg.skip === true){ return; } + if(this._isArray(tg)){ + if(idx<=tg.length){ + if((!tg.inFlight)&&(tg.iterated == true)){ + if(tg["tearDown"]){ tg.tearDown(this); } + doh._groupFinished(groupName, !tg.failures); + return; + } + } + if(!idx){ + tg.inFlight = 0; + tg.iterated = false; + tg.failures = 0; + } + doh._groupStarted(groupName); + if(!idx){ + this._setupGroupForRun(groupName, idx); + if(tg["setUp"]){ tg.setUp(this); } + } + for(var y=(idx||0); y"); + } + */ + } + } + }catch(e){ + print("\n"+doh._line); + print("The Dojo Unit Test Harness, $Rev: 20389 $"); + print("Copyright (c) 2009, The Dojo Foundation, All Rights Reserved"); + print(doh._line, "\n"); + + try{ + var dojoUrl = "../../dojo/dojo.js"; + var testUrl = ""; + var testModule = "dojo.tests.module"; + var dohBase = ""; + for(x=0; x + + + require.js: domReady Test + + + + +

      require.js: domReady Test

      +

      Check console for messages

      + + + + diff --git a/htdocs/js/lib/vendor/components/requirejs/tests/domReady/domReadyExtraConfig-tests.js b/htdocs/js/lib/vendor/components/requirejs/tests/domReady/domReadyExtraConfig-tests.js new file mode 100644 index 000000000..bb5b25c9a --- /dev/null +++ b/htdocs/js/lib/vendor/components/requirejs/tests/domReady/domReadyExtraConfig-tests.js @@ -0,0 +1,41 @@ +/*jslint */ +/*global requirejs: false, doh: false, document: false */ + +requirejs.config({ + paths: { + domReady: '../../../domReady/domReady' + } +}); + +//Event handlers can fire out of order, so way until both have fired before +//doing the final test. +var finishCounter = 0, + master = new doh.Deferred(); + +function finished() { + finishCounter += 1; + if (finishCounter === 2) { + master.callback(true); + } +} + +doh.register( + "domReadyExtraConfig", + [ + { + name: "domReadyExtraConfig", + timeout: 3000, + runTest: function () { + return master; + } + } + ] +); +doh.run(); + +requirejs(['domReady'], finished); + +require(['domReady!'], finished); + +//This should not cause a problem, but did before #398 was fixed. +require.config({ }); diff --git a/htdocs/js/lib/vendor/components/requirejs/tests/domReady/domReadyExtraConfig.html b/htdocs/js/lib/vendor/components/requirejs/tests/domReady/domReadyExtraConfig.html new file mode 100644 index 000000000..9a20eb7bf --- /dev/null +++ b/htdocs/js/lib/vendor/components/requirejs/tests/domReady/domReadyExtraConfig.html @@ -0,0 +1,17 @@ + + + + require.js: domReady Extra Config Test + + + + +

      require.js: domReady Extra Config Test

      + +

      More info in #398

      + +

      Check console for messages

      + + + + diff --git a/htdocs/js/lib/vendor/components/requirejs/tests/domReady/one.js b/htdocs/js/lib/vendor/components/requirejs/tests/domReady/one.js new file mode 100644 index 000000000..0d54b85f6 --- /dev/null +++ b/htdocs/js/lib/vendor/components/requirejs/tests/domReady/one.js @@ -0,0 +1,8 @@ +define({ + addToDom: function () { + var div = document.createElement('div'); + div.id = 'one'; + div.setAttribute('data-name', 'one'); + document.getElementsByTagName('body')[0].appendChild(div); + } +}); diff --git a/htdocs/js/lib/vendor/components/requirejs/tests/domReady/two.js b/htdocs/js/lib/vendor/components/requirejs/tests/domReady/two.js new file mode 100644 index 000000000..385b8631f --- /dev/null +++ b/htdocs/js/lib/vendor/components/requirejs/tests/domReady/two.js @@ -0,0 +1,8 @@ +define({ + addToDom: function () { + var div = document.createElement('div'); + div.id = 'two'; + div.setAttribute('data-name', 'two'); + document.getElementsByTagName('body')[0].appendChild(div); + } +}); diff --git a/htdocs/js/lib/vendor/components/requirejs/tests/dos.js b/htdocs/js/lib/vendor/components/requirejs/tests/dos.js new file mode 100644 index 000000000..1a28c6567 --- /dev/null +++ b/htdocs/js/lib/vendor/components/requirejs/tests/dos.js @@ -0,0 +1,13 @@ +define("dos", + ["tres"], + function(tres) { + return { + name: "dos", + doSomething: function() { + return { + tresName: tres.name + }; + } + }; + } +); diff --git a/htdocs/js/lib/vendor/components/requirejs/tests/error/a.js b/htdocs/js/lib/vendor/components/requirejs/tests/error/a.js new file mode 100644 index 000000000..35be9ea32 --- /dev/null +++ b/htdocs/js/lib/vendor/components/requirejs/tests/error/a.js @@ -0,0 +1,3 @@ +define({ + name: 'a' +}); diff --git a/htdocs/js/lib/vendor/components/requirejs/tests/error/b.js b/htdocs/js/lib/vendor/components/requirejs/tests/error/b.js new file mode 100644 index 000000000..b8bdcebb1 --- /dev/null +++ b/htdocs/js/lib/vendor/components/requirejs/tests/error/b.js @@ -0,0 +1,4 @@ +define({ + name: 'b' +}); + diff --git a/htdocs/js/lib/vendor/components/requirejs/tests/error/c.js b/htdocs/js/lib/vendor/components/requirejs/tests/error/c.js new file mode 100644 index 000000000..917537a7a --- /dev/null +++ b/htdocs/js/lib/vendor/components/requirejs/tests/error/c.js @@ -0,0 +1,6 @@ +define(['a'], function (a) { + return { + name: 'c', + a: a + }; +}); diff --git a/htdocs/js/lib/vendor/components/requirejs/tests/error/d.js b/htdocs/js/lib/vendor/components/requirejs/tests/error/d.js new file mode 100644 index 000000000..0d140efb1 --- /dev/null +++ b/htdocs/js/lib/vendor/components/requirejs/tests/error/d.js @@ -0,0 +1,7 @@ +define(['b'], function (b) { + return { + name: 'd', + b: b + }; +}); + diff --git a/htdocs/js/lib/vendor/components/requirejs/tests/error/defineError.js b/htdocs/js/lib/vendor/components/requirejs/tests/error/defineError.js new file mode 100644 index 000000000..15a7b4602 --- /dev/null +++ b/htdocs/js/lib/vendor/components/requirejs/tests/error/defineError.js @@ -0,0 +1,6 @@ +define(['a'], function (a) { + return { + name: 'hasDefineError', + broken: a.doesNotExist.blowsUp + }; +}); diff --git a/htdocs/js/lib/vendor/components/requirejs/tests/error/defineErrorLocal.html b/htdocs/js/lib/vendor/components/requirejs/tests/error/defineErrorLocal.html new file mode 100644 index 000000000..678374a7b --- /dev/null +++ b/htdocs/js/lib/vendor/components/requirejs/tests/error/defineErrorLocal.html @@ -0,0 +1,68 @@ + + + + require.js: Define Error Local Test + + + + + + +

      require.js: Define Error Local Test

      +

      A factory function error calls the local error handler and later loads still work.

      +

      Check console for messages

      + + diff --git a/htdocs/js/lib/vendor/components/requirejs/tests/error/errorContinue.html b/htdocs/js/lib/vendor/components/requirejs/tests/error/errorContinue.html new file mode 100644 index 000000000..b40988226 --- /dev/null +++ b/htdocs/js/lib/vendor/components/requirejs/tests/error/errorContinue.html @@ -0,0 +1,61 @@ + + + + require.js: Load Error/Continue Loading Test + + + + + + +

      require.js: Load Error/Continue Loading Test

      +

      A failure of one module does not mean later loads are broken.

      +

      Check console for messages

      + + diff --git a/htdocs/js/lib/vendor/components/requirejs/tests/error/errorContinueLocal.html b/htdocs/js/lib/vendor/components/requirejs/tests/error/errorContinueLocal.html new file mode 100644 index 000000000..ef8cd0791 --- /dev/null +++ b/htdocs/js/lib/vendor/components/requirejs/tests/error/errorContinueLocal.html @@ -0,0 +1,58 @@ + + + + require.js: Load Error/Continue Loading Local Test + + + + + + +

      require.js: Load Error/Continue Loading Local Test

      +

      A failure of one module does not mean later loads are broken.

      +

      Check console for messages

      + + diff --git a/htdocs/js/lib/vendor/components/requirejs/tests/error/plug.js b/htdocs/js/lib/vendor/components/requirejs/tests/error/plug.js new file mode 100644 index 000000000..3c562dfc3 --- /dev/null +++ b/htdocs/js/lib/vendor/components/requirejs/tests/error/plug.js @@ -0,0 +1,12 @@ +define({ + load: function (id, require, load, config) { + 'use strict'; + if (id === 'broken') { + var err = new Error('broken'); + err.plugMessage = id; + load.error(err); + } else { + load(id); + } + } +}); \ No newline at end of file diff --git a/htdocs/js/lib/vendor/components/requirejs/tests/error/pluginErrorContinue.html b/htdocs/js/lib/vendor/components/requirejs/tests/error/pluginErrorContinue.html new file mode 100644 index 000000000..651d8c698 --- /dev/null +++ b/htdocs/js/lib/vendor/components/requirejs/tests/error/pluginErrorContinue.html @@ -0,0 +1,65 @@ + + + + require.js: Plugin Load Error/Continue Loading Test + + + + + + +

      require.js: Plugin Load Error/Continue Loading Test

      +

      A failure of one plugin loaded resource does not mean later loads are broken.

      +

      Check console for messages

      + + diff --git a/htdocs/js/lib/vendor/components/requirejs/tests/error/pluginErrorContinueLocal.html b/htdocs/js/lib/vendor/components/requirejs/tests/error/pluginErrorContinueLocal.html new file mode 100644 index 000000000..64063e540 --- /dev/null +++ b/htdocs/js/lib/vendor/components/requirejs/tests/error/pluginErrorContinueLocal.html @@ -0,0 +1,55 @@ + + + + require.js: Plugin Load Error/Continue Loading Local Test + + + + + + +

      require.js: Plugin Load Error/Continue Loading Local Test

      +

      A failure of one plugin resource load does not mean later loads are broken.

      +

      Check console for messages

      + + diff --git a/htdocs/js/lib/vendor/components/requirejs/tests/exports/am.js b/htdocs/js/lib/vendor/components/requirejs/tests/exports/am.js new file mode 100644 index 000000000..f06268c8f --- /dev/null +++ b/htdocs/js/lib/vendor/components/requirejs/tests/exports/am.js @@ -0,0 +1,13 @@ +define( + [ + 'bm', + 'cm', + 'module', + 'exports' + ], + function (bm, cm, module, exports) { + exports.name = 'am'; + exports.bName = bm.name; + exports.cName = cm.name; + } +); diff --git a/htdocs/js/lib/vendor/components/requirejs/tests/exports/assign.js b/htdocs/js/lib/vendor/components/requirejs/tests/exports/assign.js new file mode 100644 index 000000000..d260a9023 --- /dev/null +++ b/htdocs/js/lib/vendor/components/requirejs/tests/exports/assign.js @@ -0,0 +1,5 @@ +define("assign", + ["require", "exports", "module"], + function (require, exports, module) { + module.exports = "assign"; +}); diff --git a/htdocs/js/lib/vendor/components/requirejs/tests/exports/assign2.js b/htdocs/js/lib/vendor/components/requirejs/tests/exports/assign2.js new file mode 100644 index 000000000..c6cd0c859 --- /dev/null +++ b/htdocs/js/lib/vendor/components/requirejs/tests/exports/assign2.js @@ -0,0 +1,4 @@ +define(["module", "exports", "require"], + function (module, exports, require) { + module.exports = "assign2"; +}); diff --git a/htdocs/js/lib/vendor/components/requirejs/tests/exports/bm.js b/htdocs/js/lib/vendor/components/requirejs/tests/exports/bm.js new file mode 100644 index 000000000..e08a3071f --- /dev/null +++ b/htdocs/js/lib/vendor/components/requirejs/tests/exports/bm.js @@ -0,0 +1,6 @@ +define([ + 'module', + 'exports' +], function (module, exports) { + exports.name = 'bm'; +}); diff --git a/htdocs/js/lib/vendor/components/requirejs/tests/exports/cm.js b/htdocs/js/lib/vendor/components/requirejs/tests/exports/cm.js new file mode 100644 index 000000000..cc0b035e6 --- /dev/null +++ b/htdocs/js/lib/vendor/components/requirejs/tests/exports/cm.js @@ -0,0 +1,6 @@ +define([ + 'module', + 'exports' +], function (module, exports) { + exports.name = 'cm'; +}); diff --git a/htdocs/js/lib/vendor/components/requirejs/tests/exports/exports-tests.js b/htdocs/js/lib/vendor/components/requirejs/tests/exports/exports-tests.js new file mode 100644 index 000000000..34d4f6676 --- /dev/null +++ b/htdocs/js/lib/vendor/components/requirejs/tests/exports/exports-tests.js @@ -0,0 +1,26 @@ +require.config({ + baseUrl: requirejs.isBrowser ? "./" : "./exports/" +}); + +require( + ["require", "vanilla", "funcSet", "assign", "assign2", "usethis", + "implicitModule", "simpleReturn"], + function(require, vanilla, funcSet, assign, assign2, usethis, + implicitModule, simpleReturn) { + doh.register( + "exports", + [ + function exports(t){ + t.is("vanilla", vanilla.name); + t.is("funcSet", funcSet); + t.is("assign", assign); + t.is("assign2", assign2); + t.is("usethis", usethis.name); + t.is("implicitModule", implicitModule()); + t.is("simpleReturn", simpleReturn()); + } + ] + ); + doh.run(); + } +); diff --git a/htdocs/js/lib/vendor/components/requirejs/tests/exports/exports.html b/htdocs/js/lib/vendor/components/requirejs/tests/exports/exports.html new file mode 100644 index 000000000..14233f9a5 --- /dev/null +++ b/htdocs/js/lib/vendor/components/requirejs/tests/exports/exports.html @@ -0,0 +1,14 @@ + + + + require.js: Exports Test + + + + + + +

      require.js: Exports Test

      +

      Check console for messages

      + + diff --git a/htdocs/js/lib/vendor/components/requirejs/tests/exports/funcSet.js b/htdocs/js/lib/vendor/components/requirejs/tests/exports/funcSet.js new file mode 100644 index 000000000..7a607e8f7 --- /dev/null +++ b/htdocs/js/lib/vendor/components/requirejs/tests/exports/funcSet.js @@ -0,0 +1,5 @@ +define("funcSet", + ["require", "exports", "module"], + function (require, exports, module) { + module.exports = "funcSet"; +}); diff --git a/htdocs/js/lib/vendor/components/requirejs/tests/exports/implicitModule.js b/htdocs/js/lib/vendor/components/requirejs/tests/exports/implicitModule.js new file mode 100644 index 000000000..4c021d375 --- /dev/null +++ b/htdocs/js/lib/vendor/components/requirejs/tests/exports/implicitModule.js @@ -0,0 +1,7 @@ +define(function (require, exports, module) { + if (module.exports) { + module.exports = function () { + return 'implicitModule'; + }; + } +}); diff --git a/htdocs/js/lib/vendor/components/requirejs/tests/exports/moduleAndExports-tests.js b/htdocs/js/lib/vendor/components/requirejs/tests/exports/moduleAndExports-tests.js new file mode 100644 index 000000000..8c2efbab6 --- /dev/null +++ b/htdocs/js/lib/vendor/components/requirejs/tests/exports/moduleAndExports-tests.js @@ -0,0 +1,18 @@ +require({ + baseUrl: requirejs.isBrowser ? "./" : "./exports/" + }, + ['am'], + function(am) { + doh.register( + "moduleAndExports", + [ + function moduleAndExports(t){ + t.is('am', am.name); + t.is('bm', am.bName); + t.is('cm', am.cName); + } + ] + ); + doh.run(); + } +); diff --git a/htdocs/js/lib/vendor/components/requirejs/tests/exports/moduleAndExports.html b/htdocs/js/lib/vendor/components/requirejs/tests/exports/moduleAndExports.html new file mode 100644 index 000000000..678dbb44e --- /dev/null +++ b/htdocs/js/lib/vendor/components/requirejs/tests/exports/moduleAndExports.html @@ -0,0 +1,14 @@ + + + + require.js: Module and Exports Test + + + + + + +

      require.js: Module and Exports Test

      +

      Check console for messages

      + + diff --git a/htdocs/js/lib/vendor/components/requirejs/tests/exports/simpleReturn.js b/htdocs/js/lib/vendor/components/requirejs/tests/exports/simpleReturn.js new file mode 100644 index 000000000..7b5e7f08c --- /dev/null +++ b/htdocs/js/lib/vendor/components/requirejs/tests/exports/simpleReturn.js @@ -0,0 +1,10 @@ +//This file does not use exports, just +//return, but need to test that it does not +//automatically get an exports object assigned +define( + function () { + return function () { + return 'simpleReturn'; + }; + } +); diff --git a/htdocs/js/lib/vendor/components/requirejs/tests/exports/usethis.js b/htdocs/js/lib/vendor/components/requirejs/tests/exports/usethis.js new file mode 100644 index 000000000..1c19f055c --- /dev/null +++ b/htdocs/js/lib/vendor/components/requirejs/tests/exports/usethis.js @@ -0,0 +1,3 @@ +define(function (require, exports) { + this.name = 'usethis'; +}); diff --git a/htdocs/js/lib/vendor/components/requirejs/tests/exports/vanilla.js b/htdocs/js/lib/vendor/components/requirejs/tests/exports/vanilla.js new file mode 100644 index 000000000..2168e47c6 --- /dev/null +++ b/htdocs/js/lib/vendor/components/requirejs/tests/exports/vanilla.js @@ -0,0 +1,5 @@ +define("vanilla", + ["require", "exports", "module"], + function (require, exports, module) { + exports.name = "vanilla"; +}); diff --git a/htdocs/js/lib/vendor/components/requirejs/tests/foo b/htdocs/js/lib/vendor/components/requirejs/tests/foo new file mode 100644 index 000000000..1b7338a03 --- /dev/null +++ b/htdocs/js/lib/vendor/components/requirejs/tests/foo @@ -0,0 +1,5 @@ +//A test for loading a file with a protocol URL via require() + +var foo = { + name: "foo" +}; \ No newline at end of file diff --git a/htdocs/js/lib/vendor/components/requirejs/tests/func.js b/htdocs/js/lib/vendor/components/requirejs/tests/func.js new file mode 100644 index 000000000..6e4775f93 --- /dev/null +++ b/htdocs/js/lib/vendor/components/requirejs/tests/func.js @@ -0,0 +1,7 @@ +define("func", + function () { + return function () { + return "You called a function"; + } + } +); diff --git a/htdocs/js/lib/vendor/components/requirejs/tests/funcFour.js b/htdocs/js/lib/vendor/components/requirejs/tests/funcFour.js new file mode 100644 index 000000000..12db975ad --- /dev/null +++ b/htdocs/js/lib/vendor/components/requirejs/tests/funcFour.js @@ -0,0 +1,14 @@ +define("funcFour", + ["require", "funcThree"], + function (require) { + var four = function (arg) { + return "FOUR called with " + arg; + }; + + four.suffix = function () { + return require("funcThree").suffix(); + }; + + return four; + } +); diff --git a/htdocs/js/lib/vendor/components/requirejs/tests/funcOne.js b/htdocs/js/lib/vendor/components/requirejs/tests/funcOne.js new file mode 100644 index 000000000..4620592aa --- /dev/null +++ b/htdocs/js/lib/vendor/components/requirejs/tests/funcOne.js @@ -0,0 +1,15 @@ +define("funcOne", + ["require", "funcTwo"], + function (require) { + var one = function (name) { + this.name = name; + }; + + one.prototype.getName = function () { + var inst = new (require("funcTwo"))("-NESTED"); + return this.name + inst.name; + }; + + return one; + } +); diff --git a/htdocs/js/lib/vendor/components/requirejs/tests/funcThree.js b/htdocs/js/lib/vendor/components/requirejs/tests/funcThree.js new file mode 100644 index 000000000..b02bf89ee --- /dev/null +++ b/htdocs/js/lib/vendor/components/requirejs/tests/funcThree.js @@ -0,0 +1,14 @@ +define("funcThree", + ["funcFour"], + function (four) { + var three = function (arg) { + return arg + "-" + require("funcFour").suffix(); + }; + + three.suffix = function () { + return "THREE_SUFFIX"; + }; + + return three; + } +); diff --git a/htdocs/js/lib/vendor/components/requirejs/tests/funcTwo.js b/htdocs/js/lib/vendor/components/requirejs/tests/funcTwo.js new file mode 100644 index 000000000..38afc0eeb --- /dev/null +++ b/htdocs/js/lib/vendor/components/requirejs/tests/funcTwo.js @@ -0,0 +1,15 @@ +define("funcTwo", + ["require", "funcOne"], + function (require) { + var two = function (name) { + this.name = name; + this.one = new (require("funcOne"))("ONE"); + }; + + two.prototype.oneName = function () { + return this.one.getName(); + }; + + return two; + } +); diff --git a/htdocs/js/lib/vendor/components/requirejs/tests/i18n/common.html b/htdocs/js/lib/vendor/components/requirejs/tests/i18n/common.html new file mode 100644 index 000000000..114dff251 --- /dev/null +++ b/htdocs/js/lib/vendor/components/requirejs/tests/i18n/common.html @@ -0,0 +1,51 @@ + + + + require.js: Common I18N Test + + + + + + +

      Common i18n bundle test

      +

      This page tests for an i18n plugin resource that is specified by two different modules.

      + + diff --git a/htdocs/js/lib/vendor/components/requirejs/tests/i18n/commonA.js b/htdocs/js/lib/vendor/components/requirejs/tests/i18n/commonA.js new file mode 100644 index 000000000..fcdf9746b --- /dev/null +++ b/htdocs/js/lib/vendor/components/requirejs/tests/i18n/commonA.js @@ -0,0 +1,3 @@ +define(['i18n!nls/colors'], function (colors) { + return colors.red; +}); diff --git a/htdocs/js/lib/vendor/components/requirejs/tests/i18n/commonB.js b/htdocs/js/lib/vendor/components/requirejs/tests/i18n/commonB.js new file mode 100644 index 000000000..3e7c43e99 --- /dev/null +++ b/htdocs/js/lib/vendor/components/requirejs/tests/i18n/commonB.js @@ -0,0 +1,3 @@ +define(['i18n!nls/colors'], function (colors) { + return colors.blue; +}); diff --git a/htdocs/js/lib/vendor/components/requirejs/tests/i18n/i18n.html b/htdocs/js/lib/vendor/components/requirejs/tests/i18n/i18n.html new file mode 100644 index 000000000..c4b9bad5b --- /dev/null +++ b/htdocs/js/lib/vendor/components/requirejs/tests/i18n/i18n.html @@ -0,0 +1,82 @@ + + + + require.js: I18N Test + + + + + + +

      i18n bundle test

      +

      This page tests the i18n bundling in require.js. You can change the locale to use by passing locale= or bundle=

      + + diff --git a/htdocs/js/lib/vendor/components/requirejs/tests/i18n/nls/colors.js b/htdocs/js/lib/vendor/components/requirejs/tests/i18n/nls/colors.js new file mode 100644 index 000000000..4090dc16d --- /dev/null +++ b/htdocs/js/lib/vendor/components/requirejs/tests/i18n/nls/colors.js @@ -0,0 +1,17 @@ +define({ + "root": { + red: "red", + blue: "blue", + green: "green", + black: { + opacity: 1, + rgb: { + r: "0", + g: "0", + b: "0" + } + } + }, + "en-us-surfer": true, + "fr": true +}); diff --git a/htdocs/js/lib/vendor/components/requirejs/tests/i18n/nls/en-us-surfer/colors.js b/htdocs/js/lib/vendor/components/requirejs/tests/i18n/nls/en-us-surfer/colors.js new file mode 100644 index 000000000..08d46129d --- /dev/null +++ b/htdocs/js/lib/vendor/components/requirejs/tests/i18n/nls/en-us-surfer/colors.js @@ -0,0 +1,6 @@ +define({ + red: "red, dude", + black: { + opacity: 0.5 + } +}); diff --git a/htdocs/js/lib/vendor/components/requirejs/tests/i18n/nls/fr/colors.js b/htdocs/js/lib/vendor/components/requirejs/tests/i18n/nls/fr/colors.js new file mode 100644 index 000000000..c5392fc80 --- /dev/null +++ b/htdocs/js/lib/vendor/components/requirejs/tests/i18n/nls/fr/colors.js @@ -0,0 +1,4 @@ +define({ + red: "rouge", + blue: "bleu" +}); diff --git a/htdocs/js/lib/vendor/components/requirejs/tests/i18n/testModule.js b/htdocs/js/lib/vendor/components/requirejs/tests/i18n/testModule.js new file mode 100644 index 000000000..ad6901582 --- /dev/null +++ b/htdocs/js/lib/vendor/components/requirejs/tests/i18n/testModule.js @@ -0,0 +1,5 @@ +//A sample module to use in the i18n build test. + +define(["i18n!nls/colors"], function (colors) { + var red = colors.red; +}); \ No newline at end of file diff --git a/htdocs/js/lib/vendor/components/requirejs/tests/index.html b/htdocs/js/lib/vendor/components/requirejs/tests/index.html new file mode 100644 index 000000000..ffa986177 --- /dev/null +++ b/htdocs/js/lib/vendor/components/requirejs/tests/index.html @@ -0,0 +1,12 @@ + + + + require.js: Tests + + +

      require.js: Tests

      +
        +
      1. All Automated Tests +
      + + diff --git a/htdocs/js/lib/vendor/components/requirejs/tests/isBrowser/a.js b/htdocs/js/lib/vendor/components/requirejs/tests/isBrowser/a.js new file mode 100644 index 000000000..5fe6afd5a --- /dev/null +++ b/htdocs/js/lib/vendor/components/requirejs/tests/isBrowser/a.js @@ -0,0 +1,5 @@ +define(function (require) { + return { + isBrowser: require.isBrowser + }; +}); diff --git a/htdocs/js/lib/vendor/components/requirejs/tests/isBrowser/isBrowser-tests.js b/htdocs/js/lib/vendor/components/requirejs/tests/isBrowser/isBrowser-tests.js new file mode 100644 index 000000000..0a37582a1 --- /dev/null +++ b/htdocs/js/lib/vendor/components/requirejs/tests/isBrowser/isBrowser-tests.js @@ -0,0 +1,17 @@ +require({ + baseUrl: "./" + }, + ["a"], + function(a) { + doh.register( + "isBrowser", + [ + function isBrowser(t){ + t.is(true, a.isBrowser); + t.is(true, requirejs.isBrowser); + } + ] + ); + doh.run(); + } +); diff --git a/htdocs/js/lib/vendor/components/requirejs/tests/isBrowser/isBrowser.html b/htdocs/js/lib/vendor/components/requirejs/tests/isBrowser/isBrowser.html new file mode 100644 index 000000000..647cdd9e7 --- /dev/null +++ b/htdocs/js/lib/vendor/components/requirejs/tests/isBrowser/isBrowser.html @@ -0,0 +1,16 @@ + + + + require.js: isBrowser Test + + + + + + +

      require.js: isBrowser Test

      +

      Confirm isBrowser is available since it is used by others now. + Info in Issue 293.

      +

      Check console for messages

      + + diff --git a/htdocs/js/lib/vendor/components/requirejs/tests/issue379/issue379.html b/htdocs/js/lib/vendor/components/requirejs/tests/issue379/issue379.html new file mode 100644 index 000000000..0dc38f742 --- /dev/null +++ b/htdocs/js/lib/vendor/components/requirejs/tests/issue379/issue379.html @@ -0,0 +1,14 @@ + + + + require.js: Bug 379 Test + + + + + +

      require.js: Bug 379 Test

      +

      More info.

      +

      Check console for messages

      + + diff --git a/htdocs/js/lib/vendor/components/requirejs/tests/issue379/issue379.js b/htdocs/js/lib/vendor/components/requirejs/tests/issue379/issue379.js new file mode 100644 index 000000000..a6991aed0 --- /dev/null +++ b/htdocs/js/lib/vendor/components/requirejs/tests/issue379/issue379.js @@ -0,0 +1,31 @@ +define('a',[], {}); + +define('text!template.html',[],function () { return 'TEXT';}); + +define('b',['text!template.html'], function(tmpl) { + return 'b ' + tmpl; +}); + +define('c',['text!template.html'], function(tmpl) { + return 'c ' + tmpl; +}); + +require(['a'], function (a) { + require({ + paths: { + 'text': '../../../text/text' + } + }, ['b', 'c'], function(b, c) { + + doh.register( + "issue379", + [ + function issue379(t){ + t.is('b TEXT', b); + t.is('c TEXT', c); + } + ] + ); + doh.run(); + }); +}); \ No newline at end of file diff --git a/htdocs/js/lib/vendor/components/requirejs/tests/jquery/jquery.html b/htdocs/js/lib/vendor/components/requirejs/tests/jquery/jquery.html new file mode 100644 index 000000000..a56deefc3 --- /dev/null +++ b/htdocs/js/lib/vendor/components/requirejs/tests/jquery/jquery.html @@ -0,0 +1,33 @@ + + + + jQuery+RequireJS Sample Page + + + + + + + +

      jQuery+RequireJS Test Page

      +

      Tests loading of jquery plugins with require.

      + + diff --git a/htdocs/js/lib/vendor/components/requirejs/tests/jquery/jqueryDynamic.html b/htdocs/js/lib/vendor/components/requirejs/tests/jquery/jqueryDynamic.html new file mode 100644 index 000000000..2527b3647 --- /dev/null +++ b/htdocs/js/lib/vendor/components/requirejs/tests/jquery/jqueryDynamic.html @@ -0,0 +1,38 @@ + + + + jQuery+RequireJS Sample Page + + + + + + +

      jQuery+RequireJS Test Page

      +

      Tests loading of jquery plugins with require.

      + + diff --git a/htdocs/js/lib/vendor/components/requirejs/tests/jquery/jqueryDynamic2.html b/htdocs/js/lib/vendor/components/requirejs/tests/jquery/jqueryDynamic2.html new file mode 100644 index 000000000..4f11706a3 --- /dev/null +++ b/htdocs/js/lib/vendor/components/requirejs/tests/jquery/jqueryDynamic2.html @@ -0,0 +1,45 @@ + + + + jQuery+RequireJS Sample Page + + + + + + +

      jQuery+RequireJS Test Page

      +

      Tests loading of jquery plugins with require.

      + + diff --git a/htdocs/js/lib/vendor/components/requirejs/tests/jquery/scripts/app.js b/htdocs/js/lib/vendor/components/requirejs/tests/jquery/scripts/app.js new file mode 100644 index 000000000..295ebe0c6 --- /dev/null +++ b/htdocs/js/lib/vendor/components/requirejs/tests/jquery/scripts/app.js @@ -0,0 +1 @@ +define(["jquery.alpha", "jquery.beta"], function() {}); diff --git a/htdocs/js/lib/vendor/components/requirejs/tests/jquery/scripts/dynamicApp.js b/htdocs/js/lib/vendor/components/requirejs/tests/jquery/scripts/dynamicApp.js new file mode 100644 index 000000000..b652ad257 --- /dev/null +++ b/htdocs/js/lib/vendor/components/requirejs/tests/jquery/scripts/dynamicApp.js @@ -0,0 +1,18 @@ +require({ + "baseUrl": "./scripts/", + "paths": { + "jquery": "http://ajax.microsoft.com/ajax/jQuery/jquery-1.7.1.min" + //"jquery": "http://ajax.googleapis.com/ajax/libs/jquery/1.4.4/jquery.min" + }, + priority: ['jquery'] +}); + +define(["jquery.gamma", "jquery.epsilon"], function() { + + $(function () { + doh.is('epsilon', $('body').epsilon()); + doh.is('epsilon', $('body').epsilon()); + readyFired(); + }); + +}); diff --git a/htdocs/js/lib/vendor/components/requirejs/tests/jquery/scripts/jquery-1.7.1.js b/htdocs/js/lib/vendor/components/requirejs/tests/jquery/scripts/jquery-1.7.1.js new file mode 100644 index 000000000..8ccd0ea78 --- /dev/null +++ b/htdocs/js/lib/vendor/components/requirejs/tests/jquery/scripts/jquery-1.7.1.js @@ -0,0 +1,9266 @@ +/*! + * jQuery JavaScript Library v1.7.1 + * 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: Mon Nov 21 21:11:03 2011 -0500 + */ +(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 + // Prioritize #id over to avoid XSS via location.hash (#9521) + 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+$/, + + // 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]|[0-9])/ig, + rmsPrefix = /^-ms-/, + + // 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.7.1", + + // 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.add( fn ); + + return this; + }, + + eq: function( i ) { + i = +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.fireWith( document, [ jQuery ] ); + + // Trigger any bound ready events + if ( jQuery.fn.trigger ) { + jQuery( document ).trigger( "ready" ).off( "ready" ); + } + } + }, + + bindReady: function() { + if ( readyList ) { + return; + } + + readyList = jQuery.Callbacks( "once memory" ); + + // 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; + }, + + isNumeric: function( obj ) { + return !isNaN( parseFloat(obj) ) && isFinite( 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; + } + + try { + // Not own constructor property must be Object + if ( obj.constructor && + !hasOwn.call(obj, "constructor") && + !hasOwn.call(obj.constructor.prototype, "isPrototypeOf") ) { + return false; + } + } catch ( e ) { + // IE8,9 Will throw exceptions on certain host objects #9897 + 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 new Error( 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 + parseXML: function( data ) { + var xml, tmp; + try { + 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 ); + } + } catch( e ) { + xml = undefined; + } + if ( !xml || !xml.documentElement || xml.getElementsByTagName( "parsererror" ).length ) { + 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 ); + } + }, + + // Convert dashed to camelCase; used by the css and data modules + // Microsoft forgot to hump their vendor prefix (#9572) + camelCase: function( string ) { + return string.replace( rmsPrefix, "ms-" ).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' + // 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, i ) { + var len; + + if ( array ) { + if ( indexOf ) { + return indexOf.call( array, elem, i ); + } + + len = array.length; + i = i ? i < 0 ? Math.max( 0, len + i ) : i : 0; + + for ( ; i < len; i++ ) { + // Skip accessing in sparse arrays + if ( i in array && 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; + +})(); + + +// String to Object flags format cache +var flagsCache = {}; + +// Convert String-formatted flags into Object-formatted ones and store in cache +function createFlags( flags ) { + var object = flagsCache[ flags ] = {}, + i, length; + flags = flags.split( /\s+/ ); + for ( i = 0, length = flags.length; i < length; i++ ) { + object[ flags[i] ] = true; + } + return object; +} + +/* + * Create a callback list using the following parameters: + * + * flags: an optional list of space-separated flags that will change how + * the callback list behaves + * + * By default a callback list will act like an event callback list and can be + * "fired" multiple times. + * + * Possible flags: + * + * once: will ensure the callback list can only be fired once (like a Deferred) + * + * memory: will keep track of previous values and will call any callback added + * after the list has been fired right away with the latest "memorized" + * values (like a Deferred) + * + * unique: will ensure a callback can only be added once (no duplicate in the list) + * + * stopOnFalse: interrupt callings when a callback returns false + * + */ +jQuery.Callbacks = function( flags ) { + + // Convert flags from String-formatted to Object-formatted + // (we check in cache first) + flags = flags ? ( flagsCache[ flags ] || createFlags( flags ) ) : {}; + + var // Actual callback list + list = [], + // Stack of fire calls for repeatable lists + stack = [], + // Last fire value (for non-forgettable lists) + memory, + // Flag to know if list is currently firing + firing, + // First callback to fire (used internally by add and fireWith) + firingStart, + // End of the loop when firing + firingLength, + // Index of currently firing callback (modified by remove if needed) + firingIndex, + // Add one or several callbacks to the list + add = function( args ) { + var i, + length, + elem, + type, + actual; + for ( i = 0, length = args.length; i < length; i++ ) { + elem = args[ i ]; + type = jQuery.type( elem ); + if ( type === "array" ) { + // Inspect recursively + add( elem ); + } else if ( type === "function" ) { + // Add if not in unique mode and callback is not in + if ( !flags.unique || !self.has( elem ) ) { + list.push( elem ); + } + } + } + }, + // Fire callbacks + fire = function( context, args ) { + args = args || []; + memory = !flags.memory || [ context, args ]; + firing = true; + firingIndex = firingStart || 0; + firingStart = 0; + firingLength = list.length; + for ( ; list && firingIndex < firingLength; firingIndex++ ) { + if ( list[ firingIndex ].apply( context, args ) === false && flags.stopOnFalse ) { + memory = true; // Mark as halted + break; + } + } + firing = false; + if ( list ) { + if ( !flags.once ) { + if ( stack && stack.length ) { + memory = stack.shift(); + self.fireWith( memory[ 0 ], memory[ 1 ] ); + } + } else if ( memory === true ) { + self.disable(); + } else { + list = []; + } + } + }, + // Actual Callbacks object + self = { + // Add a callback or a collection of callbacks to the list + add: function() { + if ( list ) { + var length = list.length; + add( arguments ); + // Do we need to add the callbacks to the + // current firing batch? + if ( firing ) { + firingLength = list.length; + // With memory, if we're not firing then + // we should call right away, unless previous + // firing was halted (stopOnFalse) + } else if ( memory && memory !== true ) { + firingStart = length; + fire( memory[ 0 ], memory[ 1 ] ); + } + } + return this; + }, + // Remove a callback from the list + remove: function() { + if ( list ) { + var args = arguments, + argIndex = 0, + argLength = args.length; + for ( ; argIndex < argLength ; argIndex++ ) { + for ( var i = 0; i < list.length; i++ ) { + if ( args[ argIndex ] === list[ i ] ) { + // Handle firingIndex and firingLength + if ( firing ) { + if ( i <= firingLength ) { + firingLength--; + if ( i <= firingIndex ) { + firingIndex--; + } + } + } + // Remove the element + list.splice( i--, 1 ); + // If we have some unicity property then + // we only need to do this once + if ( flags.unique ) { + break; + } + } + } + } + } + return this; + }, + // Control if a given callback is in the list + has: function( fn ) { + if ( list ) { + var i = 0, + length = list.length; + for ( ; i < length; i++ ) { + if ( fn === list[ i ] ) { + return true; + } + } + } + return false; + }, + // Remove all callbacks from the list + empty: function() { + list = []; + return this; + }, + // Have the list do nothing anymore + disable: function() { + list = stack = memory = undefined; + return this; + }, + // Is it disabled? + disabled: function() { + return !list; + }, + // Lock the list in its current state + lock: function() { + stack = undefined; + if ( !memory || memory === true ) { + self.disable(); + } + return this; + }, + // Is it locked? + locked: function() { + return !stack; + }, + // Call all callbacks with the given context and arguments + fireWith: function( context, args ) { + if ( stack ) { + if ( firing ) { + if ( !flags.once ) { + stack.push( [ context, args ] ); + } + } else if ( !( flags.once && memory ) ) { + fire( context, args ); + } + } + return this; + }, + // Call all the callbacks with the given arguments + fire: function() { + self.fireWith( this, arguments ); + return this; + }, + // To know if the callbacks have already been called at least once + fired: function() { + return !!memory; + } + }; + + return self; +}; + + + + +var // Static reference to slice + sliceDeferred = [].slice; + +jQuery.extend({ + + Deferred: function( func ) { + var doneList = jQuery.Callbacks( "once memory" ), + failList = jQuery.Callbacks( "once memory" ), + progressList = jQuery.Callbacks( "memory" ), + state = "pending", + lists = { + resolve: doneList, + reject: failList, + notify: progressList + }, + promise = { + done: doneList.add, + fail: failList.add, + progress: progressList.add, + + state: function() { + return state; + }, + + // Deprecated + isResolved: doneList.fired, + isRejected: failList.fired, + + then: function( doneCallbacks, failCallbacks, progressCallbacks ) { + deferred.done( doneCallbacks ).fail( failCallbacks ).progress( progressCallbacks ); + return this; + }, + always: function() { + deferred.done.apply( deferred, arguments ).fail.apply( deferred, arguments ); + return this; + }, + pipe: function( fnDone, fnFail, fnProgress ) { + return jQuery.Deferred(function( newDefer ) { + jQuery.each( { + done: [ fnDone, "resolve" ], + fail: [ fnFail, "reject" ], + progress: [ fnProgress, "notify" ] + }, 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, newDefer.notify ); + } else { + newDefer[ action + "With" ]( this === deferred ? newDefer : this, [ 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 ) { + obj = promise; + } else { + for ( var key in promise ) { + obj[ key ] = promise[ key ]; + } + } + return obj; + } + }, + deferred = promise.promise({}), + key; + + for ( key in lists ) { + deferred[ key ] = lists[ key ].fire; + deferred[ key + "With" ] = lists[ key ].fireWith; + } + + // Handle state + deferred.done( function() { + state = "resolved"; + }, failList.disable, progressList.lock ).fail( function() { + state = "rejected"; + }, doneList.disable, progressList.lock ); + + // Call given func if any + if ( func ) { + func.call( deferred, deferred ); + } + + // All done! + return deferred; + }, + + // Deferred helper + when: function( firstParam ) { + var args = sliceDeferred.call( arguments, 0 ), + i = 0, + length = args.length, + pValues = new Array( length ), + count = length, + pCount = length, + deferred = length <= 1 && firstParam && jQuery.isFunction( firstParam.promise ) ? + firstParam : + jQuery.Deferred(), + promise = deferred.promise(); + function resolveFunc( i ) { + return function( value ) { + args[ i ] = arguments.length > 1 ? sliceDeferred.call( arguments, 0 ) : value; + if ( !( --count ) ) { + deferred.resolveWith( deferred, args ); + } + }; + } + function progressFunc( i ) { + return function( value ) { + pValues[ i ] = arguments.length > 1 ? sliceDeferred.call( arguments, 0 ) : value; + deferred.notifyWith( promise, pValues ); + }; + } + if ( length > 1 ) { + for ( ; i < length; i++ ) { + if ( args[ i ] && args[ i ].promise && jQuery.isFunction( args[ i ].promise ) ) { + args[ i ].promise().then( resolveFunc(i), deferred.reject, progressFunc(i) ); + } else { + --count; + } + } + if ( !count ) { + deferred.resolveWith( deferred, args ); + } + } else if ( deferred !== firstParam ) { + deferred.resolveWith( deferred, length ? [ firstParam ] : [] ); + } + return promise; + } +}); + + + + +jQuery.support = (function() { + + var support, + all, + a, + select, + opt, + input, + marginDiv, + fragment, + tds, + events, + eventName, + i, + isSupported, + div = document.createElement( "div" ), + documentElement = document.documentElement; + + // 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", + + // Tests for enctype support on a form(#6743) + enctype: !!document.createElement("form").enctype, + + // Makes sure cloning an html5 element does not cause problems + // Where outerHTML is undefined, this still works + html5Clone: document.createElement("nav").cloneNode( true ).outerHTML !== "<:nav>", + + // 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 its 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.lastChild ); + + // WebKit doesn't clone checked state correctly in fragments + support.checkClone = fragment.cloneNode( true ).cloneNode( true ).lastChild.checked; + + // Check if a disconnected checkbox will retain its checked + // value of true after appended to the DOM (IE6/7) + support.appendChecked = input.checked; + + fragment.removeChild( input ); + fragment.appendChild( div ); + + 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 ( window.getComputedStyle ) { + marginDiv = document.createElement( "div" ); + marginDiv.style.width = "0"; + marginDiv.style.marginRight = "0"; + div.style.width = "2px"; + div.appendChild( marginDiv ); + support.reliableMarginRight = + ( parseInt( ( window.getComputedStyle( marginDiv, null ) || { marginRight: 0 } ).marginRight, 10 ) || 0 ) === 0; + } + + // Technique from Juriy Zaytsev + // http://perfectionkills.com/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; + } + } + + fragment.removeChild( div ); + + // Null elements to avoid leaks in IE + fragment = select = opt = marginDiv = div = input = null; + + // Run tests that need a body at doc ready + jQuery(function() { + var container, outer, inner, table, td, offsetSupport, + conMarginTop, ptlm, vb, style, html, + body = document.getElementsByTagName("body")[0]; + + if ( !body ) { + // Return for frameset docs that don't have a body + return; + } + + conMarginTop = 1; + ptlm = "position:absolute;top:0;left:0;width:1px;height:1px;margin:0;"; + vb = "visibility:hidden;border:0;"; + style = "style='" + ptlm + "border:5px solid #000;padding:0;'"; + html = "
      " + + "" + + "
      "; + + container = document.createElement("div"); + container.style.cssText = vb + "width:0;height:0;position:static;top:0;margin-top:" + conMarginTop + "px"; + body.insertBefore( container, body.firstChild ); + + // Construct the test element + div = document.createElement("div"); + container.appendChild( div ); + + // 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) + div.innerHTML = "
      t
      "; + tds = div.getElementsByTagName( "td" ); + 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 ); + + // Figure out if the W3C box model works as expected + div.innerHTML = ""; + div.style.width = div.style.paddingLeft = "1px"; + jQuery.boxModel = support.boxModel = div.offsetWidth === 2; + + if ( typeof div.style.zoom !== "undefined" ) { + // 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.style.cssText = ptlm + vb; + div.innerHTML = html; + + outer = div.firstChild; + inner = outer.firstChild; + td = outer.nextSibling.firstChild.firstChild; + + offsetSupport = { + doesNotAddBorder: ( inner.offsetTop !== 5 ), + doesAddBorderForTableAndCells: ( td.offsetTop === 5 ) + }; + + inner.style.position = "fixed"; + inner.style.top = "20px"; + + // safari subtracts parent border width here which is 5px + offsetSupport.fixedPosition = ( inner.offsetTop === 20 || inner.offsetTop === 15 ); + inner.style.position = inner.style.top = ""; + + outer.style.overflow = "hidden"; + outer.style.position = "relative"; + + offsetSupport.subtractsBorderForOverflowNotVisible = ( inner.offsetTop === -5 ); + offsetSupport.doesNotIncludeMarginInBodyOffset = ( body.offsetTop !== conMarginTop ); + + body.removeChild( container ); + div = container = null; + + jQuery.extend( support, offsetSupport ); + }); + + return support; +})(); + + + + +var rbrace = /^(?:\{.*\}|\[.*\])$/, + rmultiDash = /([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 privateCache, thisCache, ret, + internalKey = jQuery.expando, + getByName = typeof name === "string", + + // 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[ internalKey ] : elem[ internalKey ] && internalKey, + isEvents = name === "events"; + + // 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 || !cache[id] || (!isEvents && !pvt && !cache[id].data)) && 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[ internalKey ] = id = ++jQuery.uuid; + } else { + id = internalKey; + } + } + + if ( !cache[ id ] ) { + cache[ id ] = {}; + + // 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 ] = jQuery.extend( cache[ id ], name ); + } else { + cache[ id ].data = jQuery.extend( cache[ id ].data, name ); + } + } + + privateCache = thisCache = cache[ id ]; + + // jQuery data() is stored in a separate object inside the object's internal data + // cache in order to avoid key collisions between internal data and user-defined + // data. + if ( !pvt ) { + if ( !thisCache.data ) { + thisCache.data = {}; + } + + thisCache = thisCache.data; + } + + if ( data !== undefined ) { + thisCache[ jQuery.camelCase( name ) ] = data; + } + + // Users should not attempt to inspect the internal events object using jQuery.data, + // it is undocumented and subject to change. But does anyone listen? No. + if ( isEvents && !thisCache[ name ] ) { + return privateCache.events; + } + + // Check for both converted-to-camel and non-converted data property names + // If a data property was specified + if ( getByName ) { + + // First Try to find as-is property data + ret = thisCache[ name ]; + + // Test for null|undefined property data + if ( ret == null ) { + + // Try to find the camelCased property + ret = thisCache[ jQuery.camelCase( name ) ]; + } + } else { + ret = thisCache; + } + + return ret; + }, + + removeData: function( elem, name, pvt /* Internal Use Only */ ) { + if ( !jQuery.acceptData( elem ) ) { + return; + } + + var thisCache, i, l, + + // Reference to internal data cache key + 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[ internalKey ] : internalKey; + + // If there is already no cache entry for this object, there is no + // purpose in continuing + if ( !cache[ id ] ) { + return; + } + + if ( name ) { + + thisCache = pvt ? cache[ id ] : cache[ id ].data; + + if ( thisCache ) { + + // Support array or space separated string names for data keys + if ( !jQuery.isArray( name ) ) { + + // try the string as a key before any manipulation + if ( name in thisCache ) { + name = [ name ]; + } else { + + // split the camel cased version by spaces unless a key with the spaces exists + name = jQuery.camelCase( name ); + if ( name in thisCache ) { + name = [ name ]; + } else { + name = name.split( " " ); + } + } + } + + for ( i = 0, l = name.length; i < l; i++ ) { + delete thisCache[ name[i] ]; + } + + // If there is no data left in the cache, we want to continue + // and let the cache object itself get destroyed + if ( !( pvt ? isEmptyDataObject : jQuery.isEmptyObject )( thisCache ) ) { + return; + } + } + } + + // See jQuery.data for more information + if ( !pvt ) { + delete cache[ id ].data; + + // Don't destroy the parent cache unless the internal data object + // had been the only thing left in it + if ( !isEmptyDataObject(cache[ id ]) ) { + return; + } + } + + // 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 + // Ensure that `cache` is not a window object #10080 + if ( jQuery.support.deleteExpando || !cache.setInterval ) { + delete cache[ id ]; + } else { + cache[ id ] = null; + } + + // We destroyed the cache and need to eliminate the expando on the node to avoid + // false lookups in the cache for entries that no longer exist + 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[ internalKey ]; + } else if ( elem.removeAttribute ) { + elem.removeAttribute( internalKey ); + } else { + elem[ internalKey ] = 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 parts, attr, name, + data = null; + + if ( typeof key === "undefined" ) { + if ( this.length ) { + data = jQuery.data( this[0] ); + + if ( this[0].nodeType === 1 && !jQuery._data( this[0], "parsedAttrs" ) ) { + attr = this[0].attributes; + 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 ] ); + } + } + jQuery._data( this[0], "parsedAttrs", true ); + } + } + + return data; + + } else if ( typeof key === "object" ) { + return this.each(function() { + jQuery.data( this, key ); + }); + } + + 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 self = jQuery( this ), + args = [ parts[0], value ]; + + self.triggerHandler( "setData" + parts[1] + "!", args ); + jQuery.data( this, key, value ); + self.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" ).toLowerCase(); + + data = elem.getAttribute( name ); + + if ( typeof data === "string" ) { + try { + data = data === "true" ? true : + data === "false" ? false : + data === "null" ? null : + jQuery.isNumeric( 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; +} + +// checks a cache object for emptiness +function isEmptyDataObject( obj ) { + for ( var name in obj ) { + + // if the public data object is empty, the private is still empty + if ( name === "data" && jQuery.isEmptyObject( obj[name] ) ) { + continue; + } + 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 ); + if ( defer && + ( src === "queue" || !jQuery._data(elem, queueDataKey) ) && + ( src === "mark" || !jQuery._data(elem, markDataKey) ) ) { + // 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 ) && + !jQuery._data( elem, markDataKey ) ) { + jQuery.removeData( elem, deferDataKey, true ); + defer.fire(); + } + }, 0 ); + } +} + +jQuery.extend({ + + _mark: function( elem, type ) { + if ( elem ) { + type = ( type || "fx" ) + "mark"; + jQuery._data( elem, type, (jQuery._data( elem, type ) || 0) + 1 ); + } + }, + + _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 ) || 1) - 1 ); + if ( count ) { + jQuery._data( elem, key, count ); + } else { + jQuery.removeData( elem, key, true ); + handleQueueMarkDefer( elem, type, "mark" ); + } + } + }, + + queue: function( elem, type, data ) { + var q; + if ( elem ) { + type = ( type || "fx" ) + "queue"; + q = jQuery._data( elem, type ); + + // 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) ); + } else { + q.push( data ); + } + } + return q || []; + } + }, + + dequeue: function( elem, type ) { + type = type || "fx"; + + var queue = jQuery.queue( elem, type ), + fn = queue.shift(), + hooks = {}; + + // 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" ); + } + + jQuery._data( elem, type + ".run", hooks ); + fn.call( elem, function() { + jQuery.dequeue( elem, type ); + }, hooks ); + } + + if ( !queue.length ) { + jQuery.removeData( elem, type + "queue " + type + ".run", 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( next, hooks ) { + var timeout = setTimeout( next, time ); + hooks.stop = function() { + clearTimeout( timeout ); + }; + }); + }, + 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.Callbacks( "once memory" ), true ) )) { + count++; + tmp.add( 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, + getSetAttribute = jQuery.support.getSetAttribute, + nodeHook, boolHook, fixSpecified; + +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 + " ", + i = 0, + l = this.length; + for ( ; i < l; i++ ) { + if ( this[i].nodeType === 1 && (" " + this[i].className + " ").replace(rclass, " ").indexOf( className ) > -1 ) { + return true; + } + } + + return false; + }, + + val: function( value ) { + var hooks, ret, isFunction, + 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; + } + + 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, i, max, option, + 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 + i = one ? index : 0; + max = one ? index + 1 : options.length; + for ( ; i < max; i++ ) { + 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 + }, + + attr: function( elem, name, value, pass ) { + var ret, hooks, notxml, + nType = elem.nodeType; + + // don't get/set attributes on text, comment and attribute nodes + if ( !elem || nType === 3 || nType === 8 || nType === 2 ) { + return; + } + + if ( pass && name in jQuery.attrFn ) { + return jQuery( elem )[ name ]( value ); + } + + // Fallback to prop when attributes are not supported + if ( typeof elem.getAttribute === "undefined" ) { + return jQuery.prop( elem, name, value ); + } + + notxml = nType !== 1 || !jQuery.isXMLDoc( elem ); + + // All attributes are lowercase + // Grab necessary hook if one is defined + if ( notxml ) { + name = name.toLowerCase(); + hooks = jQuery.attrHooks[ name ] || ( rboolean.test( name ) ? boolHook : nodeHook ); + } + + if ( value !== undefined ) { + + if ( value === null ) { + jQuery.removeAttr( elem, name ); + return; + + } 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, value ) { + var propName, attrNames, name, l, + i = 0; + + if ( value && elem.nodeType === 1 ) { + attrNames = value.toLowerCase().split( rspace ); + l = attrNames.length; + + for ( ; i < l; i++ ) { + name = attrNames[ i ]; + + if ( name ) { + propName = jQuery.propFix[ name ] || name; + + // See #9699 for explanation of this approach (setting first, then removal) + jQuery.attr( elem, name, "" ); + elem.removeAttribute( getSetAttribute ? name : propName ); + + // Set corresponding property to false for boolean attributes + if ( rboolean.test( name ) && propName 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; + } + } + }, + // Use the value property for back compat + // Use the nodeHook for button elements in IE6/7 (#1954) + value: { + get: function( elem, name ) { + if ( nodeHook && jQuery.nodeName( elem, "button" ) ) { + return nodeHook.get( elem, name ); + } + return name in elem ? + elem.value : + null; + }, + set: function( elem, value, name ) { + if ( nodeHook && jQuery.nodeName( elem, "button" ) ) { + return nodeHook.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 ret, hooks, notxml, + nType = elem.nodeType; + + // don't get/set properties on text, comment and attribute nodes + if ( !elem || nType === 3 || nType === 8 || nType === 2 ) { + return; + } + + 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 )) !== null ) { + return ret; + + } else { + return elem[ name ]; + } + } + }, + + propHooks: { + 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; + } + } + } +}); + +// Add the tabIndex propHook to attrHooks for back-compat (different case is intentional) +jQuery.attrHooks.tabindex = jQuery.propHooks.tabIndex; + +// Hook for boolean attributes +boolHook = { + get: function( elem, name ) { + // Align boolean attributes with corresponding properties + // Fall back to attribute presence where some booleans are not supported + var attrNode, + property = jQuery.prop( elem, name ); + return property === true || typeof property !== "boolean" && ( attrNode = elem.getAttributeNode(name) ) && attrNode.nodeValue !== false ? + 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 ( !getSetAttribute ) { + + fixSpecified = { + name: true, + id: true + }; + + // Use this for any attribute in IE6/7 + // This fixes almost every IE6/7 issue + nodeHook = jQuery.valHooks.button = { + get: function( elem, name ) { + var ret; + ret = elem.getAttributeNode( name ); + return ret && ( fixSpecified[ name ] ? ret.nodeValue !== "" : ret.specified ) ? + ret.nodeValue : + undefined; + }, + set: function( elem, value, name ) { + // Set the existing or create a new attribute node + var ret = elem.getAttributeNode( name ); + if ( !ret ) { + ret = document.createAttribute( name ); + elem.setAttributeNode( ret ); + } + return ( ret.nodeValue = value + "" ); + } + }; + + // Apply the nodeHook to tabindex + jQuery.attrHooks.tabindex.set = nodeHook.set; + + // 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; + } + } + }); + }); + + // Set contenteditable to false on removals(#10429) + // Setting to empty string throws an error as an invalid value + jQuery.attrHooks.contenteditable = { + get: nodeHook.get, + set: function( elem, value, name ) { + if ( value === "" ) { + value = "false"; + } + nodeHook.set( elem, value, name ); + } + }; +} + + +// 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; + } + } + return null; + } + }); +} + +// IE6/7 call enctype encoding +if ( !jQuery.support.enctype ) { + jQuery.propFix.enctype = "encoding"; +} + +// 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 rformElems = /^(?:textarea|input|select)$/i, + rtypenamespace = /^([^\.]*)?(?:\.(.+))?$/, + rhoverHack = /\bhover(\.\S+)?\b/, + rkeyEvent = /^key/, + rmouseEvent = /^(?:mouse|contextmenu)|click/, + rfocusMorph = /^(?:focusinfocus|focusoutblur)$/, + rquickIs = /^(\w*)(?:#([\w\-]+))?(?:\.([\w\-]+))?$/, + quickParse = function( selector ) { + var quick = rquickIs.exec( selector ); + if ( quick ) { + // 0 1 2 3 + // [ _, tag, id, class ] + quick[1] = ( quick[1] || "" ).toLowerCase(); + quick[3] = quick[3] && new RegExp( "(?:^|\\s)" + quick[3] + "(?:\\s|$)" ); + } + return quick; + }, + quickIs = function( elem, m ) { + var attrs = elem.attributes || {}; + return ( + (!m[1] || elem.nodeName.toLowerCase() === m[1]) && + (!m[2] || (attrs.id || {}).value === m[2]) && + (!m[3] || m[3].test( (attrs[ "class" ] || {}).value )) + ); + }, + hoverHack = function( events ) { + return jQuery.event.special.hover ? events : events.replace( rhoverHack, "mouseenter$1 mouseleave$1" ); + }; + +/* + * Helper functions for managing events -- not part of the public interface. + * Props to Dean Edwards' addEvent library for many of the ideas. + */ +jQuery.event = { + + add: function( elem, types, handler, data, selector ) { + + var elemData, eventHandle, events, + t, tns, type, namespaces, handleObj, + handleObjIn, quick, handlers, special; + + // Don't attach events to noData or text/comment nodes (allow plain objects tho) + if ( elem.nodeType === 3 || elem.nodeType === 8 || !types || !handler || !(elemData = jQuery._data( elem )) ) { + return; + } + + // Caller can pass in an object of custom data in lieu of the handler + if ( handler.handler ) { + handleObjIn = handler; + handler = handleObjIn.handler; + } + + // Make sure that the handler has a unique ID, used to find/remove it later + if ( !handler.guid ) { + handler.guid = jQuery.guid++; + } + + // Init the element's event structure and main handler, if this is the first + events = elemData.events; + if ( !events ) { + elemData.events = events = {}; + } + eventHandle = elemData.handle; + 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.dispatch.apply( eventHandle.elem, arguments ) : + undefined; + }; + // Add elem as a property of the handle fn to prevent a memory leak with IE non-native events + eventHandle.elem = elem; + } + + // Handle multiple events separated by a space + // jQuery(...).bind("mouseover mouseout", fn); + types = jQuery.trim( hoverHack(types) ).split( " " ); + for ( t = 0; t < types.length; t++ ) { + + tns = rtypenamespace.exec( types[t] ) || []; + type = tns[1]; + namespaces = ( tns[2] || "" ).split( "." ).sort(); + + // If event changes its type, use the special event handlers for the changed type + special = jQuery.event.special[ type ] || {}; + + // If selector defined, determine special event api type, otherwise given type + type = ( selector ? special.delegateType : special.bindType ) || type; + + // Update special based on newly reset type + special = jQuery.event.special[ type ] || {}; + + // handleObj is passed to all event handlers + handleObj = jQuery.extend({ + type: type, + origType: tns[1], + data: data, + handler: handler, + guid: handler.guid, + selector: selector, + quick: quickParse( selector ), + namespace: namespaces.join(".") + }, handleObjIn ); + + // Init the event handler queue if we're the first + handlers = events[ type ]; + if ( !handlers ) { + handlers = events[ type ] = []; + handlers.delegateCount = 0; + + // 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 to the element's handler list, delegates in front + if ( selector ) { + handlers.splice( handlers.delegateCount++, 0, handleObj ); + } else { + handlers.push( handleObj ); + } + + // Keep track of which events have ever 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, selector, mappedTypes ) { + + var elemData = jQuery.hasData( elem ) && jQuery._data( elem ), + t, tns, type, origType, namespaces, origCount, + j, events, special, handle, eventType, handleObj; + + if ( !elemData || !(events = elemData.events) ) { + return; + } + + // Once for each type.namespace in types; type may be omitted + types = jQuery.trim( hoverHack( types || "" ) ).split(" "); + for ( t = 0; t < types.length; t++ ) { + tns = rtypenamespace.exec( types[t] ) || []; + type = origType = tns[1]; + namespaces = tns[2]; + + // Unbind all events (on this namespace, if provided) for the element + if ( !type ) { + for ( type in events ) { + jQuery.event.remove( elem, type + types[ t ], handler, selector, true ); + } + continue; + } + + special = jQuery.event.special[ type ] || {}; + type = ( selector? special.delegateType : special.bindType ) || type; + eventType = events[ type ] || []; + origCount = eventType.length; + namespaces = namespaces ? new RegExp("(^|\\.)" + namespaces.split(".").sort().join("\\.(?:.*\\.)?") + "(\\.|$)") : null; + + // Remove matching events + for ( j = 0; j < eventType.length; j++ ) { + handleObj = eventType[ j ]; + + if ( ( mappedTypes || origType === handleObj.origType ) && + ( !handler || handler.guid === handleObj.guid ) && + ( !namespaces || namespaces.test( handleObj.namespace ) ) && + ( !selector || selector === handleObj.selector || selector === "**" && handleObj.selector ) ) { + eventType.splice( j--, 1 ); + + if ( handleObj.selector ) { + eventType.delegateCount--; + } + if ( special.remove ) { + special.remove.call( elem, handleObj ); + } + } + } + + // Remove generic event handler if we removed something and no more handlers exist + // (avoids potential for endless recursion during removal of special event handlers) + if ( eventType.length === 0 && origCount !== eventType.length ) { + if ( !special.teardown || special.teardown.call( elem, namespaces ) === false ) { + jQuery.removeEvent( elem, type, elemData.handle ); + } + + delete events[ type ]; + } + } + + // Remove the expando if it's no longer used + if ( jQuery.isEmptyObject( events ) ) { + handle = elemData.handle; + if ( handle ) { + handle.elem = null; + } + + // removeData also checks for emptiness and clears the expando if empty + // so use it instead of delete + jQuery.removeData( elem, [ "events", "handle" ], 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 ) { + // Don't do events on text and comment nodes + if ( elem && (elem.nodeType === 3 || elem.nodeType === 8) ) { + return; + } + + // Event object or event type + var type = event.type || event, + namespaces = [], + cache, exclusive, i, cur, old, ontype, special, handle, eventPath, bubbleType; + + // focus/blur morphs to focusin/out; ensure we're not firing them right now + if ( rfocusMorph.test( type + jQuery.event.triggered ) ) { + return; + } + + 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.isTrigger = true; + event.exclusive = exclusive; + event.namespace = namespaces.join( "." ); + event.namespace_re = event.namespace? new RegExp("(^|\\.)" + namespaces.join("\\.(?:.*\\.)?") + "(\\.|$)") : null; + ontype = type.indexOf( ":" ) < 0 ? "on" + type : ""; + + // Handle a global trigger + if ( !elem ) { + + // TODO: Stop taunting the data cache; remove global events and always attach to document + cache = jQuery.cache; + for ( i in cache ) { + if ( cache[ i ].events && cache[ i ].events[ type ] ) { + jQuery.event.trigger( event, data, cache[ i ].handle.elem, true ); + } + } + return; + } + + // Clean up the event in case it is being reused + event.result = undefined; + if ( !event.target ) { + 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 ); + + // Allow special events to draw outside the lines + special = jQuery.event.special[ type ] || {}; + if ( special.trigger && special.trigger.apply( elem, data ) === false ) { + return; + } + + // Determine event propagation path in advance, per W3C events spec (#9951) + // Bubble up to document, then to window; watch for a global ownerDocument var (#9724) + eventPath = [[ elem, special.bindType || type ]]; + if ( !onlyHandlers && !special.noBubble && !jQuery.isWindow( elem ) ) { + + bubbleType = special.delegateType || type; + cur = rfocusMorph.test( bubbleType + type ) ? elem : elem.parentNode; + old = null; + for ( ; cur; cur = cur.parentNode ) { + eventPath.push([ cur, bubbleType ]); + old = cur; + } + + // Only add window if we got to document (e.g., not plain obj or detached DOM) + if ( old && old === elem.ownerDocument ) { + eventPath.push([ old.defaultView || old.parentWindow || window, bubbleType ]); + } + } + + // Fire handlers on the event path + for ( i = 0; i < eventPath.length && !event.isPropagationStopped(); i++ ) { + + cur = eventPath[i][0]; + event.type = eventPath[i][1]; + + handle = ( jQuery._data( cur, "events" ) || {} )[ event.type ] && jQuery._data( cur, "handle" ); + if ( handle ) { + handle.apply( cur, data ); + } + // Note that this is a bare JS function and not a jQuery handler + handle = ontype && cur[ ontype ]; + if ( handle && jQuery.acceptData( cur ) && handle.apply( cur, data ) === false ) { + event.preventDefault(); + } + } + event.type = type; + + // If nobody prevented the default action, do it now + if ( !onlyHandlers && !event.isDefaultPrevented() ) { + + if ( (!special._default || special._default.apply( elem.ownerDocument, data ) === 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. + // Don't do default actions on window, that's where global variables be (#6170) + // IE<9 dies on focus/blur to hidden element (#1486) + if ( ontype && elem[ type ] && ((type !== "focus" && type !== "blur") || event.target.offsetWidth !== 0) && !jQuery.isWindow( elem ) ) { + + // Don't re-trigger an onFOO event when we call its FOO() method + old = elem[ ontype ]; + + if ( old ) { + elem[ ontype ] = null; + } + + // Prevent re-triggering of the same event, since we already bubbled it above + jQuery.event.triggered = type; + elem[ type ](); + jQuery.event.triggered = undefined; + + if ( old ) { + elem[ ontype ] = old; + } + } + } + } + + return event.result; + }, + + dispatch: function( event ) { + + // Make a writable jQuery.Event from the native event object + event = jQuery.event.fix( event || window.event ); + + var handlers = ( (jQuery._data( this, "events" ) || {} )[ event.type ] || []), + delegateCount = handlers.delegateCount, + args = [].slice.call( arguments, 0 ), + run_all = !event.exclusive && !event.namespace, + handlerQueue = [], + i, j, cur, jqcur, ret, selMatch, matched, matches, handleObj, sel, related; + + // Use the fix-ed jQuery.Event rather than the (read-only) native event + args[0] = event; + event.delegateTarget = this; + + // Determine handlers that should run if there are delegated events + // Avoid disabled elements in IE (#6911) and non-left-click bubbling in Firefox (#3861) + if ( delegateCount && !event.target.disabled && !(event.button && event.type === "click") ) { + + // Pregenerate a single jQuery object for reuse with .is() + jqcur = jQuery(this); + jqcur.context = this.ownerDocument || this; + + for ( cur = event.target; cur != this; cur = cur.parentNode || this ) { + selMatch = {}; + matches = []; + jqcur[0] = cur; + for ( i = 0; i < delegateCount; i++ ) { + handleObj = handlers[ i ]; + sel = handleObj.selector; + + if ( selMatch[ sel ] === undefined ) { + selMatch[ sel ] = ( + handleObj.quick ? quickIs( cur, handleObj.quick ) : jqcur.is( sel ) + ); + } + if ( selMatch[ sel ] ) { + matches.push( handleObj ); + } + } + if ( matches.length ) { + handlerQueue.push({ elem: cur, matches: matches }); + } + } + } + + // Add the remaining (directly-bound) handlers + if ( handlers.length > delegateCount ) { + handlerQueue.push({ elem: this, matches: handlers.slice( delegateCount ) }); + } + + // Run delegates first; they may want to stop propagation beneath us + for ( i = 0; i < handlerQueue.length && !event.isPropagationStopped(); i++ ) { + matched = handlerQueue[ i ]; + event.currentTarget = matched.elem; + + for ( j = 0; j < matched.matches.length && !event.isImmediatePropagationStopped(); j++ ) { + handleObj = matched.matches[ j ]; + + // Triggered event must either 1) be non-exclusive and have no namespace, or + // 2) have namespace(s) a subset or equal to those in the bound event (both can have no namespace). + if ( run_all || (!event.namespace && !handleObj.namespace) || event.namespace_re && event.namespace_re.test( handleObj.namespace ) ) { + + event.data = handleObj.data; + event.handleObj = handleObj; + + ret = ( (jQuery.event.special[ handleObj.origType ] || {}).handle || handleObj.handler ) + .apply( matched.elem, args ); + + if ( ret !== undefined ) { + event.result = ret; + if ( ret === false ) { + event.preventDefault(); + event.stopPropagation(); + } + } + } + } + } + + return event.result; + }, + + // Includes some event props shared by KeyEvent and MouseEvent + // *** attrChange attrName relatedNode srcElement are not normalized, non-W3C, deprecated, will be removed in 1.8 *** + props: "attrChange attrName relatedNode srcElement altKey bubbles cancelable ctrlKey currentTarget eventPhase metaKey relatedTarget shiftKey target timeStamp view which".split(" "), + + fixHooks: {}, + + keyHooks: { + props: "char charCode key keyCode".split(" "), + filter: function( event, original ) { + + // Add which for key events + if ( event.which == null ) { + event.which = original.charCode != null ? original.charCode : original.keyCode; + } + + return event; + } + }, + + mouseHooks: { + props: "button buttons clientX clientY fromElement offsetX offsetY pageX pageY screenX screenY toElement".split(" "), + filter: function( event, original ) { + var eventDoc, doc, body, + button = original.button, + fromElement = original.fromElement; + + // Calculate pageX/Y if missing and clientX/Y available + if ( event.pageX == null && original.clientX != null ) { + eventDoc = event.target.ownerDocument || document; + doc = eventDoc.documentElement; + body = eventDoc.body; + + event.pageX = original.clientX + ( doc && doc.scrollLeft || body && body.scrollLeft || 0 ) - ( doc && doc.clientLeft || body && body.clientLeft || 0 ); + event.pageY = original.clientY + ( doc && doc.scrollTop || body && body.scrollTop || 0 ) - ( doc && doc.clientTop || body && body.clientTop || 0 ); + } + + // Add relatedTarget, if necessary + if ( !event.relatedTarget && fromElement ) { + event.relatedTarget = fromElement === event.target ? original.toElement : fromElement; + } + + // Add which for click: 1 === left; 2 === middle; 3 === right + // Note: button is not normalized, so don't use it + if ( !event.which && button !== undefined ) { + event.which = ( button & 1 ? 1 : ( button & 2 ? 3 : ( button & 4 ? 2 : 0 ) ) ); + } + + return event; + } + }, + + fix: function( event ) { + if ( event[ jQuery.expando ] ) { + return event; + } + + // Create a writable copy of the event object and normalize some properties + var i, prop, + originalEvent = event, + fixHook = jQuery.event.fixHooks[ event.type ] || {}, + copy = fixHook.props ? this.props.concat( fixHook.props ) : this.props; + + event = jQuery.Event( originalEvent ); + + for ( i = copy.length; i; ) { + prop = copy[ --i ]; + event[ prop ] = originalEvent[ prop ]; + } + + // Fix target property, if necessary (#1925, IE 6/7/8 & Safari2) + if ( !event.target ) { + event.target = originalEvent.srcElement || document; + } + + // Target should not be a text node (#504, Safari) + if ( event.target.nodeType === 3 ) { + event.target = event.target.parentNode; + } + + // For mouse/key events; add metaKey if it's not there (#3368, IE6/7/8) + if ( event.metaKey === undefined ) { + event.metaKey = event.ctrlKey; + } + + return fixHook.filter? fixHook.filter( event, originalEvent ) : event; + }, + + special: { + ready: { + // Make sure the ready event is setup + setup: jQuery.bindReady + }, + + load: { + // Prevent triggered image.load events from bubbling to window.load + noBubble: true + }, + + focus: { + delegateType: "focusin" + }, + blur: { + delegateType: "focusout" + }, + + 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; + } + } + } + }, + + simulate: function( type, elem, event, bubble ) { + // 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. + var e = jQuery.extend( + new jQuery.Event(), + event, + { type: type, + isSimulated: true, + originalEvent: {} + } + ); + if ( bubble ) { + jQuery.event.trigger( e, null, elem ); + } else { + jQuery.event.dispatch.call( elem, e ); + } + if ( e.isDefaultPrevented() ) { + event.preventDefault(); + } + } +}; + +// Some plugins are using, but it's undocumented/deprecated and will be removed. +// The 1.7 special event interface should provide all the hooks needed now. +jQuery.event.handle = jQuery.event.dispatch; + +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 instanceof jQuery.Event) ) { + 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 ); + } + + // Create a timestamp if incoming event doesn't have one + this.timeStamp = src && src.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 +}; + +// Create mouseenter/leave events using mouseover/out and event-time checks +jQuery.each({ + mouseenter: "mouseover", + mouseleave: "mouseout" +}, function( orig, fix ) { + jQuery.event.special[ orig ] = { + delegateType: fix, + bindType: fix, + + handle: function( event ) { + var target = this, + related = event.relatedTarget, + handleObj = event.handleObj, + selector = handleObj.selector, + ret; + + // For mousenter/leave call the handler if related is outside the target. + // NB: No relatedTarget if the mouse left/entered the browser window + if ( !related || (related !== target && !jQuery.contains( target, related )) ) { + event.type = handleObj.origType; + ret = handleObj.handler.apply( this, arguments ); + event.type = fix; + } + return ret; + } + }; +}); + +// IE submit delegation +if ( !jQuery.support.submitBubbles ) { + + jQuery.event.special.submit = { + setup: function() { + // Only need this for delegated form submit events + if ( jQuery.nodeName( this, "form" ) ) { + return false; + } + + // Lazy-add a submit handler when a descendant form may potentially be submitted + jQuery.event.add( this, "click._submit keypress._submit", function( e ) { + // Node name check avoids a VML-related crash in IE (#9807) + var elem = e.target, + form = jQuery.nodeName( elem, "input" ) || jQuery.nodeName( elem, "button" ) ? elem.form : undefined; + if ( form && !form._submit_attached ) { + jQuery.event.add( form, "submit._submit", function( event ) { + // If form was submitted by the user, bubble the event up the tree + if ( this.parentNode && !event.isTrigger ) { + jQuery.event.simulate( "submit", this.parentNode, event, true ); + } + }); + form._submit_attached = true; + } + }); + // return undefined since we don't need an event listener + }, + + teardown: function() { + // Only need this for delegated form submit events + if ( jQuery.nodeName( this, "form" ) ) { + return false; + } + + // Remove delegated handlers; cleanData eventually reaps submit handlers attached above + jQuery.event.remove( this, "._submit" ); + } + }; +} + +// IE change delegation and checkbox/radio fix +if ( !jQuery.support.changeBubbles ) { + + jQuery.event.special.change = { + + setup: function() { + + if ( rformElems.test( this.nodeName ) ) { + // IE doesn't fire change on a check/radio until blur; trigger it on click + // after a propertychange. Eat the blur-change in special.change.handle. + // This still fires onchange a second time for check/radio after blur. + if ( this.type === "checkbox" || this.type === "radio" ) { + jQuery.event.add( this, "propertychange._change", function( event ) { + if ( event.originalEvent.propertyName === "checked" ) { + this._just_changed = true; + } + }); + jQuery.event.add( this, "click._change", function( event ) { + if ( this._just_changed && !event.isTrigger ) { + this._just_changed = false; + jQuery.event.simulate( "change", this, event, true ); + } + }); + } + return false; + } + // Delegated event; lazy-add a change handler on descendant inputs + jQuery.event.add( this, "beforeactivate._change", function( e ) { + var elem = e.target; + + if ( rformElems.test( elem.nodeName ) && !elem._change_attached ) { + jQuery.event.add( elem, "change._change", function( event ) { + if ( this.parentNode && !event.isSimulated && !event.isTrigger ) { + jQuery.event.simulate( "change", this.parentNode, event, true ); + } + }); + elem._change_attached = true; + } + }); + }, + + handle: function( event ) { + var elem = event.target; + + // Swallow native change events from checkbox/radio, we already triggered them above + if ( this !== elem || event.isSimulated || event.isTrigger || (elem.type !== "radio" && elem.type !== "checkbox") ) { + return event.handleObj.handler.apply( this, arguments ); + } + }, + + teardown: function() { + jQuery.event.remove( this, "._change" ); + + return rformElems.test( this.nodeName ); + } + }; +} + +// 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, + handler = function( event ) { + jQuery.event.simulate( fix, event.target, jQuery.event.fix( event ), true ); + }; + + jQuery.event.special[ fix ] = { + setup: function() { + if ( attaches++ === 0 ) { + document.addEventListener( orig, handler, true ); + } + }, + teardown: function() { + if ( --attaches === 0 ) { + document.removeEventListener( orig, handler, true ); + } + } + }; + }); +} + +jQuery.fn.extend({ + + on: function( types, selector, data, fn, /*INTERNAL*/ one ) { + var origFn, type; + + // Types can be a map of types/handlers + if ( typeof types === "object" ) { + // ( types-Object, selector, data ) + if ( typeof selector !== "string" ) { + // ( types-Object, data ) + data = selector; + selector = undefined; + } + for ( type in types ) { + this.on( type, selector, data, types[ type ], one ); + } + return this; + } + + if ( data == null && fn == null ) { + // ( types, fn ) + fn = selector; + data = selector = undefined; + } else if ( fn == null ) { + if ( typeof selector === "string" ) { + // ( types, selector, fn ) + fn = data; + data = undefined; + } else { + // ( types, data, fn ) + fn = data; + data = selector; + selector = undefined; + } + } + if ( fn === false ) { + fn = returnFalse; + } else if ( !fn ) { + return this; + } + + if ( one === 1 ) { + origFn = fn; + fn = function( event ) { + // Can use an empty set, since event contains the info + jQuery().off( event ); + return origFn.apply( this, arguments ); + }; + // Use same guid so caller can remove using origFn + fn.guid = origFn.guid || ( origFn.guid = jQuery.guid++ ); + } + return this.each( function() { + jQuery.event.add( this, types, fn, data, selector ); + }); + }, + one: function( types, selector, data, fn ) { + return this.on.call( this, types, selector, data, fn, 1 ); + }, + off: function( types, selector, fn ) { + if ( types && types.preventDefault && types.handleObj ) { + // ( event ) dispatched jQuery.Event + var handleObj = types.handleObj; + jQuery( types.delegateTarget ).off( + handleObj.namespace? handleObj.type + "." + handleObj.namespace : handleObj.type, + handleObj.selector, + handleObj.handler + ); + return this; + } + if ( typeof types === "object" ) { + // ( types-object [, selector] ) + for ( var type in types ) { + this.off( type, selector, types[ type ] ); + } + return this; + } + if ( selector === false || typeof selector === "function" ) { + // ( types [, fn] ) + fn = selector; + selector = undefined; + } + if ( fn === false ) { + fn = returnFalse; + } + return this.each(function() { + jQuery.event.remove( this, types, fn, selector ); + }); + }, + + bind: function( types, data, fn ) { + return this.on( types, null, data, fn ); + }, + unbind: function( types, fn ) { + return this.off( types, null, fn ); + }, + + live: function( types, data, fn ) { + jQuery( this.context ).on( types, this.selector, data, fn ); + return this; + }, + die: function( types, fn ) { + jQuery( this.context ).off( types, this.selector || "**", fn ); + return this; + }, + + delegate: function( selector, types, data, fn ) { + return this.on( types, selector, data, fn ); + }, + undelegate: function( selector, types, fn ) { + // ( namespace ) or ( selector, types [, fn] ) + return arguments.length == 1? this.off( selector, "**" ) : this.off( types, selector, fn ); + }, + + 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 ); + } +}); + +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 contextmenu").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.on( name, null, data, fn ) : + this.trigger( name ); + }; + + if ( jQuery.attrFn ) { + jQuery.attrFn[ name ] = true; + } + + if ( rkeyEvent.test( name ) ) { + jQuery.event.fixHooks[ name ] = jQuery.event.keyHooks; + } + + if ( rmouseEvent.test( name ) ) { + jQuery.event.fixHooks[ name ] = jQuery.event.mouseHooks; + } +}); + + + +/*! + * 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, + expando = "sizcache" + (Math.random() + '').replace('.', ''), + done = 0, + toString = Object.prototype.toString, + hasDuplicate = false, + baseHasDuplicate = true, + rBackslash = /\\/g, + rReturn = /\r\n/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, seed ); + + } 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, seed ); + } + } + + } 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, i, len, match, type, left; + + if ( !expr ) { + return []; + } + + for ( i = 0, len = Expr.order.length; i < len; i++ ) { + type = Expr.order[i]; + + if ( (match = Expr.leftMatch[ type ].exec( expr )) ) { + 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, + type, found, item, filter, left, + i, pass, + old = expr, + result = [], + curLoop = set, + isXMLFilter = set && set[0] && Sizzle.isXML( set[0] ); + + while ( expr && set.length ) { + for ( type in Expr.filter ) { + if ( (match = Expr.leftMatch[ type ].exec( expr )) != null && match[2] ) { + 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 ( i = 0; (item = curLoop[i]) != null; i++ ) { + if ( item ) { + found = filter( item, match, i, curLoop ); + 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 new Error( "Syntax error, unrecognized expression: " + msg ); +}; + +/** + * Utility function for retreiving the text value of an array of DOM nodes + * @param {Array|Element} elem + */ +var getText = Sizzle.getText = function( elem ) { + var i, node, + nodeType = elem.nodeType, + ret = ""; + + if ( nodeType ) { + if ( nodeType === 1 || nodeType === 9 ) { + // Use textContent || innerText for elements + if ( typeof elem.textContent === 'string' ) { + return elem.textContent; + } else if ( typeof elem.innerText === 'string' ) { + // Replace IE's carriage returns + return elem.innerText.replace( rReturn, '' ); + } else { + // Traverse it's children + for ( elem = elem.firstChild; elem; elem = elem.nextSibling) { + ret += getText( elem ); + } + } + } else if ( nodeType === 3 || nodeType === 4 ) { + return elem.nodeValue; + } + } else { + + // If no nodeType, this is expected to be an array + for ( i = 0; (node = elem[i]); i++ ) { + // Do not traverse comment nodes + if ( node.nodeType !== 8 ) { + ret += getText( node ); + } + } + } + return ret; +}; + +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 || 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 first, last, + doneName, parent, cache, + count, diff, + 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": + first = match[2]; + last = match[3]; + + if ( first === 1 && last === 0 ) { + return true; + } + + doneName = match[0]; + parent = elem.parentNode; + + if ( parent && (parent[ expando ] !== doneName || !elem.nodeIndex) ) { + count = 0; + + for ( node = parent.firstChild; node; node = node.nextSibling ) { + if ( node.nodeType === 1 ) { + node.nodeIndex = ++count; + } + } + + parent[ expando ] = doneName; + } + + 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 && 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 = Sizzle.attr ? + Sizzle.attr( elem, name ) : + 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 && Sizzle.attr ? + result != null : + 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; + }; +} + +// 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[ expando ] === doneName ) { + match = checkSet[elem.sizset]; + break; + } + + if ( elem.nodeType === 1 && !isXML ){ + elem[ expando ] = 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[ expando ] === doneName ) { + match = checkSet[elem.sizset]; + break; + } + + if ( elem.nodeType === 1 ) { + if ( !isXML ) { + elem[ expando ] = 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, seed ) { + 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, seed ); + } + + return Sizzle.filter( later, tmpSet ); +}; + +// EXPOSE +// Override sizzle attribute retrieval +Sizzle.attr = jQuery.attr; +Sizzle.selectors.attrMap = {}; +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" ? + // If this is a positional selector, check membership in the returned set + // so $("p:first").is("p:last") won't return true for a doc with two "p". + POS.test( selector ) ? + jQuery( selector, this.context ).index( this[0] ) >= 0 : + jQuery.filter( selector, this ).length > 0 : + this.filter( selector ).length > 0 ); + }, + + closest: function( selectors, context ) { + var ret = [], i, l, cur = this[0]; + + // Array (deprecated as of jQuery 1.7) + if ( jQuery.isArray( selectors ) ) { + var level = 1; + + while ( cur && cur.ownerDocument && cur !== context ) { + for ( i = 0; i < selectors.length; i++ ) { + + if ( jQuery( cur ).is( selectors[ i ] ) ) { + ret.push({ selector: selectors[ i ], 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 ) { + + // No argument, return index in parent + if ( !elem ) { + return ( this[0] && this[0].parentNode ) ? this.prevAll().length : -1; + } + + // index in selector + if ( typeof elem === "string" ) { + return jQuery.inArray( this[0], jQuery( elem ) ); + } + + // 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 ); + + 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, slice.call( arguments ).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; + }); +} + + + + +function createSafeFragment( document ) { + var list = nodeNames.split( "|" ), + safeFrag = document.createDocumentFragment(); + + if ( safeFrag.createElement ) { + while ( list.length ) { + safeFrag.createElement( + list.pop() + ); + } + } + return safeFrag; +} + +var nodeNames = "abbr|article|aside|audio|canvas|datalist|details|figcaption|figure|footer|" + + "header|hgroup|mark|meter|nav|output|progress|section|summary|time|video", + 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, "", "" ] + }, + safeFragment = createSafeFragment( document ); + +wrapMap.optgroup = wrapMap.option; +wrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead; +wrapMap.th = wrapMap.td; + +// IE can't serialize and + + + + + +

      require.js: JSONP Test

      +

      Test for usage of a JSONP URL as a dependency.

      + REQUIRES access to internet/Twitter to run the test. Otherwise it will fail. +

      Check console for messages

      + + diff --git a/htdocs/js/lib/vendor/components/requirejs/tests/jsonp/lamp.js b/htdocs/js/lib/vendor/components/requirejs/tests/jsonp/lamp.js new file mode 100644 index 000000000..6ed7152b8 --- /dev/null +++ b/htdocs/js/lib/vendor/components/requirejs/tests/jsonp/lamp.js @@ -0,0 +1,3 @@ +define("lamp", { + color: "blue" +}); diff --git a/htdocs/js/lib/vendor/components/requirejs/tests/jsonp/twitter.html b/htdocs/js/lib/vendor/components/requirejs/tests/jsonp/twitter.html new file mode 100644 index 000000000..fc9bb1c68 --- /dev/null +++ b/htdocs/js/lib/vendor/components/requirejs/tests/jsonp/twitter.html @@ -0,0 +1,26 @@ + + + + require.js: JSONP Test: Twitter + + + + +

      require.js: JSONP Test: Twitter

      +

      Just a standalone .

      + REQUIRES access to internet/Twitter to run. Otherwise it will fail. +

      Check console for the current trends JSON return value.

      + + diff --git a/htdocs/js/lib/vendor/components/requirejs/tests/layers/build.sh b/htdocs/js/lib/vendor/components/requirejs/tests/layers/build.sh new file mode 100755 index 000000000..139084313 --- /dev/null +++ b/htdocs/js/lib/vendor/components/requirejs/tests/layers/build.sh @@ -0,0 +1 @@ +../../build/build.sh baseUrl=../.. name=require out=allplugins-require.js optimize=none diff --git a/htdocs/js/lib/vendor/components/requirejs/tests/layers/epsilon.js b/htdocs/js/lib/vendor/components/requirejs/tests/layers/epsilon.js new file mode 100644 index 000000000..7a66e57fb --- /dev/null +++ b/htdocs/js/lib/vendor/components/requirejs/tests/layers/epsilon.js @@ -0,0 +1,5 @@ +define("epsilon", + { + name: "epsilon" + } +); diff --git a/htdocs/js/lib/vendor/components/requirejs/tests/layers/helloWorld.txt b/htdocs/js/lib/vendor/components/requirejs/tests/layers/helloWorld.txt new file mode 100644 index 000000000..95d09f2b1 --- /dev/null +++ b/htdocs/js/lib/vendor/components/requirejs/tests/layers/helloWorld.txt @@ -0,0 +1 @@ +hello world \ No newline at end of file diff --git a/htdocs/js/lib/vendor/components/requirejs/tests/layers/layer1.js b/htdocs/js/lib/vendor/components/requirejs/tests/layers/layer1.js new file mode 100644 index 000000000..963ab00e9 --- /dev/null +++ b/htdocs/js/lib/vendor/components/requirejs/tests/layers/layer1.js @@ -0,0 +1,31 @@ +//Example layer file. + +define("alpha", + ["beta", "gamma"], + function (beta, gamma) { + return { + name: "alpha", + betaName: beta.name + }; + } +); + +define("beta", + ["gamma"], + function (gamma) { + return { + name: "beta", + gammaName: gamma.name + }; + } +); + +define("gamma", + ["epsilon"], + function (epsilon) { + return { + name: "gamma", + epsilonName: epsilon.name + }; + } +); diff --git a/htdocs/js/lib/vendor/components/requirejs/tests/layers/layers.html b/htdocs/js/lib/vendor/components/requirejs/tests/layers/layers.html new file mode 100644 index 000000000..dda26c00c --- /dev/null +++ b/htdocs/js/lib/vendor/components/requirejs/tests/layers/layers.html @@ -0,0 +1,57 @@ + + + + require.js: Layers Test + + + + + + +

      require.js: Layers Test

      +

      Check console for messages

      + + diff --git a/htdocs/js/lib/vendor/components/requirejs/tests/map.js b/htdocs/js/lib/vendor/components/requirejs/tests/map.js new file mode 100644 index 000000000..3e0757485 --- /dev/null +++ b/htdocs/js/lib/vendor/components/requirejs/tests/map.js @@ -0,0 +1,7 @@ +define("map", + function() { + return { + name: "map" + }; + } +); diff --git a/htdocs/js/lib/vendor/components/requirejs/tests/mapConfig/a1.js b/htdocs/js/lib/vendor/components/requirejs/tests/mapConfig/a1.js new file mode 100644 index 000000000..b5d612cc6 --- /dev/null +++ b/htdocs/js/lib/vendor/components/requirejs/tests/mapConfig/a1.js @@ -0,0 +1,6 @@ +define(['c', 'c/sub'], function (c, csub) { + return { + c: c, + csub: csub + }; +}); diff --git a/htdocs/js/lib/vendor/components/requirejs/tests/mapConfig/a1/sub/one.js b/htdocs/js/lib/vendor/components/requirejs/tests/mapConfig/a1/sub/one.js new file mode 100644 index 000000000..b5d612cc6 --- /dev/null +++ b/htdocs/js/lib/vendor/components/requirejs/tests/mapConfig/a1/sub/one.js @@ -0,0 +1,6 @@ +define(['c', 'c/sub'], function (c, csub) { + return { + c: c, + csub: csub + }; +}); diff --git a/htdocs/js/lib/vendor/components/requirejs/tests/mapConfig/adapter/d.js b/htdocs/js/lib/vendor/components/requirejs/tests/mapConfig/adapter/d.js new file mode 100644 index 000000000..ca18376ab --- /dev/null +++ b/htdocs/js/lib/vendor/components/requirejs/tests/mapConfig/adapter/d.js @@ -0,0 +1,4 @@ +define(['d'], function(d) { + d.adapted = true; + return d; +}); diff --git a/htdocs/js/lib/vendor/components/requirejs/tests/mapConfig/another/c.js b/htdocs/js/lib/vendor/components/requirejs/tests/mapConfig/another/c.js new file mode 100644 index 000000000..5216d414c --- /dev/null +++ b/htdocs/js/lib/vendor/components/requirejs/tests/mapConfig/another/c.js @@ -0,0 +1,6 @@ +define(['./minor'], function (minor) { + return { + name: 'another/c', + minorName: minor.name + }; +}); diff --git a/htdocs/js/lib/vendor/components/requirejs/tests/mapConfig/another/c/dim.js b/htdocs/js/lib/vendor/components/requirejs/tests/mapConfig/another/c/dim.js new file mode 100644 index 000000000..c965bf3ac --- /dev/null +++ b/htdocs/js/lib/vendor/components/requirejs/tests/mapConfig/another/c/dim.js @@ -0,0 +1,3 @@ +define({ + name: 'another/c/dim' +}); diff --git a/htdocs/js/lib/vendor/components/requirejs/tests/mapConfig/another/c/sub.js b/htdocs/js/lib/vendor/components/requirejs/tests/mapConfig/another/c/sub.js new file mode 100644 index 000000000..c2768d857 --- /dev/null +++ b/htdocs/js/lib/vendor/components/requirejs/tests/mapConfig/another/c/sub.js @@ -0,0 +1,6 @@ +define(['./dim'], function (dim) { + return { + name: 'another/c/sub', + dimName: dim.name + }; +}); diff --git a/htdocs/js/lib/vendor/components/requirejs/tests/mapConfig/another/minor.js b/htdocs/js/lib/vendor/components/requirejs/tests/mapConfig/another/minor.js new file mode 100644 index 000000000..c055b139c --- /dev/null +++ b/htdocs/js/lib/vendor/components/requirejs/tests/mapConfig/another/minor.js @@ -0,0 +1,4 @@ +define({ + name: 'another/minor' +}); + diff --git a/htdocs/js/lib/vendor/components/requirejs/tests/mapConfig/b.js b/htdocs/js/lib/vendor/components/requirejs/tests/mapConfig/b.js new file mode 100644 index 000000000..b5d612cc6 --- /dev/null +++ b/htdocs/js/lib/vendor/components/requirejs/tests/mapConfig/b.js @@ -0,0 +1,6 @@ +define(['c', 'c/sub'], function (c, csub) { + return { + c: c, + csub: csub + }; +}); diff --git a/htdocs/js/lib/vendor/components/requirejs/tests/mapConfig/built/mapConfig-tests.js b/htdocs/js/lib/vendor/components/requirejs/tests/mapConfig/built/mapConfig-tests.js new file mode 100644 index 000000000..de68bc274 --- /dev/null +++ b/htdocs/js/lib/vendor/components/requirejs/tests/mapConfig/built/mapConfig-tests.js @@ -0,0 +1,82 @@ + +define('c1',{ + name: 'c1' +}); + +define('c1/sub',{ + name: 'c1/sub' +}); + +define('a',['c', 'c/sub'], function (c, csub) { + return { + c: c, + csub: csub + }; +}); + +define('c',{ + name: 'c' +}); + +define('c/sub',{ + name: 'c/sub' +}); + +define('b',['c', 'c/sub'], function (c, csub) { + return { + c: c, + csub: csub + }; +}); + +define('c2',{ + name: 'c2' +}); + +define('c2/sub',{ + name: 'c2/sub' +}); + +define('a/sub/one',['c', 'c/sub'], function (c, csub) { + return { + c: c, + csub: csub + }; +}); + +require({ + baseUrl: './', + paths: { + a: 'a1' + }, + + map: { + 'a': { + c: 'c1' + }, + 'a/sub/one': { + 'c': 'c2' + } + } + }, + ['a', 'b', 'c', 'a/sub/one'], + function(a, b, c, one) { + doh.register( + 'mapConfig', + [ + function mapConfig(t){ + t.is('c1', a.c.name); + t.is('c1/sub', a.csub.name); + t.is('c2', one.c.name); + t.is('c2/sub', one.csub.name); + t.is('c', b.c.name); + t.is('c/sub', b.csub.name); + t.is('c', c.name); + } + ] + ); + doh.run(); + } +); + +define("mapConfig-tests", function(){}); diff --git a/htdocs/js/lib/vendor/components/requirejs/tests/mapConfig/built/mapConfigBuilt.html b/htdocs/js/lib/vendor/components/requirejs/tests/mapConfig/built/mapConfigBuilt.html new file mode 100644 index 000000000..377cd32c0 --- /dev/null +++ b/htdocs/js/lib/vendor/components/requirejs/tests/mapConfig/built/mapConfigBuilt.html @@ -0,0 +1,15 @@ + + + + require.js: Map Config Built Test + + + + + + +

      require.js: Map Config Built Test

      +

      Test using the map config after a build.

      +

      Check console for messages

      + + diff --git a/htdocs/js/lib/vendor/components/requirejs/tests/mapConfig/built/mapConfigPlugin-tests.js b/htdocs/js/lib/vendor/components/requirejs/tests/mapConfig/built/mapConfigPlugin-tests.js new file mode 100644 index 000000000..4f64f027a --- /dev/null +++ b/htdocs/js/lib/vendor/components/requirejs/tests/mapConfig/built/mapConfigPlugin-tests.js @@ -0,0 +1,91 @@ + +define('plug',{ + load: function (name, require, load, config) { + if (!name) { + name = 'main'; + } else if (name.charAt(0) === '/') { + name = 'main' + name; + } + + //Only grab the first segment of the name. + //This is just to be different, nothing + //that is required behavior. + name = name.split('/').shift(); + + name = 'plug/' + name; + + require([name], load); + } +}); +define('plug/c1',{ + name: 'plug!c1' +}); + +define('a',['c', 'c/sub'], function (c, csub) { + return { + c: c, + csub: csub + }; +}); + +define('plug/main',{ + name: 'plug!main' +}); + +define('b',['c', 'c/sub'], function (c, csub) { + return { + c: c, + csub: csub + }; +}); + +define('plug/c2',{ + name: 'plug!c2' +}); + +define('a/sub/one',['c', 'c/sub'], function (c, csub) { + return { + c: c, + csub: csub + }; +}); + +require({ + baseUrl: './', + paths: { + a: 'a1' + }, + + map: { + '*': { + c: 'plug!' + }, + 'a': { + c: 'plug!c1' + }, + 'a/sub/one': { + 'c': 'plug!c2' + } + } + }, + ['a', 'b', 'c', 'a/sub/one'], + function(a, b, c, one) { + doh.register( + 'mapConfigPlugin', + [ + function mapConfigPlugin(t){ + t.is('plug!c1', a.c.name); + t.is('plug!c1', a.csub.name); + t.is('plug!c2', one.c.name); + t.is('plug!c2', one.csub.name); + t.is('plug!main', b.c.name); + t.is('plug!main', b.csub.name); + t.is('plug!main', c.name); + } + ] + ); + doh.run(); + } +); + +define("mapConfigPlugin-tests", function(){}); diff --git a/htdocs/js/lib/vendor/components/requirejs/tests/mapConfig/built/mapConfigPluginBuilt.html b/htdocs/js/lib/vendor/components/requirejs/tests/mapConfig/built/mapConfigPluginBuilt.html new file mode 100644 index 000000000..5d293220e --- /dev/null +++ b/htdocs/js/lib/vendor/components/requirejs/tests/mapConfig/built/mapConfigPluginBuilt.html @@ -0,0 +1,15 @@ + + + + require.js: Map Config Plugin Built Test + + + + + + +

      require.js: Map Config Plugin Built Test

      +

      Test using the map config with plugin value after a build.

      +

      Check console for messages

      + + diff --git a/htdocs/js/lib/vendor/components/requirejs/tests/mapConfig/built/mapConfigStar-tests.js b/htdocs/js/lib/vendor/components/requirejs/tests/mapConfig/built/mapConfigStar-tests.js new file mode 100644 index 000000000..630613848 --- /dev/null +++ b/htdocs/js/lib/vendor/components/requirejs/tests/mapConfig/built/mapConfigStar-tests.js @@ -0,0 +1,100 @@ + +define('c1',{ + name: 'c1' +}); + +define('c1/sub',{ + name: 'c1/sub' +}); + +define('a',['c', 'c/sub'], function (c, csub) { + return { + c: c, + csub: csub + }; +}); + +define('another/minor',{ + name: 'another/minor' +}); + + +define('another/c',['./minor'], function (minor) { + return { + name: 'another/c', + minorName: minor.name + }; +}); + +define('another/c/dim',{ + name: 'another/c/dim' +}); + +define('another/c/sub',['./dim'], function (dim) { + return { + name: 'another/c/sub', + dimName: dim.name + }; +}); + +define('b',['c', 'c/sub'], function (c, csub) { + return { + c: c, + csub: csub + }; +}); + +define('c2',{ + name: 'c2' +}); + +define('a/sub/one',['c', 'c/sub'], function (c, csub) { + return { + c: c, + csub: csub + }; +}); + +require({ + baseUrl: './', + paths: { + a: 'a1' + }, + + map: { + '*': { + 'c': 'another/c' + }, + 'a': { + c: 'c1' + }, + 'a/sub/one': { + 'c': 'c2', + 'c/sub': 'another/c/sub' + } + } + }, + ['a', 'b', 'c', 'a/sub/one'], + function(a, b, c, one) { + doh.register( + 'mapConfigStar', + [ + function mapConfigStar(t){ + t.is('c1', a.c.name); + t.is('c1/sub', a.csub.name); + t.is('c2', one.c.name); + t.is('another/c/sub', one.csub.name); + t.is('another/c/dim', one.csub.dimName); + t.is('another/c', b.c.name); + t.is('another/minor', b.c.minorName); + t.is('another/c/sub', b.csub.name); + t.is('another/c', c.name); + t.is('another/minor', c.minorName); + } + ] + ); + doh.run(); + } +); + +define("mapConfigStar-tests", function(){}); diff --git a/htdocs/js/lib/vendor/components/requirejs/tests/mapConfig/built/mapConfigStarAdapter-tests.js b/htdocs/js/lib/vendor/components/requirejs/tests/mapConfig/built/mapConfigStarAdapter-tests.js new file mode 100644 index 000000000..e7afa0ad3 --- /dev/null +++ b/htdocs/js/lib/vendor/components/requirejs/tests/mapConfig/built/mapConfigStarAdapter-tests.js @@ -0,0 +1,49 @@ + +define('d',{ + name: 'd' +}); + +define('adapter/d',['d'], function(d) { + d.adapted = true; + return d; +}); + +define('e',['d'], function (d) { + return { + name: 'e', + d: d + }; +}); + +/*global doh */ +require({ + baseUrl: './', + map: { + '*': { + 'd': 'adapter/d' + }, + 'adapter/d': { + d: 'd' + } + } + }, + ['e', 'adapter/d'], + function(e, adapterD) { + + doh.register( + 'mapConfigStarAdapter', + [ + function mapConfigStarAdapter(t){ + t.is('e', e.name); + t.is('d', e.d.name); + t.is(true, e.d.adapted); + t.is(true, adapterD.adapted); + t.is('d', adapterD.name); + } + ] + ); + doh.run(); + } +); + +define("mapConfigStarAdapter-tests", function(){}); diff --git a/htdocs/js/lib/vendor/components/requirejs/tests/mapConfig/built/mapConfigStarAdapterBuilt.html b/htdocs/js/lib/vendor/components/requirejs/tests/mapConfig/built/mapConfigStarAdapterBuilt.html new file mode 100644 index 000000000..205f50159 --- /dev/null +++ b/htdocs/js/lib/vendor/components/requirejs/tests/mapConfig/built/mapConfigStarAdapterBuilt.html @@ -0,0 +1,15 @@ + + + + require.js: Map Config Star Adapter Built Test + + + + + + +

      require.js: Map Config Star Adapter Built Test

      +

      Test using '*' with an adapter in the built map config.

      +

      Check console for messages

      + + diff --git a/htdocs/js/lib/vendor/components/requirejs/tests/mapConfig/built/mapConfigStarBuilt.html b/htdocs/js/lib/vendor/components/requirejs/tests/mapConfig/built/mapConfigStarBuilt.html new file mode 100644 index 000000000..14590b63c --- /dev/null +++ b/htdocs/js/lib/vendor/components/requirejs/tests/mapConfig/built/mapConfigStarBuilt.html @@ -0,0 +1,15 @@ + + + + require.js: Map Config Star Built Test + + + + + + +

      require.js: Map Config Star Built Test

      +

      Test using '*' in the built map config.

      +

      Check console for messages

      + + diff --git a/htdocs/js/lib/vendor/components/requirejs/tests/mapConfig/c.js b/htdocs/js/lib/vendor/components/requirejs/tests/mapConfig/c.js new file mode 100644 index 000000000..f01a0f832 --- /dev/null +++ b/htdocs/js/lib/vendor/components/requirejs/tests/mapConfig/c.js @@ -0,0 +1,3 @@ +define({ + name: 'c' +}); diff --git a/htdocs/js/lib/vendor/components/requirejs/tests/mapConfig/c/sub.js b/htdocs/js/lib/vendor/components/requirejs/tests/mapConfig/c/sub.js new file mode 100644 index 000000000..7baae0037 --- /dev/null +++ b/htdocs/js/lib/vendor/components/requirejs/tests/mapConfig/c/sub.js @@ -0,0 +1,3 @@ +define({ + name: 'c/sub' +}); diff --git a/htdocs/js/lib/vendor/components/requirejs/tests/mapConfig/c1.js b/htdocs/js/lib/vendor/components/requirejs/tests/mapConfig/c1.js new file mode 100644 index 000000000..e88ab8e5b --- /dev/null +++ b/htdocs/js/lib/vendor/components/requirejs/tests/mapConfig/c1.js @@ -0,0 +1,3 @@ +define({ + name: 'c1' +}); diff --git a/htdocs/js/lib/vendor/components/requirejs/tests/mapConfig/c1/sub.js b/htdocs/js/lib/vendor/components/requirejs/tests/mapConfig/c1/sub.js new file mode 100644 index 000000000..02a33ff76 --- /dev/null +++ b/htdocs/js/lib/vendor/components/requirejs/tests/mapConfig/c1/sub.js @@ -0,0 +1,3 @@ +define({ + name: 'c1/sub' +}); diff --git a/htdocs/js/lib/vendor/components/requirejs/tests/mapConfig/c2.js b/htdocs/js/lib/vendor/components/requirejs/tests/mapConfig/c2.js new file mode 100644 index 000000000..5d8143e2b --- /dev/null +++ b/htdocs/js/lib/vendor/components/requirejs/tests/mapConfig/c2.js @@ -0,0 +1,3 @@ +define({ + name: 'c2' +}); diff --git a/htdocs/js/lib/vendor/components/requirejs/tests/mapConfig/c2/sub.js b/htdocs/js/lib/vendor/components/requirejs/tests/mapConfig/c2/sub.js new file mode 100644 index 000000000..7384fb844 --- /dev/null +++ b/htdocs/js/lib/vendor/components/requirejs/tests/mapConfig/c2/sub.js @@ -0,0 +1,3 @@ +define({ + name: 'c2/sub' +}); diff --git a/htdocs/js/lib/vendor/components/requirejs/tests/mapConfig/d.js b/htdocs/js/lib/vendor/components/requirejs/tests/mapConfig/d.js new file mode 100644 index 000000000..0612045f8 --- /dev/null +++ b/htdocs/js/lib/vendor/components/requirejs/tests/mapConfig/d.js @@ -0,0 +1,3 @@ +define({ + name: 'd' +}); diff --git a/htdocs/js/lib/vendor/components/requirejs/tests/mapConfig/e.js b/htdocs/js/lib/vendor/components/requirejs/tests/mapConfig/e.js new file mode 100644 index 000000000..d2d3c47dc --- /dev/null +++ b/htdocs/js/lib/vendor/components/requirejs/tests/mapConfig/e.js @@ -0,0 +1,6 @@ +define(['d'], function (d) { + return { + name: 'e', + d: d + }; +}); diff --git a/htdocs/js/lib/vendor/components/requirejs/tests/mapConfig/mapConfig-tests.js b/htdocs/js/lib/vendor/components/requirejs/tests/mapConfig/mapConfig-tests.js new file mode 100644 index 000000000..59546e475 --- /dev/null +++ b/htdocs/js/lib/vendor/components/requirejs/tests/mapConfig/mapConfig-tests.js @@ -0,0 +1,34 @@ +require({ + baseUrl: './', + paths: { + a: 'a1' + }, + + map: { + 'a': { + c: 'c1' + }, + 'a/sub/one': { + 'c': 'c2' + } + } + }, + ['a', 'b', 'c', 'a/sub/one'], + function(a, b, c, one) { + doh.register( + 'mapConfig', + [ + function mapConfig(t){ + t.is('c1', a.c.name); + t.is('c1/sub', a.csub.name); + t.is('c2', one.c.name); + t.is('c2/sub', one.csub.name); + t.is('c', b.c.name); + t.is('c/sub', b.csub.name); + t.is('c', c.name); + } + ] + ); + doh.run(); + } +); diff --git a/htdocs/js/lib/vendor/components/requirejs/tests/mapConfig/mapConfig.html b/htdocs/js/lib/vendor/components/requirejs/tests/mapConfig/mapConfig.html new file mode 100644 index 000000000..db49ef039 --- /dev/null +++ b/htdocs/js/lib/vendor/components/requirejs/tests/mapConfig/mapConfig.html @@ -0,0 +1,15 @@ + + + + require.js: Map Config Test + + + + + + +

      require.js: Map Config Test

      +

      Test using the map config.

      +

      Check console for messages

      + + diff --git a/htdocs/js/lib/vendor/components/requirejs/tests/mapConfig/mapConfigDelayed-tests.js b/htdocs/js/lib/vendor/components/requirejs/tests/mapConfig/mapConfigDelayed-tests.js new file mode 100644 index 000000000..eb48978df --- /dev/null +++ b/htdocs/js/lib/vendor/components/requirejs/tests/mapConfig/mapConfigDelayed-tests.js @@ -0,0 +1,39 @@ +define('one', function () { + return { name: 'one' }; +}); + +define('two', function () { + return { name: 'two' }; +}); + +define('three', ['one'], function (one) { + return { name: 'three', + one: one + }; +}); + +require([], function() { + require({ + map : { + '*': { + 'one': 'two' + } + } + }, + ['three'], + function (three) { + doh.register( + 'mapConfigDelayed', + [ + function mapConfigDelayed(t){ + t.is('three', three.name); + t.is('two', three.one.name); + } + ] + ); + doh.run(); + } + ); +}); + +define("app", function(){}); diff --git a/htdocs/js/lib/vendor/components/requirejs/tests/mapConfig/mapConfigDelayed.html b/htdocs/js/lib/vendor/components/requirejs/tests/mapConfig/mapConfigDelayed.html new file mode 100644 index 000000000..e9de60d08 --- /dev/null +++ b/htdocs/js/lib/vendor/components/requirejs/tests/mapConfig/mapConfigDelayed.html @@ -0,0 +1,17 @@ + + + + require.js: Multiple Map Delayed Test + + + + + + +

      require.js: Multiple Map Config Delayed Test

      +

      Test application of map config after some have already registered + modules via define, but have not activated them yet. Related to: + 309

      +

      Check console for messages

      + + diff --git a/htdocs/js/lib/vendor/components/requirejs/tests/mapConfig/mapConfigMulti-tests.js b/htdocs/js/lib/vendor/components/requirejs/tests/mapConfig/mapConfigMulti-tests.js new file mode 100644 index 000000000..ff13e89a3 --- /dev/null +++ b/htdocs/js/lib/vendor/components/requirejs/tests/mapConfig/mapConfigMulti-tests.js @@ -0,0 +1,39 @@ +require({ + baseUrl: './', + paths: { + a: 'a1' + }, + + map: { + 'a': { + c: 'c1' + } + } +}); + +require({ + map: { + 'a/sub/one': { + 'c': 'c2' + } + } + }, + ['a', 'b', 'c', 'a/sub/one'], + function(a, b, c, one) { + doh.register( + 'mapConfig', + [ + function mapConfig(t){ + t.is('c1', a.c.name); + t.is('c1/sub', a.csub.name); + t.is('c2', one.c.name); + t.is('c2/sub', one.csub.name); + t.is('c', b.c.name); + t.is('c/sub', b.csub.name); + t.is('c', c.name); + } + ] + ); + doh.run(); + } +); diff --git a/htdocs/js/lib/vendor/components/requirejs/tests/mapConfig/mapConfigMulti.html b/htdocs/js/lib/vendor/components/requirejs/tests/mapConfig/mapConfigMulti.html new file mode 100644 index 000000000..d100d2f45 --- /dev/null +++ b/htdocs/js/lib/vendor/components/requirejs/tests/mapConfig/mapConfigMulti.html @@ -0,0 +1,15 @@ + + + + require.js: Multiple Map Config Test + + + + + + +

      require.js: Multiple Map Config Test

      +

      Test using the map config.

      +

      Check console for messages

      + + diff --git a/htdocs/js/lib/vendor/components/requirejs/tests/mapConfig/mapConfigPlugin-tests.js b/htdocs/js/lib/vendor/components/requirejs/tests/mapConfig/mapConfigPlugin-tests.js new file mode 100644 index 000000000..205ab6733 --- /dev/null +++ b/htdocs/js/lib/vendor/components/requirejs/tests/mapConfig/mapConfigPlugin-tests.js @@ -0,0 +1,37 @@ +require({ + baseUrl: './', + paths: { + a: 'a1' + }, + + map: { + '*': { + c: 'plug!' + }, + 'a': { + c: 'plug!c1' + }, + 'a/sub/one': { + 'c': 'plug!c2' + } + } + }, + ['a', 'b', 'c', 'a/sub/one'], + function(a, b, c, one) { + doh.register( + 'mapConfigPlugin', + [ + function mapConfigPlugin(t){ + t.is('plug!c1', a.c.name); + t.is('plug!c1', a.csub.name); + t.is('plug!c2', one.c.name); + t.is('plug!c2', one.csub.name); + t.is('plug!main', b.c.name); + t.is('plug!main', b.csub.name); + t.is('plug!main', c.name); + } + ] + ); + doh.run(); + } +); diff --git a/htdocs/js/lib/vendor/components/requirejs/tests/mapConfig/mapConfigPlugin.html b/htdocs/js/lib/vendor/components/requirejs/tests/mapConfig/mapConfigPlugin.html new file mode 100644 index 000000000..3590e5c87 --- /dev/null +++ b/htdocs/js/lib/vendor/components/requirejs/tests/mapConfig/mapConfigPlugin.html @@ -0,0 +1,17 @@ + + + + require.js: Map Config Plugin Test + + + + + + +

      require.js: Map Config Plugin Test

      +

      Test using the map config that has a plugin + for a value. + More info. +

      Check console for messages

      + + diff --git a/htdocs/js/lib/vendor/components/requirejs/tests/mapConfig/mapConfigRelative-tests.js b/htdocs/js/lib/vendor/components/requirejs/tests/mapConfig/mapConfigRelative-tests.js new file mode 100644 index 000000000..6017a0996 --- /dev/null +++ b/htdocs/js/lib/vendor/components/requirejs/tests/mapConfig/mapConfigRelative-tests.js @@ -0,0 +1,29 @@ +define('lib/b', [], { name: 'b' }); + +define('b1', [], { name: 'b1' }); + +define('lib/a', ['./b'], function(b) { + return { + name: 'a', + b: b + }; +}); + +require({ + map: { + 'lib/a': { + 'lib/b': 'b1' + } + } +},['lib/a'], function(a) { + doh.register( + 'mapConfigRelative', + [ + function mapConfigRelative(t){ + t.is('a', a.name); + t.is('b1', a.b.name); + } + ] + ); + doh.run(); +}); diff --git a/htdocs/js/lib/vendor/components/requirejs/tests/mapConfig/mapConfigRelative.html b/htdocs/js/lib/vendor/components/requirejs/tests/mapConfig/mapConfigRelative.html new file mode 100644 index 000000000..28615f8f7 --- /dev/null +++ b/htdocs/js/lib/vendor/components/requirejs/tests/mapConfig/mapConfigRelative.html @@ -0,0 +1,16 @@ + + + + require.js: Map Config Relative Test + + + + + + +

      require.js: Map Config Relative Test

      +

      Test using the map config on a relative dependency ID. More info: + 350

      +

      Check console for messages

      + + diff --git a/htdocs/js/lib/vendor/components/requirejs/tests/mapConfig/mapConfigSpecificity-tests.js b/htdocs/js/lib/vendor/components/requirejs/tests/mapConfig/mapConfigSpecificity-tests.js new file mode 100644 index 000000000..d08ceeb5f --- /dev/null +++ b/htdocs/js/lib/vendor/components/requirejs/tests/mapConfig/mapConfigSpecificity-tests.js @@ -0,0 +1,39 @@ +define('foo-1.0/bar/baz', [], function(){ return '1.0'; }); +define('foo-1.2/bar/baz', [], function(){ return '1.2'; }); + +define('oldmodule', ['foo/bar/baz'], function(baz) { + return { + name: 'oldmodule', + baz: baz + }; +}); + + +require({ + baseUrl: './', + + map: { + 'oldmodule': { + //This one should be favored over the * value. + 'foo' : 'foo-1.0' + }, + + '*': { + 'foo/bar' : 'foo-1.2/bar' + } + } + }, + ['oldmodule'], + function(oldmodule) { + doh.register( + 'mapConfigSpecificity', + [ + function mapConfigSpecificity(t){ + t.is('oldmodule', oldmodule.name); + t.is('1.0', oldmodule.baz); + } + ] + ); + doh.run(); + } +); diff --git a/htdocs/js/lib/vendor/components/requirejs/tests/mapConfig/mapConfigSpecificity.html b/htdocs/js/lib/vendor/components/requirejs/tests/mapConfig/mapConfigSpecificity.html new file mode 100644 index 000000000..822c53482 --- /dev/null +++ b/htdocs/js/lib/vendor/components/requirejs/tests/mapConfig/mapConfigSpecificity.html @@ -0,0 +1,16 @@ + + + + require.js: Map Config Specificity Test + + + + + + +

      require.js: Map Config Specificity Test

      +

      Test specificity of the map config. + More info.

      +

      Check console for messages

      + + diff --git a/htdocs/js/lib/vendor/components/requirejs/tests/mapConfig/mapConfigStar-tests.js b/htdocs/js/lib/vendor/components/requirejs/tests/mapConfig/mapConfigStar-tests.js new file mode 100644 index 000000000..f23083101 --- /dev/null +++ b/htdocs/js/lib/vendor/components/requirejs/tests/mapConfig/mapConfigStar-tests.js @@ -0,0 +1,41 @@ +require({ + baseUrl: './', + paths: { + a: 'a1' + }, + + map: { + '*': { + 'c': 'another/c' + }, + 'a': { + c: 'c1' + }, + 'a/sub/one': { + 'c': 'c2', + 'c/sub': 'another/c/sub' + } + } + }, + ['a', 'b', 'c', 'a/sub/one'], + function(a, b, c, one) { + doh.register( + 'mapConfigStar', + [ + function mapConfigStar(t){ + t.is('c1', a.c.name); + t.is('c1/sub', a.csub.name); + t.is('c2', one.c.name); + t.is('another/c/sub', one.csub.name); + t.is('another/c/dim', one.csub.dimName); + t.is('another/c', b.c.name); + t.is('another/minor', b.c.minorName); + t.is('another/c/sub', b.csub.name); + t.is('another/c', c.name); + t.is('another/minor', c.minorName); + } + ] + ); + doh.run(); + } +); diff --git a/htdocs/js/lib/vendor/components/requirejs/tests/mapConfig/mapConfigStar.html b/htdocs/js/lib/vendor/components/requirejs/tests/mapConfig/mapConfigStar.html new file mode 100644 index 000000000..a875694f4 --- /dev/null +++ b/htdocs/js/lib/vendor/components/requirejs/tests/mapConfig/mapConfigStar.html @@ -0,0 +1,15 @@ + + + + require.js: Map Config Star Test + + + + + + +

      require.js: Map Config Star Test

      +

      Test using '*' in the map config.

      +

      Check console for messages

      + + diff --git a/htdocs/js/lib/vendor/components/requirejs/tests/mapConfig/mapConfigStarAdapter-tests.js b/htdocs/js/lib/vendor/components/requirejs/tests/mapConfig/mapConfigStarAdapter-tests.js new file mode 100644 index 000000000..ecd162135 --- /dev/null +++ b/htdocs/js/lib/vendor/components/requirejs/tests/mapConfig/mapConfigStarAdapter-tests.js @@ -0,0 +1,30 @@ +/*global doh */ +require({ + baseUrl: './', + map: { + '*': { + 'd': 'adapter/d' + }, + 'adapter/d': { + d: 'd' + } + } + }, + ['e', 'adapter/d'], + function(e, adapterD) { + 'use strict'; + doh.register( + 'mapConfigStarAdapter', + [ + function mapConfigStarAdapter(t){ + t.is('e', e.name); + t.is('d', e.d.name); + t.is(true, e.d.adapted); + t.is(true, adapterD.adapted); + t.is('d', adapterD.name); + } + ] + ); + doh.run(); + } +); diff --git a/htdocs/js/lib/vendor/components/requirejs/tests/mapConfig/mapConfigStarAdapter.html b/htdocs/js/lib/vendor/components/requirejs/tests/mapConfig/mapConfigStarAdapter.html new file mode 100644 index 000000000..ca009fd04 --- /dev/null +++ b/htdocs/js/lib/vendor/components/requirejs/tests/mapConfig/mapConfigStarAdapter.html @@ -0,0 +1,18 @@ + + + + require.js: Map Config Star Swap Test + + + + + + +

      require.js: Map Config Star Swap Test

      +

      Test using '*' in the map config, but with an adapter module + that is used to load the non-* version and add to it. More info: + #277

      + +

      Check console for messages

      + + diff --git a/htdocs/js/lib/vendor/components/requirejs/tests/mapConfig/plug.js b/htdocs/js/lib/vendor/components/requirejs/tests/mapConfig/plug.js new file mode 100644 index 000000000..a13559b2b --- /dev/null +++ b/htdocs/js/lib/vendor/components/requirejs/tests/mapConfig/plug.js @@ -0,0 +1,18 @@ +define({ + load: function (name, require, load, config) { + if (!name) { + name = 'main'; + } else if (name.charAt(0) === '/') { + name = 'main' + name; + } + + //Only grab the first segment of the name. + //This is just to be different, nothing + //that is required behavior. + name = name.split('/').shift(); + + name = 'plug/' + name; + + require([name], load); + } +}); \ No newline at end of file diff --git a/htdocs/js/lib/vendor/components/requirejs/tests/mapConfig/plug/c1.js b/htdocs/js/lib/vendor/components/requirejs/tests/mapConfig/plug/c1.js new file mode 100644 index 000000000..f02437f91 --- /dev/null +++ b/htdocs/js/lib/vendor/components/requirejs/tests/mapConfig/plug/c1.js @@ -0,0 +1,3 @@ +define({ + name: 'plug!c1' +}); diff --git a/htdocs/js/lib/vendor/components/requirejs/tests/mapConfig/plug/c2.js b/htdocs/js/lib/vendor/components/requirejs/tests/mapConfig/plug/c2.js new file mode 100644 index 000000000..4a9d0cf4d --- /dev/null +++ b/htdocs/js/lib/vendor/components/requirejs/tests/mapConfig/plug/c2.js @@ -0,0 +1,3 @@ +define({ + name: 'plug!c2' +}); diff --git a/htdocs/js/lib/vendor/components/requirejs/tests/mapConfig/plug/main.js b/htdocs/js/lib/vendor/components/requirejs/tests/mapConfig/plug/main.js new file mode 100644 index 000000000..10fd8d0af --- /dev/null +++ b/htdocs/js/lib/vendor/components/requirejs/tests/mapConfig/plug/main.js @@ -0,0 +1,3 @@ +define({ + name: 'plug!main' +}); diff --git a/htdocs/js/lib/vendor/components/requirejs/tests/moduleConfig/a.js b/htdocs/js/lib/vendor/components/requirejs/tests/moduleConfig/a.js new file mode 100644 index 000000000..044e669e0 --- /dev/null +++ b/htdocs/js/lib/vendor/components/requirejs/tests/moduleConfig/a.js @@ -0,0 +1,5 @@ +define(['module'], function (module) { + return { + type: module.config().id + }; +}); diff --git a/htdocs/js/lib/vendor/components/requirejs/tests/moduleConfig/b/c.js b/htdocs/js/lib/vendor/components/requirejs/tests/moduleConfig/b/c.js new file mode 100644 index 000000000..156b1b45a --- /dev/null +++ b/htdocs/js/lib/vendor/components/requirejs/tests/moduleConfig/b/c.js @@ -0,0 +1,6 @@ +define(function (require, exports, module) { + return { + food: module.config().id + }; +}); + diff --git a/htdocs/js/lib/vendor/components/requirejs/tests/moduleConfig/moduleConfig-tests.js b/htdocs/js/lib/vendor/components/requirejs/tests/moduleConfig/moduleConfig-tests.js new file mode 100644 index 000000000..0eb145c98 --- /dev/null +++ b/htdocs/js/lib/vendor/components/requirejs/tests/moduleConfig/moduleConfig-tests.js @@ -0,0 +1,26 @@ +require({ + baseUrl: './', + config: { + a: { + id: 'magic' + }, + 'b/c': { + id: 'beans' + } + } + }, + ['a', 'b/c', 'plain'], + function(a, c, plain) { + doh.register( + 'moduleConfig', + [ + function moduleConfig(t){ + t.is('magic', a.type); + t.is('beans', c.food); + t.is('plain', plain.id); + } + ] + ); + doh.run(); + } +); diff --git a/htdocs/js/lib/vendor/components/requirejs/tests/moduleConfig/moduleConfig.html b/htdocs/js/lib/vendor/components/requirejs/tests/moduleConfig/moduleConfig.html new file mode 100644 index 000000000..d1d054b5c --- /dev/null +++ b/htdocs/js/lib/vendor/components/requirejs/tests/moduleConfig/moduleConfig.html @@ -0,0 +1,15 @@ + + + + require.js: Module Config Test + + + + + + +

      require.js: Module Config Test

      +

      Test passing data to a module via a config config. :)

      +

      Check console for messages

      + + diff --git a/htdocs/js/lib/vendor/components/requirejs/tests/moduleConfig/plain.js b/htdocs/js/lib/vendor/components/requirejs/tests/moduleConfig/plain.js new file mode 100644 index 000000000..fa9f07cdc --- /dev/null +++ b/htdocs/js/lib/vendor/components/requirejs/tests/moduleConfig/plain.js @@ -0,0 +1,6 @@ +define(function (require, exports, module) { + return { + //no config, just should get an empty object. + id: 'plain' + (module.config().foo || '') + } +}); diff --git a/htdocs/js/lib/vendor/components/requirejs/tests/multiversion.html b/htdocs/js/lib/vendor/components/requirejs/tests/multiversion.html new file mode 100644 index 000000000..2a8ce41b7 --- /dev/null +++ b/htdocs/js/lib/vendor/components/requirejs/tests/multiversion.html @@ -0,0 +1,95 @@ + + + + require.js: Multiversion Test + + + + + + +

      require.js: Multiversion Test

      + +

      Check console for messages.

      + +

      This test loads two different versions of a module by using the + "context" settings for require.

      + +

      It also tests loading a plain js file.

      + + diff --git a/htdocs/js/lib/vendor/components/requirejs/tests/nestedDefine/four.js b/htdocs/js/lib/vendor/components/requirejs/tests/nestedDefine/four.js new file mode 100644 index 000000000..f030e2325 --- /dev/null +++ b/htdocs/js/lib/vendor/components/requirejs/tests/nestedDefine/four.js @@ -0,0 +1,7 @@ +define(['two', 'three'], function (two, three) { + return { + name: 'four', + twoName: two.name, + threeName: three.name + }; +}); diff --git a/htdocs/js/lib/vendor/components/requirejs/tests/nestedDefine/nestedDefine.html b/htdocs/js/lib/vendor/components/requirejs/tests/nestedDefine/nestedDefine.html new file mode 100644 index 000000000..699f6d496 --- /dev/null +++ b/htdocs/js/lib/vendor/components/requirejs/tests/nestedDefine/nestedDefine.html @@ -0,0 +1,50 @@ + + + + require.js: Nested Define Test + + + + + + +

      require.js: Nested Define Test

      +

      Make sure a nested, named define call works in IE.

      +

      Check console for messages

      + + diff --git a/htdocs/js/lib/vendor/components/requirejs/tests/nestedDefine/nestedDefine2.html b/htdocs/js/lib/vendor/components/requirejs/tests/nestedDefine/nestedDefine2.html new file mode 100644 index 000000000..1f7612bd4 --- /dev/null +++ b/htdocs/js/lib/vendor/components/requirejs/tests/nestedDefine/nestedDefine2.html @@ -0,0 +1,15 @@ + + + + require.js: Nested Define2 Test + + + + + +

      require.js: Nested Define2 Test

      +

      Make sure a nested, named define call inside a require call is seen + by another require call done inside the outer require call..

      +

      Check console for messages

      + + diff --git a/htdocs/js/lib/vendor/components/requirejs/tests/nestedDefine/nestedDefine2.js b/htdocs/js/lib/vendor/components/requirejs/tests/nestedDefine/nestedDefine2.js new file mode 100644 index 000000000..7aacd9bdc --- /dev/null +++ b/htdocs/js/lib/vendor/components/requirejs/tests/nestedDefine/nestedDefine2.js @@ -0,0 +1,24 @@ + +require(['one'], function (one) { + + define('nested', ['two'], function (two) { + return { + name: 'nested', + two: two + }; + }); + + require(['nested'], function (nested) { + doh.register( + "nestedDefine2", + [ + function nestedDefine2(t) { + t.is("one", one.name); + t.is("two", nested.two.name); + t.is("nested", nested.name); + } + ] + ); + doh.run(); + }); +}); diff --git a/htdocs/js/lib/vendor/components/requirejs/tests/nestedDefine/one.js b/htdocs/js/lib/vendor/components/requirejs/tests/nestedDefine/one.js new file mode 100644 index 000000000..154839283 --- /dev/null +++ b/htdocs/js/lib/vendor/components/requirejs/tests/nestedDefine/one.js @@ -0,0 +1,3 @@ +define({ + name: 'one' +}); diff --git a/htdocs/js/lib/vendor/components/requirejs/tests/nestedDefine/two.js b/htdocs/js/lib/vendor/components/requirejs/tests/nestedDefine/two.js new file mode 100644 index 000000000..96e1a9959 --- /dev/null +++ b/htdocs/js/lib/vendor/components/requirejs/tests/nestedDefine/two.js @@ -0,0 +1,3 @@ +define({ + name: 'two' +}); diff --git a/htdocs/js/lib/vendor/components/requirejs/tests/nestedRelativeRequire/main.js b/htdocs/js/lib/vendor/components/requirejs/tests/nestedRelativeRequire/main.js new file mode 100644 index 000000000..92da3024b --- /dev/null +++ b/htdocs/js/lib/vendor/components/requirejs/tests/nestedRelativeRequire/main.js @@ -0,0 +1 @@ +require(['sub/a']); diff --git a/htdocs/js/lib/vendor/components/requirejs/tests/nestedRelativeRequire/nestedRelativeRequire.html b/htdocs/js/lib/vendor/components/requirejs/tests/nestedRelativeRequire/nestedRelativeRequire.html new file mode 100644 index 000000000..1a26643d0 --- /dev/null +++ b/htdocs/js/lib/vendor/components/requirejs/tests/nestedRelativeRequire/nestedRelativeRequire.html @@ -0,0 +1,15 @@ + + + + require.js: Nested Relative Require Test + + + + + +

      require.js: Nested Relative Require Test

      +

      Tests that a nested relative require([]) inside a define()'d module works.

      +

      More info: 282.

      +

      Check console for messages

      + + diff --git a/htdocs/js/lib/vendor/components/requirejs/tests/nestedRelativeRequire/sub/a.js b/htdocs/js/lib/vendor/components/requirejs/tests/nestedRelativeRequire/sub/a.js new file mode 100644 index 000000000..d388328af --- /dev/null +++ b/htdocs/js/lib/vendor/components/requirejs/tests/nestedRelativeRequire/sub/a.js @@ -0,0 +1,3 @@ +define(function(require) { + require(['./b']); +}); diff --git a/htdocs/js/lib/vendor/components/requirejs/tests/nestedRelativeRequire/sub/b.js b/htdocs/js/lib/vendor/components/requirejs/tests/nestedRelativeRequire/sub/b.js new file mode 100644 index 000000000..663f96d95 --- /dev/null +++ b/htdocs/js/lib/vendor/components/requirejs/tests/nestedRelativeRequire/sub/b.js @@ -0,0 +1,12 @@ +define(function(require) { + doh.register( + 'nestedRelativeRequire', + [ + function nestedRelativeRequire(t){ + //Just confirm it loaded. + t.is(true, true); + } + ] + ); + doh.run(); +}); diff --git a/htdocs/js/lib/vendor/components/requirejs/tests/nestedRequire/a.js b/htdocs/js/lib/vendor/components/requirejs/tests/nestedRequire/a.js new file mode 100644 index 000000000..b63b06b0d --- /dev/null +++ b/htdocs/js/lib/vendor/components/requirejs/tests/nestedRequire/a.js @@ -0,0 +1,13 @@ +define(['base'], function (base) { + return { + name: 'a', + counter: 0, + doSomething: function () { + this.counter += 1; + this.base = base; + //This should not cause double notifications. + require(['base'], function () { + }); + } + }; +}); diff --git a/htdocs/js/lib/vendor/components/requirejs/tests/nestedRequire/base.js b/htdocs/js/lib/vendor/components/requirejs/tests/nestedRequire/base.js new file mode 100644 index 000000000..22ce76fec --- /dev/null +++ b/htdocs/js/lib/vendor/components/requirejs/tests/nestedRequire/base.js @@ -0,0 +1,3 @@ +define({ + name: 'base' +}); diff --git a/htdocs/js/lib/vendor/components/requirejs/tests/nestedRequire/nestedRequire-tests.js b/htdocs/js/lib/vendor/components/requirejs/tests/nestedRequire/nestedRequire-tests.js new file mode 100644 index 000000000..14e60c72f --- /dev/null +++ b/htdocs/js/lib/vendor/components/requirejs/tests/nestedRequire/nestedRequire-tests.js @@ -0,0 +1,22 @@ +require({ + baseUrl: './' + }, + ['a'], + function(a) { + //This call then triggers another require call + //for a loaded resource. Make sure it does not + //trigger a double notification. + a.doSomething(); + + doh.register( + 'nestedRequire', + [ + function nestedRequire(t){ + t.is(1, a.counter); + t.is('base', a.base.name); + } + ] + ); + doh.run(); + } +); diff --git a/htdocs/js/lib/vendor/components/requirejs/tests/nestedRequire/nestedRequire.html b/htdocs/js/lib/vendor/components/requirejs/tests/nestedRequire/nestedRequire.html new file mode 100644 index 000000000..bee641d4a --- /dev/null +++ b/htdocs/js/lib/vendor/components/requirejs/tests/nestedRequire/nestedRequire.html @@ -0,0 +1,16 @@ + + + + require.js: Nested Require Test + + + + + + +

      require.js: Nested Require Test

      +

      Test that a require callback triggering another require does not do + a double notification.

      +

      Check console for messages

      + + diff --git a/htdocs/js/lib/vendor/components/requirejs/tests/nestedRequireConfig/nestedRequireConfig.html b/htdocs/js/lib/vendor/components/requirejs/tests/nestedRequireConfig/nestedRequireConfig.html new file mode 100644 index 000000000..201280be9 --- /dev/null +++ b/htdocs/js/lib/vendor/components/requirejs/tests/nestedRequireConfig/nestedRequireConfig.html @@ -0,0 +1,16 @@ + + + + require.js: Nested Require Config Test + + + + + +

      require.js: Nested Require Config Test

      +

      Make sure a nested require that sets a paths config works when target + module is finally loaded. + Info in Issue 309.

      +

      Check console for messages

      + + diff --git a/htdocs/js/lib/vendor/components/requirejs/tests/nestedRequireConfig/nestedRequireConfig.js b/htdocs/js/lib/vendor/components/requirejs/tests/nestedRequireConfig/nestedRequireConfig.js new file mode 100644 index 000000000..e9565a369 --- /dev/null +++ b/htdocs/js/lib/vendor/components/requirejs/tests/nestedRequireConfig/nestedRequireConfig.js @@ -0,0 +1,29 @@ +define('components/one/One', ['jquery'], function () { + return { + name: 'One' + }; +}); + +require([], function () { + require({ + paths : { + 'jquery' : 'http://code.jquery.com/jquery-1.7.2.min' + } + }, + [ + 'components/one/One' + ], function (One) { + doh.register( + "nestedRequireConfig", + [ + function nestedRequireConfig(t){ + t.is('One', One.name); + t.is(true, !!jQuery); + } + ] + ); + doh.run(); + }); + +}); +define("nestedRequireConfig", function(){}); \ No newline at end of file diff --git a/htdocs/js/lib/vendor/components/requirejs/tests/onResourceLoad/a.js b/htdocs/js/lib/vendor/components/requirejs/tests/onResourceLoad/a.js new file mode 100644 index 000000000..43b12280b --- /dev/null +++ b/htdocs/js/lib/vendor/components/requirejs/tests/onResourceLoad/a.js @@ -0,0 +1,13 @@ +define(function (require) { + //Important, notice the space between require and arg calls + var b = require ('b'); + + return (a = { + name: 'a', + b: b, + ids: [], + add: function (id) { + this.ids.push(id); + } + }); +}); diff --git a/htdocs/js/lib/vendor/components/requirejs/tests/onResourceLoad/b.js b/htdocs/js/lib/vendor/components/requirejs/tests/onResourceLoad/b.js new file mode 100644 index 000000000..6a0edcdb1 --- /dev/null +++ b/htdocs/js/lib/vendor/components/requirejs/tests/onResourceLoad/b.js @@ -0,0 +1,3 @@ +define({ + name: 'b' +}); diff --git a/htdocs/js/lib/vendor/components/requirejs/tests/onResourceLoad/nestedRequire-tests.js b/htdocs/js/lib/vendor/components/requirejs/tests/onResourceLoad/nestedRequire-tests.js new file mode 100644 index 000000000..e4875a73e --- /dev/null +++ b/htdocs/js/lib/vendor/components/requirejs/tests/onResourceLoad/nestedRequire-tests.js @@ -0,0 +1,44 @@ +var doneCount = 0; +var master = new doh.Deferred(); + +function finish(a) { + doh.is('a', a.name); + doh.is('b', a.b.name); + doh.is(2, a.ids.length); + doh.is('b', a.ids[0]); + doh.is('a', a.ids[1]); + master.callback(true); +} + +requirejs.onResourceLoad = function (context, map, depArray) { + require(["a"], function(a) { + doneCount += 1; + a.add(map.id); + + if (doneCount === 2) { + finish(a); + } + }); +}; + +require({ + baseUrl: './' + }, + ['a'], + function(a, b) { + + doh.register( + "onResourceLoadNestedRequire", + [ + { + name: "onResourceLoadNestedRequire", + timeout: 5000, + runTest: function () { + return master; + } + } + ] + ); + doh.run(); + } +); diff --git a/htdocs/js/lib/vendor/components/requirejs/tests/onResourceLoad/nestedRequire.html b/htdocs/js/lib/vendor/components/requirejs/tests/onResourceLoad/nestedRequire.html new file mode 100644 index 000000000..3e03ad407 --- /dev/null +++ b/htdocs/js/lib/vendor/components/requirejs/tests/onResourceLoad/nestedRequire.html @@ -0,0 +1,16 @@ + + + + require.js: onResourceLoad with nested require Test + + + + + + +

      require.js: onResourceLoad with nested require Test

      +

      Test semi-private API onResourceLoad with nested require. Documented + in Issue 262.

      +

      Check console for messages

      + + diff --git a/htdocs/js/lib/vendor/components/requirejs/tests/one.js b/htdocs/js/lib/vendor/components/requirejs/tests/one.js new file mode 100644 index 000000000..f068735a3 --- /dev/null +++ b/htdocs/js/lib/vendor/components/requirejs/tests/one.js @@ -0,0 +1,18 @@ +// +// Test comment +// +define('one', + [ + "require", "two" + ], + function(require) { + var one = { + size: "large", + doSomething: function() { + return require("two"); + } + }; + + return one; + } +) diff --git a/htdocs/js/lib/vendor/components/requirejs/tests/packages/bar/0.4/scripts/main.js b/htdocs/js/lib/vendor/components/requirejs/tests/packages/bar/0.4/scripts/main.js new file mode 100644 index 000000000..f7e99b4d1 --- /dev/null +++ b/htdocs/js/lib/vendor/components/requirejs/tests/packages/bar/0.4/scripts/main.js @@ -0,0 +1,4 @@ +define({ + name: 'bar', + version: '0.4' +}); diff --git a/htdocs/js/lib/vendor/components/requirejs/tests/packages/baz/lib/helper.js b/htdocs/js/lib/vendor/components/requirejs/tests/packages/baz/lib/helper.js new file mode 100644 index 000000000..37e807ac8 --- /dev/null +++ b/htdocs/js/lib/vendor/components/requirejs/tests/packages/baz/lib/helper.js @@ -0,0 +1,3 @@ +define({ + name: "baz/helper" +}); diff --git a/htdocs/js/lib/vendor/components/requirejs/tests/packages/baz/lib/index.js b/htdocs/js/lib/vendor/components/requirejs/tests/packages/baz/lib/index.js new file mode 100644 index 000000000..79790a72d --- /dev/null +++ b/htdocs/js/lib/vendor/components/requirejs/tests/packages/baz/lib/index.js @@ -0,0 +1,8 @@ +define(['bar', 'foo', './helper'], function (bar, foo, helper) { + return { + name: 'baz', + barDepVersion: bar.version, + fooName: foo.name, + helperName: helper.name + }; +}); diff --git a/htdocs/js/lib/vendor/components/requirejs/tests/packages/dojox/door.js b/htdocs/js/lib/vendor/components/requirejs/tests/packages/dojox/door.js new file mode 100644 index 000000000..9331374ee --- /dev/null +++ b/htdocs/js/lib/vendor/components/requirejs/tests/packages/dojox/door.js @@ -0,0 +1,3 @@ +define({ + name: 'dojox/door' +}); diff --git a/htdocs/js/lib/vendor/components/requirejs/tests/packages/dojox/window/pane.js b/htdocs/js/lib/vendor/components/requirejs/tests/packages/dojox/window/pane.js new file mode 100644 index 000000000..c53c9e555 --- /dev/null +++ b/htdocs/js/lib/vendor/components/requirejs/tests/packages/dojox/window/pane.js @@ -0,0 +1,3 @@ +define({ + name: 'dojox/window/pane' +}); diff --git a/htdocs/js/lib/vendor/components/requirejs/tests/packages/dojox/window/window.js b/htdocs/js/lib/vendor/components/requirejs/tests/packages/dojox/window/window.js new file mode 100644 index 000000000..b8834c2b6 --- /dev/null +++ b/htdocs/js/lib/vendor/components/requirejs/tests/packages/dojox/window/window.js @@ -0,0 +1,6 @@ +define(['./pane'], function (pane) { + return { + name: 'dojox/window', + paneName: pane.name + }; +}); diff --git a/htdocs/js/lib/vendor/components/requirejs/tests/packages/foo/lib/main.js b/htdocs/js/lib/vendor/components/requirejs/tests/packages/foo/lib/main.js new file mode 100644 index 000000000..95cae3083 --- /dev/null +++ b/htdocs/js/lib/vendor/components/requirejs/tests/packages/foo/lib/main.js @@ -0,0 +1,4 @@ +define(function (require, exports) { + exports.name = 'foo'; + exports.alphaName = require('alpha').name; +}); diff --git a/htdocs/js/lib/vendor/components/requirejs/tests/packages/foo/lib/second.js b/htdocs/js/lib/vendor/components/requirejs/tests/packages/foo/lib/second.js new file mode 100644 index 000000000..15656d2e0 --- /dev/null +++ b/htdocs/js/lib/vendor/components/requirejs/tests/packages/foo/lib/second.js @@ -0,0 +1,3 @@ +define({ + name: 'foo/second' +}); diff --git a/htdocs/js/lib/vendor/components/requirejs/tests/packages/funky/index.js b/htdocs/js/lib/vendor/components/requirejs/tests/packages/funky/index.js new file mode 100644 index 000000000..701fc2ae2 --- /dev/null +++ b/htdocs/js/lib/vendor/components/requirejs/tests/packages/funky/index.js @@ -0,0 +1,6 @@ +define(['./lib/monkey'], function (monkey) { + return { + name: 'funky', + monkeyName: monkey.name + }; +}); diff --git a/htdocs/js/lib/vendor/components/requirejs/tests/packages/funky/lib/monkey.js b/htdocs/js/lib/vendor/components/requirejs/tests/packages/funky/lib/monkey.js new file mode 100644 index 000000000..35a3bf681 --- /dev/null +++ b/htdocs/js/lib/vendor/components/requirejs/tests/packages/funky/lib/monkey.js @@ -0,0 +1,3 @@ +define({ + name: 'monkey' +}); diff --git a/htdocs/js/lib/vendor/components/requirejs/tests/packages/optimizing/build.js b/htdocs/js/lib/vendor/components/requirejs/tests/packages/optimizing/build.js new file mode 100644 index 000000000..e851bb7b3 --- /dev/null +++ b/htdocs/js/lib/vendor/components/requirejs/tests/packages/optimizing/build.js @@ -0,0 +1,29 @@ +({ + appDir: '.', + baseUrl: '.', + dir: 'built', + optimize: 'none', + + packages: [ + { + name: 'engine', + location: 'packages/engine' + }, + { + name: 'tires', + location: 'packages/tires' + }, + { + name: 'fuel', + location: 'packages/fuel' + } + ], + + modules: [ + { name: "main" }, + { name: "engine" }, + { name: "tires" }, + { name: "fuel" } + ] + +}) \ No newline at end of file diff --git a/htdocs/js/lib/vendor/components/requirejs/tests/packages/optimizing/main.js b/htdocs/js/lib/vendor/components/requirejs/tests/packages/optimizing/main.js new file mode 100644 index 000000000..2309b00df --- /dev/null +++ b/htdocs/js/lib/vendor/components/requirejs/tests/packages/optimizing/main.js @@ -0,0 +1,34 @@ +require.config({ + packages: [ + { + name: 'engine', + location: 'packages/engine' + }, + { + name: 'tires', + location: 'packages/tires' + }, + { + name: 'fuel', + location: 'packages/fuel' + } + ] +}); + +define(['engine', 'tires', 'fuel'], function (engine, tires, fuel) { + + doh.register( + "optimizingPackages", + [ + function optimizingPackages(t){ + t.is("engine", engine.name); + t.is("pistons", engine.pistonsName); + t.is("sparkplugs", engine.sparkplugsName); + t.is("tires", tires.name); + t.is("fuel", fuel.name); + } + ] + ); + doh.run(); + +}); diff --git a/htdocs/js/lib/vendor/components/requirejs/tests/packages/optimizing/optimizing-built.html b/htdocs/js/lib/vendor/components/requirejs/tests/packages/optimizing/optimizing-built.html new file mode 100644 index 000000000..ad8375f59 --- /dev/null +++ b/htdocs/js/lib/vendor/components/requirejs/tests/packages/optimizing/optimizing-built.html @@ -0,0 +1,14 @@ + + + + require.js: Optimizing Packages Test + + + + + +

      require.js: Optimizing Packages Test

      +

      Tests that a package project works the same before and after an optimization.

      +

      Check console for messages

      + + diff --git a/htdocs/js/lib/vendor/components/requirejs/tests/packages/optimizing/optimizing.html b/htdocs/js/lib/vendor/components/requirejs/tests/packages/optimizing/optimizing.html new file mode 100644 index 000000000..9a1f5b702 --- /dev/null +++ b/htdocs/js/lib/vendor/components/requirejs/tests/packages/optimizing/optimizing.html @@ -0,0 +1,14 @@ + + + + require.js: Optimizing Packages Test + + + + + +

      require.js: Optimizing Packages Test

      +

      Tests that a package project works the same before and after an optimization.

      +

      Check console for messages

      + + diff --git a/htdocs/js/lib/vendor/components/requirejs/tests/packages/optimizing/packages/engine/main.js b/htdocs/js/lib/vendor/components/requirejs/tests/packages/optimizing/packages/engine/main.js new file mode 100644 index 000000000..d6fa174e1 --- /dev/null +++ b/htdocs/js/lib/vendor/components/requirejs/tests/packages/optimizing/packages/engine/main.js @@ -0,0 +1,7 @@ +define(['./pistons', './sparkplugs'], function (pistons, sparkplugs) { + return { + name: 'engine', + pistonsName: pistons.name, + sparkplugsName: sparkplugs.name + }; +}); \ No newline at end of file diff --git a/htdocs/js/lib/vendor/components/requirejs/tests/packages/optimizing/packages/engine/pistons.js b/htdocs/js/lib/vendor/components/requirejs/tests/packages/optimizing/packages/engine/pistons.js new file mode 100644 index 000000000..352f068b7 --- /dev/null +++ b/htdocs/js/lib/vendor/components/requirejs/tests/packages/optimizing/packages/engine/pistons.js @@ -0,0 +1,3 @@ +define({ + name: 'pistons' +}); \ No newline at end of file diff --git a/htdocs/js/lib/vendor/components/requirejs/tests/packages/optimizing/packages/engine/sparkplugs.js b/htdocs/js/lib/vendor/components/requirejs/tests/packages/optimizing/packages/engine/sparkplugs.js new file mode 100644 index 000000000..2ae616786 --- /dev/null +++ b/htdocs/js/lib/vendor/components/requirejs/tests/packages/optimizing/packages/engine/sparkplugs.js @@ -0,0 +1,3 @@ +define({ + name: 'sparkplugs' +}); \ No newline at end of file diff --git a/htdocs/js/lib/vendor/components/requirejs/tests/packages/optimizing/packages/fuel/main.js b/htdocs/js/lib/vendor/components/requirejs/tests/packages/optimizing/packages/fuel/main.js new file mode 100644 index 000000000..9a61262a5 --- /dev/null +++ b/htdocs/js/lib/vendor/components/requirejs/tests/packages/optimizing/packages/fuel/main.js @@ -0,0 +1,3 @@ +define({ + name: 'fuel' +}); diff --git a/htdocs/js/lib/vendor/components/requirejs/tests/packages/optimizing/packages/tires/main.js b/htdocs/js/lib/vendor/components/requirejs/tests/packages/optimizing/packages/tires/main.js new file mode 100644 index 000000000..79db3c082 --- /dev/null +++ b/htdocs/js/lib/vendor/components/requirejs/tests/packages/optimizing/packages/tires/main.js @@ -0,0 +1,3 @@ +define({ + name: 'tires' +}); \ No newline at end of file diff --git a/htdocs/js/lib/vendor/components/requirejs/tests/packages/packages-tests.js b/htdocs/js/lib/vendor/components/requirejs/tests/packages/packages-tests.js new file mode 100644 index 000000000..e4d66f2d8 --- /dev/null +++ b/htdocs/js/lib/vendor/components/requirejs/tests/packages/packages-tests.js @@ -0,0 +1,90 @@ +require({ + baseUrl: requirejs.isBrowser ? "./" : "./packages/", + paths: { + 'alpha/replace' : 'replace' + }, + packages: [ + { + name: 'alpha', + location: 'pkgs/alpha' + }, + { + name: 'beta', + location: 'pkgs/beta/0.2/scripts', + main: 'beta' + }, + { + name: 'dojox/chair', + location: 'pkgs/dojox/chair' + }, + { + name: 'dojox/table', + location: 'pkgs/dojox/table', + main: 'table' + }, + { + name: 'bar', + location: 'bar/0.4', + main: 'scripts/main' + }, + { + name: 'foo', + location: 'foo/lib' + }, + { + name: 'funky', + main: 'index.js' + }, + { + name: 'baz', + location: 'baz/lib', + main: 'index' + }, + { + name: 'dojox/window', + location: 'dojox/window', + main: 'window' + } + ] + }, + ["require", "alpha", "alpha/replace", "beta", "beta/util", "bar", "baz", + "foo", "foo/second", "dojox/chair", "dojox/table", "dojox/door", "dojox/window/pane", + "dojox/window", "dojox/table/legs", "funky"], +function(require, alpha, replace, beta, util, bar, baz, + foo, second, chair, table, door, pane, + window, legs, funky) { + var dataUrl = require.toUrl('foo/../data.html'); + doh.register( + "packages", + [ + function packages(t){ + t.is("alpha", alpha.name); + t.is("fake/alpha/replace", replace.name); + t.is("beta", beta); + t.is("beta/util", util.name); + t.is("bar", bar.name); + t.is("0.4", bar.version); + t.is("baz", baz.name); + t.is("0.4", baz.barDepVersion); + t.is("foo", baz.fooName); + t.is("baz/helper", baz.helperName); + t.is("foo", foo.name); + t.is("alpha", foo.alphaName); + t.is("foo/second", second.name); + t.is((requirejs.isBrowser ? "./foo/lib/../data.html" : "./packages/foo/lib/../data.html"), dataUrl); + t.is('dojox/chair', chair.name); + t.is('dojox/chair/legs', chair.legsName); + t.is('dojox/table', table.name); + t.is('dojox/chair', table.chairName); + t.is('dojox/table/legs', legs.name); + t.is('dojox/door', door.name); + t.is('dojox/window/pane', pane.name); + t.is('dojox/window', window.name); + t.is('dojox/window/pane', window.paneName); + t.is('funky', funky.name); + t.is('monkey', funky.monkeyName); + } + ] + ); + doh.run(); +}); diff --git a/htdocs/js/lib/vendor/components/requirejs/tests/packages/packages.html b/htdocs/js/lib/vendor/components/requirejs/tests/packages/packages.html new file mode 100644 index 000000000..8f367ec4e --- /dev/null +++ b/htdocs/js/lib/vendor/components/requirejs/tests/packages/packages.html @@ -0,0 +1,14 @@ + + + + require.js: Packages Test + + + + + + +

      require.js: Packages Test

      +

      Check console for messages

      + + diff --git a/htdocs/js/lib/vendor/components/requirejs/tests/packages/pkgs/alpha/main.js b/htdocs/js/lib/vendor/components/requirejs/tests/packages/pkgs/alpha/main.js new file mode 100644 index 000000000..ca75acdb3 --- /dev/null +++ b/htdocs/js/lib/vendor/components/requirejs/tests/packages/pkgs/alpha/main.js @@ -0,0 +1,3 @@ +define({ + name: 'alpha' +}); \ No newline at end of file diff --git a/htdocs/js/lib/vendor/components/requirejs/tests/packages/pkgs/alpha/replace.js b/htdocs/js/lib/vendor/components/requirejs/tests/packages/pkgs/alpha/replace.js new file mode 100644 index 000000000..45aed7f98 --- /dev/null +++ b/htdocs/js/lib/vendor/components/requirejs/tests/packages/pkgs/alpha/replace.js @@ -0,0 +1,3 @@ +define({ + name: 'alpha/replace' +}); diff --git a/htdocs/js/lib/vendor/components/requirejs/tests/packages/pkgs/beta/0.2/scripts/beta.js b/htdocs/js/lib/vendor/components/requirejs/tests/packages/pkgs/beta/0.2/scripts/beta.js new file mode 100644 index 000000000..6bac25a1f --- /dev/null +++ b/htdocs/js/lib/vendor/components/requirejs/tests/packages/pkgs/beta/0.2/scripts/beta.js @@ -0,0 +1,3 @@ +define(function () { + return 'beta'; +}); diff --git a/htdocs/js/lib/vendor/components/requirejs/tests/packages/pkgs/beta/0.2/scripts/util.js b/htdocs/js/lib/vendor/components/requirejs/tests/packages/pkgs/beta/0.2/scripts/util.js new file mode 100644 index 000000000..39b0155ed --- /dev/null +++ b/htdocs/js/lib/vendor/components/requirejs/tests/packages/pkgs/beta/0.2/scripts/util.js @@ -0,0 +1,3 @@ +define({ + name: 'beta/util' +}); diff --git a/htdocs/js/lib/vendor/components/requirejs/tests/packages/pkgs/dojox/chair/legs.js b/htdocs/js/lib/vendor/components/requirejs/tests/packages/pkgs/dojox/chair/legs.js new file mode 100644 index 000000000..af489b556 --- /dev/null +++ b/htdocs/js/lib/vendor/components/requirejs/tests/packages/pkgs/dojox/chair/legs.js @@ -0,0 +1,3 @@ +define({ + name: 'dojox/chair/legs' +}); diff --git a/htdocs/js/lib/vendor/components/requirejs/tests/packages/pkgs/dojox/chair/main.js b/htdocs/js/lib/vendor/components/requirejs/tests/packages/pkgs/dojox/chair/main.js new file mode 100644 index 000000000..0a08ab6d4 --- /dev/null +++ b/htdocs/js/lib/vendor/components/requirejs/tests/packages/pkgs/dojox/chair/main.js @@ -0,0 +1,6 @@ +define(['./legs'], function (legs) { + return { + name: 'dojox/chair', + legsName: legs.name + } +}); diff --git a/htdocs/js/lib/vendor/components/requirejs/tests/packages/pkgs/dojox/table/legs.js b/htdocs/js/lib/vendor/components/requirejs/tests/packages/pkgs/dojox/table/legs.js new file mode 100644 index 000000000..d2b91a916 --- /dev/null +++ b/htdocs/js/lib/vendor/components/requirejs/tests/packages/pkgs/dojox/table/legs.js @@ -0,0 +1,3 @@ +define({ + name: 'dojox/table/legs' +}); diff --git a/htdocs/js/lib/vendor/components/requirejs/tests/packages/pkgs/dojox/table/table.js b/htdocs/js/lib/vendor/components/requirejs/tests/packages/pkgs/dojox/table/table.js new file mode 100644 index 000000000..5a6ebe392 --- /dev/null +++ b/htdocs/js/lib/vendor/components/requirejs/tests/packages/pkgs/dojox/table/table.js @@ -0,0 +1,6 @@ +define(['dojox/chair'], function (chair) { + return { + name: 'dojox/table', + chairName: chair.name + }; +}); diff --git a/htdocs/js/lib/vendor/components/requirejs/tests/packages/replace.js b/htdocs/js/lib/vendor/components/requirejs/tests/packages/replace.js new file mode 100644 index 000000000..50e7bcac4 --- /dev/null +++ b/htdocs/js/lib/vendor/components/requirejs/tests/packages/replace.js @@ -0,0 +1,4 @@ +//Tests overriding a package path with a more specific mapping. +define({ + name: 'fake/alpha/replace' +}); diff --git a/htdocs/js/lib/vendor/components/requirejs/tests/pathArray/pathArray.html b/htdocs/js/lib/vendor/components/requirejs/tests/pathArray/pathArray.html new file mode 100644 index 000000000..421840c27 --- /dev/null +++ b/htdocs/js/lib/vendor/components/requirejs/tests/pathArray/pathArray.html @@ -0,0 +1,56 @@ + + + + require.js: Path Array Test + + + + + + +

      require.js: Path Array Test

      + +

      Using an array for a path value to get retries. See + 257

      + +

      Check console for messages

      + + diff --git a/htdocs/js/lib/vendor/components/requirejs/tests/pathArray/pathArrayFail.html b/htdocs/js/lib/vendor/components/requirejs/tests/pathArray/pathArrayFail.html new file mode 100644 index 000000000..6b832517e --- /dev/null +++ b/htdocs/js/lib/vendor/components/requirejs/tests/pathArray/pathArrayFail.html @@ -0,0 +1,72 @@ + + + + require.js: Path Array Fail Test + + + + + + +

      require.js: Path Array Fail Test

      + +

      Using an array for a path value to get retries, but fail on all the + retries. For more info see + 257

      + +

      Check console for messages

      + + diff --git a/htdocs/js/lib/vendor/components/requirejs/tests/pathArray/real.js b/htdocs/js/lib/vendor/components/requirejs/tests/pathArray/real.js new file mode 100644 index 000000000..c041aaa42 --- /dev/null +++ b/htdocs/js/lib/vendor/components/requirejs/tests/pathArray/real.js @@ -0,0 +1,3 @@ +define({ + name: 'real' +}); diff --git a/htdocs/js/lib/vendor/components/requirejs/tests/paths/first.js/first.js b/htdocs/js/lib/vendor/components/requirejs/tests/paths/first.js/first.js new file mode 100644 index 000000000..72b6a942e --- /dev/null +++ b/htdocs/js/lib/vendor/components/requirejs/tests/paths/first.js/first.js @@ -0,0 +1,8 @@ +globalCounter += 1; + +define(['./second'], function (second) { + globalCounter += 1; + return { + load: second + }; +}); diff --git a/htdocs/js/lib/vendor/components/requirejs/tests/paths/first.js/second.js b/htdocs/js/lib/vendor/components/requirejs/tests/paths/first.js/second.js new file mode 100644 index 000000000..9ebcda1a0 --- /dev/null +++ b/htdocs/js/lib/vendor/components/requirejs/tests/paths/first.js/second.js @@ -0,0 +1,8 @@ +define(['./first'], function () { + return function (id, parentRequire, loaded) { + loaded({ + name: 'first', + secondName: 'second' + }); + }; +}); diff --git a/htdocs/js/lib/vendor/components/requirejs/tests/paths/impl/array.js b/htdocs/js/lib/vendor/components/requirejs/tests/paths/impl/array.js new file mode 100644 index 000000000..8a5d357ac --- /dev/null +++ b/htdocs/js/lib/vendor/components/requirejs/tests/paths/impl/array.js @@ -0,0 +1,6 @@ +define(['./util'], function (util) { + return { + name: 'impl/array', + utilName: util.name + }; +}); diff --git a/htdocs/js/lib/vendor/components/requirejs/tests/paths/impl/util.js b/htdocs/js/lib/vendor/components/requirejs/tests/paths/impl/util.js new file mode 100644 index 000000000..ee090bc74 --- /dev/null +++ b/htdocs/js/lib/vendor/components/requirejs/tests/paths/impl/util.js @@ -0,0 +1,3 @@ +define({ + name: 'impl/util' +}); diff --git a/htdocs/js/lib/vendor/components/requirejs/tests/paths/paths.html b/htdocs/js/lib/vendor/components/requirejs/tests/paths/paths.html new file mode 100644 index 000000000..8853d0ddd --- /dev/null +++ b/htdocs/js/lib/vendor/components/requirejs/tests/paths/paths.html @@ -0,0 +1,54 @@ + + + + require.js: paths Test + + + + + + +

      require.js: paths Test

      +

      Check console for messages

      + + diff --git a/htdocs/js/lib/vendor/components/requirejs/tests/paths/relativeModuleId-tests.js b/htdocs/js/lib/vendor/components/requirejs/tests/paths/relativeModuleId-tests.js new file mode 100644 index 000000000..32208ef40 --- /dev/null +++ b/htdocs/js/lib/vendor/components/requirejs/tests/paths/relativeModuleId-tests.js @@ -0,0 +1,21 @@ +require({ + baseUrl: "./", + paths: { + "array": "impl/array" + } + }, + ["require", "array"], + function(require, array) { + doh.register( + "relativeModuleId", + [ + function relativeModuleId(t){ + t.is("impl/array", array.name); + t.is("util", array.utilName); + } + ] + ); + + doh.run(); + } +); diff --git a/htdocs/js/lib/vendor/components/requirejs/tests/paths/relativeModuleId.html b/htdocs/js/lib/vendor/components/requirejs/tests/paths/relativeModuleId.html new file mode 100644 index 000000000..5e49f1bcb --- /dev/null +++ b/htdocs/js/lib/vendor/components/requirejs/tests/paths/relativeModuleId.html @@ -0,0 +1,13 @@ + + + + require.js: Relative Module ID Test + + + + + +

      require.js: Relative Module ID Test

      +

      Check console for messages

      + + diff --git a/htdocs/js/lib/vendor/components/requirejs/tests/paths/relativeNormalize/bar/baz.js b/htdocs/js/lib/vendor/components/requirejs/tests/paths/relativeNormalize/bar/baz.js new file mode 100644 index 000000000..a73cbaa74 --- /dev/null +++ b/htdocs/js/lib/vendor/components/requirejs/tests/paths/relativeNormalize/bar/baz.js @@ -0,0 +1,6 @@ +define(function (require) { + return { + name: 'baz', + foo: require('./foo') + }; +}); diff --git a/htdocs/js/lib/vendor/components/requirejs/tests/paths/relativeNormalize/foo2.js b/htdocs/js/lib/vendor/components/requirejs/tests/paths/relativeNormalize/foo2.js new file mode 100644 index 000000000..751142ada --- /dev/null +++ b/htdocs/js/lib/vendor/components/requirejs/tests/paths/relativeNormalize/foo2.js @@ -0,0 +1,3 @@ +define({ + name: 'foo2' +}); diff --git a/htdocs/js/lib/vendor/components/requirejs/tests/paths/relativeNormalize/relativeNormalize-tests.js b/htdocs/js/lib/vendor/components/requirejs/tests/paths/relativeNormalize/relativeNormalize-tests.js new file mode 100644 index 000000000..f4b2f2f95 --- /dev/null +++ b/htdocs/js/lib/vendor/components/requirejs/tests/paths/relativeNormalize/relativeNormalize-tests.js @@ -0,0 +1,21 @@ +require({ + baseUrl: "./", + paths: { + "bar/foo": "foo2" + } + }, + ["require", "bar/baz"], + function(require, baz) { + doh.register( + "relativeNormalize", + [ + function relativeNormalize(t){ + t.is("baz", baz.name); + t.is("foo2", baz.foo.name); + } + ] + ); + + doh.run(); + } +); diff --git a/htdocs/js/lib/vendor/components/requirejs/tests/paths/relativeNormalize/relativeNormalize.html b/htdocs/js/lib/vendor/components/requirejs/tests/paths/relativeNormalize/relativeNormalize.html new file mode 100644 index 000000000..a0bcd2c52 --- /dev/null +++ b/htdocs/js/lib/vendor/components/requirejs/tests/paths/relativeNormalize/relativeNormalize.html @@ -0,0 +1,17 @@ + + + + require.js: Relative Normalize Test + + + + + +

      require.js: Relative Normalize Test

      + +

      Make sure relative require inside a module gets normalized using paths config. + More info in 294

      + +

      Check console for messages

      + + diff --git a/htdocs/js/lib/vendor/components/requirejs/tests/paths/util.js b/htdocs/js/lib/vendor/components/requirejs/tests/paths/util.js new file mode 100644 index 000000000..a0cc74f78 --- /dev/null +++ b/htdocs/js/lib/vendor/components/requirejs/tests/paths/util.js @@ -0,0 +1,3 @@ +define({ + name: 'util' +}); diff --git a/htdocs/js/lib/vendor/components/requirejs/tests/plugins/a.js b/htdocs/js/lib/vendor/components/requirejs/tests/plugins/a.js new file mode 100644 index 000000000..35be9ea32 --- /dev/null +++ b/htdocs/js/lib/vendor/components/requirejs/tests/plugins/a.js @@ -0,0 +1,3 @@ +define({ + name: 'a' +}); diff --git a/htdocs/js/lib/vendor/components/requirejs/tests/plugins/b.js b/htdocs/js/lib/vendor/components/requirejs/tests/plugins/b.js new file mode 100644 index 000000000..297279f14 --- /dev/null +++ b/htdocs/js/lib/vendor/components/requirejs/tests/plugins/b.js @@ -0,0 +1,5 @@ +define(function () { + return { + name: "b" + }; +}); diff --git a/htdocs/js/lib/vendor/components/requirejs/tests/plugins/c.js b/htdocs/js/lib/vendor/components/requirejs/tests/plugins/c.js new file mode 100644 index 000000000..c863301c5 --- /dev/null +++ b/htdocs/js/lib/vendor/components/requirejs/tests/plugins/c.js @@ -0,0 +1,3 @@ +define({ + name: "c" +}); diff --git a/htdocs/js/lib/vendor/components/requirejs/tests/plugins/double.html b/htdocs/js/lib/vendor/components/requirejs/tests/plugins/double.html new file mode 100644 index 000000000..393ab93a0 --- /dev/null +++ b/htdocs/js/lib/vendor/components/requirejs/tests/plugins/double.html @@ -0,0 +1,51 @@ + + + + require.js: Double Plugin Call Test + + + + + + +

      require.js: Double Plugin Call Test

      +

      Check console for messages

      + + diff --git a/htdocs/js/lib/vendor/components/requirejs/tests/plugins/double.js b/htdocs/js/lib/vendor/components/requirejs/tests/plugins/double.js new file mode 100644 index 000000000..61a4f118f --- /dev/null +++ b/htdocs/js/lib/vendor/components/requirejs/tests/plugins/double.js @@ -0,0 +1,5 @@ +define({ + load: function (name, req, load, config) { + load('x'); + } +}); diff --git a/htdocs/js/lib/vendor/components/requirejs/tests/plugins/earth.js b/htdocs/js/lib/vendor/components/requirejs/tests/plugins/earth.js new file mode 100644 index 000000000..ed3e3ec99 --- /dev/null +++ b/htdocs/js/lib/vendor/components/requirejs/tests/plugins/earth.js @@ -0,0 +1,13 @@ +define(function (require) { + return { + getA: function () { + return require("./index!0?./a:./b:./c"); + }, + getC: function () { + return require("./index!2?./a:./b:./c"); + }, + getB: function () { + return require("./index!1?./a:./b:./c"); + } + }; +}); diff --git a/htdocs/js/lib/vendor/components/requirejs/tests/plugins/fromText/a.refine b/htdocs/js/lib/vendor/components/requirejs/tests/plugins/fromText/a.refine new file mode 100644 index 000000000..a3c306156 --- /dev/null +++ b/htdocs/js/lib/vendor/components/requirejs/tests/plugins/fromText/a.refine @@ -0,0 +1,4 @@ +//The refine plugin changes the word refine into define. +refine({ + name: 'a' +}); diff --git a/htdocs/js/lib/vendor/components/requirejs/tests/plugins/fromText/fromText-tests.js b/htdocs/js/lib/vendor/components/requirejs/tests/plugins/fromText/fromText-tests.js new file mode 100644 index 000000000..dc7c688fc --- /dev/null +++ b/htdocs/js/lib/vendor/components/requirejs/tests/plugins/fromText/fromText-tests.js @@ -0,0 +1,18 @@ +require({ + baseUrl: requirejs.isBrowser ? './' : './plugins/fromText', + paths: { + 'text': '../../../../text/text' + } +}, ['refine!a'], +function (a) { + + doh.register( + 'pluginsFromText', + [ + function pluginsFromText(t){ + t.is('a', a.name); + } + ] + ); + doh.run(); +}); diff --git a/htdocs/js/lib/vendor/components/requirejs/tests/plugins/fromText/fromText.html b/htdocs/js/lib/vendor/components/requirejs/tests/plugins/fromText/fromText.html new file mode 100644 index 000000000..0cc46c524 --- /dev/null +++ b/htdocs/js/lib/vendor/components/requirejs/tests/plugins/fromText/fromText.html @@ -0,0 +1,13 @@ + + + + require.js: fromText Plugin Test + + + + + +

      require.js: fromText Plugin Test

      +

      Check console for messages

      + + diff --git a/htdocs/js/lib/vendor/components/requirejs/tests/plugins/fromText/refine.js b/htdocs/js/lib/vendor/components/requirejs/tests/plugins/fromText/refine.js new file mode 100644 index 000000000..0a98e6efe --- /dev/null +++ b/htdocs/js/lib/vendor/components/requirejs/tests/plugins/fromText/refine.js @@ -0,0 +1,130 @@ + +/*jslint strict: false, plusplus: false */ +/*global define: false, require: false, XMLHttpRequest: false, ActiveXObject: false, + window: false, Packages: false, java: false, process: false */ + +(function () { + //Load the text plugin, so that the XHR calls can be made. + var buildMap = {}, fetchText, fs, + progIds = ['Msxml2.XMLHTTP', 'Microsoft.XMLHTTP', 'Msxml2.XMLHTTP.4.0']; + + function createXhr() { + //Would love to dump the ActiveX crap in here. Need IE 6 to die first. + var xhr, i, progId; + if (typeof XMLHttpRequest !== "undefined") { + return new XMLHttpRequest(); + } else { + for (i = 0; i < 3; i++) { + progId = progIds[i]; + try { + xhr = new ActiveXObject(progId); + } catch (e) {} + + if (xhr) { + progIds = [progId]; // so faster next time + break; + } + } + } + + if (!xhr) { + throw new Error("require.getXhr(): XMLHttpRequest not available"); + } + + return xhr; + } + + if (typeof window !== "undefined" && window.navigator && window.document) { + fetchText = function (url, callback) { + var xhr = createXhr(); + xhr.open('GET', url, true); + xhr.onreadystatechange = function (evt) { + //Do not explicitly handle errors, those should be + //visible via console output in the browser. + if (xhr.readyState === 4) { + callback(xhr.responseText); + } + }; + xhr.send(null); + }; + } else if (typeof process !== "undefined" && + process.versions && + !!process.versions.node) { + //Using special require.nodeRequire, something added by r.js. + fs = require.nodeRequire('fs'); + + fetchText = function (url, callback) { + callback(fs.readFileSync(url, 'utf8')); + }; + } else if (typeof Packages !== 'undefined') { + //Why Java, why is this so awkward? + fetchText = function (url, callback) { + var encoding = "utf-8", + file = new java.io.File(url), + lineSeparator = java.lang.System.getProperty("line.separator"), + input = new java.io.BufferedReader(new java.io.InputStreamReader(new java.io.FileInputStream(file), encoding)), + stringBuffer, line, + content = ''; + try { + stringBuffer = new java.lang.StringBuffer(); + line = input.readLine(); + + // Byte Order Mark (BOM) - The Unicode Standard, version 3.0, page 324 + // http://www.unicode.org/faq/utf_bom.html + + // Note that when we use utf-8, the BOM should appear as "EF BB BF", but it doesn't due to this bug in the JDK: + // http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4508058 + if (line && line.length() && line.charAt(0) === 0xfeff) { + // Eat the BOM, since we've already found the encoding on this file, + // and we plan to concatenating this buffer with others; the BOM should + // only appear at the top of a file. + line = line.substring(1); + } + + stringBuffer.append(line); + + while ((line = input.readLine()) !== null) { + stringBuffer.append(lineSeparator); + stringBuffer.append(line); + } + //Make sure we return a JavaScript string and not a Java string. + content = String(stringBuffer.toString()); //String + } finally { + input.close(); + } + callback(content); + }; + } + + define(function () { + return { + load: function (name, parentRequire, load, config) { + var url = parentRequire.toUrl(name + '.refine'); + fetchText(url, function (text) { + text = text.replace(/refine\s*\(/g, 'define('); + + if (config.isBuild) { + buildMap[name] = text; + } + + //Add in helpful debug line + text += "\r\n//@ sourceURL=" + url; + + load.fromText(text); + + parentRequire([name], function (value) { + load(value); + }); + }); + }, + + write: function (pluginName, name, write) { + if (name in buildMap) { + var text = buildMap[name]; + write.asModule(pluginName + "!" + name, text); + } + } + }; + }); + +}()); diff --git a/htdocs/js/lib/vendor/components/requirejs/tests/plugins/fromTextNoDefine/a.refine b/htdocs/js/lib/vendor/components/requirejs/tests/plugins/fromTextNoDefine/a.refine new file mode 100644 index 000000000..d0f61f225 --- /dev/null +++ b/htdocs/js/lib/vendor/components/requirejs/tests/plugins/fromTextNoDefine/a.refine @@ -0,0 +1,6 @@ +//Note the use of window instead of var a = {}, +//since the var will be created in the scope of the eval call, +//which is not global. +window.a = { + name: 'a' +}; diff --git a/htdocs/js/lib/vendor/components/requirejs/tests/plugins/fromTextNoDefine/fromTextNoDefine-tests.js b/htdocs/js/lib/vendor/components/requirejs/tests/plugins/fromTextNoDefine/fromTextNoDefine-tests.js new file mode 100644 index 000000000..25c545da0 --- /dev/null +++ b/htdocs/js/lib/vendor/components/requirejs/tests/plugins/fromTextNoDefine/fromTextNoDefine-tests.js @@ -0,0 +1,18 @@ +require({ + baseUrl: requirejs.isBrowser ? './' : './plugins/fromText', + paths: { + 'text': '../../../../text/text' + } +}, ['refine!a'], +function () { + + doh.register( + 'pluginsFromTextNoDefine', + [ + function pluginsFromTextNoDefine(t){ + t.is('a', a.name); + } + ] + ); + doh.run(); +}); diff --git a/htdocs/js/lib/vendor/components/requirejs/tests/plugins/fromTextNoDefine/fromTextNoDefine.html b/htdocs/js/lib/vendor/components/requirejs/tests/plugins/fromTextNoDefine/fromTextNoDefine.html new file mode 100644 index 000000000..fbbf9d149 --- /dev/null +++ b/htdocs/js/lib/vendor/components/requirejs/tests/plugins/fromTextNoDefine/fromTextNoDefine.html @@ -0,0 +1,16 @@ + + + + require.js: fromText Plugin No Define Test + + + + + +

      require.js: fromText Plugin No Define Test

      +

      Tests that a plugin that transpiles to JS but does not call + define still works. More info: + 313. +

      Check console for messages

      + + diff --git a/htdocs/js/lib/vendor/components/requirejs/tests/plugins/fromTextNoDefine/refine.js b/htdocs/js/lib/vendor/components/requirejs/tests/plugins/fromTextNoDefine/refine.js new file mode 100644 index 000000000..f25578841 --- /dev/null +++ b/htdocs/js/lib/vendor/components/requirejs/tests/plugins/fromTextNoDefine/refine.js @@ -0,0 +1,130 @@ + +/*jslint strict: false, plusplus: false */ +/*global define: false, require: false, XMLHttpRequest: false, ActiveXObject: false, + window: false, Packages: false, java: false, process: false */ + +(function () { + //Load the text plugin, so that the XHR calls can be made. + var buildMap = {}, fetchText, fs, + progIds = ['Msxml2.XMLHTTP', 'Microsoft.XMLHTTP', 'Msxml2.XMLHTTP.4.0']; + + function createXhr() { + //Would love to dump the ActiveX crap in here. Need IE 6 to die first. + var xhr, i, progId; + if (typeof XMLHttpRequest !== "undefined") { + return new XMLHttpRequest(); + } else { + for (i = 0; i < 3; i++) { + progId = progIds[i]; + try { + xhr = new ActiveXObject(progId); + } catch (e) {} + + if (xhr) { + progIds = [progId]; // so faster next time + break; + } + } + } + + if (!xhr) { + throw new Error("require.getXhr(): XMLHttpRequest not available"); + } + + return xhr; + } + + if (typeof window !== "undefined" && window.navigator && window.document) { + fetchText = function (url, callback) { + var xhr = createXhr(); + xhr.open('GET', url, true); + xhr.onreadystatechange = function (evt) { + //Do not explicitly handle errors, those should be + //visible via console output in the browser. + if (xhr.readyState === 4) { + callback(xhr.responseText); + } + }; + xhr.send(null); + }; + } else if (typeof process !== "undefined" && + process.versions && + !!process.versions.node) { + //Using special require.nodeRequire, something added by r.js. + fs = require.nodeRequire('fs'); + + fetchText = function (url, callback) { + callback(fs.readFileSync(url, 'utf8')); + }; + } else if (typeof Packages !== 'undefined') { + //Why Java, why is this so awkward? + fetchText = function (url, callback) { + var encoding = "utf-8", + file = new java.io.File(url), + lineSeparator = java.lang.System.getProperty("line.separator"), + input = new java.io.BufferedReader(new java.io.InputStreamReader(new java.io.FileInputStream(file), encoding)), + stringBuffer, line, + content = ''; + try { + stringBuffer = new java.lang.StringBuffer(); + line = input.readLine(); + + // Byte Order Mark (BOM) - The Unicode Standard, version 3.0, page 324 + // http://www.unicode.org/faq/utf_bom.html + + // Note that when we use utf-8, the BOM should appear as "EF BB BF", but it doesn't due to this bug in the JDK: + // http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4508058 + if (line && line.length() && line.charAt(0) === 0xfeff) { + // Eat the BOM, since we've already found the encoding on this file, + // and we plan to concatenating this buffer with others; the BOM should + // only appear at the top of a file. + line = line.substring(1); + } + + stringBuffer.append(line); + + while ((line = input.readLine()) !== null) { + stringBuffer.append(lineSeparator); + stringBuffer.append(line); + } + //Make sure we return a JavaScript string and not a Java string. + content = String(stringBuffer.toString()); //String + } finally { + input.close(); + } + callback(content); + }; + } + + define(function () { + return { + load: function (name, parentRequire, load, config) { + var url = parentRequire.toUrl(name + '.refine'); + fetchText(url, function (text) { + text = text.replace(/refine/g, 'define'); + + if (config.isBuild) { + buildMap[name] = text; + } + + //Add in helpful debug line + text += "\r\n//@ sourceURL=" + url; + + load.fromText(name, text); + + parentRequire([name], function (value) { + load(value); + }); + }); + }, + + write: function (pluginName, name, write) { + if (name in buildMap) { + var text = buildMap[name]; + write.asModule(pluginName + "!" + name, text); + } + } + }; + }); + +}()); diff --git a/htdocs/js/lib/vendor/components/requirejs/tests/plugins/index.js b/htdocs/js/lib/vendor/components/requirejs/tests/plugins/index.js new file mode 100644 index 000000000..e5a10dead --- /dev/null +++ b/htdocs/js/lib/vendor/components/requirejs/tests/plugins/index.js @@ -0,0 +1,37 @@ +(function () { + + function parse(name) { + var parts = name.split('?'), + index = parseInt(parts[0], 10), + choices = parts[1].split(':'), + choice = choices[index]; + + return { + index: index, + choices: choices, + choice: choice + }; + } + + define({ + pluginBuilder: './indexBuilder', + normalize: function (name, normalize) { + var parsed = parse(name), + choices = parsed.choices; + + //Normalize each path choice. + for (i = 0; i < choices.length; i++) { + choices[i] = normalize(choices[i]); + } + + return parsed.index + '?' + choices.join(':'); + }, + + load: function (name, req, load, config) { + req([parse(name).choice], function (value) { + load(value); + }); + } + }); + +}()); diff --git a/htdocs/js/lib/vendor/components/requirejs/tests/plugins/indexBuilder.js b/htdocs/js/lib/vendor/components/requirejs/tests/plugins/indexBuilder.js new file mode 100644 index 000000000..dff29d482 --- /dev/null +++ b/htdocs/js/lib/vendor/components/requirejs/tests/plugins/indexBuilder.js @@ -0,0 +1,44 @@ +(function () { + + function parse(name) { + var parts = name.split('?'), + index = parseInt(parts[0], 10), + choices = parts[1].split(':'), + choice = choices[index]; + + return { + index: index, + choices: choices, + choice: choice + }; + } + + define({ + normalize: function (name, normalize) { + var parsed = parse(name), + choices = parsed.choices; + + //Normalize each path choice. + for (i = 0; i < choices.length; i++) { + choices[i] = normalize(choices[i]); + } + + return parsed.index + '?' + choices.join(':'); + }, + + load: function (name, req, load, config) { + req([parse(name).choice], function (value) { + load(value); + }); + }, + + //This is strictly not necessary (and *not* recommended), + //but just doing it as a test. + write: function (pluginName, moduleName, write) { + var parsed = parse(moduleName); + write("define('" + pluginName + "!" + moduleName + + "', ['" + parsed.choice + "'], function (value) { return value;});\n"); + } + }); + +}()); diff --git a/htdocs/js/lib/vendor/components/requirejs/tests/plugins/nameOnly-tests.js b/htdocs/js/lib/vendor/components/requirejs/tests/plugins/nameOnly-tests.js new file mode 100644 index 000000000..2f24e989c --- /dev/null +++ b/htdocs/js/lib/vendor/components/requirejs/tests/plugins/nameOnly-tests.js @@ -0,0 +1,15 @@ +require({ + baseUrl: requirejs.isBrowser ? "./" : "./plugins/" +}, ['require', 'nameOnly!'], +function (require, nameOnly) { + + doh.register( + "pluginsNameOnly", + [ + function pluginsNameOnly(t){ + t.is("nameOnly", nameOnly.name); + } + ] + ); + doh.run(); +}); diff --git a/htdocs/js/lib/vendor/components/requirejs/tests/plugins/nameOnly.html b/htdocs/js/lib/vendor/components/requirejs/tests/plugins/nameOnly.html new file mode 100644 index 000000000..87c5b240b --- /dev/null +++ b/htdocs/js/lib/vendor/components/requirejs/tests/plugins/nameOnly.html @@ -0,0 +1,13 @@ + + + + require.js: Name Only Plugin Test + + + + + +

      require.js: Name Only Plugin Test

      +

      Check console for messages

      + + diff --git a/htdocs/js/lib/vendor/components/requirejs/tests/plugins/nameOnly.js b/htdocs/js/lib/vendor/components/requirejs/tests/plugins/nameOnly.js new file mode 100644 index 000000000..6f656c442 --- /dev/null +++ b/htdocs/js/lib/vendor/components/requirejs/tests/plugins/nameOnly.js @@ -0,0 +1,8 @@ + +define({ + load: function (name, require, onLoad, config) { + onLoad({ + name: 'nameOnly' + }); + } +}); diff --git a/htdocs/js/lib/vendor/components/requirejs/tests/plugins/onerror/onerror-tests.js b/htdocs/js/lib/vendor/components/requirejs/tests/plugins/onerror/onerror-tests.js new file mode 100644 index 000000000..9248ad363 --- /dev/null +++ b/htdocs/js/lib/vendor/components/requirejs/tests/plugins/onerror/onerror-tests.js @@ -0,0 +1,30 @@ + +var master = new doh.Deferred(); + +doh.register( + "pluginsOnError", + [ + { + name: "pluginsOnError", + timeout: 5000, + runTest: function () { + return master; + } + } + ] +); +doh.run(); + +require({ + baseUrl: requirejs.isBrowser ? "./" : "./plugins/onerror", + enforceDefine: true +}, ['thrower!'], +function (thrower) { + master.callback(false); +}, +function (err) { + master.callback(true); +}); + +//Since enforceDefine is used below, define somthing here. +define({}); diff --git a/htdocs/js/lib/vendor/components/requirejs/tests/plugins/onerror/onerror.html b/htdocs/js/lib/vendor/components/requirejs/tests/plugins/onerror/onerror.html new file mode 100644 index 000000000..3b3d207e7 --- /dev/null +++ b/htdocs/js/lib/vendor/components/requirejs/tests/plugins/onerror/onerror.html @@ -0,0 +1,16 @@ + + + + require.js: Plugin onerror Test + + + + + +

      require.js: Plugin onerror Test

      + + More info. + +

      Check console for messages

      + + diff --git a/htdocs/js/lib/vendor/components/requirejs/tests/plugins/onerror/thrower.js b/htdocs/js/lib/vendor/components/requirejs/tests/plugins/onerror/thrower.js new file mode 100644 index 000000000..18823de3c --- /dev/null +++ b/htdocs/js/lib/vendor/components/requirejs/tests/plugins/onerror/thrower.js @@ -0,0 +1,6 @@ + +define({ + load: function (name, req, load, config) { + req(['fake'], load, load.error); + } +}); diff --git a/htdocs/js/lib/vendor/components/requirejs/tests/plugins/pluginLast/app.js b/htdocs/js/lib/vendor/components/requirejs/tests/plugins/pluginLast/app.js new file mode 100644 index 000000000..015f3bbe6 --- /dev/null +++ b/htdocs/js/lib/vendor/components/requirejs/tests/plugins/pluginLast/app.js @@ -0,0 +1,8 @@ +define(['specificCollection', 'bigCollection'], function (specificCollection, bigCollection) { + + return { + name: 'app', + specificCollection: specificCollection, + bigCollection: bigCollection + } +}); diff --git a/htdocs/js/lib/vendor/components/requirejs/tests/plugins/pluginLast/bigCollection.html b/htdocs/js/lib/vendor/components/requirejs/tests/plugins/pluginLast/bigCollection.html new file mode 100644 index 000000000..da24bd1b3 --- /dev/null +++ b/htdocs/js/lib/vendor/components/requirejs/tests/plugins/pluginLast/bigCollection.html @@ -0,0 +1 @@ +bigCollection \ No newline at end of file diff --git a/htdocs/js/lib/vendor/components/requirejs/tests/plugins/pluginLast/bigCollection.js b/htdocs/js/lib/vendor/components/requirejs/tests/plugins/pluginLast/bigCollection.js new file mode 100644 index 000000000..dfd9a568c --- /dev/null +++ b/htdocs/js/lib/vendor/components/requirejs/tests/plugins/pluginLast/bigCollection.js @@ -0,0 +1,7 @@ +define(['collection', 'text!bigCollection.html'], function (collection, html) { + return { + name: 'bigCollection', + html: html, + collection: collection + }; +}); \ No newline at end of file diff --git a/htdocs/js/lib/vendor/components/requirejs/tests/plugins/pluginLast/collection.js b/htdocs/js/lib/vendor/components/requirejs/tests/plugins/pluginLast/collection.js new file mode 100644 index 000000000..682e1fb8f --- /dev/null +++ b/htdocs/js/lib/vendor/components/requirejs/tests/plugins/pluginLast/collection.js @@ -0,0 +1,8 @@ +define(['collectionHelper'], function (collectionHelper) { + return { + name: 'collection', + collectionHelperName: collectionHelper.name, + componentName: collectionHelper.componentName, + componentHtml: collectionHelper.componentHtml + }; +}); diff --git a/htdocs/js/lib/vendor/components/requirejs/tests/plugins/pluginLast/collectionHelper.js b/htdocs/js/lib/vendor/components/requirejs/tests/plugins/pluginLast/collectionHelper.js new file mode 100644 index 000000000..8a37a5a4b --- /dev/null +++ b/htdocs/js/lib/vendor/components/requirejs/tests/plugins/pluginLast/collectionHelper.js @@ -0,0 +1,7 @@ +define(['component'], function (component) { + return { + name: 'collectionHelper', + componentName: component.name, + componentHtml: component.html + }; +}); diff --git a/htdocs/js/lib/vendor/components/requirejs/tests/plugins/pluginLast/common.js b/htdocs/js/lib/vendor/components/requirejs/tests/plugins/pluginLast/common.js new file mode 100644 index 000000000..67f9f126b --- /dev/null +++ b/htdocs/js/lib/vendor/components/requirejs/tests/plugins/pluginLast/common.js @@ -0,0 +1,3 @@ +define({ + name: 'common' +}); diff --git a/htdocs/js/lib/vendor/components/requirejs/tests/plugins/pluginLast/component.html b/htdocs/js/lib/vendor/components/requirejs/tests/plugins/pluginLast/component.html new file mode 100644 index 000000000..01b716fcc --- /dev/null +++ b/htdocs/js/lib/vendor/components/requirejs/tests/plugins/pluginLast/component.html @@ -0,0 +1 @@ +component \ No newline at end of file diff --git a/htdocs/js/lib/vendor/components/requirejs/tests/plugins/pluginLast/component.js b/htdocs/js/lib/vendor/components/requirejs/tests/plugins/pluginLast/component.js new file mode 100644 index 000000000..cf5b7447a --- /dev/null +++ b/htdocs/js/lib/vendor/components/requirejs/tests/plugins/pluginLast/component.js @@ -0,0 +1,7 @@ +define(['text!component.html'], function (html) { + return { + name: 'component', + html: html + }; +}); + diff --git a/htdocs/js/lib/vendor/components/requirejs/tests/plugins/pluginLast/main.js b/htdocs/js/lib/vendor/components/requirejs/tests/plugins/pluginLast/main.js new file mode 100644 index 000000000..61eb440e1 --- /dev/null +++ b/htdocs/js/lib/vendor/components/requirejs/tests/plugins/pluginLast/main.js @@ -0,0 +1,39 @@ +requirejs.config({ + paths: { + text: '../../circular/complexPlugin/slowText' + } +}); + +//First make sure the plugin is loaded, so that there is nothing waiting for +//normalization. + +require(['text'], function (text) { + + function trim(text) { + return text.replace(/^\s+/, '').replace(/\s+$/, ''); + } + + require(['app'], function (app) { + + doh.register( + "pluginsLast", + [ + function pluginsLast(t){ + t.is("app", app.name); + t.is("specificCollection", app.specificCollection.name); + t.is("specificCollection", app.specificCollection.html); + t.is("bigCollection", app.bigCollection.name); + t.is("bigCollection", app.bigCollection.html); + + t.is("collection", app.bigCollection.collection.name); + t.is("collectionHelper", app.bigCollection.collection.collectionHelperName); + t.is("component", app.bigCollection.collection.componentName); + t.is("component", app.bigCollection.collection.componentHtml); + } + ] + ); + doh.run(); + + }); + +}); diff --git a/htdocs/js/lib/vendor/components/requirejs/tests/plugins/pluginLast/pluginLast.html b/htdocs/js/lib/vendor/components/requirejs/tests/plugins/pluginLast/pluginLast.html new file mode 100644 index 000000000..794cc039d --- /dev/null +++ b/htdocs/js/lib/vendor/components/requirejs/tests/plugins/pluginLast/pluginLast.html @@ -0,0 +1,16 @@ + + + + require.js: Plugin Last Test + + + + + +

      require.js: Plugin Last Test

      +

      Test more complex plugin example where cycle breaking is being invoked + when it should not. More info: + 306.

      +

      Check console for messages

      + + diff --git a/htdocs/js/lib/vendor/components/requirejs/tests/plugins/pluginLast/specificCollection.html b/htdocs/js/lib/vendor/components/requirejs/tests/plugins/pluginLast/specificCollection.html new file mode 100644 index 000000000..8de79a252 --- /dev/null +++ b/htdocs/js/lib/vendor/components/requirejs/tests/plugins/pluginLast/specificCollection.html @@ -0,0 +1 @@ +specificCollection \ No newline at end of file diff --git a/htdocs/js/lib/vendor/components/requirejs/tests/plugins/pluginLast/specificCollection.js b/htdocs/js/lib/vendor/components/requirejs/tests/plugins/pluginLast/specificCollection.js new file mode 100644 index 000000000..95964b1a9 --- /dev/null +++ b/htdocs/js/lib/vendor/components/requirejs/tests/plugins/pluginLast/specificCollection.js @@ -0,0 +1,7 @@ +define(['collection', 'text!specificCollection.html'], function (collection, html) { + return { + name: 'specificCollection', + html: html, + collection: collection + }; +}); \ No newline at end of file diff --git a/htdocs/js/lib/vendor/components/requirejs/tests/plugins/pluginMap/dynamic/application.js b/htdocs/js/lib/vendor/components/requirejs/tests/plugins/pluginMap/dynamic/application.js new file mode 100644 index 000000000..fbf666590 --- /dev/null +++ b/htdocs/js/lib/vendor/components/requirejs/tests/plugins/pluginMap/dynamic/application.js @@ -0,0 +1,6 @@ +define('application', ['person'], function(person) { + return { + name: 'application', + person: person + }; +}); diff --git a/htdocs/js/lib/vendor/components/requirejs/tests/plugins/pluginMap/dynamic/employee.js b/htdocs/js/lib/vendor/components/requirejs/tests/plugins/pluginMap/dynamic/employee.js new file mode 100644 index 000000000..45ff70aff --- /dev/null +++ b/htdocs/js/lib/vendor/components/requirejs/tests/plugins/pluginMap/dynamic/employee.js @@ -0,0 +1,5 @@ +define('employee', ['plugin!person'], function(person) { + return { + name: 'employed ' + person.name + }; +}); diff --git a/htdocs/js/lib/vendor/components/requirejs/tests/plugins/pluginMap/dynamic/main.js b/htdocs/js/lib/vendor/components/requirejs/tests/plugins/pluginMap/dynamic/main.js new file mode 100644 index 000000000..87d459964 --- /dev/null +++ b/htdocs/js/lib/vendor/components/requirejs/tests/plugins/pluginMap/dynamic/main.js @@ -0,0 +1,23 @@ +require({ + map: { + '*': { + 'person': 'employee' + }, + 'employee': { + 'person': 'person' + } + } +}, ['application'], function (application) { + + doh.register( + 'pluginMapDynamic', + [ + function pluginMapDynamic(t){ + t.is('application', application.name); + t.is('employed person', application.person.name); + } + ] + ); + doh.run(); + +}); diff --git a/htdocs/js/lib/vendor/components/requirejs/tests/plugins/pluginMap/dynamic/person.js b/htdocs/js/lib/vendor/components/requirejs/tests/plugins/pluginMap/dynamic/person.js new file mode 100644 index 000000000..0820d528e --- /dev/null +++ b/htdocs/js/lib/vendor/components/requirejs/tests/plugins/pluginMap/dynamic/person.js @@ -0,0 +1,3 @@ +define('person', [], { + name: 'person' +}); diff --git a/htdocs/js/lib/vendor/components/requirejs/tests/plugins/pluginMap/dynamic/plugin.js b/htdocs/js/lib/vendor/components/requirejs/tests/plugins/pluginMap/dynamic/plugin.js new file mode 100644 index 000000000..60ec02c02 --- /dev/null +++ b/htdocs/js/lib/vendor/components/requirejs/tests/plugins/pluginMap/dynamic/plugin.js @@ -0,0 +1,7 @@ +define('plugin', [], { + load: function (name, req, load, config) { + req([name], function (value) { + load(value); + }); + } +}); diff --git a/htdocs/js/lib/vendor/components/requirejs/tests/plugins/pluginMap/dynamic/pluginMapDynamic.html b/htdocs/js/lib/vendor/components/requirejs/tests/plugins/pluginMap/dynamic/pluginMapDynamic.html new file mode 100644 index 000000000..1e55c1632 --- /dev/null +++ b/htdocs/js/lib/vendor/components/requirejs/tests/plugins/pluginMap/dynamic/pluginMapDynamic.html @@ -0,0 +1,15 @@ + + + + require.js: Plugin Map DynamicTest + + + + + +

      require.js: Plugin Map Test

      +

      Test using the map config with plugins and dynamically loaded modules. More info: + 326

      +

      Check console for messages

      + + diff --git a/htdocs/js/lib/vendor/components/requirejs/tests/plugins/pluginMap/pluginMap-tests.js b/htdocs/js/lib/vendor/components/requirejs/tests/plugins/pluginMap/pluginMap-tests.js new file mode 100644 index 000000000..a7be0e552 --- /dev/null +++ b/htdocs/js/lib/vendor/components/requirejs/tests/plugins/pluginMap/pluginMap-tests.js @@ -0,0 +1,48 @@ +define('plugin', [], { + load: function (name, req, load, config) { + req([name], function (value) { + load(value); + }); + } +}); + +define('person', [], { + name: 'person' +}); + +define('employee', ['plugin!person'], function(person) { + return { + name: 'employed ' + person.name + }; +}); + +define('application', ['person'], function(person) { + return { + name: 'application', + person: person + }; +}); + +require({ + map: { + '*': { + 'person': 'employee' + }, + 'employee': { + 'person': 'person' + } + } +}, ['application'], function (application) { + + doh.register( + 'pluginMap', + [ + function pluginMap(t){ + t.is('application', application.name); + t.is('employed person', application.person.name); + } + ] + ); + doh.run(); + +}); diff --git a/htdocs/js/lib/vendor/components/requirejs/tests/plugins/pluginMap/pluginMap.html b/htdocs/js/lib/vendor/components/requirejs/tests/plugins/pluginMap/pluginMap.html new file mode 100644 index 000000000..322896ff0 --- /dev/null +++ b/htdocs/js/lib/vendor/components/requirejs/tests/plugins/pluginMap/pluginMap.html @@ -0,0 +1,16 @@ + + + + require.js: Plugin Map Test + + + + + + +

      require.js: Plugin Map Test

      +

      Test using the map config with plugins. More info: + 320

      +

      Check console for messages

      + + diff --git a/htdocs/js/lib/vendor/components/requirejs/tests/plugins/pluginMapSameName/plugin/plugin.js b/htdocs/js/lib/vendor/components/requirejs/tests/plugins/pluginMapSameName/plugin/plugin.js new file mode 100644 index 000000000..9a5b3590d --- /dev/null +++ b/htdocs/js/lib/vendor/components/requirejs/tests/plugins/pluginMapSameName/plugin/plugin.js @@ -0,0 +1,6 @@ +define({ + load: function (id, require, load, config) { + load(id); + } +}); + diff --git a/htdocs/js/lib/vendor/components/requirejs/tests/plugins/pluginMapSameName/pluginMapSameName-tests.js b/htdocs/js/lib/vendor/components/requirejs/tests/plugins/pluginMapSameName/pluginMapSameName-tests.js new file mode 100644 index 000000000..a03b703f0 --- /dev/null +++ b/htdocs/js/lib/vendor/components/requirejs/tests/plugins/pluginMapSameName/pluginMapSameName-tests.js @@ -0,0 +1,19 @@ +require({ + map: { + '*': { + 'plugin': 'plugin/plugin' + } + } +}, ['plugin!foo'], function (value) { + + doh.register( + 'pluginMapSameName', + [ + function pluginMapSameName(t){ + t.is('foo', value); + } + ] + ); + doh.run(); + +}); diff --git a/htdocs/js/lib/vendor/components/requirejs/tests/plugins/pluginMapSameName/pluginMapSameName.html b/htdocs/js/lib/vendor/components/requirejs/tests/plugins/pluginMapSameName/pluginMapSameName.html new file mode 100644 index 000000000..ab63d3be4 --- /dev/null +++ b/htdocs/js/lib/vendor/components/requirejs/tests/plugins/pluginMapSameName/pluginMapSameName.html @@ -0,0 +1,18 @@ + + + + require.js: Plugin Map Same Name Test + + + + + + +

      require.js: Plugin Map Same Name Test

      +

      Test using the map config with plugins. but include a map value that + contains the original name of the plugin, to confirm the map translation + is only done once: + 484

      +

      Check console for messages

      + + diff --git a/htdocs/js/lib/vendor/components/requirejs/tests/plugins/pluginShim/a.refine b/htdocs/js/lib/vendor/components/requirejs/tests/plugins/pluginShim/a.refine new file mode 100644 index 000000000..dde07ed3d --- /dev/null +++ b/htdocs/js/lib/vendor/components/requirejs/tests/plugins/pluginShim/a.refine @@ -0,0 +1,4 @@ +//The refine plugin changes the word refine into define. +refine({ + name: 'a' + window.legacy.name +}); diff --git a/htdocs/js/lib/vendor/components/requirejs/tests/plugins/pluginShim/legacy.js b/htdocs/js/lib/vendor/components/requirejs/tests/plugins/pluginShim/legacy.js new file mode 100644 index 000000000..626655e90 --- /dev/null +++ b/htdocs/js/lib/vendor/components/requirejs/tests/plugins/pluginShim/legacy.js @@ -0,0 +1,4 @@ +window.legacy = { + name: 'legacy' +}; + diff --git a/htdocs/js/lib/vendor/components/requirejs/tests/plugins/pluginShim/pluginShim-tests.js b/htdocs/js/lib/vendor/components/requirejs/tests/plugins/pluginShim/pluginShim-tests.js new file mode 100644 index 000000000..46eb2700d --- /dev/null +++ b/htdocs/js/lib/vendor/components/requirejs/tests/plugins/pluginShim/pluginShim-tests.js @@ -0,0 +1,22 @@ +require({ + baseUrl: requirejs.isBrowser ? './' : './plugins/pluginShim', + paths: { + 'text': '../../../../text/text', + 'refine': '../fromText/refine' + }, + shim: { + 'refine!a': ['!legacy'] + } +}, ['refine!a'], +function (a) { + + doh.register( + 'pluginShim', + [ + function pluginShim(t){ + t.is('alegacy', a.name); + } + ] + ); + doh.run(); +}); diff --git a/htdocs/js/lib/vendor/components/requirejs/tests/plugins/pluginShim/pluginShim.html b/htdocs/js/lib/vendor/components/requirejs/tests/plugins/pluginShim/pluginShim.html new file mode 100644 index 000000000..3f7aff1e4 --- /dev/null +++ b/htdocs/js/lib/vendor/components/requirejs/tests/plugins/pluginShim/pluginShim.html @@ -0,0 +1,15 @@ + + + + require.js: pluginShim Plugin Test + + + + + +

      require.js: pluginShim Plugin Test

      +

      Confirms that shim config works with plugin resources. More info: + 324. +

      Check console for messages

      + + diff --git a/htdocs/js/lib/vendor/components/requirejs/tests/plugins/prime/a.js b/htdocs/js/lib/vendor/components/requirejs/tests/plugins/prime/a.js new file mode 100644 index 000000000..08a327bbc --- /dev/null +++ b/htdocs/js/lib/vendor/components/requirejs/tests/plugins/prime/a.js @@ -0,0 +1,3 @@ +define({ + name: 'aPrime' +}); diff --git a/htdocs/js/lib/vendor/components/requirejs/tests/plugins/prime/b.js b/htdocs/js/lib/vendor/components/requirejs/tests/plugins/prime/b.js new file mode 100644 index 000000000..3601a996d --- /dev/null +++ b/htdocs/js/lib/vendor/components/requirejs/tests/plugins/prime/b.js @@ -0,0 +1,5 @@ +define(function () { + return { + name: "bPrime" + }; +}); diff --git a/htdocs/js/lib/vendor/components/requirejs/tests/plugins/prime/c.js b/htdocs/js/lib/vendor/components/requirejs/tests/plugins/prime/c.js new file mode 100644 index 000000000..68956fd3e --- /dev/null +++ b/htdocs/js/lib/vendor/components/requirejs/tests/plugins/prime/c.js @@ -0,0 +1,3 @@ +define({ + name: "cPrime" +}); diff --git a/htdocs/js/lib/vendor/components/requirejs/tests/plugins/prime/earth.js b/htdocs/js/lib/vendor/components/requirejs/tests/plugins/prime/earth.js new file mode 100644 index 000000000..497df68cb --- /dev/null +++ b/htdocs/js/lib/vendor/components/requirejs/tests/plugins/prime/earth.js @@ -0,0 +1,13 @@ +define(function (require) { + return { + getA: function () { + return require("../index!0?./a:./b:./c"); + }, + getC: function () { + return require("../index!2?./a:./b:./c"); + }, + getB: function () { + return require("../index!1?./a:./b:./c"); + } + }; +}); diff --git a/htdocs/js/lib/vendor/components/requirejs/tests/plugins/sync-tests.js b/htdocs/js/lib/vendor/components/requirejs/tests/plugins/sync-tests.js new file mode 100644 index 000000000..5b78cd8f0 --- /dev/null +++ b/htdocs/js/lib/vendor/components/requirejs/tests/plugins/sync-tests.js @@ -0,0 +1,20 @@ +require({ + baseUrl: requirejs.isBrowser ? "./" : "./plugins/" +}, ['require', 'earth', 'prime/earth'], +function (require, earth, primeEarth) { + + doh.register( + "pluginsSync", + [ + function pluginsSync(t){ + t.is("a", earth.getA().name); + t.is("c", earth.getC().name); + t.is("b", earth.getB().name); + t.is("aPrime", primeEarth.getA().name); + t.is("cPrime", primeEarth.getC().name); + t.is("bPrime", primeEarth.getB().name); + } + ] + ); + doh.run(); +}); diff --git a/htdocs/js/lib/vendor/components/requirejs/tests/plugins/sync.html b/htdocs/js/lib/vendor/components/requirejs/tests/plugins/sync.html new file mode 100644 index 000000000..a2e06b183 --- /dev/null +++ b/htdocs/js/lib/vendor/components/requirejs/tests/plugins/sync.html @@ -0,0 +1,13 @@ + + + + require.js: Sync Plugin Test + + + + + +

      require.js: Sync Plugin Test

      +

      Check console for messages

      + + diff --git a/htdocs/js/lib/vendor/components/requirejs/tests/plugins/textDepend/test.txt b/htdocs/js/lib/vendor/components/requirejs/tests/plugins/textDepend/test.txt new file mode 100644 index 000000000..95d09f2b1 --- /dev/null +++ b/htdocs/js/lib/vendor/components/requirejs/tests/plugins/textDepend/test.txt @@ -0,0 +1 @@ +hello world \ No newline at end of file diff --git a/htdocs/js/lib/vendor/components/requirejs/tests/plugins/textDepend/textDepend-tests.js b/htdocs/js/lib/vendor/components/requirejs/tests/plugins/textDepend/textDepend-tests.js new file mode 100644 index 000000000..dd8840187 --- /dev/null +++ b/htdocs/js/lib/vendor/components/requirejs/tests/plugins/textDepend/textDepend-tests.js @@ -0,0 +1,18 @@ +require({ + baseUrl: requirejs.isBrowser ? './' : './plugins/textDepend', + paths: { + 'text': '../../../../text/text' + } +}, ['textDepend!a'], +function (textValue) { + + doh.register( + 'textDepend', + [ + function textDepend(t){ + t.is('hello world', textValue); + } + ] + ); + doh.run(); +}); diff --git a/htdocs/js/lib/vendor/components/requirejs/tests/plugins/textDepend/textDepend.html b/htdocs/js/lib/vendor/components/requirejs/tests/plugins/textDepend/textDepend.html new file mode 100644 index 000000000..9777694ff --- /dev/null +++ b/htdocs/js/lib/vendor/components/requirejs/tests/plugins/textDepend/textDepend.html @@ -0,0 +1,13 @@ + + + + require.js: Plugin that has text! Dependency Test + + + + + +

      require.js: Plugin that has text! Dependency Test

      +

      Check console for messages

      + + diff --git a/htdocs/js/lib/vendor/components/requirejs/tests/plugins/textDepend/textDepend.js b/htdocs/js/lib/vendor/components/requirejs/tests/plugins/textDepend/textDepend.js new file mode 100644 index 000000000..87820af08 --- /dev/null +++ b/htdocs/js/lib/vendor/components/requirejs/tests/plugins/textDepend/textDepend.js @@ -0,0 +1,7 @@ +define(['text!test.txt'], function (text) { + return { + load: function (name, req, load, config) { + load(text); + } + }; +}); diff --git a/htdocs/js/lib/vendor/components/requirejs/tests/queryPath.html b/htdocs/js/lib/vendor/components/requirejs/tests/queryPath.html new file mode 100644 index 000000000..93d8e8603 --- /dev/null +++ b/htdocs/js/lib/vendor/components/requirejs/tests/queryPath.html @@ -0,0 +1,56 @@ + + + + require.js: Querystring Path Test + + + + + + +

      require.js: Querystring Path Test

      +

      Check console for messages

      + + diff --git a/htdocs/js/lib/vendor/components/requirejs/tests/relative/foo/bar.js b/htdocs/js/lib/vendor/components/requirejs/tests/relative/foo/bar.js new file mode 100644 index 000000000..ab76348f1 --- /dev/null +++ b/htdocs/js/lib/vendor/components/requirejs/tests/relative/foo/bar.js @@ -0,0 +1,3 @@ +define({ + name: 'bar' +}); diff --git a/htdocs/js/lib/vendor/components/requirejs/tests/relative/foo/bar/message.txt b/htdocs/js/lib/vendor/components/requirejs/tests/relative/foo/bar/message.txt new file mode 100644 index 000000000..95d09f2b1 --- /dev/null +++ b/htdocs/js/lib/vendor/components/requirejs/tests/relative/foo/bar/message.txt @@ -0,0 +1 @@ +hello world \ No newline at end of file diff --git a/htdocs/js/lib/vendor/components/requirejs/tests/relative/foo/bar/one.js b/htdocs/js/lib/vendor/components/requirejs/tests/relative/foo/bar/one.js new file mode 100644 index 000000000..f44c9a26e --- /dev/null +++ b/htdocs/js/lib/vendor/components/requirejs/tests/relative/foo/bar/one.js @@ -0,0 +1,11 @@ +define("foo/bar/one", + ["require", ".", "./two", "../three", "text!./message.txt"], + function (require, bar, two, three, message) { + return { + name: "one", + barName: bar.name, + twoName: two.name, + threeName: three.name, + message: message + }; +}); diff --git a/htdocs/js/lib/vendor/components/requirejs/tests/relative/foo/bar/two.js b/htdocs/js/lib/vendor/components/requirejs/tests/relative/foo/bar/two.js new file mode 100644 index 000000000..521822a16 --- /dev/null +++ b/htdocs/js/lib/vendor/components/requirejs/tests/relative/foo/bar/two.js @@ -0,0 +1,3 @@ +define("foo/bar/two", { + name: "two" +}); diff --git a/htdocs/js/lib/vendor/components/requirejs/tests/relative/foo/three.js b/htdocs/js/lib/vendor/components/requirejs/tests/relative/foo/three.js new file mode 100644 index 000000000..36aa2fcb2 --- /dev/null +++ b/htdocs/js/lib/vendor/components/requirejs/tests/relative/foo/three.js @@ -0,0 +1,3 @@ +define("foo/three", { + name: "three" +}); diff --git a/htdocs/js/lib/vendor/components/requirejs/tests/relative/greek/alpha.js b/htdocs/js/lib/vendor/components/requirejs/tests/relative/greek/alpha.js new file mode 100644 index 000000000..38a4bc8d6 --- /dev/null +++ b/htdocs/js/lib/vendor/components/requirejs/tests/relative/greek/alpha.js @@ -0,0 +1,7 @@ +define(function (require, exports) { + + exports.name = 'alpha'; + exports.getGreekName = function () { + return require('.').name; + }; +}); diff --git a/htdocs/js/lib/vendor/components/requirejs/tests/relative/greek/main.js b/htdocs/js/lib/vendor/components/requirejs/tests/relative/greek/main.js new file mode 100644 index 000000000..6b9f47ec4 --- /dev/null +++ b/htdocs/js/lib/vendor/components/requirejs/tests/relative/greek/main.js @@ -0,0 +1,3 @@ +define(function (require, exports) { + exports.name = 'greek'; +}); \ No newline at end of file diff --git a/htdocs/js/lib/vendor/components/requirejs/tests/relative/outsideBaseUrl/2.js b/htdocs/js/lib/vendor/components/requirejs/tests/relative/outsideBaseUrl/2.js new file mode 100644 index 000000000..88c89d47d --- /dev/null +++ b/htdocs/js/lib/vendor/components/requirejs/tests/relative/outsideBaseUrl/2.js @@ -0,0 +1,6 @@ +define(["require","exports","module","./b/3"], function (r, e, m, b3) { + return { + name: 'two', + b3: b3 + }; +}) diff --git a/htdocs/js/lib/vendor/components/requirejs/tests/relative/outsideBaseUrl/a/outsideBaseUrl.html b/htdocs/js/lib/vendor/components/requirejs/tests/relative/outsideBaseUrl/a/outsideBaseUrl.html new file mode 100644 index 000000000..121256b1f --- /dev/null +++ b/htdocs/js/lib/vendor/components/requirejs/tests/relative/outsideBaseUrl/a/outsideBaseUrl.html @@ -0,0 +1,33 @@ + + + + require.js: Relative Module Name Outside baseUrl Test + + + + + + +

      require.js: Relative Module Name Outside baseUrl Test

      +

      From Issue #158

      +

      Check console for messages

      + + diff --git a/htdocs/js/lib/vendor/components/requirejs/tests/relative/outsideBaseUrl/b/1.js b/htdocs/js/lib/vendor/components/requirejs/tests/relative/outsideBaseUrl/b/1.js new file mode 100644 index 000000000..9cc742fdb --- /dev/null +++ b/htdocs/js/lib/vendor/components/requirejs/tests/relative/outsideBaseUrl/b/1.js @@ -0,0 +1,6 @@ +define(["require","exports","module","../2"], function (r, e, m, two) { + return { + name: 'b1', + two: two + }; +}) \ No newline at end of file diff --git a/htdocs/js/lib/vendor/components/requirejs/tests/relative/outsideBaseUrl/b/3.js b/htdocs/js/lib/vendor/components/requirejs/tests/relative/outsideBaseUrl/b/3.js new file mode 100644 index 000000000..8c03cad6b --- /dev/null +++ b/htdocs/js/lib/vendor/components/requirejs/tests/relative/outsideBaseUrl/b/3.js @@ -0,0 +1,5 @@ +define(["require","exports","module"], function () { + return { + name: 'b3' + }; +}); diff --git a/htdocs/js/lib/vendor/components/requirejs/tests/relative/relative-tests.js b/htdocs/js/lib/vendor/components/requirejs/tests/relative/relative-tests.js new file mode 100644 index 000000000..61bf3b83b --- /dev/null +++ b/htdocs/js/lib/vendor/components/requirejs/tests/relative/relative-tests.js @@ -0,0 +1,34 @@ +require({ + baseUrl: requirejs.isBrowser ? "./" : "./relative/", + paths: { + text: "../../../text/text" + }, + packages: [ + { + name: 'greek', + main: 'main', + lib: '.' + } + ] + }, + ["require", "foo/bar/one", "greek/alpha"], + function(require, one, alpha) { + doh.register( + "relative", + [ + function relative(t){ + t.is("one", one.name); + t.is("bar", one.barName); + t.is("two", one.twoName); + t.is("three", one.threeName); + t.is("hello world", one.message); + + t.is('alpha', alpha.name); + t.is('greek', alpha.getGreekName()); + } + ] + ); + + doh.run(); + } +); diff --git a/htdocs/js/lib/vendor/components/requirejs/tests/relative/relative.html b/htdocs/js/lib/vendor/components/requirejs/tests/relative/relative.html new file mode 100644 index 000000000..a792adaba --- /dev/null +++ b/htdocs/js/lib/vendor/components/requirejs/tests/relative/relative.html @@ -0,0 +1,14 @@ + + + + require.js: Relative Module Names Test + + + + + + +

      require.js: Relative Module Names Test

      +

      Check console for messages

      + + diff --git a/htdocs/js/lib/vendor/components/requirejs/tests/relative/relativeBaseUrl-tests.js b/htdocs/js/lib/vendor/components/requirejs/tests/relative/relativeBaseUrl-tests.js new file mode 100644 index 000000000..978e65867 --- /dev/null +++ b/htdocs/js/lib/vendor/components/requirejs/tests/relative/relativeBaseUrl-tests.js @@ -0,0 +1,24 @@ +//Use a property on require so if the test runs in node, it is visible. +//Remove it when done with the test. +require.relativeBaseUrlCounter = 0; + +require({ + baseUrl: requirejs.isBrowser ? "./" : "./relative/" + }, + ["./top", "top"], + function(top1, top2) { + doh.register( + "relativeBaseUrl", + [ + function relativeBaseUrl(t){ + t.is(top1.id, top2.id); + t.is(1, require.relativeBaseUrlCounter); + + delete require.relativeBaseUrlCounter; + } + ] + ); + + doh.run(); + } +); diff --git a/htdocs/js/lib/vendor/components/requirejs/tests/relative/relativeBaseUrl.html b/htdocs/js/lib/vendor/components/requirejs/tests/relative/relativeBaseUrl.html new file mode 100644 index 000000000..6c28c9155 --- /dev/null +++ b/htdocs/js/lib/vendor/components/requirejs/tests/relative/relativeBaseUrl.html @@ -0,0 +1,14 @@ + + + + require.js: Relative Module Names at baseUrl Test + + + + + + +

      require.js: Relative Module Names at baseUrl Test

      +

      Check console for messages

      + + diff --git a/htdocs/js/lib/vendor/components/requirejs/tests/relative/top.js b/htdocs/js/lib/vendor/components/requirejs/tests/relative/top.js new file mode 100644 index 000000000..3e79d555e --- /dev/null +++ b/htdocs/js/lib/vendor/components/requirejs/tests/relative/top.js @@ -0,0 +1,7 @@ + +define(function () { + require.relativeBaseUrlCounter += 1; + return { + id: require.relativeBaseUrlCounter + }; +}); diff --git a/htdocs/js/lib/vendor/components/requirejs/tests/remoteUrls/jqwrap.js b/htdocs/js/lib/vendor/components/requirejs/tests/remoteUrls/jqwrap.js new file mode 100644 index 000000000..46928c2a0 --- /dev/null +++ b/htdocs/js/lib/vendor/components/requirejs/tests/remoteUrls/jqwrap.js @@ -0,0 +1,10 @@ +define(function (require) { + //Tests detecting a full URL dependency inside simplified wrapper. + require('https://ajax.googleapis.com/ajax/libs/jquery/1.6.4/jquery.min.js'); + + function noop() {}; + + return { + isFunction: jQuery.isFunction(noop) + }; +}); diff --git a/htdocs/js/lib/vendor/components/requirejs/tests/remoteUrls/remoteUrls-tests.js b/htdocs/js/lib/vendor/components/requirejs/tests/remoteUrls/remoteUrls-tests.js new file mode 100644 index 000000000..376928a81 --- /dev/null +++ b/htdocs/js/lib/vendor/components/requirejs/tests/remoteUrls/remoteUrls-tests.js @@ -0,0 +1,17 @@ +require({ + baseUrl: requirejs.isBrowser ? "./" : "./remoteUrls/" + }, + ["require", "jqwrap"], + function(require, jqwrap) { + doh.register( + "remoteUrls", + [ + function remoteUrls(t){ + t.is(true, jqwrap.isFunction); + } + ] + ); + + doh.run(); + } +); diff --git a/htdocs/js/lib/vendor/components/requirejs/tests/remoteUrls/remoteUrls.html b/htdocs/js/lib/vendor/components/requirejs/tests/remoteUrls/remoteUrls.html new file mode 100644 index 000000000..d3afe6709 --- /dev/null +++ b/htdocs/js/lib/vendor/components/requirejs/tests/remoteUrls/remoteUrls.html @@ -0,0 +1,14 @@ + + + + require.js: Remote URL Test + + + + + + +

      require.js: Remote URL Test

      +

      Check console for messages

      + + diff --git a/htdocs/js/lib/vendor/components/requirejs/tests/requirePluginLoad/requirePluginLoad-tests.js b/htdocs/js/lib/vendor/components/requirejs/tests/requirePluginLoad/requirePluginLoad-tests.js new file mode 100644 index 000000000..32a06d386 --- /dev/null +++ b/htdocs/js/lib/vendor/components/requirejs/tests/requirePluginLoad/requirePluginLoad-tests.js @@ -0,0 +1,54 @@ + +var globals = {}; + +define('plug',{ + load: function () { + throw new Error('Cannot dynamically load'); + } +}); + +define('app/test',[], function() { + return { name: 'test' }; +}); + +define('app/test2',[], function() { + return { name: 'test2' }; +}); + +define('plug!app/main',["!app/test", "!app/test2"], function(test, test2) { + return { + name: 'main', + test: test, + test2: test2 + }; +}); + +require(["plug!app/main"], + function(main) { + globals.main = main; + } +); +define("app/run", function(){}); + + +require({ + baseUrl: "./" + }, + ["app/run"], + function() { + doh.register( + "requirePluginLoad", + [ + function requirePluginLoad(t){ + var main = globals.main; + + t.is("main", main.name); + t.is("test", main.test.name); + t.is("test2", main.test2.name); + } + ] + ); + + doh.run(); + } +); diff --git a/htdocs/js/lib/vendor/components/requirejs/tests/requirePluginLoad/requirePluginLoad.html b/htdocs/js/lib/vendor/components/requirejs/tests/requirePluginLoad/requirePluginLoad.html new file mode 100644 index 000000000..7a41d376f --- /dev/null +++ b/htdocs/js/lib/vendor/components/requirejs/tests/requirePluginLoad/requirePluginLoad.html @@ -0,0 +1,18 @@ + + + + require.js: Require Plugin Load Test + + + + + + +

      require.js: Require Plugin Load Test

      +

      Make sure two requires in a built file that has inlined plugin + resources do not call the plugin's load method. See + ticket 256 + for more information.

      +

      Check console for messages

      + + diff --git a/htdocs/js/lib/vendor/components/requirejs/tests/shim/a.js b/htdocs/js/lib/vendor/components/requirejs/tests/shim/a.js new file mode 100644 index 000000000..2e0367e98 --- /dev/null +++ b/htdocs/js/lib/vendor/components/requirejs/tests/shim/a.js @@ -0,0 +1,5 @@ +(function (root) { + root.A = { + name: 'a' + }; +}(this)); diff --git a/htdocs/js/lib/vendor/components/requirejs/tests/shim/b.js b/htdocs/js/lib/vendor/components/requirejs/tests/shim/b.js new file mode 100644 index 000000000..dd68c23aa --- /dev/null +++ b/htdocs/js/lib/vendor/components/requirejs/tests/shim/b.js @@ -0,0 +1,5 @@ +var B = { + name: 'b', + aValue: A.name, + dValue: new D() +}; diff --git a/htdocs/js/lib/vendor/components/requirejs/tests/shim/basic-tests.js b/htdocs/js/lib/vendor/components/requirejs/tests/shim/basic-tests.js new file mode 100644 index 000000000..ab8bcdd89 --- /dev/null +++ b/htdocs/js/lib/vendor/components/requirejs/tests/shim/basic-tests.js @@ -0,0 +1,43 @@ +require({ + baseUrl: './', + shim: { + a: { + exports: 'A.name', + init: function () { + window.globalA = this.A.name; + } + }, + 'b': ['a', 'd'], + 'c': { + deps: ['a', 'b'], + exports: 'C' + }, + 'e': { + exports: 'e.nested.e', + init: function () { + return { + name: e.nested.e.name + 'Modified' + }; + } + } + } + }, + ['a', 'c', 'e'], + function(a, c, e) { + doh.register( + 'shimBasic', + [ + function shimBasic(t){ + t.is('a', a); + t.is('a', window.globalA); + t.is('a', c.b.aValue); + t.is('b', c.b.name); + t.is('c', c.name); + t.is('d', c.b.dValue.name); + t.is('eModified', e.name); + } + ] + ); + doh.run(); + } +); diff --git a/htdocs/js/lib/vendor/components/requirejs/tests/shim/basic.html b/htdocs/js/lib/vendor/components/requirejs/tests/shim/basic.html new file mode 100644 index 000000000..81830f19d --- /dev/null +++ b/htdocs/js/lib/vendor/components/requirejs/tests/shim/basic.html @@ -0,0 +1,15 @@ + + + + require.js: Basic Shim Test + + + + + + +

      require.js: Basic Shim Test

      +

      Basic test of the shim config support.

      +

      Check console for messages

      + + diff --git a/htdocs/js/lib/vendor/components/requirejs/tests/shim/built/basic-built.html b/htdocs/js/lib/vendor/components/requirejs/tests/shim/built/basic-built.html new file mode 100644 index 000000000..93d0b6bfe --- /dev/null +++ b/htdocs/js/lib/vendor/components/requirejs/tests/shim/built/basic-built.html @@ -0,0 +1,16 @@ + + + + require.js: Basic Built Shim Test + + + + + + +

      require.js: Basic Built Shim Test

      +

      Basic test of the shim config support in built form.

      +

      Be sure to run the build via r.js to get the latest code in the test.

      +

      Check console for messages

      + + diff --git a/htdocs/js/lib/vendor/components/requirejs/tests/shim/built/basic-tests.js b/htdocs/js/lib/vendor/components/requirejs/tests/shim/built/basic-tests.js new file mode 100644 index 000000000..c47f088e7 --- /dev/null +++ b/htdocs/js/lib/vendor/components/requirejs/tests/shim/built/basic-tests.js @@ -0,0 +1,111 @@ + +(function (root) { + root.A = { + name: 'a' + }; +}(this)); + +define("a", (function (global) { + return function () { + var ret, fn; + fn = function () { + window.globalA = this.A.name; + }; + ret = fn.apply(global, arguments); + return ret || global.A.name; + }; +}(this))); + +function D() { + this.name = 'd'; +}; + +define("d", function(){}); + +var B = { + name: 'b', + aValue: A.name, + dValue: new D() +}; + +define("b", function(){}); + +var C = { + name: 'c', + a: A, + b: B +}; + +define("c", ["a","b"], (function (global) { + return function () { + var ret, fn; + return ret || global.C; + }; +}(this))); + +var e = { + nested: { + e: { + name: 'e' + } + } +}; + +define("e", (function (global) { + return function () { + var ret, fn; + fn = function () { + return { + name: e.nested.e.name + 'Modified' + }; + }; + ret = fn.apply(global, arguments); + return ret || global.e.nested.e; + }; +}(this))); + +require({ + baseUrl: './', + shim: { + a: { + exports: 'A.name', + init: function () { + window.globalA = this.A.name; + } + }, + 'b': ['a', 'd'], + 'c': { + deps: ['a', 'b'], + exports: 'C' + }, + 'e': { + exports: 'e.nested.e', + init: function () { + return { + name: e.nested.e.name + 'Modified' + }; + } + } + } + }, + ['a', 'c', 'e'], + function(a, c, e) { + doh.register( + 'shimBasic', + [ + function shimBasic(t){ + t.is('a', a); + t.is('a', window.globalA); + t.is('a', c.b.aValue); + t.is('b', c.b.name); + t.is('c', c.name); + t.is('d', c.b.dValue.name); + t.is('eModified', e.name); + } + ] + ); + doh.run(); + } +); + +define("basic-tests", function(){}); diff --git a/htdocs/js/lib/vendor/components/requirejs/tests/shim/c.js b/htdocs/js/lib/vendor/components/requirejs/tests/shim/c.js new file mode 100644 index 000000000..565007e44 --- /dev/null +++ b/htdocs/js/lib/vendor/components/requirejs/tests/shim/c.js @@ -0,0 +1,5 @@ +var C = { + name: 'c', + a: A, + b: B +}; diff --git a/htdocs/js/lib/vendor/components/requirejs/tests/shim/d.js b/htdocs/js/lib/vendor/components/requirejs/tests/shim/d.js new file mode 100644 index 000000000..ef444847a --- /dev/null +++ b/htdocs/js/lib/vendor/components/requirejs/tests/shim/d.js @@ -0,0 +1,3 @@ +function D() { + this.name = 'd'; +}; diff --git a/htdocs/js/lib/vendor/components/requirejs/tests/shim/e.js b/htdocs/js/lib/vendor/components/requirejs/tests/shim/e.js new file mode 100644 index 000000000..0e20b5242 --- /dev/null +++ b/htdocs/js/lib/vendor/components/requirejs/tests/shim/e.js @@ -0,0 +1,7 @@ +var e = { + nested: { + e: { + name: 'e' + } + } +}; diff --git a/htdocs/js/lib/vendor/components/requirejs/tests/simple-badbase.html b/htdocs/js/lib/vendor/components/requirejs/tests/simple-badbase.html new file mode 100644 index 000000000..45e33dc16 --- /dev/null +++ b/htdocs/js/lib/vendor/components/requirejs/tests/simple-badbase.html @@ -0,0 +1,55 @@ + + + require.js: Simple Bad Base Test + + + + + + + + +

      require.js: Simple Test

      +

      You may need to change the IP address used for this test for it to work correctly.

      +

      Check console for messages

      + + diff --git a/htdocs/js/lib/vendor/components/requirejs/tests/simple-nohead.html b/htdocs/js/lib/vendor/components/requirejs/tests/simple-nohead.html new file mode 100644 index 000000000..33a1b0634 --- /dev/null +++ b/htdocs/js/lib/vendor/components/requirejs/tests/simple-nohead.html @@ -0,0 +1,30 @@ + + +

      require.js: Simple Test, no head tag

      +

      Check console for messages

      + + + + + + diff --git a/htdocs/js/lib/vendor/components/requirejs/tests/simple-tests.js b/htdocs/js/lib/vendor/components/requirejs/tests/simple-tests.js new file mode 100644 index 000000000..e7fe6df6c --- /dev/null +++ b/htdocs/js/lib/vendor/components/requirejs/tests/simple-tests.js @@ -0,0 +1,23 @@ +require({ + baseUrl: "./" + }, + ["require", "map", "simple", "dimple", "func"], + function(require, map, simple, dimple, func) { + doh.register( + "simple", + [ + function colors(t){ + t.is("map", map.name); + t.is("blue", simple.color); + t.is("dimple-blue", dimple.color); + t.is("You called a function", func()); + } + ] + ); + + //In rhino there is no more simple tests, but in web browser there is. + if (typeof moreSimpleTests === 'undefined') { + doh.run(); + } + } +); diff --git a/htdocs/js/lib/vendor/components/requirejs/tests/simple.html b/htdocs/js/lib/vendor/components/requirejs/tests/simple.html new file mode 100644 index 000000000..ec8cc7487 --- /dev/null +++ b/htdocs/js/lib/vendor/components/requirejs/tests/simple.html @@ -0,0 +1,36 @@ + + + + require.js: Simple Test + + + + + + + + +

      require.js: Simple Test

      +

      Check console for messages

      + + diff --git a/htdocs/js/lib/vendor/components/requirejs/tests/simple.js b/htdocs/js/lib/vendor/components/requirejs/tests/simple.js new file mode 100644 index 000000000..79552cff9 --- /dev/null +++ b/htdocs/js/lib/vendor/components/requirejs/tests/simple.js @@ -0,0 +1,7 @@ +define("simple", + function() { + return { + color: "blue" + }; + } +); diff --git a/htdocs/js/lib/vendor/components/requirejs/tests/specialDeps/foo.js b/htdocs/js/lib/vendor/components/requirejs/tests/specialDeps/foo.js new file mode 100644 index 000000000..fd78cdbac --- /dev/null +++ b/htdocs/js/lib/vendor/components/requirejs/tests/specialDeps/foo.js @@ -0,0 +1,4 @@ +define(function(require, exports, module) { + require('exports').name = 'foo'; + require('require')('exports').related = require('module').config().related; +}); \ No newline at end of file diff --git a/htdocs/js/lib/vendor/components/requirejs/tests/specialDeps/specialDeps-tests.js b/htdocs/js/lib/vendor/components/requirejs/tests/specialDeps/specialDeps-tests.js new file mode 100644 index 000000000..c840ea847 --- /dev/null +++ b/htdocs/js/lib/vendor/components/requirejs/tests/specialDeps/specialDeps-tests.js @@ -0,0 +1,20 @@ +require.config({ + config: { + foo: { + related: 'bar' + } + } +}); + +require(["foo"], function (foo) { + doh.register( + "specialDeps", + [ + function specialDeps(t) { + t.is("foo", foo.name); + t.is("bar", foo.related); + } + ] + ); + doh.run(); +}); diff --git a/htdocs/js/lib/vendor/components/requirejs/tests/specialDeps/specialDeps.html b/htdocs/js/lib/vendor/components/requirejs/tests/specialDeps/specialDeps.html new file mode 100644 index 000000000..a3a4cb0c6 --- /dev/null +++ b/htdocs/js/lib/vendor/components/requirejs/tests/specialDeps/specialDeps.html @@ -0,0 +1,17 @@ + + + + require.js: Special Dependencies Test + + + + + +

      require.js: Special Dependencies Test

      + +

      Tests for require("require"|"exports"|"module") inside a module. + More info.

      + +

      Check console for messages

      + + diff --git a/htdocs/js/lib/vendor/components/requirejs/tests/text/local.js b/htdocs/js/lib/vendor/components/requirejs/tests/text/local.js new file mode 100644 index 000000000..d25af0f45 --- /dev/null +++ b/htdocs/js/lib/vendor/components/requirejs/tests/text/local.js @@ -0,0 +1,5 @@ +define(['text!./resources/local.html'], function (localHtml) { + return { + localHtml: localHtml + } +}); diff --git a/htdocs/js/lib/vendor/components/requirejs/tests/text/plain.txt b/htdocs/js/lib/vendor/components/requirejs/tests/text/plain.txt new file mode 100644 index 000000000..95d09f2b1 --- /dev/null +++ b/htdocs/js/lib/vendor/components/requirejs/tests/text/plain.txt @@ -0,0 +1 @@ +hello world \ No newline at end of file diff --git a/htdocs/js/lib/vendor/components/requirejs/tests/text/resources/local.html b/htdocs/js/lib/vendor/components/requirejs/tests/text/resources/local.html new file mode 100644 index 000000000..f62ec6215 --- /dev/null +++ b/htdocs/js/lib/vendor/components/requirejs/tests/text/resources/local.html @@ -0,0 +1 @@ +

      Local

      \ No newline at end of file diff --git a/htdocs/js/lib/vendor/components/requirejs/tests/text/resources/sample.html b/htdocs/js/lib/vendor/components/requirejs/tests/text/resources/sample.html new file mode 100644 index 000000000..058326184 --- /dev/null +++ b/htdocs/js/lib/vendor/components/requirejs/tests/text/resources/sample.html @@ -0,0 +1,8 @@ + + + + sample.html + + +Hello World! + diff --git a/htdocs/js/lib/vendor/components/requirejs/tests/text/separate.js b/htdocs/js/lib/vendor/components/requirejs/tests/text/separate.js new file mode 100644 index 000000000..a838789ac --- /dev/null +++ b/htdocs/js/lib/vendor/components/requirejs/tests/text/separate.js @@ -0,0 +1,2 @@ +//Stub file for testing optimization of all plugin resources in a build. +define(['text!resources/sample.html!strip'], function () {}); diff --git a/htdocs/js/lib/vendor/components/requirejs/tests/text/subwidget.html b/htdocs/js/lib/vendor/components/requirejs/tests/text/subwidget.html new file mode 100644 index 000000000..3fd9b9dde --- /dev/null +++ b/htdocs/js/lib/vendor/components/requirejs/tests/text/subwidget.html @@ -0,0 +1,8 @@ + + + + sample.html + + +

      This is a subwidget

      + diff --git a/htdocs/js/lib/vendor/components/requirejs/tests/text/subwidget.js b/htdocs/js/lib/vendor/components/requirejs/tests/text/subwidget.js new file mode 100644 index 000000000..9fd082299 --- /dev/null +++ b/htdocs/js/lib/vendor/components/requirejs/tests/text/subwidget.js @@ -0,0 +1,10 @@ +define("subwidget", + ["text!subwidget.html!strip", "text!subwidget2.html"], + function(template, template2) { + return { + name: "subwidget", + template: template, + template2: template2 + }; + } +); diff --git a/htdocs/js/lib/vendor/components/requirejs/tests/text/subwidget2.html b/htdocs/js/lib/vendor/components/requirejs/tests/text/subwidget2.html new file mode 100644 index 000000000..13a0a035b --- /dev/null +++ b/htdocs/js/lib/vendor/components/requirejs/tests/text/subwidget2.html @@ -0,0 +1 @@ +This! is template2 \ No newline at end of file diff --git a/htdocs/js/lib/vendor/components/requirejs/tests/text/text.html b/htdocs/js/lib/vendor/components/requirejs/tests/text/text.html new file mode 100644 index 000000000..a3eba8dc3 --- /dev/null +++ b/htdocs/js/lib/vendor/components/requirejs/tests/text/text.html @@ -0,0 +1,53 @@ + + + + require.js: Text Test + + + + + + +

      require.js: Text Test

      +

      Test for usage of text! require plugin. +

      Check console for messages

      + + diff --git a/htdocs/js/lib/vendor/components/requirejs/tests/text/textBuilt.html b/htdocs/js/lib/vendor/components/requirejs/tests/text/textBuilt.html new file mode 100644 index 000000000..f22d69b2b --- /dev/null +++ b/htdocs/js/lib/vendor/components/requirejs/tests/text/textBuilt.html @@ -0,0 +1,14 @@ + + + + require.js: Text Built Test + + + + + +

      require.js: Text Built Test

      +

      Test for usage of text! require plugin in a build scenario where text resources are inlined. +

      Check console for messages

      + + diff --git a/htdocs/js/lib/vendor/components/requirejs/tests/text/textBuilt.js b/htdocs/js/lib/vendor/components/requirejs/tests/text/textBuilt.js new file mode 100644 index 000000000..b88b5ada4 --- /dev/null +++ b/htdocs/js/lib/vendor/components/requirejs/tests/text/textBuilt.js @@ -0,0 +1,64 @@ +(function () { + define('text',[],function () { + var text = { + load: function (name, req, onLoad, config) { + throw "THE TEXT PLUGIN LOAD() FUNCTION SHOULD NOT BE CALLED"; + } + }; + + return text; + }); +}()); +define('text!subwidget.html!strip', function () { return '

      This is a subwidget

      ';}); +define('text!subwidget2.html', function () { return 'This! is template2';}); + +define("subwidget", + ["text!subwidget.html!strip", "text!subwidget2.html"], + function(template, template2) { + return { + name: "subwidget", + template: template, + template2: template2 + }; + } +); +define('text!widget.html', function () { return '

      This is a widget!

      I am in a widget

      ';}); + +define("widget", + ["subwidget", "text!widget.html"], + function(subwidget, template) { + return { + subWidgetName: subwidget.name, + subWidgetTemplate: subwidget.template, + subWidgetTemplate2: subwidget.template2, + template: template + }; + } +); + +/****************** TEST CODE IS BELOW ******************/ + +require({ + baseUrl: "./", + paths: { + text: "../../../text/text" + } +}); +require( + ["widget"], + function(widget) { + doh.register( + "text", + [ + function text(t){ + t.is('

      This is a widget!

      I am in a widget

      ', widget.template); + t.is('subwidget', widget.subWidgetName); + t.is('

      This is a subwidget

      ', widget.subWidgetTemplate); + t.is('This! is template2', widget.subWidgetTemplate2); + } + ] + ); + doh.run(); + + } +); diff --git a/htdocs/js/lib/vendor/components/requirejs/tests/text/textOnError.html b/htdocs/js/lib/vendor/components/requirejs/tests/text/textOnError.html new file mode 100644 index 000000000..f9c4d30bf --- /dev/null +++ b/htdocs/js/lib/vendor/components/requirejs/tests/text/textOnError.html @@ -0,0 +1,49 @@ + + + + require.js: Text onError Test + + + + + + +

      require.js: Text Test

      +

      Test for text! plugin triggering an error. +

      Check console for messages

      + + diff --git a/htdocs/js/lib/vendor/components/requirejs/tests/text/textOnXhr.html b/htdocs/js/lib/vendor/components/requirejs/tests/text/textOnXhr.html new file mode 100644 index 000000000..727848451 --- /dev/null +++ b/htdocs/js/lib/vendor/components/requirejs/tests/text/textOnXhr.html @@ -0,0 +1,53 @@ + + + + require.js: Text onXhr Test + + + + + + +

      require.js: Text onXhr Test

      +

      Test onXhr for the text plugin. +

      Check console for messages

      + + diff --git a/htdocs/js/lib/vendor/components/requirejs/tests/text/textOnly.html b/htdocs/js/lib/vendor/components/requirejs/tests/text/textOnly.html new file mode 100644 index 000000000..fbc62b583 --- /dev/null +++ b/htdocs/js/lib/vendor/components/requirejs/tests/text/textOnly.html @@ -0,0 +1,35 @@ + + + + require.js: Text Test + + + + + + +

      require.js: Text Test

      +

      Test for usage of text! require plugin. +

      Check console for messages

      + + diff --git a/htdocs/js/lib/vendor/components/requirejs/tests/text/widget.html b/htdocs/js/lib/vendor/components/requirejs/tests/text/widget.html new file mode 100644 index 000000000..c11c4531e --- /dev/null +++ b/htdocs/js/lib/vendor/components/requirejs/tests/text/widget.html @@ -0,0 +1 @@ +

      This is a widget!

      I am in a widget

      \ No newline at end of file diff --git a/htdocs/js/lib/vendor/components/requirejs/tests/text/widget.js b/htdocs/js/lib/vendor/components/requirejs/tests/text/widget.js new file mode 100644 index 000000000..4075369d9 --- /dev/null +++ b/htdocs/js/lib/vendor/components/requirejs/tests/text/widget.js @@ -0,0 +1,11 @@ +define("widget", + ["subwidget", "text!widget.html"], + function(subwidget, template) { + return { + subWidgetName: subwidget.name, + subWidgetTemplate: subwidget.template, + subWidgetTemplate2: subwidget.template2, + template: template + }; + } +); diff --git a/htdocs/js/lib/vendor/components/requirejs/tests/trailingComma/a.js b/htdocs/js/lib/vendor/components/requirejs/tests/trailingComma/a.js new file mode 100644 index 000000000..85c1a9791 --- /dev/null +++ b/htdocs/js/lib/vendor/components/requirejs/tests/trailingComma/a.js @@ -0,0 +1,5 @@ +define(function (require) { + return { + name: 'a' + }; +}); diff --git a/htdocs/js/lib/vendor/components/requirejs/tests/trailingComma/trailingComma.html b/htdocs/js/lib/vendor/components/requirejs/tests/trailingComma/trailingComma.html new file mode 100644 index 000000000..1b689112c --- /dev/null +++ b/htdocs/js/lib/vendor/components/requirejs/tests/trailingComma/trailingComma.html @@ -0,0 +1,15 @@ + + + + require.js: Trailing Comma Test + + + + + +

      require.js: Trailing Comma Test

      +

      Make sure a trailing comma in IE does not cause an error in the loader. + Info in Issue 299.

      +

      Check console for messages

      + + diff --git a/htdocs/js/lib/vendor/components/requirejs/tests/trailingComma/trailingComma.js b/htdocs/js/lib/vendor/components/requirejs/tests/trailingComma/trailingComma.js new file mode 100644 index 000000000..fa02ad0e4 --- /dev/null +++ b/htdocs/js/lib/vendor/components/requirejs/tests/trailingComma/trailingComma.js @@ -0,0 +1,13 @@ + +//Trailing comma is there ON PURPOSE +require(['a',], function(a) { + doh.register( + "trailingComma", + [ + function trailingComma(t){ + t.is('a', a.name, 'a.name is a'); + } + ] + ); + doh.run(); +}); diff --git a/htdocs/js/lib/vendor/components/requirejs/tests/tres.js b/htdocs/js/lib/vendor/components/requirejs/tests/tres.js new file mode 100644 index 000000000..e3eba9350 --- /dev/null +++ b/htdocs/js/lib/vendor/components/requirejs/tests/tres.js @@ -0,0 +1,7 @@ +define("tres", + function() { + return { + name: "tres" + }; + } +); diff --git a/htdocs/js/lib/vendor/components/requirejs/tests/two.js b/htdocs/js/lib/vendor/components/requirejs/tests/two.js new file mode 100644 index 000000000..8c4c055e6 --- /dev/null +++ b/htdocs/js/lib/vendor/components/requirejs/tests/two.js @@ -0,0 +1,12 @@ +define("two", + ["require", "one"], + function(require, one) { + return { + size: "small", + color: "redtwo", + doSomething: function() { + return require("one").doSomething(); + } + }; + } +); diff --git a/htdocs/js/lib/vendor/components/requirejs/tests/undef/globalFoo.js b/htdocs/js/lib/vendor/components/requirejs/tests/undef/globalFoo.js new file mode 100644 index 000000000..ea1c868d4 --- /dev/null +++ b/htdocs/js/lib/vendor/components/requirejs/tests/undef/globalFoo.js @@ -0,0 +1,4 @@ +var globalFoo = { + name: 'globalFoo' +}; + diff --git a/htdocs/js/lib/vendor/components/requirejs/tests/undef/real.js b/htdocs/js/lib/vendor/components/requirejs/tests/undef/real.js new file mode 100644 index 000000000..c041aaa42 --- /dev/null +++ b/htdocs/js/lib/vendor/components/requirejs/tests/undef/real.js @@ -0,0 +1,3 @@ +define({ + name: 'real' +}); diff --git a/htdocs/js/lib/vendor/components/requirejs/tests/undef/undef.html b/htdocs/js/lib/vendor/components/requirejs/tests/undef/undef.html new file mode 100644 index 000000000..fbd9710b9 --- /dev/null +++ b/htdocs/js/lib/vendor/components/requirejs/tests/undef/undef.html @@ -0,0 +1,66 @@ + + + + require.js: requirejs.undef() Test + + + + + + +

      require.js: requirejs.undef() Test

      +

      Use requirejs.undef() to reset and load a module from a different path.

      +

      Check console for messages

      + + diff --git a/htdocs/js/lib/vendor/components/requirejs/tests/undef/undefEnforceShim.html b/htdocs/js/lib/vendor/components/requirejs/tests/undef/undefEnforceShim.html new file mode 100644 index 000000000..5add3f6bd --- /dev/null +++ b/htdocs/js/lib/vendor/components/requirejs/tests/undef/undefEnforceShim.html @@ -0,0 +1,77 @@ + + + + require.js: requirejs.undef() Test + + + + + + +

      require.js: requirejs.undef() Test

      +

      Use requirejs.undef() to reset and load a module from a different path.

      +

      Check console for messages

      + + diff --git a/htdocs/js/lib/vendor/components/requirejs/tests/undef/undefLocal.html b/htdocs/js/lib/vendor/components/requirejs/tests/undef/undefLocal.html new file mode 100644 index 000000000..c40d79538 --- /dev/null +++ b/htdocs/js/lib/vendor/components/requirejs/tests/undef/undefLocal.html @@ -0,0 +1,57 @@ + + + + require.js: requirejs.undef() Test + + + + + + +

      require.js: requirejs.undef() Test

      +

      Use requirejs.undef() to reset and load a module from a different path.

      +

      Check console for messages

      + + diff --git a/htdocs/js/lib/vendor/components/requirejs/tests/undef/undefNoRequire.html b/htdocs/js/lib/vendor/components/requirejs/tests/undef/undefNoRequire.html new file mode 100644 index 000000000..d623aad13 --- /dev/null +++ b/htdocs/js/lib/vendor/components/requirejs/tests/undef/undefNoRequire.html @@ -0,0 +1,50 @@ + + + + require.js: requirejs.undef() No Require Test + + + + + + +

      require.js: requirejs.undef() No Require Test

      +

      Use requirejs.undef() to reset, but called before the first require() + for the module. + More info.

      +

      Check console for messages

      + + diff --git a/htdocs/js/lib/vendor/components/requirejs/tests/uniques/one.js b/htdocs/js/lib/vendor/components/requirejs/tests/uniques/one.js new file mode 100644 index 000000000..ccaa684d0 --- /dev/null +++ b/htdocs/js/lib/vendor/components/requirejs/tests/uniques/one.js @@ -0,0 +1,8 @@ +define(function (require) { + return { + name: "one", + threeName: require("three").name, + threeName2: require("three").name + }; +}); + diff --git a/htdocs/js/lib/vendor/components/requirejs/tests/uniques/three.js b/htdocs/js/lib/vendor/components/requirejs/tests/uniques/three.js new file mode 100644 index 000000000..3d52f9e1a --- /dev/null +++ b/htdocs/js/lib/vendor/components/requirejs/tests/uniques/three.js @@ -0,0 +1,3 @@ +define("three", { + name: "three" +}); diff --git a/htdocs/js/lib/vendor/components/requirejs/tests/uniques/two.js b/htdocs/js/lib/vendor/components/requirejs/tests/uniques/two.js new file mode 100644 index 000000000..f272edb48 --- /dev/null +++ b/htdocs/js/lib/vendor/components/requirejs/tests/uniques/two.js @@ -0,0 +1,8 @@ +define("two", ["one", "three", "one"], function (one, three, one2) { + return { + name: "two", + oneName: one.name, + oneName2: one2.name, + threeName: three.name + }; +}); diff --git a/htdocs/js/lib/vendor/components/requirejs/tests/uniques/uniques.html b/htdocs/js/lib/vendor/components/requirejs/tests/uniques/uniques.html new file mode 100644 index 000000000..0138e3a54 --- /dev/null +++ b/htdocs/js/lib/vendor/components/requirejs/tests/uniques/uniques.html @@ -0,0 +1,39 @@ + + + + require.js: Unique Dependency Test + + + + + + +

      require.js: Unique Dependency Test

      +

      Make sure if a dependency is listed more than once code still operates correctly.

      +

      Check console for messages

      + + diff --git a/htdocs/js/lib/vendor/components/requirejs/tests/universal/eye.js b/htdocs/js/lib/vendor/components/requirejs/tests/universal/eye.js new file mode 100644 index 000000000..96ba2cbb6 --- /dev/null +++ b/htdocs/js/lib/vendor/components/requirejs/tests/universal/eye.js @@ -0,0 +1,9 @@ +!function (name, definition) { + if (typeof module != 'undefined') module.exports = definition() + else if (typeof define == 'function' && typeof define.amd == 'object') define(name, definition) + else this[name] = definition() +}('eye', function() { + return { + name: 'eye' + } +}) diff --git a/htdocs/js/lib/vendor/components/requirejs/tests/universal/newt.js b/htdocs/js/lib/vendor/components/requirejs/tests/universal/newt.js new file mode 100644 index 000000000..fc4f2041e --- /dev/null +++ b/htdocs/js/lib/vendor/components/requirejs/tests/universal/newt.js @@ -0,0 +1,32 @@ +/*jslint strict: false */ +/*global define: false, module: false, require: false, window: false */ + +(function (define) { + //The 'id' is optional, but recommended if this is + //a popular web library that is used mostly in + //non-AMD/Node environments. + define(function (require) { + //If have dependencies, get them here + var tail = require('tail'), + eye = require('eye'); + + //Return the module definition. + return { + name: 'newt', + eyeName: eye.name, + tailName: tail.name + }; + }); +}(typeof define === 'function' && define.amd ? define : function (id, factory) { + if (typeof module !== 'undefined' && module.exports) { + //Node + module.exports = factory(require); + } else { + //Create a global function. Only works if + //the code does not have dependencies, or + //dependencies fit the call pattern below. + window.myGlobal = factory(function (value) { + return window[value]; + }); + } +})); diff --git a/htdocs/js/lib/vendor/components/requirejs/tests/universal/spell.js b/htdocs/js/lib/vendor/components/requirejs/tests/universal/spell.js new file mode 100644 index 000000000..5e5b77ab1 --- /dev/null +++ b/htdocs/js/lib/vendor/components/requirejs/tests/universal/spell.js @@ -0,0 +1,32 @@ +/*jslint strict: false */ +/*global define: false, module: false, require: false, window: false */ + +(function (define) { + //The 'id' is optional, but recommended if this is + //a popular web library that is used mostly in + //non-AMD/Node environments. + define('spell', function (require) { + //If have dependencies, get them here + var newt = require('newt'); + + //Return the module definition. + return { + name: 'spell', + newtName: newt.name, + tailName: newt.tailName, + eyeName: newt.eyeName + }; + }); +}(typeof define === 'function' && define.amd ? define : function (id, factory) { + if (typeof module !== 'undefined' && module.exports) { + //Node + module.exports = factory(require); + } else { + //Create a global function. Only works if + //the code does not have dependencies, or + //dependencies fit the call pattern below. + window.myGlobal = factory(function (value) { + return window[value]; + }); + } +})); diff --git a/htdocs/js/lib/vendor/components/requirejs/tests/universal/tail.js b/htdocs/js/lib/vendor/components/requirejs/tests/universal/tail.js new file mode 100644 index 000000000..3c805790c --- /dev/null +++ b/htdocs/js/lib/vendor/components/requirejs/tests/universal/tail.js @@ -0,0 +1,9 @@ +!function (name, definition) { + if (typeof module != 'undefined') module.exports = definition() + else if (typeof define == 'function' && typeof define.amd == 'object') define('tail', function(){return definition()}) + else this[name] = definition() +}('tail', function() { + return { + name: 'tail' + } +}) diff --git a/htdocs/js/lib/vendor/components/requirejs/tests/universal/universal-built.html b/htdocs/js/lib/vendor/components/requirejs/tests/universal/universal-built.html new file mode 100644 index 000000000..aa6b3621f --- /dev/null +++ b/htdocs/js/lib/vendor/components/requirejs/tests/universal/universal-built.html @@ -0,0 +1,13 @@ + + + + require.js: Universal Module Wrapper: Built Tests + + + + + +

      require.js: Universal Module Wrapper: Built Tests

      +

      Check console for messages

      + + diff --git a/htdocs/js/lib/vendor/components/requirejs/tests/universal/universal-tests-built-expected.js b/htdocs/js/lib/vendor/components/requirejs/tests/universal/universal-tests-built-expected.js new file mode 100644 index 000000000..df80fec92 --- /dev/null +++ b/htdocs/js/lib/vendor/components/requirejs/tests/universal/universal-tests-built-expected.js @@ -0,0 +1,106 @@ + +!function (name, definition) { + if (typeof module != 'undefined') module.exports = definition() + else if (typeof define == 'function' && typeof define.amd == 'object') define('tail',[], function(){return definition()}) + else this[name] = definition() +}('tail', function() { + return { + name: 'tail' + } +}) +; +!function (name, definition) { + if (typeof module != 'undefined') module.exports = definition() + else if (typeof define == 'function' && typeof define.amd == 'object') define(name, definition) + else this[name] = definition() +}('eye', function() { + return { + name: 'eye' + } +}) +; +define("eye", function(){}); + +/*jslint strict: false */ +/*global define: false, module: false, require: false, window: false */ + +(function (define) { + //The 'id' is optional, but recommended if this is + //a popular web library that is used mostly in + //non-AMD/Node environments. + define('newt',['require','tail','eye'],function (require) { + //If have dependencies, get them here + var tail = require('tail'), + eye = require('eye'); + + //Return the module definition. + return { + name: 'newt', + eyeName: eye.name, + tailName: tail.name + }; + }); +}(typeof define === 'function' && define.amd ? define : function (id, factory) { + if (typeof module !== 'undefined' && module.exports) { + //Node + module.exports = factory(require); + } else { + //Create a global function. Only works if + //the code does not have dependencies, or + //dependencies fit the call pattern below. + window.myGlobal = factory(function (value) { + return window[value]; + }); + } +})); + +/*jslint strict: false */ +/*global define: false, module: false, require: false, window: false */ + +(function (define) { + //The 'id' is optional, but recommended if this is + //a popular web library that is used mostly in + //non-AMD/Node environments. + define('spell',['require','newt'], function (require) { + //If have dependencies, get them here + var newt = require('newt'); + + //Return the module definition. + return { + name: 'spell', + newtName: newt.name, + tailName: newt.tailName, + eyeName: newt.eyeName + }; + }); +}(typeof define === 'function' && define.amd ? define : function (id, factory) { + if (typeof module !== 'undefined' && module.exports) { + //Node + module.exports = factory(require); + } else { + //Create a global function. Only works if + //the code does not have dependencies, or + //dependencies fit the call pattern below. + window.myGlobal = factory(function (value) { + return window[value]; + }); + } +})); + +require({baseUrl: requirejs.isBrowser ? "./" : "./universal/"}, ["spell"], function(spell) { + doh.register( + "universal", + [ + function universal(t){ + t.is('spell', spell.name); + t.is('newt', spell.newtName); + t.is('tail', spell.tailName); + t.is('eye', spell.eyeName); + } + ] + ); + + doh.run(); +}); + +define("universal-tests", function(){}); diff --git a/htdocs/js/lib/vendor/components/requirejs/tests/universal/universal-tests-built.js b/htdocs/js/lib/vendor/components/requirejs/tests/universal/universal-tests-built.js new file mode 100644 index 000000000..df80fec92 --- /dev/null +++ b/htdocs/js/lib/vendor/components/requirejs/tests/universal/universal-tests-built.js @@ -0,0 +1,106 @@ + +!function (name, definition) { + if (typeof module != 'undefined') module.exports = definition() + else if (typeof define == 'function' && typeof define.amd == 'object') define('tail',[], function(){return definition()}) + else this[name] = definition() +}('tail', function() { + return { + name: 'tail' + } +}) +; +!function (name, definition) { + if (typeof module != 'undefined') module.exports = definition() + else if (typeof define == 'function' && typeof define.amd == 'object') define(name, definition) + else this[name] = definition() +}('eye', function() { + return { + name: 'eye' + } +}) +; +define("eye", function(){}); + +/*jslint strict: false */ +/*global define: false, module: false, require: false, window: false */ + +(function (define) { + //The 'id' is optional, but recommended if this is + //a popular web library that is used mostly in + //non-AMD/Node environments. + define('newt',['require','tail','eye'],function (require) { + //If have dependencies, get them here + var tail = require('tail'), + eye = require('eye'); + + //Return the module definition. + return { + name: 'newt', + eyeName: eye.name, + tailName: tail.name + }; + }); +}(typeof define === 'function' && define.amd ? define : function (id, factory) { + if (typeof module !== 'undefined' && module.exports) { + //Node + module.exports = factory(require); + } else { + //Create a global function. Only works if + //the code does not have dependencies, or + //dependencies fit the call pattern below. + window.myGlobal = factory(function (value) { + return window[value]; + }); + } +})); + +/*jslint strict: false */ +/*global define: false, module: false, require: false, window: false */ + +(function (define) { + //The 'id' is optional, but recommended if this is + //a popular web library that is used mostly in + //non-AMD/Node environments. + define('spell',['require','newt'], function (require) { + //If have dependencies, get them here + var newt = require('newt'); + + //Return the module definition. + return { + name: 'spell', + newtName: newt.name, + tailName: newt.tailName, + eyeName: newt.eyeName + }; + }); +}(typeof define === 'function' && define.amd ? define : function (id, factory) { + if (typeof module !== 'undefined' && module.exports) { + //Node + module.exports = factory(require); + } else { + //Create a global function. Only works if + //the code does not have dependencies, or + //dependencies fit the call pattern below. + window.myGlobal = factory(function (value) { + return window[value]; + }); + } +})); + +require({baseUrl: requirejs.isBrowser ? "./" : "./universal/"}, ["spell"], function(spell) { + doh.register( + "universal", + [ + function universal(t){ + t.is('spell', spell.name); + t.is('newt', spell.newtName); + t.is('tail', spell.tailName); + t.is('eye', spell.eyeName); + } + ] + ); + + doh.run(); +}); + +define("universal-tests", function(){}); diff --git a/htdocs/js/lib/vendor/components/requirejs/tests/universal/universal-tests.js b/htdocs/js/lib/vendor/components/requirejs/tests/universal/universal-tests.js new file mode 100644 index 000000000..3c6a9de1f --- /dev/null +++ b/htdocs/js/lib/vendor/components/requirejs/tests/universal/universal-tests.js @@ -0,0 +1,15 @@ +require({baseUrl: requirejs.isBrowser ? "./" : "./universal/"}, ["spell"], function(spell) { + doh.register( + "universal", + [ + function universal(t){ + t.is('spell', spell.name); + t.is('newt', spell.newtName); + t.is('tail', spell.tailName); + t.is('eye', spell.eyeName); + } + ] + ); + + doh.run(); +}); diff --git a/htdocs/js/lib/vendor/components/requirejs/tests/universal/universal.html b/htdocs/js/lib/vendor/components/requirejs/tests/universal/universal.html new file mode 100644 index 000000000..1d7f32d21 --- /dev/null +++ b/htdocs/js/lib/vendor/components/requirejs/tests/universal/universal.html @@ -0,0 +1,13 @@ + + + + require.js: Universal Module Wrapper Tests + + + + + +

      require.js: Universal Module Wrapper Tests

      +

      Check console for messages

      + + diff --git a/htdocs/js/lib/vendor/components/requirejs/tests/uno.js b/htdocs/js/lib/vendor/components/requirejs/tests/uno.js new file mode 100644 index 000000000..dcc57dce2 --- /dev/null +++ b/htdocs/js/lib/vendor/components/requirejs/tests/uno.js @@ -0,0 +1,14 @@ +define("uno", + ["dos", "tres"], + function(dos, tres) { + return { + name: "uno", + doSomething: function() { + return { + dosName: dos.name, + tresName: tres.name + }; + } + }; + } +); diff --git a/htdocs/js/lib/vendor/components/requirejs/tests/urlfetch/one.js b/htdocs/js/lib/vendor/components/requirejs/tests/urlfetch/one.js new file mode 100644 index 000000000..92184aeb5 --- /dev/null +++ b/htdocs/js/lib/vendor/components/requirejs/tests/urlfetch/one.js @@ -0,0 +1,3 @@ +var one = { + name: "one" +}; diff --git a/htdocs/js/lib/vendor/components/requirejs/tests/urlfetch/three.js b/htdocs/js/lib/vendor/components/requirejs/tests/urlfetch/three.js new file mode 100644 index 000000000..d78a542c2 --- /dev/null +++ b/htdocs/js/lib/vendor/components/requirejs/tests/urlfetch/three.js @@ -0,0 +1,10 @@ +define("three", { + name: "three" +}); + +define("four", ["three"], function (three) { + return { + name: "four", + threeName: "three" + }; +}); diff --git a/htdocs/js/lib/vendor/components/requirejs/tests/urlfetch/two.js b/htdocs/js/lib/vendor/components/requirejs/tests/urlfetch/two.js new file mode 100644 index 000000000..8617a31b7 --- /dev/null +++ b/htdocs/js/lib/vendor/components/requirejs/tests/urlfetch/two.js @@ -0,0 +1,10 @@ +define("one", { + name: "one" +}); + +define("two", ["one"], function (one) { + return { + name: "two", + oneName: "one" + }; +}); diff --git a/htdocs/js/lib/vendor/components/requirejs/tests/urlfetch/urlfetch.html b/htdocs/js/lib/vendor/components/requirejs/tests/urlfetch/urlfetch.html new file mode 100644 index 000000000..9d1afaa1a --- /dev/null +++ b/htdocs/js/lib/vendor/components/requirejs/tests/urlfetch/urlfetch.html @@ -0,0 +1,64 @@ + + + + require.js: urlFetch Mapping Test + + + + + + +

      require.js: urlFetch Mapping Test

      +

      Make sure that multiple modules mapped to the same URL only get + the URL fetched once.

      +

      Check console for messages

      + + diff --git a/htdocs/js/lib/vendor/components/requirejs/tests/version1/alpha.js b/htdocs/js/lib/vendor/components/requirejs/tests/version1/alpha.js new file mode 100644 index 000000000..7b5c52e3f --- /dev/null +++ b/htdocs/js/lib/vendor/components/requirejs/tests/version1/alpha.js @@ -0,0 +1,7 @@ +define("alpha", + function() { + return { + version: 1 + }; + } +); diff --git a/htdocs/js/lib/vendor/components/requirejs/tests/version1/beta.js b/htdocs/js/lib/vendor/components/requirejs/tests/version1/beta.js new file mode 100644 index 000000000..e92bd1a18 --- /dev/null +++ b/htdocs/js/lib/vendor/components/requirejs/tests/version1/beta.js @@ -0,0 +1,7 @@ +define("beta", + function() { + return { + version: 1 + }; + } +); diff --git a/htdocs/js/lib/vendor/components/requirejs/tests/version1/gamma.js b/htdocs/js/lib/vendor/components/requirejs/tests/version1/gamma.js new file mode 100644 index 000000000..3f6333da5 --- /dev/null +++ b/htdocs/js/lib/vendor/components/requirejs/tests/version1/gamma.js @@ -0,0 +1,3 @@ +gamma = { + color: "green" +} diff --git a/htdocs/js/lib/vendor/components/requirejs/tests/version1/omega.js b/htdocs/js/lib/vendor/components/requirejs/tests/version1/omega.js new file mode 100644 index 000000000..14906836f --- /dev/null +++ b/htdocs/js/lib/vendor/components/requirejs/tests/version1/omega.js @@ -0,0 +1,7 @@ +define("omega", + function() { + return { + version: 1 + }; + } +); diff --git a/htdocs/js/lib/vendor/components/requirejs/tests/version2/alpha.js b/htdocs/js/lib/vendor/components/requirejs/tests/version2/alpha.js new file mode 100644 index 000000000..2c452a948 --- /dev/null +++ b/htdocs/js/lib/vendor/components/requirejs/tests/version2/alpha.js @@ -0,0 +1,7 @@ +define("alpha", + function() { + return { + version: 2 + }; + } +); diff --git a/htdocs/js/lib/vendor/components/requirejs/tests/version2/beta.js b/htdocs/js/lib/vendor/components/requirejs/tests/version2/beta.js new file mode 100644 index 000000000..69b870b33 --- /dev/null +++ b/htdocs/js/lib/vendor/components/requirejs/tests/version2/beta.js @@ -0,0 +1,7 @@ +define("beta", + function() { + return { + version: 2 + }; + } +); diff --git a/htdocs/js/lib/vendor/components/requirejs/tests/version2/epsilon.js b/htdocs/js/lib/vendor/components/requirejs/tests/version2/epsilon.js new file mode 100644 index 000000000..038a6323f --- /dev/null +++ b/htdocs/js/lib/vendor/components/requirejs/tests/version2/epsilon.js @@ -0,0 +1,3 @@ +epsilon = { + color: "red" +} diff --git a/htdocs/js/lib/vendor/components/requirejs/tests/version2/omega.js b/htdocs/js/lib/vendor/components/requirejs/tests/version2/omega.js new file mode 100644 index 000000000..79a2f7024 --- /dev/null +++ b/htdocs/js/lib/vendor/components/requirejs/tests/version2/omega.js @@ -0,0 +1,7 @@ +define("omega", + function() { + return { + version: 2 + }; + } +); diff --git a/htdocs/js/lib/vendor/components/requirejs/tests/workers.html b/htdocs/js/lib/vendor/components/requirejs/tests/workers.html new file mode 100644 index 000000000..ce5c16df9 --- /dev/null +++ b/htdocs/js/lib/vendor/components/requirejs/tests/workers.html @@ -0,0 +1,56 @@ + + + + require.js: Web Workers Test + + + + + +

      require.js: Web Workers Test

      +

      Check console for messages

      + + diff --git a/htdocs/js/lib/vendor/components/requirejs/tests/workers.js b/htdocs/js/lib/vendor/components/requirejs/tests/workers.js new file mode 100644 index 000000000..aaefed204 --- /dev/null +++ b/htdocs/js/lib/vendor/components/requirejs/tests/workers.js @@ -0,0 +1,13 @@ +importScripts('../require.js'); + +require({ + baseUrl: "./" + }, + ["require", "simple", "anon/blue", "func", "anon/green"], + function(require, simple, blue, func, green) { + postMessage(simple.color); + postMessage(green.name); + postMessage(func()); + postMessage(blue.name); + } +); diff --git a/htdocs/js/lib/vendor/components/requirejs/updatesubs.sh b/htdocs/js/lib/vendor/components/requirejs/updatesubs.sh new file mode 100755 index 000000000..befe2d2d4 --- /dev/null +++ b/htdocs/js/lib/vendor/components/requirejs/updatesubs.sh @@ -0,0 +1,58 @@ +#!/bin/bash + +# This script updates the sub projects that depend on the main requirejs +# project. It is assumed the sub projects are siblings to this project +# the the names specified below. + +echo "Updating r.js" +cp require.js ../r.js/require.js +cd ../r.js +node dist.js +cd ../requirejs + +# The RequireJS+jQuery sample project. +echo "Updating jQuery sample project" +cp require.js ../require-jquery/parts/require.js +cp ../r.js/r.js ../require-jquery/jquery-require-sample/r.js +cd ../require-jquery/parts +./update.sh +cd ../../requirejs + +# The sample projects +echo "Updating requirejs/example-multipage" +cp require.js ../example-multipage/www/js/lib/require.js +cp ../r.js/r.js ../example-multipage/tools/r.js + +echo "Updating requirejs/example-multipage-shim" +cp require.js ../example-multipage-shim/www/js/lib/require.js +cp ../r.js/r.js ../example-multipage-shim/tools/r.js + +echo "Updating requirejs/example-libglobal" +cp require.js ../example-libglobal/lib/require.js +cp ../r.js/r.js ../example-libglobal/tools/r.js + +echo "Updating volojs/create-template" +cp require.js ../../volojs/create-template/www/js/lib/require.js +cp ../r.js/r.js ../../volojs/create-template/tools/r.js + +echo "Updating volojs/create-responsive-template" +cp require.js ../../volojs/create-responsive-template/www/js/lib/require.js +cp ../r.js/r.js ../../volojs/create-responsive-template/tools/r.js + +# The cajon project +echo "Updating the cajon project" +cp require.js ../cajon/tools/require.js +cp ../r.js/r.js ../cajon/tools/r.js +cd ../cajon/tools +./build-cajon.js +cd ../../requirejs + +# The require-cs project +echo "Updating the require-cs CoffeeScript plugin" +cp require.js ../require-cs/demo/lib/require.js +cp ../r.js/r.js ../require-cs/tools/r.js + +# The npm container stuff +echo "Updating requirejs-npm" +cp require.js ../requirejs-npm/requirejs/require.js +cp ../r.js/r.js ../requirejs-npm/requirejs/bin/r.js diff --git a/htdocs/js/lib/vendor/datepicker/css/datepicker.css b/htdocs/js/lib/vendor/datepicker/css/datepicker.css new file mode 100755 index 000000000..bd9b6b903 --- /dev/null +++ b/htdocs/js/lib/vendor/datepicker/css/datepicker.css @@ -0,0 +1,7 @@ + /* + Datepicker for Bootstrap + Copyright 2012 Stefan Petre + Licensed under the Apache License v2.0 + http://www.apache.org/licenses/LICENSE-2.0 +*/ + .datepicker { top: 0; left: 0; padding: 4px; margin-top: 1px; -webkit-border-radius: 4px; -moz-border-radius: 4px; border-radius: 4px; /*.dow { border-top: 1px solid #ddd !important; }*/ } .datepicker:before { content: ''; display: inline-block; border-left: 7px solid transparent; border-right: 7px solid transparent; border-bottom: 7px solid #ccc; border-bottom-color: rgba(0, 0, 0, 0.2); position: absolute; top: -7px; left: 6px; } .datepicker:after { content: ''; display: inline-block; border-left: 6px solid transparent; border-right: 6px solid transparent; border-bottom: 6px solid #ffffff; position: absolute; top: -6px; left: 7px; } .datepicker > div { display: none; } .datepicker table { width: 100%; margin: 0; } .datepicker td, .datepicker th { text-align: center; width: 20px; height: 20px; -webkit-border-radius: 4px; -moz-border-radius: 4px; border-radius: 4px; } .datepicker td.day:hover { background: #eeeeee; cursor: pointer; } .datepicker td.old, .datepicker td.new { color: #999999; } .datepicker td.active, .datepicker td.active:hover { background-color: #006dcc; background-image: -moz-linear-gradient(top, #0088cc, #0044cc); background-image: -ms-linear-gradient(top, #0088cc, #0044cc); background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#0088cc), to(#0044cc)); background-image: -webkit-linear-gradient(top, #0088cc, #0044cc); background-image: -o-linear-gradient(top, #0088cc, #0044cc); background-image: linear-gradient(top, #0088cc, #0044cc); background-repeat: repeat-x; filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#0088cc', endColorstr='#0044cc', GradientType=0); border-color: #0044cc #0044cc #002a80; border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25); filter: progid:DXImageTransform.Microsoft.gradient(enabled = false); color: #fff; text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25); } .datepicker td.active:hover, .datepicker td.active:hover:hover, .datepicker td.active:active, .datepicker td.active:hover:active, .datepicker td.active.active, .datepicker td.active:hover.active, .datepicker td.active.disabled, .datepicker td.active:hover.disabled, .datepicker td.active[disabled], .datepicker td.active:hover[disabled] { background-color: #0044cc; } .datepicker td.active:active, .datepicker td.active:hover:active, .datepicker td.active.active, .datepicker td.active:hover.active { background-color: #003399 \9; } .datepicker td span { display: block; width: 47px; height: 54px; line-height: 54px; float: left; margin: 2px; cursor: pointer; -webkit-border-radius: 4px; -moz-border-radius: 4px; border-radius: 4px; } .datepicker td span:hover { background: #eeeeee; } .datepicker td span.active { background-color: #006dcc; background-image: -moz-linear-gradient(top, #0088cc, #0044cc); background-image: -ms-linear-gradient(top, #0088cc, #0044cc); background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#0088cc), to(#0044cc)); background-image: -webkit-linear-gradient(top, #0088cc, #0044cc); background-image: -o-linear-gradient(top, #0088cc, #0044cc); background-image: linear-gradient(top, #0088cc, #0044cc); background-repeat: repeat-x; filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#0088cc', endColorstr='#0044cc', GradientType=0); border-color: #0044cc #0044cc #002a80; border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25); filter: progid:DXImageTransform.Microsoft.gradient(enabled = false); color: #fff; text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25); } .datepicker td span.active:hover, .datepicker td span.active:active, .datepicker td span.active.active, .datepicker td span.active.disabled, .datepicker td span.active[disabled] { background-color: #0044cc; } .datepicker td span.active:active, .datepicker td span.active.active { background-color: #003399 \9; } .datepicker td span.old { color: #999999; } .datepicker th.switch { width: 145px; } .datepicker th.next, .datepicker th.prev { font-size: 19.5px; } .datepicker thead tr:first-child th { cursor: pointer; } .datepicker thead tr:first-child th:hover { background: #eeeeee; } .input-append.date .add-on i, .input-prepend.date .add-on i { display: block; cursor: pointer; width: 16px; height: 16px; } \ No newline at end of file diff --git a/htdocs/js/lib/vendor/datepicker/js/bootstrap-datepicker.js b/htdocs/js/lib/vendor/datepicker/js/bootstrap-datepicker.js new file mode 100755 index 000000000..8875ec124 --- /dev/null +++ b/htdocs/js/lib/vendor/datepicker/js/bootstrap-datepicker.js @@ -0,0 +1,454 @@ +/* ========================================================= + * bootstrap-datepicker.js + * http://www.eyecon.ro/bootstrap-datepicker + * ========================================================= + * Copyright 2012 Stefan Petre + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ========================================================= */ + +!function( $ ) { + + // Picker object + + var Datepicker = function(element, options){ + this.element = $(element); + this.format = DPGlobal.parseFormat(options.format||this.element.data('date-format')||'mm/dd/yyyy'); + this.picker = $(DPGlobal.template) + .appendTo('body') + .on({ + click: $.proxy(this.click, this), + mousedown: $.proxy(this.mousedown, this) + }); + this.isInput = this.element.is('input'); + this.component = this.element.is('.date') ? this.element.find('.add-on') : false; + + if (this.isInput) { + this.element.on({ + focus: $.proxy(this.show, this), + blur: $.proxy(this.hide, this), + keyup: $.proxy(this.update, this) + }); + } else { + if (this.component){ + this.component.on('click', $.proxy(this.show, this)); + } else { + this.element.on('click', $.proxy(this.show, this)); + } + } + this.minViewMode = options.minViewMode||this.element.data('date-minviewmode')||0; + if (typeof this.minViewMode === 'string') { + switch (this.minViewMode) { + case 'months': + this.minViewMode = 1; + break; + case 'years': + this.minViewMode = 2; + break; + default: + this.minViewMode = 0; + break; + } + } + this.viewMode = options.viewMode||this.element.data('date-viewmode')||0; + if (typeof this.viewMode === 'string') { + switch (this.viewMode) { + case 'months': + this.viewMode = 1; + break; + case 'years': + this.viewMode = 2; + break; + default: + this.viewMode = 0; + break; + } + } + this.startViewMode = this.viewMode; + this.weekStart = options.weekStart||this.element.data('date-weekstart')||0; + this.weekEnd = this.weekStart === 0 ? 6 : this.weekStart - 1; + this.fillDow(); + this.fillMonths(); + this.update(); + this.showMode(); + }; + + Datepicker.prototype = { + constructor: Datepicker, + + show: function(e) { + this.picker.show(); + this.height = this.component ? this.component.outerHeight() : this.element.outerHeight(); + this.place(); + $(window).on('resize', $.proxy(this.place, this)); + if (e ) { + e.stopPropagation(); + e.preventDefault(); + } + if (!this.isInput) { + $(document).on('mousedown', $.proxy(this.hide, this)); + } + this.element.trigger({ + type: 'show', + date: this.date + }); + }, + + hide: function(){ + this.picker.hide(); + $(window).off('resize', this.place); + this.viewMode = this.startViewMode; + this.showMode(); + if (!this.isInput) { + $(document).off('mousedown', this.hide); + } + this.set(); + this.element.trigger({ + type: 'hide', + date: this.date + }); + }, + + set: function() { + var formated = DPGlobal.formatDate(this.date, this.format); + if (!this.isInput) { + if (this.component){ + this.element.find('input').prop('value', formated); + } + this.element.data('date', formated); + } else { + this.element.prop('value', formated); + } + }, + + setValue: function(newDate) { + if (typeof newDate === 'string') { + this.date = DPGlobal.parseDate(newDate, this.format); + } else { + this.date = new Date(newDate); + } + this.set(); + this.viewDate = new Date(this.date.getFullYear(), this.date.getMonth(), 1, 0, 0, 0, 0); + this.fill(); + }, + + place: function(){ + var offset = this.component ? this.component.offset() : this.element.offset(); + this.picker.css({ + top: offset.top + this.height, + left: offset.left + }); + }, + + update: function(newDate){ + this.date = DPGlobal.parseDate( + typeof newDate === 'string' ? newDate : (this.isInput ? this.element.prop('value') : this.element.data('date')), + this.format + ); + this.viewDate = new Date(this.date.getFullYear(), this.date.getMonth(), 1, 0, 0, 0, 0); + this.fill(); + }, + + fillDow: function(){ + var dowCnt = this.weekStart; + var html = ''; + while (dowCnt < this.weekStart + 7) { + html += ''+DPGlobal.dates.daysMin[(dowCnt++)%7]+''; + } + html += ''; + this.picker.find('.datepicker-days thead').append(html); + }, + + fillMonths: function(){ + var html = ''; + var i = 0 + while (i < 12) { + html += ''+DPGlobal.dates.monthsShort[i++]+''; + } + this.picker.find('.datepicker-months td').append(html); + }, + + fill: function() { + var d = new Date(this.viewDate), + year = d.getFullYear(), + month = d.getMonth(), + currentDate = this.date.valueOf(); + this.picker.find('.datepicker-days th:eq(1)') + .text(DPGlobal.dates.months[month]+' '+year); + var prevMonth = new Date(year, month-1, 28,0,0,0,0), + day = DPGlobal.getDaysInMonth(prevMonth.getFullYear(), prevMonth.getMonth()); + prevMonth.setDate(day); + prevMonth.setDate(day - (prevMonth.getDay() - this.weekStart + 7)%7); + var nextMonth = new Date(prevMonth); + nextMonth.setDate(nextMonth.getDate() + 42); + nextMonth = nextMonth.valueOf(); + html = []; + var clsName; + while(prevMonth.valueOf() < nextMonth) { + if (prevMonth.getDay() === this.weekStart) { + html.push(''); + } + clsName = ''; + if (prevMonth.getMonth() < month) { + clsName += ' old'; + } else if (prevMonth.getMonth() > month) { + clsName += ' new'; + } + if (prevMonth.valueOf() === currentDate) { + clsName += ' active'; + } + html.push(''+prevMonth.getDate() + ''); + if (prevMonth.getDay() === this.weekEnd) { + html.push(''); + } + prevMonth.setDate(prevMonth.getDate()+1); + } + this.picker.find('.datepicker-days tbody').empty().append(html.join('')); + var currentYear = this.date.getFullYear(); + + var months = this.picker.find('.datepicker-months') + .find('th:eq(1)') + .text(year) + .end() + .find('span').removeClass('active'); + if (currentYear === year) { + months.eq(this.date.getMonth()).addClass('active'); + } + + html = ''; + year = parseInt(year/10, 10) * 10; + var yearCont = this.picker.find('.datepicker-years') + .find('th:eq(1)') + .text(year + '-' + (year + 9)) + .end() + .find('td'); + year -= 1; + for (var i = -1; i < 11; i++) { + html += ''+year+''; + year += 1; + } + yearCont.html(html); + }, + + click: function(e) { + e.stopPropagation(); + e.preventDefault(); + var target = $(e.target).closest('span, td, th'); + if (target.length === 1) { + switch(target[0].nodeName.toLowerCase()) { + case 'th': + switch(target[0].className) { + case 'switch': + this.showMode(1); + break; + case 'prev': + case 'next': + this.viewDate['set'+DPGlobal.modes[this.viewMode].navFnc].call( + this.viewDate, + this.viewDate['get'+DPGlobal.modes[this.viewMode].navFnc].call(this.viewDate) + + DPGlobal.modes[this.viewMode].navStep * (target[0].className === 'prev' ? -1 : 1) + ); + this.fill(); + this.set(); + break; + } + break; + case 'span': + if (target.is('.month')) { + var month = target.parent().find('span').index(target); + this.viewDate.setMonth(month); + } else { + var year = parseInt(target.text(), 10)||0; + this.viewDate.setFullYear(year); + } + if (this.viewMode !== 0) { + this.date = new Date(this.viewDate); + this.element.trigger({ + type: 'changeDate', + date: this.date, + viewMode: DPGlobal.modes[this.viewMode].clsName + }); + } + this.showMode(-1); + this.fill(); + this.set(); + break; + case 'td': + if (target.is('.day')){ + var day = parseInt(target.text(), 10)||1; + var month = this.viewDate.getMonth(); + if (target.is('.old')) { + month -= 1; + } else if (target.is('.new')) { + month += 1; + } + var year = this.viewDate.getFullYear(); + this.date = new Date(year, month, day,0,0,0,0); + this.viewDate = new Date(year, month, Math.min(28, day),0,0,0,0); + this.fill(); + this.set(); + this.element.trigger({ + type: 'changeDate', + date: this.date, + viewMode: DPGlobal.modes[this.viewMode].clsName + }); + } + break; + } + } + }, + + mousedown: function(e){ + e.stopPropagation(); + e.preventDefault(); + }, + + showMode: function(dir) { + if (dir) { + this.viewMode = Math.max(this.minViewMode, Math.min(2, this.viewMode + dir)); + } + this.picker.find('>div').hide().filter('.datepicker-'+DPGlobal.modes[this.viewMode].clsName).show(); + } + }; + + $.fn.datepicker = function ( option, val ) { + return this.each(function () { + var $this = $(this), + data = $this.data('datepicker'), + options = typeof option === 'object' && option; + if (!data) { + $this.data('datepicker', (data = new Datepicker(this, $.extend({}, $.fn.datepicker.defaults,options)))); + } + if (typeof option === 'string') data[option](val); + }); + }; + + $.fn.datepicker.defaults = { + }; + $.fn.datepicker.Constructor = Datepicker; + + var DPGlobal = { + modes: [ + { + clsName: 'days', + navFnc: 'Month', + navStep: 1 + }, + { + clsName: 'months', + navFnc: 'FullYear', + navStep: 1 + }, + { + clsName: 'years', + navFnc: 'FullYear', + navStep: 10 + }], + dates:{ + days: ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"], + daysShort: ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"], + daysMin: ["Su", "Mo", "Tu", "We", "Th", "Fr", "Sa", "Su"], + months: ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"], + monthsShort: ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"] + }, + isLeapYear: function (year) { + return (((year % 4 === 0) && (year % 100 !== 0)) || (year % 400 === 0)) + }, + getDaysInMonth: function (year, month) { + return [31, (DPGlobal.isLeapYear(year) ? 29 : 28), 31, 30, 31, 30, 31, 31, 30, 31, 30, 31][month] + }, + parseFormat: function(format){ + var separator = format.match(/[.\/\-\s].*?/), + parts = format.split(/\W+/); + if (!separator || !parts || parts.length === 0){ + throw new Error("Invalid date format."); + } + return {separator: separator, parts: parts}; + }, + parseDate: function(date, format) { + var parts = date.split(format.separator), + date = new Date(), + val; + date.setHours(0); + date.setMinutes(0); + date.setSeconds(0); + date.setMilliseconds(0); + if (parts.length === format.parts.length) { + for (var i=0, cnt = format.parts.length; i < cnt; i++) { + val = parseInt(parts[i], 10)||1; + switch(format.parts[i]) { + case 'dd': + case 'd': + date.setDate(val); + break; + case 'mm': + case 'm': + date.setMonth(val - 1); + break; + case 'yy': + date.setFullYear(2000 + val); + break; + case 'yyyy': + date.setFullYear(val); + break; + } + } + } + return date; + }, + formatDate: function(date, format){ + var val = { + d: date.getDate(), + m: date.getMonth() + 1, + yy: date.getFullYear().toString().substring(2), + yyyy: date.getFullYear() + }; + val.dd = (val.d < 10 ? '0' : '') + val.d; + val.mm = (val.m < 10 ? '0' : '') + val.m; + var date = []; + for (var i=0, cnt = format.parts.length; i < cnt; i++) { + date.push(val[format.parts[i]]); + } + return date.join(format.separator); + }, + headTemplate: ''+ + ''+ + '‹'+ + ''+ + '›'+ + ''+ + '', + contTemplate: '' + }; + DPGlobal.template = ''; + +}( window.jQuery ) \ No newline at end of file diff --git a/htdocs/js/lib/vendor/datepicker/less/datepicker.less b/htdocs/js/lib/vendor/datepicker/less/datepicker.less new file mode 100755 index 000000000..bab7fd414 --- /dev/null +++ b/htdocs/js/lib/vendor/datepicker/less/datepicker.less @@ -0,0 +1,119 @@ +/*! + * Datepicker for Bootstrap + * + * Copyright 2012 Stefan Petre + * Licensed under the Apache License v2.0 + * http://www.apache.org/licenses/LICENSE-2.0 + * + */ + +.datepicker { + top: 0; + left: 0; + padding: 4px; + margin-top: 1px; + .border-radius(4px); + &:before { + content: ''; + display: inline-block; + border-left: 7px solid transparent; + border-right: 7px solid transparent; + border-bottom: 7px solid #ccc; + border-bottom-color: rgba(0,0,0,.2); + position: absolute; + top: -7px; + left: 6px; + } + &:after { + content: ''; + display: inline-block; + border-left: 6px solid transparent; + border-right: 6px solid transparent; + border-bottom: 6px solid @white; + position: absolute; + top: -6px; + left: 7px; + } + >div { + display: none; + } + table{ + width: 100%; + margin: 0; + } + td, + th{ + text-align: center; + width: 20px; + height: 20px; + .border-radius(4px); + } + td { + &.day:hover { + background: @grayLighter; + cursor: pointer; + } + &.old, + &.new { + color: @grayLight; + } + &.active, + &.active:hover { + .buttonBackground(@primaryButtonBackground, spin(@primaryButtonBackground, 20)); + color: #fff; + text-shadow: 0 -1px 0 rgba(0,0,0,.25); + } + span { + display: block; + width: 47px; + height: 54px; + line-height: 54px; + float: left; + margin: 2px; + cursor: pointer; + .border-radius(4px); + &:hover { + background: @grayLighter; + } + &.active { + .buttonBackground(@primaryButtonBackground, spin(@primaryButtonBackground, 20)); + color: #fff; + text-shadow: 0 -1px 0 rgba(0,0,0,.25); + } + &.old { + color: @grayLight; + } + } + } + + th { + &.switch { + width: 145px; + } + &.next, + &.prev { + font-size: @baseFontSize * 1.5; + } + } + + thead tr:first-child th { + cursor: pointer; + &:hover{ + background: @grayLighter; + } + } + /*.dow { + border-top: 1px solid #ddd !important; + }*/ +} +.input-append, +.input-prepend { + &.date { + .add-on i { + display: block; + cursor: pointer; + width: 16px; + height: 16px; + } + } +} \ No newline at end of file diff --git a/htdocs/js/lib/vendor/editablegrid-2.0.1/editablegrid-2.0.1.js b/htdocs/js/lib/vendor/editablegrid-2.0.1/editablegrid-2.0.1.js index 9ada92770..cc5ac4ac2 100755 --- a/htdocs/js/lib/vendor/editablegrid-2.0.1/editablegrid-2.0.1.js +++ b/htdocs/js/lib/vendor/editablegrid-2.0.1/editablegrid-2.0.1.js @@ -8,5 +8,7 @@ * Dual licensed under the MIT or GPL Version 2 licenses. * http://editablegrid.net/license */ - -eval(function(p,a,c,k,e,d){e=function(c){return(c35?String.fromCharCode(c+29):c.toString(36))};if(!''.replace(/^/,String)){while(c--){d[e(c)]=k[c]||e(c)}k=[function(e){return d[e]}];e=function(){return'\\w+'};c=1};while(c--){if(k[c]){p=p.replace(new RegExp('\\b'+e(c)+'\\b','g'),k[c])}}return p}('x(P 1o$=="T"){y 1o$(a){D 1d.a9(a)}}y 2Y(a){u b={1c:"",1e:"",3i:O,9d:O,Q:"2r",1v:F,1z:-1,2S:"",20:",",2g:".",2T:N,1i:O,1P:F,2E:F,1u:F,2I:F,2G:[],2Q:F,2p:F,X:-1};G(u c 1h b){t[c]=(P a=="T"||P a[c]=="T")?b[c]:a[c]}}2Y.C.4Y=y(b){u a=t.2Q.4Y(t.J,t,b);D a?a:t.2p};2Y.C.4U=y(b){u a=t.2Q.4U(t.J,t,b);D a?a:t.2p};2Y.C.2x=y(b){G(u a=0;a-1,9U:3p.3l.1G("9Z/")>-1,8i:3p.3l.1G("8i")>-1&&3p.3l.1G("ad")===-1,b9:!!3p.3l.2l(/ac.*ae.*af/)};t.1c=b;t.I=[];t.M=[];t.U=F;t.1m=F;t.2m=-1;t.23=N;t.7w=t.9o();t.7s=1;t.4V=-1;t.3a=0;t.3Q=F;t.3t=F;t.67=F;t.66=F;x(t.3m){t.6b=L 8r();t.6b.2Z=t.7w+"/8p/ag.8t";t.65=L 8r();t.65.2Z=t.7w+"/8p/a4.8t"}};E.C.4c=y(){};E.C.8P=y(){};E.C.9b=y(c,b,a){};E.C.52=y(a,b){};E.C.6S=y(){};E.C.7N=y(e,b,a,c,d){};E.C.90=y(b,a){};E.C.8X=y(b,a){D N};E.C.5W=y(b,a){D O};E.C.8W=y(){};E.C.8j=y(1q){u 7f=1q;u 5g=1q.1G("?")>=0?"&":"?";1q+=5g+1k.8E(1k.8G()*8F);1r(t){x(2v.7e){1m=L 7e("8h.8l");1m.7B=y(){x(1m.7p==4){4b();4c()}};1m.2F(1q)}K{x(2v.4R){1m=L 4R();1m.7B=y(){x(t.7p==4){1m=t.a6;x(!1m){D N}4b();4c()}};1m.4k("7K",1q,O);1m.7G("")}K{x(1d.7z&&1d.7z.8v){1m=1d.7z.8v("","",F);1m.ah=y(){4b();4c()};1m.2F(1q)}K{19("8U 2F a ai 1q 1r t 7L!");D N}}}D O}};E.C.ar=y(a){x(2v.8n){u b=L 8n();t.1m=b.aq(a,"at/au")}K{t.1m=L 7e("8h.8l");t.1m.an="N";t.1m.8j(a)}t.4b()};E.C.4b=y(){1r(t){t.M=[];t.U=F;t.14=F;u 2U=1m.2k("2U");x(2U&&2U.H>=1){t.I=[];u 7l=2U[0].2k("R");G(u i=0;i<7l.H;i++){u 2c=7l[i];u Q=2c.1l("Q");u 2p=F;u 1Y=2c.2k("1X");x(1Y.H>0){2p={};u 4a=1Y[0].2k("9Y");x(4a.H>0){G(u g=0;g<4a.H;g++){u 7g={};1Y=4a[g].2k("S");G(u v=0;v<1Y.H;v++){7g[1Y[v].1l("S")]=1Y[v].1s?1Y[v].1s.5R:""}2p[4a[g].1l("1e")]=7g}}K{1Y=1Y[0].2k("S");G(u v=0;v<1Y.H;v++){2p[1Y[v].1l("S")]=1Y[v].1s?1Y[v].1s.5R:""}}}I.17(L 2Y({1c:2c.1l("1c"),1e:(P 2c.1l("1e")=="2r"?2c.1l("1e"):2c.1l("1c")),Q:(2c.1l("Q")?2c.1l("Q"):"2r"),3i:2c.1l("3i")=="O",1i:(2c.1l("1i")?2c.1l("1i")=="O":O),2p:2p}))}5e()}u V=1m.2k("1M");G(u i=0;i=I.H){19("ap 6J bc ba I G 1M "+(i+1))}K{5H=I[j].1c}}2X[5H]=21[j].1s?21[j].1s.5R:""}u 2j={2s:O,2b:i,1b:V[i].1l("1b")?V[i].1l("1b"):""};G(u 5J=0;5J=0?"&":"?";1q+=5g+1k.8E(1k.8G()*8F);x(!2v.4R){19("8U 2F a 3f 1q 1r t 7L!");D N}1r(t){u 4B=L 4R();4B.7B=y(){x(t.7p==4){x(!t.7J){D N}x(!4C(t.7J)){19("1D 3f M bv bp 1q \'"+7f+"\'");D N}4c()}};4B.4k("7K",1q,O);4B.7G("")}D O};E.C.bo=y(a){D t.4C(a)};E.C.2F=y(a){D t.4C(a)};E.C.4C=y(2n){x(P 2n=="2r"){2n=b0("("+2n+")")}x(!2n){D N}t.M=[];t.U=F;t.14=F;x(2n.2U){t.I=[];G(u c=0;c<2n.2U.H;c++){u 2i=2n.2U[c];t.I.17(L 2Y({1c:2i.1c,1e:(2i.1e?2i.1e:2i.1c),Q:(2i.Q?2i.Q:"2r"),3i:(2i.3i?O:N),1i:(P 2i.1i=="T"?O:(2i.1i?O:N)),2p:2i.1X?2i.1X:F}))}t.5e()}x(2n.M){G(u i=0;i<2n.M.H;i++){u 1M=2n.M[i];x(!1M.1X){3W}x(aG.C.4i.6U(1M.1X)!=="[2A 5T]"){2X=1M.1X}K{G(u j=0;j<1M.1X.H&&j0){t.1H.1J(t.1Q.V[0])}t.7s=t.1H.V.H;u k=t.1H.V;G(u f=0;f1?b:1}}u k=t.1Q.V;G(u f=0;f=0};E.C.2H=y(b){u a=t.1E(b);x(a<0){19("[2H] 2Y 7q aQ 1r 2L 6T 1c "+b);D F}D t.I[a]};E.C.94=y(a){D t.2H(a).1c};E.C.3L=y(a){D t.2H(a).1e};E.C.5x=y(a){D t.2H(a).Q};E.C.aS=y(a){D t.2H(a).1v};E.C.aR=y(a){D t.2H(a).1z};E.C.5L=y(b){u a=t.2H(b);D(a.1i&&a.5d())};E.C.b8=y(b){u a=t.2H(b);D a.5d()};E.C.1p=y(d,b){x(b<0||b>=t.I.H){19("[1p] 1D R 2L "+b);D F}u a=t.I[b];x(d<0){D a.1e}x(P t.M[d]=="T"){19("[1p] 1D 1M 2L "+d);D F}u c=t.M[d]["I"];D c?c[b]:F};E.C.54=y(d,a){u c=t.1p(d,a);x(c!==F){u b=d<0?t.I[a].1P:t.I[a].1u;c=b.6K(d,c)}D c};E.C.6H=y(h,d,g,c){x(P c=="T"){c=O}u a=F;x(d<0||d>=t.I.H){19("[6H] 1D R 2L "+d);D F}u b=t.I[d];x(h<0){a=b.1e;b.1e=g}K{u f=t.M[h]["I"];a=f[d];x(f){f[d]=t.3v(d,g)}}x(c){u e=h<0?b.1P:b.1u;e.2V(h,d,t.5Y(h,d),g)}D a};E.C.1E=y(a){x(P a=="T"||a===""){D-1}x(!W(a)&&a>=0&&a=t.M.H)?F:t.M[a]["1b"]};E.C.4Z=y(a){a=P a=="2A"?a.4O:a;G(u b=0;b=d){a[b].2b--}}t.M.49(f,1);x(t.U!=F){G(u b=0;b=h){b[a].2b++}}t.M.49(p+g,0,f);x(t.U!=F){x(e===F){t.U.49(p+g,0,f)}K{G(u a=0;a=t.M.H){D t.7c(t.M.H-1,d,b,a,c)}D t.7i(e,0,d,b,a,c)};E.C.7c=y(e,d,b,a,c){x(e<0){D t.91(0,d,b,a,c)}x(e>=t.M.H){e=t.M.H-1}D t.7i(e,1,d,b,a,c)};E.C.9z=y(c,d){u b=t.1E(c);x(b<0){19("[9z] 1D R: "+c)}K{u a=t.I[b];a.1P=(t.3m&&a.Q!="55")?L 4g(a.1c,d):d;x(d){x(t.3m&&a.Q!="55"){a.1P.J=t;a.1P.R=a}d.J=t;d.R=a}}};E.C.97=y(c,d){u b=t.1E(c);x(b<0){19("[97] 1D R: "+c)}K{u a=t.I[b];a.1u=d;x(d){d.J=t;d.R=a}}};E.C.9H=y(d,c){u b=t.1E(d);x(b<0){19("[9H] 1D R: "+d)}K{u a=t.I[b];a.2I=c;x(c){c.J=t;c.R=a}}};E.C.9J=y(d,c){u b=t.1E(d);x(b<0){19("[9J] 1D R: "+d)}K{u a=t.I[b];a.2E=c;x(c){c.J=t;c.R=a}}};E.C.9L=y(c,a){u b=t.1E(c);x(b<0){19("[9L] 1D R: "+c)}K{t.I[b].2Q=a}t.7b(t.I[b]);t.7a(t.I[b])};E.C.9h=y(b){u a=t.1E(b);x(a<0){19("[9h] 1D R: "+b)}K{t.I[a].2G=[]}};E.C.93=y(b){u a=t.1E(b);x(a<0){19("[93] 1D R: "+b)}D t.7u(t.I[a])};E.C.7u=y(a){x(a.Q=="2w"||a.Q=="2W"){a.2G.17(L 5u(a.Q))}K{x(a.Q=="7r"){a.2G.17(L 5v())}K{x(a.Q=="7y"||a.Q=="1q"){a.2G.17(L 4F())}K{x(a.Q=="2t"){a.2G.17(L 5Q(t))}}}}};E.C.9u=y(c,a){u b=t.1E(c);x(b<0){19("[9u] 1D R: "+c)}K{t.I[b].2G.17(a)}};E.C.ab=y(a){t.5E=a};E.C.5Y=y(c,a){u b=t.4Q(c);x(b==F){19("[5Y] 1D 1M 2L "+c);D F}D b.3X[a]};E.C.6s=y(b){u a=0;1W(b!=F&&t.5X(b)){4w{a+=b.a3;b=b.9N}48(c){b=F}}D a};E.C.8D=y(b){u a=0;1W(b!=F&&t.5X(b)){4w{a+=b.a5;b=b.9N}48(c){b=F}}D a};E.C.69=y(2e,25,46){1r(t){x(P 14!="T"&&14!=F){u 50=U==F?M:U;9P();u V=1Q.V;u 5U=0;u 6h=0;u 18=0;G(u i=0;i0&&6h>=1O)){x(V[i].1a.44!="5t"){V[i].1a.44="5t";V[i].43=O}}K{x(5U<1O*3a){5U++;x(V[i].1a.44!="5t"){V[i].1a.44="5t";V[i].43=O}}K{6h++;u 2j=[];u 21=V[i].3X;x(P V[i].43!="T"&&V[i].43){V[i].1a.44="";V[i].43=N}G(u j=0;j<21.H&&j0){4M=3a*1O;5Z=1k.76(2B(),4M+1O)}t.14=1d.1F("14");14.25=25||"J";x(P 46!="T"){14.1b=46}1W(1o$(2e).3Z()){1o$(2e).3g(1o$(2e).1s)}1o$(2e).1J(14);x(5E){u 6e=1d.1F("9W");6e.2o=t.5E;14.1J(6e)}t.1H=1d.1F("6d");14.1J(1H);u 9y=1H.5V(0);u 2y=3M();G(u c=0;c<2y;c++){u 9w=1d.1F("9M");u 4x=9y.1J(9w);I[c].1P.2V(-1,c,4x,I[c].1e)}t.1Q=1d.1F("6c");14.1J(1Q);u 9s=0;G(u i=4M;i<5Z;i++){u 4A=1Q.5V(9s++);4A.4O=M[i]["1b"];4A.1b=t.3o(M[i]["1b"]);G(j=0;j<2y;j++){u 4x=4A.9G(j);I[j].1u.2V(i,j,4x,1p(i,j))}}1o$(2e).J=t;x(79){1o$(2e).9k=y(e){t.J.4v(e)}}K{1o$(2e).5b=y(e){t.J.4v(e)}}}9b(2e,25,46)}};E.C.b7=y(d,c,b){u a=t.3r("6L")?Y(t.36("6L")):0;t.2m=t.3r("4p")&&t.98(t.36("4p"))?t.36("4p"):-1;t.23=t.3r("4p")&&t.3r("23")?t.36("23")=="O":N;t.3Q=t.3r("3Y")?t.36("3Y"):F;t.3a=0;t.69(d,c,b);t.3S();t.3Y();t.2J(a)};E.C.3O=y(){x(t.3t!=F){t.14=F}t.69(t.3t,t.67,t.66)};E.C.9P=y(){1r(t){u V=1H.V;G(u i=0;i<1;i++){u 2j=[];u 21=V[i].3X;u 3w=0;G(u j=0;j<21.H&&3w1?4e:1}}}};E.C.4v=y(e){e=e||2v.8T;1r(t){u 1n=e.1n||e.br;1W(1n){x(1n.3s=="A"||1n.3s=="bt"||1n.3s=="9M"){4j}K{1n=1n.1U}}x(!1n||!1n.1U||!1n.1U.1U||(1n.1U.1U.3s!="6c"&&1n.1U.1U.3s!="6d")||1n.3z){D}x(1n.3s=="A"){D}u 18=4Z(1n.1U);u X=1n.b1;u R=I[X];x(R){x(18>-1&&18!=4V){90(4V,18);4V=18}x(!R.3i){8W(R)}K{x(18<0){x(R.2E&&8X(18,X)){R.2E.6k(18,X,1n,R.1e)}}K{x(R.2I&&5W(18,X)){R.2I.6k(18,X,1n,1p(18,X))}}}}}};E.C.3S=y(2O,35,3R){1r(t){x(P 2O=="T"&&2m===-1){52(-1,23);D O}x(P 2O=="T"){2O=2m}x(P 35=="T"){35=23}45("4p",2O);45("23",35);u X=2O;x(Y(X,10)!==-1){X=t.1E(2O);x(X<0){19("[3S] 1D R: "+2O);D N}}x(!3m){52(X,35);D}u 78=U!=F;x(78){M=U}u 1L=X<0?"":5x(X);u 2K=[];u 1f=2B();G(u i=0;i<1f-(3C?1:0);i++){2K.17([X<0?F:54(i,X),i,M[i].2b])}2K.3S(X<0?9i:1L=="2w"||1L=="2W"?99:1L=="3j"?92:1L=="2t"?9O:95);x(35){2K=2K.aJ()}x(3C){2K.17([X<0?F:54(1f-1,X),1f-1,M[1f-1].2b])}u 50=M;M=[];G(u i=0;i<2K.H;i++){M.17(50[2K[i][1]])}7x 2K;x(78){U=M;M=[];G(u r=0;r<1f;r++){x(U[r].2s){M.17(U[r])}}}x(3R){2J(0)}K{3O()}52(X,35);D O}};E.C.3Y=y(53){1r(t){x(P 53!="T"){t.3Q=53;t.45("3Y",53)}x(3Q==F||3Q==""){x(U!=F){M=U;U=F;G(u r=0;r<2B();r++){M[r].2s=O}2J(0);6S()}D}u 6R=3Q.2N().40(" ");x(U!=F){M=U}u 1f=2B();u 2y=3M();G(u r=0;r<1f;r++){M[r].2s=O;u 6Q="";G(u c=0;c<2y;c++){6Q+=54(r,c)+" "}G(u i=0;i<6R.H;i++){x(6Q.2N().1G(6R[i])<0){M[r].2s=N;4j}}}U=M;M=[];G(u r=0;r<1f;r++){x(U[r].2s){M.17(U[r])}}2J(0);6S()}};E.C.aO=y(a){t.1O=Y(a);x(W(t.1O)){t.1O=0}t.3a=0;t.3O()};E.C.4s=y(){x(t.1O<=0){19("4s: 8A 6T 6P 7X 2f 6J ("+t.1O+")");D-1}D 1k.aN(t.2B()/t.1O)};E.C.33=y(){x(t.1O<=0){19("aP: 8A 6T 6P 7X 2f 6J ("+t.1O+")");D-1}D t.3a};E.C.2J=y(a){t.3a=a;t.45("6L",a);t.3O()};E.C.aL=y(){x(t.6V()){t.2J(t.33()-1)}};E.C.aB=y(){x(t.6V()){t.2J(0)}};E.C.aC=y(){x(t.73()){t.2J(t.33()+1)}};E.C.az=y(){x(t.73()){t.2J(t.4s()-1)}};E.C.6V=y(){D t.33()>0};E.C.73=y(){D t.33()0&&1f>26){1f=26}u 2z=0;G(u c=0;c<2y;c++){x(!5L(c)){3W}u 1i=L 6G(8I?"b4":"1i");1i.2M=2M;1i.2D=3x[Z.b2.H%3x.H];1i.6F="8Q";1i.1y=3L(c);G(u r=0;r<1f;r++){x(5m(r,"8z")=="1"){3W}u S=1p(r,c);x(S>2z){2z=S}1i.1X.17(S)}Z.6u(1i)}u 1A=10;1W(1A<2z){1A*=10}u 3V=1A/10;1W(1A-3V>2z){1A-=3V}u 3T=[];G(u r=0;r<1f;r++){x(5m(r,"8z")=="1"){3W}u 1e=5m(r,"aw");3T.17(1e?1e:1p(r,3D))}Z.8O={5n:1,8y:10,2D:"#3U","41-2D":"#3U",5P:{8x:5S,5P:3T},"3d":5};Z.8k={5n:4,8g:3,2D:"#8c","41-2D":"#3U",8d:0,8e:1A/10,1T:1A};Z.8m={1y:5l||3L(1B),1a:"{1Z-2f: 5s; 3h: #5z}"};Z.8u={1y:"",1a:"{1Z-2f: 5s; 3h: #5z}"};5j(2h,Z)}};E.C.bf=y(2h,2C,1B,24){1r(t){x(4m&&!5B()){D N}t.5l=F;t.3K="#6E";t.2M=0.8;t.26=0;t.5S=0;x(24){G(u p 1h 24){t[p]=24[p]}}1B=1B||0;u 3D=1E(1B);u Z=L 4l();Z.6C=3K;Z.6z({1y:2C||"",1a:"{1Z-2f: 6A; 3h:#6y; 1Z-5F: 6w; 1y-5w: 6x;}"});u 2y=3M();u 1f=2B()-(3C?1:0);x(26>0&&1f>26){1f=26}u 2z=0;u 1i=L 6G("bd");1i.2M=2M;1i.8o=3x;1i.6F="8Q";1i.6j=[];G(u c=0;c<2y;c++){x(!5L(c)){3W}1i.6j.17({2D:3x[1i.6j.H%3x.H],1y:3L(c),"1Z-2f":"13"})}G(u r=0;r<1f;r++){u 6l=[];u 5O=0;G(u c=0;c<2y;c++){x(!5L(c)){3W}u S=1p(r,c);S=W(S)?0:S;5O+=S;6l.17(S)}x(5O>2z){2z=5O}1i.1X.17(6l)}Z.6u(1i);u 1A=10;1W(1A<2z){1A*=10}u 3V=1A/10;1W(1A-3V>2z){1A-=3V}u 3T=[];G(u r=0;r<1f;r++){3T.17(1p(r,3D))}Z.8O={5n:1,8y:10,2D:"#3U","41-2D":"#3U",5P:{8x:5S,5P:3T},"3d":5};Z.8k={5n:4,8g:3,2D:"#8c","41-2D":"#3U",8d:0,8e:1A/10,1T:1A};Z.8m={1y:5l||3L(1B),1a:"{1Z-2f: 5s; 3h: #5z}"};Z.8u={1y:"",1a:"{1Z-2f: 5s; 3h: #5z}"};5j(2h,Z)}};E.C.a7=y(2h,2C,3B,1B,24){1r(t){x(4m&&!5B()){D N}t.5A=0;t.3K="#6E";t.2M=0.5;t.26=0;t.8w=O;x(24){G(u p 1h 24){t[p]=24[p]}}u 1L=5x(3B);x(1L!="2W"&&1L!="2w"&&3B!=1B){D}1B=1B||0;2C=(P 2C=="T"||2C===F)?3L(3B):2C;u 5r=1E(3B);u 3D=1E(1B);u Z=L 4l();Z.6C=3K;Z.6z({1y:2C,1a:"{1Z-2f: 6A; 3h:#6y; 1Z-5F: 6w; 1y-5w: 6x;}"});u 1f=2B()-(3C?1:0);x(26>0&&1f>26){1f=26}u 2q=L 6G("2q");2q.8o=8s;2q.2M=2M;2q["eN-6F"]=8w;x(P 5A!="T"&&5A!==F){2q["eO-eQ"]=5A}x(3B==1B){u 3A={};G(u r=0;r<1f;r++){u 3c=1p(r,5r);x(3c 1h 3A){3A[3c]++}K{3A[3c]=1}}G(u S 1h 3A){u 6D=3A[S];2q.1X.17({S:6D,1e:S+" ("+(3u*(6D/1f)).8f(1)+"%)"})}}K{u 6v=0;G(u r=0;r<1f;r++){u 3c=1p(r,5r);6v+=W(3c)?0:3c}G(u r=0;r<1f;r++){u S=1p(r,5r);u 1e=1p(r,3D);x(!W(S)){2q.1X.17({S:S,1e:1e+" ("+(3u*(S/6v)).8f(1)+"%)"})}}}Z.6u(2q);x(2q.1X.H>0){5j(2h,Z)}D 2q.1X.H}};E.C.5j=y(2h,Z){x(P t.3E=="T"||!t.3E){t.3E="4k-6n-Z.3J";u e=1d.2k("9l");G(u i=0;i0){d.51("dZ",t.4o)}x(t.4t>0){d.51("2f",t.4t)}K{d.1a.37=t.J.7n(b)+"3k"}u a=t.J.47(b);x(t.47){d.1a.77=a+"3k"}d.S=t.6W(c);d.e1=y(e){t.2u.6X(t)};D d};1t.C.3G=y(a,b){1V.C.3G.6U(t,a,b,-1*t.J.5G(b),-1*(t.J.4L(b)+1));t.6X(b);b.7E()};y 3H(a){t.1L=a}3H.C=L 1t(-1,32);3H.C.6W=y(a){D W(a)?"":(a+"").1C(".",t.R.20)};3H.C.4u=y(a){D a.S.1C(",",".")};3H.C.72=y(a){D t.1L=="2w"?Y(a):3b(a)};y 4G(a){t.8a=75;t.82=22;t.84=O;t.7D=O;t.1K(a)}4G.C=L 1V();4G.C.4E=y(f,m){u a=1d.1F("7E");x(t.7D){a.1a.37=1k.1T(t.8a,t.J.7n(f))+"3k"}x(t.84){a.1a.77=1k.1T(t.82,t.J.47(f))+"3k"}u l=t.R.4U(f.18);u h=0,c=N;G(u k 1h l){x(P l[k]=="2A"){u b=1d.1F("e4");b.1e=k;a.1J(b);u d=l[k];G(u k 1h d){u g=1d.1F("6i");g.1y=d[k];g.S=k;b.1J(g);x(k==m){a.74=h;c=O}h++}}K{u g=1d.1F("6i");g.1y=l[k];g.S=k;4w{a.59(g,F)}48(j){a.59(g)}x(k==m){a.74=h;c=O}h++}}x(!c){u g=1d.1F("6i");g.1y=m?m:"";g.S=m?m:"";4w{a.59(g,a.24[0])}48(j){a.59(g)}a.74=0}a.et=y(e){t.2P=F;t.2u.3y(t.16,t.S)};D a};y 57(a){t.1K(a)}57.C=L 1t();57.C.3G=y(a,b){1t.C.3G.6U(t,a,b);$(b).6M({4J:t.J.4J=="7d"?"dd/7T/7S":"7T/dd/7S",eu:y(){t.6N=t.2P;t.2P=F},ex:y(c){x(c!=""){t.2u.3y(b.16,c)}K{x(t.6N!=F){t.6N()}}}}).6M("eq")};y 1R(a){t.1K(a)}1R.C.1K=y(a){G(u b 1h a){t[b]=a[b]}};1R.C.2V=y(d,b,a,c){a.18=d;a.X=b;1W(a.3Z()){a.3g(a.1s)}x(t.R.5d()){E.C.5c(a,"3n")}x(t.R.Q=="3j"){E.C.5c(a,"3j")}D t.2a(a,P c=="2r"&&t.R.Q!="55"?8L(c,"6B").1C(/\\s\\s/g,"&8b; "):c)};1R.C.2a=y(a,b){a.2o=b?b:""};1R.C.6K=y(b,a){D a};y 3F(a){t.1K(a)}3F.C=L 1R();3F.C.6O=y(f,d){u c="";x(P d!="T"){u a=t.R.4Y(f);x(d 1h a){c=a[d]}G(u e 1h a){x(P a[e]=="2A"&&d 1h a[e]){c=a[e][d]}}x(c==""){u b=P d=="3n"&&W(d);c=b?"":d}}D c};3F.C.2a=y(a,b){a.2o=t.6O(a.18,b)};3F.C.6K=y(b,a){D t.6O(b,a)};y 4W(a){t.1K(a)}4W.C=L 1R();4W.C.2a=y(c,e){u d=t.R||{};u a=P e=="3n"&&W(e);u b=a?(d.2S||""):e;x(P b=="3n"){x(d.1z!==F){b=7F(b,d.1z,d.20,d.2g)}x(d.1v!==F){x(d.2T){b=d.1v+" "+b}K{b=b+" "+d.1v}}}c.2o=b;c.1a.f9=a?"fN":""};y 4r(a){t.1K(a)}4r.C=L 1R();4r.C.2V=y(d,b,a,c){x(a.1s&&(P a.1s.1l!="y"||a.1s.1l("1L")!="9F")){1W(a.3Z()){a.3g(a.1s)}}a.18=d;a.X=b;D t.2a(a,c)};4r.C.2a=y(a,c){c=(c&&c!=0&&c!="N")?O:N;x(a.1s){a.1s.61=c;D}u d=1d.1F("9E");d.51("1L","9F");d.16=a;d.9n=t;u b=L 1V();b.J=t.J;b.R=t.R;d.5b=y(e){a.18=t.9n.J.4Z(a.1U);a.3z=O;b.3y(a,d.61?O:N)};a.1J(d);d.61=c;d.fn=(!t.R.3i||!t.J.5W(a.18,a.X));a.25="3j"};y 4X(a){t.1K(a)}4X.C=L 1R();4X.C.2a=y(a,b){a.2o=b?""+b+"":""};y 56(a){t.1K(a)}56.C=L 1R();56.C.2a=y(a,b){a.2o=b?""+b+"":""};y 5f(a){t.1K(a)}5f.C=L 1R;5f.C.2a=y(a,c){u b=t.J.4q(c);x(P b=="2A"){a.2o=b.89}K{a.2o=c}};y 4g(a,b){t.3N=a;t.1u=b}4g.C=L 1R();4g.C.2a=y(3P,S){x(!S){x(t.1u){t.1u.2a(3P,S)}}K{u 2R=1d.1F("a");3P.1J(2R);2R.3N=t.3N;2R.1a.ff="fh";2R.2o=S;2R.J=t.J;2R.6g=t;2R.5b=y(){1r(t.J){u 21=1H.V[0].3X;u 6f=-1;u 3R=N;x(2m!=t.3N){6f=2m;2m=t.3N;23=N;3R=O}K{x(!23){23=O}K{6f=2m;2m=-1;23=N;3R=O}}3S(2m,23,3R)}};x(t.J.2m==t.3N){3P.1J(1d.fv("\\fu"));3P.1J(t.J.23?t.J.65:t.J.6b)}x(t.1u){t.1u.2a(3P,S)}}};E.C.9v=y(a,d,b){u e=L 85();e.dW(e.cm()+b);u c=cl(d)+((b==F)?"":"; ck="+e.cn());1d.9m=a+"="+c};E.C.9c=y(c){u b=1d.9m.40(";");G(u d=0;d0&&(a.25==b||L 1j("(^|\\\\s)"+b+"(\\\\s|$)").7m(a.25)))};E.C.5c=y(a,b){x(!t.9a(a,b)){a.25+=(a.25?" ":"")+b}};E.C.9f=y(a,b){a.25=t.9g(a.25.1C(L 1j("(^|\\\\s+)"+b+"(\\\\s+|$)")," "))};5o.C.1w=y(){D(t.1C(/^[\\s\\8Y]+/,"").1C(/[\\s\\8Y]+$/,""))};5o.C.bK=y(a){D(t.2l("^"+a)==a)};5o.C.bJ=y(a){D(t.2l(a+"$")==a)};E.C.4q=y(m,g){g=g||t.4J;g=g||"7d";u m;u l;u c;u k;u d;u a;u n;u j;u f=N;u h=L 5T("-"," ","/",".");u b;u e=0;u o=t.9D;o=o||["bL","bM","bO","bN","bH","bG","bA","bz","by","bB","bC","bF"];x(!m||m.H<1){D 0}G(b=0;b12||n<1){D 5}j=Y(d,10);x(W(j)){D 4}x(j<70){j=bE+j;d=""+j}x(j<3u){j=7R+j;d=""+j}x(j<7R||j>bD){D 11}x((n==1||n==3||n==5||n==7||n==8||n==10||n==12)&&(a>31||a<1)){D 6}x((n==4||n==6||n==9||n==11)&&(a>30||a<1)){D 7}x(n==2){x(a<1){D 8}x(83(j)==O){x(a>29){D 9}}K{x(a>28){D 10}}}D{89:(g=="86"?o[n-1]+" "+a+" "+d:a+" "+o[n-1]+" "+d),7h:85.7v(n+"/"+a+"/"+j),bP:j+"-"+n+"-"+a}};y 83(a){x(a%3u==0){x(a%c3==0){D O}}K{x((a%4)==0){D O}}D N}4z=y(a){t.1S=F;t.2d=F;t.1g="";t.1x=F;t.3e=F;t.7v=y(d){u c=d.2l(/^(([A-4d-z][0-9A-4d-z+.-]*)(:))?((\\/\\/)([^\\/?#]*))?([^?#]*)((\\?)([^#]*))?((#)(.*))?/);t.1S=c[3]?c[2]:F;t.2d=c[5]?c[6]:F;t.1g=c[7];t.1x=c[9]?c[10]:F;t.3e=c[12]?c[13]:F;D t};t.4i=y(){u c="";x(t.1S!=F){c=c+t.1S+":"}x(t.2d!=F){c=c+"//"+t.2d}x(t.1g!=F){c=c+t.1g}x(t.1x!=F){c=c+"?"+t.1x}x(t.3e!=F){c=c+"#"+t.3e}D c};t.7H=y(e){u e=L 4z(e);u d=t;u c=L 4z;x(e.1S==F){D N}x(d.1S!=F&&d.1S.2N()==e.1S.2N()){d.1S=F}x(d.1S!=F){c.1S=d.1S;c.2d=d.2d;c.1g=b(d.1g);c.1x=d.1x}K{x(d.2d!=F){c.2d=d.2d;c.1g=b(d.1g);c.1x=d.1x}K{x(d.1g==""){c.1g=e.1g;x(d.1x!=F){c.1x=d.1x}K{c.1x=e.1x}}K{x(d.1g.1N(0,1)=="/"){c.1g=b(d.1g)}K{x(e.2d!=F&&e.1g==""){c.1g="/"+d.1g}K{c.1g=e.1g.1C(/[^\\/]+$/,"")+d.1g}c.1g=b(c.1g)}c.1x=d.1x}c.2d=e.2d}c.1S=e.1S}c.3e=d.3e;D c};y b(e){u c="";1W(e){x(e.1N(0,3)=="../"||e.1N(0,2)=="./"){e=e.1C(/^\\.+/,"").1N(1)}K{x(e.1N(0,3)=="/./"||e=="/."){e="/"+e.1N(3)}K{x(e.1N(0,4)=="/../"||e=="/.."){e="/"+e.1N(4);c=c.1C(/\\/?[^\\/]*$/,"")}K{x(e=="."||e==".."){e=""}K{u d=e.2l(/^\\/?[^\\/]*/)[0];e=e.1N(d.H);c=c+d}}}}}D c}x(a){t.7v(a)}};y 6p(j,g){u d={},f={},c=0,a="";u e={},b={};u k={},h={};e[0]="4y";e[1]="5N";b[0]="6B";b[2]="7C";b[3]="8q";k=!W(j)?e[j]:j?j.5h():"4y";h=!W(g)?b[g]:g?g.5h():"7C";x(k!=="4y"&&k!=="5N"){bS L bR("bU: "+k+" 7q bV")}d["38"]="&bY;";x(k==="5N"){d["bX"]="&8b;";d["bW"]="&cJ;";d["cK"]="&dz;";d["dy"]="&dx;";d["dA"]="&dB;";d["dD"]="&dC;";d["dw"]="&dv;";d["dp"]="&do;";d["dn"]="&dq;";d["dr"]="&du;";d["dt"]="&ds;";d["dE"]="&dF;";d["dR"]="&7q;";d["dQ"]="&dP;";d["dS"]="&dT;";d["dV"]="&dU;";d["dO"]="&dN;";d["dI"]="&dH;";d["dG"]="&dJ;";d["dK"]="&dM;";d["dL"]="&dm;";d["dl"]="&cX;";d["cW"]="&cV;";d["cY"]="&cZ;";d["d1"]="&d0;";d["cU"]="&cT;";d["cN"]="&cM;";d["cL"]="&cO;";d["cP"]="&cS;";d["cR"]="&cQ;";d["d2"]="&d3;";d["dg"]="&df;";d["de"]="&dh;";d["di"]="&dk;";d["dj"]="&dc;";d["db"]="&d6;";d["d5"]="&d4;";d["d7"]="&d8;";d["da"]="&d9;";d["eY"]="&bT;";d["7I"]="&bZ;";d["c0"]="&c6;";d["c7"]="&c5;";d["c4"]="&c1;";d["c2"]="&bQ;";d["bI"]="&c8;";d["c9"]="&cy;";d["cz"]="&cx;";d["ct"]="&cu;";d["cv"]="&cH;";d["cI"]="&cF;";d["cD"]="&cf;";d["ce"]="&cd;";d["ca"]="&cb;";d["cc"]="&ci;";d["el"]="&fy;";d["fz"]="&fx;";d["fw"]="&ft;";d["fA"]="&fB;";d["fG"]="&fH;";d["fF"]="&fE;";d["fC"]="&fD;";d["fs"]="&fr;";d["fg"]="&fe;";d["fb"]="&fc;";d["fj"]="&fp;";d["fq"]="&fo;";d["fJ"]="&fk;";d["fl"]="&fm;";d["fI"]="&fL;";d["fQ"]="&fO;";d["fP"]="&fK;";d["fM"]="&em;";d["en"]="&eo;";d["fa"]="&ek;";d["eh"]="&ei;";d["ej"]="&ep;";d["ew"]="&ev;";d["er"]="&es;";d["eg"]="&ef;";d["e3"]="&e5;";d["e2"]="&dY;";d["e0"]="&e6;";d["e7"]="&ed;";d["ec"]="&e9;";d["ey"]="&f0;";d["f1"]="&f7;";d["f8"]="&f2;";d["f4"]="&eS;";d["eR"]="&eF;";d["eH"]="&eE;";d["eD"]="&eA;";d["eB"]="&eC;";d["eI"]="&eJ;";d["eP"]="&eK;";d["eL"]="&eM;"}x(h!=="6B"){d["34"]="&9X;"}x(h==="8q"){d["39"]="'"}d["60"]="&as;";d["62"]="&ak;";G(c 1h d){a=5o.9R(c);f[a]=d[c]}D f}y 9S(b,e){u d={},c="",a="";a=b.4i();x(N===(d=t.6p("5N",e))){D N}d["\'"]=" V;";G(c 1h d){a=a.40(c).4D(d[c])}D a}y 8L(b,e){u d={},c="",a="";a=b.4i();x(N===(d=t.6p("4y",e))){D N}G(c 1h d){a=a.40(c).4D(d[c])}D a}y 7F(f,c,h,e){f=(f+"").1C(/[^0-9+\\-aM.]/g,"");u b=!7Q(+f)?0:+f,a=!7Q(+c)?0:c,k=(P e==="T")?",":e,d=(P h==="T")?".":h,j="",g=y(o,m){u l=1k.aV(10,m);D""+1k.96(o*l)/l};j=(a<0?(""+b):(a?g(b,a):""+1k.96(b))).40(".");x(j[0].H>3){j[0]=j[0].1C(/\\B(?=(?:\\d{3})+(?!\\d))/g,k)}x((j[1]||"").H0&&a.1G(".")<(a.H-2))};y 5Q(a){t.41=a}5Q.C=L 42;5Q.C.2x=y(a){D a==""||P t.41.4q(a)=="2A"};',62,983,'|||||||||||||||||||||||||||||this|var|||if|function||||prototype|return|EditableGrid|null|for|length|columns|editablegrid|else|new|data|false|true|typeof|datatype|column|value|undefined|dataUnfiltered|rows|isNaN|columnIndex|parseInt|chart|||||table||element|push|rowIndex|alert|style|id|name|document|label|rowCount|path|in|bar|RegExp|Math|getAttribute|xmlDoc|target|_|getValueAt|url|with|firstChild|TextCellEditor|cellRenderer|unit|trim|query|text|precision|ymax|labelColumnIndexOrName|replace|Invalid|getColumnIndex|createElement|indexOf|tHead|getStyle|appendChild|init|type|row|substr|pageSize|headerRenderer|tBody|CellRenderer|scheme|max|parentNode|CellEditor|while|values|enumValues|font|decimal_point|cols||sortDescending|options|className|limit||||render|originalIndex|col|authority|containerid|size|thousands_separator|divId|columndata|rowData|getElementsByTagName|match|sortedColumnName|jsonData|innerHTML|optionValues|pie|string|visible|date|celleditor|window|integer|isValid|columnCount|maxvalue|object|getRowCount|title|colour|headerEditor|load|cellValidators|getColumn|cellEditor|setPageIndex|row_array|index|alpha|toLowerCase|columnIndexOrName|onblur|enumProvider|link|nansymbol|unit_before_number|metadata|_render|double|cellValues|Column|src||||getCurrentPageIndex||descending|localget|width|||currentPageIndex|parseFloat|rowValue||fragment|JSON|removeChild|color|editable|boolean|px|userAgent|enableSort|number|_getRowDOMId|navigator|left|localisset|tagName|currentContainerid|100|getTypedValue|columnIndexInModel|smartColorsBar|applyEditing|isEditing|distinctValues|valueColumnIndexOrName|ignoreLastRow|cLabel|ofcSwf|EnumCellRenderer|displayEditor|NumberCellEditor|newValue|swf|bgColor|getColumnLabel|getColumnCount|columnName|refreshGrid|cell|currentFilter|backOnFirstPage|sort|xLabels|E2E2E2|dec_step|continue|cells|filter|hasChildNodes|split|grid|CellValidator|hidden_by_editablegrid|display|localset|tableid|autoHeight|catch|splice|enumGroups|processXML|tableLoaded|Za|colspan|href|SortHeaderRenderer|div|toString|break|open|ofc_chart|EditableGrid_check_lib|editmode|maxLength|sortColumnIndexOrName|checkDate|CheckboxCellRenderer|getPageCount|fieldSize|getEditorValue|mouseClicked|try|td|HTML_SPECIALCHARS|URI|tr|ajaxRequest|processJSON|join|getEditor|WebsiteCellValidator|SelectCellEditor|This|method|dateFormat|library|borderTop|startRowIndex|javascript|rowId|needs|getRow|XMLHttpRequest|the|attributeName|getOptionValuesForEdit|lastSelectedRowIndex|NumberCellRenderer|EmailCellRenderer|getOptionValuesForRender|getRowIndex|_data|setAttribute|tableSorted|filterString|getDisplayValueAt|html|WebsiteCellRenderer|DateCellEditor|cellValue|add|padding|onclick|addClassName|isNumerical|processColumns|DateCellRenderer|sep|toUpperCase|offsetWidth|updateChart|localStorage|legend|getRowAttribute|stroke|String|EditableGrid_pending_charts|stringify|cValue|11px|none|NumberCellValidator|EmailCellValidator|align|getColumnType|border|000033|startAngle|checkChartLib|paddingLeft|findSWF|caption|family|borderLeft|colname|node|attrIndex|offsetHeight|isColumnBar|paddingTop|HTML_ENTITIES|valueStack|labels|DateCellValidator|nodeValue|rotateXLabels|Array|skipped|insertRow|isEditable|isStatic|getCell|endRowIndex||checked||verticalAlign|_localget|sortDownImage|currentTableid|currentClassName|has_local_storage|_rendergrid|enableStore|sortUpImage|TBODY|THEAD|captionElement|clearPrevious|renderer|displayed|option|keys|edit|valueRow|swfobject|flash|keyCode|get_html_translation_table|cancelEditing|editorzoneid|getCellX|absolute|add_element|total|Verdana|center|0000ff|set_title|20px|ENT_NOQUOTES|bg_colour|occurences|ffffff|fill|ofc_element|setValueAt|previousValue|defined|getDisplayValue|pageIndex|datepicker|onblur_backup|getLabel|invalid|rowContent|words|tableFiltered|or|call|canGoBack|editorValue|updateStyle|invalidClassName|_clearEditor||EditableGrid_loadChart|formatValue|canGoForward|selectedIndex||min|height|filterActive|doubleclick|_createCellEditor|_createCellRenderer|insertAfter|EU|ActiveXObject|orig_url|groupOptionValues|sortDate|_insert|paddingBottom|Opera|columnDeclarations|test|autoWidth|paddingRight|readyState|not|email|nbHeaderRows|top|_addDefaultCellValidators|parse|baseUrl|delete|website|implementation|right|onreadystatechange|ENT_COMPAT|adaptWidth|select|number_format|send|toAbsolute|200|responseText|GET|browser|setTimeout|modelChanged|formattedValue|startPageIndex|isFinite|1900|yy|mm|insertBefore|strTemp|_createHeaderEditor|page|_createHeaderRenderer|dot|comma|endPageIndex|minHeight|LeapYear|adaptHeight|Date|US|z0|EnumProvider|formattedDate|minWidth|nbsp|428BC7|offset|steps|toFixed|tick_length|Microsoft|Gecko|loadXML|y_axis|XMLDOM|x_legend|DOMParser|colours|images|ENT_QUOTES|Image|smartColorsPie|png|y_legend|createDocument|gradientFill|rotate|tick_height|skip|no|fontSize|nodeName|getCellY|floor|100000|random|fixed|bar3d|fontFamily|saveOnBlur|htmlspecialchars|EditableGrid_get_chart_data|get|x_axis|chartRendered|transparent|allowSimultaneousEdition|attributes|event|Cannot|parseColumnType|readonlyWarning|isHeaderEditable|xA0|append|rowSelected|insert|sort_boolean|addDefaultCellValidators|getColumnName|sort_alpha|round|setCellRenderer|hasColumn|sort_numeric|hasClassName|tableRendered|getCookie|renderable|_localset|removeClassName|strip|clearCellValidators|unsort|bottom|ondblclick|script|cookie|cellrenderer|detectDir|position|getComputedStyle|currentStyle|insertRowIndex|static|addCellValidator|setCookie|headerCell|borderBottom|trHeader|setHeaderRenderer||9_|isSame|shortMonthNames|input|checkbox|insertCell|setCellEditor|remove|setHeaderEditor|borderRight|setEnumProvider|TH|offsetParent|sort_date|_renderHeaders|efe100|fromCharCode|htmlentities|instead|WebKit|039|CAPTION|quot|group|AppleWebKit|two|to|4040f6|offsetLeft|bullet_arrow_down|offsetTop|responseXML|renderPieChart|dc243c|getElementById||setCaption|Apple|KHTML|Mobile|Safari|bullet_arrow_up|onload|XML|config|gt|00f629|arguments|async|nGot|You|parseFromString|loadXMLFromString|lt|application|xml|Unable|barlabel|FFD700|getSlidingPageInterval|lastPage|removeRow|firstPage|nextPage|getRowValues|0000FF|00FFFF|Object|addRow|FF00FF|reverse|getPagesInInterval|prevPage|Ee|ceil|setPageSize|getCurrentPage|found|getColumnPrecision|getColumnUnit|IE|getRowId|pow|attachToHTMLTable|given|tBodies|setRowAttribute|eval|cellIndex|elements|loadJSON|bar_3d|takes|6f8183|renderGrid|isColumnNumerical|MobileSafari|many||too|bar_stack|and|renderStackedBarChart|item|renderBarChart|constructor|attachEvent|FF0000|00FF00|Browser|attrName|loadJSONFromString|from|111111|srcElement|The|TD|800080|obtained|f93fb1|onkeydown|Sep|Aug|Jul|Oct|Nov|2100|2000|Dec|Jun|May|205|endsWith|startsWith|Jan|Feb|Apr|Mar|dbDate|Igrave|Error|throw|Ccedil|Table|supported|161|160|amp|Egrave|201|Euml|204|400|203|Ecirc|Eacute|202|Iacute|206|213|Otilde|214|Ocirc|212|Oacute|getPropertyValue|defaultView|Ouml|_localisset|expires|escape|getDate|toUTCString|unescape|getItem|setItem|vertical|borderRightWidth|208|ETH|209|js|Iuml|Icirc|207|base|location|borderTopWidth|211|borderLeftWidth|Ograve|borderBottomWidth|Ntilde|210|iexcl|162|187|ordm|186|raquo|188|frac12|189|frac14|sup1|185|para|182|micro|183|middot|cedil|184|190|frac34|Auml|196|Atilde|197|Aring|AElig|198|195|Acirc||192|iquest|191|Agrave|193|194|Aacute|181|acute|168|sect|167|uml|169|ordf|170|copy|brvbar|166|pound|163|cent|164|curren|yen|165|171|laquo|178|plusmn|177|sup2|179|180|sup3|deg|176|shy|173|172|174|reg|macr|175|setDate|localeCompare|ntilde|maxlength|242|onkeyup|241|240|optgroup|eth|ograve|243|scrollTop|ocirc|scrollLeft|middle|244|oacute|textAlign|iuml|239|235|euml|236|ecirc|215|egrave|233|eacute|igrave|show|238|icirc|onchange|beforeShow|iacute|237|onClose|245|focus|ucirc|252|uuml|251|uacute|ugrave|openflashchart|250|253|yacute|thorn|255|yuml|gradient|start|254|angle|249|oslash|salign|Opaque|wmode|AllowScriptAccess|always|199|clearChart|otilde|246|divide|embedSWF|248|500|expressInstall|ouml|247|fontWeight|234|224|agrave|http|szlig|cursor|223|pointer|mailto|225|atilde|228|auml|disabled|acirc|aacute|226|THORN|222|Ugrave|u00a0|createTextNode|217|Oslash|times|216|218|Uacute|221|Yacute|Uuml|220|219|Ucirc|229|227|ccedil|aring|232|normal|aelig|231|230'.split('|'),0,{})) +define([], function(){ +var editablegrid = eval(function(p,a,c,k,e,d){e=function(c){return(c35?String.fromCharCode(c+29):c.toString(36))};if(!''.replace(/^/,String)){while(c--){d[e(c)]=k[c]||e(c)}k=[function(e){return d[e]}];e=function(){return'\\w+'};c=1};while(c--){if(k[c]){p=p.replace(new RegExp('\\b'+e(c)+'\\b','g'),k[c])}}return p}('x(P 1o$=="T"){y 1o$(a){D 1d.a9(a)}}y 2Y(a){u b={1c:"",1e:"",3i:O,9d:O,Q:"2r",1v:F,1z:-1,2S:"",20:",",2g:".",2T:N,1i:O,1P:F,2E:F,1u:F,2I:F,2G:[],2Q:F,2p:F,X:-1};G(u c 1h b){t[c]=(P a=="T"||P a[c]=="T")?b[c]:a[c]}}2Y.C.4Y=y(b){u a=t.2Q.4Y(t.J,t,b);D a?a:t.2p};2Y.C.4U=y(b){u a=t.2Q.4U(t.J,t,b);D a?a:t.2p};2Y.C.2x=y(b){G(u a=0;a-1,9U:3p.3l.1G("9Z/")>-1,8i:3p.3l.1G("8i")>-1&&3p.3l.1G("ad")===-1,b9:!!3p.3l.2l(/ac.*ae.*af/)};t.1c=b;t.I=[];t.M=[];t.U=F;t.1m=F;t.2m=-1;t.23=N;t.7w=t.9o();t.7s=1;t.4V=-1;t.3a=0;t.3Q=F;t.3t=F;t.67=F;t.66=F;x(t.3m){t.6b=L 8r();t.6b.2Z=t.7w+"/8p/ag.8t";t.65=L 8r();t.65.2Z=t.7w+"/8p/a4.8t"}};E.C.4c=y(){};E.C.8P=y(){};E.C.9b=y(c,b,a){};E.C.52=y(a,b){};E.C.6S=y(){};E.C.7N=y(e,b,a,c,d){};E.C.90=y(b,a){};E.C.8X=y(b,a){D N};E.C.5W=y(b,a){D O};E.C.8W=y(){};E.C.8j=y(1q){u 7f=1q;u 5g=1q.1G("?")>=0?"&":"?";1q+=5g+1k.8E(1k.8G()*8F);1r(t){x(2v.7e){1m=L 7e("8h.8l");1m.7B=y(){x(1m.7p==4){4b();4c()}};1m.2F(1q)}K{x(2v.4R){1m=L 4R();1m.7B=y(){x(t.7p==4){1m=t.a6;x(!1m){D N}4b();4c()}};1m.4k("7K",1q,O);1m.7G("")}K{x(1d.7z&&1d.7z.8v){1m=1d.7z.8v("","",F);1m.ah=y(){4b();4c()};1m.2F(1q)}K{19("8U 2F a ai 1q 1r t 7L!");D N}}}D O}};E.C.ar=y(a){x(2v.8n){u b=L 8n();t.1m=b.aq(a,"at/au")}K{t.1m=L 7e("8h.8l");t.1m.an="N";t.1m.8j(a)}t.4b()};E.C.4b=y(){1r(t){t.M=[];t.U=F;t.14=F;u 2U=1m.2k("2U");x(2U&&2U.H>=1){t.I=[];u 7l=2U[0].2k("R");G(u i=0;i<7l.H;i++){u 2c=7l[i];u Q=2c.1l("Q");u 2p=F;u 1Y=2c.2k("1X");x(1Y.H>0){2p={};u 4a=1Y[0].2k("9Y");x(4a.H>0){G(u g=0;g<4a.H;g++){u 7g={};1Y=4a[g].2k("S");G(u v=0;v<1Y.H;v++){7g[1Y[v].1l("S")]=1Y[v].1s?1Y[v].1s.5R:""}2p[4a[g].1l("1e")]=7g}}K{1Y=1Y[0].2k("S");G(u v=0;v<1Y.H;v++){2p[1Y[v].1l("S")]=1Y[v].1s?1Y[v].1s.5R:""}}}I.17(L 2Y({1c:2c.1l("1c"),1e:(P 2c.1l("1e")=="2r"?2c.1l("1e"):2c.1l("1c")),Q:(2c.1l("Q")?2c.1l("Q"):"2r"),3i:2c.1l("3i")=="O",1i:(2c.1l("1i")?2c.1l("1i")=="O":O),2p:2p}))}5e()}u V=1m.2k("1M");G(u i=0;i=I.H){19("ap 6J bc ba I G 1M "+(i+1))}K{5H=I[j].1c}}2X[5H]=21[j].1s?21[j].1s.5R:""}u 2j={2s:O,2b:i,1b:V[i].1l("1b")?V[i].1l("1b"):""};G(u 5J=0;5J=0?"&":"?";1q+=5g+1k.8E(1k.8G()*8F);x(!2v.4R){19("8U 2F a 3f 1q 1r t 7L!");D N}1r(t){u 4B=L 4R();4B.7B=y(){x(t.7p==4){x(!t.7J){D N}x(!4C(t.7J)){19("1D 3f M bv bp 1q \'"+7f+"\'");D N}4c()}};4B.4k("7K",1q,O);4B.7G("")}D O};E.C.bo=y(a){D t.4C(a)};E.C.2F=y(a){D t.4C(a)};E.C.4C=y(2n){x(P 2n=="2r"){2n=b0("("+2n+")")}x(!2n){D N}t.M=[];t.U=F;t.14=F;x(2n.2U){t.I=[];G(u c=0;c<2n.2U.H;c++){u 2i=2n.2U[c];t.I.17(L 2Y({1c:2i.1c,1e:(2i.1e?2i.1e:2i.1c),Q:(2i.Q?2i.Q:"2r"),3i:(2i.3i?O:N),1i:(P 2i.1i=="T"?O:(2i.1i?O:N)),2p:2i.1X?2i.1X:F}))}t.5e()}x(2n.M){G(u i=0;i<2n.M.H;i++){u 1M=2n.M[i];x(!1M.1X){3W}x(aG.C.4i.6U(1M.1X)!=="[2A 5T]"){2X=1M.1X}K{G(u j=0;j<1M.1X.H&&j0){t.1H.1J(t.1Q.V[0])}t.7s=t.1H.V.H;u k=t.1H.V;G(u f=0;f1?b:1}}u k=t.1Q.V;G(u f=0;f=0};E.C.2H=y(b){u a=t.1E(b);x(a<0){19("[2H] 2Y 7q aQ 1r 2L 6T 1c "+b);D F}D t.I[a]};E.C.94=y(a){D t.2H(a).1c};E.C.3L=y(a){D t.2H(a).1e};E.C.5x=y(a){D t.2H(a).Q};E.C.aS=y(a){D t.2H(a).1v};E.C.aR=y(a){D t.2H(a).1z};E.C.5L=y(b){u a=t.2H(b);D(a.1i&&a.5d())};E.C.b8=y(b){u a=t.2H(b);D a.5d()};E.C.1p=y(d,b){x(b<0||b>=t.I.H){19("[1p] 1D R 2L "+b);D F}u a=t.I[b];x(d<0){D a.1e}x(P t.M[d]=="T"){19("[1p] 1D 1M 2L "+d);D F}u c=t.M[d]["I"];D c?c[b]:F};E.C.54=y(d,a){u c=t.1p(d,a);x(c!==F){u b=d<0?t.I[a].1P:t.I[a].1u;c=b.6K(d,c)}D c};E.C.6H=y(h,d,g,c){x(P c=="T"){c=O}u a=F;x(d<0||d>=t.I.H){19("[6H] 1D R 2L "+d);D F}u b=t.I[d];x(h<0){a=b.1e;b.1e=g}K{u f=t.M[h]["I"];a=f[d];x(f){f[d]=t.3v(d,g)}}x(c){u e=h<0?b.1P:b.1u;e.2V(h,d,t.5Y(h,d),g)}D a};E.C.1E=y(a){x(P a=="T"||a===""){D-1}x(!W(a)&&a>=0&&a=t.M.H)?F:t.M[a]["1b"]};E.C.4Z=y(a){a=P a=="2A"?a.4O:a;G(u b=0;b=d){a[b].2b--}}t.M.49(f,1);x(t.U!=F){G(u b=0;b=h){b[a].2b++}}t.M.49(p+g,0,f);x(t.U!=F){x(e===F){t.U.49(p+g,0,f)}K{G(u a=0;a=t.M.H){D t.7c(t.M.H-1,d,b,a,c)}D t.7i(e,0,d,b,a,c)};E.C.7c=y(e,d,b,a,c){x(e<0){D t.91(0,d,b,a,c)}x(e>=t.M.H){e=t.M.H-1}D t.7i(e,1,d,b,a,c)};E.C.9z=y(c,d){u b=t.1E(c);x(b<0){19("[9z] 1D R: "+c)}K{u a=t.I[b];a.1P=(t.3m&&a.Q!="55")?L 4g(a.1c,d):d;x(d){x(t.3m&&a.Q!="55"){a.1P.J=t;a.1P.R=a}d.J=t;d.R=a}}};E.C.97=y(c,d){u b=t.1E(c);x(b<0){19("[97] 1D R: "+c)}K{u a=t.I[b];a.1u=d;x(d){d.J=t;d.R=a}}};E.C.9H=y(d,c){u b=t.1E(d);x(b<0){19("[9H] 1D R: "+d)}K{u a=t.I[b];a.2I=c;x(c){c.J=t;c.R=a}}};E.C.9J=y(d,c){u b=t.1E(d);x(b<0){19("[9J] 1D R: "+d)}K{u a=t.I[b];a.2E=c;x(c){c.J=t;c.R=a}}};E.C.9L=y(c,a){u b=t.1E(c);x(b<0){19("[9L] 1D R: "+c)}K{t.I[b].2Q=a}t.7b(t.I[b]);t.7a(t.I[b])};E.C.9h=y(b){u a=t.1E(b);x(a<0){19("[9h] 1D R: "+b)}K{t.I[a].2G=[]}};E.C.93=y(b){u a=t.1E(b);x(a<0){19("[93] 1D R: "+b)}D t.7u(t.I[a])};E.C.7u=y(a){x(a.Q=="2w"||a.Q=="2W"){a.2G.17(L 5u(a.Q))}K{x(a.Q=="7r"){a.2G.17(L 5v())}K{x(a.Q=="7y"||a.Q=="1q"){a.2G.17(L 4F())}K{x(a.Q=="2t"){a.2G.17(L 5Q(t))}}}}};E.C.9u=y(c,a){u b=t.1E(c);x(b<0){19("[9u] 1D R: "+c)}K{t.I[b].2G.17(a)}};E.C.ab=y(a){t.5E=a};E.C.5Y=y(c,a){u b=t.4Q(c);x(b==F){19("[5Y] 1D 1M 2L "+c);D F}D b.3X[a]};E.C.6s=y(b){u a=0;1W(b!=F&&t.5X(b)){4w{a+=b.a3;b=b.9N}48(c){b=F}}D a};E.C.8D=y(b){u a=0;1W(b!=F&&t.5X(b)){4w{a+=b.a5;b=b.9N}48(c){b=F}}D a};E.C.69=y(2e,25,46){1r(t){x(P 14!="T"&&14!=F){u 50=U==F?M:U;9P();u V=1Q.V;u 5U=0;u 6h=0;u 18=0;G(u i=0;i0&&6h>=1O)){x(V[i].1a.44!="5t"){V[i].1a.44="5t";V[i].43=O}}K{x(5U<1O*3a){5U++;x(V[i].1a.44!="5t"){V[i].1a.44="5t";V[i].43=O}}K{6h++;u 2j=[];u 21=V[i].3X;x(P V[i].43!="T"&&V[i].43){V[i].1a.44="";V[i].43=N}G(u j=0;j<21.H&&j0){4M=3a*1O;5Z=1k.76(2B(),4M+1O)}t.14=1d.1F("14");14.25=25||"J";x(P 46!="T"){14.1b=46}1W(1o$(2e).3Z()){1o$(2e).3g(1o$(2e).1s)}1o$(2e).1J(14);x(5E){u 6e=1d.1F("9W");6e.2o=t.5E;14.1J(6e)}t.1H=1d.1F("6d");14.1J(1H);u 9y=1H.5V(0);u 2y=3M();G(u c=0;c<2y;c++){u 9w=1d.1F("9M");u 4x=9y.1J(9w);I[c].1P.2V(-1,c,4x,I[c].1e)}t.1Q=1d.1F("6c");14.1J(1Q);u 9s=0;G(u i=4M;i<5Z;i++){u 4A=1Q.5V(9s++);4A.4O=M[i]["1b"];4A.1b=t.3o(M[i]["1b"]);G(j=0;j<2y;j++){u 4x=4A.9G(j);I[j].1u.2V(i,j,4x,1p(i,j))}}1o$(2e).J=t;x(79){1o$(2e).9k=y(e){t.J.4v(e)}}K{1o$(2e).5b=y(e){t.J.4v(e)}}}9b(2e,25,46)}};E.C.b7=y(d,c,b){u a=t.3r("6L")?Y(t.36("6L")):0;t.2m=t.3r("4p")&&t.98(t.36("4p"))?t.36("4p"):-1;t.23=t.3r("4p")&&t.3r("23")?t.36("23")=="O":N;t.3Q=t.3r("3Y")?t.36("3Y"):F;t.3a=0;t.69(d,c,b);t.3S();t.3Y();t.2J(a)};E.C.3O=y(){x(t.3t!=F){t.14=F}t.69(t.3t,t.67,t.66)};E.C.9P=y(){1r(t){u V=1H.V;G(u i=0;i<1;i++){u 2j=[];u 21=V[i].3X;u 3w=0;G(u j=0;j<21.H&&3w1?4e:1}}}};E.C.4v=y(e){e=e||2v.8T;1r(t){u 1n=e.1n||e.br;1W(1n){x(1n.3s=="A"||1n.3s=="bt"||1n.3s=="9M"){4j}K{1n=1n.1U}}x(!1n||!1n.1U||!1n.1U.1U||(1n.1U.1U.3s!="6c"&&1n.1U.1U.3s!="6d")||1n.3z){D}x(1n.3s=="A"){D}u 18=4Z(1n.1U);u X=1n.b1;u R=I[X];x(R){x(18>-1&&18!=4V){90(4V,18);4V=18}x(!R.3i){8W(R)}K{x(18<0){x(R.2E&&8X(18,X)){R.2E.6k(18,X,1n,R.1e)}}K{x(R.2I&&5W(18,X)){R.2I.6k(18,X,1n,1p(18,X))}}}}}};E.C.3S=y(2O,35,3R){1r(t){x(P 2O=="T"&&2m===-1){52(-1,23);D O}x(P 2O=="T"){2O=2m}x(P 35=="T"){35=23}45("4p",2O);45("23",35);u X=2O;x(Y(X,10)!==-1){X=t.1E(2O);x(X<0){19("[3S] 1D R: "+2O);D N}}x(!3m){52(X,35);D}u 78=U!=F;x(78){M=U}u 1L=X<0?"":5x(X);u 2K=[];u 1f=2B();G(u i=0;i<1f-(3C?1:0);i++){2K.17([X<0?F:54(i,X),i,M[i].2b])}2K.3S(X<0?9i:1L=="2w"||1L=="2W"?99:1L=="3j"?92:1L=="2t"?9O:95);x(35){2K=2K.aJ()}x(3C){2K.17([X<0?F:54(1f-1,X),1f-1,M[1f-1].2b])}u 50=M;M=[];G(u i=0;i<2K.H;i++){M.17(50[2K[i][1]])}7x 2K;x(78){U=M;M=[];G(u r=0;r<1f;r++){x(U[r].2s){M.17(U[r])}}}x(3R){2J(0)}K{3O()}52(X,35);D O}};E.C.3Y=y(53){1r(t){x(P 53!="T"){t.3Q=53;t.45("3Y",53)}x(3Q==F||3Q==""){x(U!=F){M=U;U=F;G(u r=0;r<2B();r++){M[r].2s=O}2J(0);6S()}D}u 6R=3Q.2N().40(" ");x(U!=F){M=U}u 1f=2B();u 2y=3M();G(u r=0;r<1f;r++){M[r].2s=O;u 6Q="";G(u c=0;c<2y;c++){6Q+=54(r,c)+" "}G(u i=0;i<6R.H;i++){x(6Q.2N().1G(6R[i])<0){M[r].2s=N;4j}}}U=M;M=[];G(u r=0;r<1f;r++){x(U[r].2s){M.17(U[r])}}2J(0);6S()}};E.C.aO=y(a){t.1O=Y(a);x(W(t.1O)){t.1O=0}t.3a=0;t.3O()};E.C.4s=y(){x(t.1O<=0){19("4s: 8A 6T 6P 7X 2f 6J ("+t.1O+")");D-1}D 1k.aN(t.2B()/t.1O)};E.C.33=y(){x(t.1O<=0){19("aP: 8A 6T 6P 7X 2f 6J ("+t.1O+")");D-1}D t.3a};E.C.2J=y(a){t.3a=a;t.45("6L",a);t.3O()};E.C.aL=y(){x(t.6V()){t.2J(t.33()-1)}};E.C.aB=y(){x(t.6V()){t.2J(0)}};E.C.aC=y(){x(t.73()){t.2J(t.33()+1)}};E.C.az=y(){x(t.73()){t.2J(t.4s()-1)}};E.C.6V=y(){D t.33()>0};E.C.73=y(){D t.33()0&&1f>26){1f=26}u 2z=0;G(u c=0;c<2y;c++){x(!5L(c)){3W}u 1i=L 6G(8I?"b4":"1i");1i.2M=2M;1i.2D=3x[Z.b2.H%3x.H];1i.6F="8Q";1i.1y=3L(c);G(u r=0;r<1f;r++){x(5m(r,"8z")=="1"){3W}u S=1p(r,c);x(S>2z){2z=S}1i.1X.17(S)}Z.6u(1i)}u 1A=10;1W(1A<2z){1A*=10}u 3V=1A/10;1W(1A-3V>2z){1A-=3V}u 3T=[];G(u r=0;r<1f;r++){x(5m(r,"8z")=="1"){3W}u 1e=5m(r,"aw");3T.17(1e?1e:1p(r,3D))}Z.8O={5n:1,8y:10,2D:"#3U","41-2D":"#3U",5P:{8x:5S,5P:3T},"3d":5};Z.8k={5n:4,8g:3,2D:"#8c","41-2D":"#3U",8d:0,8e:1A/10,1T:1A};Z.8m={1y:5l||3L(1B),1a:"{1Z-2f: 5s; 3h: #5z}"};Z.8u={1y:"",1a:"{1Z-2f: 5s; 3h: #5z}"};5j(2h,Z)}};E.C.bf=y(2h,2C,1B,24){1r(t){x(4m&&!5B()){D N}t.5l=F;t.3K="#6E";t.2M=0.8;t.26=0;t.5S=0;x(24){G(u p 1h 24){t[p]=24[p]}}1B=1B||0;u 3D=1E(1B);u Z=L 4l();Z.6C=3K;Z.6z({1y:2C||"",1a:"{1Z-2f: 6A; 3h:#6y; 1Z-5F: 6w; 1y-5w: 6x;}"});u 2y=3M();u 1f=2B()-(3C?1:0);x(26>0&&1f>26){1f=26}u 2z=0;u 1i=L 6G("bd");1i.2M=2M;1i.8o=3x;1i.6F="8Q";1i.6j=[];G(u c=0;c<2y;c++){x(!5L(c)){3W}1i.6j.17({2D:3x[1i.6j.H%3x.H],1y:3L(c),"1Z-2f":"13"})}G(u r=0;r<1f;r++){u 6l=[];u 5O=0;G(u c=0;c<2y;c++){x(!5L(c)){3W}u S=1p(r,c);S=W(S)?0:S;5O+=S;6l.17(S)}x(5O>2z){2z=5O}1i.1X.17(6l)}Z.6u(1i);u 1A=10;1W(1A<2z){1A*=10}u 3V=1A/10;1W(1A-3V>2z){1A-=3V}u 3T=[];G(u r=0;r<1f;r++){3T.17(1p(r,3D))}Z.8O={5n:1,8y:10,2D:"#3U","41-2D":"#3U",5P:{8x:5S,5P:3T},"3d":5};Z.8k={5n:4,8g:3,2D:"#8c","41-2D":"#3U",8d:0,8e:1A/10,1T:1A};Z.8m={1y:5l||3L(1B),1a:"{1Z-2f: 5s; 3h: #5z}"};Z.8u={1y:"",1a:"{1Z-2f: 5s; 3h: #5z}"};5j(2h,Z)}};E.C.a7=y(2h,2C,3B,1B,24){1r(t){x(4m&&!5B()){D N}t.5A=0;t.3K="#6E";t.2M=0.5;t.26=0;t.8w=O;x(24){G(u p 1h 24){t[p]=24[p]}}u 1L=5x(3B);x(1L!="2W"&&1L!="2w"&&3B!=1B){D}1B=1B||0;2C=(P 2C=="T"||2C===F)?3L(3B):2C;u 5r=1E(3B);u 3D=1E(1B);u Z=L 4l();Z.6C=3K;Z.6z({1y:2C,1a:"{1Z-2f: 6A; 3h:#6y; 1Z-5F: 6w; 1y-5w: 6x;}"});u 1f=2B()-(3C?1:0);x(26>0&&1f>26){1f=26}u 2q=L 6G("2q");2q.8o=8s;2q.2M=2M;2q["eN-6F"]=8w;x(P 5A!="T"&&5A!==F){2q["eO-eQ"]=5A}x(3B==1B){u 3A={};G(u r=0;r<1f;r++){u 3c=1p(r,5r);x(3c 1h 3A){3A[3c]++}K{3A[3c]=1}}G(u S 1h 3A){u 6D=3A[S];2q.1X.17({S:6D,1e:S+" ("+(3u*(6D/1f)).8f(1)+"%)"})}}K{u 6v=0;G(u r=0;r<1f;r++){u 3c=1p(r,5r);6v+=W(3c)?0:3c}G(u r=0;r<1f;r++){u S=1p(r,5r);u 1e=1p(r,3D);x(!W(S)){2q.1X.17({S:S,1e:1e+" ("+(3u*(S/6v)).8f(1)+"%)"})}}}Z.6u(2q);x(2q.1X.H>0){5j(2h,Z)}D 2q.1X.H}};E.C.5j=y(2h,Z){x(P t.3E=="T"||!t.3E){t.3E="4k-6n-Z.3J";u e=1d.2k("9l");G(u i=0;i0){d.51("dZ",t.4o)}x(t.4t>0){d.51("2f",t.4t)}K{d.1a.37=t.J.7n(b)+"3k"}u a=t.J.47(b);x(t.47){d.1a.77=a+"3k"}d.S=t.6W(c);d.e1=y(e){t.2u.6X(t)};D d};1t.C.3G=y(a,b){1V.C.3G.6U(t,a,b,-1*t.J.5G(b),-1*(t.J.4L(b)+1));t.6X(b);b.7E()};y 3H(a){t.1L=a}3H.C=L 1t(-1,32);3H.C.6W=y(a){D W(a)?"":(a+"").1C(".",t.R.20)};3H.C.4u=y(a){D a.S.1C(",",".")};3H.C.72=y(a){D t.1L=="2w"?Y(a):3b(a)};y 4G(a){t.8a=75;t.82=22;t.84=O;t.7D=O;t.1K(a)}4G.C=L 1V();4G.C.4E=y(f,m){u a=1d.1F("7E");x(t.7D){a.1a.37=1k.1T(t.8a,t.J.7n(f))+"3k"}x(t.84){a.1a.77=1k.1T(t.82,t.J.47(f))+"3k"}u l=t.R.4U(f.18);u h=0,c=N;G(u k 1h l){x(P l[k]=="2A"){u b=1d.1F("e4");b.1e=k;a.1J(b);u d=l[k];G(u k 1h d){u g=1d.1F("6i");g.1y=d[k];g.S=k;b.1J(g);x(k==m){a.74=h;c=O}h++}}K{u g=1d.1F("6i");g.1y=l[k];g.S=k;4w{a.59(g,F)}48(j){a.59(g)}x(k==m){a.74=h;c=O}h++}}x(!c){u g=1d.1F("6i");g.1y=m?m:"";g.S=m?m:"";4w{a.59(g,a.24[0])}48(j){a.59(g)}a.74=0}a.et=y(e){t.2P=F;t.2u.3y(t.16,t.S)};D a};y 57(a){t.1K(a)}57.C=L 1t();57.C.3G=y(a,b){1t.C.3G.6U(t,a,b);$(b).6M({4J:t.J.4J=="7d"?"dd/7T/7S":"7T/dd/7S",eu:y(){t.6N=t.2P;t.2P=F},ex:y(c){x(c!=""){t.2u.3y(b.16,c)}K{x(t.6N!=F){t.6N()}}}}).6M("eq")};y 1R(a){t.1K(a)}1R.C.1K=y(a){G(u b 1h a){t[b]=a[b]}};1R.C.2V=y(d,b,a,c){a.18=d;a.X=b;1W(a.3Z()){a.3g(a.1s)}x(t.R.5d()){E.C.5c(a,"3n")}x(t.R.Q=="3j"){E.C.5c(a,"3j")}D t.2a(a,P c=="2r"&&t.R.Q!="55"?8L(c,"6B").1C(/\\s\\s/g,"&8b; "):c)};1R.C.2a=y(a,b){a.2o=b?b:""};1R.C.6K=y(b,a){D a};y 3F(a){t.1K(a)}3F.C=L 1R();3F.C.6O=y(f,d){u c="";x(P d!="T"){u a=t.R.4Y(f);x(d 1h a){c=a[d]}G(u e 1h a){x(P a[e]=="2A"&&d 1h a[e]){c=a[e][d]}}x(c==""){u b=P d=="3n"&&W(d);c=b?"":d}}D c};3F.C.2a=y(a,b){a.2o=t.6O(a.18,b)};3F.C.6K=y(b,a){D t.6O(b,a)};y 4W(a){t.1K(a)}4W.C=L 1R();4W.C.2a=y(c,e){u d=t.R||{};u a=P e=="3n"&&W(e);u b=a?(d.2S||""):e;x(P b=="3n"){x(d.1z!==F){b=7F(b,d.1z,d.20,d.2g)}x(d.1v!==F){x(d.2T){b=d.1v+" "+b}K{b=b+" "+d.1v}}}c.2o=b;c.1a.f9=a?"fN":""};y 4r(a){t.1K(a)}4r.C=L 1R();4r.C.2V=y(d,b,a,c){x(a.1s&&(P a.1s.1l!="y"||a.1s.1l("1L")!="9F")){1W(a.3Z()){a.3g(a.1s)}}a.18=d;a.X=b;D t.2a(a,c)};4r.C.2a=y(a,c){c=(c&&c!=0&&c!="N")?O:N;x(a.1s){a.1s.61=c;D}u d=1d.1F("9E");d.51("1L","9F");d.16=a;d.9n=t;u b=L 1V();b.J=t.J;b.R=t.R;d.5b=y(e){a.18=t.9n.J.4Z(a.1U);a.3z=O;b.3y(a,d.61?O:N)};a.1J(d);d.61=c;d.fn=(!t.R.3i||!t.J.5W(a.18,a.X));a.25="3j"};y 4X(a){t.1K(a)}4X.C=L 1R();4X.C.2a=y(a,b){a.2o=b?""+b+"":""};y 56(a){t.1K(a)}56.C=L 1R();56.C.2a=y(a,b){a.2o=b?""+b+"":""};y 5f(a){t.1K(a)}5f.C=L 1R;5f.C.2a=y(a,c){u b=t.J.4q(c);x(P b=="2A"){a.2o=b.89}K{a.2o=c}};y 4g(a,b){t.3N=a;t.1u=b}4g.C=L 1R();4g.C.2a=y(3P,S){x(!S){x(t.1u){t.1u.2a(3P,S)}}K{u 2R=1d.1F("a");3P.1J(2R);2R.3N=t.3N;2R.1a.ff="fh";2R.2o=S;2R.J=t.J;2R.6g=t;2R.5b=y(){1r(t.J){u 21=1H.V[0].3X;u 6f=-1;u 3R=N;x(2m!=t.3N){6f=2m;2m=t.3N;23=N;3R=O}K{x(!23){23=O}K{6f=2m;2m=-1;23=N;3R=O}}3S(2m,23,3R)}};x(t.J.2m==t.3N){3P.1J(1d.fv("\\fu"));3P.1J(t.J.23?t.J.65:t.J.6b)}x(t.1u){t.1u.2a(3P,S)}}};E.C.9v=y(a,d,b){u e=L 85();e.dW(e.cm()+b);u c=cl(d)+((b==F)?"":"; ck="+e.cn());1d.9m=a+"="+c};E.C.9c=y(c){u b=1d.9m.40(";");G(u d=0;d0&&(a.25==b||L 1j("(^|\\\\s)"+b+"(\\\\s|$)").7m(a.25)))};E.C.5c=y(a,b){x(!t.9a(a,b)){a.25+=(a.25?" ":"")+b}};E.C.9f=y(a,b){a.25=t.9g(a.25.1C(L 1j("(^|\\\\s+)"+b+"(\\\\s+|$)")," "))};5o.C.1w=y(){D(t.1C(/^[\\s\\8Y]+/,"").1C(/[\\s\\8Y]+$/,""))};5o.C.bK=y(a){D(t.2l("^"+a)==a)};5o.C.bJ=y(a){D(t.2l(a+"$")==a)};E.C.4q=y(m,g){g=g||t.4J;g=g||"7d";u m;u l;u c;u k;u d;u a;u n;u j;u f=N;u h=L 5T("-"," ","/",".");u b;u e=0;u o=t.9D;o=o||["bL","bM","bO","bN","bH","bG","bA","bz","by","bB","bC","bF"];x(!m||m.H<1){D 0}G(b=0;b12||n<1){D 5}j=Y(d,10);x(W(j)){D 4}x(j<70){j=bE+j;d=""+j}x(j<3u){j=7R+j;d=""+j}x(j<7R||j>bD){D 11}x((n==1||n==3||n==5||n==7||n==8||n==10||n==12)&&(a>31||a<1)){D 6}x((n==4||n==6||n==9||n==11)&&(a>30||a<1)){D 7}x(n==2){x(a<1){D 8}x(83(j)==O){x(a>29){D 9}}K{x(a>28){D 10}}}D{89:(g=="86"?o[n-1]+" "+a+" "+d:a+" "+o[n-1]+" "+d),7h:85.7v(n+"/"+a+"/"+j),bP:j+"-"+n+"-"+a}};y 83(a){x(a%3u==0){x(a%c3==0){D O}}K{x((a%4)==0){D O}}D N}4z=y(a){t.1S=F;t.2d=F;t.1g="";t.1x=F;t.3e=F;t.7v=y(d){u c=d.2l(/^(([A-4d-z][0-9A-4d-z+.-]*)(:))?((\\/\\/)([^\\/?#]*))?([^?#]*)((\\?)([^#]*))?((#)(.*))?/);t.1S=c[3]?c[2]:F;t.2d=c[5]?c[6]:F;t.1g=c[7];t.1x=c[9]?c[10]:F;t.3e=c[12]?c[13]:F;D t};t.4i=y(){u c="";x(t.1S!=F){c=c+t.1S+":"}x(t.2d!=F){c=c+"//"+t.2d}x(t.1g!=F){c=c+t.1g}x(t.1x!=F){c=c+"?"+t.1x}x(t.3e!=F){c=c+"#"+t.3e}D c};t.7H=y(e){u e=L 4z(e);u d=t;u c=L 4z;x(e.1S==F){D N}x(d.1S!=F&&d.1S.2N()==e.1S.2N()){d.1S=F}x(d.1S!=F){c.1S=d.1S;c.2d=d.2d;c.1g=b(d.1g);c.1x=d.1x}K{x(d.2d!=F){c.2d=d.2d;c.1g=b(d.1g);c.1x=d.1x}K{x(d.1g==""){c.1g=e.1g;x(d.1x!=F){c.1x=d.1x}K{c.1x=e.1x}}K{x(d.1g.1N(0,1)=="/"){c.1g=b(d.1g)}K{x(e.2d!=F&&e.1g==""){c.1g="/"+d.1g}K{c.1g=e.1g.1C(/[^\\/]+$/,"")+d.1g}c.1g=b(c.1g)}c.1x=d.1x}c.2d=e.2d}c.1S=e.1S}c.3e=d.3e;D c};y b(e){u c="";1W(e){x(e.1N(0,3)=="../"||e.1N(0,2)=="./"){e=e.1C(/^\\.+/,"").1N(1)}K{x(e.1N(0,3)=="/./"||e=="/."){e="/"+e.1N(3)}K{x(e.1N(0,4)=="/../"||e=="/.."){e="/"+e.1N(4);c=c.1C(/\\/?[^\\/]*$/,"")}K{x(e=="."||e==".."){e=""}K{u d=e.2l(/^\\/?[^\\/]*/)[0];e=e.1N(d.H);c=c+d}}}}}D c}x(a){t.7v(a)}};y 6p(j,g){u d={},f={},c=0,a="";u e={},b={};u k={},h={};e[0]="4y";e[1]="5N";b[0]="6B";b[2]="7C";b[3]="8q";k=!W(j)?e[j]:j?j.5h():"4y";h=!W(g)?b[g]:g?g.5h():"7C";x(k!=="4y"&&k!=="5N"){bS L bR("bU: "+k+" 7q bV")}d["38"]="&bY;";x(k==="5N"){d["bX"]="&8b;";d["bW"]="&cJ;";d["cK"]="&dz;";d["dy"]="&dx;";d["dA"]="&dB;";d["dD"]="&dC;";d["dw"]="&dv;";d["dp"]="&do;";d["dn"]="&dq;";d["dr"]="&du;";d["dt"]="&ds;";d["dE"]="&dF;";d["dR"]="&7q;";d["dQ"]="&dP;";d["dS"]="&dT;";d["dV"]="&dU;";d["dO"]="&dN;";d["dI"]="&dH;";d["dG"]="&dJ;";d["dK"]="&dM;";d["dL"]="&dm;";d["dl"]="&cX;";d["cW"]="&cV;";d["cY"]="&cZ;";d["d1"]="&d0;";d["cU"]="&cT;";d["cN"]="&cM;";d["cL"]="&cO;";d["cP"]="&cS;";d["cR"]="&cQ;";d["d2"]="&d3;";d["dg"]="&df;";d["de"]="&dh;";d["di"]="&dk;";d["dj"]="&dc;";d["db"]="&d6;";d["d5"]="&d4;";d["d7"]="&d8;";d["da"]="&d9;";d["eY"]="&bT;";d["7I"]="&bZ;";d["c0"]="&c6;";d["c7"]="&c5;";d["c4"]="&c1;";d["c2"]="&bQ;";d["bI"]="&c8;";d["c9"]="&cy;";d["cz"]="&cx;";d["ct"]="&cu;";d["cv"]="&cH;";d["cI"]="&cF;";d["cD"]="&cf;";d["ce"]="&cd;";d["ca"]="&cb;";d["cc"]="&ci;";d["el"]="&fy;";d["fz"]="&fx;";d["fw"]="&ft;";d["fA"]="&fB;";d["fG"]="&fH;";d["fF"]="&fE;";d["fC"]="&fD;";d["fs"]="&fr;";d["fg"]="&fe;";d["fb"]="&fc;";d["fj"]="&fp;";d["fq"]="&fo;";d["fJ"]="&fk;";d["fl"]="&fm;";d["fI"]="&fL;";d["fQ"]="&fO;";d["fP"]="&fK;";d["fM"]="&em;";d["en"]="&eo;";d["fa"]="&ek;";d["eh"]="&ei;";d["ej"]="&ep;";d["ew"]="&ev;";d["er"]="&es;";d["eg"]="&ef;";d["e3"]="&e5;";d["e2"]="&dY;";d["e0"]="&e6;";d["e7"]="&ed;";d["ec"]="&e9;";d["ey"]="&f0;";d["f1"]="&f7;";d["f8"]="&f2;";d["f4"]="&eS;";d["eR"]="&eF;";d["eH"]="&eE;";d["eD"]="&eA;";d["eB"]="&eC;";d["eI"]="&eJ;";d["eP"]="&eK;";d["eL"]="&eM;"}x(h!=="6B"){d["34"]="&9X;"}x(h==="8q"){d["39"]="'"}d["60"]="&as;";d["62"]="&ak;";G(c 1h d){a=5o.9R(c);f[a]=d[c]}D f}y 9S(b,e){u d={},c="",a="";a=b.4i();x(N===(d=t.6p("5N",e))){D N}d["\'"]=" V;";G(c 1h d){a=a.40(c).4D(d[c])}D a}y 8L(b,e){u d={},c="",a="";a=b.4i();x(N===(d=t.6p("4y",e))){D N}G(c 1h d){a=a.40(c).4D(d[c])}D a}y 7F(f,c,h,e){f=(f+"").1C(/[^0-9+\\-aM.]/g,"");u b=!7Q(+f)?0:+f,a=!7Q(+c)?0:c,k=(P e==="T")?",":e,d=(P h==="T")?".":h,j="",g=y(o,m){u l=1k.aV(10,m);D""+1k.96(o*l)/l};j=(a<0?(""+b):(a?g(b,a):""+1k.96(b))).40(".");x(j[0].H>3){j[0]=j[0].1C(/\\B(?=(?:\\d{3})+(?!\\d))/g,k)}x((j[1]||"").H0&&a.1G(".")<(a.H-2))};y 5Q(a){t.41=a}5Q.C=L 42;5Q.C.2x=y(a){D a==""||P t.41.4q(a)=="2A"};',62,983,'|||||||||||||||||||||||||||||this|var|||if|function||||prototype|return|EditableGrid|null|for|length|columns|editablegrid|else|new|data|false|true|typeof|datatype|column|value|undefined|dataUnfiltered|rows|isNaN|columnIndex|parseInt|chart|||||table||element|push|rowIndex|alert|style|id|name|document|label|rowCount|path|in|bar|RegExp|Math|getAttribute|xmlDoc|target|_|getValueAt|url|with|firstChild|TextCellEditor|cellRenderer|unit|trim|query|text|precision|ymax|labelColumnIndexOrName|replace|Invalid|getColumnIndex|createElement|indexOf|tHead|getStyle|appendChild|init|type|row|substr|pageSize|headerRenderer|tBody|CellRenderer|scheme|max|parentNode|CellEditor|while|values|enumValues|font|decimal_point|cols||sortDescending|options|className|limit||||render|originalIndex|col|authority|containerid|size|thousands_separator|divId|columndata|rowData|getElementsByTagName|match|sortedColumnName|jsonData|innerHTML|optionValues|pie|string|visible|date|celleditor|window|integer|isValid|columnCount|maxvalue|object|getRowCount|title|colour|headerEditor|load|cellValidators|getColumn|cellEditor|setPageIndex|row_array|index|alpha|toLowerCase|columnIndexOrName|onblur|enumProvider|link|nansymbol|unit_before_number|metadata|_render|double|cellValues|Column|src||||getCurrentPageIndex||descending|localget|width|||currentPageIndex|parseFloat|rowValue||fragment|JSON|removeChild|color|editable|boolean|px|userAgent|enableSort|number|_getRowDOMId|navigator|left|localisset|tagName|currentContainerid|100|getTypedValue|columnIndexInModel|smartColorsBar|applyEditing|isEditing|distinctValues|valueColumnIndexOrName|ignoreLastRow|cLabel|ofcSwf|EnumCellRenderer|displayEditor|NumberCellEditor|newValue|swf|bgColor|getColumnLabel|getColumnCount|columnName|refreshGrid|cell|currentFilter|backOnFirstPage|sort|xLabels|E2E2E2|dec_step|continue|cells|filter|hasChildNodes|split|grid|CellValidator|hidden_by_editablegrid|display|localset|tableid|autoHeight|catch|splice|enumGroups|processXML|tableLoaded|Za|colspan|href|SortHeaderRenderer|div|toString|break|open|ofc_chart|EditableGrid_check_lib|editmode|maxLength|sortColumnIndexOrName|checkDate|CheckboxCellRenderer|getPageCount|fieldSize|getEditorValue|mouseClicked|try|td|HTML_SPECIALCHARS|URI|tr|ajaxRequest|processJSON|join|getEditor|WebsiteCellValidator|SelectCellEditor|This|method|dateFormat|library|borderTop|startRowIndex|javascript|rowId|needs|getRow|XMLHttpRequest|the|attributeName|getOptionValuesForEdit|lastSelectedRowIndex|NumberCellRenderer|EmailCellRenderer|getOptionValuesForRender|getRowIndex|_data|setAttribute|tableSorted|filterString|getDisplayValueAt|html|WebsiteCellRenderer|DateCellEditor|cellValue|add|padding|onclick|addClassName|isNumerical|processColumns|DateCellRenderer|sep|toUpperCase|offsetWidth|updateChart|localStorage|legend|getRowAttribute|stroke|String|EditableGrid_pending_charts|stringify|cValue|11px|none|NumberCellValidator|EmailCellValidator|align|getColumnType|border|000033|startAngle|checkChartLib|paddingLeft|findSWF|caption|family|borderLeft|colname|node|attrIndex|offsetHeight|isColumnBar|paddingTop|HTML_ENTITIES|valueStack|labels|DateCellValidator|nodeValue|rotateXLabels|Array|skipped|insertRow|isEditable|isStatic|getCell|endRowIndex||checked||verticalAlign|_localget|sortDownImage|currentTableid|currentClassName|has_local_storage|_rendergrid|enableStore|sortUpImage|TBODY|THEAD|captionElement|clearPrevious|renderer|displayed|option|keys|edit|valueRow|swfobject|flash|keyCode|get_html_translation_table|cancelEditing|editorzoneid|getCellX|absolute|add_element|total|Verdana|center|0000ff|set_title|20px|ENT_NOQUOTES|bg_colour|occurences|ffffff|fill|ofc_element|setValueAt|previousValue|defined|getDisplayValue|pageIndex|datepicker|onblur_backup|getLabel|invalid|rowContent|words|tableFiltered|or|call|canGoBack|editorValue|updateStyle|invalidClassName|_clearEditor||EditableGrid_loadChart|formatValue|canGoForward|selectedIndex||min|height|filterActive|doubleclick|_createCellEditor|_createCellRenderer|insertAfter|EU|ActiveXObject|orig_url|groupOptionValues|sortDate|_insert|paddingBottom|Opera|columnDeclarations|test|autoWidth|paddingRight|readyState|not|email|nbHeaderRows|top|_addDefaultCellValidators|parse|baseUrl|delete|website|implementation|right|onreadystatechange|ENT_COMPAT|adaptWidth|select|number_format|send|toAbsolute|200|responseText|GET|browser|setTimeout|modelChanged|formattedValue|startPageIndex|isFinite|1900|yy|mm|insertBefore|strTemp|_createHeaderEditor|page|_createHeaderRenderer|dot|comma|endPageIndex|minHeight|LeapYear|adaptHeight|Date|US|z0|EnumProvider|formattedDate|minWidth|nbsp|428BC7|offset|steps|toFixed|tick_length|Microsoft|Gecko|loadXML|y_axis|XMLDOM|x_legend|DOMParser|colours|images|ENT_QUOTES|Image|smartColorsPie|png|y_legend|createDocument|gradientFill|rotate|tick_height|skip|no|fontSize|nodeName|getCellY|floor|100000|random|fixed|bar3d|fontFamily|saveOnBlur|htmlspecialchars|EditableGrid_get_chart_data|get|x_axis|chartRendered|transparent|allowSimultaneousEdition|attributes|event|Cannot|parseColumnType|readonlyWarning|isHeaderEditable|xA0|append|rowSelected|insert|sort_boolean|addDefaultCellValidators|getColumnName|sort_alpha|round|setCellRenderer|hasColumn|sort_numeric|hasClassName|tableRendered|getCookie|renderable|_localset|removeClassName|strip|clearCellValidators|unsort|bottom|ondblclick|script|cookie|cellrenderer|detectDir|position|getComputedStyle|currentStyle|insertRowIndex|static|addCellValidator|setCookie|headerCell|borderBottom|trHeader|setHeaderRenderer||9_|isSame|shortMonthNames|input|checkbox|insertCell|setCellEditor|remove|setHeaderEditor|borderRight|setEnumProvider|TH|offsetParent|sort_date|_renderHeaders|efe100|fromCharCode|htmlentities|instead|WebKit|039|CAPTION|quot|group|AppleWebKit|two|to|4040f6|offsetLeft|bullet_arrow_down|offsetTop|responseXML|renderPieChart|dc243c|getElementById||setCaption|Apple|KHTML|Mobile|Safari|bullet_arrow_up|onload|XML|config|gt|00f629|arguments|async|nGot|You|parseFromString|loadXMLFromString|lt|application|xml|Unable|barlabel|FFD700|getSlidingPageInterval|lastPage|removeRow|firstPage|nextPage|getRowValues|0000FF|00FFFF|Object|addRow|FF00FF|reverse|getPagesInInterval|prevPage|Ee|ceil|setPageSize|getCurrentPage|found|getColumnPrecision|getColumnUnit|IE|getRowId|pow|attachToHTMLTable|given|tBodies|setRowAttribute|eval|cellIndex|elements|loadJSON|bar_3d|takes|6f8183|renderGrid|isColumnNumerical|MobileSafari|many||too|bar_stack|and|renderStackedBarChart|item|renderBarChart|constructor|attachEvent|FF0000|00FF00|Browser|attrName|loadJSONFromString|from|111111|srcElement|The|TD|800080|obtained|f93fb1|onkeydown|Sep|Aug|Jul|Oct|Nov|2100|2000|Dec|Jun|May|205|endsWith|startsWith|Jan|Feb|Apr|Mar|dbDate|Igrave|Error|throw|Ccedil|Table|supported|161|160|amp|Egrave|201|Euml|204|400|203|Ecirc|Eacute|202|Iacute|206|213|Otilde|214|Ocirc|212|Oacute|getPropertyValue|defaultView|Ouml|_localisset|expires|escape|getDate|toUTCString|unescape|getItem|setItem|vertical|borderRightWidth|208|ETH|209|js|Iuml|Icirc|207|base|location|borderTopWidth|211|borderLeftWidth|Ograve|borderBottomWidth|Ntilde|210|iexcl|162|187|ordm|186|raquo|188|frac12|189|frac14|sup1|185|para|182|micro|183|middot|cedil|184|190|frac34|Auml|196|Atilde|197|Aring|AElig|198|195|Acirc||192|iquest|191|Agrave|193|194|Aacute|181|acute|168|sect|167|uml|169|ordf|170|copy|brvbar|166|pound|163|cent|164|curren|yen|165|171|laquo|178|plusmn|177|sup2|179|180|sup3|deg|176|shy|173|172|174|reg|macr|175|setDate|localeCompare|ntilde|maxlength|242|onkeyup|241|240|optgroup|eth|ograve|243|scrollTop|ocirc|scrollLeft|middle|244|oacute|textAlign|iuml|239|235|euml|236|ecirc|215|egrave|233|eacute|igrave|show|238|icirc|onchange|beforeShow|iacute|237|onClose|245|focus|ucirc|252|uuml|251|uacute|ugrave|openflashchart|250|253|yacute|thorn|255|yuml|gradient|start|254|angle|249|oslash|salign|Opaque|wmode|AllowScriptAccess|always|199|clearChart|otilde|246|divide|embedSWF|248|500|expressInstall|ouml|247|fontWeight|234|224|agrave|http|szlig|cursor|223|pointer|mailto|225|atilde|228|auml|disabled|acirc|aacute|226|THORN|222|Ugrave|u00a0|createTextNode|217|Oslash|times|216|218|Uacute|221|Yacute|Uuml|220|219|Ucirc|229|227|ccedil|aring|232|normal|aelig|231|230'.split('|'),0,{})) +return editablegrid; +}); \ No newline at end of file diff --git a/htdocs/js/lib/vendor/editablegrid-2.0.1/editablegrid.js b/htdocs/js/lib/vendor/editablegrid-2.0.1/editablegrid.js new file mode 100644 index 000000000..097b28306 --- /dev/null +++ b/htdocs/js/lib/vendor/editablegrid-2.0.1/editablegrid.js @@ -0,0 +1,3889 @@ +define([], function(){ + if (typeof _$ == 'undefined') { + function _$(elementId) { return document.getElementById(elementId); } + } + + /** + * Creates a new enumeration provider + * @constructor + * @class Base class for all enumeration providers + * @param {Object} config + */ + function EnumProvider(config) + { + // default properties + this.getOptionValuesForRender = function(grid, column, rowIndex) { return null; }; + this.getOptionValuesForEdit = function(grid, column, rowIndex) { return null; }; + + // override default properties with the ones given + for (var p in config) this[p] = config[p]; + } + + + /** + * Creates a new column + * @constructor + * @class Represents a column in the editable grid + * @param {Object} config + */ + function Column(config) + { + // default properties + var props = { + name: "", + label: "", + editable: true, + renderable: true, + datatype: "string", + unit: null, + precision: -1, // means that all decimals are displayed + nansymbol: '', + decimal_point: ',', + thousands_separator: '.', + unit_before_number: false, + bar: true, // is the column to be displayed in a bar chart ? relevant only for numerical columns + headerRenderer: null, + headerEditor: null, + cellRenderer: null, + cellEditor: null, + cellValidators: [], + enumProvider: null, + optionValues: null, + columnIndex: -1 + }; + + // override default properties with the ones given + for (var p in props) this[p] = (typeof config == 'undefined' || typeof config[p] == 'undefined') ? props[p] : config[p]; + } + + Column.prototype.getOptionValuesForRender = function(rowIndex) { + var values = this.enumProvider.getOptionValuesForRender(this.editablegrid, this, rowIndex); + return values ? values : this.optionValues; + }; + + Column.prototype.getOptionValuesForEdit = function(rowIndex) { + var values = this.enumProvider.getOptionValuesForEdit(this.editablegrid, this, rowIndex); + return values ? values : this.optionValues; + }; + + Column.prototype.isValid = function(value) { + for (var i = 0; i < this.cellValidators.length; i++) if (!this.cellValidators[i].isValid(value)) return false; + return true; + }; + + Column.prototype.isNumerical = function() { + return this.datatype =='double' || this.datatype =='integer'; + }; + + /** + * Creates a new EditableGrid. + *

      You can specify here some configuration options (optional). + *
      You can also set these same configuration options afterwards. + *

      These options are: + *

        + *
      • enableSort: enable sorting when clicking on column headers (default=true)
      • + *
      • doubleclick: use double click to edit cells (default=false)
      • + *
      • editmode: can be one of + *
          + *
        • absolute: cell editor comes over the cell (default)
        • + *
        • static: cell editor comes inside the cell
        • + *
        • fixed: cell editor comes in an external div
        • + *
        + *
      • + *
      • editorzoneid: used only when editmode is set to fixed, it is the id of the div to use for cell editors
      • + *
      • allowSimultaneousEdition: tells if several cells can be edited at the same time (default=false)
        + * Warning: on some Linux browsers (eg. Epiphany), a blur event is sent when the user clicks on a 'select' input to expand it. + * So practically, in these browsers you should set allowSimultaneousEdition to true if you want to use columns with option values and/or enum providers. + * This also used to happen in older versions of Google Chrome Linux but it has been fixed, so upgrade if needed.
      • + *
      • saveOnBlur: should be cells saved when clicking elsewhere ? (default=true)
      • + *
      • invalidClassName: CSS class to apply to text fields when the entered value is invalid (default="invalid")
      • + *
      • ignoreLastRow: ignore last row when sorting and charting the data (typically for a 'total' row)
      • + *
      • caption: text to use as the grid's caption
      • + *
      • dateFormat: EU or US (default="EU")
      • + *
      • shortMonthNames: list of month names (default=["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"])
      • + *
      • smartColorsBar: colors used for rendering (stacked) bar charts
      • + *
      • smartColorsPie: colors used for rendering pie charts
      • + *
      • pageSize: maximum number of rows displayed (0 means we don't want any pagination, which is the default)
      • + *
      + * @constructor + * @class EditableGrid + */ + function EditableGrid(name, config) { if (name) this.init(name, config); } + + /** + * Default properties + */ + EditableGrid.prototype.enableSort = true; + EditableGrid.prototype.enableStore = true; + EditableGrid.prototype.doubleclick = false; + EditableGrid.prototype.editmode = "absolute"; + EditableGrid.prototype.editorzoneid = ""; + EditableGrid.prototype.allowSimultaneousEdition = false; + EditableGrid.prototype.saveOnBlur = true; + EditableGrid.prototype.invalidClassName = "invalid"; + EditableGrid.prototype.ignoreLastRow = false; + EditableGrid.prototype.caption = null; + EditableGrid.prototype.dateFormat = "EU"; + EditableGrid.prototype.shortMonthNames = null; + EditableGrid.prototype.smartColorsBar = ["#dc243c","#4040f6","#00f629","#efe100","#f93fb1","#6f8183","#111111"]; + EditableGrid.prototype.smartColorsPie = ["#FF0000","#00FF00","#0000FF","#FFD700","#FF00FF","#00FFFF","#800080"]; + EditableGrid.prototype.pageSize = 0; // client-side pagination + + // server-side pagination, sorting and filtering + EditableGrid.prototype.serverSide = false; + EditableGrid.prototype.pageCount = 0; + EditableGrid.prototype.totalRowCount = 0; + EditableGrid.prototype.unfilteredRowCount = 0; + EditableGrid.prototype.lastURL = null; + + EditableGrid.prototype.init = function (name, config) + { + if (typeof name != "string" || (typeof config != "object" && typeof config != "undefined")) { + alert("The EditableGrid constructor takes two arguments:\n- name (string)\n- config (object)\n\nGot instead " + (typeof name) + " and " + (typeof config) + "."); + }; + + // override default properties with the ones given + if (typeof config != 'undefined') for (var p in config) this[p] = config[p]; + + this.Browser = { + IE: !!(window.attachEvent && navigator.userAgent.indexOf('Opera') === -1), + Opera: navigator.userAgent.indexOf('Opera') > -1, + WebKit: navigator.userAgent.indexOf('AppleWebKit/') > -1, + Gecko: navigator.userAgent.indexOf('Gecko') > -1 && navigator.userAgent.indexOf('KHTML') === -1, + MobileSafari: !!navigator.userAgent.match(/Apple.*Mobile.*Safari/) + }; + + // private data + this.name = name; + this.columns = []; + this.data = []; + this.dataUnfiltered = null; // non null means that data is filtered + this.xmlDoc = null; + this.sortedColumnName = -1; + this.sortDescending = false; + this.baseUrl = this.detectDir(); + this.nbHeaderRows = 1; + this.lastSelectedRowIndex = -1; + this.currentPageIndex = 0; + this.currentFilter = null; + this.currentContainerid = null; + this.currentClassName = null; + this.currentTableid = null; + + if (this.enableSort) { + this.sortUpImage = new Image(); + this.sortUpImage.src = this.baseUrl + "/images/bullet_arrow_up.png"; + this.sortDownImage = new Image(); + this.sortDownImage.src = this.baseUrl + "/images/bullet_arrow_down.png"; + } + }; + + /** + * Callback functions + */ + + EditableGrid.prototype.tableLoaded = function() {}; + EditableGrid.prototype.chartRendered = function() {}; + EditableGrid.prototype.tableRendered = function(containerid, className, tableid) {}; + EditableGrid.prototype.tableSorted = function(columnIndex, descending) {}; + EditableGrid.prototype.tableFiltered = function() {}; + EditableGrid.prototype.modelChanged = function(rowIndex, columnIndex, oldValue, newValue, row) {}; + EditableGrid.prototype.rowSelected = function(oldRowIndex, newRowIndex) {}; + EditableGrid.prototype.isHeaderEditable = function(rowIndex, columnIndex) { return false; }; + EditableGrid.prototype.isEditable =function(rowIndex, columnIndex) { return true; }; + EditableGrid.prototype.readonlyWarning = function() {}; + + /** + * Load metadata and/or data from an XML url + * The callback "tableLoaded" is called when loading is complete. + */ + EditableGrid.prototype.loadXML = function(url, callback) + { + // we use a trick to avoid getting an old version from the browser's cache + var orig_url = url; + var sep = url.indexOf('?') >= 0 ? '&' : '?'; + url += sep + Math.floor(Math.random() * 100000); + + var self = this; + with (this) { + + // IE + if (window.ActiveXObject) + { + xmlDoc = new ActiveXObject("Microsoft.XMLDOM"); + xmlDoc.onreadystatechange = function() { + if (xmlDoc.readyState == 4) { + processXML(); + _callback('xml', orig_url, callback); + } + }; + xmlDoc.load(url); + } + + // Safari + else if (/*Browser.WebKit && */ window.XMLHttpRequest) + { + xmlDoc = new XMLHttpRequest(); + xmlDoc.onreadystatechange = function () { + if (this.readyState == 4) { + xmlDoc = this.responseXML; + if (!xmlDoc) { /* alert("Could not load XML from url '" + orig_url + "'"); */ return false; } + processXML(); + _callback('xml', orig_url, callback); + } + }; + xmlDoc.open("GET", url, true); + xmlDoc.send(""); + } + + // Firefox (and other browsers) + else if (document.implementation && document.implementation.createDocument) + { + xmlDoc = document.implementation.createDocument("", "", null); + xmlDoc.onload = function() { + processXML(); + _callback('xml', orig_url, callback); + }; + xmlDoc.load(url); + } + + // should never happen + else { + alert("Cannot load a XML url with this browser!"); + return false; + } + + return true; + } + }; + + /** + * Load metadata and/or data from an XML string + * No callback "tableLoaded" is called since this is a synchronous operation. + * + * Contributed by Tim Consolazio of Tcoz Tech Services, tcoz@tcoz.com + * http://tcoztechwire.blogspot.com/2012/04/setxmlfromstring-extension-for.html + */ + EditableGrid.prototype.loadXMLFromString = function(xml) + { + if (window.DOMParser) { + var parser = new DOMParser(); + this.xmlDoc = parser.parseFromString(xml, "application/xml"); + } + else { + this.xmlDoc = new ActiveXObject("Microsoft.XMLDOM"); // IE + this.xmlDoc.async = "false"; + this.xmlDoc.loadXML(xml); + } + + this.processXML(); + }; + + /** + * Process the XML content + * @private + */ + EditableGrid.prototype.processXML = function() + { + with (this) { + + // clear model and pointer to current table + this.data = []; + this.dataUnfiltered = null; + this.table = null; + + // load metadata (only one tag --> metadata[0]) + var metadata = xmlDoc.getElementsByTagName("metadata"); + if (metadata && metadata.length >= 1) { + + this.columns = []; + var columnDeclarations = metadata[0].getElementsByTagName("column"); + for (var i = 0; i < columnDeclarations.length; i++) { + + // get column type + var col = columnDeclarations[i]; + var datatype = col.getAttribute("datatype"); + + // get enumerated values if any + var optionValues = null; + var enumValues = col.getElementsByTagName("values"); + if (enumValues.length > 0) { + optionValues = {}; + + var enumGroups = enumValues[0].getElementsByTagName("group"); + if (enumGroups.length > 0) { + for (var g = 0; g < enumGroups.length; g++) { + var groupOptionValues = {}; + enumValues = enumGroups[g].getElementsByTagName("value"); + for (var v = 0; v < enumValues.length; v++) { + groupOptionValues[enumValues[v].getAttribute("value")] = enumValues[v].firstChild ? enumValues[v].firstChild.nodeValue : ""; + } + optionValues[enumGroups[g].getAttribute("label")] = groupOptionValues; + } + } + else { + enumValues = enumValues[0].getElementsByTagName("value"); + for (var v = 0; v < enumValues.length; v++) { + optionValues[enumValues[v].getAttribute("value")] = enumValues[v].firstChild ? enumValues[v].firstChild.nodeValue : ""; + } + } + } + + // create new column + columns.push(new Column({ + name: col.getAttribute("name"), + label: (typeof col.getAttribute("label") == 'string' ? col.getAttribute("label") : col.getAttribute("name")), + datatype: (col.getAttribute("datatype") ? col.getAttribute("datatype") : "string"), + editable: col.getAttribute("editable") == "true", + bar: (col.getAttribute("bar") ? col.getAttribute("bar") == "true" : true), + optionValues: optionValues + })); + } + + // process columns + processColumns(); + } + + // if no row id is provided, we create one since we need one + var defaultRowId = 1; + + // load content + var rows = xmlDoc.getElementsByTagName("row"); + for (var i = 0; i < rows.length; i++) + { + // get all defined cell values + var cellValues = {}; + var cols = rows[i].getElementsByTagName("column"); + for (var j = 0; j < cols.length; j++) { + var colname = cols[j].getAttribute("name"); + if (!colname) { + if (j >= columns.length) alert("You defined too many columns for row " + (i+1)); + else colname = columns[j].name; + } + cellValues[colname] = cols[j].firstChild ? cols[j].firstChild.nodeValue : ""; + } + + // for each row we keep the orginal index, the id and all other attributes that may have been set in the XML + var rowData = { visible: true, originalIndex: i, id: rows[i].getAttribute("id") ? rows[i].getAttribute("id") : defaultRowId++ }; + for (var attrIndex = 0; attrIndex < rows[i].attributes.length; attrIndex++) { + var node = rows[i].attributes.item(attrIndex); + if (node.nodeName != "id") rowData[node.nodeName] = node.nodeValue; + } + + // get column values for this rows + rowData.columns = []; + for (var c = 0; c < columns.length; c++) { + var cellValue = columns[c].name in cellValues ? cellValues[columns[c].name] : ""; + rowData.columns.push(getTypedValue(c, cellValue)); + } + + // add row data in our model + data.push(rowData); + } + } + + return true; + }; + + /** + * Load metadata and/or data from a JSON url + * The callback "tableLoaded" is called when loading is complete. + */ + EditableGrid.prototype.loadJSON = function(url, callback) + { + // we use a trick to avoid getting an old version from the browser's cache + var orig_url = url; + var sep = url.indexOf('?') >= 0 ? '&' : '?'; + url += sep + Math.floor(Math.random() * 100000); + + // should never happen + if (!window.XMLHttpRequest) { + alert("Cannot load a JSON url with this browser!"); + return false; + } + + var self = this; + with (this) { + + var ajaxRequest = new XMLHttpRequest(); + ajaxRequest.onreadystatechange = function () { + if (this.readyState == 4) { + if (!this.responseText) { /* alert("Could not load JSON from url '" + orig_url + "'"); */ return false; } + if (!processJSON(this.responseText)) { alert("Invalid JSON data obtained from url '" + orig_url + "'"); return false; } + _callback('json', orig_url, callback); + } + }; + + ajaxRequest.open("GET", url, true); + ajaxRequest.send(""); + } + + return true; + }; + + EditableGrid.prototype._callback = function(type, url, callback) + { + if (callback) callback.call(this); + else { + + // replace refreshGrid to enable server-side pagination, sorting and filtering + if (this.serverSide) { + this.refreshGrid = function() { + + // add pagination, filtering and sorting parameters to the last used url + var url = this.lastURL + (this.lastURL.indexOf('?') >= 0 ? '&' : '?') + + "page=" + (this.currentPageIndex + 1) + + "&filter=" + (this.currentFilter ? encodeURIComponent(this.currentFilter) : "") + + "&sort=" + (this.sortedColumnName && this.sortedColumnName != -1 ? encodeURIComponent(this.sortedColumnName) : "") + + "&asc=" + (this.sortDescending ? 0 : 1); + + // the original refreshGrid will be called after ajax request is done (ie. after updated data have been loaded) + var callback = function() { EditableGrid.prototype.refreshGrid.call(this); }; + + // load data using the parameterized url + if (type == 'xml') this.loadXML(url, callback); + else this.loadJSON(url, callback); + }; + } + + this.lastURL = url; + this.tableLoaded(); + } + }; + + /** + * Load metadata and/or data from a JSON string + * No callback "tableLoaded" is called since this is a synchronous operation. + */ + EditableGrid.prototype.loadJSONFromString = function(json) + { + return this.processJSON(json); + }; + + /** + * Load metadata and/or data from a Javascript object + * No callback "tableLoaded" is called since this is a synchronous operation. + */ + EditableGrid.prototype.load = function(object) + { + return this.processJSON(object); + }; + + /** + * Process the JSON content + * @private + */ + EditableGrid.prototype.processJSON = function(jsonData) + { + if (typeof jsonData == "string") jsonData = eval("(" + jsonData + ")"); + if (!jsonData) return false; + + // clear model and pointer to current table + this.data = []; + this.dataUnfiltered = null; + this.table = null; + + // load metadata + if (jsonData.metadata) { + + // create columns + this.columns = []; + for (var c = 0; c < jsonData.metadata.length; c++) { + var columndata = jsonData.metadata[c]; + this.columns.push(new Column({ + name: columndata.name, + label: (columndata.label ? columndata.label : columndata.name), + datatype: (columndata.datatype ? columndata.datatype : "string"), + editable: (columndata.editable ? true : false), + bar: (typeof columndata.bar == 'undefined' ? true : (columndata.bar ? true : false)), + optionValues: columndata.values ? columndata.values : null + })); + } + + // process columns + this.processColumns(); + } + + // load server-side pagination data + if (jsonData.paginator) { + this.pageCount = jsonData.paginator.pagecount; + this.totalRowCount = jsonData.paginator.totalrowcount; + this.unfilteredRowCount = jsonData.paginator.unfilteredrowcount; + } + + // if no row id is provided, we create one since we need one + var defaultRowId = 1; + + // load content + if (jsonData.data) for (var i = 0; i < jsonData.data.length; i++) + { + var row = jsonData.data[i]; + if (!row.values) continue; + + // row values can be given as an array (same order as columns) or as an object (associative array) + if (Object.prototype.toString.call(row.values) !== '[object Array]' ) cellValues = row.values; + else { + cellValues = {}; + for (var j = 0; j < row.values.length && j < this.columns.length; j++) cellValues[this.columns[j].name] = row.values[j]; + } + + // for each row we keep the orginal index, the id and all other attributes that may have been set in the JSON + var rowData = { visible: true, originalIndex: i, id: row.id ? row.id : defaultRowId++ }; + for (var attributeName in row) if (attributeName != "id" && attributeName != "values") rowData[attributeName] = row[attributeName]; + + // get column values for this rows + rowData.columns = []; + for (var c = 0; c < this.columns.length; c++) { + var cellValue = this.columns[c].name in cellValues ? cellValues[this.columns[c].name] : ""; + rowData.columns.push(this.getTypedValue(c, cellValue)); + } + + // add row data in our model + this.data.push(rowData); + } + + return true; + }; + + /** + * Process columns + * @private + */ + EditableGrid.prototype.processColumns = function() + { + for (var columnIndex = 0; columnIndex < this.columns.length; columnIndex++) { + + var column = this.columns[columnIndex]; + + // set column index and back pointer + column.columnIndex = columnIndex; + column.editablegrid = this; + + // parse column type + this.parseColumnType(column); + + // create suited enum provider if none given + if (!column.enumProvider) column.enumProvider = column.optionValues ? new EnumProvider() : null; + + // create suited cell renderer if none given + if (!column.cellRenderer) this._createCellRenderer(column); + if (!column.headerRenderer) this._createHeaderRenderer(column); + + // create suited cell editor if none given + if (!column.cellEditor) this._createCellEditor(column); + if (!column.headerEditor) this._createHeaderEditor(column); + + // add default cell validators based on the column type + this._addDefaultCellValidators(column); + } + }; + + /** + * Parse column type + * @private + */ + + EditableGrid.prototype.parseColumnType = function(column) + { + // extract precision, unit and number format from type if 6 given + if (column.datatype.match(/(.*)\((.*),(.*),(.*),(.*),(.*),(.*)\)$/)) { + column.datatype = RegExp.$1; + column.unit = RegExp.$2; + column.precision = parseInt(RegExp.$3); + column.decimal_point = RegExp.$4; + column.thousands_separator = RegExp.$5; + column.unit_before_number = RegExp.$6; + column.nansymbol = RegExp.$7; + + // trim should be done after fetching RegExp matches beacuse it itself uses a RegExp and causes interferences! + column.unit = column.unit.trim(); + column.decimal_point = column.decimal_point.trim(); + column.thousands_separator = column.thousands_separator.trim(); + column.unit_before_number = column.unit_before_number.trim() == '1'; + column.nansymbol = column.nansymbol.trim(); + } + + // extract precision, unit and number format from type if 5 given + else if (column.datatype.match(/(.*)\((.*),(.*),(.*),(.*),(.*)\)$/)) { + column.datatype = RegExp.$1; + column.unit = RegExp.$2; + column.precision = parseInt(RegExp.$3); + column.decimal_point = RegExp.$4; + column.thousands_separator = RegExp.$5; + column.unit_before_number = RegExp.$6; + + // trim should be done after fetching RegExp matches beacuse it itself uses a RegExp and causes interferences! + column.unit = column.unit.trim(); + column.decimal_point = column.decimal_point.trim(); + column.thousands_separator = column.thousands_separator.trim(); + column.unit_before_number = column.unit_before_number.trim() == '1'; + } + + // extract precision, unit and nansymbol from type if 3 given + else if (column.datatype.match(/(.*)\((.*),(.*),(.*)\)$/)) { + column.datatype = RegExp.$1; + column.unit = RegExp.$2.trim(); + column.precision = parseInt(RegExp.$3); + column.nansymbol = RegExp.$4.trim(); + } + + // extract precision and unit from type if two given + else if (column.datatype.match(/(.*)\((.*),(.*)\)$/)) { + column.datatype = RegExp.$1.trim(); + column.unit = RegExp.$2.trim(); + column.precision = parseInt(RegExp.$3); + } + + // extract precision or unit from type if any given + else if (column.datatype.match(/(.*)\((.*)\)$/)) { + column.datatype = RegExp.$1.trim(); + var unit_or_precision = RegExp.$2.trim(); + if (unit_or_precision.match(/^[0-9]*$/)) column.precision = parseInt(unit_or_precision); + else column.unit = unit_or_precision; + } + + if (column.decimal_point == 'comma') column.decimal_point = ','; + if (column.decimal_point == 'dot') column.decimal_point = '.'; + if (column.thousands_separator == 'comma') column.thousands_separator = ','; + if (column.thousands_separator == 'dot') column.thousands_separator = '.'; + + if (isNaN(column.precision)) column.precision = -1; + if (column.unit == '') column.unit = null; + if (column.nansymbol == '') column.nansymbol = null; + }; + + /** + * Get typed value + * @private + */ + + EditableGrid.prototype.getTypedValue = function(columnIndex, cellValue) + { + var colType = this.getColumnType(columnIndex); + if (colType == 'boolean') cellValue = (cellValue && cellValue != 0 && cellValue != "false") ? true : false; + if (colType == 'integer') { cellValue = parseInt(cellValue, 10); } + if (colType == 'double') { cellValue = parseFloat(cellValue); } + if (colType == 'string') { cellValue = "" + cellValue; } + return cellValue; + }; + + /** + * Attach to an existing HTML table. + * The second parameter can be used to give the column definitions. + * This parameter is left for compatibility, but is deprecated: you should now use "load" to setup the metadata. + */ + EditableGrid.prototype.attachToHTMLTable = function(_table, _columns) + { + // clear model and pointer to current table + this.data = []; + this.dataUnfiltered = null; + this.table = null; + + // process columns if given + if (_columns) { + this.columns = _columns; + this.processColumns(); + } + + // get pointers to table components + this.table = typeof _table == 'string' ? _$(_table) : _table ; + if (!this.table) alert("Invalid table given: " + _table); + this.tHead = this.table.tHead; + this.tBody = this.table.tBodies[0]; + + // create table body if needed + if (!this.tBody) { + this.tBody = document.createElement("TBODY"); + this.table.insertBefore(this.tBody, this.table.firstChild); + } + + // create table header if needed + if (!this.tHead) { + this.tHead = document.createElement("THEAD"); + this.table.insertBefore(this.tHead, this.tBody); + } + + // if header is empty use first body row as header + if (this.tHead.rows.length == 0 && this.tBody.rows.length > 0) + this.tHead.appendChild(this.tBody.rows[0]); + + // get number of rows in header + this.nbHeaderRows = this.tHead.rows.length; + + // load header labels + var rows = this.tHead.rows; + for (var i = 0; i < rows.length; i++) { + var cols = rows[i].cells; + var columnIndexInModel = 0; + for (var j = 0; j < cols.length && columnIndexInModel < this.columns.length; j++) { + if (!this.columns[columnIndexInModel].label || this.columns[columnIndexInModel].label == this.columns[columnIndexInModel].name) this.columns[columnIndexInModel].label = cols[j].innerHTML; + var colspan = parseInt(cols[j].getAttribute("colspan")); + columnIndexInModel += colspan > 1 ? colspan : 1; + } + } + + // load content + var rows = this.tBody.rows; + for (var i = 0; i < rows.length; i++) { + var rowData = []; + var cols = rows[i].cells; + for (var j = 0; j < cols.length && j < this.columns.length; j++) rowData.push(this.getTypedValue(j, cols[j].innerHTML)); + this.data.push({ visible: true, originalIndex: i, id: rows[i].id, columns: rowData }); + rows[i].rowId = rows[i].id; + rows[i].id = this._getRowDOMId(rows[i].id); + } + }; + + /** + * Creates a suitable cell renderer for the column + * @private + */ + EditableGrid.prototype._createCellRenderer = function(column) + { + column.cellRenderer = + column.enumProvider ? new EnumCellRenderer() : + column.datatype == "integer" || column.datatype == "double" ? new NumberCellRenderer() : + column.datatype == "boolean" ? new CheckboxCellRenderer() : + column.datatype == "email" ? new EmailCellRenderer() : + column.datatype == "website" || column.datatype == "url" ? new WebsiteCellRenderer() : + column.datatype == "date" ? new DateCellRenderer() : + new CellRenderer(); + + // give access to the column from the cell renderer + if (column.cellRenderer) { + column.cellRenderer.editablegrid = this; + column.cellRenderer.column = column; + } + }; + + /** + * Creates a suitable header cell renderer for the column + * @private + */ + EditableGrid.prototype._createHeaderRenderer = function(column) + { + column.headerRenderer = (this.enableSort && column.datatype != "html") ? new SortHeaderRenderer(column.name) : new CellRenderer(); + + // give access to the column from the header cell renderer + if (column.headerRenderer) { + column.headerRenderer.editablegrid = this; + column.headerRenderer.column = column; + } + }; + + /** + * Creates a suitable cell editor for the column + * @private + */ + EditableGrid.prototype._createCellEditor = function(column) + { + column.cellEditor = + column.enumProvider ? new SelectCellEditor() : + column.datatype == "integer" || column.datatype == "double" ? new NumberCellEditor(column.datatype) : + column.datatype == "boolean" ? null : + column.datatype == "email" ? new TextCellEditor(column.precision) : + column.datatype == "website" || column.datatype == "url" ? new TextCellEditor(column.precision) : + column.datatype == "date" ? (typeof $ == 'undefined' || typeof $.datepicker == 'undefined' ? new TextCellEditor(column.precision, 10) : new DateCellEditor({ fieldSize: column.precision, maxLength: 10 })) : + new TextCellEditor(column.precision); + + // give access to the column from the cell editor + if (column.cellEditor) { + column.cellEditor.editablegrid = this; + column.cellEditor.column = column; + } + }; + + /** + * Creates a suitable header cell editor for the column + * @private + */ + EditableGrid.prototype._createHeaderEditor = function(column) + { + column.headerEditor = new TextCellEditor(); + + // give access to the column from the cell editor + if (column.headerEditor) { + column.headerEditor.editablegrid = this; + column.headerEditor.column = column; + } + }; + + /** + * Returns the number of rows + */ + EditableGrid.prototype.getRowCount = function() + { + return this.data.length; + }; + + /** + * Returns the number of rows, not taking the filter into account if any + */ + EditableGrid.prototype.getUnfilteredRowCount = function() + { + // given if server-side filtering is involved + if (this.unfilteredRowCount > 0) return this.unfilteredRowCount; + + var _data = this.dataUnfiltered == null ? this.data : this.dataUnfiltered; + return _data.length; + }; + + /** + * Returns the number of rows in all pages + */ + EditableGrid.prototype.getTotalRowCount = function() + { + // different from getRowCount only is server-side pagination is involved + if (this.totalRowCount > 0) return this.totalRowCount; + + return this.getRowCount(); + }; + + /** + * Returns the number of columns + */ + EditableGrid.prototype.getColumnCount = function() + { + return this.columns.length; + }; + + /** + * Returns true if the column exists + * @param {Object} columnIndexOrName index or name of the column + */ + EditableGrid.prototype.hasColumn = function(columnIndexOrName) + { + return this.getColumnIndex(columnIndexOrName) >= 0; + }; + + /** + * Returns the column + * @param {Object} columnIndexOrName index or name of the column + */ + EditableGrid.prototype.getColumn = function(columnIndexOrName) + { + var colIndex = this.getColumnIndex(columnIndexOrName); + if (colIndex < 0) { alert("[getColumn] Column not found with index or name " + columnIndexOrName); return null; } + return this.columns[colIndex]; + }; + + /** + * Returns the name of a column + * @param {Object} columnIndexOrName index or name of the column + */ + EditableGrid.prototype.getColumnName = function(columnIndexOrName) + { + return this.getColumn(columnIndexOrName).name; + }; + + /** + * Returns the label of a column + * @param {Object} columnIndexOrName index or name of the column + */ + EditableGrid.prototype.getColumnLabel = function(columnIndexOrName) + { + return this.getColumn(columnIndexOrName).label; + }; + + /** + * Returns the type of a column + * @param {Object} columnIndexOrName index or name of the column + */ + EditableGrid.prototype.getColumnType = function(columnIndexOrName) + { + return this.getColumn(columnIndexOrName).datatype; + }; + + /** + * Returns the unit of a column + * @param {Object} columnIndexOrName index or name of the column + */ + EditableGrid.prototype.getColumnUnit = function(columnIndexOrName) + { + return this.getColumn(columnIndexOrName).unit; + }; + + /** + * Returns the precision of a column + * @param {Object} columnIndexOrName index or name of the column + */ + EditableGrid.prototype.getColumnPrecision = function(columnIndexOrName) + { + return this.getColumn(columnIndexOrName).precision; + }; + + /** + * Returns true if the column is to be displayed in a bar chart + * @param {Object} columnIndexOrName index or name of the column + */ + EditableGrid.prototype.isColumnBar = function(columnIndexOrName) + { + var column = this.getColumn(columnIndexOrName); + return (column.bar && column.isNumerical()); + }; + + /** + * Returns true if the column is numerical (double or integer) + * @param {Object} columnIndexOrName index or name of the column + */ + EditableGrid.prototype.isColumnNumerical = function(columnIndexOrName) + { + var column = this.getColumn(columnIndexOrName); + return column.isNumerical();; + }; + + /** + * Returns the value at the specified index + * @param {Integer} rowIndex + * @param {Integer} columnIndex + */ + EditableGrid.prototype.getValueAt = function(rowIndex, columnIndex) + { + // check and get column + if (columnIndex < 0 || columnIndex >= this.columns.length) { alert("[getValueAt] Invalid column index " + columnIndex); return null; } + var column = this.columns[columnIndex]; + + // get value in model + if (rowIndex < 0) return column.label; + + if (typeof this.data[rowIndex] == 'undefined') { alert("[getValueAt] Invalid row index " + rowIndex); return null; } + var rowData = this.data[rowIndex]['columns']; + return rowData ? rowData[columnIndex] : null; + }; + + /** + * Returns the display value (used for sorting and filtering) at the specified index + * @param {Integer} rowIndex + * @param {Integer} columnIndex + */ + EditableGrid.prototype.getDisplayValueAt = function(rowIndex, columnIndex) + { + var value = this.getValueAt(rowIndex, columnIndex); + if (value !== null) { + // use renderer to get the value that must be used for sorting + var renderer = rowIndex < 0 ? this.columns[columnIndex].headerRenderer : this.columns[columnIndex].cellRenderer; + value = renderer.getDisplayValue(rowIndex, value); + } + return value; + }; + + + /** + * Sets the value at the specified index + * @param {Integer} rowIndex + * @param {Integer} columnIndex + * @param {Object} value + * @param {Boolean} render + */ + EditableGrid.prototype.setValueAt = function(rowIndex, columnIndex, value, render) + { + if (typeof render == "undefined") render = true; + var previousValue = null;; + + // check and get column + if (columnIndex < 0 || columnIndex >= this.columns.length) { alert("[setValueAt] Invalid column index " + columnIndex); return null; } + var column = this.columns[columnIndex]; + + // set new value in model + if (rowIndex < 0) { + previousValue = column.label; + column.label = value; + } + else { + var rowData = this.data[rowIndex]['columns']; + previousValue = rowData[columnIndex]; + if (rowData) rowData[columnIndex] = this.getTypedValue(columnIndex, value); + } + + // render new value + if (render) { + var renderer = rowIndex < 0 ? column.headerRenderer : column.cellRenderer; + renderer._render(rowIndex, columnIndex, this.getCell(rowIndex, columnIndex), value); + } + + return previousValue; + }; + + /** + * Find column index from its name + * @param {Object} columnIndexOrName index or name of the column + */ + EditableGrid.prototype.getColumnIndex = function(columnIndexOrName) + { + if (typeof columnIndexOrName == "undefined" || columnIndexOrName === "") return -1; + + // TODO: problem because the name of a column could be a valid index, and we cannot make the distinction here! + + // if columnIndexOrName is a number which is a valid index return it + if (!isNaN(columnIndexOrName) && columnIndexOrName >= 0 && columnIndexOrName < this.columns.length) return columnIndexOrName; + + // otherwise search for the name + for (var c = 0; c < this.columns.length; c++) if (this.columns[c].name == columnIndexOrName) return c; + + return -1; + }; + + /** + * Get HTML row object at given index + * @param {Integer} index of the row + */ + EditableGrid.prototype.getRow = function(rowIndex) + { + if (rowIndex < 0) return this.tHead.rows[rowIndex + this.nbHeaderRows]; + if (typeof this.data[rowIndex] == 'undefined') { alert("[getRow] Invalid row index " + rowIndex); return null; } + return _$(this._getRowDOMId(this.data[rowIndex].id)); + }; + + /** + * Get row id for given row index + * @param {Integer} index of the row + */ + EditableGrid.prototype.getRowId = function(rowIndex) + { + return (rowIndex < 0 || rowIndex >= this.data.length) ? null : this.data[rowIndex]['id']; + }; + + /** + * Get index of row (in filtered data) with given id + * @param {Integer} rowId or HTML row object + */ + EditableGrid.prototype.getRowIndex = function(rowId) + { + rowId = typeof rowId == 'object' ? rowId.rowId : rowId; + for (var rowIndex = 0; rowIndex < this.data.length; rowIndex++) if (this.data[rowIndex].id == rowId) return rowIndex; + return -1; + }; + + /** + * Get custom row attribute specified in XML + * @param {Integer} index of the row + * @param {String} name of the attribute + */ + EditableGrid.prototype.getRowAttribute = function(rowIndex, attributeName) + { + return this.data[rowIndex][attributeName]; + }; + + /** + * Set custom row attribute + * @param {Integer} index of the row + * @param {String} name of the attribute + * @param value of the attribute + */ + EditableGrid.prototype.setRowAttribute = function(rowIndex, attributeName, attributeValue) + { + this.data[rowIndex][attributeName] = attributeValue; + }; + + /** + * Get Id of row in HTML DOM + * @private + */ + EditableGrid.prototype._getRowDOMId = function(rowId) + { + return this.currentContainerid != null ? this.name + "_" + rowId : rowId; + }; + + /** + * Remove row with given id + * Deprecated: use remove(rowIndex) instead + * @param {Integer} rowId + */ + EditableGrid.prototype.removeRow = function(rowId) + { + return this.remove(this.getRowIndex(rowId)); + }; + + /** + * Remove row at given index + * @param {Integer} rowIndex + */ + EditableGrid.prototype.remove = function(rowIndex) + { + var rowId = this.data[rowIndex].id; + var originalIndex = this.data[rowIndex].originalIndex; + var _data = this.dataUnfiltered == null ? this.data : this.dataUnfiltered; + + // delete row from DOM (needed for attach mode) + var tr = _$(this._getRowDOMId(rowId)); + if (tr != null) this.tBody.removeChild(tr); + + // update originalRowIndex + for (var r = 0; r < _data.length; r++) if (_data[r].originalIndex >= originalIndex) _data[r].originalIndex--; + + // delete row from data + this.data.splice(rowIndex, 1); + if (this.dataUnfiltered != null) for (var r = 0; r < this.dataUnfiltered.length; r++) if (this.dataUnfiltered[r].id == rowId) { this.dataUnfiltered.splice(r, 1); break; } + + // refresh grid + this.refreshGrid(); + }; + + /** + * Return an associative array (column name => value) of values in row with given index + * @param {Integer} rowIndex + */ + EditableGrid.prototype.getRowValues = function(rowIndex) + { + var rowValues = {}; + for (var columnIndex = 0; columnIndex < this.getColumnCount(); columnIndex++) { + rowValues[this.getColumnName(columnIndex)] = this.getValueAt(rowIndex, columnIndex); + } + return rowValues; + }; + + /** + * Append row with given id and data + * @param {Integer} rowId id of new row + * @param {Integer} columns + * @param {Boolean} dontSort + */ + EditableGrid.prototype.append = function(rowId, cellValues, rowAttributes, dontSort) + { + return this.insertAfter(this.data.length - 1, rowId, cellValues, rowAttributes, dontSort); + }; + + /** + * Append row with given id and data + * Deprecated: use appendRow instead + * @param {Integer} rowId id of new row + * @param {Integer} columns + * @param {Boolean} dontSort + */ + EditableGrid.prototype.addRow = function(rowId, cellValues, rowAttributes, dontSort) + { + return this.append(rowId, cellValues, rowAttributes, dontSort); + }; + + /** + * Insert row with given id and data at given location + * We know rowIndex is valid, unless the table is empty + * @private + */ + EditableGrid.prototype._insert = function(rowIndex, offset, rowId, cellValues, rowAttributes, dontSort) + { + var originalRowId = null; + var originalIndex = 0; + var _data = this.dataUnfiltered == null ? this.data : this.dataUnfiltered; + + if (typeof this.data[rowIndex] != "undefined") { + originalRowId = this.data[rowIndex].id; + originalIndex = this.data[rowIndex].originalIndex + offset; + } + + // append row in DOM (needed for attach mode) + if (this.currentContainerid == null) { + var tr = this.tBody.insertRow(rowIndex + offset); + tr.rowId = rowId; + tr.id = this._getRowDOMId(rowId); + for (var c = 0; c < this.columns.length; c++) tr.insertCell(c); + } + + // build data for new row + var rowData = { visible: true, originalIndex: originalIndex, id: rowId }; + if (rowAttributes) for (var attributeName in rowAttributes) rowData[attributeName] = rowAttributes[attrName]; + rowData.columns = []; + for (var c = 0; c < this.columns.length; c++) { + var cellValue = this.columns[c].name in cellValues ? cellValues[this.columns[c].name] : ""; + rowData.columns.push(this.getTypedValue(c, cellValue)); + } + + // update originalRowIndex + for (var r = 0; r < _data.length; r++) if (_data[r].originalIndex >= originalIndex) _data[r].originalIndex++; + + // append row in data + this.data.splice(rowIndex + offset, 0, rowData); + if (this.dataUnfiltered != null) { + if (originalRowId === null) this.dataUnfiltered.splice(rowIndex + offset, 0, rowData); + else for (var r = 0; r < this.dataUnfiltered.length; r++) if (this.dataUnfiltered[r].id == originalRowId) { this.dataUnfiltered.splice(r + offset, 0, rowData); break; } + } + + // refresh grid + this.refreshGrid(); + + // sort and filter table + if (!dontSort) this.sort(); + this.filter(); + }; + + /** + * Insert row with given id and data before given row index + * @param {Integer} rowIndex index of row before which to insert new row + * @param {Integer} rowId id of new row + * @param {Integer} columns + * @param {Boolean} dontSort + */ + EditableGrid.prototype.insert = function(rowIndex, rowId, cellValues, rowAttributes, dontSort) + { + if (rowIndex < 0) rowIndex = 0; + if (rowIndex >= this.data.length && this.data.length > 0) return this.insertAfter(this.data.length - 1, rowId, cellValues, rowAttributes, dontSort); + return this._insert(rowIndex, 0, rowId, cellValues, rowAttributes, dontSort); + }; + + /** + * Insert row with given id and data after given row index + * @param {Integer} rowIndex index of row after which to insert new row + * @param {Integer} rowId id of new row + * @param {Integer} columns + * @param {Boolean} dontSort + */ + EditableGrid.prototype.insertAfter = function(rowIndex, rowId, cellValues, rowAttributes, dontSort) + { + if (rowIndex < 0) return this.insert(0, rowId, cellValues, rowAttributes, dontSort); + if (rowIndex >= this.data.length) rowIndex = this.data.length - 1; + return this._insert(rowIndex, 1, rowId, cellValues, rowAttributes, dontSort); + }; + + /** + * Sets the column header cell renderer for the specified column index + * @param {Object} columnIndexOrName index or name of the column + * @param {CellRenderer} cellRenderer + */ + EditableGrid.prototype.setHeaderRenderer = function(columnIndexOrName, cellRenderer) + { + var columnIndex = this.getColumnIndex(columnIndexOrName); + if (columnIndex < 0) alert("[setHeaderRenderer] Invalid column: " + columnIndexOrName); + else { + var column = this.columns[columnIndex]; + column.headerRenderer = (this.enableSort && column.datatype != "html") ? new SortHeaderRenderer(column.name, cellRenderer) : cellRenderer; + + // give access to the column from the cell renderer + if (cellRenderer) { + if (this.enableSort && column.datatype != "html") { + column.headerRenderer.editablegrid = this; + column.headerRenderer.column = column; + } + cellRenderer.editablegrid = this; + cellRenderer.column = column; + } + } + }; + + /** + * Sets the cell renderer for the specified column index + * @param {Object} columnIndexOrName index or name of the column + * @param {CellRenderer} cellRenderer + */ + EditableGrid.prototype.setCellRenderer = function(columnIndexOrName, cellRenderer) + { + var columnIndex = this.getColumnIndex(columnIndexOrName); + if (columnIndex < 0) alert("[setCellRenderer] Invalid column: " + columnIndexOrName); + else { + var column = this.columns[columnIndex]; + column.cellRenderer = cellRenderer; + + // give access to the column from the cell renderer + if (cellRenderer) { + cellRenderer.editablegrid = this; + cellRenderer.column = column; + } + } + }; + + /** + * Sets the cell editor for the specified column index + * @param {Object} columnIndexOrName index or name of the column + * @param {CellEditor} cellEditor + */ + EditableGrid.prototype.setCellEditor = function(columnIndexOrName, cellEditor) + { + var columnIndex = this.getColumnIndex(columnIndexOrName); + if (columnIndex < 0) alert("[setCellEditor] Invalid column: " + columnIndexOrName); + else { + var column = this.columns[columnIndex]; + column.cellEditor = cellEditor; + + // give access to the column from the cell editor + if (cellEditor) { + cellEditor.editablegrid = this; + cellEditor.column = column; + } + } + }; + + /** + * Sets the header cell editor for the specified column index + * @param {Object} columnIndexOrName index or name of the column + * @param {CellEditor} cellEditor + */ + EditableGrid.prototype.setHeaderEditor = function(columnIndexOrName, cellEditor) + { + var columnIndex = this.getColumnIndex(columnIndexOrName); + if (columnIndex < 0) alert("[setHeaderEditor] Invalid column: " + columnIndexOrName); + else { + var column = this.columns[columnIndex]; + column.headerEditor = cellEditor; + + // give access to the column from the cell editor + if (cellEditor) { + cellEditor.editablegrid = this; + cellEditor.column = column; + } + } + }; + + /** + * Sets the enum provider for the specified column index + * @param {Object} columnIndexOrName index or name of the column + * @param {EnumProvider} enumProvider + */ + EditableGrid.prototype.setEnumProvider = function(columnIndexOrName, enumProvider) + { + var columnIndex = this.getColumnIndex(columnIndexOrName); + if (columnIndex < 0) alert("[setEnumProvider] Invalid column: " + columnIndexOrName); + else this.columns[columnIndex].enumProvider = enumProvider; + + // we must recreate the cell renderer and editor for this column + this._createCellRenderer(this.columns[columnIndex]); + this._createCellEditor(this.columns[columnIndex]); + }; + + /** + * Clear all cell validators for the specified column index + * @param {Object} columnIndexOrName index or name of the column + */ + EditableGrid.prototype.clearCellValidators = function(columnIndexOrName) + { + var columnIndex = this.getColumnIndex(columnIndexOrName); + if (columnIndex < 0) alert("[clearCellValidators] Invalid column: " + columnIndexOrName); + else this.columns[columnIndex].cellValidators = []; + }; + + /** + * Adds default cell validators for the specified column index (according to the column type) + * @param {Object} columnIndexOrName index or name of the column + */ + EditableGrid.prototype.addDefaultCellValidators = function(columnIndexOrName) + { + var columnIndex = this.getColumnIndex(columnIndexOrName); + if (columnIndex < 0) alert("[addDefaultCellValidators] Invalid column: " + columnIndexOrName); + return this._addDefaultCellValidators(this.columns[columnIndex]); + }; + + /** + * Adds default cell validators for the specified column + * @private + */ + EditableGrid.prototype._addDefaultCellValidators = function(column) + { + if (column.datatype == "integer" || column.datatype == "double") column.cellValidators.push(new NumberCellValidator(column.datatype)); + else if (column.datatype == "email") column.cellValidators.push(new EmailCellValidator()); + else if (column.datatype == "website" || column.datatype == "url") column.cellValidators.push(new WebsiteCellValidator()); + else if (column.datatype == "date") column.cellValidators.push(new DateCellValidator(this)); + }; + + /** + * Adds a cell validator for the specified column index + * @param {Object} columnIndexOrName index or name of the column + * @param {CellValidator} cellValidator + */ + EditableGrid.prototype.addCellValidator = function(columnIndexOrName, cellValidator) + { + var columnIndex = this.getColumnIndex(columnIndexOrName); + if (columnIndex < 0) alert("[addCellValidator] Invalid column: " + columnIndexOrName); + else this.columns[columnIndex].cellValidators.push(cellValidator); + }; + + /** + * Sets the table caption: set as null to remove + * @param columnIndexOrName + * @param caption + * @return + */ + EditableGrid.prototype.setCaption = function(caption) + { + this.caption = caption; + }; + + /** + * Get cell element at given row and column + */ + EditableGrid.prototype.getCell = function(rowIndex, columnIndex) + { + var row = this.getRow(rowIndex); + if (row == null) { alert("[getCell] Invalid row index " + rowIndex); return null; } + return row.cells[columnIndex]; + }; + + /** + * Get cell X position relative to the first non static offset parent + * @private + */ + EditableGrid.prototype.getCellX = function(oElement) + { + var iReturnValue = 0; + while (oElement != null && this.isStatic(oElement)) try { + iReturnValue += oElement.offsetLeft; + oElement = oElement.offsetParent; + } catch(err) { oElement = null; } + return iReturnValue; + }; + + /** + * Get cell Y position relative to the first non static offset parent + * @private + */ + EditableGrid.prototype.getCellY = function(oElement) + { + var iReturnValue = 0; + while (oElement != null && this.isStatic(oElement)) try { + iReturnValue += oElement.offsetTop; + oElement = oElement.offsetParent; + } catch(err) { oElement = null; } + return iReturnValue; + }; + + /** + * Private + * @param containerid + * @param className + * @param tableid + * @return + */ + EditableGrid.prototype._rendergrid = function(containerid, className, tableid) + { + with (this) { + + _currentPageIndex = getCurrentPageIndex(); + + // if we are already attached to an existing table, just update the cell contents + if (typeof table != "undefined" && table != null) { + + var _data = dataUnfiltered == null ? data : dataUnfiltered; + + // render headers + _renderHeaders(); + + // render content + var rows = tBody.rows; + var skipped = 0; + var displayed = 0; + var rowIndex = 0; + + for (var i = 0; i < rows.length; i++) { + + // filtering and pagination in attach mode means hiding rows + if (!_data[i].visible || (pageSize > 0 && displayed >= pageSize)) { + if (rows[i].style.display != 'none') { + rows[i].style.display = 'none'; + rows[i].hidden_by_editablegrid = true; + } + } + else { + if (skipped < pageSize * _currentPageIndex) { + skipped++; + if (rows[i].style.display != 'none') { + rows[i].style.display = 'none'; + rows[i].hidden_by_editablegrid = true; + } + } + else { + displayed++; + var rowData = []; + var cols = rows[i].cells; + if (typeof rows[i].hidden_by_editablegrid != 'undefined' && rows[i].hidden_by_editablegrid) { + rows[i].style.display = ''; + rows[i].hidden_by_editablegrid = false; + } + for (var j = 0; j < cols.length && j < columns.length; j++) + if (columns[j].renderable) columns[j].cellRenderer._render(rowIndex, j, cols[j], getValueAt(rowIndex,j)); + } + rowIndex++; + } + } + + // attach handler on click or double click + table.editablegrid = this; + if (doubleclick) table.ondblclick = function(e) { this.editablegrid.mouseClicked(e); }; + else table.onclick = function(e) { this.editablegrid.mouseClicked(e); }; + } + + // we must render a whole new table + else { + + if (!_$(containerid)) return alert("Unable to get element [" + containerid + "]"); + + currentContainerid = containerid; + currentClassName = className; + currentTableid = tableid; + + var startRowIndex = 0; + var endRowIndex = getRowCount(); + + // paginate if required + if (pageSize > 0) { + startRowIndex = _currentPageIndex * pageSize; + endRowIndex = Math.min(getRowCount(), startRowIndex + pageSize); + } + + // create editablegrid table and add it to our container + this.table = document.createElement("table"); + table.className = className || "editablegrid"; + if (typeof tableid != "undefined") table.id = tableid; + while (_$(containerid).hasChildNodes()) _$(containerid).removeChild(_$(containerid).firstChild); + _$(containerid).appendChild(table); + + // create header + if (caption) { + var captionElement = document.createElement("CAPTION"); + captionElement.innerHTML = this.caption; + table.appendChild(captionElement); + } + + this.tHead = document.createElement("THEAD"); + table.appendChild(tHead); + var trHeader = tHead.insertRow(0); + var columnCount = getColumnCount(); + for (var c = 0; c < columnCount; c++) { + var headerCell = document.createElement("TH"); + var td = trHeader.appendChild(headerCell); + columns[c].headerRenderer._render(-1, c, td, columns[c].label); + } + + // create body and rows + this.tBody = document.createElement("TBODY"); + table.appendChild(tBody); + var insertRowIndex = 0; + for (var i = startRowIndex; i < endRowIndex; i++) { + var tr = tBody.insertRow(insertRowIndex++); + tr.rowId = data[i]['id']; + tr.id = this._getRowDOMId(data[i]['id']); + for (j = 0; j < columnCount; j++) { + + // create cell and render its content + var td = tr.insertCell(j); + columns[j].cellRenderer._render(i, j, td, getValueAt(i,j)); + } + } + + // attach handler on click or double click + _$(containerid).editablegrid = this; + if (doubleclick) _$(containerid).ondblclick = function(e) { this.editablegrid.mouseClicked(e); }; + else _$(containerid).onclick = function(e) { this.editablegrid.mouseClicked(e); }; + } + + // callback + tableRendered(containerid, className, tableid); + } + }; + + + /** + * Renders the grid as an HTML table in the document + * @param {String} containerid + * id of the div in which you wish to render the HTML table (this parameter is ignored if you used attachToHTMLTable) + * @param {String} className + * CSS class name to be applied to the table (this parameter is ignored if you used attachToHTMLTable) + * @param {String} tableid + * ID to give to the table (this parameter is ignored if you used attachToHTMLTable) + * @see EditableGrid#attachToHTMLTable + * @see EditableGrid#loadXML + */ + EditableGrid.prototype.renderGrid = function(containerid, className, tableid) + { + // restore stored parameters, or use default values if nothing stored + var pageIndex = this.localisset('pageIndex') ? parseInt(this.localget('pageIndex')) : 0; + this.sortedColumnName = this.localisset('sortColumnIndexOrName') && this.hasColumn(this.localget('sortColumnIndexOrName')) ? this.localget('sortColumnIndexOrName') : -1; + this.sortDescending = this.localisset('sortColumnIndexOrName') && this.localisset('sortDescending') ? this.localget('sortDescending') == 'true' : false; + this.currentFilter = this.localisset('filter') ? this.localget('filter') : null; + + // actually render grid + this.currentPageIndex = 0; + this._rendergrid(containerid, className, tableid); + + // sort and filter table + if (!this.serverSide) { + this.sort() ; + this.filter(); + } + + // go to stored page (or first if nothing stored) + this.setPageIndex(pageIndex < 0 ? 0 : pageIndex); + }; + + /** + * Refreshes the grid + * @return + */ + EditableGrid.prototype.refreshGrid = function() + { + if (this.currentContainerid != null) this.table = null; // if we are not in "attach mode", clear table to force a full re-render + this._rendergrid(this.currentContainerid, this.currentClassName, this.currentTableid); + }; + + /** + * Render all column headers + * @private + */ + EditableGrid.prototype._renderHeaders = function() + { + with (this) { + var rows = tHead.rows; + for (var i = 0; i < 1 /*rows.length*/; i++) { + var rowData = []; + var cols = rows[i].cells; + var columnIndexInModel = 0; + for (var j = 0; j < cols.length && columnIndexInModel < columns.length; j++) { + columns[columnIndexInModel].headerRenderer._render(-1, columnIndexInModel, cols[j], columns[columnIndexInModel].label); + var colspan = parseInt(cols[j].getAttribute("colspan")); + columnIndexInModel += colspan > 1 ? colspan : 1; + } + } + } + }; + + /** + * Mouse click handler + * @param {Object} e + * @private + */ + EditableGrid.prototype.mouseClicked = function(e) + { + e = e || window.event; + with (this) { + + // get row and column index from the clicked cell + var target = e.target || e.srcElement; + + // go up parents to find a cell or a link under the clicked position + while (target) if (target.tagName == "A" || target.tagName == "TD" || target.tagName == "TH") break; else target = target.parentNode; + if (!target || !target.parentNode || !target.parentNode.parentNode || (target.parentNode.parentNode.tagName != "TBODY" && target.parentNode.parentNode.tagName != "THEAD") || target.isEditing) return; + + // don't handle clicks on links + if (target.tagName == "A") return; + + // get cell position in table + var rowIndex = getRowIndex(target.parentNode); + var columnIndex = target.cellIndex; + + var column = columns[columnIndex]; + if (column) { + + // if another row has been selected: callback + if (rowIndex > -1 && rowIndex != lastSelectedRowIndex) { + rowSelected(lastSelectedRowIndex, rowIndex); + lastSelectedRowIndex = rowIndex; + } + + // edit current cell value + if (!column.editable) { readonlyWarning(column); } + else { + if (rowIndex < 0) { + if (column.headerEditor && isHeaderEditable(rowIndex, columnIndex)) + column.headerEditor.edit(rowIndex, columnIndex, target, column.label); + } + else if (column.cellEditor && isEditable(rowIndex, columnIndex)) + column.cellEditor.edit(rowIndex, columnIndex, target, getValueAt(rowIndex, columnIndex)); + } + } + } + }; + + /** + * Sort on a column + * @param {Object} columnIndexOrName index or name of the column + * @param {Boolean} descending + */ + EditableGrid.prototype.sort = function(columnIndexOrName, descending, backOnFirstPage) + { + with (this) { + + if (typeof columnIndexOrName == 'undefined' && sortedColumnName === -1) { + + // avoid a double render, but still send the expected callback + tableSorted(-1, sortDescending); + return true; + } + + if (typeof columnIndexOrName == 'undefined') columnIndexOrName = sortedColumnName; + if (typeof descending == 'undefined') descending = sortDescending; + + localset('sortColumnIndexOrName', columnIndexOrName); + localset('sortDescending', descending); + + // if filtering is done on server-side, we are done here + if (serverSide) return backOnFirstPage ? setPageIndex(0) : refreshGrid(); + + var columnIndex = columnIndexOrName; + if (parseInt(columnIndex, 10) !== -1) { + columnIndex = this.getColumnIndex(columnIndexOrName); + if (columnIndex < 0) { + alert("[sort] Invalid column: " + columnIndexOrName); + return false; + } + } + + if (!enableSort) { + tableSorted(columnIndex, descending); + return; + } + + // work on unfiltered data + var filterActive = dataUnfiltered != null; + if (filterActive) data = dataUnfiltered; + + var type = columnIndex < 0 ? "" : getColumnType(columnIndex); + var row_array = []; + var rowCount = getRowCount(); + for (var i = 0; i < rowCount - (ignoreLastRow ? 1 : 0); i++) row_array.push([columnIndex < 0 ? null : getDisplayValueAt(i, columnIndex), i, data[i].originalIndex]); + row_array.sort(columnIndex < 0 ? unsort : + type == "integer" || type == "double" ? sort_numeric : + type == "boolean" ? sort_boolean : + type == "date" ? sort_date : + sort_alpha); + + if (descending) row_array = row_array.reverse(); + if (ignoreLastRow) row_array.push([columnIndex < 0 ? null : getDisplayValueAt(rowCount - 1, columnIndex), rowCount - 1, data[rowCount - 1].originalIndex]); + + // rebuild data using the new order + var _data = data; + data = []; + for (var i = 0; i < row_array.length; i++) data.push(_data[row_array[i][1]]); + delete row_array; + + if (filterActive) { + + // keep only visible rows in data + dataUnfiltered = data; + data = []; + for (var r = 0; r < rowCount; r++) if (dataUnfiltered[r].visible) data.push(dataUnfiltered[r]); + } + + // refresh grid (back on first page if sort column has changed) and callback + if (backOnFirstPage) setPageIndex(0); else refreshGrid(); + tableSorted(columnIndex, descending); + return true; + } + }; + + + /** + * Filter the content of the table + * @param {String} filterString String string used to filter: all words must be found in the row + */ + EditableGrid.prototype.filter = function(filterString) + { + with (this) { + + if (typeof filterString != 'undefined') { + this.currentFilter = filterString; + this.localset('filter', filterString); + } + + // if filtering is done on server-side, we are done here + if (serverSide) return setPageIndex(0); + + // un-filter if no or empty filter set + if (currentFilter == null || currentFilter == "") { + if (dataUnfiltered != null) { + data = dataUnfiltered; + dataUnfiltered = null; + for (var r = 0; r < getRowCount(); r++) data[r].visible = true; + setPageIndex(0); + tableFiltered(); + } + return; + } + + var words = currentFilter.toLowerCase().split(" "); + + // work on unfiltered data + if (dataUnfiltered != null) data = dataUnfiltered; + + var rowCount = getRowCount(); + var columnCount = getColumnCount(); + for (var r = 0; r < rowCount; r++) { + var row = data[r]; + row.visible = true; + var rowContent = ""; + + // add column values + for (var c = 0; c < columnCount; c++) { + if (getColumnType(c) == 'boolean') continue; + var displayValue = getDisplayValueAt(r, c); + var value = getValueAt(r, c); + rowContent += displayValue + " " + (displayValue == value ? "" : value + " "); + } + + // add attribute values + for (var attributeName in row) { + if (attributeName != "visible" && attributeName != "originalIndex" && attributeName != "columns") rowContent += row[attributeName]; + } + + // if row contents do not match one word in the filter, hide the row + for (var i = 0; i < words.length; i++) { + var word = words[i]; + var match = false; + + // a word starting with "!" means that we want a NON match + var invertMatch = word.startsWith("!"); + if (invertMatch) word = word.substr(1); + + // if word is of the form "colname/attributename=value" or "colname/attributename!=value", only this column/attribute is used + var colindex = -1; + var attributeName = null; + if (word.contains("!=")) { + var parts = word.split("!="); + colindex = getColumnIndex(parts[0]); + if (colindex >= 0) { + word = parts[1]; + invertMatch = !invertMatch; + } + else if (typeof row[parts[0]] != 'undefined') { + attributeName = parts[0]; + word = parts[1]; + invertMatch = !invertMatch; + } + } + else if (word.contains("=")) { + var parts = word.split("="); + colindex = getColumnIndex(parts[0]); + if (colindex >= 0) word = parts[1]; + else if (typeof row[parts[0]] != 'undefined') { + attributeName = parts[0]; + word = parts[1]; + } + } + + // a word ending with "!" means that a column must match this word exactly + if (!word.endsWith("!")) { + if (colindex >= 0) match = (getValueAt(r, colindex) + ' ' + getDisplayValueAt(r, colindex)).trim().toLowerCase().indexOf(word) >= 0; + else if (attributeName !== null) match = (''+getRowAttribute(r, attributeName)).trim().toLowerCase().indexOf(word) >= 0; + else match = rowContent.toLowerCase().indexOf(word) >= 0; + } + else { + word = word.substr(0, word.length - 1); + if (colindex >= 0) match = (''+getDisplayValueAt(r, colindex)).trim().toLowerCase() == word || (''+getValueAt(r, colindex)).trim().toLowerCase() == word; + else if (attributeName !== null) match = (''+getRowAttribute(r, attributeName)).trim().toLowerCase() == word; + else for (var c = 0; c < columnCount; c++) { + if (getColumnType(c) == 'boolean') continue; + if ((''+getDisplayValueAt(r, c)).trim().toLowerCase() == word || (''+getValueAt(r, c)).trim().toLowerCase() == word) match = true; + } + } + + if (invertMatch ? match : !match) { + data[r].visible = false; + break; + } + } + } + + // keep only visible rows in data + dataUnfiltered = data; + data = []; + for (var r = 0; r < rowCount; r++) if (dataUnfiltered[r].visible) data.push(dataUnfiltered[r]); + + // refresh grid (back on first page) and callback + setPageIndex(0); + tableFiltered(); + } + }; + + /** + * Sets the page size(pageSize of 0 means no pagination) + * @param {Integer} pageSize Integer page size + */ + EditableGrid.prototype.setPageSize = function(pageSize) + { + this.pageSize = parseInt(pageSize); + if (isNaN(this.pageSize)) this.pageSize = 0; + this.currentPageIndex = 0; + this.refreshGrid(); + }; + + /** + * Returns the number of pages according to the current page size + */ + EditableGrid.prototype.getPageCount = function() + { + if (this.getRowCount() == 0) return 0; + if (this.pageCount > 0) return this.pageCount; // server side pagination + else if (this.pageSize <= 0) { alert("getPageCount: no or invalid page size defined (" + this.pageSize + ")"); return -1; } + return Math.ceil(this.getRowCount() / this.pageSize); + }; + + /** + * Returns the number of pages according to the current page size + */ + EditableGrid.prototype.getCurrentPageIndex = function() + { + if (this.pageSize <= 0 && !this.serverSide) return 0; + + // if page index does not exist anymore, go to last page (without losing the information of the current page) + return Math.max(0, this.currentPageIndex >= this.getPageCount() ? this.getPageCount() - 1 : this.currentPageIndex); + }; + + /** + * Sets the current page (no effect if pageSize is 0) + * @param {Integer} pageIndex Integer page index + */ + EditableGrid.prototype.setPageIndex = function(pageIndex) + { + this.currentPageIndex = pageIndex; + this.localset('pageIndex', pageIndex); + this.refreshGrid(); + }; + + /** + * Go the previous page if we are not already on the first page + * @return + */ + EditableGrid.prototype.prevPage = function() + { + if (this.canGoBack()) this.setPageIndex(this.getCurrentPageIndex() - 1); + }; + + /** + * Go the first page if we are not already on the first page + * @return + */ + EditableGrid.prototype.firstPage = function() + { + if (this.canGoBack()) this.setPageIndex(0); + }; + + /** + * Go the next page if we are not already on the last page + * @return + */ + EditableGrid.prototype.nextPage = function() + { + if (this.canGoForward()) this.setPageIndex(this.getCurrentPageIndex() + 1); + }; + + /** + * Go the last page if we are not already on the last page + * @return + */ + EditableGrid.prototype.lastPage = function() + { + if (this.canGoForward()) this.setPageIndex(this.getPageCount() - 1); + }; + + /** + * Returns true if we are not already on the first page + * @return + */ + EditableGrid.prototype.canGoBack = function() + { + return this.getCurrentPageIndex() > 0; + }; + + /** + * Returns true if we are not already on the last page + * @return + */ + EditableGrid.prototype.canGoForward = function() + { + return this.getCurrentPageIndex() < this.getPageCount() - 1; + }; + + /** + * Returns an interval { startPageIndex: ..., endPageIndex: ... } so that a window of the given size is visible around the current page (hence the 'sliding'). + * If pagination is not enabled this method displays an alert and returns null. + * If pagination is enabled but there is only one page this function returns null (wihtout error). + * @param slidingWindowSize size of the visible window + * @return + */ + EditableGrid.prototype.getSlidingPageInterval = function(slidingWindowSize) + { + var nbPages = this.getPageCount(); + if (nbPages <= 1) return null; + + var curPageIndex = this.getCurrentPageIndex(); + var startPageIndex = Math.max(0, curPageIndex - Math.floor(slidingWindowSize/2)); + var endPageIndex = Math.min(nbPages - 1, curPageIndex + Math.floor(slidingWindowSize/2)); + + if (endPageIndex - startPageIndex < slidingWindowSize) { + var diff = slidingWindowSize - (endPageIndex - startPageIndex + 1); + startPageIndex = Math.max(0, startPageIndex - diff); + endPageIndex = Math.min(nbPages - 1, endPageIndex + diff); + } + + return { startPageIndex: startPageIndex, endPageIndex: endPageIndex }; + }; + + /** + * Returns an array of page indices in the given interval. + * + * @param interval + * The given interval must be an object with properties 'startPageIndex' and 'endPageIndex'. + * This interval may for example have been obtained with getCurrentPageInterval. + * + * @param callback + * The given callback is applied to each page index before adding it to the result array. + * This callback is optional: if none given, the page index will be added as is to the array. + * If given , the callback will be called with two parameters: pageIndex (integer) and isCurrent (boolean). + * + * @return + */ + EditableGrid.prototype.getPagesInInterval = function(interval, callback) + { + var pages = []; + for (var p = interval.startPageIndex; p <= interval.endPageIndex; p++) { + pages.push(typeof callback == 'function' ? callback(p, p == this.getCurrentPageIndex()) : p); + } + return pages; + }; + + var EditableGrid_pending_charts = {}; +var EditableGrid_check_lib = true; + +function EditableGrid_loadChart(divId) +{ + var swf = findSWF(divId); + if (swf && typeof swf.load == "function") swf.load(JSON.stringify(EditableGrid_pending_charts[divId])); + else setTimeout("EditableGrid_loadChart('"+divId+"');", 100); +} + +function EditableGrid_get_chart_data(divId) +{ + setTimeout("EditableGrid_loadChart('"+divId+"');", 100); + return JSON.stringify(EditableGrid_pending_charts[divId]); +} + +EditableGrid.prototype.checkChartLib = function() +{ + EditableGrid_check_lib = false; + if (typeof JSON.stringify == 'undefined') { alert('This method needs the JSON javascript library'); return false; } + else if (typeof findSWF == 'undefined') { alert('This method needs the open flash chart javascript library (findSWF)'); return false; } + else if (typeof ofc_chart == 'undefined') { alert('This method needs the open flash chart javascript library (ofc_chart)'); return false; } + else if (typeof swfobject == 'undefined') { alert('This method needs the swfobject javascript library'); return false; } + else return true; +}; + +/** + * renderBarChart + * Render open flash bar chart for the data contained in the table model + * @param divId + * @param title + * @param labelColumnIndexOrName + * @param options: legend (label of labelColumnIndexOrName), bgColor (#ffffff), alpha (0.9), limit (0), bar3d (true), rotateXLabels (0) + * @return + */ +EditableGrid.prototype.renderBarChart = function(divId, title, labelColumnIndexOrName, options) +{ + with (this) { + + if (EditableGrid_check_lib && !checkChartLib()) return false; + + // default options + this.legend = null; + this.bgColor = "#ffffff"; + this.alpha = 0.9; + this.limit = 0; + this.bar3d = true; + this.rotateXLabels = 0; + + // override default options with the ones given + if (options) for (var p in options) this[p] = options[p]; + + labelColumnIndexOrName = labelColumnIndexOrName || 0; + var cLabel = getColumnIndex(labelColumnIndexOrName); + + var chart = new ofc_chart(); + chart.bg_colour = bgColor; + chart.set_title({text: title || '', style: "{font-size: 20px; color:#0000ff; font-family: Verdana; text-align: center;}"}); + + var columnCount = getColumnCount(); + var rowCount = getRowCount() - (ignoreLastRow ? 1 : 0); + if (limit > 0 && rowCount > limit) rowCount = limit; + + var maxvalue = 0; + for (var c = 0; c < columnCount; c++) { + if (!isColumnBar(c)) continue; + var bar = new ofc_element(bar3d ? "bar_3d" : "bar"); + bar.alpha = alpha; + bar.colour = smartColorsBar[chart.elements.length % smartColorsBar.length]; + bar.fill = "transparent"; + bar.text = getColumnLabel(c); + for (var r = 0; r < rowCount; r++) { + if (getRowAttribute(r, "skip") == "1") continue; + var value = getValueAt(r,c); + if (value > maxvalue) maxvalue = value; + bar.values.push(value); + } + chart.add_element(bar); + } + + // round the y max value + var ymax = 10; + while (ymax < maxvalue) ymax *= 10; + var dec_step = ymax / 10; + while (ymax - dec_step > maxvalue) ymax -= dec_step; + + var xLabels = []; + for (var r = 0; r < rowCount; r++) { + if (getRowAttribute(r, "skip") == "1") continue; + var label = getRowAttribute(r, "barlabel"); // if there is a barlabel attribute, use it and ignore labelColumn + xLabels.push(label ? label : getValueAt(r,cLabel)); + } + + chart.x_axis = { + stroke: 1, + tick_height: 10, + colour: "#E2E2E2", + "grid-colour": "#E2E2E2", + labels: { rotate: rotateXLabels, labels: xLabels }, + "3d": 5 + }; + + chart.y_axis = { + stroke: 4, + tick_length: 3, + colour: "#428BC7", + "grid-colour": "#E2E2E2", + offset: 0, + steps: ymax / 10.0, + max: ymax + }; + + // chart.num_decimals = 0; + + chart.x_legend = { + text: legend || getColumnLabel(labelColumnIndexOrName), + style: "{font-size: 11px; color: #000033}" + }; + + chart.y_legend = { + text: "", + style: "{font-size: 11px; color: #000033}" + }; + + updateChart(divId, chart); + } +}; + +/** + * renderStackedBarChart + * Render open flash stacked bar chart for the data contained in the table model + * @param divId + * @param title + * @param labelColumnIndexOrName + * @param options: legend (label of labelColumnIndexOrName), bgColor (#ffffff), alpha (0.8), limit (0), rotateXLabels (0) + * @return + */ +EditableGrid.prototype.renderStackedBarChart = function(divId, title, labelColumnIndexOrName, options) +{ + with (this) { + + if (EditableGrid_check_lib && !checkChartLib()) return false; + + // default options + this.legend = null; + this.bgColor = "#ffffff"; + this.alpha = 0.8; + this.limit = 0; + this.rotateXLabels = 0; + + // override default options with the ones given + if (options) for (var p in options) this[p] = options[p]; + + labelColumnIndexOrName = labelColumnIndexOrName || 0; + var cLabel = getColumnIndex(labelColumnIndexOrName); + + var chart = new ofc_chart(); + chart.bg_colour = bgColor; + chart.set_title({text: title || '', style: "{font-size: 20px; color:#0000ff; font-family: Verdana; text-align: center;}"}); + + var columnCount = getColumnCount(); + var rowCount = getRowCount() - (ignoreLastRow ? 1 : 0); + if (limit > 0 && rowCount > limit) rowCount = limit; + + var maxvalue = 0; + var bar = new ofc_element("bar_stack"); + bar.alpha = alpha; + bar.colours = smartColorsBar; + bar.fill = "transparent"; + bar.keys = []; + + for (var c = 0; c < columnCount; c++) { + if (!isColumnBar(c)) continue; + bar.keys.push({ colour: smartColorsBar[bar.keys.length % smartColorsBar.length], text: getColumnLabel(c), "font-size": '13' }); + } + + for (var r = 0; r < rowCount; r++) { + var valueRow = []; + var valueStack = 0; + for (var c = 0; c < columnCount; c++) { + if (!isColumnBar(c)) continue; + var value = getValueAt(r,c); + value = isNaN(value) ? 0 : value; + valueStack += value; + valueRow.push(value); + } + if (valueStack > maxvalue) maxvalue = valueStack; + bar.values.push(valueRow); + } + + chart.add_element(bar); + + // round the y max value + var ymax = 10; + while (ymax < maxvalue) ymax *= 10; + var dec_step = ymax / 10; + while (ymax - dec_step > maxvalue) ymax -= dec_step; + + var xLabels = []; + for (var r = 0; r < rowCount; r++) xLabels.push(getValueAt(r,cLabel)); + + chart.x_axis = { + stroke: 1, + tick_height: 10, + colour: "#E2E2E2", + "grid-colour": "#E2E2E2", + labels: { rotate: rotateXLabels, labels: xLabels }, + "3d": 5 + }; + + chart.y_axis = { + stroke: 4, + tick_length: 3, + colour: "#428BC7", + "grid-colour": "#E2E2E2", + offset: 0, + steps: ymax / 10.0, + max: ymax + }; + + // chart.num_decimals = 0; + + chart.x_legend = { + text: legend || getColumnLabel(labelColumnIndexOrName), + style: "{font-size: 11px; color: #000033}" + }; + + chart.y_legend = { + text: "", + style: "{font-size: 11px; color: #000033}" + }; + + updateChart(divId, chart); + } +}; + +/** + * renderPieChart + * @param divId + * @param title + * @param valueColumnIndexOrName + * @param labelColumnIndexOrName: if same as valueColumnIndexOrName, the chart will display the frequency of values in this column + * @param options: startAngle (0), bgColor (#ffffff), alpha (0.5), limit (0), gradientFill (true) + * @return + */ +EditableGrid.prototype.renderPieChart = function(divId, title, valueColumnIndexOrName, labelColumnIndexOrName, options) +{ + with (this) { + + if (EditableGrid_check_lib && !checkChartLib()) return false; + + // default options + this.startAngle = 0; + this.bgColor = "#ffffff"; + this.alpha = 0.5; + this.limit = 0; + this.gradientFill = true; + + // override default options with the ones given + if (options) for (var p in options) this[p] = options[p]; + + var type = getColumnType(valueColumnIndexOrName); + if (type != "double" && type != "integer" && valueColumnIndexOrName != labelColumnIndexOrName) return; + + labelColumnIndexOrName = labelColumnIndexOrName || 0; + title = (typeof title == 'undefined' || title === null) ? getColumnLabel(valueColumnIndexOrName) : title; + + var cValue = getColumnIndex(valueColumnIndexOrName); + var cLabel = getColumnIndex(labelColumnIndexOrName); + + var chart = new ofc_chart(); + chart.bg_colour = bgColor; + chart.set_title({text: title, style: "{font-size: 20px; color:#0000ff; font-family: Verdana; text-align: center;}"}); + + var rowCount = getRowCount() - (ignoreLastRow ? 1 : 0); + if (limit > 0 && rowCount > limit) rowCount = limit; + + var pie = new ofc_element("pie"); + pie.colours = smartColorsPie; + pie.alpha = alpha; + pie['gradient-fill'] = gradientFill; + + if (typeof startAngle != 'undefined' && startAngle !== null) pie['start-angle'] = startAngle; + + if (valueColumnIndexOrName == labelColumnIndexOrName) { + + // frequency pie chart + var distinctValues = {}; + for (var r = 0; r < rowCount; r++) { + var rowValue = getValueAt(r,cValue); + if (rowValue in distinctValues) distinctValues[rowValue]++; + else distinctValues[rowValue] = 1; + } + + for (var value in distinctValues) { + var occurences = distinctValues[value]; + pie.values.push({value : occurences, label: value + ' (' + (100 * (occurences / rowCount)).toFixed(1) + '%)'}); + } + } + else { + + var total = 0; + for (var r = 0; r < rowCount; r++) { + var rowValue = getValueAt(r,cValue); + total += isNaN(rowValue) ? 0 : rowValue; + } + + for (var r = 0; r < rowCount; r++) { + var value = getValueAt(r,cValue); + var label = getValueAt(r,cLabel); + if (!isNaN(value)) pie.values.push({value : value, label: label + ' (' + (100 * (value / total)).toFixed(1) + '%)'}); + } + } + + chart.add_element(pie); + + if (pie.values.length > 0) updateChart(divId, chart); + return pie.values.length; + } +}; + +/** + * updateChart + * @param divId + * @param chart + * @return + */ +EditableGrid.prototype.updateChart = function(divId, chart) +{ + if (typeof this.ofcSwf == 'undefined' || !this.ofcSwf) { + + // detect openflashchart swf location + this.ofcSwf = 'open-flash-chart.swf'; // defaults to current directory + var e = document.getElementsByTagName('script'); + for (var i = 0; i < e.length; i++) { + var index = e[i].src.indexOf('openflashchart'); + if (index != -1) { + this.ofcSwf = e[i].src.substr(0, index + 15) + this.ofcSwf; + break; + } + }; + } + + with (this) { + + // reload or create new swf chart + var swf = findSWF(divId); + if (swf && typeof swf.load == "function") swf.load(JSON.stringify(chart)); + else { + var div = _$(divId); + EditableGrid_pending_charts[divId] = chart; + + // get chart dimensions + var w = parseInt(getStyle(div, 'width')); + var h = parseInt(getStyle(div, 'height')); + w = Math.max(isNaN(w)?0:w, div.offsetWidth); + h = Math.max(isNaN(h)?0:h, div.offsetHeight); + + swfobject.embedSWF(this.ofcSwf, + divId, + "" + (w || 500), + "" + (h || 200), + "9.0.0", "expressInstall.swf", { "get-data": "EditableGrid_get_chart_data", "id": divId }, null, + { wmode: "Opaque", salign: "l", AllowScriptAccess:"always"} + ); + } + + chartRendered(); + } +}; + +/** + * clearChart + * @param divId + * @return + */ +EditableGrid.prototype.clearChart = function(divId) +{ + // how ? +}; + +/** + * Abstract cell editor + * @constructor + * @class Base class for all cell editors + */ + +function CellEditor(config) { this.init(config); } + +CellEditor.prototype.init = function(config) +{ + // override default properties with the ones given + if (config) for (var p in config) this[p] = config[p]; +}; + +CellEditor.prototype.edit = function(rowIndex, columnIndex, element, value) +{ + // tag element and remember all the things we need to apply/cancel edition + element.isEditing = true; + element.rowIndex = rowIndex; + element.columnIndex = columnIndex; + + // call the specialized getEditor method + var editorInput = this.getEditor(element, value); + if (!editorInput) return false; + + // give access to the cell editor and element from the editor widget + editorInput.element = element; + editorInput.celleditor = this; + + // listen to pressed keys + // - tab does not work with onkeyup (it's too late) + // - on Safari escape does not work with onkeypress + // - with onkeydown everything is fine (but don't forget to return false) + editorInput.onkeydown = function(event) { + + event = event || window.event; + + // ENTER or TAB: apply value + if (event.keyCode == 13 || event.keyCode == 9) { + + // backup onblur then remove it: it will be restored if editing could not be applied + this.onblur_backup = this.onblur; + this.onblur = null; + if (this.celleditor.applyEditing(this.element, this.celleditor.getEditorValue(this)) === false) this.onblur = this.onblur_backup; + return false; + } + + // ESC: cancel editing + if (event.keyCode == 27) { + this.onblur = null; + this.celleditor.cancelEditing(this.element); + return false; + } + }; + + // if simultaneous edition is not allowed, we cancel edition when focus is lost + if (!this.editablegrid.allowSimultaneousEdition) editorInput.onblur = this.editablegrid.saveOnBlur ? + function(event) { + + // backup onblur then remove it: it will be restored if editing could not be applied + this.onblur_backup = this.onblur; + this.onblur = null; + if (this.celleditor.applyEditing(this.element, this.celleditor.getEditorValue(this)) === false) this.onblur = this.onblur_backup; + } + : + function(event) { + this.onblur = null; + this.celleditor.cancelEditing(this.element); + }; + + // display the resulting editor widget + this.displayEditor(element, editorInput); + + // give focus to the created editor + editorInput.focus(); +}; + +CellEditor.prototype.getEditor = function(element, value) { + return null; +}; + +CellEditor.prototype.getEditorValue = function(editorInput) { + return editorInput.value; +}; + +CellEditor.prototype.formatValue = function(value) { + return value; +}; + +CellEditor.prototype.displayEditor = function(element, editorInput, adjustX, adjustY) +{ + // use same font in input as in cell content + editorInput.style.fontFamily = this.editablegrid.getStyle(element, "fontFamily", "font-family"); + editorInput.style.fontSize = this.editablegrid.getStyle(element, "fontSize", "font-size"); + + // static mode: add input field in the table cell + if (this.editablegrid.editmode == "static") { + while (element.hasChildNodes()) element.removeChild(element.firstChild); + element.appendChild(editorInput); + } + + // absolute mode: add input field in absolute position over table cell, leaving current content + if (this.editablegrid.editmode == "absolute") { + element.appendChild(editorInput); + editorInput.style.position = "absolute"; + + // position editor input on the cell with the same padding as the actual cell content (and center vertically if vertical-align is set to "middle") + var paddingLeft = this.editablegrid.paddingLeft(element); + var paddingTop = this.editablegrid.paddingTop(element); + var offsetScrollX = this.editablegrid.table.parentNode ? parseInt(this.editablegrid.table.parentNode.scrollLeft) : 0; + var offsetScrollY = this.editablegrid.table.parentNode ? parseInt(this.editablegrid.table.parentNode.scrollTop) : 0; + var vCenter = this.editablegrid.verticalAlign(element) == "middle" ? (element.offsetHeight - editorInput.offsetHeight) / 2 - paddingTop : 0; + editorInput.style.left = (this.editablegrid.getCellX(element) - offsetScrollX + paddingLeft + (adjustX ? adjustX : 0)) + "px"; + editorInput.style.top = (this.editablegrid.getCellY(element) - offsetScrollY + paddingTop + vCenter + (adjustY ? adjustY : 0)) + "px"; + + // if number type: align field and its content to the right + if (this.column.datatype == 'integer' || this.column.datatype == 'double') { + var rightPadding = this.editablegrid.getCellX(element) - offsetScrollX + element.offsetWidth - (parseInt(editorInput.style.left) + editorInput.offsetWidth); + editorInput.style.left = (parseInt(editorInput.style.left) + rightPadding) + "px"; + editorInput.style.textAlign = "right"; + } + } + + // fixed mode: don't show input field in the cell + if (this.editablegrid.editmode == "fixed") { + var editorzone = _$(this.editablegrid.editorzoneid); + while (editorzone.hasChildNodes()) editorzone.removeChild(editorzone.firstChild); + editorzone.appendChild(editorInput); + } +}; + +CellEditor.prototype._clearEditor = function(element) +{ + // untag element + element.isEditing = false; + + // clear fixed editor zone if any + if (this.editablegrid.editmode == "fixed") { + var editorzone = _$(this.editablegrid.editorzoneid); + while (editorzone.hasChildNodes()) editorzone.removeChild(editorzone.firstChild); + } +}; + +CellEditor.prototype.cancelEditing = function(element) +{ + with (this) { + + // check that the element is still being edited (otherwise onblur will be called on textfields that have been closed when we go to another tab in Firefox) + if (element && element.isEditing) { + + // render value before editon + var renderer = this == column.headerEditor ? column.headerRenderer : column.cellRenderer; + renderer._render(element.rowIndex, element.columnIndex, element, editablegrid.getValueAt(element.rowIndex, element.columnIndex)); + + _clearEditor(element); + } + } +}; + +CellEditor.prototype.applyEditing = function(element, newValue) +{ + with (this) { + + // check that the element is still being edited (otherwise onblur will be called on textfields that have been closed when we go to another tab in Firefox) + if (element && element.isEditing) { + + // do nothing if the value is rejected by at least one validator + if (!column.isValid(newValue)) return false; + + // format the value before applying + var formattedValue = formatValue(newValue); + + // update model and render cell (keeping previous value) + var previousValue = editablegrid.setValueAt(element.rowIndex, element.columnIndex, formattedValue); + + // if the new value is different than the previous one, let the user handle the model change + var newValue = editablegrid.getValueAt(element.rowIndex, element.columnIndex); + if (!this.editablegrid.isSame(newValue, previousValue)) { + editablegrid.modelChanged(element.rowIndex, element.columnIndex, previousValue, newValue, editablegrid.getRow(element.rowIndex)); + } + + _clearEditor(element); + return true; + } + + return false; + } +}; + +/** + * Text cell editor + * @constructor + * @class Class to edit a cell with an HTML text input + */ + +function TextCellEditor(size, maxlen, config) { + if (size) this.fieldSize = size; + if (maxlen) this.maxLength = maxlen; + if (config) this.init(config); +}; + +TextCellEditor.prototype = new CellEditor(); +TextCellEditor.prototype.fieldSize = -1; +TextCellEditor.prototype.maxLength = -1; +TextCellEditor.prototype.autoHeight = true; + +TextCellEditor.prototype.editorValue = function(value) { + return value; +}; + +TextCellEditor.prototype.updateStyle = function(htmlInput) +{ + // change style for invalid values + if (this.column.isValid(this.getEditorValue(htmlInput))) this.editablegrid.removeClassName(htmlInput, this.editablegrid.invalidClassName); + else this.editablegrid.addClassName(htmlInput, this.editablegrid.invalidClassName); +}; + +TextCellEditor.prototype.getEditor = function(element, value) +{ + // create and initialize text field + var htmlInput = document.createElement("input"); + htmlInput.setAttribute("type", "text"); + if (this.maxLength > 0) htmlInput.setAttribute("maxlength", this.maxLength); + + if (this.fieldSize > 0) htmlInput.setAttribute("size", this.fieldSize); + else htmlInput.style.width = this.editablegrid.autoWidth(element) + 'px'; // auto-adapt width to cell, if no length specified + + var autoHeight = this.editablegrid.autoHeight(element); + if (this.autoHeight) htmlInput.style.height = autoHeight + 'px'; // auto-adapt height to cell + htmlInput.value = this.editorValue(value); + + // listen to keyup to check validity and update style of input field + htmlInput.onkeyup = function(event) { this.celleditor.updateStyle(this); }; + + return htmlInput; +}; + +TextCellEditor.prototype.displayEditor = function(element, htmlInput) +{ + // call base method + CellEditor.prototype.displayEditor.call(this, element, htmlInput, -1 * this.editablegrid.borderLeft(htmlInput), -1 * (this.editablegrid.borderTop(htmlInput) + 1)); + + // update style of input field + this.updateStyle(htmlInput); + + // select text + htmlInput.select(); +}; + +/** + * Number cell editor + * @constructor + * @class Class to edit a numeric cell with an HTML text input + */ + +function NumberCellEditor(type) { this.type = type; } +NumberCellEditor.prototype = new TextCellEditor(-1, 32); + +// editorValue is called in getEditor to initialize field +NumberCellEditor.prototype.editorValue = function(value) { + return isNaN(value) ? "" : (value + '').replace('.', this.column.decimal_point); +}; + +// getEditorValue is called before passing to isValid and applyEditing +NumberCellEditor.prototype.getEditorValue = function(editorInput) { + return editorInput.value.replace(',', '.'); +}; + +// formatValue is called in applyEditing +NumberCellEditor.prototype.formatValue = function(value) +{ + return this.type == 'integer' ? parseInt(value) : parseFloat(value); +}; + +/** + * Select cell editor + * @constructor + * @class Class to edit a cell with an HTML select input + */ + +function SelectCellEditor(config) { + this.minWidth = 75; + this.minHeight = 22; + this.adaptHeight = true; + this.adaptWidth = true; + this.init(config); +} + +SelectCellEditor.prototype = new CellEditor(); +SelectCellEditor.prototype.getEditor = function(element, value) +{ + // create select list + var htmlInput = document.createElement("select"); + + // auto adapt dimensions to cell, with a min width + if (this.adaptWidth) htmlInput.style.width = Math.max(this.minWidth, this.editablegrid.autoWidth(element)) + 'px'; + if (this.adaptHeight) htmlInput.style.height = Math.max(this.minHeight, this.editablegrid.autoHeight(element)) + 'px'; + + // get column option values for this row + var optionValues = this.column.getOptionValuesForEdit(element.rowIndex); + + // add these options, selecting the current one + var index = 0, valueFound = false; + for (var optionValue in optionValues) { + + // if values are grouped + if (typeof optionValues[optionValue] == 'object') { + + var optgroup = document.createElement('optgroup'); + optgroup.label = optionValue; + htmlInput.appendChild(optgroup); + + var groupOptionValues = optionValues[optionValue]; + for (var optionValue in groupOptionValues) { + + var option = document.createElement('option'); + option.text = groupOptionValues[optionValue]; + option.value = optionValue; + optgroup.appendChild(option); + if (optionValue == value) { htmlInput.selectedIndex = index; valueFound = true; } + index++; + } + } + else { + + var option = document.createElement('option'); + option.text = optionValues[optionValue]; + option.value = optionValue; + // add does not work as expected in IE7 (cf. second arg) + try { htmlInput.add(option, null); } catch (e) { htmlInput.add(option); } + if (optionValue == value) { htmlInput.selectedIndex = index; valueFound = true; } + index++; + } + } + + // if the current value is not in the list add it to the front + if (!valueFound) { + var option = document.createElement('option'); + option.text = value ? value : ""; + option.value = value ? value : ""; + // add does not work as expected in IE7 (cf. second arg) + try { htmlInput.add(option, htmlInput.options[0]); } catch (e) { htmlInput.add(option); } + htmlInput.selectedIndex = 0; + } + + // when a new value is selected we apply it + htmlInput.onchange = function(event) { this.onblur = null; this.celleditor.applyEditing(this.element, this.value); }; + + return htmlInput; +}; + +/** + * Datepicker cell editor + * + * Text field editor with date picker capabilities. + * Uses the jQuery UI's datepicker. + * This editor is used automatically for date columns if we detect that the jQuery UI's datepicker is present. + * + * @constructor Accepts an option object containing the following properties: + * - fieldSize: integer (default=auto-adapt) + * - maxLength: integer (default=255) + * + * @class Class to edit a cell with a datepicker linked to the HTML text input + */ + +function DateCellEditor(config) +{ + // erase defaults with given options + this.init(config); +}; + +// inherits TextCellEditor functionalities +DateCellEditor.prototype = new TextCellEditor(); + +// redefine displayEditor to setup datepicker +DateCellEditor.prototype.displayEditor = function(element, htmlInput) +{ + // call base method + TextCellEditor.prototype.displayEditor.call(this, element, htmlInput); + + $(htmlInput).datepicker({ + dateFormat: this.editablegrid.dateFormat == "EU" ? "dd/mm/yy" : "mm/dd/yy", + beforeShow: function() { + // the field cannot be blurred until the datepicker has gone away + // otherwise we get the "missing instance data" exception + this.onblur_backup = this.onblur; + this.onblur = null; + }, + onClose: function(dateText) { + // apply date if any, otherwise call original onblur event + if (dateText != '') this.celleditor.applyEditing(htmlInput.element, dateText); + else if (this.onblur_backup != null) this.onblur_backup(); + + } + }).datepicker('show'); +}; + +/** + * Abstract cell renderer + * @constructor + * @class Base class for all cell renderers + * @param {Object} config + */ + +function CellRenderer(config) { this.init(config); } + +CellRenderer.prototype.init = function(config) +{ + // override default properties with the ones given + for (var p in config) this[p] = config[p]; +}; + +CellRenderer.prototype._render = function(rowIndex, columnIndex, element, value) +{ + // remember all the things we need + element.rowIndex = rowIndex; + element.columnIndex = columnIndex; + + // remove existing content + while (element.hasChildNodes()) element.removeChild(element.firstChild); + + // always apply the number style to numerical cells and column headers + if (this.column.isNumerical()) EditableGrid.prototype.addClassName(element, "number"); + + // always apply the boolean style to boolean column headers + if (this.column.datatype == 'boolean') EditableGrid.prototype.addClassName(element, "boolean"); + + // call the specialized render method + return this.render(element, typeof value == 'string' && this.column.datatype != "html" ? htmlspecialchars(value, 'ENT_NOQUOTES').replace(/\s\s/g, '  ') : value); +}; + +CellRenderer.prototype.render = function(element, value) +{ + element.innerHTML = value ? value : ""; +}; + +CellRenderer.prototype.getDisplayValue = function(rowIndex, value) +{ + return value; +}; + +/** + * Enum cell renderer + * @constructor + * @class Class to render a cell with enum values + */ + +function EnumCellRenderer(config) { this.init(config); } +EnumCellRenderer.prototype = new CellRenderer(); +EnumCellRenderer.prototype.getLabel = function(rowIndex, value) +{ + var label = ""; + if (typeof value != 'undefined') { + var optionValues = this.column.getOptionValuesForRender(rowIndex); + if (value in optionValues) label = optionValues[value]; + for (var optionValue in optionValues) if (typeof optionValues[optionValue] == 'object' && value in optionValues[optionValue]) label = optionValues[optionValue][value]; + if (label == "") { + var isNAN = typeof value == 'number' && isNaN(value); + label = isNAN ? "" : value; + } + } + return label; +}; + +EnumCellRenderer.prototype.render = function(element, value) +{ + element.innerHTML = this.getLabel(element.rowIndex, value); +}; + +EnumCellRenderer.prototype.getDisplayValue = function(rowIndex, value) +{ + // if the column has enumerated values, sort and filter on the value label + return this.getLabel(rowIndex, value); +}; + +/** + * Number cell renderer + * @constructor + * @class Class to render a cell with numerical values + */ + +function NumberCellRenderer(config) { this.init(config); } +NumberCellRenderer.prototype = new CellRenderer(); +NumberCellRenderer.prototype.render = function(element, value) +{ + var column = this.column || {}; // in case somebody calls new NumberCellRenderer().render(..) + + var isNAN = typeof value == 'number' && isNaN(value); + var displayValue = isNAN ? (column.nansymbol || "") : value; + if (typeof displayValue == 'number') { + + if (column.precision !== null) { + // displayValue = displayValue.toFixed(column.precision); + displayValue = number_format(displayValue, column.precision, column.decimal_point, column.thousands_separator); + } + + if (column.unit !== null) { + if (column.unit_before_number) displayValue = column.unit + ' ' + displayValue; + else displayValue = displayValue + ' ' + column.unit; + } + } + + element.innerHTML = displayValue; + element.style.fontWeight = isNAN ? "normal" : ""; +}; + +/** + * Checkbox cell renderer + * @constructor + * @class Class to render a cell with an HTML checkbox + */ + +function CheckboxCellRenderer(config) { this.init(config); } +CheckboxCellRenderer.prototype = new CellRenderer(); + +CheckboxCellRenderer.prototype._render = function(rowIndex, columnIndex, element, value) +{ + // if a checkbox already exists keep it, otherwise clear current content + if (element.firstChild && (typeof element.firstChild.getAttribute != "function" || element.firstChild.getAttribute("type") != "checkbox")) + while (element.hasChildNodes()) element.removeChild(element.firstChild); + + // remember all the things we need + element.rowIndex = rowIndex; + element.columnIndex = columnIndex; + + // call the specialized render method + return this.render(element, value); +}; + +CheckboxCellRenderer.prototype.render = function(element, value) +{ + // convert value to boolean just in case + value = (value && value != 0 && value != "false") ? true : false; + + // if check box already created, just update its state + if (element.firstChild) { element.firstChild.checked = value; return; } + + // create and initialize checkbox + var htmlInput = document.createElement("input"); + htmlInput.setAttribute("type", "checkbox"); + + // give access to the cell editor and element from the editor field + htmlInput.element = element; + htmlInput.cellrenderer = this; + + // this renderer is a little special because it allows direct edition + var cellEditor = new CellEditor(); + cellEditor.editablegrid = this.editablegrid; + cellEditor.column = this.column; + htmlInput.onclick = function(event) { + element.rowIndex = this.cellrenderer.editablegrid.getRowIndex(element.parentNode); // in case it has changed due to sorting or remove + element.isEditing = true; + cellEditor.applyEditing(element, htmlInput.checked ? true : false); + }; + + element.appendChild(htmlInput); + htmlInput.checked = value; + htmlInput.disabled = (!this.column.editable || !this.editablegrid.isEditable(element.rowIndex, element.columnIndex)); + + element.className = "boolean"; +}; + +/** + * Email cell renderer + * @constructor + * @class Class to render a cell with emails + */ + +function EmailCellRenderer(config) { this.init(config); } +EmailCellRenderer.prototype = new CellRenderer(); +EmailCellRenderer.prototype.render = function(element, value) +{ + element.innerHTML = value ? "" + value + "" : ""; +}; + +/** + * Website cell renderer + * @constructor + * @class Class to render a cell with websites + */ + +function WebsiteCellRenderer(config) { this.init(config); } +WebsiteCellRenderer.prototype = new CellRenderer(); +WebsiteCellRenderer.prototype.render = function(element, value) +{ + element.innerHTML = value ? "" + value + "" : ""; +}; + +/** + * Date cell renderer + * @constructor + * @class Class to render a cell containing a date + */ + +function DateCellRenderer(config) { this.init(config); } +DateCellRenderer.prototype = new CellRenderer; + +DateCellRenderer.prototype.render = function(cell, value) +{ + var date = this.editablegrid.checkDate(value); + if (typeof date == "object") cell.innerHTML = date.formattedDate; + else cell.innerHTML = value; +}; + +/** + * Sort header renderer + * @constructor + * @class Class to add sorting functionalities to headers + */ + +function SortHeaderRenderer(columnName, cellRenderer) { this.columnName = columnName; this.cellRenderer = cellRenderer; }; +SortHeaderRenderer.prototype = new CellRenderer(); +SortHeaderRenderer.prototype.render = function(cell, value) +{ + if (!value) { if (this.cellRenderer) this.cellRenderer.render(cell, value); } + else { + + // create a link that will sort (alternatively ascending/descending) + var link = document.createElement("a"); + cell.appendChild(link); + link.columnName = this.columnName; + link.style.cursor = "pointer"; + link.innerHTML = value; + link.editablegrid = this.editablegrid; + link.renderer = this; + link.onclick = function() { + with (this.editablegrid) { + + var cols = tHead.rows[0].cells; + var clearPrevious = -1; + var backOnFirstPage = false; + + if (sortedColumnName != this.columnName) { + clearPrevious = sortedColumnName; + sortedColumnName = this.columnName; + sortDescending = false; + backOnFirstPage = true; + } + else { + if (!sortDescending) sortDescending = true; + else { + clearPrevious = sortedColumnName; + sortedColumnName = -1; + sortDescending = false; + backOnFirstPage = true; + } + } + + // render header for previous sort column (not needed anymore since the grid is now fully refreshed after a sort - cf. possible pagination) + // var j = getColumnIndex(clearPrevious); + // if (j >= 0) columns[j].headerRenderer._render(-1, j, cols[j], columns[j].label); + + sort(sortedColumnName, sortDescending, backOnFirstPage); + + // render header for new sort column (not needed anymore since the grid is now fully refreshed after a sort - cf. possible pagination) + // var j = getColumnIndex(sortedColumnName); + // if (j >= 0) columns[j].headerRenderer._render(-1, j, cols[j], columns[j].label); + } + }; + + // add an arrow to indicate if sort is ascending or descending + if (this.editablegrid.sortedColumnName == this.columnName) { + cell.appendChild(document.createTextNode("\u00a0")); + cell.appendChild(this.editablegrid.sortDescending ? this.editablegrid.sortDownImage: this.editablegrid.sortUpImage); + } + + // call user renderer if any + if (this.cellRenderer) this.cellRenderer.render(cell, value); + } +}; + +EditableGrid.prototype.setCookie = function(c_name, value, exdays) +{ + var exdate = new Date(); + exdate.setDate(exdate.getDate() + exdays); + var c_value = escape(value) + ((exdays == null) ? "" : "; expires=" + exdate.toUTCString()); + document.cookie = c_name + "=" + c_value; +}; + +EditableGrid.prototype.getCookie = function(c_name) +{ + var _cookies = document.cookie.split(";"); + for (var i = 0; i < _cookies.length; i++) { + var x = _cookies[i].substr(0, _cookies[i].indexOf("=")); + var y = _cookies[i].substr(_cookies[i].indexOf("=") + 1); + x = x.replace(/^\s+|\s+$/g, ""); + if (x == c_name) return unescape(y); + } + + return null; +}; + +EditableGrid.prototype.has_local_storage = function() +{ + try { return 'localStorage' in window && window['localStorage'] !== null; } catch(e) { return false; } +}; + +EditableGrid.prototype._localset = function(key, value) +{ + if (this.has_local_storage()) localStorage.setItem(key, value); + else this.setCookie(key, value, null); +}; + +EditableGrid.prototype._localget = function(key) +{ + if (this.has_local_storage()) return localStorage.getItem(key); + return this.getCookie(key); +}; + +EditableGrid.prototype._localisset = function(key) +{ + if (this.has_local_storage()) return localStorage.getItem(key) !== null; + return this.getCookie(key) !== null; +}; + +EditableGrid.prototype.localset = function(key, value) +{ + if (this.enableStore) return this._localset(this.name + '_' + key, value); +}; + +EditableGrid.prototype.localget = function(key) +{ + return this.enableStore ? this._localget(this.name + '_' + key) : null; +}; + +EditableGrid.prototype.localisset = function(key) +{ + return this.enableStore ? this._localget(this.name + '_' + key) !== null : false; +}; + +EditableGrid.prototype.unsort = function(a,b) +{ + // at index 2 we have the originalIndex + aa = isNaN(a[2]) ? 0 : parseFloat(a[2]); + bb = isNaN(b[2]) ? 0 : parseFloat(b[2]); + return aa-bb; +}; + +EditableGrid.prototype.sort_numeric = function(a,b) +{ + aa = isNaN(a[0]) ? 0 : parseFloat(a[0]); + bb = isNaN(b[0]) ? 0 : parseFloat(b[0]); + return aa-bb; +}; + +EditableGrid.prototype.sort_boolean = function(a,b) +{ + aa = !a[0] || a[0] == "false" ? 0 : 1; + bb = !b[0] || b[0] == "false" ? 0 : 1; + return aa-bb; +}; + +EditableGrid.prototype.sort_alpha = function(a,b) +{ + if (a[0].toLowerCase()==b[0].toLowerCase()) return 0; + return a[0].toLowerCase().localeCompare(b[0].toLowerCase()); +}; + +EditableGrid.prototype.sort_date = function(a,b) +{ + date = EditableGrid.prototype.checkDate(a[0]); + aa = typeof date == "object" ? date.sortDate : 0; + date = EditableGrid.prototype.checkDate(b[0]); + bb = typeof date == "object" ? date.sortDate : 0; + return aa-bb; +}; + +/** + * Returns computed style property for element + * @private + */ +EditableGrid.prototype.getStyle = function(element, stylePropCamelStyle, stylePropCSSStyle) +{ + stylePropCSSStyle = stylePropCSSStyle || stylePropCamelStyle; + if (element.currentStyle) return element.currentStyle[stylePropCamelStyle]; + else if (window.getComputedStyle) return document.defaultView.getComputedStyle(element,null).getPropertyValue(stylePropCSSStyle); + return element.style[stylePropCamelStyle]; +}; + +/** + * Returns true if the element has a static positioning + * @private + */ +EditableGrid.prototype.isStatic = function (element) +{ + var position = this.getStyle(element, 'position'); + return (!position || position == "static"); +}; + +EditableGrid.prototype.verticalAlign = function (element) +{ + return this.getStyle(element, "verticalAlign", "vertical-align"); +}; + +EditableGrid.prototype.paddingLeft = function (element) +{ + var padding = parseInt(this.getStyle(element, "paddingLeft", "padding-left")); + return isNaN(padding) ? 0 : Math.max(0, padding); +}; + +EditableGrid.prototype.paddingRight = function (element) +{ + var padding = parseInt(this.getStyle(element, "paddingRight", "padding-right")); + return isNaN(padding) ? 0 : Math.max(0, padding); +}; + +EditableGrid.prototype.paddingTop = function (element) +{ + var padding = parseInt(this.getStyle(element, "paddingTop", "padding-top")); + return isNaN(padding) ? 0 : Math.max(0, padding); +}; + +EditableGrid.prototype.paddingBottom = function (element) +{ + var padding = parseInt(this.getStyle(element, "paddingBottom", "padding-bottom")); + return isNaN(padding) ? 0 : Math.max(0, padding); +}; + +EditableGrid.prototype.borderLeft = function (element) +{ + var border_l = parseInt(this.getStyle(element, "borderRightWidth", "border-right-width")); + var border_r = parseInt(this.getStyle(element, "borderLeftWidth", "border-left-width")); + border_l = isNaN(border_l) ? 0 : border_l; + border_r = isNaN(border_r) ? 0 : border_r; + return Math.max(border_l, border_r); +}; + +EditableGrid.prototype.borderRight = function (element) +{ + return this.borderLeft(element); +}; + +EditableGrid.prototype.borderTop = function (element) +{ + var border_t = parseInt(this.getStyle(element, "borderTopWidth", "border-top-width")); + var border_b = parseInt(this.getStyle(element, "borderBottomWidth", "border-bottom-width")); + border_t = isNaN(border_t) ? 0 : border_t; + border_b = isNaN(border_b) ? 0 : border_b; + return Math.max(border_t, border_b); +}; + +EditableGrid.prototype.borderBottom = function (element) +{ + return this.borderTop(element); +}; + +/** + * Returns auto width for editor + * @private + */ +EditableGrid.prototype.autoWidth = function (element) +{ + return element.offsetWidth - this.paddingLeft(element) - this.paddingRight(element) - this.borderLeft(element) - this.borderRight(element); +}; + +/** + * Returns auto height for editor + * @private + */ +EditableGrid.prototype.autoHeight = function (element) +{ + return element.offsetHeight - this.paddingTop(element) - this.paddingBottom(element) - this.borderTop(element) - this.borderBottom(element); +}; + +/** + * Detects the directory when the js sources can be found + * @private + */ +EditableGrid.prototype.detectDir = function() +{ + var base = location.href; + var e = document.getElementsByTagName('base'); + for (var i=0; i 0 && (element.className == className || new RegExp("(^|\\s)" + className + "(\\s|$)").test(element.className))); }; +EditableGrid.prototype.addClassName = function(element, className) { if (!this.hasClassName(element, className)) element.className += (element.className ? ' ' : '') + className; }; +EditableGrid.prototype.removeClassName = function(element, className) { element.className = this.strip(element.className.replace(new RegExp("(^|\\s+)" + className + "(\\s+|$)"), ' ')); }; + +/** + * Useful string methods + * @private + */ +String.prototype.trim = function() { return (this.replace(/^[\s\xA0]+/, "").replace(/[\s\xA0]+$/, "")); }; +String.prototype.contains = function(str) { return (this.match(str)==str); }; +String.prototype.startsWith = function(str) { return (this.match("^"+str)==str); }; +String.prototype.endsWith = function(str) { return (this.match(str+"$")==str); }; + +// Accepted formats: (for EU just switch month and day) +// +// mm-dd-yyyy +// mm/dd/yyyy +// mm.dd.yyyy +// mm dd yyyy +// mmm dd yyyy +// mmddyyyy +// +// m-d-yyyy +// m/d/yyyy +// m.d.yyyy, +// m d yyyy +// mmm d yyyy +// +// // m-d-yy +// // m/d/yy +// // m.d.yy +// // m d yy, +// // mmm d yy (yy is 20yy) + +/** + * Checks validity of a date string + * @private + */ +EditableGrid.prototype.checkDate = function(strDate, strDatestyle) +{ + strDatestyle = strDatestyle || this.dateFormat; + strDatestyle = strDatestyle || "EU"; + + var strDate; + var strDateArray; + var strDay; + var strMonth; + var strYear; + var intday; + var intMonth; + var intYear; + var booFound = false; + var strSeparatorArray = new Array("-"," ","/","."); + var intElementNr; + var err = 0; + + var strMonthArray = this.shortMonthNames; + strMonthArray = strMonthArray || ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"]; + + if (!strDate || strDate.length < 1) return 0; + + for (intElementNr = 0; intElementNr < strSeparatorArray.length; intElementNr++) { + if (strDate.indexOf(strSeparatorArray[intElementNr]) != -1) { + strDateArray = strDate.split(strSeparatorArray[intElementNr]); + if (strDateArray.length != 3) return 1; + else { + strDay = strDateArray[0]; + strMonth = strDateArray[1]; + strYear = strDateArray[2]; + } + booFound = true; + } + } + + if (booFound == false) { + if (strDate.length <= 5) return 1; + strDay = strDate.substr(0, 2); + strMonth = strDate.substr(2, 2); + strYear = strDate.substr(4); + } + + // if (strYear.length == 2) strYear = '20' + strYear; + + // US style + if (strDatestyle == "US") { + strTemp = strDay; + strDay = strMonth; + strMonth = strTemp; + } + + // get and check day + intday = parseInt(strDay, 10); + if (isNaN(intday)) return 2; + + // get and check month + intMonth = parseInt(strMonth, 10); + if (isNaN(intMonth)) { + for (i = 0;i<12;i++) { + if (strMonth.toUpperCase() == strMonthArray[i].toUpperCase()) { + intMonth = i+1; + strMonth = strMonthArray[i]; + i = 12; + } + } + if (isNaN(intMonth)) return 3; + } + if (intMonth>12 || intMonth<1) return 5; + + // get and check year + intYear = parseInt(strYear, 10); + if (isNaN(intYear)) return 4; + if (intYear < 70) { intYear = 2000 + intYear; strYear = '' + intYear; } // 70 become 1970, 69 becomes 1969, as with PHP's date_parse_from_format + if (intYear < 100) { intYear = 1900 + intYear; strYear = '' + intYear; } + if (intYear < 1900 || intYear > 2100) return 11; + + // check day in month + if ((intMonth == 1 || intMonth == 3 || intMonth == 5 || intMonth == 7 || intMonth == 8 || intMonth == 10 || intMonth == 12) && (intday > 31 || intday < 1)) return 6; + if ((intMonth == 4 || intMonth == 6 || intMonth == 9 || intMonth == 11) && (intday > 30 || intday < 1)) return 7; + if (intMonth == 2) { + if (intday < 1) return 8; + if (LeapYear(intYear) == true) { if (intday > 29) return 9; } + else if (intday > 28) return 10; + } + + // return formatted date + return { + formattedDate: (strDatestyle == "US" ? strMonthArray[intMonth-1] + " " + intday+" " + strYear : intday + " " + strMonthArray[intMonth-1]/*.toLowerCase()*/ + " " + strYear), + sortDate: Date.parse(intMonth + "/" + intday + "/" + intYear), + dbDate: intYear + "-" + intMonth + "-" + intday + }; +}; + +function LeapYear(intYear) +{ + if (intYear % 100 == 0) { if (intYear % 400 == 0) return true; } + else if ((intYear % 4) == 0) return true; + return false; +} + +// See RFC3986 +URI = function(uri) +{ + this.scheme = null; + this.authority = null; + this.path = ''; + this.query = null; + this.fragment = null; + + this.parse = function(uri) { + var m = uri.match(/^(([A-Za-z][0-9A-Za-z+.-]*)(:))?((\/\/)([^\/?#]*))?([^?#]*)((\?)([^#]*))?((#)(.*))?/); + this.scheme = m[3] ? m[2] : null; + this.authority = m[5] ? m[6] : null; + this.path = m[7]; + this.query = m[9] ? m[10] : null; + this.fragment = m[12] ? m[13] : null; + return this; + }; + + this.toString = function() { + var result = ''; + if(this.scheme != null) result = result + this.scheme + ':'; + if(this.authority != null) result = result + '//' + this.authority; + if(this.path != null) result = result + this.path; + if(this.query != null) result = result + '?' + this.query; + if(this.fragment != null) result = result + '#' + this.fragment; + return result; + }; + + this.toAbsolute = function(base) { + var base = new URI(base); + var r = this; + var t = new URI; + + if(base.scheme == null) return false; + + if(r.scheme != null && r.scheme.toLowerCase() == base.scheme.toLowerCase()) { + r.scheme = null; + } + + if(r.scheme != null) { + t.scheme = r.scheme; + t.authority = r.authority; + t.path = removeDotSegments(r.path); + t.query = r.query; + } else { + if(r.authority != null) { + t.authority = r.authority; + t.path = removeDotSegments(r.path); + t.query = r.query; + } else { + if(r.path == '') { + t.path = base.path; + if(r.query != null) { + t.query = r.query; + } else { + t.query = base.query; + } + } else { + if(r.path.substr(0,1) == '/') { + t.path = removeDotSegments(r.path); + } else { + if(base.authority != null && base.path == '') { + t.path = '/'+r.path; + } else { + t.path = base.path.replace(/[^\/]+$/,'')+r.path; + } + t.path = removeDotSegments(t.path); + } + t.query = r.query; + } + t.authority = base.authority; + } + t.scheme = base.scheme; + } + t.fragment = r.fragment; + + return t; + }; + + function removeDotSegments(path) { + var out = ''; + while(path) { + if(path.substr(0,3)=='../' || path.substr(0,2)=='./') { + path = path.replace(/^\.+/,'').substr(1); + } else if(path.substr(0,3)=='/./' || path=='/.') { + path = '/'+path.substr(3); + } else if(path.substr(0,4)=='/../' || path=='/..') { + path = '/'+path.substr(4); + out = out.replace(/\/?[^\/]*$/, ''); + } else if(path=='.' || path=='..') { + path = ''; + } else { + var rm = path.match(/^\/?[^\/]*/)[0]; + path = path.substr(rm.length); + out = out + rm; + } + } + return out; + } + + if(uri) { + this.parse(uri); + } +}; + +function get_html_translation_table (table, quote_style) { + // http://kevin.vanzonneveld.net + // + original by: Philip Peterson + // + revised by: Kevin van Zonneveld (http://kevin.vanzonneveld.net) + // + bugfixed by: noname + // + bugfixed by: Alex + // + bugfixed by: Marco + // + bugfixed by: madipta + // + improved by: KELAN + // + improved by: Brett Zamir (http://brett-zamir.me) + // + bugfixed by: Brett Zamir (http://brett-zamir.me) + // + input by: Frank Forte + // + bugfixed by: T.Wild + // + input by: Ratheous + // % note: It has been decided that we're not going to add global + // % note: dependencies to php.js, meaning the constants are not + // % note: real constants, but strings instead. Integers are also supported if someone + // % note: chooses to create the constants themselves. + // * example 1: get_html_translation_table('HTML_SPECIALCHARS'); + // * returns 1: {'"': '"', '&': '&', '<': '<', '>': '>'} + + var entities = {}, hash_map = {}, decimal = 0, symbol = ''; + var constMappingTable = {}, constMappingQuoteStyle = {}; + var useTable = {}, useQuoteStyle = {}; + + // Translate arguments + constMappingTable[0] = 'HTML_SPECIALCHARS'; + constMappingTable[1] = 'HTML_ENTITIES'; + constMappingQuoteStyle[0] = 'ENT_NOQUOTES'; + constMappingQuoteStyle[2] = 'ENT_COMPAT'; + constMappingQuoteStyle[3] = 'ENT_QUOTES'; + + useTable = !isNaN(table) ? constMappingTable[table] : table ? table.toUpperCase() : 'HTML_SPECIALCHARS'; + useQuoteStyle = !isNaN(quote_style) ? constMappingQuoteStyle[quote_style] : quote_style ? quote_style.toUpperCase() : 'ENT_COMPAT'; + + if (useTable !== 'HTML_SPECIALCHARS' && useTable !== 'HTML_ENTITIES') { + throw new Error("Table: "+useTable+' not supported'); + // return false; + } + + entities['38'] = '&'; + if (useTable === 'HTML_ENTITIES') { + entities['160'] = ' '; + entities['161'] = '¡'; + entities['162'] = '¢'; + entities['163'] = '£'; + entities['164'] = '¤'; + entities['165'] = '¥'; + entities['166'] = '¦'; + entities['167'] = '§'; + entities['168'] = '¨'; + entities['169'] = '©'; + entities['170'] = 'ª'; + entities['171'] = '«'; + entities['172'] = '¬'; + entities['173'] = '­'; + entities['174'] = '®'; + entities['175'] = '¯'; + entities['176'] = '°'; + entities['177'] = '±'; + entities['178'] = '²'; + entities['179'] = '³'; + entities['180'] = '´'; + entities['181'] = 'µ'; + entities['182'] = '¶'; + entities['183'] = '·'; + entities['184'] = '¸'; + entities['185'] = '¹'; + entities['186'] = 'º'; + entities['187'] = '»'; + entities['188'] = '¼'; + entities['189'] = '½'; + entities['190'] = '¾'; + entities['191'] = '¿'; + entities['192'] = 'À'; + entities['193'] = 'Á'; + entities['194'] = 'Â'; + entities['195'] = 'Ã'; + entities['196'] = 'Ä'; + entities['197'] = 'Å'; + entities['198'] = 'Æ'; + entities['199'] = 'Ç'; + entities['200'] = 'È'; + entities['201'] = 'É'; + entities['202'] = 'Ê'; + entities['203'] = 'Ë'; + entities['204'] = 'Ì'; + entities['205'] = 'Í'; + entities['206'] = 'Î'; + entities['207'] = 'Ï'; + entities['208'] = 'Ð'; + entities['209'] = 'Ñ'; + entities['210'] = 'Ò'; + entities['211'] = 'Ó'; + entities['212'] = 'Ô'; + entities['213'] = 'Õ'; + entities['214'] = 'Ö'; + entities['215'] = '×'; + entities['216'] = 'Ø'; + entities['217'] = 'Ù'; + entities['218'] = 'Ú'; + entities['219'] = 'Û'; + entities['220'] = 'Ü'; + entities['221'] = 'Ý'; + entities['222'] = 'Þ'; + entities['223'] = 'ß'; + entities['224'] = 'à'; + entities['225'] = 'á'; + entities['226'] = 'â'; + entities['227'] = 'ã'; + entities['228'] = 'ä'; + entities['229'] = 'å'; + entities['230'] = 'æ'; + entities['231'] = 'ç'; + entities['232'] = 'è'; + entities['233'] = 'é'; + entities['234'] = 'ê'; + entities['235'] = 'ë'; + entities['236'] = 'ì'; + entities['237'] = 'í'; + entities['238'] = 'î'; + entities['239'] = 'ï'; + entities['240'] = 'ð'; + entities['241'] = 'ñ'; + entities['242'] = 'ò'; + entities['243'] = 'ó'; + entities['244'] = 'ô'; + entities['245'] = 'õ'; + entities['246'] = 'ö'; + entities['247'] = '÷'; + entities['248'] = 'ø'; + entities['249'] = 'ù'; + entities['250'] = 'ú'; + entities['251'] = 'û'; + entities['252'] = 'ü'; + entities['253'] = 'ý'; + entities['254'] = 'þ'; + entities['255'] = 'ÿ'; + } + + if (useQuoteStyle !== 'ENT_NOQUOTES') { + entities['34'] = '"'; + } + if (useQuoteStyle === 'ENT_QUOTES') { + entities['39'] = '''; + } + entities['60'] = '<'; + entities['62'] = '>'; + + + // ascii decimals to real symbols + for (decimal in entities) { + symbol = String.fromCharCode(decimal); + hash_map[symbol] = entities[decimal]; + } + + return hash_map; +} + +function htmlentities(string, quote_style) +{ + var hash_map = {}, symbol = '', tmp_str = ''; + tmp_str = string.toString(); + if (false === (hash_map = get_html_translation_table('HTML_ENTITIES', quote_style))) return false; + hash_map["'"] = '''; + for (symbol in hash_map) tmp_str = tmp_str.split(symbol).join(hash_map[symbol]); + return tmp_str; +} + +function htmlspecialchars(string, quote_style) +{ + var hash_map = {}, symbol = '', tmp_str = ''; + tmp_str = string.toString(); + if (false === (hash_map = get_html_translation_table('HTML_SPECIALCHARS', quote_style))) return false; + for (symbol in hash_map) tmp_str = tmp_str.split(symbol).join(hash_map[symbol]); + return tmp_str; +} + +function number_format (number, decimals, dec_point, thousands_sep) { + // http://kevin.vanzonneveld.net + // + original by: Jonas Raoni Soares Silva (http://www.jsfromhell.com) + // + improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net) + // + bugfix by: Michael White (http://getsprink.com) + // + bugfix by: Benjamin Lupton + // + bugfix by: Allan Jensen (http://www.winternet.no) + // + revised by: Jonas Raoni Soares Silva (http://www.jsfromhell.com) + // + bugfix by: Howard Yeend + // + revised by: Luke Smith (http://lucassmith.name) + // + bugfix by: Diogo Resende + // + bugfix by: Rival + // + input by: Kheang Hok Chin (http://www.distantia.ca/) + // + improved by: davook + // + improved by: Brett Zamir (http://brett-zamir.me) + // + input by: Jay Klehr + // + improved by: Brett Zamir (http://brett-zamir.me) + // + input by: Amir Habibi (http://www.residence-mixte.com/) + // + bugfix by: Brett Zamir (http://brett-zamir.me) + // + improved by: Theriault + // + input by: Amirouche + // + improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net) + // * example 1: number_format(1234.56); + // * returns 1: '1,235' + // * example 2: number_format(1234.56, 2, ',', ' '); + // * returns 2: '1 234,56' + // * example 3: number_format(1234.5678, 2, '.', ''); + // * returns 3: '1234.57' + // * example 4: number_format(67, 2, ',', '.'); + // * returns 4: '67,00' + // * example 5: number_format(1000); + // * returns 5: '1,000' + // * example 6: number_format(67.311, 2); + // * returns 6: '67.31' + // * example 7: number_format(1000.55, 1); + // * returns 7: '1,000.6' + // * example 8: number_format(67000, 5, ',', '.'); + // * returns 8: '67.000,00000' + // * example 9: number_format(0.9, 0); + // * returns 9: '1' + // * example 10: number_format('1.20', 2); + // * returns 10: '1.20' + // * example 11: number_format('1.20', 4); + // * returns 11: '1.2000' + // * example 12: number_format('1.2000', 3); + // * returns 12: '1.200' + // * example 13: number_format('1 000,50', 2, '.', ' '); + // * returns 13: '100 050.00' + // Strip all characters but numerical ones. + number = (number + '').replace(/[^0-9+\-Ee.]/g, ''); + var n = !isFinite(+number) ? 0 : +number, + prec = !isFinite(+decimals) ? 0 : /*Math.abs(*/decimals/*)*/, + sep = (typeof thousands_sep === 'undefined') ? ',' : thousands_sep, + dec = (typeof dec_point === 'undefined') ? '.' : dec_point, + s = '', + toFixedFix = function (n, prec) { + var k = Math.pow(10, prec); + return '' + Math.round(n * k) / k; + }; + // Fix for IE parseFloat(0.55).toFixed(0) = 0; + s = (prec < 0 ? ('' + n) : (prec ? toFixedFix(n, prec) : '' + Math.round(n))).split('.'); + if (s[0].length > 3) { + s[0] = s[0].replace(/\B(?=(?:\d{3})+(?!\d))/g, sep); + } + if ((s[1] || '').length < prec) { + s[1] = s[1] || ''; + s[1] += new Array(prec - s[1].length + 1).join('0'); + } + return s.join(dec); +} + +/** + * Abstract cell validator + * @constructor + * @class Base class for all cell validators + */ + +function CellValidator(config) +{ + // default properties + var props = { isValid: null }; + + // override default properties with the ones given + for (var p in props) if (typeof config != 'undefined' && typeof config[p] != 'undefined') this[p] = config[p]; +} + +CellValidator.prototype.isValid = function(value) +{ + return true; +}; + +/** + * Number cell validator + * @constructor + * @class Class to validate a numeric cell + */ + +function NumberCellValidator(type) { this.type = type; } +NumberCellValidator.prototype = new CellValidator; +NumberCellValidator.prototype.isValid = function(value) +{ + // check that it is a valid number + if (isNaN(value)) return false; + + // for integers check that it's not a float + if (this.type == "integer" && value != "" && parseInt(value) != parseFloat(value)) return false; + + // the integer or double is valid + return true; +}; + +/** + * Email cell validator + * @constructor + * @class Class to validate a cell containing an email + */ + +function EmailCellValidator() {} +EmailCellValidator.prototype = new CellValidator; +EmailCellValidator.prototype.isValid = function(value) { return value == "" || /^([A-Za-z0-9_\-\.])+\@([A-Za-z0-9_\-\.])+\.([A-Za-z]{2,4})$/.test(value); }; + +/** + * Website cell validator + * @constructor + * @class Class to validate a cell containing a website + */ + +function WebsiteCellValidator() {} +WebsiteCellValidator.prototype = new CellValidator; +WebsiteCellValidator.prototype.isValid = function(value) { return value == "" || (value.indexOf(".") > 0 && value.indexOf(".") < (value.length - 2)); }; + +/** + * Date cell validator + * @constructor + * @augments CellValidator + * @class Class to validate a cell containing a date + */ + +function DateCellValidator(grid) { this.grid = grid; } +DateCellValidator.prototype = new CellValidator; + +DateCellValidator.prototype.isValid = function(value) +{ + return value == "" || typeof this.grid.checkDate(value) == "object"; +}; + + return EditableGrid; + +}); diff --git a/htdocs/js/lib/vendor/jquery-drag-drop/css/ui-lightness/images/ui-bg_diagonals-thick_18_b81900_40x40.png b/htdocs/js/lib/vendor/jquery-drag-drop/css/ui-lightness/images/ui-bg_diagonals-thick_18_b81900_40x40.png new file mode 100755 index 000000000..954e22dbd Binary files /dev/null and b/htdocs/js/lib/vendor/jquery-drag-drop/css/ui-lightness/images/ui-bg_diagonals-thick_18_b81900_40x40.png differ diff --git a/htdocs/js/lib/vendor/jquery-drag-drop/css/ui-lightness/images/ui-bg_diagonals-thick_20_666666_40x40.png b/htdocs/js/lib/vendor/jquery-drag-drop/css/ui-lightness/images/ui-bg_diagonals-thick_20_666666_40x40.png new file mode 100755 index 000000000..64ece5707 Binary files /dev/null and b/htdocs/js/lib/vendor/jquery-drag-drop/css/ui-lightness/images/ui-bg_diagonals-thick_20_666666_40x40.png differ diff --git a/htdocs/js/lib/vendor/jquery-drag-drop/css/ui-lightness/images/ui-bg_flat_10_000000_40x100.png b/htdocs/js/lib/vendor/jquery-drag-drop/css/ui-lightness/images/ui-bg_flat_10_000000_40x100.png new file mode 100755 index 000000000..abdc01082 Binary files /dev/null and b/htdocs/js/lib/vendor/jquery-drag-drop/css/ui-lightness/images/ui-bg_flat_10_000000_40x100.png differ diff --git a/htdocs/js/lib/vendor/jquery-drag-drop/css/ui-lightness/images/ui-bg_glass_100_f6f6f6_1x400.png b/htdocs/js/lib/vendor/jquery-drag-drop/css/ui-lightness/images/ui-bg_glass_100_f6f6f6_1x400.png new file mode 100755 index 000000000..9b383f4d2 Binary files /dev/null and b/htdocs/js/lib/vendor/jquery-drag-drop/css/ui-lightness/images/ui-bg_glass_100_f6f6f6_1x400.png differ diff --git a/htdocs/js/lib/vendor/jquery-drag-drop/css/ui-lightness/images/ui-bg_glass_100_fdf5ce_1x400.png b/htdocs/js/lib/vendor/jquery-drag-drop/css/ui-lightness/images/ui-bg_glass_100_fdf5ce_1x400.png new file mode 100755 index 000000000..a23baad25 Binary files /dev/null and b/htdocs/js/lib/vendor/jquery-drag-drop/css/ui-lightness/images/ui-bg_glass_100_fdf5ce_1x400.png differ diff --git a/htdocs/js/lib/vendor/jquery-drag-drop/css/ui-lightness/images/ui-bg_glass_65_ffffff_1x400.png b/htdocs/js/lib/vendor/jquery-drag-drop/css/ui-lightness/images/ui-bg_glass_65_ffffff_1x400.png new file mode 100755 index 000000000..42ccba269 Binary files /dev/null and b/htdocs/js/lib/vendor/jquery-drag-drop/css/ui-lightness/images/ui-bg_glass_65_ffffff_1x400.png differ diff --git a/htdocs/js/lib/vendor/jquery-drag-drop/css/ui-lightness/images/ui-bg_gloss-wave_35_f6a828_500x100.png b/htdocs/js/lib/vendor/jquery-drag-drop/css/ui-lightness/images/ui-bg_gloss-wave_35_f6a828_500x100.png new file mode 100755 index 000000000..1b1972b56 Binary files /dev/null and b/htdocs/js/lib/vendor/jquery-drag-drop/css/ui-lightness/images/ui-bg_gloss-wave_35_f6a828_500x100.png differ diff --git a/htdocs/js/lib/vendor/jquery-drag-drop/css/ui-lightness/images/ui-bg_highlight-soft_100_eeeeee_1x100.png b/htdocs/js/lib/vendor/jquery-drag-drop/css/ui-lightness/images/ui-bg_highlight-soft_100_eeeeee_1x100.png new file mode 100755 index 000000000..f1273672d Binary files /dev/null and b/htdocs/js/lib/vendor/jquery-drag-drop/css/ui-lightness/images/ui-bg_highlight-soft_100_eeeeee_1x100.png differ diff --git a/htdocs/js/lib/vendor/jquery-drag-drop/css/ui-lightness/images/ui-bg_highlight-soft_75_ffe45c_1x100.png b/htdocs/js/lib/vendor/jquery-drag-drop/css/ui-lightness/images/ui-bg_highlight-soft_75_ffe45c_1x100.png new file mode 100755 index 000000000..32f86222a Binary files /dev/null and b/htdocs/js/lib/vendor/jquery-drag-drop/css/ui-lightness/images/ui-bg_highlight-soft_75_ffe45c_1x100.png differ diff --git a/htdocs/js/lib/vendor/jquery-drag-drop/css/ui-lightness/images/ui-icons_222222_256x240.png b/htdocs/js/lib/vendor/jquery-drag-drop/css/ui-lightness/images/ui-icons_222222_256x240.png new file mode 100755 index 000000000..b273ff111 Binary files /dev/null and b/htdocs/js/lib/vendor/jquery-drag-drop/css/ui-lightness/images/ui-icons_222222_256x240.png differ diff --git a/htdocs/js/lib/vendor/jquery-drag-drop/css/ui-lightness/images/ui-icons_228ef1_256x240.png b/htdocs/js/lib/vendor/jquery-drag-drop/css/ui-lightness/images/ui-icons_228ef1_256x240.png new file mode 100755 index 000000000..a641a371a Binary files /dev/null and b/htdocs/js/lib/vendor/jquery-drag-drop/css/ui-lightness/images/ui-icons_228ef1_256x240.png differ diff --git a/htdocs/js/lib/vendor/jquery-drag-drop/css/ui-lightness/images/ui-icons_ef8c08_256x240.png b/htdocs/js/lib/vendor/jquery-drag-drop/css/ui-lightness/images/ui-icons_ef8c08_256x240.png new file mode 100755 index 000000000..85e63e9f6 Binary files /dev/null and b/htdocs/js/lib/vendor/jquery-drag-drop/css/ui-lightness/images/ui-icons_ef8c08_256x240.png differ diff --git a/htdocs/js/lib/vendor/jquery-drag-drop/css/ui-lightness/images/ui-icons_ffd27a_256x240.png b/htdocs/js/lib/vendor/jquery-drag-drop/css/ui-lightness/images/ui-icons_ffd27a_256x240.png new file mode 100755 index 000000000..e117effa3 Binary files /dev/null and b/htdocs/js/lib/vendor/jquery-drag-drop/css/ui-lightness/images/ui-icons_ffd27a_256x240.png differ diff --git a/htdocs/js/lib/vendor/jquery-drag-drop/css/ui-lightness/images/ui-icons_ffffff_256x240.png b/htdocs/js/lib/vendor/jquery-drag-drop/css/ui-lightness/images/ui-icons_ffffff_256x240.png new file mode 100755 index 000000000..42f8f992c Binary files /dev/null and b/htdocs/js/lib/vendor/jquery-drag-drop/css/ui-lightness/images/ui-icons_ffffff_256x240.png differ diff --git a/htdocs/js/lib/vendor/jquery-drag-drop/css/ui-lightness/jquery-ui-1.9.2.custom.css b/htdocs/js/lib/vendor/jquery-drag-drop/css/ui-lightness/jquery-ui-1.9.2.custom.css new file mode 100755 index 000000000..16fb4743f --- /dev/null +++ b/htdocs/js/lib/vendor/jquery-drag-drop/css/ui-lightness/jquery-ui-1.9.2.custom.css @@ -0,0 +1,280 @@ +/*! jQuery UI - v1.9.2 - 2012-11-26 +* http://jqueryui.com +* Includes: jquery.ui.core.css, jquery.ui.resizable.css, jquery.ui.selectable.css +* To view and modify this theme, visit http://jqueryui.com/themeroller/?ffDefault=Trebuchet%20MS%2CTahoma%2CVerdana%2CArial%2Csans-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 +* Copyright (c) 2012 jQuery Foundation and other contributors Licensed MIT */ + +/* Layout helpers +----------------------------------*/ +.ui-helper-hidden { display: none; } +.ui-helper-hidden-accessible { border: 0; clip: rect(0 0 0 0); height: 1px; margin: -1px; overflow: hidden; padding: 0; position: absolute; width: 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:before, .ui-helper-clearfix:after { content: ""; display: table; } +.ui-helper-clearfix:after { clear: both; } +.ui-helper-clearfix { zoom: 1; } +.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%; } +.ui-resizable { position: relative;} +.ui-resizable-handle { position: absolute;font-size: 0.1px; 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;}.ui-selectable-helper { position: absolute; z-index: 100; border:1px dotted black; } + +/* 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, .ui-state-hover a:link, .ui-state-hover a:visited { 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; } + +/* 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; } +.ui-state-disabled .ui-icon { filter:Alpha(Opacity=35); } /* For IE8 - See #6059 */ + +/* 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-on { background-position: -96px -144px; } +.ui-icon-radio-off { 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: .5;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: .2;filter:Alpha(Opacity=20); -moz-border-radius: 5px; -khtml-border-radius: 5px; -webkit-border-radius: 5px; border-radius: 5px; } \ No newline at end of file diff --git a/htdocs/js/lib/vendor/jquery-drag-drop/css/ui-lightness/jquery-ui-1.9.2.custom.min.css b/htdocs/js/lib/vendor/jquery-drag-drop/css/ui-lightness/jquery-ui-1.9.2.custom.min.css new file mode 100755 index 000000000..088c799e8 --- /dev/null +++ b/htdocs/js/lib/vendor/jquery-drag-drop/css/ui-lightness/jquery-ui-1.9.2.custom.min.css @@ -0,0 +1,5 @@ +/*! jQuery UI - v1.9.2 - 2012-11-26 +* http://jqueryui.com +* Includes: jquery.ui.core.css, jquery.ui.resizable.css, jquery.ui.selectable.css +* To view and modify this theme, visit http://jqueryui.com/themeroller/?ffDefault=Trebuchet%20MS%2CTahoma%2CVerdana%2CArial%2Csans-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 +* Copyright (c) 2012 jQuery Foundation and other contributors Licensed MIT */.ui-helper-hidden{display:none}.ui-helper-hidden-accessible{border:0;clip:rect(0 0 0 0);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width: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:before,.ui-helper-clearfix:after{content:"";display:table}.ui-helper-clearfix:after{clear:both}.ui-helper-clearfix{zoom:1}.ui-helper-zfix{width:100%;height:100%;top:0;left:0;position:absolute;opacity:0;filter:Alpha(Opacity=0)}.ui-state-disabled{cursor:default!important}.ui-icon{display:block;text-indent:-99999px;overflow:hidden;background-repeat:no-repeat}.ui-widget-overlay{position:absolute;top:0;left:0;width:100%;height:100%}.ui-resizable{position:relative}.ui-resizable-handle{position:absolute;font-size:0.1px;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}.ui-selectable-helper{position:absolute;z-index:100;border:1px dotted black}.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 #ddd;background:#eee url(images/ui-bg_highlight-soft_100_eeeeee_1x100.png) 50% top repeat-x;color:#333}.ui-widget-content a{color:#333}.ui-widget-header{border:1px solid #e78f08;background:#f6a828 url(images/ui-bg_gloss-wave_35_f6a828_500x100.png) 50% 50% repeat-x;color:#fff;font-weight:bold}.ui-widget-header a{color:#fff}.ui-state-default,.ui-widget-content .ui-state-default,.ui-widget-header .ui-state-default{border:1px solid #ccc;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,.ui-state-hover a:link,.ui-state-hover a:visited{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:#fff 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-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:#fff}.ui-state-error a,.ui-widget-content .ui-state-error a,.ui-widget-header .ui-state-error a{color:#fff}.ui-state-error-text,.ui-widget-content .ui-state-error-text,.ui-widget-header .ui-state-error-text{color:#fff}.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}.ui-state-disabled .ui-icon{filter:Alpha(Opacity=35)}.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)}.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-on{background-position:-96px -144px}.ui-icon-radio-off{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{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}.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}.ui-widget-overlay{background:#666 url(images/ui-bg_diagonals-thick_20_666666_40x40.png) 50% 50% repeat;opacity:.5;filter:Alpha(Opacity=50)}.ui-widget-shadow{margin:-5px 0 0 -5px;padding:5px;background:#000 url(images/ui-bg_flat_10_000000_40x100.png) 50% 50% repeat-x;opacity:.2;filter:Alpha(Opacity=20);-moz-border-radius:5px;-khtml-border-radius:5px;-webkit-border-radius:5px;border-radius:5px} \ No newline at end of file diff --git a/htdocs/js/lib/vendor/jquery-drag-drop/development-bundle/AUTHORS.txt b/htdocs/js/lib/vendor/jquery-drag-drop/development-bundle/AUTHORS.txt new file mode 100755 index 000000000..02e2d31cf --- /dev/null +++ b/htdocs/js/lib/vendor/jquery-drag-drop/development-bundle/AUTHORS.txt @@ -0,0 +1,217 @@ +Authors ordered by first contribution +A list of current team members is available at http://jqueryui.com/about + +Paul Bakaus +Richard Worth +Yehuda Katz +Sean Catchpole +John Resig +Tane Piper +Dmitri Gaskin +Klaus Hartl +Stefan Petre +Gilles van den Hoven +Micheil Bryan Smith +Jörn Zaefferer +Marc Grabanski +Keith Wood +Brandon Aaron +Scott González +Eduardo Lundgren +Aaron Eisenberger +Joan Piedra +Bruno Basto +Remy Sharp +Bohdan Ganicky +David Bolter +Chi Cheng +Ca-Phun Ung +Ariel Flesler +Maggie Costello Wachs +Scott Jehl +Todd Parker +Andrew Powell +Brant Burnett +Douglas Neiner +Paul Irish +Ralph Whitbeck +Thibault Duplessis +Dominique Vincent +Jack Hsu +Adam Sontag +Carl Fürstenberg +Kevin Dalman +Alberto Fernández Capel +Jacek Jędrzejewski (http://jacek.jedrzejewski.name) +Ting Kuei +Samuel Cormier-Iijima +Jon Palmer +Ben Hollis +Justin MacCarthy +Eyal Kobrigo +Tiago Freire +Diego Tres +Holger Rüprich +Ziling Zhao +Mike Alsup +Robson Braga Araujo +Pierre-Henri Ausseil +Christopher McCulloh +Andrew Newcomb +Lim Chee Aun +Jorge Barreiro +Daniel Steigerwald +John Firebaugh +John Enters +Andrey Kapitcyn +Dmitry Petrov +Eric Hynds +Chairat Sunthornwiphat +Josh Varner +Stéphane Raimbault +Jay Merrifield +J. Ryan Stinnett +Peter Heiberg +Alex Dovenmuehle +Jamie Gegerson +Raymond Schwartz +Phillip Barnes +Kyle Wilkinson +Khaled AlHourani +Marian Rudzynski +Jean-Francois Remy +Doug Blood +Filippo Cavallarin +Heiko Henning +Aliaksandr Rahalevich +Mario Visic +Xavi Ramirez +Max Schnur +Saji Nediyanchath +Corey Frang +Aaron Peterson +Ivan Peters +Mohamed Cherif Bouchelaghem +Marcos Sousa +Michael DellaNoce +George Marshall +Tobias Brunner +Martin Solli +David Petersen +Dan Heberden +William Kevin Manire +Gilmore Davidson +Michael Wu +Adam Parod +Guillaume Gautreau +Marcel Toele +Dan Streetman +Matt Hoskins +Giovanni Giacobbi +Kyle Florence +Pavol Hluchý +Hans Hillen +Mark Johnson +Trey Hunner +Shane Whittet +Edward A Faulkner +Adam Baratz +Kato Kazuyoshi +Eike Send +Kris Borchers +Eddie Monge +Israel Tsadok +Carson McDonald +Jason Davies +Garrison Locke +David Murdoch +Benjamin Scott Boyle +Jesse Baird +Jonathan Vingiano +Dylan Just +Hiroshi Tomita +Glenn Goodrich +Tarafder Ashek-E-Elahi +Ryan Neufeld +Marc Neuwirth +Philip Graham +Benjamin Sterling +Wesley Walser +Kouhei Sutou +Karl Kirch +Chris Kelly +Jay Oster +Alexander Polomoshnov +David Leal +Igor Milla +Dave Methvin +Florian Gutmann +Marwan Al Jubeh +Milan Broum +Sebastian Sauer +Gaëtan Muller +Michel Weimerskirch +William Griffiths +Stojce Slavkovski +David Soms +David De Sloovere +Michael P. Jung +Shannon Pekary +Matthew Edward Hutton +James Khoury +Rob Loach +Alberto Monteiro +Alex Rhea +Krzysztof Rosiński +Ryan Olton +Genie <386@mail.com> +Rick Waldron +Ian Simpson +Lev Kitsis +Ted VanToll +Justin Domnitz +Douglas Cerna +Bert ter Heide +Jasvir Nagra +Petr Hromadko +Harri Kilpiö +Lado Lomidze +Amir E. Aharoni +Simon Sattes +Jo Liss +Guntupalli Karunakar +Shahyar Ghobadpour +Lukasz Lipinski +Timo Tijhof +Jason Moon +Martin Frost +Eneko Illarramendi +EungJun Yi +Courtland Allen +Viktar Varvanovich +Danny Trunk +Pavel Stetina +Michael Stay +Steven Roussey +Michael Hollis +Lee Rowlands +Timmy Willison +Karl Swedberg +Baoju Yuan +Maciej Mroziński +Luis Dalmolin +Mark Aaron Shirley +Martin Hoch +Jiayi Yang +Philipp Benjamin Köppchen +Sindre Sorhus +Bernhard Sirlinger +Jared A. Scheel +Rafael Xavier de Souza +John Chen +Dale Kocian +Mike Sherov +Andrew Couch +Marc-Andre Lafortune +Avinash R +Cory Gackenheimer diff --git a/htdocs/js/lib/vendor/jquery-drag-drop/development-bundle/MIT-LICENSE.txt b/htdocs/js/lib/vendor/jquery-drag-drop/development-bundle/MIT-LICENSE.txt new file mode 100755 index 000000000..741585591 --- /dev/null +++ b/htdocs/js/lib/vendor/jquery-drag-drop/development-bundle/MIT-LICENSE.txt @@ -0,0 +1,26 @@ +Copyright 2012 jQuery Foundation and other contributors, +http://jqueryui.com/ + +This software consists of voluntary contributions made by many +individuals (AUTHORS.txt, http://jqueryui.com/about) For exact +contribution history, see the revision history and logs, available +at http://jquery-ui.googlecode.com/svn/ + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/htdocs/js/lib/vendor/jquery-drag-drop/development-bundle/README.md b/htdocs/js/lib/vendor/jquery-drag-drop/development-bundle/README.md new file mode 100755 index 000000000..e7ae90e8a --- /dev/null +++ b/htdocs/js/lib/vendor/jquery-drag-drop/development-bundle/README.md @@ -0,0 +1,99 @@ +[jQuery UI](http://jqueryui.com/) - Interactions and Widgets for the web +================================ + +jQuery UI provides interactions like Drag and Drop and widgets like Autocomplete, Tabs and Slider and makes these as easy to use as jQuery itself. + +If you want to use jQuery UI, go to [jqueryui.com](http://jqueryui.com) to get started. Or visit the [Using jQuery UI Forum](http://forum.jquery.com/using-jquery-ui) for discussions and questions. + +If you are interested in helping develop jQuery UI, you are in the right place. +To discuss development with team members and the community, visit the [Developing jQuery UI Forum](http://forum.jquery.com/developing-jquery-ui) or in #jquery on irc.freednode.net. + + +For contributors +--- + +If you want to help and provide a patch for a bugfix or new feature, please take +a few minutes and look at [our Getting Involved guide](http://wiki.jqueryui.com/w/page/35263114/Getting-Involved). +In particular check out the [Coding standards](http://wiki.jqueryui.com/w/page/12137737/Coding-standards) +and [Commit Message Style Guide](http://wiki.jqueryui.com/w/page/25941597/Commit-Message-Style-Guide). + +In general, fork the project, create a branch for a specific change and send a +pull request for that branch. Don't mix unrelated changes. You can use the commit +message as the description for the pull request. + + +Running the Unit Tests +--- + +Run the unit tests with a local server that supports PHP. No database is required. Pre-configured php local servers are available for Windows and Mac. Here are some options: + +- Windows: [WAMP download](http://www.wampserver.com/en/) +- Mac: [MAMP download](http://www.mamp.info/en/index.html) +- Linux: [Setting up LAMP](https://www.linux.com/learn/tutorials/288158-easy-lamp-server-installation) +- [Mongoose (most platforms)](http://code.google.com/p/mongoose/) + + +Building jQuery UI +--- + +jQuery UI uses the [grunt](http://github.com/cowboy/grunt) build system. Building jQuery UI requires node.js and a command line zip program. + +Install grunt. + +`npm install grunt -g` + +Clone the jQuery UI git repo. + +`git clone git://github.com/jquery/jquery-ui.git` + +`cd jquery-ui` + +Install node modules. + +`npm install` + +Run grunt. + +`grunt build` + +There are many other tasks that can be run through grunt. For a list of all tasks: + +`grunt --help` + + +For committers +--- + +When looking at pull requests, first check for [proper commit messages](http://wiki.jqueryui.com/w/page/12137724/Bug-Fixing-Guide). + +Do not merge pull requests directly through GitHub's interface. +Most pull requests are a single commit; cherry-picking will avoid creating a merge commit. +It's also common for contributors to make minor fixes in an additional one or two commits. +These should be squashed before landing in master. + +**Make sure the author has a valid name and email address associated with the commit.** + +Fetch the remote first: + + git fetch [their-fork.git] [their-branch] + +Then cherry-pick the commit(s): + + git cherry-pick [sha-of-commit] + +If you need to edit the commit message: + + git cherry-pick -e [sha-of-commit] + +If you need to edit the changes: + + git cherry-pick -n [sha-of-commit] + # make changes + git commit --author="[author-name-and-email]" + +If it should go to the stable brach, cherry-pick it to stable: + + git checkout 1-8-stable + git cherry-pick -x [sha-of-commit-from-master] + +*NOTE: Do not cherry-pick into 1-8-stable until you have pushed the commit from master upstream.* diff --git a/htdocs/js/lib/vendor/jquery-drag-drop/development-bundle/demos/demos.css b/htdocs/js/lib/vendor/jquery-drag-drop/development-bundle/demos/demos.css new file mode 100755 index 000000000..da9ad833a --- /dev/null +++ b/htdocs/js/lib/vendor/jquery-drag-drop/development-bundle/demos/demos.css @@ -0,0 +1,19 @@ +body { + font-size: 62.5%; + font-family: "Trebuchet MS", "Arial", "Helvetica", "Verdana", "sans-serif"; +} + +table { + font-size: 1em; +} + +.demo-description { + clear: both; + padding: 12px; + font-size: 1.3em; + line-height: 1.4em; +} + +.ui-draggable, .ui-droppable { + background-position: top; +} diff --git a/htdocs/js/lib/vendor/jquery-drag-drop/development-bundle/demos/draggable/constrain-movement.html b/htdocs/js/lib/vendor/jquery-drag-drop/development-bundle/demos/draggable/constrain-movement.html new file mode 100755 index 000000000..ddc833688 --- /dev/null +++ b/htdocs/js/lib/vendor/jquery-drag-drop/development-bundle/demos/draggable/constrain-movement.html @@ -0,0 +1,58 @@ + + + + + jQuery UI Draggable - Constrain movement + + + + + + + + + + + + +

      Constrain movement along an axis:

      + +
      +

      I can be dragged only vertically

      +
      + +
      +

      I can be dragged only horizontally

      +
      + +

      Or to within another DOM element:

      +
      +
      +

      I'm contained within the box

      +
      + +
      +

      I'm contained within my parent

      +
      +
      + +
      +

      Constrain the movement of each draggable by defining the boundaries of the draggable area. Set the axis option to limit the draggable's path to the x- or y-axis, or use the containment option to specify a parent DOM element or a jQuery selector, like 'document.'

      +
      + + diff --git a/htdocs/js/lib/vendor/jquery-drag-drop/development-bundle/demos/draggable/cursor-style.html b/htdocs/js/lib/vendor/jquery-drag-drop/development-bundle/demos/draggable/cursor-style.html new file mode 100755 index 000000000..bf35721f8 --- /dev/null +++ b/htdocs/js/lib/vendor/jquery-drag-drop/development-bundle/demos/draggable/cursor-style.html @@ -0,0 +1,42 @@ + + + + + jQuery UI Draggable - Cursor style + + + + + + + + + + + + +
      +

      I will always stick to the center (relative to the mouse)

      +
      + +
      +

      My cursor is at left -5 and top -5

      +
      + +
      +

      My cursor position is only controlled for the 'bottom' value

      +
      + +
      +

      Position the cursor while dragging the object. By default the cursor appears in the center of the dragged object; use the cursorAt option to specify another location relative to the draggable (specify a pixel value from the top, right, bottom, and/or left). Customize the cursor's appearance by supplying the cursor option with a valid CSS cursor value: default, move, pointer, crosshair, etc.

      +
      + + diff --git a/htdocs/js/lib/vendor/jquery-drag-drop/development-bundle/demos/draggable/default.html b/htdocs/js/lib/vendor/jquery-drag-drop/development-bundle/demos/draggable/default.html new file mode 100755 index 000000000..32ed8bfde --- /dev/null +++ b/htdocs/js/lib/vendor/jquery-drag-drop/development-bundle/demos/draggable/default.html @@ -0,0 +1,32 @@ + + + + + jQuery UI Draggable - Default functionality + + + + + + + + + + + + +
      +

      Drag me around

      +
      + +
      +

      Enable draggable functionality on any DOM element. Move the draggable object by clicking on it with the mouse and dragging it anywhere within the viewport.

      +
      + + diff --git a/htdocs/js/lib/vendor/jquery-drag-drop/development-bundle/demos/draggable/delay-start.html b/htdocs/js/lib/vendor/jquery-drag-drop/development-bundle/demos/draggable/delay-start.html new file mode 100755 index 000000000..0e0ee9f58 --- /dev/null +++ b/htdocs/js/lib/vendor/jquery-drag-drop/development-bundle/demos/draggable/delay-start.html @@ -0,0 +1,38 @@ + + + + + jQuery UI Draggable - Delay start + + + + + + + + + + + + +
      +

      Only if you drag me by 20 pixels, the dragging will start

      +
      + +
      +

      Regardless of the distance, you have to drag and wait for 1000ms before dragging starts

      +
      + +
      +

      Delay the start of dragging for a number of milliseconds with the delay option; prevent dragging until the cursor is held down and dragged a specifed number of pixels with the distance option.

      +
      + + diff --git a/htdocs/js/lib/vendor/jquery-drag-drop/development-bundle/demos/draggable/events.html b/htdocs/js/lib/vendor/jquery-drag-drop/development-bundle/demos/draggable/events.html new file mode 100755 index 000000000..4146cd6a8 --- /dev/null +++ b/htdocs/js/lib/vendor/jquery-drag-drop/development-bundle/demos/draggable/events.html @@ -0,0 +1,70 @@ + + + + + jQuery UI Draggable - Events + + + + + + + + + + + + +
      + +

      Drag me to trigger the chain of events.

      + +
        +
      • "start" invoked 0x
      • +
      • "drag" invoked 0x
      • +
      • "stop" invoked 0x
      • +
      +
      + +
      +

      Layer functionality onto the draggable using the start, drag, and stop events. Start is fired at the start of the drag; drag during the drag; and stop when dragging stops.

      +
      + + diff --git a/htdocs/js/lib/vendor/jquery-drag-drop/development-bundle/demos/draggable/handle.html b/htdocs/js/lib/vendor/jquery-drag-drop/development-bundle/demos/draggable/handle.html new file mode 100755 index 000000000..0dc540a80 --- /dev/null +++ b/htdocs/js/lib/vendor/jquery-drag-drop/development-bundle/demos/draggable/handle.html @@ -0,0 +1,41 @@ + + + + + jQuery UI Draggable - Handles + + + + + + + + + + + + +
      +

      I can be dragged only by this handle

      +
      + +
      +

      You can drag me around…

      +

      …but you can't drag me by this handle.

      +
      + +
      +

      Allow dragging only when the cursor is over a specific part of the draggable. Use the handle option to specify the jQuery selector of an element (or group of elements) used to drag the object.

      +

      Or prevent dragging when the cursor is over a specific element (or group of elements) within the draggable. Use the cancel option to specify a jQuery selector over which to "cancel" draggable functionality.

      +
      + + diff --git a/htdocs/js/lib/vendor/jquery-drag-drop/development-bundle/demos/draggable/index.html b/htdocs/js/lib/vendor/jquery-drag-drop/development-bundle/demos/draggable/index.html new file mode 100755 index 000000000..93850684d --- /dev/null +++ b/htdocs/js/lib/vendor/jquery-drag-drop/development-bundle/demos/draggable/index.html @@ -0,0 +1,24 @@ + + + + + jQuery UI Draggable Demos + + + + + + + diff --git a/htdocs/js/lib/vendor/jquery-drag-drop/development-bundle/demos/draggable/revert.html b/htdocs/js/lib/vendor/jquery-drag-drop/development-bundle/demos/draggable/revert.html new file mode 100755 index 000000000..742fc1d4f --- /dev/null +++ b/htdocs/js/lib/vendor/jquery-drag-drop/development-bundle/demos/draggable/revert.html @@ -0,0 +1,37 @@ + + + + + jQuery UI Draggable - Revert position + + + + + + + + + + + + +
      +

      Revert the original

      +
      + +
      +

      Revert the helper

      +
      + +
      +

      Return the draggable (or it's helper) to its original location when dragging stops with the boolean revert option.

      +
      + + diff --git a/htdocs/js/lib/vendor/jquery-drag-drop/development-bundle/demos/draggable/scroll.html b/htdocs/js/lib/vendor/jquery-drag-drop/development-bundle/demos/draggable/scroll.html new file mode 100755 index 000000000..5b64d6cad --- /dev/null +++ b/htdocs/js/lib/vendor/jquery-drag-drop/development-bundle/demos/draggable/scroll.html @@ -0,0 +1,44 @@ + + + + + jQuery UI Draggable - Auto-scroll + + + + + + + + + + + + +
      +

      Scroll set to true, default settings

      +
      + +
      +

      scrollSensitivity set to 100

      +
      + +
      +

      scrollSpeed set to 100

      +
      + +
      + +
      +

      Automatically scroll the document when the draggable is moved beyond the viewport. Set the scroll option to true to enable auto-scrolling, and fine-tune when scrolling is triggered and its speed with the scrollSensitivity and scrollSpeed options.

      +
      + + diff --git a/htdocs/js/lib/vendor/jquery-drag-drop/development-bundle/demos/draggable/snap-to.html b/htdocs/js/lib/vendor/jquery-drag-drop/development-bundle/demos/draggable/snap-to.html new file mode 100755 index 000000000..c7bc5f48e --- /dev/null +++ b/htdocs/js/lib/vendor/jquery-drag-drop/development-bundle/demos/draggable/snap-to.html @@ -0,0 +1,61 @@ + + + + + jQuery UI Draggable - Snap to element or grid + + + + + + + + + + + + +
      +

      I'm a snap target

      +
      + +
      + +
      +

      Default (snap: true), snaps to all other draggable elements

      +
      + +
      +

      I only snap to the big box

      +
      + +
      +

      I only snap to the outer edges of the big box

      +
      + +
      +

      I snap to a 20 x 20 grid

      +
      + +
      +

      I snap to a 80 x 80 grid

      +
      + +
      +

      Snap the draggable to the inner or outer boundaries of a DOM element. Use the snap, snapMode (inner, outer, both), and snapTolerance (distance in pixels the draggable must be from the element when snapping is invoked) options.

      +

      Or snap the draggable to a grid. Set the dimensions of grid cells (height and width in pixels) with the grid option.

      +
      + + diff --git a/htdocs/js/lib/vendor/jquery-drag-drop/development-bundle/demos/draggable/sortable.html b/htdocs/js/lib/vendor/jquery-drag-drop/development-bundle/demos/draggable/sortable.html new file mode 100755 index 000000000..77f7053cd --- /dev/null +++ b/htdocs/js/lib/vendor/jquery-drag-drop/development-bundle/demos/draggable/sortable.html @@ -0,0 +1,50 @@ + + + + + jQuery UI Draggable + Sortable + + + + + + + + + + + + + +
        +
      • Drag me down
      • +
      + +
        +
      • Item 1
      • +
      • Item 2
      • +
      • Item 3
      • +
      • Item 4
      • +
      • Item 5
      • +
      + +
      +

      Draggables are built to interact seamlessly with sortables.

      +
      + + diff --git a/htdocs/js/lib/vendor/jquery-drag-drop/development-bundle/demos/draggable/visual-feedback.html b/htdocs/js/lib/vendor/jquery-drag-drop/development-bundle/demos/draggable/visual-feedback.html new file mode 100755 index 000000000..80e230c65 --- /dev/null +++ b/htdocs/js/lib/vendor/jquery-drag-drop/development-bundle/demos/draggable/visual-feedback.html @@ -0,0 +1,70 @@ + + + + + jQuery UI Draggable - Visual feedback + + + + + + + + + + + + +

      With helpers:

      + +
      +

      Original

      +
      + +
      +

      Semi-transparent clone

      +
      + +
      +

      Custom helper (in combination with cursorAt)

      +
      + +

      Stacked:

      +
      +
      +

      We are draggables..

      +
      + +
      +

      ..whose z-indexes are controlled automatically..

      +
      + +
      +

      ..with the stack option.

      +
      +
      + +
      +

      Provide feedback to users as they drag an object in the form of a helper. The helper option accepts the values 'original' (the draggable object moves with the cursor), 'clone' (a duplicate of the draggable moves with the cursor), or a function that returns a DOM element (that element is shown near the cursor during drag). Control the helper's transparency with the opacity option.

      +

      To clarify which draggable is in play, bring the draggable in motion to front. Use the zIndex option to set a higher z-index for the helper, if in play, or use the stack option to ensure that the last item dragged will appear on top of others in the same group on drag stop.

      +
      + + diff --git a/htdocs/js/lib/vendor/jquery-drag-drop/development-bundle/demos/droppable/accepted-elements.html b/htdocs/js/lib/vendor/jquery-drag-drop/development-bundle/demos/droppable/accepted-elements.html new file mode 100755 index 000000000..6e2f76432 --- /dev/null +++ b/htdocs/js/lib/vendor/jquery-drag-drop/development-bundle/demos/droppable/accepted-elements.html @@ -0,0 +1,53 @@ + + + + + jQuery UI Droppable - Accept + + + + + + + + + + + + + +
      +

      I'm draggable but can't be dropped

      +
      + +
      +

      Drag me to my target

      +
      + +
      +

      accept: '#draggable'

      +
      + +
      +

      Specify using the accept option which element (or group of elements) is accepted by the target droppable.

      +
      + + diff --git a/htdocs/js/lib/vendor/jquery-drag-drop/development-bundle/demos/droppable/default.html b/htdocs/js/lib/vendor/jquery-drag-drop/development-bundle/demos/droppable/default.html new file mode 100755 index 000000000..88699dc74 --- /dev/null +++ b/htdocs/js/lib/vendor/jquery-drag-drop/development-bundle/demos/droppable/default.html @@ -0,0 +1,46 @@ + + + + + jQuery UI Droppable - Default functionality + + + + + + + + + + + + + +
      +

      Drag me to my target

      +
      + +
      +

      Drop here

      +
      + +
      +

      Enable any DOM element to be droppable, a target for draggable elements.

      +
      + + diff --git a/htdocs/js/lib/vendor/jquery-drag-drop/development-bundle/demos/droppable/images/high_tatras.jpg b/htdocs/js/lib/vendor/jquery-drag-drop/development-bundle/demos/droppable/images/high_tatras.jpg new file mode 100755 index 000000000..5723680df Binary files /dev/null and b/htdocs/js/lib/vendor/jquery-drag-drop/development-bundle/demos/droppable/images/high_tatras.jpg differ diff --git a/htdocs/js/lib/vendor/jquery-drag-drop/development-bundle/demos/droppable/images/high_tatras2.jpg b/htdocs/js/lib/vendor/jquery-drag-drop/development-bundle/demos/droppable/images/high_tatras2.jpg new file mode 100755 index 000000000..1acad3afb Binary files /dev/null and b/htdocs/js/lib/vendor/jquery-drag-drop/development-bundle/demos/droppable/images/high_tatras2.jpg differ diff --git a/htdocs/js/lib/vendor/jquery-drag-drop/development-bundle/demos/droppable/images/high_tatras2_min.jpg b/htdocs/js/lib/vendor/jquery-drag-drop/development-bundle/demos/droppable/images/high_tatras2_min.jpg new file mode 100755 index 000000000..493e0824a Binary files /dev/null and b/htdocs/js/lib/vendor/jquery-drag-drop/development-bundle/demos/droppable/images/high_tatras2_min.jpg differ diff --git a/htdocs/js/lib/vendor/jquery-drag-drop/development-bundle/demos/droppable/images/high_tatras3.jpg b/htdocs/js/lib/vendor/jquery-drag-drop/development-bundle/demos/droppable/images/high_tatras3.jpg new file mode 100755 index 000000000..e158b1ae0 Binary files /dev/null and b/htdocs/js/lib/vendor/jquery-drag-drop/development-bundle/demos/droppable/images/high_tatras3.jpg differ diff --git a/htdocs/js/lib/vendor/jquery-drag-drop/development-bundle/demos/droppable/images/high_tatras3_min.jpg b/htdocs/js/lib/vendor/jquery-drag-drop/development-bundle/demos/droppable/images/high_tatras3_min.jpg new file mode 100755 index 000000000..4aa96b01e Binary files /dev/null and b/htdocs/js/lib/vendor/jquery-drag-drop/development-bundle/demos/droppable/images/high_tatras3_min.jpg differ diff --git a/htdocs/js/lib/vendor/jquery-drag-drop/development-bundle/demos/droppable/images/high_tatras4.jpg b/htdocs/js/lib/vendor/jquery-drag-drop/development-bundle/demos/droppable/images/high_tatras4.jpg new file mode 100755 index 000000000..da4124d88 Binary files /dev/null and b/htdocs/js/lib/vendor/jquery-drag-drop/development-bundle/demos/droppable/images/high_tatras4.jpg differ diff --git a/htdocs/js/lib/vendor/jquery-drag-drop/development-bundle/demos/droppable/images/high_tatras4_min.jpg b/htdocs/js/lib/vendor/jquery-drag-drop/development-bundle/demos/droppable/images/high_tatras4_min.jpg new file mode 100755 index 000000000..794dbdf78 Binary files /dev/null and b/htdocs/js/lib/vendor/jquery-drag-drop/development-bundle/demos/droppable/images/high_tatras4_min.jpg differ diff --git a/htdocs/js/lib/vendor/jquery-drag-drop/development-bundle/demos/droppable/images/high_tatras_min.jpg b/htdocs/js/lib/vendor/jquery-drag-drop/development-bundle/demos/droppable/images/high_tatras_min.jpg new file mode 100755 index 000000000..51e0cdedf Binary files /dev/null and b/htdocs/js/lib/vendor/jquery-drag-drop/development-bundle/demos/droppable/images/high_tatras_min.jpg differ diff --git a/htdocs/js/lib/vendor/jquery-drag-drop/development-bundle/demos/droppable/index.html b/htdocs/js/lib/vendor/jquery-drag-drop/development-bundle/demos/droppable/index.html new file mode 100755 index 000000000..deca6e4bc --- /dev/null +++ b/htdocs/js/lib/vendor/jquery-drag-drop/development-bundle/demos/droppable/index.html @@ -0,0 +1,20 @@ + + + + + jQuery UI Droppable Demos + + + + + + + diff --git a/htdocs/js/lib/vendor/jquery-drag-drop/development-bundle/demos/droppable/photo-manager.html b/htdocs/js/lib/vendor/jquery-drag-drop/development-bundle/demos/droppable/photo-manager.html new file mode 100755 index 000000000..5c3e52007 --- /dev/null +++ b/htdocs/js/lib/vendor/jquery-drag-drop/development-bundle/demos/droppable/photo-manager.html @@ -0,0 +1,182 @@ + + + + + jQuery UI Droppable - Simple photo manager + + + + + + + + + + + + + + + + +
      + + + +
      +

      Trash Trash

      +
      + +
      + +
      +

      You can delete an image either by dragging it to the Trash or by clicking the trash icon.

      +

      You can "recycle" an image by dragging it back to the gallery or by clicking the recycle icon.

      +

      You can view larger image by clicking the zoom icon. jQuery UI dialog widget is used for the modal window.

      +
      + + diff --git a/htdocs/js/lib/vendor/jquery-drag-drop/development-bundle/demos/droppable/propagation.html b/htdocs/js/lib/vendor/jquery-drag-drop/development-bundle/demos/droppable/propagation.html new file mode 100755 index 000000000..2b7e16849 --- /dev/null +++ b/htdocs/js/lib/vendor/jquery-drag-drop/development-bundle/demos/droppable/propagation.html @@ -0,0 +1,73 @@ + + + + + jQuery UI Droppable - Prevent propagation + + + + + + + + + + + + + +
      +

      Drag me to my target

      +
      + +
      +

      Outer droppable

      +
      +

      Inner droppable (not greedy)

      +
      +
      + +
      +

      Outer droppable

      +
      +

      Inner droppable (greedy)

      +
      +
      + +
      +

      When working with nested droppables — for example, you may have an editable directory structure displayed as a tree, with folder and document nodes — the greedy option set to true prevents event propagation when a draggable is dropped on a child node (droppable).

      +
      + + diff --git a/htdocs/js/lib/vendor/jquery-drag-drop/development-bundle/demos/droppable/revert.html b/htdocs/js/lib/vendor/jquery-drag-drop/development-bundle/demos/droppable/revert.html new file mode 100755 index 000000000..eed45c56c --- /dev/null +++ b/htdocs/js/lib/vendor/jquery-drag-drop/development-bundle/demos/droppable/revert.html @@ -0,0 +1,54 @@ + + + + + jQuery UI Droppable - Revert draggable position + + + + + + + + + + + + + +
      +

      I revert when I'm dropped

      +
      + +
      +

      I revert when I'm not dropped

      +
      + +
      +

      Drop me here

      +
      + +
      +

      Return the draggable (or it's helper) to its original location when dragging stops with the boolean revert option set on the draggable.

      +
      + + diff --git a/htdocs/js/lib/vendor/jquery-drag-drop/development-bundle/demos/droppable/shopping-cart.html b/htdocs/js/lib/vendor/jquery-drag-drop/development-bundle/demos/droppable/shopping-cart.html new file mode 100755 index 000000000..9909f4f04 --- /dev/null +++ b/htdocs/js/lib/vendor/jquery-drag-drop/development-bundle/demos/droppable/shopping-cart.html @@ -0,0 +1,94 @@ + + + + + jQuery UI Droppable - Shopping Cart Demo + + + + + + + + + + + + + + + +
      +

      Products

      +
      +

      T-Shirts

      +
      +
        +
      • Lolcat Shirt
      • +
      • Cheezeburger Shirt
      • +
      • Buckit Shirt
      • +
      +
      +

      Bags

      +
      +
        +
      • Zebra Striped
      • +
      • Black Leather
      • +
      • Alligator Leather
      • +
      +
      +

      Gadgets

      +
      +
        +
      • iPhone
      • +
      • iPod
      • +
      • iPad
      • +
      +
      +
      +
      + +
      +

      Shopping Cart

      +
      +
        +
      1. Add your items here
      2. +
      +
      +
      + +
      +

      Demonstrate how to use an accordion to structure products into a catalog and make use of drag and drop for adding them to a shopping cart, where they are sortable.

      +
      + + diff --git a/htdocs/js/lib/vendor/jquery-drag-drop/development-bundle/demos/droppable/visual-feedback.html b/htdocs/js/lib/vendor/jquery-drag-drop/development-bundle/demos/droppable/visual-feedback.html new file mode 100755 index 000000000..3af911f9d --- /dev/null +++ b/htdocs/js/lib/vendor/jquery-drag-drop/development-bundle/demos/droppable/visual-feedback.html @@ -0,0 +1,72 @@ + + + + + jQuery UI Droppable - Visual feedback + + + + + + + + + + + + + +

      Feedback on hover:

      + +
      +

      Drag me to my target

      +
      + +
      +

      Drop here

      +
      + +

      Feedback on activating draggable:

      + +
      +

      Drag me to my target

      +
      + +
      +

      Drop here

      +
      + +
      +

      Change the droppable's appearance on hover, or when the droppable is active (an acceptable draggable is dropped on it). Use the hoverClass or activeClass options to specify respective classes.

      +
      + + diff --git a/htdocs/js/lib/vendor/jquery-drag-drop/development-bundle/demos/images/calendar.gif b/htdocs/js/lib/vendor/jquery-drag-drop/development-bundle/demos/images/calendar.gif new file mode 100755 index 000000000..d0abaa7c0 Binary files /dev/null and b/htdocs/js/lib/vendor/jquery-drag-drop/development-bundle/demos/images/calendar.gif differ diff --git a/htdocs/js/lib/vendor/jquery-drag-drop/development-bundle/demos/images/demo-config-on-tile.gif b/htdocs/js/lib/vendor/jquery-drag-drop/development-bundle/demos/images/demo-config-on-tile.gif new file mode 100755 index 000000000..a96b5bf33 Binary files /dev/null and b/htdocs/js/lib/vendor/jquery-drag-drop/development-bundle/demos/images/demo-config-on-tile.gif differ diff --git a/htdocs/js/lib/vendor/jquery-drag-drop/development-bundle/demos/images/demo-config-on.gif b/htdocs/js/lib/vendor/jquery-drag-drop/development-bundle/demos/images/demo-config-on.gif new file mode 100755 index 000000000..e3b6d7c0f Binary files /dev/null and b/htdocs/js/lib/vendor/jquery-drag-drop/development-bundle/demos/images/demo-config-on.gif differ diff --git a/htdocs/js/lib/vendor/jquery-drag-drop/development-bundle/demos/images/demo-spindown-closed.gif b/htdocs/js/lib/vendor/jquery-drag-drop/development-bundle/demos/images/demo-spindown-closed.gif new file mode 100755 index 000000000..ad4bd3781 Binary files /dev/null and b/htdocs/js/lib/vendor/jquery-drag-drop/development-bundle/demos/images/demo-spindown-closed.gif differ diff --git a/htdocs/js/lib/vendor/jquery-drag-drop/development-bundle/demos/images/demo-spindown-open.gif b/htdocs/js/lib/vendor/jquery-drag-drop/development-bundle/demos/images/demo-spindown-open.gif new file mode 100755 index 000000000..e1c60aa55 Binary files /dev/null and b/htdocs/js/lib/vendor/jquery-drag-drop/development-bundle/demos/images/demo-spindown-open.gif differ diff --git a/htdocs/js/lib/vendor/jquery-drag-drop/development-bundle/demos/images/icon-docs-info.gif b/htdocs/js/lib/vendor/jquery-drag-drop/development-bundle/demos/images/icon-docs-info.gif new file mode 100755 index 000000000..ea6d2bece Binary files /dev/null and b/htdocs/js/lib/vendor/jquery-drag-drop/development-bundle/demos/images/icon-docs-info.gif differ diff --git a/htdocs/js/lib/vendor/jquery-drag-drop/development-bundle/demos/images/pbar-ani.gif b/htdocs/js/lib/vendor/jquery-drag-drop/development-bundle/demos/images/pbar-ani.gif new file mode 100755 index 000000000..cb59a04f9 Binary files /dev/null and b/htdocs/js/lib/vendor/jquery-drag-drop/development-bundle/demos/images/pbar-ani.gif differ diff --git a/htdocs/js/lib/vendor/jquery-drag-drop/development-bundle/demos/position/cycler.html b/htdocs/js/lib/vendor/jquery-drag-drop/development-bundle/demos/position/cycler.html new file mode 100755 index 000000000..2a6373c0e --- /dev/null +++ b/htdocs/js/lib/vendor/jquery-drag-drop/development-bundle/demos/position/cycler.html @@ -0,0 +1,107 @@ + + + + + jQuery UI Position - Image Cycler + + + + + + + + + + + +
      + earth + flight + rocket + + + +
      + +
      +

      A photoviewer prototype using Position to place images at the center, left and right and cycle them. +
      Use the links at the top to cycle, or click on the images on the left and right. +
      Note how the images are repositioned when resizing the window. +

      + + diff --git a/htdocs/js/lib/vendor/jquery-drag-drop/development-bundle/demos/position/default.html b/htdocs/js/lib/vendor/jquery-drag-drop/development-bundle/demos/position/default.html new file mode 100755 index 000000000..f91bbaa5f --- /dev/null +++ b/htdocs/js/lib/vendor/jquery-drag-drop/development-bundle/demos/position/default.html @@ -0,0 +1,142 @@ + + + + + jQuery UI Position - Default functionality + + + + + + + + + + + + + +
      +

      + This is the position parent element. +

      +
      + +
      +

      + to position +

      +
      + +
      +

      + to position 2 +

      +
      + +
      + position... +
      + my: + + +
      +
      + at: + + +
      +
      + offset: + +
      +
      + collision: + + +
      +
      + +
      +

      Use the form controls to configure the positioning, or drag the positioned element to modify its offset. +
      Drag around the parent element to see collision detection in action.

      +
      + + diff --git a/htdocs/js/lib/vendor/jquery-drag-drop/development-bundle/demos/position/images/earth.jpg b/htdocs/js/lib/vendor/jquery-drag-drop/development-bundle/demos/position/images/earth.jpg new file mode 100755 index 000000000..e5477f754 Binary files /dev/null and b/htdocs/js/lib/vendor/jquery-drag-drop/development-bundle/demos/position/images/earth.jpg differ diff --git a/htdocs/js/lib/vendor/jquery-drag-drop/development-bundle/demos/position/images/flight.jpg b/htdocs/js/lib/vendor/jquery-drag-drop/development-bundle/demos/position/images/flight.jpg new file mode 100755 index 000000000..362bd1a22 Binary files /dev/null and b/htdocs/js/lib/vendor/jquery-drag-drop/development-bundle/demos/position/images/flight.jpg differ diff --git a/htdocs/js/lib/vendor/jquery-drag-drop/development-bundle/demos/position/images/rocket.jpg b/htdocs/js/lib/vendor/jquery-drag-drop/development-bundle/demos/position/images/rocket.jpg new file mode 100755 index 000000000..9c0495c61 Binary files /dev/null and b/htdocs/js/lib/vendor/jquery-drag-drop/development-bundle/demos/position/images/rocket.jpg differ diff --git a/htdocs/js/lib/vendor/jquery-drag-drop/development-bundle/demos/position/index.html b/htdocs/js/lib/vendor/jquery-drag-drop/development-bundle/demos/position/index.html new file mode 100755 index 000000000..a7b754876 --- /dev/null +++ b/htdocs/js/lib/vendor/jquery-drag-drop/development-bundle/demos/position/index.html @@ -0,0 +1,15 @@ + + + + + jQuery UI Position Demo + + + + + + + diff --git a/htdocs/js/lib/vendor/jquery-drag-drop/development-bundle/demos/resizable/animate.html b/htdocs/js/lib/vendor/jquery-drag-drop/development-bundle/demos/resizable/animate.html new file mode 100755 index 000000000..31db5dbf2 --- /dev/null +++ b/htdocs/js/lib/vendor/jquery-drag-drop/development-bundle/demos/resizable/animate.html @@ -0,0 +1,36 @@ + + + + + jQuery UI Resizable - Animate + + + + + + + + + + + + +
      +

      Animate

      +
      + +
      +

      Animate the resize action using the animate option (boolean). When this option is set to true, drag the outline to the desired location; the element animates to that size on drag stop.

      +
      + + diff --git a/htdocs/js/lib/vendor/jquery-drag-drop/development-bundle/demos/resizable/aspect-ratio.html b/htdocs/js/lib/vendor/jquery-drag-drop/development-bundle/demos/resizable/aspect-ratio.html new file mode 100755 index 000000000..0f4fc5d02 --- /dev/null +++ b/htdocs/js/lib/vendor/jquery-drag-drop/development-bundle/demos/resizable/aspect-ratio.html @@ -0,0 +1,35 @@ + + + + + jQuery UI Resizable - Preserve aspect ratio + + + + + + + + + + + + +
      +

      Preserve aspect ratio

      +
      + +
      +

      Maintain the existing aspect ratio or set a new one to constrain the proportions on resize. Set the aspectRatio option to true, and optionally pass in a new ratio (i.e., 4/3)

      +
      + + diff --git a/htdocs/js/lib/vendor/jquery-drag-drop/development-bundle/demos/resizable/constrain-area.html b/htdocs/js/lib/vendor/jquery-drag-drop/development-bundle/demos/resizable/constrain-area.html new file mode 100755 index 000000000..fdfdbd2d7 --- /dev/null +++ b/htdocs/js/lib/vendor/jquery-drag-drop/development-bundle/demos/resizable/constrain-area.html @@ -0,0 +1,40 @@ + + + + + jQuery UI Resizable - Constrain resize area + + + + + + + + + + + + +
      +

      Containment

      +
      +

      Resizable

      +
      +
      + +
      +

      Define the boundaries of the resizable area. Use the containment option to specify a parent DOM element or a jQuery selector, like 'document.'

      +
      + + diff --git a/htdocs/js/lib/vendor/jquery-drag-drop/development-bundle/demos/resizable/default.html b/htdocs/js/lib/vendor/jquery-drag-drop/development-bundle/demos/resizable/default.html new file mode 100755 index 000000000..09e675e63 --- /dev/null +++ b/htdocs/js/lib/vendor/jquery-drag-drop/development-bundle/demos/resizable/default.html @@ -0,0 +1,33 @@ + + + + + jQuery UI Resizable - Default functionality + + + + + + + + + + + + +
      +

      Resizable

      +
      + +
      +

      Enable any DOM element to be resizable. With the cursor grab the right or bottom border and drag to the desired width or height.

      +
      + + diff --git a/htdocs/js/lib/vendor/jquery-drag-drop/development-bundle/demos/resizable/delay-start.html b/htdocs/js/lib/vendor/jquery-drag-drop/development-bundle/demos/resizable/delay-start.html new file mode 100755 index 000000000..eecb7acae --- /dev/null +++ b/htdocs/js/lib/vendor/jquery-drag-drop/development-bundle/demos/resizable/delay-start.html @@ -0,0 +1,45 @@ + + + + + jQuery UI Resizable - Delay start + + + + + + + + + + + + +

      Time delay (ms):

      +
      +

      Time

      +
      + +

      Distance delay (px):

      +
      +

      Distance

      +
      + +
      +

      Delay the start of resizng for a number of milliseconds with the delay option; prevent resizing until the cursor is held down and dragged a specifed number of pixels with the distance option.

      +
      + + diff --git a/htdocs/js/lib/vendor/jquery-drag-drop/development-bundle/demos/resizable/helper.html b/htdocs/js/lib/vendor/jquery-drag-drop/development-bundle/demos/resizable/helper.html new file mode 100755 index 000000000..baafb4453 --- /dev/null +++ b/htdocs/js/lib/vendor/jquery-drag-drop/development-bundle/demos/resizable/helper.html @@ -0,0 +1,36 @@ + + + + + jQuery UI Resizable - Helper + + + + + + + + + + + + +
      +

      Helper

      +
      + +
      +

      Display only an outline of the element while resizing by setting the helper option to a CSS class.

      +
      + + diff --git a/htdocs/js/lib/vendor/jquery-drag-drop/development-bundle/demos/resizable/index.html b/htdocs/js/lib/vendor/jquery-drag-drop/development-bundle/demos/resizable/index.html new file mode 100755 index 000000000..7c626e253 --- /dev/null +++ b/htdocs/js/lib/vendor/jquery-drag-drop/development-bundle/demos/resizable/index.html @@ -0,0 +1,24 @@ + + + + + jQuery UI Resizable Demos + + + + + + + diff --git a/htdocs/js/lib/vendor/jquery-drag-drop/development-bundle/demos/resizable/max-min.html b/htdocs/js/lib/vendor/jquery-drag-drop/development-bundle/demos/resizable/max-min.html new file mode 100755 index 000000000..3025b2823 --- /dev/null +++ b/htdocs/js/lib/vendor/jquery-drag-drop/development-bundle/demos/resizable/max-min.html @@ -0,0 +1,38 @@ + + + + + jQuery UI Resizable - Maximum / minimum size + + + + + + + + + + + + +
      +

      Resize larger / smaller

      +
      + +
      +

      Limit the resizable element to a maximum or minimum height or width using the maxHeight, maxWidth, minHeight, and minWidth options.

      +
      + + diff --git a/htdocs/js/lib/vendor/jquery-drag-drop/development-bundle/demos/resizable/snap-to-grid.html b/htdocs/js/lib/vendor/jquery-drag-drop/development-bundle/demos/resizable/snap-to-grid.html new file mode 100755 index 000000000..84e374daa --- /dev/null +++ b/htdocs/js/lib/vendor/jquery-drag-drop/development-bundle/demos/resizable/snap-to-grid.html @@ -0,0 +1,35 @@ + + + + + jQuery UI Resizable - Snap to grid + + + + + + + + + + + + +
      +

      Grid

      +
      + +
      +

      Snap the resizable element to a grid. Set the dimensions of grid cells (height and width in pixels) with the grid option.

      +
      + + diff --git a/htdocs/js/lib/vendor/jquery-drag-drop/development-bundle/demos/resizable/synchronous-resize.html b/htdocs/js/lib/vendor/jquery-drag-drop/development-bundle/demos/resizable/synchronous-resize.html new file mode 100755 index 000000000..e654560e6 --- /dev/null +++ b/htdocs/js/lib/vendor/jquery-drag-drop/development-bundle/demos/resizable/synchronous-resize.html @@ -0,0 +1,42 @@ + + + + + jQuery UI Resizable - Synchronous resize + + + + + + + + + + + + +
      +

      Resize

      +
      + +
      +

      will also resize

      +
      + +
      +

      Resize multiple elements simultaneously by clicking and dragging the sides of one. Pass a shared selector into the alsoResize option.

      +
      + + diff --git a/htdocs/js/lib/vendor/jquery-drag-drop/development-bundle/demos/resizable/textarea.html b/htdocs/js/lib/vendor/jquery-drag-drop/development-bundle/demos/resizable/textarea.html new file mode 100755 index 000000000..3c7c3a46d --- /dev/null +++ b/htdocs/js/lib/vendor/jquery-drag-drop/development-bundle/demos/resizable/textarea.html @@ -0,0 +1,34 @@ + + + + + jQuery UI Resizable - Textarea + + + + + + + + + + + + + + +
      +

      Display only an outline of the element while resizing by setting the helper option to a CSS class.

      +
      + + diff --git a/htdocs/js/lib/vendor/jquery-drag-drop/development-bundle/demos/resizable/visual-feedback.html b/htdocs/js/lib/vendor/jquery-drag-drop/development-bundle/demos/resizable/visual-feedback.html new file mode 100755 index 000000000..211a3aebf --- /dev/null +++ b/htdocs/js/lib/vendor/jquery-drag-drop/development-bundle/demos/resizable/visual-feedback.html @@ -0,0 +1,36 @@ + + + + + jQuery UI Resizable - Visual feedback + + + + + + + + + + + + +
      +

      Ghost

      +
      + +
      +

      Instead of showing the actual element during resize, set the ghost option to true to show a semi-transparent part of the element.

      +
      + + diff --git a/htdocs/js/lib/vendor/jquery-drag-drop/development-bundle/demos/selectable/default.html b/htdocs/js/lib/vendor/jquery-drag-drop/development-bundle/demos/selectable/default.html new file mode 100755 index 000000000..4e49b284c --- /dev/null +++ b/htdocs/js/lib/vendor/jquery-drag-drop/development-bundle/demos/selectable/default.html @@ -0,0 +1,43 @@ + + + + + jQuery UI Selectable - Default functionality + + + + + + + + + + + + + +
        +
      1. Item 1
      2. +
      3. Item 2
      4. +
      5. Item 3
      6. +
      7. Item 4
      8. +
      9. Item 5
      10. +
      11. Item 6
      12. +
      13. Item 7
      14. +
      + +
      +

      Enable a DOM element (or group of elements) to be selectable. Draw a box with your cursor to select items. Hold down the Ctrl key to make multiple non-adjacent selections.

      +
      + + diff --git a/htdocs/js/lib/vendor/jquery-drag-drop/development-bundle/demos/selectable/display-grid.html b/htdocs/js/lib/vendor/jquery-drag-drop/development-bundle/demos/selectable/display-grid.html new file mode 100755 index 000000000..7924c57fa --- /dev/null +++ b/htdocs/js/lib/vendor/jquery-drag-drop/development-bundle/demos/selectable/display-grid.html @@ -0,0 +1,48 @@ + + + + + jQuery UI Selectable - Display as grid + + + + + + + + + + + + + +
        +
      1. 1
      2. +
      3. 2
      4. +
      5. 3
      6. +
      7. 4
      8. +
      9. 5
      10. +
      11. 6
      12. +
      13. 7
      14. +
      15. 8
      16. +
      17. 9
      18. +
      19. 10
      20. +
      21. 11
      22. +
      23. 12
      24. +
      + +
      +

      To arrange selectable items as a grid, give them identical dimensions and float them using CSS.

      +
      + + diff --git a/htdocs/js/lib/vendor/jquery-drag-drop/development-bundle/demos/selectable/index.html b/htdocs/js/lib/vendor/jquery-drag-drop/development-bundle/demos/selectable/index.html new file mode 100755 index 000000000..a82830c60 --- /dev/null +++ b/htdocs/js/lib/vendor/jquery-drag-drop/development-bundle/demos/selectable/index.html @@ -0,0 +1,16 @@ + + + + + jQuery UI Selectable Demos + + + + + + + diff --git a/htdocs/js/lib/vendor/jquery-drag-drop/development-bundle/demos/selectable/serialize.html b/htdocs/js/lib/vendor/jquery-drag-drop/development-bundle/demos/selectable/serialize.html new file mode 100755 index 000000000..cca6cddb9 --- /dev/null +++ b/htdocs/js/lib/vendor/jquery-drag-drop/development-bundle/demos/selectable/serialize.html @@ -0,0 +1,54 @@ + + + + + jQuery UI Selectable - Serialize + + + + + + + + + + + + + +

      +You've selected: none. +

      + +
        +
      1. Item 1
      2. +
      3. Item 2
      4. +
      5. Item 3
      6. +
      7. Item 4
      8. +
      9. Item 5
      10. +
      11. Item 6
      12. +
      + +
      +

      Write a function that fires on the stop event to collect the index values of selected items. Present values as feedback, or pass as a data string.

      +
      + + diff --git a/htdocs/js/lib/vendor/jquery-drag-drop/development-bundle/demos/sortable/connect-lists-through-tabs.html b/htdocs/js/lib/vendor/jquery-drag-drop/development-bundle/demos/sortable/connect-lists-through-tabs.html new file mode 100755 index 000000000..2ef6fdc1f --- /dev/null +++ b/htdocs/js/lib/vendor/jquery-drag-drop/development-bundle/demos/sortable/connect-lists-through-tabs.html @@ -0,0 +1,72 @@ + + + + + jQuery UI Sortable - Connect lists with Tabs + + + + + + + + + + + + + + +
      + +
      +
        +
      • Item 1
      • +
      • Item 2
      • +
      • Item 3
      • +
      • Item 4
      • +
      • Item 5
      • +
      +
      +
      +
        +
      • Item 1
      • +
      • Item 2
      • +
      • Item 3
      • +
      • Item 4
      • +
      • Item 5
      • +
      +
      +
      + +
      +

      Sort items from one list into another and vice versa, by dropping the list item on the appropriate tab above.

      +
      + + diff --git a/htdocs/js/lib/vendor/jquery-drag-drop/development-bundle/demos/sortable/connect-lists.html b/htdocs/js/lib/vendor/jquery-drag-drop/development-bundle/demos/sortable/connect-lists.html new file mode 100755 index 000000000..dd845add7 --- /dev/null +++ b/htdocs/js/lib/vendor/jquery-drag-drop/development-bundle/demos/sortable/connect-lists.html @@ -0,0 +1,52 @@ + + + + + jQuery UI Sortable - Connect lists + + + + + + + + + + + + +
        +
      • Item 1
      • +
      • Item 2
      • +
      • Item 3
      • +
      • Item 4
      • +
      • Item 5
      • +
      + +
        +
      • Item 1
      • +
      • Item 2
      • +
      • Item 3
      • +
      • Item 4
      • +
      • Item 5
      • +
      + +
      +

      + Sort items from one list into another and vice versa, by passing a selector into + the connectWith option. The simplest way to do this is to + group all related lists with a CSS class, and then pass that class into the + sortable function (i.e., connectWith: '.myclass'). +

      +
      + + diff --git a/htdocs/js/lib/vendor/jquery-drag-drop/development-bundle/demos/sortable/default.html b/htdocs/js/lib/vendor/jquery-drag-drop/development-bundle/demos/sortable/default.html new file mode 100755 index 000000000..843be3246 --- /dev/null +++ b/htdocs/js/lib/vendor/jquery-drag-drop/development-bundle/demos/sortable/default.html @@ -0,0 +1,45 @@ + + + + + jQuery UI Sortable - Default functionality + + + + + + + + + + + + +
        +
      • Item 1
      • +
      • Item 2
      • +
      • Item 3
      • +
      • Item 4
      • +
      • Item 5
      • +
      • Item 6
      • +
      • Item 7
      • +
      + +
      +

      + Enable a group of DOM elements to be sortable. Click on and drag an + element to a new spot within the list, and the other items will adjust to + fit. By default, sortable items share draggable properties. +

      +
      + + diff --git a/htdocs/js/lib/vendor/jquery-drag-drop/development-bundle/demos/sortable/delay-start.html b/htdocs/js/lib/vendor/jquery-drag-drop/development-bundle/demos/sortable/delay-start.html new file mode 100755 index 000000000..5c2cd367a --- /dev/null +++ b/htdocs/js/lib/vendor/jquery-drag-drop/development-bundle/demos/sortable/delay-start.html @@ -0,0 +1,61 @@ + + + + + jQuery UI Sortable - Delay start + + + + + + + + + + + + +

      Time delay of 300ms:

      + +
        +
      • Item 1
      • +
      • Item 2
      • +
      • Item 3
      • +
      • Item 4
      • +
      + +

      Distance delay of 15px:

      + +
        +
      • Item 1
      • +
      • Item 2
      • +
      • Item 3
      • +
      • Item 4
      • +
      + +
      +

      + Prevent accidental sorting either by delay (time) or distance. Set a number of + milliseconds the element needs to be dragged before sorting starts + with the delay option. Set a distance in pixels the element + needs to be dragged before sorting starts with the distance + option. +

      +
      + + diff --git a/htdocs/js/lib/vendor/jquery-drag-drop/development-bundle/demos/sortable/display-grid.html b/htdocs/js/lib/vendor/jquery-drag-drop/development-bundle/demos/sortable/display-grid.html new file mode 100755 index 000000000..af02a4507 --- /dev/null +++ b/htdocs/js/lib/vendor/jquery-drag-drop/development-bundle/demos/sortable/display-grid.html @@ -0,0 +1,48 @@ + + + + + jQuery UI Sortable - Display as grid + + + + + + + + + + + + +
        +
      • 1
      • +
      • 2
      • +
      • 3
      • +
      • 4
      • +
      • 5
      • +
      • 6
      • +
      • 7
      • +
      • 8
      • +
      • 9
      • +
      • 10
      • +
      • 11
      • +
      • 12
      • +
      + +
      +

      + To arrange sortable items as a grid, give them identical dimensions and + float them using CSS. +

      +
      + + diff --git a/htdocs/js/lib/vendor/jquery-drag-drop/development-bundle/demos/sortable/empty-lists.html b/htdocs/js/lib/vendor/jquery-drag-drop/development-bundle/demos/sortable/empty-lists.html new file mode 100755 index 000000000..cd8fa31a1 --- /dev/null +++ b/htdocs/js/lib/vendor/jquery-drag-drop/development-bundle/demos/sortable/empty-lists.html @@ -0,0 +1,63 @@ + + + + + jQuery UI Sortable - Handle empty lists + + + + + + + + + + + + +
        +
      • Can be dropped..
      • +
      • ..on an empty list
      • +
      • Item 3
      • +
      • Item 4
      • +
      • Item 5
      • +
      + +
        +
      • Cannot be dropped..
      • +
      • ..on an empty list
      • +
      • Item 3
      • +
      • Item 4
      • +
      • Item 5
      • +
      + +
        +
      + +
      + +
      +

      + Prevent all items in a list from being dropped into a separate, empty list + using the dropOnEmpty option set to false. By default, + sortable items can be dropped on empty lists. +

      +
      + + diff --git a/htdocs/js/lib/vendor/jquery-drag-drop/development-bundle/demos/sortable/index.html b/htdocs/js/lib/vendor/jquery-drag-drop/development-bundle/demos/sortable/index.html new file mode 100755 index 000000000..66b0b5ced --- /dev/null +++ b/htdocs/js/lib/vendor/jquery-drag-drop/development-bundle/demos/sortable/index.html @@ -0,0 +1,22 @@ + + + + + jQuery UI Sortable Demos + + + + + + + diff --git a/htdocs/js/lib/vendor/jquery-drag-drop/development-bundle/demos/sortable/items.html b/htdocs/js/lib/vendor/jquery-drag-drop/development-bundle/demos/sortable/items.html new file mode 100755 index 000000000..bbdcba0a7 --- /dev/null +++ b/htdocs/js/lib/vendor/jquery-drag-drop/development-bundle/demos/sortable/items.html @@ -0,0 +1,64 @@ + + + + + jQuery UI Sortable - Include / exclude items + + + + + + + + + + + + +

      Specify which items are sortable:

      + +
        +
      • Item 1
      • +
      • (I'm not sortable or a drop target)
      • +
      • (I'm not sortable or a drop target)
      • +
      • Item 4
      • +
      + +

      Cancel sorting (but keep as drop targets):

      + +
        +
      • Item 1
      • +
      • (I'm not sortable)
      • +
      • (I'm not sortable)
      • +
      • Item 4
      • +
      + +
      +

      + Specify which items are eligible to sort by passing a jQuery selector into + the items option. Items excluded from this option are not + sortable, nor are they valid targets for sortable items. +

      +

      + To only prevent sorting on certain items, pass a jQuery selector into the + cancel option. Cancelled items remain valid sort targets for + others. +

      +
      + + diff --git a/htdocs/js/lib/vendor/jquery-drag-drop/development-bundle/demos/sortable/placeholder.html b/htdocs/js/lib/vendor/jquery-drag-drop/development-bundle/demos/sortable/placeholder.html new file mode 100755 index 000000000..609324f99 --- /dev/null +++ b/htdocs/js/lib/vendor/jquery-drag-drop/development-bundle/demos/sortable/placeholder.html @@ -0,0 +1,50 @@ + + + + + jQuery UI Sortable - Drop placeholder + + + + + + + + + + + + +
        +
      • Item 1
      • +
      • Item 2
      • +
      • Item 3
      • +
      • Item 4
      • +
      • Item 5
      • +
      • Item 6
      • +
      • Item 7
      • +
      + +
      +

      + When dragging a sortable item to a new location, other items will make room + for the that item by shifting to allow white space between them. Pass a + class into the placeholder option to style that space to + be visible. Use the boolean forcePlaceholderSize option + to set dimensions on the placeholder. +

      +
      + + diff --git a/htdocs/js/lib/vendor/jquery-drag-drop/development-bundle/demos/sortable/portlets.html b/htdocs/js/lib/vendor/jquery-drag-drop/development-bundle/demos/sortable/portlets.html new file mode 100755 index 000000000..68c668c7b --- /dev/null +++ b/htdocs/js/lib/vendor/jquery-drag-drop/development-bundle/demos/sortable/portlets.html @@ -0,0 +1,90 @@ + + + + + jQuery UI Sortable - Portlets + + + + + + + + + + + + +
      + +
      +
      Feeds
      +
      Lorem ipsum dolor sit amet, consectetuer adipiscing elit
      +
      + +
      +
      News
      +
      Lorem ipsum dolor sit amet, consectetuer adipiscing elit
      +
      + +
      + +
      + +
      +
      Shopping
      +
      Lorem ipsum dolor sit amet, consectetuer adipiscing elit
      +
      + +
      + +
      + +
      +
      Links
      +
      Lorem ipsum dolor sit amet, consectetuer adipiscing elit
      +
      + +
      +
      Images
      +
      Lorem ipsum dolor sit amet, consectetuer adipiscing elit
      +
      + +
      + +
      +

      + Enable portlets (styled divs) as sortables and use the connectWith + option to allow sorting between columns. +

      +
      + + diff --git a/htdocs/js/lib/vendor/jquery-drag-drop/development-bundle/demos/widget/default.html b/htdocs/js/lib/vendor/jquery-drag-drop/development-bundle/demos/widget/default.html new file mode 100755 index 000000000..60797b214 --- /dev/null +++ b/htdocs/js/lib/vendor/jquery-drag-drop/development-bundle/demos/widget/default.html @@ -0,0 +1,178 @@ + + + + + jQuery UI Widget - Default functionality + + + + + + + + + + + + +
      +
      color me
      +
      color me
      +
      color me
      + + +
      + +
      +

      This demo shows a simple custom widget built using the widget factory (jquery.ui.widget.js).

      +

      The three boxes are initialized in different ways. Clicking them changes their background color. View source to see how it works, its heavily commented

      +
      + + diff --git a/htdocs/js/lib/vendor/jquery-drag-drop/development-bundle/demos/widget/index.html b/htdocs/js/lib/vendor/jquery-drag-drop/development-bundle/demos/widget/index.html new file mode 100755 index 000000000..d518b070d --- /dev/null +++ b/htdocs/js/lib/vendor/jquery-drag-drop/development-bundle/demos/widget/index.html @@ -0,0 +1,14 @@ + + + + + jQuery UI Widget Demo + + + + + + + diff --git a/htdocs/js/lib/vendor/jquery-drag-drop/development-bundle/docs/draggable.html b/htdocs/js/lib/vendor/jquery-drag-drop/development-bundle/docs/draggable.html new file mode 100755 index 000000000..fa98aa644 --- /dev/null +++ b/htdocs/js/lib/vendor/jquery-drag-drop/development-bundle/docs/draggable.html @@ -0,0 +1,750 @@ + + + + + jQuery UI draggable documentation + + + + + +

      QuickNavOverviewExamples +

      + +
      +

      Events

      + + + + +

      +Draggable Widgetversion added: 1.0 +

      +
      +

      Description: Allow elements to be moved using the mouse.

      +

      Options

      +

      addClassesType: Boolean +

      +
      +Default: true +
      +
      If set to false, will prevent the ui-draggable class from being added. This may be desired as a performance optimization when calling .draggable() on hundreds of elements.
      +Code examples:

      Initialize the draggable with the addClasses option specified:

      +
      $( ".selector" ).draggable({ addClasses: false });
      +

      Get or set the addClasses option, after initialization:

      +
      // getter
      var addClasses = $( ".selector" ).draggable( "option", "addClasses" );
       
      // setter
      $( ".selector" ).draggable( "option", "addClasses", false );
      +
      +
      +

      appendToType: jQuery or Element or Selector or String +

      +
      +Default: "parent" +
      +
      Which element the draggable helper should be appended to while dragging.
      +Multiple types supported:
        +
      • +jQuery: A jQuery object containing the element to append the helper to.
      • +
      • +Element: The element to append the helper to.
      • +
      • +Selector: A selector specifying which element to append the helper to.
      • +
      • +String: The string "parent" will cause the helper to be a sibling of the draggable.
      • +
      +Code examples:

      Initialize the draggable with the appendTo option specified:

      +
      $( ".selector" ).draggable({ appendTo: "body" });
      +

      Get or set the appendTo option, after initialization:

      +
      // getter
      var appendTo = $( ".selector" ).draggable( "option", "appendTo" );
       
      // setter
      $( ".selector" ).draggable( "option", "appendTo", "body" );
      +
      +
      +

      axisType: String +

      +
      +Default: false +
      +
      Constrains dragging to either the horizontal (x) or vertical (y) axis. Possible values: "x", "y".
      +Code examples:

      Initialize the draggable with the axis option specified:

      +
      $( ".selector" ).draggable({ axis: "x" });
      +

      Get or set the axis option, after initialization:

      +
      // getter
      var axis = $( ".selector" ).draggable( "option", "axis" );
       
      // setter
      $( ".selector" ).draggable( "option", "axis", "x" );
      +
      +
      +

      cancelType: Selector +

      +
      +Default: "input,textarea,button,select,option" +
      +
      Prevents dragging from starting on specified elements.
      +Code examples:

      Initialize the draggable with the cancel option specified:

      +
      $( ".selector" ).draggable({ cancel: ".title" });
      +

      Get or set the cancel option, after initialization:

      +
      // getter
      var cancel = $( ".selector" ).draggable( "option", "cancel" );
       
      // setter
      $( ".selector" ).draggable( "option", "cancel", ".title" );
      +
      +
      +

      connectToSortableType: Selector +

      +
      +Default: false +
      +
      Allows the draggable to be dropped onto the specified sortables. If this option is used, a draggable can be dropped onto a sortable list and then becomes part of it. Note: The helper option must be set to "clone" in order to work flawlessly. Requires the jQuery UI Sortable plugin to be included.
      +Code examples:

      Initialize the draggable with the connectToSortable option specified:

      +
      $( ".selector" ).draggable({ connectToSortable: "#my-sortable" });
      +

      Get or set the connectToSortable option, after initialization:

      +
      // getter
      var connectToSortable = $( ".selector" ).draggable( "option", "connectToSortable" );
       
      // setter
      $( ".selector" ).draggable( "option", "connectToSortable", "#my-sortable" );
      +
      +
      +

      containmentType: Selector or Element or String or Array +

      +
      +Default: false +
      +
      Constrains dragging to within the bounds of the specified element or region.
      +Multiple types supported:
        +
      • +Selector: The draggable element will be contained to the bounding box of the first element found by the selector. If no element is found, no containment will be set.
      • +
      • +Element: The draggable element will be contained to the bounding box of this element.
      • +
      • +String: Possible values: "parent", "document", "window".
      • +
      • +Array: An array defining a bounding box in the form [ x1, y1, x2, y2 ].
      • +
      +Code examples:

      Initialize the draggable with the containment option specified:

      +
      $( ".selector" ).draggable({ containment: "parent" });
      +

      Get or set the containment option, after initialization:

      +
      // getter
      var containment = $( ".selector" ).draggable( "option", "containment" );
       
      // setter
      $( ".selector" ).draggable( "option", "containment", "parent" );
      +
      +
      +

      cursorType: String +

      +
      +Default: "auto" +
      +
      The CSS cursor during the drag operation.
      +Code examples:

      Initialize the draggable with the cursor option specified:

      +
      $( ".selector" ).draggable({ cursor: "crosshair" });
      +

      Get or set the cursor option, after initialization:

      +
      // getter
      var cursor = $( ".selector" ).draggable( "option", "cursor" );
       
      // setter
      $( ".selector" ).draggable( "option", "cursor", "crosshair" );
      +
      +
      +

      cursorAtType: Object +

      +
      +Default: false +
      +
      Sets the offset of the dragging helper relative to the mouse cursor. Coordinates can be given as a hash using a combination of one or two keys: { top, left, right, bottom }.
      +Code examples:

      Initialize the draggable with the cursorAt option specified:

      +
      $( ".selector" ).draggable({ cursorAt: { left: 5 } });
      +

      Get or set the cursorAt option, after initialization:

      +
      // getter
      var cursorAt = $( ".selector" ).draggable( "option", "cursorAt" );
       
      // setter
      $( ".selector" ).draggable( "option", "cursorAt", { left: 5 } );
      +
      +
      +

      delayType: Number +

      +
      +Default: 0 +
      +
      Time in milliseconds after mousedown until dragging should start. This option can be used to prevent unwanted drags when clicking on an element.
      +Code examples:

      Initialize the draggable with the delay option specified:

      +
      $( ".selector" ).draggable({ delay: 300 });
      +

      Get or set the delay option, after initialization:

      +
      // getter
      var delay = $( ".selector" ).draggable( "option", "delay" );
       
      // setter
      $( ".selector" ).draggable( "option", "delay", 300 );
      +
      +
      +

      disabledType: Boolean +

      +
      +Default: false +
      +
      Disables the draggable if set to true.
      +Code examples:

      Initialize the draggable with the disabled option specified:

      +
      $( ".selector" ).draggable({ disabled: true });
      +

      Get or set the disabled option, after initialization:

      +
      // getter
      var disabled = $( ".selector" ).draggable( "option", "disabled" );
       
      // setter
      $( ".selector" ).draggable( "option", "disabled", true );
      +
      +
      +

      distanceType: Number +

      +
      +Default: 1 +
      +
      Distance in pixels after mousedown the mouse must move before dragging should start. This option can be used to prevent unwanted drags when clicking on an element.
      +Code examples:

      Initialize the draggable with the distance option specified:

      +
      $( ".selector" ).draggable({ distance: 10 });
      +

      Get or set the distance option, after initialization:

      +
      // getter
      var distance = $( ".selector" ).draggable( "option", "distance" );
       
      // setter
      $( ".selector" ).draggable( "option", "distance", 10 );
      +
      +
      +

      gridType: Array +

      +
      +Default: false +
      +
      Snaps the dragging helper to a grid, every x and y pixels. The array must be of the form [ x, y ].
      +Code examples:

      Initialize the draggable with the grid option specified:

      +
      $( ".selector" ).draggable({ grid: [ 50, 20 ] });
      +

      Get or set the grid option, after initialization:

      +
      // getter
      var grid = $( ".selector" ).draggable( "option", "grid" );
       
      // setter
      $( ".selector" ).draggable( "option", "grid", [ 50, 20 ] );
      +
      +
      +

      handleType: Selector or Element +

      +
      +Default: false +
      +
      If specified, restricts dragging from starting unless the mousedown occurs on the specified element(s).
      +Code examples:

      Initialize the draggable with the handle option specified:

      +
      $( ".selector" ).draggable({ handle: "h2" });
      +

      Get or set the handle option, after initialization:

      +
      // getter
      var handle = $( ".selector" ).draggable( "option", "handle" );
       
      // setter
      $( ".selector" ).draggable( "option", "handle", "h2" );
      +
      +
      +

      helperType: String or Function() +

      +
      +Default: "original" +
      +
      Allows for a helper element to be used for dragging display.
      +Multiple types supported:
        +
      • +String: If set to "clone", then the element will be cloned and the clone will be dragged.
      • +
      • +Function: A function that will return a DOMElement to use while dragging.
      • +
      +Code examples:

      Initialize the draggable with the helper option specified:

      +
      $( ".selector" ).draggable({ helper: "clone" });
      +

      Get or set the helper option, after initialization:

      +
      // getter
      var helper = $( ".selector" ).draggable( "option", "helper" );
       
      // setter
      $( ".selector" ).draggable( "option", "helper", "clone" );
      +
      +
      +

      iframeFixType: Boolean or Selector +

      +
      +Default: false +
      +
      Prevent iframes from capturing the mousemove events during a drag. Useful in combination with the cursorAt option, or in any case where the mouse cursor may not be over the helper.
      +Multiple types supported:
        +
      • +Boolean: When set to true, transparent overlays will be placed over all iframes on the page.
      • +
      • +Selector: Any iframes matching the selector will be covered by transparent overlays.
      • +
      +Code examples:

      Initialize the draggable with the iframeFix option specified:

      +
      $( ".selector" ).draggable({ iframeFix: true });
      +

      Get or set the iframeFix option, after initialization:

      +
      // getter
      var iframeFix = $( ".selector" ).draggable( "option", "iframeFix" );
       
      // setter
      $( ".selector" ).draggable( "option", "iframeFix", true );
      +
      +
      +

      opacityType: Number +

      +
      +Default: false +
      +
      Opacity for the helper while being dragged.
      +Code examples:

      Initialize the draggable with the opacity option specified:

      +
      $( ".selector" ).draggable({ opacity: 0.35 });
      +

      Get or set the opacity option, after initialization:

      +
      // getter
      var opacity = $( ".selector" ).draggable( "option", "opacity" );
       
      // setter
      $( ".selector" ).draggable( "option", "opacity", 0.35 );
      +
      +
      +

      refreshPositionsType: Boolean +

      +
      +Default: false +
      +
      + If set to true, all droppable positions are calculated on every mousemove. + Caution: This solves issues on highly dynamic pages, but dramatically decreases performance. +
      +Code examples:

      Initialize the draggable with the refreshPositions option specified:

      +
      $( ".selector" ).draggable({ refreshPositions: true });
      +

      Get or set the refreshPositions option, after initialization:

      +
      // getter
      var refreshPositions = $( ".selector" ).draggable( "option", "refreshPositions" );
       
      // setter
      $( ".selector" ).draggable( "option", "refreshPositions", true );
      +
      +
      +

      revertType: Boolean or String +

      +
      +Default: false +
      +
      Whether the element should revert to its start position when dragging stops.
      +Multiple types supported:
        +
      • +Boolean: If set to true the element will always revert.
      • +
      • +String: If set to "invalid", revert will only occur if the draggable has not been dropped on a droppable. For "valid", it's the other way around.
      • +
      +Code examples:

      Initialize the draggable with the revert option specified:

      +
      $( ".selector" ).draggable({ revert: true });
      +

      Get or set the revert option, after initialization:

      +
      // getter
      var revert = $( ".selector" ).draggable( "option", "revert" );
       
      // setter
      $( ".selector" ).draggable( "option", "revert", true );
      +
      +
      +

      revertDurationType: Number +

      +
      +Default: 500 +
      +
      The duration of the revert animation, in milliseconds. Ignored if the revert option is false.
      +Code examples:

      Initialize the draggable with the revertDuration option specified:

      +
      $( ".selector" ).draggable({ revertDuration: 200 });
      +

      Get or set the revertDuration option, after initialization:

      +
      // getter
      var revertDuration = $( ".selector" ).draggable( "option", "revertDuration" );
       
      // setter
      $( ".selector" ).draggable( "option", "revertDuration", 200 );
      +
      +
      +

      scopeType: String +

      +
      +Default: "default" +
      +
      Used to group sets of draggable and droppable items, in addition to droppable's accept option. A draggable with the same scope value as a droppable will be accepted by the droppable.
      +Code examples:

      Initialize the draggable with the scope option specified:

      +
      $( ".selector" ).draggable({ scope: "tasks" });
      +

      Get or set the scope option, after initialization:

      +
      // getter
      var scope = $( ".selector" ).draggable( "option", "scope" );
       
      // setter
      $( ".selector" ).draggable( "option", "scope", "tasks" );
      +
      +
      +

      scrollType: Boolean +

      +
      +Default: true +
      +
      If set to true, container auto-scrolls while dragging.
      +Code examples:

      Initialize the draggable with the scroll option specified:

      +
      $( ".selector" ).draggable({ scroll: false });
      +

      Get or set the scroll option, after initialization:

      +
      // getter
      var scroll = $( ".selector" ).draggable( "option", "scroll" );
       
      // setter
      $( ".selector" ).draggable( "option", "scroll", false );
      +
      +
      +

      scrollSensitivityType: Number +

      +
      +Default: 20 +
      +
      Distance in pixels from the edge of the viewport after which the viewport should scroll. Distance is relative to pointer, not the draggable. Ignored if the scroll option is false.
      +Code examples:

      Initialize the draggable with the scrollSensitivity option specified:

      +
      $( ".selector" ).draggable({ scrollSensitivity: 100 });
      +

      Get or set the scrollSensitivity option, after initialization:

      +
      // getter
      var scrollSensitivity = $( ".selector" ).draggable( "option", "scrollSensitivity" );
       
      // setter
      $( ".selector" ).draggable( "option", "scrollSensitivity", 100 );
      +
      +
      +

      scrollSpeedType: Number +

      +
      +Default: 20 +
      +
      The speed at which the window should scroll once the mouse pointer gets within the scrollSensitivity distance. Ignored if the scroll option is false.
      +Code examples:

      Initialize the draggable with the scrollSpeed option specified:

      +
      $( ".selector" ).draggable({ scrollSpeed: 100 });
      +

      Get or set the scrollSpeed option, after initialization:

      +
      // getter
      var scrollSpeed = $( ".selector" ).draggable( "option", "scrollSpeed" );
       
      // setter
      $( ".selector" ).draggable( "option", "scrollSpeed", 100 );
      +
      +
      +

      snapType: Boolean or Selector +

      +
      +Default: false +
      +
      Whether the element should snap to other elements.
      +Multiple types supported:
        +
      • +Boolean: When set to true, the element will snap to all other draggable elements.
      • +
      • +Selector: A selector specifying which elements to snap to.
      • +
      +Code examples:

      Initialize the draggable with the snap option specified:

      +
      $( ".selector" ).draggable({ snap: true });
      +

      Get or set the snap option, after initialization:

      +
      // getter
      var snap = $( ".selector" ).draggable( "option", "snap" );
       
      // setter
      $( ".selector" ).draggable( "option", "snap", true );
      +
      +
      +

      snapModeType: String +

      +
      +Default: "both" +
      +
      Determines which edges of snap elements the draggable will snap to. Ignored if the snap option is false. Possible values: "inner", "outer", "both".
      +Code examples:

      Initialize the draggable with the snapMode option specified:

      +
      $( ".selector" ).draggable({ snapMode: "inner" });
      +

      Get or set the snapMode option, after initialization:

      +
      // getter
      var snapMode = $( ".selector" ).draggable( "option", "snapMode" );
       
      // setter
      $( ".selector" ).draggable( "option", "snapMode", "inner" );
      +
      +
      +

      snapToleranceType: Number +

      +
      +Default: 20 +
      +
      The distance in pixels from the snap element edges at which snapping should occur. Ignored if the snap option is false.
      +Code examples:

      Initialize the draggable with the snapTolerance option specified:

      +
      $( ".selector" ).draggable({ snapTolerance: 30 });
      +

      Get or set the snapTolerance option, after initialization:

      +
      // getter
      var snapTolerance = $( ".selector" ).draggable( "option", "snapTolerance" );
       
      // setter
      $( ".selector" ).draggable( "option", "snapTolerance", 30 );
      +
      +
      +

      stackType: Selector +

      +
      +Default: false +
      +
      Controls the z-index of the set of elements that match the selector, always brings the currently dragged item to the front. Very useful in things like window managers.
      +Code examples:

      Initialize the draggable with the stack option specified:

      +
      $( ".selector" ).draggable({ stack: ".products" });
      +

      Get or set the stack option, after initialization:

      +
      // getter
      var stack = $( ".selector" ).draggable( "option", "stack" );
       
      // setter
      $( ".selector" ).draggable( "option", "stack", ".products" );
      +
      +
      +

      zIndexType: Number +

      +
      +Default: false +
      +
      Z-index for the helper while being dragged.
      +Code examples:

      Initialize the draggable with the zIndex option specified:

      +
      $( ".selector" ).draggable({ zIndex: 100 });
      +

      Get or set the zIndex option, after initialization:

      +
      // getter
      var zIndex = $( ".selector" ).draggable( "option", "zIndex" );
       
      // setter
      $( ".selector" ).draggable( "option", "zIndex", 100 );
      +

      Methods

      +
      +

      destroy()

      +
      + Removes the draggable functionality completely. This will return the element back to its pre-init state. +
      +
      • This method does not accept any arguments.
      +
      +
      +Code examples:

      Invoke the destroy method:

      +
      $( ".selector" ).draggable( "destroy" );
      +
      +
      +
      +
      +

      disable()

      +
      + Disables the draggable. +
      +
      • This method does not accept any arguments.
      +
      +
      +Code examples:

      Invoke the disable method:

      +
      $( ".selector" ).draggable( "disable" );
      +
      +
      +
      +
      +

      enable()

      +
      + Enables the draggable. +
      +
      • This method does not accept any arguments.
      +
      +
      +Code examples:

      Invoke the enable method:

      +
      $( ".selector" ).draggable( "enable" );
      +
      +
      +
      +
      +

      option( optionName ) Returns: Object +

      +
      Gets the value currently associated with the specified optionName.
      +
      • +
        optionName
        +
        Type: String +
        +
        The name of the option to get.
        +
      +
      +
      +Code examples:

      Invoke the method:

      +
      var isDisabled = $( ".selector" ).draggable( "option", "disabled" );
      +
      +
      +

      option() Returns: PlainObject +

      +
      Gets an object containing key/value pairs representing the current draggable options hash.
      +
      • This method does not accept any arguments.
      +
      +
      +Code examples:

      Invoke the method:

      +
      var options = $( ".selector" ).draggable( "option" );
      +
      +
      +

      option( optionName, value )

      +
      Sets the value of the draggable option associated with the specified optionName.
      +
        +
      • +
        optionName
        +
        Type: String +
        +
        The name of the option to set.
        +
      • +
      • +
        value
        +
        Type: Object +
        +
        A value to set for the option.
        +
      • +
      +
      +
      +Code examples:

      Invoke the method:

      +
      $( ".selector" ).draggable( "option", "disabled", true );
      +
      +
      +

      option( options )

      +
      Sets one or more options for the draggable.
      +
      • +
        options
        +
        Type: Object +
        +
        A map of option-value pairs to set.
        +
      +
      +
      +Code examples:

      Invoke the method:

      +
      $( ".selector" ).draggable( "option", { disabled: true } );
      +
      +
      +
      +
      +

      widget() Returns: jQuery +

      +
      + Returns a jQuery object containing the draggable element. +
      +
      • This method does not accept any arguments.
      +
      +
      +Code examples:

      Invoke the widget method:

      +
      var widget = $( ".selector" ).draggable( "widget" );
      +
      +

      Events

      +

      create( event, ui )Type: dragcreate +

      +
      + Triggered when the draggable is created. +
      +
        +
      • +
        event
        +
        Type: Event +
        +
        +
      • +
      • +
        ui
        +
        Type: Object +
        +
        +
      • +
      +
      +Code examples:

      Initialize the draggable with the create callback specified:

      +
      $( ".selector" ).draggable({
          create: function( event, ui ) {}
      });
      +

      Bind an event listener to the dragcreate event:

      +
      $( ".selector" ).on( "dragcreate", function( event, ui ) {} );
      +
      +
      +
      +

      drag( event, ui )Type: drag +

      +
      Triggered while the mouse is moved during the dragging.
      +
        +
      • +
        event
        +
        Type: Event +
        +
        +
      • +
      • +
        ui
        +
        Type: Object +
        +
        +
          +
        • +
          helper
          +
          Type: jQuery +
          +
          The jQuery object representing the helper that's being dragged.
          +
        • +
        • +
          position
          +
          Type: Object +
          +
          Current CSS position of the helper as { top, left } object.
          +
        • +
        • +
          offset
          +
          Type: Object +
          +
          Current offset position of the helper as { top, left } object.
          +
        • +
        +
      • +
      +
      +Code examples:

      Initialize the draggable with the drag callback specified:

      +
      $( ".selector" ).draggable({
          drag: function( event, ui ) {}
      });
      +

      Bind an event listener to the drag event:

      +
      $( ".selector" ).on( "drag", function( event, ui ) {} );
      +
      +
      +
      +

      start( event, ui )Type: dragstart +

      +
      Triggered when dragging starts.
      +
        +
      • +
        event
        +
        Type: Event +
        +
        +
      • +
      • +
        ui
        +
        Type: Object +
        +
        +
          +
        • +
          helper
          +
          Type: jQuery +
          +
          The jQuery object representing the helper that's being dragged.
          +
        • +
        • +
          position
          +
          Type: Object +
          +
          Current CSS position of the helper as { top, left } object.
          +
        • +
        • +
          offset
          +
          Type: Object +
          +
          Current offset position of the helper as { top, left } object.
          +
        • +
        +
      • +
      +
      +Code examples:

      Initialize the draggable with the start callback specified:

      +
      $( ".selector" ).draggable({
          start: function( event, ui ) {}
      });
      +

      Bind an event listener to the dragstart event:

      +
      $( ".selector" ).on( "dragstart", function( event, ui ) {} );
      +
      +
      +
      +

      stop( event, ui )Type: dragstop +

      +
      Triggered when dragging stops.
      +
        +
      • +
        event
        +
        Type: Event +
        +
        +
      • +
      • +
        ui
        +
        Type: Object +
        +
        +
          +
        • +
          helper
          +
          Type: jQuery +
          +
          The jQuery object representing the helper that's being dragged.
          +
        • +
        • +
          position
          +
          Type: Object +
          +
          Current CSS position of the helper as { top, left } object.
          +
        • +
        • +
          offset
          +
          Type: Object +
          +
          Current offset position of the helper as { top, left } object.
          +
        • +
        +
      • +
      +
      +Code examples:

      Initialize the draggable with the stop callback specified:

      +
      $( ".selector" ).draggable({
          stop: function( event, ui ) {}
      });
      +

      Bind an event listener to the dragstop event:

      +
      $( ".selector" ).on( "dragstop", function( event, ui ) {} );
      +
      +
      +

      Overview

      +

      Make the selected elements draggable by mouse. If you want not just drag, but drag & drop, see the jQuery UI Droppable plugin, which provides a drop target for draggables.

      +
      +

      Example:

      +

      A simple jQuery UI Draggable

      +
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      24
      25
      26
      <!doctype html>
      <html lang="en">
      <head>
          <meta charset="utf-8">
          <title>draggable demo</title>
          <link rel="stylesheet" href="http://code.jquery.com/ui/1.9.2/themes/base/jquery-ui.css">
          <style>
          #draggable {
              width: 100px;
              height: 100px;
              background: #ccc;
          }
          </style>
          <script src="http://code.jquery.com/jquery-1.8.3.js"></script>
          <script src="http://code.jquery.com/ui/1.9.2/jquery-ui.js"></script>
      </head>
      <body>
       
      <div id="draggable">Drag me</div>
       
      <script>
      $( "#draggable" ).draggable();
      </script>
       
      </body>
      </html>
      +

      Demo:

      +
      +
      +
      + + + diff --git a/htdocs/js/lib/vendor/jquery-drag-drop/development-bundle/docs/droppable.html b/htdocs/js/lib/vendor/jquery-drag-drop/development-bundle/docs/droppable.html new file mode 100755 index 000000000..30b39c8bb --- /dev/null +++ b/htdocs/js/lib/vendor/jquery-drag-drop/development-bundle/docs/droppable.html @@ -0,0 +1,557 @@ + + + + + jQuery UI droppable documentation + + + + + +

      QuickNavOverviewExamples +

      + +

      +Droppable Widgetversion added: 1.0 +

      +
      +

      Description: Create targets for draggable elements.

      +

      Options

      +

      acceptType: Selector or Function() +

      +
      +Default: "*" +
      +
      Controls which draggable elements are accepted by the droppable.
      +Multiple types supported:
        +
      • +Selector: A selector indicating which draggable elements are accepted.
      • +
      • +Function: A function that will be called for each draggable on the page (passed as the first argument to the function). The function must return true if the draggable should be accepted.
      • +
      +Code examples:

      Initialize the droppable with the accept option specified:

      +
      $( ".selector" ).droppable({ accept: ".special" });
      +

      Get or set the accept option, after initialization:

      +
      // getter
      var accept = $( ".selector" ).droppable( "option", "accept" );
       
      // setter
      $( ".selector" ).droppable( "option", "accept", ".special" );
      +
      +
      +

      activeClassType: String +

      +
      +Default: false +
      +
      If specified, the class will be added to the droppable while an acceptable draggable is being dragged.
      +Code examples:

      Initialize the droppable with the activeClass option specified:

      +
      $( ".selector" ).droppable({ activeClass: "ui-state-highlight" });
      +

      Get or set the activeClass option, after initialization:

      +
      // getter
      var activeClass = $( ".selector" ).droppable( "option", "activeClass" );
       
      // setter
      $( ".selector" ).droppable( "option", "activeClass", "ui-state-highlight" );
      +
      +
      +

      addClassesType: Boolean +

      +
      +Default: true +
      +
      If set to false, will prevent the ui-droppable class from being added. This may be desired as a performance optimization when calling .droppable() init on hundreds of elements.
      +Code examples:

      Initialize the droppable with the addClasses option specified:

      +
      $( ".selector" ).droppable({ addClasses: false });
      +

      Get or set the addClasses option, after initialization:

      +
      // getter
      var addClasses = $( ".selector" ).droppable( "option", "addClasses" );
       
      // setter
      $( ".selector" ).droppable( "option", "addClasses", false );
      +
      +
      +

      disabledType: Boolean +

      +
      +Default: false +
      +
      Disables the droppable if set to true.
      +Code examples:

      Initialize the droppable with the disabled option specified:

      +
      $( ".selector" ).droppable({ disabled: true });
      +

      Get or set the disabled option, after initialization:

      +
      // getter
      var disabled = $( ".selector" ).droppable( "option", "disabled" );
       
      // setter
      $( ".selector" ).droppable( "option", "disabled", true );
      +
      +
      +

      greedyType: Boolean +

      +
      +Default: false +
      +
      By default, when an element is dropped on nested droppables, each droppable will receive the element. However, by setting this option to true, any parent droppables will not receive the element.
      +Code examples:

      Initialize the droppable with the greedy option specified:

      +
      $( ".selector" ).droppable({ greedy: true });
      +

      Get or set the greedy option, after initialization:

      +
      // getter
      var greedy = $( ".selector" ).droppable( "option", "greedy" );
       
      // setter
      $( ".selector" ).droppable( "option", "greedy", true );
      +
      +
      +

      hoverClassType: String +

      +
      +Default: false +
      +
      If specified, the class will be added to the droppable while an acceptable draggable is being hovered over the droppable.
      +Code examples:

      Initialize the droppable with the hoverClass option specified:

      +
      $( ".selector" ).droppable({ hoverClass: "drop-hover" });
      +

      Get or set the hoverClass option, after initialization:

      +
      // getter
      var hoverClass = $( ".selector" ).droppable( "option", "hoverClass" );
       
      // setter
      $( ".selector" ).droppable( "option", "hoverClass", "drop-hover" );
      +
      +
      +

      scopeType: String +

      +
      +Default: "default" +
      +
      Used to group sets of draggable and droppable items, in addition to the accept option. A draggable with the same scope value as a droppable will be accepted.
      +Code examples:

      Initialize the droppable with the scope option specified:

      +
      $( ".selector" ).droppable({ scope: "tasks" });
      +

      Get or set the scope option, after initialization:

      +
      // getter
      var scope = $( ".selector" ).droppable( "option", "scope" );
       
      // setter
      $( ".selector" ).droppable( "option", "scope", "tasks" );
      +
      +
      +

      toleranceType: String +

      +
      +Default: "intersect" +
      +
      + Specifies which mode to use for testing whether a draggable is hovering over a droppable. Possible values: +
        +
      • +"fit": Draggable overlaps the droppable entirely.
      • +
      • +"intersect": Draggable overlaps the droppable at least 50% in both directions.
      • +
      • +"pointer": Mouse pointer overlaps the droppable.
      • +
      • +"touch": Draggable overlaps the droppable any amount.
      • +
      +
      +Code examples:

      Initialize the droppable with the tolerance option specified:

      +
      $( ".selector" ).droppable({ tolerance: "fit" });
      +

      Get or set the tolerance option, after initialization:

      +
      // getter
      var tolerance = $( ".selector" ).droppable( "option", "tolerance" );
       
      // setter
      $( ".selector" ).droppable( "option", "tolerance", "fit" );
      +

      Methods

      +
      +

      destroy()

      +
      + Removes the droppable functionality completely. This will return the element back to its pre-init state. +
      +
      • This method does not accept any arguments.
      +
      +
      +Code examples:

      Invoke the destroy method:

      +
      $( ".selector" ).droppable( "destroy" );
      +
      +
      +
      +
      +

      disable()

      +
      + Disables the droppable. +
      +
      • This method does not accept any arguments.
      +
      +
      +Code examples:

      Invoke the disable method:

      +
      $( ".selector" ).droppable( "disable" );
      +
      +
      +
      +
      +

      enable()

      +
      + Enables the droppable. +
      +
      • This method does not accept any arguments.
      +
      +
      +Code examples:

      Invoke the enable method:

      +
      $( ".selector" ).droppable( "enable" );
      +
      +
      +
      +
      +

      option( optionName ) Returns: Object +

      +
      Gets the value currently associated with the specified optionName.
      +
      • +
        optionName
        +
        Type: String +
        +
        The name of the option to get.
        +
      +
      +
      +Code examples:

      Invoke the method:

      +
      var isDisabled = $( ".selector" ).droppable( "option", "disabled" );
      +
      +
      +

      option() Returns: PlainObject +

      +
      Gets an object containing key/value pairs representing the current droppable options hash.
      +
      • This method does not accept any arguments.
      +
      +
      +Code examples:

      Invoke the method:

      +
      var options = $( ".selector" ).droppable( "option" );
      +
      +
      +

      option( optionName, value )

      +
      Sets the value of the droppable option associated with the specified optionName.
      +
        +
      • +
        optionName
        +
        Type: String +
        +
        The name of the option to set.
        +
      • +
      • +
        value
        +
        Type: Object +
        +
        A value to set for the option.
        +
      • +
      +
      +
      +Code examples:

      Invoke the method:

      +
      $( ".selector" ).droppable( "option", "disabled", true );
      +
      +
      +

      option( options )

      +
      Sets one or more options for the droppable.
      +
      • +
        options
        +
        Type: Object +
        +
        A map of option-value pairs to set.
        +
      +
      +
      +Code examples:

      Invoke the method:

      +
      $( ".selector" ).droppable( "option", { disabled: true } );
      +
      +
      +
      +
      +

      widget() Returns: jQuery +

      +
      + Returns a jQuery object containing the droppable element. +
      +
      • This method does not accept any arguments.
      +
      +
      +Code examples:

      Invoke the widget method:

      +
      var widget = $( ".selector" ).droppable( "widget" );
      +
      +

      Events

      +

      activate( event, ui )Type: dropactivate +

      +
      Triggered when an accepted draggable starts dragging. This can be useful if you want to make the droppable "light up" when it can be dropped on.
      +
        +
      • +
        event
        +
        Type: Event +
        +
        +
      • +
      • +
        ui
        +
        Type: Object +
        +
        +
          +
        • +
          draggable
          +
          Type: jQuery +
          +
          A jQuery object representing the draggable element.
          +
        • +
        • +
          helper
          +
          Type: jQuery +
          +
          A jQuery object representing the helper that is being dragged.
          +
        • +
        • +
          position
          +
          Type: Object +
          +
          Current CSS position of the draggable helper as { top, left } object.
          +
        • +
        • +
          offset
          +
          Type: Object +
          +
          Current offset position of the draggable helper as { top, left } object.
          +
        • +
        +
      • +
      +
      +Code examples:

      Initialize the droppable with the activate callback specified:

      +
      $( ".selector" ).droppable({
          activate: function( event, ui ) {}
      });
      +

      Bind an event listener to the dropactivate event:

      +
      $( ".selector" ).on( "dropactivate", function( event, ui ) {} );
      +
      +
      +
      +

      create( event, ui )Type: dropcreate +

      +
      + Triggered when the droppable is created. +
      +
        +
      • +
        event
        +
        Type: Event +
        +
        +
      • +
      • +
        ui
        +
        Type: Object +
        +
        +
      • +
      +
      +Code examples:

      Initialize the droppable with the create callback specified:

      +
      $( ".selector" ).droppable({
          create: function( event, ui ) {}
      });
      +

      Bind an event listener to the dropcreate event:

      +
      $( ".selector" ).on( "dropcreate", function( event, ui ) {} );
      +
      +
      +
      +

      deactivate( event, ui )Type: dropdeactivate +

      +
      Triggered when an accepted draggable stops dragging.
      +
        +
      • +
        event
        +
        Type: Event +
        +
        +
      • +
      • +
        ui
        +
        Type: Object +
        +
        +
          +
        • +
          draggable
          +
          Type: jQuery +
          +
          A jQuery object representing the draggable element.
          +
        • +
        • +
          helper
          +
          Type: jQuery +
          +
          A jQuery object representing the helper that is being dragged.
          +
        • +
        • +
          position
          +
          Type: Object +
          +
          Current CSS position of the draggable helper as { top, left } object.
          +
        • +
        • +
          offset
          +
          Type: Object +
          +
          Current offset position of the draggable helper as { top, left } object.
          +
        • +
        +
      • +
      +
      +Code examples:

      Initialize the droppable with the deactivate callback specified:

      +
      $( ".selector" ).droppable({
          deactivate: function( event, ui ) {}
      });
      +

      Bind an event listener to the dropdeactivate event:

      +
      $( ".selector" ).on( "dropdeactivate", function( event, ui ) {} );
      +
      +
      +
      +

      drop( event, ui )Type: drop +

      +
      Triggered when an accepted draggable is dropped on the droppable (based on thetolerance option).
      +
        +
      • +
        event
        +
        Type: Event +
        +
        +
      • +
      • +
        ui
        +
        Type: Object +
        +
        +
          +
        • +
          draggable
          +
          Type: jQuery +
          +
          A jQuery object representing the draggable element.
          +
        • +
        • +
          helper
          +
          Type: jQuery +
          +
          A jQuery object representing the helper that is being dragged.
          +
        • +
        • +
          position
          +
          Type: Object +
          +
          Current CSS position of the draggable helper as { top, left } object.
          +
        • +
        • +
          offset
          +
          Type: Object +
          +
          Current offset position of the draggable helper as { top, left } object.
          +
        • +
        +
      • +
      +
      +Code examples:

      Initialize the droppable with the drop callback specified:

      +
      $( ".selector" ).droppable({
          drop: function( event, ui ) {}
      });
      +

      Bind an event listener to the drop event:

      +
      $( ".selector" ).on( "drop", function( event, ui ) {} );
      +
      +
      +
      +

      out( event, ui )Type: dropout +

      +
      Triggered when an accepted draggable is dragged out of the droppable (based on thetolerance option).
      +
        +
      • +
        event
        +
        Type: Event +
        +
        +
      • +
      • +
        ui
        +
        Type: Object +
        +
        +
      • +
      +
      +Code examples:

      Initialize the droppable with the out callback specified:

      +
      $( ".selector" ).droppable({
          out: function( event, ui ) {}
      });
      +

      Bind an event listener to the dropout event:

      +
      $( ".selector" ).on( "dropout", function( event, ui ) {} );
      +
      +
      +
      +

      over( event, ui )Type: dropover +

      +
      Triggered when an accepted draggable is dragged over the droppable (based on thetolerance option).
      +
        +
      • +
        event
        +
        Type: Event +
        +
        +
      • +
      • +
        ui
        +
        Type: Object +
        +
        +
          +
        • +
          draggable
          +
          Type: jQuery +
          +
          A jQuery object representing the draggable element.
          +
        • +
        • +
          helper
          +
          Type: jQuery +
          +
          A jQuery object representing the helper that is being dragged.
          +
        • +
        • +
          position
          +
          Type: Object +
          +
          Current CSS position of the draggable helper as { top, left } object.
          +
        • +
        • +
          offset
          +
          Type: Object +
          +
          Current offset position of the draggable helper as { top, left } object.
          +
        • +
        +
      • +
      +
      +Code examples:

      Initialize the droppable with the over callback specified:

      +
      $( ".selector" ).droppable({
          over: function( event, ui ) {}
      });
      +

      Bind an event listener to the dropover event:

      +
      $( ".selector" ).on( "dropover", function( event, ui ) {} );
      +
      +
      +

      Overview

      +

      The jQuery UI Droppable plugin makes selected elements droppable (meaning they accept being dropped on by draggables). You can specify which draggables each will accept.

      +
      +

      Example:

      +

      A pair of draggable and droppable elements.

      +
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      24
      25
      26
      27
      28
      29
      30
      31
      32
      33
      34
      35
      36
      37
      38
      39
      40
      41
      42
      <!doctype html>
      <html lang="en">
      <head>
          <meta charset="utf-8">
          <title>droppable demo</title>
          <link rel="stylesheet" href="http://code.jquery.com/ui/1.9.2/themes/base/jquery-ui.css">
          <style>
          #draggable {
              width: 100px;
              height: 100px;
              background: #ccc;
          }
          #droppable {
              position: absolute;
              left: 250px;
              top: 0;
              width: 125px;
              height: 125px;
              background: #999;
              color: #fff;
              padding: 10px;
          }
          </style>
          <script src="http://code.jquery.com/jquery-1.8.3.js"></script>
          <script src="http://code.jquery.com/ui/1.9.2/jquery-ui.js"></script>
      </head>
      <body>
       
      <div id="droppable">Drop here</div>
      <div id="draggable">Drag me</div>
       
      <script>
      $( "#draggable" ).draggable();
      $( "#droppable" ).droppable({
          drop: function() {
              alert( "dropped" );
          }
      });
      </script>
       
      </body>
      </html>
      +

      Demo:

      +
      +
      +
      + + + diff --git a/htdocs/js/lib/vendor/jquery-drag-drop/development-bundle/docs/jQuery.widget.html b/htdocs/js/lib/vendor/jquery-drag-drop/development-bundle/docs/jQuery.widget.html new file mode 100755 index 000000000..4b30f904c --- /dev/null +++ b/htdocs/js/lib/vendor/jquery-drag-drop/development-bundle/docs/jQuery.widget.html @@ -0,0 +1,611 @@ + + + + + jQuery UI jQuery documentation + + + + + +
      +

      Contents:

      + +

      jQuery.widget( name [, base ], prototype )

      +
      +

      Description: Create stateful jQuery plugins using the same abstraction as all jQuery UI widgets.

      +
      • +

        jQuery.widget( name [, base ], prototype )

        +
          +
        • +
          name
          +
          Type: String +
          +
          The name of the widget to create, including the namespace.
          +
        • +
        • +
          base
          +
          Type: Function()
          +
          The base widget to inherit from. This must be a constructor that can be instantiated with the `new` keyword. Defaults to jQuery.Widget.
          +
        • +
        • +
          prototype
          +
          Type: PlainObject +
          +
          The object to use as a prototype for the widget.
          +
        • +
        +
      +
      +

      You can create new widgets from scratch, using just the $.Widget object as a base to inherit from, or you can explicitly inherit from existing jQuery UI or third-party widgets. Defining a widget with the same name as you inherit from even allows you to extend widgets in place.

      + +

      jQuery UI contains many widgets that maintain state and therefore have a slightly different usage pattern than typical jQuery plugins. All of jQuery UI's widgets use the same patterns, which is defined by the widget factory. So if you learn how to use one widget, then you'll know how to use all of them.

      + +

      Note: This documentation shows examples using the progressbar widget but the syntax is the same for every widget.

      + +

      Initialization

      + +

      In order to track the state of the widget, we must introduce a full life cycle for the widget. The life cycle starts when the widget is initalized. To initialize a widget, we simply call the plugin on one or more elements.

      + +
      $( "#elem" ).progressbar();
      + +

      This will initialize each element in the jQuery object, in this case the element with an id of "elem". Because we called the progressbar() method with no parameters, the widget is initialized with its default options. We can pass a set of options during initialization in order to override the default options.

      + +
      $( "#elem" ).progressbar({ value: 20 });
      + +

      We can pass as many or as few options as we want during initialization. Any options that we don't pass will just use their default values.

      + +

      The options are part of the widget's state, so we can set options after initialization as well. We'll see this later with the option method.

      + +

      Methods

      + +

      Now that the widget is initialized, we can query its state or perform actions on the widget. All actions after initialization take the form of a method call. To call a method on a widget, we pass the name of the method to the jQuery plugin. For example, to call the value() method on our progressbar widget, we would use:

      + +
      $( "#elem" ).progressbar( "value" );
      + +

      If the method accepts parameters, we can pass them after the method name. For example, to pass the parameter 40 to the value() method, we can use:

      + +
      $( "#elem" ).progressbar( "value", 40 );
      + +

      Just like other methods in jQuery, most widget methods return the jQuery object for chaining.

      + +
      $( "#elem" )
          .progressbar( "value", 90 )
          .addClass( "almost-done" );
      + +

      Each widget will have its own set of methods based on the functionality that the widget provides. However, there are a few methods that exist on all widgets, which are documented below.

      + +

      Events

      + +

      All widgets have events associated with their various behaviors to notify you when the state is changing. For most widgets, when the events are triggered, the names are prefixed with the widget name. For example, we can bind to progressbar's change event which is triggered whenever the value changes.

      + +
      $( "#elem" ).bind( "progressbarchange", function() {
          alert( "The value has changed!" );
      });
      + +

      Each event has a corresponding callback, which is exposed as an option. We can hook into progressbar's change callback instead of binding to the progressbarchange event, if we want to.

      + +
      $( "#elem" ).progressbar({
          change: function() {
              alert( "The value has changed!" );
          }
      });
      + +

      All widgets have a create event which is triggered upon instantiation.

      +
      +

      QuickNav

      +

      Options

      + + + +
      + +
      +

      Events

      + +

      Base Widget

      +
      +

      Description: The base widget used by the widget factory.

      +

      Options

      +

      disabledType: Boolean +

      +
      +Default: false +
      +
      Disables the jQuery.Widget if set to true.
      +Code examples:

      Initialize the jQuery.Widget with the disabled option specified:

      +
      $( ".selector" ).jQuery.Widget({ disabled: true });
      +

      Get or set the disabled option, after initialization:

      +
      // getter
      var disabled = $( ".selector" ).jQuery.Widget( "option", "disabled" );
       
      // setter
      $( ".selector" ).jQuery.Widget( "option", "disabled", true );
      +
      +
      +

      hideType: Boolean or Number or String or Object +

      +
      +Default: null +
      +
      If and how to animate the hiding of the element.
      +Multiple types supported:
        +
      • +Boolean: + When set to false, no animation will be used and the element will be hidden immediately. + When set to true, the element will fade out with the default duration and the default easing. +
      • +
      • +Number: + The element will fade out with the specified duration and the default easing. +
      • +
      • +String: + The element will be hidden using the specified effect. + The value can either be the name of a built-in jQuery animateion method, such as "slideUp", or the name of a jQuery UI effect, such as "fold". + In either case the effect will be used with the default duration and the default easing. +
      • +
      • +Object: If the value is an object, then effect, duration, and easing properties may be provided. If the effect property contains the name of a jQuery method, then that method will be used; otherwise it is assumed to be the name of a jQuery UI effect. When using a jQuery UI effect that supports additional settings, you may include those settings in the object and they will be passed to the effect. If duration or easing is omitted, then the default values will be used. If effect is omitted, then "fadeOut" will be used.
      • +
      +Code examples:

      Initialize the jQuery.Widget with the hide option specified:

      +
      $( ".selector" ).jQuery.Widget({ hide: { effect: "explode", duration: 1000 } });
      +

      Get or set the hide option, after initialization:

      +
      // getter
      var hide = $( ".selector" ).jQuery.Widget( "option", "hide" );
       
      // setter
      $( ".selector" ).jQuery.Widget( "option", "hide", { effect: "explode", duration: 1000 } );
      +
      +
      +

      showType: Boolean or Number or String or Object +

      +
      +Default: null +
      +
      If and how to animate the showing of the element.
      +Multiple types supported:
        +
      • +Boolean: + When set to false, no animation will be used and the element will be shown immediately. + When set to true, the element will fade in with the default duration and the default easing. +
      • +
      • +Number: + The element will fade in with the specified duration and the default easing. +
      • +
      • +String: + The element will be shown using the specified effect. + The value can either be the name of a built-in jQuery animateion method, such as "slideDown", or the name of a jQuery UI effect, such as "fold". + In either case the effect will be used with the default duration and the default easing. +
      • +
      • +Object: If the value is an object, then effect, duration, and easing properties may be provided. If the effect property contains the name of a jQuery method, then that method will be used; otherwise it is assumed to be the name of a jQuery UI effect. When using a jQuery UI effect that supports additional settings, you may include those settings in the object and they will be passed to the effect. If duration or easing is omitted, then the default values will be used. If effect is omitted, then "fadeIn" will be used.
      • +
      +Code examples:

      Initialize the jQuery.Widget with the show option specified:

      +
      $( ".selector" ).jQuery.Widget({ show: { effect: "blind", duration: 800 } });
      +

      Get or set the show option, after initialization:

      +
      // getter
      var show = $( ".selector" ).jQuery.Widget( "option", "show" );
       
      // setter
      $( ".selector" ).jQuery.Widget( "option", "show", { effect: "blind", duration: 800 } );
      +

      Methods

      +

      _create()

      +
      + The _create() method is the widget's constructor. + There are no parameters, but this.element and this.options are already set. +
      +
      • This method does not accept any arguments.
      +
      +
      +

      _delay( fn [, delay ] ) Returns: Number +

      +
      + Invokes the provided function after a specified delay. Keeps this context correct. Essentially setTimeout(). +

      Returns the timeout ID for use with clearTimeout().

      +
      +
        +
      • +
        fn
        +
        Type: Function() or String +
        +
        The function to invoke. Can also be the name of a method on the widget.
        +
      • +
      • +
        delay
        +
        Type: Number +
        +
        The number of milliseconds to wait before invoking the function. Deafults to 0.
        +
      • +
      +
      +
      +

      _destroy()

      +
      + The public destroy() method cleans up all common data, events, etc. and then delegates out to _destroy() for custom, widget-specific, cleanup. +
      +
      • This method does not accept any arguments.
      +
      +
      +

      _focusable( element )

      +
      + Sets up element to apply the ui-state-focus class on focus. +

      The event handlers are automatically cleaned up on destroy.

      +
      +
      • +
        element
        +
        Type: jQuery +
        +
        The element(s) to apply the focusable behavior to.
        +
      +
      +
      +

      _getCreateEventData() Returns: Object +

      +
      + All widgets trigger the create event. By default, no data is provided in the event, but this method can return an object which will be passed as the create event's data. +
      +
      • This method does not accept any arguments.
      +
      +
      +

      _getCreateOptions() Returns: Object +

      +
      + This method allows the widget to define a custom method for defining options during instantiation. This user-provided options override the options returned by this method which override the default options. +
      +
      • This method does not accept any arguments.
      +
      +
      +

      _hide( element, option [, callback ] )

      +
      + Hides an element immediately, using built-in animation methods, or using custom effects. + See the hide option for possible option values. +
      +
        +
      • +
        element
        +
        Type: jQuery +
        +
        The element(s) to hide.
        +
      • +
      • +
        option
        +
        Type: Object +
        +
        The settings defining how to hide the element.
        +
      • +
      • +
        callback
        +
        Type: Function()
        +
        Callback to invoke after the element has been fully hidden.
        +
      • +
      +
      +
      +

      _hoverable( element )

      +
      + Sets up element to apply the ui-state-hover class on hover. +

      The event handlers are automatically cleaned up on destroy.

      +
      +
      • +
        element
        +
        Type: jQuery +
        +
        The element(s) to apply the hoverable behavior to.
        +
      +
      +
      +

      _init()

      +
      + Widgets have the concept of initialization that is distinct from creation. Any time the plugin is called with no arguments or with only an option hash, the widget is initialized; this includes when the widget is created. + +

      Note: Initialization should only be handled if there is a logical action to perform on successive calls to the widget with no arguments.

      +
      +
      • This method does not accept any arguments.
      +
      +
      +

      _off( element, eventName )

      +
      + Unbinds event handlers from the specified element(s). +
      +
        +
      • +
        element
        +
        Type: jQuery +
        +
        + The element(s) to unbind the event handlers from. Unlike the _on() method, the elements are required for _off(). +
        +
      • +
      • +
        eventName
        +
        Type: String +
        +
        One or more space-separated event types.
        +
      • +
      +
      +
      +

      _on( [element ], handlers )

      +
      + Binds event handlers to the specified element(s). Delegation is supported via selectors inside the event names, e.g., "click .foo". The _on() method provides several benefits of direct event binding: +
        +
      • Maintains proper this context inside the handlers.
      • +
      • Automatically handles disabled widgets: If the widget is disabled or the event occurs on an element with the ui-state-disabled class, the event handler is not invoked.
      • +
      • Event handlers are automatically namespaced and cleaned up on destroy.
      • +
      +
      +
        +
      • +
        element
        +
        Type: jQuery +
        +
        Which element(s) to bind the event handlers to. If no element is provided, this.element is used.
        +
      • +
      • +
        handlers
        +
        Type: Object +
        +
        + A map in which the string keys represent the event type and optional selector for delegation, and the values represent a handler function to be called for the event. +
        +
      • +
      +
      +
      +

      _setOption( key, value )

      +
      + Called from the _setOptions() method for each individual option. Widget state should be updated based on changes. +
      +
        +
      • +
        key
        +
        Type: String +
        +
        The name of the option to set.
        +
      • +
      • +
        value
        +
        Type: Object +
        +
        A value to set for the option.
        +
      • +
      +
      +
      +

      _setOptions( options )

      +
      + Called whenever the option() method is called, regardless of the form in which the option() method was called. +

      Overriding this is useful if you can defer processor-intensive changes for multiple option changes.

      +
      +
      • +
        options
        +
        Type: Object +
        +
        A map of option-value pairs to set.
        +
      +
      +
      +

      _show( element, option [, callback ] )

      +
      + Shows an element immediately, using built-in animation methods, or using custom effects. + See the show option for possible option values. +
      +
        +
      • +
        element
        +
        Type: jQuery +
        +
        The element(s) to show.
        +
      • +
      • +
        option
        +
        Type: Object +
        +
        The settings defining how to show the element.
        +
      • +
      • +
        callback
        +
        Type: Function()
        +
        Callback to invoke after the element has been fully shown.
        +
      • +
      +
      +
      +

      _super()

      +
      + Invokes the method of the same name from the parent widget, with any specified arguments. Essentially .call(). +
      +
      • This method does not accept any arguments.
      +
      +
      +

      _superApply( arguments )

      +
      + Invokes the method of the same name from the parent widget, with the array of arguments. Essentially .apply(). +
      +
      • +
        arguments
        +
        Type: Array +
        +
        Array of arguments to pass to the parent method.
        +
      +
      +
      +

      _trigger( type [, event ] [, data ] )

      +
      + Triggers an event and its associated callback. +

      The option with the name equal to type is invoked as the callback.

      +

      The event name is the widget name + type.

      +

      Note: When providing data, you must provide all three parameters. If there is no event to pass along, just pass null.

      +
      +
        +
      • +
        type
        +
        Type: String +
        +
        The type should match the name of a callback option. The full event type will be generated automatically.
        +
      • +
      • +
        event
        +
        Type: Event +
        +
        The original event that caused this event to occur; useful for providing context to the listener.
        +
      • +
      • +
        data
        +
        Type: Object +
        +
        A hash of data associated with the event.
        +
      • +
      +
      +
      +

      destroy()

      +
      + Removes the jQuery.Widget functionality completely. This will return the element back to its pre-init state. +
      +
      • This method does not accept any arguments.
      +
      +
      +

      disable()

      +
      + Disables the jQuery.Widget. +
      +
      • This method does not accept any arguments.
      +
      +
      +

      enable()

      +
      + Enables the jQuery.Widget. +
      +
      • This method does not accept any arguments.
      +
      +
      +
      +

      option( optionName ) Returns: Object +

      +
      Gets the value currently associated with the specified optionName.
      +
      • +
        optionName
        +
        Type: String +
        +
        The name of the option to get.
        +
      +
      +
      +Code examples:

      Invoke the method:

      +
      var isDisabled = $( ".selector" ).jQuery.Widget( "option", "disabled" );
      +
      +
      +

      option() Returns: PlainObject +

      +
      Gets an object containing key/value pairs representing the current jQuery.Widget options hash.
      +
      • This method does not accept any arguments.
      +
      +
      +Code examples:

      Invoke the method:

      +
      var options = $( ".selector" ).jQuery.Widget( "option" );
      +
      +
      +

      option( optionName, value )

      +
      Sets the value of the jQuery.Widget option associated with the specified optionName.
      +
        +
      • +
        optionName
        +
        Type: String +
        +
        The name of the option to set.
        +
      • +
      • +
        value
        +
        Type: Object +
        +
        A value to set for the option.
        +
      • +
      +
      +
      +Code examples:

      Invoke the method:

      +
      $( ".selector" ).jQuery.Widget( "option", "disabled", true );
      +
      +
      +

      option( options )

      +
      Sets one or more options for the jQuery.Widget.
      +
      • +
        options
        +
        Type: Object +
        +
        A map of option-value pairs to set.
        +
      +
      +
      +Code examples:

      Invoke the method:

      +
      $( ".selector" ).jQuery.Widget( "option", { disabled: true } );
      +
      +
      +
      +

      widget() Returns: jQuery +

      +
      + Returns a jQuery object containing the original element or other relevant generated element. +
      +
      • This method does not accept any arguments.
      +

      Events

      +

      create( event, ui )Type: jQuery.Widgetcreate +

      +
      + Triggered when the jQuery.Widget is created. +
      +
        +
      • +
        event
        +
        Type: Event +
        +
        +
      • +
      • +
        ui
        +
        Type: Object +
        +
        +
      • +
      +
      +Code examples:

      Initialize the jQuery.Widget with the create callback specified:

      +
      $( ".selector" ).jQuery.Widget({
          create: function( event, ui ) {}
      });
      +

      Bind an event listener to the jQuery.Widgetcreate event:

      +
      $( ".selector" ).on( "jQuery.Widgetcreate", function( event, ui ) {} );
      +
      +
      +
      + + + diff --git a/htdocs/js/lib/vendor/jquery-drag-drop/development-bundle/docs/mouse.html b/htdocs/js/lib/vendor/jquery-drag-drop/development-bundle/docs/mouse.html new file mode 100755 index 000000000..7fd4d0e86 --- /dev/null +++ b/htdocs/js/lib/vendor/jquery-drag-drop/development-bundle/docs/mouse.html @@ -0,0 +1,239 @@ + + + + + jQuery UI mouse documentation + + + + + +

      QuickNavOverview +

      +

      Options

      + + + +
      + +

      Events

      Mouse Interaction

      +
      +

      Description: The base interaction layer.

      +

      Options

      +

      cancelType: Selector +

      +
      +Default: "input,textarea,button,select,option" +
      +
      Prevents interactions from starting on specified elements.
      +Code examples:

      Initialize the jQuery.ui.mouse with the cancel option specified:

      +
      $( ".selector" ).jQuery.ui.mouse({ cancel: ".title" });
      +

      Get or set the cancel option, after initialization:

      +
      // getter
      var cancel = $( ".selector" ).jQuery.ui.mouse( "option", "cancel" );
       
      // setter
      $( ".selector" ).jQuery.ui.mouse( "option", "cancel", ".title" );
      +
      +
      +

      delayType: Number +

      +
      +Default: 0 +
      +
      Time in milliseconds after mousedown until the interaction should start. This option can be used to prevent unwanted interactions when clicking on an element.
      +Code examples:

      Initialize the jQuery.ui.mouse with the delay option specified:

      +
      $( ".selector" ).jQuery.ui.mouse({ delay: 300 });
      +

      Get or set the delay option, after initialization:

      +
      // getter
      var delay = $( ".selector" ).jQuery.ui.mouse( "option", "delay" );
       
      // setter
      $( ".selector" ).jQuery.ui.mouse( "option", "delay", 300 );
      +
      +
      +

      distanceType: Number +

      +
      +Default: 1 +
      +
      Distance in pixels after mousedown the mouse must move before the interaction should start. This option can be used to prevent unwanted interactions when clicking on an element.
      +Code examples:

      Initialize the jQuery.ui.mouse with the distance option specified:

      +
      $( ".selector" ).jQuery.ui.mouse({ distance: 10 });
      +

      Get or set the distance option, after initialization:

      +
      // getter
      var distance = $( ".selector" ).jQuery.ui.mouse( "option", "distance" );
       
      // setter
      $( ".selector" ).jQuery.ui.mouse( "option", "distance", 10 );
      +

      Methods

      +
      +

      _mouseCapture() Returns: Boolean +

      +
      + Determines whether an interaction should start based on event target of the interaction. The default implementation always returns true. +
      +
      • This method does not accept any arguments.
      +
      +
      +Code examples:

      Invoke the _mouseCapture method:

      +
      $( ".selector" ).jQuery.ui.mouse( "_mouseCapture" );
      +
      +
      +
      +
      +

      _mouseDelayMet() Returns: Boolean +

      +
      + Determines whether the delay option has been met for the current interaction. +
      +
      • This method does not accept any arguments.
      +
      +
      +Code examples:

      Invoke the _mouseDelayMet method:

      +
      $( ".selector" ).jQuery.ui.mouse( "_mouseDelayMet" );
      +
      +
      +
      +
      +

      _mouseDestroy()

      +
      + Destroys the interaction event handlers. This must be called from the extending widget's _destroy() method. +
      +
      • This method does not accept any arguments.
      +
      +
      +Code examples:

      Invoke the _mouseDestroy method:

      +
      $( ".selector" ).jQuery.ui.mouse( "_mouseDestroy" );
      +
      +
      +
      +
      +

      _mouseDistanceMet() Returns: Boolean +

      +
      + Determines whether the distance option has been met for the current interaction. +
      +
      • This method does not accept any arguments.
      +
      +
      +Code examples:

      Invoke the _mouseDistanceMet method:

      +
      $( ".selector" ).jQuery.ui.mouse( "_mouseDistanceMet" );
      +
      +
      +
      +
      +

      _mouseDown()

      +
      + Handles the beginning of an interaction. Verifies that the event is associated with the primary mouse button and ensures that the delay and distance options are met prior to starting the interaction. When the interaction is ready to start, invokes the _mouseStart() method for the extending widget to handle. +
      +
      • This method does not accept any arguments.
      +
      +
      +Code examples:

      Invoke the _mouseDown method:

      +
      $( ".selector" ).jQuery.ui.mouse( "_mouseDown" );
      +
      +
      +
      +
      +

      _mouseDrag()

      +
      + The extending widget should implement a _mouseDrag() method to handle each movement of an interaction. This method will receive the mouse event associated with the movement. +
      +
      • This method does not accept any arguments.
      +
      +
      +Code examples:

      Invoke the _mouseDrag method:

      +
      $( ".selector" ).jQuery.ui.mouse( "_mouseDrag" );
      +
      +
      +
      +
      +

      _mouseInit()

      +
      + Initializes the interaction event handlers. This must be called from the extending widget's _create() method. +
      +
      • This method does not accept any arguments.
      +
      +
      +Code examples:

      Invoke the _mouseInit method:

      +
      $( ".selector" ).jQuery.ui.mouse( "_mouseInit" );
      +
      +
      +
      +
      +

      _mouseMove()

      +
      + Handles each movement of the interaction. Invokes the mouseDrag() method for the extending widget to handle. +
      +
      • This method does not accept any arguments.
      +
      +
      +Code examples:

      Invoke the _mouseMove method:

      +
      $( ".selector" ).jQuery.ui.mouse( "_mouseMove" );
      +
      +
      +
      +
      +

      _mouseStart()

      +
      + The extending widget should implement a _mouseStart() method to handle the beginning of an interaction. This method will receive the mouse event associated with the start of the interaction. +
      +
      • This method does not accept any arguments.
      +
      +
      +Code examples:

      Invoke the _mouseStart method:

      +
      $( ".selector" ).jQuery.ui.mouse( "_mouseStart" );
      +
      +
      +
      +
      +

      _mouseStop()

      +
      + The extending widget should implement a _mouseStop() method to handle the end of an interaction. This method will receive the mouse event associated with the end of the interaction. +
      +
      • This method does not accept any arguments.
      +
      +
      +Code examples:

      Invoke the _mouseStop method:

      +
      $( ".selector" ).jQuery.ui.mouse( "_mouseStop" );
      +
      +
      +
      +
      +

      _mouseUp()

      +
      + Handles the end of the interaction. Invokes the mouseStop() method for the extending widget to handle. +
      +
      • This method does not accept any arguments.
      +
      +
      +Code examples:

      Invoke the _mouseUp method:

      +
      $( ".selector" ).jQuery.ui.mouse( "_mouseUp" );
      +
      +
      +

      Overview

      +

      Similar to jQuery.Widget, the mouse interaction is not intended to be used directly. It is purely a base layer for other widgets to inherit from. This page only documents what is added to jQuery.Widget, but it does include internal methods that are not intended to be overwritten. The intended public API is _mouseStart(), _mouseDrag(), _mouseStop(), and _mouseCapture().

      +
      +
      + + + diff --git a/htdocs/js/lib/vendor/jquery-drag-drop/development-bundle/docs/position.html b/htdocs/js/lib/vendor/jquery-drag-drop/development-bundle/docs/position.html new file mode 100755 index 000000000..60d815dac --- /dev/null +++ b/htdocs/js/lib/vendor/jquery-drag-drop/development-bundle/docs/position.html @@ -0,0 +1,116 @@ + + + + + jQuery UI position documentation + + + + + +

      +.position( options ) Returns: jQueryversion added: 1.8 +

      +
      +

      Description: Position an element relative to another.

      +
      • +

        .position( options )

        +
        • +
          options
          +
          Type: Object +
          +
          +
            +
          • +
            +my (default: "center")
            +
            Type: String +
            +
            Defines which position on the element being positioned to align with the target element: "horizontal vertical" alignment. A single value such as "right" will be normalized to "right center", "top" will be normalized to "center top" (following CSS convention). Acceptable horizontal values: "left", "center", "right". Acceptable vertical values: "top", "center", "bottom". Example: "left top" or "center center". Each dimension can also contain offsets, in pixels or percent, e.g., "right+10 top-25%". Percentage offsets are relative to the element being positioned.
            +
          • +
          • +
            +at (default: "center")
            +
            Type: String +
            +
            Defines which position on the target element to align the positioned element against: "horizontal vertical" alignment. See the my option for full details on possible values. Perecentage offsets are relative to the target element.
            +
          • +
          • +
            +of (default: null)
            +
            Type: Selector or Element or jQuery or Event +
            +
            Which element to position against. If you provide a selector or jQuery object, the first matching element will be used. If you provide an event object, the pageX and pageY properties will be used. Example: "#top-menu" +
            +
          • +
          • +
            +collision (default: "flip")
            +
            Type: String +
            +
            +

            When the positioned element overflows the window in some direction, move it to an alternative position. Similar to my and at, this accepts a single value or a pair for horizontal/vertical, e.g., "flip", "fit", "fit flip", "fit none".

            +
              +
            • +"flip": Flips the element to the opposite side of the target and the collision detection is run again to see if it will fit. Whichever side allows more of the element to be visible will be used.
            • +
            • +"fit": Shift the element away from the edge of the window.
            • +
            • +"flipfit": First applies the flip logic, placing the element on whichever side allows more of the element to be visible. Then the fit logic is applied to ensure as much of the element is visible as possible.
            • +
            • +"none": Does not apply any collision detection.
            • +
            +
            +
          • +
          • +
            +using (default: null)
            +
            Type: Function()
            +
            + When specified, the actual property setting is delegated to this callback. Receives two parameters: The first is a hash of top and left values for the position that should be set and can be forwarded to .css() or .animate(). +

            The second provides feedback about the position and dimensions of both elements, as well as calculations to their relative position. Both target and element have these properties: element, left, top, width, height. In addition, there's horizontal, vertical and important, giving you twelve potential directions like { horizontal: "center", vertical: "left", important: "horizontal" }.

            +
            +
          • +
          • +
            +within (default: window)
            +
            Type: Selector or Element or jQuery +
            +
            Element to position within, affecting collision detection. If you provide a selector or jQuery object, the first matching element will be used.
            +
          • +
          +
        +
      +
      +

      The jQuery UI .position() method allows you to position an element relative to the window, document, another element, or the cursor/mouse, without worrying about offset parents.

      +

      Note: jQuery UI does not support positioning hidden elements.

      +

      This is a standalone jQuery plugin and has no dependencies on other jQuery UI components.

      +

      This plugin extends jQuery's built-in .position() method. If jQuery UI is not loaded, calling the .position() method may not fail directly, as the method still exists. However, the expected behavior will not occur.

      +
      +

      Example:

      +

      A simple jQuery UI Position example.

      +
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      24
      25
      26
      27
      28
      29
      30
      31
      32
      33
      34
      35
      36
      37
      38
      39
      40
      41
      42
      43
      44
      45
      46
      47
      48
      49
      50
      51
      52
      53
      54
      55
      56
      <!doctype html>
      <html lang="en">
      <head>
          <meta charset="utf-8">
          <title>position demo</title>
          <link rel="stylesheet" href="http://code.jquery.com/ui/1.9.2/themes/base/jquery-ui.css">
          <style>
          .positionDiv {
              position: absolute;
              width: 75px;
              height: 75px;
              background: green;
          }
          </style>
          <script src="http://code.jquery.com/jquery-1.8.3.js"></script>
          <script src="http://code.jquery.com/ui/1.9.2/jquery-ui.js"></script>
      </head>
      <body>
       
      <div id="targetElement">
          <div class="positionDiv" id="position1"></div>
          <div class="positionDiv" id="position2"></div>
          <div class="positionDiv" id="position3"></div>
          <div class="positionDiv" id="position4"></div>
      </div>
       
      <script>
      $( "#position1" ).position({
          my: "center",
          at: "center",
          of: "#targetElement"
      });
       
      $( "#position2" ).position({
          my: "left top",
          at: "left top",
          of: "#targetElement"
      });
       
      $( "#position3" ).position({
          my: "right center",
          at: "right bottom",
          of: "#targetElement"
      });
       
      $( document ).mousemove(function( event ) {
          $( "#position4" ).position({
              my: "left+3 bottom-3",
              of: event,
              collision: "fit"
          });
      });
      </script>
       
      </body>
      </html>
      +

      Demo:

      +
      +
      +
      + + + diff --git a/htdocs/js/lib/vendor/jquery-drag-drop/development-bundle/docs/resizable.html b/htdocs/js/lib/vendor/jquery-drag-drop/development-bundle/docs/resizable.html new file mode 100755 index 000000000..cd6ae37ef --- /dev/null +++ b/htdocs/js/lib/vendor/jquery-drag-drop/development-bundle/docs/resizable.html @@ -0,0 +1,694 @@ + + + + + jQuery UI resizable documentation + + + + + +

      QuickNavOverviewExamples +

      + +
      +

      Events

      + + + + +

      +Resizable Widgetversion added: 1.0 +

      +
      +

      Description: Change the size of an element using the mouse.

      +

      Options

      +

      alsoResizeType: Selector or jQuery or Element +

      +
      +Default: false +
      +
      One or more elements to resize synchronously with the resizable element.
      +Code examples:

      Initialize the resizable with the alsoResize option specified:

      +
      $( ".selector" ).resizable({ alsoResize: "#mirror" });
      +

      Get or set the alsoResize option, after initialization:

      +
      // getter
      var alsoResize = $( ".selector" ).resizable( "option", "alsoResize" );
       
      // setter
      $( ".selector" ).resizable( "option", "alsoResize", "#mirror" );
      +
      +
      +

      animateType: Boolean +

      +
      +Default: false +
      +
      Animates to the final size after resizing.
      +Code examples:

      Initialize the resizable with the animate option specified:

      +
      $( ".selector" ).resizable({ animate: true });
      +

      Get or set the animate option, after initialization:

      +
      // getter
      var animate = $( ".selector" ).resizable( "option", "animate" );
       
      // setter
      $( ".selector" ).resizable( "option", "animate", true );
      +
      +
      +

      animateDurationType: Number or String +

      +
      +Default: "slow" +
      +
      How long to animate when using the animate option.
      +Multiple types supported:
        +
      • +Number: Duration in milliseconds.
      • +
      • +String: A named duration, such as "slow" or "fast".
      • +
      +Code examples:

      Initialize the resizable with the animateDuration option specified:

      +
      $( ".selector" ).resizable({ animateDuration: "fast" });
      +

      Get or set the animateDuration option, after initialization:

      +
      // getter
      var animateDuration = $( ".selector" ).resizable( "option", "animateDuration" );
       
      // setter
      $( ".selector" ).resizable( "option", "animateDuration", "fast" );
      +
      +
      +

      animateEasingType: String +

      +
      +Default: "swing" +
      +
      Which easing to apply when using the animate option.
      +Code examples:

      Initialize the resizable with the animateEasing option specified:

      +
      $( ".selector" ).resizable({ animateEasing: "easeOutBounce" });
      +

      Get or set the animateEasing option, after initialization:

      +
      // getter
      var animateEasing = $( ".selector" ).resizable( "option", "animateEasing" );
       
      // setter
      $( ".selector" ).resizable( "option", "animateEasing", "easeOutBounce" );
      +
      +
      +

      aspectRatioType: Boolean or Number +

      +
      +Default: false +
      +
      Whether the element should be constrained to a specific aspect ratio.
      +Multiple types supported:
        +
      • +Boolean: When set to true, the element will maintain its original aspect ratio.
      • +
      • +Number: Force the element to maintain a specific aspect ratio during resizing.
      • +
      +Code examples:

      Initialize the resizable with the aspectRatio option specified:

      +
      $( ".selector" ).resizable({ aspectRatio: true });
      +

      Get or set the aspectRatio option, after initialization:

      +
      // getter
      var aspectRatio = $( ".selector" ).resizable( "option", "aspectRatio" );
       
      // setter
      $( ".selector" ).resizable( "option", "aspectRatio", true );
      +
      +
      +

      autoHideType: Boolean +

      +
      +Default: false +
      +
      Whether the handles should hide when the user is not hovering over the element.
      +Code examples:

      Initialize the resizable with the autoHide option specified:

      +
      $( ".selector" ).resizable({ autoHide: true });
      +

      Get or set the autoHide option, after initialization:

      +
      // getter
      var autoHide = $( ".selector" ).resizable( "option", "autoHide" );
       
      // setter
      $( ".selector" ).resizable( "option", "autoHide", true );
      +
      +
      +

      cancelType: Selector +

      +
      +Default: "input,textarea,button,select,option" +
      +
      Prevents resizing from starting on specified elements.
      +Code examples:

      Initialize the resizable with the cancel option specified:

      +
      $( ".selector" ).resizable({ cancel: ".cancel" });
      +

      Get or set the cancel option, after initialization:

      +
      // getter
      var cancel = $( ".selector" ).resizable( "option", "cancel" );
       
      // setter
      $( ".selector" ).resizable( "option", "cancel", ".cancel" );
      +
      +
      +

      containmentType: Selector or Element or String +

      +
      +Default: false +
      +
      Constrains resizing to within the bounds of the specified element or region.
      +Multiple types supported:
        +
      • +Selector: The resizable element will be contained to the bounding box of the first element found by the selector. If no element is found, no containment will be set.
      • +
      • +Element: The resizable element will be contained to the bounding box of this element.
      • +
      • +String: Possible values: "parent" and "document".
      • +
      +Code examples:

      Initialize the resizable with the containment option specified:

      +
      $( ".selector" ).resizable({ containment: "parent" });
      +

      Get or set the containment option, after initialization:

      +
      // getter
      var containment = $( ".selector" ).resizable( "option", "containment" );
       
      // setter
      $( ".selector" ).resizable( "option", "containment", "parent" );
      +
      +
      +

      delayType: Number +

      +
      +Default: 0 +
      +
      Tolerance, in milliseconds, for when resizing should start. If specified, resizing will not start until after mouse is moved beyond duration. This can help prevent unintended resizing when clicking on an element.
      +Code examples:

      Initialize the resizable with the delay option specified:

      +
      $( ".selector" ).resizable({ delay: 150 });
      +

      Get or set the delay option, after initialization:

      +
      // getter
      var delay = $( ".selector" ).resizable( "option", "delay" );
       
      // setter
      $( ".selector" ).resizable( "option", "delay", 150 );
      +
      +
      +

      disabledType: Boolean +

      +
      +Default: false +
      +
      Disables the resizable if set to true.
      +Code examples:

      Initialize the resizable with the disabled option specified:

      +
      $( ".selector" ).resizable({ disabled: true });
      +

      Get or set the disabled option, after initialization:

      +
      // getter
      var disabled = $( ".selector" ).resizable( "option", "disabled" );
       
      // setter
      $( ".selector" ).resizable( "option", "disabled", true );
      +
      +
      +

      distanceType: Number +

      +
      +Default: 1 +
      +
      Tolerance, in pixels, for when resizing should start. If specified, resizing will not start until after mouse is moved beyond distance. This can help prevent unintended resizing when clicking on an element.
      +Code examples:

      Initialize the resizable with the distance option specified:

      +
      $( ".selector" ).resizable({ distance: 30 });
      +

      Get or set the distance option, after initialization:

      +
      // getter
      var distance = $( ".selector" ).resizable( "option", "distance" );
       
      // setter
      $( ".selector" ).resizable( "option", "distance", 30 );
      +
      +
      +

      ghostType: Boolean +

      +
      +Default: false +
      +
      If set to true, a semi-transparent helper element is shown for resizing.
      +Code examples:

      Initialize the resizable with the ghost option specified:

      +
      $( ".selector" ).resizable({ ghost: true });
      +

      Get or set the ghost option, after initialization:

      +
      // getter
      var ghost = $( ".selector" ).resizable( "option", "ghost" );
       
      // setter
      $( ".selector" ).resizable( "option", "ghost", true );
      +
      +
      +

      gridType: Array +

      +
      +Default: false +
      +
      Snaps the resizing element to a grid, every x and y pixels. Array values: [ x, y ].
      +Code examples:

      Initialize the resizable with the grid option specified:

      +
      $( ".selector" ).resizable({ grid: [ 20, 10 ] });
      +

      Get or set the grid option, after initialization:

      +
      // getter
      var grid = $( ".selector" ).resizable( "option", "grid" );
       
      // setter
      $( ".selector" ).resizable( "option", "grid", [ 20, 10 ] );
      +
      +
      +

      handlesType: String or Object +

      +
      +Default: "e, s, se" +
      +
      Which handles can be used for resizing.
      +Multiple types supported:
        +
      • +String: A comma delimited list of any of the following: n, e, s, w, ne, se, sw, nw, all. The necessary handles will be auto-generated by the plugin.
      • +
      • +Object: The following keys are supported: { n, e, s, w, ne, se, sw, nw }. The value of any specified should be a jQuery selector matching the child element of the resizable to use as that handle. If the handle is not a child of the resizable, you can pass in the DOMElement or a valid jQuery object directly.
      • +
      +Code examples:

      Initialize the resizable with the handles option specified:

      +
      $( ".selector" ).resizable({ handles: "n, e, s, w" });
      +

      Get or set the handles option, after initialization:

      +
      // getter
      var handles = $( ".selector" ).resizable( "option", "handles" );
       
      // setter
      $( ".selector" ).resizable( "option", "handles", "n, e, s, w" );
      +
      +
      +

      helperType: String +

      +
      +Default: false +
      +
      A class name that will be added to a proxy element to outline the resize during the drag of the resize handle. Once the resize is complete, the original element is sized.
      +Code examples:

      Initialize the resizable with the helper option specified:

      +
      $( ".selector" ).resizable({ helper: "resizable-helper" });
      +

      Get or set the helper option, after initialization:

      +
      // getter
      var helper = $( ".selector" ).resizable( "option", "helper" );
       
      // setter
      $( ".selector" ).resizable( "option", "helper", "resizable-helper" );
      +
      +
      +

      maxHeightType: Number +

      +
      +Default: null +
      +
      The maximum height the resizable should be allowed to resize to.
      +Code examples:

      Initialize the resizable with the maxHeight option specified:

      +
      $( ".selector" ).resizable({ maxHeight: 300 });
      +

      Get or set the maxHeight option, after initialization:

      +
      // getter
      var maxHeight = $( ".selector" ).resizable( "option", "maxHeight" );
       
      // setter
      $( ".selector" ).resizable( "option", "maxHeight", 300 );
      +
      +
      +

      maxWidthType: Number +

      +
      +Default: null +
      +
      The maximum width the resizable should be allowed to resize to.
      +Code examples:

      Initialize the resizable with the maxWidth option specified:

      +
      $( ".selector" ).resizable({ maxWidth: 300 });
      +

      Get or set the maxWidth option, after initialization:

      +
      // getter
      var maxWidth = $( ".selector" ).resizable( "option", "maxWidth" );
       
      // setter
      $( ".selector" ).resizable( "option", "maxWidth", 300 );
      +
      +
      +

      minHeightType: Number +

      +
      +Default: 10 +
      +
      The minimum height the resizable should be allowed to resize to.
      +Code examples:

      Initialize the resizable with the minHeight option specified:

      +
      $( ".selector" ).resizable({ minHeight: 150 });
      +

      Get or set the minHeight option, after initialization:

      +
      // getter
      var minHeight = $( ".selector" ).resizable( "option", "minHeight" );
       
      // setter
      $( ".selector" ).resizable( "option", "minHeight", 150 );
      +
      +
      +

      minWidthType: Number +

      +
      +Default: 10 +
      +
      The minimum width the resizable should be allowed to resize to.
      +Code examples:

      Initialize the resizable with the minWidth option specified:

      +
      $( ".selector" ).resizable({ minWidth: 150 });
      +

      Get or set the minWidth option, after initialization:

      +
      // getter
      var minWidth = $( ".selector" ).resizable( "option", "minWidth" );
       
      // setter
      $( ".selector" ).resizable( "option", "minWidth", 150 );
      +

      Methods

      +
      +

      destroy()

      +
      + Removes the resizable functionality completely. This will return the element back to its pre-init state. +
      +
      • This method does not accept any arguments.
      +
      +
      +Code examples:

      Invoke the destroy method:

      +
      $( ".selector" ).resizable( "destroy" );
      +
      +
      +
      +
      +

      disable()

      +
      + Disables the resizable. +
      +
      • This method does not accept any arguments.
      +
      +
      +Code examples:

      Invoke the disable method:

      +
      $( ".selector" ).resizable( "disable" );
      +
      +
      +
      +
      +

      enable()

      +
      + Enables the resizable. +
      +
      • This method does not accept any arguments.
      +
      +
      +Code examples:

      Invoke the enable method:

      +
      $( ".selector" ).resizable( "enable" );
      +
      +
      +
      +
      +

      option( optionName ) Returns: Object +

      +
      Gets the value currently associated with the specified optionName.
      +
      • +
        optionName
        +
        Type: String +
        +
        The name of the option to get.
        +
      +
      +
      +Code examples:

      Invoke the method:

      +
      var isDisabled = $( ".selector" ).resizable( "option", "disabled" );
      +
      +
      +

      option() Returns: PlainObject +

      +
      Gets an object containing key/value pairs representing the current resizable options hash.
      +
      • This method does not accept any arguments.
      +
      +
      +Code examples:

      Invoke the method:

      +
      var options = $( ".selector" ).resizable( "option" );
      +
      +
      +

      option( optionName, value )

      +
      Sets the value of the resizable option associated with the specified optionName.
      +
        +
      • +
        optionName
        +
        Type: String +
        +
        The name of the option to set.
        +
      • +
      • +
        value
        +
        Type: Object +
        +
        A value to set for the option.
        +
      • +
      +
      +
      +Code examples:

      Invoke the method:

      +
      $( ".selector" ).resizable( "option", "disabled", true );
      +
      +
      +

      option( options )

      +
      Sets one or more options for the resizable.
      +
      • +
        options
        +
        Type: Object +
        +
        A map of option-value pairs to set.
        +
      +
      +
      +Code examples:

      Invoke the method:

      +
      $( ".selector" ).resizable( "option", { disabled: true } );
      +
      +
      +
      +
      +

      widget() Returns: jQuery +

      +
      + Returns a jQuery object containing the resizable element. +
      +
      • This method does not accept any arguments.
      +
      +
      +Code examples:

      Invoke the widget method:

      +
      var widget = $( ".selector" ).resizable( "widget" );
      +
      +

      Events

      +

      create( event, ui )Type: resizecreate +

      +
      + Triggered when the resizable is created. +
      +
        +
      • +
        event
        +
        Type: Event +
        +
        +
      • +
      • +
        ui
        +
        Type: Object +
        +
        +
      • +
      +
      +Code examples:

      Initialize the resizable with the create callback specified:

      +
      $( ".selector" ).resizable({
          create: function( event, ui ) {}
      });
      +

      Bind an event listener to the resizecreate event:

      +
      $( ".selector" ).on( "resizecreate", function( event, ui ) {} );
      +
      +
      +
      +

      resize( event, ui )Type: resize +

      +
      This event is triggered during the resize, on the drag of the resize handler.
      +
        +
      • +
        event
        +
        Type: Event +
        +
        +
      • +
      • +
        ui
        +
        Type: Object +
        +
        +
          +
        • +
          element
          +
          Type: jQuery +
          +
          The jQuery object representing the element to be resized
          +
        • +
        • +
          helper
          +
          Type: jQuery +
          +
          The jQuery object representing the helper that's being resized
          +
        • +
        • +
          originalElement
          +
          Type: jQuery +
          +
          The jQuery object representing the original element before it is wrapped
          +
        • +
        • +
          originalPosition
          +
          Type: Object +
          +
          The position represented as { left, top } before the resizable is resized
          +
        • +
        • +
          originalSize
          +
          Type: Object +
          +
          The size represented as { width, height } before the resizable is resized
          +
        • +
        • +
          position
          +
          Type: Object +
          +
          The current position represented as { left, top } +
          +
        • +
        • +
          size
          +
          Type: Object +
          +
          The current size represented as { width, height } +
          +
        • +
        +
      • +
      +
      +Code examples:

      Initialize the resizable with the resize callback specified:

      +
      $( ".selector" ).resizable({
          resize: function( event, ui ) {}
      });
      +

      Bind an event listener to the resize event:

      +
      $( ".selector" ).on( "resize", function( event, ui ) {} );
      +
      +
      +
      +

      start( event, ui )Type: resizestart +

      +
      This event is triggered at the start of a resize operation.
      +
        +
      • +
        event
        +
        Type: Event +
        +
        +
      • +
      • +
        ui
        +
        Type: Object +
        +
        +
          +
        • +
          element
          +
          Type: jQuery +
          +
          The jQuery object representing the element to be resized
          +
        • +
        • +
          helper
          +
          Type: jQuery +
          +
          The jQuery object representing the helper that's being resized
          +
        • +
        • +
          originalElement
          +
          Type: jQuery +
          +
          The jQuery object representing the original element before it is wrapped
          +
        • +
        • +
          originalPosition
          +
          Type: Object +
          +
          The position represented as { left, top } before the resizable is resized
          +
        • +
        • +
          originalSize
          +
          Type: Object +
          +
          The size represented as { width, height } before the resizable is resized
          +
        • +
        • +
          position
          +
          Type: Object +
          +
          The current position represented as { left, top } +
          +
        • +
        • +
          size
          +
          Type: Object +
          +
          The current size represented as { width, height } +
          +
        • +
        +
      • +
      +
      +Code examples:

      Initialize the resizable with the start callback specified:

      +
      $( ".selector" ).resizable({
          start: function( event, ui ) {}
      });
      +

      Bind an event listener to the resizestart event:

      +
      $( ".selector" ).on( "resizestart", function( event, ui ) {} );
      +
      +
      +
      +

      stop( event, ui )Type: resizestop +

      +
      This event is triggered at the end of a resize operation.
      +
        +
      • +
        event
        +
        Type: Event +
        +
        +
      • +
      • +
        ui
        +
        Type: Object +
        +
        +
          +
        • +
          element
          +
          Type: jQuery +
          +
          The jQuery object representing the element to be resized
          +
        • +
        • +
          helper
          +
          Type: jQuery +
          +
          The jQuery object representing the helper that's being resized
          +
        • +
        • +
          originalElement
          +
          Type: jQuery +
          +
          The jQuery object representing the original element before it is wrapped
          +
        • +
        • +
          originalPosition
          +
          Type: Object +
          +
          The position represented as { left, top } before the resizable is resized
          +
        • +
        • +
          originalSize
          +
          Type: Object +
          +
          The size represented as { width, height } before the resizable is resized
          +
        • +
        • +
          position
          +
          Type: Object +
          +
          The current position represented as { left, top } +
          +
        • +
        • +
          size
          +
          Type: Object +
          +
          The current size represented as { width, height } +
          +
        • +
        +
      • +
      +
      +Code examples:

      Initialize the resizable with the stop callback specified:

      +
      $( ".selector" ).resizable({
          stop: function( event, ui ) {}
      });
      +

      Bind an event listener to the resizestop event:

      +
      $( ".selector" ).on( "resizestop", function( event, ui ) {} );
      +
      +
      +

      Overview

      +

      The jQuery UI Resizable plugin makes selected elements resizable (meaning they have draggable resize handles). You can specify one or more handles as well as min and max width and height.

      +
      +

      Additional Notes:

      +
      • + This widget requires some functional CSS, otherwise it won't work. If you build a custom theme, use the widget's specific CSS file as a starting point. +
      +

      Example:

      +

      A simple jQuery UI Resizable.

      +
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      24
      25
      <!doctype html>
      <html lang="en">
      <head>
          <meta charset="utf-8">
          <title>resizable demo</title>
          <link rel="stylesheet" href="http://code.jquery.com/ui/1.9.2/themes/base/jquery-ui.css">
          <style>
          #resizable {
              width: 100px;
              height: 100px;
              background: #ccc;
      }   </style>
          <script src="http://code.jquery.com/jquery-1.8.3.js"></script>
          <script src="http://code.jquery.com/ui/1.9.2/jquery-ui.js"></script>
      </head>
      <body>
       
      <div id="resizable"></div>
       
      <script>
      $( "#resizable" ).resizable();
      </script>
       
      </body>
      </html>
      +

      Demo:

      +
      +
      +
      + + + diff --git a/htdocs/js/lib/vendor/jquery-drag-drop/development-bundle/docs/selectable.html b/htdocs/js/lib/vendor/jquery-drag-drop/development-bundle/docs/selectable.html new file mode 100755 index 000000000..9260a9819 --- /dev/null +++ b/htdocs/js/lib/vendor/jquery-drag-drop/development-bundle/docs/selectable.html @@ -0,0 +1,509 @@ + + + + + jQuery UI selectable documentation + + + + + +

      QuickNavOverviewExamples +

      + +

      +Selectable Widgetversion added: 1.0 +

      +
      +

      Description: Use the mouse to select elements, individually or in a group.

      +

      Options

      +

      appendToType: Selector +

      +
      +Default: "body" +
      +
      Which element the selection helper (the lasso) should be appended to.
      +Code examples:

      Initialize the selectable with the appendTo option specified:

      +
      $( ".selector" ).selectable({ appendTo: "#someElem" });
      +

      Get or set the appendTo option, after initialization:

      +
      // getter
      var appendTo = $( ".selector" ).selectable( "option", "appendTo" );
       
      // setter
      $( ".selector" ).selectable( "option", "appendTo", "#someElem" );
      +
      +
      +

      autoRefreshType: Boolean +

      +
      +Default: true +
      +
      This determines whether to refresh (recalculate) the position and size of each selectee at the beginning of each select operation. If you have many items, you may want to set this to false and call the refresh() method manually.
      +Code examples:

      Initialize the selectable with the autoRefresh option specified:

      +
      $( ".selector" ).selectable({ autoRefresh: false });
      +

      Get or set the autoRefresh option, after initialization:

      +
      // getter
      var autoRefresh = $( ".selector" ).selectable( "option", "autoRefresh" );
       
      // setter
      $( ".selector" ).selectable( "option", "autoRefresh", false );
      +
      +
      +

      cancelType: Selector +

      +
      +Default: "input,textarea,button,select,option" +
      +
      Prevents selecting if you start on elements matching the selector.
      +Code examples:

      Initialize the selectable with the cancel option specified:

      +
      $( ".selector" ).selectable({ cancel: a,.cancel });
      +

      Get or set the cancel option, after initialization:

      +
      // getter
      var cancel = $( ".selector" ).selectable( "option", "cancel" );
       
      // setter
      $( ".selector" ).selectable( "option", "cancel", a,.cancel );
      +
      +
      +

      delayType: Integer +

      +
      +Default: 0 +
      +
      Time in milliseconds to define when the selecting should start. This helps prevent unwanted selections when clicking on an element.
      +Code examples:

      Initialize the selectable with the delay option specified:

      +
      $( ".selector" ).selectable({ delay: 150 });
      +

      Get or set the delay option, after initialization:

      +
      // getter
      var delay = $( ".selector" ).selectable( "option", "delay" );
       
      // setter
      $( ".selector" ).selectable( "option", "delay", 150 );
      +
      +
      +

      disabledType: Boolean +

      +
      +Default: false +
      +
      Disables the selectable if set to true.
      +Code examples:

      Initialize the selectable with the disabled option specified:

      +
      $( ".selector" ).selectable({ disabled: true });
      +

      Get or set the disabled option, after initialization:

      +
      // getter
      var disabled = $( ".selector" ).selectable( "option", "disabled" );
       
      // setter
      $( ".selector" ).selectable( "option", "disabled", true );
      +
      +
      +

      distanceType: Number +

      +
      +Default: 0 +
      +
      Tolerance, in pixels, for when selecting should start. If specified, selecting will not start until the mouse has been dragged beyond the specified distance.
      +Code examples:

      Initialize the selectable with the distance option specified:

      +
      $( ".selector" ).selectable({ distance: 30 });
      +

      Get or set the distance option, after initialization:

      +
      // getter
      var distance = $( ".selector" ).selectable( "option", "distance" );
       
      // setter
      $( ".selector" ).selectable( "option", "distance", 30 );
      +
      +
      +

      filterType: Selector +

      +
      +Default: "*" +
      +
      The matching child elements will be made selectees (able to be selected).
      +Code examples:

      Initialize the selectable with the filter option specified:

      +
      $( ".selector" ).selectable({ filter: li });
      +

      Get or set the filter option, after initialization:

      +
      // getter
      var filter = $( ".selector" ).selectable( "option", "filter" );
       
      // setter
      $( ".selector" ).selectable( "option", "filter", li );
      +
      +
      +

      toleranceType: String +

      +
      +Default: "touch" +
      +
      + Specifies which mode to use for testing whether the lasso should select an item. Possible values: +
        +
      • +"fit": Lasso overlaps the item entirely.
      • +
      • +"touch": Lasso overlaps the item by any amount.
      • +
      +
      +Code examples:

      Initialize the selectable with the tolerance option specified:

      +
      $( ".selector" ).selectable({ tolerance: "fit" });
      +

      Get or set the tolerance option, after initialization:

      +
      // getter
      var tolerance = $( ".selector" ).selectable( "option", "tolerance" );
       
      // setter
      $( ".selector" ).selectable( "option", "tolerance", "fit" );
      +

      Methods

      +
      +

      destroy()

      +
      + Removes the selectable functionality completely. This will return the element back to its pre-init state. +
      +
      • This method does not accept any arguments.
      +
      +
      +Code examples:

      Invoke the destroy method:

      +
      $( ".selector" ).selectable( "destroy" );
      +
      +
      +
      +
      +

      disable()

      +
      + Disables the selectable. +
      +
      • This method does not accept any arguments.
      +
      +
      +Code examples:

      Invoke the disable method:

      +
      $( ".selector" ).selectable( "disable" );
      +
      +
      +
      +
      +

      enable()

      +
      + Enables the selectable. +
      +
      • This method does not accept any arguments.
      +
      +
      +Code examples:

      Invoke the enable method:

      +
      $( ".selector" ).selectable( "enable" );
      +
      +
      +
      +
      +

      option( optionName ) Returns: Object +

      +
      Gets the value currently associated with the specified optionName.
      +
      • +
        optionName
        +
        Type: String +
        +
        The name of the option to get.
        +
      +
      +
      +Code examples:

      Invoke the method:

      +
      var isDisabled = $( ".selector" ).selectable( "option", "disabled" );
      +
      +
      +

      option() Returns: PlainObject +

      +
      Gets an object containing key/value pairs representing the current selectable options hash.
      +
      • This method does not accept any arguments.
      +
      +
      +Code examples:

      Invoke the method:

      +
      var options = $( ".selector" ).selectable( "option" );
      +
      +
      +

      option( optionName, value )

      +
      Sets the value of the selectable option associated with the specified optionName.
      +
        +
      • +
        optionName
        +
        Type: String +
        +
        The name of the option to set.
        +
      • +
      • +
        value
        +
        Type: Object +
        +
        A value to set for the option.
        +
      • +
      +
      +
      +Code examples:

      Invoke the method:

      +
      $( ".selector" ).selectable( "option", "disabled", true );
      +
      +
      +

      option( options )

      +
      Sets one or more options for the selectable.
      +
      • +
        options
        +
        Type: Object +
        +
        A map of option-value pairs to set.
        +
      +
      +
      +Code examples:

      Invoke the method:

      +
      $( ".selector" ).selectable( "option", { disabled: true } );
      +
      +
      +
      +
      +

      refresh()

      +
      Refresh the position and size of each selectee element. This method can be used to manually recalculate the position and size of each selectee when the autoRefresh option is set to false.
      +
      • This method does not accept any arguments.
      +
      +
      +Code examples:

      Invoke the refresh method:

      +
      $( ".selector" ).selectable( "refresh" );
      +
      +
      +
      +
      +

      widget() Returns: jQuery +

      +
      + Returns a jQuery object containing the selectable element. +
      +
      • This method does not accept any arguments.
      +
      +
      +Code examples:

      Invoke the widget method:

      +
      var widget = $( ".selector" ).selectable( "widget" );
      +
      +

      Events

      +

      create( event, ui )Type: selectablecreate +

      +
      + Triggered when the selectable is created. +
      +
        +
      • +
        event
        +
        Type: Event +
        +
        +
      • +
      • +
        ui
        +
        Type: Object +
        +
        +
      • +
      +
      +Code examples:

      Initialize the selectable with the create callback specified:

      +
      $( ".selector" ).selectable({
          create: function( event, ui ) {}
      });
      +

      Bind an event listener to the selectablecreate event:

      +
      $( ".selector" ).on( "selectablecreate", function( event, ui ) {} );
      +
      +
      +
      +

      selected( event, ui )Type: selectableselected +

      +
      Triggered at the end of the select operation, on each element added to the selection.
      +
        +
      • +
        event
        +
        Type: Event +
        +
        +
      • +
      • +
        ui
        +
        Type: Object +
        +
        +
        • +
          selected
          +
          Type: Element +
          +
          The selectable item that has been selected.
          +
        +
      • +
      +
      +Code examples:

      Initialize the selectable with the selected callback specified:

      +
      $( ".selector" ).selectable({
          selected: function( event, ui ) {}
      });
      +

      Bind an event listener to the selectableselected event:

      +
      $( ".selector" ).on( "selectableselected", function( event, ui ) {} );
      +
      +
      +
      +

      selecting( event, ui )Type: selectableselecting +

      +
      Triggered during the select operation, on each element added to the selection.
      +
        +
      • +
        event
        +
        Type: Event +
        +
        +
      • +
      • +
        ui
        +
        Type: Object +
        +
        +
        • +
          selecting
          +
          Type: Element +
          +
          The current selectable item being selected.
          +
        +
      • +
      +
      +Code examples:

      Initialize the selectable with the selecting callback specified:

      +
      $( ".selector" ).selectable({
          selecting: function( event, ui ) {}
      });
      +

      Bind an event listener to the selectableselecting event:

      +
      $( ".selector" ).on( "selectableselecting", function( event, ui ) {} );
      +
      +
      +
      +

      start( event, ui )Type: selectablestart +

      +
      Triggered at the beginning of the select operation.
      +
        +
      • +
        event
        +
        Type: Event +
        +
        +
      • +
      • +
        ui
        +
        Type: Object +
        +
        +
      • +
      +
      +Code examples:

      Initialize the selectable with the start callback specified:

      +
      $( ".selector" ).selectable({
          start: function( event, ui ) {}
      });
      +

      Bind an event listener to the selectablestart event:

      +
      $( ".selector" ).on( "selectablestart", function( event, ui ) {} );
      +
      +
      +
      +

      stop( event, ui )Type: selectablestop +

      +
      Triggered at the end of the select operation.
      +
        +
      • +
        event
        +
        Type: Event +
        +
        +
      • +
      • +
        ui
        +
        Type: Object +
        +
        +
      • +
      +
      +Code examples:

      Initialize the selectable with the stop callback specified:

      +
      $( ".selector" ).selectable({
          stop: function( event, ui ) {}
      });
      +

      Bind an event listener to the selectablestop event:

      +
      $( ".selector" ).on( "selectablestop", function( event, ui ) {} );
      +
      +
      +
      +

      unselected( event, ui )Type: selectableunselected +

      +
      Triggered at the end of the select operation, on each element removed from the selection.
      +
        +
      • +
        event
        +
        Type: Event +
        +
        +
      • +
      • +
        ui
        +
        Type: Object +
        +
        +
        • +
          unselected
          +
          Type: Element +
          +
          The selectable item that has been unselected.
          +
        +
      • +
      +
      +Code examples:

      Initialize the selectable with the unselected callback specified:

      +
      $( ".selector" ).selectable({
          unselected: function( event, ui ) {}
      });
      +

      Bind an event listener to the selectableunselected event:

      +
      $( ".selector" ).on( "selectableunselected", function( event, ui ) {} );
      +
      +
      +
      +

      unselecting( event, ui )Type: selectableunselecting +

      +
      Triggered during the select operation, on each element removed from the selection.
      +
        +
      • +
        event
        +
        Type: Event +
        +
        +
      • +
      • +
        ui
        +
        Type: Object +
        +
        +
        • +
          unselecting
          +
          Type: Element +
          +
          The current selectable item being unselected.
          +
        +
      • +
      +
      +Code examples:

      Initialize the selectable with the unselecting callback specified:

      +
      $( ".selector" ).selectable({
          unselecting: function( event, ui ) {}
      });
      +

      Bind an event listener to the selectableunselecting event:

      +
      $( ".selector" ).on( "selectableunselecting", function( event, ui ) {} );
      +
      +
      +

      Overview

      +

      The jQuery UI Selectable plugin allows for elements to be selected by dragging a box (sometimes called a lasso) with the mouse over the elements. Elements can also be selected via click or drag while holding the ctrl/meta key, allowing for multiple (non-contiguous) selections.

      +
      +

      Additional Notes:

      +
      • + This widget requires some functional CSS, otherwise it won't work. If you build a custom theme, use the widget's specific CSS file as a starting point. +
      +

      Example:

      +

      A simple jQuery UI Selectable.

      +
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      24
      25
      26
      27
      28
      29
      30
      31
      32
      33
      <!doctype html>
      <html lang="en">
      <head>
          <meta charset="utf-8">
          <title>selectable demo</title>
          <link rel="stylesheet" href="http://code.jquery.com/ui/1.9.2/themes/base/jquery-ui.css">
          <style>
          #selectable .ui-selecting {
              background: #ccc;
          }
          #selectable .ui-selected {
              background: #999;
          }
          </style>
          <script src="http://code.jquery.com/jquery-1.8.3.js"></script>
          <script src="http://code.jquery.com/ui/1.9.2/jquery-ui.js"></script>
      </head>
      <body>
       
      <ul id="selectable">
          <li>Item 1</li>
          <li>Item 2</li>
          <li>Item 3</li>
          <li>Item 4</li>
          <li>Item 5</li>
      </ul>
       
      <script>
      $( "#selectable" ).selectable();
      </script>
       
      </body>
      </html>
      +

      Demo:

      +
      +
      +
      + + + diff --git a/htdocs/js/lib/vendor/jquery-drag-drop/development-bundle/docs/sortable.html b/htdocs/js/lib/vendor/jquery-drag-drop/development-bundle/docs/sortable.html new file mode 100755 index 000000000..1b5523b66 --- /dev/null +++ b/htdocs/js/lib/vendor/jquery-drag-drop/development-bundle/docs/sortable.html @@ -0,0 +1,1469 @@ + + + + + jQuery UI sortable documentation + + + + + +

      QuickNavOverviewExamples +

      + +

      +Sortable Widgetversion added: 1.0 +

      +
      +

      Description: Reorder elements in a list or grid using the mouse.

      +

      Options

      +

      appendToType: jQuery or Element or Selector or String +

      +
      +Default: "parent" +
      +
      Defines where the helper that moves with the mouse is being appended to during the drag (for example, to resolve overlap/zIndex issues).
      +Multiple types supported:
        +
      • +jQuery: A jQuery object containing the element to append the helper to.
      • +
      • +Element: The element to append the helper to.
      • +
      • +Selector: A selector specifying which element to append the helper to.
      • +
      • +String: The string "parent" will cause the helper to be a sibling of the sortable item.
      • +
      +Code examples:

      Initialize the sortable with the appendTo option specified:

      +
      $( ".selector" ).sortable({ appendTo: document.body });
      +

      Get or set the appendTo option, after initialization:

      +
      // getter
      var appendTo = $( ".selector" ).sortable( "option", "appendTo" );
       
      // setter
      $( ".selector" ).sortable( "option", "appendTo", document.body );
      +
      +
      +

      axisType: String +

      +
      +Default: false +
      +
      If defined, the items can be dragged only horizontally or vertically. Possible values: "x", "y".
      +Code examples:

      Initialize the sortable with the axis option specified:

      +
      $( ".selector" ).sortable({ axis: "x" });
      +

      Get or set the axis option, after initialization:

      +
      // getter
      var axis = $( ".selector" ).sortable( "option", "axis" );
       
      // setter
      $( ".selector" ).sortable( "option", "axis", "x" );
      +
      +
      +

      cancelType: Selector +

      +
      +Default: ":input,button" +
      +
      Prevents sorting if you start on elements matching the selector.
      +Code examples:

      Initialize the sortable with the cancel option specified:

      +
      $( ".selector" ).sortable({ cancel: "a,button" });
      +

      Get or set the cancel option, after initialization:

      +
      // getter
      var cancel = $( ".selector" ).sortable( "option", "cancel" );
       
      // setter
      $( ".selector" ).sortable( "option", "cancel", "a,button" );
      +
      +
      +

      connectWithType: Selector +

      +
      +Default: false +
      +
      A selector of other sortable elements that the items from this list should be connected to. This is a one-way relationship, if you want the items to be connected in both directions, the connectWith option must be set on both sortable elements.
      +Code examples:

      Initialize the sortable with the connectWith option specified:

      +
      $( ".selector" ).sortable({ connectWith: "#shopping-cart" });
      +

      Get or set the connectWith option, after initialization:

      +
      // getter
      var connectWith = $( ".selector" ).sortable( "option", "connectWith" );
       
      // setter
      $( ".selector" ).sortable( "option", "connectWith", "#shopping-cart" );
      +
      +
      +

      containmentType: Element or Selector or String +

      +
      +Default: false +
      +
      +

      Defines a bounding box that the sortable items are contrained to while dragging.

      + +

      Note: The element specified for containment must have a calculated width and height (though it need not be explicit). For example, if you have float: left sortable children and specify containment: "parent" be sure to have float: left on the sortable/parent container as well or it will have height: 0, causing undefined behavior.

      +
      +Multiple types supported:
        +
      • +Element: An element to use as the container.
      • +
      • +Selector: A selector specifying an element to use as the container.
      • +
      • +String: A string identifying an element to use as the container. Possible values: "parent", "document", "window".
      • +
      +Code examples:

      Initialize the sortable with the containment option specified:

      +
      $( ".selector" ).sortable({ containment: "parent" });
      +

      Get or set the containment option, after initialization:

      +
      // getter
      var containment = $( ".selector" ).sortable( "option", "containment" );
       
      // setter
      $( ".selector" ).sortable( "option", "containment", "parent" );
      +
      +
      +

      cursorType: String +

      +
      +Default: "auto" +
      +
      Defines the cursor that is being shown while sorting.
      +Code examples:

      Initialize the sortable with the cursor option specified:

      +
      $( ".selector" ).sortable({ cursor: "move" });
      +

      Get or set the cursor option, after initialization:

      +
      // getter
      var cursor = $( ".selector" ).sortable( "option", "cursor" );
       
      // setter
      $( ".selector" ).sortable( "option", "cursor", "move" );
      +
      +
      +

      cursorAtType: Object +

      +
      +Default: false +
      +
      Moves the sorting element or helper so the cursor always appears to drag from the same position. Coordinates can be given as a hash using a combination of one or two keys: { top, left, right, bottom }.
      +Code examples:

      Initialize the sortable with the cursorAt option specified:

      +
      $( ".selector" ).sortable({ cursorAt: { left: 5 } });
      +

      Get or set the cursorAt option, after initialization:

      +
      // getter
      var cursorAt = $( ".selector" ).sortable( "option", "cursorAt" );
       
      // setter
      $( ".selector" ).sortable( "option", "cursorAt", { left: 5 } );
      +
      +
      +

      delayType: Integer +

      +
      +Default: 0 +
      +
      Time in milliseconds to define when the sorting should start. Adding a delay helps preventing unwanted drags when clicking on an element.
      +Code examples:

      Initialize the sortable with the delay option specified:

      +
      $( ".selector" ).sortable({ delay: 150 });
      +

      Get or set the delay option, after initialization:

      +
      // getter
      var delay = $( ".selector" ).sortable( "option", "delay" );
       
      // setter
      $( ".selector" ).sortable( "option", "delay", 150 );
      +
      +
      +

      disabledType: Boolean +

      +
      +Default: false +
      +
      Disables the sortable if set to true.
      +Code examples:

      Initialize the sortable with the disabled option specified:

      +
      $( ".selector" ).sortable({ disabled: true });
      +

      Get or set the disabled option, after initialization:

      +
      // getter
      var disabled = $( ".selector" ).sortable( "option", "disabled" );
       
      // setter
      $( ".selector" ).sortable( "option", "disabled", true );
      +
      +
      +

      distanceType: Number +

      +
      +Default: 1 +
      +
      Tolerance, in pixels, for when sorting should start. If specified, sorting will not start until after mouse is dragged beyond distance. Can be used to allow for clicks on elements within a handle.
      +Code examples:

      Initialize the sortable with the distance option specified:

      +
      $( ".selector" ).sortable({ distance: 5 });
      +

      Get or set the distance option, after initialization:

      +
      // getter
      var distance = $( ".selector" ).sortable( "option", "distance" );
       
      // setter
      $( ".selector" ).sortable( "option", "distance", 5 );
      +
      +
      +

      dropOnEmptyType: Boolean +

      +
      +Default: true +
      +
      If false, items from this sortable can't be dropped on an empty connect sortable (see the connectWith option.
      +Code examples:

      Initialize the sortable with the dropOnEmpty option specified:

      +
      $( ".selector" ).sortable({ dropOnEmpty: false });
      +

      Get or set the dropOnEmpty option, after initialization:

      +
      // getter
      var dropOnEmpty = $( ".selector" ).sortable( "option", "dropOnEmpty" );
       
      // setter
      $( ".selector" ).sortable( "option", "dropOnEmpty", false );
      +
      +
      +

      forceHelperSizeType: Boolean +

      +
      +Default: false +
      +
      If true, forces the helper to have a size.
      +Code examples:

      Initialize the sortable with the forceHelperSize option specified:

      +
      $( ".selector" ).sortable({ forceHelperSize: true });
      +

      Get or set the forceHelperSize option, after initialization:

      +
      // getter
      var forceHelperSize = $( ".selector" ).sortable( "option", "forceHelperSize" );
       
      // setter
      $( ".selector" ).sortable( "option", "forceHelperSize", true );
      +
      +
      +

      forcePlaceholderSizeType: Boolean +

      +
      +Default: false +
      +
      If true, forces the placeholder to have a size.
      +Code examples:

      Initialize the sortable with the forcePlaceholderSize option specified:

      +
      $( ".selector" ).sortable({ forcePlaceholderSize: true });
      +

      Get or set the forcePlaceholderSize option, after initialization:

      +
      // getter
      var forcePlaceholderSize = $( ".selector" ).sortable( "option", "forcePlaceholderSize" );
       
      // setter
      $( ".selector" ).sortable( "option", "forcePlaceholderSize", true );
      +
      +
      +

      gridType: Array +

      +
      +Default: false +
      +
      Snaps the sorting element or helper to a grid, every x and y pixels. Array values: [ x, y ].
      +Code examples:

      Initialize the sortable with the grid option specified:

      +
      $( ".selector" ).sortable({ grid: [ 20, 10 ] });
      +

      Get or set the grid option, after initialization:

      +
      // getter
      var grid = $( ".selector" ).sortable( "option", "grid" );
       
      // setter
      $( ".selector" ).sortable( "option", "grid", [ 20, 10 ] );
      +
      +
      +

      handleType: Selector or Element +

      +
      +Default: false +
      +
      Restricts sort start click to the specified element.
      +Code examples:

      Initialize the sortable with the handle option specified:

      +
      $( ".selector" ).sortable({ handle: ".handle" });
      +

      Get or set the handle option, after initialization:

      +
      // getter
      var handle = $( ".selector" ).sortable( "option", "handle" );
       
      // setter
      $( ".selector" ).sortable( "option", "handle", ".handle" );
      +
      +
      +

      helperType: String or Function() +

      +
      +Default: "original" +
      +
      Allows for a helper element to be used for dragging display.
      +Multiple types supported:
        +
      • +String: If set to "clone", then the element will be cloned and the clone will be dragged.
      • +
      • +Function: A function that will return a DOMElement to use while dragging. The function receives the event and the element being sorted.
      • +
      +Code examples:

      Initialize the sortable with the helper option specified:

      +
      $( ".selector" ).sortable({ helper: "clone" });
      +

      Get or set the helper option, after initialization:

      +
      // getter
      var helper = $( ".selector" ).sortable( "option", "helper" );
       
      // setter
      $( ".selector" ).sortable( "option", "helper", "clone" );
      +
      +
      +

      itemsType: Selector +

      +
      +Default: "> *" +
      +
      Specifies which items inside the element should be sortable.
      +Code examples:

      Initialize the sortable with the items option specified:

      +
      $( ".selector" ).sortable({ items: "> li" });
      +

      Get or set the items option, after initialization:

      +
      // getter
      var items = $( ".selector" ).sortable( "option", "items" );
       
      // setter
      $( ".selector" ).sortable( "option", "items", "> li" );
      +
      +
      +

      opacityType: Number +

      +
      +Default: false +
      +
      Defines the opacity of the helper while sorting. From 0.01 to 1.
      +Code examples:

      Initialize the sortable with the opacity option specified:

      +
      $( ".selector" ).sortable({ opacity: 0.5 });
      +

      Get or set the opacity option, after initialization:

      +
      // getter
      var opacity = $( ".selector" ).sortable( "option", "opacity" );
       
      // setter
      $( ".selector" ).sortable( "option", "opacity", 0.5 );
      +
      +
      +

      placeholderType: String +

      +
      +Default: false +
      +
      A class name that gets applied to the otherwise white space.
      +Code examples:

      Initialize the sortable with the placeholder option specified:

      +
      $( ".selector" ).sortable({ placeholder: "sortable-placeholder" });
      +

      Get or set the placeholder option, after initialization:

      +
      // getter
      var placeholder = $( ".selector" ).sortable( "option", "placeholder" );
       
      // setter
      $( ".selector" ).sortable( "option", "placeholder", "sortable-placeholder" );
      +
      +
      +

      revertType: Boolean or Number +

      +
      +Default: false +
      +
      Whether the sortable items should revert to their new positions using a smooth animation.
      +Multiple types supported:
        +
      • +Boolean: When set to true, the items will animate with the default duration.
      • +
      • +Number: The duration for the animation, in milliseconds.
      • +
      +Code examples:

      Initialize the sortable with the revert option specified:

      +
      $( ".selector" ).sortable({ revert: true });
      +

      Get or set the revert option, after initialization:

      +
      // getter
      var revert = $( ".selector" ).sortable( "option", "revert" );
       
      // setter
      $( ".selector" ).sortable( "option", "revert", true );
      +
      +
      +

      scrollType: Boolean +

      +
      +Default: true +
      +
      If set to true, the page scrolls when coming to an edge.
      +Code examples:

      Initialize the sortable with the scroll option specified:

      +
      $( ".selector" ).sortable({ scroll: false });
      +

      Get or set the scroll option, after initialization:

      +
      // getter
      var scroll = $( ".selector" ).sortable( "option", "scroll" );
       
      // setter
      $( ".selector" ).sortable( "option", "scroll", false );
      +
      +
      +

      scrollSensitivityType: Number +

      +
      +Default: 20 +
      +
      Defines how near the mouse must be to an edge to start scrolling.
      +Code examples:

      Initialize the sortable with the scrollSensitivity option specified:

      +
      $( ".selector" ).sortable({ scrollSensitivity: 10 });
      +

      Get or set the scrollSensitivity option, after initialization:

      +
      // getter
      var scrollSensitivity = $( ".selector" ).sortable( "option", "scrollSensitivity" );
       
      // setter
      $( ".selector" ).sortable( "option", "scrollSensitivity", 10 );
      +
      +
      +

      scrollSpeedType: Number +

      +
      +Default: 20 +
      +
      The speed at which the window should scroll once the mouse pointer gets within the scrollSensitivity distance.
      +Code examples:

      Initialize the sortable with the scrollSpeed option specified:

      +
      $( ".selector" ).sortable({ scrollSpeed: 40 });
      +

      Get or set the scrollSpeed option, after initialization:

      +
      // getter
      var scrollSpeed = $( ".selector" ).sortable( "option", "scrollSpeed" );
       
      // setter
      $( ".selector" ).sortable( "option", "scrollSpeed", 40 );
      +
      +
      +

      toleranceType: String +

      +
      +Default: "intersect" +
      +
      + Specifies which mode to use for testing whether the item being moved is hovering over another item. Possible values: +
        +
      • +"intersect": The item overlaps the other item by at least 50%.
      • +
      • +"pointer": The mouse pointer overlaps the other item.
      • +
      +
      +Code examples:

      Initialize the sortable with the tolerance option specified:

      +
      $( ".selector" ).sortable({ tolerance: "pointer" });
      +

      Get or set the tolerance option, after initialization:

      +
      // getter
      var tolerance = $( ".selector" ).sortable( "option", "tolerance" );
       
      // setter
      $( ".selector" ).sortable( "option", "tolerance", "pointer" );
      +
      +
      +

      zIndexType: Integer +

      +
      +Default: 1000 +
      +
      Z-index for element/helper while being sorted.
      +Code examples:

      Initialize the sortable with the zIndex option specified:

      +
      $( ".selector" ).sortable({ zIndex: 9999 });
      +

      Get or set the zIndex option, after initialization:

      +
      // getter
      var zIndex = $( ".selector" ).sortable( "option", "zIndex" );
       
      // setter
      $( ".selector" ).sortable( "option", "zIndex", 9999 );
      +

      Methods

      +
      +

      cancel()

      +
      Cancels a change in the current sortable and reverts it to the state prior to when the current sort was started. Useful in the stop and receive callback functions.
      +
      • This method does not accept any arguments.
      +
      +
      +Code examples:

      Invoke the cancel method:

      +
      $( ".selector" ).sortable( "cancel" );
      +
      +
      +
      +
      +

      destroy()

      +
      + Removes the sortable functionality completely. This will return the element back to its pre-init state. +
      +
      • This method does not accept any arguments.
      +
      +
      +Code examples:

      Invoke the destroy method:

      +
      $( ".selector" ).sortable( "destroy" );
      +
      +
      +
      +
      +

      disable()

      +
      + Disables the sortable. +
      +
      • This method does not accept any arguments.
      +
      +
      +Code examples:

      Invoke the disable method:

      +
      $( ".selector" ).sortable( "disable" );
      +
      +
      +
      +
      +

      enable()

      +
      + Enables the sortable. +
      +
      • This method does not accept any arguments.
      +
      +
      +Code examples:

      Invoke the enable method:

      +
      $( ".selector" ).sortable( "enable" );
      +
      +
      +
      +
      +

      option( optionName ) Returns: Object +

      +
      Gets the value currently associated with the specified optionName.
      +
      • +
        optionName
        +
        Type: String +
        +
        The name of the option to get.
        +
      +
      +
      +Code examples:

      Invoke the method:

      +
      var isDisabled = $( ".selector" ).sortable( "option", "disabled" );
      +
      +
      +

      option() Returns: PlainObject +

      +
      Gets an object containing key/value pairs representing the current sortable options hash.
      +
      • This method does not accept any arguments.
      +
      +
      +Code examples:

      Invoke the method:

      +
      var options = $( ".selector" ).sortable( "option" );
      +
      +
      +

      option( optionName, value )

      +
      Sets the value of the sortable option associated with the specified optionName.
      +
        +
      • +
        optionName
        +
        Type: String +
        +
        The name of the option to set.
        +
      • +
      • +
        value
        +
        Type: Object +
        +
        A value to set for the option.
        +
      • +
      +
      +
      +Code examples:

      Invoke the method:

      +
      $( ".selector" ).sortable( "option", "disabled", true );
      +
      +
      +

      option( options )

      +
      Sets one or more options for the sortable.
      +
      • +
        options
        +
        Type: Object +
        +
        A map of option-value pairs to set.
        +
      +
      +
      +Code examples:

      Invoke the method:

      +
      $( ".selector" ).sortable( "option", { disabled: true } );
      +
      +
      +
      +
      +

      refresh()

      +
      Refresh the sortable items. Triggers the reloading of all sortable items, causing new items to be recognized.
      +
      • This method does not accept any arguments.
      +
      +
      +Code examples:

      Invoke the refresh method:

      +
      $( ".selector" ).sortable( "refresh" );
      +
      +
      +
      +
      +

      refreshPositions()

      +
      Refresh the cached positions of the sortable items. Calling this method refreshes the cached item positions of all sortables.
      +
      • This method does not accept any arguments.
      +
      +
      +Code examples:

      Invoke the refreshPositions method:

      +
      $( ".selector" ).sortable( "refreshPositions" );
      +
      +
      +
      +
      +

      serialize( options ) Returns: String +

      +
      +

      Serializes the sortable's item ids into a form/ajax submittable string. Calling this method produces a hash that can be appended to any url to easily submit a new item order back to the server.

      + +

      It works by default by looking at the id of each item in the format "setname_number", and it spits out a hash like "setname[]=number&setname[]=number".

      + +

      Note: If serialize returns an empty string, make sure the id attributes include an underscore. They must be in the form: "set_number" For example, a 3 element list with id attributes "foo_1", "foo_5", "foo_2" will serialize to "foo[]=1&foo[]=5&foo[]=2". You can use an underscore, equal sign or hyphen to separate the set and number. For example "foo=1", "foo-1", and "foo_1" all serialize to "foo[]=1".

      +
      +
      • +
        options
        +
        Type: Object +
        +
        Options to customize the serialization.
        +
          +
        • +
          +key (default: the part of the attribute in front of the separator)
          +
          Type: String +
          +
          Replaces part1[] with the specified value.
          +
        • +
        • +
          +attribute (default: "id")
          +
          Type: String +
          +
          The name of the attribute to use for the values.
          +
        • +
        • +
          +expression (default: /(.+)[-=_](.+)/)
          +
          Type: RegExp +
          +
          A regular expression used to split the attribute value into key and value parts.
          +
        • +
        +
      +
      +
      +Code examples:

      Invoke the serialize method:

      +
      var sorted = $( ".selector" ).sortable( "serialize", { key: "sort" } );
      +
      +
      +
      +
      +

      toArray() Returns: Array +

      +
      Serializes the sortable's item id's into an array of string.
      +
      • This method does not accept any arguments.
      +
      +
      +Code examples:

      Invoke the toArray method:

      +
      var sortedIDs = $( ".selector" ).sortable( "toArray" );
      +
      +
      +
      +
      +

      widget() Returns: jQuery +

      +
      + Returns a jQuery object containing the sortable element. +
      +
      • This method does not accept any arguments.
      +
      +
      +Code examples:

      Invoke the widget method:

      +
      var widget = $( ".selector" ).sortable( "widget" );
      +
      +

      Events

      +

      activate( event, ui )Type: sortactivate +

      +
      This event is triggered when using connected lists, every connected list on drag start receives it.
      +
        +
      • +
        event
        +
        Type: Event +
        +
        +
      • +
      • +
        ui
        +
        Type: Object +
        +
        +
          +
        • +
          helper
          +
          Type: jQuery +
          +
          The jQuery object representing the helper being sorted
          +
        • +
        • +
          item
          +
          Type: jQuery +
          +
          The jQuery object representing the current dragged element
          +
        • +
        • +
          offset
          +
          Type: Object +
          +
          The current absolute position of the helper represented as { top, left } +
          +
        • +
        • +
          position
          +
          Type: Object +
          +
          The current position of the helper represented as { top, left } +
          +
        • +
        • +
          originalPosition
          +
          Type: Object +
          +
          The original position of the element represented as { top, left } +
          +
        • +
        • +
          sender
          +
          Type: jQuery +
          +
          The sortable that the item comes from if moving from one sortable to another
          +
        • +
        +
      • +
      +
      +Code examples:

      Initialize the sortable with the activate callback specified:

      +
      $( ".selector" ).sortable({
          activate: function( event, ui ) {}
      });
      +

      Bind an event listener to the sortactivate event:

      +
      $( ".selector" ).on( "sortactivate", function( event, ui ) {} );
      +
      +
      +
      +

      beforeStop( event, ui )Type: sortbeforestop +

      +
      This event is triggered when sorting stops, but when the placeholder/helper is still available.
      +
        +
      • +
        event
        +
        Type: Event +
        +
        +
      • +
      • +
        ui
        +
        Type: Object +
        +
        +
          +
        • +
          helper
          +
          Type: jQuery +
          +
          The jQuery object representing the helper being sorted
          +
        • +
        • +
          item
          +
          Type: jQuery +
          +
          The jQuery object representing the current dragged element
          +
        • +
        • +
          offset
          +
          Type: Object +
          +
          The current absolute position of the helper represented as { top, left } +
          +
        • +
        • +
          position
          +
          Type: Object +
          +
          The current position of the helper represented as { top, left } +
          +
        • +
        • +
          originalPosition
          +
          Type: Object +
          +
          The original position of the element represented as { top, left } +
          +
        • +
        • +
          sender
          +
          Type: jQuery +
          +
          The sortable that the item comes from if moving from one sortable to another
          +
        • +
        +
      • +
      +
      +Code examples:

      Initialize the sortable with the beforeStop callback specified:

      +
      $( ".selector" ).sortable({
          beforeStop: function( event, ui ) {}
      });
      +

      Bind an event listener to the sortbeforestop event:

      +
      $( ".selector" ).on( "sortbeforestop", function( event, ui ) {} );
      +
      +
      +
      +

      change( event, ui )Type: sortchange +

      +
      This event is triggered during sorting, but only when the DOM position has changed.
      +
        +
      • +
        event
        +
        Type: Event +
        +
        +
      • +
      • +
        ui
        +
        Type: Object +
        +
        +
          +
        • +
          helper
          +
          Type: jQuery +
          +
          The jQuery object representing the helper being sorted
          +
        • +
        • +
          item
          +
          Type: jQuery +
          +
          The jQuery object representing the current dragged element
          +
        • +
        • +
          offset
          +
          Type: Object +
          +
          The current absolute position of the helper represented as { top, left } +
          +
        • +
        • +
          position
          +
          Type: Object +
          +
          The current position of the helper represented as { top, left } +
          +
        • +
        • +
          originalPosition
          +
          Type: Object +
          +
          The original position of the element represented as { top, left } +
          +
        • +
        • +
          sender
          +
          Type: jQuery +
          +
          The sortable that the item comes from if moving from one sortable to another
          +
        • +
        +
      • +
      +
      +Code examples:

      Initialize the sortable with the change callback specified:

      +
      $( ".selector" ).sortable({
          change: function( event, ui ) {}
      });
      +

      Bind an event listener to the sortchange event:

      +
      $( ".selector" ).on( "sortchange", function( event, ui ) {} );
      +
      +
      +
      +

      create( event, ui )Type: sortcreate +

      +
      + Triggered when the sortable is created. +
      +
        +
      • +
        event
        +
        Type: Event +
        +
        +
      • +
      • +
        ui
        +
        Type: Object +
        +
        +
      • +
      +
      +Code examples:

      Initialize the sortable with the create callback specified:

      +
      $( ".selector" ).sortable({
          create: function( event, ui ) {}
      });
      +

      Bind an event listener to the sortcreate event:

      +
      $( ".selector" ).on( "sortcreate", function( event, ui ) {} );
      +
      +
      +
      +

      deactivate( event, ui )Type: sortdeactivate +

      +
      This event is triggered when sorting was stopped, is propagated to all possible connected lists.
      +
        +
      • +
        event
        +
        Type: Event +
        +
        +
      • +
      • +
        ui
        +
        Type: Object +
        +
        +
          +
        • +
          helper
          +
          Type: jQuery +
          +
          The jQuery object representing the helper being sorted
          +
        • +
        • +
          item
          +
          Type: jQuery +
          +
          The jQuery object representing the current dragged element
          +
        • +
        • +
          offset
          +
          Type: Object +
          +
          The current absolute position of the helper represented as { top, left } +
          +
        • +
        • +
          position
          +
          Type: Object +
          +
          The current position of the helper represented as { top, left } +
          +
        • +
        • +
          originalPosition
          +
          Type: Object +
          +
          The original position of the element represented as { top, left } +
          +
        • +
        • +
          sender
          +
          Type: jQuery +
          +
          The sortable that the item comes from if moving from one sortable to another
          +
        • +
        +
      • +
      +
      +Code examples:

      Initialize the sortable with the deactivate callback specified:

      +
      $( ".selector" ).sortable({
          deactivate: function( event, ui ) {}
      });
      +

      Bind an event listener to the sortdeactivate event:

      +
      $( ".selector" ).on( "sortdeactivate", function( event, ui ) {} );
      +
      +
      +
      +

      out( event, ui )Type: sortout +

      +
      This event is triggered when a sortable item is moved away from a connected list.
      +
        +
      • +
        event
        +
        Type: Event +
        +
        +
      • +
      • +
        ui
        +
        Type: Object +
        +
        +
          +
        • +
          helper
          +
          Type: jQuery +
          +
          The jQuery object representing the helper being sorted
          +
        • +
        • +
          item
          +
          Type: jQuery +
          +
          The jQuery object representing the current dragged element
          +
        • +
        • +
          offset
          +
          Type: Object +
          +
          The current absolute position of the helper represented as { top, left } +
          +
        • +
        • +
          position
          +
          Type: Object +
          +
          The current position of the helper represented as { top, left } +
          +
        • +
        • +
          originalPosition
          +
          Type: Object +
          +
          The original position of the element represented as { top, left } +
          +
        • +
        • +
          sender
          +
          Type: jQuery +
          +
          The sortable that the item comes from if moving from one sortable to another
          +
        • +
        +
      • +
      +
      +Code examples:

      Initialize the sortable with the out callback specified:

      +
      $( ".selector" ).sortable({
          out: function( event, ui ) {}
      });
      +

      Bind an event listener to the sortout event:

      +
      $( ".selector" ).on( "sortout", function( event, ui ) {} );
      +
      +
      +
      +

      over( event, ui )Type: sortover +

      +
      This event is triggered when a sortable item is moved into a connected list.
      +
        +
      • +
        event
        +
        Type: Event +
        +
        +
      • +
      • +
        ui
        +
        Type: Object +
        +
        +
          +
        • +
          helper
          +
          Type: jQuery +
          +
          The jQuery object representing the helper being sorted
          +
        • +
        • +
          item
          +
          Type: jQuery +
          +
          The jQuery object representing the current dragged element
          +
        • +
        • +
          offset
          +
          Type: Object +
          +
          The current absolute position of the helper represented as { top, left } +
          +
        • +
        • +
          position
          +
          Type: Object +
          +
          The current position of the helper represented as { top, left } +
          +
        • +
        • +
          originalPosition
          +
          Type: Object +
          +
          The original position of the element represented as { top, left } +
          +
        • +
        • +
          sender
          +
          Type: jQuery +
          +
          The sortable that the item comes from if moving from one sortable to another
          +
        • +
        +
      • +
      +
      +Code examples:

      Initialize the sortable with the over callback specified:

      +
      $( ".selector" ).sortable({
          over: function( event, ui ) {}
      });
      +

      Bind an event listener to the sortover event:

      +
      $( ".selector" ).on( "sortover", function( event, ui ) {} );
      +
      +
      +
      +

      receive( event, ui )Type: sortreceive +

      +
      This event is triggered when a connected sortable list has received an item from another list.
      +
        +
      • +
        event
        +
        Type: Event +
        +
        +
      • +
      • +
        ui
        +
        Type: Object +
        +
        +
          +
        • +
          helper
          +
          Type: jQuery +
          +
          The jQuery object representing the helper being sorted
          +
        • +
        • +
          item
          +
          Type: jQuery +
          +
          The jQuery object representing the current dragged element
          +
        • +
        • +
          offset
          +
          Type: Object +
          +
          The current absolute position of the helper represented as { top, left } +
          +
        • +
        • +
          position
          +
          Type: Object +
          +
          The current position of the helper represented as { top, left } +
          +
        • +
        • +
          originalPosition
          +
          Type: Object +
          +
          The original position of the element represented as { top, left } +
          +
        • +
        • +
          sender
          +
          Type: jQuery +
          +
          The sortable that the item comes from if moving from one sortable to another
          +
        • +
        +
      • +
      +
      +Code examples:

      Initialize the sortable with the receive callback specified:

      +
      $( ".selector" ).sortable({
          receive: function( event, ui ) {}
      });
      +

      Bind an event listener to the sortreceive event:

      +
      $( ".selector" ).on( "sortreceive", function( event, ui ) {} );
      +
      +
      +
      +

      remove( event, ui )Type: sortremove +

      +
      This event is triggered when a sortable item has been dragged out from the list and into another.
      +
        +
      • +
        event
        +
        Type: Event +
        +
        +
      • +
      • +
        ui
        +
        Type: Object +
        +
        +
          +
        • +
          helper
          +
          Type: jQuery +
          +
          The jQuery object representing the helper being sorted
          +
        • +
        • +
          item
          +
          Type: jQuery +
          +
          The jQuery object representing the current dragged element
          +
        • +
        • +
          offset
          +
          Type: Object +
          +
          The current absolute position of the helper represented as { top, left } +
          +
        • +
        • +
          position
          +
          Type: Object +
          +
          The current position of the helper represented as { top, left } +
          +
        • +
        • +
          originalPosition
          +
          Type: Object +
          +
          The original position of the element represented as { top, left } +
          +
        • +
        • +
          sender
          +
          Type: jQuery +
          +
          The sortable that the item comes from if moving from one sortable to another
          +
        • +
        +
      • +
      +
      +Code examples:

      Initialize the sortable with the remove callback specified:

      +
      $( ".selector" ).sortable({
          remove: function( event, ui ) {}
      });
      +

      Bind an event listener to the sortremove event:

      +
      $( ".selector" ).on( "sortremove", function( event, ui ) {} );
      +
      +
      +
      +

      sort( event, ui )Type: sort +

      +
      This event is triggered during sorting.
      +
        +
      • +
        event
        +
        Type: Event +
        +
        +
      • +
      • +
        ui
        +
        Type: Object +
        +
        +
          +
        • +
          helper
          +
          Type: jQuery +
          +
          The jQuery object representing the helper being sorted
          +
        • +
        • +
          item
          +
          Type: jQuery +
          +
          The jQuery object representing the current dragged element
          +
        • +
        • +
          offset
          +
          Type: Object +
          +
          The current absolute position of the helper represented as { top, left } +
          +
        • +
        • +
          position
          +
          Type: Object +
          +
          The current position of the helper represented as { top, left } +
          +
        • +
        • +
          originalPosition
          +
          Type: Object +
          +
          The original position of the element represented as { top, left } +
          +
        • +
        • +
          sender
          +
          Type: jQuery +
          +
          The sortable that the item comes from if moving from one sortable to another
          +
        • +
        +
      • +
      +
      +Code examples:

      Initialize the sortable with the sort callback specified:

      +
      $( ".selector" ).sortable({
          sort: function( event, ui ) {}
      });
      +

      Bind an event listener to the sort event:

      +
      $( ".selector" ).on( "sort", function( event, ui ) {} );
      +
      +
      +
      +

      start( event, ui )Type: sortstart +

      +
      This event is triggered when sorting starts.
      +
        +
      • +
        event
        +
        Type: Event +
        +
        +
      • +
      • +
        ui
        +
        Type: Object +
        +
        +
          +
        • +
          helper
          +
          Type: jQuery +
          +
          The jQuery object representing the helper being sorted
          +
        • +
        • +
          item
          +
          Type: jQuery +
          +
          The jQuery object representing the current dragged element
          +
        • +
        • +
          offset
          +
          Type: Object +
          +
          The current absolute position of the helper represented as { top, left } +
          +
        • +
        • +
          position
          +
          Type: Object +
          +
          The current position of the helper represented as { top, left } +
          +
        • +
        • +
          originalPosition
          +
          Type: Object +
          +
          The original position of the element represented as { top, left } +
          +
        • +
        • +
          sender
          +
          Type: jQuery +
          +
          The sortable that the item comes from if moving from one sortable to another
          +
        • +
        +
      • +
      +
      +Code examples:

      Initialize the sortable with the start callback specified:

      +
      $( ".selector" ).sortable({
          start: function( event, ui ) {}
      });
      +

      Bind an event listener to the sortstart event:

      +
      $( ".selector" ).on( "sortstart", function( event, ui ) {} );
      +
      +
      +
      +

      stop( event, ui )Type: sortstop +

      +
      This event is triggered when sorting has stopped.
      +
        +
      • +
        event
        +
        Type: Event +
        +
        +
      • +
      • +
        ui
        +
        Type: Object +
        +
        +
          +
        • +
          helper
          +
          Type: jQuery +
          +
          The jQuery object representing the helper being sorted
          +
        • +
        • +
          item
          +
          Type: jQuery +
          +
          The jQuery object representing the current dragged element
          +
        • +
        • +
          offset
          +
          Type: Object +
          +
          The current absolute position of the helper represented as { top, left } +
          +
        • +
        • +
          position
          +
          Type: Object +
          +
          The current position of the helper represented as { top, left } +
          +
        • +
        • +
          originalPosition
          +
          Type: Object +
          +
          The original position of the element represented as { top, left } +
          +
        • +
        • +
          sender
          +
          Type: jQuery +
          +
          The sortable that the item comes from if moving from one sortable to another
          +
        • +
        +
      • +
      +
      +Code examples:

      Initialize the sortable with the stop callback specified:

      +
      $( ".selector" ).sortable({
          stop: function( event, ui ) {}
      });
      +

      Bind an event listener to the sortstop event:

      +
      $( ".selector" ).on( "sortstop", function( event, ui ) {} );
      +
      +
      +
      +

      update( event, ui )Type: sortupdate +

      +
      This event is triggered when the user stopped sorting and the DOM position has changed.
      +
        +
      • +
        event
        +
        Type: Event +
        +
        +
      • +
      • +
        ui
        +
        Type: Object +
        +
        +
          +
        • +
          helper
          +
          Type: jQuery +
          +
          The jQuery object representing the helper being sorted
          +
        • +
        • +
          item
          +
          Type: jQuery +
          +
          The jQuery object representing the current dragged element
          +
        • +
        • +
          offset
          +
          Type: Object +
          +
          The current absolute position of the helper represented as { top, left } +
          +
        • +
        • +
          position
          +
          Type: Object +
          +
          The current position of the helper represented as { top, left } +
          +
        • +
        • +
          originalPosition
          +
          Type: Object +
          +
          The original position of the element represented as { top, left } +
          +
        • +
        • +
          sender
          +
          Type: jQuery +
          +
          The sortable that the item comes from if moving from one sortable to another
          +
        • +
        +
      • +
      +
      +Code examples:

      Initialize the sortable with the update callback specified:

      +
      $( ".selector" ).sortable({
          update: function( event, ui ) {}
      });
      +

      Bind an event listener to the sortupdate event:

      +
      $( ".selector" ).on( "sortupdate", function( event, ui ) {} );
      +
      +
      +

      Overview

      +

      The jQuery UI Sortable plugin makes selected elements sortable by dragging with the mouse.

      +

      Note: In order to sort table rows, the tbody must be made sortable, not the table.

      +
      +

      Example:

      +

      A simple jQuery UI Sortable.

      +
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      <!doctype html>
      <html lang="en">
      <head>
          <meta charset="utf-8">
          <title>sortable demo</title>
          <link rel="stylesheet" href="http://code.jquery.com/ui/1.9.2/themes/base/jquery-ui.css">
          <script src="http://code.jquery.com/jquery-1.8.3.js"></script>
          <script src="http://code.jquery.com/ui/1.9.2/jquery-ui.js"></script>
      </head>
      <body>
       
      <ul id="sortable">
          <li>Item 1</li>
          <li>Item 2</li>
          <li>Item 3</li>
          <li>Item 4</li>
          <li>Item 5</li>
      </ul>
       
      <script>$("#sortable").sortable();</script>
       
      </body>
      </html>
      +

      Demo:

      +
      +
      +
      + + + diff --git a/htdocs/js/lib/vendor/jquery-drag-drop/development-bundle/external/globalize.culture.de-DE.js b/htdocs/js/lib/vendor/jquery-drag-drop/development-bundle/external/globalize.culture.de-DE.js new file mode 100755 index 000000000..5466bd75e --- /dev/null +++ b/htdocs/js/lib/vendor/jquery-drag-drop/development-bundle/external/globalize.culture.de-DE.js @@ -0,0 +1,81 @@ +/* + * Globalize Culture de-DE + * + * http://github.com/jquery/globalize + * + * Copyright Software Freedom Conservancy, Inc. + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * This file was generated by the Globalize Culture Generator + * Translation: bugs found in this file need to be fixed in the generator + */ + +(function( window, undefined ) { + +var Globalize; + +if ( typeof require !== "undefined" + && typeof exports !== "undefined" + && typeof module !== "undefined" ) { + // Assume CommonJS + Globalize = require( "globalize" ); +} else { + // Global variable + Globalize = window.Globalize; +} + +Globalize.addCultureInfo( "de-DE", "default", { + name: "de-DE", + englishName: "German (Germany)", + nativeName: "Deutsch (Deutschland)", + language: "de", + numberFormat: { + ",": ".", + ".": ",", + NaN: "n. def.", + negativeInfinity: "-unendlich", + positiveInfinity: "+unendlich", + percent: { + pattern: ["-n%","n%"], + ",": ".", + ".": "," + }, + currency: { + pattern: ["-n $","n $"], + ",": ".", + ".": ",", + symbol: "€" + } + }, + calendars: { + standard: { + "/": ".", + firstDay: 1, + days: { + names: ["Sonntag","Montag","Dienstag","Mittwoch","Donnerstag","Freitag","Samstag"], + namesAbbr: ["So","Mo","Di","Mi","Do","Fr","Sa"], + namesShort: ["So","Mo","Di","Mi","Do","Fr","Sa"] + }, + months: { + names: ["Januar","Februar","März","April","Mai","Juni","Juli","August","September","Oktober","November","Dezember",""], + namesAbbr: ["Jan","Feb","Mrz","Apr","Mai","Jun","Jul","Aug","Sep","Okt","Nov","Dez",""] + }, + AM: null, + PM: null, + eras: [{"name":"n. Chr.","start":null,"offset":0}], + patterns: { + d: "dd.MM.yyyy", + D: "dddd, d. MMMM yyyy", + t: "HH:mm", + T: "HH:mm:ss", + f: "dddd, d. MMMM yyyy HH:mm", + F: "dddd, d. MMMM yyyy HH:mm:ss", + M: "dd MMMM", + Y: "MMMM yyyy" + } + } + } +}); + +}( this )); diff --git a/htdocs/js/lib/vendor/jquery-drag-drop/development-bundle/external/globalize.culture.ja-JP.js b/htdocs/js/lib/vendor/jquery-drag-drop/development-bundle/external/globalize.culture.ja-JP.js new file mode 100755 index 000000000..a9469d709 --- /dev/null +++ b/htdocs/js/lib/vendor/jquery-drag-drop/development-bundle/external/globalize.culture.ja-JP.js @@ -0,0 +1,100 @@ +/* + * Globalize Culture ja-JP + * + * http://github.com/jquery/globalize + * + * Copyright Software Freedom Conservancy, Inc. + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * This file was generated by the Globalize Culture Generator + * Translation: bugs found in this file need to be fixed in the generator + */ + +(function( window, undefined ) { + +var Globalize; + +if ( typeof require !== "undefined" + && typeof exports !== "undefined" + && typeof module !== "undefined" ) { + // Assume CommonJS + Globalize = require( "globalize" ); +} else { + // Global variable + Globalize = window.Globalize; +} + +Globalize.addCultureInfo( "ja-JP", "default", { + name: "ja-JP", + englishName: "Japanese (Japan)", + nativeName: "日本語 (日本)", + language: "ja", + numberFormat: { + NaN: "NaN (非数値)", + negativeInfinity: "-∞", + positiveInfinity: "+∞", + percent: { + pattern: ["-n%","n%"] + }, + currency: { + pattern: ["-$n","$n"], + decimals: 0, + symbol: "¥" + } + }, + calendars: { + standard: { + days: { + names: ["日曜日","月曜日","火曜日","水曜日","木曜日","金曜日","土曜日"], + namesAbbr: ["日","月","火","水","木","金","土"], + namesShort: ["日","月","火","水","木","金","土"] + }, + months: { + names: ["1月","2月","3月","4月","5月","6月","7月","8月","9月","10月","11月","12月",""], + namesAbbr: ["1","2","3","4","5","6","7","8","9","10","11","12",""] + }, + AM: ["午前","午前","午前"], + PM: ["午後","午後","午後"], + eras: [{"name":"西暦","start":null,"offset":0}], + patterns: { + d: "yyyy/MM/dd", + D: "yyyy'年'M'月'd'日'", + t: "H:mm", + T: "H:mm:ss", + f: "yyyy'年'M'月'd'日' H:mm", + F: "yyyy'年'M'月'd'日' H:mm:ss", + M: "M'月'd'日'", + Y: "yyyy'年'M'月'" + } + }, + Japanese: { + name: "Japanese", + days: { + names: ["日曜日","月曜日","火曜日","水曜日","木曜日","金曜日","土曜日"], + namesAbbr: ["日","月","火","水","木","金","土"], + namesShort: ["日","月","火","水","木","金","土"] + }, + months: { + names: ["1月","2月","3月","4月","5月","6月","7月","8月","9月","10月","11月","12月",""], + namesAbbr: ["1","2","3","4","5","6","7","8","9","10","11","12",""] + }, + AM: ["午前","午前","午前"], + PM: ["午後","午後","午後"], + eras: [{"name":"平成","start":null,"offset":1867},{"name":"昭和","start":-1812153600000,"offset":1911},{"name":"大正","start":-1357603200000,"offset":1925},{"name":"明治","start":60022080000,"offset":1988}], + twoDigitYearMax: 99, + patterns: { + d: "gg y/M/d", + D: "gg y'年'M'月'd'日'", + t: "H:mm", + T: "H:mm:ss", + f: "gg y'年'M'月'd'日' H:mm", + F: "gg y'年'M'月'd'日' H:mm:ss", + M: "M'月'd'日'", + Y: "gg y'年'M'月'" + } + } + } +}); + +}( this )); diff --git a/htdocs/js/lib/vendor/jquery-drag-drop/development-bundle/external/globalize.js b/htdocs/js/lib/vendor/jquery-drag-drop/development-bundle/external/globalize.js new file mode 100755 index 000000000..ebaca1748 --- /dev/null +++ b/htdocs/js/lib/vendor/jquery-drag-drop/development-bundle/external/globalize.js @@ -0,0 +1,1573 @@ +/*! + * Globalize + * + * http://github.com/jquery/globalize + * + * Copyright Software Freedom Conservancy, Inc. + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + */ + +(function( window, undefined ) { + +var Globalize, + // private variables + regexHex, + regexInfinity, + regexParseFloat, + regexTrim, + // private JavaScript utility functions + arrayIndexOf, + endsWith, + extend, + isArray, + isFunction, + isObject, + startsWith, + trim, + truncate, + zeroPad, + // private Globalization utility functions + appendPreOrPostMatch, + expandFormat, + formatDate, + formatNumber, + getTokenRegExp, + getEra, + getEraYear, + parseExact, + parseNegativePattern; + +// Global variable (Globalize) or CommonJS module (globalize) +Globalize = function( cultureSelector ) { + return new Globalize.prototype.init( cultureSelector ); +}; + +if ( typeof require !== "undefined" + && typeof exports !== "undefined" + && typeof module !== "undefined" ) { + // Assume CommonJS + module.exports = Globalize; +} else { + // Export as global variable + window.Globalize = Globalize; +} + +Globalize.cultures = {}; + +Globalize.prototype = { + constructor: Globalize, + init: function( cultureSelector ) { + this.cultures = Globalize.cultures; + this.cultureSelector = cultureSelector; + + return this; + } +}; +Globalize.prototype.init.prototype = Globalize.prototype; + +// 1. When defining a culture, all fields are required except the ones stated as optional. +// 2. Each culture should have a ".calendars" object with at least one calendar named "standard" +// which serves as the default calendar in use by that culture. +// 3. Each culture should have a ".calendar" object which is the current calendar being used, +// it may be dynamically changed at any time to one of the calendars in ".calendars". +Globalize.cultures[ "default" ] = { + // A unique name for the culture in the form - + name: "en", + // the name of the culture in the english language + englishName: "English", + // the name of the culture in its own language + nativeName: "English", + // whether the culture uses right-to-left text + isRTL: false, + // "language" is used for so-called "specific" cultures. + // For example, the culture "es-CL" means "Spanish, in Chili". + // It represents the Spanish-speaking culture as it is in Chili, + // which might have different formatting rules or even translations + // than Spanish in Spain. A "neutral" culture is one that is not + // specific to a region. For example, the culture "es" is the generic + // Spanish culture, which may be a more generalized version of the language + // that may or may not be what a specific culture expects. + // For a specific culture like "es-CL", the "language" field refers to the + // neutral, generic culture information for the language it is using. + // This is not always a simple matter of the string before the dash. + // For example, the "zh-Hans" culture is netural (Simplified Chinese). + // And the "zh-SG" culture is Simplified Chinese in Singapore, whose lanugage + // field is "zh-CHS", not "zh". + // This field should be used to navigate from a specific culture to it's + // more general, neutral culture. If a culture is already as general as it + // can get, the language may refer to itself. + language: "en", + // numberFormat defines general number formatting rules, like the digits in + // each grouping, the group separator, and how negative numbers are displayed. + numberFormat: { + // [negativePattern] + // Note, numberFormat.pattern has no "positivePattern" unlike percent and currency, + // but is still defined as an array for consistency with them. + // negativePattern: one of "(n)|-n|- n|n-|n -" + pattern: [ "-n" ], + // number of decimal places normally shown + decimals: 2, + // string that separates number groups, as in 1,000,000 + ",": ",", + // string that separates a number from the fractional portion, as in 1.99 + ".": ".", + // array of numbers indicating the size of each number group. + // TODO: more detailed description and example + groupSizes: [ 3 ], + // symbol used for positive numbers + "+": "+", + // symbol used for negative numbers + "-": "-", + // symbol used for NaN (Not-A-Number) + NaN: "NaN", + // symbol used for Negative Infinity + negativeInfinity: "-Infinity", + // symbol used for Positive Infinity + positiveInfinity: "Infinity", + percent: { + // [negativePattern, positivePattern] + // negativePattern: one of "-n %|-n%|-%n|%-n|%n-|n-%|n%-|-% n|n %-|% n-|% -n|n- %" + // positivePattern: one of "n %|n%|%n|% n" + pattern: [ "-n %", "n %" ], + // number of decimal places normally shown + decimals: 2, + // array of numbers indicating the size of each number group. + // TODO: more detailed description and example + groupSizes: [ 3 ], + // string that separates number groups, as in 1,000,000 + ",": ",", + // string that separates a number from the fractional portion, as in 1.99 + ".": ".", + // symbol used to represent a percentage + symbol: "%" + }, + currency: { + // [negativePattern, positivePattern] + // negativePattern: one of "($n)|-$n|$-n|$n-|(n$)|-n$|n-$|n$-|-n $|-$ n|n $-|$ n-|$ -n|n- $|($ n)|(n $)" + // positivePattern: one of "$n|n$|$ n|n $" + pattern: [ "($n)", "$n" ], + // number of decimal places normally shown + decimals: 2, + // array of numbers indicating the size of each number group. + // TODO: more detailed description and example + groupSizes: [ 3 ], + // string that separates number groups, as in 1,000,000 + ",": ",", + // string that separates a number from the fractional portion, as in 1.99 + ".": ".", + // symbol used to represent currency + symbol: "$" + } + }, + // calendars defines all the possible calendars used by this culture. + // There should be at least one defined with name "standard", and is the default + // calendar used by the culture. + // A calendar contains information about how dates are formatted, information about + // the calendar's eras, a standard set of the date formats, + // translations for day and month names, and if the calendar is not based on the Gregorian + // calendar, conversion functions to and from the Gregorian calendar. + calendars: { + standard: { + // name that identifies the type of calendar this is + name: "Gregorian_USEnglish", + // separator of parts of a date (e.g. "/" in 11/05/1955) + "/": "/", + // separator of parts of a time (e.g. ":" in 05:44 PM) + ":": ":", + // the first day of the week (0 = Sunday, 1 = Monday, etc) + firstDay: 0, + days: { + // full day names + names: [ "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday" ], + // abbreviated day names + namesAbbr: [ "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" ], + // shortest day names + namesShort: [ "Su", "Mo", "Tu", "We", "Th", "Fr", "Sa" ] + }, + months: { + // full month names (13 months for lunar calendards -- 13th month should be "" if not lunar) + names: [ "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December", "" ], + // abbreviated month names + namesAbbr: [ "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec", "" ] + }, + // AM and PM designators in one of these forms: + // The usual view, and the upper and lower case versions + // [ standard, lowercase, uppercase ] + // The culture does not use AM or PM (likely all standard date formats use 24 hour time) + // null + AM: [ "AM", "am", "AM" ], + PM: [ "PM", "pm", "PM" ], + eras: [ + // eras in reverse chronological order. + // name: the name of the era in this culture (e.g. A.D., C.E.) + // start: when the era starts in ticks (gregorian, gmt), null if it is the earliest supported era. + // offset: offset in years from gregorian calendar + { + "name": "A.D.", + "start": null, + "offset": 0 + } + ], + // when a two digit year is given, it will never be parsed as a four digit + // year greater than this year (in the appropriate era for the culture) + // Set it as a full year (e.g. 2029) or use an offset format starting from + // the current year: "+19" would correspond to 2029 if the current year 2010. + twoDigitYearMax: 2029, + // set of predefined date and time patterns used by the culture + // these represent the format someone in this culture would expect + // to see given the portions of the date that are shown. + patterns: { + // short date pattern + d: "M/d/yyyy", + // long date pattern + D: "dddd, MMMM dd, yyyy", + // short time pattern + t: "h:mm tt", + // long time pattern + T: "h:mm:ss tt", + // long date, short time pattern + f: "dddd, MMMM dd, yyyy h:mm tt", + // long date, long time pattern + F: "dddd, MMMM dd, yyyy h:mm:ss tt", + // month/day pattern + M: "MMMM dd", + // month/year pattern + Y: "yyyy MMMM", + // S is a sortable format that does not vary by culture + S: "yyyy\u0027-\u0027MM\u0027-\u0027dd\u0027T\u0027HH\u0027:\u0027mm\u0027:\u0027ss" + } + // optional fields for each calendar: + /* + monthsGenitive: + Same as months but used when the day preceeds the month. + Omit if the culture has no genitive distinction in month names. + For an explaination of genitive months, see http://blogs.msdn.com/michkap/archive/2004/12/25/332259.aspx + convert: + Allows for the support of non-gregorian based calendars. This convert object is used to + to convert a date to and from a gregorian calendar date to handle parsing and formatting. + The two functions: + fromGregorian( date ) + Given the date as a parameter, return an array with parts [ year, month, day ] + corresponding to the non-gregorian based year, month, and day for the calendar. + toGregorian( year, month, day ) + Given the non-gregorian year, month, and day, return a new Date() object + set to the corresponding date in the gregorian calendar. + */ + } + }, + // For localized strings + messages: {} +}; + +Globalize.cultures[ "default" ].calendar = Globalize.cultures[ "default" ].calendars.standard; + +Globalize.cultures[ "en" ] = Globalize.cultures[ "default" ]; + +Globalize.cultureSelector = "en"; + +// +// private variables +// + +regexHex = /^0x[a-f0-9]+$/i; +regexInfinity = /^[+-]?infinity$/i; +regexParseFloat = /^[+-]?\d*\.?\d*(e[+-]?\d+)?$/; +regexTrim = /^\s+|\s+$/g; + +// +// private JavaScript utility functions +// + +arrayIndexOf = function( array, item ) { + if ( array.indexOf ) { + return array.indexOf( item ); + } + for ( var i = 0, length = array.length; i < length; i++ ) { + if ( array[i] === item ) { + return i; + } + } + return -1; +}; + +endsWith = function( value, pattern ) { + return value.substr( value.length - pattern.length ) === pattern; +}; + +extend = function( deep ) { + 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" && !isFunction(target) ) { + target = {}; + } + + 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 && ( isObject(copy) || (copyIsArray = isArray(copy)) ) ) { + if ( copyIsArray ) { + copyIsArray = false; + clone = src && isArray(src) ? src : []; + + } else { + clone = src && isObject(src) ? src : {}; + } + + // Never move original objects, clone them + target[ name ] = extend( deep, clone, copy ); + + // Don't bring in undefined values + } else if ( copy !== undefined ) { + target[ name ] = copy; + } + } + } + } + + // Return the modified object + return target; +}; + +isArray = Array.isArray || function( obj ) { + return Object.prototype.toString.call( obj ) === "[object Array]"; +}; + +isFunction = function( obj ) { + return Object.prototype.toString.call( obj ) === "[object Function]" +} + +isObject = function( obj ) { + return Object.prototype.toString.call( obj ) === "[object Object]"; +}; + +startsWith = function( value, pattern ) { + return value.indexOf( pattern ) === 0; +}; + +trim = function( value ) { + return ( value + "" ).replace( regexTrim, "" ); +}; + +truncate = function( value ) { + return value | 0; +}; + +zeroPad = function( str, count, left ) { + var l; + for ( l = str.length; l < count; l += 1 ) { + str = ( left ? ("0" + str) : (str + "0") ); + } + return str; +}; + +// +// private Globalization utility functions +// + +appendPreOrPostMatch = function( preMatch, strings ) { + // appends pre- and post- token match strings while removing escaped characters. + // Returns a single quote count which is used to determine if the token occurs + // in a string literal. + var quoteCount = 0, + escaped = false; + for ( var i = 0, il = preMatch.length; i < il; i++ ) { + var c = preMatch.charAt( i ); + switch ( c ) { + case "\'": + if ( escaped ) { + strings.push( "\'" ); + } + else { + quoteCount++; + } + escaped = false; + break; + case "\\": + if ( escaped ) { + strings.push( "\\" ); + } + escaped = !escaped; + break; + default: + strings.push( c ); + escaped = false; + break; + } + } + return quoteCount; +}; + +expandFormat = function( cal, format ) { + // expands unspecified or single character date formats into the full pattern. + format = format || "F"; + var pattern, + patterns = cal.patterns, + len = format.length; + if ( len === 1 ) { + pattern = patterns[ format ]; + if ( !pattern ) { + throw "Invalid date format string \'" + format + "\'."; + } + format = pattern; + } + else if ( len === 2 && format.charAt(0) === "%" ) { + // %X escape format -- intended as a custom format string that is only one character, not a built-in format. + format = format.charAt( 1 ); + } + return format; +}; + +formatDate = function( value, format, culture ) { + var cal = culture.calendar, + convert = cal.convert; + + if ( !format || !format.length || format === "i" ) { + var ret; + if ( culture && culture.name.length ) { + if ( convert ) { + // non-gregorian calendar, so we cannot use built-in toLocaleString() + ret = formatDate( value, cal.patterns.F, culture ); + } + else { + var eraDate = new Date( value.getTime() ), + era = getEra( value, cal.eras ); + eraDate.setFullYear( getEraYear(value, cal, era) ); + ret = eraDate.toLocaleString(); + } + } + else { + ret = value.toString(); + } + return ret; + } + + var eras = cal.eras, + sortable = format === "s"; + format = expandFormat( cal, format ); + + // Start with an empty string + ret = []; + var hour, + zeros = [ "0", "00", "000" ], + foundDay, + checkedDay, + dayPartRegExp = /([^d]|^)(d|dd)([^d]|$)/g, + quoteCount = 0, + tokenRegExp = getTokenRegExp(), + converted; + + function padZeros( num, c ) { + var r, s = num + ""; + if ( c > 1 && s.length < c ) { + r = ( zeros[c - 2] + s); + return r.substr( r.length - c, c ); + } + else { + r = s; + } + return r; + } + + function hasDay() { + if ( foundDay || checkedDay ) { + return foundDay; + } + foundDay = dayPartRegExp.test( format ); + checkedDay = true; + return foundDay; + } + + function getPart( date, part ) { + if ( converted ) { + return converted[ part ]; + } + switch ( part ) { + case 0: return date.getFullYear(); + case 1: return date.getMonth(); + case 2: return date.getDate(); + } + } + + if ( !sortable && convert ) { + converted = convert.fromGregorian( value ); + } + + for ( ; ; ) { + // Save the current index + var index = tokenRegExp.lastIndex, + // Look for the next pattern + ar = tokenRegExp.exec( format ); + + // Append the text before the pattern (or the end of the string if not found) + var preMatch = format.slice( index, ar ? ar.index : format.length ); + quoteCount += appendPreOrPostMatch( preMatch, ret ); + + if ( !ar ) { + break; + } + + // do not replace any matches that occur inside a string literal. + if ( quoteCount % 2 ) { + ret.push( ar[0] ); + continue; + } + + var current = ar[ 0 ], + clength = current.length; + + switch ( current ) { + case "ddd": + //Day of the week, as a three-letter abbreviation + case "dddd": + // Day of the week, using the full name + var names = ( clength === 3 ) ? cal.days.namesAbbr : cal.days.names; + ret.push( names[value.getDay()] ); + break; + case "d": + // Day of month, without leading zero for single-digit days + case "dd": + // Day of month, with leading zero for single-digit days + foundDay = true; + ret.push( + padZeros( getPart(value, 2), clength ) + ); + break; + case "MMM": + // Month, as a three-letter abbreviation + case "MMMM": + // Month, using the full name + var part = getPart( value, 1 ); + ret.push( + ( cal.monthsGenitive && hasDay() ) + ? + cal.monthsGenitive[ clength === 3 ? "namesAbbr" : "names" ][ part ] + : + cal.months[ clength === 3 ? "namesAbbr" : "names" ][ part ] + ); + break; + case "M": + // Month, as digits, with no leading zero for single-digit months + case "MM": + // Month, as digits, with leading zero for single-digit months + ret.push( + padZeros( getPart(value, 1) + 1, clength ) + ); + break; + case "y": + // Year, as two digits, but with no leading zero for years less than 10 + case "yy": + // Year, as two digits, with leading zero for years less than 10 + case "yyyy": + // Year represented by four full digits + part = converted ? converted[ 0 ] : getEraYear( value, cal, getEra(value, eras), sortable ); + if ( clength < 4 ) { + part = part % 100; + } + ret.push( + padZeros( part, clength ) + ); + break; + case "h": + // Hours with no leading zero for single-digit hours, using 12-hour clock + case "hh": + // Hours with leading zero for single-digit hours, using 12-hour clock + hour = value.getHours() % 12; + if ( hour === 0 ) hour = 12; + ret.push( + padZeros( hour, clength ) + ); + break; + case "H": + // Hours with no leading zero for single-digit hours, using 24-hour clock + case "HH": + // Hours with leading zero for single-digit hours, using 24-hour clock + ret.push( + padZeros( value.getHours(), clength ) + ); + break; + case "m": + // Minutes with no leading zero for single-digit minutes + case "mm": + // Minutes with leading zero for single-digit minutes + ret.push( + padZeros( value.getMinutes(), clength ) + ); + break; + case "s": + // Seconds with no leading zero for single-digit seconds + case "ss": + // Seconds with leading zero for single-digit seconds + ret.push( + padZeros( value.getSeconds(), clength ) + ); + break; + case "t": + // One character am/pm indicator ("a" or "p") + case "tt": + // Multicharacter am/pm indicator + part = value.getHours() < 12 ? ( cal.AM ? cal.AM[0] : " " ) : ( cal.PM ? cal.PM[0] : " " ); + ret.push( clength === 1 ? part.charAt(0) : part ); + break; + case "f": + // Deciseconds + case "ff": + // Centiseconds + case "fff": + // Milliseconds + ret.push( + padZeros( value.getMilliseconds(), 3 ).substr( 0, clength ) + ); + break; + case "z": + // Time zone offset, no leading zero + case "zz": + // Time zone offset with leading zero + hour = value.getTimezoneOffset() / 60; + ret.push( + ( hour <= 0 ? "+" : "-" ) + padZeros( Math.floor(Math.abs(hour)), clength ) + ); + break; + case "zzz": + // Time zone offset with leading zero + hour = value.getTimezoneOffset() / 60; + ret.push( + ( hour <= 0 ? "+" : "-" ) + padZeros( Math.floor(Math.abs(hour)), 2 ) + // Hard coded ":" separator, rather than using cal.TimeSeparator + // Repeated here for consistency, plus ":" was already assumed in date parsing. + + ":" + padZeros( Math.abs(value.getTimezoneOffset() % 60), 2 ) + ); + break; + case "g": + case "gg": + if ( cal.eras ) { + ret.push( + cal.eras[ getEra(value, eras) ].name + ); + } + break; + case "/": + ret.push( cal["/"] ); + break; + default: + throw "Invalid date format pattern \'" + current + "\'."; + break; + } + } + return ret.join( "" ); +}; + +// formatNumber +(function() { + var expandNumber; + + expandNumber = function( number, precision, formatInfo ) { + var groupSizes = formatInfo.groupSizes, + curSize = groupSizes[ 0 ], + curGroupIndex = 1, + factor = Math.pow( 10, precision ), + rounded = Math.round( number * factor ) / factor; + + if ( !isFinite(rounded) ) { + rounded = number; + } + number = rounded; + + var numberString = number+"", + right = "", + split = numberString.split( /e/i ), + exponent = split.length > 1 ? parseInt( split[1], 10 ) : 0; + numberString = split[ 0 ]; + split = numberString.split( "." ); + numberString = split[ 0 ]; + right = split.length > 1 ? split[ 1 ] : ""; + + var l; + if ( exponent > 0 ) { + right = zeroPad( right, exponent, false ); + numberString += right.slice( 0, exponent ); + right = right.substr( exponent ); + } + else if ( exponent < 0 ) { + exponent = -exponent; + numberString = zeroPad( numberString, exponent + 1 ); + right = numberString.slice( -exponent, numberString.length ) + right; + numberString = numberString.slice( 0, -exponent ); + } + + if ( precision > 0 ) { + right = formatInfo[ "." ] + + ( (right.length > precision) ? right.slice(0, precision) : zeroPad(right, precision) ); + } + else { + right = ""; + } + + var stringIndex = numberString.length - 1, + sep = formatInfo[ "," ], + ret = ""; + + while ( stringIndex >= 0 ) { + if ( curSize === 0 || curSize > stringIndex ) { + return numberString.slice( 0, stringIndex + 1 ) + ( ret.length ? (sep + ret + right) : right ); + } + ret = numberString.slice( stringIndex - curSize + 1, stringIndex + 1 ) + ( ret.length ? (sep + ret) : "" ); + + stringIndex -= curSize; + + if ( curGroupIndex < groupSizes.length ) { + curSize = groupSizes[ curGroupIndex ]; + curGroupIndex++; + } + } + + return numberString.slice( 0, stringIndex + 1 ) + sep + ret + right; + }; + + formatNumber = function( value, format, culture ) { + if ( !isFinite(value) ) { + if ( value === Infinity ) { + return culture.numberFormat.positiveInfinity; + } + if ( value === -Infinity ) { + return culture.numberFormat.negativeInfinity; + } + return culture.numberFormat.NaN; + } + if ( !format || format === "i" ) { + return culture.name.length ? value.toLocaleString() : value.toString(); + } + format = format || "D"; + + var nf = culture.numberFormat, + number = Math.abs( value ), + precision = -1, + pattern; + if ( format.length > 1 ) precision = parseInt( format.slice(1), 10 ); + + var current = format.charAt( 0 ).toUpperCase(), + formatInfo; + + switch ( current ) { + case "D": + pattern = "n"; + number = truncate( number ); + if ( precision !== -1 ) { + number = zeroPad( "" + number, precision, true ); + } + if ( value < 0 ) number = "-" + number; + break; + case "N": + formatInfo = nf; + // fall through + case "C": + formatInfo = formatInfo || nf.currency; + // fall through + case "P": + formatInfo = formatInfo || nf.percent; + pattern = value < 0 ? formatInfo.pattern[ 0 ] : ( formatInfo.pattern[1] || "n" ); + if ( precision === -1 ) precision = formatInfo.decimals; + number = expandNumber( number * (current === "P" ? 100 : 1), precision, formatInfo ); + break; + default: + throw "Bad number format specifier: " + current; + } + + var patternParts = /n|\$|-|%/g, + ret = ""; + for ( ; ; ) { + var index = patternParts.lastIndex, + ar = patternParts.exec( pattern ); + + ret += pattern.slice( index, ar ? ar.index : pattern.length ); + + if ( !ar ) { + break; + } + + switch ( ar[0] ) { + case "n": + ret += number; + break; + case "$": + ret += nf.currency.symbol; + break; + case "-": + // don't make 0 negative + if ( /[1-9]/.test(number) ) { + ret += nf[ "-" ]; + } + break; + case "%": + ret += nf.percent.symbol; + break; + } + } + + return ret; + }; + +}()); + +getTokenRegExp = function() { + // regular expression for matching date and time tokens in format strings. + return /\/|dddd|ddd|dd|d|MMMM|MMM|MM|M|yyyy|yy|y|hh|h|HH|H|mm|m|ss|s|tt|t|fff|ff|f|zzz|zz|z|gg|g/g; +}; + +getEra = function( date, eras ) { + if ( !eras ) return 0; + var start, ticks = date.getTime(); + for ( var i = 0, l = eras.length; i < l; i++ ) { + start = eras[ i ].start; + if ( start === null || ticks >= start ) { + return i; + } + } + return 0; +}; + +getEraYear = function( date, cal, era, sortable ) { + var year = date.getFullYear(); + if ( !sortable && cal.eras ) { + // convert normal gregorian year to era-shifted gregorian + // year by subtracting the era offset + year -= cal.eras[ era ].offset; + } + return year; +}; + +// parseExact +(function() { + var expandYear, + getDayIndex, + getMonthIndex, + getParseRegExp, + outOfRange, + toUpper, + toUpperArray; + + expandYear = function( cal, year ) { + // expands 2-digit year into 4 digits. + var now = new Date(), + era = getEra( now ); + if ( year < 100 ) { + var twoDigitYearMax = cal.twoDigitYearMax; + twoDigitYearMax = typeof twoDigitYearMax === "string" ? new Date().getFullYear() % 100 + parseInt( twoDigitYearMax, 10 ) : twoDigitYearMax; + var curr = getEraYear( now, cal, era ); + year += curr - ( curr % 100 ); + if ( year > twoDigitYearMax ) { + year -= 100; + } + } + return year; + }; + + getDayIndex = function ( cal, value, abbr ) { + var ret, + days = cal.days, + upperDays = cal._upperDays; + if ( !upperDays ) { + cal._upperDays = upperDays = [ + toUpperArray( days.names ), + toUpperArray( days.namesAbbr ), + toUpperArray( days.namesShort ) + ]; + } + value = toUpper( value ); + if ( abbr ) { + ret = arrayIndexOf( upperDays[1], value ); + if ( ret === -1 ) { + ret = arrayIndexOf( upperDays[2], value ); + } + } + else { + ret = arrayIndexOf( upperDays[0], value ); + } + return ret; + }; + + getMonthIndex = function( cal, value, abbr ) { + var months = cal.months, + monthsGen = cal.monthsGenitive || cal.months, + upperMonths = cal._upperMonths, + upperMonthsGen = cal._upperMonthsGen; + if ( !upperMonths ) { + cal._upperMonths = upperMonths = [ + toUpperArray( months.names ), + toUpperArray( months.namesAbbr ) + ]; + cal._upperMonthsGen = upperMonthsGen = [ + toUpperArray( monthsGen.names ), + toUpperArray( monthsGen.namesAbbr ) + ]; + } + value = toUpper( value ); + var i = arrayIndexOf( abbr ? upperMonths[1] : upperMonths[0], value ); + if ( i < 0 ) { + i = arrayIndexOf( abbr ? upperMonthsGen[1] : upperMonthsGen[0], value ); + } + return i; + }; + + getParseRegExp = function( cal, format ) { + // converts a format string into a regular expression with groups that + // can be used to extract date fields from a date string. + // check for a cached parse regex. + var re = cal._parseRegExp; + if ( !re ) { + cal._parseRegExp = re = {}; + } + else { + var reFormat = re[ format ]; + if ( reFormat ) { + return reFormat; + } + } + + // expand single digit formats, then escape regular expression characters. + var expFormat = expandFormat( cal, format ).replace( /([\^\$\.\*\+\?\|\[\]\(\)\{\}])/g, "\\\\$1" ), + regexp = [ "^" ], + groups = [], + index = 0, + quoteCount = 0, + tokenRegExp = getTokenRegExp(), + match; + + // iterate through each date token found. + while ( (match = tokenRegExp.exec(expFormat)) !== null ) { + var preMatch = expFormat.slice( index, match.index ); + index = tokenRegExp.lastIndex; + + // don't replace any matches that occur inside a string literal. + quoteCount += appendPreOrPostMatch( preMatch, regexp ); + if ( quoteCount % 2 ) { + regexp.push( match[0] ); + continue; + } + + // add a regex group for the token. + var m = match[ 0 ], + len = m.length, + add; + switch ( m ) { + case "dddd": case "ddd": + case "MMMM": case "MMM": + case "gg": case "g": + add = "(\\D+)"; + break; + case "tt": case "t": + add = "(\\D*)"; + break; + case "yyyy": + case "fff": + case "ff": + case "f": + add = "(\\d{" + len + "})"; + break; + case "dd": case "d": + case "MM": case "M": + case "yy": case "y": + case "HH": case "H": + case "hh": case "h": + case "mm": case "m": + case "ss": case "s": + add = "(\\d\\d?)"; + break; + case "zzz": + add = "([+-]?\\d\\d?:\\d{2})"; + break; + case "zz": case "z": + add = "([+-]?\\d\\d?)"; + break; + case "/": + add = "(\\" + cal[ "/" ] + ")"; + break; + default: + throw "Invalid date format pattern \'" + m + "\'."; + break; + } + if ( add ) { + regexp.push( add ); + } + groups.push( match[0] ); + } + appendPreOrPostMatch( expFormat.slice(index), regexp ); + regexp.push( "$" ); + + // allow whitespace to differ when matching formats. + var regexpStr = regexp.join( "" ).replace( /\s+/g, "\\s+" ), + parseRegExp = { "regExp": regexpStr, "groups": groups }; + + // cache the regex for this format. + return re[ format ] = parseRegExp; + }; + + outOfRange = function( value, low, high ) { + return value < low || value > high; + }; + + toUpper = function( value ) { + // "he-IL" has non-breaking space in weekday names. + return value.split( "\u00A0" ).join( " " ).toUpperCase(); + }; + + toUpperArray = function( arr ) { + var results = []; + for ( var i = 0, l = arr.length; i < l; i++ ) { + results[ i ] = toUpper( arr[i] ); + } + return results; + }; + + parseExact = function( value, format, culture ) { + // try to parse the date string by matching against the format string + // while using the specified culture for date field names. + value = trim( value ); + var cal = culture.calendar, + // convert date formats into regular expressions with groupings. + // use the regexp to determine the input format and extract the date fields. + parseInfo = getParseRegExp( cal, format ), + match = new RegExp( parseInfo.regExp ).exec( value ); + if ( match === null ) { + return null; + } + // found a date format that matches the input. + var groups = parseInfo.groups, + era = null, year = null, month = null, date = null, weekDay = null, + hour = 0, hourOffset, min = 0, sec = 0, msec = 0, tzMinOffset = null, + pmHour = false; + // iterate the format groups to extract and set the date fields. + for ( var j = 0, jl = groups.length; j < jl; j++ ) { + var matchGroup = match[ j + 1 ]; + if ( matchGroup ) { + var current = groups[ j ], + clength = current.length, + matchInt = parseInt( matchGroup, 10 ); + switch ( current ) { + case "dd": case "d": + // Day of month. + date = matchInt; + // check that date is generally in valid range, also checking overflow below. + if ( outOfRange(date, 1, 31) ) return null; + break; + case "MMM": case "MMMM": + month = getMonthIndex( cal, matchGroup, clength === 3 ); + if ( outOfRange(month, 0, 11) ) return null; + break; + case "M": case "MM": + // Month. + month = matchInt - 1; + if ( outOfRange(month, 0, 11) ) return null; + break; + case "y": case "yy": + case "yyyy": + year = clength < 4 ? expandYear( cal, matchInt ) : matchInt; + if ( outOfRange(year, 0, 9999) ) return null; + break; + case "h": case "hh": + // Hours (12-hour clock). + hour = matchInt; + if ( hour === 12 ) hour = 0; + if ( outOfRange(hour, 0, 11) ) return null; + break; + case "H": case "HH": + // Hours (24-hour clock). + hour = matchInt; + if ( outOfRange(hour, 0, 23) ) return null; + break; + case "m": case "mm": + // Minutes. + min = matchInt; + if ( outOfRange(min, 0, 59) ) return null; + break; + case "s": case "ss": + // Seconds. + sec = matchInt; + if ( outOfRange(sec, 0, 59) ) return null; + break; + case "tt": case "t": + // AM/PM designator. + // see if it is standard, upper, or lower case PM. If not, ensure it is at least one of + // the AM tokens. If not, fail the parse for this format. + pmHour = cal.PM && ( matchGroup === cal.PM[0] || matchGroup === cal.PM[1] || matchGroup === cal.PM[2] ); + if ( + !pmHour && ( + !cal.AM || ( matchGroup !== cal.AM[0] && matchGroup !== cal.AM[1] && matchGroup !== cal.AM[2] ) + ) + ) return null; + break; + case "f": + // Deciseconds. + case "ff": + // Centiseconds. + case "fff": + // Milliseconds. + msec = matchInt * Math.pow( 10, 3 - clength ); + if ( outOfRange(msec, 0, 999) ) return null; + break; + case "ddd": + // Day of week. + case "dddd": + // Day of week. + weekDay = getDayIndex( cal, matchGroup, clength === 3 ); + if ( outOfRange(weekDay, 0, 6) ) return null; + break; + case "zzz": + // Time zone offset in +/- hours:min. + var offsets = matchGroup.split( /:/ ); + if ( offsets.length !== 2 ) return null; + hourOffset = parseInt( offsets[0], 10 ); + if ( outOfRange(hourOffset, -12, 13) ) return null; + var minOffset = parseInt( offsets[1], 10 ); + if ( outOfRange(minOffset, 0, 59) ) return null; + tzMinOffset = ( hourOffset * 60 ) + ( startsWith(matchGroup, "-") ? -minOffset : minOffset ); + break; + case "z": case "zz": + // Time zone offset in +/- hours. + hourOffset = matchInt; + if ( outOfRange(hourOffset, -12, 13) ) return null; + tzMinOffset = hourOffset * 60; + break; + case "g": case "gg": + var eraName = matchGroup; + if ( !eraName || !cal.eras ) return null; + eraName = trim( eraName.toLowerCase() ); + for ( var i = 0, l = cal.eras.length; i < l; i++ ) { + if ( eraName === cal.eras[i].name.toLowerCase() ) { + era = i; + break; + } + } + // could not find an era with that name + if ( era === null ) return null; + break; + } + } + } + var result = new Date(), defaultYear, convert = cal.convert; + defaultYear = convert ? convert.fromGregorian( result )[ 0 ] : result.getFullYear(); + if ( year === null ) { + year = defaultYear; + } + else if ( cal.eras ) { + // year must be shifted to normal gregorian year + // but not if year was not specified, its already normal gregorian + // per the main if clause above. + year += cal.eras[( era || 0 )].offset; + } + // set default day and month to 1 and January, so if unspecified, these are the defaults + // instead of the current day/month. + if ( month === null ) { + month = 0; + } + if ( date === null ) { + date = 1; + } + // now have year, month, and date, but in the culture's calendar. + // convert to gregorian if necessary + if ( convert ) { + result = convert.toGregorian( year, month, date ); + // conversion failed, must be an invalid match + if ( result === null ) return null; + } + else { + // have to set year, month and date together to avoid overflow based on current date. + result.setFullYear( year, month, date ); + // check to see if date overflowed for specified month (only checked 1-31 above). + if ( result.getDate() !== date ) return null; + // invalid day of week. + if ( weekDay !== null && result.getDay() !== weekDay ) { + return null; + } + } + // if pm designator token was found make sure the hours fit the 24-hour clock. + if ( pmHour && hour < 12 ) { + hour += 12; + } + result.setHours( hour, min, sec, msec ); + if ( tzMinOffset !== null ) { + // adjust timezone to utc before applying local offset. + var adjustedMin = result.getMinutes() - ( tzMinOffset + result.getTimezoneOffset() ); + // Safari limits hours and minutes to the range of -127 to 127. We need to use setHours + // to ensure both these fields will not exceed this range. adjustedMin will range + // somewhere between -1440 and 1500, so we only need to split this into hours. + result.setHours( result.getHours() + parseInt(adjustedMin / 60, 10), adjustedMin % 60 ); + } + return result; + }; +}()); + +parseNegativePattern = function( value, nf, negativePattern ) { + var neg = nf[ "-" ], + pos = nf[ "+" ], + ret; + switch ( negativePattern ) { + case "n -": + neg = " " + neg; + pos = " " + pos; + // fall through + case "n-": + if ( endsWith(value, neg) ) { + ret = [ "-", value.substr(0, value.length - neg.length) ]; + } + else if ( endsWith(value, pos) ) { + ret = [ "+", value.substr(0, value.length - pos.length) ]; + } + break; + case "- n": + neg += " "; + pos += " "; + // fall through + case "-n": + if ( startsWith(value, neg) ) { + ret = [ "-", value.substr(neg.length) ]; + } + else if ( startsWith(value, pos) ) { + ret = [ "+", value.substr(pos.length) ]; + } + break; + case "(n)": + if ( startsWith(value, "(") && endsWith(value, ")") ) { + ret = [ "-", value.substr(1, value.length - 2) ]; + } + break; + } + return ret || [ "", value ]; +}; + +// +// public instance functions +// + +Globalize.prototype.findClosestCulture = function( cultureSelector ) { + return Globalize.findClosestCulture.call( this, cultureSelector ); +}; + +Globalize.prototype.format = function( value, format, cultureSelector ) { + return Globalize.format.call( this, value, format, cultureSelector ); +}; + +Globalize.prototype.localize = function( key, cultureSelector ) { + return Globalize.localize.call( this, key, cultureSelector ); +}; + +Globalize.prototype.parseInt = function( value, radix, cultureSelector ) { + return Globalize.parseInt.call( this, value, radix, cultureSelector ); +}; + +Globalize.prototype.parseFloat = function( value, radix, cultureSelector ) { + return Globalize.parseFloat.call( this, value, radix, cultureSelector ); +}; + +Globalize.prototype.culture = function( cultureSelector ) { + return Globalize.culture.call( this, cultureSelector ); +}; + +// +// public singleton functions +// + +Globalize.addCultureInfo = function( cultureName, baseCultureName, info ) { + + var base = {}, + isNew = false; + + if ( typeof cultureName !== "string" ) { + // cultureName argument is optional string. If not specified, assume info is first + // and only argument. Specified info deep-extends current culture. + info = cultureName; + cultureName = this.culture().name; + base = this.cultures[ cultureName ]; + } else if ( typeof baseCultureName !== "string" ) { + // baseCultureName argument is optional string. If not specified, assume info is second + // argument. Specified info deep-extends specified culture. + // If specified culture does not exist, create by deep-extending default + info = baseCultureName; + isNew = ( this.cultures[ cultureName ] == null ); + base = this.cultures[ cultureName ] || this.cultures[ "default" ]; + } else { + // cultureName and baseCultureName specified. Assume a new culture is being created + // by deep-extending an specified base culture + isNew = true; + base = this.cultures[ baseCultureName ]; + } + + this.cultures[ cultureName ] = extend(true, {}, + base, + info + ); + // Make the standard calendar the current culture if it's a new culture + if ( isNew ) { + this.cultures[ cultureName ].calendar = this.cultures[ cultureName ].calendars.standard; + } +}; + +Globalize.findClosestCulture = function( name ) { + var match; + if ( !name ) { + return this.cultures[ this.cultureSelector ] || this.cultures[ "default" ]; + } + if ( typeof name === "string" ) { + name = name.split( "," ); + } + if ( isArray(name) ) { + var lang, + cultures = this.cultures, + list = name, + i, l = list.length, + prioritized = []; + for ( i = 0; i < l; i++ ) { + name = trim( list[i] ); + var pri, parts = name.split( ";" ); + lang = trim( parts[0] ); + if ( parts.length === 1 ) { + pri = 1; + } + else { + name = trim( parts[1] ); + if ( name.indexOf("q=") === 0 ) { + name = name.substr( 2 ); + pri = parseFloat( name ); + pri = isNaN( pri ) ? 0 : pri; + } + else { + pri = 1; + } + } + prioritized.push({ lang: lang, pri: pri }); + } + prioritized.sort(function( a, b ) { + return a.pri < b.pri ? 1 : -1; + }); + + // exact match + for ( i = 0; i < l; i++ ) { + lang = prioritized[ i ].lang; + match = cultures[ lang ]; + if ( match ) { + return match; + } + } + + // neutral language match + for ( i = 0; i < l; i++ ) { + lang = prioritized[ i ].lang; + do { + var index = lang.lastIndexOf( "-" ); + if ( index === -1 ) { + break; + } + // strip off the last part. e.g. en-US => en + lang = lang.substr( 0, index ); + match = cultures[ lang ]; + if ( match ) { + return match; + } + } + while ( 1 ); + } + + // last resort: match first culture using that language + for ( i = 0; i < l; i++ ) { + lang = prioritized[ i ].lang; + for ( var cultureKey in cultures ) { + var culture = cultures[ cultureKey ]; + if ( culture.language == lang ) { + return culture; + } + } + } + } + else if ( typeof name === "object" ) { + return name; + } + return match || null; +}; + +Globalize.format = function( value, format, cultureSelector ) { + culture = this.findClosestCulture( cultureSelector ); + if ( value instanceof Date ) { + value = formatDate( value, format, culture ); + } + else if ( typeof value === "number" ) { + value = formatNumber( value, format, culture ); + } + return value; +}; + +Globalize.localize = function( key, cultureSelector ) { + return this.findClosestCulture( cultureSelector ).messages[ key ] || + this.cultures[ "default" ].messages[ key ]; +}; + +Globalize.parseDate = function( value, formats, culture ) { + culture = this.findClosestCulture( culture ); + + var date, prop, patterns; + if ( formats ) { + if ( typeof formats === "string" ) { + formats = [ formats ]; + } + if ( formats.length ) { + for ( var i = 0, l = formats.length; i < l; i++ ) { + var format = formats[ i ]; + if ( format ) { + date = parseExact( value, format, culture ); + if ( date ) { + break; + } + } + } + } + } else { + patterns = culture.calendar.patterns; + for ( prop in patterns ) { + date = parseExact( value, patterns[prop], culture ); + if ( date ) { + break; + } + } + } + + return date || null; +}; + +Globalize.parseInt = function( value, radix, cultureSelector ) { + return truncate( Globalize.parseFloat(value, radix, cultureSelector) ); +}; + +Globalize.parseFloat = function( value, radix, cultureSelector ) { + // radix argument is optional + if ( typeof radix !== "number" ) { + cultureSelector = radix; + radix = 10; + } + + var culture = this.findClosestCulture( cultureSelector ); + var ret = NaN, + nf = culture.numberFormat; + + if ( value.indexOf(culture.numberFormat.currency.symbol) > -1 ) { + // remove currency symbol + value = value.replace( culture.numberFormat.currency.symbol, "" ); + // replace decimal seperator + value = value.replace( culture.numberFormat.currency["."], culture.numberFormat["."] ); + } + + // trim leading and trailing whitespace + value = trim( value ); + + // allow infinity or hexidecimal + if ( regexInfinity.test(value) ) { + ret = parseFloat( value ); + } + else if ( !radix && regexHex.test(value) ) { + ret = parseInt( value, 16 ); + } + else { + + // determine sign and number + var signInfo = parseNegativePattern( value, nf, nf.pattern[0] ), + sign = signInfo[ 0 ], + num = signInfo[ 1 ]; + + // #44 - try parsing as "(n)" + if ( sign === "" && nf.pattern[0] !== "(n)" ) { + signInfo = parseNegativePattern( value, nf, "(n)" ); + sign = signInfo[ 0 ]; + num = signInfo[ 1 ]; + } + + // try parsing as "-n" + if ( sign === "" && nf.pattern[0] !== "-n" ) { + signInfo = parseNegativePattern( value, nf, "-n" ); + sign = signInfo[ 0 ]; + num = signInfo[ 1 ]; + } + + sign = sign || "+"; + + // determine exponent and number + var exponent, + intAndFraction, + exponentPos = num.indexOf( "e" ); + if ( exponentPos < 0 ) exponentPos = num.indexOf( "E" ); + if ( exponentPos < 0 ) { + intAndFraction = num; + exponent = null; + } + else { + intAndFraction = num.substr( 0, exponentPos ); + exponent = num.substr( exponentPos + 1 ); + } + // determine decimal position + var integer, + fraction, + decSep = nf[ "." ], + decimalPos = intAndFraction.indexOf( decSep ); + if ( decimalPos < 0 ) { + integer = intAndFraction; + fraction = null; + } + else { + integer = intAndFraction.substr( 0, decimalPos ); + fraction = intAndFraction.substr( decimalPos + decSep.length ); + } + // handle groups (e.g. 1,000,000) + var groupSep = nf[ "," ]; + integer = integer.split( groupSep ).join( "" ); + var altGroupSep = groupSep.replace( /\u00A0/g, " " ); + if ( groupSep !== altGroupSep ) { + integer = integer.split( altGroupSep ).join( "" ); + } + // build a natively parsable number string + var p = sign + integer; + if ( fraction !== null ) { + p += "." + fraction; + } + if ( exponent !== null ) { + // exponent itself may have a number patternd + var expSignInfo = parseNegativePattern( exponent, nf, "-n" ); + p += "e" + ( expSignInfo[0] || "+" ) + expSignInfo[ 1 ]; + } + if ( regexParseFloat.test(p) ) { + ret = parseFloat( p ); + } + } + return ret; +}; + +Globalize.culture = function( cultureSelector ) { + // setter + if ( typeof cultureSelector !== "undefined" ) { + this.cultureSelector = cultureSelector; + } + // getter + return this.findClosestCulture( cultureSelector ) || this.culture[ "default" ]; +}; + +}( this )); diff --git a/htdocs/js/lib/vendor/jquery-drag-drop/development-bundle/external/jquery.bgiframe-2.1.2.js b/htdocs/js/lib/vendor/jquery-drag-drop/development-bundle/external/jquery.bgiframe-2.1.2.js new file mode 100755 index 000000000..5cd38bb1d --- /dev/null +++ b/htdocs/js/lib/vendor/jquery-drag-drop/development-bundle/external/jquery.bgiframe-2.1.2.js @@ -0,0 +1,39 @@ +/*! Copyright (c) 2010 Brandon Aaron (http://brandonaaron.net) + * Licensed under the MIT License (LICENSE.txt). + * + * Version 2.1.2 + */ + +(function($){ + +$.fn.bgiframe = ($.browser.msie && /msie 6\.0/i.test(navigator.userAgent) ? function(s) { + s = $.extend({ + top : 'auto', // auto == .currentStyle.borderTopWidth + left : 'auto', // auto == .currentStyle.borderLeftWidth + width : 'auto', // auto == offsetWidth + height : 'auto', // auto == offsetHeight + opacity : true, + src : 'javascript:false;' + }, s); + var html = ' \ +
      \ + Powered by JSLitmus \ +
      '; + + /** + * The public API for creating and running tests + */ + window.JSLitmus = { + /** The list of all tests that have been registered with JSLitmus.test */ + _tests: [], + /** The queue of tests that need to be run */ + _queue: [], + + /** + * The parsed query parameters the current page URL. This is provided as a + * convenience for test functions - it's not used by JSLitmus proper + */ + params: {}, + + /** + * Initialize + */ + _init: function() { + // Parse query params into JSLitmus.params[] hash + var match = (location + '').match(/([^?#]*)(#.*)?$/); + if (match) { + var pairs = match[1].split('&'); + for (var i = 0; i < pairs.length; i++) { + var pair = pairs[i].split('='); + if (pair.length > 1) { + var key = pair.shift(); + var value = pair.length > 1 ? pair.join('=') : pair[0]; + this.params[key] = value; + } + } + } + + // Write out the stylesheet. We have to do this here because IE + // doesn't honor sheets written after the document has loaded. + document.write(STYLESHEET); + + // Setup the rest of the UI once the document is loaded + if (window.addEventListener) { + window.addEventListener('load', this._setup, false); + } else if (document.addEventListener) { + document.addEventListener('load', this._setup, false); + } else if (window.attachEvent) { + window.attachEvent('onload', this._setup); + } + + return this; + }, + + /** + * Set up the UI + */ + _setup: function() { + var el = jsl.$('jslitmus_container'); + if (!el) document.body.appendChild(el = document.createElement('div')); + + el.innerHTML = MARKUP; + + // Render the UI for all our tests + for (var i=0; i < JSLitmus._tests.length; i++) + JSLitmus.renderTest(JSLitmus._tests[i]); + }, + + /** + * (Re)render all the test results + */ + renderAll: function() { + for (var i = 0; i < JSLitmus._tests.length; i++) + JSLitmus.renderTest(JSLitmus._tests[i]); + JSLitmus.renderChart(); + }, + + /** + * (Re)render the chart graphics + */ + renderChart: function() { + var url = JSLitmus.chartUrl(); + jsl.$('chart_link').href = url; + jsl.$('chart_image').src = url; + jsl.$('chart').style.display = ''; + + // Update the tiny URL + jsl.$('tiny_url').src = 'http://tinyurl.com/api-create.php?url='+escape(url); + }, + + /** + * (Re)render the results for a specific test + */ + renderTest: function(test) { + // Make a new row if needed + if (!test._row) { + var trow = jsl.$('test_row_template'); + if (!trow) return; + + test._row = trow.cloneNode(true); + test._row.style.display = ''; + test._row.id = ''; + test._row.onclick = function() {JSLitmus._queueTest(test);}; + test._row.title = 'Run ' + test.name + ' test'; + trow.parentNode.appendChild(test._row); + test._row.cells[0].innerHTML = test.name; + } + + var cell = test._row.cells[1]; + var cns = [test.loopArg ? 'test_looping' : 'test_nonlooping']; + + if (test.error) { + cns.push('test_error'); + cell.innerHTML = + '
      ' + test.error + '
      ' + + '
      • ' + + jsl.join(test.error, ': ', '
      • ') + + '
      '; + } else { + if (test.running) { + cns.push('test_running'); + cell.innerHTML = 'running'; + } else if (jsl.indexOf(JSLitmus._queue, test) >= 0) { + cns.push('test_pending'); + cell.innerHTML = 'pending'; + } else if (test.count) { + cns.push('test_done'); + var hz = test.getHz(jsl.$('test_normalize').checked); + cell.innerHTML = hz != Infinity ? hz : '∞'; + cell.title = 'Looped ' + test.count + ' times in ' + test.time + ' seconds'; + } else { + cell.innerHTML = 'ready'; + } + } + cell.className = cns.join(' '); + }, + + /** + * Create a new test + */ + test: function(name, f) { + // Create the Test object + var test = new Test(name, f); + JSLitmus._tests.push(test); + + // Re-render if the test state changes + test.onChange = JSLitmus.renderTest; + + // Run the next test if this one finished + test.onStop = function(test) { + if (JSLitmus.onTestFinish) JSLitmus.onTestFinish(test); + JSLitmus.currentTest = null; + JSLitmus._nextTest(); + }; + + // Render the new test + this.renderTest(test); + }, + + /** + * Add all tests to the run queue + */ + runAll: function(e) { + e = e || window.event; + var reverse = e && e.shiftKey, len = JSLitmus._tests.length; + for (var i = 0; i < len; i++) { + JSLitmus._queueTest(JSLitmus._tests[!reverse ? i : (len - i - 1)]); + } + }, + + /** + * Remove all tests from the run queue. The current test has to finish on + * it's own though + */ + stop: function() { + while (JSLitmus._queue.length) { + var test = JSLitmus._queue.shift(); + JSLitmus.renderTest(test); + } + }, + + /** + * Run the next test in the run queue + */ + _nextTest: function() { + if (!JSLitmus.currentTest) { + var test = JSLitmus._queue.shift(); + if (test) { + jsl.$('stop_button').disabled = false; + JSLitmus.currentTest = test; + test.run(); + JSLitmus.renderTest(test); + if (JSLitmus.onTestStart) JSLitmus.onTestStart(test); + } else { + jsl.$('stop_button').disabled = true; + JSLitmus.renderChart(); + } + } + }, + + /** + * Add a test to the run queue + */ + _queueTest: function(test) { + if (jsl.indexOf(JSLitmus._queue, test) >= 0) return; + JSLitmus._queue.push(test); + JSLitmus.renderTest(test); + JSLitmus._nextTest(); + }, + + /** + * Generate a Google Chart URL that shows the data for all tests + */ + chartUrl: function() { + var n = JSLitmus._tests.length, markers = [], data = []; + var d, min = 0, max = -1e10; + var normalize = jsl.$('test_normalize').checked; + + // Gather test data + for (var i=0; i < JSLitmus._tests.length; i++) { + var test = JSLitmus._tests[i]; + if (test.count) { + var hz = test.getHz(normalize); + var v = hz != Infinity ? hz : 0; + data.push(v); + markers.push('t' + jsl.escape(test.name + '(' + jsl.toLabel(hz)+ ')') + ',000000,0,' + + markers.length + ',10'); + max = Math.max(v, max); + } + } + if (markers.length <= 0) return null; + + // Build chart title + var title = document.getElementsByTagName('title'); + title = (title && title.length) ? title[0].innerHTML : null; + var chart_title = []; + if (title) chart_title.push(title); + chart_title.push('Ops/sec (' + platform + ')'); + + // Build labels + var labels = [jsl.toLabel(min), jsl.toLabel(max)]; + + var w = 250, bw = 15; + var bs = 5; + var h = markers.length*(bw + bs) + 30 + chart_title.length*20; + + var params = { + chtt: escape(chart_title.join('|')), + chts: '000000,10', + cht: 'bhg', // chart type + chd: 't:' + data.join(','), // data set + chds: min + ',' + max, // max/min of data + chxt: 'x', // label axes + chxl: '0:|' + labels.join('|'), // labels + chsp: '0,1', + chm: markers.join('|'), // test names + chbh: [bw, 0, bs].join(','), // bar widths + // chf: 'bg,lg,0,eeeeee,0,eeeeee,.5,ffffff,1', // gradient + chs: w + 'x' + h + }; + return 'http://chart.apis.google.com/chart?' + jsl.join(params, '=', '&'); + } + }; + + JSLitmus._init(); +})(); \ No newline at end of file diff --git a/htdocs/js/lib/webwork/components/backbone/test/vendor/json2.js b/htdocs/js/lib/webwork/components/backbone/test/vendor/json2.js new file mode 100644 index 000000000..236025992 --- /dev/null +++ b/htdocs/js/lib/webwork/components/backbone/test/vendor/json2.js @@ -0,0 +1,481 @@ +/* + http://www.JSON.org/json2.js + 2009-09-29 + + Public Domain. + + NO WARRANTY EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK. + + See http://www.JSON.org/js.html + + + This code should be minified before deployment. + See http://javascript.crockford.com/jsmin.html + + USE YOUR OWN COPY. IT IS EXTREMELY UNWISE TO LOAD CODE FROM SERVERS YOU DO + NOT CONTROL. + + + This file creates a global JSON object containing two methods: stringify + and parse. + + JSON.stringify(value, replacer, space) + value any JavaScript value, usually an object or array. + + replacer an optional parameter that determines how object + values are stringified for objects. It can be a + function or an array of strings. + + space an optional parameter that specifies the indentation + of nested structures. If it is omitted, the text will + be packed without extra whitespace. If it is a number, + it will specify the number of spaces to indent at each + level. If it is a string (such as '\t' or ' '), + it contains the characters used to indent at each level. + + This method produces a JSON text from a JavaScript value. + + When an object value is found, if the object contains a toJSON + method, its toJSON method will be called and the result will be + stringified. A toJSON method does not serialize: it returns the + value represented by the name/value pair that should be serialized, + or undefined if nothing should be serialized. The toJSON method + will be passed the key associated with the value, and this will be + bound to the value + + For example, this would serialize Dates as ISO strings. + + Date.prototype.toJSON = function (key) { + function f(n) { + // Format integers to have at least two digits. + return n < 10 ? '0' + n : n; + } + + return this.getUTCFullYear() + '-' + + f(this.getUTCMonth() + 1) + '-' + + f(this.getUTCDate()) + 'T' + + f(this.getUTCHours()) + ':' + + f(this.getUTCMinutes()) + ':' + + f(this.getUTCSeconds()) + 'Z'; + }; + + You can provide an optional replacer method. It will be passed the + key and value of each member, with this bound to the containing + object. The value that is returned from your method will be + serialized. If your method returns undefined, then the member will + be excluded from the serialization. + + If the replacer parameter is an array of strings, then it will be + used to select the members to be serialized. It filters the results + such that only members with keys listed in the replacer array are + stringified. + + Values that do not have JSON representations, such as undefined or + functions, will not be serialized. Such values in objects will be + dropped; in arrays they will be replaced with null. You can use + a replacer function to replace those with JSON values. + JSON.stringify(undefined) returns undefined. + + The optional space parameter produces a stringification of the + value that is filled with line breaks and indentation to make it + easier to read. + + If the space parameter is a non-empty string, then that string will + be used for indentation. If the space parameter is a number, then + the indentation will be that many spaces. + + Example: + + text = JSON.stringify(['e', {pluribus: 'unum'}]); + // text is '["e",{"pluribus":"unum"}]' + + + text = JSON.stringify(['e', {pluribus: 'unum'}], null, '\t'); + // text is '[\n\t"e",\n\t{\n\t\t"pluribus": "unum"\n\t}\n]' + + text = JSON.stringify([new Date()], function (key, value) { + return this[key] instanceof Date ? + 'Date(' + this[key] + ')' : value; + }); + // text is '["Date(---current time---)"]' + + + JSON.parse(text, reviver) + This method parses a JSON text to produce an object or array. + It can throw a SyntaxError exception. + + The optional reviver parameter is a function that can filter and + transform the results. It receives each of the keys and values, + and its return value is used instead of the original value. + If it returns what it received, then the structure is not modified. + If it returns undefined then the member is deleted. + + Example: + + // Parse the text. Values that look like ISO date strings will + // be converted to Date objects. + + myData = JSON.parse(text, function (key, value) { + var a; + if (typeof value === 'string') { + a = +/^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2}(?:\.\d*)?)Z$/.exec(value); + if (a) { + return new Date(Date.UTC(+a[1], +a[2] - 1, +a[3], +a[4], + +a[5], +a[6])); + } + } + return value; + }); + + myData = JSON.parse('["Date(09/09/2001)"]', function (key, value) { + var d; + if (typeof value === 'string' && + value.slice(0, 5) === 'Date(' && + value.slice(-1) === ')') { + d = new Date(value.slice(5, -1)); + if (d) { + return d; + } + } + return value; + }); + + + This is a reference implementation. You are free to copy, modify, or + redistribute. +*/ + +/*jslint evil: true, strict: false */ + +/*members "", "\b", "\t", "\n", "\f", "\r", "\"", JSON, "\\", apply, + call, charCodeAt, getUTCDate, getUTCFullYear, getUTCHours, + getUTCMinutes, getUTCMonth, getUTCSeconds, hasOwnProperty, join, + lastIndex, length, parse, prototype, push, replace, slice, stringify, + test, toJSON, toString, valueOf +*/ + + +// Create a JSON object only if one does not already exist. We create the +// methods in a closure to avoid creating global variables. + +if (!this.JSON) { + this.JSON = {}; +} + +(function () { + + function f(n) { + // Format integers to have at least two digits. + return n < 10 ? '0' + n : n; + } + + if (typeof Date.prototype.toJSON !== 'function') { + + Date.prototype.toJSON = function (key) { + + return isFinite(this.valueOf()) ? + this.getUTCFullYear() + '-' + + f(this.getUTCMonth() + 1) + '-' + + f(this.getUTCDate()) + 'T' + + f(this.getUTCHours()) + ':' + + f(this.getUTCMinutes()) + ':' + + f(this.getUTCSeconds()) + 'Z' : null; + }; + + String.prototype.toJSON = + Number.prototype.toJSON = + Boolean.prototype.toJSON = function (key) { + return this.valueOf(); + }; + } + + var cx = /[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g, + escapable = /[\\\"\x00-\x1f\x7f-\x9f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g, + gap, + indent, + meta = { // table of character substitutions + '\b': '\\b', + '\t': '\\t', + '\n': '\\n', + '\f': '\\f', + '\r': '\\r', + '"' : '\\"', + '\\': '\\\\' + }, + rep; + + + function quote(string) { + +// If the string contains no control characters, no quote characters, and no +// backslash characters, then we can safely slap some quotes around it. +// Otherwise we must also replace the offending characters with safe escape +// sequences. + + escapable.lastIndex = 0; + return escapable.test(string) ? + '"' + string.replace(escapable, function (a) { + var c = meta[a]; + return typeof c === 'string' ? c : + '\\u' + ('0000' + a.charCodeAt(0).toString(16)).slice(-4); + }) + '"' : + '"' + string + '"'; + } + + + function str(key, holder) { + +// Produce a string from holder[key]. + + var i, // The loop counter. + k, // The member key. + v, // The member value. + length, + mind = gap, + partial, + value = holder[key]; + +// If the value has a toJSON method, call it to obtain a replacement value. + + if (value && typeof value === 'object' && + typeof value.toJSON === 'function') { + value = value.toJSON(key); + } + +// If we were called with a replacer function, then call the replacer to +// obtain a replacement value. + + if (typeof rep === 'function') { + value = rep.call(holder, key, value); + } + +// What happens next depends on the value's type. + + switch (typeof value) { + case 'string': + return quote(value); + + case 'number': + +// JSON numbers must be finite. Encode non-finite numbers as null. + + return isFinite(value) ? String(value) : 'null'; + + case 'boolean': + case 'null': + +// If the value is a boolean or null, convert it to a string. Note: +// typeof null does not produce 'null'. The case is included here in +// the remote chance that this gets fixed someday. + + return String(value); + +// If the type is 'object', we might be dealing with an object or an array or +// null. + + case 'object': + +// Due to a specification blunder in ECMAScript, typeof null is 'object', +// so watch out for that case. + + if (!value) { + return 'null'; + } + +// Make an array to hold the partial results of stringifying this object value. + + gap += indent; + partial = []; + +// Is the value an array? + + if (Object.prototype.toString.apply(value) === '[object Array]') { + +// The value is an array. Stringify every element. Use null as a placeholder +// for non-JSON values. + + length = value.length; + for (i = 0; i < length; i += 1) { + partial[i] = str(i, value) || 'null'; + } + +// Join all of the elements together, separated with commas, and wrap them in +// brackets. + + v = partial.length === 0 ? '[]' : + gap ? '[\n' + gap + + partial.join(',\n' + gap) + '\n' + + mind + ']' : + '[' + partial.join(',') + ']'; + gap = mind; + return v; + } + +// If the replacer is an array, use it to select the members to be stringified. + + if (rep && typeof rep === 'object') { + length = rep.length; + for (i = 0; i < length; i += 1) { + k = rep[i]; + if (typeof k === 'string') { + v = str(k, value); + if (v) { + partial.push(quote(k) + (gap ? ': ' : ':') + v); + } + } + } + } else { + +// Otherwise, iterate through all of the keys in the object. + + for (k in value) { + if (Object.hasOwnProperty.call(value, k)) { + v = str(k, value); + if (v) { + partial.push(quote(k) + (gap ? ': ' : ':') + v); + } + } + } + } + +// Join all of the member texts together, separated with commas, +// and wrap them in braces. + + v = partial.length === 0 ? '{}' : + gap ? '{\n' + gap + partial.join(',\n' + gap) + '\n' + + mind + '}' : '{' + partial.join(',') + '}'; + gap = mind; + return v; + } + } + +// If the JSON object does not yet have a stringify method, give it one. + + if (typeof JSON.stringify !== 'function') { + JSON.stringify = function (value, replacer, space) { + +// The stringify method takes a value and an optional replacer, and an optional +// space parameter, and returns a JSON text. The replacer can be a function +// that can replace values, or an array of strings that will select the keys. +// A default replacer method can be provided. Use of the space parameter can +// produce text that is more easily readable. + + var i; + gap = ''; + indent = ''; + +// If the space parameter is a number, make an indent string containing that +// many spaces. + + if (typeof space === 'number') { + for (i = 0; i < space; i += 1) { + indent += ' '; + } + +// If the space parameter is a string, it will be used as the indent string. + + } else if (typeof space === 'string') { + indent = space; + } + +// If there is a replacer, it must be a function or an array. +// Otherwise, throw an error. + + rep = replacer; + if (replacer && typeof replacer !== 'function' && + (typeof replacer !== 'object' || + typeof replacer.length !== 'number')) { + throw new Error('JSON.stringify'); + } + +// Make a fake root object containing our value under the key of ''. +// Return the result of stringifying the value. + + return str('', {'': value}); + }; + } + + +// If the JSON object does not yet have a parse method, give it one. + + if (typeof JSON.parse !== 'function') { + JSON.parse = function (text, reviver) { + +// The parse method takes a text and an optional reviver function, and returns +// a JavaScript value if the text is a valid JSON text. + + var j; + + function walk(holder, key) { + +// The walk method is used to recursively walk the resulting structure so +// that modifications can be made. + + var k, v, value = holder[key]; + if (value && typeof value === 'object') { + for (k in value) { + if (Object.hasOwnProperty.call(value, k)) { + v = walk(value, k); + if (v !== undefined) { + value[k] = v; + } else { + delete value[k]; + } + } + } + } + return reviver.call(holder, key, value); + } + + +// Parsing happens in four stages. In the first stage, we replace certain +// Unicode characters with escape sequences. JavaScript handles many characters +// incorrectly, either silently deleting them, or treating them as line endings. + + cx.lastIndex = 0; + if (cx.test(text)) { + text = text.replace(cx, function (a) { + return '\\u' + + ('0000' + a.charCodeAt(0).toString(16)).slice(-4); + }); + } + +// In the second stage, we run the text against regular expressions that look +// for non-JSON patterns. We are especially concerned with '()' and 'new' +// because they can cause invocation, and '=' because it can cause mutation. +// But just to be safe, we want to reject all unexpected forms. + +// We split the second stage into 4 regexp operations in order to work around +// crippling inefficiencies in IE's and Safari's regexp engines. First we +// replace the JSON backslash pairs with '@' (a non-JSON character). Second, we +// replace all simple value tokens with ']' characters. Third, we delete all +// open brackets that follow a colon or comma or that begin the text. Finally, +// we look to see that the remaining characters are only whitespace or ']' or +// ',' or ':' or '{' or '}'. If that is so, then the text is safe for eval. + + if (/^[\],:{}\s]*$/. +test(text.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g, '@'). +replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g, ']'). +replace(/(?:^|:|,)(?:\s*\[)+/g, ''))) { + +// In the third stage we use the eval function to compile the text into a +// JavaScript structure. The '{' operator is subject to a syntactic ambiguity +// in JavaScript: it can begin a block or an object literal. We wrap the text +// in parens to eliminate the ambiguity. + + j = eval('(' + text + ')'); + +// In the optional fourth stage, we recursively walk the new structure, passing +// each name/value pair to a reviver function for possible transformation. + + return typeof reviver === 'function' ? + walk({'': j}, '') : j; + } + +// If the text is not JSON parseable, then a SyntaxError is thrown. + + throw new SyntaxError('JSON.parse'); + }; + } +}()); \ No newline at end of file diff --git a/htdocs/js/lib/webwork/components/backbone/test/vendor/qunit.css b/htdocs/js/lib/webwork/components/backbone/test/vendor/qunit.css new file mode 100755 index 000000000..19844c5fe --- /dev/null +++ b/htdocs/js/lib/webwork/components/backbone/test/vendor/qunit.css @@ -0,0 +1,226 @@ +/** + * QUnit 1.1.0 - A JavaScript Unit Testing Framework + * + * http://docs.jquery.com/QUnit + * + * Copyright (c) 2011 John Resig, Jörn Zaefferer + * Dual licensed under the MIT (MIT-LICENSE.txt) + * or GPL (GPL-LICENSE.txt) licenses. + */ + +/** Font Family and Sizes */ + +#qunit-tests, #qunit-header, #qunit-banner, #qunit-testrunner-toolbar, #qunit-userAgent, #qunit-testresult { + font-family: "Helvetica Neue Light", "HelveticaNeue-Light", "Helvetica Neue", Calibri, Helvetica, Arial, sans-serif; +} + +#qunit-testrunner-toolbar, #qunit-userAgent, #qunit-testresult, #qunit-tests li { font-size: small; } +#qunit-tests { font-size: smaller; } + + +/** Resets */ + +#qunit-tests, #qunit-tests ol, #qunit-header, #qunit-banner, #qunit-userAgent, #qunit-testresult { + margin: 0; + padding: 0; +} + + +/** Header */ + +#qunit-header { + padding: 0.5em 0 0.5em 1em; + + color: #8699a4; + background-color: #0d3349; + + font-size: 1.5em; + line-height: 1em; + font-weight: normal; + + border-radius: 15px 15px 0 0; + -moz-border-radius: 15px 15px 0 0; + -webkit-border-top-right-radius: 15px; + -webkit-border-top-left-radius: 15px; +} + +#qunit-header a { + text-decoration: none; + color: #c2ccd1; +} + +#qunit-header a:hover, +#qunit-header a:focus { + color: #fff; +} + +#qunit-banner { + height: 5px; +} + +#qunit-testrunner-toolbar { + padding: 0.5em 0 0.5em 2em; + color: #5E740B; + background-color: #eee; +} + +#qunit-userAgent { + padding: 0.5em 0 0.5em 2.5em; + background-color: #2b81af; + color: #fff; + text-shadow: rgba(0, 0, 0, 0.5) 2px 2px 1px; +} + + +/** Tests: Pass/Fail */ + +#qunit-tests { + list-style-position: inside; +} + +#qunit-tests li { + padding: 0.4em 0.5em 0.4em 2.5em; + border-bottom: 1px solid #fff; + list-style-position: inside; +} + +#qunit-tests.hidepass li.pass, #qunit-tests.hidepass li.running { + display: none; +} + +#qunit-tests li strong { + cursor: pointer; +} + +#qunit-tests li a { + padding: 0.5em; + color: #c2ccd1; + text-decoration: none; +} +#qunit-tests li a:hover, +#qunit-tests li a:focus { + color: #000; +} + +#qunit-tests ol { + margin-top: 0.5em; + padding: 0.5em; + + background-color: #fff; + + border-radius: 15px; + -moz-border-radius: 15px; + -webkit-border-radius: 15px; + + box-shadow: inset 0px 2px 13px #999; + -moz-box-shadow: inset 0px 2px 13px #999; + -webkit-box-shadow: inset 0px 2px 13px #999; +} + +#qunit-tests table { + border-collapse: collapse; + margin-top: .2em; +} + +#qunit-tests th { + text-align: right; + vertical-align: top; + padding: 0 .5em 0 0; +} + +#qunit-tests td { + vertical-align: top; +} + +#qunit-tests pre { + margin: 0; + white-space: pre-wrap; + word-wrap: break-word; +} + +#qunit-tests del { + background-color: #e0f2be; + color: #374e0c; + text-decoration: none; +} + +#qunit-tests ins { + background-color: #ffcaca; + color: #500; + text-decoration: none; +} + +/*** Test Counts */ + +#qunit-tests b.counts { color: black; } +#qunit-tests b.passed { color: #5E740B; } +#qunit-tests b.failed { color: #710909; } + +#qunit-tests li li { + margin: 0.5em; + padding: 0.4em 0.5em 0.4em 0.5em; + background-color: #fff; + border-bottom: none; + list-style-position: inside; +} + +/*** Passing Styles */ + +#qunit-tests li li.pass { + color: #5E740B; + background-color: #fff; + border-left: 26px solid #C6E746; +} + +#qunit-tests .pass { color: #528CE0; background-color: #D2E0E6; } +#qunit-tests .pass .test-name { color: #366097; } + +#qunit-tests .pass .test-actual, +#qunit-tests .pass .test-expected { color: #999999; } + +#qunit-banner.qunit-pass { background-color: #C6E746; } + +/*** Failing Styles */ + +#qunit-tests li li.fail { + color: #710909; + background-color: #fff; + border-left: 26px solid #EE5757; + white-space: pre; +} + +#qunit-tests > li:last-child { + border-radius: 0 0 15px 15px; + -moz-border-radius: 0 0 15px 15px; + -webkit-border-bottom-right-radius: 15px; + -webkit-border-bottom-left-radius: 15px; +} + +#qunit-tests .fail { color: #000000; background-color: #EE5757; } +#qunit-tests .fail .test-name, +#qunit-tests .fail .module-name { color: #000000; } + +#qunit-tests .fail .test-actual { color: #EE5757; } +#qunit-tests .fail .test-expected { color: green; } + +#qunit-banner.qunit-fail { background-color: #EE5757; } + + +/** Result */ + +#qunit-testresult { + padding: 0.5em 0.5em 0.5em 2.5em; + + color: #2b81af; + background-color: #D2E0E6; + + border-bottom: 1px solid white; +} + +/** Fixture */ + +#qunit-fixture { + position: absolute; + top: -10000px; + left: -10000px; +} diff --git a/htdocs/js/lib/webwork/components/backbone/test/vendor/qunit.js b/htdocs/js/lib/webwork/components/backbone/test/vendor/qunit.js new file mode 100755 index 000000000..89c22b360 --- /dev/null +++ b/htdocs/js/lib/webwork/components/backbone/test/vendor/qunit.js @@ -0,0 +1,1585 @@ +/** + * QUnit 1.1.0 - A JavaScript Unit Testing Framework + * + * http://docs.jquery.com/QUnit + * + * Copyright (c) 2011 John Resig, Jörn Zaefferer + * Dual licensed under the MIT (MIT-LICENSE.txt) + * or GPL (GPL-LICENSE.txt) licenses. + */ + +(function(window) { + +var defined = { + setTimeout: typeof window.setTimeout !== "undefined", + sessionStorage: (function() { + try { + return !!sessionStorage.getItem; + } catch(e) { + return false; + } + })() +}; + +var testId = 0, + toString = Object.prototype.toString, + hasOwn = Object.prototype.hasOwnProperty; + +var Test = function(name, testName, expected, testEnvironmentArg, async, callback) { + this.name = name; + this.testName = testName; + this.expected = expected; + this.testEnvironmentArg = testEnvironmentArg; + this.async = async; + this.callback = callback; + this.assertions = []; +}; +Test.prototype = { + init: function() { + var tests = id("qunit-tests"); + if (tests) { + var b = document.createElement("strong"); + b.innerHTML = "Running " + this.name; + var li = document.createElement("li"); + li.appendChild( b ); + li.className = "running"; + li.id = this.id = "test-output" + testId++; + tests.appendChild( li ); + } + }, + setup: function() { + if (this.module != config.previousModule) { + if ( config.previousModule ) { + runLoggingCallbacks('moduleDone', QUnit, { + name: config.previousModule, + failed: config.moduleStats.bad, + passed: config.moduleStats.all - config.moduleStats.bad, + total: config.moduleStats.all + } ); + } + config.previousModule = this.module; + config.moduleStats = { all: 0, bad: 0 }; + runLoggingCallbacks( 'moduleStart', QUnit, { + name: this.module + } ); + } + + config.current = this; + this.testEnvironment = extend({ + setup: function() {}, + teardown: function() {} + }, this.moduleTestEnvironment); + if (this.testEnvironmentArg) { + extend(this.testEnvironment, this.testEnvironmentArg); + } + + runLoggingCallbacks( 'testStart', QUnit, { + name: this.testName, + module: this.module + }); + + // allow utility functions to access the current test environment + // TODO why?? + QUnit.current_testEnvironment = this.testEnvironment; + + try { + if ( !config.pollution ) { + saveGlobal(); + } + + this.testEnvironment.setup.call(this.testEnvironment); + } catch(e) { + QUnit.ok( false, "Setup failed on " + this.testName + ": " + e.message ); + } + }, + run: function() { + config.current = this; + if ( this.async ) { + QUnit.stop(); + } + + if ( config.notrycatch ) { + this.callback.call(this.testEnvironment); + return; + } + try { + this.callback.call(this.testEnvironment); + } catch(e) { + fail("Test " + this.testName + " died, exception and test follows", e, this.callback); + QUnit.ok( false, "Died on test #" + (this.assertions.length + 1) + ": " + e.message + " - " + QUnit.jsDump.parse(e) ); + // else next test will carry the responsibility + saveGlobal(); + + // Restart the tests if they're blocking + if ( config.blocking ) { + start(); + } + } + }, + teardown: function() { + config.current = this; + try { + this.testEnvironment.teardown.call(this.testEnvironment); + checkPollution(); + } catch(e) { + QUnit.ok( false, "Teardown failed on " + this.testName + ": " + e.message ); + } + }, + finish: function() { + config.current = this; + if ( this.expected != null && this.expected != this.assertions.length ) { + QUnit.ok( false, "Expected " + this.expected + " assertions, but " + this.assertions.length + " were run" ); + } + + var good = 0, bad = 0, + tests = id("qunit-tests"); + + config.stats.all += this.assertions.length; + config.moduleStats.all += this.assertions.length; + + if ( tests ) { + var ol = document.createElement("ol"); + + for ( var i = 0; i < this.assertions.length; i++ ) { + var assertion = this.assertions[i]; + + var li = document.createElement("li"); + li.className = assertion.result ? "pass" : "fail"; + li.innerHTML = assertion.message || (assertion.result ? "okay" : "failed"); + ol.appendChild( li ); + + if ( assertion.result ) { + good++; + } else { + bad++; + config.stats.bad++; + config.moduleStats.bad++; + } + } + + // store result when possible + if ( QUnit.config.reorder && defined.sessionStorage ) { + if (bad) { + sessionStorage.setItem("qunit-" + this.module + "-" + this.testName, bad); + } else { + sessionStorage.removeItem("qunit-" + this.module + "-" + this.testName); + } + } + + if (bad == 0) { + ol.style.display = "none"; + } + + var b = document.createElement("strong"); + b.innerHTML = this.name + " (" + bad + ", " + good + ", " + this.assertions.length + ")"; + + var a = document.createElement("a"); + a.innerHTML = "Rerun"; + a.href = QUnit.url({ filter: getText([b]).replace(/\([^)]+\)$/, "").replace(/(^\s*|\s*$)/g, "") }); + + addEvent(b, "click", function() { + var next = b.nextSibling.nextSibling, + display = next.style.display; + next.style.display = display === "none" ? "block" : "none"; + }); + + addEvent(b, "dblclick", function(e) { + var target = e && e.target ? e.target : window.event.srcElement; + if ( target.nodeName.toLowerCase() == "span" || target.nodeName.toLowerCase() == "b" ) { + target = target.parentNode; + } + if ( window.location && target.nodeName.toLowerCase() === "strong" ) { + window.location = QUnit.url({ filter: getText([target]).replace(/\([^)]+\)$/, "").replace(/(^\s*|\s*$)/g, "") }); + } + }); + + var li = id(this.id); + li.className = bad ? "fail" : "pass"; + li.removeChild( li.firstChild ); + li.appendChild( b ); + li.appendChild( a ); + li.appendChild( ol ); + + } else { + for ( var i = 0; i < this.assertions.length; i++ ) { + if ( !this.assertions[i].result ) { + bad++; + config.stats.bad++; + config.moduleStats.bad++; + } + } + } + + try { + QUnit.reset(); + } catch(e) { + fail("reset() failed, following Test " + this.testName + ", exception and reset fn follows", e, QUnit.reset); + } + + runLoggingCallbacks( 'testDone', QUnit, { + name: this.testName, + module: this.module, + failed: bad, + passed: this.assertions.length - bad, + total: this.assertions.length + } ); + }, + + queue: function() { + var test = this; + synchronize(function() { + test.init(); + }); + function run() { + // each of these can by async + synchronize(function() { + test.setup(); + }); + synchronize(function() { + test.run(); + }); + synchronize(function() { + test.teardown(); + }); + synchronize(function() { + test.finish(); + }); + } + // defer when previous test run passed, if storage is available + var bad = QUnit.config.reorder && defined.sessionStorage && +sessionStorage.getItem("qunit-" + this.module + "-" + this.testName); + if (bad) { + run(); + } else { + synchronize(run, true); + }; + } + +}; + +var QUnit = { + + // call on start of module test to prepend name to all tests + module: function(name, testEnvironment) { + config.currentModule = name; + config.currentModuleTestEnviroment = testEnvironment; + }, + + asyncTest: function(testName, expected, callback) { + if ( arguments.length === 2 ) { + callback = expected; + expected = null; + } + + QUnit.test(testName, expected, callback, true); + }, + + test: function(testName, expected, callback, async) { + var name = '' + testName + '', testEnvironmentArg; + + if ( arguments.length === 2 ) { + callback = expected; + expected = null; + } + // is 2nd argument a testEnvironment? + if ( expected && typeof expected === 'object') { + testEnvironmentArg = expected; + expected = null; + } + + if ( config.currentModule ) { + name = '' + config.currentModule + ": " + name; + } + + if ( !validTest(config.currentModule + ": " + testName) ) { + return; + } + + var test = new Test(name, testName, expected, testEnvironmentArg, async, callback); + test.module = config.currentModule; + test.moduleTestEnvironment = config.currentModuleTestEnviroment; + test.queue(); + }, + + /** + * Specify the number of expected assertions to gurantee that failed test (no assertions are run at all) don't slip through. + */ + expect: function(asserts) { + config.current.expected = asserts; + }, + + /** + * Asserts true. + * @example ok( "asdfasdf".length > 5, "There must be at least 5 chars" ); + */ + ok: function(a, msg) { + a = !!a; + var details = { + result: a, + message: msg + }; + msg = escapeInnerText(msg); + runLoggingCallbacks( 'log', QUnit, details ); + config.current.assertions.push({ + result: a, + message: msg + }); + }, + + /** + * Checks that the first two arguments are equal, with an optional message. + * Prints out both actual and expected values. + * + * Prefered to ok( actual == expected, message ) + * + * @example equal( format("Received {0} bytes.", 2), "Received 2 bytes." ); + * + * @param Object actual + * @param Object expected + * @param String message (optional) + */ + equal: function(actual, expected, message) { + QUnit.push(expected == actual, actual, expected, message); + }, + + notEqual: function(actual, expected, message) { + QUnit.push(expected != actual, actual, expected, message); + }, + + deepEqual: function(actual, expected, message) { + QUnit.push(QUnit.equiv(actual, expected), actual, expected, message); + }, + + notDeepEqual: function(actual, expected, message) { + QUnit.push(!QUnit.equiv(actual, expected), actual, expected, message); + }, + + strictEqual: function(actual, expected, message) { + QUnit.push(expected === actual, actual, expected, message); + }, + + notStrictEqual: function(actual, expected, message) { + QUnit.push(expected !== actual, actual, expected, message); + }, + + raises: function(block, expected, message) { + var actual, ok = false; + + if (typeof expected === 'string') { + message = expected; + expected = null; + } + + try { + block(); + } catch (e) { + actual = e; + } + + if (actual) { + // we don't want to validate thrown error + if (!expected) { + ok = true; + // expected is a regexp + } else if (QUnit.objectType(expected) === "regexp") { + ok = expected.test(actual); + // expected is a constructor + } else if (actual instanceof expected) { + ok = true; + // expected is a validation function which returns true is validation passed + } else if (expected.call({}, actual) === true) { + ok = true; + } + } + + QUnit.ok(ok, message); + }, + + start: function(count) { + config.semaphore -= count || 1; + if (config.semaphore > 0) { + // don't start until equal number of stop-calls + return; + } + if (config.semaphore < 0) { + // ignore if start is called more often then stop + config.semaphore = 0; + } + // A slight delay, to avoid any current callbacks + if ( defined.setTimeout ) { + window.setTimeout(function() { + if (config.semaphore > 0) { + return; + } + if ( config.timeout ) { + clearTimeout(config.timeout); + } + + config.blocking = false; + process(true); + }, 13); + } else { + config.blocking = false; + process(true); + } + }, + + stop: function(count) { + config.semaphore += count || 1; + config.blocking = true; + + if ( config.testTimeout && defined.setTimeout ) { + clearTimeout(config.timeout); + config.timeout = window.setTimeout(function() { + QUnit.ok( false, "Test timed out" ); + config.semaphore = 1; + QUnit.start(); + }, config.testTimeout); + } + } +}; + +//We want access to the constructor's prototype +(function() { + function F(){}; + F.prototype = QUnit; + QUnit = new F(); + //Make F QUnit's constructor so that we can add to the prototype later + QUnit.constructor = F; +})(); + +// Backwards compatibility, deprecated +QUnit.equals = QUnit.equal; +QUnit.same = QUnit.deepEqual; + +// Maintain internal state +var config = { + // The queue of tests to run + queue: [], + + // block until document ready + blocking: true, + + // when enabled, show only failing tests + // gets persisted through sessionStorage and can be changed in UI via checkbox + hidepassed: false, + + // by default, run previously failed tests first + // very useful in combination with "Hide passed tests" checked + reorder: true, + + // by default, modify document.title when suite is done + altertitle: true, + + urlConfig: ['noglobals', 'notrycatch'], + + //logging callback queues + begin: [], + done: [], + log: [], + testStart: [], + testDone: [], + moduleStart: [], + moduleDone: [] +}; + +// Load paramaters +(function() { + var location = window.location || { search: "", protocol: "file:" }, + params = location.search.slice( 1 ).split( "&" ), + length = params.length, + urlParams = {}, + current; + + if ( params[ 0 ] ) { + for ( var i = 0; i < length; i++ ) { + current = params[ i ].split( "=" ); + current[ 0 ] = decodeURIComponent( current[ 0 ] ); + // allow just a key to turn on a flag, e.g., test.html?noglobals + current[ 1 ] = current[ 1 ] ? decodeURIComponent( current[ 1 ] ) : true; + urlParams[ current[ 0 ] ] = current[ 1 ]; + } + } + + QUnit.urlParams = urlParams; + config.filter = urlParams.filter; + + // Figure out if we're running the tests from a server or not + QUnit.isLocal = !!(location.protocol === 'file:'); +})(); + +// Expose the API as global variables, unless an 'exports' +// object exists, in that case we assume we're in CommonJS +if ( typeof exports === "undefined" || typeof require === "undefined" ) { + extend(window, QUnit); + window.QUnit = QUnit; +} else { + extend(exports, QUnit); + exports.QUnit = QUnit; +} + +// define these after exposing globals to keep them in these QUnit namespace only +extend(QUnit, { + config: config, + + // Initialize the configuration options + init: function() { + extend(config, { + stats: { all: 0, bad: 0 }, + moduleStats: { all: 0, bad: 0 }, + started: +new Date, + updateRate: 1000, + blocking: false, + autostart: true, + autorun: false, + filter: "", + queue: [], + semaphore: 0 + }); + + var tests = id( "qunit-tests" ), + banner = id( "qunit-banner" ), + result = id( "qunit-testresult" ); + + if ( tests ) { + tests.innerHTML = ""; + } + + if ( banner ) { + banner.className = ""; + } + + if ( result ) { + result.parentNode.removeChild( result ); + } + + if ( tests ) { + result = document.createElement( "p" ); + result.id = "qunit-testresult"; + result.className = "result"; + tests.parentNode.insertBefore( result, tests ); + result.innerHTML = 'Running...
       '; + } + }, + + /** + * Resets the test setup. Useful for tests that modify the DOM. + * + * If jQuery is available, uses jQuery's html(), otherwise just innerHTML. + */ + reset: function() { + if ( window.jQuery ) { + jQuery( "#qunit-fixture" ).html( config.fixture ); + } else { + var main = id( 'qunit-fixture' ); + if ( main ) { + main.innerHTML = config.fixture; + } + } + }, + + /** + * Trigger an event on an element. + * + * @example triggerEvent( document.body, "click" ); + * + * @param DOMElement elem + * @param String type + */ + triggerEvent: function( elem, type, event ) { + if ( document.createEvent ) { + event = document.createEvent("MouseEvents"); + event.initMouseEvent(type, true, true, elem.ownerDocument.defaultView, + 0, 0, 0, 0, 0, false, false, false, false, 0, null); + elem.dispatchEvent( event ); + + } else if ( elem.fireEvent ) { + elem.fireEvent("on"+type); + } + }, + + // Safe object type checking + is: function( type, obj ) { + return QUnit.objectType( obj ) == type; + }, + + objectType: function( obj ) { + if (typeof obj === "undefined") { + return "undefined"; + + // consider: typeof null === object + } + if (obj === null) { + return "null"; + } + + var type = toString.call( obj ).match(/^\[object\s(.*)\]$/)[1] || ''; + + switch (type) { + case 'Number': + if (isNaN(obj)) { + return "nan"; + } else { + return "number"; + } + case 'String': + case 'Boolean': + case 'Array': + case 'Date': + case 'RegExp': + case 'Function': + return type.toLowerCase(); + } + if (typeof obj === "object") { + return "object"; + } + return undefined; + }, + + push: function(result, actual, expected, message) { + var details = { + result: result, + message: message, + actual: actual, + expected: expected + }; + + message = escapeInnerText(message) || (result ? "okay" : "failed"); + message = '' + message + ""; + expected = escapeInnerText(QUnit.jsDump.parse(expected)); + actual = escapeInnerText(QUnit.jsDump.parse(actual)); + var output = message + ''; + if (actual != expected) { + output += ''; + output += ''; + } + if (!result) { + var source = sourceFromStacktrace(); + if (source) { + details.source = source; + output += ''; + } + } + output += "
      Expected:
      ' + expected + '
      Result:
      ' + actual + '
      Diff:
      ' + QUnit.diff(expected, actual) +'
      Source:
      ' + escapeInnerText(source) + '
      "; + + runLoggingCallbacks( 'log', QUnit, details ); + + config.current.assertions.push({ + result: !!result, + message: output + }); + }, + + url: function( params ) { + params = extend( extend( {}, QUnit.urlParams ), params ); + var querystring = "?", + key; + for ( key in params ) { + if ( !hasOwn.call( params, key ) ) { + continue; + } + querystring += encodeURIComponent( key ) + "=" + + encodeURIComponent( params[ key ] ) + "&"; + } + return window.location.pathname + querystring.slice( 0, -1 ); + }, + + extend: extend, + id: id, + addEvent: addEvent +}); + +//QUnit.constructor is set to the empty F() above so that we can add to it's prototype later +//Doing this allows us to tell if the following methods have been overwritten on the actual +//QUnit object, which is a deprecated way of using the callbacks. +extend(QUnit.constructor.prototype, { + // Logging callbacks; all receive a single argument with the listed properties + // run test/logs.html for any related changes + begin: registerLoggingCallback('begin'), + // done: { failed, passed, total, runtime } + done: registerLoggingCallback('done'), + // log: { result, actual, expected, message } + log: registerLoggingCallback('log'), + // testStart: { name } + testStart: registerLoggingCallback('testStart'), + // testDone: { name, failed, passed, total } + testDone: registerLoggingCallback('testDone'), + // moduleStart: { name } + moduleStart: registerLoggingCallback('moduleStart'), + // moduleDone: { name, failed, passed, total } + moduleDone: registerLoggingCallback('moduleDone') +}); + +if ( typeof document === "undefined" || document.readyState === "complete" ) { + config.autorun = true; +} + +QUnit.load = function() { + runLoggingCallbacks( 'begin', QUnit, {} ); + + // Initialize the config, saving the execution queue + var oldconfig = extend({}, config); + QUnit.init(); + extend(config, oldconfig); + + config.blocking = false; + + var urlConfigHtml = '', len = config.urlConfig.length; + for ( var i = 0, val; i < len, val = config.urlConfig[i]; i++ ) { + config[val] = QUnit.urlParams[val]; + urlConfigHtml += ''; + } + + var userAgent = id("qunit-userAgent"); + if ( userAgent ) { + userAgent.innerHTML = navigator.userAgent; + } + var banner = id("qunit-header"); + if ( banner ) { + banner.innerHTML = ' ' + banner.innerHTML + ' ' + urlConfigHtml; + addEvent( banner, "change", function( event ) { + var params = {}; + params[ event.target.name ] = event.target.checked ? true : undefined; + window.location = QUnit.url( params ); + }); + } + + var toolbar = id("qunit-testrunner-toolbar"); + if ( toolbar ) { + var filter = document.createElement("input"); + filter.type = "checkbox"; + filter.id = "qunit-filter-pass"; + addEvent( filter, "click", function() { + var ol = document.getElementById("qunit-tests"); + if ( filter.checked ) { + ol.className = ol.className + " hidepass"; + } else { + var tmp = " " + ol.className.replace( /[\n\t\r]/g, " " ) + " "; + ol.className = tmp.replace(/ hidepass /, " "); + } + if ( defined.sessionStorage ) { + if (filter.checked) { + sessionStorage.setItem("qunit-filter-passed-tests", "true"); + } else { + sessionStorage.removeItem("qunit-filter-passed-tests"); + } + } + }); + if ( config.hidepassed || defined.sessionStorage && sessionStorage.getItem("qunit-filter-passed-tests") ) { + filter.checked = true; + var ol = document.getElementById("qunit-tests"); + ol.className = ol.className + " hidepass"; + } + toolbar.appendChild( filter ); + + var label = document.createElement("label"); + label.setAttribute("for", "qunit-filter-pass"); + label.innerHTML = "Hide passed tests"; + toolbar.appendChild( label ); + } + + var main = id('qunit-fixture'); + if ( main ) { + config.fixture = main.innerHTML; + } + + if (config.autostart) { + QUnit.start(); + } +}; + +addEvent(window, "load", QUnit.load); + +// addEvent(window, "error") gives us a useless event object +window.onerror = function( message, file, line ) { + if ( QUnit.config.current ) { + ok( false, message + ", " + file + ":" + line ); + } else { + test( "global failure", function() { + ok( false, message + ", " + file + ":" + line ); + }); + } +}; + +function done() { + config.autorun = true; + + // Log the last module results + if ( config.currentModule ) { + runLoggingCallbacks( 'moduleDone', QUnit, { + name: config.currentModule, + failed: config.moduleStats.bad, + passed: config.moduleStats.all - config.moduleStats.bad, + total: config.moduleStats.all + } ); + } + + var banner = id("qunit-banner"), + tests = id("qunit-tests"), + runtime = +new Date - config.started, + passed = config.stats.all - config.stats.bad, + html = [ + 'Tests completed in ', + runtime, + ' milliseconds.
      ', + '', + passed, + ' tests of ', + config.stats.all, + ' passed, ', + config.stats.bad, + ' failed.' + ].join(''); + + if ( banner ) { + banner.className = (config.stats.bad ? "qunit-fail" : "qunit-pass"); + } + + if ( tests ) { + id( "qunit-testresult" ).innerHTML = html; + } + + if ( config.altertitle && typeof document !== "undefined" && document.title ) { + // show ✖ for good, ✔ for bad suite result in title + // use escape sequences in case file gets loaded with non-utf-8-charset + document.title = [ + (config.stats.bad ? "\u2716" : "\u2714"), + document.title.replace(/^[\u2714\u2716] /i, "") + ].join(" "); + } + + runLoggingCallbacks( 'done', QUnit, { + failed: config.stats.bad, + passed: passed, + total: config.stats.all, + runtime: runtime + } ); +} + +function validTest( name ) { + var filter = config.filter, + run = false; + + if ( !filter ) { + return true; + } + + var not = filter.charAt( 0 ) === "!"; + if ( not ) { + filter = filter.slice( 1 ); + } + + if ( name.indexOf( filter ) !== -1 ) { + return !not; + } + + if ( not ) { + run = true; + } + + return run; +} + +// so far supports only Firefox, Chrome and Opera (buggy) +// could be extended in the future to use something like https://github.com/csnover/TraceKit +function sourceFromStacktrace() { + try { + throw new Error(); + } catch ( e ) { + if (e.stacktrace) { + // Opera + return e.stacktrace.split("\n")[6]; + } else if (e.stack) { + // Firefox, Chrome + return e.stack.split("\n")[4]; + } else if (e.sourceURL) { + // Safari, PhantomJS + // TODO sourceURL points at the 'throw new Error' line above, useless + //return e.sourceURL + ":" + e.line; + } + } +} + +function escapeInnerText(s) { + if (!s) { + return ""; + } + s = s + ""; + return s.replace(/[\&<>]/g, function(s) { + switch(s) { + case "&": return "&"; + case "<": return "<"; + case ">": return ">"; + default: return s; + } + }); +} + +function synchronize( callback, last ) { + config.queue.push( callback ); + + if ( config.autorun && !config.blocking ) { + process(last); + } +} + +function process( last ) { + var start = new Date().getTime(); + config.depth = config.depth ? config.depth + 1 : 1; + + while ( config.queue.length && !config.blocking ) { + if ( !defined.setTimeout || config.updateRate <= 0 || ( ( new Date().getTime() - start ) < config.updateRate ) ) { + config.queue.shift()(); + } else { + window.setTimeout( function(){ + process( last ); + }, 13 ); + break; + } + } + config.depth--; + if ( last && !config.blocking && !config.queue.length && config.depth === 0 ) { + done(); + } +} + +function saveGlobal() { + config.pollution = []; + + if ( config.noglobals ) { + for ( var key in window ) { + if ( !hasOwn.call( window, key ) ) { + continue; + } + config.pollution.push( key ); + } + } +} + +function checkPollution( name ) { + var old = config.pollution; + saveGlobal(); + + var newGlobals = diff( config.pollution, old ); + if ( newGlobals.length > 0 ) { + ok( false, "Introduced global variable(s): " + newGlobals.join(", ") ); + } + + var deletedGlobals = diff( old, config.pollution ); + if ( deletedGlobals.length > 0 ) { + ok( false, "Deleted global variable(s): " + deletedGlobals.join(", ") ); + } +} + +// returns a new Array with the elements that are in a but not in b +function diff( a, b ) { + var result = a.slice(); + for ( var i = 0; i < result.length; i++ ) { + for ( var j = 0; j < b.length; j++ ) { + if ( result[i] === b[j] ) { + result.splice(i, 1); + i--; + break; + } + } + } + return result; +} + +function fail(message, exception, callback) { + if ( typeof console !== "undefined" && console.error && console.warn ) { + console.error(message); + console.error(exception); + console.warn(callback.toString()); + + } else if ( window.opera && opera.postError ) { + opera.postError(message, exception, callback.toString); + } +} + +function extend(a, b) { + for ( var prop in b ) { + if ( b[prop] === undefined ) { + delete a[prop]; + } else { + a[prop] = b[prop]; + } + } + + return a; +} + +function addEvent(elem, type, fn) { + if ( elem.addEventListener ) { + elem.addEventListener( type, fn, false ); + } else if ( elem.attachEvent ) { + elem.attachEvent( "on" + type, fn ); + } else { + fn(); + } +} + +function id(name) { + return !!(typeof document !== "undefined" && document && document.getElementById) && + document.getElementById( name ); +} + +function registerLoggingCallback(key){ + return function(callback){ + config[key].push( callback ); + }; +} + +// Supports deprecated method of completely overwriting logging callbacks +function runLoggingCallbacks(key, scope, args) { + //debugger; + var callbacks; + if ( QUnit.hasOwnProperty(key) ) { + QUnit[key].call(scope, args); + } else { + callbacks = config[key]; + for( var i = 0; i < callbacks.length; i++ ) { + callbacks[i].call( scope, args ); + } + } +} + +// Test for equality any JavaScript type. +// Author: Philippe Rathé +QUnit.equiv = function () { + + var innerEquiv; // the real equiv function + var callers = []; // stack to decide between skip/abort functions + var parents = []; // stack to avoiding loops from circular referencing + + // Call the o related callback with the given arguments. + function bindCallbacks(o, callbacks, args) { + var prop = QUnit.objectType(o); + if (prop) { + if (QUnit.objectType(callbacks[prop]) === "function") { + return callbacks[prop].apply(callbacks, args); + } else { + return callbacks[prop]; // or undefined + } + } + } + + var callbacks = function () { + + // for string, boolean, number and null + function useStrictEquality(b, a) { + if (b instanceof a.constructor || a instanceof b.constructor) { + // to catch short annotaion VS 'new' annotation of a + // declaration + // e.g. var i = 1; + // var j = new Number(1); + return a == b; + } else { + return a === b; + } + } + + return { + "string" : useStrictEquality, + "boolean" : useStrictEquality, + "number" : useStrictEquality, + "null" : useStrictEquality, + "undefined" : useStrictEquality, + + "nan" : function(b) { + return isNaN(b); + }, + + "date" : function(b, a) { + return QUnit.objectType(b) === "date" + && a.valueOf() === b.valueOf(); + }, + + "regexp" : function(b, a) { + return QUnit.objectType(b) === "regexp" + && a.source === b.source && // the regex itself + a.global === b.global && // and its modifers + // (gmi) ... + a.ignoreCase === b.ignoreCase + && a.multiline === b.multiline; + }, + + // - skip when the property is a method of an instance (OOP) + // - abort otherwise, + // initial === would have catch identical references anyway + "function" : function() { + var caller = callers[callers.length - 1]; + return caller !== Object && typeof caller !== "undefined"; + }, + + "array" : function(b, a) { + var i, j, loop; + var len; + + // b could be an object literal here + if (!(QUnit.objectType(b) === "array")) { + return false; + } + + len = a.length; + if (len !== b.length) { // safe and faster + return false; + } + + // track reference to avoid circular references + parents.push(a); + for (i = 0; i < len; i++) { + loop = false; + for (j = 0; j < parents.length; j++) { + if (parents[j] === a[i]) { + loop = true;// dont rewalk array + } + } + if (!loop && !innerEquiv(a[i], b[i])) { + parents.pop(); + return false; + } + } + parents.pop(); + return true; + }, + + "object" : function(b, a) { + var i, j, loop; + var eq = true; // unless we can proove it + var aProperties = [], bProperties = []; // collection of + // strings + + // comparing constructors is more strict than using + // instanceof + if (a.constructor !== b.constructor) { + return false; + } + + // stack constructor before traversing properties + callers.push(a.constructor); + // track reference to avoid circular references + parents.push(a); + + for (i in a) { // be strict: don't ensures hasOwnProperty + // and go deep + loop = false; + for (j = 0; j < parents.length; j++) { + if (parents[j] === a[i]) + loop = true; // don't go down the same path + // twice + } + aProperties.push(i); // collect a's properties + + if (!loop && !innerEquiv(a[i], b[i])) { + eq = false; + break; + } + } + + callers.pop(); // unstack, we are done + parents.pop(); + + for (i in b) { + bProperties.push(i); // collect b's properties + } + + // Ensures identical properties name + return eq + && innerEquiv(aProperties.sort(), bProperties + .sort()); + } + }; + }(); + + innerEquiv = function() { // can take multiple arguments + var args = Array.prototype.slice.apply(arguments); + if (args.length < 2) { + return true; // end transition + } + + return (function(a, b) { + if (a === b) { + return true; // catch the most you can + } else if (a === null || b === null || typeof a === "undefined" + || typeof b === "undefined" + || QUnit.objectType(a) !== QUnit.objectType(b)) { + return false; // don't lose time with error prone cases + } else { + return bindCallbacks(a, callbacks, [ b, a ]); + } + + // apply transition with (1..n) arguments + })(args[0], args[1]) + && arguments.callee.apply(this, args.splice(1, + args.length - 1)); + }; + + return innerEquiv; + +}(); + +/** + * jsDump Copyright (c) 2008 Ariel Flesler - aflesler(at)gmail(dot)com | + * http://flesler.blogspot.com Licensed under BSD + * (http://www.opensource.org/licenses/bsd-license.php) Date: 5/15/2008 + * + * @projectDescription Advanced and extensible data dumping for Javascript. + * @version 1.0.0 + * @author Ariel Flesler + * @link {http://flesler.blogspot.com/2008/05/jsdump-pretty-dump-of-any-javascript.html} + */ +QUnit.jsDump = (function() { + function quote( str ) { + return '"' + str.toString().replace(/"/g, '\\"') + '"'; + }; + function literal( o ) { + return o + ''; + }; + function join( pre, arr, post ) { + var s = jsDump.separator(), + base = jsDump.indent(), + inner = jsDump.indent(1); + if ( arr.join ) + arr = arr.join( ',' + s + inner ); + if ( !arr ) + return pre + post; + return [ pre, inner + arr, base + post ].join(s); + }; + function array( arr, stack ) { + var i = arr.length, ret = Array(i); + this.up(); + while ( i-- ) + ret[i] = this.parse( arr[i] , undefined , stack); + this.down(); + return join( '[', ret, ']' ); + }; + + var reName = /^function (\w+)/; + + var jsDump = { + parse:function( obj, type, stack ) { //type is used mostly internally, you can fix a (custom)type in advance + stack = stack || [ ]; + var parser = this.parsers[ type || this.typeOf(obj) ]; + type = typeof parser; + var inStack = inArray(obj, stack); + if (inStack != -1) { + return 'recursion('+(inStack - stack.length)+')'; + } + //else + if (type == 'function') { + stack.push(obj); + var res = parser.call( this, obj, stack ); + stack.pop(); + return res; + } + // else + return (type == 'string') ? parser : this.parsers.error; + }, + typeOf:function( obj ) { + var type; + if ( obj === null ) { + type = "null"; + } else if (typeof obj === "undefined") { + type = "undefined"; + } else if (QUnit.is("RegExp", obj)) { + type = "regexp"; + } else if (QUnit.is("Date", obj)) { + type = "date"; + } else if (QUnit.is("Function", obj)) { + type = "function"; + } else if (typeof obj.setInterval !== undefined && typeof obj.document !== "undefined" && typeof obj.nodeType === "undefined") { + type = "window"; + } else if (obj.nodeType === 9) { + type = "document"; + } else if (obj.nodeType) { + type = "node"; + } else if ( + // native arrays + toString.call( obj ) === "[object Array]" || + // NodeList objects + ( typeof obj.length === "number" && typeof obj.item !== "undefined" && ( obj.length ? obj.item(0) === obj[0] : ( obj.item( 0 ) === null && typeof obj[0] === "undefined" ) ) ) + ) { + type = "array"; + } else { + type = typeof obj; + } + return type; + }, + separator:function() { + return this.multiline ? this.HTML ? '
      ' : '\n' : this.HTML ? ' ' : ' '; + }, + indent:function( extra ) {// extra can be a number, shortcut for increasing-calling-decreasing + if ( !this.multiline ) + return ''; + var chr = this.indentChar; + if ( this.HTML ) + chr = chr.replace(/\t/g,' ').replace(/ /g,' '); + return Array( this._depth_ + (extra||0) ).join(chr); + }, + up:function( a ) { + this._depth_ += a || 1; + }, + down:function( a ) { + this._depth_ -= a || 1; + }, + setParser:function( name, parser ) { + this.parsers[name] = parser; + }, + // The next 3 are exposed so you can use them + quote:quote, + literal:literal, + join:join, + // + _depth_: 1, + // This is the list of parsers, to modify them, use jsDump.setParser + parsers:{ + window: '[Window]', + document: '[Document]', + error:'[ERROR]', //when no parser is found, shouldn't happen + unknown: '[Unknown]', + 'null':'null', + 'undefined':'undefined', + 'function':function( fn ) { + var ret = 'function', + name = 'name' in fn ? fn.name : (reName.exec(fn)||[])[1];//functions never have name in IE + if ( name ) + ret += ' ' + name; + ret += '('; + + ret = [ ret, QUnit.jsDump.parse( fn, 'functionArgs' ), '){'].join(''); + return join( ret, QUnit.jsDump.parse(fn,'functionCode'), '}' ); + }, + array: array, + nodelist: array, + arguments: array, + object:function( map, stack ) { + var ret = [ ]; + QUnit.jsDump.up(); + for ( var key in map ) { + var val = map[key]; + ret.push( QUnit.jsDump.parse(key,'key') + ': ' + QUnit.jsDump.parse(val, undefined, stack)); + } + QUnit.jsDump.down(); + return join( '{', ret, '}' ); + }, + node:function( node ) { + var open = QUnit.jsDump.HTML ? '<' : '<', + close = QUnit.jsDump.HTML ? '>' : '>'; + + var tag = node.nodeName.toLowerCase(), + ret = open + tag; + + for ( var a in QUnit.jsDump.DOMAttrs ) { + var val = node[QUnit.jsDump.DOMAttrs[a]]; + if ( val ) + ret += ' ' + a + '=' + QUnit.jsDump.parse( val, 'attribute' ); + } + return ret + close + open + '/' + tag + close; + }, + functionArgs:function( fn ) {//function calls it internally, it's the arguments part of the function + var l = fn.length; + if ( !l ) return ''; + + var args = Array(l); + while ( l-- ) + args[l] = String.fromCharCode(97+l);//97 is 'a' + return ' ' + args.join(', ') + ' '; + }, + key:quote, //object calls it internally, the key part of an item in a map + functionCode:'[code]', //function calls it internally, it's the content of the function + attribute:quote, //node calls it internally, it's an html attribute value + string:quote, + date:quote, + regexp:literal, //regex + number:literal, + 'boolean':literal + }, + DOMAttrs:{//attributes to dump from nodes, name=>realName + id:'id', + name:'name', + 'class':'className' + }, + HTML:false,//if true, entities are escaped ( <, >, \t, space and \n ) + indentChar:' ',//indentation unit + multiline:true //if true, items in a collection, are separated by a \n, else just a space. + }; + + return jsDump; +})(); + +// from Sizzle.js +function getText( 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 += getText( elem.childNodes ); + } + } + + return ret; +}; + +//from jquery.js +function inArray( elem, array ) { + if ( array.indexOf ) { + return array.indexOf( elem ); + } + + for ( var i = 0, length = array.length; i < length; i++ ) { + if ( array[ i ] === elem ) { + return i; + } + } + + return -1; +} + +/* + * Javascript Diff Algorithm + * By John Resig (http://ejohn.org/) + * Modified by Chu Alan "sprite" + * + * Released under the MIT license. + * + * More Info: + * http://ejohn.org/projects/javascript-diff-algorithm/ + * + * Usage: QUnit.diff(expected, actual) + * + * QUnit.diff("the quick brown fox jumped over", "the quick fox jumps over") == "the quick brown fox jumped jumps over" + */ +QUnit.diff = (function() { + function diff(o, n) { + var ns = {}; + var os = {}; + + for (var i = 0; i < n.length; i++) { + if (ns[n[i]] == null) + ns[n[i]] = { + rows: [], + o: null + }; + ns[n[i]].rows.push(i); + } + + for (var i = 0; i < o.length; i++) { + if (os[o[i]] == null) + os[o[i]] = { + rows: [], + n: null + }; + os[o[i]].rows.push(i); + } + + for (var i in ns) { + if ( !hasOwn.call( ns, i ) ) { + continue; + } + if (ns[i].rows.length == 1 && typeof(os[i]) != "undefined" && os[i].rows.length == 1) { + n[ns[i].rows[0]] = { + text: n[ns[i].rows[0]], + row: os[i].rows[0] + }; + o[os[i].rows[0]] = { + text: o[os[i].rows[0]], + row: ns[i].rows[0] + }; + } + } + + for (var i = 0; i < n.length - 1; i++) { + if (n[i].text != null && n[i + 1].text == null && n[i].row + 1 < o.length && o[n[i].row + 1].text == null && + n[i + 1] == o[n[i].row + 1]) { + n[i + 1] = { + text: n[i + 1], + row: n[i].row + 1 + }; + o[n[i].row + 1] = { + text: o[n[i].row + 1], + row: i + 1 + }; + } + } + + for (var i = n.length - 1; i > 0; i--) { + if (n[i].text != null && n[i - 1].text == null && n[i].row > 0 && o[n[i].row - 1].text == null && + n[i - 1] == o[n[i].row - 1]) { + n[i - 1] = { + text: n[i - 1], + row: n[i].row - 1 + }; + o[n[i].row - 1] = { + text: o[n[i].row - 1], + row: i - 1 + }; + } + } + + return { + o: o, + n: n + }; + } + + return function(o, n) { + o = o.replace(/\s+$/, ''); + n = n.replace(/\s+$/, ''); + var out = diff(o == "" ? [] : o.split(/\s+/), n == "" ? [] : n.split(/\s+/)); + + var str = ""; + + var oSpace = o.match(/\s+/g); + if (oSpace == null) { + oSpace = [" "]; + } + else { + oSpace.push(" "); + } + var nSpace = n.match(/\s+/g); + if (nSpace == null) { + nSpace = [" "]; + } + else { + nSpace.push(" "); + } + + if (out.n.length == 0) { + for (var i = 0; i < out.o.length; i++) { + str += '' + out.o[i] + oSpace[i] + ""; + } + } + else { + if (out.n[0].text == null) { + for (n = 0; n < out.o.length && out.o[n].text == null; n++) { + str += '' + out.o[n] + oSpace[n] + ""; + } + } + + for (var i = 0; i < out.n.length; i++) { + if (out.n[i].text == null) { + str += '' + out.n[i] + nSpace[i] + ""; + } + else { + var pre = ""; + + for (n = out.n[i].row + 1; n < out.o.length && out.o[n].text == null; n++) { + pre += '' + out.o[n] + oSpace[n] + ""; + } + str += " " + out.n[i].text + nSpace[i] + pre; + } + } + } + + return str; + }; +})(); + +})(this); diff --git a/htdocs/js/lib/webwork/components/backbone/test/vendor/underscore-1.3.1.js b/htdocs/js/lib/webwork/components/backbone/test/vendor/underscore-1.3.1.js new file mode 100644 index 000000000..208d4cd89 --- /dev/null +++ b/htdocs/js/lib/webwork/components/backbone/test/vendor/underscore-1.3.1.js @@ -0,0 +1,999 @@ +// Underscore.js 1.3.1 +// (c) 2009-2012 Jeremy Ashkenas, DocumentCloud Inc. +// Underscore is freely distributable under the MIT license. +// Portions of Underscore are inspired or borrowed from Prototype, +// Oliver Steele's Functional, and John Resig's Micro-Templating. +// For all details and documentation: +// http://documentcloud.github.com/underscore + +(function() { + + // Baseline setup + // -------------- + + // Establish the root object, `window` in the browser, or `global` on the server. + var root = this; + + // Save the previous value of the `_` variable. + var previousUnderscore = root._; + + // Establish the object that gets returned to break out of a loop iteration. + var breaker = {}; + + // Save bytes in the minified (but not gzipped) version: + var ArrayProto = Array.prototype, ObjProto = Object.prototype, FuncProto = Function.prototype; + + // Create quick reference variables for speed access to core prototypes. + var slice = ArrayProto.slice, + unshift = ArrayProto.unshift, + toString = ObjProto.toString, + hasOwnProperty = ObjProto.hasOwnProperty; + + // All **ECMAScript 5** native function implementations that we hope to use + // are declared here. + var + nativeForEach = ArrayProto.forEach, + nativeMap = ArrayProto.map, + nativeReduce = ArrayProto.reduce, + nativeReduceRight = ArrayProto.reduceRight, + nativeFilter = ArrayProto.filter, + nativeEvery = ArrayProto.every, + nativeSome = ArrayProto.some, + nativeIndexOf = ArrayProto.indexOf, + nativeLastIndexOf = ArrayProto.lastIndexOf, + nativeIsArray = Array.isArray, + nativeKeys = Object.keys, + nativeBind = FuncProto.bind; + + // Create a safe reference to the Underscore object for use below. + var _ = function(obj) { return new wrapper(obj); }; + + // Export the Underscore object for **Node.js**, with + // backwards-compatibility for the old `require()` API. If we're in + // the browser, add `_` as a global object via a string identifier, + // for Closure Compiler "advanced" mode. + if (typeof exports !== 'undefined') { + if (typeof module !== 'undefined' && module.exports) { + exports = module.exports = _; + } + exports._ = _; + } else { + root['_'] = _; + } + + // Current version. + _.VERSION = '1.3.1'; + + // Collection Functions + // -------------------- + + // The cornerstone, an `each` implementation, aka `forEach`. + // Handles objects with the built-in `forEach`, arrays, and raw objects. + // Delegates to **ECMAScript 5**'s native `forEach` if available. + var each = _.each = _.forEach = function(obj, iterator, context) { + if (obj == null) return; + if (nativeForEach && obj.forEach === nativeForEach) { + obj.forEach(iterator, context); + } else if (obj.length === +obj.length) { + for (var i = 0, l = obj.length; i < l; i++) { + if (i in obj && iterator.call(context, obj[i], i, obj) === breaker) return; + } + } else { + for (var key in obj) { + if (_.has(obj, key)) { + if (iterator.call(context, obj[key], key, obj) === breaker) return; + } + } + } + }; + + // Return the results of applying the iterator to each element. + // Delegates to **ECMAScript 5**'s native `map` if available. + _.map = _.collect = function(obj, iterator, context) { + var results = []; + if (obj == null) return results; + if (nativeMap && obj.map === nativeMap) return obj.map(iterator, context); + each(obj, function(value, index, list) { + results[results.length] = iterator.call(context, value, index, list); + }); + if (obj.length === +obj.length) results.length = obj.length; + return results; + }; + + // **Reduce** builds up a single result from a list of values, aka `inject`, + // or `foldl`. Delegates to **ECMAScript 5**'s native `reduce` if available. + _.reduce = _.foldl = _.inject = function(obj, iterator, memo, context) { + var initial = arguments.length > 2; + if (obj == null) obj = []; + if (nativeReduce && obj.reduce === nativeReduce) { + if (context) iterator = _.bind(iterator, context); + return initial ? obj.reduce(iterator, memo) : obj.reduce(iterator); + } + each(obj, function(value, index, list) { + if (!initial) { + memo = value; + initial = true; + } else { + memo = iterator.call(context, memo, value, index, list); + } + }); + if (!initial) throw new TypeError('Reduce of empty array with no initial value'); + return memo; + }; + + // The right-associative version of reduce, also known as `foldr`. + // Delegates to **ECMAScript 5**'s native `reduceRight` if available. + _.reduceRight = _.foldr = function(obj, iterator, memo, context) { + var initial = arguments.length > 2; + if (obj == null) obj = []; + if (nativeReduceRight && obj.reduceRight === nativeReduceRight) { + if (context) iterator = _.bind(iterator, context); + return initial ? obj.reduceRight(iterator, memo) : obj.reduceRight(iterator); + } + var reversed = _.toArray(obj).reverse(); + if (context && !initial) iterator = _.bind(iterator, context); + return initial ? _.reduce(reversed, iterator, memo, context) : _.reduce(reversed, iterator); + }; + + // Return the first value which passes a truth test. Aliased as `detect`. + _.find = _.detect = function(obj, iterator, context) { + var result; + any(obj, function(value, index, list) { + if (iterator.call(context, value, index, list)) { + result = value; + return true; + } + }); + return result; + }; + + // Return all the elements that pass a truth test. + // Delegates to **ECMAScript 5**'s native `filter` if available. + // Aliased as `select`. + _.filter = _.select = function(obj, iterator, context) { + var results = []; + if (obj == null) return results; + if (nativeFilter && obj.filter === nativeFilter) return obj.filter(iterator, context); + each(obj, function(value, index, list) { + if (iterator.call(context, value, index, list)) results[results.length] = value; + }); + return results; + }; + + // Return all the elements for which a truth test fails. + _.reject = function(obj, iterator, context) { + var results = []; + if (obj == null) return results; + each(obj, function(value, index, list) { + if (!iterator.call(context, value, index, list)) results[results.length] = value; + }); + return results; + }; + + // Determine whether all of the elements match a truth test. + // Delegates to **ECMAScript 5**'s native `every` if available. + // Aliased as `all`. + _.every = _.all = function(obj, iterator, context) { + var result = true; + if (obj == null) return result; + if (nativeEvery && obj.every === nativeEvery) return obj.every(iterator, context); + each(obj, function(value, index, list) { + if (!(result = result && iterator.call(context, value, index, list))) return breaker; + }); + return result; + }; + + // Determine if at least one element in the object matches a truth test. + // Delegates to **ECMAScript 5**'s native `some` if available. + // Aliased as `any`. + var any = _.some = _.any = function(obj, iterator, context) { + iterator || (iterator = _.identity); + var result = false; + if (obj == null) return result; + if (nativeSome && obj.some === nativeSome) return obj.some(iterator, context); + each(obj, function(value, index, list) { + if (result || (result = iterator.call(context, value, index, list))) return breaker; + }); + return !!result; + }; + + // Determine if a given value is included in the array or object using `===`. + // Aliased as `contains`. + _.include = _.contains = function(obj, target) { + var found = false; + if (obj == null) return found; + if (nativeIndexOf && obj.indexOf === nativeIndexOf) return obj.indexOf(target) != -1; + found = any(obj, function(value) { + return value === target; + }); + return found; + }; + + // Invoke a method (with arguments) on every item in a collection. + _.invoke = function(obj, method) { + var args = slice.call(arguments, 2); + return _.map(obj, function(value) { + return (_.isFunction(method) ? method || value : value[method]).apply(value, args); + }); + }; + + // Convenience version of a common use case of `map`: fetching a property. + _.pluck = function(obj, key) { + return _.map(obj, function(value){ return value[key]; }); + }; + + // Return the maximum element or (element-based computation). + _.max = function(obj, iterator, context) { + if (!iterator && _.isArray(obj)) return Math.max.apply(Math, obj); + if (!iterator && _.isEmpty(obj)) return -Infinity; + var result = {computed : -Infinity}; + each(obj, function(value, index, list) { + var computed = iterator ? iterator.call(context, value, index, list) : value; + computed >= result.computed && (result = {value : value, computed : computed}); + }); + return result.value; + }; + + // Return the minimum element (or element-based computation). + _.min = function(obj, iterator, context) { + if (!iterator && _.isArray(obj)) return Math.min.apply(Math, obj); + if (!iterator && _.isEmpty(obj)) return Infinity; + var result = {computed : Infinity}; + each(obj, function(value, index, list) { + var computed = iterator ? iterator.call(context, value, index, list) : value; + computed < result.computed && (result = {value : value, computed : computed}); + }); + return result.value; + }; + + // Shuffle an array. + _.shuffle = function(obj) { + var shuffled = [], rand; + each(obj, function(value, index, list) { + if (index == 0) { + shuffled[0] = value; + } else { + rand = Math.floor(Math.random() * (index + 1)); + shuffled[index] = shuffled[rand]; + shuffled[rand] = value; + } + }); + return shuffled; + }; + + // Sort the object's values by a criterion produced by an iterator. + _.sortBy = function(obj, iterator, context) { + return _.pluck(_.map(obj, function(value, index, list) { + return { + value : value, + criteria : iterator.call(context, value, index, list) + }; + }).sort(function(left, right) { + var a = left.criteria, b = right.criteria; + return a < b ? -1 : a > b ? 1 : 0; + }), 'value'); + }; + + // Groups the object's values by a criterion. Pass either a string attribute + // to group by, or a function that returns the criterion. + _.groupBy = function(obj, val) { + var result = {}; + var iterator = _.isFunction(val) ? val : function(obj) { return obj[val]; }; + each(obj, function(value, index) { + var key = iterator(value, index); + (result[key] || (result[key] = [])).push(value); + }); + return result; + }; + + // Use a comparator function to figure out at what index an object should + // be inserted so as to maintain order. Uses binary search. + _.sortedIndex = function(array, obj, iterator) { + iterator || (iterator = _.identity); + var low = 0, high = array.length; + while (low < high) { + var mid = (low + high) >> 1; + iterator(array[mid]) < iterator(obj) ? low = mid + 1 : high = mid; + } + return low; + }; + + // Safely convert anything iterable into a real, live array. + _.toArray = function(iterable) { + if (!iterable) return []; + if (iterable.toArray) return iterable.toArray(); + if (_.isArray(iterable)) return slice.call(iterable); + if (_.isArguments(iterable)) return slice.call(iterable); + return _.values(iterable); + }; + + // Return the number of elements in an object. + _.size = function(obj) { + return _.toArray(obj).length; + }; + + // Array Functions + // --------------- + + // Get the first element of an array. Passing **n** will return the first N + // values in the array. Aliased as `head`. The **guard** check allows it to work + // with `_.map`. + _.first = _.head = function(array, n, guard) { + return (n != null) && !guard ? slice.call(array, 0, n) : array[0]; + }; + + // Returns everything but the last entry of the array. Especcialy useful on + // the arguments object. Passing **n** will return all the values in + // the array, excluding the last N. The **guard** check allows it to work with + // `_.map`. + _.initial = function(array, n, guard) { + return slice.call(array, 0, array.length - ((n == null) || guard ? 1 : n)); + }; + + // Get the last element of an array. Passing **n** will return the last N + // values in the array. The **guard** check allows it to work with `_.map`. + _.last = function(array, n, guard) { + if ((n != null) && !guard) { + return slice.call(array, Math.max(array.length - n, 0)); + } else { + return array[array.length - 1]; + } + }; + + // Returns everything but the first entry of the array. Aliased as `tail`. + // Especially useful on the arguments object. Passing an **index** will return + // the rest of the values in the array from that index onward. The **guard** + // check allows it to work with `_.map`. + _.rest = _.tail = function(array, index, guard) { + return slice.call(array, (index == null) || guard ? 1 : index); + }; + + // Trim out all falsy values from an array. + _.compact = function(array) { + return _.filter(array, function(value){ return !!value; }); + }; + + // Return a completely flattened version of an array. + _.flatten = function(array, shallow) { + return _.reduce(array, function(memo, value) { + if (_.isArray(value)) return memo.concat(shallow ? value : _.flatten(value)); + memo[memo.length] = value; + return memo; + }, []); + }; + + // Return a version of the array that does not contain the specified value(s). + _.without = function(array) { + return _.difference(array, slice.call(arguments, 1)); + }; + + // Produce a duplicate-free version of the array. If the array has already + // been sorted, you have the option of using a faster algorithm. + // Aliased as `unique`. + _.uniq = _.unique = function(array, isSorted, iterator) { + var initial = iterator ? _.map(array, iterator) : array; + var result = []; + _.reduce(initial, function(memo, el, i) { + if (0 == i || (isSorted === true ? _.last(memo) != el : !_.include(memo, el))) { + memo[memo.length] = el; + result[result.length] = array[i]; + } + return memo; + }, []); + return result; + }; + + // Produce an array that contains the union: each distinct element from all of + // the passed-in arrays. + _.union = function() { + return _.uniq(_.flatten(arguments, true)); + }; + + // Produce an array that contains every item shared between all the + // passed-in arrays. (Aliased as "intersect" for back-compat.) + _.intersection = _.intersect = function(array) { + var rest = slice.call(arguments, 1); + return _.filter(_.uniq(array), function(item) { + return _.every(rest, function(other) { + return _.indexOf(other, item) >= 0; + }); + }); + }; + + // Take the difference between one array and a number of other arrays. + // Only the elements present in just the first array will remain. + _.difference = function(array) { + var rest = _.flatten(slice.call(arguments, 1)); + return _.filter(array, function(value){ return !_.include(rest, value); }); + }; + + // Zip together multiple lists into a single array -- elements that share + // an index go together. + _.zip = function() { + var args = slice.call(arguments); + var length = _.max(_.pluck(args, 'length')); + var results = new Array(length); + for (var i = 0; i < length; i++) results[i] = _.pluck(args, "" + i); + return results; + }; + + // If the browser doesn't supply us with indexOf (I'm looking at you, **MSIE**), + // we need this function. Return the position of the first occurrence of an + // item in an array, or -1 if the item is not included in the array. + // Delegates to **ECMAScript 5**'s native `indexOf` if available. + // If the array is large and already in sort order, pass `true` + // for **isSorted** to use binary search. + _.indexOf = function(array, item, isSorted) { + if (array == null) return -1; + var i, l; + if (isSorted) { + i = _.sortedIndex(array, item); + return array[i] === item ? i : -1; + } + if (nativeIndexOf && array.indexOf === nativeIndexOf) return array.indexOf(item); + for (i = 0, l = array.length; i < l; i++) if (i in array && array[i] === item) return i; + return -1; + }; + + // Delegates to **ECMAScript 5**'s native `lastIndexOf` if available. + _.lastIndexOf = function(array, item) { + if (array == null) return -1; + if (nativeLastIndexOf && array.lastIndexOf === nativeLastIndexOf) return array.lastIndexOf(item); + var i = array.length; + while (i--) if (i in array && array[i] === item) return i; + return -1; + }; + + // Generate an integer Array containing an arithmetic progression. A port of + // the native Python `range()` function. See + // [the Python documentation](http://docs.python.org/library/functions.html#range). + _.range = function(start, stop, step) { + if (arguments.length <= 1) { + stop = start || 0; + start = 0; + } + step = arguments[2] || 1; + + var len = Math.max(Math.ceil((stop - start) / step), 0); + var idx = 0; + var range = new Array(len); + + while(idx < len) { + range[idx++] = start; + start += step; + } + + return range; + }; + + // Function (ahem) Functions + // ------------------ + + // Reusable constructor function for prototype setting. + var ctor = function(){}; + + // Create a function bound to a given object (assigning `this`, and arguments, + // optionally). Binding with arguments is also known as `curry`. + // Delegates to **ECMAScript 5**'s native `Function.bind` if available. + // We check for `func.bind` first, to fail fast when `func` is undefined. + _.bind = function bind(func, context) { + var bound, args; + if (func.bind === nativeBind && nativeBind) return nativeBind.apply(func, slice.call(arguments, 1)); + if (!_.isFunction(func)) throw new TypeError; + args = slice.call(arguments, 2); + return bound = function() { + if (!(this instanceof bound)) return func.apply(context, args.concat(slice.call(arguments))); + ctor.prototype = func.prototype; + var self = new ctor; + var result = func.apply(self, args.concat(slice.call(arguments))); + if (Object(result) === result) return result; + return self; + }; + }; + + // Bind all of an object's methods to that object. Useful for ensuring that + // all callbacks defined on an object belong to it. + _.bindAll = function(obj) { + var funcs = slice.call(arguments, 1); + if (funcs.length == 0) funcs = _.functions(obj); + each(funcs, function(f) { obj[f] = _.bind(obj[f], obj); }); + return obj; + }; + + // Memoize an expensive function by storing its results. + _.memoize = function(func, hasher) { + var memo = {}; + hasher || (hasher = _.identity); + return function() { + var key = hasher.apply(this, arguments); + return _.has(memo, key) ? memo[key] : (memo[key] = func.apply(this, arguments)); + }; + }; + + // Delays a function for the given number of milliseconds, and then calls + // it with the arguments supplied. + _.delay = function(func, wait) { + var args = slice.call(arguments, 2); + return setTimeout(function(){ return func.apply(func, args); }, wait); + }; + + // Defers a function, scheduling it to run after the current call stack has + // cleared. + _.defer = function(func) { + return _.delay.apply(_, [func, 1].concat(slice.call(arguments, 1))); + }; + + // Returns a function, that, when invoked, will only be triggered at most once + // during a given window of time. + _.throttle = function(func, wait) { + var context, args, timeout, throttling, more; + var whenDone = _.debounce(function(){ more = throttling = false; }, wait); + return function() { + context = this; args = arguments; + var later = function() { + timeout = null; + if (more) func.apply(context, args); + whenDone(); + }; + if (!timeout) timeout = setTimeout(later, wait); + if (throttling) { + more = true; + } else { + func.apply(context, args); + } + whenDone(); + throttling = true; + }; + }; + + // Returns a function, that, as long as it continues to be invoked, will not + // be triggered. The function will be called after it stops being called for + // N milliseconds. + _.debounce = function(func, wait) { + var timeout; + return function() { + var context = this, args = arguments; + var later = function() { + timeout = null; + func.apply(context, args); + }; + clearTimeout(timeout); + timeout = setTimeout(later, wait); + }; + }; + + // Returns a function that will be executed at most one time, no matter how + // often you call it. Useful for lazy initialization. + _.once = function(func) { + var ran = false, memo; + return function() { + if (ran) return memo; + ran = true; + return memo = func.apply(this, arguments); + }; + }; + + // Returns the first function passed as an argument to the second, + // allowing you to adjust arguments, run code before and after, and + // conditionally execute the original function. + _.wrap = function(func, wrapper) { + return function() { + var args = [func].concat(slice.call(arguments, 0)); + return wrapper.apply(this, args); + }; + }; + + // Returns a function that is the composition of a list of functions, each + // consuming the return value of the function that follows. + _.compose = function() { + var funcs = arguments; + return function() { + var args = arguments; + for (var i = funcs.length - 1; i >= 0; i--) { + args = [funcs[i].apply(this, args)]; + } + return args[0]; + }; + }; + + // Returns a function that will only be executed after being called N times. + _.after = function(times, func) { + if (times <= 0) return func(); + return function() { + if (--times < 1) { return func.apply(this, arguments); } + }; + }; + + // Object Functions + // ---------------- + + // Retrieve the names of an object's properties. + // Delegates to **ECMAScript 5**'s native `Object.keys` + _.keys = nativeKeys || function(obj) { + if (obj !== Object(obj)) throw new TypeError('Invalid object'); + var keys = []; + for (var key in obj) if (_.has(obj, key)) keys[keys.length] = key; + return keys; + }; + + // Retrieve the values of an object's properties. + _.values = function(obj) { + return _.map(obj, _.identity); + }; + + // Return a sorted list of the function names available on the object. + // Aliased as `methods` + _.functions = _.methods = function(obj) { + var names = []; + for (var key in obj) { + if (_.isFunction(obj[key])) names.push(key); + } + return names.sort(); + }; + + // Extend a given object with all the properties in passed-in object(s). + _.extend = function(obj) { + each(slice.call(arguments, 1), function(source) { + for (var prop in source) { + obj[prop] = source[prop]; + } + }); + return obj; + }; + + // Fill in a given object with default properties. + _.defaults = function(obj) { + each(slice.call(arguments, 1), function(source) { + for (var prop in source) { + if (obj[prop] == null) obj[prop] = source[prop]; + } + }); + return obj; + }; + + // Create a (shallow-cloned) duplicate of an object. + _.clone = function(obj) { + if (!_.isObject(obj)) return obj; + return _.isArray(obj) ? obj.slice() : _.extend({}, obj); + }; + + // Invokes interceptor with the obj, and then returns obj. + // The primary purpose of this method is to "tap into" a method chain, in + // order to perform operations on intermediate results within the chain. + _.tap = function(obj, interceptor) { + interceptor(obj); + return obj; + }; + + // Internal recursive comparison function. + function eq(a, b, stack) { + // Identical objects are equal. `0 === -0`, but they aren't identical. + // See the Harmony `egal` proposal: http://wiki.ecmascript.org/doku.php?id=harmony:egal. + if (a === b) return a !== 0 || 1 / a == 1 / b; + // A strict comparison is necessary because `null == undefined`. + if (a == null || b == null) return a === b; + // Unwrap any wrapped objects. + if (a._chain) a = a._wrapped; + if (b._chain) b = b._wrapped; + // Invoke a custom `isEqual` method if one is provided. + if (a.isEqual && _.isFunction(a.isEqual)) return a.isEqual(b); + if (b.isEqual && _.isFunction(b.isEqual)) return b.isEqual(a); + // Compare `[[Class]]` names. + var className = toString.call(a); + if (className != toString.call(b)) return false; + switch (className) { + // Strings, numbers, dates, and booleans are compared by value. + case '[object String]': + // Primitives and their corresponding object wrappers are equivalent; thus, `"5"` is + // equivalent to `new String("5")`. + return a == String(b); + case '[object Number]': + // `NaN`s are equivalent, but non-reflexive. An `egal` comparison is performed for + // other numeric values. + return a != +a ? b != +b : (a == 0 ? 1 / a == 1 / b : a == +b); + case '[object Date]': + case '[object Boolean]': + // Coerce dates and booleans to numeric primitive values. Dates are compared by their + // millisecond representations. Note that invalid dates with millisecond representations + // of `NaN` are not equivalent. + return +a == +b; + // RegExps are compared by their source patterns and flags. + case '[object RegExp]': + return a.source == b.source && + a.global == b.global && + a.multiline == b.multiline && + a.ignoreCase == b.ignoreCase; + } + if (typeof a != 'object' || typeof b != 'object') return false; + // Assume equality for cyclic structures. The algorithm for detecting cyclic + // structures is adapted from ES 5.1 section 15.12.3, abstract operation `JO`. + var length = stack.length; + while (length--) { + // Linear search. Performance is inversely proportional to the number of + // unique nested structures. + if (stack[length] == a) return true; + } + // Add the first object to the stack of traversed objects. + stack.push(a); + var size = 0, result = true; + // Recursively compare objects and arrays. + if (className == '[object Array]') { + // Compare array lengths to determine if a deep comparison is necessary. + size = a.length; + result = size == b.length; + if (result) { + // Deep compare the contents, ignoring non-numeric properties. + while (size--) { + // Ensure commutative equality for sparse arrays. + if (!(result = size in a == size in b && eq(a[size], b[size], stack))) break; + } + } + } else { + // Objects with different constructors are not equivalent. + if ('constructor' in a != 'constructor' in b || a.constructor != b.constructor) return false; + // Deep compare objects. + for (var key in a) { + if (_.has(a, key)) { + // Count the expected number of properties. + size++; + // Deep compare each member. + if (!(result = _.has(b, key) && eq(a[key], b[key], stack))) break; + } + } + // Ensure that both objects contain the same number of properties. + if (result) { + for (key in b) { + if (_.has(b, key) && !(size--)) break; + } + result = !size; + } + } + // Remove the first object from the stack of traversed objects. + stack.pop(); + return result; + } + + // Perform a deep comparison to check if two objects are equal. + _.isEqual = function(a, b) { + return eq(a, b, []); + }; + + // Is a given array, string, or object empty? + // An "empty" object has no enumerable own-properties. + _.isEmpty = function(obj) { + if (_.isArray(obj) || _.isString(obj)) return obj.length === 0; + for (var key in obj) if (_.has(obj, key)) return false; + return true; + }; + + // Is a given value a DOM element? + _.isElement = function(obj) { + return !!(obj && obj.nodeType == 1); + }; + + // Is a given value an array? + // Delegates to ECMA5's native Array.isArray + _.isArray = nativeIsArray || function(obj) { + return toString.call(obj) == '[object Array]'; + }; + + // Is a given variable an object? + _.isObject = function(obj) { + return obj === Object(obj); + }; + + // Is a given variable an arguments object? + _.isArguments = function(obj) { + return toString.call(obj) == '[object Arguments]'; + }; + if (!_.isArguments(arguments)) { + _.isArguments = function(obj) { + return !!(obj && _.has(obj, 'callee')); + }; + } + + // Is a given value a function? + _.isFunction = function(obj) { + return toString.call(obj) == '[object Function]'; + }; + + // Is a given value a string? + _.isString = function(obj) { + return toString.call(obj) == '[object String]'; + }; + + // Is a given value a number? + _.isNumber = function(obj) { + return toString.call(obj) == '[object Number]'; + }; + + // Is the given value `NaN`? + _.isNaN = function(obj) { + // `NaN` is the only value for which `===` is not reflexive. + return obj !== obj; + }; + + // Is a given value a boolean? + _.isBoolean = function(obj) { + return obj === true || obj === false || toString.call(obj) == '[object Boolean]'; + }; + + // Is a given value a date? + _.isDate = function(obj) { + return toString.call(obj) == '[object Date]'; + }; + + // Is the given value a regular expression? + _.isRegExp = function(obj) { + return toString.call(obj) == '[object RegExp]'; + }; + + // Is a given value equal to null? + _.isNull = function(obj) { + return obj === null; + }; + + // Is a given variable undefined? + _.isUndefined = function(obj) { + return obj === void 0; + }; + + // Has own property? + _.has = function(obj, key) { + return hasOwnProperty.call(obj, key); + }; + + // Utility Functions + // ----------------- + + // Run Underscore.js in *noConflict* mode, returning the `_` variable to its + // previous owner. Returns a reference to the Underscore object. + _.noConflict = function() { + root._ = previousUnderscore; + return this; + }; + + // Keep the identity function around for default iterators. + _.identity = function(value) { + return value; + }; + + // Run a function **n** times. + _.times = function (n, iterator, context) { + for (var i = 0; i < n; i++) iterator.call(context, i); + }; + + // Escape a string for HTML interpolation. + _.escape = function(string) { + return (''+string).replace(/&/g, '&').replace(//g, '>').replace(/"/g, '"').replace(/'/g, ''').replace(/\//g,'/'); + }; + + // Add your own custom functions to the Underscore object, ensuring that + // they're correctly added to the OOP wrapper as well. + _.mixin = function(obj) { + each(_.functions(obj), function(name){ + addToWrapper(name, _[name] = obj[name]); + }); + }; + + // Generate a unique integer id (unique within the entire client session). + // Useful for temporary DOM ids. + var idCounter = 0; + _.uniqueId = function(prefix) { + var id = idCounter++; + return prefix ? prefix + id : id; + }; + + // By default, Underscore uses ERB-style template delimiters, change the + // following template settings to use alternative delimiters. + _.templateSettings = { + evaluate : /<%([\s\S]+?)%>/g, + interpolate : /<%=([\s\S]+?)%>/g, + escape : /<%-([\s\S]+?)%>/g + }; + + // When customizing `templateSettings`, if you don't want to define an + // interpolation, evaluation or escaping regex, we need one that is + // guaranteed not to match. + var noMatch = /.^/; + + // Within an interpolation, evaluation, or escaping, remove HTML escaping + // that had been previously added. + var unescape = function(code) { + return code.replace(/\\\\/g, '\\').replace(/\\'/g, "'"); + }; + + // JavaScript micro-templating, similar to John Resig's implementation. + // Underscore templating handles arbitrary delimiters, preserves whitespace, + // and correctly escapes quotes within interpolated code. + _.template = function(str, data) { + var c = _.templateSettings; + var tmpl = 'var __p=[],print=function(){__p.push.apply(__p,arguments);};' + + 'with(obj||{}){__p.push(\'' + + str.replace(/\\/g, '\\\\') + .replace(/'/g, "\\'") + .replace(c.escape || noMatch, function(match, code) { + return "',_.escape(" + unescape(code) + "),'"; + }) + .replace(c.interpolate || noMatch, function(match, code) { + return "'," + unescape(code) + ",'"; + }) + .replace(c.evaluate || noMatch, function(match, code) { + return "');" + unescape(code).replace(/[\r\n\t]/g, ' ') + ";__p.push('"; + }) + .replace(/\r/g, '\\r') + .replace(/\n/g, '\\n') + .replace(/\t/g, '\\t') + + "');}return __p.join('');"; + var func = new Function('obj', '_', tmpl); + if (data) return func(data, _); + return function(data) { + return func.call(this, data, _); + }; + }; + + // Add a "chain" function, which will delegate to the wrapper. + _.chain = function(obj) { + return _(obj).chain(); + }; + + // The OOP Wrapper + // --------------- + + // If Underscore is called as a function, it returns a wrapped object that + // can be used OO-style. This wrapper holds altered versions of all the + // underscore functions. Wrapped objects may be chained. + var wrapper = function(obj) { this._wrapped = obj; }; + + // Expose `wrapper.prototype` as `_.prototype` + _.prototype = wrapper.prototype; + + // Helper function to continue chaining intermediate results. + var result = function(obj, chain) { + return chain ? _(obj).chain() : obj; + }; + + // A method to easily add functions to the OOP wrapper. + var addToWrapper = function(name, func) { + wrapper.prototype[name] = function() { + var args = slice.call(arguments); + unshift.call(args, this._wrapped); + return result(func.apply(_, args), this._chain); + }; + }; + + // Add all of the Underscore functions to the wrapper object. + _.mixin(_); + + // Add all mutator Array functions to the wrapper. + each(['pop', 'push', 'reverse', 'shift', 'sort', 'splice', 'unshift'], function(name) { + var method = ArrayProto[name]; + wrapper.prototype[name] = function() { + var wrapped = this._wrapped; + method.apply(wrapped, arguments); + var length = wrapped.length; + if ((name == 'shift' || name == 'splice') && length === 0) delete wrapped[0]; + return result(wrapped, this._chain); + }; + }); + + // Add all accessor Array functions to the wrapper. + each(['concat', 'join', 'slice'], function(name) { + var method = ArrayProto[name]; + wrapper.prototype[name] = function() { + return result(method.apply(this._wrapped, arguments), this._chain); + }; + }); + + // Start chaining a wrapped Underscore object. + wrapper.prototype.chain = function() { + this._chain = true; + return this; + }; + + // Extracts the result from a wrapped and chained object. + wrapper.prototype.value = function() { + return this._wrapped; + }; + +}).call(this); diff --git a/htdocs/js/lib/webwork/components/backbone/test/vendor/zepto-0.6.js b/htdocs/js/lib/webwork/components/backbone/test/vendor/zepto-0.6.js new file mode 100644 index 000000000..e1e458146 --- /dev/null +++ b/htdocs/js/lib/webwork/components/backbone/test/vendor/zepto-0.6.js @@ -0,0 +1,692 @@ +(function(undefined){ + if (String.prototype.trim === undefined) // fix for iOS 3.2 + String.prototype.trim = function(){ return this.replace(/^\s+/, '').replace(/\s+$/, '') }; + + // For iOS 3.x + // from https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/reduce + if (Array.prototype.reduce === undefined) + Array.prototype.reduce = function(fun){ + if(this === void 0 || this === null) throw new TypeError(); + var t = Object(this), len = t.length >>> 0, k = 0, accumulator; + if(typeof fun != 'function') throw new TypeError(); + if(len == 0 && arguments.length == 1) throw new TypeError(); + + if(arguments.length >= 2) + accumulator = arguments[1]; + else + do{ + if(k in t){ + accumulator = t[k++]; + break; + } + if(++k >= len) throw new TypeError(); + } while (true); + + while (k < len){ + if(k in t) accumulator = fun.call(undefined, accumulator, t[k], k, t); + k++; + } + return accumulator; + }; + +})(); +var Zepto = (function() { + var undefined, key, css, $$, classList, + emptyArray = [], slice = emptyArray.slice, + document = window.document, + elementDisplay = {}, classCache = {}, + getComputedStyle = document.defaultView.getComputedStyle, + fragmentRE = /^\s*<[^>]+>/, + container = document.createElement('div'); + + function isF(value) { return ({}).toString.call(value) == "[object Function]" } + function isO(value) { return value instanceof Object } + function isA(value) { return value instanceof Array } + + function compact(array) { return array.filter(function(item){ return item !== undefined && item !== null }) } + function flatten(array) { return [].concat.apply([], array) } + function camelize(str) { return str.replace(/-+(.)?/g, function(match, chr){ return chr ? chr.toUpperCase() : '' }) } + function uniq(array) { return array.filter(function(item,index,array){ return array.indexOf(item) == index }) } + + function classRE(name){ + return name in classCache ? + classCache[name] : (classCache[name] = new RegExp('(^|\\s)' + name + '(\\s|$)')); + } + + function defaultDisplay(nodeName) { + var element, display; + if (!elementDisplay[nodeName]) { + element = document.createElement(nodeName); + document.body.insertAdjacentElement("beforeEnd", element); + display = getComputedStyle(element, '').getPropertyValue("display"); + element.parentNode.removeChild(element); + display == "none" && (display = "block"); + elementDisplay[nodeName] = display; + } + return elementDisplay[nodeName]; + } + + function fragment(html) { + container.innerHTML = ('' + html).trim(); + return slice.call(container.childNodes); + } + + function Z(dom, selector){ + dom = dom || emptyArray; + dom.__proto__ = Z.prototype; + dom.selector = selector || ''; + return dom; + } + + function $(selector, context){ + if (!selector) return Z(); + if (context !== undefined) return $(context).find(selector); + else if (isF(selector)) return $(document).ready(selector); + else if (selector instanceof Z) return selector; + else { + var dom; + if (isA(selector)) dom = compact(selector); + else if (selector instanceof Element || selector === window || selector === document) + dom = [selector], selector = null; + else if (fragmentRE.test(selector)) dom = fragment(selector); + else if (selector.nodeType && selector.nodeType == 3) dom = [selector]; + else dom = $$(document, selector); + return Z(dom, selector); + } + } + + $.extend = function(target, source){ for (key in source) target[key] = source[key]; return target } + $.qsa = $$ = function(element, selector){ return slice.call(element.querySelectorAll(selector)) } + + function filtered(nodes, selector){ + return selector === undefined ? $(nodes) : $(nodes).filter(selector); + } + + function funcArg(context, arg, idx, payload){ + return isF(arg) ? arg.call(context, idx, payload) : arg; + } + + $.isFunction = isF; + $.isObject = isO; + $.isArray = isA; + + $.fn = { + forEach: emptyArray.forEach, + map: emptyArray.map, + reduce: emptyArray.reduce, + push: emptyArray.push, + indexOf: emptyArray.indexOf, + concat: emptyArray.concat, + ready: function(callback){ + if (document.readyState == 'complete' || document.readyState == 'loaded') callback(); + document.addEventListener('DOMContentLoaded', callback, false); return this; + }, + get: function(idx){ return idx === undefined ? this : this[idx] }, + size: function(){ return this.length }, + remove: function(){ return this.each(function(){ this.parentNode.removeChild(this) }) }, + each: function(callback){ + this.forEach(function(el, idx){ callback.call(el, idx, el) }); + return this; + }, + filter: function(selector){ + return $([].filter.call(this, function(element){ + return $$(element.parentNode, selector).indexOf(element) >= 0; + })); + }, + add:function(selector,context){ + return $(uniq(this.concat($(selector,context)))); + }, + is: function(selector){ + return this.length > 0 && $(this[0]).filter(selector).length > 0; + }, + not: function(selector){ + var nodes=[]; + if (isF(selector) && selector.call !== undefined) + this.each(function(idx){ + if (!selector.call(this,idx)) nodes.push(this); + }); + else { + var ignores = slice.call( + typeof selector == 'string' ? + this.filter(selector) : + selector instanceof NodeList ? selector : $(selector)); + slice.call(this).forEach(function(el){ + if (ignores.indexOf(el) < 0) nodes.push(el); + }); + } + return $(nodes); + }, + eq: function(idx){ return $(this[idx]) }, + first: function(){ return $(this[0]) }, + last: function(){ return $(this[this.length - 1]) }, + find: function(selector){ + var result; + if (this.length == 1) result = $$(this[0], selector); + else result = flatten(this.map(function(el){ return $$(el, selector) })); + return $(result); + }, + closest: function(selector, context){ + var node = this[0], nodes = $$(context !== undefined ? context : document, selector); + if (nodes.length === 0) node = null; + while(node && node !== document && nodes.indexOf(node) < 0) node = node.parentNode; + return $(node !== document && node); + }, + parents: function(selector){ + var ancestors = [], nodes = this; + while (nodes.length > 0) + nodes = compact(nodes.map(function(node){ + if ((node = node.parentNode) && node !== document && ancestors.indexOf(node) < 0) { + ancestors.push(node); + return node; + } + })); + return filtered(ancestors, selector); + }, + parent: function(selector){ + return filtered(uniq(compact(this.pluck('parentNode'))), selector); + }, + children: function(selector){ + return filtered(flatten(this.map(function(el){ return slice.call(el.children) })), selector); + }, + siblings: function(selector){ + return filtered(flatten(this.map(function(el){ + return slice.call(el.parentNode.children).filter(function(child){ return child!==el }); + })), selector); + }, + empty: function(){ return this.each(function(){ this.innerHTML = '' }) }, + pluck: function(property){ return this.map(function(element){ return element[property] }) }, + show: function(){ + return this.each(function() { + this.style.display == "none" && (this.style.display = null); + if (getComputedStyle(this, '').getPropertyValue("display") == "none") { + this.style.display = defaultDisplay(this.nodeName) + } + }) + }, + replaceWith: function(newContent) { + return this.each(function() { + var element = $(this), + prev = element.prev(); + element.remove(); + prev.after(newContent); + }); + }, + hide: function(){ + return this.css("display", "none") + }, + toggle: function(){ + return this.css("display") == "none" ? this.show() : this.hide(); + }, + prev: function(){ return $(this.pluck('previousElementSibling')) }, + next: function(){ return $(this.pluck('nextElementSibling')) }, + html: function(html){ + return html === undefined ? + (this.length > 0 ? this[0].innerHTML : null) : + this.each(function(idx){ this.innerHTML = funcArg(this, html, idx, this.innerHTML) }); + }, + text: function(text){ + return text === undefined ? + (this.length > 0 ? this[0].innerText : null) : + this.each(function(){ this.innerText = text }); + }, + attr: function(name, value){ + return (typeof name == 'string' && value === undefined) ? + (this.length > 0 && this[0].nodeName == 'INPUT' && this[0].type == 'text' && name == 'value') ? (this.val()) : + (this.length > 0 ? this[0].getAttribute(name) || (name in this[0] ? this[0][name] : undefined) : undefined) : + this.each(function(idx){ + if (isO(name)) for (key in name) this.setAttribute(key, name[key]) + else this.setAttribute(name, funcArg(this, value, idx, this.getAttribute(name))); + }); + }, + removeAttr: function(name) { + return this.each(function() { this.removeAttribute(name); }); + }, + data: function(name, value){ + return this.attr('data-' + name, value); + }, + val: function(value){ + return (value === undefined) ? + (this.length > 0 ? this[0].value : null) : + this.each(function(){ + this.value = value; + }); + }, + offset: function(){ + if(this.length==0) return null; + var obj = this[0].getBoundingClientRect(); + return { + left: obj.left + document.body.scrollLeft, + top: obj.top + document.body.scrollTop, + width: obj.width, + height: obj.height + }; + }, + css: function(property, value){ + if (value === undefined && typeof property == 'string') + return this[0].style[camelize(property)] || getComputedStyle(this[0], '').getPropertyValue(property); + css = ''; + for (key in property) css += key + ':' + property[key] + ';'; + if (typeof property == 'string') css = property + ':' + value; + return this.each(function() { this.style.cssText += ';' + css }); + }, + index: function(element){ + return this.indexOf($(element)[0]); + }, + hasClass: function(name){ + return classRE(name).test(this[0].className); + }, + addClass: function(name){ + return this.each(function(idx) { + classList = []; + var cls = this.className, newName = funcArg(this, name, idx, cls); + newName.split(/\s+/g).forEach(function(klass) { + if (!$(this).hasClass(klass)) { + classList.push(klass) + } + }, this); + classList.length && (this.className += (cls ? " " : "") + classList.join(" ")) + }) + }, + removeClass: function(name){ + return this.each(function(idx) { + classList = this.className; + funcArg(this, name, idx, classList).split(/\s+/g).forEach(function(klass) { + classList = classList.replace(classRE(klass), " ") + }); + this.className = classList.trim() + }) + }, + toggleClass: function(name, when){ + return this.each(function(idx){ + var cls = this.className, newName = funcArg(this, name, idx, cls); + ((when !== undefined && !when) || $(this).hasClass(newName)) ? + $(this).removeClass(newName) : $(this).addClass(newName) + }); + }, + submit: function () { + return this.each(function () { + try { + // Submit first form element + this.submit(); + return; + } catch(e) {}; + }); + } + }; + + ['width', 'height'].forEach(function(property){ + $.fn[property] = function(){ var offset = this.offset(); return offset ? offset[property] : null } + }); + + var adjacencyOperators = [ 'prepend', 'after', 'before', 'append' ]; + function insert(operator, element, other) { + var parent = (!operator || operator == 3) ? element : element.parentNode; + parent.insertBefore(other, + !operator ? parent.firstChild : // prepend + operator == 1 ? element.nextSibling : // after + operator == 2 ? element : // before + null); // append + } + + adjacencyOperators.forEach(function(key, operator) { + $.fn[key] = function(html){ + if (typeof(html) != 'object') + html = fragment(html); + + return this.each(function(index, element){ + if (html.length || html instanceof Z) { + dom = html; + for (var i=0; i= 200 && xhr.status < 300) || xhr.status == 0) { + if (mime == 'application/json') { + try { result = JSON.parse(xhr.responseText); } + catch (e) { error = e; } + } + else result = xhr.responseText; + if (error) settings.error(xhr, 'parsererror', error); + else settings.success(result, 'success', xhr); + } else { + error = true; + settings.error(xhr, 'error'); + } + settings.complete(xhr, error ? 'error' : 'success'); + } + }; + + xhr.open(settings.type, settings.url, true); + if (settings.beforeSend(xhr, settings) === false) { + xhr.abort(); + return false; + } + + if (settings.contentType) settings.headers['Content-Type'] = settings.contentType; + for (name in settings.headers) xhr.setRequestHeader(name, settings.headers[name]); + xhr.send(settings.data); + + return xhr; + }; + + $.get = function(url, success){ $.ajax({ url: url, success: success }) }; + $.post = function(url, data, success, dataType){ + if ($.isFunction(data)) dataType = dataType || success, success = data, data = null; + $.ajax({ type: 'POST', url: url, data: data, success: success, dataType: dataType }); + }; + $.getJSON = function(url, success){ $.ajax({ url: url, success: success, dataType: 'json' }) }; + + $.fn.load = function(url, success){ + if (!this.length) return this; + var self = this, parts = url.split(/\s/), selector; + if (parts.length > 1) url = parts[0], selector = parts[1]; + $.get(url, function(response){ + self.html(selector ? + $(document.createElement('div')).html(response).find(selector).html() + : response); + success && success(); + }); + return this; + }; + + $.param = function(obj, v){ + var result = [], add = function(key, value){ + result.push(encodeURIComponent(v ? v + '[' + key + ']' : key) + + '=' + encodeURIComponent(value)); + }, + isObjArray = $.isArray(obj); + + for(key in obj) + if(isObject(obj[key])) + result.push($.param(obj[key], (v ? v + '[' + key + ']' : key))); + else + add(isObjArray ? '' : key, obj[key]); + + return result.join('&').replace('%20', '+'); + }; +})(Zepto); +(function($){ + var touch = {}, touchTimeout; + + function parentIfText(node){ + return 'tagName' in node ? node : node.parentNode; + } + + function swipeDirection(x1, x2, y1, y2){ + var xDelta = Math.abs(x1 - x2), yDelta = Math.abs(y1 - y2); + if (xDelta >= yDelta) { + return (x1 - x2 > 0 ? 'Left' : 'Right'); + } else { + return (y1 - y2 > 0 ? 'Up' : 'Down'); + } + } + + $(document).ready(function(){ + $(document.body).bind('touchstart', function(e){ + var now = Date.now(), delta = now - (touch.last || now); + touch.target = parentIfText(e.touches[0].target); + touchTimeout && clearTimeout(touchTimeout); + touch.x1 = e.touches[0].pageX; + touch.y1 = e.touches[0].pageY; + if (delta > 0 && delta <= 250) touch.isDoubleTap = true; + touch.last = now; + }).bind('touchmove', function(e){ + touch.x2 = e.touches[0].pageX; + touch.y2 = e.touches[0].pageY; + }).bind('touchend', function(e){ + if (touch.isDoubleTap) { + $(touch.target).trigger('doubleTap'); + touch = {}; + } else if (touch.x2 > 0 || touch.y2 > 0) { + (Math.abs(touch.x1 - touch.x2) > 30 || Math.abs(touch.y1 - touch.y2) > 30) && + $(touch.target).trigger('swipe') && + $(touch.target).trigger('swipe' + (swipeDirection(touch.x1, touch.x2, touch.y1, touch.y2))); + touch.x1 = touch.x2 = touch.y1 = touch.y2 = touch.last = 0; + } else if ('last' in touch) { + touchTimeout = setTimeout(function(){ + touchTimeout = null; + $(touch.target).trigger('tap') + touch = {}; + }, 250); + } + }).bind('touchcancel', function(){ touch = {} }); + }); + + ['swipe', 'swipeLeft', 'swipeRight', 'swipeUp', 'swipeDown', 'doubleTap', 'tap'].forEach(function(m){ + $.fn[m] = function(callback){ return this.bind(m, callback) } + }); +})(Zepto); diff --git a/htdocs/js/lib/webwork/components/backbone/test/view.js b/htdocs/js/lib/webwork/components/backbone/test/view.js new file mode 100644 index 000000000..eda89b236 --- /dev/null +++ b/htdocs/js/lib/webwork/components/backbone/test/view.js @@ -0,0 +1,217 @@ +$(document).ready(function() { + + var view; + + module("Backbone.View", { + + setup: function() { + view = new Backbone.View({ + id : 'test-view', + className : 'test-view' + }); + } + + }); + + test("View: constructor", function() { + equal(view.el.id, 'test-view'); + equal(view.el.className, 'test-view'); + equal(view.options.id, 'test-view'); + equal(view.options.className, 'test-view'); + }); + + test("View: jQuery", function() { + view.setElement(document.body); + ok(view.$('#qunit-header a').get(0).innerHTML.match(/Backbone Test Suite/)); + ok(view.$('#qunit-header a').get(1).innerHTML.match(/Backbone Speed Suite/)); + }); + + test("View: make", function() { + var div = view.make('div', {id: 'test-div'}, "one two three"); + equal(div.tagName.toLowerCase(), 'div'); + equal(div.id, 'test-div'); + equal($(div).text(), 'one two three'); + }); + + test("View: make can take falsy values for content", function() { + var div = view.make('div', {id: 'test-div'}, 0); + equal($(div).text(), '0'); + + var div = view.make('div', {id: 'test-div'}, ''); + equal($(div).text(), ''); + }); + + test("View: initialize", function() { + var View = Backbone.View.extend({ + initialize: function() { + this.one = 1; + } + }); + var view = new View; + equal(view.one, 1); + }); + + test("View: delegateEvents", function() { + var counter = 0; + var counter2 = 0; + view.setElement(document.body); + view.increment = function(){ counter++; }; + view.$el.bind('click', function(){ counter2++; }); + var events = {"click #qunit-banner": "increment"}; + view.delegateEvents(events); + $('#qunit-banner').trigger('click'); + equal(counter, 1); + equal(counter2, 1); + $('#qunit-banner').trigger('click'); + equal(counter, 2); + equal(counter2, 2); + view.delegateEvents(events); + $('#qunit-banner').trigger('click'); + equal(counter, 3); + equal(counter2, 3); + }); + + test("View: delegateEvents allows functions for callbacks", function() { + view.counter = 0; + view.setElement("#qunit-banner"); + var events = {"click": function() { this.counter++; }}; + view.delegateEvents(events); + $('#qunit-banner').trigger('click'); + equal(view.counter, 1); + $('#qunit-banner').trigger('click'); + equal(view.counter, 2); + view.delegateEvents(events); + $('#qunit-banner').trigger('click'); + equal(view.counter, 3); + }); + + test("View: undelegateEvents", function() { + var counter = 0; + var counter2 = 0; + view.setElement(document.body); + view.increment = function(){ counter++; }; + $(view.el).unbind('click'); + $(view.el).bind('click', function(){ counter2++; }); + var events = {"click #qunit-userAgent": "increment"}; + view.delegateEvents(events); + $('#qunit-userAgent').trigger('click'); + equal(counter, 1); + equal(counter2, 1); + view.undelegateEvents(); + $('#qunit-userAgent').trigger('click'); + equal(counter, 1); + equal(counter2, 2); + view.delegateEvents(events); + $('#qunit-userAgent').trigger('click'); + equal(counter, 2); + equal(counter2, 3); + }); + + test("View: _ensureElement with DOM node el", function() { + var ViewClass = Backbone.View.extend({ + el: document.body + }); + var view = new ViewClass; + equal(view.el, document.body); + }); + + test("View: _ensureElement with string el", function() { + var ViewClass = Backbone.View.extend({ + el: "body" + }); + var view = new ViewClass; + equal(view.el, document.body); + + ViewClass = Backbone.View.extend({ + el: "body > h2" + }); + view = new ViewClass; + equal(view.el, $("#qunit-banner").get(0)); + + ViewClass = Backbone.View.extend({ + el: "#nonexistent" + }); + view = new ViewClass; + ok(!view.el); + }); + + test("View: with attributes", function() { + var view = new Backbone.View({attributes : {'class': 'one', id: 'two'}}); + equal(view.el.className, 'one'); + equal(view.el.id, 'two'); + }); + + test("View: with attributes as a function", function() { + var viewClass = Backbone.View.extend({ + attributes: function() { + return {'class': 'dynamic'}; + } + }); + equal((new viewClass).el.className, 'dynamic'); + }); + + test("View: multiple views per element", function() { + var count = 0, ViewClass = Backbone.View.extend({ + el: $("body"), + events: { + "click": "click" + }, + click: function() { + count++; + } + }); + + var view1 = new ViewClass; + $("body").trigger("click"); + equal(1, count); + + var view2 = new ViewClass; + $("body").trigger("click"); + equal(3, count); + + view1.delegateEvents(); + $("body").trigger("click"); + equal(5, count); + }); + + test("View: custom events, with namespaces", function() { + var count = 0; + var ViewClass = Backbone.View.extend({ + el: $('body'), + events: function() { + return {"fake$event.namespaced": "run"}; + }, + run: function() { + count++; + } + }); + + var view = new ViewClass; + $('body').trigger('fake$event').trigger('fake$event'); + equal(count, 2); + $('body').unbind('.namespaced'); + $('body').trigger('fake$event'); + equal(count, 2); + }); + + test("#1048 - setElement uses provided object.", function() { + var $el = $('body'); + var view = new Backbone.View({el: $el}); + ok(view.$el === $el); + view.setElement($el = $($el)); + ok(view.$el === $el); + }); + + test("#986 - Undelegate before changing element.", 1, function() { + var a = $(''); + var b = $(''); + var View = Backbone.View.extend({ + events: {click: function(e) { ok(view.el === e.target); }} + }); + var view = new View({el: a}); + view.setElement(b); + a.trigger('click'); + b.trigger('click'); + }); + +}); diff --git a/htdocs/js/lib/webwork/components/jquery/component.json b/htdocs/js/lib/webwork/components/jquery/component.json new file mode 100644 index 000000000..529c419f5 --- /dev/null +++ b/htdocs/js/lib/webwork/components/jquery/component.json @@ -0,0 +1,13 @@ +{ + "name": "jquery", + "version": "1.8.1", + "main": "./jquery.js", + "dependencies": {}, + "_id": "jquery@1.8.1", + "readme": "ERROR: No README.md file found!", + "description": "ERROR: No README.md file found!", + "repository": { + "type": "git", + "url": "git://github.com/components/jquery.git" + } +} \ No newline at end of file diff --git a/htdocs/js/lib/webwork/components/jquery/jquery-1.8.3.js b/htdocs/js/lib/webwork/components/jquery/jquery-1.8.3.js new file mode 100755 index 000000000..a86bf797a --- /dev/null +++ b/htdocs/js/lib/webwork/components/jquery/jquery-1.8.3.js @@ -0,0 +1,9472 @@ +/*! + * jQuery JavaScript Library v1.8.3 + * http://jquery.com/ + * + * Includes Sizzle.js + * http://sizzlejs.com/ + * + * Copyright 2012 jQuery Foundation and other contributors + * Released under the MIT license + * http://jquery.org/license + * + * Date: Tue Nov 13 2012 08:20:33 GMT-0500 (Eastern Standard Time) + */ +(function( window, undefined ) { +var + // A central reference to the root jQuery(document) + rootjQuery, + + // The deferred used on DOM ready + readyList, + + // Use the correct document accordingly with window argument (sandbox) + document = window.document, + location = window.location, + navigator = window.navigator, + + // Map over jQuery in case of overwrite + _jQuery = window.jQuery, + + // Map over the $ in case of overwrite + _$ = window.$, + + // Save a reference to some core methods + core_push = Array.prototype.push, + core_slice = Array.prototype.slice, + core_indexOf = Array.prototype.indexOf, + core_toString = Object.prototype.toString, + core_hasOwn = Object.prototype.hasOwnProperty, + core_trim = String.prototype.trim, + + // Define a local copy of jQuery + jQuery = function( selector, context ) { + // The jQuery object is actually just the init constructor 'enhanced' + return new jQuery.fn.init( selector, context, rootjQuery ); + }, + + // Used for matching numbers + core_pnum = /[\-+]?(?:\d*\.|)\d+(?:[eE][\-+]?\d+|)/.source, + + // Used for detecting and trimming whitespace + core_rnotwhite = /\S/, + core_rspace = /\s+/, + + // Make sure we trim BOM and NBSP (here's looking at you, Safari 5.0 and IE) + rtrim = /^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g, + + // A simple way to check for HTML strings + // Prioritize #id over to avoid XSS via location.hash (#9521) + rquickExpr = /^(?:[^#<]*(<[\w\W]+>)[^>]*$|#([\w\-]*)$)/, + + // Match a standalone tag + rsingleTag = /^<(\w+)\s*\/?>(?:<\/\1>|)$/, + + // JSON RegExp + rvalidchars = /^[\],:{}\s]*$/, + rvalidbraces = /(?:^|:|,)(?:\s*\[)+/g, + rvalidescape = /\\(?:["\\\/bfnrt]|u[\da-fA-F]{4})/g, + rvalidtokens = /"[^"\\\r\n]*"|true|false|null|-?(?:\d\d*\.|)\d+(?:[eE][\-+]?\d+|)/g, + + // Matches dashed string for camelizing + rmsPrefix = /^-ms-/, + rdashAlpha = /-([\da-z])/gi, + + // Used by jQuery.camelCase as callback to replace() + fcamelCase = function( all, letter ) { + return ( letter + "" ).toUpperCase(); + }, + + // The ready event handler and self cleanup method + DOMContentLoaded = function() { + if ( document.addEventListener ) { + document.removeEventListener( "DOMContentLoaded", DOMContentLoaded, false ); + jQuery.ready(); + } else if ( document.readyState === "complete" ) { + // we're here because readyState === "complete" in oldIE + // which is good enough for us to call the dom ready! + document.detachEvent( "onreadystatechange", DOMContentLoaded ); + jQuery.ready(); + } + }, + + // [[Class]] -> type pairs + class2type = {}; + +jQuery.fn = jQuery.prototype = { + constructor: jQuery, + init: function( selector, context, rootjQuery ) { + var match, elem, ret, doc; + + // Handle $(""), $(null), $(undefined), $(false) + if ( !selector ) { + return this; + } + + // Handle $(DOMElement) + if ( selector.nodeType ) { + this.context = this[0] = selector; + this.length = 1; + return this; + } + + // Handle HTML strings + if ( typeof selector === "string" ) { + 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 = rquickExpr.exec( selector ); + } + + // Match html or make sure no context is specified for #id + if ( match && (match[1] || !context) ) { + + // HANDLE: $(html) -> $(array) + if ( match[1] ) { + context = context instanceof jQuery ? context[0] : context; + doc = ( context && context.nodeType ? context.ownerDocument || context : document ); + + // scripts is true for back-compat + selector = jQuery.parseHTML( match[1], doc, true ); + if ( rsingleTag.test( match[1] ) && jQuery.isPlainObject( context ) ) { + this.attr.call( selector, context, true ); + } + + 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.8.3", + + // 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 core_slice.call( this ); + }, + + // 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 = jQuery.merge( this.constructor(), 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 ) { + // Add the callback + jQuery.ready.promise().done( fn ); + + return this; + }, + + eq: function( i ) { + i = +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( core_slice.apply( this, arguments ), + "slice", core_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: core_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 ) { + + // Abort if there are pending holds or we're already ready + if ( wait === true ? --jQuery.readyWait : jQuery.isReady ) { + return; + } + + // 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").off("ready"); + } + }, + + // 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"; + }, + + isWindow: function( obj ) { + return obj != null && obj == obj.window; + }, + + isNumeric: function( obj ) { + return !isNaN( parseFloat(obj) ) && isFinite( obj ); + }, + + type: function( obj ) { + return obj == null ? + String( obj ) : + class2type[ core_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; + } + + try { + // Not own constructor property must be Object + if ( obj.constructor && + !core_hasOwn.call(obj, "constructor") && + !core_hasOwn.call(obj.constructor.prototype, "isPrototypeOf") ) { + return false; + } + } catch ( e ) { + // IE8,9 Will throw exceptions on certain host objects #9897 + 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 || core_hasOwn.call( obj, key ); + }, + + isEmptyObject: function( obj ) { + var name; + for ( name in obj ) { + return false; + } + return true; + }, + + error: function( msg ) { + throw new Error( msg ); + }, + + // data: string of html + // context (optional): If specified, the fragment will be created in this context, defaults to document + // scripts (optional): If true, will include scripts passed in the html string + parseHTML: function( data, context, scripts ) { + var parsed; + if ( !data || typeof data !== "string" ) { + return null; + } + if ( typeof context === "boolean" ) { + scripts = context; + context = 0; + } + context = context || document; + + // Single tag + if ( (parsed = rsingleTag.exec( data )) ) { + return [ context.createElement( parsed[1] ) ]; + } + + parsed = jQuery.buildFragment( [ data ], context, scripts ? null : [] ); + return jQuery.merge( [], + (parsed.cacheable ? jQuery.clone( parsed.fragment ) : parsed.fragment).childNodes ); + }, + + parseJSON: function( data ) { + if ( !data || typeof data !== "string") { + 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 + parseXML: function( data ) { + var xml, tmp; + if ( !data || typeof data !== "string" ) { + return null; + } + try { + 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 ); + } + } catch( e ) { + xml = undefined; + } + if ( !xml || !xml.documentElement || xml.getElementsByTagName( "parsererror" ).length ) { + 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 && core_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 ); + } + }, + + // Convert dashed to camelCase; used by the css and data modules + // Microsoft forgot to hump their vendor prefix (#9572) + camelCase: function( string ) { + return string.replace( rmsPrefix, "ms-" ).replace( rdashAlpha, fcamelCase ); + }, + + nodeName: function( elem, name ) { + return elem.nodeName && elem.nodeName.toLowerCase() === name.toLowerCase(); + }, + + // args is for internal usage only + each: function( obj, callback, args ) { + var name, + i = 0, + length = obj.length, + isObj = length === undefined || jQuery.isFunction( obj ); + + if ( args ) { + if ( isObj ) { + for ( name in obj ) { + if ( callback.apply( obj[ name ], args ) === false ) { + break; + } + } + } else { + for ( ; i < length; ) { + if ( callback.apply( obj[ i++ ], args ) === false ) { + break; + } + } + } + + // A special, fast, case for the most common use of each + } else { + if ( isObj ) { + for ( name in obj ) { + if ( callback.call( obj[ name ], name, obj[ name ] ) === false ) { + break; + } + } + } else { + for ( ; i < length; ) { + if ( callback.call( obj[ i ], i, obj[ i++ ] ) === false ) { + break; + } + } + } + } + + return obj; + }, + + // Use native String.trim function wherever possible + trim: core_trim && !core_trim.call("\uFEFF\xA0") ? + function( text ) { + return text == null ? + "" : + core_trim.call( text ); + } : + + // Otherwise use our own trimming functionality + function( text ) { + return text == null ? + "" : + ( text + "" ).replace( rtrim, "" ); + }, + + // results is for internal usage only + makeArray: function( arr, results ) { + var type, + ret = results || []; + + if ( arr != null ) { + // The window, strings (and functions) also have 'length' + // Tweaked logic slightly to handle Blackberry 4.7 RegExp issues #6930 + type = jQuery.type( arr ); + + if ( arr.length == null || type === "string" || type === "function" || type === "regexp" || jQuery.isWindow( arr ) ) { + core_push.call( ret, arr ); + } else { + jQuery.merge( ret, arr ); + } + } + + return ret; + }, + + inArray: function( elem, arr, i ) { + var len; + + if ( arr ) { + if ( core_indexOf ) { + return core_indexOf.call( arr, elem, i ); + } + + len = arr.length; + i = i ? i < 0 ? Math.max( 0, len + i ) : i : 0; + + for ( ; i < len; i++ ) { + // Skip accessing in sparse arrays + if ( i in arr && arr[ i ] === elem ) { + return i; + } + } + } + + return -1; + }, + + merge: function( first, second ) { + var l = second.length, + i = first.length, + j = 0; + + if ( typeof l === "number" ) { + for ( ; 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 retVal, + ret = [], + i = 0, + length = elems.length; + inv = !!inv; + + // Go through the array, only saving the items + // that pass the validator function + for ( ; 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 ) { + var tmp, args, proxy; + + if ( typeof context === "string" ) { + 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 + args = core_slice.call( arguments, 2 ); + proxy = function() { + return fn.apply( context, args.concat( core_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 || jQuery.guid++; + + return proxy; + }, + + // Multifunctional method to get and set values of a collection + // The value/s can optionally be executed if it's a function + access: function( elems, fn, key, value, chainable, emptyGet, pass ) { + var exec, + bulk = key == null, + i = 0, + length = elems.length; + + // Sets many values + if ( key && typeof key === "object" ) { + for ( i in key ) { + jQuery.access( elems, fn, i, key[i], 1, emptyGet, value ); + } + chainable = 1; + + // Sets one value + } else if ( value !== undefined ) { + // Optionally, function values get executed if exec is true + exec = pass === undefined && jQuery.isFunction( value ); + + if ( bulk ) { + // Bulk operations only iterate when executing function values + if ( exec ) { + exec = fn; + fn = function( elem, key, value ) { + return exec.call( jQuery( elem ), value ); + }; + + // Otherwise they run against the entire set + } else { + fn.call( elems, value ); + fn = null; + } + } + + if ( fn ) { + for (; i < length; i++ ) { + fn( elems[i], key, exec ? value.call( elems[i], i, fn( elems[i], key ) ) : value, pass ); + } + } + + chainable = 1; + } + + return chainable ? + elems : + + // Gets + bulk ? + fn.call( elems ) : + length ? fn( elems[0], key ) : emptyGet; + }, + + now: function() { + return ( new Date() ).getTime(); + } +}); + +jQuery.ready.promise = function( obj ) { + if ( !readyList ) { + + readyList = jQuery.Deferred(); + + // Catch cases where $(document).ready() is called after the browser event has already occurred. + // we once tried to use readyState "interactive" here, but it caused issues like the one + // discovered by ChrisS here: http://bugs.jquery.com/ticket/12282#comment:15 + if ( document.readyState === "complete" ) { + // Handle it asynchronously to allow scripts the opportunity to delay ready + setTimeout( jQuery.ready, 1 ); + + // Standards-based browsers support DOMContentLoaded + } else 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 { + // 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 top = false; + + try { + top = window.frameElement == null && document.documentElement; + } catch(e) {} + + if ( top && top.doScroll ) { + (function doScrollCheck() { + if ( !jQuery.isReady ) { + + try { + // Use the trick by Diego Perini + // http://javascript.nwbox.com/IEContentLoaded/ + top.doScroll("left"); + } catch(e) { + return setTimeout( doScrollCheck, 50 ); + } + + // and execute any waiting functions + jQuery.ready(); + } + })(); + } + } + } + return readyList.promise( obj ); +}; + +// Populate the class2type map +jQuery.each("Boolean Number String Function Array Date RegExp Object".split(" "), function(i, name) { + class2type[ "[object " + name + "]" ] = name.toLowerCase(); +}); + +// All jQuery objects should point back to these +rootjQuery = jQuery(document); +// String to Object options format cache +var optionsCache = {}; + +// Convert String-formatted options into Object-formatted ones and store in cache +function createOptions( options ) { + var object = optionsCache[ options ] = {}; + jQuery.each( options.split( core_rspace ), function( _, flag ) { + object[ flag ] = true; + }); + return object; +} + +/* + * Create a callback list using the following parameters: + * + * options: an optional list of space-separated options that will change how + * the callback list behaves or a more traditional option object + * + * By default a callback list will act like an event callback list and can be + * "fired" multiple times. + * + * Possible options: + * + * once: will ensure the callback list can only be fired once (like a Deferred) + * + * memory: will keep track of previous values and will call any callback added + * after the list has been fired right away with the latest "memorized" + * values (like a Deferred) + * + * unique: will ensure a callback can only be added once (no duplicate in the list) + * + * stopOnFalse: interrupt callings when a callback returns false + * + */ +jQuery.Callbacks = function( options ) { + + // Convert options from String-formatted to Object-formatted if needed + // (we check in cache first) + options = typeof options === "string" ? + ( optionsCache[ options ] || createOptions( options ) ) : + jQuery.extend( {}, options ); + + var // Last fire value (for non-forgettable lists) + memory, + // Flag to know if list was already fired + fired, + // Flag to know if list is currently firing + firing, + // First callback to fire (used internally by add and fireWith) + firingStart, + // End of the loop when firing + firingLength, + // Index of currently firing callback (modified by remove if needed) + firingIndex, + // Actual callback list + list = [], + // Stack of fire calls for repeatable lists + stack = !options.once && [], + // Fire callbacks + fire = function( data ) { + memory = options.memory && data; + fired = true; + firingIndex = firingStart || 0; + firingStart = 0; + firingLength = list.length; + firing = true; + for ( ; list && firingIndex < firingLength; firingIndex++ ) { + if ( list[ firingIndex ].apply( data[ 0 ], data[ 1 ] ) === false && options.stopOnFalse ) { + memory = false; // To prevent further calls using add + break; + } + } + firing = false; + if ( list ) { + if ( stack ) { + if ( stack.length ) { + fire( stack.shift() ); + } + } else if ( memory ) { + list = []; + } else { + self.disable(); + } + } + }, + // Actual Callbacks object + self = { + // Add a callback or a collection of callbacks to the list + add: function() { + if ( list ) { + // First, we save the current length + var start = list.length; + (function add( args ) { + jQuery.each( args, function( _, arg ) { + var type = jQuery.type( arg ); + if ( type === "function" ) { + if ( !options.unique || !self.has( arg ) ) { + list.push( arg ); + } + } else if ( arg && arg.length && type !== "string" ) { + // Inspect recursively + add( arg ); + } + }); + })( arguments ); + // Do we need to add the callbacks to the + // current firing batch? + if ( firing ) { + firingLength = list.length; + // With memory, if we're not firing then + // we should call right away + } else if ( memory ) { + firingStart = start; + fire( memory ); + } + } + return this; + }, + // Remove a callback from the list + remove: function() { + if ( list ) { + jQuery.each( arguments, function( _, arg ) { + var index; + while( ( index = jQuery.inArray( arg, list, index ) ) > -1 ) { + list.splice( index, 1 ); + // Handle firing indexes + if ( firing ) { + if ( index <= firingLength ) { + firingLength--; + } + if ( index <= firingIndex ) { + firingIndex--; + } + } + } + }); + } + return this; + }, + // Control if a given callback is in the list + has: function( fn ) { + return jQuery.inArray( fn, list ) > -1; + }, + // Remove all callbacks from the list + empty: function() { + list = []; + return this; + }, + // Have the list do nothing anymore + disable: function() { + list = stack = memory = undefined; + return this; + }, + // Is it disabled? + disabled: function() { + return !list; + }, + // Lock the list in its current state + lock: function() { + stack = undefined; + if ( !memory ) { + self.disable(); + } + return this; + }, + // Is it locked? + locked: function() { + return !stack; + }, + // Call all callbacks with the given context and arguments + fireWith: function( context, args ) { + args = args || []; + args = [ context, args.slice ? args.slice() : args ]; + if ( list && ( !fired || stack ) ) { + if ( firing ) { + stack.push( args ); + } else { + fire( args ); + } + } + return this; + }, + // Call all the callbacks with the given arguments + fire: function() { + self.fireWith( this, arguments ); + return this; + }, + // To know if the callbacks have already been called at least once + fired: function() { + return !!fired; + } + }; + + return self; +}; +jQuery.extend({ + + Deferred: function( func ) { + var tuples = [ + // action, add listener, listener list, final state + [ "resolve", "done", jQuery.Callbacks("once memory"), "resolved" ], + [ "reject", "fail", jQuery.Callbacks("once memory"), "rejected" ], + [ "notify", "progress", jQuery.Callbacks("memory") ] + ], + state = "pending", + promise = { + state: function() { + return state; + }, + always: function() { + deferred.done( arguments ).fail( arguments ); + return this; + }, + then: function( /* fnDone, fnFail, fnProgress */ ) { + var fns = arguments; + return jQuery.Deferred(function( newDefer ) { + jQuery.each( tuples, function( i, tuple ) { + var action = tuple[ 0 ], + fn = fns[ i ]; + // deferred[ done | fail | progress ] for forwarding actions to newDefer + deferred[ tuple[1] ]( jQuery.isFunction( fn ) ? + function() { + var returned = fn.apply( this, arguments ); + if ( returned && jQuery.isFunction( returned.promise ) ) { + returned.promise() + .done( newDefer.resolve ) + .fail( newDefer.reject ) + .progress( newDefer.notify ); + } else { + newDefer[ action + "With" ]( this === deferred ? newDefer : this, [ returned ] ); + } + } : + newDefer[ action ] + ); + }); + fns = null; + }).promise(); + }, + // Get a promise for this deferred + // If obj is provided, the promise aspect is added to the object + promise: function( obj ) { + return obj != null ? jQuery.extend( obj, promise ) : promise; + } + }, + deferred = {}; + + // Keep pipe for back-compat + promise.pipe = promise.then; + + // Add list-specific methods + jQuery.each( tuples, function( i, tuple ) { + var list = tuple[ 2 ], + stateString = tuple[ 3 ]; + + // promise[ done | fail | progress ] = list.add + promise[ tuple[1] ] = list.add; + + // Handle state + if ( stateString ) { + list.add(function() { + // state = [ resolved | rejected ] + state = stateString; + + // [ reject_list | resolve_list ].disable; progress_list.lock + }, tuples[ i ^ 1 ][ 2 ].disable, tuples[ 2 ][ 2 ].lock ); + } + + // deferred[ resolve | reject | notify ] = list.fire + deferred[ tuple[0] ] = list.fire; + deferred[ tuple[0] + "With" ] = list.fireWith; + }); + + // Make the deferred a promise + promise.promise( deferred ); + + // Call given func if any + if ( func ) { + func.call( deferred, deferred ); + } + + // All done! + return deferred; + }, + + // Deferred helper + when: function( subordinate /* , ..., subordinateN */ ) { + var i = 0, + resolveValues = core_slice.call( arguments ), + length = resolveValues.length, + + // the count of uncompleted subordinates + remaining = length !== 1 || ( subordinate && jQuery.isFunction( subordinate.promise ) ) ? length : 0, + + // the master Deferred. If resolveValues consist of only a single Deferred, just use that. + deferred = remaining === 1 ? subordinate : jQuery.Deferred(), + + // Update function for both resolve and progress values + updateFunc = function( i, contexts, values ) { + return function( value ) { + contexts[ i ] = this; + values[ i ] = arguments.length > 1 ? core_slice.call( arguments ) : value; + if( values === progressValues ) { + deferred.notifyWith( contexts, values ); + } else if ( !( --remaining ) ) { + deferred.resolveWith( contexts, values ); + } + }; + }, + + progressValues, progressContexts, resolveContexts; + + // add listeners to Deferred subordinates; treat others as resolved + if ( length > 1 ) { + progressValues = new Array( length ); + progressContexts = new Array( length ); + resolveContexts = new Array( length ); + for ( ; i < length; i++ ) { + if ( resolveValues[ i ] && jQuery.isFunction( resolveValues[ i ].promise ) ) { + resolveValues[ i ].promise() + .done( updateFunc( i, resolveContexts, resolveValues ) ) + .fail( deferred.reject ) + .progress( updateFunc( i, progressContexts, progressValues ) ); + } else { + --remaining; + } + } + } + + // if we're not waiting on anything, resolve the master + if ( !remaining ) { + deferred.resolveWith( resolveContexts, resolveValues ); + } + + return deferred.promise(); + } +}); +jQuery.support = (function() { + + var support, + all, + a, + select, + opt, + input, + fragment, + eventName, + i, + isSupported, + clickFn, + div = document.createElement("div"); + + // Setup + div.setAttribute( "className", "t" ); + div.innerHTML = "
      a"; + + // Support tests won't run in some limited or non-browser environments + all = div.getElementsByTagName("*"); + a = div.getElementsByTagName("a")[ 0 ]; + if ( !all || !a || !all.length ) { + return {}; + } + + // First batch of tests + select = document.createElement("select"); + opt = select.appendChild( document.createElement("option") ); + input = div.getElementsByTagName("input")[ 0 ]; + + a.style.cssText = "top:1px;float:left;opacity:.5"; + 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.5/.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", + + // Tests for enctype support on a form (#6743) + enctype: !!document.createElement("form").enctype, + + // Makes sure cloning an html5 element does not cause problems + // Where outerHTML is undefined, this still works + html5Clone: document.createElement("nav").cloneNode( true ).outerHTML !== "<:nav>", + + // jQuery.support.boxModel DEPRECATED in 1.8 since we don't support Quirks Mode + boxModel: ( document.compatMode === "CSS1Compat" ), + + // Will be defined later + submitBubbles: true, + changeBubbles: true, + focusinBubbles: false, + deleteExpando: true, + noCloneEvent: true, + inlineBlockNeedsLayout: false, + shrinkWrapBlocks: false, + reliableMarginRight: true, + boxSizingReliable: true, + pixelPosition: false + }; + + // 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", clickFn = function() { + // Cloning a node shouldn't copy over any + // bound event handlers (IE does this) + support.noCloneEvent = false; + }); + div.cloneNode( true ).fireEvent("onclick"); + div.detachEvent( "onclick", clickFn ); + } + + // Check if a radio maintains its 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" ); + + // #11217 - WebKit loses check when the name is after the checked attribute + input.setAttribute( "name", "t" ); + + div.appendChild( input ); + fragment = document.createDocumentFragment(); + fragment.appendChild( div.lastChild ); + + // WebKit doesn't clone checked state correctly in fragments + support.checkClone = fragment.cloneNode( true ).cloneNode( true ).lastChild.checked; + + // Check if a disconnected checkbox will retain its checked + // value of true after appended to the DOM (IE6/7) + support.appendChecked = input.checked; + + fragment.removeChild( input ); + fragment.appendChild( div ); + + // Technique from Juriy Zaytsev + // http://perfectionkills.com/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: true, + change: true, + focusin: true + }) { + eventName = "on" + i; + isSupported = ( eventName in div ); + if ( !isSupported ) { + div.setAttribute( eventName, "return;" ); + isSupported = ( typeof div[ eventName ] === "function" ); + } + support[ i + "Bubbles" ] = isSupported; + } + } + + // Run tests that need a body at doc ready + jQuery(function() { + var container, div, tds, marginDiv, + divReset = "padding:0;margin:0;border:0;display:block;overflow:hidden;", + body = document.getElementsByTagName("body")[0]; + + if ( !body ) { + // Return for frameset docs that don't have a body + return; + } + + container = document.createElement("div"); + container.style.cssText = "visibility:hidden;border:0;width:0;height:0;position:static;top:0;margin-top:1px"; + body.insertBefore( container, body.firstChild ); + + // Construct the test element + div = document.createElement("div"); + container.appendChild( div ); + + // 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) + div.innerHTML = "
      t
      "; + tds = div.getElementsByTagName("td"); + tds[ 0 ].style.cssText = "padding:0;margin:0;border:0;display:none"; + 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 ); + + // Check box-sizing and margin behavior + div.innerHTML = ""; + div.style.cssText = "box-sizing:border-box;-moz-box-sizing:border-box;-webkit-box-sizing:border-box;padding:1px;border:1px;display:block;width:4px;margin-top:1%;position:absolute;top:1%;"; + support.boxSizing = ( div.offsetWidth === 4 ); + support.doesNotIncludeMarginInBodyOffset = ( body.offsetTop !== 1 ); + + // NOTE: To any future maintainer, we've window.getComputedStyle + // because jsdom on node.js will break without it. + if ( window.getComputedStyle ) { + support.pixelPosition = ( window.getComputedStyle( div, null ) || {} ).top !== "1%"; + support.boxSizingReliable = ( window.getComputedStyle( div, null ) || { width: "4px" } ).width === "4px"; + + // 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 + marginDiv = document.createElement("div"); + marginDiv.style.cssText = div.style.cssText = divReset; + marginDiv.style.marginRight = marginDiv.style.width = "0"; + div.style.width = "1px"; + div.appendChild( marginDiv ); + support.reliableMarginRight = + !parseFloat( ( window.getComputedStyle( marginDiv, null ) || {} ).marginRight ); + } + + if ( typeof div.style.zoom !== "undefined" ) { + // 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.innerHTML = ""; + div.style.cssText = divReset + "width:1px;padding:1px;display:inline;zoom:1"; + support.inlineBlockNeedsLayout = ( div.offsetWidth === 3 ); + + // Check if elements with layout shrink-wrap their children + // (IE 6 does this) + div.style.display = "block"; + div.style.overflow = "visible"; + div.innerHTML = "
      "; + div.firstChild.style.width = "5px"; + support.shrinkWrapBlocks = ( div.offsetWidth !== 3 ); + + container.style.zoom = 1; + } + + // Null elements to avoid leaks in IE + body.removeChild( container ); + container = div = tds = marginDiv = null; + }); + + // Null elements to avoid leaks in IE + fragment.removeChild( div ); + all = a = select = opt = input = fragment = div = null; + + return support; +})(); +var rbrace = /(?:\{[\s\S]*\}|\[[\s\S]*\])$/, + rmultiDash = /([A-Z])/g; + +jQuery.extend({ + cache: {}, + + deletedIds: [], + + // Remove at next major release (1.9/2.0) + 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 thisCache, ret, + internalKey = jQuery.expando, + getByName = typeof name === "string", + + // 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[ internalKey ] : elem[ internalKey ] && internalKey; + + // 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 || !cache[id] || (!pvt && !cache[id].data)) && 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[ internalKey ] = id = jQuery.deletedIds.pop() || jQuery.guid++; + } else { + id = internalKey; + } + } + + if ( !cache[ id ] ) { + cache[ id ] = {}; + + // 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 ] = jQuery.extend( cache[ id ], name ); + } else { + cache[ id ].data = jQuery.extend( cache[ id ].data, name ); + } + } + + thisCache = cache[ id ]; + + // jQuery data() is stored in a separate object inside the object's internal data + // cache in order to avoid key collisions between internal data and user-defined + // data. + if ( !pvt ) { + if ( !thisCache.data ) { + thisCache.data = {}; + } + + thisCache = thisCache.data; + } + + if ( data !== undefined ) { + thisCache[ jQuery.camelCase( name ) ] = data; + } + + // Check for both converted-to-camel and non-converted data property names + // If a data property was specified + if ( getByName ) { + + // First Try to find as-is property data + ret = thisCache[ name ]; + + // Test for null|undefined property data + if ( ret == null ) { + + // Try to find the camelCased property + ret = thisCache[ jQuery.camelCase( name ) ]; + } + } else { + ret = thisCache; + } + + return ret; + }, + + removeData: function( elem, name, pvt /* Internal Use Only */ ) { + if ( !jQuery.acceptData( elem ) ) { + return; + } + + var thisCache, i, l, + + isNode = elem.nodeType, + + // See jQuery.data for more information + cache = isNode ? jQuery.cache : elem, + 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 ) { + + thisCache = pvt ? cache[ id ] : cache[ id ].data; + + if ( thisCache ) { + + // Support array or space separated string names for data keys + if ( !jQuery.isArray( name ) ) { + + // try the string as a key before any manipulation + if ( name in thisCache ) { + name = [ name ]; + } else { + + // split the camel cased version by spaces unless a key with the spaces exists + name = jQuery.camelCase( name ); + if ( name in thisCache ) { + name = [ name ]; + } else { + name = name.split(" "); + } + } + } + + for ( i = 0, l = name.length; i < l; i++ ) { + delete thisCache[ name[i] ]; + } + + // If there is no data left in the cache, we want to continue + // and let the cache object itself get destroyed + if ( !( pvt ? isEmptyDataObject : jQuery.isEmptyObject )( thisCache ) ) { + return; + } + } + } + + // See jQuery.data for more information + if ( !pvt ) { + delete cache[ id ].data; + + // Don't destroy the parent cache unless the internal data object + // had been the only thing left in it + if ( !isEmptyDataObject( cache[ id ] ) ) { + return; + } + } + + // Destroy the cache + if ( isNode ) { + jQuery.cleanData( [ elem ], true ); + + // Use delete when supported for expandos or `cache` is not a window per isWindow (#10080) + } else if ( jQuery.support.deleteExpando || cache != cache.window ) { + delete cache[ id ]; + + // When all else fails, null + } else { + cache[ id ] = 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 ) { + var noData = elem.nodeName && jQuery.noData[ elem.nodeName.toLowerCase() ]; + + // nodes accept data unless otherwise specified; rejection can be conditional + return !noData || noData !== true && elem.getAttribute("classid") === noData; + } +}); + +jQuery.fn.extend({ + data: function( key, value ) { + var parts, part, attr, name, l, + elem = this[0], + i = 0, + data = null; + + // Gets all values + if ( key === undefined ) { + if ( this.length ) { + data = jQuery.data( elem ); + + if ( elem.nodeType === 1 && !jQuery._data( elem, "parsedAttrs" ) ) { + attr = elem.attributes; + for ( l = attr.length; i < l; i++ ) { + name = attr[i].name; + + if ( !name.indexOf( "data-" ) ) { + name = jQuery.camelCase( name.substring(5) ); + + dataAttr( elem, name, data[ name ] ); + } + } + jQuery._data( elem, "parsedAttrs", true ); + } + } + + return data; + } + + // Sets multiple values + if ( typeof key === "object" ) { + return this.each(function() { + jQuery.data( this, key ); + }); + } + + parts = key.split( ".", 2 ); + parts[1] = parts[1] ? "." + parts[1] : ""; + part = parts[1] + "!"; + + return jQuery.access( this, function( value ) { + + if ( value === undefined ) { + data = this.triggerHandler( "getData" + part, [ parts[0] ] ); + + // Try to fetch any internally stored data first + if ( data === undefined && elem ) { + data = jQuery.data( elem, key ); + data = dataAttr( elem, key, data ); + } + + return data === undefined && parts[1] ? + this.data( parts[0] ) : + data; + } + + parts[1] = value; + this.each(function() { + var self = jQuery( this ); + + self.triggerHandler( "setData" + part, parts ); + jQuery.data( this, key, value ); + self.triggerHandler( "changeData" + part, parts ); + }); + }, null, value, arguments.length > 1, null, false ); + }, + + 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" ).toLowerCase(); + + data = elem.getAttribute( name ); + + if ( typeof data === "string" ) { + try { + data = data === "true" ? true : + data === "false" ? false : + data === "null" ? null : + // Only convert to a number if it doesn't change the string + +data + "" === data ? +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; +} + +// checks a cache object for emptiness +function isEmptyDataObject( obj ) { + var name; + for ( name in obj ) { + + // if the public data object is empty, the private is still empty + if ( name === "data" && jQuery.isEmptyObject( obj[name] ) ) { + continue; + } + if ( name !== "toJSON" ) { + return false; + } + } + + return true; +} +jQuery.extend({ + queue: function( elem, type, data ) { + var queue; + + if ( elem ) { + type = ( type || "fx" ) + "queue"; + queue = jQuery._data( elem, type ); + + // Speed up dequeue by getting out quickly if this is just a lookup + if ( data ) { + if ( !queue || jQuery.isArray(data) ) { + queue = jQuery._data( elem, type, jQuery.makeArray(data) ); + } else { + queue.push( data ); + } + } + return queue || []; + } + }, + + dequeue: function( elem, type ) { + type = type || "fx"; + + var queue = jQuery.queue( elem, type ), + startLength = queue.length, + fn = queue.shift(), + hooks = jQuery._queueHooks( elem, type ), + next = function() { + jQuery.dequeue( elem, type ); + }; + + // If the fx queue is dequeued, always remove the progress sentinel + if ( fn === "inprogress" ) { + fn = queue.shift(); + startLength--; + } + + if ( fn ) { + + // Add a progress sentinel to prevent the fx queue from being + // automatically dequeued + if ( type === "fx" ) { + queue.unshift( "inprogress" ); + } + + // clear up the last queue stop function + delete hooks.stop; + fn.call( elem, next, hooks ); + } + + if ( !startLength && hooks ) { + hooks.empty.fire(); + } + }, + + // not intended for public consumption - generates a queueHooks object, or returns the current one + _queueHooks: function( elem, type ) { + var key = type + "queueHooks"; + return jQuery._data( elem, key ) || jQuery._data( elem, key, { + empty: jQuery.Callbacks("once memory").add(function() { + jQuery.removeData( elem, type + "queue", true ); + jQuery.removeData( elem, key, true ); + }) + }); + } +}); + +jQuery.fn.extend({ + queue: function( type, data ) { + var setter = 2; + + if ( typeof type !== "string" ) { + data = type; + type = "fx"; + setter--; + } + + if ( arguments.length < setter ) { + return jQuery.queue( this[0], type ); + } + + return data === undefined ? + this : + this.each(function() { + var queue = jQuery.queue( this, type, data ); + + // ensure a hooks for this queue + jQuery._queueHooks( this, type ); + + 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( next, hooks ) { + var timeout = setTimeout( next, time ); + hooks.stop = function() { + clearTimeout( timeout ); + }; + }); + }, + 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, obj ) { + var tmp, + count = 1, + defer = jQuery.Deferred(), + elements = this, + i = this.length, + resolve = function() { + if ( !( --count ) ) { + defer.resolveWith( elements, [ elements ] ); + } + }; + + if ( typeof type !== "string" ) { + obj = type; + type = undefined; + } + type = type || "fx"; + + while( i-- ) { + tmp = jQuery._data( elements[ i ], type + "queueHooks" ); + if ( tmp && tmp.empty ) { + count++; + tmp.empty.add( resolve ); + } + } + resolve(); + return defer.promise( obj ); + } +}); +var nodeHook, boolHook, fixSpecified, + rclass = /[\t\r\n]/g, + 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, + getSetAttribute = jQuery.support.getSetAttribute; + +jQuery.fn.extend({ + attr: function( name, value ) { + return jQuery.access( this, jQuery.attr, name, value, arguments.length > 1 ); + }, + + removeAttr: function( name ) { + return this.each(function() { + jQuery.removeAttr( this, name ); + }); + }, + + prop: function( name, value ) { + return jQuery.access( this, jQuery.prop, name, value, arguments.length > 1 ); + }, + + 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( core_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 ] + " " ) < 0 ) { + setClass += classNames[ c ] + " "; + } + } + elem.className = jQuery.trim( setClass ); + } + } + } + } + + return this; + }, + + removeClass: function( value ) { + var removes, className, elem, c, cl, i, l; + + 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 ) { + removes = ( value || "" ).split( core_rspace ); + + for ( i = 0, l = this.length; i < l; i++ ) { + elem = this[ i ]; + if ( elem.nodeType === 1 && elem.className ) { + + className = (" " + elem.className + " ").replace( rclass, " " ); + + // loop over each item in the removal list + for ( c = 0, cl = removes.length; c < cl; c++ ) { + // Remove until there is nothing to remove, + while ( className.indexOf(" " + removes[ c ] + " ") >= 0 ) { + className = className.replace( " " + removes[ c ] + " " , " " ); + } + } + elem.className = value ? jQuery.trim( 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( core_rspace ); + + while ( (className = classNames[ i++ ]) ) { + // check each className given, space separated 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 + " ", + i = 0, + l = this.length; + for ( ; i < l; i++ ) { + if ( this[i].nodeType === 1 && (" " + this[i].className + " ").replace(rclass, " ").indexOf( className ) >= 0 ) { + return true; + } + } + + return false; + }, + + val: function( value ) { + var hooks, ret, isFunction, + elem = this[0]; + + if ( !arguments.length ) { + if ( elem ) { + hooks = jQuery.valHooks[ elem.type ] || jQuery.valHooks[ elem.nodeName.toLowerCase() ]; + + 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; + } + + isFunction = jQuery.isFunction( value ); + + return this.each(function( i ) { + var val, + self = jQuery(this); + + 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.type ] || jQuery.valHooks[ this.nodeName.toLowerCase() ]; + + // 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, option, + options = elem.options, + index = elem.selectedIndex, + one = elem.type === "select-one" || index < 0, + values = one ? null : [], + max = one ? index + 1 : options.length, + i = index < 0 ? + max : + one ? index : 0; + + // Loop through all the selected options + for ( ; i < max; i++ ) { + option = options[ i ]; + + // oldIE doesn't update selected after form reset (#2551) + if ( ( option.selected || i === index ) && + // Don't return options that are disabled or in a disabled optgroup + ( 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 ); + } + } + + 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; + } + } + }, + + // Unused in 1.8, left in so attrFn-stabbers won't die; remove in 1.9 + attrFn: {}, + + attr: function( elem, name, value, pass ) { + var ret, hooks, notxml, + nType = elem.nodeType; + + // don't get/set attributes on text, comment and attribute nodes + if ( !elem || nType === 3 || nType === 8 || nType === 2 ) { + return; + } + + if ( pass && jQuery.isFunction( jQuery.fn[ name ] ) ) { + return jQuery( elem )[ name ]( value ); + } + + // Fallback to prop when attributes are not supported + if ( typeof elem.getAttribute === "undefined" ) { + return jQuery.prop( elem, name, value ); + } + + notxml = nType !== 1 || !jQuery.isXMLDoc( elem ); + + // All attributes are lowercase + // Grab necessary hook if one is defined + if ( notxml ) { + name = name.toLowerCase(); + hooks = jQuery.attrHooks[ name ] || ( rboolean.test( name ) ? boolHook : nodeHook ); + } + + if ( value !== undefined ) { + + if ( value === null ) { + jQuery.removeAttr( elem, name ); + return; + + } 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, value ) { + var propName, attrNames, name, isBool, + i = 0; + + if ( value && elem.nodeType === 1 ) { + + attrNames = value.split( core_rspace ); + + for ( ; i < attrNames.length; i++ ) { + name = attrNames[ i ]; + + if ( name ) { + propName = jQuery.propFix[ name ] || name; + isBool = rboolean.test( name ); + + // See #9699 for explanation of this approach (setting first, then removal) + // Do not do this for boolean attributes (see #10870) + if ( !isBool ) { + jQuery.attr( elem, name, "" ); + } + elem.removeAttribute( getSetAttribute ? name : propName ); + + // Set corresponding property to false for boolean attributes + if ( isBool && propName 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; + } + } + }, + // Use the value property for back compat + // Use the nodeHook for button elements in IE6/7 (#1954) + value: { + get: function( elem, name ) { + if ( nodeHook && jQuery.nodeName( elem, "button" ) ) { + return nodeHook.get( elem, name ); + } + return name in elem ? + elem.value : + null; + }, + set: function( elem, value, name ) { + if ( nodeHook && jQuery.nodeName( elem, "button" ) ) { + return nodeHook.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 ret, hooks, notxml, + nType = elem.nodeType; + + // don't get/set properties on text, comment and attribute nodes + if ( !elem || nType === 3 || nType === 8 || nType === 2 ) { + return; + } + + 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 )) !== null ) { + return ret; + + } else { + return elem[ name ]; + } + } + }, + + propHooks: { + 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; + } + } + } +}); + +// Hook for boolean attributes +boolHook = { + get: function( elem, name ) { + // Align boolean attributes with corresponding properties + // Fall back to attribute presence where some booleans are not supported + var attrNode, + property = jQuery.prop( elem, name ); + return property === true || typeof property !== "boolean" && ( attrNode = elem.getAttributeNode(name) ) && attrNode.nodeValue !== false ? + 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 ( !getSetAttribute ) { + + fixSpecified = { + name: true, + id: true, + coords: true + }; + + // Use this for any attribute in IE6/7 + // This fixes almost every IE6/7 issue + nodeHook = jQuery.valHooks.button = { + get: function( elem, name ) { + var ret; + ret = elem.getAttributeNode( name ); + return ret && ( fixSpecified[ name ] ? ret.value !== "" : ret.specified ) ? + ret.value : + undefined; + }, + set: function( elem, value, name ) { + // Set the existing or create a new attribute node + var ret = elem.getAttributeNode( name ); + if ( !ret ) { + ret = document.createAttribute( name ); + elem.setAttributeNode( ret ); + } + return ( ret.value = 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; + } + } + }); + }); + + // Set contenteditable to false on removals(#10429) + // Setting to empty string throws an error as an invalid value + jQuery.attrHooks.contenteditable = { + get: nodeHook.get, + set: function( elem, value, name ) { + if ( value === "" ) { + value = "false"; + } + nodeHook.set( elem, value, name ); + } + }; +} + + +// 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; + } + } + return null; + } + }); +} + +// IE6/7 call enctype encoding +if ( !jQuery.support.enctype ) { + jQuery.propFix.enctype = "encoding"; +} + +// 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 rformElems = /^(?:textarea|input|select)$/i, + rtypenamespace = /^([^\.]*|)(?:\.(.+)|)$/, + rhoverHack = /(?:^|\s)hover(\.\S+|)\b/, + rkeyEvent = /^key/, + rmouseEvent = /^(?:mouse|contextmenu)|click/, + rfocusMorph = /^(?:focusinfocus|focusoutblur)$/, + hoverHack = function( events ) { + return jQuery.event.special.hover ? events : events.replace( rhoverHack, "mouseenter$1 mouseleave$1" ); + }; + +/* + * Helper functions for managing events -- not part of the public interface. + * Props to Dean Edwards' addEvent library for many of the ideas. + */ +jQuery.event = { + + add: function( elem, types, handler, data, selector ) { + + var elemData, eventHandle, events, + t, tns, type, namespaces, handleObj, + handleObjIn, handlers, special; + + // Don't attach events to noData or text/comment nodes (allow plain objects tho) + if ( elem.nodeType === 3 || elem.nodeType === 8 || !types || !handler || !(elemData = jQuery._data( elem )) ) { + return; + } + + // Caller can pass in an object of custom data in lieu of the handler + if ( handler.handler ) { + handleObjIn = handler; + handler = handleObjIn.handler; + selector = handleObjIn.selector; + } + + // Make sure that the handler has a unique ID, used to find/remove it later + if ( !handler.guid ) { + handler.guid = jQuery.guid++; + } + + // Init the element's event structure and main handler, if this is the first + events = elemData.events; + if ( !events ) { + elemData.events = events = {}; + } + eventHandle = elemData.handle; + 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.dispatch.apply( eventHandle.elem, arguments ) : + undefined; + }; + // Add elem as a property of the handle fn to prevent a memory leak with IE non-native events + eventHandle.elem = elem; + } + + // Handle multiple events separated by a space + // jQuery(...).bind("mouseover mouseout", fn); + types = jQuery.trim( hoverHack(types) ).split( " " ); + for ( t = 0; t < types.length; t++ ) { + + tns = rtypenamespace.exec( types[t] ) || []; + type = tns[1]; + namespaces = ( tns[2] || "" ).split( "." ).sort(); + + // If event changes its type, use the special event handlers for the changed type + special = jQuery.event.special[ type ] || {}; + + // If selector defined, determine special event api type, otherwise given type + type = ( selector ? special.delegateType : special.bindType ) || type; + + // Update special based on newly reset type + special = jQuery.event.special[ type ] || {}; + + // handleObj is passed to all event handlers + handleObj = jQuery.extend({ + type: type, + origType: tns[1], + data: data, + handler: handler, + guid: handler.guid, + selector: selector, + needsContext: selector && jQuery.expr.match.needsContext.test( selector ), + namespace: namespaces.join(".") + }, handleObjIn ); + + // Init the event handler queue if we're the first + handlers = events[ type ]; + if ( !handlers ) { + handlers = events[ type ] = []; + handlers.delegateCount = 0; + + // 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 to the element's handler list, delegates in front + if ( selector ) { + handlers.splice( handlers.delegateCount++, 0, handleObj ); + } else { + handlers.push( handleObj ); + } + + // Keep track of which events have ever 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, selector, mappedTypes ) { + + var t, tns, type, origType, namespaces, origCount, + j, events, special, eventType, handleObj, + elemData = jQuery.hasData( elem ) && jQuery._data( elem ); + + if ( !elemData || !(events = elemData.events) ) { + return; + } + + // Once for each type.namespace in types; type may be omitted + types = jQuery.trim( hoverHack( types || "" ) ).split(" "); + for ( t = 0; t < types.length; t++ ) { + tns = rtypenamespace.exec( types[t] ) || []; + type = origType = tns[1]; + namespaces = tns[2]; + + // Unbind all events (on this namespace, if provided) for the element + if ( !type ) { + for ( type in events ) { + jQuery.event.remove( elem, type + types[ t ], handler, selector, true ); + } + continue; + } + + special = jQuery.event.special[ type ] || {}; + type = ( selector? special.delegateType : special.bindType ) || type; + eventType = events[ type ] || []; + origCount = eventType.length; + namespaces = namespaces ? new RegExp("(^|\\.)" + namespaces.split(".").sort().join("\\.(?:.*\\.|)") + "(\\.|$)") : null; + + // Remove matching events + for ( j = 0; j < eventType.length; j++ ) { + handleObj = eventType[ j ]; + + if ( ( mappedTypes || origType === handleObj.origType ) && + ( !handler || handler.guid === handleObj.guid ) && + ( !namespaces || namespaces.test( handleObj.namespace ) ) && + ( !selector || selector === handleObj.selector || selector === "**" && handleObj.selector ) ) { + eventType.splice( j--, 1 ); + + if ( handleObj.selector ) { + eventType.delegateCount--; + } + if ( special.remove ) { + special.remove.call( elem, handleObj ); + } + } + } + + // Remove generic event handler if we removed something and no more handlers exist + // (avoids potential for endless recursion during removal of special event handlers) + if ( eventType.length === 0 && origCount !== eventType.length ) { + if ( !special.teardown || special.teardown.call( elem, namespaces, elemData.handle ) === false ) { + jQuery.removeEvent( elem, type, elemData.handle ); + } + + delete events[ type ]; + } + } + + // Remove the expando if it's no longer used + if ( jQuery.isEmptyObject( events ) ) { + delete elemData.handle; + + // removeData also checks for emptiness and clears the expando if empty + // so use it instead of delete + jQuery.removeData( elem, "events", 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 ) { + // Don't do events on text and comment nodes + if ( elem && (elem.nodeType === 3 || elem.nodeType === 8) ) { + return; + } + + // Event object or event type + var cache, exclusive, i, cur, old, ontype, special, handle, eventPath, bubbleType, + type = event.type || event, + namespaces = []; + + // focus/blur morphs to focusin/out; ensure we're not firing them right now + if ( rfocusMorph.test( type + jQuery.event.triggered ) ) { + return; + } + + 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.isTrigger = true; + event.exclusive = exclusive; + event.namespace = namespaces.join( "." ); + event.namespace_re = event.namespace? new RegExp("(^|\\.)" + namespaces.join("\\.(?:.*\\.|)") + "(\\.|$)") : null; + ontype = type.indexOf( ":" ) < 0 ? "on" + type : ""; + + // Handle a global trigger + if ( !elem ) { + + // TODO: Stop taunting the data cache; remove global events and always attach to document + cache = jQuery.cache; + for ( i in cache ) { + if ( cache[ i ].events && cache[ i ].events[ type ] ) { + jQuery.event.trigger( event, data, cache[ i ].handle.elem, true ); + } + } + return; + } + + // Clean up the event in case it is being reused + event.result = undefined; + if ( !event.target ) { + 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 ); + + // Allow special events to draw outside the lines + special = jQuery.event.special[ type ] || {}; + if ( special.trigger && special.trigger.apply( elem, data ) === false ) { + return; + } + + // Determine event propagation path in advance, per W3C events spec (#9951) + // Bubble up to document, then to window; watch for a global ownerDocument var (#9724) + eventPath = [[ elem, special.bindType || type ]]; + if ( !onlyHandlers && !special.noBubble && !jQuery.isWindow( elem ) ) { + + bubbleType = special.delegateType || type; + cur = rfocusMorph.test( bubbleType + type ) ? elem : elem.parentNode; + for ( old = elem; cur; cur = cur.parentNode ) { + eventPath.push([ cur, bubbleType ]); + old = cur; + } + + // Only add window if we got to document (e.g., not plain obj or detached DOM) + if ( old === (elem.ownerDocument || document) ) { + eventPath.push([ old.defaultView || old.parentWindow || window, bubbleType ]); + } + } + + // Fire handlers on the event path + for ( i = 0; i < eventPath.length && !event.isPropagationStopped(); i++ ) { + + cur = eventPath[i][0]; + event.type = eventPath[i][1]; + + handle = ( jQuery._data( cur, "events" ) || {} )[ event.type ] && jQuery._data( cur, "handle" ); + if ( handle ) { + handle.apply( cur, data ); + } + // Note that this is a bare JS function and not a jQuery handler + handle = ontype && cur[ ontype ]; + if ( handle && jQuery.acceptData( cur ) && handle.apply && handle.apply( cur, data ) === false ) { + event.preventDefault(); + } + } + event.type = type; + + // If nobody prevented the default action, do it now + if ( !onlyHandlers && !event.isDefaultPrevented() ) { + + if ( (!special._default || special._default.apply( elem.ownerDocument, data ) === 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. + // Don't do default actions on window, that's where global variables be (#6170) + // IE<9 dies on focus/blur to hidden element (#1486) + if ( ontype && elem[ type ] && ((type !== "focus" && type !== "blur") || event.target.offsetWidth !== 0) && !jQuery.isWindow( elem ) ) { + + // Don't re-trigger an onFOO event when we call its FOO() method + old = elem[ ontype ]; + + if ( old ) { + elem[ ontype ] = null; + } + + // Prevent re-triggering of the same event, since we already bubbled it above + jQuery.event.triggered = type; + elem[ type ](); + jQuery.event.triggered = undefined; + + if ( old ) { + elem[ ontype ] = old; + } + } + } + } + + return event.result; + }, + + dispatch: function( event ) { + + // Make a writable jQuery.Event from the native event object + event = jQuery.event.fix( event || window.event ); + + var i, j, cur, ret, selMatch, matched, matches, handleObj, sel, related, + handlers = ( (jQuery._data( this, "events" ) || {} )[ event.type ] || []), + delegateCount = handlers.delegateCount, + args = core_slice.call( arguments ), + run_all = !event.exclusive && !event.namespace, + special = jQuery.event.special[ event.type ] || {}, + handlerQueue = []; + + // Use the fix-ed jQuery.Event rather than the (read-only) native event + args[0] = event; + event.delegateTarget = this; + + // Call the preDispatch hook for the mapped type, and let it bail if desired + if ( special.preDispatch && special.preDispatch.call( this, event ) === false ) { + return; + } + + // Determine handlers that should run if there are delegated events + // Avoid non-left-click bubbling in Firefox (#3861) + if ( delegateCount && !(event.button && event.type === "click") ) { + + for ( cur = event.target; cur != this; cur = cur.parentNode || this ) { + + // Don't process clicks (ONLY) on disabled elements (#6911, #8165, #11382, #11764) + if ( cur.disabled !== true || event.type !== "click" ) { + selMatch = {}; + matches = []; + for ( i = 0; i < delegateCount; i++ ) { + handleObj = handlers[ i ]; + sel = handleObj.selector; + + if ( selMatch[ sel ] === undefined ) { + selMatch[ sel ] = handleObj.needsContext ? + jQuery( sel, this ).index( cur ) >= 0 : + jQuery.find( sel, this, null, [ cur ] ).length; + } + if ( selMatch[ sel ] ) { + matches.push( handleObj ); + } + } + if ( matches.length ) { + handlerQueue.push({ elem: cur, matches: matches }); + } + } + } + } + + // Add the remaining (directly-bound) handlers + if ( handlers.length > delegateCount ) { + handlerQueue.push({ elem: this, matches: handlers.slice( delegateCount ) }); + } + + // Run delegates first; they may want to stop propagation beneath us + for ( i = 0; i < handlerQueue.length && !event.isPropagationStopped(); i++ ) { + matched = handlerQueue[ i ]; + event.currentTarget = matched.elem; + + for ( j = 0; j < matched.matches.length && !event.isImmediatePropagationStopped(); j++ ) { + handleObj = matched.matches[ j ]; + + // Triggered event must either 1) be non-exclusive and have no namespace, or + // 2) have namespace(s) a subset or equal to those in the bound event (both can have no namespace). + if ( run_all || (!event.namespace && !handleObj.namespace) || event.namespace_re && event.namespace_re.test( handleObj.namespace ) ) { + + event.data = handleObj.data; + event.handleObj = handleObj; + + ret = ( (jQuery.event.special[ handleObj.origType ] || {}).handle || handleObj.handler ) + .apply( matched.elem, args ); + + if ( ret !== undefined ) { + event.result = ret; + if ( ret === false ) { + event.preventDefault(); + event.stopPropagation(); + } + } + } + } + } + + // Call the postDispatch hook for the mapped type + if ( special.postDispatch ) { + special.postDispatch.call( this, event ); + } + + return event.result; + }, + + // Includes some event props shared by KeyEvent and MouseEvent + // *** attrChange attrName relatedNode srcElement are not normalized, non-W3C, deprecated, will be removed in 1.8 *** + props: "attrChange attrName relatedNode srcElement altKey bubbles cancelable ctrlKey currentTarget eventPhase metaKey relatedTarget shiftKey target timeStamp view which".split(" "), + + fixHooks: {}, + + keyHooks: { + props: "char charCode key keyCode".split(" "), + filter: function( event, original ) { + + // Add which for key events + if ( event.which == null ) { + event.which = original.charCode != null ? original.charCode : original.keyCode; + } + + return event; + } + }, + + mouseHooks: { + props: "button buttons clientX clientY fromElement offsetX offsetY pageX pageY screenX screenY toElement".split(" "), + filter: function( event, original ) { + var eventDoc, doc, body, + button = original.button, + fromElement = original.fromElement; + + // Calculate pageX/Y if missing and clientX/Y available + if ( event.pageX == null && original.clientX != null ) { + eventDoc = event.target.ownerDocument || document; + doc = eventDoc.documentElement; + body = eventDoc.body; + + event.pageX = original.clientX + ( doc && doc.scrollLeft || body && body.scrollLeft || 0 ) - ( doc && doc.clientLeft || body && body.clientLeft || 0 ); + event.pageY = original.clientY + ( doc && doc.scrollTop || body && body.scrollTop || 0 ) - ( doc && doc.clientTop || body && body.clientTop || 0 ); + } + + // Add relatedTarget, if necessary + if ( !event.relatedTarget && fromElement ) { + event.relatedTarget = fromElement === event.target ? original.toElement : fromElement; + } + + // Add which for click: 1 === left; 2 === middle; 3 === right + // Note: button is not normalized, so don't use it + if ( !event.which && button !== undefined ) { + event.which = ( button & 1 ? 1 : ( button & 2 ? 3 : ( button & 4 ? 2 : 0 ) ) ); + } + + return event; + } + }, + + fix: function( event ) { + if ( event[ jQuery.expando ] ) { + return event; + } + + // Create a writable copy of the event object and normalize some properties + var i, prop, + originalEvent = event, + fixHook = jQuery.event.fixHooks[ event.type ] || {}, + copy = fixHook.props ? this.props.concat( fixHook.props ) : this.props; + + event = jQuery.Event( originalEvent ); + + for ( i = copy.length; i; ) { + prop = copy[ --i ]; + event[ prop ] = originalEvent[ prop ]; + } + + // Fix target property, if necessary (#1925, IE 6/7/8 & Safari2) + if ( !event.target ) { + event.target = originalEvent.srcElement || document; + } + + // Target should not be a text node (#504, Safari) + if ( event.target.nodeType === 3 ) { + event.target = event.target.parentNode; + } + + // For mouse/key events, metaKey==false if it's undefined (#3368, #11328; IE6/7/8) + event.metaKey = !!event.metaKey; + + return fixHook.filter? fixHook.filter( event, originalEvent ) : event; + }, + + special: { + load: { + // Prevent triggered image.load events from bubbling to window.load + noBubble: true + }, + + focus: { + delegateType: "focusin" + }, + blur: { + delegateType: "focusout" + }, + + 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; + } + } + } + }, + + simulate: function( type, elem, event, bubble ) { + // 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. + var e = jQuery.extend( + new jQuery.Event(), + event, + { type: type, + isSimulated: true, + originalEvent: {} + } + ); + if ( bubble ) { + jQuery.event.trigger( e, null, elem ); + } else { + jQuery.event.dispatch.call( elem, e ); + } + if ( e.isDefaultPrevented() ) { + event.preventDefault(); + } + } +}; + +// Some plugins are using, but it's undocumented/deprecated and will be removed. +// The 1.7 special event interface should provide all the hooks needed now. +jQuery.event.handle = jQuery.event.dispatch; + +jQuery.removeEvent = document.removeEventListener ? + function( elem, type, handle ) { + if ( elem.removeEventListener ) { + elem.removeEventListener( type, handle, false ); + } + } : + function( elem, type, handle ) { + var name = "on" + type; + + if ( elem.detachEvent ) { + + // #8545, #7054, preventing memory leaks for custom events in IE6-8 + // detachEvent needed property on element, by name of that event, to properly expose it to GC + if ( typeof elem[ name ] === "undefined" ) { + elem[ name ] = null; + } + + elem.detachEvent( name, handle ); + } + }; + +jQuery.Event = function( src, props ) { + // Allow instantiation without the 'new' keyword + if ( !(this instanceof jQuery.Event) ) { + 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 ); + } + + // Create a timestamp if incoming event doesn't have one + this.timeStamp = src && src.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 +}; + +// Create mouseenter/leave events using mouseover/out and event-time checks +jQuery.each({ + mouseenter: "mouseover", + mouseleave: "mouseout" +}, function( orig, fix ) { + jQuery.event.special[ orig ] = { + delegateType: fix, + bindType: fix, + + handle: function( event ) { + var ret, + target = this, + related = event.relatedTarget, + handleObj = event.handleObj, + selector = handleObj.selector; + + // For mousenter/leave call the handler if related is outside the target. + // NB: No relatedTarget if the mouse left/entered the browser window + if ( !related || (related !== target && !jQuery.contains( target, related )) ) { + event.type = handleObj.origType; + ret = handleObj.handler.apply( this, arguments ); + event.type = fix; + } + return ret; + } + }; +}); + +// IE submit delegation +if ( !jQuery.support.submitBubbles ) { + + jQuery.event.special.submit = { + setup: function() { + // Only need this for delegated form submit events + if ( jQuery.nodeName( this, "form" ) ) { + return false; + } + + // Lazy-add a submit handler when a descendant form may potentially be submitted + jQuery.event.add( this, "click._submit keypress._submit", function( e ) { + // Node name check avoids a VML-related crash in IE (#9807) + var elem = e.target, + form = jQuery.nodeName( elem, "input" ) || jQuery.nodeName( elem, "button" ) ? elem.form : undefined; + if ( form && !jQuery._data( form, "_submit_attached" ) ) { + jQuery.event.add( form, "submit._submit", function( event ) { + event._submit_bubble = true; + }); + jQuery._data( form, "_submit_attached", true ); + } + }); + // return undefined since we don't need an event listener + }, + + postDispatch: function( event ) { + // If form was submitted by the user, bubble the event up the tree + if ( event._submit_bubble ) { + delete event._submit_bubble; + if ( this.parentNode && !event.isTrigger ) { + jQuery.event.simulate( "submit", this.parentNode, event, true ); + } + } + }, + + teardown: function() { + // Only need this for delegated form submit events + if ( jQuery.nodeName( this, "form" ) ) { + return false; + } + + // Remove delegated handlers; cleanData eventually reaps submit handlers attached above + jQuery.event.remove( this, "._submit" ); + } + }; +} + +// IE change delegation and checkbox/radio fix +if ( !jQuery.support.changeBubbles ) { + + jQuery.event.special.change = { + + setup: function() { + + if ( rformElems.test( this.nodeName ) ) { + // IE doesn't fire change on a check/radio until blur; trigger it on click + // after a propertychange. Eat the blur-change in special.change.handle. + // This still fires onchange a second time for check/radio after blur. + if ( this.type === "checkbox" || this.type === "radio" ) { + jQuery.event.add( this, "propertychange._change", function( event ) { + if ( event.originalEvent.propertyName === "checked" ) { + this._just_changed = true; + } + }); + jQuery.event.add( this, "click._change", function( event ) { + if ( this._just_changed && !event.isTrigger ) { + this._just_changed = false; + } + // Allow triggered, simulated change events (#11500) + jQuery.event.simulate( "change", this, event, true ); + }); + } + return false; + } + // Delegated event; lazy-add a change handler on descendant inputs + jQuery.event.add( this, "beforeactivate._change", function( e ) { + var elem = e.target; + + if ( rformElems.test( elem.nodeName ) && !jQuery._data( elem, "_change_attached" ) ) { + jQuery.event.add( elem, "change._change", function( event ) { + if ( this.parentNode && !event.isSimulated && !event.isTrigger ) { + jQuery.event.simulate( "change", this.parentNode, event, true ); + } + }); + jQuery._data( elem, "_change_attached", true ); + } + }); + }, + + handle: function( event ) { + var elem = event.target; + + // Swallow native change events from checkbox/radio, we already triggered them above + if ( this !== elem || event.isSimulated || event.isTrigger || (elem.type !== "radio" && elem.type !== "checkbox") ) { + return event.handleObj.handler.apply( this, arguments ); + } + }, + + teardown: function() { + jQuery.event.remove( this, "._change" ); + + return !rformElems.test( this.nodeName ); + } + }; +} + +// 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, + handler = function( event ) { + jQuery.event.simulate( fix, event.target, jQuery.event.fix( event ), true ); + }; + + jQuery.event.special[ fix ] = { + setup: function() { + if ( attaches++ === 0 ) { + document.addEventListener( orig, handler, true ); + } + }, + teardown: function() { + if ( --attaches === 0 ) { + document.removeEventListener( orig, handler, true ); + } + } + }; + }); +} + +jQuery.fn.extend({ + + on: function( types, selector, data, fn, /*INTERNAL*/ one ) { + var origFn, type; + + // Types can be a map of types/handlers + if ( typeof types === "object" ) { + // ( types-Object, selector, data ) + if ( typeof selector !== "string" ) { // && selector != null + // ( types-Object, data ) + data = data || selector; + selector = undefined; + } + for ( type in types ) { + this.on( type, selector, data, types[ type ], one ); + } + return this; + } + + if ( data == null && fn == null ) { + // ( types, fn ) + fn = selector; + data = selector = undefined; + } else if ( fn == null ) { + if ( typeof selector === "string" ) { + // ( types, selector, fn ) + fn = data; + data = undefined; + } else { + // ( types, data, fn ) + fn = data; + data = selector; + selector = undefined; + } + } + if ( fn === false ) { + fn = returnFalse; + } else if ( !fn ) { + return this; + } + + if ( one === 1 ) { + origFn = fn; + fn = function( event ) { + // Can use an empty set, since event contains the info + jQuery().off( event ); + return origFn.apply( this, arguments ); + }; + // Use same guid so caller can remove using origFn + fn.guid = origFn.guid || ( origFn.guid = jQuery.guid++ ); + } + return this.each( function() { + jQuery.event.add( this, types, fn, data, selector ); + }); + }, + one: function( types, selector, data, fn ) { + return this.on( types, selector, data, fn, 1 ); + }, + off: function( types, selector, fn ) { + var handleObj, type; + if ( types && types.preventDefault && types.handleObj ) { + // ( event ) dispatched jQuery.Event + handleObj = types.handleObj; + jQuery( types.delegateTarget ).off( + handleObj.namespace ? handleObj.origType + "." + handleObj.namespace : handleObj.origType, + handleObj.selector, + handleObj.handler + ); + return this; + } + if ( typeof types === "object" ) { + // ( types-object [, selector] ) + for ( type in types ) { + this.off( type, selector, types[ type ] ); + } + return this; + } + if ( selector === false || typeof selector === "function" ) { + // ( types [, fn] ) + fn = selector; + selector = undefined; + } + if ( fn === false ) { + fn = returnFalse; + } + return this.each(function() { + jQuery.event.remove( this, types, fn, selector ); + }); + }, + + bind: function( types, data, fn ) { + return this.on( types, null, data, fn ); + }, + unbind: function( types, fn ) { + return this.off( types, null, fn ); + }, + + live: function( types, data, fn ) { + jQuery( this.context ).on( types, this.selector, data, fn ); + return this; + }, + die: function( types, fn ) { + jQuery( this.context ).off( types, this.selector || "**", fn ); + return this; + }, + + delegate: function( selector, types, data, fn ) { + return this.on( types, selector, data, fn ); + }, + undelegate: function( selector, types, fn ) { + // ( namespace ) or ( selector, types [, fn] ) + return arguments.length === 1 ? this.off( selector, "**" ) : this.off( types, selector || "**", fn ); + }, + + 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 ); + } +}); + +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 contextmenu").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.on( name, null, data, fn ) : + this.trigger( name ); + }; + + if ( rkeyEvent.test( name ) ) { + jQuery.event.fixHooks[ name ] = jQuery.event.keyHooks; + } + + if ( rmouseEvent.test( name ) ) { + jQuery.event.fixHooks[ name ] = jQuery.event.mouseHooks; + } +}); +/*! + * Sizzle CSS Selector Engine + * Copyright 2012 jQuery Foundation and other contributors + * Released under the MIT license + * http://sizzlejs.com/ + */ +(function( window, undefined ) { + +var cachedruns, + assertGetIdNotName, + Expr, + getText, + isXML, + contains, + compile, + sortOrder, + hasDuplicate, + outermostContext, + + baseHasDuplicate = true, + strundefined = "undefined", + + expando = ( "sizcache" + Math.random() ).replace( ".", "" ), + + Token = String, + document = window.document, + docElem = document.documentElement, + dirruns = 0, + done = 0, + pop = [].pop, + push = [].push, + slice = [].slice, + // Use a stripped-down indexOf if a native one is unavailable + indexOf = [].indexOf || function( elem ) { + var i = 0, + len = this.length; + for ( ; i < len; i++ ) { + if ( this[i] === elem ) { + return i; + } + } + return -1; + }, + + // Augment a function for special use by Sizzle + markFunction = function( fn, value ) { + fn[ expando ] = value == null || value; + return fn; + }, + + createCache = function() { + var cache = {}, + keys = []; + + return markFunction(function( key, value ) { + // Only keep the most recent entries + if ( keys.push( key ) > Expr.cacheLength ) { + delete cache[ keys.shift() ]; + } + + // Retrieve with (key + " ") to avoid collision with native Object.prototype properties (see Issue #157) + return (cache[ key + " " ] = value); + }, cache ); + }, + + classCache = createCache(), + tokenCache = createCache(), + compilerCache = createCache(), + + // Regex + + // Whitespace characters http://www.w3.org/TR/css3-selectors/#whitespace + whitespace = "[\\x20\\t\\r\\n\\f]", + // http://www.w3.org/TR/css3-syntax/#characters + characterEncoding = "(?:\\\\.|[-\\w]|[^\\x00-\\xa0])+", + + // Loosely modeled on CSS identifier characters + // An unquoted value should be a CSS identifier (http://www.w3.org/TR/css3-selectors/#attribute-selectors) + // Proper syntax: http://www.w3.org/TR/CSS21/syndata.html#value-def-identifier + identifier = characterEncoding.replace( "w", "w#" ), + + // Acceptable operators http://www.w3.org/TR/selectors/#attribute-selectors + operators = "([*^$|!~]?=)", + attributes = "\\[" + whitespace + "*(" + characterEncoding + ")" + whitespace + + "*(?:" + operators + whitespace + "*(?:(['\"])((?:\\\\.|[^\\\\])*?)\\3|(" + identifier + ")|)|)" + whitespace + "*\\]", + + // Prefer arguments not in parens/brackets, + // then attribute selectors and non-pseudos (denoted by :), + // then anything else + // These preferences are here to reduce the number of selectors + // needing tokenize in the PSEUDO preFilter + pseudos = ":(" + characterEncoding + ")(?:\\((?:(['\"])((?:\\\\.|[^\\\\])*?)\\2|([^()[\\]]*|(?:(?:" + attributes + ")|[^:]|\\\\.)*|.*))\\)|)", + + // For matchExpr.POS and matchExpr.needsContext + pos = ":(even|odd|eq|gt|lt|nth|first|last)(?:\\(" + whitespace + + "*((?:-\\d)?\\d*)" + whitespace + "*\\)|)(?=[^-]|$)", + + // Leading and non-escaped trailing whitespace, capturing some non-whitespace characters preceding the latter + rtrim = new RegExp( "^" + whitespace + "+|((?:^|[^\\\\])(?:\\\\.)*)" + whitespace + "+$", "g" ), + + rcomma = new RegExp( "^" + whitespace + "*," + whitespace + "*" ), + rcombinators = new RegExp( "^" + whitespace + "*([\\x20\\t\\r\\n\\f>+~])" + whitespace + "*" ), + rpseudo = new RegExp( pseudos ), + + // Easily-parseable/retrievable ID or TAG or CLASS selectors + rquickExpr = /^(?:#([\w\-]+)|(\w+)|\.([\w\-]+))$/, + + rnot = /^:not/, + rsibling = /[\x20\t\r\n\f]*[+~]/, + rendsWithNot = /:not\($/, + + rheader = /h\d/i, + rinputs = /input|select|textarea|button/i, + + rbackslash = /\\(?!\\)/g, + + matchExpr = { + "ID": new RegExp( "^#(" + characterEncoding + ")" ), + "CLASS": new RegExp( "^\\.(" + characterEncoding + ")" ), + "NAME": new RegExp( "^\\[name=['\"]?(" + characterEncoding + ")['\"]?\\]" ), + "TAG": new RegExp( "^(" + characterEncoding.replace( "w", "w*" ) + ")" ), + "ATTR": new RegExp( "^" + attributes ), + "PSEUDO": new RegExp( "^" + pseudos ), + "POS": new RegExp( pos, "i" ), + "CHILD": new RegExp( "^:(only|nth|first|last)-child(?:\\(" + whitespace + + "*(even|odd|(([+-]|)(\\d*)n|)" + whitespace + "*(?:([+-]|)" + whitespace + + "*(\\d+)|))" + whitespace + "*\\)|)", "i" ), + // For use in libraries implementing .is() + "needsContext": new RegExp( "^" + whitespace + "*[>+~]|" + pos, "i" ) + }, + + // Support + + // Used for testing something on an element + assert = function( fn ) { + var div = document.createElement("div"); + + try { + return fn( div ); + } catch (e) { + return false; + } finally { + // release memory in IE + div = null; + } + }, + + // Check if getElementsByTagName("*") returns only elements + assertTagNameNoComments = assert(function( div ) { + div.appendChild( document.createComment("") ); + return !div.getElementsByTagName("*").length; + }), + + // Check if getAttribute returns normalized href attributes + assertHrefNotNormalized = assert(function( div ) { + div.innerHTML = ""; + return div.firstChild && typeof div.firstChild.getAttribute !== strundefined && + div.firstChild.getAttribute("href") === "#"; + }), + + // Check if attributes should be retrieved by attribute nodes + assertAttributes = assert(function( div ) { + div.innerHTML = ""; + var type = typeof div.lastChild.getAttribute("multiple"); + // IE8 returns a string for some attributes even when not present + return type !== "boolean" && type !== "string"; + }), + + // Check if getElementsByClassName can be trusted + assertUsableClassName = assert(function( div ) { + // Opera can't find a second classname (in 9.6) + div.innerHTML = ""; + if ( !div.getElementsByClassName || !div.getElementsByClassName("e").length ) { + return false; + } + + // Safari 3.2 caches class attributes and doesn't catch changes + div.lastChild.className = "e"; + return div.getElementsByClassName("e").length === 2; + }), + + // Check if getElementById returns elements by name + // Check if getElementsByName privileges form controls or returns elements by ID + assertUsableName = assert(function( div ) { + // Inject content + div.id = expando + 0; + div.innerHTML = "
      "; + docElem.insertBefore( div, docElem.firstChild ); + + // Test + var pass = document.getElementsByName && + // buggy browsers will return fewer than the correct 2 + document.getElementsByName( expando ).length === 2 + + // buggy browsers will return more than the correct 0 + document.getElementsByName( expando + 0 ).length; + assertGetIdNotName = !document.getElementById( expando ); + + // Cleanup + docElem.removeChild( div ); + + return pass; + }); + +// If slice is not available, provide a backup +try { + slice.call( docElem.childNodes, 0 )[0].nodeType; +} catch ( e ) { + slice = function( i ) { + var elem, + results = []; + for ( ; (elem = this[i]); i++ ) { + results.push( elem ); + } + return results; + }; +} + +function Sizzle( selector, context, results, seed ) { + results = results || []; + context = context || document; + var match, elem, xml, m, + nodeType = context.nodeType; + + if ( !selector || typeof selector !== "string" ) { + return results; + } + + if ( nodeType !== 1 && nodeType !== 9 ) { + return []; + } + + xml = isXML( context ); + + if ( !xml && !seed ) { + if ( (match = rquickExpr.exec( selector )) ) { + // Speed-up: Sizzle("#ID") + if ( (m = match[1]) ) { + if ( nodeType === 9 ) { + elem = context.getElementById( m ); + // 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, Opera, and Webkit return items + // by name instead of ID + if ( elem.id === m ) { + results.push( elem ); + return results; + } + } else { + return results; + } + } else { + // Context is not a document + if ( context.ownerDocument && (elem = context.ownerDocument.getElementById( m )) && + contains( context, elem ) && elem.id === m ) { + results.push( elem ); + return results; + } + } + + // Speed-up: Sizzle("TAG") + } else if ( match[2] ) { + push.apply( results, slice.call(context.getElementsByTagName( selector ), 0) ); + return results; + + // Speed-up: Sizzle(".CLASS") + } else if ( (m = match[3]) && assertUsableClassName && context.getElementsByClassName ) { + push.apply( results, slice.call(context.getElementsByClassName( m ), 0) ); + return results; + } + } + } + + // All others + return select( selector.replace( rtrim, "$1" ), context, results, seed, xml ); +} + +Sizzle.matches = function( expr, elements ) { + return Sizzle( expr, null, null, elements ); +}; + +Sizzle.matchesSelector = function( elem, expr ) { + return Sizzle( expr, null, null, [ elem ] ).length > 0; +}; + +// Returns a function to use in pseudos for input types +function createInputPseudo( type ) { + return function( elem ) { + var name = elem.nodeName.toLowerCase(); + return name === "input" && elem.type === type; + }; +} + +// Returns a function to use in pseudos for buttons +function createButtonPseudo( type ) { + return function( elem ) { + var name = elem.nodeName.toLowerCase(); + return (name === "input" || name === "button") && elem.type === type; + }; +} + +// Returns a function to use in pseudos for positionals +function createPositionalPseudo( fn ) { + return markFunction(function( argument ) { + argument = +argument; + return markFunction(function( seed, matches ) { + var j, + matchIndexes = fn( [], seed.length, argument ), + i = matchIndexes.length; + + // Match elements found at the specified indexes + while ( i-- ) { + if ( seed[ (j = matchIndexes[i]) ] ) { + seed[j] = !(matches[j] = seed[j]); + } + } + }); + }); +} + +/** + * Utility function for retrieving the text value of an array of DOM nodes + * @param {Array|Element} elem + */ +getText = Sizzle.getText = function( elem ) { + var node, + ret = "", + i = 0, + nodeType = elem.nodeType; + + if ( nodeType ) { + if ( nodeType === 1 || nodeType === 9 || nodeType === 11 ) { + // Use textContent for elements + // innerText usage removed for consistency of new lines (see #11153) + if ( typeof elem.textContent === "string" ) { + return elem.textContent; + } else { + // Traverse its children + for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) { + ret += getText( elem ); + } + } + } else if ( nodeType === 3 || nodeType === 4 ) { + return elem.nodeValue; + } + // Do not include comment or processing instruction nodes + } else { + + // If no nodeType, this is expected to be an array + for ( ; (node = elem[i]); i++ ) { + // Do not traverse comment nodes + ret += getText( node ); + } + } + return ret; +}; + +isXML = 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).documentElement; + return documentElement ? documentElement.nodeName !== "HTML" : false; +}; + +// Element contains another +contains = Sizzle.contains = docElem.contains ? + function( a, b ) { + var adown = a.nodeType === 9 ? a.documentElement : a, + bup = b && b.parentNode; + return a === bup || !!( bup && bup.nodeType === 1 && adown.contains && adown.contains(bup) ); + } : + docElem.compareDocumentPosition ? + function( a, b ) { + return b && !!( a.compareDocumentPosition( b ) & 16 ); + } : + function( a, b ) { + while ( (b = b.parentNode) ) { + if ( b === a ) { + return true; + } + } + return false; + }; + +Sizzle.attr = function( elem, name ) { + var val, + xml = isXML( elem ); + + if ( !xml ) { + name = name.toLowerCase(); + } + if ( (val = Expr.attrHandle[ name ]) ) { + return val( elem ); + } + if ( xml || assertAttributes ) { + return elem.getAttribute( name ); + } + val = elem.getAttributeNode( name ); + return val ? + typeof elem[ name ] === "boolean" ? + elem[ name ] ? name : null : + val.specified ? val.value : null : + null; +}; + +Expr = Sizzle.selectors = { + + // Can be adjusted by the user + cacheLength: 50, + + createPseudo: markFunction, + + match: matchExpr, + + // IE6/7 return a modified href + attrHandle: assertHrefNotNormalized ? + {} : + { + "href": function( elem ) { + return elem.getAttribute( "href", 2 ); + }, + "type": function( elem ) { + return elem.getAttribute("type"); + } + }, + + find: { + "ID": assertGetIdNotName ? + function( id, context, xml ) { + if ( typeof context.getElementById !== strundefined && !xml ) { + var m = context.getElementById( id ); + // Check parentNode to catch when Blackberry 4.6 returns + // nodes that are no longer in the document #6963 + return m && m.parentNode ? [m] : []; + } + } : + function( id, context, xml ) { + if ( typeof context.getElementById !== strundefined && !xml ) { + var m = context.getElementById( id ); + + return m ? + m.id === id || typeof m.getAttributeNode !== strundefined && m.getAttributeNode("id").value === id ? + [m] : + undefined : + []; + } + }, + + "TAG": assertTagNameNoComments ? + function( tag, context ) { + if ( typeof context.getElementsByTagName !== strundefined ) { + return context.getElementsByTagName( tag ); + } + } : + function( tag, context ) { + var results = context.getElementsByTagName( tag ); + + // Filter out possible comments + if ( tag === "*" ) { + var elem, + tmp = [], + i = 0; + + for ( ; (elem = results[i]); i++ ) { + if ( elem.nodeType === 1 ) { + tmp.push( elem ); + } + } + + return tmp; + } + return results; + }, + + "NAME": assertUsableName && function( tag, context ) { + if ( typeof context.getElementsByName !== strundefined ) { + return context.getElementsByName( name ); + } + }, + + "CLASS": assertUsableClassName && function( className, context, xml ) { + if ( typeof context.getElementsByClassName !== strundefined && !xml ) { + return context.getElementsByClassName( className ); + } + } + }, + + relative: { + ">": { dir: "parentNode", first: true }, + " ": { dir: "parentNode" }, + "+": { dir: "previousSibling", first: true }, + "~": { dir: "previousSibling" } + }, + + preFilter: { + "ATTR": function( match ) { + match[1] = match[1].replace( rbackslash, "" ); + + // Move the given value to match[3] whether quoted or unquoted + match[3] = ( match[4] || match[5] || "" ).replace( rbackslash, "" ); + + if ( match[2] === "~=" ) { + match[3] = " " + match[3] + " "; + } + + return match.slice( 0, 4 ); + }, + + "CHILD": function( match ) { + /* matches from matchExpr["CHILD"] + 1 type (only|nth|...) + 2 argument (even|odd|\d*|\d*n([+-]\d+)?|...) + 3 xn-component of xn+y argument ([+-]?\d*n|) + 4 sign of xn-component + 5 x of xn-component + 6 sign of y-component + 7 y of y-component + */ + match[1] = match[1].toLowerCase(); + + if ( match[1] === "nth" ) { + // nth-child requires argument + if ( !match[2] ) { + Sizzle.error( match[0] ); + } + + // numeric x and y parameters for Expr.filter.CHILD + // remember that false/true cast respectively to 0/1 + match[3] = +( match[3] ? match[4] + (match[5] || 1) : 2 * ( match[2] === "even" || match[2] === "odd" ) ); + match[4] = +( ( match[6] + match[7] ) || match[2] === "odd" ); + + // other types prohibit arguments + } else if ( match[2] ) { + Sizzle.error( match[0] ); + } + + return match; + }, + + "PSEUDO": function( match ) { + var unquoted, excess; + if ( matchExpr["CHILD"].test( match[0] ) ) { + return null; + } + + if ( match[3] ) { + match[2] = match[3]; + } else if ( (unquoted = match[4]) ) { + // Only check arguments that contain a pseudo + if ( rpseudo.test(unquoted) && + // Get excess from tokenize (recursively) + (excess = tokenize( unquoted, true )) && + // advance to the next closing parenthesis + (excess = unquoted.indexOf( ")", unquoted.length - excess ) - unquoted.length) ) { + + // excess is a negative index + unquoted = unquoted.slice( 0, excess ); + match[0] = match[0].slice( 0, excess ); + } + match[2] = unquoted; + } + + // Return only captures needed by the pseudo filter method (type and argument) + return match.slice( 0, 3 ); + } + }, + + filter: { + "ID": assertGetIdNotName ? + function( id ) { + id = id.replace( rbackslash, "" ); + return function( elem ) { + return elem.getAttribute("id") === id; + }; + } : + function( id ) { + id = id.replace( rbackslash, "" ); + return function( elem ) { + var node = typeof elem.getAttributeNode !== strundefined && elem.getAttributeNode("id"); + return node && node.value === id; + }; + }, + + "TAG": function( nodeName ) { + if ( nodeName === "*" ) { + return function() { return true; }; + } + nodeName = nodeName.replace( rbackslash, "" ).toLowerCase(); + + return function( elem ) { + return elem.nodeName && elem.nodeName.toLowerCase() === nodeName; + }; + }, + + "CLASS": function( className ) { + var pattern = classCache[ expando ][ className + " " ]; + + return pattern || + (pattern = new RegExp( "(^|" + whitespace + ")" + className + "(" + whitespace + "|$)" )) && + classCache( className, function( elem ) { + return pattern.test( elem.className || (typeof elem.getAttribute !== strundefined && elem.getAttribute("class")) || "" ); + }); + }, + + "ATTR": function( name, operator, check ) { + return function( elem, context ) { + var result = Sizzle.attr( elem, name ); + + if ( result == null ) { + return operator === "!="; + } + if ( !operator ) { + return true; + } + + result += ""; + + return operator === "=" ? result === check : + operator === "!=" ? result !== check : + operator === "^=" ? check && result.indexOf( check ) === 0 : + operator === "*=" ? check && result.indexOf( check ) > -1 : + operator === "$=" ? check && result.substr( result.length - check.length ) === check : + operator === "~=" ? ( " " + result + " " ).indexOf( check ) > -1 : + operator === "|=" ? result === check || result.substr( 0, check.length + 1 ) === check + "-" : + false; + }; + }, + + "CHILD": function( type, argument, first, last ) { + + if ( type === "nth" ) { + return function( elem ) { + var node, diff, + parent = elem.parentNode; + + if ( first === 1 && last === 0 ) { + return true; + } + + if ( parent ) { + diff = 0; + for ( node = parent.firstChild; node; node = node.nextSibling ) { + if ( node.nodeType === 1 ) { + diff++; + if ( elem === node ) { + break; + } + } + } + } + + // Incorporate the offset (or cast to NaN), then check against cycle size + diff -= last; + return diff === first || ( diff % first === 0 && diff / first >= 0 ); + }; + } + + return function( elem ) { + var 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; + + /* falls through */ + case "last": + while ( (node = node.nextSibling) ) { + if ( node.nodeType === 1 ) { + return false; + } + } + + return true; + } + }; + }, + + "PSEUDO": function( pseudo, argument ) { + // pseudo-class names are case-insensitive + // http://www.w3.org/TR/selectors/#pseudo-classes + // Prioritize by case sensitivity in case custom pseudos are added with uppercase letters + // Remember that setFilters inherits from pseudos + var args, + fn = Expr.pseudos[ pseudo ] || Expr.setFilters[ pseudo.toLowerCase() ] || + Sizzle.error( "unsupported pseudo: " + pseudo ); + + // The user may use createPseudo to indicate that + // arguments are needed to create the filter function + // just as Sizzle does + if ( fn[ expando ] ) { + return fn( argument ); + } + + // But maintain support for old signatures + if ( fn.length > 1 ) { + args = [ pseudo, pseudo, "", argument ]; + return Expr.setFilters.hasOwnProperty( pseudo.toLowerCase() ) ? + markFunction(function( seed, matches ) { + var idx, + matched = fn( seed, argument ), + i = matched.length; + while ( i-- ) { + idx = indexOf.call( seed, matched[i] ); + seed[ idx ] = !( matches[ idx ] = matched[i] ); + } + }) : + function( elem ) { + return fn( elem, 0, args ); + }; + } + + return fn; + } + }, + + pseudos: { + "not": markFunction(function( selector ) { + // Trim the selector passed to compile + // to avoid treating leading and trailing + // spaces as combinators + var input = [], + results = [], + matcher = compile( selector.replace( rtrim, "$1" ) ); + + return matcher[ expando ] ? + markFunction(function( seed, matches, context, xml ) { + var elem, + unmatched = matcher( seed, null, xml, [] ), + i = seed.length; + + // Match elements unmatched by `matcher` + while ( i-- ) { + if ( (elem = unmatched[i]) ) { + seed[i] = !(matches[i] = elem); + } + } + }) : + function( elem, context, xml ) { + input[0] = elem; + matcher( input, null, xml, results ); + return !results.pop(); + }; + }), + + "has": markFunction(function( selector ) { + return function( elem ) { + return Sizzle( selector, elem ).length > 0; + }; + }), + + "contains": markFunction(function( text ) { + return function( elem ) { + return ( elem.textContent || elem.innerText || getText( elem ) ).indexOf( text ) > -1; + }; + }), + + "enabled": function( elem ) { + return elem.disabled === false; + }, + + "disabled": function( elem ) { + return elem.disabled === true; + }, + + "checked": function( elem ) { + // In CSS3, :checked should return both checked and selected elements + // http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked + var nodeName = elem.nodeName.toLowerCase(); + return (nodeName === "input" && !!elem.checked) || (nodeName === "option" && !!elem.selected); + }, + + "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 !Expr.pseudos["empty"]( elem ); + }, + + "empty": function( elem ) { + // http://www.w3.org/TR/selectors/#empty-pseudo + // :empty is only affected by element nodes and content nodes(including text(3), cdata(4)), + // not comment, processing instructions, or others + // Thanks to Diego Perini for the nodeName shortcut + // Greater than "@" means alpha characters (specifically not starting with "#" or "?") + var nodeType; + elem = elem.firstChild; + while ( elem ) { + if ( elem.nodeName > "@" || (nodeType = elem.nodeType) === 3 || nodeType === 4 ) { + return false; + } + elem = elem.nextSibling; + } + return true; + }, + + "header": function( elem ) { + return rheader.test( elem.nodeName ); + }, + + "text": function( elem ) { + var type, attr; + // 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" && + (type = elem.type) === "text" && + ( (attr = elem.getAttribute("type")) == null || attr.toLowerCase() === type ); + }, + + // Input types + "radio": createInputPseudo("radio"), + "checkbox": createInputPseudo("checkbox"), + "file": createInputPseudo("file"), + "password": createInputPseudo("password"), + "image": createInputPseudo("image"), + + "submit": createButtonPseudo("submit"), + "reset": createButtonPseudo("reset"), + + "button": function( elem ) { + var name = elem.nodeName.toLowerCase(); + return name === "input" && elem.type === "button" || name === "button"; + }, + + "input": function( elem ) { + return rinputs.test( elem.nodeName ); + }, + + "focus": function( elem ) { + var doc = elem.ownerDocument; + return elem === doc.activeElement && (!doc.hasFocus || doc.hasFocus()) && !!(elem.type || elem.href || ~elem.tabIndex); + }, + + "active": function( elem ) { + return elem === elem.ownerDocument.activeElement; + }, + + // Positional types + "first": createPositionalPseudo(function() { + return [ 0 ]; + }), + + "last": createPositionalPseudo(function( matchIndexes, length ) { + return [ length - 1 ]; + }), + + "eq": createPositionalPseudo(function( matchIndexes, length, argument ) { + return [ argument < 0 ? argument + length : argument ]; + }), + + "even": createPositionalPseudo(function( matchIndexes, length ) { + for ( var i = 0; i < length; i += 2 ) { + matchIndexes.push( i ); + } + return matchIndexes; + }), + + "odd": createPositionalPseudo(function( matchIndexes, length ) { + for ( var i = 1; i < length; i += 2 ) { + matchIndexes.push( i ); + } + return matchIndexes; + }), + + "lt": createPositionalPseudo(function( matchIndexes, length, argument ) { + for ( var i = argument < 0 ? argument + length : argument; --i >= 0; ) { + matchIndexes.push( i ); + } + return matchIndexes; + }), + + "gt": createPositionalPseudo(function( matchIndexes, length, argument ) { + for ( var i = argument < 0 ? argument + length : argument; ++i < length; ) { + matchIndexes.push( i ); + } + return matchIndexes; + }) + } +}; + +function siblingCheck( a, b, ret ) { + if ( a === b ) { + return ret; + } + + var cur = a.nextSibling; + + while ( cur ) { + if ( cur === b ) { + return -1; + } + + cur = cur.nextSibling; + } + + return 1; +} + +sortOrder = docElem.compareDocumentPosition ? + function( a, b ) { + if ( a === b ) { + hasDuplicate = true; + return 0; + } + + return ( !a.compareDocumentPosition || !b.compareDocumentPosition ? + a.compareDocumentPosition : + a.compareDocumentPosition(b) & 4 + ) ? -1 : 1; + } : + 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 ); + }; + +// Always assume the presence of duplicates if sort doesn't +// pass them to our comparison function (as in Google Chrome). +[0, 0].sort( sortOrder ); +baseHasDuplicate = !hasDuplicate; + +// Document sorting and removing duplicates +Sizzle.uniqueSort = function( results ) { + var elem, + duplicates = [], + i = 1, + j = 0; + + hasDuplicate = baseHasDuplicate; + results.sort( sortOrder ); + + if ( hasDuplicate ) { + for ( ; (elem = results[i]); i++ ) { + if ( elem === results[ i - 1 ] ) { + j = duplicates.push( i ); + } + } + while ( j-- ) { + results.splice( duplicates[ j ], 1 ); + } + } + + return results; +}; + +Sizzle.error = function( msg ) { + throw new Error( "Syntax error, unrecognized expression: " + msg ); +}; + +function tokenize( selector, parseOnly ) { + var matched, match, tokens, type, + soFar, groups, preFilters, + cached = tokenCache[ expando ][ selector + " " ]; + + if ( cached ) { + return parseOnly ? 0 : cached.slice( 0 ); + } + + soFar = selector; + groups = []; + preFilters = Expr.preFilter; + + while ( soFar ) { + + // Comma and first run + if ( !matched || (match = rcomma.exec( soFar )) ) { + if ( match ) { + // Don't consume trailing commas as valid + soFar = soFar.slice( match[0].length ) || soFar; + } + groups.push( tokens = [] ); + } + + matched = false; + + // Combinators + if ( (match = rcombinators.exec( soFar )) ) { + tokens.push( matched = new Token( match.shift() ) ); + soFar = soFar.slice( matched.length ); + + // Cast descendant combinators to space + matched.type = match[0].replace( rtrim, " " ); + } + + // Filters + for ( type in Expr.filter ) { + if ( (match = matchExpr[ type ].exec( soFar )) && (!preFilters[ type ] || + (match = preFilters[ type ]( match ))) ) { + + tokens.push( matched = new Token( match.shift() ) ); + soFar = soFar.slice( matched.length ); + matched.type = type; + matched.matches = match; + } + } + + if ( !matched ) { + break; + } + } + + // Return the length of the invalid excess + // if we're just parsing + // Otherwise, throw an error or return tokens + return parseOnly ? + soFar.length : + soFar ? + Sizzle.error( selector ) : + // Cache the tokens + tokenCache( selector, groups ).slice( 0 ); +} + +function addCombinator( matcher, combinator, base ) { + var dir = combinator.dir, + checkNonElements = base && combinator.dir === "parentNode", + doneName = done++; + + return combinator.first ? + // Check against closest ancestor/preceding element + function( elem, context, xml ) { + while ( (elem = elem[ dir ]) ) { + if ( checkNonElements || elem.nodeType === 1 ) { + return matcher( elem, context, xml ); + } + } + } : + + // Check against all ancestor/preceding elements + function( elem, context, xml ) { + // We can't set arbitrary data on XML nodes, so they don't benefit from dir caching + if ( !xml ) { + var cache, + dirkey = dirruns + " " + doneName + " ", + cachedkey = dirkey + cachedruns; + while ( (elem = elem[ dir ]) ) { + if ( checkNonElements || elem.nodeType === 1 ) { + if ( (cache = elem[ expando ]) === cachedkey ) { + return elem.sizset; + } else if ( typeof cache === "string" && cache.indexOf(dirkey) === 0 ) { + if ( elem.sizset ) { + return elem; + } + } else { + elem[ expando ] = cachedkey; + if ( matcher( elem, context, xml ) ) { + elem.sizset = true; + return elem; + } + elem.sizset = false; + } + } + } + } else { + while ( (elem = elem[ dir ]) ) { + if ( checkNonElements || elem.nodeType === 1 ) { + if ( matcher( elem, context, xml ) ) { + return elem; + } + } + } + } + }; +} + +function elementMatcher( matchers ) { + return matchers.length > 1 ? + function( elem, context, xml ) { + var i = matchers.length; + while ( i-- ) { + if ( !matchers[i]( elem, context, xml ) ) { + return false; + } + } + return true; + } : + matchers[0]; +} + +function condense( unmatched, map, filter, context, xml ) { + var elem, + newUnmatched = [], + i = 0, + len = unmatched.length, + mapped = map != null; + + for ( ; i < len; i++ ) { + if ( (elem = unmatched[i]) ) { + if ( !filter || filter( elem, context, xml ) ) { + newUnmatched.push( elem ); + if ( mapped ) { + map.push( i ); + } + } + } + } + + return newUnmatched; +} + +function setMatcher( preFilter, selector, matcher, postFilter, postFinder, postSelector ) { + if ( postFilter && !postFilter[ expando ] ) { + postFilter = setMatcher( postFilter ); + } + if ( postFinder && !postFinder[ expando ] ) { + postFinder = setMatcher( postFinder, postSelector ); + } + return markFunction(function( seed, results, context, xml ) { + var temp, i, elem, + preMap = [], + postMap = [], + preexisting = results.length, + + // Get initial elements from seed or context + elems = seed || multipleContexts( selector || "*", context.nodeType ? [ context ] : context, [] ), + + // Prefilter to get matcher input, preserving a map for seed-results synchronization + matcherIn = preFilter && ( seed || !selector ) ? + condense( elems, preMap, preFilter, context, xml ) : + elems, + + matcherOut = matcher ? + // If we have a postFinder, or filtered seed, or non-seed postFilter or preexisting results, + postFinder || ( seed ? preFilter : preexisting || postFilter ) ? + + // ...intermediate processing is necessary + [] : + + // ...otherwise use results directly + results : + matcherIn; + + // Find primary matches + if ( matcher ) { + matcher( matcherIn, matcherOut, context, xml ); + } + + // Apply postFilter + if ( postFilter ) { + temp = condense( matcherOut, postMap ); + postFilter( temp, [], context, xml ); + + // Un-match failing elements by moving them back to matcherIn + i = temp.length; + while ( i-- ) { + if ( (elem = temp[i]) ) { + matcherOut[ postMap[i] ] = !(matcherIn[ postMap[i] ] = elem); + } + } + } + + if ( seed ) { + if ( postFinder || preFilter ) { + if ( postFinder ) { + // Get the final matcherOut by condensing this intermediate into postFinder contexts + temp = []; + i = matcherOut.length; + while ( i-- ) { + if ( (elem = matcherOut[i]) ) { + // Restore matcherIn since elem is not yet a final match + temp.push( (matcherIn[i] = elem) ); + } + } + postFinder( null, (matcherOut = []), temp, xml ); + } + + // Move matched elements from seed to results to keep them synchronized + i = matcherOut.length; + while ( i-- ) { + if ( (elem = matcherOut[i]) && + (temp = postFinder ? indexOf.call( seed, elem ) : preMap[i]) > -1 ) { + + seed[temp] = !(results[temp] = elem); + } + } + } + + // Add elements to results, through postFinder if defined + } else { + matcherOut = condense( + matcherOut === results ? + matcherOut.splice( preexisting, matcherOut.length ) : + matcherOut + ); + if ( postFinder ) { + postFinder( null, results, matcherOut, xml ); + } else { + push.apply( results, matcherOut ); + } + } + }); +} + +function matcherFromTokens( tokens ) { + var checkContext, matcher, j, + len = tokens.length, + leadingRelative = Expr.relative[ tokens[0].type ], + implicitRelative = leadingRelative || Expr.relative[" "], + i = leadingRelative ? 1 : 0, + + // The foundational matcher ensures that elements are reachable from top-level context(s) + matchContext = addCombinator( function( elem ) { + return elem === checkContext; + }, implicitRelative, true ), + matchAnyContext = addCombinator( function( elem ) { + return indexOf.call( checkContext, elem ) > -1; + }, implicitRelative, true ), + matchers = [ function( elem, context, xml ) { + return ( !leadingRelative && ( xml || context !== outermostContext ) ) || ( + (checkContext = context).nodeType ? + matchContext( elem, context, xml ) : + matchAnyContext( elem, context, xml ) ); + } ]; + + for ( ; i < len; i++ ) { + if ( (matcher = Expr.relative[ tokens[i].type ]) ) { + matchers = [ addCombinator( elementMatcher( matchers ), matcher ) ]; + } else { + matcher = Expr.filter[ tokens[i].type ].apply( null, tokens[i].matches ); + + // Return special upon seeing a positional matcher + if ( matcher[ expando ] ) { + // Find the next relative operator (if any) for proper handling + j = ++i; + for ( ; j < len; j++ ) { + if ( Expr.relative[ tokens[j].type ] ) { + break; + } + } + return setMatcher( + i > 1 && elementMatcher( matchers ), + i > 1 && tokens.slice( 0, i - 1 ).join("").replace( rtrim, "$1" ), + matcher, + i < j && matcherFromTokens( tokens.slice( i, j ) ), + j < len && matcherFromTokens( (tokens = tokens.slice( j )) ), + j < len && tokens.join("") + ); + } + matchers.push( matcher ); + } + } + + return elementMatcher( matchers ); +} + +function matcherFromGroupMatchers( elementMatchers, setMatchers ) { + var bySet = setMatchers.length > 0, + byElement = elementMatchers.length > 0, + superMatcher = function( seed, context, xml, results, expandContext ) { + var elem, j, matcher, + setMatched = [], + matchedCount = 0, + i = "0", + unmatched = seed && [], + outermost = expandContext != null, + contextBackup = outermostContext, + // We must always have either seed elements or context + elems = seed || byElement && Expr.find["TAG"]( "*", expandContext && context.parentNode || context ), + // Nested matchers should use non-integer dirruns + dirrunsUnique = (dirruns += contextBackup == null ? 1 : Math.E); + + if ( outermost ) { + outermostContext = context !== document && context; + cachedruns = superMatcher.el; + } + + // Add elements passing elementMatchers directly to results + for ( ; (elem = elems[i]) != null; i++ ) { + if ( byElement && elem ) { + for ( j = 0; (matcher = elementMatchers[j]); j++ ) { + if ( matcher( elem, context, xml ) ) { + results.push( elem ); + break; + } + } + if ( outermost ) { + dirruns = dirrunsUnique; + cachedruns = ++superMatcher.el; + } + } + + // Track unmatched elements for set filters + if ( bySet ) { + // They will have gone through all possible matchers + if ( (elem = !matcher && elem) ) { + matchedCount--; + } + + // Lengthen the array for every element, matched or not + if ( seed ) { + unmatched.push( elem ); + } + } + } + + // Apply set filters to unmatched elements + matchedCount += i; + if ( bySet && i !== matchedCount ) { + for ( j = 0; (matcher = setMatchers[j]); j++ ) { + matcher( unmatched, setMatched, context, xml ); + } + + if ( seed ) { + // Reintegrate element matches to eliminate the need for sorting + if ( matchedCount > 0 ) { + while ( i-- ) { + if ( !(unmatched[i] || setMatched[i]) ) { + setMatched[i] = pop.call( results ); + } + } + } + + // Discard index placeholder values to get only actual matches + setMatched = condense( setMatched ); + } + + // Add matches to results + push.apply( results, setMatched ); + + // Seedless set matches succeeding multiple successful matchers stipulate sorting + if ( outermost && !seed && setMatched.length > 0 && + ( matchedCount + setMatchers.length ) > 1 ) { + + Sizzle.uniqueSort( results ); + } + } + + // Override manipulation of globals by nested matchers + if ( outermost ) { + dirruns = dirrunsUnique; + outermostContext = contextBackup; + } + + return unmatched; + }; + + superMatcher.el = 0; + return bySet ? + markFunction( superMatcher ) : + superMatcher; +} + +compile = Sizzle.compile = function( selector, group /* Internal Use Only */ ) { + var i, + setMatchers = [], + elementMatchers = [], + cached = compilerCache[ expando ][ selector + " " ]; + + if ( !cached ) { + // Generate a function of recursive functions that can be used to check each element + if ( !group ) { + group = tokenize( selector ); + } + i = group.length; + while ( i-- ) { + cached = matcherFromTokens( group[i] ); + if ( cached[ expando ] ) { + setMatchers.push( cached ); + } else { + elementMatchers.push( cached ); + } + } + + // Cache the compiled function + cached = compilerCache( selector, matcherFromGroupMatchers( elementMatchers, setMatchers ) ); + } + return cached; +}; + +function multipleContexts( selector, contexts, results ) { + var i = 0, + len = contexts.length; + for ( ; i < len; i++ ) { + Sizzle( selector, contexts[i], results ); + } + return results; +} + +function select( selector, context, results, seed, xml ) { + var i, tokens, token, type, find, + match = tokenize( selector ), + j = match.length; + + if ( !seed ) { + // Try to minimize operations if there is only one group + if ( match.length === 1 ) { + + // Take a shortcut and set the context if the root selector is an ID + tokens = match[0] = match[0].slice( 0 ); + if ( tokens.length > 2 && (token = tokens[0]).type === "ID" && + context.nodeType === 9 && !xml && + Expr.relative[ tokens[1].type ] ) { + + context = Expr.find["ID"]( token.matches[0].replace( rbackslash, "" ), context, xml )[0]; + if ( !context ) { + return results; + } + + selector = selector.slice( tokens.shift().length ); + } + + // Fetch a seed set for right-to-left matching + for ( i = matchExpr["POS"].test( selector ) ? -1 : tokens.length - 1; i >= 0; i-- ) { + token = tokens[i]; + + // Abort if we hit a combinator + if ( Expr.relative[ (type = token.type) ] ) { + break; + } + if ( (find = Expr.find[ type ]) ) { + // Search, expanding context for leading sibling combinators + if ( (seed = find( + token.matches[0].replace( rbackslash, "" ), + rsibling.test( tokens[0].type ) && context.parentNode || context, + xml + )) ) { + + // If seed is empty or no tokens remain, we can return early + tokens.splice( i, 1 ); + selector = seed.length && tokens.join(""); + if ( !selector ) { + push.apply( results, slice.call( seed, 0 ) ); + return results; + } + + break; + } + } + } + } + } + + // Compile and execute a filtering function + // Provide `match` to avoid retokenization if we modified the selector above + compile( selector, match )( + seed, + context, + xml, + results, + rsibling.test( selector ) + ); + return results; +} + +if ( document.querySelectorAll ) { + (function() { + var disconnectedMatch, + oldSelect = select, + rescape = /'|\\/g, + rattributeQuotes = /\=[\x20\t\r\n\f]*([^'"\]]*)[\x20\t\r\n\f]*\]/g, + + // qSa(:focus) reports false when true (Chrome 21), no need to also add to buggyMatches since matches checks buggyQSA + // A support test would require too much code (would include document ready) + rbuggyQSA = [ ":focus" ], + + // matchesSelector(:active) reports false when true (IE9/Opera 11.5) + // A support test would require too much code (would include document ready) + // just skip matchesSelector for :active + rbuggyMatches = [ ":active" ], + matches = docElem.matchesSelector || + docElem.mozMatchesSelector || + docElem.webkitMatchesSelector || + docElem.oMatchesSelector || + docElem.msMatchesSelector; + + // Build QSA regex + // Regex strategy adopted from Diego Perini + assert(function( div ) { + // Select is set to empty string on purpose + // This is to test IE's treatment of not explictly + // setting a boolean content attribute, + // since its presence should be enough + // http://bugs.jquery.com/ticket/12359 + div.innerHTML = ""; + + // IE8 - Some boolean attributes are not treated correctly + if ( !div.querySelectorAll("[selected]").length ) { + rbuggyQSA.push( "\\[" + whitespace + "*(?:checked|disabled|ismap|multiple|readonly|selected|value)" ); + } + + // Webkit/Opera - :checked should return selected option elements + // http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked + // IE8 throws error here (do not put tests after this one) + if ( !div.querySelectorAll(":checked").length ) { + rbuggyQSA.push(":checked"); + } + }); + + assert(function( div ) { + + // Opera 10-12/IE9 - ^= $= *= and empty values + // Should not select anything + div.innerHTML = "

      "; + if ( div.querySelectorAll("[test^='']").length ) { + rbuggyQSA.push( "[*^$]=" + whitespace + "*(?:\"\"|'')" ); + } + + // FF 3.5 - :enabled/:disabled and hidden elements (hidden elements are still enabled) + // IE8 throws error here (do not put tests after this one) + div.innerHTML = ""; + if ( !div.querySelectorAll(":enabled").length ) { + rbuggyQSA.push(":enabled", ":disabled"); + } + }); + + // rbuggyQSA always contains :focus, so no need for a length check + rbuggyQSA = /* rbuggyQSA.length && */ new RegExp( rbuggyQSA.join("|") ); + + select = function( selector, context, results, seed, xml ) { + // Only use querySelectorAll when not filtering, + // when this is not xml, + // and when no QSA bugs apply + if ( !seed && !xml && !rbuggyQSA.test( selector ) ) { + var groups, i, + old = true, + nid = expando, + newContext = context, + newSelector = context.nodeType === 9 && selector; + + // 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 + if ( context.nodeType === 1 && context.nodeName.toLowerCase() !== "object" ) { + groups = tokenize( selector ); + + if ( (old = context.getAttribute("id")) ) { + nid = old.replace( rescape, "\\$&" ); + } else { + context.setAttribute( "id", nid ); + } + nid = "[id='" + nid + "'] "; + + i = groups.length; + while ( i-- ) { + groups[i] = nid + groups[i].join(""); + } + newContext = rsibling.test( selector ) && context.parentNode || context; + newSelector = groups.join(","); + } + + if ( newSelector ) { + try { + push.apply( results, slice.call( newContext.querySelectorAll( + newSelector + ), 0 ) ); + return results; + } catch(qsaError) { + } finally { + if ( !old ) { + context.removeAttribute("id"); + } + } + } + } + + return oldSelect( selector, context, results, seed, xml ); + }; + + if ( matches ) { + assert(function( div ) { + // Check to see if it's possible to do matchesSelector + // on a disconnected node (IE 9) + disconnectedMatch = matches.call( div, "div" ); + + // This should fail with an exception + // Gecko does not error, returns false instead + try { + matches.call( div, "[test!='']:sizzle" ); + rbuggyMatches.push( "!=", pseudos ); + } catch ( e ) {} + }); + + // rbuggyMatches always contains :active and :focus, so no need for a length check + rbuggyMatches = /* rbuggyMatches.length && */ new RegExp( rbuggyMatches.join("|") ); + + Sizzle.matchesSelector = function( elem, expr ) { + // Make sure that attribute selectors are quoted + expr = expr.replace( rattributeQuotes, "='$1']" ); + + // rbuggyMatches always contains :active, so no need for an existence check + if ( !isXML( elem ) && !rbuggyMatches.test( expr ) && !rbuggyQSA.test( expr ) ) { + try { + var ret = matches.call( elem, 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 + elem.document && elem.document.nodeType !== 11 ) { + return ret; + } + } catch(e) {} + } + + return Sizzle( expr, null, null, [ elem ] ).length > 0; + }; + } + })(); +} + +// Deprecated +Expr.pseudos["nth"] = Expr.pseudos["eq"]; + +// Back-compat +function setFilters() {} +Expr.filters = setFilters.prototype = Expr.pseudos; +Expr.setFilters = new setFilters(); + +// Override sizzle attribute retrieval +Sizzle.attr = jQuery.attr; +jQuery.find = Sizzle; +jQuery.expr = Sizzle.selectors; +jQuery.expr[":"] = jQuery.expr.pseudos; +jQuery.unique = Sizzle.uniqueSort; +jQuery.text = Sizzle.getText; +jQuery.isXMLDoc = Sizzle.isXML; +jQuery.contains = Sizzle.contains; + + +})( window ); +var runtil = /Until$/, + rparentsprev = /^(?:parents|prev(?:Until|All))/, + isSimple = /^.[^:#\[\.,]*$/, + rneedsContext = jQuery.expr.match.needsContext, + // 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 i, l, length, n, r, ret, + self = this; + + 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; + } + } + }); + } + + ret = this.pushStack( "", "find", selector ); + + 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 i, + targets = jQuery( target, this ), + len = targets.length; + + return this.filter(function() { + for ( i = 0; i < len; 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" ? + // If this is a positional/relative selector, check membership in the returned set + // so $("p:first").is("p:last") won't return true for a doc with two "p". + rneedsContext.test( selector ) ? + jQuery( selector, this.context ).index( this[0] ) >= 0 : + jQuery.filter( selector, this ).length > 0 : + this.filter( selector ).length > 0 ); + }, + + closest: function( selectors, context ) { + var cur, + i = 0, + l = this.length, + ret = [], + pos = rneedsContext.test( selectors ) || typeof selectors !== "string" ? + jQuery( selectors, context || this.context ) : + 0; + + for ( ; i < l; i++ ) { + cur = this[i]; + + while ( cur && cur.ownerDocument && cur !== context && cur.nodeType !== 11 ) { + if ( pos ? pos.index(cur) > -1 : jQuery.find.matchesSelector(cur, selectors) ) { + ret.push( cur ); + break; + } + cur = cur.parentNode; + } + } + + 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 ) { + + // No argument, return index in parent + if ( !elem ) { + return ( this[0] && this[0].parentNode ) ? this.prevAll().length : -1; + } + + // index in selector + if ( typeof elem === "string" ) { + return jQuery.inArray( this[0], jQuery( elem ) ); + } + + // 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 ) ); + }, + + addBack: function( selector ) { + return this.add( selector == null ? + this.prevObject : this.prevObject.filter(selector) + ); + } +}); + +jQuery.fn.andSelf = jQuery.fn.addBack; + +// 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; +} + +function sibling( cur, dir ) { + do { + cur = cur[ dir ]; + } while ( cur && cur.nodeType !== 1 ); + + return cur; +} + +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 sibling( elem, "nextSibling" ); + }, + prev: function( elem ) { + return sibling( elem, "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.merge( [], elem.childNodes ); + } +}, function( name, fn ) { + jQuery.fn[ name ] = function( until, selector ) { + var ret = jQuery.map( this, fn, until ); + + 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 && rparentsprev.test( name ) ) { + ret = ret.reverse(); + } + + return this.pushStack( ret, name, core_slice.call( arguments ).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; + }, + + 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; + }); +} +function createSafeFragment( document ) { + var list = nodeNames.split( "|" ), + safeFrag = document.createDocumentFragment(); + + if ( safeFrag.createElement ) { + while ( list.length ) { + safeFrag.createElement( + list.pop() + ); + } + } + return safeFrag; +} + +var nodeNames = "abbr|article|aside|audio|bdi|canvas|data|datalist|details|figcaption|figure|footer|" + + "header|hgroup|mark|meter|nav|output|progress|section|summary|time|video", + rinlinejQuery = / jQuery\d+="(?:null|\d+)"/g, + rleadingWhitespace = /^\s+/, + rxhtmlTag = /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/gi, + rtagName = /<([\w:]+)/, + rtbody = /]", "i"), + rcheckableType = /^(?:checkbox|radio)$/, + // checked="checked" or checked + rchecked = /checked\s*(?:[^=]|=\s*.checked.)/i, + rscriptType = /\/(java|ecma)script/i, + rcleanScript = /^\s*\s*$/g, + wrapMap = { + option: [ 1, "" ], + legend: [ 1, "
      ", "
      " ], + thead: [ 1, "", "
      " ], + tr: [ 2, "", "
      " ], + td: [ 3, "", "
      " ], + col: [ 2, "", "
      " ], + area: [ 1, "", "" ], + _default: [ 0, "", "" ] + }, + safeFragment = createSafeFragment( document ), + fragmentDiv = safeFragment.appendChild( document.createElement("div") ); + +wrapMap.optgroup = wrapMap.option; +wrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead; +wrapMap.th = wrapMap.td; + +// IE6-8 can't serialize link, script, style, or any html5 (NoScope) tags, +// unless wrapped in a div with non-breaking characters in front of it. +if ( !jQuery.support.htmlSerialize ) { + wrapMap._default = [ 1, "X
      ", "
      " ]; +} + +jQuery.fn.extend({ + text: function( value ) { + return jQuery.access( this, function( value ) { + return value === undefined ? + jQuery.text( this ) : + this.empty().append( ( this[0] && this[0].ownerDocument || document ).createTextNode( value ) ); + }, null, value, arguments.length ); + }, + + wrapAll: function( html ) { + if ( jQuery.isFunction( html ) ) { + return this.each(function(i) { + jQuery(this).wrapAll( html.call(this, i) ); + }); + } + + if ( this[0] ) { + // The elements to wrap the target around + var wrap = jQuery( html, this[0].ownerDocument ).eq(0).clone(true); + + if ( this[0].parentNode ) { + wrap.insertBefore( this[0] ); + } + + wrap.map(function() { + var elem = this; + + while ( elem.firstChild && elem.firstChild.nodeType === 1 ) { + elem = elem.firstChild; + } + + return elem; + }).append( this ); + } + + return this; + }, + + wrapInner: function( html ) { + if ( jQuery.isFunction( html ) ) { + return this.each(function(i) { + jQuery(this).wrapInner( html.call(this, i) ); + }); + } + + return this.each(function() { + var self = jQuery( this ), + contents = self.contents(); + + if ( contents.length ) { + contents.wrapAll( html ); + + } else { + self.append( html ); + } + }); + }, + + wrap: function( html ) { + var isFunction = jQuery.isFunction( html ); + + return this.each(function(i) { + jQuery( this ).wrapAll( isFunction ? html.call(this, i) : html ); + }); + }, + + unwrap: function() { + return this.parent().each(function() { + if ( !jQuery.nodeName( this, "body" ) ) { + jQuery( this ).replaceWith( this.childNodes ); + } + }).end(); + }, + + append: function() { + return this.domManip(arguments, true, function( elem ) { + if ( this.nodeType === 1 || this.nodeType === 11 ) { + this.appendChild( elem ); + } + }); + }, + + prepend: function() { + return this.domManip(arguments, true, function( elem ) { + if ( this.nodeType === 1 || this.nodeType === 11 ) { + this.insertBefore( elem, this.firstChild ); + } + }); + }, + + before: function() { + if ( !isDisconnected( this[0] ) ) { + return this.domManip(arguments, false, function( elem ) { + this.parentNode.insertBefore( elem, this ); + }); + } + + if ( arguments.length ) { + var set = jQuery.clean( arguments ); + return this.pushStack( jQuery.merge( set, this ), "before", this.selector ); + } + }, + + after: function() { + if ( !isDisconnected( this[0] ) ) { + return this.domManip(arguments, false, function( elem ) { + this.parentNode.insertBefore( elem, this.nextSibling ); + }); + } + + if ( arguments.length ) { + var set = jQuery.clean( arguments ); + return this.pushStack( jQuery.merge( this, set ), "after", this.selector ); + } + }, + + // keepData is for internal use only--do not document + remove: function( selector, keepData ) { + var elem, + i = 0; + + for ( ; (elem = this[i]) != null; i++ ) { + if ( !selector || jQuery.filter( selector, [ elem ] ).length ) { + if ( !keepData && elem.nodeType === 1 ) { + jQuery.cleanData( elem.getElementsByTagName("*") ); + jQuery.cleanData( [ elem ] ); + } + + if ( elem.parentNode ) { + elem.parentNode.removeChild( elem ); + } + } + } + + return this; + }, + + empty: function() { + var elem, + i = 0; + + for ( ; (elem = this[i]) != null; i++ ) { + // Remove element nodes and prevent memory leaks + if ( elem.nodeType === 1 ) { + jQuery.cleanData( elem.getElementsByTagName("*") ); + } + + // Remove any remaining nodes + while ( elem.firstChild ) { + elem.removeChild( elem.firstChild ); + } + } + + return this; + }, + + clone: function( dataAndEvents, deepDataAndEvents ) { + dataAndEvents = dataAndEvents == null ? false : dataAndEvents; + deepDataAndEvents = deepDataAndEvents == null ? dataAndEvents : deepDataAndEvents; + + return this.map( function () { + return jQuery.clone( this, dataAndEvents, deepDataAndEvents ); + }); + }, + + html: function( value ) { + return jQuery.access( this, function( value ) { + var elem = this[0] || {}, + i = 0, + l = this.length; + + if ( value === undefined ) { + return elem.nodeType === 1 ? + elem.innerHTML.replace( rinlinejQuery, "" ) : + undefined; + } + + // See if we can take a shortcut and just use innerHTML + if ( typeof value === "string" && !rnoInnerhtml.test( value ) && + ( jQuery.support.htmlSerialize || !rnoshimcache.test( value ) ) && + ( jQuery.support.leadingWhitespace || !rleadingWhitespace.test( value ) ) && + !wrapMap[ ( rtagName.exec( value ) || ["", ""] )[1].toLowerCase() ] ) { + + value = value.replace( rxhtmlTag, "<$1>" ); + + try { + for (; i < l; i++ ) { + // Remove element nodes and prevent memory leaks + elem = this[i] || {}; + if ( elem.nodeType === 1 ) { + jQuery.cleanData( elem.getElementsByTagName( "*" ) ); + elem.innerHTML = value; + } + } + + elem = 0; + + // If using innerHTML throws an exception, use the fallback method + } catch(e) {} + } + + if ( elem ) { + this.empty().append( value ); + } + }, null, value, arguments.length ); + }, + + replaceWith: function( value ) { + if ( !isDisconnected( this[0] ) ) { + // Make sure that the elements are removed from the DOM before they are inserted + // this can help fix replacing a parent with child elements + if ( jQuery.isFunction( value ) ) { + return this.each(function(i) { + var self = jQuery(this), old = self.html(); + self.replaceWith( value.call( this, i, old ) ); + }); + } + + if ( typeof value !== "string" ) { + value = jQuery( value ).detach(); + } + + return this.each(function() { + var next = this.nextSibling, + parent = this.parentNode; + + jQuery( this ).remove(); + + if ( next ) { + jQuery(next).before( value ); + } else { + jQuery(parent).append( value ); + } + }); + } + + return this.length ? + this.pushStack( jQuery(jQuery.isFunction(value) ? value() : value), "replaceWith", value ) : + this; + }, + + detach: function( selector ) { + return this.remove( selector, true ); + }, + + domManip: function( args, table, callback ) { + + // Flatten any nested arrays + args = [].concat.apply( [], args ); + + var results, first, fragment, iNoClone, + i = 0, + value = args[0], + scripts = [], + l = this.length; + + // We can't cloneNode fragments that contain checked, in WebKit + if ( !jQuery.support.checkClone && l > 1 && typeof value === "string" && rchecked.test( value ) ) { + return this.each(function() { + jQuery(this).domManip( args, table, callback ); + }); + } + + if ( jQuery.isFunction(value) ) { + return this.each(function(i) { + var self = jQuery(this); + args[0] = value.call( this, i, table ? self.html() : undefined ); + self.domManip( args, table, callback ); + }); + } + + if ( this[0] ) { + results = jQuery.buildFragment( args, this, scripts ); + fragment = results.fragment; + first = fragment.firstChild; + + if ( fragment.childNodes.length === 1 ) { + fragment = first; + } + + if ( first ) { + table = table && jQuery.nodeName( first, "tr" ); + + // Use the original fragment for the last item instead of the first because it can end up + // being emptied incorrectly in certain situations (#8070). + // Fragments from the fragment cache must always be cloned and never used in place. + for ( iNoClone = results.cacheable || l - 1; i < l; i++ ) { + callback.call( + table && jQuery.nodeName( this[i], "table" ) ? + findOrAppend( this[i], "tbody" ) : + this[i], + i === iNoClone ? + fragment : + jQuery.clone( fragment, true, true ) + ); + } + } + + // Fix #11809: Avoid leaking memory + fragment = first = null; + + if ( scripts.length ) { + jQuery.each( scripts, function( i, elem ) { + if ( elem.src ) { + if ( jQuery.ajax ) { + jQuery.ajax({ + url: elem.src, + type: "GET", + dataType: "script", + async: false, + global: false, + "throws": true + }); + } else { + jQuery.error("no ajax"); + } + } else { + jQuery.globalEval( ( elem.text || elem.textContent || elem.innerHTML || "" ).replace( rcleanScript, "" ) ); + } + + if ( elem.parentNode ) { + elem.parentNode.removeChild( elem ); + } + }); + } + } + + return this; + } +}); + +function findOrAppend( elem, tag ) { + return elem.getElementsByTagName( tag )[0] || elem.appendChild( elem.ownerDocument.createElement( tag ) ); +} + +function cloneCopyEvent( src, dest ) { + + if ( dest.nodeType !== 1 || !jQuery.hasData( src ) ) { + return; + } + + var type, i, l, + oldData = jQuery._data( src ), + curData = jQuery._data( dest, oldData ), + events = oldData.events; + + if ( events ) { + delete curData.handle; + curData.events = {}; + + for ( type in events ) { + for ( i = 0, l = events[ type ].length; i < l; i++ ) { + jQuery.event.add( dest, type, events[ type ][ i ] ); + } + } + } + + // make the cloned public data object a copy from the original + if ( curData.data ) { + curData.data = jQuery.extend( {}, curData.data ); + } +} + +function cloneFixAttributes( src, dest ) { + var nodeName; + + // We do not need to do anything for non-Elements + if ( dest.nodeType !== 1 ) { + return; + } + + // clearAttributes removes the attributes, which we don't want, + // but also removes the attachEvent events, which we *do* want + if ( dest.clearAttributes ) { + dest.clearAttributes(); + } + + // mergeAttributes, in contrast, only merges back on the + // original attributes, not the events + if ( dest.mergeAttributes ) { + dest.mergeAttributes( src ); + } + + nodeName = dest.nodeName.toLowerCase(); + + if ( nodeName === "object" ) { + // IE6-10 improperly clones children of object elements using classid. + // IE10 throws NoModificationAllowedError if parent is null, #12132. + if ( dest.parentNode ) { + dest.outerHTML = src.outerHTML; + } + + // This path appears unavoidable for IE9. When cloning an object + // element in IE9, the outerHTML strategy above is not sufficient. + // If the src has innerHTML and the destination does not, + // copy the src.innerHTML into the dest.innerHTML. #10324 + if ( jQuery.support.html5Clone && (src.innerHTML && !jQuery.trim(dest.innerHTML)) ) { + dest.innerHTML = src.innerHTML; + } + + } else if ( nodeName === "input" && rcheckableType.test( src.type ) ) { + // IE6-8 fails to persist the checked state of a cloned checkbox + // or radio button. Worse, IE6-7 fail to give the cloned element + // a checked appearance if the defaultChecked value isn't also set + + dest.defaultChecked = dest.checked = src.checked; + + // IE6-7 get confused and end up setting the value of a cloned + // checkbox/radio button to an empty string instead of "on" + if ( dest.value !== src.value ) { + dest.value = src.value; + } + + // IE6-8 fails to return the selected option to the default selected + // state when cloning options + } else if ( nodeName === "option" ) { + dest.selected = src.defaultSelected; + + // IE6-8 fails to set the defaultValue to the correct value when + // cloning other types of input fields + } else if ( nodeName === "input" || nodeName === "textarea" ) { + dest.defaultValue = src.defaultValue; + + // IE blanks contents when cloning scripts + } else if ( nodeName === "script" && dest.text !== src.text ) { + dest.text = src.text; + } + + // Event data gets referenced instead of copied if the expando + // gets copied too + dest.removeAttribute( jQuery.expando ); +} + +jQuery.buildFragment = function( args, context, scripts ) { + var fragment, cacheable, cachehit, + first = args[ 0 ]; + + // Set context from what may come in as undefined or a jQuery collection or a node + // Updated to fix #12266 where accessing context[0] could throw an exception in IE9/10 & + // also doubles as fix for #8950 where plain objects caused createDocumentFragment exception + context = context || document; + context = !context.nodeType && context[0] || context; + context = context.ownerDocument || context; + + // Only cache "small" (1/2 KB) HTML strings that are associated with the main document + // Cloning options loses the selected state, so don't cache them + // IE 6 doesn't like it when you put or elements in a fragment + // Also, WebKit does not clone 'checked' attributes on cloneNode, so don't cache + // Lastly, IE6,7,8 will not correctly reuse cached fragments that were created from unknown elems #10501 + if ( args.length === 1 && typeof first === "string" && first.length < 512 && context === document && + first.charAt(0) === "<" && !rnocache.test( first ) && + (jQuery.support.checkClone || !rchecked.test( first )) && + (jQuery.support.html5Clone || !rnoshimcache.test( first )) ) { + + // Mark cacheable and look for a hit + cacheable = true; + fragment = jQuery.fragments[ first ]; + cachehit = fragment !== undefined; + } + + if ( !fragment ) { + fragment = context.createDocumentFragment(); + jQuery.clean( args, context, fragment, scripts ); + + // Update the cache, but only store false + // unless this is a second parsing of the same content + if ( cacheable ) { + jQuery.fragments[ first ] = cachehit && fragment; + } + } + + return { fragment: fragment, cacheable: cacheable }; +}; + +jQuery.fragments = {}; + +jQuery.each({ + appendTo: "append", + prependTo: "prepend", + insertBefore: "before", + insertAfter: "after", + replaceAll: "replaceWith" +}, function( name, original ) { + jQuery.fn[ name ] = function( selector ) { + var elems, + i = 0, + ret = [], + insert = jQuery( selector ), + l = insert.length, + parent = this.length === 1 && this[0].parentNode; + + if ( (parent == null || parent && parent.nodeType === 11 && parent.childNodes.length === 1) && l === 1 ) { + insert[ original ]( this[0] ); + return this; + } else { + for ( ; i < l; i++ ) { + elems = ( i > 0 ? this.clone(true) : this ).get(); + jQuery( insert[i] )[ original ]( elems ); + ret = ret.concat( elems ); + } + + return this.pushStack( ret, name, insert.selector ); + } + }; +}); + +function getAll( elem ) { + if ( typeof elem.getElementsByTagName !== "undefined" ) { + return elem.getElementsByTagName( "*" ); + + } else if ( typeof elem.querySelectorAll !== "undefined" ) { + return elem.querySelectorAll( "*" ); + + } else { + return []; + } +} + +// Used in clean, fixes the defaultChecked property +function fixDefaultChecked( elem ) { + if ( rcheckableType.test( elem.type ) ) { + elem.defaultChecked = elem.checked; + } +} + +jQuery.extend({ + clone: function( elem, dataAndEvents, deepDataAndEvents ) { + var srcElements, + destElements, + i, + clone; + + if ( jQuery.support.html5Clone || jQuery.isXMLDoc(elem) || !rnoshimcache.test( "<" + elem.nodeName + ">" ) ) { + clone = elem.cloneNode( true ); + + // IE<=8 does not properly clone detached, unknown element nodes + } else { + fragmentDiv.innerHTML = elem.outerHTML; + fragmentDiv.removeChild( clone = fragmentDiv.firstChild ); + } + + if ( (!jQuery.support.noCloneEvent || !jQuery.support.noCloneChecked) && + (elem.nodeType === 1 || elem.nodeType === 11) && !jQuery.isXMLDoc(elem) ) { + // IE copies events bound via attachEvent when using cloneNode. + // Calling detachEvent on the clone will also remove the events + // from the original. In order to get around this, we use some + // proprietary methods to clear the events. Thanks to MooTools + // guys for this hotness. + + cloneFixAttributes( elem, clone ); + + // Using Sizzle here is crazy slow, so we use getElementsByTagName instead + srcElements = getAll( elem ); + destElements = getAll( clone ); + + // Weird iteration because IE will replace the length property + // with an element if you are cloning the body and one of the + // elements on the page has a name or id of "length" + for ( i = 0; srcElements[i]; ++i ) { + // Ensure that the destination node is not null; Fixes #9587 + if ( destElements[i] ) { + cloneFixAttributes( srcElements[i], destElements[i] ); + } + } + } + + // Copy the events from the original to the clone + if ( dataAndEvents ) { + cloneCopyEvent( elem, clone ); + + if ( deepDataAndEvents ) { + srcElements = getAll( elem ); + destElements = getAll( clone ); + + for ( i = 0; srcElements[i]; ++i ) { + cloneCopyEvent( srcElements[i], destElements[i] ); + } + } + } + + srcElements = destElements = null; + + // Return the cloned set + return clone; + }, + + clean: function( elems, context, fragment, scripts ) { + var i, j, elem, tag, wrap, depth, div, hasBody, tbody, len, handleScript, jsTags, + safe = context === document && safeFragment, + ret = []; + + // Ensure that context is a document + if ( !context || typeof context.createDocumentFragment === "undefined" ) { + context = document; + } + + // Use the already-created safe fragment if context permits + for ( i = 0; (elem = elems[i]) != null; i++ ) { + if ( typeof elem === "number" ) { + elem += ""; + } + + if ( !elem ) { + continue; + } + + // Convert html string into DOM nodes + if ( typeof elem === "string" ) { + if ( !rhtml.test( elem ) ) { + elem = context.createTextNode( elem ); + } else { + // Ensure a safe container in which to render the html + safe = safe || createSafeFragment( context ); + div = context.createElement("div"); + safe.appendChild( div ); + + // Fix "XHTML"-style tags in all browsers + elem = elem.replace(rxhtmlTag, "<$1>"); + + // Go to html and back, then peel off extra wrappers + tag = ( rtagName.exec( elem ) || ["", ""] )[1].toLowerCase(); + wrap = wrapMap[ tag ] || wrapMap._default; + depth = wrap[0]; + div.innerHTML = wrap[1] + elem + wrap[2]; + + // Move to the right depth + while ( depth-- ) { + div = div.lastChild; + } + + // Remove IE's autoinserted from table fragments + if ( !jQuery.support.tbody ) { + + // String was a , *may* have spurious + hasBody = rtbody.test(elem); + tbody = tag === "table" && !hasBody ? + div.firstChild && div.firstChild.childNodes : + + // String was a bare or + wrap[1] === "
      " && !hasBody ? + div.childNodes : + []; + + for ( j = tbody.length - 1; j >= 0 ; --j ) { + if ( jQuery.nodeName( tbody[ j ], "tbody" ) && !tbody[ j ].childNodes.length ) { + tbody[ j ].parentNode.removeChild( tbody[ j ] ); + } + } + } + + // IE completely kills leading whitespace when innerHTML is used + if ( !jQuery.support.leadingWhitespace && rleadingWhitespace.test( elem ) ) { + div.insertBefore( context.createTextNode( rleadingWhitespace.exec(elem)[0] ), div.firstChild ); + } + + elem = div.childNodes; + + // Take out of fragment container (we need a fresh div each time) + div.parentNode.removeChild( div ); + } + } + + if ( elem.nodeType ) { + ret.push( elem ); + } else { + jQuery.merge( ret, elem ); + } + } + + // Fix #11356: Clear elements from safeFragment + if ( div ) { + elem = div = safe = null; + } + + // Reset defaultChecked for any radios and checkboxes + // about to be appended to the DOM in IE 6/7 (#8060) + if ( !jQuery.support.appendChecked ) { + for ( i = 0; (elem = ret[i]) != null; i++ ) { + if ( jQuery.nodeName( elem, "input" ) ) { + fixDefaultChecked( elem ); + } else if ( typeof elem.getElementsByTagName !== "undefined" ) { + jQuery.grep( elem.getElementsByTagName("input"), fixDefaultChecked ); + } + } + } + + // Append elements to a provided document fragment + if ( fragment ) { + // Special handling of each script element + handleScript = function( elem ) { + // Check if we consider it executable + if ( !elem.type || rscriptType.test( elem.type ) ) { + // Detach the script and store it in the scripts array (if provided) or the fragment + // Return truthy to indicate that it has been handled + return scripts ? + scripts.push( elem.parentNode ? elem.parentNode.removeChild( elem ) : elem ) : + fragment.appendChild( elem ); + } + }; + + for ( i = 0; (elem = ret[i]) != null; i++ ) { + // Check if we're done after handling an executable script + if ( !( jQuery.nodeName( elem, "script" ) && handleScript( elem ) ) ) { + // Append to fragment and handle embedded scripts + fragment.appendChild( elem ); + if ( typeof elem.getElementsByTagName !== "undefined" ) { + // handleScript alters the DOM, so use jQuery.merge to ensure snapshot iteration + jsTags = jQuery.grep( jQuery.merge( [], elem.getElementsByTagName("script") ), handleScript ); + + // Splice the scripts into ret after their former ancestor and advance our index beyond them + ret.splice.apply( ret, [i + 1, 0].concat( jsTags ) ); + i += jsTags.length; + } + } + } + } + + return ret; + }, + + cleanData: function( elems, /* internal */ acceptData ) { + var data, id, elem, type, + i = 0, + internalKey = jQuery.expando, + cache = jQuery.cache, + deleteExpando = jQuery.support.deleteExpando, + special = jQuery.event.special; + + for ( ; (elem = elems[i]) != null; i++ ) { + + if ( acceptData || jQuery.acceptData( elem ) ) { + + id = elem[ internalKey ]; + data = id && cache[ id ]; + + if ( data ) { + if ( data.events ) { + for ( type in data.events ) { + if ( special[ type ] ) { + jQuery.event.remove( elem, type ); + + // This is a shortcut to avoid jQuery.event.remove's overhead + } else { + jQuery.removeEvent( elem, type, data.handle ); + } + } + } + + // Remove cache only if it was not already removed by jQuery.event.remove + if ( cache[ id ] ) { + + delete cache[ id ]; + + // 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 ( deleteExpando ) { + delete elem[ internalKey ]; + + } else if ( elem.removeAttribute ) { + elem.removeAttribute( internalKey ); + + } else { + elem[ internalKey ] = null; + } + + jQuery.deletedIds.push( id ); + } + } + } + } + } +}); +// Limit scope pollution from any deprecated API +(function() { + +var matched, browser; + +// Use of jQuery.browser is frowned upon. +// More details: http://api.jquery.com/jQuery.browser +// jQuery.uaMatch maintained for back-compat +jQuery.uaMatch = function( ua ) { + ua = ua.toLowerCase(); + + var match = /(chrome)[ \/]([\w.]+)/.exec( ua ) || + /(webkit)[ \/]([\w.]+)/.exec( ua ) || + /(opera)(?:.*version|)[ \/]([\w.]+)/.exec( ua ) || + /(msie) ([\w.]+)/.exec( ua ) || + ua.indexOf("compatible") < 0 && /(mozilla)(?:.*? rv:([\w.]+)|)/.exec( ua ) || + []; + + return { + browser: match[ 1 ] || "", + version: match[ 2 ] || "0" + }; +}; + +matched = jQuery.uaMatch( navigator.userAgent ); +browser = {}; + +if ( matched.browser ) { + browser[ matched.browser ] = true; + browser.version = matched.version; +} + +// Chrome is Webkit, but Webkit is also Safari. +if ( browser.chrome ) { + browser.webkit = true; +} else if ( browser.webkit ) { + browser.safari = true; +} + +jQuery.browser = browser; + +jQuery.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; +}; + +})(); +var curCSS, iframe, iframeDoc, + ralpha = /alpha\([^)]*\)/i, + ropacity = /opacity=([^)]*)/, + rposition = /^(top|right|bottom|left)$/, + // swappable if display is none or starts with table except "table", "table-cell", or "table-caption" + // see here for display values: https://developer.mozilla.org/en-US/docs/CSS/display + rdisplayswap = /^(none|table(?!-c[ea]).+)/, + rmargin = /^margin/, + rnumsplit = new RegExp( "^(" + core_pnum + ")(.*)$", "i" ), + rnumnonpx = new RegExp( "^(" + core_pnum + ")(?!px)[a-z%]+$", "i" ), + rrelNum = new RegExp( "^([-+])=(" + core_pnum + ")", "i" ), + elemdisplay = { BODY: "block" }, + + cssShow = { position: "absolute", visibility: "hidden", display: "block" }, + cssNormalTransform = { + letterSpacing: 0, + fontWeight: 400 + }, + + cssExpand = [ "Top", "Right", "Bottom", "Left" ], + cssPrefixes = [ "Webkit", "O", "Moz", "ms" ], + + eventsToggle = jQuery.fn.toggle; + +// return a css property mapped to a potentially vendor prefixed property +function vendorPropName( style, name ) { + + // shortcut for names that are not vendor prefixed + if ( name in style ) { + return name; + } + + // check for vendor prefixed names + var capName = name.charAt(0).toUpperCase() + name.slice(1), + origName = name, + i = cssPrefixes.length; + + while ( i-- ) { + name = cssPrefixes[ i ] + capName; + if ( name in style ) { + return name; + } + } + + return origName; +} + +function isHidden( elem, el ) { + elem = el || elem; + return jQuery.css( elem, "display" ) === "none" || !jQuery.contains( elem.ownerDocument, elem ); +} + +function showHide( elements, show ) { + var elem, display, + values = [], + index = 0, + length = elements.length; + + for ( ; index < length; index++ ) { + elem = elements[ index ]; + if ( !elem.style ) { + continue; + } + values[ index ] = jQuery._data( elem, "olddisplay" ); + if ( show ) { + // Reset the inline display of this element to learn if it is + // being hidden by cascaded rules or not + if ( !values[ index ] && elem.style.display === "none" ) { + elem.style.display = ""; + } + + // Set elements which have been overridden with display: none + // in a stylesheet to whatever the default browser style is + // for such an element + if ( elem.style.display === "" && isHidden( elem ) ) { + values[ index ] = jQuery._data( elem, "olddisplay", css_defaultDisplay(elem.nodeName) ); + } + } else { + display = curCSS( elem, "display" ); + + if ( !values[ index ] && display !== "none" ) { + jQuery._data( elem, "olddisplay", display ); + } + } + } + + // Set the display of most of the elements in a second loop + // to avoid the constant reflow + for ( index = 0; index < length; index++ ) { + elem = elements[ index ]; + if ( !elem.style ) { + continue; + } + if ( !show || elem.style.display === "none" || elem.style.display === "" ) { + elem.style.display = show ? values[ index ] || "" : "none"; + } + } + + return elements; +} + +jQuery.fn.extend({ + css: function( name, value ) { + return jQuery.access( this, function( elem, name, value ) { + return value !== undefined ? + jQuery.style( elem, name, value ) : + jQuery.css( elem, name ); + }, name, value, arguments.length > 1 ); + }, + show: function() { + return showHide( this, true ); + }, + hide: function() { + return showHide( this ); + }, + toggle: function( state, fn2 ) { + var bool = typeof state === "boolean"; + + if ( jQuery.isFunction( state ) && jQuery.isFunction( fn2 ) ) { + return eventsToggle.apply( this, arguments ); + } + + return this.each(function() { + if ( bool ? state : isHidden( this ) ) { + jQuery( this ).show(); + } else { + jQuery( this ).hide(); + } + }); + } +}); + +jQuery.extend({ + // Add in style property hooks for overriding the default + // behavior of getting and setting a style property + cssHooks: { + opacity: { + get: function( elem, computed ) { + if ( computed ) { + // We should always get a number back from opacity + var ret = curCSS( elem, "opacity" ); + return ret === "" ? "1" : ret; + + } + } + } + }, + + // Exclude the following css properties to add px + cssNumber: { + "fillOpacity": true, + "fontWeight": true, + "lineHeight": true, + "opacity": true, + "orphans": true, + "widows": true, + "zIndex": true, + "zoom": true + }, + + // Add in properties whose names you wish to fix before + // setting or getting the value + cssProps: { + // normalize float css property + "float": jQuery.support.cssFloat ? "cssFloat" : "styleFloat" + }, + + // Get and set the style property on a DOM Node + style: function( elem, name, value, extra ) { + // Don't set styles on text and comment nodes + if ( !elem || elem.nodeType === 3 || elem.nodeType === 8 || !elem.style ) { + return; + } + + // Make sure that we're working with the right name + var ret, type, hooks, + origName = jQuery.camelCase( name ), + style = elem.style; + + name = jQuery.cssProps[ origName ] || ( jQuery.cssProps[ origName ] = vendorPropName( style, origName ) ); + + // gets hook for the prefixed version + // followed by the unprefixed version + hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ]; + + // Check if we're setting a value + if ( value !== undefined ) { + type = typeof value; + + // convert relative number strings (+= or -=) to relative numbers. #7345 + if ( type === "string" && (ret = rrelNum.exec( value )) ) { + value = ( ret[1] + 1 ) * ret[2] + parseFloat( jQuery.css( elem, name ) ); + // Fixes bug #9237 + type = "number"; + } + + // Make sure that NaN and null values aren't set. See: #7116 + if ( value == null || type === "number" && isNaN( value ) ) { + return; + } + + // If a number was passed in, add 'px' to the (except for certain CSS properties) + if ( type === "number" && !jQuery.cssNumber[ origName ] ) { + value += "px"; + } + + // If a hook was provided, use that value, otherwise just set the specified value + if ( !hooks || !("set" in hooks) || (value = hooks.set( elem, value, extra )) !== undefined ) { + // Wrapped to prevent IE from throwing errors when 'invalid' values are provided + // Fixes bug #5509 + try { + style[ name ] = value; + } catch(e) {} + } + + } else { + // If a hook was provided get the non-computed value from there + if ( hooks && "get" in hooks && (ret = hooks.get( elem, false, extra )) !== undefined ) { + return ret; + } + + // Otherwise just get the value from the style object + return style[ name ]; + } + }, + + css: function( elem, name, numeric, extra ) { + var val, num, hooks, + origName = jQuery.camelCase( name ); + + // Make sure that we're working with the right name + name = jQuery.cssProps[ origName ] || ( jQuery.cssProps[ origName ] = vendorPropName( elem.style, origName ) ); + + // gets hook for the prefixed version + // followed by the unprefixed version + hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ]; + + // If a hook was provided get the computed value from there + if ( hooks && "get" in hooks ) { + val = hooks.get( elem, true, extra ); + } + + // Otherwise, if a way to get the computed value exists, use that + if ( val === undefined ) { + val = curCSS( elem, name ); + } + + //convert "normal" to computed value + if ( val === "normal" && name in cssNormalTransform ) { + val = cssNormalTransform[ name ]; + } + + // Return, converting to number if forced or a qualifier was provided and val looks numeric + if ( numeric || extra !== undefined ) { + num = parseFloat( val ); + return numeric || jQuery.isNumeric( num ) ? num || 0 : val; + } + return val; + }, + + // A method for quickly swapping in/out CSS properties to get correct calculations + swap: function( elem, options, callback ) { + var ret, name, + old = {}; + + // Remember the old values, and insert the new ones + for ( name in options ) { + old[ name ] = elem.style[ name ]; + elem.style[ name ] = options[ name ]; + } + + ret = callback.call( elem ); + + // Revert the old values + for ( name in options ) { + elem.style[ name ] = old[ name ]; + } + + return ret; + } +}); + +// NOTE: To any future maintainer, we've window.getComputedStyle +// because jsdom on node.js will break without it. +if ( window.getComputedStyle ) { + curCSS = function( elem, name ) { + var ret, width, minWidth, maxWidth, + computed = window.getComputedStyle( elem, null ), + style = elem.style; + + if ( computed ) { + + // getPropertyValue is only needed for .css('filter') in IE9, see #12537 + ret = computed.getPropertyValue( name ) || computed[ name ]; + + if ( ret === "" && !jQuery.contains( elem.ownerDocument, elem ) ) { + ret = jQuery.style( elem, name ); + } + + // A tribute to the "awesome hack by Dean Edwards" + // Chrome < 17 and Safari 5.0 uses "computed value" instead of "used value" for margin-right + // Safari 5.1.7 (at least) returns percentage for a larger set of values, but width seems to be reliably pixels + // this is against the CSSOM draft spec: http://dev.w3.org/csswg/cssom/#resolved-values + if ( rnumnonpx.test( ret ) && rmargin.test( name ) ) { + width = style.width; + minWidth = style.minWidth; + maxWidth = style.maxWidth; + + style.minWidth = style.maxWidth = style.width = ret; + ret = computed.width; + + style.width = width; + style.minWidth = minWidth; + style.maxWidth = maxWidth; + } + } + + return ret; + }; +} else if ( document.documentElement.currentStyle ) { + curCSS = function( elem, name ) { + var left, rsLeft, + ret = elem.currentStyle && elem.currentStyle[ name ], + style = elem.style; + + // Avoid setting ret to empty string here + // so we don't default to auto + if ( ret == null && style && style[ name ] ) { + ret = style[ name ]; + } + + // From the awesome hack by Dean Edwards + // http://erik.eae.net/archives/2007/07/27/18.54.15/#comment-102291 + + // If we're not dealing with a regular pixel number + // but a number that has a weird ending, we need to convert it to pixels + // but not position css attributes, as those are proportional to the parent element instead + // and we can't measure the parent instead because it might trigger a "stacking dolls" problem + if ( rnumnonpx.test( ret ) && !rposition.test( name ) ) { + + // Remember the original values + left = style.left; + rsLeft = elem.runtimeStyle && elem.runtimeStyle.left; + + // Put in the new values to get a computed value out + if ( rsLeft ) { + elem.runtimeStyle.left = elem.currentStyle.left; + } + style.left = name === "fontSize" ? "1em" : ret; + ret = style.pixelLeft + "px"; + + // Revert the changed values + style.left = left; + if ( rsLeft ) { + elem.runtimeStyle.left = rsLeft; + } + } + + return ret === "" ? "auto" : ret; + }; +} + +function setPositiveNumber( elem, value, subtract ) { + var matches = rnumsplit.exec( value ); + return matches ? + Math.max( 0, matches[ 1 ] - ( subtract || 0 ) ) + ( matches[ 2 ] || "px" ) : + value; +} + +function augmentWidthOrHeight( elem, name, extra, isBorderBox ) { + var i = extra === ( isBorderBox ? "border" : "content" ) ? + // If we already have the right measurement, avoid augmentation + 4 : + // Otherwise initialize for horizontal or vertical properties + name === "width" ? 1 : 0, + + val = 0; + + for ( ; i < 4; i += 2 ) { + // both box models exclude margin, so add it if we want it + if ( extra === "margin" ) { + // we use jQuery.css instead of curCSS here + // because of the reliableMarginRight CSS hook! + val += jQuery.css( elem, extra + cssExpand[ i ], true ); + } + + // From this point on we use curCSS for maximum performance (relevant in animations) + if ( isBorderBox ) { + // border-box includes padding, so remove it if we want content + if ( extra === "content" ) { + val -= parseFloat( curCSS( elem, "padding" + cssExpand[ i ] ) ) || 0; + } + + // at this point, extra isn't border nor margin, so remove border + if ( extra !== "margin" ) { + val -= parseFloat( curCSS( elem, "border" + cssExpand[ i ] + "Width" ) ) || 0; + } + } else { + // at this point, extra isn't content, so add padding + val += parseFloat( curCSS( elem, "padding" + cssExpand[ i ] ) ) || 0; + + // at this point, extra isn't content nor padding, so add border + if ( extra !== "padding" ) { + val += parseFloat( curCSS( elem, "border" + cssExpand[ i ] + "Width" ) ) || 0; + } + } + } + + return val; +} + +function getWidthOrHeight( elem, name, extra ) { + + // Start with offset property, which is equivalent to the border-box value + var val = name === "width" ? elem.offsetWidth : elem.offsetHeight, + valueIsBorderBox = true, + isBorderBox = jQuery.support.boxSizing && jQuery.css( elem, "boxSizing" ) === "border-box"; + + // some non-html elements return undefined for offsetWidth, so check for null/undefined + // svg - https://bugzilla.mozilla.org/show_bug.cgi?id=649285 + // MathML - https://bugzilla.mozilla.org/show_bug.cgi?id=491668 + if ( val <= 0 || val == null ) { + // Fall back to computed then uncomputed css if necessary + val = curCSS( elem, name ); + if ( val < 0 || val == null ) { + val = elem.style[ name ]; + } + + // Computed unit is not pixels. Stop here and return. + if ( rnumnonpx.test(val) ) { + return val; + } + + // we need the check for style in case a browser which returns unreliable values + // for getComputedStyle silently falls back to the reliable elem.style + valueIsBorderBox = isBorderBox && ( jQuery.support.boxSizingReliable || val === elem.style[ name ] ); + + // Normalize "", auto, and prepare for extra + val = parseFloat( val ) || 0; + } + + // use the active box-sizing model to add/subtract irrelevant styles + return ( val + + augmentWidthOrHeight( + elem, + name, + extra || ( isBorderBox ? "border" : "content" ), + valueIsBorderBox + ) + ) + "px"; +} + + +// Try to determine the default display value of an element +function css_defaultDisplay( nodeName ) { + if ( elemdisplay[ nodeName ] ) { + return elemdisplay[ nodeName ]; + } + + var elem = jQuery( "<" + nodeName + ">" ).appendTo( document.body ), + display = elem.css("display"); + elem.remove(); + + // If the simple way fails, + // get element's real default display by attaching it to a temp iframe + if ( display === "none" || display === "" ) { + // Use the already-created iframe if possible + iframe = document.body.appendChild( + iframe || jQuery.extend( document.createElement("iframe"), { + frameBorder: 0, + width: 0, + height: 0 + }) + ); + + // Create a cacheable copy of the iframe document on first call. + // IE and Opera will allow us to reuse the iframeDoc without re-writing the fake HTML + // document to it; WebKit & Firefox won't allow reusing the iframe document. + if ( !iframeDoc || !iframe.createElement ) { + iframeDoc = ( iframe.contentWindow || iframe.contentDocument ).document; + iframeDoc.write(""); + iframeDoc.close(); + } + + elem = iframeDoc.body.appendChild( iframeDoc.createElement(nodeName) ); + + display = curCSS( elem, "display" ); + document.body.removeChild( iframe ); + } + + // Store the correct default display + elemdisplay[ nodeName ] = display; + + return display; +} + +jQuery.each([ "height", "width" ], function( i, name ) { + jQuery.cssHooks[ name ] = { + get: function( elem, computed, extra ) { + if ( computed ) { + // certain elements can have dimension info if we invisibly show them + // however, it must have a current display style that would benefit from this + if ( elem.offsetWidth === 0 && rdisplayswap.test( curCSS( elem, "display" ) ) ) { + return jQuery.swap( elem, cssShow, function() { + return getWidthOrHeight( elem, name, extra ); + }); + } else { + return getWidthOrHeight( elem, name, extra ); + } + } + }, + + set: function( elem, value, extra ) { + return setPositiveNumber( elem, value, extra ? + augmentWidthOrHeight( + elem, + name, + extra, + jQuery.support.boxSizing && jQuery.css( elem, "boxSizing" ) === "border-box" + ) : 0 + ); + } + }; +}); + +if ( !jQuery.support.opacity ) { + jQuery.cssHooks.opacity = { + get: function( elem, computed ) { + // IE uses filters for opacity + return ropacity.test( (computed && elem.currentStyle ? elem.currentStyle.filter : elem.style.filter) || "" ) ? + ( 0.01 * parseFloat( RegExp.$1 ) ) + "" : + computed ? "1" : ""; + }, + + set: function( elem, value ) { + var style = elem.style, + currentStyle = elem.currentStyle, + opacity = jQuery.isNumeric( value ) ? "alpha(opacity=" + value * 100 + ")" : "", + filter = currentStyle && currentStyle.filter || style.filter || ""; + + // IE has trouble with opacity if it does not have layout + // Force it by setting the zoom level + style.zoom = 1; + + // if setting opacity to 1, and no other filters exist - attempt to remove filter attribute #6652 + if ( value >= 1 && jQuery.trim( filter.replace( ralpha, "" ) ) === "" && + style.removeAttribute ) { + + // Setting style.filter to null, "" & " " still leave "filter:" in the cssText + // if "filter:" is present at all, clearType is disabled, we want to avoid this + // style.removeAttribute is IE Only, but so apparently is this code path... + style.removeAttribute( "filter" ); + + // if there there is no filter style applied in a css rule, we are done + if ( currentStyle && !currentStyle.filter ) { + return; + } + } + + // otherwise, set new filter values + style.filter = ralpha.test( filter ) ? + filter.replace( ralpha, opacity ) : + filter + " " + opacity; + } + }; +} + +// These hooks cannot be added until DOM ready because the support test +// for it is not run until after DOM ready +jQuery(function() { + if ( !jQuery.support.reliableMarginRight ) { + jQuery.cssHooks.marginRight = { + get: function( elem, computed ) { + // WebKit Bug 13343 - getComputedStyle returns wrong value for margin-right + // Work around by temporarily setting element display to inline-block + return jQuery.swap( elem, { "display": "inline-block" }, function() { + if ( computed ) { + return curCSS( elem, "marginRight" ); + } + }); + } + }; + } + + // Webkit bug: https://bugs.webkit.org/show_bug.cgi?id=29084 + // getComputedStyle returns percent when specified for top/left/bottom/right + // rather than make the css module depend on the offset module, we just check for it here + if ( !jQuery.support.pixelPosition && jQuery.fn.position ) { + jQuery.each( [ "top", "left" ], function( i, prop ) { + jQuery.cssHooks[ prop ] = { + get: function( elem, computed ) { + if ( computed ) { + var ret = curCSS( elem, prop ); + // if curCSS returns percentage, fallback to offset + return rnumnonpx.test( ret ) ? jQuery( elem ).position()[ prop ] + "px" : ret; + } + } + }; + }); + } + +}); + +if ( jQuery.expr && jQuery.expr.filters ) { + jQuery.expr.filters.hidden = function( elem ) { + return ( elem.offsetWidth === 0 && elem.offsetHeight === 0 ) || (!jQuery.support.reliableHiddenOffsets && ((elem.style && elem.style.display) || curCSS( elem, "display" )) === "none"); + }; + + jQuery.expr.filters.visible = function( elem ) { + return !jQuery.expr.filters.hidden( elem ); + }; +} + +// These hooks are used by animate to expand properties +jQuery.each({ + margin: "", + padding: "", + border: "Width" +}, function( prefix, suffix ) { + jQuery.cssHooks[ prefix + suffix ] = { + expand: function( value ) { + var i, + + // assumes a single number if not a string + parts = typeof value === "string" ? value.split(" ") : [ value ], + expanded = {}; + + for ( i = 0; i < 4; i++ ) { + expanded[ prefix + cssExpand[ i ] + suffix ] = + parts[ i ] || parts[ i - 2 ] || parts[ 0 ]; + } + + return expanded; + } + }; + + if ( !rmargin.test( prefix ) ) { + jQuery.cssHooks[ prefix + suffix ].set = setPositiveNumber; + } +}); +var r20 = /%20/g, + rbracket = /\[\]$/, + rCRLF = /\r?\n/g, + rinput = /^(?:color|date|datetime|datetime-local|email|hidden|month|number|password|range|search|tel|text|time|url|week)$/i, + rselectTextarea = /^(?:select|textarea)/i; + +jQuery.fn.extend({ + serialize: function() { + return jQuery.param( this.serializeArray() ); + }, + serializeArray: function() { + return this.map(function(){ + return this.elements ? jQuery.makeArray( this.elements ) : this; + }) + .filter(function(){ + return this.name && !this.disabled && + ( this.checked || rselectTextarea.test( this.nodeName ) || + rinput.test( this.type ) ); + }) + .map(function( i, elem ){ + var val = jQuery( this ).val(); + + return val == null ? + null : + jQuery.isArray( val ) ? + jQuery.map( val, function( val, i ){ + return { name: elem.name, value: val.replace( rCRLF, "\r\n" ) }; + }) : + { name: elem.name, value: val.replace( rCRLF, "\r\n" ) }; + }).get(); + } +}); + +//Serialize an array of form elements or a set of +//key/values into a query string +jQuery.param = function( a, traditional ) { + var prefix, + s = [], + add = function( key, value ) { + // If value is a function, invoke it and return its value + value = jQuery.isFunction( value ) ? value() : ( value == null ? "" : value ); + s[ s.length ] = encodeURIComponent( key ) + "=" + encodeURIComponent( value ); + }; + + // Set traditional to true for jQuery <= 1.3.2 behavior. + if ( traditional === undefined ) { + traditional = jQuery.ajaxSettings && jQuery.ajaxSettings.traditional; + } + + // If an array was passed in, assume that it is an array of form elements. + if ( jQuery.isArray( a ) || ( a.jquery && !jQuery.isPlainObject( a ) ) ) { + // Serialize the form elements + jQuery.each( a, function() { + add( this.name, this.value ); + }); + + } else { + // If traditional, encode the "old" way (the way 1.3.2 or older + // did it), otherwise encode params recursively. + for ( prefix in a ) { + buildParams( prefix, a[ prefix ], traditional, add ); + } + } + + // Return the resulting serialization + return s.join( "&" ).replace( r20, "+" ); +}; + +function buildParams( prefix, obj, traditional, add ) { + var name; + + if ( jQuery.isArray( obj ) ) { + // Serialize array item. + jQuery.each( obj, function( i, v ) { + if ( traditional || rbracket.test( prefix ) ) { + // Treat each array item as a scalar. + add( prefix, v ); + + } else { + // If array item is non-scalar (array or object), encode its + // numeric index to resolve deserialization ambiguity issues. + // Note that rack (as of 1.0.0) can't currently deserialize + // nested arrays properly, and attempting to do so may cause + // a server error. Possible fixes are to modify rack's + // deserialization algorithm or to provide an option or flag + // to force array serialization to be shallow. + buildParams( prefix + "[" + ( typeof v === "object" ? i : "" ) + "]", v, traditional, add ); + } + }); + + } else if ( !traditional && jQuery.type( obj ) === "object" ) { + // Serialize object item. + for ( name in obj ) { + buildParams( prefix + "[" + name + "]", obj[ name ], traditional, add ); + } + + } else { + // Serialize scalar item. + add( prefix, obj ); + } +} +var + // Document location + ajaxLocParts, + ajaxLocation, + + rhash = /#.*$/, + rheaders = /^(.*?):[ \t]*([^\r\n]*)\r?$/mg, // IE leaves an \r character at EOL + // #7653, #8125, #8152: local protocol detection + rlocalProtocol = /^(?:about|app|app\-storage|.+\-extension|file|res|widget):$/, + rnoContent = /^(?:GET|HEAD)$/, + rprotocol = /^\/\//, + rquery = /\?/, + rscript = /)<[^<]*)*<\/script>/gi, + rts = /([?&])_=[^&]*/, + rurl = /^([\w\+\.\-]+:)(?:\/\/([^\/?#:]*)(?::(\d+)|)|)/, + + // Keep a copy of the old load method + _load = jQuery.fn.load, + + /* Prefilters + * 1) They are useful to introduce custom dataTypes (see ajax/jsonp.js for an example) + * 2) These are called: + * - BEFORE asking for a transport + * - AFTER param serialization (s.data is a string if s.processData is true) + * 3) key is the dataType + * 4) the catchall symbol "*" can be used + * 5) execution will start with transport dataType and THEN continue down to "*" if needed + */ + prefilters = {}, + + /* Transports bindings + * 1) key is the dataType + * 2) the catchall symbol "*" can be used + * 3) selection will start with transport dataType and THEN go to "*" if needed + */ + transports = {}, + + // Avoid comment-prolog char sequence (#10098); must appease lint and evade compression + allTypes = ["*/"] + ["*"]; + +// #8138, IE may throw an exception when accessing +// a field from window.location if document.domain has been set +try { + ajaxLocation = location.href; +} catch( e ) { + // Use the href attribute of an A element + // since IE will modify it given document.location + ajaxLocation = document.createElement( "a" ); + ajaxLocation.href = ""; + ajaxLocation = ajaxLocation.href; +} + +// Segment location into parts +ajaxLocParts = rurl.exec( ajaxLocation.toLowerCase() ) || []; + +// Base "constructor" for jQuery.ajaxPrefilter and jQuery.ajaxTransport +function addToPrefiltersOrTransports( structure ) { + + // dataTypeExpression is optional and defaults to "*" + return function( dataTypeExpression, func ) { + + if ( typeof dataTypeExpression !== "string" ) { + func = dataTypeExpression; + dataTypeExpression = "*"; + } + + var dataType, list, placeBefore, + dataTypes = dataTypeExpression.toLowerCase().split( core_rspace ), + i = 0, + length = dataTypes.length; + + if ( jQuery.isFunction( func ) ) { + // For each dataType in the dataTypeExpression + for ( ; i < length; i++ ) { + dataType = dataTypes[ i ]; + // We control if we're asked to add before + // any existing element + placeBefore = /^\+/.test( dataType ); + if ( placeBefore ) { + dataType = dataType.substr( 1 ) || "*"; + } + list = structure[ dataType ] = structure[ dataType ] || []; + // then we add to the structure accordingly + list[ placeBefore ? "unshift" : "push" ]( func ); + } + } + }; +} + +// Base inspection function for prefilters and transports +function inspectPrefiltersOrTransports( structure, options, originalOptions, jqXHR, + dataType /* internal */, inspected /* internal */ ) { + + dataType = dataType || options.dataTypes[ 0 ]; + inspected = inspected || {}; + + inspected[ dataType ] = true; + + var selection, + list = structure[ dataType ], + i = 0, + length = list ? list.length : 0, + executeOnly = ( structure === prefilters ); + + for ( ; i < length && ( executeOnly || !selection ); i++ ) { + selection = list[ i ]( options, originalOptions, jqXHR ); + // If we got redirected to another dataType + // we try there if executing only and not done already + if ( typeof selection === "string" ) { + if ( !executeOnly || inspected[ selection ] ) { + selection = undefined; + } else { + options.dataTypes.unshift( selection ); + selection = inspectPrefiltersOrTransports( + structure, options, originalOptions, jqXHR, selection, inspected ); + } + } + } + // If we're only executing or nothing was selected + // we try the catchall dataType if not done already + if ( ( executeOnly || !selection ) && !inspected[ "*" ] ) { + selection = inspectPrefiltersOrTransports( + structure, options, originalOptions, jqXHR, "*", inspected ); + } + // unnecessary when only executing (prefilters) + // but it'll be ignored by the caller in that case + return selection; +} + +// A special extend for ajax options +// that takes "flat" options (not to be deep extended) +// Fixes #9887 +function ajaxExtend( target, src ) { + var key, deep, + flatOptions = jQuery.ajaxSettings.flatOptions || {}; + for ( key in src ) { + if ( src[ key ] !== undefined ) { + ( flatOptions[ key ] ? target : ( deep || ( deep = {} ) ) )[ key ] = src[ key ]; + } + } + if ( deep ) { + jQuery.extend( true, target, deep ); + } +} + +jQuery.fn.load = function( url, params, callback ) { + if ( typeof url !== "string" && _load ) { + return _load.apply( this, arguments ); + } + + // Don't do a request if no elements are being requested + if ( !this.length ) { + return this; + } + + var selector, type, response, + self = this, + off = url.indexOf(" "); + + if ( off >= 0 ) { + selector = url.slice( off, url.length ); + url = url.slice( 0, off ); + } + + // If it's a function + if ( jQuery.isFunction( params ) ) { + + // We assume that it's the callback + callback = params; + params = undefined; + + // Otherwise, build a param string + } else if ( params && typeof params === "object" ) { + type = "POST"; + } + + // Request the remote document + jQuery.ajax({ + url: url, + + // if "type" variable is undefined, then "GET" method will be used + type: type, + dataType: "html", + data: params, + complete: function( jqXHR, status ) { + if ( callback ) { + self.each( callback, response || [ jqXHR.responseText, status, jqXHR ] ); + } + } + }).done(function( responseText ) { + + // Save response for use in complete callback + response = arguments; + + // See if a selector was specified + self.html( selector ? + + // Create a dummy div to hold the results + jQuery("
      ") + + // inject the contents of the document in, removing the scripts + // to avoid any 'Permission Denied' errors in IE + .append( responseText.replace( rscript, "" ) ) + + // Locate the specified elements + .find( selector ) : + + // If not, just inject the full result + responseText ); + + }); + + return this; +}; + +// Attach a bunch of functions for handling common AJAX events +jQuery.each( "ajaxStart ajaxStop ajaxComplete ajaxError ajaxSuccess ajaxSend".split( " " ), function( i, o ){ + jQuery.fn[ o ] = function( f ){ + return this.on( o, f ); + }; +}); + +jQuery.each( [ "get", "post" ], function( i, method ) { + jQuery[ method ] = function( url, data, callback, type ) { + // shift arguments if data argument was omitted + if ( jQuery.isFunction( data ) ) { + type = type || callback; + callback = data; + data = undefined; + } + + return jQuery.ajax({ + type: method, + url: url, + data: data, + success: callback, + dataType: type + }); + }; +}); + +jQuery.extend({ + + getScript: function( url, callback ) { + return jQuery.get( url, undefined, callback, "script" ); + }, + + getJSON: function( url, data, callback ) { + return jQuery.get( url, data, callback, "json" ); + }, + + // Creates a full fledged settings object into target + // with both ajaxSettings and settings fields. + // If target is omitted, writes into ajaxSettings. + ajaxSetup: function( target, settings ) { + if ( settings ) { + // Building a settings object + ajaxExtend( target, jQuery.ajaxSettings ); + } else { + // Extending ajaxSettings + settings = target; + target = jQuery.ajaxSettings; + } + ajaxExtend( target, settings ); + return target; + }, + + ajaxSettings: { + url: ajaxLocation, + isLocal: rlocalProtocol.test( ajaxLocParts[ 1 ] ), + global: true, + type: "GET", + contentType: "application/x-www-form-urlencoded; charset=UTF-8", + processData: true, + async: true, + /* + timeout: 0, + data: null, + dataType: null, + username: null, + password: null, + cache: null, + throws: false, + traditional: false, + headers: {}, + */ + + accepts: { + xml: "application/xml, text/xml", + html: "text/html", + text: "text/plain", + json: "application/json, text/javascript", + "*": allTypes + }, + + contents: { + xml: /xml/, + html: /html/, + json: /json/ + }, + + responseFields: { + xml: "responseXML", + text: "responseText" + }, + + // List of data converters + // 1) key format is "source_type destination_type" (a single space in-between) + // 2) the catchall symbol "*" can be used for source_type + converters: { + + // Convert anything to text + "* text": window.String, + + // Text to html (true = no transformation) + "text html": true, + + // Evaluate text as a json expression + "text json": jQuery.parseJSON, + + // Parse text as xml + "text xml": jQuery.parseXML + }, + + // For options that shouldn't be deep extended: + // you can add your own custom options here if + // and when you create one that shouldn't be + // deep extended (see ajaxExtend) + flatOptions: { + context: true, + url: true + } + }, + + ajaxPrefilter: addToPrefiltersOrTransports( prefilters ), + ajaxTransport: addToPrefiltersOrTransports( transports ), + + // Main method + ajax: function( url, options ) { + + // If url is an object, simulate pre-1.5 signature + if ( typeof url === "object" ) { + options = url; + url = undefined; + } + + // Force options to be an object + options = options || {}; + + var // ifModified key + ifModifiedKey, + // Response headers + responseHeadersString, + responseHeaders, + // transport + transport, + // timeout handle + timeoutTimer, + // Cross-domain detection vars + parts, + // To know if global events are to be dispatched + fireGlobals, + // Loop variable + i, + // Create the final options object + s = jQuery.ajaxSetup( {}, options ), + // Callbacks context + callbackContext = s.context || s, + // Context for global events + // It's the callbackContext if one was provided in the options + // and if it's a DOM node or a jQuery collection + globalEventContext = callbackContext !== s && + ( callbackContext.nodeType || callbackContext instanceof jQuery ) ? + jQuery( callbackContext ) : jQuery.event, + // Deferreds + deferred = jQuery.Deferred(), + completeDeferred = jQuery.Callbacks( "once memory" ), + // Status-dependent callbacks + statusCode = s.statusCode || {}, + // Headers (they are sent all at once) + requestHeaders = {}, + requestHeadersNames = {}, + // The jqXHR state + state = 0, + // Default abort message + strAbort = "canceled", + // Fake xhr + jqXHR = { + + readyState: 0, + + // Caches the header + setRequestHeader: function( name, value ) { + if ( !state ) { + var lname = name.toLowerCase(); + name = requestHeadersNames[ lname ] = requestHeadersNames[ lname ] || name; + requestHeaders[ name ] = value; + } + return this; + }, + + // Raw string + getAllResponseHeaders: function() { + return state === 2 ? responseHeadersString : null; + }, + + // Builds headers hashtable if needed + getResponseHeader: function( key ) { + var match; + if ( state === 2 ) { + if ( !responseHeaders ) { + responseHeaders = {}; + while( ( match = rheaders.exec( responseHeadersString ) ) ) { + responseHeaders[ match[1].toLowerCase() ] = match[ 2 ]; + } + } + match = responseHeaders[ key.toLowerCase() ]; + } + return match === undefined ? null : match; + }, + + // Overrides response content-type header + overrideMimeType: function( type ) { + if ( !state ) { + s.mimeType = type; + } + return this; + }, + + // Cancel the request + abort: function( statusText ) { + statusText = statusText || strAbort; + if ( transport ) { + transport.abort( statusText ); + } + done( 0, statusText ); + return this; + } + }; + + // Callback for when everything is done + // It is defined here because jslint complains if it is declared + // at the end of the function (which would be more logical and readable) + function done( status, nativeStatusText, responses, headers ) { + var isSuccess, success, error, response, modified, + statusText = nativeStatusText; + + // Called once + if ( state === 2 ) { + return; + } + + // State is "done" now + state = 2; + + // Clear timeout if it exists + if ( timeoutTimer ) { + clearTimeout( timeoutTimer ); + } + + // Dereference transport for early garbage collection + // (no matter how long the jqXHR object will be used) + transport = undefined; + + // Cache response headers + responseHeadersString = headers || ""; + + // Set readyState + jqXHR.readyState = status > 0 ? 4 : 0; + + // Get response data + if ( responses ) { + response = ajaxHandleResponses( s, jqXHR, responses ); + } + + // If successful, handle type chaining + if ( status >= 200 && status < 300 || status === 304 ) { + + // Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode. + if ( s.ifModified ) { + + modified = jqXHR.getResponseHeader("Last-Modified"); + if ( modified ) { + jQuery.lastModified[ ifModifiedKey ] = modified; + } + modified = jqXHR.getResponseHeader("Etag"); + if ( modified ) { + jQuery.etag[ ifModifiedKey ] = modified; + } + } + + // If not modified + if ( status === 304 ) { + + statusText = "notmodified"; + isSuccess = true; + + // If we have data + } else { + + isSuccess = ajaxConvert( s, response ); + statusText = isSuccess.state; + success = isSuccess.data; + error = isSuccess.error; + isSuccess = !error; + } + } else { + // We extract error from statusText + // then normalize statusText and status for non-aborts + error = statusText; + if ( !statusText || status ) { + statusText = "error"; + if ( status < 0 ) { + status = 0; + } + } + } + + // Set data for the fake xhr object + jqXHR.status = status; + jqXHR.statusText = ( nativeStatusText || statusText ) + ""; + + // Success/Error + if ( isSuccess ) { + deferred.resolveWith( callbackContext, [ success, statusText, jqXHR ] ); + } else { + deferred.rejectWith( callbackContext, [ jqXHR, statusText, error ] ); + } + + // Status-dependent callbacks + jqXHR.statusCode( statusCode ); + statusCode = undefined; + + if ( fireGlobals ) { + globalEventContext.trigger( "ajax" + ( isSuccess ? "Success" : "Error" ), + [ jqXHR, s, isSuccess ? success : error ] ); + } + + // Complete + completeDeferred.fireWith( callbackContext, [ jqXHR, statusText ] ); + + if ( fireGlobals ) { + globalEventContext.trigger( "ajaxComplete", [ jqXHR, s ] ); + // Handle the global AJAX counter + if ( !( --jQuery.active ) ) { + jQuery.event.trigger( "ajaxStop" ); + } + } + } + + // Attach deferreds + deferred.promise( jqXHR ); + jqXHR.success = jqXHR.done; + jqXHR.error = jqXHR.fail; + jqXHR.complete = completeDeferred.add; + + // Status-dependent callbacks + jqXHR.statusCode = function( map ) { + if ( map ) { + var tmp; + if ( state < 2 ) { + for ( tmp in map ) { + statusCode[ tmp ] = [ statusCode[tmp], map[tmp] ]; + } + } else { + tmp = map[ jqXHR.status ]; + jqXHR.always( tmp ); + } + } + return this; + }; + + // Remove hash character (#7531: and string promotion) + // Add protocol if not provided (#5866: IE7 issue with protocol-less urls) + // We also use the url parameter if available + s.url = ( ( url || s.url ) + "" ).replace( rhash, "" ).replace( rprotocol, ajaxLocParts[ 1 ] + "//" ); + + // Extract dataTypes list + s.dataTypes = jQuery.trim( s.dataType || "*" ).toLowerCase().split( core_rspace ); + + // A cross-domain request is in order when we have a protocol:host:port mismatch + if ( s.crossDomain == null ) { + parts = rurl.exec( s.url.toLowerCase() ); + s.crossDomain = !!( parts && + ( parts[ 1 ] !== ajaxLocParts[ 1 ] || parts[ 2 ] !== ajaxLocParts[ 2 ] || + ( parts[ 3 ] || ( parts[ 1 ] === "http:" ? 80 : 443 ) ) != + ( ajaxLocParts[ 3 ] || ( ajaxLocParts[ 1 ] === "http:" ? 80 : 443 ) ) ) + ); + } + + // Convert data if not already a string + if ( s.data && s.processData && typeof s.data !== "string" ) { + s.data = jQuery.param( s.data, s.traditional ); + } + + // Apply prefilters + inspectPrefiltersOrTransports( prefilters, s, options, jqXHR ); + + // If request was aborted inside a prefilter, stop there + if ( state === 2 ) { + return jqXHR; + } + + // We can fire global events as of now if asked to + fireGlobals = s.global; + + // Uppercase the type + s.type = s.type.toUpperCase(); + + // Determine if request has content + s.hasContent = !rnoContent.test( s.type ); + + // Watch for a new set of requests + if ( fireGlobals && jQuery.active++ === 0 ) { + jQuery.event.trigger( "ajaxStart" ); + } + + // More options handling for requests with no content + if ( !s.hasContent ) { + + // If data is available, append data to url + if ( s.data ) { + s.url += ( rquery.test( s.url ) ? "&" : "?" ) + s.data; + // #9682: remove data so that it's not used in an eventual retry + delete s.data; + } + + // Get ifModifiedKey before adding the anti-cache parameter + ifModifiedKey = s.url; + + // Add anti-cache in url if needed + if ( s.cache === false ) { + + var ts = jQuery.now(), + // try replacing _= if it is there + ret = s.url.replace( rts, "$1_=" + ts ); + + // if nothing was replaced, add timestamp to the end + s.url = ret + ( ( ret === s.url ) ? ( rquery.test( s.url ) ? "&" : "?" ) + "_=" + ts : "" ); + } + } + + // Set the correct header, if data is being sent + if ( s.data && s.hasContent && s.contentType !== false || options.contentType ) { + jqXHR.setRequestHeader( "Content-Type", s.contentType ); + } + + // Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode. + if ( s.ifModified ) { + ifModifiedKey = ifModifiedKey || s.url; + if ( jQuery.lastModified[ ifModifiedKey ] ) { + jqXHR.setRequestHeader( "If-Modified-Since", jQuery.lastModified[ ifModifiedKey ] ); + } + if ( jQuery.etag[ ifModifiedKey ] ) { + jqXHR.setRequestHeader( "If-None-Match", jQuery.etag[ ifModifiedKey ] ); + } + } + + // Set the Accepts header for the server, depending on the dataType + jqXHR.setRequestHeader( + "Accept", + s.dataTypes[ 0 ] && s.accepts[ s.dataTypes[0] ] ? + s.accepts[ s.dataTypes[0] ] + ( s.dataTypes[ 0 ] !== "*" ? ", " + allTypes + "; q=0.01" : "" ) : + s.accepts[ "*" ] + ); + + // Check for headers option + for ( i in s.headers ) { + jqXHR.setRequestHeader( i, s.headers[ i ] ); + } + + // Allow custom headers/mimetypes and early abort + if ( s.beforeSend && ( s.beforeSend.call( callbackContext, jqXHR, s ) === false || state === 2 ) ) { + // Abort if not done already and return + return jqXHR.abort(); + + } + + // aborting is no longer a cancellation + strAbort = "abort"; + + // Install callbacks on deferreds + for ( i in { success: 1, error: 1, complete: 1 } ) { + jqXHR[ i ]( s[ i ] ); + } + + // Get transport + transport = inspectPrefiltersOrTransports( transports, s, options, jqXHR ); + + // If no transport, we auto-abort + if ( !transport ) { + done( -1, "No Transport" ); + } else { + jqXHR.readyState = 1; + // Send global event + if ( fireGlobals ) { + globalEventContext.trigger( "ajaxSend", [ jqXHR, s ] ); + } + // Timeout + if ( s.async && s.timeout > 0 ) { + timeoutTimer = setTimeout( function(){ + jqXHR.abort( "timeout" ); + }, s.timeout ); + } + + try { + state = 1; + transport.send( requestHeaders, done ); + } catch (e) { + // Propagate exception as error if not done + if ( state < 2 ) { + done( -1, e ); + // Simply rethrow otherwise + } else { + throw e; + } + } + } + + return jqXHR; + }, + + // Counter for holding the number of active queries + active: 0, + + // Last-Modified header cache for next request + lastModified: {}, + etag: {} + +}); + +/* Handles responses to an ajax request: + * - sets all responseXXX fields accordingly + * - finds the right dataType (mediates between content-type and expected dataType) + * - returns the corresponding response + */ +function ajaxHandleResponses( s, jqXHR, responses ) { + + var ct, type, finalDataType, firstDataType, + contents = s.contents, + dataTypes = s.dataTypes, + responseFields = s.responseFields; + + // Fill responseXXX fields + for ( type in responseFields ) { + if ( type in responses ) { + jqXHR[ responseFields[type] ] = responses[ type ]; + } + } + + // Remove auto dataType and get content-type in the process + while( dataTypes[ 0 ] === "*" ) { + dataTypes.shift(); + if ( ct === undefined ) { + ct = s.mimeType || jqXHR.getResponseHeader( "content-type" ); + } + } + + // Check if we're dealing with a known content-type + if ( ct ) { + for ( type in contents ) { + if ( contents[ type ] && contents[ type ].test( ct ) ) { + dataTypes.unshift( type ); + break; + } + } + } + + // Check to see if we have a response for the expected dataType + if ( dataTypes[ 0 ] in responses ) { + finalDataType = dataTypes[ 0 ]; + } else { + // Try convertible dataTypes + for ( type in responses ) { + if ( !dataTypes[ 0 ] || s.converters[ type + " " + dataTypes[0] ] ) { + finalDataType = type; + break; + } + if ( !firstDataType ) { + firstDataType = type; + } + } + // Or just use first one + finalDataType = finalDataType || firstDataType; + } + + // If we found a dataType + // We add the dataType to the list if needed + // and return the corresponding response + if ( finalDataType ) { + if ( finalDataType !== dataTypes[ 0 ] ) { + dataTypes.unshift( finalDataType ); + } + return responses[ finalDataType ]; + } +} + +// Chain conversions given the request and the original response +function ajaxConvert( s, response ) { + + var conv, conv2, current, tmp, + // Work with a copy of dataTypes in case we need to modify it for conversion + dataTypes = s.dataTypes.slice(), + prev = dataTypes[ 0 ], + converters = {}, + i = 0; + + // Apply the dataFilter if provided + if ( s.dataFilter ) { + response = s.dataFilter( response, s.dataType ); + } + + // Create converters map with lowercased keys + if ( dataTypes[ 1 ] ) { + for ( conv in s.converters ) { + converters[ conv.toLowerCase() ] = s.converters[ conv ]; + } + } + + // Convert to each sequential dataType, tolerating list modification + for ( ; (current = dataTypes[++i]); ) { + + // There's only work to do if current dataType is non-auto + if ( current !== "*" ) { + + // Convert response if prev dataType is non-auto and differs from current + if ( prev !== "*" && prev !== current ) { + + // Seek a direct converter + conv = converters[ prev + " " + current ] || converters[ "* " + current ]; + + // If none found, seek a pair + if ( !conv ) { + for ( conv2 in converters ) { + + // If conv2 outputs current + tmp = conv2.split(" "); + if ( tmp[ 1 ] === current ) { + + // If prev can be converted to accepted input + conv = converters[ prev + " " + tmp[ 0 ] ] || + converters[ "* " + tmp[ 0 ] ]; + if ( conv ) { + // Condense equivalence converters + if ( conv === true ) { + conv = converters[ conv2 ]; + + // Otherwise, insert the intermediate dataType + } else if ( converters[ conv2 ] !== true ) { + current = tmp[ 0 ]; + dataTypes.splice( i--, 0, current ); + } + + break; + } + } + } + } + + // Apply converter (if not an equivalence) + if ( conv !== true ) { + + // Unless errors are allowed to bubble, catch and return them + if ( conv && s["throws"] ) { + response = conv( response ); + } else { + try { + response = conv( response ); + } catch ( e ) { + return { state: "parsererror", error: conv ? e : "No conversion from " + prev + " to " + current }; + } + } + } + } + + // Update prev for next iteration + prev = current; + } + } + + return { state: "success", data: response }; +} +var oldCallbacks = [], + rquestion = /\?/, + rjsonp = /(=)\?(?=&|$)|\?\?/, + nonce = jQuery.now(); + +// Default jsonp settings +jQuery.ajaxSetup({ + jsonp: "callback", + jsonpCallback: function() { + var callback = oldCallbacks.pop() || ( jQuery.expando + "_" + ( nonce++ ) ); + this[ callback ] = true; + return callback; + } +}); + +// Detect, normalize options and install callbacks for jsonp requests +jQuery.ajaxPrefilter( "json jsonp", function( s, originalSettings, jqXHR ) { + + var callbackName, overwritten, responseContainer, + data = s.data, + url = s.url, + hasCallback = s.jsonp !== false, + replaceInUrl = hasCallback && rjsonp.test( url ), + replaceInData = hasCallback && !replaceInUrl && typeof data === "string" && + !( s.contentType || "" ).indexOf("application/x-www-form-urlencoded") && + rjsonp.test( data ); + + // Handle iff the expected data type is "jsonp" or we have a parameter to set + if ( s.dataTypes[ 0 ] === "jsonp" || replaceInUrl || replaceInData ) { + + // Get callback name, remembering preexisting value associated with it + callbackName = s.jsonpCallback = jQuery.isFunction( s.jsonpCallback ) ? + s.jsonpCallback() : + s.jsonpCallback; + overwritten = window[ callbackName ]; + + // Insert callback into url or form data + if ( replaceInUrl ) { + s.url = url.replace( rjsonp, "$1" + callbackName ); + } else if ( replaceInData ) { + s.data = data.replace( rjsonp, "$1" + callbackName ); + } else if ( hasCallback ) { + s.url += ( rquestion.test( url ) ? "&" : "?" ) + s.jsonp + "=" + callbackName; + } + + // Use data converter to retrieve json after script execution + s.converters["script json"] = function() { + if ( !responseContainer ) { + jQuery.error( callbackName + " was not called" ); + } + return responseContainer[ 0 ]; + }; + + // force json dataType + s.dataTypes[ 0 ] = "json"; + + // Install callback + window[ callbackName ] = function() { + responseContainer = arguments; + }; + + // Clean-up function (fires after converters) + jqXHR.always(function() { + // Restore preexisting value + window[ callbackName ] = overwritten; + + // Save back as free + if ( s[ callbackName ] ) { + // make sure that re-using the options doesn't screw things around + s.jsonpCallback = originalSettings.jsonpCallback; + + // save the callback name for future use + oldCallbacks.push( callbackName ); + } + + // Call if it was a function and we have a response + if ( responseContainer && jQuery.isFunction( overwritten ) ) { + overwritten( responseContainer[ 0 ] ); + } + + responseContainer = overwritten = undefined; + }); + + // Delegate to script + return "script"; + } +}); +// Install script dataType +jQuery.ajaxSetup({ + accepts: { + script: "text/javascript, application/javascript, application/ecmascript, application/x-ecmascript" + }, + contents: { + script: /javascript|ecmascript/ + }, + converters: { + "text script": function( text ) { + jQuery.globalEval( text ); + return text; + } + } +}); + +// Handle cache's special case and global +jQuery.ajaxPrefilter( "script", function( s ) { + if ( s.cache === undefined ) { + s.cache = false; + } + if ( s.crossDomain ) { + s.type = "GET"; + s.global = false; + } +}); + +// Bind script tag hack transport +jQuery.ajaxTransport( "script", function(s) { + + // This transport only deals with cross domain requests + if ( s.crossDomain ) { + + var script, + head = document.head || document.getElementsByTagName( "head" )[0] || document.documentElement; + + return { + + send: function( _, callback ) { + + script = document.createElement( "script" ); + + script.async = "async"; + + if ( s.scriptCharset ) { + script.charset = s.scriptCharset; + } + + script.src = s.url; + + // Attach handlers for all browsers + script.onload = script.onreadystatechange = function( _, isAbort ) { + + if ( isAbort || !script.readyState || /loaded|complete/.test( script.readyState ) ) { + + // Handle memory leak in IE + script.onload = script.onreadystatechange = null; + + // Remove the script + if ( head && script.parentNode ) { + head.removeChild( script ); + } + + // Dereference the script + script = undefined; + + // Callback if not abort + if ( !isAbort ) { + callback( 200, "success" ); + } + } + }; + // Use insertBefore instead of appendChild to circumvent an IE6 bug. + // This arises when a base node is used (#2709 and #4378). + head.insertBefore( script, head.firstChild ); + }, + + abort: function() { + if ( script ) { + script.onload( 0, 1 ); + } + } + }; + } +}); +var xhrCallbacks, + // #5280: Internet Explorer will keep connections alive if we don't abort on unload + xhrOnUnloadAbort = window.ActiveXObject ? function() { + // Abort all pending requests + for ( var key in xhrCallbacks ) { + xhrCallbacks[ key ]( 0, 1 ); + } + } : false, + xhrId = 0; + +// Functions to create xhrs +function createStandardXHR() { + try { + return new window.XMLHttpRequest(); + } catch( e ) {} +} + +function createActiveXHR() { + try { + return new window.ActiveXObject( "Microsoft.XMLHTTP" ); + } catch( e ) {} +} + +// Create the request object +// (This is still attached to ajaxSettings for backward compatibility) +jQuery.ajaxSettings.xhr = window.ActiveXObject ? + /* Microsoft failed to properly + * implement the XMLHttpRequest in IE7 (can't request local files), + * so we use the ActiveXObject when it is available + * Additionally XMLHttpRequest can be disabled in IE7/IE8 so + * we need a fallback. + */ + function() { + return !this.isLocal && createStandardXHR() || createActiveXHR(); + } : + // For all other browsers, use the standard XMLHttpRequest object + createStandardXHR; + +// Determine support properties +(function( xhr ) { + jQuery.extend( jQuery.support, { + ajax: !!xhr, + cors: !!xhr && ( "withCredentials" in xhr ) + }); +})( jQuery.ajaxSettings.xhr() ); + +// Create transport if the browser can provide an xhr +if ( jQuery.support.ajax ) { + + jQuery.ajaxTransport(function( s ) { + // Cross domain only allowed if supported through XMLHttpRequest + if ( !s.crossDomain || jQuery.support.cors ) { + + var callback; + + return { + send: function( headers, complete ) { + + // Get a new xhr + var handle, i, + xhr = s.xhr(); + + // Open the socket + // Passing null username, generates a login popup on Opera (#2865) + if ( s.username ) { + xhr.open( s.type, s.url, s.async, s.username, s.password ); + } else { + xhr.open( s.type, s.url, s.async ); + } + + // Apply custom fields if provided + if ( s.xhrFields ) { + for ( i in s.xhrFields ) { + xhr[ i ] = s.xhrFields[ i ]; + } + } + + // Override mime type if needed + if ( s.mimeType && xhr.overrideMimeType ) { + xhr.overrideMimeType( s.mimeType ); + } + + // X-Requested-With header + // For cross-domain requests, seeing as conditions for a preflight are + // akin to a jigsaw puzzle, we simply never set it to be sure. + // (it can always be set on a per-request basis or even using ajaxSetup) + // For same-domain requests, won't change header if already provided. + if ( !s.crossDomain && !headers["X-Requested-With"] ) { + headers[ "X-Requested-With" ] = "XMLHttpRequest"; + } + + // Need an extra try/catch for cross domain requests in Firefox 3 + try { + for ( i in headers ) { + xhr.setRequestHeader( i, headers[ i ] ); + } + } catch( _ ) {} + + // Do send the request + // This may raise an exception which is actually + // handled in jQuery.ajax (so no try/catch here) + xhr.send( ( s.hasContent && s.data ) || null ); + + // Listener + callback = function( _, isAbort ) { + + var status, + statusText, + responseHeaders, + responses, + xml; + + // Firefox throws exceptions when accessing properties + // of an xhr when a network error occurred + // http://helpful.knobs-dials.com/index.php/Component_returned_failure_code:_0x80040111_(NS_ERROR_NOT_AVAILABLE) + try { + + // Was never called and is aborted or complete + if ( callback && ( isAbort || xhr.readyState === 4 ) ) { + + // Only called once + callback = undefined; + + // Do not keep as active anymore + if ( handle ) { + xhr.onreadystatechange = jQuery.noop; + if ( xhrOnUnloadAbort ) { + delete xhrCallbacks[ handle ]; + } + } + + // If it's an abort + if ( isAbort ) { + // Abort it manually if needed + if ( xhr.readyState !== 4 ) { + xhr.abort(); + } + } else { + status = xhr.status; + responseHeaders = xhr.getAllResponseHeaders(); + responses = {}; + xml = xhr.responseXML; + + // Construct response list + if ( xml && xml.documentElement /* #4958 */ ) { + responses.xml = xml; + } + + // When requesting binary data, IE6-9 will throw an exception + // on any attempt to access responseText (#11426) + try { + responses.text = xhr.responseText; + } catch( e ) { + } + + // Firefox throws an exception when accessing + // statusText for faulty cross-domain requests + try { + statusText = xhr.statusText; + } catch( e ) { + // We normalize with Webkit giving an empty statusText + statusText = ""; + } + + // Filter status for non standard behaviors + + // If the request is local and we have data: assume a success + // (success with no data won't get notified, that's the best we + // can do given current implementations) + if ( !status && s.isLocal && !s.crossDomain ) { + status = responses.text ? 200 : 404; + // IE - #1450: sometimes returns 1223 when it should be 204 + } else if ( status === 1223 ) { + status = 204; + } + } + } + } catch( firefoxAccessException ) { + if ( !isAbort ) { + complete( -1, firefoxAccessException ); + } + } + + // Call complete if needed + if ( responses ) { + complete( status, statusText, responses, responseHeaders ); + } + }; + + if ( !s.async ) { + // if we're in sync mode we fire the callback + callback(); + } else if ( xhr.readyState === 4 ) { + // (IE6 & IE7) if it's in cache and has been + // retrieved directly we need to fire the callback + setTimeout( callback, 0 ); + } else { + handle = ++xhrId; + if ( xhrOnUnloadAbort ) { + // Create the active xhrs callbacks list if needed + // and attach the unload handler + if ( !xhrCallbacks ) { + xhrCallbacks = {}; + jQuery( window ).unload( xhrOnUnloadAbort ); + } + // Add to list of active xhrs callbacks + xhrCallbacks[ handle ] = callback; + } + xhr.onreadystatechange = callback; + } + }, + + abort: function() { + if ( callback ) { + callback(0,1); + } + } + }; + } + }); +} +var fxNow, timerId, + rfxtypes = /^(?:toggle|show|hide)$/, + rfxnum = new RegExp( "^(?:([-+])=|)(" + core_pnum + ")([a-z%]*)$", "i" ), + rrun = /queueHooks$/, + animationPrefilters = [ defaultPrefilter ], + tweeners = { + "*": [function( prop, value ) { + var end, unit, + tween = this.createTween( prop, value ), + parts = rfxnum.exec( value ), + target = tween.cur(), + start = +target || 0, + scale = 1, + maxIterations = 20; + + if ( parts ) { + end = +parts[2]; + unit = parts[3] || ( jQuery.cssNumber[ prop ] ? "" : "px" ); + + // We need to compute starting value + if ( unit !== "px" && start ) { + // Iteratively approximate from a nonzero starting point + // Prefer the current property, because this process will be trivial if it uses the same units + // Fallback to end or a simple constant + start = jQuery.css( tween.elem, prop, true ) || end || 1; + + do { + // If previous iteration zeroed out, double until we get *something* + // Use a string for doubling factor so we don't accidentally see scale as unchanged below + scale = scale || ".5"; + + // Adjust and apply + start = start / scale; + jQuery.style( tween.elem, prop, start + unit ); + + // Update scale, tolerating zero or NaN from tween.cur() + // And breaking the loop if scale is unchanged or perfect, or if we've just had enough + } while ( scale !== (scale = tween.cur() / target) && scale !== 1 && --maxIterations ); + } + + tween.unit = unit; + tween.start = start; + // If a +=/-= token was provided, we're doing a relative animation + tween.end = parts[1] ? start + ( parts[1] + 1 ) * end : end; + } + return tween; + }] + }; + +// Animations created synchronously will run synchronously +function createFxNow() { + setTimeout(function() { + fxNow = undefined; + }, 0 ); + return ( fxNow = jQuery.now() ); +} + +function createTweens( animation, props ) { + jQuery.each( props, function( prop, value ) { + var collection = ( tweeners[ prop ] || [] ).concat( tweeners[ "*" ] ), + index = 0, + length = collection.length; + for ( ; index < length; index++ ) { + if ( collection[ index ].call( animation, prop, value ) ) { + + // we're done with this property + return; + } + } + }); +} + +function Animation( elem, properties, options ) { + var result, + index = 0, + tweenerIndex = 0, + length = animationPrefilters.length, + deferred = jQuery.Deferred().always( function() { + // don't match elem in the :animated selector + delete tick.elem; + }), + tick = function() { + var currentTime = fxNow || createFxNow(), + remaining = Math.max( 0, animation.startTime + animation.duration - currentTime ), + // archaic crash bug won't allow us to use 1 - ( 0.5 || 0 ) (#12497) + temp = remaining / animation.duration || 0, + percent = 1 - temp, + index = 0, + length = animation.tweens.length; + + for ( ; index < length ; index++ ) { + animation.tweens[ index ].run( percent ); + } + + deferred.notifyWith( elem, [ animation, percent, remaining ]); + + if ( percent < 1 && length ) { + return remaining; + } else { + deferred.resolveWith( elem, [ animation ] ); + return false; + } + }, + animation = deferred.promise({ + elem: elem, + props: jQuery.extend( {}, properties ), + opts: jQuery.extend( true, { specialEasing: {} }, options ), + originalProperties: properties, + originalOptions: options, + startTime: fxNow || createFxNow(), + duration: options.duration, + tweens: [], + createTween: function( prop, end, easing ) { + var tween = jQuery.Tween( elem, animation.opts, prop, end, + animation.opts.specialEasing[ prop ] || animation.opts.easing ); + animation.tweens.push( tween ); + return tween; + }, + stop: function( gotoEnd ) { + var index = 0, + // if we are going to the end, we want to run all the tweens + // otherwise we skip this part + length = gotoEnd ? animation.tweens.length : 0; + + for ( ; index < length ; index++ ) { + animation.tweens[ index ].run( 1 ); + } + + // resolve when we played the last frame + // otherwise, reject + if ( gotoEnd ) { + deferred.resolveWith( elem, [ animation, gotoEnd ] ); + } else { + deferred.rejectWith( elem, [ animation, gotoEnd ] ); + } + return this; + } + }), + props = animation.props; + + propFilter( props, animation.opts.specialEasing ); + + for ( ; index < length ; index++ ) { + result = animationPrefilters[ index ].call( animation, elem, props, animation.opts ); + if ( result ) { + return result; + } + } + + createTweens( animation, props ); + + if ( jQuery.isFunction( animation.opts.start ) ) { + animation.opts.start.call( elem, animation ); + } + + jQuery.fx.timer( + jQuery.extend( tick, { + anim: animation, + queue: animation.opts.queue, + elem: elem + }) + ); + + // attach callbacks from options + return animation.progress( animation.opts.progress ) + .done( animation.opts.done, animation.opts.complete ) + .fail( animation.opts.fail ) + .always( animation.opts.always ); +} + +function propFilter( props, specialEasing ) { + var index, name, easing, value, hooks; + + // camelCase, specialEasing and expand cssHook pass + for ( index in props ) { + name = jQuery.camelCase( index ); + easing = specialEasing[ name ]; + value = props[ index ]; + if ( jQuery.isArray( value ) ) { + easing = value[ 1 ]; + value = props[ index ] = value[ 0 ]; + } + + if ( index !== name ) { + props[ name ] = value; + delete props[ index ]; + } + + hooks = jQuery.cssHooks[ name ]; + if ( hooks && "expand" in hooks ) { + value = hooks.expand( value ); + delete props[ name ]; + + // not quite $.extend, this wont overwrite keys already present. + // also - reusing 'index' from above because we have the correct "name" + for ( index in value ) { + if ( !( index in props ) ) { + props[ index ] = value[ index ]; + specialEasing[ index ] = easing; + } + } + } else { + specialEasing[ name ] = easing; + } + } +} + +jQuery.Animation = jQuery.extend( Animation, { + + tweener: function( props, callback ) { + if ( jQuery.isFunction( props ) ) { + callback = props; + props = [ "*" ]; + } else { + props = props.split(" "); + } + + var prop, + index = 0, + length = props.length; + + for ( ; index < length ; index++ ) { + prop = props[ index ]; + tweeners[ prop ] = tweeners[ prop ] || []; + tweeners[ prop ].unshift( callback ); + } + }, + + prefilter: function( callback, prepend ) { + if ( prepend ) { + animationPrefilters.unshift( callback ); + } else { + animationPrefilters.push( callback ); + } + } +}); + +function defaultPrefilter( elem, props, opts ) { + var index, prop, value, length, dataShow, toggle, tween, hooks, oldfire, + anim = this, + style = elem.style, + orig = {}, + handled = [], + hidden = elem.nodeType && isHidden( elem ); + + // handle queue: false promises + if ( !opts.queue ) { + hooks = jQuery._queueHooks( elem, "fx" ); + if ( hooks.unqueued == null ) { + hooks.unqueued = 0; + oldfire = hooks.empty.fire; + hooks.empty.fire = function() { + if ( !hooks.unqueued ) { + oldfire(); + } + }; + } + hooks.unqueued++; + + anim.always(function() { + // doing this makes sure that the complete handler will be called + // before this completes + anim.always(function() { + hooks.unqueued--; + if ( !jQuery.queue( elem, "fx" ).length ) { + hooks.empty.fire(); + } + }); + }); + } + + // height/width overflow pass + if ( elem.nodeType === 1 && ( "height" in props || "width" in props ) ) { + // Make sure that nothing sneaks out + // Record all 3 overflow attributes because IE does not + // change the overflow attribute when overflowX and + // overflowY are set to the same value + opts.overflow = [ style.overflow, style.overflowX, style.overflowY ]; + + // Set display property to inline-block for height/width + // animations on inline elements that are having width/height animated + if ( jQuery.css( elem, "display" ) === "inline" && + jQuery.css( elem, "float" ) === "none" ) { + + // inline-level elements accept inline-block; + // block-level elements need to be inline with layout + if ( !jQuery.support.inlineBlockNeedsLayout || css_defaultDisplay( elem.nodeName ) === "inline" ) { + style.display = "inline-block"; + + } else { + style.zoom = 1; + } + } + } + + if ( opts.overflow ) { + style.overflow = "hidden"; + if ( !jQuery.support.shrinkWrapBlocks ) { + anim.done(function() { + style.overflow = opts.overflow[ 0 ]; + style.overflowX = opts.overflow[ 1 ]; + style.overflowY = opts.overflow[ 2 ]; + }); + } + } + + + // show/hide pass + for ( index in props ) { + value = props[ index ]; + if ( rfxtypes.exec( value ) ) { + delete props[ index ]; + toggle = toggle || value === "toggle"; + if ( value === ( hidden ? "hide" : "show" ) ) { + continue; + } + handled.push( index ); + } + } + + length = handled.length; + if ( length ) { + dataShow = jQuery._data( elem, "fxshow" ) || jQuery._data( elem, "fxshow", {} ); + if ( "hidden" in dataShow ) { + hidden = dataShow.hidden; + } + + // store state if its toggle - enables .stop().toggle() to "reverse" + if ( toggle ) { + dataShow.hidden = !hidden; + } + if ( hidden ) { + jQuery( elem ).show(); + } else { + anim.done(function() { + jQuery( elem ).hide(); + }); + } + anim.done(function() { + var prop; + jQuery.removeData( elem, "fxshow", true ); + for ( prop in orig ) { + jQuery.style( elem, prop, orig[ prop ] ); + } + }); + for ( index = 0 ; index < length ; index++ ) { + prop = handled[ index ]; + tween = anim.createTween( prop, hidden ? dataShow[ prop ] : 0 ); + orig[ prop ] = dataShow[ prop ] || jQuery.style( elem, prop ); + + if ( !( prop in dataShow ) ) { + dataShow[ prop ] = tween.start; + if ( hidden ) { + tween.end = tween.start; + tween.start = prop === "width" || prop === "height" ? 1 : 0; + } + } + } + } +} + +function Tween( elem, options, prop, end, easing ) { + return new Tween.prototype.init( elem, options, prop, end, easing ); +} +jQuery.Tween = Tween; + +Tween.prototype = { + constructor: Tween, + init: function( elem, options, prop, end, easing, unit ) { + this.elem = elem; + this.prop = prop; + this.easing = easing || "swing"; + this.options = options; + this.start = this.now = this.cur(); + this.end = end; + this.unit = unit || ( jQuery.cssNumber[ prop ] ? "" : "px" ); + }, + cur: function() { + var hooks = Tween.propHooks[ this.prop ]; + + return hooks && hooks.get ? + hooks.get( this ) : + Tween.propHooks._default.get( this ); + }, + run: function( percent ) { + var eased, + hooks = Tween.propHooks[ this.prop ]; + + if ( this.options.duration ) { + this.pos = eased = jQuery.easing[ this.easing ]( + percent, this.options.duration * percent, 0, 1, this.options.duration + ); + } else { + this.pos = eased = percent; + } + this.now = ( this.end - this.start ) * eased + this.start; + + if ( this.options.step ) { + this.options.step.call( this.elem, this.now, this ); + } + + if ( hooks && hooks.set ) { + hooks.set( this ); + } else { + Tween.propHooks._default.set( this ); + } + return this; + } +}; + +Tween.prototype.init.prototype = Tween.prototype; + +Tween.propHooks = { + _default: { + get: function( tween ) { + var result; + + if ( tween.elem[ tween.prop ] != null && + (!tween.elem.style || tween.elem.style[ tween.prop ] == null) ) { + return tween.elem[ tween.prop ]; + } + + // passing any value as a 4th parameter to .css will automatically + // attempt a parseFloat and fallback to a string if the parse fails + // so, simple values such as "10px" are parsed to Float. + // complex values such as "rotate(1rad)" are returned as is. + result = jQuery.css( tween.elem, tween.prop, false, "" ); + // Empty strings, null, undefined and "auto" are converted to 0. + return !result || result === "auto" ? 0 : result; + }, + set: function( tween ) { + // use step hook for back compat - use cssHook if its there - use .style if its + // available and use plain properties where available + if ( jQuery.fx.step[ tween.prop ] ) { + jQuery.fx.step[ tween.prop ]( tween ); + } else if ( tween.elem.style && ( tween.elem.style[ jQuery.cssProps[ tween.prop ] ] != null || jQuery.cssHooks[ tween.prop ] ) ) { + jQuery.style( tween.elem, tween.prop, tween.now + tween.unit ); + } else { + tween.elem[ tween.prop ] = tween.now; + } + } + } +}; + +// Remove in 2.0 - this supports IE8's panic based approach +// to setting things on disconnected nodes + +Tween.propHooks.scrollTop = Tween.propHooks.scrollLeft = { + set: function( tween ) { + if ( tween.elem.nodeType && tween.elem.parentNode ) { + tween.elem[ tween.prop ] = tween.now; + } + } +}; + +jQuery.each([ "toggle", "show", "hide" ], function( i, name ) { + var cssFn = jQuery.fn[ name ]; + jQuery.fn[ name ] = function( speed, easing, callback ) { + return speed == null || typeof speed === "boolean" || + // special check for .toggle( handler, handler, ... ) + ( !i && jQuery.isFunction( speed ) && jQuery.isFunction( easing ) ) ? + cssFn.apply( this, arguments ) : + this.animate( genFx( name, true ), speed, easing, callback ); + }; +}); + +jQuery.fn.extend({ + fadeTo: function( speed, to, easing, callback ) { + + // show any hidden elements after setting opacity to 0 + return this.filter( isHidden ).css( "opacity", 0 ).show() + + // animate to the value specified + .end().animate({ opacity: to }, speed, easing, callback ); + }, + animate: function( prop, speed, easing, callback ) { + var empty = jQuery.isEmptyObject( prop ), + optall = jQuery.speed( speed, easing, callback ), + doAnimation = function() { + // Operate on a copy of prop so per-property easing won't be lost + var anim = Animation( this, jQuery.extend( {}, prop ), optall ); + + // Empty animations resolve immediately + if ( empty ) { + anim.stop( true ); + } + }; + + return empty || optall.queue === false ? + this.each( doAnimation ) : + this.queue( optall.queue, doAnimation ); + }, + stop: function( type, clearQueue, gotoEnd ) { + var stopQueue = function( hooks ) { + var stop = hooks.stop; + delete hooks.stop; + stop( gotoEnd ); + }; + + if ( typeof type !== "string" ) { + gotoEnd = clearQueue; + clearQueue = type; + type = undefined; + } + if ( clearQueue && type !== false ) { + this.queue( type || "fx", [] ); + } + + return this.each(function() { + var dequeue = true, + index = type != null && type + "queueHooks", + timers = jQuery.timers, + data = jQuery._data( this ); + + if ( index ) { + if ( data[ index ] && data[ index ].stop ) { + stopQueue( data[ index ] ); + } + } else { + for ( index in data ) { + if ( data[ index ] && data[ index ].stop && rrun.test( index ) ) { + stopQueue( data[ index ] ); + } + } + } + + for ( index = timers.length; index--; ) { + if ( timers[ index ].elem === this && (type == null || timers[ index ].queue === type) ) { + timers[ index ].anim.stop( gotoEnd ); + dequeue = false; + timers.splice( index, 1 ); + } + } + + // start the next in the queue if the last step wasn't forced + // timers currently will call their complete callbacks, which will dequeue + // but only if they were gotoEnd + if ( dequeue || !gotoEnd ) { + jQuery.dequeue( this, type ); + } + }); + } +}); + +// Generate parameters to create a standard animation +function genFx( type, includeWidth ) { + var which, + attrs = { height: type }, + i = 0; + + // if we include width, step value is 1 to do all cssExpand values, + // if we don't include width, step value is 2 to skip over Left and Right + includeWidth = includeWidth? 1 : 0; + for( ; i < 4 ; i += 2 - includeWidth ) { + which = cssExpand[ i ]; + attrs[ "margin" + which ] = attrs[ "padding" + which ] = type; + } + + if ( includeWidth ) { + attrs.opacity = attrs.width = type; + } + + return attrs; +} + +// Generate shortcuts for custom animations +jQuery.each({ + slideDown: genFx("show"), + slideUp: genFx("hide"), + slideToggle: genFx("toggle"), + fadeIn: { opacity: "show" }, + fadeOut: { opacity: "hide" }, + fadeToggle: { opacity: "toggle" } +}, function( name, props ) { + jQuery.fn[ name ] = function( speed, easing, callback ) { + return this.animate( props, speed, easing, callback ); + }; +}); + +jQuery.speed = function( speed, easing, fn ) { + var opt = speed && typeof speed === "object" ? jQuery.extend( {}, speed ) : { + complete: fn || !fn && easing || + jQuery.isFunction( speed ) && speed, + duration: speed, + easing: fn && easing || easing && !jQuery.isFunction( easing ) && easing + }; + + opt.duration = jQuery.fx.off ? 0 : typeof opt.duration === "number" ? opt.duration : + opt.duration in jQuery.fx.speeds ? jQuery.fx.speeds[ opt.duration ] : jQuery.fx.speeds._default; + + // normalize opt.queue - true/undefined/null -> "fx" + if ( opt.queue == null || opt.queue === true ) { + opt.queue = "fx"; + } + + // Queueing + opt.old = opt.complete; + + opt.complete = function() { + if ( jQuery.isFunction( opt.old ) ) { + opt.old.call( this ); + } + + if ( opt.queue ) { + jQuery.dequeue( this, opt.queue ); + } + }; + + return opt; +}; + +jQuery.easing = { + linear: function( p ) { + return p; + }, + swing: function( p ) { + return 0.5 - Math.cos( p*Math.PI ) / 2; + } +}; + +jQuery.timers = []; +jQuery.fx = Tween.prototype.init; +jQuery.fx.tick = function() { + var timer, + timers = jQuery.timers, + i = 0; + + fxNow = jQuery.now(); + + for ( ; i < timers.length; i++ ) { + timer = timers[ i ]; + // Checks the timer has not already been removed + if ( !timer() && timers[ i ] === timer ) { + timers.splice( i--, 1 ); + } + } + + if ( !timers.length ) { + jQuery.fx.stop(); + } + fxNow = undefined; +}; + +jQuery.fx.timer = function( timer ) { + if ( timer() && jQuery.timers.push( timer ) && !timerId ) { + timerId = setInterval( jQuery.fx.tick, jQuery.fx.interval ); + } +}; + +jQuery.fx.interval = 13; + +jQuery.fx.stop = function() { + clearInterval( timerId ); + timerId = null; +}; + +jQuery.fx.speeds = { + slow: 600, + fast: 200, + // Default speed + _default: 400 +}; + +// Back Compat <1.8 extension point +jQuery.fx.step = {}; + +if ( jQuery.expr && jQuery.expr.filters ) { + jQuery.expr.filters.animated = function( elem ) { + return jQuery.grep(jQuery.timers, function( fn ) { + return elem === fn.elem; + }).length; + }; +} +var rroot = /^(?:body|html)$/i; + +jQuery.fn.offset = function( options ) { + if ( arguments.length ) { + return options === undefined ? + this : + this.each(function( i ) { + jQuery.offset.setOffset( this, options, i ); + }); + } + + var docElem, body, win, clientTop, clientLeft, scrollTop, scrollLeft, + box = { top: 0, left: 0 }, + elem = this[ 0 ], + doc = elem && elem.ownerDocument; + + if ( !doc ) { + return; + } + + if ( (body = doc.body) === elem ) { + return jQuery.offset.bodyOffset( elem ); + } + + docElem = doc.documentElement; + + // Make sure it's not a disconnected DOM node + if ( !jQuery.contains( docElem, elem ) ) { + return box; + } + + // If we don't have gBCR, just use 0,0 rather than error + // BlackBerry 5, iOS 3 (original iPhone) + if ( typeof elem.getBoundingClientRect !== "undefined" ) { + box = elem.getBoundingClientRect(); + } + win = getWindow( doc ); + clientTop = docElem.clientTop || body.clientTop || 0; + clientLeft = docElem.clientLeft || body.clientLeft || 0; + scrollTop = win.pageYOffset || docElem.scrollTop; + scrollLeft = win.pageXOffset || docElem.scrollLeft; + return { + top: box.top + scrollTop - clientTop, + left: box.left + scrollLeft - clientLeft + }; +}; + +jQuery.offset = { + + bodyOffset: function( body ) { + var top = body.offsetTop, + left = body.offsetLeft; + + if ( jQuery.support.doesNotIncludeMarginInBodyOffset ) { + top += parseFloat( jQuery.css(body, "marginTop") ) || 0; + left += parseFloat( jQuery.css(body, "marginLeft") ) || 0; + } + + return { top: top, left: left }; + }, + + setOffset: function( elem, options, i ) { + var position = jQuery.css( elem, "position" ); + + // set position first, in-case top/left are set even on static elem + if ( position === "static" ) { + elem.style.position = "relative"; + } + + var curElem = jQuery( elem ), + curOffset = curElem.offset(), + curCSSTop = jQuery.css( elem, "top" ), + curCSSLeft = jQuery.css( elem, "left" ), + calculatePosition = ( position === "absolute" || position === "fixed" ) && jQuery.inArray("auto", [curCSSTop, curCSSLeft]) > -1, + props = {}, curPosition = {}, curTop, curLeft; + + // need to be able to calculate position if either top or left is auto and position is either absolute or fixed + if ( calculatePosition ) { + curPosition = curElem.position(); + curTop = curPosition.top; + curLeft = curPosition.left; + } else { + curTop = parseFloat( curCSSTop ) || 0; + curLeft = parseFloat( curCSSLeft ) || 0; + } + + if ( jQuery.isFunction( options ) ) { + options = options.call( elem, i, curOffset ); + } + + if ( options.top != null ) { + props.top = ( options.top - curOffset.top ) + curTop; + } + if ( options.left != null ) { + props.left = ( options.left - curOffset.left ) + curLeft; + } + + if ( "using" in options ) { + options.using.call( elem, props ); + } else { + curElem.css( props ); + } + } +}; + + +jQuery.fn.extend({ + + position: function() { + if ( !this[0] ) { + return; + } + + var elem = this[0], + + // Get *real* offsetParent + offsetParent = this.offsetParent(), + + // Get correct offsets + offset = this.offset(), + parentOffset = rroot.test(offsetParent[0].nodeName) ? { top: 0, left: 0 } : offsetParent.offset(); + + // Subtract element margins + // note: when an element has margin: auto the offsetLeft and marginLeft + // are the same in Safari causing offset.left to incorrectly be 0 + offset.top -= parseFloat( jQuery.css(elem, "marginTop") ) || 0; + offset.left -= parseFloat( jQuery.css(elem, "marginLeft") ) || 0; + + // Add offsetParent borders + parentOffset.top += parseFloat( jQuery.css(offsetParent[0], "borderTopWidth") ) || 0; + parentOffset.left += parseFloat( jQuery.css(offsetParent[0], "borderLeftWidth") ) || 0; + + // Subtract the two offsets + return { + top: offset.top - parentOffset.top, + left: offset.left - parentOffset.left + }; + }, + + offsetParent: function() { + return this.map(function() { + var offsetParent = this.offsetParent || document.body; + while ( offsetParent && (!rroot.test(offsetParent.nodeName) && jQuery.css(offsetParent, "position") === "static") ) { + offsetParent = offsetParent.offsetParent; + } + return offsetParent || document.body; + }); + } +}); + + +// Create scrollLeft and scrollTop methods +jQuery.each( {scrollLeft: "pageXOffset", scrollTop: "pageYOffset"}, function( method, prop ) { + var top = /Y/.test( prop ); + + jQuery.fn[ method ] = function( val ) { + return jQuery.access( this, function( elem, method, val ) { + var win = getWindow( elem ); + + if ( val === undefined ) { + return win ? (prop in win) ? win[ prop ] : + win.document.documentElement[ method ] : + elem[ method ]; + } + + if ( win ) { + win.scrollTo( + !top ? val : jQuery( win ).scrollLeft(), + top ? val : jQuery( win ).scrollTop() + ); + + } else { + elem[ method ] = val; + } + }, method, val, arguments.length, null ); + }; +}); + +function getWindow( elem ) { + return jQuery.isWindow( elem ) ? + elem : + elem.nodeType === 9 ? + elem.defaultView || elem.parentWindow : + false; +} +// Create innerHeight, innerWidth, height, width, outerHeight and outerWidth methods +jQuery.each( { Height: "height", Width: "width" }, function( name, type ) { + jQuery.each( { padding: "inner" + name, content: type, "": "outer" + name }, function( defaultExtra, funcName ) { + // margin is only for outerHeight, outerWidth + jQuery.fn[ funcName ] = function( margin, value ) { + var chainable = arguments.length && ( defaultExtra || typeof margin !== "boolean" ), + extra = defaultExtra || ( margin === true || value === true ? "margin" : "border" ); + + return jQuery.access( this, function( elem, type, value ) { + var doc; + + if ( jQuery.isWindow( elem ) ) { + // As of 5/8/2012 this will yield incorrect results for Mobile Safari, but there + // isn't a whole lot we can do. See pull request at this URL for discussion: + // https://github.com/jquery/jquery/pull/764 + return elem.document.documentElement[ "client" + name ]; + } + + // Get document width or height + if ( elem.nodeType === 9 ) { + doc = elem.documentElement; + + // Either scroll[Width/Height] or offset[Width/Height] or client[Width/Height], whichever is greatest + // unfortunately, this causes bug #3838 in IE6/8 only, but there is currently no good, small way to fix it. + return Math.max( + elem.body[ "scroll" + name ], doc[ "scroll" + name ], + elem.body[ "offset" + name ], doc[ "offset" + name ], + doc[ "client" + name ] + ); + } + + return value === undefined ? + // Get width or height on the element, requesting but not forcing parseFloat + jQuery.css( elem, type, value, extra ) : + + // Set width or height on the element + jQuery.style( elem, type, value, extra ); + }, type, chainable ? margin : undefined, chainable, null ); + }; + }); +}); +// Expose jQuery to the global object +window.jQuery = window.$ = jQuery; + +// Expose jQuery as an AMD module, but only for AMD loaders that +// understand the issues with loading multiple versions of jQuery +// in a page that all might call define(). The loader will indicate +// they have special allowances for multiple jQuery versions by +// specifying define.amd.jQuery = true. Register as a named module, +// since jQuery can be concatenated with other files that may use define, +// but not use a proper concatenation script that understands anonymous +// AMD modules. A named AMD is safest and most robust way to register. +// Lowercase jquery is used because AMD module names are derived from +// file names, and jQuery is normally delivered in a lowercase file name. +// Do this after creating the global so that if an AMD module wants to call +// noConflict to hide this version of jQuery, it will work. +if ( typeof define === "function" && define.amd && define.amd.jQuery ) { + define( "jquery", [], function () { return jQuery; } ); +} + +})( window ); diff --git a/htdocs/js/lib/webwork/components/jquery/jquery.js b/htdocs/js/lib/webwork/components/jquery/jquery.js new file mode 100644 index 000000000..973ef3d9a --- /dev/null +++ b/htdocs/js/lib/webwork/components/jquery/jquery.js @@ -0,0 +1,9301 @@ +/*! + * jQuery JavaScript Library v1.8.1 + * http://jquery.com/ + * + * Includes Sizzle.js + * http://sizzlejs.com/ + * + * Copyright 2012 jQuery Foundation and other contributors + * Released under the MIT license + * http://jquery.org/license + * + * Date: Thu Aug 30 2012 17:17:22 GMT-0400 (Eastern Daylight Time) + */ +(function( window, undefined ) { +var + // A central reference to the root jQuery(document) + rootjQuery, + + // The deferred used on DOM ready + readyList, + + // Use the correct document accordingly with window argument (sandbox) + document = window.document, + location = window.location, + navigator = window.navigator, + + // Map over jQuery in case of overwrite + _jQuery = window.jQuery, + + // Map over the $ in case of overwrite + _$ = window.$, + + // Save a reference to some core methods + core_push = Array.prototype.push, + core_slice = Array.prototype.slice, + core_indexOf = Array.prototype.indexOf, + core_toString = Object.prototype.toString, + core_hasOwn = Object.prototype.hasOwnProperty, + core_trim = String.prototype.trim, + + // Define a local copy of jQuery + jQuery = function( selector, context ) { + // The jQuery object is actually just the init constructor 'enhanced' + return new jQuery.fn.init( selector, context, rootjQuery ); + }, + + // Used for matching numbers + core_pnum = /[\-+]?(?:\d*\.|)\d+(?:[eE][\-+]?\d+|)/.source, + + // Used for detecting and trimming whitespace + core_rnotwhite = /\S/, + core_rspace = /\s+/, + + // Make sure we trim BOM and NBSP (here's looking at you, Safari 5.0 and IE) + rtrim = /^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g, + + // A simple way to check for HTML strings + // Prioritize #id over to avoid XSS via location.hash (#9521) + rquickExpr = /^(?:[^#<]*(<[\w\W]+>)[^>]*$|#([\w\-]*)$)/, + + // Match a standalone tag + rsingleTag = /^<(\w+)\s*\/?>(?:<\/\1>|)$/, + + // JSON RegExp + rvalidchars = /^[\],:{}\s]*$/, + rvalidbraces = /(?:^|:|,)(?:\s*\[)+/g, + rvalidescape = /\\(?:["\\\/bfnrt]|u[\da-fA-F]{4})/g, + rvalidtokens = /"[^"\\\r\n]*"|true|false|null|-?(?:\d\d*\.|)\d+(?:[eE][\-+]?\d+|)/g, + + // Matches dashed string for camelizing + rmsPrefix = /^-ms-/, + rdashAlpha = /-([\da-z])/gi, + + // Used by jQuery.camelCase as callback to replace() + fcamelCase = function( all, letter ) { + return ( letter + "" ).toUpperCase(); + }, + + // The ready event handler and self cleanup method + DOMContentLoaded = function() { + if ( document.addEventListener ) { + document.removeEventListener( "DOMContentLoaded", DOMContentLoaded, false ); + jQuery.ready(); + } else if ( document.readyState === "complete" ) { + // we're here because readyState === "complete" in oldIE + // which is good enough for us to call the dom ready! + document.detachEvent( "onreadystatechange", DOMContentLoaded ); + jQuery.ready(); + } + }, + + // [[Class]] -> type pairs + class2type = {}; + +jQuery.fn = jQuery.prototype = { + constructor: jQuery, + init: function( selector, context, rootjQuery ) { + var match, elem, ret, doc; + + // Handle $(""), $(null), $(undefined), $(false) + if ( !selector ) { + return this; + } + + // Handle $(DOMElement) + if ( selector.nodeType ) { + this.context = this[0] = selector; + this.length = 1; + return this; + } + + // Handle HTML strings + if ( typeof selector === "string" ) { + 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 = rquickExpr.exec( selector ); + } + + // Match html or make sure no context is specified for #id + if ( match && (match[1] || !context) ) { + + // HANDLE: $(html) -> $(array) + if ( match[1] ) { + context = context instanceof jQuery ? context[0] : context; + doc = ( context && context.nodeType ? context.ownerDocument || context : document ); + + // scripts is true for back-compat + selector = jQuery.parseHTML( match[1], doc, true ); + if ( rsingleTag.test( match[1] ) && jQuery.isPlainObject( context ) ) { + this.attr.call( selector, context, true ); + } + + 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.8.1", + + // 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 core_slice.call( this ); + }, + + // 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 = jQuery.merge( this.constructor(), 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 ) { + // Add the callback + jQuery.ready.promise().done( fn ); + + return this; + }, + + eq: function( i ) { + i = +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( core_slice.apply( this, arguments ), + "slice", core_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: core_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 ) { + + // Abort if there are pending holds or we're already ready + if ( wait === true ? --jQuery.readyWait : jQuery.isReady ) { + return; + } + + // 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").off("ready"); + } + }, + + // 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"; + }, + + isWindow: function( obj ) { + return obj != null && obj == obj.window; + }, + + isNumeric: function( obj ) { + return !isNaN( parseFloat(obj) ) && isFinite( obj ); + }, + + type: function( obj ) { + return obj == null ? + String( obj ) : + class2type[ core_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; + } + + try { + // Not own constructor property must be Object + if ( obj.constructor && + !core_hasOwn.call(obj, "constructor") && + !core_hasOwn.call(obj.constructor.prototype, "isPrototypeOf") ) { + return false; + } + } catch ( e ) { + // IE8,9 Will throw exceptions on certain host objects #9897 + 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 || core_hasOwn.call( obj, key ); + }, + + isEmptyObject: function( obj ) { + var name; + for ( name in obj ) { + return false; + } + return true; + }, + + error: function( msg ) { + throw new Error( msg ); + }, + + // data: string of html + // context (optional): If specified, the fragment will be created in this context, defaults to document + // scripts (optional): If true, will include scripts passed in the html string + parseHTML: function( data, context, scripts ) { + var parsed; + if ( !data || typeof data !== "string" ) { + return null; + } + if ( typeof context === "boolean" ) { + scripts = context; + context = 0; + } + context = context || document; + + // Single tag + if ( (parsed = rsingleTag.exec( data )) ) { + return [ context.createElement( parsed[1] ) ]; + } + + parsed = jQuery.buildFragment( [ data ], context, scripts ? null : [] ); + return jQuery.merge( [], + (parsed.cacheable ? jQuery.clone( parsed.fragment ) : parsed.fragment).childNodes ); + }, + + parseJSON: function( data ) { + if ( !data || typeof data !== "string") { + 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 + parseXML: function( data ) { + var xml, tmp; + if ( !data || typeof data !== "string" ) { + return null; + } + try { + 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 ); + } + } catch( e ) { + xml = undefined; + } + if ( !xml || !xml.documentElement || xml.getElementsByTagName( "parsererror" ).length ) { + 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 && core_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 ); + } + }, + + // Convert dashed to camelCase; used by the css and data modules + // Microsoft forgot to hump their vendor prefix (#9572) + camelCase: function( string ) { + return string.replace( rmsPrefix, "ms-" ).replace( rdashAlpha, fcamelCase ); + }, + + nodeName: function( elem, name ) { + return elem.nodeName && elem.nodeName.toUpperCase() === name.toUpperCase(); + }, + + // args is for internal usage only + each: function( obj, callback, args ) { + var name, + i = 0, + length = obj.length, + isObj = length === undefined || jQuery.isFunction( obj ); + + if ( args ) { + if ( isObj ) { + for ( name in obj ) { + if ( callback.apply( obj[ name ], args ) === false ) { + break; + } + } + } else { + for ( ; i < length; ) { + if ( callback.apply( obj[ i++ ], args ) === false ) { + break; + } + } + } + + // A special, fast, case for the most common use of each + } else { + if ( isObj ) { + for ( name in obj ) { + if ( callback.call( obj[ name ], name, obj[ name ] ) === false ) { + break; + } + } + } else { + for ( ; i < length; ) { + if ( callback.call( obj[ i ], i, obj[ i++ ] ) === false ) { + break; + } + } + } + } + + return obj; + }, + + // Use native String.trim function wherever possible + trim: core_trim && !core_trim.call("\uFEFF\xA0") ? + function( text ) { + return text == null ? + "" : + core_trim.call( text ); + } : + + // Otherwise use our own trimming functionality + function( text ) { + return text == null ? + "" : + text.toString().replace( rtrim, "" ); + }, + + // results is for internal usage only + makeArray: function( arr, results ) { + var type, + ret = results || []; + + if ( arr != null ) { + // The window, strings (and functions) also have 'length' + // Tweaked logic slightly to handle Blackberry 4.7 RegExp issues #6930 + type = jQuery.type( arr ); + + if ( arr.length == null || type === "string" || type === "function" || type === "regexp" || jQuery.isWindow( arr ) ) { + core_push.call( ret, arr ); + } else { + jQuery.merge( ret, arr ); + } + } + + return ret; + }, + + inArray: function( elem, arr, i ) { + var len; + + if ( arr ) { + if ( core_indexOf ) { + return core_indexOf.call( arr, elem, i ); + } + + len = arr.length; + i = i ? i < 0 ? Math.max( 0, len + i ) : i : 0; + + for ( ; i < len; i++ ) { + // Skip accessing in sparse arrays + if ( i in arr && arr[ i ] === elem ) { + return i; + } + } + } + + return -1; + }, + + merge: function( first, second ) { + var l = second.length, + i = first.length, + j = 0; + + if ( typeof l === "number" ) { + for ( ; 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 retVal, + ret = [], + i = 0, + length = elems.length; + inv = !!inv; + + // Go through the array, only saving the items + // that pass the validator function + for ( ; 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 ) { + var tmp, args, proxy; + + if ( typeof context === "string" ) { + 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 + args = core_slice.call( arguments, 2 ); + proxy = function() { + return fn.apply( context, args.concat( core_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; + }, + + // Multifunctional method to get and set values of a collection + // The value/s can optionally be executed if it's a function + access: function( elems, fn, key, value, chainable, emptyGet, pass ) { + var exec, + bulk = key == null, + i = 0, + length = elems.length; + + // Sets many values + if ( key && typeof key === "object" ) { + for ( i in key ) { + jQuery.access( elems, fn, i, key[i], 1, emptyGet, value ); + } + chainable = 1; + + // Sets one value + } else if ( value !== undefined ) { + // Optionally, function values get executed if exec is true + exec = pass === undefined && jQuery.isFunction( value ); + + if ( bulk ) { + // Bulk operations only iterate when executing function values + if ( exec ) { + exec = fn; + fn = function( elem, key, value ) { + return exec.call( jQuery( elem ), value ); + }; + + // Otherwise they run against the entire set + } else { + fn.call( elems, value ); + fn = null; + } + } + + if ( fn ) { + for (; i < length; i++ ) { + fn( elems[i], key, exec ? value.call( elems[i], i, fn( elems[i], key ) ) : value, pass ); + } + } + + chainable = 1; + } + + return chainable ? + elems : + + // Gets + bulk ? + fn.call( elems ) : + length ? fn( elems[0], key ) : emptyGet; + }, + + now: function() { + return ( new Date() ).getTime(); + } +}); + +jQuery.ready.promise = function( obj ) { + if ( !readyList ) { + + readyList = jQuery.Deferred(); + + // Catch cases where $(document).ready() is called after the browser event has already occurred. + // we once tried to use readyState "interactive" here, but it caused issues like the one + // discovered by ChrisS here: http://bugs.jquery.com/ticket/12282#comment:15 + if ( document.readyState === "complete" ) { + // Handle it asynchronously to allow scripts the opportunity to delay ready + setTimeout( jQuery.ready, 1 ); + + // Standards-based browsers support DOMContentLoaded + } else 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 { + // 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 top = false; + + try { + top = window.frameElement == null && document.documentElement; + } catch(e) {} + + if ( top && top.doScroll ) { + (function doScrollCheck() { + if ( !jQuery.isReady ) { + + try { + // Use the trick by Diego Perini + // http://javascript.nwbox.com/IEContentLoaded/ + top.doScroll("left"); + } catch(e) { + return setTimeout( doScrollCheck, 50 ); + } + + // and execute any waiting functions + jQuery.ready(); + } + })(); + } + } + } + return readyList.promise( obj ); +}; + +// Populate the class2type map +jQuery.each("Boolean Number String Function Array Date RegExp Object".split(" "), function(i, name) { + class2type[ "[object " + name + "]" ] = name.toLowerCase(); +}); + +// All jQuery objects should point back to these +rootjQuery = jQuery(document); +// String to Object options format cache +var optionsCache = {}; + +// Convert String-formatted options into Object-formatted ones and store in cache +function createOptions( options ) { + var object = optionsCache[ options ] = {}; + jQuery.each( options.split( core_rspace ), function( _, flag ) { + object[ flag ] = true; + }); + return object; +} + +/* + * Create a callback list using the following parameters: + * + * options: an optional list of space-separated options that will change how + * the callback list behaves or a more traditional option object + * + * By default a callback list will act like an event callback list and can be + * "fired" multiple times. + * + * Possible options: + * + * once: will ensure the callback list can only be fired once (like a Deferred) + * + * memory: will keep track of previous values and will call any callback added + * after the list has been fired right away with the latest "memorized" + * values (like a Deferred) + * + * unique: will ensure a callback can only be added once (no duplicate in the list) + * + * stopOnFalse: interrupt callings when a callback returns false + * + */ +jQuery.Callbacks = function( options ) { + + // Convert options from String-formatted to Object-formatted if needed + // (we check in cache first) + options = typeof options === "string" ? + ( optionsCache[ options ] || createOptions( options ) ) : + jQuery.extend( {}, options ); + + var // Last fire value (for non-forgettable lists) + memory, + // Flag to know if list was already fired + fired, + // Flag to know if list is currently firing + firing, + // First callback to fire (used internally by add and fireWith) + firingStart, + // End of the loop when firing + firingLength, + // Index of currently firing callback (modified by remove if needed) + firingIndex, + // Actual callback list + list = [], + // Stack of fire calls for repeatable lists + stack = !options.once && [], + // Fire callbacks + fire = function( data ) { + memory = options.memory && data; + fired = true; + firingIndex = firingStart || 0; + firingStart = 0; + firingLength = list.length; + firing = true; + for ( ; list && firingIndex < firingLength; firingIndex++ ) { + if ( list[ firingIndex ].apply( data[ 0 ], data[ 1 ] ) === false && options.stopOnFalse ) { + memory = false; // To prevent further calls using add + break; + } + } + firing = false; + if ( list ) { + if ( stack ) { + if ( stack.length ) { + fire( stack.shift() ); + } + } else if ( memory ) { + list = []; + } else { + self.disable(); + } + } + }, + // Actual Callbacks object + self = { + // Add a callback or a collection of callbacks to the list + add: function() { + if ( list ) { + // First, we save the current length + var start = list.length; + (function add( args ) { + jQuery.each( args, function( _, arg ) { + var type = jQuery.type( arg ); + if ( type === "function" && ( !options.unique || !self.has( arg ) ) ) { + list.push( arg ); + } else if ( arg && arg.length && type !== "string" ) { + // Inspect recursively + add( arg ); + } + }); + })( arguments ); + // Do we need to add the callbacks to the + // current firing batch? + if ( firing ) { + firingLength = list.length; + // With memory, if we're not firing then + // we should call right away + } else if ( memory ) { + firingStart = start; + fire( memory ); + } + } + return this; + }, + // Remove a callback from the list + remove: function() { + if ( list ) { + jQuery.each( arguments, function( _, arg ) { + var index; + while( ( index = jQuery.inArray( arg, list, index ) ) > -1 ) { + list.splice( index, 1 ); + // Handle firing indexes + if ( firing ) { + if ( index <= firingLength ) { + firingLength--; + } + if ( index <= firingIndex ) { + firingIndex--; + } + } + } + }); + } + return this; + }, + // Control if a given callback is in the list + has: function( fn ) { + return jQuery.inArray( fn, list ) > -1; + }, + // Remove all callbacks from the list + empty: function() { + list = []; + return this; + }, + // Have the list do nothing anymore + disable: function() { + list = stack = memory = undefined; + return this; + }, + // Is it disabled? + disabled: function() { + return !list; + }, + // Lock the list in its current state + lock: function() { + stack = undefined; + if ( !memory ) { + self.disable(); + } + return this; + }, + // Is it locked? + locked: function() { + return !stack; + }, + // Call all callbacks with the given context and arguments + fireWith: function( context, args ) { + args = args || []; + args = [ context, args.slice ? args.slice() : args ]; + if ( list && ( !fired || stack ) ) { + if ( firing ) { + stack.push( args ); + } else { + fire( args ); + } + } + return this; + }, + // Call all the callbacks with the given arguments + fire: function() { + self.fireWith( this, arguments ); + return this; + }, + // To know if the callbacks have already been called at least once + fired: function() { + return !!fired; + } + }; + + return self; +}; +jQuery.extend({ + + Deferred: function( func ) { + var tuples = [ + // action, add listener, listener list, final state + [ "resolve", "done", jQuery.Callbacks("once memory"), "resolved" ], + [ "reject", "fail", jQuery.Callbacks("once memory"), "rejected" ], + [ "notify", "progress", jQuery.Callbacks("memory") ] + ], + state = "pending", + promise = { + state: function() { + return state; + }, + always: function() { + deferred.done( arguments ).fail( arguments ); + return this; + }, + then: function( /* fnDone, fnFail, fnProgress */ ) { + var fns = arguments; + return jQuery.Deferred(function( newDefer ) { + jQuery.each( tuples, function( i, tuple ) { + var action = tuple[ 0 ], + fn = fns[ i ]; + // deferred[ done | fail | progress ] for forwarding actions to newDefer + deferred[ tuple[1] ]( jQuery.isFunction( fn ) ? + function() { + var returned = fn.apply( this, arguments ); + if ( returned && jQuery.isFunction( returned.promise ) ) { + returned.promise() + .done( newDefer.resolve ) + .fail( newDefer.reject ) + .progress( newDefer.notify ); + } else { + newDefer[ action + "With" ]( this === deferred ? newDefer : this, [ returned ] ); + } + } : + newDefer[ action ] + ); + }); + fns = null; + }).promise(); + }, + // Get a promise for this deferred + // If obj is provided, the promise aspect is added to the object + promise: function( obj ) { + return typeof obj === "object" ? jQuery.extend( obj, promise ) : promise; + } + }, + deferred = {}; + + // Keep pipe for back-compat + promise.pipe = promise.then; + + // Add list-specific methods + jQuery.each( tuples, function( i, tuple ) { + var list = tuple[ 2 ], + stateString = tuple[ 3 ]; + + // promise[ done | fail | progress ] = list.add + promise[ tuple[1] ] = list.add; + + // Handle state + if ( stateString ) { + list.add(function() { + // state = [ resolved | rejected ] + state = stateString; + + // [ reject_list | resolve_list ].disable; progress_list.lock + }, tuples[ i ^ 1 ][ 2 ].disable, tuples[ 2 ][ 2 ].lock ); + } + + // deferred[ resolve | reject | notify ] = list.fire + deferred[ tuple[0] ] = list.fire; + deferred[ tuple[0] + "With" ] = list.fireWith; + }); + + // Make the deferred a promise + promise.promise( deferred ); + + // Call given func if any + if ( func ) { + func.call( deferred, deferred ); + } + + // All done! + return deferred; + }, + + // Deferred helper + when: function( subordinate /* , ..., subordinateN */ ) { + var i = 0, + resolveValues = core_slice.call( arguments ), + length = resolveValues.length, + + // the count of uncompleted subordinates + remaining = length !== 1 || ( subordinate && jQuery.isFunction( subordinate.promise ) ) ? length : 0, + + // the master Deferred. If resolveValues consist of only a single Deferred, just use that. + deferred = remaining === 1 ? subordinate : jQuery.Deferred(), + + // Update function for both resolve and progress values + updateFunc = function( i, contexts, values ) { + return function( value ) { + contexts[ i ] = this; + values[ i ] = arguments.length > 1 ? core_slice.call( arguments ) : value; + if( values === progressValues ) { + deferred.notifyWith( contexts, values ); + } else if ( !( --remaining ) ) { + deferred.resolveWith( contexts, values ); + } + }; + }, + + progressValues, progressContexts, resolveContexts; + + // add listeners to Deferred subordinates; treat others as resolved + if ( length > 1 ) { + progressValues = new Array( length ); + progressContexts = new Array( length ); + resolveContexts = new Array( length ); + for ( ; i < length; i++ ) { + if ( resolveValues[ i ] && jQuery.isFunction( resolveValues[ i ].promise ) ) { + resolveValues[ i ].promise() + .done( updateFunc( i, resolveContexts, resolveValues ) ) + .fail( deferred.reject ) + .progress( updateFunc( i, progressContexts, progressValues ) ); + } else { + --remaining; + } + } + } + + // if we're not waiting on anything, resolve the master + if ( !remaining ) { + deferred.resolveWith( resolveContexts, resolveValues ); + } + + return deferred.promise(); + } +}); +jQuery.support = (function() { + + var support, + all, + a, + select, + opt, + input, + fragment, + eventName, + i, + isSupported, + clickFn, + div = document.createElement("div"); + + // Preliminary tests + div.setAttribute( "className", "t" ); + div.innerHTML = "
      a"; + + all = div.getElementsByTagName("*"); + a = div.getElementsByTagName("a")[ 0 ]; + a.style.cssText = "top:1px;float:left;opacity:.5"; + + // 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.5/.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", + + // Tests for enctype support on a form(#6743) + enctype: !!document.createElement("form").enctype, + + // Makes sure cloning an html5 element does not cause problems + // Where outerHTML is undefined, this still works + html5Clone: document.createElement("nav").cloneNode( true ).outerHTML !== "<:nav>", + + // jQuery.support.boxModel DEPRECATED in 1.8 since we don't support Quirks Mode + boxModel: ( document.compatMode === "CSS1Compat" ), + + // Will be defined later + submitBubbles: true, + changeBubbles: true, + focusinBubbles: false, + deleteExpando: true, + noCloneEvent: true, + inlineBlockNeedsLayout: false, + shrinkWrapBlocks: false, + reliableMarginRight: true, + boxSizingReliable: true, + pixelPosition: false + }; + + // 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", clickFn = function() { + // Cloning a node shouldn't copy over any + // bound event handlers (IE does this) + support.noCloneEvent = false; + }); + div.cloneNode( true ).fireEvent("onclick"); + div.detachEvent( "onclick", clickFn ); + } + + // Check if a radio maintains its 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" ); + + // #11217 - WebKit loses check when the name is after the checked attribute + input.setAttribute( "name", "t" ); + + div.appendChild( input ); + fragment = document.createDocumentFragment(); + fragment.appendChild( div.lastChild ); + + // WebKit doesn't clone checked state correctly in fragments + support.checkClone = fragment.cloneNode( true ).cloneNode( true ).lastChild.checked; + + // Check if a disconnected checkbox will retain its checked + // value of true after appended to the DOM (IE6/7) + support.appendChecked = input.checked; + + fragment.removeChild( input ); + fragment.appendChild( div ); + + // Technique from Juriy Zaytsev + // http://perfectionkills.com/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: true, + change: true, + focusin: true + }) { + eventName = "on" + i; + isSupported = ( eventName in div ); + if ( !isSupported ) { + div.setAttribute( eventName, "return;" ); + isSupported = ( typeof div[ eventName ] === "function" ); + } + support[ i + "Bubbles" ] = isSupported; + } + } + + // Run tests that need a body at doc ready + jQuery(function() { + var container, div, tds, marginDiv, + divReset = "padding:0;margin:0;border:0;display:block;overflow:hidden;", + body = document.getElementsByTagName("body")[0]; + + if ( !body ) { + // Return for frameset docs that don't have a body + return; + } + + container = document.createElement("div"); + container.style.cssText = "visibility:hidden;border:0;width:0;height:0;position:static;top:0;margin-top:1px"; + body.insertBefore( container, body.firstChild ); + + // Construct the test element + div = document.createElement("div"); + container.appendChild( div ); + + // 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) + div.innerHTML = "
      t
      "; + tds = div.getElementsByTagName("td"); + tds[ 0 ].style.cssText = "padding:0;margin:0;border:0;display:none"; + 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 ); + + // Check box-sizing and margin behavior + div.innerHTML = ""; + div.style.cssText = "box-sizing:border-box;-moz-box-sizing:border-box;-webkit-box-sizing:border-box;padding:1px;border:1px;display:block;width:4px;margin-top:1%;position:absolute;top:1%;"; + support.boxSizing = ( div.offsetWidth === 4 ); + support.doesNotIncludeMarginInBodyOffset = ( body.offsetTop !== 1 ); + + // NOTE: To any future maintainer, we've window.getComputedStyle + // because jsdom on node.js will break without it. + if ( window.getComputedStyle ) { + support.pixelPosition = ( window.getComputedStyle( div, null ) || {} ).top !== "1%"; + support.boxSizingReliable = ( window.getComputedStyle( div, null ) || { width: "4px" } ).width === "4px"; + + // 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 + marginDiv = document.createElement("div"); + marginDiv.style.cssText = div.style.cssText = divReset; + marginDiv.style.marginRight = marginDiv.style.width = "0"; + div.style.width = "1px"; + div.appendChild( marginDiv ); + support.reliableMarginRight = + !parseFloat( ( window.getComputedStyle( marginDiv, null ) || {} ).marginRight ); + } + + if ( typeof div.style.zoom !== "undefined" ) { + // 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.innerHTML = ""; + div.style.cssText = divReset + "width:1px;padding:1px;display:inline;zoom:1"; + support.inlineBlockNeedsLayout = ( div.offsetWidth === 3 ); + + // Check if elements with layout shrink-wrap their children + // (IE 6 does this) + div.style.display = "block"; + div.style.overflow = "visible"; + div.innerHTML = "
      "; + div.firstChild.style.width = "5px"; + support.shrinkWrapBlocks = ( div.offsetWidth !== 3 ); + + container.style.zoom = 1; + } + + // Null elements to avoid leaks in IE + body.removeChild( container ); + container = div = tds = marginDiv = null; + }); + + // Null elements to avoid leaks in IE + fragment.removeChild( div ); + all = a = select = opt = input = fragment = div = null; + + return support; +})(); +var rbrace = /(?:\{[\s\S]*\}|\[[\s\S]*\])$/, + rmultiDash = /([A-Z])/g; + +jQuery.extend({ + cache: {}, + + deletedIds: [], + + // 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 thisCache, ret, + internalKey = jQuery.expando, + getByName = typeof name === "string", + + // 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[ internalKey ] : elem[ internalKey ] && internalKey; + + // 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 || !cache[id] || (!pvt && !cache[id].data)) && 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[ internalKey ] = id = jQuery.deletedIds.pop() || ++jQuery.uuid; + } else { + id = internalKey; + } + } + + if ( !cache[ id ] ) { + cache[ id ] = {}; + + // 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 ] = jQuery.extend( cache[ id ], name ); + } else { + cache[ id ].data = jQuery.extend( cache[ id ].data, name ); + } + } + + thisCache = cache[ id ]; + + // jQuery data() is stored in a separate object inside the object's internal data + // cache in order to avoid key collisions between internal data and user-defined + // data. + if ( !pvt ) { + if ( !thisCache.data ) { + thisCache.data = {}; + } + + thisCache = thisCache.data; + } + + if ( data !== undefined ) { + thisCache[ jQuery.camelCase( name ) ] = data; + } + + // Check for both converted-to-camel and non-converted data property names + // If a data property was specified + if ( getByName ) { + + // First Try to find as-is property data + ret = thisCache[ name ]; + + // Test for null|undefined property data + if ( ret == null ) { + + // Try to find the camelCased property + ret = thisCache[ jQuery.camelCase( name ) ]; + } + } else { + ret = thisCache; + } + + return ret; + }, + + removeData: function( elem, name, pvt /* Internal Use Only */ ) { + if ( !jQuery.acceptData( elem ) ) { + return; + } + + var thisCache, i, l, + + isNode = elem.nodeType, + + // See jQuery.data for more information + cache = isNode ? jQuery.cache : elem, + 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 ) { + + thisCache = pvt ? cache[ id ] : cache[ id ].data; + + if ( thisCache ) { + + // Support array or space separated string names for data keys + if ( !jQuery.isArray( name ) ) { + + // try the string as a key before any manipulation + if ( name in thisCache ) { + name = [ name ]; + } else { + + // split the camel cased version by spaces unless a key with the spaces exists + name = jQuery.camelCase( name ); + if ( name in thisCache ) { + name = [ name ]; + } else { + name = name.split(" "); + } + } + } + + for ( i = 0, l = name.length; i < l; i++ ) { + delete thisCache[ name[i] ]; + } + + // If there is no data left in the cache, we want to continue + // and let the cache object itself get destroyed + if ( !( pvt ? isEmptyDataObject : jQuery.isEmptyObject )( thisCache ) ) { + return; + } + } + } + + // See jQuery.data for more information + if ( !pvt ) { + delete cache[ id ].data; + + // Don't destroy the parent cache unless the internal data object + // had been the only thing left in it + if ( !isEmptyDataObject( cache[ id ] ) ) { + return; + } + } + + // Destroy the cache + if ( isNode ) { + jQuery.cleanData( [ elem ], true ); + + // Use delete when supported for expandos or `cache` is not a window per isWindow (#10080) + } else if ( jQuery.support.deleteExpando || cache != cache.window ) { + delete cache[ id ]; + + // When all else fails, null + } else { + cache[ id ] = 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 ) { + var noData = elem.nodeName && jQuery.noData[ elem.nodeName.toLowerCase() ]; + + // nodes accept data unless otherwise specified; rejection can be conditional + return !noData || noData !== true && elem.getAttribute("classid") === noData; + } +}); + +jQuery.fn.extend({ + data: function( key, value ) { + var parts, part, attr, name, l, + elem = this[0], + i = 0, + data = null; + + // Gets all values + if ( key === undefined ) { + if ( this.length ) { + data = jQuery.data( elem ); + + if ( elem.nodeType === 1 && !jQuery._data( elem, "parsedAttrs" ) ) { + attr = elem.attributes; + for ( l = attr.length; i < l; i++ ) { + name = attr[i].name; + + if ( name.indexOf( "data-" ) === 0 ) { + name = jQuery.camelCase( name.substring(5) ); + + dataAttr( elem, name, data[ name ] ); + } + } + jQuery._data( elem, "parsedAttrs", true ); + } + } + + return data; + } + + // Sets multiple values + if ( typeof key === "object" ) { + return this.each(function() { + jQuery.data( this, key ); + }); + } + + parts = key.split( ".", 2 ); + parts[1] = parts[1] ? "." + parts[1] : ""; + part = parts[1] + "!"; + + return jQuery.access( this, function( value ) { + + if ( value === undefined ) { + data = this.triggerHandler( "getData" + part, [ parts[0] ] ); + + // Try to fetch any internally stored data first + if ( data === undefined && elem ) { + data = jQuery.data( elem, key ); + data = dataAttr( elem, key, data ); + } + + return data === undefined && parts[1] ? + this.data( parts[0] ) : + data; + } + + parts[1] = value; + this.each(function() { + var self = jQuery( this ); + + self.triggerHandler( "setData" + part, parts ); + jQuery.data( this, key, value ); + self.triggerHandler( "changeData" + part, parts ); + }); + }, null, value, arguments.length > 1, null, false ); + }, + + 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" ).toLowerCase(); + + data = elem.getAttribute( name ); + + if ( typeof data === "string" ) { + try { + data = data === "true" ? true : + data === "false" ? false : + data === "null" ? null : + // Only convert to a number if it doesn't change the string + +data + "" === data ? +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; +} + +// checks a cache object for emptiness +function isEmptyDataObject( obj ) { + var name; + for ( name in obj ) { + + // if the public data object is empty, the private is still empty + if ( name === "data" && jQuery.isEmptyObject( obj[name] ) ) { + continue; + } + if ( name !== "toJSON" ) { + return false; + } + } + + return true; +} +jQuery.extend({ + queue: function( elem, type, data ) { + var queue; + + if ( elem ) { + type = ( type || "fx" ) + "queue"; + queue = jQuery._data( elem, type ); + + // Speed up dequeue by getting out quickly if this is just a lookup + if ( data ) { + if ( !queue || jQuery.isArray(data) ) { + queue = jQuery._data( elem, type, jQuery.makeArray(data) ); + } else { + queue.push( data ); + } + } + return queue || []; + } + }, + + dequeue: function( elem, type ) { + type = type || "fx"; + + var queue = jQuery.queue( elem, type ), + startLength = queue.length, + fn = queue.shift(), + hooks = jQuery._queueHooks( elem, type ), + next = function() { + jQuery.dequeue( elem, type ); + }; + + // If the fx queue is dequeued, always remove the progress sentinel + if ( fn === "inprogress" ) { + fn = queue.shift(); + startLength--; + } + + if ( fn ) { + + // Add a progress sentinel to prevent the fx queue from being + // automatically dequeued + if ( type === "fx" ) { + queue.unshift( "inprogress" ); + } + + // clear up the last queue stop function + delete hooks.stop; + fn.call( elem, next, hooks ); + } + + if ( !startLength && hooks ) { + hooks.empty.fire(); + } + }, + + // not intended for public consumption - generates a queueHooks object, or returns the current one + _queueHooks: function( elem, type ) { + var key = type + "queueHooks"; + return jQuery._data( elem, key ) || jQuery._data( elem, key, { + empty: jQuery.Callbacks("once memory").add(function() { + jQuery.removeData( elem, type + "queue", true ); + jQuery.removeData( elem, key, true ); + }) + }); + } +}); + +jQuery.fn.extend({ + queue: function( type, data ) { + var setter = 2; + + if ( typeof type !== "string" ) { + data = type; + type = "fx"; + setter--; + } + + if ( arguments.length < setter ) { + return jQuery.queue( this[0], type ); + } + + return data === undefined ? + this : + this.each(function() { + var queue = jQuery.queue( this, type, data ); + + // ensure a hooks for this queue + jQuery._queueHooks( this, type ); + + 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( next, hooks ) { + var timeout = setTimeout( next, time ); + hooks.stop = function() { + clearTimeout( timeout ); + }; + }); + }, + 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, obj ) { + var tmp, + count = 1, + defer = jQuery.Deferred(), + elements = this, + i = this.length, + resolve = function() { + if ( !( --count ) ) { + defer.resolveWith( elements, [ elements ] ); + } + }; + + if ( typeof type !== "string" ) { + obj = type; + type = undefined; + } + type = type || "fx"; + + while( i-- ) { + tmp = jQuery._data( elements[ i ], type + "queueHooks" ); + if ( tmp && tmp.empty ) { + count++; + tmp.empty.add( resolve ); + } + } + resolve(); + return defer.promise( obj ); + } +}); +var nodeHook, boolHook, fixSpecified, + rclass = /[\t\r\n]/g, + 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, + getSetAttribute = jQuery.support.getSetAttribute; + +jQuery.fn.extend({ + attr: function( name, value ) { + return jQuery.access( this, jQuery.attr, name, value, arguments.length > 1 ); + }, + + removeAttr: function( name ) { + return this.each(function() { + jQuery.removeAttr( this, name ); + }); + }, + + prop: function( name, value ) { + return jQuery.access( this, jQuery.prop, name, value, arguments.length > 1 ); + }, + + 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( core_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 removes, className, elem, c, cl, i, l; + + 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 ) { + removes = ( value || "" ).split( core_rspace ); + + for ( i = 0, l = this.length; i < l; i++ ) { + elem = this[ i ]; + if ( elem.nodeType === 1 && elem.className ) { + + className = (" " + elem.className + " ").replace( rclass, " " ); + + // loop over each item in the removal list + for ( c = 0, cl = removes.length; c < cl; c++ ) { + // Remove until there is nothing to remove, + while ( className.indexOf(" " + removes[ c ] + " ") > -1 ) { + className = className.replace( " " + removes[ c ] + " " , " " ); + } + } + elem.className = value ? jQuery.trim( 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( core_rspace ); + + while ( (className = classNames[ i++ ]) ) { + // check each className given, space separated 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 + " ", + i = 0, + l = this.length; + for ( ; i < l; i++ ) { + if ( this[i].nodeType === 1 && (" " + this[i].className + " ").replace(rclass, " ").indexOf( className ) > -1 ) { + return true; + } + } + + return false; + }, + + val: function( value ) { + var hooks, ret, isFunction, + elem = this[0]; + + if ( !arguments.length ) { + if ( elem ) { + hooks = jQuery.valHooks[ elem.type ] || jQuery.valHooks[ elem.nodeName.toLowerCase() ]; + + 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; + } + + isFunction = jQuery.isFunction( value ); + + return this.each(function( i ) { + var val, + self = jQuery(this); + + 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.type ] || jQuery.valHooks[ this.nodeName.toLowerCase() ]; + + // 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, i, max, option, + 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 + i = one ? index : 0; + max = one ? index + 1 : options.length; + for ( ; i < max; i++ ) { + 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; + } + } + }, + + // Unused in 1.8, left in so attrFn-stabbers won't die; remove in 1.9 + attrFn: {}, + + attr: function( elem, name, value, pass ) { + var ret, hooks, notxml, + nType = elem.nodeType; + + // don't get/set attributes on text, comment and attribute nodes + if ( !elem || nType === 3 || nType === 8 || nType === 2 ) { + return; + } + + if ( pass && jQuery.isFunction( jQuery.fn[ name ] ) ) { + return jQuery( elem )[ name ]( value ); + } + + // Fallback to prop when attributes are not supported + if ( typeof elem.getAttribute === "undefined" ) { + return jQuery.prop( elem, name, value ); + } + + notxml = nType !== 1 || !jQuery.isXMLDoc( elem ); + + // All attributes are lowercase + // Grab necessary hook if one is defined + if ( notxml ) { + name = name.toLowerCase(); + hooks = jQuery.attrHooks[ name ] || ( rboolean.test( name ) ? boolHook : nodeHook ); + } + + if ( value !== undefined ) { + + if ( value === null ) { + jQuery.removeAttr( elem, name ); + return; + + } 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, value ) { + var propName, attrNames, name, isBool, + i = 0; + + if ( value && elem.nodeType === 1 ) { + + attrNames = value.split( core_rspace ); + + for ( ; i < attrNames.length; i++ ) { + name = attrNames[ i ]; + + if ( name ) { + propName = jQuery.propFix[ name ] || name; + isBool = rboolean.test( name ); + + // See #9699 for explanation of this approach (setting first, then removal) + // Do not do this for boolean attributes (see #10870) + if ( !isBool ) { + jQuery.attr( elem, name, "" ); + } + elem.removeAttribute( getSetAttribute ? name : propName ); + + // Set corresponding property to false for boolean attributes + if ( isBool && propName 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; + } + } + }, + // Use the value property for back compat + // Use the nodeHook for button elements in IE6/7 (#1954) + value: { + get: function( elem, name ) { + if ( nodeHook && jQuery.nodeName( elem, "button" ) ) { + return nodeHook.get( elem, name ); + } + return name in elem ? + elem.value : + null; + }, + set: function( elem, value, name ) { + if ( nodeHook && jQuery.nodeName( elem, "button" ) ) { + return nodeHook.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 ret, hooks, notxml, + nType = elem.nodeType; + + // don't get/set properties on text, comment and attribute nodes + if ( !elem || nType === 3 || nType === 8 || nType === 2 ) { + return; + } + + 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 )) !== null ) { + return ret; + + } else { + return elem[ name ]; + } + } + }, + + propHooks: { + 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; + } + } + } +}); + +// Hook for boolean attributes +boolHook = { + get: function( elem, name ) { + // Align boolean attributes with corresponding properties + // Fall back to attribute presence where some booleans are not supported + var attrNode, + property = jQuery.prop( elem, name ); + return property === true || typeof property !== "boolean" && ( attrNode = elem.getAttributeNode(name) ) && attrNode.nodeValue !== false ? + 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 ( !getSetAttribute ) { + + fixSpecified = { + name: true, + id: true, + coords: true + }; + + // Use this for any attribute in IE6/7 + // This fixes almost every IE6/7 issue + nodeHook = jQuery.valHooks.button = { + get: function( elem, name ) { + var ret; + ret = elem.getAttributeNode( name ); + return ret && ( fixSpecified[ name ] ? ret.value !== "" : ret.specified ) ? + ret.value : + undefined; + }, + set: function( elem, value, name ) { + // Set the existing or create a new attribute node + var ret = elem.getAttributeNode( name ); + if ( !ret ) { + ret = document.createAttribute( name ); + elem.setAttributeNode( ret ); + } + return ( ret.value = 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; + } + } + }); + }); + + // Set contenteditable to false on removals(#10429) + // Setting to empty string throws an error as an invalid value + jQuery.attrHooks.contenteditable = { + get: nodeHook.get, + set: function( elem, value, name ) { + if ( value === "" ) { + value = "false"; + } + nodeHook.set( elem, value, name ); + } + }; +} + + +// 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; + } + } + return null; + } + }); +} + +// IE6/7 call enctype encoding +if ( !jQuery.support.enctype ) { + jQuery.propFix.enctype = "encoding"; +} + +// 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 rformElems = /^(?:textarea|input|select)$/i, + rtypenamespace = /^([^\.]*|)(?:\.(.+)|)$/, + rhoverHack = /(?:^|\s)hover(\.\S+|)\b/, + rkeyEvent = /^key/, + rmouseEvent = /^(?:mouse|contextmenu)|click/, + rfocusMorph = /^(?:focusinfocus|focusoutblur)$/, + hoverHack = function( events ) { + return jQuery.event.special.hover ? events : events.replace( rhoverHack, "mouseenter$1 mouseleave$1" ); + }; + +/* + * Helper functions for managing events -- not part of the public interface. + * Props to Dean Edwards' addEvent library for many of the ideas. + */ +jQuery.event = { + + add: function( elem, types, handler, data, selector ) { + + var elemData, eventHandle, events, + t, tns, type, namespaces, handleObj, + handleObjIn, handlers, special; + + // Don't attach events to noData or text/comment nodes (allow plain objects tho) + if ( elem.nodeType === 3 || elem.nodeType === 8 || !types || !handler || !(elemData = jQuery._data( elem )) ) { + return; + } + + // Caller can pass in an object of custom data in lieu of the handler + if ( handler.handler ) { + handleObjIn = handler; + handler = handleObjIn.handler; + selector = handleObjIn.selector; + } + + // Make sure that the handler has a unique ID, used to find/remove it later + if ( !handler.guid ) { + handler.guid = jQuery.guid++; + } + + // Init the element's event structure and main handler, if this is the first + events = elemData.events; + if ( !events ) { + elemData.events = events = {}; + } + eventHandle = elemData.handle; + 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.dispatch.apply( eventHandle.elem, arguments ) : + undefined; + }; + // Add elem as a property of the handle fn to prevent a memory leak with IE non-native events + eventHandle.elem = elem; + } + + // Handle multiple events separated by a space + // jQuery(...).bind("mouseover mouseout", fn); + types = jQuery.trim( hoverHack(types) ).split( " " ); + for ( t = 0; t < types.length; t++ ) { + + tns = rtypenamespace.exec( types[t] ) || []; + type = tns[1]; + namespaces = ( tns[2] || "" ).split( "." ).sort(); + + // If event changes its type, use the special event handlers for the changed type + special = jQuery.event.special[ type ] || {}; + + // If selector defined, determine special event api type, otherwise given type + type = ( selector ? special.delegateType : special.bindType ) || type; + + // Update special based on newly reset type + special = jQuery.event.special[ type ] || {}; + + // handleObj is passed to all event handlers + handleObj = jQuery.extend({ + type: type, + origType: tns[1], + data: data, + handler: handler, + guid: handler.guid, + selector: selector, + namespace: namespaces.join(".") + }, handleObjIn ); + + // Init the event handler queue if we're the first + handlers = events[ type ]; + if ( !handlers ) { + handlers = events[ type ] = []; + handlers.delegateCount = 0; + + // 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 to the element's handler list, delegates in front + if ( selector ) { + handlers.splice( handlers.delegateCount++, 0, handleObj ); + } else { + handlers.push( handleObj ); + } + + // Keep track of which events have ever 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, selector, mappedTypes ) { + + var t, tns, type, origType, namespaces, origCount, + j, events, special, eventType, handleObj, + elemData = jQuery.hasData( elem ) && jQuery._data( elem ); + + if ( !elemData || !(events = elemData.events) ) { + return; + } + + // Once for each type.namespace in types; type may be omitted + types = jQuery.trim( hoverHack( types || "" ) ).split(" "); + for ( t = 0; t < types.length; t++ ) { + tns = rtypenamespace.exec( types[t] ) || []; + type = origType = tns[1]; + namespaces = tns[2]; + + // Unbind all events (on this namespace, if provided) for the element + if ( !type ) { + for ( type in events ) { + jQuery.event.remove( elem, type + types[ t ], handler, selector, true ); + } + continue; + } + + special = jQuery.event.special[ type ] || {}; + type = ( selector? special.delegateType : special.bindType ) || type; + eventType = events[ type ] || []; + origCount = eventType.length; + namespaces = namespaces ? new RegExp("(^|\\.)" + namespaces.split(".").sort().join("\\.(?:.*\\.|)") + "(\\.|$)") : null; + + // Remove matching events + for ( j = 0; j < eventType.length; j++ ) { + handleObj = eventType[ j ]; + + if ( ( mappedTypes || origType === handleObj.origType ) && + ( !handler || handler.guid === handleObj.guid ) && + ( !namespaces || namespaces.test( handleObj.namespace ) ) && + ( !selector || selector === handleObj.selector || selector === "**" && handleObj.selector ) ) { + eventType.splice( j--, 1 ); + + if ( handleObj.selector ) { + eventType.delegateCount--; + } + if ( special.remove ) { + special.remove.call( elem, handleObj ); + } + } + } + + // Remove generic event handler if we removed something and no more handlers exist + // (avoids potential for endless recursion during removal of special event handlers) + if ( eventType.length === 0 && origCount !== eventType.length ) { + if ( !special.teardown || special.teardown.call( elem, namespaces, elemData.handle ) === false ) { + jQuery.removeEvent( elem, type, elemData.handle ); + } + + delete events[ type ]; + } + } + + // Remove the expando if it's no longer used + if ( jQuery.isEmptyObject( events ) ) { + delete elemData.handle; + + // removeData also checks for emptiness and clears the expando if empty + // so use it instead of delete + jQuery.removeData( elem, "events", 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 ) { + // Don't do events on text and comment nodes + if ( elem && (elem.nodeType === 3 || elem.nodeType === 8) ) { + return; + } + + // Event object or event type + var cache, exclusive, i, cur, old, ontype, special, handle, eventPath, bubbleType, + type = event.type || event, + namespaces = []; + + // focus/blur morphs to focusin/out; ensure we're not firing them right now + if ( rfocusMorph.test( type + jQuery.event.triggered ) ) { + return; + } + + 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.isTrigger = true; + event.exclusive = exclusive; + event.namespace = namespaces.join( "." ); + event.namespace_re = event.namespace? new RegExp("(^|\\.)" + namespaces.join("\\.(?:.*\\.|)") + "(\\.|$)") : null; + ontype = type.indexOf( ":" ) < 0 ? "on" + type : ""; + + // Handle a global trigger + if ( !elem ) { + + // TODO: Stop taunting the data cache; remove global events and always attach to document + cache = jQuery.cache; + for ( i in cache ) { + if ( cache[ i ].events && cache[ i ].events[ type ] ) { + jQuery.event.trigger( event, data, cache[ i ].handle.elem, true ); + } + } + return; + } + + // Clean up the event in case it is being reused + event.result = undefined; + if ( !event.target ) { + 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 ); + + // Allow special events to draw outside the lines + special = jQuery.event.special[ type ] || {}; + if ( special.trigger && special.trigger.apply( elem, data ) === false ) { + return; + } + + // Determine event propagation path in advance, per W3C events spec (#9951) + // Bubble up to document, then to window; watch for a global ownerDocument var (#9724) + eventPath = [[ elem, special.bindType || type ]]; + if ( !onlyHandlers && !special.noBubble && !jQuery.isWindow( elem ) ) { + + bubbleType = special.delegateType || type; + cur = rfocusMorph.test( bubbleType + type ) ? elem : elem.parentNode; + for ( old = elem; cur; cur = cur.parentNode ) { + eventPath.push([ cur, bubbleType ]); + old = cur; + } + + // Only add window if we got to document (e.g., not plain obj or detached DOM) + if ( old === (elem.ownerDocument || document) ) { + eventPath.push([ old.defaultView || old.parentWindow || window, bubbleType ]); + } + } + + // Fire handlers on the event path + for ( i = 0; i < eventPath.length && !event.isPropagationStopped(); i++ ) { + + cur = eventPath[i][0]; + event.type = eventPath[i][1]; + + handle = ( jQuery._data( cur, "events" ) || {} )[ event.type ] && jQuery._data( cur, "handle" ); + if ( handle ) { + handle.apply( cur, data ); + } + // Note that this is a bare JS function and not a jQuery handler + handle = ontype && cur[ ontype ]; + if ( handle && jQuery.acceptData( cur ) && handle.apply( cur, data ) === false ) { + event.preventDefault(); + } + } + event.type = type; + + // If nobody prevented the default action, do it now + if ( !onlyHandlers && !event.isDefaultPrevented() ) { + + if ( (!special._default || special._default.apply( elem.ownerDocument, data ) === 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. + // Don't do default actions on window, that's where global variables be (#6170) + // IE<9 dies on focus/blur to hidden element (#1486) + if ( ontype && elem[ type ] && ((type !== "focus" && type !== "blur") || event.target.offsetWidth !== 0) && !jQuery.isWindow( elem ) ) { + + // Don't re-trigger an onFOO event when we call its FOO() method + old = elem[ ontype ]; + + if ( old ) { + elem[ ontype ] = null; + } + + // Prevent re-triggering of the same event, since we already bubbled it above + jQuery.event.triggered = type; + elem[ type ](); + jQuery.event.triggered = undefined; + + if ( old ) { + elem[ ontype ] = old; + } + } + } + } + + return event.result; + }, + + dispatch: function( event ) { + + // Make a writable jQuery.Event from the native event object + event = jQuery.event.fix( event || window.event ); + + var i, j, cur, ret, selMatch, matched, matches, handleObj, sel, related, + handlers = ( (jQuery._data( this, "events" ) || {} )[ event.type ] || []), + delegateCount = handlers.delegateCount, + args = [].slice.call( arguments ), + run_all = !event.exclusive && !event.namespace, + special = jQuery.event.special[ event.type ] || {}, + handlerQueue = []; + + // Use the fix-ed jQuery.Event rather than the (read-only) native event + args[0] = event; + event.delegateTarget = this; + + // Call the preDispatch hook for the mapped type, and let it bail if desired + if ( special.preDispatch && special.preDispatch.call( this, event ) === false ) { + return; + } + + // Determine handlers that should run if there are delegated events + // Avoid non-left-click bubbling in Firefox (#3861) + if ( delegateCount && !(event.button && event.type === "click") ) { + + for ( cur = event.target; cur != this; cur = cur.parentNode || this ) { + + // Don't process clicks (ONLY) on disabled elements (#6911, #8165, #11382, #11764) + if ( cur.disabled !== true || event.type !== "click" ) { + selMatch = {}; + matches = []; + for ( i = 0; i < delegateCount; i++ ) { + handleObj = handlers[ i ]; + sel = handleObj.selector; + + if ( selMatch[ sel ] === undefined ) { + selMatch[ sel ] = jQuery( sel, this ).index( cur ) >= 0; + } + if ( selMatch[ sel ] ) { + matches.push( handleObj ); + } + } + if ( matches.length ) { + handlerQueue.push({ elem: cur, matches: matches }); + } + } + } + } + + // Add the remaining (directly-bound) handlers + if ( handlers.length > delegateCount ) { + handlerQueue.push({ elem: this, matches: handlers.slice( delegateCount ) }); + } + + // Run delegates first; they may want to stop propagation beneath us + for ( i = 0; i < handlerQueue.length && !event.isPropagationStopped(); i++ ) { + matched = handlerQueue[ i ]; + event.currentTarget = matched.elem; + + for ( j = 0; j < matched.matches.length && !event.isImmediatePropagationStopped(); j++ ) { + handleObj = matched.matches[ j ]; + + // Triggered event must either 1) be non-exclusive and have no namespace, or + // 2) have namespace(s) a subset or equal to those in the bound event (both can have no namespace). + if ( run_all || (!event.namespace && !handleObj.namespace) || event.namespace_re && event.namespace_re.test( handleObj.namespace ) ) { + + event.data = handleObj.data; + event.handleObj = handleObj; + + ret = ( (jQuery.event.special[ handleObj.origType ] || {}).handle || handleObj.handler ) + .apply( matched.elem, args ); + + if ( ret !== undefined ) { + event.result = ret; + if ( ret === false ) { + event.preventDefault(); + event.stopPropagation(); + } + } + } + } + } + + // Call the postDispatch hook for the mapped type + if ( special.postDispatch ) { + special.postDispatch.call( this, event ); + } + + return event.result; + }, + + // Includes some event props shared by KeyEvent and MouseEvent + // *** attrChange attrName relatedNode srcElement are not normalized, non-W3C, deprecated, will be removed in 1.8 *** + props: "attrChange attrName relatedNode srcElement altKey bubbles cancelable ctrlKey currentTarget eventPhase metaKey relatedTarget shiftKey target timeStamp view which".split(" "), + + fixHooks: {}, + + keyHooks: { + props: "char charCode key keyCode".split(" "), + filter: function( event, original ) { + + // Add which for key events + if ( event.which == null ) { + event.which = original.charCode != null ? original.charCode : original.keyCode; + } + + return event; + } + }, + + mouseHooks: { + props: "button buttons clientX clientY fromElement offsetX offsetY pageX pageY screenX screenY toElement".split(" "), + filter: function( event, original ) { + var eventDoc, doc, body, + button = original.button, + fromElement = original.fromElement; + + // Calculate pageX/Y if missing and clientX/Y available + if ( event.pageX == null && original.clientX != null ) { + eventDoc = event.target.ownerDocument || document; + doc = eventDoc.documentElement; + body = eventDoc.body; + + event.pageX = original.clientX + ( doc && doc.scrollLeft || body && body.scrollLeft || 0 ) - ( doc && doc.clientLeft || body && body.clientLeft || 0 ); + event.pageY = original.clientY + ( doc && doc.scrollTop || body && body.scrollTop || 0 ) - ( doc && doc.clientTop || body && body.clientTop || 0 ); + } + + // Add relatedTarget, if necessary + if ( !event.relatedTarget && fromElement ) { + event.relatedTarget = fromElement === event.target ? original.toElement : fromElement; + } + + // Add which for click: 1 === left; 2 === middle; 3 === right + // Note: button is not normalized, so don't use it + if ( !event.which && button !== undefined ) { + event.which = ( button & 1 ? 1 : ( button & 2 ? 3 : ( button & 4 ? 2 : 0 ) ) ); + } + + return event; + } + }, + + fix: function( event ) { + if ( event[ jQuery.expando ] ) { + return event; + } + + // Create a writable copy of the event object and normalize some properties + var i, prop, + originalEvent = event, + fixHook = jQuery.event.fixHooks[ event.type ] || {}, + copy = fixHook.props ? this.props.concat( fixHook.props ) : this.props; + + event = jQuery.Event( originalEvent ); + + for ( i = copy.length; i; ) { + prop = copy[ --i ]; + event[ prop ] = originalEvent[ prop ]; + } + + // Fix target property, if necessary (#1925, IE 6/7/8 & Safari2) + if ( !event.target ) { + event.target = originalEvent.srcElement || document; + } + + // Target should not be a text node (#504, Safari) + if ( event.target.nodeType === 3 ) { + event.target = event.target.parentNode; + } + + // For mouse/key events, metaKey==false if it's undefined (#3368, #11328; IE6/7/8) + event.metaKey = !!event.metaKey; + + return fixHook.filter? fixHook.filter( event, originalEvent ) : event; + }, + + special: { + load: { + // Prevent triggered image.load events from bubbling to window.load + noBubble: true + }, + + focus: { + delegateType: "focusin" + }, + blur: { + delegateType: "focusout" + }, + + 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; + } + } + } + }, + + simulate: function( type, elem, event, bubble ) { + // 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. + var e = jQuery.extend( + new jQuery.Event(), + event, + { type: type, + isSimulated: true, + originalEvent: {} + } + ); + if ( bubble ) { + jQuery.event.trigger( e, null, elem ); + } else { + jQuery.event.dispatch.call( elem, e ); + } + if ( e.isDefaultPrevented() ) { + event.preventDefault(); + } + } +}; + +// Some plugins are using, but it's undocumented/deprecated and will be removed. +// The 1.7 special event interface should provide all the hooks needed now. +jQuery.event.handle = jQuery.event.dispatch; + +jQuery.removeEvent = document.removeEventListener ? + function( elem, type, handle ) { + if ( elem.removeEventListener ) { + elem.removeEventListener( type, handle, false ); + } + } : + function( elem, type, handle ) { + var name = "on" + type; + + if ( elem.detachEvent ) { + + // #8545, #7054, preventing memory leaks for custom events in IE6-8 – + // detachEvent needed property on element, by name of that event, to properly expose it to GC + if ( typeof elem[ name ] === "undefined" ) { + elem[ name ] = null; + } + + elem.detachEvent( name, handle ); + } + }; + +jQuery.Event = function( src, props ) { + // Allow instantiation without the 'new' keyword + if ( !(this instanceof jQuery.Event) ) { + 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 ); + } + + // Create a timestamp if incoming event doesn't have one + this.timeStamp = src && src.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 +}; + +// Create mouseenter/leave events using mouseover/out and event-time checks +jQuery.each({ + mouseenter: "mouseover", + mouseleave: "mouseout" +}, function( orig, fix ) { + jQuery.event.special[ orig ] = { + delegateType: fix, + bindType: fix, + + handle: function( event ) { + var ret, + target = this, + related = event.relatedTarget, + handleObj = event.handleObj, + selector = handleObj.selector; + + // For mousenter/leave call the handler if related is outside the target. + // NB: No relatedTarget if the mouse left/entered the browser window + if ( !related || (related !== target && !jQuery.contains( target, related )) ) { + event.type = handleObj.origType; + ret = handleObj.handler.apply( this, arguments ); + event.type = fix; + } + return ret; + } + }; +}); + +// IE submit delegation +if ( !jQuery.support.submitBubbles ) { + + jQuery.event.special.submit = { + setup: function() { + // Only need this for delegated form submit events + if ( jQuery.nodeName( this, "form" ) ) { + return false; + } + + // Lazy-add a submit handler when a descendant form may potentially be submitted + jQuery.event.add( this, "click._submit keypress._submit", function( e ) { + // Node name check avoids a VML-related crash in IE (#9807) + var elem = e.target, + form = jQuery.nodeName( elem, "input" ) || jQuery.nodeName( elem, "button" ) ? elem.form : undefined; + if ( form && !jQuery._data( form, "_submit_attached" ) ) { + jQuery.event.add( form, "submit._submit", function( event ) { + event._submit_bubble = true; + }); + jQuery._data( form, "_submit_attached", true ); + } + }); + // return undefined since we don't need an event listener + }, + + postDispatch: function( event ) { + // If form was submitted by the user, bubble the event up the tree + if ( event._submit_bubble ) { + delete event._submit_bubble; + if ( this.parentNode && !event.isTrigger ) { + jQuery.event.simulate( "submit", this.parentNode, event, true ); + } + } + }, + + teardown: function() { + // Only need this for delegated form submit events + if ( jQuery.nodeName( this, "form" ) ) { + return false; + } + + // Remove delegated handlers; cleanData eventually reaps submit handlers attached above + jQuery.event.remove( this, "._submit" ); + } + }; +} + +// IE change delegation and checkbox/radio fix +if ( !jQuery.support.changeBubbles ) { + + jQuery.event.special.change = { + + setup: function() { + + if ( rformElems.test( this.nodeName ) ) { + // IE doesn't fire change on a check/radio until blur; trigger it on click + // after a propertychange. Eat the blur-change in special.change.handle. + // This still fires onchange a second time for check/radio after blur. + if ( this.type === "checkbox" || this.type === "radio" ) { + jQuery.event.add( this, "propertychange._change", function( event ) { + if ( event.originalEvent.propertyName === "checked" ) { + this._just_changed = true; + } + }); + jQuery.event.add( this, "click._change", function( event ) { + if ( this._just_changed && !event.isTrigger ) { + this._just_changed = false; + } + // Allow triggered, simulated change events (#11500) + jQuery.event.simulate( "change", this, event, true ); + }); + } + return false; + } + // Delegated event; lazy-add a change handler on descendant inputs + jQuery.event.add( this, "beforeactivate._change", function( e ) { + var elem = e.target; + + if ( rformElems.test( elem.nodeName ) && !jQuery._data( elem, "_change_attached" ) ) { + jQuery.event.add( elem, "change._change", function( event ) { + if ( this.parentNode && !event.isSimulated && !event.isTrigger ) { + jQuery.event.simulate( "change", this.parentNode, event, true ); + } + }); + jQuery._data( elem, "_change_attached", true ); + } + }); + }, + + handle: function( event ) { + var elem = event.target; + + // Swallow native change events from checkbox/radio, we already triggered them above + if ( this !== elem || event.isSimulated || event.isTrigger || (elem.type !== "radio" && elem.type !== "checkbox") ) { + return event.handleObj.handler.apply( this, arguments ); + } + }, + + teardown: function() { + jQuery.event.remove( this, "._change" ); + + return !rformElems.test( this.nodeName ); + } + }; +} + +// 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, + handler = function( event ) { + jQuery.event.simulate( fix, event.target, jQuery.event.fix( event ), true ); + }; + + jQuery.event.special[ fix ] = { + setup: function() { + if ( attaches++ === 0 ) { + document.addEventListener( orig, handler, true ); + } + }, + teardown: function() { + if ( --attaches === 0 ) { + document.removeEventListener( orig, handler, true ); + } + } + }; + }); +} + +jQuery.fn.extend({ + + on: function( types, selector, data, fn, /*INTERNAL*/ one ) { + var origFn, type; + + // Types can be a map of types/handlers + if ( typeof types === "object" ) { + // ( types-Object, selector, data ) + if ( typeof selector !== "string" ) { // && selector != null + // ( types-Object, data ) + data = data || selector; + selector = undefined; + } + for ( type in types ) { + this.on( type, selector, data, types[ type ], one ); + } + return this; + } + + if ( data == null && fn == null ) { + // ( types, fn ) + fn = selector; + data = selector = undefined; + } else if ( fn == null ) { + if ( typeof selector === "string" ) { + // ( types, selector, fn ) + fn = data; + data = undefined; + } else { + // ( types, data, fn ) + fn = data; + data = selector; + selector = undefined; + } + } + if ( fn === false ) { + fn = returnFalse; + } else if ( !fn ) { + return this; + } + + if ( one === 1 ) { + origFn = fn; + fn = function( event ) { + // Can use an empty set, since event contains the info + jQuery().off( event ); + return origFn.apply( this, arguments ); + }; + // Use same guid so caller can remove using origFn + fn.guid = origFn.guid || ( origFn.guid = jQuery.guid++ ); + } + return this.each( function() { + jQuery.event.add( this, types, fn, data, selector ); + }); + }, + one: function( types, selector, data, fn ) { + return this.on( types, selector, data, fn, 1 ); + }, + off: function( types, selector, fn ) { + var handleObj, type; + if ( types && types.preventDefault && types.handleObj ) { + // ( event ) dispatched jQuery.Event + handleObj = types.handleObj; + jQuery( types.delegateTarget ).off( + handleObj.namespace ? handleObj.origType + "." + handleObj.namespace : handleObj.origType, + handleObj.selector, + handleObj.handler + ); + return this; + } + if ( typeof types === "object" ) { + // ( types-object [, selector] ) + for ( type in types ) { + this.off( type, selector, types[ type ] ); + } + return this; + } + if ( selector === false || typeof selector === "function" ) { + // ( types [, fn] ) + fn = selector; + selector = undefined; + } + if ( fn === false ) { + fn = returnFalse; + } + return this.each(function() { + jQuery.event.remove( this, types, fn, selector ); + }); + }, + + bind: function( types, data, fn ) { + return this.on( types, null, data, fn ); + }, + unbind: function( types, fn ) { + return this.off( types, null, fn ); + }, + + live: function( types, data, fn ) { + jQuery( this.context ).on( types, this.selector, data, fn ); + return this; + }, + die: function( types, fn ) { + jQuery( this.context ).off( types, this.selector || "**", fn ); + return this; + }, + + delegate: function( selector, types, data, fn ) { + return this.on( types, selector, data, fn ); + }, + undelegate: function( selector, types, fn ) { + // ( namespace ) or ( selector, types [, fn] ) + return arguments.length == 1? this.off( selector, "**" ) : this.off( types, selector || "**", fn ); + }, + + 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 ); + } +}); + +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 contextmenu").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.on( name, null, data, fn ) : + this.trigger( name ); + }; + + if ( rkeyEvent.test( name ) ) { + jQuery.event.fixHooks[ name ] = jQuery.event.keyHooks; + } + + if ( rmouseEvent.test( name ) ) { + jQuery.event.fixHooks[ name ] = jQuery.event.mouseHooks; + } +}); +/*! + * Sizzle CSS Selector Engine + * Copyright 2012 jQuery Foundation and other contributors + * Released under the MIT license + * http://sizzlejs.com/ + */ +(function( window, undefined ) { + +var dirruns, + cachedruns, + assertGetIdNotName, + Expr, + getText, + isXML, + contains, + compile, + sortOrder, + hasDuplicate, + + baseHasDuplicate = true, + strundefined = "undefined", + + expando = ( "sizcache" + Math.random() ).replace( ".", "" ), + + document = window.document, + docElem = document.documentElement, + done = 0, + slice = [].slice, + push = [].push, + + // Augment a function for special use by Sizzle + markFunction = function( fn, value ) { + fn[ expando ] = value || true; + return fn; + }, + + createCache = function() { + var cache = {}, + keys = []; + + return markFunction(function( key, value ) { + // Only keep the most recent entries + if ( keys.push( key ) > Expr.cacheLength ) { + delete cache[ keys.shift() ]; + } + + return (cache[ key ] = value); + }, cache ); + }, + + classCache = createCache(), + tokenCache = createCache(), + compilerCache = createCache(), + + // Regex + + // Whitespace characters http://www.w3.org/TR/css3-selectors/#whitespace + whitespace = "[\\x20\\t\\r\\n\\f]", + // http://www.w3.org/TR/css3-syntax/#characters + characterEncoding = "(?:\\\\.|[-\\w]|[^\\x00-\\xa0])+", + + // Loosely modeled on CSS identifier characters + // An unquoted value should be a CSS identifier (http://www.w3.org/TR/css3-selectors/#attribute-selectors) + // Proper syntax: http://www.w3.org/TR/CSS21/syndata.html#value-def-identifier + identifier = characterEncoding.replace( "w", "w#" ), + + // Acceptable operators http://www.w3.org/TR/selectors/#attribute-selectors + operators = "([*^$|!~]?=)", + attributes = "\\[" + whitespace + "*(" + characterEncoding + ")" + whitespace + + "*(?:" + operators + whitespace + "*(?:(['\"])((?:\\\\.|[^\\\\])*?)\\3|(" + identifier + ")|)|)" + whitespace + "*\\]", + + // Prefer arguments not in parens/brackets, + // then attribute selectors and non-pseudos (denoted by :), + // then anything else + // These preferences are here to reduce the number of selectors + // needing tokenize in the PSEUDO preFilter + pseudos = ":(" + characterEncoding + ")(?:\\((?:(['\"])((?:\\\\.|[^\\\\])*?)\\2|([^()[\\]]*|(?:(?:" + attributes + ")|[^:]|\\\\.)*|.*))\\)|)", + + // For matchExpr.POS and matchExpr.needsContext + pos = ":(nth|eq|gt|lt|first|last|even|odd)(?:\\(((?:-\\d)?\\d*)\\)|)(?=[^-]|$)", + + // Leading and non-escaped trailing whitespace, capturing some non-whitespace characters preceding the latter + rtrim = new RegExp( "^" + whitespace + "+|((?:^|[^\\\\])(?:\\\\.)*)" + whitespace + "+$", "g" ), + + rcomma = new RegExp( "^" + whitespace + "*," + whitespace + "*" ), + rcombinators = new RegExp( "^" + whitespace + "*([\\x20\\t\\r\\n\\f>+~])" + whitespace + "*" ), + rpseudo = new RegExp( pseudos ), + + // Easily-parseable/retrievable ID or TAG or CLASS selectors + rquickExpr = /^(?:#([\w\-]+)|(\w+)|\.([\w\-]+))$/, + + rnot = /^:not/, + rsibling = /[\x20\t\r\n\f]*[+~]/, + rendsWithNot = /:not\($/, + + rheader = /h\d/i, + rinputs = /input|select|textarea|button/i, + + rbackslash = /\\(?!\\)/g, + + matchExpr = { + "ID": new RegExp( "^#(" + characterEncoding + ")" ), + "CLASS": new RegExp( "^\\.(" + characterEncoding + ")" ), + "NAME": new RegExp( "^\\[name=['\"]?(" + characterEncoding + ")['\"]?\\]" ), + "TAG": new RegExp( "^(" + characterEncoding.replace( "w", "w*" ) + ")" ), + "ATTR": new RegExp( "^" + attributes ), + "PSEUDO": new RegExp( "^" + pseudos ), + "CHILD": new RegExp( "^:(only|nth|last|first)-child(?:\\(" + whitespace + + "*(even|odd|(([+-]|)(\\d*)n|)" + whitespace + "*(?:([+-]|)" + whitespace + + "*(\\d+)|))" + whitespace + "*\\)|)", "i" ), + "POS": new RegExp( pos, "ig" ), + // For use in libraries implementing .is() + "needsContext": new RegExp( "^" + whitespace + "*[>+~]|" + pos, "i" ) + }, + + // Support + + // Used for testing something on an element + assert = function( fn ) { + var div = document.createElement("div"); + + try { + return fn( div ); + } catch (e) { + return false; + } finally { + // release memory in IE + div = null; + } + }, + + // Check if getElementsByTagName("*") returns only elements + assertTagNameNoComments = assert(function( div ) { + div.appendChild( document.createComment("") ); + return !div.getElementsByTagName("*").length; + }), + + // Check if getAttribute returns normalized href attributes + assertHrefNotNormalized = assert(function( div ) { + div.innerHTML = ""; + return div.firstChild && typeof div.firstChild.getAttribute !== strundefined && + div.firstChild.getAttribute("href") === "#"; + }), + + // Check if attributes should be retrieved by attribute nodes + assertAttributes = assert(function( div ) { + div.innerHTML = ""; + var type = typeof div.lastChild.getAttribute("multiple"); + // IE8 returns a string for some attributes even when not present + return type !== "boolean" && type !== "string"; + }), + + // Check if getElementsByClassName can be trusted + assertUsableClassName = assert(function( div ) { + // Opera can't find a second classname (in 9.6) + div.innerHTML = ""; + if ( !div.getElementsByClassName || !div.getElementsByClassName("e").length ) { + return false; + } + + // Safari 3.2 caches class attributes and doesn't catch changes + div.lastChild.className = "e"; + return div.getElementsByClassName("e").length === 2; + }), + + // Check if getElementById returns elements by name + // Check if getElementsByName privileges form controls or returns elements by ID + assertUsableName = assert(function( div ) { + // Inject content + div.id = expando + 0; + div.innerHTML = "
      "; + docElem.insertBefore( div, docElem.firstChild ); + + // Test + var pass = document.getElementsByName && + // buggy browsers will return fewer than the correct 2 + document.getElementsByName( expando ).length === 2 + + // buggy browsers will return more than the correct 0 + document.getElementsByName( expando + 0 ).length; + assertGetIdNotName = !document.getElementById( expando ); + + // Cleanup + docElem.removeChild( div ); + + return pass; + }); + +// If slice is not available, provide a backup +try { + slice.call( docElem.childNodes, 0 )[0].nodeType; +} catch ( e ) { + slice = function( i ) { + var elem, results = []; + for ( ; (elem = this[i]); i++ ) { + results.push( elem ); + } + return results; + }; +} + +function Sizzle( selector, context, results, seed ) { + results = results || []; + context = context || document; + var match, elem, xml, m, + nodeType = context.nodeType; + + if ( nodeType !== 1 && nodeType !== 9 ) { + return []; + } + + if ( !selector || typeof selector !== "string" ) { + return results; + } + + xml = isXML( context ); + + if ( !xml && !seed ) { + if ( (match = rquickExpr.exec( selector )) ) { + // Speed-up: Sizzle("#ID") + if ( (m = match[1]) ) { + if ( nodeType === 9 ) { + elem = context.getElementById( m ); + // 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, Opera, and Webkit return items + // by name instead of ID + if ( elem.id === m ) { + results.push( elem ); + return results; + } + } else { + return results; + } + } else { + // Context is not a document + if ( context.ownerDocument && (elem = context.ownerDocument.getElementById( m )) && + contains( context, elem ) && elem.id === m ) { + results.push( elem ); + return results; + } + } + + // Speed-up: Sizzle("TAG") + } else if ( match[2] ) { + push.apply( results, slice.call(context.getElementsByTagName( selector ), 0) ); + return results; + + // Speed-up: Sizzle(".CLASS") + } else if ( (m = match[3]) && assertUsableClassName && context.getElementsByClassName ) { + push.apply( results, slice.call(context.getElementsByClassName( m ), 0) ); + return results; + } + } + } + + // All others + return select( selector, context, results, seed, xml ); +} + +Sizzle.matches = function( expr, elements ) { + return Sizzle( expr, null, null, elements ); +}; + +Sizzle.matchesSelector = function( elem, expr ) { + return Sizzle( expr, null, null, [ elem ] ).length > 0; +}; + +// Returns a function to use in pseudos for input types +function createInputPseudo( type ) { + return function( elem ) { + var name = elem.nodeName.toLowerCase(); + return name === "input" && elem.type === type; + }; +} + +// Returns a function to use in pseudos for buttons +function createButtonPseudo( type ) { + return function( elem ) { + var name = elem.nodeName.toLowerCase(); + return (name === "input" || name === "button") && elem.type === type; + }; +} + +/** + * Utility function for retrieving the text value of an array of DOM nodes + * @param {Array|Element} elem + */ +getText = Sizzle.getText = function( elem ) { + var node, + ret = "", + i = 0, + nodeType = elem.nodeType; + + if ( nodeType ) { + if ( nodeType === 1 || nodeType === 9 || nodeType === 11 ) { + // Use textContent for elements + // innerText usage removed for consistency of new lines (see #11153) + if ( typeof elem.textContent === "string" ) { + return elem.textContent; + } else { + // Traverse its children + for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) { + ret += getText( elem ); + } + } + } else if ( nodeType === 3 || nodeType === 4 ) { + return elem.nodeValue; + } + // Do not include comment or processing instruction nodes + } else { + + // If no nodeType, this is expected to be an array + for ( ; (node = elem[i]); i++ ) { + // Do not traverse comment nodes + ret += getText( node ); + } + } + return ret; +}; + +isXML = Sizzle.isXML = function isXML( 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).documentElement; + return documentElement ? documentElement.nodeName !== "HTML" : false; +}; + +// Element contains another +contains = Sizzle.contains = docElem.contains ? + function( a, b ) { + var adown = a.nodeType === 9 ? a.documentElement : a, + bup = b && b.parentNode; + return a === bup || !!( bup && bup.nodeType === 1 && adown.contains && adown.contains(bup) ); + } : + docElem.compareDocumentPosition ? + function( a, b ) { + return b && !!( a.compareDocumentPosition( b ) & 16 ); + } : + function( a, b ) { + while ( (b = b.parentNode) ) { + if ( b === a ) { + return true; + } + } + return false; + }; + +Sizzle.attr = function( elem, name ) { + var attr, + xml = isXML( elem ); + + if ( !xml ) { + name = name.toLowerCase(); + } + if ( Expr.attrHandle[ name ] ) { + return Expr.attrHandle[ name ]( elem ); + } + if ( assertAttributes || xml ) { + return elem.getAttribute( name ); + } + attr = elem.getAttributeNode( name ); + return attr ? + typeof elem[ name ] === "boolean" ? + elem[ name ] ? name : null : + attr.specified ? attr.value : null : + null; +}; + +Expr = Sizzle.selectors = { + + // Can be adjusted by the user + cacheLength: 50, + + createPseudo: markFunction, + + match: matchExpr, + + order: new RegExp( "ID|TAG" + + (assertUsableName ? "|NAME" : "") + + (assertUsableClassName ? "|CLASS" : "") + ), + + // IE6/7 return a modified href + attrHandle: assertHrefNotNormalized ? + {} : + { + "href": function( elem ) { + return elem.getAttribute( "href", 2 ); + }, + "type": function( elem ) { + return elem.getAttribute("type"); + } + }, + + find: { + "ID": assertGetIdNotName ? + function( id, context, xml ) { + if ( typeof context.getElementById !== strundefined && !xml ) { + var m = context.getElementById( id ); + // Check parentNode to catch when Blackberry 4.6 returns + // nodes that are no longer in the document #6963 + return m && m.parentNode ? [m] : []; + } + } : + function( id, context, xml ) { + if ( typeof context.getElementById !== strundefined && !xml ) { + var m = context.getElementById( id ); + + return m ? + m.id === id || typeof m.getAttributeNode !== strundefined && m.getAttributeNode("id").value === id ? + [m] : + undefined : + []; + } + }, + + "TAG": assertTagNameNoComments ? + function( tag, context ) { + if ( typeof context.getElementsByTagName !== strundefined ) { + return context.getElementsByTagName( tag ); + } + } : + function( tag, context ) { + var results = context.getElementsByTagName( tag ); + + // Filter out possible comments + if ( tag === "*" ) { + var elem, + tmp = [], + i = 0; + + for ( ; (elem = results[i]); i++ ) { + if ( elem.nodeType === 1 ) { + tmp.push( elem ); + } + } + + return tmp; + } + return results; + }, + + "NAME": function( tag, context ) { + if ( typeof context.getElementsByName !== strundefined ) { + return context.getElementsByName( name ); + } + }, + + "CLASS": function( className, context, xml ) { + if ( typeof context.getElementsByClassName !== strundefined && !xml ) { + return context.getElementsByClassName( className ); + } + } + }, + + relative: { + ">": { dir: "parentNode", first: true }, + " ": { dir: "parentNode" }, + "+": { dir: "previousSibling", first: true }, + "~": { dir: "previousSibling" } + }, + + preFilter: { + "ATTR": function( match ) { + match[1] = match[1].replace( rbackslash, "" ); + + // Move the given value to match[3] whether quoted or unquoted + match[3] = ( match[4] || match[5] || "" ).replace( rbackslash, "" ); + + if ( match[2] === "~=" ) { + match[3] = " " + match[3] + " "; + } + + return match.slice( 0, 4 ); + }, + + "CHILD": function( match ) { + /* matches from matchExpr.CHILD + 1 type (only|nth|...) + 2 argument (even|odd|\d*|\d*n([+-]\d+)?|...) + 3 xn-component of xn+y argument ([+-]?\d*n|) + 4 sign of xn-component + 5 x of xn-component + 6 sign of y-component + 7 y of y-component + */ + match[1] = match[1].toLowerCase(); + + if ( match[1] === "nth" ) { + // nth-child requires argument + if ( !match[2] ) { + Sizzle.error( match[0] ); + } + + // numeric x and y parameters for Expr.filter.CHILD + // remember that false/true cast respectively to 0/1 + match[3] = +( match[3] ? match[4] + (match[5] || 1) : 2 * ( match[2] === "even" || match[2] === "odd" ) ); + match[4] = +( ( match[6] + match[7] ) || match[2] === "odd" ); + + // other types prohibit arguments + } else if ( match[2] ) { + Sizzle.error( match[0] ); + } + + return match; + }, + + "PSEUDO": function( match, context, xml ) { + var unquoted, excess; + if ( matchExpr["CHILD"].test( match[0] ) ) { + return null; + } + + if ( match[3] ) { + match[2] = match[3]; + } else if ( (unquoted = match[4]) ) { + // Only check arguments that contain a pseudo + if ( rpseudo.test(unquoted) && + // Get excess from tokenize (recursively) + (excess = tokenize( unquoted, context, xml, true )) && + // advance to the next closing parenthesis + (excess = unquoted.indexOf( ")", unquoted.length - excess ) - unquoted.length) ) { + + // excess is a negative index + unquoted = unquoted.slice( 0, excess ); + match[0] = match[0].slice( 0, excess ); + } + match[2] = unquoted; + } + + // Return only captures needed by the pseudo filter method (type and argument) + return match.slice( 0, 3 ); + } + }, + + filter: { + "ID": assertGetIdNotName ? + function( id ) { + id = id.replace( rbackslash, "" ); + return function( elem ) { + return elem.getAttribute("id") === id; + }; + } : + function( id ) { + id = id.replace( rbackslash, "" ); + return function( elem ) { + var node = typeof elem.getAttributeNode !== strundefined && elem.getAttributeNode("id"); + return node && node.value === id; + }; + }, + + "TAG": function( nodeName ) { + if ( nodeName === "*" ) { + return function() { return true; }; + } + nodeName = nodeName.replace( rbackslash, "" ).toLowerCase(); + + return function( elem ) { + return elem.nodeName && elem.nodeName.toLowerCase() === nodeName; + }; + }, + + "CLASS": function( className ) { + var pattern = classCache[ expando ][ className ]; + if ( !pattern ) { + pattern = classCache( className, new RegExp("(^|" + whitespace + ")" + className + "(" + whitespace + "|$)") ); + } + return function( elem ) { + return pattern.test( elem.className || (typeof elem.getAttribute !== strundefined && elem.getAttribute("class")) || "" ); + }; + }, + + "ATTR": function( name, operator, check ) { + if ( !operator ) { + return function( elem ) { + return Sizzle.attr( elem, name ) != null; + }; + } + + return function( elem ) { + var result = Sizzle.attr( elem, name ), + value = result + ""; + + if ( result == null ) { + return operator === "!="; + } + + switch ( operator ) { + case "=": + return value === check; + case "!=": + return value !== check; + case "^=": + return check && value.indexOf( check ) === 0; + case "*=": + return check && value.indexOf( check ) > -1; + case "$=": + return check && value.substr( value.length - check.length ) === check; + case "~=": + return ( " " + value + " " ).indexOf( check ) > -1; + case "|=": + return value === check || value.substr( 0, check.length + 1 ) === check + "-"; + } + }; + }, + + "CHILD": function( type, argument, first, last ) { + + if ( type === "nth" ) { + var doneName = done++; + + return function( elem ) { + var parent, diff, + count = 0, + node = elem; + + if ( first === 1 && last === 0 ) { + return true; + } + + parent = elem.parentNode; + + if ( parent && (parent[ expando ] !== doneName || !elem.sizset) ) { + for ( node = parent.firstChild; node; node = node.nextSibling ) { + if ( node.nodeType === 1 ) { + node.sizset = ++count; + if ( node === elem ) { + break; + } + } + } + + parent[ expando ] = doneName; + } + + diff = elem.sizset - last; + + if ( first === 0 ) { + return diff === 0; + + } else { + return ( diff % first === 0 && diff / first >= 0 ); + } + }; + } + + return function( elem ) { + var 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; + + /* falls through */ + case "last": + while ( (node = node.nextSibling) ) { + if ( node.nodeType === 1 ) { + return false; + } + } + + return true; + } + }; + }, + + "PSEUDO": function( pseudo, argument, context, xml ) { + // pseudo-class names are case-insensitive + // http://www.w3.org/TR/selectors/#pseudo-classes + // Prioritize by case sensitivity in case custom pseudos are added with uppercase letters + var args, + fn = Expr.pseudos[ pseudo ] || Expr.pseudos[ pseudo.toLowerCase() ]; + + if ( !fn ) { + Sizzle.error( "unsupported pseudo: " + pseudo ); + } + + // The user may use createPseudo to indicate that + // arguments are needed to create the filter function + // just as Sizzle does + if ( !fn[ expando ] ) { + if ( fn.length > 1 ) { + args = [ pseudo, pseudo, "", argument ]; + return function( elem ) { + return fn( elem, 0, args ); + }; + } + return fn; + } + + return fn( argument, context, xml ); + } + }, + + pseudos: { + "not": markFunction(function( selector, context, xml ) { + // Trim the selector passed to compile + // to avoid treating leading and trailing + // spaces as combinators + var matcher = compile( selector.replace( rtrim, "$1" ), context, xml ); + return function( elem ) { + return !matcher( elem ); + }; + }), + + "enabled": function( elem ) { + return elem.disabled === false; + }, + + "disabled": function( elem ) { + return elem.disabled === true; + }, + + "checked": function( elem ) { + // In CSS3, :checked should return both checked and selected elements + // http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked + var nodeName = elem.nodeName.toLowerCase(); + return (nodeName === "input" && !!elem.checked) || (nodeName === "option" && !!elem.selected); + }, + + "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 !Expr.pseudos["empty"]( elem ); + }, + + "empty": function( elem ) { + // http://www.w3.org/TR/selectors/#empty-pseudo + // :empty is only affected by element nodes and content nodes(including text(3), cdata(4)), + // not comment, processing instructions, or others + // Thanks to Diego Perini for the nodeName shortcut + // Greater than "@" means alpha characters (specifically not starting with "#" or "?") + var nodeType; + elem = elem.firstChild; + while ( elem ) { + if ( elem.nodeName > "@" || (nodeType = elem.nodeType) === 3 || nodeType === 4 ) { + return false; + } + elem = elem.nextSibling; + } + return true; + }, + + "contains": markFunction(function( text ) { + return function( elem ) { + return ( elem.textContent || elem.innerText || getText( elem ) ).indexOf( text ) > -1; + }; + }), + + "has": markFunction(function( selector ) { + return function( elem ) { + return Sizzle( selector, elem ).length > 0; + }; + }), + + "header": function( elem ) { + return rheader.test( elem.nodeName ); + }, + + "text": function( elem ) { + var type, attr; + // 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" && + (type = elem.type) === "text" && + ( (attr = elem.getAttribute("type")) == null || attr.toLowerCase() === type ); + }, + + // Input types + "radio": createInputPseudo("radio"), + "checkbox": createInputPseudo("checkbox"), + "file": createInputPseudo("file"), + "password": createInputPseudo("password"), + "image": createInputPseudo("image"), + + "submit": createButtonPseudo("submit"), + "reset": createButtonPseudo("reset"), + + "button": function( elem ) { + var name = elem.nodeName.toLowerCase(); + return name === "input" && elem.type === "button" || name === "button"; + }, + + "input": function( elem ) { + return rinputs.test( elem.nodeName ); + }, + + "focus": function( elem ) { + var doc = elem.ownerDocument; + return elem === doc.activeElement && (!doc.hasFocus || doc.hasFocus()) && !!(elem.type || elem.href); + }, + + "active": function( elem ) { + return elem === elem.ownerDocument.activeElement; + } + }, + + setFilters: { + "first": function( elements, argument, not ) { + return not ? elements.slice( 1 ) : [ elements[0] ]; + }, + + "last": function( elements, argument, not ) { + var elem = elements.pop(); + return not ? elements : [ elem ]; + }, + + "even": function( elements, argument, not ) { + var results = [], + i = not ? 1 : 0, + len = elements.length; + for ( ; i < len; i = i + 2 ) { + results.push( elements[i] ); + } + return results; + }, + + "odd": function( elements, argument, not ) { + var results = [], + i = not ? 0 : 1, + len = elements.length; + for ( ; i < len; i = i + 2 ) { + results.push( elements[i] ); + } + return results; + }, + + "lt": function( elements, argument, not ) { + return not ? elements.slice( +argument ) : elements.slice( 0, +argument ); + }, + + "gt": function( elements, argument, not ) { + return not ? elements.slice( 0, +argument + 1 ) : elements.slice( +argument + 1 ); + }, + + "eq": function( elements, argument, not ) { + var elem = elements.splice( +argument, 1 ); + return not ? elements : elem; + } + } +}; + +function siblingCheck( a, b, ret ) { + if ( a === b ) { + return ret; + } + + var cur = a.nextSibling; + + while ( cur ) { + if ( cur === b ) { + return -1; + } + + cur = cur.nextSibling; + } + + return 1; +} + +sortOrder = docElem.compareDocumentPosition ? + function( a, b ) { + if ( a === b ) { + hasDuplicate = true; + return 0; + } + + return ( !a.compareDocumentPosition || !b.compareDocumentPosition ? + a.compareDocumentPosition : + a.compareDocumentPosition(b) & 4 + ) ? -1 : 1; + } : + 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 ); + }; + +// Always assume the presence of duplicates if sort doesn't +// pass them to our comparison function (as in Google Chrome). +[0, 0].sort( sortOrder ); +baseHasDuplicate = !hasDuplicate; + +// Document sorting and removing duplicates +Sizzle.uniqueSort = function( results ) { + var elem, + i = 1; + + hasDuplicate = baseHasDuplicate; + results.sort( sortOrder ); + + if ( hasDuplicate ) { + for ( ; (elem = results[i]); i++ ) { + if ( elem === results[ i - 1 ] ) { + results.splice( i--, 1 ); + } + } + } + + return results; +}; + +Sizzle.error = function( msg ) { + throw new Error( "Syntax error, unrecognized expression: " + msg ); +}; + +function tokenize( selector, context, xml, parseOnly ) { + var matched, match, tokens, type, + soFar, groups, group, i, + preFilters, filters, + checkContext = !xml && context !== document, + // Token cache should maintain spaces + key = ( checkContext ? "" : "" ) + selector.replace( rtrim, "$1" ), + cached = tokenCache[ expando ][ key ]; + + if ( cached ) { + return parseOnly ? 0 : slice.call( cached, 0 ); + } + + soFar = selector; + groups = []; + i = 0; + preFilters = Expr.preFilter; + filters = Expr.filter; + + while ( soFar ) { + + // Comma and first run + if ( !matched || (match = rcomma.exec( soFar )) ) { + if ( match ) { + soFar = soFar.slice( match[0].length ); + tokens.selector = group; + } + groups.push( tokens = [] ); + group = ""; + + // Need to make sure we're within a narrower context if necessary + // Adding a descendant combinator will generate what is needed + if ( checkContext ) { + soFar = " " + soFar; + } + } + + matched = false; + + // Combinators + if ( (match = rcombinators.exec( soFar )) ) { + group += match[0]; + soFar = soFar.slice( match[0].length ); + + // Cast descendant combinators to space + matched = tokens.push({ + part: match.pop().replace( rtrim, " " ), + string: match[0], + captures: match + }); + } + + // Filters + for ( type in filters ) { + if ( (match = matchExpr[ type ].exec( soFar )) && (!preFilters[ type ] || + ( match = preFilters[ type ](match, context, xml) )) ) { + + group += match[0]; + soFar = soFar.slice( match[0].length ); + matched = tokens.push({ + part: type, + string: match.shift(), + captures: match + }); + } + } + + if ( !matched ) { + break; + } + } + + // Attach the full group as a selector + if ( group ) { + tokens.selector = group; + } + + // Return the length of the invalid excess + // if we're just parsing + // Otherwise, throw an error or return tokens + return parseOnly ? + soFar.length : + soFar ? + Sizzle.error( selector ) : + // Cache the tokens + slice.call( tokenCache(key, groups), 0 ); +} + +function addCombinator( matcher, combinator, context, xml ) { + var dir = combinator.dir, + doneName = done++; + + if ( !matcher ) { + // If there is no matcher to check, check against the context + matcher = function( elem ) { + return elem === context; + }; + } + return combinator.first ? + function( elem ) { + while ( (elem = elem[ dir ]) ) { + if ( elem.nodeType === 1 ) { + return matcher( elem ) && elem; + } + } + } : + xml ? + function( elem ) { + while ( (elem = elem[ dir ]) ) { + if ( elem.nodeType === 1 ) { + if ( matcher( elem ) ) { + return elem; + } + } + } + } : + function( elem ) { + var cache, + dirkey = doneName + "." + dirruns, + cachedkey = dirkey + "." + cachedruns; + while ( (elem = elem[ dir ]) ) { + if ( elem.nodeType === 1 ) { + if ( (cache = elem[ expando ]) === cachedkey ) { + return elem.sizset; + } else if ( typeof cache === "string" && cache.indexOf(dirkey) === 0 ) { + if ( elem.sizset ) { + return elem; + } + } else { + elem[ expando ] = cachedkey; + if ( matcher( elem ) ) { + elem.sizset = true; + return elem; + } + elem.sizset = false; + } + } + } + }; +} + +function addMatcher( higher, deeper ) { + return higher ? + function( elem ) { + var result = deeper( elem ); + return result && higher( result === true ? elem : result ); + } : + deeper; +} + +// ["TAG", ">", "ID", " ", "CLASS"] +function matcherFromTokens( tokens, context, xml ) { + var token, matcher, + i = 0; + + for ( ; (token = tokens[i]); i++ ) { + if ( Expr.relative[ token.part ] ) { + matcher = addCombinator( matcher, Expr.relative[ token.part ], context, xml ); + } else { + matcher = addMatcher( matcher, Expr.filter[ token.part ].apply(null, token.captures.concat( context, xml )) ); + } + } + + return matcher; +} + +function matcherFromGroupMatchers( matchers ) { + return function( elem ) { + var matcher, + j = 0; + for ( ; (matcher = matchers[j]); j++ ) { + if ( matcher(elem) ) { + return true; + } + } + return false; + }; +} + +compile = Sizzle.compile = function( selector, context, xml ) { + var group, i, len, + cached = compilerCache[ expando ][ selector ]; + + // Return a cached group function if already generated (context dependent) + if ( cached && cached.context === context ) { + return cached; + } + + // Generate a function of recursive functions that can be used to check each element + group = tokenize( selector, context, xml ); + for ( i = 0, len = group.length; i < len; i++ ) { + group[i] = matcherFromTokens(group[i], context, xml); + } + + // Cache the compiled function + cached = compilerCache( selector, matcherFromGroupMatchers(group) ); + cached.context = context; + cached.runs = cached.dirruns = 0; + return cached; +}; + +function multipleContexts( selector, contexts, results, seed ) { + var i = 0, + len = contexts.length; + for ( ; i < len; i++ ) { + Sizzle( selector, contexts[i], results, seed ); + } +} + +function handlePOSGroup( selector, posfilter, argument, contexts, seed, not ) { + var results, + fn = Expr.setFilters[ posfilter.toLowerCase() ]; + + if ( !fn ) { + Sizzle.error( posfilter ); + } + + if ( selector || !(results = seed) ) { + multipleContexts( selector || "*", contexts, (results = []), seed ); + } + + return results.length > 0 ? fn( results, argument, not ) : []; +} + +function handlePOS( groups, context, results, seed ) { + var group, part, j, groupLen, token, selector, + anchor, elements, match, matched, + lastIndex, currentContexts, not, + i = 0, + len = groups.length, + rpos = matchExpr["POS"], + // This is generated here in case matchExpr["POS"] is extended + rposgroups = new RegExp( "^" + rpos.source + "(?!" + whitespace + ")", "i" ), + // This is for making sure non-participating + // matching groups are represented cross-browser (IE6-8) + setUndefined = function() { + var i = 1, + len = arguments.length - 2; + for ( ; i < len; i++ ) { + if ( arguments[i] === undefined ) { + match[i] = undefined; + } + } + }; + + for ( ; i < len; i++ ) { + group = groups[i]; + part = ""; + elements = seed; + for ( j = 0, groupLen = group.length; j < groupLen; j++ ) { + token = group[j]; + selector = token.string; + if ( token.part === "PSEUDO" ) { + // Reset regex index to 0 + rpos.exec(""); + anchor = 0; + while ( (match = rpos.exec( selector )) ) { + matched = true; + lastIndex = rpos.lastIndex = match.index + match[0].length; + if ( lastIndex > anchor ) { + part += selector.slice( anchor, match.index ); + anchor = lastIndex; + currentContexts = [ context ]; + + if ( rcombinators.test(part) ) { + if ( elements ) { + currentContexts = elements; + } + elements = seed; + } + + if ( (not = rendsWithNot.test( part )) ) { + part = part.slice( 0, -5 ).replace( rcombinators, "$&*" ); + anchor++; + } + + if ( match.length > 1 ) { + match[0].replace( rposgroups, setUndefined ); + } + elements = handlePOSGroup( part, match[1], match[2], currentContexts, elements, not ); + } + part = ""; + } + + } + + if ( !matched ) { + part += selector; + } + matched = false; + } + + if ( part ) { + if ( rcombinators.test(part) ) { + multipleContexts( part, elements || [ context ], results, seed ); + } else { + Sizzle( part, context, results, seed ? seed.concat(elements) : elements ); + } + } else { + push.apply( results, elements ); + } + } + + // Do not sort if this is a single filter + return len === 1 ? results : Sizzle.uniqueSort( results ); +} + +function select( selector, context, results, seed, xml ) { + // Remove excessive whitespace + selector = selector.replace( rtrim, "$1" ); + var elements, matcher, cached, elem, + i, tokens, token, lastToken, findContext, type, + match = tokenize( selector, context, xml ), + contextNodeType = context.nodeType; + + // POS handling + if ( matchExpr["POS"].test(selector) ) { + return handlePOS( match, context, results, seed ); + } + + if ( seed ) { + elements = slice.call( seed, 0 ); + + // To maintain document order, only narrow the + // set if there is one group + } else if ( match.length === 1 ) { + + // Take a shortcut and set the context if the root selector is an ID + if ( (tokens = slice.call( match[0], 0 )).length > 2 && + (token = tokens[0]).part === "ID" && + contextNodeType === 9 && !xml && + Expr.relative[ tokens[1].part ] ) { + + context = Expr.find["ID"]( token.captures[0].replace( rbackslash, "" ), context, xml )[0]; + if ( !context ) { + return results; + } + + selector = selector.slice( tokens.shift().string.length ); + } + + findContext = ( (match = rsibling.exec( tokens[0].string )) && !match.index && context.parentNode ) || context; + + // Reduce the set if possible + lastToken = ""; + for ( i = tokens.length - 1; i >= 0; i-- ) { + token = tokens[i]; + type = token.part; + lastToken = token.string + lastToken; + if ( Expr.relative[ type ] ) { + break; + } + if ( Expr.order.test(type) ) { + elements = Expr.find[ type ]( token.captures[0].replace( rbackslash, "" ), findContext, xml ); + if ( elements == null ) { + continue; + } else { + selector = selector.slice( 0, selector.length - lastToken.length ) + + lastToken.replace( matchExpr[ type ], "" ); + + if ( !selector ) { + push.apply( results, slice.call(elements, 0) ); + } + + break; + } + } + } + } + + // Only loop over the given elements once + if ( selector ) { + matcher = compile( selector, context, xml ); + dirruns = matcher.dirruns++; + if ( elements == null ) { + elements = Expr.find["TAG"]( "*", (rsibling.test( selector ) && context.parentNode) || context ); + } + + for ( i = 0; (elem = elements[i]); i++ ) { + cachedruns = matcher.runs++; + if ( matcher(elem) ) { + results.push( elem ); + } + } + } + + return results; +} + +if ( document.querySelectorAll ) { + (function() { + var disconnectedMatch, + oldSelect = select, + rescape = /'|\\/g, + rattributeQuotes = /\=[\x20\t\r\n\f]*([^'"\]]*)[\x20\t\r\n\f]*\]/g, + rbuggyQSA = [], + // matchesSelector(:active) reports false when true (IE9/Opera 11.5) + // A support test would require too much code (would include document ready) + // just skip matchesSelector for :active + rbuggyMatches = [":active"], + matches = docElem.matchesSelector || + docElem.mozMatchesSelector || + docElem.webkitMatchesSelector || + docElem.oMatchesSelector || + docElem.msMatchesSelector; + + // Build QSA regex + // Regex strategy adopted from Diego Perini + assert(function( div ) { + // Select is set to empty string on purpose + // This is to test IE's treatment of not explictly + // setting a boolean content attribute, + // since its presence should be enough + // http://bugs.jquery.com/ticket/12359 + div.innerHTML = ""; + + // IE8 - Some boolean attributes are not treated correctly + if ( !div.querySelectorAll("[selected]").length ) { + rbuggyQSA.push( "\\[" + whitespace + "*(?:checked|disabled|ismap|multiple|readonly|selected|value)" ); + } + + // Webkit/Opera - :checked should return selected option elements + // http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked + // IE8 throws error here (do not put tests after this one) + if ( !div.querySelectorAll(":checked").length ) { + rbuggyQSA.push(":checked"); + } + }); + + assert(function( div ) { + + // Opera 10-12/IE9 - ^= $= *= and empty values + // Should not select anything + div.innerHTML = "

      "; + if ( div.querySelectorAll("[test^='']").length ) { + rbuggyQSA.push( "[*^$]=" + whitespace + "*(?:\"\"|'')" ); + } + + // FF 3.5 - :enabled/:disabled and hidden elements (hidden elements are still enabled) + // IE8 throws error here (do not put tests after this one) + div.innerHTML = ""; + if ( !div.querySelectorAll(":enabled").length ) { + rbuggyQSA.push(":enabled", ":disabled"); + } + }); + + rbuggyQSA = rbuggyQSA.length && new RegExp( rbuggyQSA.join("|") ); + + select = function( selector, context, results, seed, xml ) { + // Only use querySelectorAll when not filtering, + // when this is not xml, + // and when no QSA bugs apply + if ( !seed && !xml && (!rbuggyQSA || !rbuggyQSA.test( selector )) ) { + if ( context.nodeType === 9 ) { + try { + push.apply( results, slice.call(context.querySelectorAll( selector ), 0) ); + return results; + } 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 groups, i, len, + old = context.getAttribute("id"), + nid = old || expando, + newContext = rsibling.test( selector ) && context.parentNode || context; + + if ( old ) { + nid = nid.replace( rescape, "\\$&" ); + } else { + context.setAttribute( "id", nid ); + } + + groups = tokenize(selector, context, xml); + // Trailing space is unnecessary + // There is always a context check + nid = "[id='" + nid + "']"; + for ( i = 0, len = groups.length; i < len; i++ ) { + groups[i] = nid + groups[i].selector; + } + try { + push.apply( results, slice.call( newContext.querySelectorAll( + groups.join(",") + ), 0 ) ); + return results; + } catch(qsaError) { + } finally { + if ( !old ) { + context.removeAttribute("id"); + } + } + } + } + + return oldSelect( selector, context, results, seed, xml ); + }; + + if ( matches ) { + assert(function( div ) { + // Check to see if it's possible to do matchesSelector + // on a disconnected node (IE 9) + disconnectedMatch = matches.call( div, "div" ); + + // This should fail with an exception + // Gecko does not error, returns false instead + try { + matches.call( div, "[test!='']:sizzle" ); + rbuggyMatches.push( matchExpr["PSEUDO"].source, matchExpr["POS"].source, "!=" ); + } catch ( e ) {} + }); + + // rbuggyMatches always contains :active, so no need for a length check + rbuggyMatches = /* rbuggyMatches.length && */ new RegExp( rbuggyMatches.join("|") ); + + Sizzle.matchesSelector = function( elem, expr ) { + // Make sure that attribute selectors are quoted + expr = expr.replace( rattributeQuotes, "='$1']" ); + + // rbuggyMatches always contains :active, so no need for an existence check + if ( !isXML( elem ) && !rbuggyMatches.test( expr ) && (!rbuggyQSA || !rbuggyQSA.test( expr )) ) { + try { + var ret = matches.call( elem, 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 + elem.document && elem.document.nodeType !== 11 ) { + return ret; + } + } catch(e) {} + } + + return Sizzle( expr, null, null, [ elem ] ).length > 0; + }; + } + })(); +} + +// Deprecated +Expr.setFilters["nth"] = Expr.setFilters["eq"]; + +// Back-compat +Expr.filters = Expr.pseudos; + +// Override sizzle attribute retrieval +Sizzle.attr = jQuery.attr; +jQuery.find = Sizzle; +jQuery.expr = Sizzle.selectors; +jQuery.expr[":"] = jQuery.expr.pseudos; +jQuery.unique = Sizzle.uniqueSort; +jQuery.text = Sizzle.getText; +jQuery.isXMLDoc = Sizzle.isXML; +jQuery.contains = Sizzle.contains; + + +})( window ); +var runtil = /Until$/, + rparentsprev = /^(?:parents|prev(?:Until|All))/, + isSimple = /^.[^:#\[\.,]*$/, + rneedsContext = jQuery.expr.match.needsContext, + // 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 i, l, length, n, r, ret, + self = this; + + 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; + } + } + }); + } + + ret = this.pushStack( "", "find", selector ); + + 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 i, + targets = jQuery( target, this ), + len = targets.length; + + return this.filter(function() { + for ( i = 0; i < len; 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" ? + // If this is a positional/relative selector, check membership in the returned set + // so $("p:first").is("p:last") won't return true for a doc with two "p". + rneedsContext.test( selector ) ? + jQuery( selector, this.context ).index( this[0] ) >= 0 : + jQuery.filter( selector, this ).length > 0 : + this.filter( selector ).length > 0 ); + }, + + closest: function( selectors, context ) { + var cur, + i = 0, + l = this.length, + ret = [], + pos = rneedsContext.test( selectors ) || typeof selectors !== "string" ? + jQuery( selectors, context || this.context ) : + 0; + + for ( ; i < l; i++ ) { + cur = this[i]; + + while ( cur && cur.ownerDocument && cur !== context && cur.nodeType !== 11 ) { + if ( pos ? pos.index(cur) > -1 : jQuery.find.matchesSelector(cur, selectors) ) { + ret.push( cur ); + break; + } + cur = cur.parentNode; + } + } + + 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 ) { + + // No argument, return index in parent + if ( !elem ) { + return ( this[0] && this[0].parentNode ) ? this.prevAll().length : -1; + } + + // index in selector + if ( typeof elem === "string" ) { + return jQuery.inArray( this[0], jQuery( elem ) ); + } + + // 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 ) ); + }, + + addBack: function( selector ) { + return this.add( selector == null ? + this.prevObject : this.prevObject.filter(selector) + ); + } +}); + +jQuery.fn.andSelf = jQuery.fn.addBack; + +// 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; +} + +function sibling( cur, dir ) { + do { + cur = cur[ dir ]; + } while ( cur && cur.nodeType !== 1 ); + + return cur; +} + +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 sibling( elem, "nextSibling" ); + }, + prev: function( elem ) { + return sibling( elem, "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.merge( [], elem.childNodes ); + } +}, function( name, fn ) { + jQuery.fn[ name ] = function( until, selector ) { + var ret = jQuery.map( this, fn, until ); + + 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 && rparentsprev.test( name ) ) { + ret = ret.reverse(); + } + + return this.pushStack( ret, name, core_slice.call( arguments ).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; + }, + + 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; + }); +} +function createSafeFragment( document ) { + var list = nodeNames.split( "|" ), + safeFrag = document.createDocumentFragment(); + + if ( safeFrag.createElement ) { + while ( list.length ) { + safeFrag.createElement( + list.pop() + ); + } + } + return safeFrag; +} + +var nodeNames = "abbr|article|aside|audio|bdi|canvas|data|datalist|details|figcaption|figure|footer|" + + "header|hgroup|mark|meter|nav|output|progress|section|summary|time|video", + rinlinejQuery = / jQuery\d+="(?:null|\d+)"/g, + rleadingWhitespace = /^\s+/, + rxhtmlTag = /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/gi, + rtagName = /<([\w:]+)/, + rtbody = /]", "i"), + rcheckableType = /^(?:checkbox|radio)$/, + // checked="checked" or checked + rchecked = /checked\s*(?:[^=]|=\s*.checked.)/i, + rscriptType = /\/(java|ecma)script/i, + rcleanScript = /^\s*\s*$/g, + wrapMap = { + option: [ 1, "" ], + legend: [ 1, "
      ", "
      " ], + thead: [ 1, "", "
      " ], + tr: [ 2, "", "
      " ], + td: [ 3, "", "
      " ], + col: [ 2, "", "
      " ], + area: [ 1, "", "" ], + _default: [ 0, "", "" ] + }, + safeFragment = createSafeFragment( document ), + fragmentDiv = safeFragment.appendChild( document.createElement("div") ); + +wrapMap.optgroup = wrapMap.option; +wrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead; +wrapMap.th = wrapMap.td; + +// IE6-8 can't serialize link, script, style, or any html5 (NoScope) tags, +// unless wrapped in a div with non-breaking characters in front of it. +if ( !jQuery.support.htmlSerialize ) { + wrapMap._default = [ 1, "X
      ", "
      " ]; +} + +jQuery.fn.extend({ + text: function( value ) { + return jQuery.access( this, function( value ) { + return value === undefined ? + jQuery.text( this ) : + this.empty().append( ( this[0] && this[0].ownerDocument || document ).createTextNode( value ) ); + }, null, value, arguments.length ); + }, + + wrapAll: function( html ) { + if ( jQuery.isFunction( html ) ) { + return this.each(function(i) { + jQuery(this).wrapAll( html.call(this, i) ); + }); + } + + if ( this[0] ) { + // The elements to wrap the target around + var wrap = jQuery( html, this[0].ownerDocument ).eq(0).clone(true); + + if ( this[0].parentNode ) { + wrap.insertBefore( this[0] ); + } + + wrap.map(function() { + var elem = this; + + while ( elem.firstChild && elem.firstChild.nodeType === 1 ) { + elem = elem.firstChild; + } + + return elem; + }).append( this ); + } + + return this; + }, + + wrapInner: function( html ) { + if ( jQuery.isFunction( html ) ) { + return this.each(function(i) { + jQuery(this).wrapInner( html.call(this, i) ); + }); + } + + return this.each(function() { + var self = jQuery( this ), + contents = self.contents(); + + if ( contents.length ) { + contents.wrapAll( html ); + + } else { + self.append( html ); + } + }); + }, + + wrap: function( html ) { + var isFunction = jQuery.isFunction( html ); + + return this.each(function(i) { + jQuery( this ).wrapAll( isFunction ? html.call(this, i) : html ); + }); + }, + + unwrap: function() { + return this.parent().each(function() { + if ( !jQuery.nodeName( this, "body" ) ) { + jQuery( this ).replaceWith( this.childNodes ); + } + }).end(); + }, + + append: function() { + return this.domManip(arguments, true, function( elem ) { + if ( this.nodeType === 1 || this.nodeType === 11 ) { + this.appendChild( elem ); + } + }); + }, + + prepend: function() { + return this.domManip(arguments, true, function( elem ) { + if ( this.nodeType === 1 || this.nodeType === 11 ) { + this.insertBefore( elem, this.firstChild ); + } + }); + }, + + before: function() { + if ( !isDisconnected( this[0] ) ) { + return this.domManip(arguments, false, function( elem ) { + this.parentNode.insertBefore( elem, this ); + }); + } + + if ( arguments.length ) { + var set = jQuery.clean( arguments ); + return this.pushStack( jQuery.merge( set, this ), "before", this.selector ); + } + }, + + after: function() { + if ( !isDisconnected( this[0] ) ) { + return this.domManip(arguments, false, function( elem ) { + this.parentNode.insertBefore( elem, this.nextSibling ); + }); + } + + if ( arguments.length ) { + var set = jQuery.clean( arguments ); + return this.pushStack( jQuery.merge( this, set ), "after", this.selector ); + } + }, + + // keepData is for internal use only--do not document + remove: function( selector, keepData ) { + var elem, + i = 0; + + for ( ; (elem = this[i]) != null; i++ ) { + if ( !selector || jQuery.filter( selector, [ elem ] ).length ) { + if ( !keepData && elem.nodeType === 1 ) { + jQuery.cleanData( elem.getElementsByTagName("*") ); + jQuery.cleanData( [ elem ] ); + } + + if ( elem.parentNode ) { + elem.parentNode.removeChild( elem ); + } + } + } + + return this; + }, + + empty: function() { + var elem, + i = 0; + + for ( ; (elem = this[i]) != null; i++ ) { + // Remove element nodes and prevent memory leaks + if ( elem.nodeType === 1 ) { + jQuery.cleanData( elem.getElementsByTagName("*") ); + } + + // Remove any remaining nodes + while ( elem.firstChild ) { + elem.removeChild( elem.firstChild ); + } + } + + return this; + }, + + clone: function( dataAndEvents, deepDataAndEvents ) { + dataAndEvents = dataAndEvents == null ? false : dataAndEvents; + deepDataAndEvents = deepDataAndEvents == null ? dataAndEvents : deepDataAndEvents; + + return this.map( function () { + return jQuery.clone( this, dataAndEvents, deepDataAndEvents ); + }); + }, + + html: function( value ) { + return jQuery.access( this, function( value ) { + var elem = this[0] || {}, + i = 0, + l = this.length; + + if ( value === undefined ) { + return elem.nodeType === 1 ? + elem.innerHTML.replace( rinlinejQuery, "" ) : + undefined; + } + + // See if we can take a shortcut and just use innerHTML + if ( typeof value === "string" && !rnoInnerhtml.test( value ) && + ( jQuery.support.htmlSerialize || !rnoshimcache.test( value ) ) && + ( jQuery.support.leadingWhitespace || !rleadingWhitespace.test( value ) ) && + !wrapMap[ ( rtagName.exec( value ) || ["", ""] )[1].toLowerCase() ] ) { + + value = value.replace( rxhtmlTag, "<$1>" ); + + try { + for (; i < l; i++ ) { + // Remove element nodes and prevent memory leaks + elem = this[i] || {}; + if ( elem.nodeType === 1 ) { + jQuery.cleanData( elem.getElementsByTagName( "*" ) ); + elem.innerHTML = value; + } + } + + elem = 0; + + // If using innerHTML throws an exception, use the fallback method + } catch(e) {} + } + + if ( elem ) { + this.empty().append( value ); + } + }, null, value, arguments.length ); + }, + + replaceWith: function( value ) { + if ( !isDisconnected( this[0] ) ) { + // Make sure that the elements are removed from the DOM before they are inserted + // this can help fix replacing a parent with child elements + if ( jQuery.isFunction( value ) ) { + return this.each(function(i) { + var self = jQuery(this), old = self.html(); + self.replaceWith( value.call( this, i, old ) ); + }); + } + + if ( typeof value !== "string" ) { + value = jQuery( value ).detach(); + } + + return this.each(function() { + var next = this.nextSibling, + parent = this.parentNode; + + jQuery( this ).remove(); + + if ( next ) { + jQuery(next).before( value ); + } else { + jQuery(parent).append( value ); + } + }); + } + + return this.length ? + this.pushStack( jQuery(jQuery.isFunction(value) ? value() : value), "replaceWith", value ) : + this; + }, + + detach: function( selector ) { + return this.remove( selector, true ); + }, + + domManip: function( args, table, callback ) { + + // Flatten any nested arrays + args = [].concat.apply( [], args ); + + var results, first, fragment, iNoClone, + i = 0, + value = args[0], + scripts = [], + l = this.length; + + // We can't cloneNode fragments that contain checked, in WebKit + if ( !jQuery.support.checkClone && l > 1 && typeof value === "string" && rchecked.test( value ) ) { + return this.each(function() { + jQuery(this).domManip( args, table, callback ); + }); + } + + if ( jQuery.isFunction(value) ) { + return this.each(function(i) { + var self = jQuery(this); + args[0] = value.call( this, i, table ? self.html() : undefined ); + self.domManip( args, table, callback ); + }); + } + + if ( this[0] ) { + results = jQuery.buildFragment( args, this, scripts ); + fragment = results.fragment; + first = fragment.firstChild; + + if ( fragment.childNodes.length === 1 ) { + fragment = first; + } + + if ( first ) { + table = table && jQuery.nodeName( first, "tr" ); + + // Use the original fragment for the last item instead of the first because it can end up + // being emptied incorrectly in certain situations (#8070). + // Fragments from the fragment cache must always be cloned and never used in place. + for ( iNoClone = results.cacheable || l - 1; i < l; i++ ) { + callback.call( + table && jQuery.nodeName( this[i], "table" ) ? + findOrAppend( this[i], "tbody" ) : + this[i], + i === iNoClone ? + fragment : + jQuery.clone( fragment, true, true ) + ); + } + } + + // Fix #11809: Avoid leaking memory + fragment = first = null; + + if ( scripts.length ) { + jQuery.each( scripts, function( i, elem ) { + if ( elem.src ) { + if ( jQuery.ajax ) { + jQuery.ajax({ + url: elem.src, + type: "GET", + dataType: "script", + async: false, + global: false, + "throws": true + }); + } else { + jQuery.error("no ajax"); + } + } else { + jQuery.globalEval( ( elem.text || elem.textContent || elem.innerHTML || "" ).replace( rcleanScript, "" ) ); + } + + if ( elem.parentNode ) { + elem.parentNode.removeChild( elem ); + } + }); + } + } + + return this; + } +}); + +function findOrAppend( elem, tag ) { + return elem.getElementsByTagName( tag )[0] || elem.appendChild( elem.ownerDocument.createElement( tag ) ); +} + +function cloneCopyEvent( src, dest ) { + + if ( dest.nodeType !== 1 || !jQuery.hasData( src ) ) { + return; + } + + var type, i, l, + oldData = jQuery._data( src ), + curData = jQuery._data( dest, oldData ), + events = oldData.events; + + if ( events ) { + delete curData.handle; + curData.events = {}; + + for ( type in events ) { + for ( i = 0, l = events[ type ].length; i < l; i++ ) { + jQuery.event.add( dest, type, events[ type ][ i ] ); + } + } + } + + // make the cloned public data object a copy from the original + if ( curData.data ) { + curData.data = jQuery.extend( {}, curData.data ); + } +} + +function cloneFixAttributes( src, dest ) { + var nodeName; + + // We do not need to do anything for non-Elements + if ( dest.nodeType !== 1 ) { + return; + } + + // clearAttributes removes the attributes, which we don't want, + // but also removes the attachEvent events, which we *do* want + if ( dest.clearAttributes ) { + dest.clearAttributes(); + } + + // mergeAttributes, in contrast, only merges back on the + // original attributes, not the events + if ( dest.mergeAttributes ) { + dest.mergeAttributes( src ); + } + + nodeName = dest.nodeName.toLowerCase(); + + if ( nodeName === "object" ) { + // IE6-10 improperly clones children of object elements using classid. + // IE10 throws NoModificationAllowedError if parent is null, #12132. + if ( dest.parentNode ) { + dest.outerHTML = src.outerHTML; + } + + // This path appears unavoidable for IE9. When cloning an object + // element in IE9, the outerHTML strategy above is not sufficient. + // If the src has innerHTML and the destination does not, + // copy the src.innerHTML into the dest.innerHTML. #10324 + if ( jQuery.support.html5Clone && (src.innerHTML && !jQuery.trim(dest.innerHTML)) ) { + dest.innerHTML = src.innerHTML; + } + + } else if ( nodeName === "input" && rcheckableType.test( src.type ) ) { + // IE6-8 fails to persist the checked state of a cloned checkbox + // or radio button. Worse, IE6-7 fail to give the cloned element + // a checked appearance if the defaultChecked value isn't also set + + dest.defaultChecked = dest.checked = src.checked; + + // IE6-7 get confused and end up setting the value of a cloned + // checkbox/radio button to an empty string instead of "on" + if ( dest.value !== src.value ) { + dest.value = src.value; + } + + // IE6-8 fails to return the selected option to the default selected + // state when cloning options + } else if ( nodeName === "option" ) { + dest.selected = src.defaultSelected; + + // IE6-8 fails to set the defaultValue to the correct value when + // cloning other types of input fields + } else if ( nodeName === "input" || nodeName === "textarea" ) { + dest.defaultValue = src.defaultValue; + + // IE blanks contents when cloning scripts + } else if ( nodeName === "script" && dest.text !== src.text ) { + dest.text = src.text; + } + + // Event data gets referenced instead of copied if the expando + // gets copied too + dest.removeAttribute( jQuery.expando ); +} + +jQuery.buildFragment = function( args, context, scripts ) { + var fragment, cacheable, cachehit, + first = args[ 0 ]; + + // Set context from what may come in as undefined or a jQuery collection or a node + // Updated to fix #12266 where accessing context[0] could throw an exception in IE9/10 & + // also doubles as fix for #8950 where plain objects caused createDocumentFragment exception + context = context || document; + context = !context.nodeType && context[0] || context; + context = context.ownerDocument || context; + + // Only cache "small" (1/2 KB) HTML strings that are associated with the main document + // Cloning options loses the selected state, so don't cache them + // IE 6 doesn't like it when you put or elements in a fragment + // Also, WebKit does not clone 'checked' attributes on cloneNode, so don't cache + // Lastly, IE6,7,8 will not correctly reuse cached fragments that were created from unknown elems #10501 + if ( args.length === 1 && typeof first === "string" && first.length < 512 && context === document && + first.charAt(0) === "<" && !rnocache.test( first ) && + (jQuery.support.checkClone || !rchecked.test( first )) && + (jQuery.support.html5Clone || !rnoshimcache.test( first )) ) { + + // Mark cacheable and look for a hit + cacheable = true; + fragment = jQuery.fragments[ first ]; + cachehit = fragment !== undefined; + } + + if ( !fragment ) { + fragment = context.createDocumentFragment(); + jQuery.clean( args, context, fragment, scripts ); + + // Update the cache, but only store false + // unless this is a second parsing of the same content + if ( cacheable ) { + jQuery.fragments[ first ] = cachehit && fragment; + } + } + + return { fragment: fragment, cacheable: cacheable }; +}; + +jQuery.fragments = {}; + +jQuery.each({ + appendTo: "append", + prependTo: "prepend", + insertBefore: "before", + insertAfter: "after", + replaceAll: "replaceWith" +}, function( name, original ) { + jQuery.fn[ name ] = function( selector ) { + var elems, + i = 0, + ret = [], + insert = jQuery( selector ), + l = insert.length, + parent = this.length === 1 && this[0].parentNode; + + if ( (parent == null || parent && parent.nodeType === 11 && parent.childNodes.length === 1) && l === 1 ) { + insert[ original ]( this[0] ); + return this; + } else { + for ( ; i < l; i++ ) { + elems = ( i > 0 ? this.clone(true) : this ).get(); + jQuery( insert[i] )[ original ]( elems ); + ret = ret.concat( elems ); + } + + return this.pushStack( ret, name, insert.selector ); + } + }; +}); + +function getAll( elem ) { + if ( typeof elem.getElementsByTagName !== "undefined" ) { + return elem.getElementsByTagName( "*" ); + + } else if ( typeof elem.querySelectorAll !== "undefined" ) { + return elem.querySelectorAll( "*" ); + + } else { + return []; + } +} + +// Used in clean, fixes the defaultChecked property +function fixDefaultChecked( elem ) { + if ( rcheckableType.test( elem.type ) ) { + elem.defaultChecked = elem.checked; + } +} + +jQuery.extend({ + clone: function( elem, dataAndEvents, deepDataAndEvents ) { + var srcElements, + destElements, + i, + clone; + + if ( jQuery.support.html5Clone || jQuery.isXMLDoc(elem) || !rnoshimcache.test( "<" + elem.nodeName + ">" ) ) { + clone = elem.cloneNode( true ); + + // IE<=8 does not properly clone detached, unknown element nodes + } else { + fragmentDiv.innerHTML = elem.outerHTML; + fragmentDiv.removeChild( clone = fragmentDiv.firstChild ); + } + + if ( (!jQuery.support.noCloneEvent || !jQuery.support.noCloneChecked) && + (elem.nodeType === 1 || elem.nodeType === 11) && !jQuery.isXMLDoc(elem) ) { + // IE copies events bound via attachEvent when using cloneNode. + // Calling detachEvent on the clone will also remove the events + // from the original. In order to get around this, we use some + // proprietary methods to clear the events. Thanks to MooTools + // guys for this hotness. + + cloneFixAttributes( elem, clone ); + + // Using Sizzle here is crazy slow, so we use getElementsByTagName instead + srcElements = getAll( elem ); + destElements = getAll( clone ); + + // Weird iteration because IE will replace the length property + // with an element if you are cloning the body and one of the + // elements on the page has a name or id of "length" + for ( i = 0; srcElements[i]; ++i ) { + // Ensure that the destination node is not null; Fixes #9587 + if ( destElements[i] ) { + cloneFixAttributes( srcElements[i], destElements[i] ); + } + } + } + + // Copy the events from the original to the clone + if ( dataAndEvents ) { + cloneCopyEvent( elem, clone ); + + if ( deepDataAndEvents ) { + srcElements = getAll( elem ); + destElements = getAll( clone ); + + for ( i = 0; srcElements[i]; ++i ) { + cloneCopyEvent( srcElements[i], destElements[i] ); + } + } + } + + srcElements = destElements = null; + + // Return the cloned set + return clone; + }, + + clean: function( elems, context, fragment, scripts ) { + var i, j, elem, tag, wrap, depth, div, hasBody, tbody, len, handleScript, jsTags, + safe = context === document && safeFragment, + ret = []; + + // Ensure that context is a document + if ( !context || typeof context.createDocumentFragment === "undefined" ) { + context = document; + } + + // Use the already-created safe fragment if context permits + for ( i = 0; (elem = elems[i]) != null; i++ ) { + if ( typeof elem === "number" ) { + elem += ""; + } + + if ( !elem ) { + continue; + } + + // Convert html string into DOM nodes + if ( typeof elem === "string" ) { + if ( !rhtml.test( elem ) ) { + elem = context.createTextNode( elem ); + } else { + // Ensure a safe container in which to render the html + safe = safe || createSafeFragment( context ); + div = context.createElement("div"); + safe.appendChild( div ); + + // Fix "XHTML"-style tags in all browsers + elem = elem.replace(rxhtmlTag, "<$1>"); + + // Go to html and back, then peel off extra wrappers + tag = ( rtagName.exec( elem ) || ["", ""] )[1].toLowerCase(); + wrap = wrapMap[ tag ] || wrapMap._default; + depth = wrap[0]; + div.innerHTML = wrap[1] + elem + wrap[2]; + + // Move to the right depth + while ( depth-- ) { + div = div.lastChild; + } + + // Remove IE's autoinserted from table fragments + if ( !jQuery.support.tbody ) { + + // String was a , *may* have spurious + hasBody = rtbody.test(elem); + tbody = tag === "table" && !hasBody ? + div.firstChild && div.firstChild.childNodes : + + // String was a bare or + wrap[1] === "
      " && !hasBody ? + div.childNodes : + []; + + for ( j = tbody.length - 1; j >= 0 ; --j ) { + if ( jQuery.nodeName( tbody[ j ], "tbody" ) && !tbody[ j ].childNodes.length ) { + tbody[ j ].parentNode.removeChild( tbody[ j ] ); + } + } + } + + // IE completely kills leading whitespace when innerHTML is used + if ( !jQuery.support.leadingWhitespace && rleadingWhitespace.test( elem ) ) { + div.insertBefore( context.createTextNode( rleadingWhitespace.exec(elem)[0] ), div.firstChild ); + } + + elem = div.childNodes; + + // Take out of fragment container (we need a fresh div each time) + div.parentNode.removeChild( div ); + } + } + + if ( elem.nodeType ) { + ret.push( elem ); + } else { + jQuery.merge( ret, elem ); + } + } + + // Fix #11356: Clear elements from safeFragment + if ( div ) { + elem = div = safe = null; + } + + // Reset defaultChecked for any radios and checkboxes + // about to be appended to the DOM in IE 6/7 (#8060) + if ( !jQuery.support.appendChecked ) { + for ( i = 0; (elem = ret[i]) != null; i++ ) { + if ( jQuery.nodeName( elem, "input" ) ) { + fixDefaultChecked( elem ); + } else if ( typeof elem.getElementsByTagName !== "undefined" ) { + jQuery.grep( elem.getElementsByTagName("input"), fixDefaultChecked ); + } + } + } + + // Append elements to a provided document fragment + if ( fragment ) { + // Special handling of each script element + handleScript = function( elem ) { + // Check if we consider it executable + if ( !elem.type || rscriptType.test( elem.type ) ) { + // Detach the script and store it in the scripts array (if provided) or the fragment + // Return truthy to indicate that it has been handled + return scripts ? + scripts.push( elem.parentNode ? elem.parentNode.removeChild( elem ) : elem ) : + fragment.appendChild( elem ); + } + }; + + for ( i = 0; (elem = ret[i]) != null; i++ ) { + // Check if we're done after handling an executable script + if ( !( jQuery.nodeName( elem, "script" ) && handleScript( elem ) ) ) { + // Append to fragment and handle embedded scripts + fragment.appendChild( elem ); + if ( typeof elem.getElementsByTagName !== "undefined" ) { + // handleScript alters the DOM, so use jQuery.merge to ensure snapshot iteration + jsTags = jQuery.grep( jQuery.merge( [], elem.getElementsByTagName("script") ), handleScript ); + + // Splice the scripts into ret after their former ancestor and advance our index beyond them + ret.splice.apply( ret, [i + 1, 0].concat( jsTags ) ); + i += jsTags.length; + } + } + } + } + + return ret; + }, + + cleanData: function( elems, /* internal */ acceptData ) { + var data, id, elem, type, + i = 0, + internalKey = jQuery.expando, + cache = jQuery.cache, + deleteExpando = jQuery.support.deleteExpando, + special = jQuery.event.special; + + for ( ; (elem = elems[i]) != null; i++ ) { + + if ( acceptData || jQuery.acceptData( elem ) ) { + + id = elem[ internalKey ]; + data = id && cache[ id ]; + + if ( data ) { + if ( data.events ) { + for ( type in data.events ) { + if ( special[ type ] ) { + jQuery.event.remove( elem, type ); + + // This is a shortcut to avoid jQuery.event.remove's overhead + } else { + jQuery.removeEvent( elem, type, data.handle ); + } + } + } + + // Remove cache only if it was not already removed by jQuery.event.remove + if ( cache[ id ] ) { + + delete cache[ id ]; + + // 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 ( deleteExpando ) { + delete elem[ internalKey ]; + + } else if ( elem.removeAttribute ) { + elem.removeAttribute( internalKey ); + + } else { + elem[ internalKey ] = null; + } + + jQuery.deletedIds.push( id ); + } + } + } + } + } +}); +// Limit scope pollution from any deprecated API +(function() { + +var matched, browser; + +// Use of jQuery.browser is frowned upon. +// More details: http://api.jquery.com/jQuery.browser +// jQuery.uaMatch maintained for back-compat +jQuery.uaMatch = function( ua ) { + ua = ua.toLowerCase(); + + var match = /(chrome)[ \/]([\w.]+)/.exec( ua ) || + /(webkit)[ \/]([\w.]+)/.exec( ua ) || + /(opera)(?:.*version|)[ \/]([\w.]+)/.exec( ua ) || + /(msie) ([\w.]+)/.exec( ua ) || + ua.indexOf("compatible") < 0 && /(mozilla)(?:.*? rv:([\w.]+)|)/.exec( ua ) || + []; + + return { + browser: match[ 1 ] || "", + version: match[ 2 ] || "0" + }; +}; + +matched = jQuery.uaMatch( navigator.userAgent ); +browser = {}; + +if ( matched.browser ) { + browser[ matched.browser ] = true; + browser.version = matched.version; +} + +// Chrome is Webkit, but Webkit is also Safari. +if ( browser.chrome ) { + browser.webkit = true; +} else if ( browser.webkit ) { + browser.safari = true; +} + +jQuery.browser = browser; + +jQuery.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; +}; + +})(); +var curCSS, iframe, iframeDoc, + ralpha = /alpha\([^)]*\)/i, + ropacity = /opacity=([^)]*)/, + rposition = /^(top|right|bottom|left)$/, + // swappable if display is none or starts with table except "table", "table-cell", or "table-caption" + // see here for display values: https://developer.mozilla.org/en-US/docs/CSS/display + rdisplayswap = /^(none|table(?!-c[ea]).+)/, + rmargin = /^margin/, + rnumsplit = new RegExp( "^(" + core_pnum + ")(.*)$", "i" ), + rnumnonpx = new RegExp( "^(" + core_pnum + ")(?!px)[a-z%]+$", "i" ), + rrelNum = new RegExp( "^([-+])=(" + core_pnum + ")", "i" ), + elemdisplay = {}, + + cssShow = { position: "absolute", visibility: "hidden", display: "block" }, + cssNormalTransform = { + letterSpacing: 0, + fontWeight: 400 + }, + + cssExpand = [ "Top", "Right", "Bottom", "Left" ], + cssPrefixes = [ "Webkit", "O", "Moz", "ms" ], + + eventsToggle = jQuery.fn.toggle; + +// return a css property mapped to a potentially vendor prefixed property +function vendorPropName( style, name ) { + + // shortcut for names that are not vendor prefixed + if ( name in style ) { + return name; + } + + // check for vendor prefixed names + var capName = name.charAt(0).toUpperCase() + name.slice(1), + origName = name, + i = cssPrefixes.length; + + while ( i-- ) { + name = cssPrefixes[ i ] + capName; + if ( name in style ) { + return name; + } + } + + return origName; +} + +function isHidden( elem, el ) { + elem = el || elem; + return jQuery.css( elem, "display" ) === "none" || !jQuery.contains( elem.ownerDocument, elem ); +} + +function showHide( elements, show ) { + var elem, display, + values = [], + index = 0, + length = elements.length; + + for ( ; index < length; index++ ) { + elem = elements[ index ]; + if ( !elem.style ) { + continue; + } + values[ index ] = jQuery._data( elem, "olddisplay" ); + if ( show ) { + // Reset the inline display of this element to learn if it is + // being hidden by cascaded rules or not + if ( !values[ index ] && elem.style.display === "none" ) { + elem.style.display = ""; + } + + // Set elements which have been overridden with display: none + // in a stylesheet to whatever the default browser style is + // for such an element + if ( elem.style.display === "" && isHidden( elem ) ) { + values[ index ] = jQuery._data( elem, "olddisplay", css_defaultDisplay(elem.nodeName) ); + } + } else { + display = curCSS( elem, "display" ); + + if ( !values[ index ] && display !== "none" ) { + jQuery._data( elem, "olddisplay", display ); + } + } + } + + // Set the display of most of the elements in a second loop + // to avoid the constant reflow + for ( index = 0; index < length; index++ ) { + elem = elements[ index ]; + if ( !elem.style ) { + continue; + } + if ( !show || elem.style.display === "none" || elem.style.display === "" ) { + elem.style.display = show ? values[ index ] || "" : "none"; + } + } + + return elements; +} + +jQuery.fn.extend({ + css: function( name, value ) { + return jQuery.access( this, function( elem, name, value ) { + return value !== undefined ? + jQuery.style( elem, name, value ) : + jQuery.css( elem, name ); + }, name, value, arguments.length > 1 ); + }, + show: function() { + return showHide( this, true ); + }, + hide: function() { + return showHide( this ); + }, + toggle: function( state, fn2 ) { + var bool = typeof state === "boolean"; + + if ( jQuery.isFunction( state ) && jQuery.isFunction( fn2 ) ) { + return eventsToggle.apply( this, arguments ); + } + + return this.each(function() { + if ( bool ? state : isHidden( this ) ) { + jQuery( this ).show(); + } else { + jQuery( this ).hide(); + } + }); + } +}); + +jQuery.extend({ + // Add in style property hooks for overriding the default + // behavior of getting and setting a style property + cssHooks: { + opacity: { + get: function( elem, computed ) { + if ( computed ) { + // We should always get a number back from opacity + var ret = curCSS( elem, "opacity" ); + return ret === "" ? "1" : ret; + + } + } + } + }, + + // Exclude the following css properties to add px + cssNumber: { + "fillOpacity": true, + "fontWeight": true, + "lineHeight": true, + "opacity": true, + "orphans": true, + "widows": true, + "zIndex": true, + "zoom": true + }, + + // Add in properties whose names you wish to fix before + // setting or getting the value + cssProps: { + // normalize float css property + "float": jQuery.support.cssFloat ? "cssFloat" : "styleFloat" + }, + + // Get and set the style property on a DOM Node + style: function( elem, name, value, extra ) { + // Don't set styles on text and comment nodes + if ( !elem || elem.nodeType === 3 || elem.nodeType === 8 || !elem.style ) { + return; + } + + // Make sure that we're working with the right name + var ret, type, hooks, + origName = jQuery.camelCase( name ), + style = elem.style; + + name = jQuery.cssProps[ origName ] || ( jQuery.cssProps[ origName ] = vendorPropName( style, origName ) ); + + // gets hook for the prefixed version + // followed by the unprefixed version + hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ]; + + // Check if we're setting a value + if ( value !== undefined ) { + type = typeof value; + + // convert relative number strings (+= or -=) to relative numbers. #7345 + if ( type === "string" && (ret = rrelNum.exec( value )) ) { + value = ( ret[1] + 1 ) * ret[2] + parseFloat( jQuery.css( elem, name ) ); + // Fixes bug #9237 + type = "number"; + } + + // Make sure that NaN and null values aren't set. See: #7116 + if ( value == null || type === "number" && isNaN( value ) ) { + return; + } + + // If a number was passed in, add 'px' to the (except for certain CSS properties) + if ( type === "number" && !jQuery.cssNumber[ origName ] ) { + value += "px"; + } + + // If a hook was provided, use that value, otherwise just set the specified value + if ( !hooks || !("set" in hooks) || (value = hooks.set( elem, value, extra )) !== undefined ) { + // Wrapped to prevent IE from throwing errors when 'invalid' values are provided + // Fixes bug #5509 + try { + style[ name ] = value; + } catch(e) {} + } + + } else { + // If a hook was provided get the non-computed value from there + if ( hooks && "get" in hooks && (ret = hooks.get( elem, false, extra )) !== undefined ) { + return ret; + } + + // Otherwise just get the value from the style object + return style[ name ]; + } + }, + + css: function( elem, name, numeric, extra ) { + var val, num, hooks, + origName = jQuery.camelCase( name ); + + // Make sure that we're working with the right name + name = jQuery.cssProps[ origName ] || ( jQuery.cssProps[ origName ] = vendorPropName( elem.style, origName ) ); + + // gets hook for the prefixed version + // followed by the unprefixed version + hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ]; + + // If a hook was provided get the computed value from there + if ( hooks && "get" in hooks ) { + val = hooks.get( elem, true, extra ); + } + + // Otherwise, if a way to get the computed value exists, use that + if ( val === undefined ) { + val = curCSS( elem, name ); + } + + //convert "normal" to computed value + if ( val === "normal" && name in cssNormalTransform ) { + val = cssNormalTransform[ name ]; + } + + // Return, converting to number if forced or a qualifier was provided and val looks numeric + if ( numeric || extra !== undefined ) { + num = parseFloat( val ); + return numeric || jQuery.isNumeric( num ) ? num || 0 : val; + } + return val; + }, + + // A method for quickly swapping in/out CSS properties to get correct calculations + swap: function( elem, options, callback ) { + var ret, name, + old = {}; + + // Remember the old values, and insert the new ones + for ( name in options ) { + old[ name ] = elem.style[ name ]; + elem.style[ name ] = options[ name ]; + } + + ret = callback.call( elem ); + + // Revert the old values + for ( name in options ) { + elem.style[ name ] = old[ name ]; + } + + return ret; + } +}); + +// NOTE: To any future maintainer, we've window.getComputedStyle +// because jsdom on node.js will break without it. +if ( window.getComputedStyle ) { + curCSS = function( elem, name ) { + var ret, width, minWidth, maxWidth, + computed = window.getComputedStyle( elem, null ), + style = elem.style; + + if ( computed ) { + + ret = computed[ name ]; + if ( ret === "" && !jQuery.contains( elem.ownerDocument, elem ) ) { + ret = jQuery.style( elem, name ); + } + + // A tribute to the "awesome hack by Dean Edwards" + // Chrome < 17 and Safari 5.0 uses "computed value" instead of "used value" for margin-right + // Safari 5.1.7 (at least) returns percentage for a larger set of values, but width seems to be reliably pixels + // this is against the CSSOM draft spec: http://dev.w3.org/csswg/cssom/#resolved-values + if ( rnumnonpx.test( ret ) && rmargin.test( name ) ) { + width = style.width; + minWidth = style.minWidth; + maxWidth = style.maxWidth; + + style.minWidth = style.maxWidth = style.width = ret; + ret = computed.width; + + style.width = width; + style.minWidth = minWidth; + style.maxWidth = maxWidth; + } + } + + return ret; + }; +} else if ( document.documentElement.currentStyle ) { + curCSS = function( elem, name ) { + var left, rsLeft, + ret = elem.currentStyle && elem.currentStyle[ name ], + style = elem.style; + + // Avoid setting ret to empty string here + // so we don't default to auto + if ( ret == null && style && style[ name ] ) { + ret = style[ name ]; + } + + // From the awesome hack by Dean Edwards + // http://erik.eae.net/archives/2007/07/27/18.54.15/#comment-102291 + + // If we're not dealing with a regular pixel number + // but a number that has a weird ending, we need to convert it to pixels + // but not position css attributes, as those are proportional to the parent element instead + // and we can't measure the parent instead because it might trigger a "stacking dolls" problem + if ( rnumnonpx.test( ret ) && !rposition.test( name ) ) { + + // Remember the original values + left = style.left; + rsLeft = elem.runtimeStyle && elem.runtimeStyle.left; + + // Put in the new values to get a computed value out + if ( rsLeft ) { + elem.runtimeStyle.left = elem.currentStyle.left; + } + style.left = name === "fontSize" ? "1em" : ret; + ret = style.pixelLeft + "px"; + + // Revert the changed values + style.left = left; + if ( rsLeft ) { + elem.runtimeStyle.left = rsLeft; + } + } + + return ret === "" ? "auto" : ret; + }; +} + +function setPositiveNumber( elem, value, subtract ) { + var matches = rnumsplit.exec( value ); + return matches ? + Math.max( 0, matches[ 1 ] - ( subtract || 0 ) ) + ( matches[ 2 ] || "px" ) : + value; +} + +function augmentWidthOrHeight( elem, name, extra, isBorderBox ) { + var i = extra === ( isBorderBox ? "border" : "content" ) ? + // If we already have the right measurement, avoid augmentation + 4 : + // Otherwise initialize for horizontal or vertical properties + name === "width" ? 1 : 0, + + val = 0; + + for ( ; i < 4; i += 2 ) { + // both box models exclude margin, so add it if we want it + if ( extra === "margin" ) { + // we use jQuery.css instead of curCSS here + // because of the reliableMarginRight CSS hook! + val += jQuery.css( elem, extra + cssExpand[ i ], true ); + } + + // From this point on we use curCSS for maximum performance (relevant in animations) + if ( isBorderBox ) { + // border-box includes padding, so remove it if we want content + if ( extra === "content" ) { + val -= parseFloat( curCSS( elem, "padding" + cssExpand[ i ] ) ) || 0; + } + + // at this point, extra isn't border nor margin, so remove border + if ( extra !== "margin" ) { + val -= parseFloat( curCSS( elem, "border" + cssExpand[ i ] + "Width" ) ) || 0; + } + } else { + // at this point, extra isn't content, so add padding + val += parseFloat( curCSS( elem, "padding" + cssExpand[ i ] ) ) || 0; + + // at this point, extra isn't content nor padding, so add border + if ( extra !== "padding" ) { + val += parseFloat( curCSS( elem, "border" + cssExpand[ i ] + "Width" ) ) || 0; + } + } + } + + return val; +} + +function getWidthOrHeight( elem, name, extra ) { + + // Start with offset property, which is equivalent to the border-box value + var val = name === "width" ? elem.offsetWidth : elem.offsetHeight, + valueIsBorderBox = true, + isBorderBox = jQuery.support.boxSizing && jQuery.css( elem, "boxSizing" ) === "border-box"; + + // some non-html elements return undefined for offsetWidth, so check for null/undefined + // svg - https://bugzilla.mozilla.org/show_bug.cgi?id=649285 + // MathML - https://bugzilla.mozilla.org/show_bug.cgi?id=491668 + if ( val <= 0 || val == null ) { + // Fall back to computed then uncomputed css if necessary + val = curCSS( elem, name ); + if ( val < 0 || val == null ) { + val = elem.style[ name ]; + } + + // Computed unit is not pixels. Stop here and return. + if ( rnumnonpx.test(val) ) { + return val; + } + + // we need the check for style in case a browser which returns unreliable values + // for getComputedStyle silently falls back to the reliable elem.style + valueIsBorderBox = isBorderBox && ( jQuery.support.boxSizingReliable || val === elem.style[ name ] ); + + // Normalize "", auto, and prepare for extra + val = parseFloat( val ) || 0; + } + + // use the active box-sizing model to add/subtract irrelevant styles + return ( val + + augmentWidthOrHeight( + elem, + name, + extra || ( isBorderBox ? "border" : "content" ), + valueIsBorderBox + ) + ) + "px"; +} + + +// Try to determine the default display value of an element +function css_defaultDisplay( nodeName ) { + if ( elemdisplay[ nodeName ] ) { + return elemdisplay[ nodeName ]; + } + + var elem = jQuery( "<" + nodeName + ">" ).appendTo( document.body ), + display = elem.css("display"); + elem.remove(); + + // If the simple way fails, + // get element's real default display by attaching it to a temp iframe + if ( display === "none" || display === "" ) { + // Use the already-created iframe if possible + iframe = document.body.appendChild( + iframe || jQuery.extend( document.createElement("iframe"), { + frameBorder: 0, + width: 0, + height: 0 + }) + ); + + // Create a cacheable copy of the iframe document on first call. + // IE and Opera will allow us to reuse the iframeDoc without re-writing the fake HTML + // document to it; WebKit & Firefox won't allow reusing the iframe document. + if ( !iframeDoc || !iframe.createElement ) { + iframeDoc = ( iframe.contentWindow || iframe.contentDocument ).document; + iframeDoc.write(""); + iframeDoc.close(); + } + + elem = iframeDoc.body.appendChild( iframeDoc.createElement(nodeName) ); + + display = curCSS( elem, "display" ); + document.body.removeChild( iframe ); + } + + // Store the correct default display + elemdisplay[ nodeName ] = display; + + return display; +} + +jQuery.each([ "height", "width" ], function( i, name ) { + jQuery.cssHooks[ name ] = { + get: function( elem, computed, extra ) { + if ( computed ) { + // certain elements can have dimension info if we invisibly show them + // however, it must have a current display style that would benefit from this + if ( elem.offsetWidth === 0 && rdisplayswap.test( curCSS( elem, "display" ) ) ) { + return jQuery.swap( elem, cssShow, function() { + return getWidthOrHeight( elem, name, extra ); + }); + } else { + return getWidthOrHeight( elem, name, extra ); + } + } + }, + + set: function( elem, value, extra ) { + return setPositiveNumber( elem, value, extra ? + augmentWidthOrHeight( + elem, + name, + extra, + jQuery.support.boxSizing && jQuery.css( elem, "boxSizing" ) === "border-box" + ) : 0 + ); + } + }; +}); + +if ( !jQuery.support.opacity ) { + jQuery.cssHooks.opacity = { + get: function( elem, computed ) { + // IE uses filters for opacity + return ropacity.test( (computed && elem.currentStyle ? elem.currentStyle.filter : elem.style.filter) || "" ) ? + ( 0.01 * parseFloat( RegExp.$1 ) ) + "" : + computed ? "1" : ""; + }, + + set: function( elem, value ) { + var style = elem.style, + currentStyle = elem.currentStyle, + opacity = jQuery.isNumeric( value ) ? "alpha(opacity=" + value * 100 + ")" : "", + filter = currentStyle && currentStyle.filter || style.filter || ""; + + // IE has trouble with opacity if it does not have layout + // Force it by setting the zoom level + style.zoom = 1; + + // if setting opacity to 1, and no other filters exist - attempt to remove filter attribute #6652 + if ( value >= 1 && jQuery.trim( filter.replace( ralpha, "" ) ) === "" && + style.removeAttribute ) { + + // Setting style.filter to null, "" & " " still leave "filter:" in the cssText + // if "filter:" is present at all, clearType is disabled, we want to avoid this + // style.removeAttribute is IE Only, but so apparently is this code path... + style.removeAttribute( "filter" ); + + // if there there is no filter style applied in a css rule, we are done + if ( currentStyle && !currentStyle.filter ) { + return; + } + } + + // otherwise, set new filter values + style.filter = ralpha.test( filter ) ? + filter.replace( ralpha, opacity ) : + filter + " " + opacity; + } + }; +} + +// These hooks cannot be added until DOM ready because the support test +// for it is not run until after DOM ready +jQuery(function() { + if ( !jQuery.support.reliableMarginRight ) { + jQuery.cssHooks.marginRight = { + get: function( elem, computed ) { + // WebKit Bug 13343 - getComputedStyle returns wrong value for margin-right + // Work around by temporarily setting element display to inline-block + return jQuery.swap( elem, { "display": "inline-block" }, function() { + if ( computed ) { + return curCSS( elem, "marginRight" ); + } + }); + } + }; + } + + // Webkit bug: https://bugs.webkit.org/show_bug.cgi?id=29084 + // getComputedStyle returns percent when specified for top/left/bottom/right + // rather than make the css module depend on the offset module, we just check for it here + if ( !jQuery.support.pixelPosition && jQuery.fn.position ) { + jQuery.each( [ "top", "left" ], function( i, prop ) { + jQuery.cssHooks[ prop ] = { + get: function( elem, computed ) { + if ( computed ) { + var ret = curCSS( elem, prop ); + // if curCSS returns percentage, fallback to offset + return rnumnonpx.test( ret ) ? jQuery( elem ).position()[ prop ] + "px" : ret; + } + } + }; + }); + } + +}); + +if ( jQuery.expr && jQuery.expr.filters ) { + jQuery.expr.filters.hidden = function( elem ) { + return ( elem.offsetWidth === 0 && elem.offsetHeight === 0 ) || (!jQuery.support.reliableHiddenOffsets && ((elem.style && elem.style.display) || curCSS( elem, "display" )) === "none"); + }; + + jQuery.expr.filters.visible = function( elem ) { + return !jQuery.expr.filters.hidden( elem ); + }; +} + +// These hooks are used by animate to expand properties +jQuery.each({ + margin: "", + padding: "", + border: "Width" +}, function( prefix, suffix ) { + jQuery.cssHooks[ prefix + suffix ] = { + expand: function( value ) { + var i, + + // assumes a single number if not a string + parts = typeof value === "string" ? value.split(" ") : [ value ], + expanded = {}; + + for ( i = 0; i < 4; i++ ) { + expanded[ prefix + cssExpand[ i ] + suffix ] = + parts[ i ] || parts[ i - 2 ] || parts[ 0 ]; + } + + return expanded; + } + }; + + if ( !rmargin.test( prefix ) ) { + jQuery.cssHooks[ prefix + suffix ].set = setPositiveNumber; + } +}); +var r20 = /%20/g, + rbracket = /\[\]$/, + rCRLF = /\r?\n/g, + rinput = /^(?:color|date|datetime|datetime-local|email|hidden|month|number|password|range|search|tel|text|time|url|week)$/i, + rselectTextarea = /^(?:select|textarea)/i; + +jQuery.fn.extend({ + serialize: function() { + return jQuery.param( this.serializeArray() ); + }, + serializeArray: function() { + return this.map(function(){ + return this.elements ? jQuery.makeArray( this.elements ) : this; + }) + .filter(function(){ + return this.name && !this.disabled && + ( this.checked || rselectTextarea.test( this.nodeName ) || + rinput.test( this.type ) ); + }) + .map(function( i, elem ){ + var val = jQuery( this ).val(); + + return val == null ? + null : + jQuery.isArray( val ) ? + jQuery.map( val, function( val, i ){ + return { name: elem.name, value: val.replace( rCRLF, "\r\n" ) }; + }) : + { name: elem.name, value: val.replace( rCRLF, "\r\n" ) }; + }).get(); + } +}); + +//Serialize an array of form elements or a set of +//key/values into a query string +jQuery.param = function( a, traditional ) { + var prefix, + s = [], + add = function( key, value ) { + // If value is a function, invoke it and return its value + value = jQuery.isFunction( value ) ? value() : ( value == null ? "" : value ); + s[ s.length ] = encodeURIComponent( key ) + "=" + encodeURIComponent( value ); + }; + + // Set traditional to true for jQuery <= 1.3.2 behavior. + if ( traditional === undefined ) { + traditional = jQuery.ajaxSettings && jQuery.ajaxSettings.traditional; + } + + // If an array was passed in, assume that it is an array of form elements. + if ( jQuery.isArray( a ) || ( a.jquery && !jQuery.isPlainObject( a ) ) ) { + // Serialize the form elements + jQuery.each( a, function() { + add( this.name, this.value ); + }); + + } else { + // If traditional, encode the "old" way (the way 1.3.2 or older + // did it), otherwise encode params recursively. + for ( prefix in a ) { + buildParams( prefix, a[ prefix ], traditional, add ); + } + } + + // Return the resulting serialization + return s.join( "&" ).replace( r20, "+" ); +}; + +function buildParams( prefix, obj, traditional, add ) { + var name; + + if ( jQuery.isArray( obj ) ) { + // Serialize array item. + jQuery.each( obj, function( i, v ) { + if ( traditional || rbracket.test( prefix ) ) { + // Treat each array item as a scalar. + add( prefix, v ); + + } else { + // If array item is non-scalar (array or object), encode its + // numeric index to resolve deserialization ambiguity issues. + // Note that rack (as of 1.0.0) can't currently deserialize + // nested arrays properly, and attempting to do so may cause + // a server error. Possible fixes are to modify rack's + // deserialization algorithm or to provide an option or flag + // to force array serialization to be shallow. + buildParams( prefix + "[" + ( typeof v === "object" ? i : "" ) + "]", v, traditional, add ); + } + }); + + } else if ( !traditional && jQuery.type( obj ) === "object" ) { + // Serialize object item. + for ( name in obj ) { + buildParams( prefix + "[" + name + "]", obj[ name ], traditional, add ); + } + + } else { + // Serialize scalar item. + add( prefix, obj ); + } +} +var // Document location + ajaxLocation, + // Document location segments + ajaxLocParts, + + rhash = /#.*$/, + rheaders = /^(.*?):[ \t]*([^\r\n]*)\r?$/mg, // IE leaves an \r character at EOL + // #7653, #8125, #8152: local protocol detection + rlocalProtocol = /^(?:about|app|app\-storage|.+\-extension|file|res|widget):$/, + rnoContent = /^(?:GET|HEAD)$/, + rprotocol = /^\/\//, + rquery = /\?/, + rscript = /)<[^<]*)*<\/script>/gi, + rts = /([?&])_=[^&]*/, + rurl = /^([\w\+\.\-]+:)(?:\/\/([^\/?#:]*)(?::(\d+)|)|)/, + + // Keep a copy of the old load method + _load = jQuery.fn.load, + + /* Prefilters + * 1) They are useful to introduce custom dataTypes (see ajax/jsonp.js for an example) + * 2) These are called: + * - BEFORE asking for a transport + * - AFTER param serialization (s.data is a string if s.processData is true) + * 3) key is the dataType + * 4) the catchall symbol "*" can be used + * 5) execution will start with transport dataType and THEN continue down to "*" if needed + */ + prefilters = {}, + + /* Transports bindings + * 1) key is the dataType + * 2) the catchall symbol "*" can be used + * 3) selection will start with transport dataType and THEN go to "*" if needed + */ + transports = {}, + + // Avoid comment-prolog char sequence (#10098); must appease lint and evade compression + allTypes = ["*/"] + ["*"]; + +// #8138, IE may throw an exception when accessing +// a field from window.location if document.domain has been set +try { + ajaxLocation = location.href; +} catch( e ) { + // Use the href attribute of an A element + // since IE will modify it given document.location + ajaxLocation = document.createElement( "a" ); + ajaxLocation.href = ""; + ajaxLocation = ajaxLocation.href; +} + +// Segment location into parts +ajaxLocParts = rurl.exec( ajaxLocation.toLowerCase() ) || []; + +// Base "constructor" for jQuery.ajaxPrefilter and jQuery.ajaxTransport +function addToPrefiltersOrTransports( structure ) { + + // dataTypeExpression is optional and defaults to "*" + return function( dataTypeExpression, func ) { + + if ( typeof dataTypeExpression !== "string" ) { + func = dataTypeExpression; + dataTypeExpression = "*"; + } + + var dataType, list, placeBefore, + dataTypes = dataTypeExpression.toLowerCase().split( core_rspace ), + i = 0, + length = dataTypes.length; + + if ( jQuery.isFunction( func ) ) { + // For each dataType in the dataTypeExpression + for ( ; i < length; i++ ) { + dataType = dataTypes[ i ]; + // We control if we're asked to add before + // any existing element + placeBefore = /^\+/.test( dataType ); + if ( placeBefore ) { + dataType = dataType.substr( 1 ) || "*"; + } + list = structure[ dataType ] = structure[ dataType ] || []; + // then we add to the structure accordingly + list[ placeBefore ? "unshift" : "push" ]( func ); + } + } + }; +} + +// Base inspection function for prefilters and transports +function inspectPrefiltersOrTransports( structure, options, originalOptions, jqXHR, + dataType /* internal */, inspected /* internal */ ) { + + dataType = dataType || options.dataTypes[ 0 ]; + inspected = inspected || {}; + + inspected[ dataType ] = true; + + var selection, + list = structure[ dataType ], + i = 0, + length = list ? list.length : 0, + executeOnly = ( structure === prefilters ); + + for ( ; i < length && ( executeOnly || !selection ); i++ ) { + selection = list[ i ]( options, originalOptions, jqXHR ); + // If we got redirected to another dataType + // we try there if executing only and not done already + if ( typeof selection === "string" ) { + if ( !executeOnly || inspected[ selection ] ) { + selection = undefined; + } else { + options.dataTypes.unshift( selection ); + selection = inspectPrefiltersOrTransports( + structure, options, originalOptions, jqXHR, selection, inspected ); + } + } + } + // If we're only executing or nothing was selected + // we try the catchall dataType if not done already + if ( ( executeOnly || !selection ) && !inspected[ "*" ] ) { + selection = inspectPrefiltersOrTransports( + structure, options, originalOptions, jqXHR, "*", inspected ); + } + // unnecessary when only executing (prefilters) + // but it'll be ignored by the caller in that case + return selection; +} + +// A special extend for ajax options +// that takes "flat" options (not to be deep extended) +// Fixes #9887 +function ajaxExtend( target, src ) { + var key, deep, + flatOptions = jQuery.ajaxSettings.flatOptions || {}; + for ( key in src ) { + if ( src[ key ] !== undefined ) { + ( flatOptions[ key ] ? target : ( deep || ( deep = {} ) ) )[ key ] = src[ key ]; + } + } + if ( deep ) { + jQuery.extend( true, target, deep ); + } +} + +jQuery.fn.load = function( url, params, callback ) { + if ( typeof url !== "string" && _load ) { + return _load.apply( this, arguments ); + } + + // Don't do a request if no elements are being requested + if ( !this.length ) { + return this; + } + + var selector, type, response, + self = this, + off = url.indexOf(" "); + + if ( off >= 0 ) { + selector = url.slice( off, url.length ); + url = url.slice( 0, off ); + } + + // If it's a function + if ( jQuery.isFunction( params ) ) { + + // We assume that it's the callback + callback = params; + params = undefined; + + // Otherwise, build a param string + } else if ( params && typeof params === "object" ) { + type = "POST"; + } + + // Request the remote document + jQuery.ajax({ + url: url, + + // if "type" variable is undefined, then "GET" method will be used + type: type, + dataType: "html", + data: params, + complete: function( jqXHR, status ) { + if ( callback ) { + self.each( callback, response || [ jqXHR.responseText, status, jqXHR ] ); + } + } + }).done(function( responseText ) { + + // Save response for use in complete callback + response = arguments; + + // See if a selector was specified + self.html( selector ? + + // Create a dummy div to hold the results + jQuery("
      ") + + // inject the contents of the document in, removing the scripts + // to avoid any 'Permission Denied' errors in IE + .append( responseText.replace( rscript, "" ) ) + + // Locate the specified elements + .find( selector ) : + + // If not, just inject the full result + responseText ); + + }); + + return this; +}; + +// Attach a bunch of functions for handling common AJAX events +jQuery.each( "ajaxStart ajaxStop ajaxComplete ajaxError ajaxSuccess ajaxSend".split( " " ), function( i, o ){ + jQuery.fn[ o ] = function( f ){ + return this.on( o, f ); + }; +}); + +jQuery.each( [ "get", "post" ], function( i, method ) { + jQuery[ method ] = function( url, data, callback, type ) { + // shift arguments if data argument was omitted + if ( jQuery.isFunction( data ) ) { + type = type || callback; + callback = data; + data = undefined; + } + + return jQuery.ajax({ + type: method, + url: url, + data: data, + success: callback, + dataType: type + }); + }; +}); + +jQuery.extend({ + + getScript: function( url, callback ) { + return jQuery.get( url, undefined, callback, "script" ); + }, + + getJSON: function( url, data, callback ) { + return jQuery.get( url, data, callback, "json" ); + }, + + // Creates a full fledged settings object into target + // with both ajaxSettings and settings fields. + // If target is omitted, writes into ajaxSettings. + ajaxSetup: function( target, settings ) { + if ( settings ) { + // Building a settings object + ajaxExtend( target, jQuery.ajaxSettings ); + } else { + // Extending ajaxSettings + settings = target; + target = jQuery.ajaxSettings; + } + ajaxExtend( target, settings ); + return target; + }, + + ajaxSettings: { + url: ajaxLocation, + isLocal: rlocalProtocol.test( ajaxLocParts[ 1 ] ), + global: true, + type: "GET", + contentType: "application/x-www-form-urlencoded; charset=UTF-8", + processData: true, + async: true, + /* + timeout: 0, + data: null, + dataType: null, + username: null, + password: null, + cache: null, + throws: false, + traditional: false, + headers: {}, + */ + + accepts: { + xml: "application/xml, text/xml", + html: "text/html", + text: "text/plain", + json: "application/json, text/javascript", + "*": allTypes + }, + + contents: { + xml: /xml/, + html: /html/, + json: /json/ + }, + + responseFields: { + xml: "responseXML", + text: "responseText" + }, + + // List of data converters + // 1) key format is "source_type destination_type" (a single space in-between) + // 2) the catchall symbol "*" can be used for source_type + converters: { + + // Convert anything to text + "* text": window.String, + + // Text to html (true = no transformation) + "text html": true, + + // Evaluate text as a json expression + "text json": jQuery.parseJSON, + + // Parse text as xml + "text xml": jQuery.parseXML + }, + + // For options that shouldn't be deep extended: + // you can add your own custom options here if + // and when you create one that shouldn't be + // deep extended (see ajaxExtend) + flatOptions: { + context: true, + url: true + } + }, + + ajaxPrefilter: addToPrefiltersOrTransports( prefilters ), + ajaxTransport: addToPrefiltersOrTransports( transports ), + + // Main method + ajax: function( url, options ) { + + // If url is an object, simulate pre-1.5 signature + if ( typeof url === "object" ) { + options = url; + url = undefined; + } + + // Force options to be an object + options = options || {}; + + var // ifModified key + ifModifiedKey, + // Response headers + responseHeadersString, + responseHeaders, + // transport + transport, + // timeout handle + timeoutTimer, + // Cross-domain detection vars + parts, + // To know if global events are to be dispatched + fireGlobals, + // Loop variable + i, + // Create the final options object + s = jQuery.ajaxSetup( {}, options ), + // Callbacks context + callbackContext = s.context || s, + // Context for global events + // It's the callbackContext if one was provided in the options + // and if it's a DOM node or a jQuery collection + globalEventContext = callbackContext !== s && + ( callbackContext.nodeType || callbackContext instanceof jQuery ) ? + jQuery( callbackContext ) : jQuery.event, + // Deferreds + deferred = jQuery.Deferred(), + completeDeferred = jQuery.Callbacks( "once memory" ), + // Status-dependent callbacks + statusCode = s.statusCode || {}, + // Headers (they are sent all at once) + requestHeaders = {}, + requestHeadersNames = {}, + // The jqXHR state + state = 0, + // Default abort message + strAbort = "canceled", + // Fake xhr + jqXHR = { + + readyState: 0, + + // Caches the header + setRequestHeader: function( name, value ) { + if ( !state ) { + var lname = name.toLowerCase(); + name = requestHeadersNames[ lname ] = requestHeadersNames[ lname ] || name; + requestHeaders[ name ] = value; + } + return this; + }, + + // Raw string + getAllResponseHeaders: function() { + return state === 2 ? responseHeadersString : null; + }, + + // Builds headers hashtable if needed + getResponseHeader: function( key ) { + var match; + if ( state === 2 ) { + if ( !responseHeaders ) { + responseHeaders = {}; + while( ( match = rheaders.exec( responseHeadersString ) ) ) { + responseHeaders[ match[1].toLowerCase() ] = match[ 2 ]; + } + } + match = responseHeaders[ key.toLowerCase() ]; + } + return match === undefined ? null : match; + }, + + // Overrides response content-type header + overrideMimeType: function( type ) { + if ( !state ) { + s.mimeType = type; + } + return this; + }, + + // Cancel the request + abort: function( statusText ) { + statusText = statusText || strAbort; + if ( transport ) { + transport.abort( statusText ); + } + done( 0, statusText ); + return this; + } + }; + + // Callback for when everything is done + // It is defined here because jslint complains if it is declared + // at the end of the function (which would be more logical and readable) + function done( status, nativeStatusText, responses, headers ) { + var isSuccess, success, error, response, modified, + statusText = nativeStatusText; + + // Called once + if ( state === 2 ) { + return; + } + + // State is "done" now + state = 2; + + // Clear timeout if it exists + if ( timeoutTimer ) { + clearTimeout( timeoutTimer ); + } + + // Dereference transport for early garbage collection + // (no matter how long the jqXHR object will be used) + transport = undefined; + + // Cache response headers + responseHeadersString = headers || ""; + + // Set readyState + jqXHR.readyState = status > 0 ? 4 : 0; + + // Get response data + if ( responses ) { + response = ajaxHandleResponses( s, jqXHR, responses ); + } + + // If successful, handle type chaining + if ( status >= 200 && status < 300 || status === 304 ) { + + // Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode. + if ( s.ifModified ) { + + modified = jqXHR.getResponseHeader("Last-Modified"); + if ( modified ) { + jQuery.lastModified[ ifModifiedKey ] = modified; + } + modified = jqXHR.getResponseHeader("Etag"); + if ( modified ) { + jQuery.etag[ ifModifiedKey ] = modified; + } + } + + // If not modified + if ( status === 304 ) { + + statusText = "notmodified"; + isSuccess = true; + + // If we have data + } else { + + isSuccess = ajaxConvert( s, response ); + statusText = isSuccess.state; + success = isSuccess.data; + error = isSuccess.error; + isSuccess = !error; + } + } else { + // We extract error from statusText + // then normalize statusText and status for non-aborts + error = statusText; + if ( !statusText || status ) { + statusText = "error"; + if ( status < 0 ) { + status = 0; + } + } + } + + // Set data for the fake xhr object + jqXHR.status = status; + jqXHR.statusText = "" + ( nativeStatusText || statusText ); + + // Success/Error + if ( isSuccess ) { + deferred.resolveWith( callbackContext, [ success, statusText, jqXHR ] ); + } else { + deferred.rejectWith( callbackContext, [ jqXHR, statusText, error ] ); + } + + // Status-dependent callbacks + jqXHR.statusCode( statusCode ); + statusCode = undefined; + + if ( fireGlobals ) { + globalEventContext.trigger( "ajax" + ( isSuccess ? "Success" : "Error" ), + [ jqXHR, s, isSuccess ? success : error ] ); + } + + // Complete + completeDeferred.fireWith( callbackContext, [ jqXHR, statusText ] ); + + if ( fireGlobals ) { + globalEventContext.trigger( "ajaxComplete", [ jqXHR, s ] ); + // Handle the global AJAX counter + if ( !( --jQuery.active ) ) { + jQuery.event.trigger( "ajaxStop" ); + } + } + } + + // Attach deferreds + deferred.promise( jqXHR ); + jqXHR.success = jqXHR.done; + jqXHR.error = jqXHR.fail; + jqXHR.complete = completeDeferred.add; + + // Status-dependent callbacks + jqXHR.statusCode = function( map ) { + if ( map ) { + var tmp; + if ( state < 2 ) { + for ( tmp in map ) { + statusCode[ tmp ] = [ statusCode[tmp], map[tmp] ]; + } + } else { + tmp = map[ jqXHR.status ]; + jqXHR.always( tmp ); + } + } + return this; + }; + + // Remove hash character (#7531: and string promotion) + // Add protocol if not provided (#5866: IE7 issue with protocol-less urls) + // We also use the url parameter if available + s.url = ( ( url || s.url ) + "" ).replace( rhash, "" ).replace( rprotocol, ajaxLocParts[ 1 ] + "//" ); + + // Extract dataTypes list + s.dataTypes = jQuery.trim( s.dataType || "*" ).toLowerCase().split( core_rspace ); + + // Determine if a cross-domain request is in order + if ( s.crossDomain == null ) { + parts = rurl.exec( s.url.toLowerCase() ); + s.crossDomain = !!( parts && + ( parts[ 1 ] != ajaxLocParts[ 1 ] || parts[ 2 ] != ajaxLocParts[ 2 ] || + ( parts[ 3 ] || ( parts[ 1 ] === "http:" ? 80 : 443 ) ) != + ( ajaxLocParts[ 3 ] || ( ajaxLocParts[ 1 ] === "http:" ? 80 : 443 ) ) ) + ); + } + + // Convert data if not already a string + if ( s.data && s.processData && typeof s.data !== "string" ) { + s.data = jQuery.param( s.data, s.traditional ); + } + + // Apply prefilters + inspectPrefiltersOrTransports( prefilters, s, options, jqXHR ); + + // If request was aborted inside a prefilter, stop there + if ( state === 2 ) { + return jqXHR; + } + + // We can fire global events as of now if asked to + fireGlobals = s.global; + + // Uppercase the type + s.type = s.type.toUpperCase(); + + // Determine if request has content + s.hasContent = !rnoContent.test( s.type ); + + // Watch for a new set of requests + if ( fireGlobals && jQuery.active++ === 0 ) { + jQuery.event.trigger( "ajaxStart" ); + } + + // More options handling for requests with no content + if ( !s.hasContent ) { + + // If data is available, append data to url + if ( s.data ) { + s.url += ( rquery.test( s.url ) ? "&" : "?" ) + s.data; + // #9682: remove data so that it's not used in an eventual retry + delete s.data; + } + + // Get ifModifiedKey before adding the anti-cache parameter + ifModifiedKey = s.url; + + // Add anti-cache in url if needed + if ( s.cache === false ) { + + var ts = jQuery.now(), + // try replacing _= if it is there + ret = s.url.replace( rts, "$1_=" + ts ); + + // if nothing was replaced, add timestamp to the end + s.url = ret + ( ( ret === s.url ) ? ( rquery.test( s.url ) ? "&" : "?" ) + "_=" + ts : "" ); + } + } + + // Set the correct header, if data is being sent + if ( s.data && s.hasContent && s.contentType !== false || options.contentType ) { + jqXHR.setRequestHeader( "Content-Type", s.contentType ); + } + + // Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode. + if ( s.ifModified ) { + ifModifiedKey = ifModifiedKey || s.url; + if ( jQuery.lastModified[ ifModifiedKey ] ) { + jqXHR.setRequestHeader( "If-Modified-Since", jQuery.lastModified[ ifModifiedKey ] ); + } + if ( jQuery.etag[ ifModifiedKey ] ) { + jqXHR.setRequestHeader( "If-None-Match", jQuery.etag[ ifModifiedKey ] ); + } + } + + // Set the Accepts header for the server, depending on the dataType + jqXHR.setRequestHeader( + "Accept", + s.dataTypes[ 0 ] && s.accepts[ s.dataTypes[0] ] ? + s.accepts[ s.dataTypes[0] ] + ( s.dataTypes[ 0 ] !== "*" ? ", " + allTypes + "; q=0.01" : "" ) : + s.accepts[ "*" ] + ); + + // Check for headers option + for ( i in s.headers ) { + jqXHR.setRequestHeader( i, s.headers[ i ] ); + } + + // Allow custom headers/mimetypes and early abort + if ( s.beforeSend && ( s.beforeSend.call( callbackContext, jqXHR, s ) === false || state === 2 ) ) { + // Abort if not done already and return + return jqXHR.abort(); + + } + + // aborting is no longer a cancellation + strAbort = "abort"; + + // Install callbacks on deferreds + for ( i in { success: 1, error: 1, complete: 1 } ) { + jqXHR[ i ]( s[ i ] ); + } + + // Get transport + transport = inspectPrefiltersOrTransports( transports, s, options, jqXHR ); + + // If no transport, we auto-abort + if ( !transport ) { + done( -1, "No Transport" ); + } else { + jqXHR.readyState = 1; + // Send global event + if ( fireGlobals ) { + globalEventContext.trigger( "ajaxSend", [ jqXHR, s ] ); + } + // Timeout + if ( s.async && s.timeout > 0 ) { + timeoutTimer = setTimeout( function(){ + jqXHR.abort( "timeout" ); + }, s.timeout ); + } + + try { + state = 1; + transport.send( requestHeaders, done ); + } catch (e) { + // Propagate exception as error if not done + if ( state < 2 ) { + done( -1, e ); + // Simply rethrow otherwise + } else { + throw e; + } + } + } + + return jqXHR; + }, + + // Counter for holding the number of active queries + active: 0, + + // Last-Modified header cache for next request + lastModified: {}, + etag: {} + +}); + +/* Handles responses to an ajax request: + * - sets all responseXXX fields accordingly + * - finds the right dataType (mediates between content-type and expected dataType) + * - returns the corresponding response + */ +function ajaxHandleResponses( s, jqXHR, responses ) { + + var ct, type, finalDataType, firstDataType, + contents = s.contents, + dataTypes = s.dataTypes, + responseFields = s.responseFields; + + // Fill responseXXX fields + for ( type in responseFields ) { + if ( type in responses ) { + jqXHR[ responseFields[type] ] = responses[ type ]; + } + } + + // Remove auto dataType and get content-type in the process + while( dataTypes[ 0 ] === "*" ) { + dataTypes.shift(); + if ( ct === undefined ) { + ct = s.mimeType || jqXHR.getResponseHeader( "content-type" ); + } + } + + // Check if we're dealing with a known content-type + if ( ct ) { + for ( type in contents ) { + if ( contents[ type ] && contents[ type ].test( ct ) ) { + dataTypes.unshift( type ); + break; + } + } + } + + // Check to see if we have a response for the expected dataType + if ( dataTypes[ 0 ] in responses ) { + finalDataType = dataTypes[ 0 ]; + } else { + // Try convertible dataTypes + for ( type in responses ) { + if ( !dataTypes[ 0 ] || s.converters[ type + " " + dataTypes[0] ] ) { + finalDataType = type; + break; + } + if ( !firstDataType ) { + firstDataType = type; + } + } + // Or just use first one + finalDataType = finalDataType || firstDataType; + } + + // If we found a dataType + // We add the dataType to the list if needed + // and return the corresponding response + if ( finalDataType ) { + if ( finalDataType !== dataTypes[ 0 ] ) { + dataTypes.unshift( finalDataType ); + } + return responses[ finalDataType ]; + } +} + +// Chain conversions given the request and the original response +function ajaxConvert( s, response ) { + + var conv, conv2, current, tmp, + // Work with a copy of dataTypes in case we need to modify it for conversion + dataTypes = s.dataTypes.slice(), + prev = dataTypes[ 0 ], + converters = {}, + i = 0; + + // Apply the dataFilter if provided + if ( s.dataFilter ) { + response = s.dataFilter( response, s.dataType ); + } + + // Create converters map with lowercased keys + if ( dataTypes[ 1 ] ) { + for ( conv in s.converters ) { + converters[ conv.toLowerCase() ] = s.converters[ conv ]; + } + } + + // Convert to each sequential dataType, tolerating list modification + for ( ; (current = dataTypes[++i]); ) { + + // There's only work to do if current dataType is non-auto + if ( current !== "*" ) { + + // Convert response if prev dataType is non-auto and differs from current + if ( prev !== "*" && prev !== current ) { + + // Seek a direct converter + conv = converters[ prev + " " + current ] || converters[ "* " + current ]; + + // If none found, seek a pair + if ( !conv ) { + for ( conv2 in converters ) { + + // If conv2 outputs current + tmp = conv2.split(" "); + if ( tmp[ 1 ] === current ) { + + // If prev can be converted to accepted input + conv = converters[ prev + " " + tmp[ 0 ] ] || + converters[ "* " + tmp[ 0 ] ]; + if ( conv ) { + // Condense equivalence converters + if ( conv === true ) { + conv = converters[ conv2 ]; + + // Otherwise, insert the intermediate dataType + } else if ( converters[ conv2 ] !== true ) { + current = tmp[ 0 ]; + dataTypes.splice( i--, 0, current ); + } + + break; + } + } + } + } + + // Apply converter (if not an equivalence) + if ( conv !== true ) { + + // Unless errors are allowed to bubble, catch and return them + if ( conv && s["throws"] ) { + response = conv( response ); + } else { + try { + response = conv( response ); + } catch ( e ) { + return { state: "parsererror", error: conv ? e : "No conversion from " + prev + " to " + current }; + } + } + } + } + + // Update prev for next iteration + prev = current; + } + } + + return { state: "success", data: response }; +} +var oldCallbacks = [], + rquestion = /\?/, + rjsonp = /(=)\?(?=&|$)|\?\?/, + nonce = jQuery.now(); + +// Default jsonp settings +jQuery.ajaxSetup({ + jsonp: "callback", + jsonpCallback: function() { + var callback = oldCallbacks.pop() || ( jQuery.expando + "_" + ( nonce++ ) ); + this[ callback ] = true; + return callback; + } +}); + +// Detect, normalize options and install callbacks for jsonp requests +jQuery.ajaxPrefilter( "json jsonp", function( s, originalSettings, jqXHR ) { + + var callbackName, overwritten, responseContainer, + data = s.data, + url = s.url, + hasCallback = s.jsonp !== false, + replaceInUrl = hasCallback && rjsonp.test( url ), + replaceInData = hasCallback && !replaceInUrl && typeof data === "string" && + !( s.contentType || "" ).indexOf("application/x-www-form-urlencoded") && + rjsonp.test( data ); + + // Handle iff the expected data type is "jsonp" or we have a parameter to set + if ( s.dataTypes[ 0 ] === "jsonp" || replaceInUrl || replaceInData ) { + + // Get callback name, remembering preexisting value associated with it + callbackName = s.jsonpCallback = jQuery.isFunction( s.jsonpCallback ) ? + s.jsonpCallback() : + s.jsonpCallback; + overwritten = window[ callbackName ]; + + // Insert callback into url or form data + if ( replaceInUrl ) { + s.url = url.replace( rjsonp, "$1" + callbackName ); + } else if ( replaceInData ) { + s.data = data.replace( rjsonp, "$1" + callbackName ); + } else if ( hasCallback ) { + s.url += ( rquestion.test( url ) ? "&" : "?" ) + s.jsonp + "=" + callbackName; + } + + // Use data converter to retrieve json after script execution + s.converters["script json"] = function() { + if ( !responseContainer ) { + jQuery.error( callbackName + " was not called" ); + } + return responseContainer[ 0 ]; + }; + + // force json dataType + s.dataTypes[ 0 ] = "json"; + + // Install callback + window[ callbackName ] = function() { + responseContainer = arguments; + }; + + // Clean-up function (fires after converters) + jqXHR.always(function() { + // Restore preexisting value + window[ callbackName ] = overwritten; + + // Save back as free + if ( s[ callbackName ] ) { + // make sure that re-using the options doesn't screw things around + s.jsonpCallback = originalSettings.jsonpCallback; + + // save the callback name for future use + oldCallbacks.push( callbackName ); + } + + // Call if it was a function and we have a response + if ( responseContainer && jQuery.isFunction( overwritten ) ) { + overwritten( responseContainer[ 0 ] ); + } + + responseContainer = overwritten = undefined; + }); + + // Delegate to script + return "script"; + } +}); +// Install script dataType +jQuery.ajaxSetup({ + accepts: { + script: "text/javascript, application/javascript, application/ecmascript, application/x-ecmascript" + }, + contents: { + script: /javascript|ecmascript/ + }, + converters: { + "text script": function( text ) { + jQuery.globalEval( text ); + return text; + } + } +}); + +// Handle cache's special case and global +jQuery.ajaxPrefilter( "script", function( s ) { + if ( s.cache === undefined ) { + s.cache = false; + } + if ( s.crossDomain ) { + s.type = "GET"; + s.global = false; + } +}); + +// Bind script tag hack transport +jQuery.ajaxTransport( "script", function(s) { + + // This transport only deals with cross domain requests + if ( s.crossDomain ) { + + var script, + head = document.head || document.getElementsByTagName( "head" )[0] || document.documentElement; + + return { + + send: function( _, callback ) { + + script = document.createElement( "script" ); + + script.async = "async"; + + if ( s.scriptCharset ) { + script.charset = s.scriptCharset; + } + + script.src = s.url; + + // Attach handlers for all browsers + script.onload = script.onreadystatechange = function( _, isAbort ) { + + if ( isAbort || !script.readyState || /loaded|complete/.test( script.readyState ) ) { + + // Handle memory leak in IE + script.onload = script.onreadystatechange = null; + + // Remove the script + if ( head && script.parentNode ) { + head.removeChild( script ); + } + + // Dereference the script + script = undefined; + + // Callback if not abort + if ( !isAbort ) { + callback( 200, "success" ); + } + } + }; + // Use insertBefore instead of appendChild to circumvent an IE6 bug. + // This arises when a base node is used (#2709 and #4378). + head.insertBefore( script, head.firstChild ); + }, + + abort: function() { + if ( script ) { + script.onload( 0, 1 ); + } + } + }; + } +}); +var xhrCallbacks, + // #5280: Internet Explorer will keep connections alive if we don't abort on unload + xhrOnUnloadAbort = window.ActiveXObject ? function() { + // Abort all pending requests + for ( var key in xhrCallbacks ) { + xhrCallbacks[ key ]( 0, 1 ); + } + } : false, + xhrId = 0; + +// Functions to create xhrs +function createStandardXHR() { + try { + return new window.XMLHttpRequest(); + } catch( e ) {} +} + +function createActiveXHR() { + try { + return new window.ActiveXObject( "Microsoft.XMLHTTP" ); + } catch( e ) {} +} + +// Create the request object +// (This is still attached to ajaxSettings for backward compatibility) +jQuery.ajaxSettings.xhr = window.ActiveXObject ? + /* Microsoft failed to properly + * implement the XMLHttpRequest in IE7 (can't request local files), + * so we use the ActiveXObject when it is available + * Additionally XMLHttpRequest can be disabled in IE7/IE8 so + * we need a fallback. + */ + function() { + return !this.isLocal && createStandardXHR() || createActiveXHR(); + } : + // For all other browsers, use the standard XMLHttpRequest object + createStandardXHR; + +// Determine support properties +(function( xhr ) { + jQuery.extend( jQuery.support, { + ajax: !!xhr, + cors: !!xhr && ( "withCredentials" in xhr ) + }); +})( jQuery.ajaxSettings.xhr() ); + +// Create transport if the browser can provide an xhr +if ( jQuery.support.ajax ) { + + jQuery.ajaxTransport(function( s ) { + // Cross domain only allowed if supported through XMLHttpRequest + if ( !s.crossDomain || jQuery.support.cors ) { + + var callback; + + return { + send: function( headers, complete ) { + + // Get a new xhr + var handle, i, + xhr = s.xhr(); + + // Open the socket + // Passing null username, generates a login popup on Opera (#2865) + if ( s.username ) { + xhr.open( s.type, s.url, s.async, s.username, s.password ); + } else { + xhr.open( s.type, s.url, s.async ); + } + + // Apply custom fields if provided + if ( s.xhrFields ) { + for ( i in s.xhrFields ) { + xhr[ i ] = s.xhrFields[ i ]; + } + } + + // Override mime type if needed + if ( s.mimeType && xhr.overrideMimeType ) { + xhr.overrideMimeType( s.mimeType ); + } + + // X-Requested-With header + // For cross-domain requests, seeing as conditions for a preflight are + // akin to a jigsaw puzzle, we simply never set it to be sure. + // (it can always be set on a per-request basis or even using ajaxSetup) + // For same-domain requests, won't change header if already provided. + if ( !s.crossDomain && !headers["X-Requested-With"] ) { + headers[ "X-Requested-With" ] = "XMLHttpRequest"; + } + + // Need an extra try/catch for cross domain requests in Firefox 3 + try { + for ( i in headers ) { + xhr.setRequestHeader( i, headers[ i ] ); + } + } catch( _ ) {} + + // Do send the request + // This may raise an exception which is actually + // handled in jQuery.ajax (so no try/catch here) + xhr.send( ( s.hasContent && s.data ) || null ); + + // Listener + callback = function( _, isAbort ) { + + var status, + statusText, + responseHeaders, + responses, + xml; + + // Firefox throws exceptions when accessing properties + // of an xhr when a network error occurred + // http://helpful.knobs-dials.com/index.php/Component_returned_failure_code:_0x80040111_(NS_ERROR_NOT_AVAILABLE) + try { + + // Was never called and is aborted or complete + if ( callback && ( isAbort || xhr.readyState === 4 ) ) { + + // Only called once + callback = undefined; + + // Do not keep as active anymore + if ( handle ) { + xhr.onreadystatechange = jQuery.noop; + if ( xhrOnUnloadAbort ) { + delete xhrCallbacks[ handle ]; + } + } + + // If it's an abort + if ( isAbort ) { + // Abort it manually if needed + if ( xhr.readyState !== 4 ) { + xhr.abort(); + } + } else { + status = xhr.status; + responseHeaders = xhr.getAllResponseHeaders(); + responses = {}; + xml = xhr.responseXML; + + // Construct response list + if ( xml && xml.documentElement /* #4958 */ ) { + responses.xml = xml; + } + + // When requesting binary data, IE6-9 will throw an exception + // on any attempt to access responseText (#11426) + try { + responses.text = xhr.responseText; + } catch( _ ) { + } + + // Firefox throws an exception when accessing + // statusText for faulty cross-domain requests + try { + statusText = xhr.statusText; + } catch( e ) { + // We normalize with Webkit giving an empty statusText + statusText = ""; + } + + // Filter status for non standard behaviors + + // If the request is local and we have data: assume a success + // (success with no data won't get notified, that's the best we + // can do given current implementations) + if ( !status && s.isLocal && !s.crossDomain ) { + status = responses.text ? 200 : 404; + // IE - #1450: sometimes returns 1223 when it should be 204 + } else if ( status === 1223 ) { + status = 204; + } + } + } + } catch( firefoxAccessException ) { + if ( !isAbort ) { + complete( -1, firefoxAccessException ); + } + } + + // Call complete if needed + if ( responses ) { + complete( status, statusText, responses, responseHeaders ); + } + }; + + if ( !s.async ) { + // if we're in sync mode we fire the callback + callback(); + } else if ( xhr.readyState === 4 ) { + // (IE6 & IE7) if it's in cache and has been + // retrieved directly we need to fire the callback + setTimeout( callback, 0 ); + } else { + handle = ++xhrId; + if ( xhrOnUnloadAbort ) { + // Create the active xhrs callbacks list if needed + // and attach the unload handler + if ( !xhrCallbacks ) { + xhrCallbacks = {}; + jQuery( window ).unload( xhrOnUnloadAbort ); + } + // Add to list of active xhrs callbacks + xhrCallbacks[ handle ] = callback; + } + xhr.onreadystatechange = callback; + } + }, + + abort: function() { + if ( callback ) { + callback(0,1); + } + } + }; + } + }); +} +var fxNow, timerId, + rfxtypes = /^(?:toggle|show|hide)$/, + rfxnum = new RegExp( "^(?:([-+])=|)(" + core_pnum + ")([a-z%]*)$", "i" ), + rrun = /queueHooks$/, + animationPrefilters = [ defaultPrefilter ], + tweeners = { + "*": [function( prop, value ) { + var end, unit, prevScale, + tween = this.createTween( prop, value ), + parts = rfxnum.exec( value ), + target = tween.cur(), + start = +target || 0, + scale = 1; + + if ( parts ) { + end = +parts[2]; + unit = parts[3] || ( jQuery.cssNumber[ prop ] ? "" : "px" ); + + // We need to compute starting value + if ( unit !== "px" && start ) { + // Iteratively approximate from a nonzero starting point + // Prefer the current property, because this process will be trivial if it uses the same units + // Fallback to end or a simple constant + start = jQuery.css( tween.elem, prop, true ) || end || 1; + + do { + // If previous iteration zeroed out, double until we get *something* + // Use a string for doubling factor so we don't accidentally see scale as unchanged below + prevScale = scale = scale || ".5"; + + // Adjust and apply + start = start / scale; + jQuery.style( tween.elem, prop, start + unit ); + + // Update scale, tolerating zeroes from tween.cur() + scale = tween.cur() / target; + + // Stop looping if we've hit the mark or scale is unchanged + } while ( scale !== 1 && scale !== prevScale ); + } + + tween.unit = unit; + tween.start = start; + // If a +=/-= token was provided, we're doing a relative animation + tween.end = parts[1] ? start + ( parts[1] + 1 ) * end : end; + } + return tween; + }] + }; + +// Animations created synchronously will run synchronously +function createFxNow() { + setTimeout(function() { + fxNow = undefined; + }, 0 ); + return ( fxNow = jQuery.now() ); +} + +function createTweens( animation, props ) { + jQuery.each( props, function( prop, value ) { + var collection = ( tweeners[ prop ] || [] ).concat( tweeners[ "*" ] ), + index = 0, + length = collection.length; + for ( ; index < length; index++ ) { + if ( collection[ index ].call( animation, prop, value ) ) { + + // we're done with this property + return; + } + } + }); +} + +function Animation( elem, properties, options ) { + var result, + index = 0, + tweenerIndex = 0, + length = animationPrefilters.length, + deferred = jQuery.Deferred().always( function() { + // don't match elem in the :animated selector + delete tick.elem; + }), + tick = function() { + var currentTime = fxNow || createFxNow(), + remaining = Math.max( 0, animation.startTime + animation.duration - currentTime ), + percent = 1 - ( remaining / animation.duration || 0 ), + index = 0, + length = animation.tweens.length; + + for ( ; index < length ; index++ ) { + animation.tweens[ index ].run( percent ); + } + + deferred.notifyWith( elem, [ animation, percent, remaining ]); + + if ( percent < 1 && length ) { + return remaining; + } else { + deferred.resolveWith( elem, [ animation ] ); + return false; + } + }, + animation = deferred.promise({ + elem: elem, + props: jQuery.extend( {}, properties ), + opts: jQuery.extend( true, { specialEasing: {} }, options ), + originalProperties: properties, + originalOptions: options, + startTime: fxNow || createFxNow(), + duration: options.duration, + tweens: [], + createTween: function( prop, end, easing ) { + var tween = jQuery.Tween( elem, animation.opts, prop, end, + animation.opts.specialEasing[ prop ] || animation.opts.easing ); + animation.tweens.push( tween ); + return tween; + }, + stop: function( gotoEnd ) { + var index = 0, + // if we are going to the end, we want to run all the tweens + // otherwise we skip this part + length = gotoEnd ? animation.tweens.length : 0; + + for ( ; index < length ; index++ ) { + animation.tweens[ index ].run( 1 ); + } + + // resolve when we played the last frame + // otherwise, reject + if ( gotoEnd ) { + deferred.resolveWith( elem, [ animation, gotoEnd ] ); + } else { + deferred.rejectWith( elem, [ animation, gotoEnd ] ); + } + return this; + } + }), + props = animation.props; + + propFilter( props, animation.opts.specialEasing ); + + for ( ; index < length ; index++ ) { + result = animationPrefilters[ index ].call( animation, elem, props, animation.opts ); + if ( result ) { + return result; + } + } + + createTweens( animation, props ); + + if ( jQuery.isFunction( animation.opts.start ) ) { + animation.opts.start.call( elem, animation ); + } + + jQuery.fx.timer( + jQuery.extend( tick, { + anim: animation, + queue: animation.opts.queue, + elem: elem + }) + ); + + // attach callbacks from options + return animation.progress( animation.opts.progress ) + .done( animation.opts.done, animation.opts.complete ) + .fail( animation.opts.fail ) + .always( animation.opts.always ); +} + +function propFilter( props, specialEasing ) { + var index, name, easing, value, hooks; + + // camelCase, specialEasing and expand cssHook pass + for ( index in props ) { + name = jQuery.camelCase( index ); + easing = specialEasing[ name ]; + value = props[ index ]; + if ( jQuery.isArray( value ) ) { + easing = value[ 1 ]; + value = props[ index ] = value[ 0 ]; + } + + if ( index !== name ) { + props[ name ] = value; + delete props[ index ]; + } + + hooks = jQuery.cssHooks[ name ]; + if ( hooks && "expand" in hooks ) { + value = hooks.expand( value ); + delete props[ name ]; + + // not quite $.extend, this wont overwrite keys already present. + // also - reusing 'index' from above because we have the correct "name" + for ( index in value ) { + if ( !( index in props ) ) { + props[ index ] = value[ index ]; + specialEasing[ index ] = easing; + } + } + } else { + specialEasing[ name ] = easing; + } + } +} + +jQuery.Animation = jQuery.extend( Animation, { + + tweener: function( props, callback ) { + if ( jQuery.isFunction( props ) ) { + callback = props; + props = [ "*" ]; + } else { + props = props.split(" "); + } + + var prop, + index = 0, + length = props.length; + + for ( ; index < length ; index++ ) { + prop = props[ index ]; + tweeners[ prop ] = tweeners[ prop ] || []; + tweeners[ prop ].unshift( callback ); + } + }, + + prefilter: function( callback, prepend ) { + if ( prepend ) { + animationPrefilters.unshift( callback ); + } else { + animationPrefilters.push( callback ); + } + } +}); + +function defaultPrefilter( elem, props, opts ) { + var index, prop, value, length, dataShow, tween, hooks, oldfire, + anim = this, + style = elem.style, + orig = {}, + handled = [], + hidden = elem.nodeType && isHidden( elem ); + + // handle queue: false promises + if ( !opts.queue ) { + hooks = jQuery._queueHooks( elem, "fx" ); + if ( hooks.unqueued == null ) { + hooks.unqueued = 0; + oldfire = hooks.empty.fire; + hooks.empty.fire = function() { + if ( !hooks.unqueued ) { + oldfire(); + } + }; + } + hooks.unqueued++; + + anim.always(function() { + // doing this makes sure that the complete handler will be called + // before this completes + anim.always(function() { + hooks.unqueued--; + if ( !jQuery.queue( elem, "fx" ).length ) { + hooks.empty.fire(); + } + }); + }); + } + + // height/width overflow pass + if ( elem.nodeType === 1 && ( "height" in props || "width" in props ) ) { + // Make sure that nothing sneaks out + // Record all 3 overflow attributes because IE does not + // change the overflow attribute when overflowX and + // overflowY are set to the same value + opts.overflow = [ style.overflow, style.overflowX, style.overflowY ]; + + // Set display property to inline-block for height/width + // animations on inline elements that are having width/height animated + if ( jQuery.css( elem, "display" ) === "inline" && + jQuery.css( elem, "float" ) === "none" ) { + + // inline-level elements accept inline-block; + // block-level elements need to be inline with layout + if ( !jQuery.support.inlineBlockNeedsLayout || css_defaultDisplay( elem.nodeName ) === "inline" ) { + style.display = "inline-block"; + + } else { + style.zoom = 1; + } + } + } + + if ( opts.overflow ) { + style.overflow = "hidden"; + if ( !jQuery.support.shrinkWrapBlocks ) { + anim.done(function() { + style.overflow = opts.overflow[ 0 ]; + style.overflowX = opts.overflow[ 1 ]; + style.overflowY = opts.overflow[ 2 ]; + }); + } + } + + + // show/hide pass + for ( index in props ) { + value = props[ index ]; + if ( rfxtypes.exec( value ) ) { + delete props[ index ]; + if ( value === ( hidden ? "hide" : "show" ) ) { + continue; + } + handled.push( index ); + } + } + + length = handled.length; + if ( length ) { + dataShow = jQuery._data( elem, "fxshow" ) || jQuery._data( elem, "fxshow", {} ); + if ( hidden ) { + jQuery( elem ).show(); + } else { + anim.done(function() { + jQuery( elem ).hide(); + }); + } + anim.done(function() { + var prop; + jQuery.removeData( elem, "fxshow", true ); + for ( prop in orig ) { + jQuery.style( elem, prop, orig[ prop ] ); + } + }); + for ( index = 0 ; index < length ; index++ ) { + prop = handled[ index ]; + tween = anim.createTween( prop, hidden ? dataShow[ prop ] : 0 ); + orig[ prop ] = dataShow[ prop ] || jQuery.style( elem, prop ); + + if ( !( prop in dataShow ) ) { + dataShow[ prop ] = tween.start; + if ( hidden ) { + tween.end = tween.start; + tween.start = prop === "width" || prop === "height" ? 1 : 0; + } + } + } + } +} + +function Tween( elem, options, prop, end, easing ) { + return new Tween.prototype.init( elem, options, prop, end, easing ); +} +jQuery.Tween = Tween; + +Tween.prototype = { + constructor: Tween, + init: function( elem, options, prop, end, easing, unit ) { + this.elem = elem; + this.prop = prop; + this.easing = easing || "swing"; + this.options = options; + this.start = this.now = this.cur(); + this.end = end; + this.unit = unit || ( jQuery.cssNumber[ prop ] ? "" : "px" ); + }, + cur: function() { + var hooks = Tween.propHooks[ this.prop ]; + + return hooks && hooks.get ? + hooks.get( this ) : + Tween.propHooks._default.get( this ); + }, + run: function( percent ) { + var eased, + hooks = Tween.propHooks[ this.prop ]; + + if ( this.options.duration ) { + this.pos = eased = jQuery.easing[ this.easing ]( + percent, this.options.duration * percent, 0, 1, this.options.duration + ); + } else { + this.pos = eased = percent; + } + this.now = ( this.end - this.start ) * eased + this.start; + + if ( this.options.step ) { + this.options.step.call( this.elem, this.now, this ); + } + + if ( hooks && hooks.set ) { + hooks.set( this ); + } else { + Tween.propHooks._default.set( this ); + } + return this; + } +}; + +Tween.prototype.init.prototype = Tween.prototype; + +Tween.propHooks = { + _default: { + get: function( tween ) { + var result; + + if ( tween.elem[ tween.prop ] != null && + (!tween.elem.style || tween.elem.style[ tween.prop ] == null) ) { + return tween.elem[ tween.prop ]; + } + + // passing any value as a 4th parameter to .css will automatically + // attempt a parseFloat and fallback to a string if the parse fails + // so, simple values such as "10px" are parsed to Float. + // complex values such as "rotate(1rad)" are returned as is. + result = jQuery.css( tween.elem, tween.prop, false, "" ); + // Empty strings, null, undefined and "auto" are converted to 0. + return !result || result === "auto" ? 0 : result; + }, + set: function( tween ) { + // use step hook for back compat - use cssHook if its there - use .style if its + // available and use plain properties where available + if ( jQuery.fx.step[ tween.prop ] ) { + jQuery.fx.step[ tween.prop ]( tween ); + } else if ( tween.elem.style && ( tween.elem.style[ jQuery.cssProps[ tween.prop ] ] != null || jQuery.cssHooks[ tween.prop ] ) ) { + jQuery.style( tween.elem, tween.prop, tween.now + tween.unit ); + } else { + tween.elem[ tween.prop ] = tween.now; + } + } + } +}; + +// Remove in 2.0 - this supports IE8's panic based approach +// to setting things on disconnected nodes + +Tween.propHooks.scrollTop = Tween.propHooks.scrollLeft = { + set: function( tween ) { + if ( tween.elem.nodeType && tween.elem.parentNode ) { + tween.elem[ tween.prop ] = tween.now; + } + } +}; + +jQuery.each([ "toggle", "show", "hide" ], function( i, name ) { + var cssFn = jQuery.fn[ name ]; + jQuery.fn[ name ] = function( speed, easing, callback ) { + return speed == null || typeof speed === "boolean" || + // special check for .toggle( handler, handler, ... ) + ( !i && jQuery.isFunction( speed ) && jQuery.isFunction( easing ) ) ? + cssFn.apply( this, arguments ) : + this.animate( genFx( name, true ), speed, easing, callback ); + }; +}); + +jQuery.fn.extend({ + fadeTo: function( speed, to, easing, callback ) { + + // show any hidden elements after setting opacity to 0 + return this.filter( isHidden ).css( "opacity", 0 ).show() + + // animate to the value specified + .end().animate({ opacity: to }, speed, easing, callback ); + }, + animate: function( prop, speed, easing, callback ) { + var empty = jQuery.isEmptyObject( prop ), + optall = jQuery.speed( speed, easing, callback ), + doAnimation = function() { + // Operate on a copy of prop so per-property easing won't be lost + var anim = Animation( this, jQuery.extend( {}, prop ), optall ); + + // Empty animations resolve immediately + if ( empty ) { + anim.stop( true ); + } + }; + + return empty || optall.queue === false ? + this.each( doAnimation ) : + this.queue( optall.queue, doAnimation ); + }, + stop: function( type, clearQueue, gotoEnd ) { + var stopQueue = function( hooks ) { + var stop = hooks.stop; + delete hooks.stop; + stop( gotoEnd ); + }; + + if ( typeof type !== "string" ) { + gotoEnd = clearQueue; + clearQueue = type; + type = undefined; + } + if ( clearQueue && type !== false ) { + this.queue( type || "fx", [] ); + } + + return this.each(function() { + var dequeue = true, + index = type != null && type + "queueHooks", + timers = jQuery.timers, + data = jQuery._data( this ); + + if ( index ) { + if ( data[ index ] && data[ index ].stop ) { + stopQueue( data[ index ] ); + } + } else { + for ( index in data ) { + if ( data[ index ] && data[ index ].stop && rrun.test( index ) ) { + stopQueue( data[ index ] ); + } + } + } + + for ( index = timers.length; index--; ) { + if ( timers[ index ].elem === this && (type == null || timers[ index ].queue === type) ) { + timers[ index ].anim.stop( gotoEnd ); + dequeue = false; + timers.splice( index, 1 ); + } + } + + // start the next in the queue if the last step wasn't forced + // timers currently will call their complete callbacks, which will dequeue + // but only if they were gotoEnd + if ( dequeue || !gotoEnd ) { + jQuery.dequeue( this, type ); + } + }); + } +}); + +// Generate parameters to create a standard animation +function genFx( type, includeWidth ) { + var which, + attrs = { height: type }, + i = 0; + + // if we include width, step value is 1 to do all cssExpand values, + // if we don't include width, step value is 2 to skip over Left and Right + includeWidth = includeWidth? 1 : 0; + for( ; i < 4 ; i += 2 - includeWidth ) { + which = cssExpand[ i ]; + attrs[ "margin" + which ] = attrs[ "padding" + which ] = type; + } + + if ( includeWidth ) { + attrs.opacity = attrs.width = type; + } + + return attrs; +} + +// Generate shortcuts for custom animations +jQuery.each({ + slideDown: genFx("show"), + slideUp: genFx("hide"), + slideToggle: genFx("toggle"), + fadeIn: { opacity: "show" }, + fadeOut: { opacity: "hide" }, + fadeToggle: { opacity: "toggle" } +}, function( name, props ) { + jQuery.fn[ name ] = function( speed, easing, callback ) { + return this.animate( props, speed, easing, callback ); + }; +}); + +jQuery.speed = function( speed, easing, fn ) { + var opt = speed && typeof speed === "object" ? jQuery.extend( {}, speed ) : { + complete: fn || !fn && easing || + jQuery.isFunction( speed ) && speed, + duration: speed, + easing: fn && easing || easing && !jQuery.isFunction( easing ) && easing + }; + + opt.duration = jQuery.fx.off ? 0 : typeof opt.duration === "number" ? opt.duration : + opt.duration in jQuery.fx.speeds ? jQuery.fx.speeds[ opt.duration ] : jQuery.fx.speeds._default; + + // normalize opt.queue - true/undefined/null -> "fx" + if ( opt.queue == null || opt.queue === true ) { + opt.queue = "fx"; + } + + // Queueing + opt.old = opt.complete; + + opt.complete = function() { + if ( jQuery.isFunction( opt.old ) ) { + opt.old.call( this ); + } + + if ( opt.queue ) { + jQuery.dequeue( this, opt.queue ); + } + }; + + return opt; +}; + +jQuery.easing = { + linear: function( p ) { + return p; + }, + swing: function( p ) { + return 0.5 - Math.cos( p*Math.PI ) / 2; + } +}; + +jQuery.timers = []; +jQuery.fx = Tween.prototype.init; +jQuery.fx.tick = function() { + var timer, + timers = jQuery.timers, + i = 0; + + for ( ; i < timers.length; i++ ) { + timer = timers[ i ]; + // Checks the timer has not already been removed + if ( !timer() && timers[ i ] === timer ) { + timers.splice( i--, 1 ); + } + } + + if ( !timers.length ) { + jQuery.fx.stop(); + } +}; + +jQuery.fx.timer = function( timer ) { + if ( timer() && jQuery.timers.push( timer ) && !timerId ) { + timerId = setInterval( jQuery.fx.tick, jQuery.fx.interval ); + } +}; + +jQuery.fx.interval = 13; + +jQuery.fx.stop = function() { + clearInterval( timerId ); + timerId = null; +}; + +jQuery.fx.speeds = { + slow: 600, + fast: 200, + // Default speed + _default: 400 +}; + +// Back Compat <1.8 extension point +jQuery.fx.step = {}; + +if ( jQuery.expr && jQuery.expr.filters ) { + jQuery.expr.filters.animated = function( elem ) { + return jQuery.grep(jQuery.timers, function( fn ) { + return elem === fn.elem; + }).length; + }; +} +var rroot = /^(?:body|html)$/i; + +jQuery.fn.offset = function( options ) { + if ( arguments.length ) { + return options === undefined ? + this : + this.each(function( i ) { + jQuery.offset.setOffset( this, options, i ); + }); + } + + var box, docElem, body, win, clientTop, clientLeft, scrollTop, scrollLeft, top, left, + elem = this[ 0 ], + doc = elem && elem.ownerDocument; + + if ( !doc ) { + return; + } + + if ( (body = doc.body) === elem ) { + return jQuery.offset.bodyOffset( elem ); + } + + docElem = doc.documentElement; + + // Make sure we're not dealing with a disconnected DOM node + if ( !jQuery.contains( docElem, elem ) ) { + return { top: 0, left: 0 }; + } + + box = elem.getBoundingClientRect(); + win = getWindow( doc ); + clientTop = docElem.clientTop || body.clientTop || 0; + clientLeft = docElem.clientLeft || body.clientLeft || 0; + scrollTop = win.pageYOffset || docElem.scrollTop; + scrollLeft = win.pageXOffset || docElem.scrollLeft; + top = box.top + scrollTop - clientTop; + left = box.left + scrollLeft - clientLeft; + + return { top: top, left: left }; +}; + +jQuery.offset = { + + bodyOffset: function( body ) { + var top = body.offsetTop, + left = body.offsetLeft; + + if ( jQuery.support.doesNotIncludeMarginInBodyOffset ) { + top += parseFloat( jQuery.css(body, "marginTop") ) || 0; + left += parseFloat( jQuery.css(body, "marginLeft") ) || 0; + } + + return { top: top, left: left }; + }, + + setOffset: function( elem, options, i ) { + var position = jQuery.css( elem, "position" ); + + // set position first, in-case top/left are set even on static elem + if ( position === "static" ) { + elem.style.position = "relative"; + } + + var curElem = jQuery( elem ), + curOffset = curElem.offset(), + curCSSTop = jQuery.css( elem, "top" ), + curCSSLeft = jQuery.css( elem, "left" ), + calculatePosition = ( position === "absolute" || position === "fixed" ) && jQuery.inArray("auto", [curCSSTop, curCSSLeft]) > -1, + props = {}, curPosition = {}, curTop, curLeft; + + // need to be able to calculate position if either top or left is auto and position is either absolute or fixed + if ( calculatePosition ) { + curPosition = curElem.position(); + curTop = curPosition.top; + curLeft = curPosition.left; + } else { + curTop = parseFloat( curCSSTop ) || 0; + curLeft = parseFloat( curCSSLeft ) || 0; + } + + if ( jQuery.isFunction( options ) ) { + options = options.call( elem, i, curOffset ); + } + + if ( options.top != null ) { + props.top = ( options.top - curOffset.top ) + curTop; + } + if ( options.left != null ) { + props.left = ( options.left - curOffset.left ) + curLeft; + } + + if ( "using" in options ) { + options.using.call( elem, props ); + } else { + curElem.css( props ); + } + } +}; + + +jQuery.fn.extend({ + + position: function() { + if ( !this[0] ) { + return; + } + + var elem = this[0], + + // Get *real* offsetParent + offsetParent = this.offsetParent(), + + // Get correct offsets + offset = this.offset(), + parentOffset = rroot.test(offsetParent[0].nodeName) ? { top: 0, left: 0 } : offsetParent.offset(); + + // Subtract element margins + // note: when an element has margin: auto the offsetLeft and marginLeft + // are the same in Safari causing offset.left to incorrectly be 0 + offset.top -= parseFloat( jQuery.css(elem, "marginTop") ) || 0; + offset.left -= parseFloat( jQuery.css(elem, "marginLeft") ) || 0; + + // Add offsetParent borders + parentOffset.top += parseFloat( jQuery.css(offsetParent[0], "borderTopWidth") ) || 0; + parentOffset.left += parseFloat( jQuery.css(offsetParent[0], "borderLeftWidth") ) || 0; + + // Subtract the two offsets + return { + top: offset.top - parentOffset.top, + left: offset.left - parentOffset.left + }; + }, + + offsetParent: function() { + return this.map(function() { + var offsetParent = this.offsetParent || document.body; + while ( offsetParent && (!rroot.test(offsetParent.nodeName) && jQuery.css(offsetParent, "position") === "static") ) { + offsetParent = offsetParent.offsetParent; + } + return offsetParent || document.body; + }); + } +}); + + +// Create scrollLeft and scrollTop methods +jQuery.each( {scrollLeft: "pageXOffset", scrollTop: "pageYOffset"}, function( method, prop ) { + var top = /Y/.test( prop ); + + jQuery.fn[ method ] = function( val ) { + return jQuery.access( this, function( elem, method, val ) { + var win = getWindow( elem ); + + if ( val === undefined ) { + return win ? (prop in win) ? win[ prop ] : + win.document.documentElement[ method ] : + elem[ method ]; + } + + if ( win ) { + win.scrollTo( + !top ? val : jQuery( win ).scrollLeft(), + top ? val : jQuery( win ).scrollTop() + ); + + } else { + elem[ method ] = val; + } + }, method, val, arguments.length, null ); + }; +}); + +function getWindow( elem ) { + return jQuery.isWindow( elem ) ? + elem : + elem.nodeType === 9 ? + elem.defaultView || elem.parentWindow : + false; +} +// Create innerHeight, innerWidth, height, width, outerHeight and outerWidth methods +jQuery.each( { Height: "height", Width: "width" }, function( name, type ) { + jQuery.each( { padding: "inner" + name, content: type, "": "outer" + name }, function( defaultExtra, funcName ) { + // margin is only for outerHeight, outerWidth + jQuery.fn[ funcName ] = function( margin, value ) { + var chainable = arguments.length && ( defaultExtra || typeof margin !== "boolean" ), + extra = defaultExtra || ( margin === true || value === true ? "margin" : "border" ); + + return jQuery.access( this, function( elem, type, value ) { + var doc; + + if ( jQuery.isWindow( elem ) ) { + // As of 5/8/2012 this will yield incorrect results for Mobile Safari, but there + // isn't a whole lot we can do. See pull request at this URL for discussion: + // https://github.com/jquery/jquery/pull/764 + return elem.document.documentElement[ "client" + name ]; + } + + // Get document width or height + if ( elem.nodeType === 9 ) { + doc = elem.documentElement; + + // Either scroll[Width/Height] or offset[Width/Height] or client[Width/Height], whichever is greatest + // unfortunately, this causes bug #3838 in IE6/8 only, but there is currently no good, small way to fix it. + return Math.max( + elem.body[ "scroll" + name ], doc[ "scroll" + name ], + elem.body[ "offset" + name ], doc[ "offset" + name ], + doc[ "client" + name ] + ); + } + + return value === undefined ? + // Get width or height on the element, requesting but not forcing parseFloat + jQuery.css( elem, type, value, extra ) : + + // Set width or height on the element + jQuery.style( elem, type, value, extra ); + }, type, chainable ? margin : undefined, chainable, null ); + }; + }); +}); +// Expose jQuery to the global object +window.jQuery = window.$ = jQuery; + +// Expose jQuery as an AMD module, but only for AMD loaders that +// understand the issues with loading multiple versions of jQuery +// in a page that all might call define(). The loader will indicate +// they have special allowances for multiple jQuery versions by +// specifying define.amd.jQuery = true. Register as a named module, +// since jQuery can be concatenated with other files that may use define, +// but not use a proper concatenation script that understands anonymous +// AMD modules. A named AMD is safest and most robust way to register. +// Lowercase jquery is used because AMD module names are derived from +// file names, and jQuery is normally delivered in a lowercase file name. +// Do this after creating the global so that if an AMD module wants to call +// noConflict to hide this version of jQuery, it will work. +if ( typeof define === "function" && define.amd && define.amd.jQuery ) { + define( "jquery", [], function () { return jQuery; } ); +} + +})( window ); diff --git a/htdocs/js/lib/webwork/components/underscore/CNAME b/htdocs/js/lib/webwork/components/underscore/CNAME new file mode 100644 index 000000000..a007e65c4 --- /dev/null +++ b/htdocs/js/lib/webwork/components/underscore/CNAME @@ -0,0 +1 @@ +underscorejs.org diff --git a/htdocs/js/lib/webwork/components/underscore/CONTRIBUTING.md b/htdocs/js/lib/webwork/components/underscore/CONTRIBUTING.md new file mode 100644 index 000000000..36a993467 --- /dev/null +++ b/htdocs/js/lib/webwork/components/underscore/CONTRIBUTING.md @@ -0,0 +1,9 @@ +## How to contribute to Underscore.js + +* Before you open a ticket or send a pull request, [search](https://github.com/documentcloud/underscore/issues) for previous discussions about the same feature or issue. Add to the earlier ticket if you find one. + +* Before sending a pull request for a feature, be sure to have [tests](http://underscorejs.org/test/test.html). + +* Use the same coding style as the rest of the [codebase](https://github.com/documentcloud/underscore/blob/master/underscore.js). + +* In your pull request, do not add documentation or re-build the minified `underscore-min.js` file. We'll do those things before cutting a new release. \ No newline at end of file diff --git a/htdocs/js/lib/webwork/components/underscore/LICENSE b/htdocs/js/lib/webwork/components/underscore/LICENSE new file mode 100644 index 000000000..61d28c08e --- /dev/null +++ b/htdocs/js/lib/webwork/components/underscore/LICENSE @@ -0,0 +1,22 @@ +Copyright (c) 2009-2012 Jeremy Ashkenas, DocumentCloud + +Permission is hereby granted, free of charge, to any person +obtaining a copy of this software and associated documentation +files (the "Software"), to deal in the Software without +restriction, including without limitation the rights to use, +copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the +Software is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. \ No newline at end of file diff --git a/htdocs/js/lib/webwork/components/underscore/README.md b/htdocs/js/lib/webwork/components/underscore/README.md new file mode 100644 index 000000000..b1f3e50a8 --- /dev/null +++ b/htdocs/js/lib/webwork/components/underscore/README.md @@ -0,0 +1,19 @@ + __ + /\ \ __ + __ __ ___ \_\ \ __ _ __ ____ ___ ___ _ __ __ /\_\ ____ + /\ \/\ \ /' _ `\ /'_ \ /'__`\/\ __\/ ,__\ / ___\ / __`\/\ __\/'__`\ \/\ \ /',__\ + \ \ \_\ \/\ \/\ \/\ \ \ \/\ __/\ \ \//\__, `\/\ \__//\ \ \ \ \ \//\ __/ __ \ \ \/\__, `\ + \ \____/\ \_\ \_\ \___,_\ \____\\ \_\\/\____/\ \____\ \____/\ \_\\ \____\/\_\ _\ \ \/\____/ + \/___/ \/_/\/_/\/__,_ /\/____/ \/_/ \/___/ \/____/\/___/ \/_/ \/____/\/_//\ \_\ \/___/ + \ \____/ + \/___/ + +Underscore.js is a utility-belt library for JavaScript that provides +support for the usual functional suspects (each, map, reduce, filter...) +without extending any core JavaScript objects. + +For Docs, License, Tests, and pre-packed downloads, see: +http://underscorejs.org + +Many thanks to our contributors: +https://github.com/documentcloud/underscore/contributors diff --git a/htdocs/js/lib/webwork/components/underscore/Rakefile b/htdocs/js/lib/webwork/components/underscore/Rakefile new file mode 100644 index 000000000..b9fd1ca46 --- /dev/null +++ b/htdocs/js/lib/webwork/components/underscore/Rakefile @@ -0,0 +1,15 @@ +require 'rubygems' +require 'uglifier' + +desc "Use the Closure Compiler to compress Underscore.js" +task :build do + source = File.read('underscore.js') + min = Uglifier.compile(source) + File.open('underscore-min.js', 'w') {|f| f.write min } +end + +desc "Build the docco documentation" +task :doc do + sh "docco underscore.js" +end + diff --git a/htdocs/js/lib/webwork/components/underscore/component.json b/htdocs/js/lib/webwork/components/underscore/component.json new file mode 100644 index 000000000..1ca66174c --- /dev/null +++ b/htdocs/js/lib/webwork/components/underscore/component.json @@ -0,0 +1,24 @@ +{ + "name": "underscore", + "description": "JavaScript's functional programming helper library.", + "homepage": "http://underscorejs.org", + "keywords": [ + "util", + "functional", + "server", + "client", + "browser" + ], + "author": { + "name": "Jeremy Ashkenas", + "email": "jeremy@documentcloud.org" + }, + "repository": { + "type": "git", + "url": "git://github.com/documentcloud/underscore.git" + }, + "main": "underscore.js", + "version": "1.4.2", + "readme": " __\n /\\ \\ __\n __ __ ___ \\_\\ \\ __ _ __ ____ ___ ___ _ __ __ /\\_\\ ____\n /\\ \\/\\ \\ /' _ `\\ /'_ \\ /'__`\\/\\ __\\/ ,__\\ / ___\\ / __`\\/\\ __\\/'__`\\ \\/\\ \\ /',__\\\n \\ \\ \\_\\ \\/\\ \\/\\ \\/\\ \\ \\ \\/\\ __/\\ \\ \\//\\__, `\\/\\ \\__//\\ \\ \\ \\ \\ \\//\\ __/ __ \\ \\ \\/\\__, `\\\n \\ \\____/\\ \\_\\ \\_\\ \\___,_\\ \\____\\\\ \\_\\\\/\\____/\\ \\____\\ \\____/\\ \\_\\\\ \\____\\/\\_\\ _\\ \\ \\/\\____/\n \\/___/ \\/_/\\/_/\\/__,_ /\\/____/ \\/_/ \\/___/ \\/____/\\/___/ \\/_/ \\/____/\\/_//\\ \\_\\ \\/___/\n \\ \\____/\n \\/___/\n\nUnderscore.js is a utility-belt library for JavaScript that provides\nsupport for the usual functional suspects (each, map, reduce, filter...)\nwithout extending any core JavaScript objects.\n\nFor Docs, License, Tests, and pre-packed downloads, see:\nhttp://underscorejs.org\n\nMany thanks to our contributors:\nhttps://github.com/documentcloud/underscore/contributors\n", + "_id": "underscore@1.4.2" +} \ No newline at end of file diff --git a/htdocs/js/lib/webwork/components/underscore/docs/docco.css b/htdocs/js/lib/webwork/components/underscore/docs/docco.css new file mode 100644 index 000000000..04cc7ecb8 --- /dev/null +++ b/htdocs/js/lib/webwork/components/underscore/docs/docco.css @@ -0,0 +1,192 @@ +/*--------------------- Layout and Typography ----------------------------*/ +body { + font-family: 'Palatino Linotype', 'Book Antiqua', Palatino, FreeSerif, serif; + font-size: 15px; + line-height: 22px; + color: #252519; + margin: 0; padding: 0; +} +a { + color: #261a3b; +} + a:visited { + color: #261a3b; + } +p { + margin: 0 0 15px 0; +} +h1, h2, h3, h4, h5, h6 { + margin: 0px 0 15px 0; +} + h1 { + margin-top: 40px; + } +hr { + border: 0 none; + border-top: 1px solid #e5e5ee; + height: 1px; + margin: 20px 0; +} +#container { + position: relative; +} +#background { + position: fixed; + top: 0; left: 525px; right: 0; bottom: 0; + background: #f5f5ff; + border-left: 1px solid #e5e5ee; + z-index: -1; +} +#jump_to, #jump_page { + background: white; + -webkit-box-shadow: 0 0 25px #777; -moz-box-shadow: 0 0 25px #777; + -webkit-border-bottom-left-radius: 5px; -moz-border-radius-bottomleft: 5px; + font: 10px Arial; + text-transform: uppercase; + cursor: pointer; + text-align: right; +} +#jump_to, #jump_wrapper { + position: fixed; + right: 0; top: 0; + padding: 5px 10px; +} + #jump_wrapper { + padding: 0; + display: none; + } + #jump_to:hover #jump_wrapper { + display: block; + } + #jump_page { + padding: 5px 0 3px; + margin: 0 0 25px 25px; + } + #jump_page .source { + display: block; + padding: 5px 10px; + text-decoration: none; + border-top: 1px solid #eee; + } + #jump_page .source:hover { + background: #f5f5ff; + } + #jump_page .source:first-child { + } +table td { + border: 0; + outline: 0; +} + td.docs, th.docs { + max-width: 450px; + min-width: 450px; + min-height: 5px; + padding: 10px 25px 1px 50px; + overflow-x: hidden; + vertical-align: top; + text-align: left; + } + .docs pre { + margin: 15px 0 15px; + padding-left: 15px; + } + .docs p tt, .docs p code { + background: #f8f8ff; + border: 1px solid #dedede; + font-size: 12px; + padding: 0 0.2em; + } + .pilwrap { + position: relative; + } + .pilcrow { + font: 12px Arial; + text-decoration: none; + color: #454545; + position: absolute; + top: 3px; left: -20px; + padding: 1px 2px; + opacity: 0; + -webkit-transition: opacity 0.2s linear; + } + td.docs:hover .pilcrow { + opacity: 1; + } + td.code, th.code { + padding: 14px 15px 16px 25px; + width: 100%; + vertical-align: top; + background: #f5f5ff; + border-left: 1px solid #e5e5ee; + } + pre, tt, code { + font-size: 12px; line-height: 18px; + font-family: Menlo, Monaco, Consolas, "Lucida Console", monospace; + margin: 0; padding: 0; + } + + +/*---------------------- Syntax Highlighting -----------------------------*/ +td.linenos { background-color: #f0f0f0; padding-right: 10px; } +span.lineno { background-color: #f0f0f0; padding: 0 5px 0 5px; } +body .hll { background-color: #ffffcc } +body .c { color: #408080; font-style: italic } /* Comment */ +body .err { border: 1px solid #FF0000 } /* Error */ +body .k { color: #954121 } /* Keyword */ +body .o { color: #666666 } /* Operator */ +body .cm { color: #408080; font-style: italic } /* Comment.Multiline */ +body .cp { color: #BC7A00 } /* Comment.Preproc */ +body .c1 { color: #408080; font-style: italic } /* Comment.Single */ +body .cs { color: #408080; font-style: italic } /* Comment.Special */ +body .gd { color: #A00000 } /* Generic.Deleted */ +body .ge { font-style: italic } /* Generic.Emph */ +body .gr { color: #FF0000 } /* Generic.Error */ +body .gh { color: #000080; font-weight: bold } /* Generic.Heading */ +body .gi { color: #00A000 } /* Generic.Inserted */ +body .go { color: #808080 } /* Generic.Output */ +body .gp { color: #000080; font-weight: bold } /* Generic.Prompt */ +body .gs { font-weight: bold } /* Generic.Strong */ +body .gu { color: #800080; font-weight: bold } /* Generic.Subheading */ +body .gt { color: #0040D0 } /* Generic.Traceback */ +body .kc { color: #954121 } /* Keyword.Constant */ +body .kd { color: #954121; font-weight: bold } /* Keyword.Declaration */ +body .kn { color: #954121; font-weight: bold } /* Keyword.Namespace */ +body .kp { color: #954121 } /* Keyword.Pseudo */ +body .kr { color: #954121; font-weight: bold } /* Keyword.Reserved */ +body .kt { color: #B00040 } /* Keyword.Type */ +body .m { color: #666666 } /* Literal.Number */ +body .s { color: #219161 } /* Literal.String */ +body .na { color: #7D9029 } /* Name.Attribute */ +body .nb { color: #954121 } /* Name.Builtin */ +body .nc { color: #0000FF; font-weight: bold } /* Name.Class */ +body .no { color: #880000 } /* Name.Constant */ +body .nd { color: #AA22FF } /* Name.Decorator */ +body .ni { color: #999999; font-weight: bold } /* Name.Entity */ +body .ne { color: #D2413A; font-weight: bold } /* Name.Exception */ +body .nf { color: #0000FF } /* Name.Function */ +body .nl { color: #A0A000 } /* Name.Label */ +body .nn { color: #0000FF; font-weight: bold } /* Name.Namespace */ +body .nt { color: #954121; font-weight: bold } /* Name.Tag */ +body .nv { color: #19469D } /* Name.Variable */ +body .ow { color: #AA22FF; font-weight: bold } /* Operator.Word */ +body .w { color: #bbbbbb } /* Text.Whitespace */ +body .mf { color: #666666 } /* Literal.Number.Float */ +body .mh { color: #666666 } /* Literal.Number.Hex */ +body .mi { color: #666666 } /* Literal.Number.Integer */ +body .mo { color: #666666 } /* Literal.Number.Oct */ +body .sb { color: #219161 } /* Literal.String.Backtick */ +body .sc { color: #219161 } /* Literal.String.Char */ +body .sd { color: #219161; font-style: italic } /* Literal.String.Doc */ +body .s2 { color: #219161 } /* Literal.String.Double */ +body .se { color: #BB6622; font-weight: bold } /* Literal.String.Escape */ +body .sh { color: #219161 } /* Literal.String.Heredoc */ +body .si { color: #BB6688; font-weight: bold } /* Literal.String.Interpol */ +body .sx { color: #954121 } /* Literal.String.Other */ +body .sr { color: #BB6688 } /* Literal.String.Regex */ +body .s1 { color: #219161 } /* Literal.String.Single */ +body .ss { color: #19469D } /* Literal.String.Symbol */ +body .bp { color: #954121 } /* Name.Builtin.Pseudo */ +body .vc { color: #19469D } /* Name.Variable.Class */ +body .vg { color: #19469D } /* Name.Variable.Global */ +body .vi { color: #19469D } /* Name.Variable.Instance */ +body .il { color: #666666 } /* Literal.Number.Integer.Long */ \ No newline at end of file diff --git a/htdocs/js/lib/webwork/components/underscore/docs/favicon.ico b/htdocs/js/lib/webwork/components/underscore/docs/favicon.ico new file mode 100644 index 000000000..030496838 Binary files /dev/null and b/htdocs/js/lib/webwork/components/underscore/docs/favicon.ico differ diff --git a/htdocs/js/lib/webwork/components/underscore/docs/images/background.png b/htdocs/js/lib/webwork/components/underscore/docs/images/background.png new file mode 100644 index 000000000..90ee6934d Binary files /dev/null and b/htdocs/js/lib/webwork/components/underscore/docs/images/background.png differ diff --git a/htdocs/js/lib/webwork/components/underscore/docs/images/underscore.png b/htdocs/js/lib/webwork/components/underscore/docs/images/underscore.png new file mode 100644 index 000000000..dce9edb0f Binary files /dev/null and b/htdocs/js/lib/webwork/components/underscore/docs/images/underscore.png differ diff --git a/htdocs/js/lib/webwork/components/underscore/docs/underscore.html b/htdocs/js/lib/webwork/components/underscore/docs/underscore.html new file mode 100644 index 000000000..1f4b86a94 --- /dev/null +++ b/htdocs/js/lib/webwork/components/underscore/docs/underscore.html @@ -0,0 +1,800 @@ + underscore.js

      underscore.js

      Underscore.js 1.4.2
      +http://underscorejs.org
      +(c) 2009-2012 Jeremy Ashkenas, DocumentCloud Inc.
      +Underscore may be freely distributed under the MIT license.
      +
      (function() {

      Baseline setup

      Establish the root object, window in the browser, or global on the server.

        var root = this;

      Save the previous value of the _ variable.

        var previousUnderscore = root._;

      Establish the object that gets returned to break out of a loop iteration.

        var breaker = {};

      Save bytes in the minified (but not gzipped) version:

        var ArrayProto = Array.prototype, ObjProto = Object.prototype, FuncProto = Function.prototype;

      Create quick reference variables for speed access to core prototypes.

        var push             = ArrayProto.push,
      +      slice            = ArrayProto.slice,
      +      concat           = ArrayProto.concat,
      +      unshift          = ArrayProto.unshift,
      +      toString         = ObjProto.toString,
      +      hasOwnProperty   = ObjProto.hasOwnProperty;

      All ECMAScript 5 native function implementations that we hope to use +are declared here.

        var
      +    nativeForEach      = ArrayProto.forEach,
      +    nativeMap          = ArrayProto.map,
      +    nativeReduce       = ArrayProto.reduce,
      +    nativeReduceRight  = ArrayProto.reduceRight,
      +    nativeFilter       = ArrayProto.filter,
      +    nativeEvery        = ArrayProto.every,
      +    nativeSome         = ArrayProto.some,
      +    nativeIndexOf      = ArrayProto.indexOf,
      +    nativeLastIndexOf  = ArrayProto.lastIndexOf,
      +    nativeIsArray      = Array.isArray,
      +    nativeKeys         = Object.keys,
      +    nativeBind         = FuncProto.bind;

      Create a safe reference to the Underscore object for use below.

        var _ = function(obj) {
      +    if (obj instanceof _) return obj;
      +    if (!(this instanceof _)) return new _(obj);
      +    this._wrapped = obj;
      +  };

      Export the Underscore object for Node.js, with +backwards-compatibility for the old require() API. If we're in +the browser, add _ as a global object via a string identifier, +for Closure Compiler "advanced" mode.

        if (typeof exports !== 'undefined') {
      +    if (typeof module !== 'undefined' && module.exports) {
      +      exports = module.exports = _;
      +    }
      +    exports._ = _;
      +  } else {
      +    root['_'] = _;
      +  }

      Current version.

        _.VERSION = '1.4.2';

      Collection Functions

      The cornerstone, an each implementation, aka forEach. +Handles objects with the built-in forEach, arrays, and raw objects. +Delegates to ECMAScript 5's native forEach if available.

        var each = _.each = _.forEach = function(obj, iterator, context) {
      +    if (obj == null) return;
      +    if (nativeForEach && obj.forEach === nativeForEach) {
      +      obj.forEach(iterator, context);
      +    } else if (obj.length === +obj.length) {
      +      for (var i = 0, l = obj.length; i < l; i++) {
      +        if (iterator.call(context, obj[i], i, obj) === breaker) return;
      +      }
      +    } else {
      +      for (var key in obj) {
      +        if (_.has(obj, key)) {
      +          if (iterator.call(context, obj[key], key, obj) === breaker) return;
      +        }
      +      }
      +    }
      +  };

      Return the results of applying the iterator to each element. +Delegates to ECMAScript 5's native map if available.

        _.map = _.collect = function(obj, iterator, context) {
      +    var results = [];
      +    if (obj == null) return results;
      +    if (nativeMap && obj.map === nativeMap) return obj.map(iterator, context);
      +    each(obj, function(value, index, list) {
      +      results[results.length] = iterator.call(context, value, index, list);
      +    });
      +    return results;
      +  };

      Reduce builds up a single result from a list of values, aka inject, +or foldl. Delegates to ECMAScript 5's native reduce if available.

        _.reduce = _.foldl = _.inject = function(obj, iterator, memo, context) {
      +    var initial = arguments.length > 2;
      +    if (obj == null) obj = [];
      +    if (nativeReduce && obj.reduce === nativeReduce) {
      +      if (context) iterator = _.bind(iterator, context);
      +      return initial ? obj.reduce(iterator, memo) : obj.reduce(iterator);
      +    }
      +    each(obj, function(value, index, list) {
      +      if (!initial) {
      +        memo = value;
      +        initial = true;
      +      } else {
      +        memo = iterator.call(context, memo, value, index, list);
      +      }
      +    });
      +    if (!initial) throw new TypeError('Reduce of empty array with no initial value');
      +    return memo;
      +  };

      The right-associative version of reduce, also known as foldr. +Delegates to ECMAScript 5's native reduceRight if available.

        _.reduceRight = _.foldr = function(obj, iterator, memo, context) {
      +    var initial = arguments.length > 2;
      +    if (obj == null) obj = [];
      +    if (nativeReduceRight && obj.reduceRight === nativeReduceRight) {
      +      if (context) iterator = _.bind(iterator, context);
      +      return arguments.length > 2 ? obj.reduceRight(iterator, memo) : obj.reduceRight(iterator);
      +    }
      +    var length = obj.length;
      +    if (length !== +length) {
      +      var keys = _.keys(obj);
      +      length = keys.length;
      +    }
      +    each(obj, function(value, index, list) {
      +      index = keys ? keys[--length] : --length;
      +      if (!initial) {
      +        memo = obj[index];
      +        initial = true;
      +      } else {
      +        memo = iterator.call(context, memo, obj[index], index, list);
      +      }
      +    });
      +    if (!initial) throw new TypeError('Reduce of empty array with no initial value');
      +    return memo;
      +  };

      Return the first value which passes a truth test. Aliased as detect.

        _.find = _.detect = function(obj, iterator, context) {
      +    var result;
      +    any(obj, function(value, index, list) {
      +      if (iterator.call(context, value, index, list)) {
      +        result = value;
      +        return true;
      +      }
      +    });
      +    return result;
      +  };

      Return all the elements that pass a truth test. +Delegates to ECMAScript 5's native filter if available. +Aliased as select.

        _.filter = _.select = function(obj, iterator, context) {
      +    var results = [];
      +    if (obj == null) return results;
      +    if (nativeFilter && obj.filter === nativeFilter) return obj.filter(iterator, context);
      +    each(obj, function(value, index, list) {
      +      if (iterator.call(context, value, index, list)) results[results.length] = value;
      +    });
      +    return results;
      +  };

      Return all the elements for which a truth test fails.

        _.reject = function(obj, iterator, context) {
      +    var results = [];
      +    if (obj == null) return results;
      +    each(obj, function(value, index, list) {
      +      if (!iterator.call(context, value, index, list)) results[results.length] = value;
      +    });
      +    return results;
      +  };

      Determine whether all of the elements match a truth test. +Delegates to ECMAScript 5's native every if available. +Aliased as all.

        _.every = _.all = function(obj, iterator, context) {
      +    iterator || (iterator = _.identity);
      +    var result = true;
      +    if (obj == null) return result;
      +    if (nativeEvery && obj.every === nativeEvery) return obj.every(iterator, context);
      +    each(obj, function(value, index, list) {
      +      if (!(result = result && iterator.call(context, value, index, list))) return breaker;
      +    });
      +    return !!result;
      +  };

      Determine if at least one element in the object matches a truth test. +Delegates to ECMAScript 5's native some if available. +Aliased as any.

        var any = _.some = _.any = function(obj, iterator, context) {
      +    iterator || (iterator = _.identity);
      +    var result = false;
      +    if (obj == null) return result;
      +    if (nativeSome && obj.some === nativeSome) return obj.some(iterator, context);
      +    each(obj, function(value, index, list) {
      +      if (result || (result = iterator.call(context, value, index, list))) return breaker;
      +    });
      +    return !!result;
      +  };

      Determine if the array or object contains a given value (using ===). +Aliased as include.

        _.contains = _.include = function(obj, target) {
      +    var found = false;
      +    if (obj == null) return found;
      +    if (nativeIndexOf && obj.indexOf === nativeIndexOf) return obj.indexOf(target) != -1;
      +    found = any(obj, function(value) {
      +      return value === target;
      +    });
      +    return found;
      +  };

      Invoke a method (with arguments) on every item in a collection.

        _.invoke = function(obj, method) {
      +    var args = slice.call(arguments, 2);
      +    return _.map(obj, function(value) {
      +      return (_.isFunction(method) ? method : value[method]).apply(value, args);
      +    });
      +  };

      Convenience version of a common use case of map: fetching a property.

        _.pluck = function(obj, key) {
      +    return _.map(obj, function(value){ return value[key]; });
      +  };

      Convenience version of a common use case of filter: selecting only objects +with specific key:value pairs.

        _.where = function(obj, attrs) {
      +    if (_.isEmpty(attrs)) return [];
      +    return _.filter(obj, function(value) {
      +      for (var key in attrs) {
      +        if (attrs[key] !== value[key]) return false;
      +      }
      +      return true;
      +    });
      +  };

      Return the maximum element or (element-based computation). +Can't optimize arrays of integers longer than 65,535 elements. +See: https://bugs.webkit.org/show_bug.cgi?id=80797

        _.max = function(obj, iterator, context) {
      +    if (!iterator && _.isArray(obj) && obj[0] === +obj[0] && obj.length < 65535) {
      +      return Math.max.apply(Math, obj);
      +    }
      +    if (!iterator && _.isEmpty(obj)) return -Infinity;
      +    var result = {computed : -Infinity};
      +    each(obj, function(value, index, list) {
      +      var computed = iterator ? iterator.call(context, value, index, list) : value;
      +      computed >= result.computed && (result = {value : value, computed : computed});
      +    });
      +    return result.value;
      +  };

      Return the minimum element (or element-based computation).

        _.min = function(obj, iterator, context) {
      +    if (!iterator && _.isArray(obj) && obj[0] === +obj[0] && obj.length < 65535) {
      +      return Math.min.apply(Math, obj);
      +    }
      +    if (!iterator && _.isEmpty(obj)) return Infinity;
      +    var result = {computed : Infinity};
      +    each(obj, function(value, index, list) {
      +      var computed = iterator ? iterator.call(context, value, index, list) : value;
      +      computed < result.computed && (result = {value : value, computed : computed});
      +    });
      +    return result.value;
      +  };

      Shuffle an array.

        _.shuffle = function(obj) {
      +    var rand;
      +    var index = 0;
      +    var shuffled = [];
      +    each(obj, function(value) {
      +      rand = _.random(index++);
      +      shuffled[index - 1] = shuffled[rand];
      +      shuffled[rand] = value;
      +    });
      +    return shuffled;
      +  };

      An internal function to generate lookup iterators.

        var lookupIterator = function(value) {
      +    return _.isFunction(value) ? value : function(obj){ return obj[value]; };
      +  };

      Sort the object's values by a criterion produced by an iterator.

        _.sortBy = function(obj, value, context) {
      +    var iterator = lookupIterator(value);
      +    return _.pluck(_.map(obj, function(value, index, list) {
      +      return {
      +        value : value,
      +        index : index,
      +        criteria : iterator.call(context, value, index, list)
      +      };
      +    }).sort(function(left, right) {
      +      var a = left.criteria;
      +      var b = right.criteria;
      +      if (a !== b) {
      +        if (a > b || a === void 0) return 1;
      +        if (a < b || b === void 0) return -1;
      +      }
      +      return left.index < right.index ? -1 : 1;
      +    }), 'value');
      +  };

      An internal function used for aggregate "group by" operations.

        var group = function(obj, value, context, behavior) {
      +    var result = {};
      +    var iterator = lookupIterator(value);
      +    each(obj, function(value, index) {
      +      var key = iterator.call(context, value, index, obj);
      +      behavior(result, key, value);
      +    });
      +    return result;
      +  };

      Groups the object's values by a criterion. Pass either a string attribute +to group by, or a function that returns the criterion.

        _.groupBy = function(obj, value, context) {
      +    return group(obj, value, context, function(result, key, value) {
      +      (_.has(result, key) ? result[key] : (result[key] = [])).push(value);
      +    });
      +  };

      Counts instances of an object that group by a certain criterion. Pass +either a string attribute to count by, or a function that returns the +criterion.

        _.countBy = function(obj, value, context) {
      +    return group(obj, value, context, function(result, key, value) {
      +      if (!_.has(result, key)) result[key] = 0;
      +      result[key]++;
      +    });
      +  };

      Use a comparator function to figure out the smallest index at which +an object should be inserted so as to maintain order. Uses binary search.

        _.sortedIndex = function(array, obj, iterator, context) {
      +    iterator = iterator == null ? _.identity : lookupIterator(iterator);
      +    var value = iterator.call(context, obj);
      +    var low = 0, high = array.length;
      +    while (low < high) {
      +      var mid = (low + high) >>> 1;
      +      iterator.call(context, array[mid]) < value ? low = mid + 1 : high = mid;
      +    }
      +    return low;
      +  };

      Safely convert anything iterable into a real, live array.

        _.toArray = function(obj) {
      +    if (!obj) return [];
      +    if (obj.length === +obj.length) return slice.call(obj);
      +    return _.values(obj);
      +  };

      Return the number of elements in an object.

        _.size = function(obj) {
      +    return (obj.length === +obj.length) ? obj.length : _.keys(obj).length;
      +  };

      Array Functions

      Get the first element of an array. Passing n will return the first N +values in the array. Aliased as head and take. The guard check +allows it to work with _.map.

        _.first = _.head = _.take = function(array, n, guard) {
      +    return (n != null) && !guard ? slice.call(array, 0, n) : array[0];
      +  };

      Returns everything but the last entry of the array. Especially useful on +the arguments object. Passing n will return all the values in +the array, excluding the last N. The guard check allows it to work with +_.map.

        _.initial = function(array, n, guard) {
      +    return slice.call(array, 0, array.length - ((n == null) || guard ? 1 : n));
      +  };

      Get the last element of an array. Passing n will return the last N +values in the array. The guard check allows it to work with _.map.

        _.last = function(array, n, guard) {
      +    if ((n != null) && !guard) {
      +      return slice.call(array, Math.max(array.length - n, 0));
      +    } else {
      +      return array[array.length - 1];
      +    }
      +  };

      Returns everything but the first entry of the array. Aliased as tail and drop. +Especially useful on the arguments object. Passing an n will return +the rest N values in the array. The guard +check allows it to work with _.map.

        _.rest = _.tail = _.drop = function(array, n, guard) {
      +    return slice.call(array, (n == null) || guard ? 1 : n);
      +  };

      Trim out all falsy values from an array.

        _.compact = function(array) {
      +    return _.filter(array, function(value){ return !!value; });
      +  };

      Internal implementation of a recursive flatten function.

        var flatten = function(input, shallow, output) {
      +    each(input, function(value) {
      +      if (_.isArray(value)) {
      +        shallow ? push.apply(output, value) : flatten(value, shallow, output);
      +      } else {
      +        output.push(value);
      +      }
      +    });
      +    return output;
      +  };

      Return a completely flattened version of an array.

        _.flatten = function(array, shallow) {
      +    return flatten(array, shallow, []);
      +  };

      Return a version of the array that does not contain the specified value(s).

        _.without = function(array) {
      +    return _.difference(array, slice.call(arguments, 1));
      +  };

      Produce a duplicate-free version of the array. If the array has already +been sorted, you have the option of using a faster algorithm. +Aliased as unique.

        _.uniq = _.unique = function(array, isSorted, iterator, context) {
      +    var initial = iterator ? _.map(array, iterator, context) : array;
      +    var results = [];
      +    var seen = [];
      +    each(initial, function(value, index) {
      +      if (isSorted ? (!index || seen[seen.length - 1] !== value) : !_.contains(seen, value)) {
      +        seen.push(value);
      +        results.push(array[index]);
      +      }
      +    });
      +    return results;
      +  };

      Produce an array that contains the union: each distinct element from all of +the passed-in arrays.

        _.union = function() {
      +    return _.uniq(concat.apply(ArrayProto, arguments));
      +  };

      Produce an array that contains every item shared between all the +passed-in arrays.

        _.intersection = function(array) {
      +    var rest = slice.call(arguments, 1);
      +    return _.filter(_.uniq(array), function(item) {
      +      return _.every(rest, function(other) {
      +        return _.indexOf(other, item) >= 0;
      +      });
      +    });
      +  };

      Take the difference between one array and a number of other arrays. +Only the elements present in just the first array will remain.

        _.difference = function(array) {
      +    var rest = concat.apply(ArrayProto, slice.call(arguments, 1));
      +    return _.filter(array, function(value){ return !_.contains(rest, value); });
      +  };

      Zip together multiple lists into a single array -- elements that share +an index go together.

        _.zip = function() {
      +    var args = slice.call(arguments);
      +    var length = _.max(_.pluck(args, 'length'));
      +    var results = new Array(length);
      +    for (var i = 0; i < length; i++) {
      +      results[i] = _.pluck(args, "" + i);
      +    }
      +    return results;
      +  };

      Converts lists into objects. Pass either a single array of [key, value] +pairs, or two parallel arrays of the same length -- one of keys, and one of +the corresponding values.

        _.object = function(list, values) {
      +    var result = {};
      +    for (var i = 0, l = list.length; i < l; i++) {
      +      if (values) {
      +        result[list[i]] = values[i];
      +      } else {
      +        result[list[i][0]] = list[i][1];
      +      }
      +    }
      +    return result;
      +  };

      If the browser doesn't supply us with indexOf (I'm looking at you, MSIE), +we need this function. Return the position of the first occurrence of an +item in an array, or -1 if the item is not included in the array. +Delegates to ECMAScript 5's native indexOf if available. +If the array is large and already in sort order, pass true +for isSorted to use binary search.

        _.indexOf = function(array, item, isSorted) {
      +    if (array == null) return -1;
      +    var i = 0, l = array.length;
      +    if (isSorted) {
      +      if (typeof isSorted == 'number') {
      +        i = (isSorted < 0 ? Math.max(0, l + isSorted) : isSorted);
      +      } else {
      +        i = _.sortedIndex(array, item);
      +        return array[i] === item ? i : -1;
      +      }
      +    }
      +    if (nativeIndexOf && array.indexOf === nativeIndexOf) return array.indexOf(item, isSorted);
      +    for (; i < l; i++) if (array[i] === item) return i;
      +    return -1;
      +  };

      Delegates to ECMAScript 5's native lastIndexOf if available.

        _.lastIndexOf = function(array, item, from) {
      +    if (array == null) return -1;
      +    var hasIndex = from != null;
      +    if (nativeLastIndexOf && array.lastIndexOf === nativeLastIndexOf) {
      +      return hasIndex ? array.lastIndexOf(item, from) : array.lastIndexOf(item);
      +    }
      +    var i = (hasIndex ? from : array.length);
      +    while (i--) if (array[i] === item) return i;
      +    return -1;
      +  };

      Generate an integer Array containing an arithmetic progression. A port of +the native Python range() function. See +the Python documentation.

        _.range = function(start, stop, step) {
      +    if (arguments.length <= 1) {
      +      stop = start || 0;
      +      start = 0;
      +    }
      +    step = arguments[2] || 1;
      +
      +    var len = Math.max(Math.ceil((stop - start) / step), 0);
      +    var idx = 0;
      +    var range = new Array(len);
      +
      +    while(idx < len) {
      +      range[idx++] = start;
      +      start += step;
      +    }
      +
      +    return range;
      +  };

      Function (ahem) Functions

      Reusable constructor function for prototype setting.

        var ctor = function(){};

      Create a function bound to a given object (assigning this, and arguments, +optionally). Binding with arguments is also known as curry. +Delegates to ECMAScript 5's native Function.bind if available. +We check for func.bind first, to fail fast when func is undefined.

        _.bind = function bind(func, context) {
      +    var bound, args;
      +    if (func.bind === nativeBind && nativeBind) return nativeBind.apply(func, slice.call(arguments, 1));
      +    if (!_.isFunction(func)) throw new TypeError;
      +    args = slice.call(arguments, 2);
      +    return bound = function() {
      +      if (!(this instanceof bound)) return func.apply(context, args.concat(slice.call(arguments)));
      +      ctor.prototype = func.prototype;
      +      var self = new ctor;
      +      var result = func.apply(self, args.concat(slice.call(arguments)));
      +      if (Object(result) === result) return result;
      +      return self;
      +    };
      +  };

      Bind all of an object's methods to that object. Useful for ensuring that +all callbacks defined on an object belong to it.

        _.bindAll = function(obj) {
      +    var funcs = slice.call(arguments, 1);
      +    if (funcs.length == 0) funcs = _.functions(obj);
      +    each(funcs, function(f) { obj[f] = _.bind(obj[f], obj); });
      +    return obj;
      +  };

      Memoize an expensive function by storing its results.

        _.memoize = function(func, hasher) {
      +    var memo = {};
      +    hasher || (hasher = _.identity);
      +    return function() {
      +      var key = hasher.apply(this, arguments);
      +      return _.has(memo, key) ? memo[key] : (memo[key] = func.apply(this, arguments));
      +    };
      +  };

      Delays a function for the given number of milliseconds, and then calls +it with the arguments supplied.

        _.delay = function(func, wait) {
      +    var args = slice.call(arguments, 2);
      +    return setTimeout(function(){ return func.apply(null, args); }, wait);
      +  };

      Defers a function, scheduling it to run after the current call stack has +cleared.

        _.defer = function(func) {
      +    return _.delay.apply(_, [func, 1].concat(slice.call(arguments, 1)));
      +  };

      Returns a function, that, when invoked, will only be triggered at most once +during a given window of time.

        _.throttle = function(func, wait) {
      +    var context, args, timeout, throttling, more, result;
      +    var whenDone = _.debounce(function(){ more = throttling = false; }, wait);
      +    return function() {
      +      context = this; args = arguments;
      +      var later = function() {
      +        timeout = null;
      +        if (more) {
      +          result = func.apply(context, args);
      +        }
      +        whenDone();
      +      };
      +      if (!timeout) timeout = setTimeout(later, wait);
      +      if (throttling) {
      +        more = true;
      +      } else {
      +        throttling = true;
      +        result = func.apply(context, args);
      +      }
      +      whenDone();
      +      return result;
      +    };
      +  };

      Returns a function, that, as long as it continues to be invoked, will not +be triggered. The function will be called after it stops being called for +N milliseconds. If immediate is passed, trigger the function on the +leading edge, instead of the trailing.

        _.debounce = function(func, wait, immediate) {
      +    var timeout, result;
      +    return function() {
      +      var context = this, args = arguments;
      +      var later = function() {
      +        timeout = null;
      +        if (!immediate) result = func.apply(context, args);
      +      };
      +      var callNow = immediate && !timeout;
      +      clearTimeout(timeout);
      +      timeout = setTimeout(later, wait);
      +      if (callNow) result = func.apply(context, args);
      +      return result;
      +    };
      +  };

      Returns a function that will be executed at most one time, no matter how +often you call it. Useful for lazy initialization.

        _.once = function(func) {
      +    var ran = false, memo;
      +    return function() {
      +      if (ran) return memo;
      +      ran = true;
      +      memo = func.apply(this, arguments);
      +      func = null;
      +      return memo;
      +    };
      +  };

      Returns the first function passed as an argument to the second, +allowing you to adjust arguments, run code before and after, and +conditionally execute the original function.

        _.wrap = function(func, wrapper) {
      +    return function() {
      +      var args = [func];
      +      push.apply(args, arguments);
      +      return wrapper.apply(this, args);
      +    };
      +  };

      Returns a function that is the composition of a list of functions, each +consuming the return value of the function that follows.

        _.compose = function() {
      +    var funcs = arguments;
      +    return function() {
      +      var args = arguments;
      +      for (var i = funcs.length - 1; i >= 0; i--) {
      +        args = [funcs[i].apply(this, args)];
      +      }
      +      return args[0];
      +    };
      +  };

      Returns a function that will only be executed after being called N times.

        _.after = function(times, func) {
      +    if (times <= 0) return func();
      +    return function() {
      +      if (--times < 1) {
      +        return func.apply(this, arguments);
      +      }
      +    };
      +  };

      Object Functions

      Retrieve the names of an object's properties. +Delegates to ECMAScript 5's native Object.keys

        _.keys = nativeKeys || function(obj) {
      +    if (obj !== Object(obj)) throw new TypeError('Invalid object');
      +    var keys = [];
      +    for (var key in obj) if (_.has(obj, key)) keys[keys.length] = key;
      +    return keys;
      +  };

      Retrieve the values of an object's properties.

        _.values = function(obj) {
      +    var values = [];
      +    for (var key in obj) if (_.has(obj, key)) values.push(obj[key]);
      +    return values;
      +  };

      Convert an object into a list of [key, value] pairs.

        _.pairs = function(obj) {
      +    var pairs = [];
      +    for (var key in obj) if (_.has(obj, key)) pairs.push([key, obj[key]]);
      +    return pairs;
      +  };

      Invert the keys and values of an object. The values must be serializable.

        _.invert = function(obj) {
      +    var result = {};
      +    for (var key in obj) if (_.has(obj, key)) result[obj[key]] = key;
      +    return result;
      +  };

      Return a sorted list of the function names available on the object. +Aliased as methods

        _.functions = _.methods = function(obj) {
      +    var names = [];
      +    for (var key in obj) {
      +      if (_.isFunction(obj[key])) names.push(key);
      +    }
      +    return names.sort();
      +  };

      Extend a given object with all the properties in passed-in object(s).

        _.extend = function(obj) {
      +    each(slice.call(arguments, 1), function(source) {
      +      for (var prop in source) {
      +        obj[prop] = source[prop];
      +      }
      +    });
      +    return obj;
      +  };

      Return a copy of the object only containing the whitelisted properties.

        _.pick = function(obj) {
      +    var copy = {};
      +    var keys = concat.apply(ArrayProto, slice.call(arguments, 1));
      +    each(keys, function(key) {
      +      if (key in obj) copy[key] = obj[key];
      +    });
      +    return copy;
      +  };

      Return a copy of the object without the blacklisted properties.

        _.omit = function(obj) {
      +    var copy = {};
      +    var keys = concat.apply(ArrayProto, slice.call(arguments, 1));
      +    for (var key in obj) {
      +      if (!_.contains(keys, key)) copy[key] = obj[key];
      +    }
      +    return copy;
      +  };

      Fill in a given object with default properties.

        _.defaults = function(obj) {
      +    each(slice.call(arguments, 1), function(source) {
      +      for (var prop in source) {
      +        if (obj[prop] == null) obj[prop] = source[prop];
      +      }
      +    });
      +    return obj;
      +  };

      Create a (shallow-cloned) duplicate of an object.

        _.clone = function(obj) {
      +    if (!_.isObject(obj)) return obj;
      +    return _.isArray(obj) ? obj.slice() : _.extend({}, obj);
      +  };

      Invokes interceptor with the obj, and then returns obj. +The primary purpose of this method is to "tap into" a method chain, in +order to perform operations on intermediate results within the chain.

        _.tap = function(obj, interceptor) {
      +    interceptor(obj);
      +    return obj;
      +  };

      Internal recursive comparison function for isEqual.

        var eq = function(a, b, aStack, bStack) {

      Identical objects are equal. 0 === -0, but they aren't identical. +See the Harmony egal proposal: http://wiki.ecmascript.org/doku.php?id=harmony:egal.

          if (a === b) return a !== 0 || 1 / a == 1 / b;

      A strict comparison is necessary because null == undefined.

          if (a == null || b == null) return a === b;

      Unwrap any wrapped objects.

          if (a instanceof _) a = a._wrapped;
      +    if (b instanceof _) b = b._wrapped;

      Compare [[Class]] names.

          var className = toString.call(a);
      +    if (className != toString.call(b)) return false;
      +    switch (className) {

      Strings, numbers, dates, and booleans are compared by value.

            case '[object String]':

      Primitives and their corresponding object wrappers are equivalent; thus, "5" is +equivalent to new String("5").

              return a == String(b);
      +      case '[object Number]':

      NaNs are equivalent, but non-reflexive. An egal comparison is performed for +other numeric values.

              return a != +a ? b != +b : (a == 0 ? 1 / a == 1 / b : a == +b);
      +      case '[object Date]':
      +      case '[object Boolean]':

      Coerce dates and booleans to numeric primitive values. Dates are compared by their +millisecond representations. Note that invalid dates with millisecond representations +of NaN are not equivalent.

              return +a == +b;

      RegExps are compared by their source patterns and flags.

            case '[object RegExp]':
      +        return a.source == b.source &&
      +               a.global == b.global &&
      +               a.multiline == b.multiline &&
      +               a.ignoreCase == b.ignoreCase;
      +    }
      +    if (typeof a != 'object' || typeof b != 'object') return false;

      Assume equality for cyclic structures. The algorithm for detecting cyclic +structures is adapted from ES 5.1 section 15.12.3, abstract operation JO.

          var length = aStack.length;
      +    while (length--) {

      Linear search. Performance is inversely proportional to the number of +unique nested structures.

            if (aStack[length] == a) return bStack[length] == b;
      +    }

      Add the first object to the stack of traversed objects.

          aStack.push(a);
      +    bStack.push(b);
      +    var size = 0, result = true;

      Recursively compare objects and arrays.

          if (className == '[object Array]') {

      Compare array lengths to determine if a deep comparison is necessary.

            size = a.length;
      +      result = size == b.length;
      +      if (result) {

      Deep compare the contents, ignoring non-numeric properties.

              while (size--) {
      +          if (!(result = eq(a[size], b[size], aStack, bStack))) break;
      +        }
      +      }
      +    } else {

      Objects with different constructors are not equivalent, but Objects +from different frames are.

            var aCtor = a.constructor, bCtor = b.constructor;
      +      if (aCtor !== bCtor && !(_.isFunction(aCtor) && (aCtor instanceof aCtor) &&
      +                               _.isFunction(bCtor) && (bCtor instanceof bCtor))) {
      +        return false;
      +      }

      Deep compare objects.

            for (var key in a) {
      +        if (_.has(a, key)) {

      Count the expected number of properties.

                size++;

      Deep compare each member.

                if (!(result = _.has(b, key) && eq(a[key], b[key], aStack, bStack))) break;
      +        }
      +      }

      Ensure that both objects contain the same number of properties.

            if (result) {
      +        for (key in b) {
      +          if (_.has(b, key) && !(size--)) break;
      +        }
      +        result = !size;
      +      }
      +    }

      Remove the first object from the stack of traversed objects.

          aStack.pop();
      +    bStack.pop();
      +    return result;
      +  };

      Perform a deep comparison to check if two objects are equal.

        _.isEqual = function(a, b) {
      +    return eq(a, b, [], []);
      +  };

      Is a given array, string, or object empty? +An "empty" object has no enumerable own-properties.

        _.isEmpty = function(obj) {
      +    if (obj == null) return true;
      +    if (_.isArray(obj) || _.isString(obj)) return obj.length === 0;
      +    for (var key in obj) if (_.has(obj, key)) return false;
      +    return true;
      +  };

      Is a given value a DOM element?

        _.isElement = function(obj) {
      +    return !!(obj && obj.nodeType === 1);
      +  };

      Is a given value an array? +Delegates to ECMA5's native Array.isArray

        _.isArray = nativeIsArray || function(obj) {
      +    return toString.call(obj) == '[object Array]';
      +  };

      Is a given variable an object?

        _.isObject = function(obj) {
      +    return obj === Object(obj);
      +  };

      Add some isType methods: isArguments, isFunction, isString, isNumber, isDate, isRegExp.

        each(['Arguments', 'Function', 'String', 'Number', 'Date', 'RegExp'], function(name) {
      +    _['is' + name] = function(obj) {
      +      return toString.call(obj) == '[object ' + name + ']';
      +    };
      +  });

      Define a fallback version of the method in browsers (ahem, IE), where +there isn't any inspectable "Arguments" type.

        if (!_.isArguments(arguments)) {
      +    _.isArguments = function(obj) {
      +      return !!(obj && _.has(obj, 'callee'));
      +    };
      +  }

      Optimize isFunction if appropriate.

        if (typeof (/./) !== 'function') {
      +    _.isFunction = function(obj) {
      +      return typeof obj === 'function';
      +    };
      +  }

      Is a given object a finite number?

        _.isFinite = function(obj) {
      +    return _.isNumber(obj) && isFinite(obj);
      +  };

      Is the given value NaN? (NaN is the only number which does not equal itself).

        _.isNaN = function(obj) {
      +    return _.isNumber(obj) && obj != +obj;
      +  };

      Is a given value a boolean?

        _.isBoolean = function(obj) {
      +    return obj === true || obj === false || toString.call(obj) == '[object Boolean]';
      +  };

      Is a given value equal to null?

        _.isNull = function(obj) {
      +    return obj === null;
      +  };

      Is a given variable undefined?

        _.isUndefined = function(obj) {
      +    return obj === void 0;
      +  };

      Shortcut function for checking if an object has a given property directly +on itself (in other words, not on a prototype).

        _.has = function(obj, key) {
      +    return hasOwnProperty.call(obj, key);
      +  };

      Utility Functions

      Run Underscore.js in noConflict mode, returning the _ variable to its +previous owner. Returns a reference to the Underscore object.

        _.noConflict = function() {
      +    root._ = previousUnderscore;
      +    return this;
      +  };

      Keep the identity function around for default iterators.

        _.identity = function(value) {
      +    return value;
      +  };

      Run a function n times.

        _.times = function(n, iterator, context) {
      +    for (var i = 0; i < n; i++) iterator.call(context, i);
      +  };

      Return a random integer between min and max (inclusive).

        _.random = function(min, max) {
      +    if (max == null) {
      +      max = min;
      +      min = 0;
      +    }
      +    return min + (0 | Math.random() * (max - min + 1));
      +  };

      List of HTML entities for escaping.

        var entityMap = {
      +    escape: {
      +      '&': '&amp;',
      +      '<': '&lt;',
      +      '>': '&gt;',
      +      '"': '&quot;',
      +      "'": '&#x27;',
      +      '/': '&#x2F;'
      +    }
      +  };
      +  entityMap.unescape = _.invert(entityMap.escape);

      Regexes containing the keys and values listed immediately above.

        var entityRegexes = {
      +    escape:   new RegExp('[' + _.keys(entityMap.escape).join('') + ']', 'g'),
      +    unescape: new RegExp('(' + _.keys(entityMap.unescape).join('|') + ')', 'g')
      +  };

      Functions for escaping and unescaping strings to/from HTML interpolation.

        _.each(['escape', 'unescape'], function(method) {
      +    _[method] = function(string) {
      +      if (string == null) return '';
      +      return ('' + string).replace(entityRegexes[method], function(match) {
      +        return entityMap[method][match];
      +      });
      +    };
      +  });

      If the value of the named property is a function then invoke it; +otherwise, return it.

        _.result = function(object, property) {
      +    if (object == null) return null;
      +    var value = object[property];
      +    return _.isFunction(value) ? value.call(object) : value;
      +  };

      Add your own custom functions to the Underscore object.

        _.mixin = function(obj) {
      +    each(_.functions(obj), function(name){
      +      var func = _[name] = obj[name];
      +      _.prototype[name] = function() {
      +        var args = [this._wrapped];
      +        push.apply(args, arguments);
      +        return result.call(this, func.apply(_, args));
      +      };
      +    });
      +  };

      Generate a unique integer id (unique within the entire client session). +Useful for temporary DOM ids.

        var idCounter = 0;
      +  _.uniqueId = function(prefix) {
      +    var id = idCounter++;
      +    return prefix ? prefix + id : id;
      +  };

      By default, Underscore uses ERB-style template delimiters, change the +following template settings to use alternative delimiters.

        _.templateSettings = {
      +    evaluate    : /<%([\s\S]+?)%>/g,
      +    interpolate : /<%=([\s\S]+?)%>/g,
      +    escape      : /<%-([\s\S]+?)%>/g
      +  };

      When customizing templateSettings, if you don't want to define an +interpolation, evaluation or escaping regex, we need one that is +guaranteed not to match.

        var noMatch = /(.)^/;

      Certain characters need to be escaped so that they can be put into a +string literal.

        var escapes = {
      +    "'":      "'",
      +    '\\':     '\\',
      +    '\r':     'r',
      +    '\n':     'n',
      +    '\t':     't',
      +    '\u2028': 'u2028',
      +    '\u2029': 'u2029'
      +  };
      +
      +  var escaper = /\\|'|\r|\n|\t|\u2028|\u2029/g;

      JavaScript micro-templating, similar to John Resig's implementation. +Underscore templating handles arbitrary delimiters, preserves whitespace, +and correctly escapes quotes within interpolated code.

        _.template = function(text, data, settings) {
      +    settings = _.defaults({}, settings, _.templateSettings);

      Combine delimiters into one regular expression via alternation.

          var matcher = new RegExp([
      +      (settings.escape || noMatch).source,
      +      (settings.interpolate || noMatch).source,
      +      (settings.evaluate || noMatch).source
      +    ].join('|') + '|$', 'g');

      Compile the template source, escaping string literals appropriately.

          var index = 0;
      +    var source = "__p+='";
      +    text.replace(matcher, function(match, escape, interpolate, evaluate, offset) {
      +      source += text.slice(index, offset)
      +        .replace(escaper, function(match) { return '\\' + escapes[match]; });
      +      source +=
      +        escape ? "'+\n((__t=(" + escape + "))==null?'':_.escape(__t))+\n'" :
      +        interpolate ? "'+\n((__t=(" + interpolate + "))==null?'':__t)+\n'" :
      +        evaluate ? "';\n" + evaluate + "\n__p+='" : '';
      +      index = offset + match.length;
      +    });
      +    source += "';\n";

      If a variable is not specified, place data values in local scope.

          if (!settings.variable) source = 'with(obj||{}){\n' + source + '}\n';
      +
      +    source = "var __t,__p='',__j=Array.prototype.join," +
      +      "print=function(){__p+=__j.call(arguments,'');};\n" +
      +      source + "return __p;\n";
      +
      +    try {
      +      var render = new Function(settings.variable || 'obj', '_', source);
      +    } catch (e) {
      +      e.source = source;
      +      throw e;
      +    }
      +
      +    if (data) return render(data, _);
      +    var template = function(data) {
      +      return render.call(this, data, _);
      +    };

      Provide the compiled function source as a convenience for precompilation.

          template.source = 'function(' + (settings.variable || 'obj') + '){\n' + source + '}';
      +
      +    return template;
      +  };

      Add a "chain" function, which will delegate to the wrapper.

        _.chain = function(obj) {
      +    return _(obj).chain();
      +  };

      OOP

      + +

      If Underscore is called as a function, it returns a wrapped object that +can be used OO-style. This wrapper holds altered versions of all the +underscore functions. Wrapped objects may be chained.

      Helper function to continue chaining intermediate results.

        var result = function(obj) {
      +    return this._chain ? _(obj).chain() : obj;
      +  };

      Add all of the Underscore functions to the wrapper object.

        _.mixin(_);

      Add all mutator Array functions to the wrapper.

        each(['pop', 'push', 'reverse', 'shift', 'sort', 'splice', 'unshift'], function(name) {
      +    var method = ArrayProto[name];
      +    _.prototype[name] = function() {
      +      var obj = this._wrapped;
      +      method.apply(obj, arguments);
      +      if ((name == 'shift' || name == 'splice') && obj.length === 0) delete obj[0];
      +      return result.call(this, obj);
      +    };
      +  });

      Add all accessor Array functions to the wrapper.

        each(['concat', 'join', 'slice'], function(name) {
      +    var method = ArrayProto[name];
      +    _.prototype[name] = function() {
      +      return result.call(this, method.apply(this._wrapped, arguments));
      +    };
      +  });
      +
      +  _.extend(_.prototype, {

      Start chaining a wrapped Underscore object.

          chain: function() {
      +      this._chain = true;
      +      return this;
      +    },

      Extracts the result from a wrapped and chained object.

          value: function() {
      +      return this._wrapped;
      +    }
      +
      +  });
      +
      +}).call(this);
      +
      +
      \ No newline at end of file diff --git a/htdocs/js/lib/webwork/components/underscore/favicon.ico b/htdocs/js/lib/webwork/components/underscore/favicon.ico new file mode 100644 index 000000000..030496838 Binary files /dev/null and b/htdocs/js/lib/webwork/components/underscore/favicon.ico differ diff --git a/htdocs/js/lib/webwork/components/underscore/index.html b/htdocs/js/lib/webwork/components/underscore/index.html new file mode 100644 index 000000000..71b1f5a36 --- /dev/null +++ b/htdocs/js/lib/webwork/components/underscore/index.html @@ -0,0 +1,2367 @@ + + + + + + + + + Underscore.js + + + + + + +
      + +

      + +

      + +

      + Underscore is a + utility-belt library for JavaScript that provides a lot of the + functional programming support that you would expect in + Prototype.js + (or Ruby), + but without extending any of the built-in JavaScript objects. It's the + tie to go along with jQuery's tux, + and Backbone.js's suspenders. +

      + +

      + Underscore provides 80-odd functions that support both the usual + functional suspects: map, select, invoke — + as well as more specialized helpers: function binding, javascript + templating, deep equality testing, and so on. It delegates to built-in + functions, if present, so modern browsers will use the + native implementations of forEach, map, reduce, + filter, every, some and indexOf. +

      + +

      + A complete Test & Benchmark Suite + is included for your perusal. +

      + +

      + You may also read through the annotated source code. +

      + +

      + The project is + hosted on GitHub. + You can report bugs and discuss features on the + issues page, + on Freenode in the #documentcloud channel, + or send tweets to @documentcloud. +

      + +

      + Underscore is an open-source component of DocumentCloud. +

      + +

      Downloads (Right-click, and use "Save As")

      + + + + + + + + + + + + + + + + + +
      Development Version (1.4.2)40kb, Uncompressed with Plentiful Comments
      Production Version (1.4.2)4kb, Minified and Gzipped
      Edge VersionUnreleased, current master, use at your own risk
      + +
      + +

      Collection Functions (Arrays or Objects)

      + +

      + each_.each(list, iterator, [context]) + Alias: forEach +
      + Iterates over a list of elements, yielding each in turn to an iterator + function. The iterator is bound to the context object, if one is + passed. Each invocation of iterator is called with three arguments: + (element, index, list). If list is a JavaScript object, iterator's + arguments will be (value, key, list). Delegates to the native + forEach function if it exists. +

      +
      +_.each([1, 2, 3], function(num){ alert(num); });
      +=> alerts each number in turn...
      +_.each({one : 1, two : 2, three : 3}, function(num, key){ alert(num); });
      +=> alerts each number in turn...
      + +

      + map_.map(list, iterator, [context]) + Alias: collect +
      + Produces a new array of values by mapping each value in list + through a transformation function (iterator). If the native map method + exists, it will be used instead. If list is a JavaScript object, + iterator's arguments will be (value, key, list). +

      +
      +_.map([1, 2, 3], function(num){ return num * 3; });
      +=> [3, 6, 9]
      +_.map({one : 1, two : 2, three : 3}, function(num, key){ return num * 3; });
      +=> [3, 6, 9]
      + +

      + reduce_.reduce(list, iterator, memo, [context]) + Aliases: inject, foldl +
      + Also known as inject and foldl, reduce boils down a + list of values into a single value. Memo is the initial state + of the reduction, and each successive step of it should be returned by + iterator. The iterator is passed four arguments: the memo, + then the value and index (or key) of the iteration, + and finally a reference to the entire list. +

      +
      +var sum = _.reduce([1, 2, 3], function(memo, num){ return memo + num; }, 0);
      +=> 6
      +
      + +

      + reduceRight_.reduceRight(list, iterator, memo, [context]) + Alias: foldr +
      + The right-associative version of reduce. Delegates to the + JavaScript 1.8 version of reduceRight, if it exists. Foldr + is not as useful in JavaScript as it would be in a language with lazy + evaluation. +

      +
      +var list = [[0, 1], [2, 3], [4, 5]];
      +var flat = _.reduceRight(list, function(a, b) { return a.concat(b); }, []);
      +=> [4, 5, 2, 3, 0, 1]
      +
      + +

      + find_.find(list, iterator, [context]) + Alias: detect +
      + Looks through each value in the list, returning the first one that + passes a truth test (iterator). The function returns as + soon as it finds an acceptable element, and doesn't traverse the + entire list. +

      +
      +var even = _.find([1, 2, 3, 4, 5, 6], function(num){ return num % 2 == 0; });
      +=> 2
      +
      + +

      + filter_.filter(list, iterator, [context]) + Alias: select +
      + Looks through each value in the list, returning an array of all + the values that pass a truth test (iterator). Delegates to the + native filter method, if it exists. +

      +
      +var evens = _.filter([1, 2, 3, 4, 5, 6], function(num){ return num % 2 == 0; });
      +=> [2, 4, 6]
      +
      + +

      + where_.where(list, properties) +
      + Looks through each value in the list, returning an array of all + the values that contain all of the key-value pairs listed in properties. +

      +
      +_.where(listOfPlays, {author: "Shakespeare", year: 1611});
      +=> [{title: "Cymbeline", author: "Shakespeare", year: 1611},
      +    {title: "The Tempest", author: "Shakespeare", year: 1611}]
      +
      + +

      + reject_.reject(list, iterator, [context]) +
      + Returns the values in list without the elements that the truth + test (iterator) passes. The opposite of filter. +

      +
      +var odds = _.reject([1, 2, 3, 4, 5, 6], function(num){ return num % 2 == 0; });
      +=> [1, 3, 5]
      +
      + +

      + all_.all(list, iterator, [context]) + Alias: every +
      + Returns true if all of the values in the list pass the iterator + truth test. Delegates to the native method every, if present. +

      +
      +_.all([true, 1, null, 'yes'], _.identity);
      +=> false
      +
      + +

      + any_.any(list, [iterator], [context]) + Alias: some +
      + Returns true if any of the values in the list pass the + iterator truth test. Short-circuits and stops traversing the list + if a true element is found. Delegates to the native method some, + if present. +

      +
      +_.any([null, 0, 'yes', false]);
      +=> true
      +
      + +

      + contains_.contains(list, value) + Alias: include +
      + Returns true if the value is present in the list. + Uses indexOf internally, if list is an Array. +

      +
      +_.contains([1, 2, 3], 3);
      +=> true
      +
      + +

      + invoke_.invoke(list, methodName, [*arguments]) +
      + Calls the method named by methodName on each value in the list. + Any extra arguments passed to invoke will be forwarded on to the + method invocation. +

      +
      +_.invoke([[5, 1, 7], [3, 2, 1]], 'sort');
      +=> [[1, 5, 7], [1, 2, 3]]
      +
      + +

      + pluck_.pluck(list, propertyName) +
      + A convenient version of what is perhaps the most common use-case for + map: extracting a list of property values. +

      +
      +var stooges = [{name : 'moe', age : 40}, {name : 'larry', age : 50}, {name : 'curly', age : 60}];
      +_.pluck(stooges, 'name');
      +=> ["moe", "larry", "curly"]
      +
      + +

      + max_.max(list, [iterator], [context]) +
      + Returns the maximum value in list. If iterator is passed, + it will be used on each value to generate the criterion by which the + value is ranked. +

      +
      +var stooges = [{name : 'moe', age : 40}, {name : 'larry', age : 50}, {name : 'curly', age : 60}];
      +_.max(stooges, function(stooge){ return stooge.age; });
      +=> {name : 'curly', age : 60};
      +
      + +

      + min_.min(list, [iterator], [context]) +
      + Returns the minimum value in list. If iterator is passed, + it will be used on each value to generate the criterion by which the + value is ranked. +

      +
      +var numbers = [10, 5, 100, 2, 1000];
      +_.min(numbers);
      +=> 2
      +
      + +

      + sortBy_.sortBy(list, iterator, [context]) +
      + Returns a sorted copy of list, ranked in ascending order by the + results of running each value through iterator. Iterator may + also be the string name of the property to sort by (eg. length). +

      +
      +_.sortBy([1, 2, 3, 4, 5, 6], function(num){ return Math.sin(num); });
      +=> [5, 4, 6, 3, 1, 2]
      +
      + +

      + groupBy_.groupBy(list, iterator) +
      + Splits a collection into sets, grouped by the result of running each + value through iterator. If iterator is a string instead of + a function, groups by the property named by iterator on each of + the values. +

      +
      +_.groupBy([1.3, 2.1, 2.4], function(num){ return Math.floor(num); });
      +=> {1: [1.3], 2: [2.1, 2.4]}
      +
      +_.groupBy(['one', 'two', 'three'], 'length');
      +=> {3: ["one", "two"], 5: ["three"]}
      +
      + +

      + countBy_.countBy(list, iterator) +
      + Sorts a list into groups and returns a count for the number of objects + in each group. + Similar to groupBy, but instead of returning a list of values, + returns a count for the number of values in that group. +

      +
      +_.countBy([1, 2, 3, 4, 5], function(num) { 
      +  return num % 2 == 0 ? 'even' : 'odd'; 
      +});
      +=> {odd: 3, even: 2}
      +
      + +

      + shuffle_.shuffle(list) +
      + Returns a shuffled copy of the list, using a version of the + Fisher-Yates shuffle. +

      +
      +_.shuffle([1, 2, 3, 4, 5, 6]);
      +=> [4, 1, 6, 3, 5, 2]
      +
      + +

      + toArray_.toArray(list) +
      + Converts the list (anything that can be iterated over), into a + real Array. Useful for transmuting the arguments object. +

      +
      +(function(){ return _.toArray(arguments).slice(1); })(1, 2, 3, 4);
      +=> [2, 3, 4]
      +
      + +

      + size_.size(list) +
      + Return the number of values in the list. +

      +
      +_.size({one : 1, two : 2, three : 3});
      +=> 3
      +
      + +

      Array Functions

      + +

      + + Note: All array functions will also work on the arguments object. + However, Underscore functions are not designed to work on "sparse" arrays. + +

      + +

      + first_.first(array, [n]) + Alias: head, take +
      + Returns the first element of an array. Passing n will + return the first n elements of the array. +

      +
      +_.first([5, 4, 3, 2, 1]);
      +=> 5
      +
      + +

      + initial_.initial(array, [n]) +
      + Returns everything but the last entry of the array. Especially useful on + the arguments object. Pass n to exclude the last n elements + from the result. +

      +
      +_.initial([5, 4, 3, 2, 1]);
      +=> [5, 4, 3, 2]
      +
      + +

      + last_.last(array, [n]) +
      + Returns the last element of an array. Passing n will return + the last n elements of the array. +

      +
      +_.last([5, 4, 3, 2, 1]);
      +=> 1
      +
      + +

      + rest_.rest(array, [index]) + Alias: tail, drop +
      + Returns the rest of the elements in an array. Pass an index + to return the values of the array from that index onward. +

      +
      +_.rest([5, 4, 3, 2, 1]);
      +=> [4, 3, 2, 1]
      +
      + +

      + compact_.compact(array) +
      + Returns a copy of the array with all falsy values removed. + In JavaScript, false, null, 0, "", + undefined and NaN are all falsy. +

      +
      +_.compact([0, 1, false, 2, '', 3]);
      +=> [1, 2, 3]
      +
      + +

      + flatten_.flatten(array, [shallow]) +
      + Flattens a nested array (the nesting can be to any depth). If you + pass shallow, the array will only be flattened a single level. +

      +
      +_.flatten([1, [2], [3, [[4]]]]);
      +=> [1, 2, 3, 4];
      +
      +_.flatten([1, [2], [3, [[4]]]], true);
      +=> [1, 2, 3, [[4]]];
      +
      + +

      + without_.without(array, [*values]) +
      + Returns a copy of the array with all instances of the values + removed. +

      +
      +_.without([1, 2, 1, 0, 3, 1, 4], 0, 1);
      +=> [2, 3, 4]
      +
      + +

      + union_.union(*arrays) +
      + Computes the union of the passed-in arrays: the list of unique items, + in order, that are present in one or more of the arrays. +

      +
      +_.union([1, 2, 3], [101, 2, 1, 10], [2, 1]);
      +=> [1, 2, 3, 101, 10]
      +
      + +

      + intersection_.intersection(*arrays) +
      + Computes the list of values that are the intersection of all the arrays. + Each value in the result is present in each of the arrays. +

      +
      +_.intersection([1, 2, 3], [101, 2, 1, 10], [2, 1]);
      +=> [1, 2]
      +
      + +

      + difference_.difference(array, *others) +
      + Similar to without, but returns the values from array that + are not present in the other arrays. +

      +
      +_.difference([1, 2, 3, 4, 5], [5, 2, 10]);
      +=> [1, 3, 4]
      +
      + +

      + uniq_.uniq(array, [isSorted], [iterator]) + Alias: unique +
      + Produces a duplicate-free version of the array, using === to test + object equality. If you know in advance that the array is sorted, + passing true for isSorted will run a much faster algorithm. + If you want to compute unique items based on a transformation, pass an + iterator function. +

      +
      +_.uniq([1, 2, 1, 3, 1, 4]);
      +=> [1, 2, 3, 4]
      +
      + +

      + zip_.zip(*arrays) +
      + Merges together the values of each of the arrays with the + values at the corresponding position. Useful when you have separate + data sources that are coordinated through matching array indexes. + If you're working with a matrix of nested arrays, zip.apply + can transpose the matrix in a similar fashion. +

      +
      +_.zip(['moe', 'larry', 'curly'], [30, 40, 50], [true, false, false]);
      +=> [["moe", 30, true], ["larry", 40, false], ["curly", 50, false]]
      +
      + +

      + object_.object(list, [values]) +
      + Converts arrays into objects. Pass either a single list of + [key, value] pairs, or a list of keys, and a list of values. +

      +
      +_.object(['moe', 'larry', 'curly'], [30, 40, 50]);
      +=> {moe: 30, larry: 40, curly: 50}
      +
      +_.object([['moe', 30], ['larry', 40], ['curly', 50]]);
      +=> {moe: 30, larry: 40, curly: 50}
      +
      + +

      + indexOf_.indexOf(array, value, [isSorted]) +
      + Returns the index at which value can be found in the array, + or -1 if value is not present in the array. Uses the native + indexOf function unless it's missing. If you're working with a + large array, and you know that the array is already sorted, pass true + for isSorted to use a faster binary search ... or, pass a number as + the third argument in order to look for the first matching value in the + array after the given index. +

      +
      +_.indexOf([1, 2, 3], 2);
      +=> 1
      +
      + +

      + lastIndexOf_.lastIndexOf(array, value, [fromIndex]) +
      + Returns the index of the last occurrence of value in the array, + or -1 if value is not present. Uses the native lastIndexOf + function if possible. Pass fromIndex to start your search at a + given index. +

      +
      +_.lastIndexOf([1, 2, 3, 1, 2, 3], 2);
      +=> 4
      +
      + +

      + sortedIndex_.sortedIndex(list, value, [iterator]) +
      + Uses a binary search to determine the index at which the value + should be inserted into the list in order to maintain the list's + sorted order. If an iterator is passed, it will be used to compute + the sort ranking of each value, including the value you pass. +

      +
      +_.sortedIndex([10, 20, 30, 40, 50], 35);
      +=> 3
      +
      + +

      + range_.range([start], stop, [step]) +
      + A function to create flexibly-numbered lists of integers, handy for + each and map loops. start, if omitted, defaults + to 0; step defaults to 1. Returns a list of integers + from start to stop, incremented (or decremented) by step, + exclusive. +

      +
      +_.range(10);
      +=> [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
      +_.range(1, 11);
      +=> [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
      +_.range(0, 30, 5);
      +=> [0, 5, 10, 15, 20, 25]
      +_.range(0, -10, -1);
      +=> [0, -1, -2, -3, -4, -5, -6, -7, -8, -9]
      +_.range(0);
      +=> []
      +
      + +

      Function (uh, ahem) Functions

      + +

      + bind_.bind(function, object, [*arguments]) +
      + Bind a function to an object, meaning that whenever + the function is called, the value of this will be the object. + Optionally, bind arguments to the function to pre-fill them, + also known as partial application. +

      +
      +var func = function(greeting){ return greeting + ': ' + this.name };
      +func = _.bind(func, {name : 'moe'}, 'hi');
      +func();
      +=> 'hi: moe'
      +
      + +

      + bindAll_.bindAll(object, [*methodNames]) +
      + Binds a number of methods on the object, specified by + methodNames, to be run in the context of that object whenever they + are invoked. Very handy for binding functions that are going to be used + as event handlers, which would otherwise be invoked with a fairly useless + this. If no methodNames are provided, all of the object's + function properties will be bound to it. +

      +
      +var buttonView = {
      +  label   : 'underscore',
      +  onClick : function(){ alert('clicked: ' + this.label); },
      +  onHover : function(){ console.log('hovering: ' + this.label); }
      +};
      +_.bindAll(buttonView);
      +jQuery('#underscore_button').bind('click', buttonView.onClick);
      +=> When the button is clicked, this.label will have the correct value...
      +
      + +

      + memoize_.memoize(function, [hashFunction]) +
      + Memoizes a given function by caching the computed result. Useful + for speeding up slow-running computations. If passed an optional + hashFunction, it will be used to compute the hash key for storing + the result, based on the arguments to the original function. The default + hashFunction just uses the first argument to the memoized function + as the key. +

      +
      +var fibonacci = _.memoize(function(n) {
      +  return n < 2 ? n : fibonacci(n - 1) + fibonacci(n - 2);
      +});
      +
      + +

      + delay_.delay(function, wait, [*arguments]) +
      + Much like setTimeout, invokes function after wait + milliseconds. If you pass the optional arguments, they will be + forwarded on to the function when it is invoked. +

      +
      +var log = _.bind(console.log, console);
      +_.delay(log, 1000, 'logged later');
      +=> 'logged later' // Appears after one second.
      +
      + +

      + defer_.defer(function, [*arguments]) +
      + Defers invoking the function until the current call stack has cleared, + similar to using setTimeout with a delay of 0. Useful for performing + expensive computations or HTML rendering in chunks without blocking the UI thread + from updating. If you pass the optional arguments, they will be + forwarded on to the function when it is invoked. +

      +
      +_.defer(function(){ alert('deferred'); });
      +// Returns from the function before the alert runs.
      +
      + +

      + throttle_.throttle(function, wait) +
      + Creates and returns a new, throttled version of the passed function, + that, when invoked repeatedly, will only actually call the original function + at most once per every wait + milliseconds. Useful for rate-limiting events that occur faster than you + can keep up with. +

      +
      +var throttled = _.throttle(updatePosition, 100);
      +$(window).scroll(throttled);
      +
      + +

      + debounce_.debounce(function, wait, [immediate]) +
      + Creates and returns a new debounced version of the passed function that + will postpone its execution until after + wait milliseconds have elapsed since the last time it + was invoked. Useful for implementing behavior that should only happen + after the input has stopped arriving. For example: rendering a + preview of a Markdown comment, recalculating a layout after the window + has stopped being resized, and so on. +

      + +

      + Pass true for the immediate parameter to cause + debounce to trigger the function on the leading instead of the + trailing edge of the wait interval. Useful in circumstances like + preventing accidental double-clicks on a "submit" button from firing a + second time. +

      + +
      +var lazyLayout = _.debounce(calculateLayout, 300);
      +$(window).resize(lazyLayout);
      +
      + +

      + once_.once(function) +
      + Creates a version of the function that can only be called one time. + Repeated calls to the modified function will have no effect, returning + the value from the original call. Useful for initialization functions, + instead of having to set a boolean flag and then check it later. +

      +
      +var initialize = _.once(createApplication);
      +initialize();
      +initialize();
      +// Application is only created once.
      +
      + +

      + after_.after(count, function) +
      + Creates a version of the function that will only be run after first + being called count times. Useful for grouping asynchronous responses, + where you want to be sure that all the async calls have finished, before + proceeding. +

      +
      +var renderNotes = _.after(notes.length, render);
      +_.each(notes, function(note) {
      +  note.asyncSave({success: renderNotes});
      +});
      +// renderNotes is run once, after all notes have saved.
      +
      + +

      + wrap_.wrap(function, wrapper) +
      + Wraps the first function inside of the wrapper function, + passing it as the first argument. This allows the wrapper to + execute code before and after the function runs, adjust the arguments, + and execute it conditionally. +

      +
      +var hello = function(name) { return "hello: " + name; };
      +hello = _.wrap(hello, function(func) {
      +  return "before, " + func("moe") + ", after";
      +});
      +hello();
      +=> 'before, hello: moe, after'
      +
      + +

      + compose_.compose(*functions) +
      + Returns the composition of a list of functions, where each function + consumes the return value of the function that follows. In math terms, + composing the functions f(), g(), and h() produces + f(g(h())). +

      +
      +var greet    = function(name){ return "hi: " + name; };
      +var exclaim  = function(statement){ return statement + "!"; };
      +var welcome = _.compose(exclaim, greet);
      +welcome('moe');
      +=> 'hi: moe!'
      +
      + +

      Object Functions

      + +

      + keys_.keys(object) +
      + Retrieve all the names of the object's properties. +

      +
      +_.keys({one : 1, two : 2, three : 3});
      +=> ["one", "two", "three"]
      +
      + +

      + values_.values(object) +
      + Return all of the values of the object's properties. +

      +
      +_.values({one : 1, two : 2, three : 3});
      +=> [1, 2, 3]
      +
      + +

      + pairs_.pairs(object) +
      + Convert an object into a list of [key, value] pairs. +

      +
      +_.pairs({one: 1, two: 2, three: 3});
      +=> [["one", 1], ["two", 2], ["three", 3]]
      +
      + +

      + invert_.invert(object) +
      + Returns a copy of the object where the keys have become the values + and the values the keys. For this to work, all of your object's values + should be unique and string serializable. +

      +
      +_.invert({Moe: "Moses", Larry: "Louis", Curly: "Jerome"});
      +=> {Moses: "Moe", Louis: "Larry", Jerome: "Curly"};
      +
      + +

      + functions_.functions(object) + Alias: methods +
      + Returns a sorted list of the names of every method in an object — + that is to say, the name of every function property of the object. +

      +
      +_.functions(_);
      +=> ["all", "any", "bind", "bindAll", "clone", "compact", "compose" ...
      +
      + +

      + extend_.extend(destination, *sources) +
      + Copy all of the properties in the source objects over to the + destination object, and return the destination object. + It's in-order, so the last source will override properties of the same + name in previous arguments. +

      +
      +_.extend({name : 'moe'}, {age : 50});
      +=> {name : 'moe', age : 50}
      +
      + +

      + pick_.pick(object, *keys) +
      + Return a copy of the object, filtered to only have values for + the whitelisted keys (or array of valid keys). +

      +
      +_.pick({name : 'moe', age: 50, userid : 'moe1'}, 'name', 'age');
      +=> {name : 'moe', age : 50}
      +
      + +

      + omit_.omit(object, *keys) +
      + Return a copy of the object, filtered to omit the blacklisted + keys (or array of keys). +

      +
      +_.omit({name : 'moe', age : 50, userid : 'moe1'}, 'userid');
      +=> {name : 'moe', age : 50}
      +
      + +

      + defaults_.defaults(object, *defaults) +
      + Fill in null and undefined properties in object with values from the + defaults objects, and return the object. As soon as the + property is filled, further defaults will have no effect. +

      +
      +var iceCream = {flavor : "chocolate"};
      +_.defaults(iceCream, {flavor : "vanilla", sprinkles : "lots"});
      +=> {flavor : "chocolate", sprinkles : "lots"}
      +
      + +

      + clone_.clone(object) +
      + Create a shallow-copied clone of the object. Any nested objects + or arrays will be copied by reference, not duplicated. +

      +
      +_.clone({name : 'moe'});
      +=> {name : 'moe'};
      +
      + +

      + tap_.tap(object, interceptor) +
      + Invokes interceptor with the object, and then returns object. + The primary purpose of this method is to "tap into" a method chain, in order to perform operations on intermediate results within the chain. +

      +
      +_.chain([1,2,3,200])
      +  .filter(function(num) { return num % 2 == 0; })
      +  .tap(alert)
      +  .map(function(num) { return num * num })
      +  .value();
      +=> // [2, 200] (alerted)
      +=> [4, 40000]
      +
      + +

      + has_.has(object, key) +
      + Does the object contain the given key? Identical to + object.hasOwnProperty(key), but uses a safe reference to the + hasOwnProperty function, in case it's been + overridden accidentally. +

      +
      +_.has({a: 1, b: 2, c: 3}, "b");
      +=> true
      +
      + +

      + isEqual_.isEqual(object, other) +
      + Performs an optimized deep comparison between the two objects, to determine + if they should be considered equal. +

      +
      +var moe   = {name : 'moe', luckyNumbers : [13, 27, 34]};
      +var clone = {name : 'moe', luckyNumbers : [13, 27, 34]};
      +moe == clone;
      +=> false
      +_.isEqual(moe, clone);
      +=> true
      +
      + +

      + isEmpty_.isEmpty(object) +
      + Returns true if object contains no values. +

      +
      +_.isEmpty([1, 2, 3]);
      +=> false
      +_.isEmpty({});
      +=> true
      +
      + +

      + isElement_.isElement(object) +
      + Returns true if object is a DOM element. +

      +
      +_.isElement(jQuery('body')[0]);
      +=> true
      +
      + +

      + isArray_.isArray(object) +
      + Returns true if object is an Array. +

      +
      +(function(){ return _.isArray(arguments); })();
      +=> false
      +_.isArray([1,2,3]);
      +=> true
      +
      + +

      + isObject_.isObject(value) +
      + Returns true if value is an Object. Note that JavaScript + arrays and functions are objects, while (normal) strings and numbers are not. +

      +
      +_.isObject({});
      +=> true
      +_.isObject(1);
      +=> false
      +
      + +

      + isArguments_.isArguments(object) +
      + Returns true if object is an Arguments object. +

      +
      +(function(){ return _.isArguments(arguments); })(1, 2, 3);
      +=> true
      +_.isArguments([1,2,3]);
      +=> false
      +
      + +

      + isFunction_.isFunction(object) +
      + Returns true if object is a Function. +

      +
      +_.isFunction(alert);
      +=> true
      +
      + +

      + isString_.isString(object) +
      + Returns true if object is a String. +

      +
      +_.isString("moe");
      +=> true
      +
      + +

      + isNumber_.isNumber(object) +
      + Returns true if object is a Number (including NaN). +

      +
      +_.isNumber(8.4 * 5);
      +=> true
      +
      + +

      + isFinite_.isFinite(object) +
      + Returns true if object is a finite Number. +

      +
      +_.isFinite(-101);
      +=> true
      +
      +_.isFinite(-Infinity);
      +=> false
      +
      + +

      + isBoolean_.isBoolean(object) +
      + Returns true if object is either true or false. +

      +
      +_.isBoolean(null);
      +=> false
      +
      + +

      + isDate_.isDate(object) +
      + Returns true if object is a Date. +

      +
      +_.isDate(new Date());
      +=> true
      +
      + +

      + isRegExp_.isRegExp(object) +
      + Returns true if object is a RegExp. +

      +
      +_.isRegExp(/moe/);
      +=> true
      +
      + +

      + isNaN_.isNaN(object) +
      + Returns true if object is NaN.
      Note: this is not + the same as the native isNaN function, which will also return + true if the variable is undefined. +

      +
      +_.isNaN(NaN);
      +=> true
      +isNaN(undefined);
      +=> true
      +_.isNaN(undefined);
      +=> false
      +
      + +

      + isNull_.isNull(object) +
      + Returns true if the value of object is null. +

      +
      +_.isNull(null);
      +=> true
      +_.isNull(undefined);
      +=> false
      +
      + +

      + isUndefined_.isUndefined(value) +
      + Returns true if value is undefined. +

      +
      +_.isUndefined(window.missingVariable);
      +=> true
      +
      + +

      Utility Functions

      + +

      + noConflict_.noConflict() +
      + Give control of the "_" variable back to its previous owner. Returns + a reference to the Underscore object. +

      +
      +var underscore = _.noConflict();
      + +

      + identity_.identity(value) +
      + Returns the same value that is used as the argument. In math: + f(x) = x
      + This function looks useless, but is used throughout Underscore as + a default iterator. +

      +
      +var moe = {name : 'moe'};
      +moe === _.identity(moe);
      +=> true
      + +

      + times_.times(n, iterator, [context]) +
      + Invokes the given iterator function n times. Each invocation of + iterator is called with an index argument. +

      +
      +_(3).times(function(n){ genie.grantWishNumber(n); });
      + +

      + random_.random(min, max) +
      + Returns a random integer between min and max, inclusive. + If you only pass one argument, it will return a number between 0 + and that number. +

      +
      +_.random(0, 100);
      +=> 42
      + +

      + mixin_.mixin(object) +
      + Allows you to extend Underscore with your own utility functions. Pass + a hash of {name: function} definitions to have your functions + added to the Underscore object, as well as the OOP wrapper. +

      +
      +_.mixin({
      +  capitalize : function(string) {
      +    return string.charAt(0).toUpperCase() + string.substring(1).toLowerCase();
      +  }
      +});
      +_("fabio").capitalize();
      +=> "Fabio"
      +
      + +

      + uniqueId_.uniqueId([prefix]) +
      + Generate a globally-unique id for client-side models or DOM elements + that need one. If prefix is passed, the id will be appended to it. + Without prefix, returns an integer. +

      +
      +_.uniqueId('contact_');
      +=> 'contact_104'
      + +

      + escape_.escape(string) +
      + Escapes a string for insertion into HTML, replacing + &, <, >, ", ', and / characters. +

      +
      +_.escape('Curly, Larry & Moe');
      +=> "Curly, Larry &amp; Moe"
      + +

      + result_.result(object, property) +
      + If the value of the named property is a function then invoke it; otherwise, return it. +

      +
      +var object = {cheese: 'crumpets', stuff: function(){ return 'nonsense'; }};
      +_.result(object, 'cheese');
      +=> "crumpets"
      +_.result(object, 'stuff');
      +=> "nonsense"
      + +

      + template_.template(templateString, [data], [settings]) +
      + Compiles JavaScript templates into functions that can be evaluated + for rendering. Useful for rendering complicated bits of HTML from JSON + data sources. Template functions can both interpolate variables, using + <%= … %>, as well as execute arbitrary JavaScript code, with + <% … %>. If you wish to interpolate a value, and have + it be HTML-escaped, use <%- … %> When you evaluate a template function, pass in a + data object that has properties corresponding to the template's free + variables. If you're writing a one-off, you can pass the data + object as the second parameter to template in order to render + immediately instead of returning a template function. The settings argument + should be a hash containing any _.templateSettings that should be overridden. +

      + +
      +var compiled = _.template("hello: <%= name %>");
      +compiled({name : 'moe'});
      +=> "hello: moe"
      +
      +var list = "<% _.each(people, function(name) { %> <li><%= name %></li> <% }); %>";
      +_.template(list, {people : ['moe', 'curly', 'larry']});
      +=> "<li>moe</li><li>curly</li><li>larry</li>"
      +
      +var template = _.template("<b><%- value %></b>");
      +template({value : '<script>'});
      +=> "<b>&lt;script&gt;</b>"
      + +

      + You can also use print from within JavaScript code. This is + sometimes more convenient than using <%= ... %>. +

      + +
      +var compiled = _.template("<% print('Hello ' + epithet); %>");
      +compiled({epithet: "stooge"});
      +=> "Hello stooge."
      + +

      + If ERB-style delimiters aren't your cup of tea, you can change Underscore's + template settings to use different symbols to set off interpolated code. + Define an interpolate regex to match expressions that should be + interpolated verbatim, an escape regex to match expressions that should + be inserted after being HTML escaped, and an evaluate regex to match + expressions that should be evaluated without insertion into the resulting + string. You may define or omit any combination of the three. + For example, to perform + Mustache.js + style templating: +

      + +
      +_.templateSettings = {
      +  interpolate : /\{\{(.+?)\}\}/g
      +};
      +
      +var template = _.template("Hello {{ name }}!");
      +template({name : "Mustache"});
      +=> "Hello Mustache!"
      + +

      + By default, template places the values from your data in the local scope + via the with statement. However, you can specify a single variable name + with the variable setting. This can significantly improve the speed + at which a template is able to render. +

      + +
      +_.template("Using 'with': <%= data.answer %>", {answer: 'no'}, {variable: 'data'});
      +=> "Using 'with': no"
      + +

      + Precompiling your templates can be a big help when debugging errors you can't + reproduce. This is because precompiled templates can provide line numbers and + a stack trace, something that is not possible when compiling templates on the client. + The source property is available on the compiled template + function for easy precompilation. +

      + +
      <script>
      +  JST.project = <%= _.template(jstText).source %>;
      +</script>
      + + +

      Chaining

      + +

      + You can use Underscore in either an object-oriented or a functional style, + depending on your preference. The following two lines of code are + identical ways to double a list of numbers. +

      + +
      +_.map([1, 2, 3], function(n){ return n * 2; });
      +_([1, 2, 3]).map(function(n){ return n * 2; });
      + +

      + Calling chain will cause all future method calls to return + wrapped objects. When you've finished the computation, use + value to retrieve the final value. Here's an example of chaining + together a map/flatten/reduce, in order to get the word count of + every word in a song. +

      + +
      +var lyrics = [
      +  {line : 1, words : "I'm a lumberjack and I'm okay"},
      +  {line : 2, words : "I sleep all night and I work all day"},
      +  {line : 3, words : "He's a lumberjack and he's okay"},
      +  {line : 4, words : "He sleeps all night and he works all day"}
      +];
      +
      +_.chain(lyrics)
      +  .map(function(line) { return line.words.split(' '); })
      +  .flatten()
      +  .reduce(function(counts, word) {
      +    counts[word] = (counts[word] || 0) + 1;
      +    return counts;
      +}, {}).value();
      +
      +=> {lumberjack : 2, all : 4, night : 2 ... }
      + +

      + In addition, the + Array prototype's methods + are proxied through the chained Underscore object, so you can slip a + reverse or a push into your chain, and continue to + modify the array. +

      + +

      + chain_.chain(obj) +
      + Returns a wrapped object. Calling methods on this object will continue + to return wrapped objects until value is used. +

      +
      +var stooges = [{name : 'curly', age : 25}, {name : 'moe', age : 21}, {name : 'larry', age : 23}];
      +var youngest = _.chain(stooges)
      +  .sortBy(function(stooge){ return stooge.age; })
      +  .map(function(stooge){ return stooge.name + ' is ' + stooge.age; })
      +  .first()
      +  .value();
      +=> "moe is 21"
      +
      + +

      + value_(obj).value() +
      + Extracts the value of a wrapped object. +

      +
      +_([1, 2, 3]).value();
      +=> [1, 2, 3]
      +
      + + + +

      + The Underscore documentation is also available in + Simplified Chinese. +

      + +

      + Underscore.lua, + a Lua port of the functions that are applicable in both languages. + Includes OOP-wrapping and chaining. + (source) +

      + +

      + Underscore.m, an Objective-C port + of many of the Underscore.js functions, using a syntax that encourages + chaining. + (source) +

      + +

      + _.m, an alternative + Objective-C port that tries to stick a little closer to the original + Underscore.js API. + (source) +

      + +

      + Underscore.php, + a PHP port of the functions that are applicable in both languages. + Includes OOP-wrapping and chaining. + (source) +

      + +

      + Underscore-perl, + a Perl port of many of the Underscore.js functions, + aimed at on Perl hashes and arrays. + (source) +

      + +

      + Underscore.cfc, + a Coldfusion port of many of the Underscore.js functions. + (source) +

      + +

      + Underscore.string, + an Underscore extension that adds functions for string-manipulation: + trim, startsWith, contains, capitalize, + reverse, sprintf, and more. +

      + +

      + Ruby's Enumerable module. +

      + +

      + Prototype.js, which provides + JavaScript with collection functions in the manner closest to Ruby's Enumerable. +

      + +

      + Oliver Steele's + Functional JavaScript, + which includes comprehensive higher-order function support as well as string lambdas. +

      + +

      + Michael Aufreiter's Data.js, + a data manipulation + persistence library for JavaScript. +

      + +

      + Python's itertools. +

      + +

      Change Log

      + +

      + 1.4.2Oct. 1, 2012Diff
      +

        +
      • + For backwards compatibility, returned to pre-1.4.0 behavior when + passing null to iteration functions. They now become no-ops + again. +
      • +
      +

      + +

      + 1.4.1Oct. 1, 2012Diff
      +

        +
      • + Fixed a 1.4.0 regression in the lastIndexOf function. +
      • +
      +

      + +

      + 1.4.0Sept. 27, 2012Diff
      +

        +
      • + Added a pairs function, for turning a JavaScript object + into [key, value] pairs ... as well as an object + function, for converting an array of [key, value] pairs + into an object. +
      • +
      • + Added a countBy function, for counting the number of objects + in a list that match a certain criteria. +
      • +
      • + Added an invert function, for performing a simple inversion + of the keys and values in an object. +
      • +
      • + Added a where function, for easy cases of filtering a list + for objects with specific values. +
      • +
      • + Added an omit function, for filtering an object to remove + certain keys. +
      • +
      • + Added a random function, to return a random number in a + given range. +
      • +
      • + _.debounce'd functions now return their last updated value, + just like _.throttle'd functions do. +
      • +
      • + The sortBy function now runs a stable sort algorithm. +
      • +
      • + Added the optional fromIndex option to indexOf and + lastIndexOf. +
      • +
      • + "Sparse" arrays are no longer supported in Underscore iteration + functions. Use a for loop instead (or better yet, an object). +
      • +
      • + The min and max functions may now be called on + very large arrays. +
      • +
      • + Interpolation in templates now represents null and + undefined as the empty string. +
      • +
      • + Underscore iteration functions no longer accept null values + as a no-op argument. You'll get an early error instead. +
      • +
      • + A number of edge-cases fixes and tweaks, which you can spot in the + diff. + Depending on how you're using Underscore, 1.4.0 may be more + backwards-incompatible than usual — please test when you upgrade. +
      • +
      +

      + +

      + 1.3.3April 10, 2012
      +

        +
      • + Many improvements to _.template, which now provides the + source of the template function as a property, for potentially + even more efficient pre-compilation on the server-side. You may now + also set the variable option when creating a template, + which will cause your passed-in data to be made available under the + variable you named, instead of using a with statement — + significantly improving the speed of rendering the template. +
      • +
      • + Added the pick function, which allows you to filter an + object literal with a whitelist of allowed property names. +
      • +
      • + Added the result function, for convenience when working + with APIs that allow either functions or raw properties. +
      • +
      • + Added the isFinite function, because sometimes knowing that + a value is a number just ain't quite enough. +
      • +
      • + The sortBy function may now also be passed the string name + of a property to use as the sort order on each object. +
      • +
      • + Fixed uniq to work with sparse arrays. +
      • +
      • + The difference function now performs a shallow flatten + instead of a deep one when computing array differences. +
      • +
      • + The debounce function now takes an immediate + parameter, which will cause the callback to fire on the leading + instead of the trailing edge. +
      • +
      +

      + +

      + 1.3.1Jan. 23, 2012
      +

        +
      • + Added an _.has function, as a safer way to use hasOwnProperty. +
      • +
      • + Added _.collect as an alias for _.map. Smalltalkers, rejoice. +
      • +
      • + Reverted an old change so that _.extend will correctly copy + over keys with undefined values again. +
      • +
      • + Bugfix to stop escaping slashes within interpolations in _.template. +
      • +
      +

      + +

      + 1.3.0Jan. 11, 2012
      +

        +
      • + Removed AMD (RequireJS) support from Underscore. If you'd like to use + Underscore with RequireJS, you can load it as a normal script, wrap + or patch your copy, or download a forked version. +
      • +
      +

      + +

      + 1.2.4Jan. 4, 2012
      +

        +
      • + You now can (and probably should, as it's simpler) + write _.chain(list) + instead of _(list).chain(). +
      • +
      • + Fix for escaped characters in Underscore templates, and for supporting + customizations of _.templateSettings that only define one or + two of the required regexes. +
      • +
      • + Fix for passing an array as the first argument to an _.wrap'd function. +
      • +
      • + Improved compatibility with ClojureScript, which adds a call + function to String.prototype. +
      • +
      +

      + +

      + 1.2.3Dec. 7, 2011
      +

        +
      • + Dynamic scope is now preserved for compiled _.template functions, + so you can use the value of this if you like. +
      • +
      • + Sparse array support of _.indexOf, _.lastIndexOf. +
      • +
      • + Both _.reduce and _.reduceRight can now be passed an + explicitly undefined value. (There's no reason why you'd + want to do this.) +
      • +
      +

      + +

      + 1.2.2Nov. 14, 2011
      +

        +
      • + Continued tweaks to _.isEqual semantics. Now JS primitives are + considered equivalent to their wrapped versions, and arrays are compared + by their numeric properties only (#351). +
      • +
      • + _.escape no longer tries to be smart about not double-escaping + already-escaped HTML entities. Now it just escapes regardless (#350). +
      • +
      • + In _.template, you may now leave semicolons out of evaluated + statements if you wish: <% }) %> (#369). +
      • +
      • + _.after(callback, 0) will now trigger the callback immediately, + making "after" easier to use with asynchronous APIs (#366). +
      • +
      +

      + +

      + 1.2.1Oct. 24, 2011
      +

        +
      • + Several important bug fixes for _.isEqual, which should now + do better on mutated Arrays, and on non-Array objects with + length properties. (#329) +
      • +
      • + jrburke contributed Underscore exporting for AMD module loaders, + and tonylukasavage for Appcelerator Titanium. + (#335, #338) +
      • +
      • + You can now _.groupBy(list, 'property') as a shortcut for + grouping values by a particular common property. +
      • +
      • + _.throttle'd functions now fire immediately upon invocation, + and are rate-limited thereafter (#170, #266). +
      • +
      • + Most of the _.is[Type] checks no longer ducktype. +
      • +
      • + The _.bind function now also works on constructors, a-la + ES5 ... but you would never want to use _.bind on a + constructor function. +
      • +
      • + _.clone no longer wraps non-object types in Objects. +
      • +
      • + _.find and _.filter are now the preferred names for + _.detect and _.select. +
      • +
      +

      + +

      + 1.2.0Oct. 5, 2011
      +

        +
      • + The _.isEqual function now + supports true deep equality comparisons, with checks for cyclic structures, + thanks to Kit Cambridge. +
      • +
      • + Underscore templates now support HTML escaping interpolations, using + <%- ... %> syntax. +
      • +
      • + Ryan Tenney contributed _.shuffle, which uses a modified + Fisher-Yates to give you a shuffled copy of an array. +
      • +
      • + _.uniq can now be passed an optional iterator, to determine by + what criteria an object should be considered unique. +
      • +
      • + _.last now takes an optional argument which will return the last + N elements of the list. +
      • +
      • + A new _.initial function was added, as a mirror of _.rest, + which returns all the initial values of a list (except the last N). +
      • +
      +

      + +

      + 1.1.7July 13, 2011
      + Added _.groupBy, which aggregates a collection into groups of like items. + Added _.union and _.difference, to complement the + (re-named) _.intersection. + Various improvements for support of sparse arrays. + _.toArray now returns a clone, if directly passed an array. + _.functions now also returns the names of functions that are present + in the prototype chain. +

      + +

      + 1.1.6April 18, 2011
      + Added _.after, which will return a function that only runs after + first being called a specified number of times. + _.invoke can now take a direct function reference. + _.every now requires an iterator function to be passed, which + mirrors the ECMA5 API. + _.extend no longer copies keys when the value is undefined. + _.bind now errors when trying to bind an undefined value. +

      + +

      + 1.1.5Mar 20, 2011
      + Added an _.defaults function, for use merging together JS objects + representing default options. + Added an _.once function, for manufacturing functions that should + only ever execute a single time. + _.bind now delegates to the native ECMAScript 5 version, + where available. + _.keys now throws an error when used on non-Object values, as in + ECMAScript 5. + Fixed a bug with _.keys when used over sparse arrays. +

      + +

      + 1.1.4Jan 9, 2011
      + Improved compliance with ES5's Array methods when passing null + as a value. _.wrap now correctly sets this for the + wrapped function. _.indexOf now takes an optional flag for + finding the insertion index in an array that is guaranteed to already + be sorted. Avoiding the use of .callee, to allow _.isArray + to work properly in ES5's strict mode. +

      + +

      + 1.1.3Dec 1, 2010
      + In CommonJS, Underscore may now be required with just:
      + var _ = require("underscore"). + Added _.throttle and _.debounce functions. + Removed _.breakLoop, in favor of an ECMA5-style un-break-able + each implementation — this removes the try/catch, and you'll now have + better stack traces for exceptions that are thrown within an Underscore iterator. + Improved the isType family of functions for better interoperability + with Internet Explorer host objects. + _.template now correctly escapes backslashes in templates. + Improved _.reduce compatibility with the ECMA5 version: + if you don't pass an initial value, the first item in the collection is used. + _.each no longer returns the iterated collection, for improved + consistency with ES5's forEach. +

      + +

      + 1.1.2
      + Fixed _.contains, which was mistakenly pointing at + _.intersect instead of _.include, like it should + have been. Added _.unique as an alias for _.uniq. +

      + +

      + 1.1.1
      + Improved the speed of _.template, and its handling of multiline + interpolations. Ryan Tenney contributed optimizations to many Underscore + functions. An annotated version of the source code is now available. +

      + +

      + 1.1.0
      + The method signature of _.reduce has been changed to match + the ECMAScript 5 signature, instead of the Ruby/Prototype.js version. + This is a backwards-incompatible change. _.template may now be + called with no arguments, and preserves whitespace. _.contains + is a new alias for _.include. +

      + +

      + 1.0.4
      + Andri Möll contributed the _.memoize + function, which can be used to speed up expensive repeated computations + by caching the results. +

      + +

      + 1.0.3
      + Patch that makes _.isEqual return false if any property + of the compared object has a NaN value. Technically the correct + thing to do, but of questionable semantics. Watch out for NaN comparisons. +

      + +

      + 1.0.2
      + Fixes _.isArguments in recent versions of Opera, which have + arguments objects as real Arrays. +

      + +

      + 1.0.1
      + Bugfix for _.isEqual, when comparing two objects with the same + number of undefined keys, but with different names. +

      + +

      + 1.0.0
      + Things have been stable for many months now, so Underscore is now + considered to be out of beta, at 1.0. Improvements since 0.6 + include _.isBoolean, and the ability to have _.extend + take multiple source objects. +

      + +

      + 0.6.0
      + Major release. Incorporates a number of + Mile Frawley's refactors for + safer duck-typing on collection functions, and cleaner internals. A new + _.mixin method that allows you to extend Underscore with utility + functions of your own. Added _.times, which works the same as in + Ruby or Prototype.js. Native support for ECMAScript 5's Array.isArray, + and Object.keys. +

      + +

      + 0.5.8
      + Fixed Underscore's collection functions to work on + NodeLists and + HTMLCollections + once more, thanks to + Justin Tulloss. +

      + +

      + 0.5.7
      + A safer implementation of _.isArguments, and a + faster _.isNumber,
      thanks to + Jed Schmidt. +

      + +

      + 0.5.6
      + Customizable delimiters for _.template, contributed by + Noah Sloan. +

      + +

      + 0.5.5
      + Fix for a bug in MobileSafari's OOP-wrapper, with the arguments object. +

      + +

      + 0.5.4
      + Fix for multiple single quotes within a template string for + _.template. See: + Rick Strahl's blog post. +

      + +

      + 0.5.2
      + New implementations of isArray, isDate, isFunction, + isNumber, isRegExp, and isString, thanks to + a suggestion from + Robert Kieffer. + Instead of doing Object#toString + comparisons, they now check for expected properties, which is less safe, + but more than an order of magnitude faster. Most other Underscore + functions saw minor speed improvements as a result. + Evgeniy Dolzhenko + contributed _.tap, + similar to Ruby 1.9's, + which is handy for injecting side effects (like logging) into chained calls. +

      + +

      + 0.5.1
      + Added an _.isArguments function. Lots of little safety checks + and optimizations contributed by + Noah Sloan and + Andri Möll. +

      + +

      + 0.5.0
      + [API Changes] _.bindAll now takes the context object as + its first parameter. If no method names are passed, all of the context + object's methods are bound to it, enabling chaining and easier binding. + _.functions now takes a single argument and returns the names + of its Function properties. Calling _.functions(_) will get you + the previous behavior. + Added _.isRegExp so that isEqual can now test for RegExp equality. + All of the "is" functions have been shrunk down into a single definition. + Karl Guertin contributed patches. +

      + +

      + 0.4.7
      + Added isDate, isNaN, and isNull, for completeness. + Optimizations for isEqual when checking equality between Arrays + or Dates. _.keys is now 25%–2X faster (depending on your + browser) which speeds up the functions that rely on it, such as _.each. +

      + +

      + 0.4.6
      + Added the range function, a port of the + Python + function of the same name, for generating flexibly-numbered lists + of integers. Original patch contributed by + Kirill Ishanov. +

      + +

      + 0.4.5
      + Added rest for Arrays and arguments objects, and aliased + first as head, and rest as tail, + thanks to Luke Sutton's patches. + Added tests ensuring that all Underscore Array functions also work on + arguments objects. +

      + +

      + 0.4.4
      + Added isString, and isNumber, for consistency. Fixed + _.isEqual(NaN, NaN) to return true (which is debatable). +

      + +

      + 0.4.3
      + Started using the native StopIteration object in browsers that support it. + Fixed Underscore setup for CommonJS environments. +

      + +

      + 0.4.2
      + Renamed the unwrapping function to value, for clarity. +

      + +

      + 0.4.1
      + Chained Underscore objects now support the Array prototype methods, so + that you can perform the full range of operations on a wrapped array + without having to break your chain. Added a breakLoop method + to break in the middle of any Underscore iteration. Added an + isEmpty function that works on arrays and objects. +

      + +

      + 0.4.0
      + All Underscore functions can now be called in an object-oriented style, + like so: _([1, 2, 3]).map(...);. Original patch provided by + Marc-André Cournoyer. + Wrapped objects can be chained through multiple + method invocations. A functions method + was added, providing a sorted list of all the functions in Underscore. +

      + +

      + 0.3.3
      + Added the JavaScript 1.8 function reduceRight. Aliased it + as foldr, and aliased reduce as foldl. +

      + +

      + 0.3.2
      + Now runs on stock Rhino + interpreters with: load("underscore.js"). + Added identity as a utility function. +

      + +

      + 0.3.1
      + All iterators are now passed in the original collection as their third + argument, the same as JavaScript 1.6's forEach. Iterating over + objects is now called with (value, key, collection), for details + see _.each. +

      + +

      + 0.3.0
      + Added Dmitry Baranovskiy's + comprehensive optimizations, merged in + Kris Kowal's patches to make Underscore + CommonJS and + Narwhal compliant. +

      + +

      + 0.2.0
      + Added compose and lastIndexOf, renamed inject to + reduce, added aliases for inject, filter, + every, some, and forEach. +

      + +

      + 0.1.1
      + Added noConflict, so that the "Underscore" object can be assigned to + other variables. +

      + +

      + 0.1.0
      + Initial release of Underscore.js. +

      + +

      + + A DocumentCloud Project + +

      + +
      + +
      + + + + + + diff --git a/htdocs/js/lib/webwork/components/underscore/index.js b/htdocs/js/lib/webwork/components/underscore/index.js new file mode 100644 index 000000000..2cf0ca5b0 --- /dev/null +++ b/htdocs/js/lib/webwork/components/underscore/index.js @@ -0,0 +1 @@ +module.exports = require('./underscore'); diff --git a/htdocs/js/lib/webwork/components/underscore/package.json b/htdocs/js/lib/webwork/components/underscore/package.json new file mode 100644 index 000000000..849d81783 --- /dev/null +++ b/htdocs/js/lib/webwork/components/underscore/package.json @@ -0,0 +1,10 @@ +{ + "name" : "underscore", + "description" : "JavaScript's functional programming helper library.", + "homepage" : "http://underscorejs.org", + "keywords" : ["util", "functional", "server", "client", "browser"], + "author" : "Jeremy Ashkenas ", + "repository" : {"type": "git", "url": "git://github.com/documentcloud/underscore.git"}, + "main" : "underscore.js", + "version" : "1.4.2" +} diff --git a/htdocs/js/lib/webwork/components/underscore/test/arrays.js b/htdocs/js/lib/webwork/components/underscore/test/arrays.js new file mode 100644 index 000000000..a757ced67 --- /dev/null +++ b/htdocs/js/lib/webwork/components/underscore/test/arrays.js @@ -0,0 +1,194 @@ +$(document).ready(function() { + + module("Arrays"); + + test("first", function() { + equal(_.first([1,2,3]), 1, 'can pull out the first element of an array'); + equal(_([1, 2, 3]).first(), 1, 'can perform OO-style "first()"'); + equal(_.first([1,2,3], 0).join(', '), "", 'can pass an index to first'); + equal(_.first([1,2,3], 2).join(', '), '1, 2', 'can pass an index to first'); + equal(_.first([1,2,3], 5).join(', '), '1, 2, 3', 'can pass an index to first'); + var result = (function(){ return _.first(arguments); })(4, 3, 2, 1); + equal(result, 4, 'works on an arguments object.'); + result = _.map([[1,2,3],[1,2,3]], _.first); + equal(result.join(','), '1,1', 'works well with _.map'); + result = (function() { return _.take([1,2,3], 2); })(); + equal(result.join(','), '1,2', 'aliased as take'); + }); + + test("rest", function() { + var numbers = [1, 2, 3, 4]; + equal(_.rest(numbers).join(", "), "2, 3, 4", 'working rest()'); + equal(_.rest(numbers, 0).join(", "), "1, 2, 3, 4", 'working rest(0)'); + equal(_.rest(numbers, 2).join(', '), '3, 4', 'rest can take an index'); + var result = (function(){ return _(arguments).tail(); })(1, 2, 3, 4); + equal(result.join(', '), '2, 3, 4', 'aliased as tail and works on arguments object'); + result = _.map([[1,2,3],[1,2,3]], _.rest); + equal(_.flatten(result).join(','), '2,3,2,3', 'works well with _.map'); + result = (function(){ return _(arguments).drop(); })(1, 2, 3, 4); + equal(result.join(', '), '2, 3, 4', 'aliased as drop and works on arguments object'); + }); + + test("initial", function() { + equal(_.initial([1,2,3,4,5]).join(", "), "1, 2, 3, 4", 'working initial()'); + equal(_.initial([1,2,3,4],2).join(", "), "1, 2", 'initial can take an index'); + var result = (function(){ return _(arguments).initial(); })(1, 2, 3, 4); + equal(result.join(", "), "1, 2, 3", 'initial works on arguments object'); + result = _.map([[1,2,3],[1,2,3]], _.initial); + equal(_.flatten(result).join(','), '1,2,1,2', 'initial works with _.map'); + }); + + test("last", function() { + equal(_.last([1,2,3]), 3, 'can pull out the last element of an array'); + equal(_.last([1,2,3], 0).join(', '), "", 'can pass an index to last'); + equal(_.last([1,2,3], 2).join(', '), '2, 3', 'can pass an index to last'); + equal(_.last([1,2,3], 5).join(', '), '1, 2, 3', 'can pass an index to last'); + var result = (function(){ return _(arguments).last(); })(1, 2, 3, 4); + equal(result, 4, 'works on an arguments object'); + result = _.map([[1,2,3],[1,2,3]], _.last); + equal(result.join(','), '3,3', 'works well with _.map'); + }); + + test("compact", function() { + equal(_.compact([0, 1, false, 2, false, 3]).length, 3, 'can trim out all falsy values'); + var result = (function(){ return _(arguments).compact().length; })(0, 1, false, 2, false, 3); + equal(result, 3, 'works on an arguments object'); + }); + + test("flatten", function() { + if (window.JSON) { + var list = [1, [2], [3, [[[4]]]]]; + equal(JSON.stringify(_.flatten(list)), '[1,2,3,4]', 'can flatten nested arrays'); + equal(JSON.stringify(_.flatten(list, true)), '[1,2,3,[[[4]]]]', 'can shallowly flatten nested arrays'); + var result = (function(){ return _.flatten(arguments); })(1, [2], [3, [[[4]]]]); + equal(JSON.stringify(result), '[1,2,3,4]', 'works on an arguments object'); + } + }); + + test("without", function() { + var list = [1, 2, 1, 0, 3, 1, 4]; + equal(_.without(list, 0, 1).join(', '), '2, 3, 4', 'can remove all instances of an object'); + var result = (function(){ return _.without(arguments, 0, 1); })(1, 2, 1, 0, 3, 1, 4); + equal(result.join(', '), '2, 3, 4', 'works on an arguments object'); + + var list = [{one : 1}, {two : 2}]; + ok(_.without(list, {one : 1}).length == 2, 'uses real object identity for comparisons.'); + ok(_.without(list, list[0]).length == 1, 'ditto.'); + }); + + test("uniq", function() { + var list = [1, 2, 1, 3, 1, 4]; + equal(_.uniq(list).join(', '), '1, 2, 3, 4', 'can find the unique values of an unsorted array'); + + var list = [1, 1, 1, 2, 2, 3]; + equal(_.uniq(list, true).join(', '), '1, 2, 3', 'can find the unique values of a sorted array faster'); + + var list = [{name:'moe'}, {name:'curly'}, {name:'larry'}, {name:'curly'}]; + var iterator = function(value) { return value.name; }; + equal(_.map(_.uniq(list, false, iterator), iterator).join(', '), 'moe, curly, larry', 'can find the unique values of an array using a custom iterator'); + + var iterator = function(value) { return value +1; }; + var list = [1, 2, 2, 3, 4, 4]; + equal(_.uniq(list, true, iterator).join(', '), '1, 2, 3, 4', 'iterator works with sorted array'); + + var result = (function(){ return _.uniq(arguments); })(1, 2, 1, 3, 1, 4); + equal(result.join(', '), '1, 2, 3, 4', 'works on an arguments object'); + }); + + test("intersection", function() { + var stooges = ['moe', 'curly', 'larry'], leaders = ['moe', 'groucho']; + equal(_.intersection(stooges, leaders).join(''), 'moe', 'can take the set intersection of two arrays'); + equal(_(stooges).intersection(leaders).join(''), 'moe', 'can perform an OO-style intersection'); + var result = (function(){ return _.intersection(arguments, leaders); })('moe', 'curly', 'larry'); + equal(result.join(''), 'moe', 'works on an arguments object'); + }); + + test("union", function() { + var result = _.union([1, 2, 3], [2, 30, 1], [1, 40]); + equal(result.join(' '), '1 2 3 30 40', 'takes the union of a list of arrays'); + + var result = _.union([1, 2, 3], [2, 30, 1], [1, 40, [1]]); + equal(result.join(' '), '1 2 3 30 40 1', 'takes the union of a list of nested arrays'); + }); + + test("difference", function() { + var result = _.difference([1, 2, 3], [2, 30, 40]); + equal(result.join(' '), '1 3', 'takes the difference of two arrays'); + + var result = _.difference([1, 2, 3, 4], [2, 30, 40], [1, 11, 111]); + equal(result.join(' '), '3 4', 'takes the difference of three arrays'); + }); + + test('zip', function() { + var names = ['moe', 'larry', 'curly'], ages = [30, 40, 50], leaders = [true]; + var stooges = _.zip(names, ages, leaders); + equal(String(stooges), 'moe,30,true,larry,40,,curly,50,', 'zipped together arrays of different lengths'); + }); + + test('object', function() { + var result = _.object(['moe', 'larry', 'curly'], [30, 40, 50]); + var shouldBe = {moe: 30, larry: 40, curly: 50}; + ok(_.isEqual(result, shouldBe), 'two arrays zipped together into an object'); + + result = _.object([['one', 1], ['two', 2], ['three', 3]]); + shouldBe = {one: 1, two: 2, three: 3}; + ok(_.isEqual(result, shouldBe), 'an array of pairs zipped together into an object'); + + var stooges = {moe: 30, larry: 40, curly: 50}; + ok(_.isEqual(_.object(_.pairs(stooges)), stooges), 'an object converted to pairs and back to an object'); + }); + + test("indexOf", function() { + var numbers = [1, 2, 3]; + numbers.indexOf = null; + equal(_.indexOf(numbers, 2), 1, 'can compute indexOf, even without the native function'); + var result = (function(){ return _.indexOf(arguments, 2); })(1, 2, 3); + equal(result, 1, 'works on an arguments object'); + equal(_.indexOf(null, 2), -1, 'handles nulls properly'); + + var numbers = [10, 20, 30, 40, 50], num = 35; + var index = _.indexOf(numbers, num, true); + equal(index, -1, '35 is not in the list'); + + numbers = [10, 20, 30, 40, 50]; num = 40; + index = _.indexOf(numbers, num, true); + equal(index, 3, '40 is in the list'); + + numbers = [1, 40, 40, 40, 40, 40, 40, 40, 50, 60, 70]; num = 40; + index = _.indexOf(numbers, num, true); + equal(index, 1, '40 is in the list'); + + numbers = [1, 2, 3, 1, 2, 3, 1, 2, 3]; + index = _.indexOf(numbers, 2, 5); + equal(index, 7, 'supports the fromIndex argument'); + }); + + test("lastIndexOf", function() { + var numbers = [1, 0, 1]; + equal(_.lastIndexOf(numbers, 1), 2); + + numbers = [1, 0, 1, 0, 0, 1, 0, 0, 0]; + numbers.lastIndexOf = null; + equal(_.lastIndexOf(numbers, 1), 5, 'can compute lastIndexOf, even without the native function'); + equal(_.lastIndexOf(numbers, 0), 8, 'lastIndexOf the other element'); + var result = (function(){ return _.lastIndexOf(arguments, 1); })(1, 0, 1, 0, 0, 1, 0, 0, 0); + equal(result, 5, 'works on an arguments object'); + equal(_.indexOf(null, 2), -1, 'handles nulls properly'); + + numbers = [1, 2, 3, 1, 2, 3, 1, 2, 3]; + index = _.lastIndexOf(numbers, 2, 2); + equal(index, 1, 'supports the fromIndex argument'); + }); + + test("range", function() { + equal(_.range(0).join(''), '', 'range with 0 as a first argument generates an empty array'); + equal(_.range(4).join(' '), '0 1 2 3', 'range with a single positive argument generates an array of elements 0,1,2,...,n-1'); + equal(_.range(5, 8).join(' '), '5 6 7', 'range with two arguments a & b, a<b generates an array of elements a,a+1,a+2,...,b-2,b-1'); + equal(_.range(8, 5).join(''), '', 'range with two arguments a & b, b<a generates an empty array'); + equal(_.range(3, 10, 3).join(' '), '3 6 9', 'range with three arguments a & b & c, c < b-a, a < b generates an array of elements a,a+c,a+2c,...,b - (multiplier of a) < c'); + equal(_.range(3, 10, 15).join(''), '3', 'range with three arguments a & b & c, c > b-a, a < b generates an array with a single element, equal to a'); + equal(_.range(12, 7, -2).join(' '), '12 10 8', 'range with three arguments a & b & c, a > b, c < 0 generates an array of elements a,a-c,a-2c and ends with the number not less than b'); + equal(_.range(0, -10, -1).join(' '), '0 -1 -2 -3 -4 -5 -6 -7 -8 -9', 'final example in the Python docs'); + }); + +}); diff --git a/htdocs/js/lib/webwork/components/underscore/test/chaining.js b/htdocs/js/lib/webwork/components/underscore/test/chaining.js new file mode 100644 index 000000000..16cf7bf57 --- /dev/null +++ b/htdocs/js/lib/webwork/components/underscore/test/chaining.js @@ -0,0 +1,59 @@ +$(document).ready(function() { + + module("Chaining"); + + test("map/flatten/reduce", function() { + var lyrics = [ + "I'm a lumberjack and I'm okay", + "I sleep all night and I work all day", + "He's a lumberjack and he's okay", + "He sleeps all night and he works all day" + ]; + var counts = _(lyrics).chain() + .map(function(line) { return line.split(''); }) + .flatten() + .reduce(function(hash, l) { + hash[l] = hash[l] || 0; + hash[l]++; + return hash; + }, {}).value(); + ok(counts['a'] == 16 && counts['e'] == 10, 'counted all the letters in the song'); + }); + + test("select/reject/sortBy", function() { + var numbers = [1,2,3,4,5,6,7,8,9,10]; + numbers = _(numbers).chain().select(function(n) { + return n % 2 == 0; + }).reject(function(n) { + return n % 4 == 0; + }).sortBy(function(n) { + return -n; + }).value(); + equal(numbers.join(', '), "10, 6, 2", "filtered and reversed the numbers"); + }); + + test("select/reject/sortBy in functional style", function() { + var numbers = [1,2,3,4,5,6,7,8,9,10]; + numbers = _.chain(numbers).select(function(n) { + return n % 2 == 0; + }).reject(function(n) { + return n % 4 == 0; + }).sortBy(function(n) { + return -n; + }).value(); + equal(numbers.join(', '), "10, 6, 2", "filtered and reversed the numbers"); + }); + + test("reverse/concat/unshift/pop/map", function() { + var numbers = [1,2,3,4,5]; + numbers = _(numbers).chain() + .reverse() + .concat([5, 5, 5]) + .unshift(17) + .pop() + .map(function(n){ return n * 2; }) + .value(); + equal(numbers.join(', '), "34, 10, 8, 6, 4, 2, 10, 10", 'can chain together array functions.'); + }); + +}); diff --git a/htdocs/js/lib/webwork/components/underscore/test/collections.js b/htdocs/js/lib/webwork/components/underscore/test/collections.js new file mode 100644 index 000000000..efc5723d4 --- /dev/null +++ b/htdocs/js/lib/webwork/components/underscore/test/collections.js @@ -0,0 +1,416 @@ +$(document).ready(function() { + + module("Collections"); + + test("each", function() { + _.each([1, 2, 3], function(num, i) { + equal(num, i + 1, 'each iterators provide value and iteration count'); + }); + + var answers = []; + _.each([1, 2, 3], function(num){ answers.push(num * this.multiplier);}, {multiplier : 5}); + equal(answers.join(', '), '5, 10, 15', 'context object property accessed'); + + answers = []; + _.forEach([1, 2, 3], function(num){ answers.push(num); }); + equal(answers.join(', '), '1, 2, 3', 'aliased as "forEach"'); + + answers = []; + var obj = {one : 1, two : 2, three : 3}; + obj.constructor.prototype.four = 4; + _.each(obj, function(value, key){ answers.push(key); }); + equal(answers.join(", "), 'one, two, three', 'iterating over objects works, and ignores the object prototype.'); + delete obj.constructor.prototype.four; + + answer = null; + _.each([1, 2, 3], function(num, index, arr){ if (_.include(arr, num)) answer = true; }); + ok(answer, 'can reference the original collection from inside the iterator'); + + answers = 0; + _.each(null, function(){ ++answers; }); + equal(answers, 0, 'handles a null properly'); + }); + + test('map', function() { + var doubled = _.map([1, 2, 3], function(num){ return num * 2; }); + equal(doubled.join(', '), '2, 4, 6', 'doubled numbers'); + + doubled = _.collect([1, 2, 3], function(num){ return num * 2; }); + equal(doubled.join(', '), '2, 4, 6', 'aliased as "collect"'); + + var tripled = _.map([1, 2, 3], function(num){ return num * this.multiplier; }, {multiplier : 3}); + equal(tripled.join(', '), '3, 6, 9', 'tripled numbers with context'); + + var doubled = _([1, 2, 3]).map(function(num){ return num * 2; }); + equal(doubled.join(', '), '2, 4, 6', 'OO-style doubled numbers'); + + if (document.querySelectorAll) { + var ids = _.map(document.querySelectorAll('#map-test *'), function(n){ return n.id; }); + deepEqual(ids, ['id1', 'id2'], 'Can use collection methods on NodeLists.'); + } + + var ids = _.map($('#map-test').children(), function(n){ return n.id; }); + deepEqual(ids, ['id1', 'id2'], 'Can use collection methods on jQuery Array-likes.'); + + var ids = _.map(document.images, function(n){ return n.id; }); + ok(ids[0] == 'chart_image', 'can use collection methods on HTMLCollections'); + + var ifnull = _.map(null, function(){}); + ok(_.isArray(ifnull) && ifnull.length === 0, 'handles a null properly'); + }); + + test('reduce', function() { + var sum = _.reduce([1, 2, 3], function(sum, num){ return sum + num; }, 0); + equal(sum, 6, 'can sum up an array'); + + var context = {multiplier : 3}; + sum = _.reduce([1, 2, 3], function(sum, num){ return sum + num * this.multiplier; }, 0, context); + equal(sum, 18, 'can reduce with a context object'); + + sum = _.inject([1, 2, 3], function(sum, num){ return sum + num; }, 0); + equal(sum, 6, 'aliased as "inject"'); + + sum = _([1, 2, 3]).reduce(function(sum, num){ return sum + num; }, 0); + equal(sum, 6, 'OO-style reduce'); + + var sum = _.reduce([1, 2, 3], function(sum, num){ return sum + num; }); + equal(sum, 6, 'default initial value'); + + var ifnull; + try { + _.reduce(null, function(){}); + } catch (ex) { + ifnull = ex; + } + ok(ifnull instanceof TypeError, 'handles a null (without inital value) properly'); + + ok(_.reduce(null, function(){}, 138) === 138, 'handles a null (with initial value) properly'); + equal(_.reduce([], function(){}, undefined), undefined, 'undefined can be passed as a special case'); + raises(function() { _.reduce([], function(){}); }, TypeError, 'throws an error for empty arrays with no initial value'); + }); + + test('reduceRight', function() { + var list = _.reduceRight(["foo", "bar", "baz"], function(memo, str){ return memo + str; }, ''); + equal(list, 'bazbarfoo', 'can perform right folds'); + + var list = _.foldr(["foo", "bar", "baz"], function(memo, str){ return memo + str; }, ''); + equal(list, 'bazbarfoo', 'aliased as "foldr"'); + + var list = _.foldr(["foo", "bar", "baz"], function(memo, str){ return memo + str; }); + equal(list, 'bazbarfoo', 'default initial value'); + + var ifnull; + try { + _.reduceRight(null, function(){}); + } catch (ex) { + ifnull = ex; + } + ok(ifnull instanceof TypeError, 'handles a null (without inital value) properly'); + + var sum = _.reduceRight({a: 1, b: 2, c: 3}, function(sum, num){ return sum + num; }); + equal(sum, 6, 'default initial value on object'); + + ok(_.reduceRight(null, function(){}, 138) === 138, 'handles a null (with initial value) properly'); + + equal(_.reduceRight([], function(){}, undefined), undefined, 'undefined can be passed as a special case'); + raises(function() { _.reduceRight([], function(){}); }, TypeError, 'throws an error for empty arrays with no initial value'); + + // Assert that the correct arguments are being passed. + + var args, + memo = {}, + object = {a: 1, b: 2}, + lastKey = _.keys(object).pop(); + + var expected = lastKey == 'a' + ? [memo, 1, 'a', object] + : [memo, 2, 'b', object]; + + _.reduceRight(object, function() { + args || (args = _.toArray(arguments)); + }, memo); + + deepEqual(args, expected); + + // And again, with numeric keys. + + object = {'2': 'a', '1': 'b'}; + lastKey = _.keys(object).pop(); + args = null; + + expected = lastKey == '2' + ? [memo, 'a', '2', object] + : [memo, 'b', '1', object]; + + _.reduceRight(object, function() { + args || (args = _.toArray(arguments)); + }, memo); + + deepEqual(args, expected); + }); + + test('find', function() { + var array = [1, 2, 3, 4]; + strictEqual(_.find(array, function(n) { return n > 2; }), 3, 'should return first found `value`'); + strictEqual(_.find(array, function() { return false; }), void 0, 'should return `undefined` if `value` is not found'); + }); + + test('detect', function() { + var result = _.detect([1, 2, 3], function(num){ return num * 2 == 4; }); + equal(result, 2, 'found the first "2" and broke the loop'); + }); + + test('select', function() { + var evens = _.select([1, 2, 3, 4, 5, 6], function(num){ return num % 2 == 0; }); + equal(evens.join(', '), '2, 4, 6', 'selected each even number'); + + evens = _.filter([1, 2, 3, 4, 5, 6], function(num){ return num % 2 == 0; }); + equal(evens.join(', '), '2, 4, 6', 'aliased as "filter"'); + }); + + test('reject', function() { + var odds = _.reject([1, 2, 3, 4, 5, 6], function(num){ return num % 2 == 0; }); + equal(odds.join(', '), '1, 3, 5', 'rejected each even number'); + }); + + test('all', function() { + ok(_.all([], _.identity), 'the empty set'); + ok(_.all([true, true, true], _.identity), 'all true values'); + ok(!_.all([true, false, true], _.identity), 'one false value'); + ok(_.all([0, 10, 28], function(num){ return num % 2 == 0; }), 'even numbers'); + ok(!_.all([0, 11, 28], function(num){ return num % 2 == 0; }), 'an odd number'); + ok(_.all([1], _.identity) === true, 'cast to boolean - true'); + ok(_.all([0], _.identity) === false, 'cast to boolean - false'); + ok(_.every([true, true, true], _.identity), 'aliased as "every"'); + ok(!_.all([undefined, undefined, undefined], _.identity), 'works with arrays of undefined'); + }); + + test('any', function() { + var nativeSome = Array.prototype.some; + Array.prototype.some = null; + ok(!_.any([]), 'the empty set'); + ok(!_.any([false, false, false]), 'all false values'); + ok(_.any([false, false, true]), 'one true value'); + ok(_.any([null, 0, 'yes', false]), 'a string'); + ok(!_.any([null, 0, '', false]), 'falsy values'); + ok(!_.any([1, 11, 29], function(num){ return num % 2 == 0; }), 'all odd numbers'); + ok(_.any([1, 10, 29], function(num){ return num % 2 == 0; }), 'an even number'); + ok(_.any([1], _.identity) === true, 'cast to boolean - true'); + ok(_.any([0], _.identity) === false, 'cast to boolean - false'); + ok(_.some([false, false, true]), 'aliased as "some"'); + Array.prototype.some = nativeSome; + }); + + test('include', function() { + ok(_.include([1,2,3], 2), 'two is in the array'); + ok(!_.include([1,3,9], 2), 'two is not in the array'); + ok(_.contains({moe:1, larry:3, curly:9}, 3) === true, '_.include on objects checks their values'); + ok(_([1,2,3]).include(2), 'OO-style include'); + }); + + test('invoke', function() { + var list = [[5, 1, 7], [3, 2, 1]]; + var result = _.invoke(list, 'sort'); + equal(result[0].join(', '), '1, 5, 7', 'first array sorted'); + equal(result[1].join(', '), '1, 2, 3', 'second array sorted'); + }); + + test('invoke w/ function reference', function() { + var list = [[5, 1, 7], [3, 2, 1]]; + var result = _.invoke(list, Array.prototype.sort); + equal(result[0].join(', '), '1, 5, 7', 'first array sorted'); + equal(result[1].join(', '), '1, 2, 3', 'second array sorted'); + }); + + // Relevant when using ClojureScript + test('invoke when strings have a call method', function() { + String.prototype.call = function() { + return 42; + }; + var list = [[5, 1, 7], [3, 2, 1]]; + var s = "foo"; + equal(s.call(), 42, "call function exists"); + var result = _.invoke(list, 'sort'); + equal(result[0].join(', '), '1, 5, 7', 'first array sorted'); + equal(result[1].join(', '), '1, 2, 3', 'second array sorted'); + delete String.prototype.call; + equal(s.call, undefined, "call function removed"); + }); + + test('pluck', function() { + var people = [{name : 'moe', age : 30}, {name : 'curly', age : 50}]; + equal(_.pluck(people, 'name').join(', '), 'moe, curly', 'pulls names out of objects'); + }); + + test('where', function() { + var list = [{a: 1, b: 2}, {a: 2, b: 2}, {a: 1, b: 3}, {a: 1, b: 4}]; + var result = _.where(list, {a: 1}); + equal(result.length, 3); + equal(result[result.length - 1].b, 4); + result = _.where(list, {b: 2}); + equal(result.length, 2); + equal(result[0].a, 1); + }); + + test('max', function() { + equal(3, _.max([1, 2, 3]), 'can perform a regular Math.max'); + + var neg = _.max([1, 2, 3], function(num){ return -num; }); + equal(neg, 1, 'can perform a computation-based max'); + + equal(-Infinity, _.max({}), 'Maximum value of an empty object'); + equal(-Infinity, _.max([]), 'Maximum value of an empty array'); + + equal(299999, _.max(_.range(1,300000)), "Maximum value of a too-big array"); + }); + + test('min', function() { + equal(1, _.min([1, 2, 3]), 'can perform a regular Math.min'); + + var neg = _.min([1, 2, 3], function(num){ return -num; }); + equal(neg, 3, 'can perform a computation-based min'); + + equal(Infinity, _.min({}), 'Minimum value of an empty object'); + equal(Infinity, _.min([]), 'Minimum value of an empty array'); + + var now = new Date(9999999999); + var then = new Date(0); + equal(_.min([now, then]), then); + + equal(1, _.min(_.range(1,300000)), "Minimum value of a too-big array"); + }); + + test('sortBy', function() { + var people = [{name : 'curly', age : 50}, {name : 'moe', age : 30}]; + people = _.sortBy(people, function(person){ return person.age; }); + equal(_.pluck(people, 'name').join(', '), 'moe, curly', 'stooges sorted by age'); + + var list = [undefined, 4, 1, undefined, 3, 2]; + equal(_.sortBy(list, _.identity).join(','), '1,2,3,4,,', 'sortBy with undefined values'); + + var list = ["one", "two", "three", "four", "five"]; + var sorted = _.sortBy(list, 'length'); + equal(sorted.join(' '), 'one two four five three', 'sorted by length'); + + function Pair(x, y) { + this.x = x; + this.y = y; + } + + var collection = [ + new Pair(1, 1), new Pair(1, 2), + new Pair(1, 3), new Pair(1, 4), + new Pair(1, 5), new Pair(1, 6), + new Pair(2, 1), new Pair(2, 2), + new Pair(2, 3), new Pair(2, 4), + new Pair(2, 5), new Pair(2, 6), + new Pair(undefined, 1), new Pair(undefined, 2), + new Pair(undefined, 3), new Pair(undefined, 4), + new Pair(undefined, 5), new Pair(undefined, 6) + ]; + + var actual = _.sortBy(collection, function(pair) { + return pair.x; + }); + + deepEqual(actual, collection, 'sortBy should be stable'); + }); + + test('groupBy', function() { + var parity = _.groupBy([1, 2, 3, 4, 5, 6], function(num){ return num % 2; }); + ok('0' in parity && '1' in parity, 'created a group for each value'); + equal(parity[0].join(', '), '2, 4, 6', 'put each even number in the right group'); + + var list = ["one", "two", "three", "four", "five", "six", "seven", "eight", "nine", "ten"]; + var grouped = _.groupBy(list, 'length'); + equal(grouped['3'].join(' '), 'one two six ten'); + equal(grouped['4'].join(' '), 'four five nine'); + equal(grouped['5'].join(' '), 'three seven eight'); + + var context = {}; + _.groupBy([{}], function(){ ok(this === context); }, context); + + grouped = _.groupBy([4.2, 6.1, 6.4], function(num) { + return Math.floor(num) > 4 ? 'hasOwnProperty' : 'constructor'; + }); + equal(grouped.constructor.length, 1); + equal(grouped.hasOwnProperty.length, 2); + + var array = [{}]; + _.groupBy(array, function(value, index, obj){ ok(obj === array); }); + }); + + test('countBy', function() { + var parity = _.countBy([1, 2, 3, 4, 5], function(num){ return num % 2 == 0; }); + equal(parity['true'], 2); + equal(parity['false'], 3); + + var list = ["one", "two", "three", "four", "five", "six", "seven", "eight", "nine", "ten"]; + var grouped = _.countBy(list, 'length'); + equal(grouped['3'], 4); + equal(grouped['4'], 3); + equal(grouped['5'], 3); + + var context = {}; + _.countBy([{}], function(){ ok(this === context); }, context); + + grouped = _.countBy([4.2, 6.1, 6.4], function(num) { + return Math.floor(num) > 4 ? 'hasOwnProperty' : 'constructor'; + }); + equal(grouped.constructor, 1); + equal(grouped.hasOwnProperty, 2); + + var array = [{}]; + _.countBy(array, function(value, index, obj){ ok(obj === array); }); + }); + + test('sortedIndex', function() { + var numbers = [10, 20, 30, 40, 50], num = 35; + var indexForNum = _.sortedIndex(numbers, num); + equal(indexForNum, 3, '35 should be inserted at index 3'); + + var indexFor30 = _.sortedIndex(numbers, 30); + equal(indexFor30, 2, '30 should be inserted at index 2'); + + var objects = [{x: 10}, {x: 20}, {x: 30}, {x: 40}]; + var iterator = function(obj){ return obj.x; }; + strictEqual(_.sortedIndex(objects, {x: 25}, iterator), 2); + strictEqual(_.sortedIndex(objects, {x: 35}, 'x'), 3); + + var context = {1: 2, 2: 3, 3: 4}; + iterator = function(obj){ return this[obj]; }; + strictEqual(_.sortedIndex([1, 3], 2, iterator, context), 1); + }); + + test('shuffle', function() { + var numbers = _.range(10); + var shuffled = _.shuffle(numbers).sort(); + notStrictEqual(numbers, shuffled, 'original object is unmodified'); + equal(shuffled.join(','), numbers.join(','), 'contains the same members before and after shuffle'); + }); + + test('toArray', function() { + ok(!_.isArray(arguments), 'arguments object is not an array'); + ok(_.isArray(_.toArray(arguments)), 'arguments object converted into array'); + var a = [1,2,3]; + ok(_.toArray(a) !== a, 'array is cloned'); + equal(_.toArray(a).join(', '), '1, 2, 3', 'cloned array contains same elements'); + + var numbers = _.toArray({one : 1, two : 2, three : 3}); + equal(numbers.join(', '), '1, 2, 3', 'object flattened into array'); + }); + + test('size', function() { + equal(_.size({one : 1, two : 2, three : 3}), 3, 'can compute the size of an object'); + equal(_.size([1, 2, 3]), 3, 'can compute the size of an array'); + + var func = function() { + return _.size(arguments); + }; + + equal(func(1, 2, 3, 4), 4, 'can test the size of the arguments object'); + + equal(_.size('hello'), 5, 'can compute the size of a string'); + }); + +}); diff --git a/htdocs/js/lib/webwork/components/underscore/test/functions.js b/htdocs/js/lib/webwork/components/underscore/test/functions.js new file mode 100644 index 000000000..a52965877 --- /dev/null +++ b/htdocs/js/lib/webwork/components/underscore/test/functions.js @@ -0,0 +1,259 @@ +$(document).ready(function() { + + module("Functions"); + + test("bind", function() { + var context = {name : 'moe'}; + var func = function(arg) { return "name: " + (this.name || arg); }; + var bound = _.bind(func, context); + equal(bound(), 'name: moe', 'can bind a function to a context'); + + bound = _(func).bind(context); + equal(bound(), 'name: moe', 'can do OO-style binding'); + + bound = _.bind(func, null, 'curly'); + equal(bound(), 'name: curly', 'can bind without specifying a context'); + + func = function(salutation, name) { return salutation + ': ' + name; }; + func = _.bind(func, this, 'hello'); + equal(func('moe'), 'hello: moe', 'the function was partially applied in advance'); + + var func = _.bind(func, this, 'curly'); + equal(func(), 'hello: curly', 'the function was completely applied in advance'); + + var func = function(salutation, firstname, lastname) { return salutation + ': ' + firstname + ' ' + lastname; }; + func = _.bind(func, this, 'hello', 'moe', 'curly'); + equal(func(), 'hello: moe curly', 'the function was partially applied in advance and can accept multiple arguments'); + + func = function(context, message) { equal(this, context, message); }; + _.bind(func, 0, 0, 'can bind a function to `0`')(); + _.bind(func, '', '', 'can bind a function to an empty string')(); + _.bind(func, false, false, 'can bind a function to `false`')(); + + // These tests are only meaningful when using a browser without a native bind function + // To test this with a modern browser, set underscore's nativeBind to undefined + var F = function () { return this; }; + var Boundf = _.bind(F, {hello: "moe curly"}); + equal(new Boundf().hello, undefined, "function should not be bound to the context, to comply with ECMAScript 5"); + equal(Boundf().hello, "moe curly", "When called without the new operator, it's OK to be bound to the context"); + }); + + test("bindAll", function() { + var curly = {name : 'curly'}, moe = { + name : 'moe', + getName : function() { return 'name: ' + this.name; }, + sayHi : function() { return 'hi: ' + this.name; } + }; + curly.getName = moe.getName; + _.bindAll(moe, 'getName', 'sayHi'); + curly.sayHi = moe.sayHi; + equal(curly.getName(), 'name: curly', 'unbound function is bound to current object'); + equal(curly.sayHi(), 'hi: moe', 'bound function is still bound to original object'); + + curly = {name : 'curly'}; + moe = { + name : 'moe', + getName : function() { return 'name: ' + this.name; }, + sayHi : function() { return 'hi: ' + this.name; } + }; + _.bindAll(moe); + curly.sayHi = moe.sayHi; + equal(curly.sayHi(), 'hi: moe', 'calling bindAll with no arguments binds all functions to the object'); + }); + + test("memoize", function() { + var fib = function(n) { + return n < 2 ? n : fib(n - 1) + fib(n - 2); + }; + var fastFib = _.memoize(fib); + equal(fib(10), 55, 'a memoized version of fibonacci produces identical results'); + equal(fastFib(10), 55, 'a memoized version of fibonacci produces identical results'); + + var o = function(str) { + return str; + }; + var fastO = _.memoize(o); + equal(o('toString'), 'toString', 'checks hasOwnProperty'); + equal(fastO('toString'), 'toString', 'checks hasOwnProperty'); + }); + + asyncTest("delay", 2, function() { + var delayed = false; + _.delay(function(){ delayed = true; }, 100); + setTimeout(function(){ ok(!delayed, "didn't delay the function quite yet"); }, 50); + setTimeout(function(){ ok(delayed, 'delayed the function'); start(); }, 150); + }); + + asyncTest("defer", 1, function() { + var deferred = false; + _.defer(function(bool){ deferred = bool; }, true); + _.delay(function(){ ok(deferred, "deferred the function"); start(); }, 50); + }); + + asyncTest("throttle", 2, function() { + var counter = 0; + var incr = function(){ counter++; }; + var throttledIncr = _.throttle(incr, 100); + throttledIncr(); throttledIncr(); throttledIncr(); + setTimeout(throttledIncr, 70); + setTimeout(throttledIncr, 120); + setTimeout(throttledIncr, 140); + setTimeout(throttledIncr, 190); + setTimeout(throttledIncr, 220); + setTimeout(throttledIncr, 240); + _.delay(function(){ equal(counter, 1, "incr was called immediately"); }, 30); + _.delay(function(){ equal(counter, 4, "incr was throttled"); start(); }, 400); + }); + + asyncTest("throttle arguments", 2, function() { + var value = 0; + var update = function(val){ value = val; }; + var throttledUpdate = _.throttle(update, 100); + throttledUpdate(1); throttledUpdate(2); throttledUpdate(3); + setTimeout(function(){ throttledUpdate(4); }, 120); + setTimeout(function(){ throttledUpdate(5); }, 140); + setTimeout(function(){ throttledUpdate(6); }, 250); + _.delay(function(){ equal(value, 1, "updated to latest value"); }, 40); + _.delay(function(){ equal(value, 6, "updated to latest value"); start(); }, 400); + }); + + asyncTest("throttle once", 2, function() { + var counter = 0; + var incr = function(){ return ++counter; }; + var throttledIncr = _.throttle(incr, 100); + var result = throttledIncr(); + _.delay(function(){ + equal(result, 1, "throttled functions return their value"); + equal(counter, 1, "incr was called once"); start(); + }, 220); + }); + + asyncTest("throttle twice", 1, function() { + var counter = 0; + var incr = function(){ counter++; }; + var throttledIncr = _.throttle(incr, 100); + throttledIncr(); throttledIncr(); + _.delay(function(){ equal(counter, 2, "incr was called twice"); start(); }, 220); + }); + + asyncTest("throttle repeatedly with results", 9, function() { + var counter = 0; + var incr = function(){ return ++counter; }; + var throttledIncr = _.throttle(incr, 100); + var results = []; + var saveResult = function() { results.push(throttledIncr()); }; + saveResult(); saveResult(); saveResult(); + setTimeout(saveResult, 70); + setTimeout(saveResult, 120); + setTimeout(saveResult, 140); + setTimeout(saveResult, 190); + setTimeout(saveResult, 240); + setTimeout(saveResult, 260); + _.delay(function() { + equal(results[0], 1, "incr was called once"); + equal(results[1], 1, "incr was throttled"); + equal(results[2], 1, "incr was throttled"); + equal(results[3], 1, "incr was throttled"); + equal(results[4], 2, "incr was called twice"); + equal(results[5], 2, "incr was throttled"); + equal(results[6], 2, "incr was throttled"); + equal(results[7], 3, "incr was called thrice"); + equal(results[8], 3, "incr was throttled"); + start(); + }, 400); + }); + + asyncTest("debounce", 1, function() { + var counter = 0; + var incr = function(){ counter++; }; + var debouncedIncr = _.debounce(incr, 50); + debouncedIncr(); debouncedIncr(); debouncedIncr(); + setTimeout(debouncedIncr, 30); + setTimeout(debouncedIncr, 60); + setTimeout(debouncedIncr, 90); + setTimeout(debouncedIncr, 120); + setTimeout(debouncedIncr, 150); + _.delay(function(){ equal(counter, 1, "incr was debounced"); start(); }, 220); + }); + + asyncTest("debounce asap", 5, function() { + var a, b, c; + var counter = 0; + var incr = function(){ return ++counter; }; + var debouncedIncr = _.debounce(incr, 50, true); + a = debouncedIncr(); + b = debouncedIncr(); + c = debouncedIncr(); + equal(a, 1); + equal(b, 1); + equal(c, 1); + equal(counter, 1, 'incr was called immediately'); + setTimeout(debouncedIncr, 30); + setTimeout(debouncedIncr, 60); + setTimeout(debouncedIncr, 90); + setTimeout(debouncedIncr, 120); + setTimeout(debouncedIncr, 150); + _.delay(function(){ equal(counter, 1, "incr was debounced"); start(); }, 220); + }); + + asyncTest("debounce asap recursively", 2, function() { + var counter = 0; + var debouncedIncr = _.debounce(function(){ + counter++; + if (counter < 5) debouncedIncr(); + }, 50, true); + debouncedIncr(); + equal(counter, 1, 'incr was called immediately'); + _.delay(function(){ equal(counter, 1, "incr was debounced"); start(); }, 70); + }); + + test("once", function() { + var num = 0; + var increment = _.once(function(){ num++; }); + increment(); + increment(); + equal(num, 1); + }); + + test("wrap", function() { + var greet = function(name){ return "hi: " + name; }; + var backwards = _.wrap(greet, function(func, name){ return func(name) + ' ' + name.split('').reverse().join(''); }); + equal(backwards('moe'), 'hi: moe eom', 'wrapped the saluation function'); + + var inner = function(){ return "Hello "; }; + var obj = {name : "Moe"}; + obj.hi = _.wrap(inner, function(fn){ return fn() + this.name; }); + equal(obj.hi(), "Hello Moe"); + + var noop = function(){}; + var wrapped = _.wrap(noop, function(fn){ return Array.prototype.slice.call(arguments, 0); }); + var ret = wrapped(['whats', 'your'], 'vector', 'victor'); + deepEqual(ret, [noop, ['whats', 'your'], 'vector', 'victor']); + }); + + test("compose", function() { + var greet = function(name){ return "hi: " + name; }; + var exclaim = function(sentence){ return sentence + '!'; }; + var composed = _.compose(exclaim, greet); + equal(composed('moe'), 'hi: moe!', 'can compose a function that takes another'); + + composed = _.compose(greet, exclaim); + equal(composed('moe'), 'hi: moe!', 'in this case, the functions are also commutative'); + }); + + test("after", function() { + var testAfter = function(afterAmount, timesCalled) { + var afterCalled = 0; + var after = _.after(afterAmount, function() { + afterCalled++; + }); + while (timesCalled--) after(); + return afterCalled; + }; + + equal(testAfter(5, 5), 1, "after(N) should fire after being called N times"); + equal(testAfter(5, 4), 0, "after(N) should not fire unless called N times"); + equal(testAfter(0, 0), 1, "after(0) should fire immediately"); + }); + +}); diff --git a/htdocs/js/lib/webwork/components/underscore/test/index.html b/htdocs/js/lib/webwork/components/underscore/test/index.html new file mode 100644 index 000000000..ea7a13603 --- /dev/null +++ b/htdocs/js/lib/webwork/components/underscore/test/index.html @@ -0,0 +1,44 @@ + + + + Underscore Test Suite + + + + + + + + + + + + + + + +
      +
      +
      +
      +
      +
      +
      +
      +

      Underscore Speed Suite

      +

      + A representative sample of the functions are benchmarked here, to provide + a sense of how fast they might run in different browsers. + Each iteration runs on an array of 1000 elements.

      + For example, the 'intersection' test measures the number of times you can + find the intersection of two thousand-element arrays in one second. +

      +
      + + + diff --git a/htdocs/js/lib/webwork/components/underscore/test/objects.js b/htdocs/js/lib/webwork/components/underscore/test/objects.js new file mode 100644 index 000000000..22949c3bf --- /dev/null +++ b/htdocs/js/lib/webwork/components/underscore/test/objects.js @@ -0,0 +1,548 @@ +$(document).ready(function() { + + module("Objects"); + + test("keys", function() { + equal(_.keys({one : 1, two : 2}).join(', '), 'one, two', 'can extract the keys from an object'); + // the test above is not safe because it relies on for-in enumeration order + var a = []; a[1] = 0; + equal(_.keys(a).join(', '), '1', 'is not fooled by sparse arrays; see issue #95'); + raises(function() { _.keys(null); }, TypeError, 'throws an error for `null` values'); + raises(function() { _.keys(void 0); }, TypeError, 'throws an error for `undefined` values'); + raises(function() { _.keys(1); }, TypeError, 'throws an error for number primitives'); + raises(function() { _.keys('a'); }, TypeError, 'throws an error for string primitives'); + raises(function() { _.keys(true); }, TypeError, 'throws an error for boolean primitives'); + }); + + test("values", function() { + equal(_.values({one: 1, two: 2}).join(', '), '1, 2', 'can extract the values from an object'); + equal(_.values({one: 1, two: 2, length: 3}).join(', '), '1, 2, 3', '... even when one of them is "length"'); + }); + + test("pairs", function() { + deepEqual(_.pairs({one: 1, two: 2}), [['one', 1], ['two', 2]], 'can convert an object into pairs'); + deepEqual(_.pairs({one: 1, two: 2, length: 3}), [['one', 1], ['two', 2], ['length', 3]], '... even when one of them is "length"'); + }); + + test("invert", function() { + var obj = {first: 'Moe', second: 'Larry', third: 'Curly'}; + equal(_.keys(_.invert(obj)).join(' '), 'Moe Larry Curly', 'can invert an object'); + ok(_.isEqual(_.invert(_.invert(obj)), obj), 'two inverts gets you back where you started'); + + var obj = {length: 3}; + ok(_.invert(obj)['3'] == 'length', 'can invert an object with "length"') + }); + + test("functions", function() { + var obj = {a : 'dash', b : _.map, c : (/yo/), d : _.reduce}; + ok(_.isEqual(['b', 'd'], _.functions(obj)), 'can grab the function names of any passed-in object'); + + var Animal = function(){}; + Animal.prototype.run = function(){}; + equal(_.functions(new Animal).join(''), 'run', 'also looks up functions on the prototype'); + }); + + test("extend", function() { + var result; + equal(_.extend({}, {a:'b'}).a, 'b', 'can extend an object with the attributes of another'); + equal(_.extend({a:'x'}, {a:'b'}).a, 'b', 'properties in source override destination'); + equal(_.extend({x:'x'}, {a:'b'}).x, 'x', 'properties not in source dont get overriden'); + result = _.extend({x:'x'}, {a:'a'}, {b:'b'}); + ok(_.isEqual(result, {x:'x', a:'a', b:'b'}), 'can extend from multiple source objects'); + result = _.extend({x:'x'}, {a:'a', x:2}, {a:'b'}); + ok(_.isEqual(result, {x:2, a:'b'}), 'extending from multiple source objects last property trumps'); + result = _.extend({}, {a: void 0, b: null}); + equal(_.keys(result).join(''), 'ab', 'extend does not copy undefined values'); + }); + + test("pick", function() { + var result; + result = _.pick({a:1, b:2, c:3}, 'a', 'c'); + ok(_.isEqual(result, {a:1, c:3}), 'can restrict properties to those named'); + result = _.pick({a:1, b:2, c:3}, ['b', 'c']); + ok(_.isEqual(result, {b:2, c:3}), 'can restrict properties to those named in an array'); + result = _.pick({a:1, b:2, c:3}, ['a'], 'b'); + ok(_.isEqual(result, {a:1, b:2}), 'can restrict properties to those named in mixed args'); + + var Obj = function(){}; + Obj.prototype = {a: 1, b: 2, c: 3}; + ok(_.isEqual(_.pick(new Obj, 'a', 'c'), {a:1, c: 3}), 'include prototype props'); + }); + + test("omit", function() { + var result; + result = _.omit({a:1, b:2, c:3}, 'b'); + ok(_.isEqual(result, {a:1, c:3}), 'can omit a single named property'); + result = _.omit({a:1, b:2, c:3}, 'a', 'c'); + ok(_.isEqual(result, {b:2}), 'can omit several named properties'); + result = _.omit({a:1, b:2, c:3}, ['b', 'c']); + ok(_.isEqual(result, {a:1}), 'can omit properties named in an array'); + + var Obj = function(){}; + Obj.prototype = {a: 1, b: 2, c: 3}; + ok(_.isEqual(_.omit(new Obj, 'b'), {a:1, c: 3}), 'include prototype props'); + }); + + test("defaults", function() { + var result; + var options = {zero: 0, one: 1, empty: "", nan: NaN, string: "string"}; + + _.defaults(options, {zero: 1, one: 10, twenty: 20}); + equal(options.zero, 0, 'value exists'); + equal(options.one, 1, 'value exists'); + equal(options.twenty, 20, 'default applied'); + + _.defaults(options, {empty: "full"}, {nan: "nan"}, {word: "word"}, {word: "dog"}); + equal(options.empty, "", 'value exists'); + ok(_.isNaN(options.nan), "NaN isn't overridden"); + equal(options.word, "word", 'new value is added, first one wins'); + }); + + test("clone", function() { + var moe = {name : 'moe', lucky : [13, 27, 34]}; + var clone = _.clone(moe); + equal(clone.name, 'moe', 'the clone as the attributes of the original'); + + clone.name = 'curly'; + ok(clone.name == 'curly' && moe.name == 'moe', 'clones can change shallow attributes without affecting the original'); + + clone.lucky.push(101); + equal(_.last(moe.lucky), 101, 'changes to deep attributes are shared with the original'); + + equal(_.clone(undefined), void 0, 'non objects should not be changed by clone'); + equal(_.clone(1), 1, 'non objects should not be changed by clone'); + equal(_.clone(null), null, 'non objects should not be changed by clone'); + }); + + test("isEqual", function() { + function First() { + this.value = 1; + } + First.prototype.value = 1; + function Second() { + this.value = 1; + } + Second.prototype.value = 2; + + // Basic equality and identity comparisons. + ok(_.isEqual(null, null), "`null` is equal to `null`"); + ok(_.isEqual(), "`undefined` is equal to `undefined`"); + + ok(!_.isEqual(0, -0), "`0` is not equal to `-0`"); + ok(!_.isEqual(-0, 0), "Commutative equality is implemented for `0` and `-0`"); + ok(!_.isEqual(null, undefined), "`null` is not equal to `undefined`"); + ok(!_.isEqual(undefined, null), "Commutative equality is implemented for `null` and `undefined`"); + + // String object and primitive comparisons. + ok(_.isEqual("Curly", "Curly"), "Identical string primitives are equal"); + ok(_.isEqual(new String("Curly"), new String("Curly")), "String objects with identical primitive values are equal"); + ok(_.isEqual(new String("Curly"), "Curly"), "String primitives and their corresponding object wrappers are equal"); + ok(_.isEqual("Curly", new String("Curly")), "Commutative equality is implemented for string objects and primitives"); + + ok(!_.isEqual("Curly", "Larry"), "String primitives with different values are not equal"); + ok(!_.isEqual(new String("Curly"), new String("Larry")), "String objects with different primitive values are not equal"); + ok(!_.isEqual(new String("Curly"), {toString: function(){ return "Curly"; }}), "String objects and objects with a custom `toString` method are not equal"); + + // Number object and primitive comparisons. + ok(_.isEqual(75, 75), "Identical number primitives are equal"); + ok(_.isEqual(new Number(75), new Number(75)), "Number objects with identical primitive values are equal"); + ok(_.isEqual(75, new Number(75)), "Number primitives and their corresponding object wrappers are equal"); + ok(_.isEqual(new Number(75), 75), "Commutative equality is implemented for number objects and primitives"); + ok(!_.isEqual(new Number(0), -0), "`new Number(0)` and `-0` are not equal"); + ok(!_.isEqual(0, new Number(-0)), "Commutative equality is implemented for `new Number(0)` and `-0`"); + + ok(!_.isEqual(new Number(75), new Number(63)), "Number objects with different primitive values are not equal"); + ok(!_.isEqual(new Number(63), {valueOf: function(){ return 63; }}), "Number objects and objects with a `valueOf` method are not equal"); + + // Comparisons involving `NaN`. + ok(_.isEqual(NaN, NaN), "`NaN` is equal to `NaN`"); + ok(!_.isEqual(61, NaN), "A number primitive is not equal to `NaN`"); + ok(!_.isEqual(new Number(79), NaN), "A number object is not equal to `NaN`"); + ok(!_.isEqual(Infinity, NaN), "`Infinity` is not equal to `NaN`"); + + // Boolean object and primitive comparisons. + ok(_.isEqual(true, true), "Identical boolean primitives are equal"); + ok(_.isEqual(new Boolean, new Boolean), "Boolean objects with identical primitive values are equal"); + ok(_.isEqual(true, new Boolean(true)), "Boolean primitives and their corresponding object wrappers are equal"); + ok(_.isEqual(new Boolean(true), true), "Commutative equality is implemented for booleans"); + ok(!_.isEqual(new Boolean(true), new Boolean), "Boolean objects with different primitive values are not equal"); + + // Common type coercions. + ok(!_.isEqual(true, new Boolean(false)), "Boolean objects are not equal to the boolean primitive `true`"); + ok(!_.isEqual("75", 75), "String and number primitives with like values are not equal"); + ok(!_.isEqual(new Number(63), new String(63)), "String and number objects with like values are not equal"); + ok(!_.isEqual(75, "75"), "Commutative equality is implemented for like string and number values"); + ok(!_.isEqual(0, ""), "Number and string primitives with like values are not equal"); + ok(!_.isEqual(1, true), "Number and boolean primitives with like values are not equal"); + ok(!_.isEqual(new Boolean(false), new Number(0)), "Boolean and number objects with like values are not equal"); + ok(!_.isEqual(false, new String("")), "Boolean primitives and string objects with like values are not equal"); + ok(!_.isEqual(12564504e5, new Date(2009, 9, 25)), "Dates and their corresponding numeric primitive values are not equal"); + + // Dates. + ok(_.isEqual(new Date(2009, 9, 25), new Date(2009, 9, 25)), "Date objects referencing identical times are equal"); + ok(!_.isEqual(new Date(2009, 9, 25), new Date(2009, 11, 13)), "Date objects referencing different times are not equal"); + ok(!_.isEqual(new Date(2009, 11, 13), { + getTime: function(){ + return 12606876e5; + } + }), "Date objects and objects with a `getTime` method are not equal"); + ok(!_.isEqual(new Date("Curly"), new Date("Curly")), "Invalid dates are not equal"); + + // Functions. + ok(!_.isEqual(First, Second), "Different functions with identical bodies and source code representations are not equal"); + + // RegExps. + ok(_.isEqual(/(?:)/gim, /(?:)/gim), "RegExps with equivalent patterns and flags are equal"); + ok(!_.isEqual(/(?:)/g, /(?:)/gi), "RegExps with equivalent patterns and different flags are not equal"); + ok(!_.isEqual(/Moe/gim, /Curly/gim), "RegExps with different patterns and equivalent flags are not equal"); + ok(!_.isEqual(/(?:)/gi, /(?:)/g), "Commutative equality is implemented for RegExps"); + ok(!_.isEqual(/Curly/g, {source: "Larry", global: true, ignoreCase: false, multiline: false}), "RegExps and RegExp-like objects are not equal"); + + // Empty arrays, array-like objects, and object literals. + ok(_.isEqual({}, {}), "Empty object literals are equal"); + ok(_.isEqual([], []), "Empty array literals are equal"); + ok(_.isEqual([{}], [{}]), "Empty nested arrays and objects are equal"); + ok(!_.isEqual({length: 0}, []), "Array-like objects and arrays are not equal."); + ok(!_.isEqual([], {length: 0}), "Commutative equality is implemented for array-like objects"); + + ok(!_.isEqual({}, []), "Object literals and array literals are not equal"); + ok(!_.isEqual([], {}), "Commutative equality is implemented for objects and arrays"); + + // Arrays with primitive and object values. + ok(_.isEqual([1, "Larry", true], [1, "Larry", true]), "Arrays containing identical primitives are equal"); + ok(_.isEqual([(/Moe/g), new Date(2009, 9, 25)], [(/Moe/g), new Date(2009, 9, 25)]), "Arrays containing equivalent elements are equal"); + + // Multi-dimensional arrays. + var a = [new Number(47), false, "Larry", /Moe/, new Date(2009, 11, 13), ['running', 'biking', new String('programming')], {a: 47}]; + var b = [new Number(47), false, "Larry", /Moe/, new Date(2009, 11, 13), ['running', 'biking', new String('programming')], {a: 47}]; + ok(_.isEqual(a, b), "Arrays containing nested arrays and objects are recursively compared"); + + // Overwrite the methods defined in ES 5.1 section 15.4.4. + a.forEach = a.map = a.filter = a.every = a.indexOf = a.lastIndexOf = a.some = a.reduce = a.reduceRight = null; + b.join = b.pop = b.reverse = b.shift = b.slice = b.splice = b.concat = b.sort = b.unshift = null; + + // Array elements and properties. + ok(_.isEqual(a, b), "Arrays containing equivalent elements and different non-numeric properties are equal"); + a.push("White Rocks"); + ok(!_.isEqual(a, b), "Arrays of different lengths are not equal"); + a.push("East Boulder"); + b.push("Gunbarrel Ranch", "Teller Farm"); + ok(!_.isEqual(a, b), "Arrays of identical lengths containing different elements are not equal"); + + // Sparse arrays. + ok(_.isEqual(Array(3), Array(3)), "Sparse arrays of identical lengths are equal"); + ok(!_.isEqual(Array(3), Array(6)), "Sparse arrays of different lengths are not equal when both are empty"); + + // Simple objects. + ok(_.isEqual({a: "Curly", b: 1, c: true}, {a: "Curly", b: 1, c: true}), "Objects containing identical primitives are equal"); + ok(_.isEqual({a: /Curly/g, b: new Date(2009, 11, 13)}, {a: /Curly/g, b: new Date(2009, 11, 13)}), "Objects containing equivalent members are equal"); + ok(!_.isEqual({a: 63, b: 75}, {a: 61, b: 55}), "Objects of identical sizes with different values are not equal"); + ok(!_.isEqual({a: 63, b: 75}, {a: 61, c: 55}), "Objects of identical sizes with different property names are not equal"); + ok(!_.isEqual({a: 1, b: 2}, {a: 1}), "Objects of different sizes are not equal"); + ok(!_.isEqual({a: 1}, {a: 1, b: 2}), "Commutative equality is implemented for objects"); + ok(!_.isEqual({x: 1, y: undefined}, {x: 1, z: 2}), "Objects with identical keys and different values are not equivalent"); + + // `A` contains nested objects and arrays. + a = { + name: new String("Moe Howard"), + age: new Number(77), + stooge: true, + hobbies: ["acting"], + film: { + name: "Sing a Song of Six Pants", + release: new Date(1947, 9, 30), + stars: [new String("Larry Fine"), "Shemp Howard"], + minutes: new Number(16), + seconds: 54 + } + }; + + // `B` contains equivalent nested objects and arrays. + b = { + name: new String("Moe Howard"), + age: new Number(77), + stooge: true, + hobbies: ["acting"], + film: { + name: "Sing a Song of Six Pants", + release: new Date(1947, 9, 30), + stars: [new String("Larry Fine"), "Shemp Howard"], + minutes: new Number(16), + seconds: 54 + } + }; + ok(_.isEqual(a, b), "Objects with nested equivalent members are recursively compared"); + + // Instances. + ok(_.isEqual(new First, new First), "Object instances are equal"); + ok(!_.isEqual(new First, new Second), "Objects with different constructors and identical own properties are not equal"); + ok(!_.isEqual({value: 1}, new First), "Object instances and objects sharing equivalent properties are not equal"); + ok(!_.isEqual({value: 2}, new Second), "The prototype chain of objects should not be examined"); + + // Circular Arrays. + (a = []).push(a); + (b = []).push(b); + ok(_.isEqual(a, b), "Arrays containing circular references are equal"); + a.push(new String("Larry")); + b.push(new String("Larry")); + ok(_.isEqual(a, b), "Arrays containing circular references and equivalent properties are equal"); + a.push("Shemp"); + b.push("Curly"); + ok(!_.isEqual(a, b), "Arrays containing circular references and different properties are not equal"); + + // More circular arrays #767. + a = ["everything is checked but", "this", "is not"]; + a[1] = a; + b = ["everything is checked but", ["this", "array"], "is not"]; + ok(!_.isEqual(a, b), "Comparison of circular references with non-circular references are not equal"); + + // Circular Objects. + a = {abc: null}; + b = {abc: null}; + a.abc = a; + b.abc = b; + ok(_.isEqual(a, b), "Objects containing circular references are equal"); + a.def = 75; + b.def = 75; + ok(_.isEqual(a, b), "Objects containing circular references and equivalent properties are equal"); + a.def = new Number(75); + b.def = new Number(63); + ok(!_.isEqual(a, b), "Objects containing circular references and different properties are not equal"); + + // More circular objects #767. + a = {everything: "is checked", but: "this", is: "not"}; + a.but = a; + b = {everything: "is checked", but: {that:"object"}, is: "not"}; + ok(!_.isEqual(a, b), "Comparison of circular references with non-circular object references are not equal"); + + // Cyclic Structures. + a = [{abc: null}]; + b = [{abc: null}]; + (a[0].abc = a).push(a); + (b[0].abc = b).push(b); + ok(_.isEqual(a, b), "Cyclic structures are equal"); + a[0].def = "Larry"; + b[0].def = "Larry"; + ok(_.isEqual(a, b), "Cyclic structures containing equivalent properties are equal"); + a[0].def = new String("Larry"); + b[0].def = new String("Curly"); + ok(!_.isEqual(a, b), "Cyclic structures containing different properties are not equal"); + + // Complex Circular References. + a = {foo: {b: {foo: {c: {foo: null}}}}}; + b = {foo: {b: {foo: {c: {foo: null}}}}}; + a.foo.b.foo.c.foo = a; + b.foo.b.foo.c.foo = b; + ok(_.isEqual(a, b), "Cyclic structures with nested and identically-named properties are equal"); + + // Chaining. + ok(!_.isEqual(_({x: 1, y: undefined}).chain(), _({x: 1, z: 2}).chain()), 'Chained objects containing different values are not equal'); + equal(_({x: 1, y: 2}).chain().isEqual(_({x: 1, y: 2}).chain()).value(), true, '`isEqual` can be chained'); + + // Custom `isEqual` methods. + var isEqualObj = {isEqual: function (o) { return o.isEqual == this.isEqual; }, unique: {}}; + var isEqualObjClone = {isEqual: isEqualObj.isEqual, unique: {}}; + + ok(_.isEqual(isEqualObj, isEqualObjClone), 'Both objects implement identical `isEqual` methods'); + ok(_.isEqual(isEqualObjClone, isEqualObj), 'Commutative equality is implemented for objects with custom `isEqual` methods'); + ok(!_.isEqual(isEqualObj, {}), 'Objects that do not implement equivalent `isEqual` methods are not equal'); + ok(!_.isEqual({}, isEqualObj), 'Commutative equality is implemented for objects with different `isEqual` methods'); + + // Objects from another frame. + ok(_.isEqual({}, iObject)); + }); + + test("isEmpty", function() { + ok(!_([1]).isEmpty(), '[1] is not empty'); + ok(_.isEmpty([]), '[] is empty'); + ok(!_.isEmpty({one : 1}), '{one : 1} is not empty'); + ok(_.isEmpty({}), '{} is empty'); + ok(_.isEmpty(new RegExp('')), 'objects with prototype properties are empty'); + ok(_.isEmpty(null), 'null is empty'); + ok(_.isEmpty(), 'undefined is empty'); + ok(_.isEmpty(''), 'the empty string is empty'); + ok(!_.isEmpty('moe'), 'but other strings are not'); + + var obj = {one : 1}; + delete obj.one; + ok(_.isEmpty(obj), 'deleting all the keys from an object empties it'); + }); + + // Setup remote variables for iFrame tests. + var iframe = document.createElement('iframe'); + jQuery(iframe).appendTo(document.body); + var iDoc = iframe.contentDocument || iframe.contentWindow.document; + iDoc.write( + "" + ); + iDoc.close(); + + test("isElement", function() { + ok(!_.isElement('div'), 'strings are not dom elements'); + ok(_.isElement($('html')[0]), 'the html tag is a DOM element'); + ok(_.isElement(iElement), 'even from another frame'); + }); + + test("isArguments", function() { + var args = (function(){ return arguments; })(1, 2, 3); + ok(!_.isArguments('string'), 'a string is not an arguments object'); + ok(!_.isArguments(_.isArguments), 'a function is not an arguments object'); + ok(_.isArguments(args), 'but the arguments object is an arguments object'); + ok(!_.isArguments(_.toArray(args)), 'but not when it\'s converted into an array'); + ok(!_.isArguments([1,2,3]), 'and not vanilla arrays.'); + ok(_.isArguments(iArguments), 'even from another frame'); + }); + + test("isObject", function() { + ok(_.isObject(arguments), 'the arguments object is object'); + ok(_.isObject([1, 2, 3]), 'and arrays'); + ok(_.isObject($('html')[0]), 'and DOM element'); + ok(_.isObject(iElement), 'even from another frame'); + ok(_.isObject(function () {}), 'and functions'); + ok(_.isObject(iFunction), 'even from another frame'); + ok(!_.isObject(null), 'but not null'); + ok(!_.isObject(undefined), 'and not undefined'); + ok(!_.isObject('string'), 'and not string'); + ok(!_.isObject(12), 'and not number'); + ok(!_.isObject(true), 'and not boolean'); + ok(_.isObject(new String('string')), 'but new String()'); + }); + + test("isArray", function() { + ok(!_.isArray(arguments), 'the arguments object is not an array'); + ok(_.isArray([1, 2, 3]), 'but arrays are'); + ok(_.isArray(iArray), 'even from another frame'); + }); + + test("isString", function() { + ok(!_.isString(document.body), 'the document body is not a string'); + ok(_.isString([1, 2, 3].join(', ')), 'but strings are'); + ok(_.isString(iString), 'even from another frame'); + }); + + test("isNumber", function() { + ok(!_.isNumber('string'), 'a string is not a number'); + ok(!_.isNumber(arguments), 'the arguments object is not a number'); + ok(!_.isNumber(undefined), 'undefined is not a number'); + ok(_.isNumber(3 * 4 - 7 / 10), 'but numbers are'); + ok(_.isNumber(NaN), 'NaN *is* a number'); + ok(_.isNumber(Infinity), 'Infinity is a number'); + ok(_.isNumber(iNumber), 'even from another frame'); + ok(!_.isNumber('1'), 'numeric strings are not numbers'); + }); + + test("isBoolean", function() { + ok(!_.isBoolean(2), 'a number is not a boolean'); + ok(!_.isBoolean("string"), 'a string is not a boolean'); + ok(!_.isBoolean("false"), 'the string "false" is not a boolean'); + ok(!_.isBoolean("true"), 'the string "true" is not a boolean'); + ok(!_.isBoolean(arguments), 'the arguments object is not a boolean'); + ok(!_.isBoolean(undefined), 'undefined is not a boolean'); + ok(!_.isBoolean(NaN), 'NaN is not a boolean'); + ok(!_.isBoolean(null), 'null is not a boolean'); + ok(_.isBoolean(true), 'but true is'); + ok(_.isBoolean(false), 'and so is false'); + ok(_.isBoolean(iBoolean), 'even from another frame'); + }); + + test("isFunction", function() { + ok(!_.isFunction([1, 2, 3]), 'arrays are not functions'); + ok(!_.isFunction('moe'), 'strings are not functions'); + ok(_.isFunction(_.isFunction), 'but functions are'); + ok(_.isFunction(iFunction), 'even from another frame'); + }); + + test("isDate", function() { + ok(!_.isDate(100), 'numbers are not dates'); + ok(!_.isDate({}), 'objects are not dates'); + ok(_.isDate(new Date()), 'but dates are'); + ok(_.isDate(iDate), 'even from another frame'); + }); + + test("isRegExp", function() { + ok(!_.isRegExp(_.identity), 'functions are not RegExps'); + ok(_.isRegExp(/identity/), 'but RegExps are'); + ok(_.isRegExp(iRegExp), 'even from another frame'); + }); + + test("isFinite", function() { + ok(!_.isFinite(undefined), 'undefined is not Finite'); + ok(!_.isFinite(null), 'null is not Finite'); + ok(!_.isFinite(NaN), 'NaN is not Finite'); + ok(!_.isFinite(Infinity), 'Infinity is not Finite'); + ok(!_.isFinite(-Infinity), '-Infinity is not Finite'); + ok(!_.isFinite('12'), 'Strings are not numbers'); + var obj = new Number(5); + ok(_.isFinite(obj), 'Number instances can be finite'); + ok(_.isFinite(0), '0 is Finite'); + ok(_.isFinite(123), 'Ints are Finite'); + ok(_.isFinite(-12.44), 'Floats are Finite'); + }); + + test("isNaN", function() { + ok(!_.isNaN(undefined), 'undefined is not NaN'); + ok(!_.isNaN(null), 'null is not NaN'); + ok(!_.isNaN(0), '0 is not NaN'); + ok(_.isNaN(NaN), 'but NaN is'); + ok(_.isNaN(iNaN), 'even from another frame'); + ok(_.isNaN(new Number(NaN)), 'wrapped NaN is still NaN'); + }); + + test("isNull", function() { + ok(!_.isNull(undefined), 'undefined is not null'); + ok(!_.isNull(NaN), 'NaN is not null'); + ok(_.isNull(null), 'but null is'); + ok(_.isNull(iNull), 'even from another frame'); + }); + + test("isUndefined", function() { + ok(!_.isUndefined(1), 'numbers are defined'); + ok(!_.isUndefined(null), 'null is defined'); + ok(!_.isUndefined(false), 'false is defined'); + ok(!_.isUndefined(NaN), 'NaN is defined'); + ok(_.isUndefined(), 'nothing is undefined'); + ok(_.isUndefined(undefined), 'undefined is undefined'); + ok(_.isUndefined(iUndefined), 'even from another frame'); + }); + + if (window.ActiveXObject) { + test("IE host objects", function() { + var xml = new ActiveXObject("Msxml2.DOMDocument.3.0"); + ok(!_.isNumber(xml)); + ok(!_.isBoolean(xml)); + ok(!_.isNaN(xml)); + ok(!_.isFunction(xml)); + ok(!_.isNull(xml)); + ok(!_.isUndefined(xml)); + }); + } + + test("tap", function() { + var intercepted = null; + var interceptor = function(obj) { intercepted = obj; }; + var returned = _.tap(1, interceptor); + equal(intercepted, 1, "passes tapped object to interceptor"); + equal(returned, 1, "returns tapped object"); + + returned = _([1,2,3]).chain(). + map(function(n){ return n * 2; }). + max(). + tap(interceptor). + value(); + ok(returned == 6 && intercepted == 6, 'can use tapped objects in a chain'); + }); +}); diff --git a/htdocs/js/lib/webwork/components/underscore/test/speed.js b/htdocs/js/lib/webwork/components/underscore/test/speed.js new file mode 100644 index 000000000..05e3f2a37 --- /dev/null +++ b/htdocs/js/lib/webwork/components/underscore/test/speed.js @@ -0,0 +1,75 @@ +(function() { + + var numbers = []; + for (var i=0; i<1000; i++) numbers.push(i); + var objects = _.map(numbers, function(n){ return {num : n}; }); + var randomized = _.sortBy(numbers, function(){ return Math.random(); }); + var deep = _.map(_.range(100), function() { return _.range(1000); }); + + JSLitmus.test('_.each()', function() { + var timesTwo = []; + _.each(numbers, function(num){ timesTwo.push(num * 2); }); + return timesTwo; + }); + + JSLitmus.test('_(list).each()', function() { + var timesTwo = []; + _(numbers).each(function(num){ timesTwo.push(num * 2); }); + return timesTwo; + }); + + JSLitmus.test('jQuery.each()', function() { + var timesTwo = []; + jQuery.each(numbers, function(){ timesTwo.push(this * 2); }); + return timesTwo; + }); + + JSLitmus.test('_.map()', function() { + return _.map(objects, function(obj){ return obj.num; }); + }); + + JSLitmus.test('jQuery.map()', function() { + return jQuery.map(objects, function(obj){ return obj.num; }); + }); + + JSLitmus.test('_.pluck()', function() { + return _.pluck(objects, 'num'); + }); + + JSLitmus.test('_.uniq()', function() { + return _.uniq(randomized); + }); + + JSLitmus.test('_.uniq() (sorted)', function() { + return _.uniq(numbers, true); + }); + + JSLitmus.test('_.sortBy()', function() { + return _.sortBy(numbers, function(num){ return -num; }); + }); + + JSLitmus.test('_.isEqual()', function() { + return _.isEqual(numbers, randomized); + }); + + JSLitmus.test('_.keys()', function() { + return _.keys(objects); + }); + + JSLitmus.test('_.values()', function() { + return _.values(objects); + }); + + JSLitmus.test('_.intersection()', function() { + return _.intersection(numbers, randomized); + }); + + JSLitmus.test('_.range()', function() { + return _.range(1000); + }); + + JSLitmus.test('_.flatten()', function() { + return _.flatten(deep); + }); + +})(); diff --git a/htdocs/js/lib/webwork/components/underscore/test/utility.js b/htdocs/js/lib/webwork/components/underscore/test/utility.js new file mode 100644 index 000000000..c9be20ad7 --- /dev/null +++ b/htdocs/js/lib/webwork/components/underscore/test/utility.js @@ -0,0 +1,249 @@ +$(document).ready(function() { + + var templateSettings; + + module("Utility", { + + setup: function() { + templateSettings = _.clone(_.templateSettings); + }, + + teardown: function() { + _.templateSettings = templateSettings; + } + + }); + + test("#750 - Return _ instance.", 2, function() { + var instance = _([]); + ok(_(instance) === instance); + ok(new _(instance) === instance); + }); + + test("identity", function() { + var moe = {name : 'moe'}; + equal(_.identity(moe), moe, 'moe is the same as his identity'); + }); + + test("uniqueId", function() { + var ids = [], i = 0; + while(i++ < 100) ids.push(_.uniqueId()); + equal(_.uniq(ids).length, ids.length, 'can generate a globally-unique stream of ids'); + }); + + test("times", function() { + var vals = []; + _.times(3, function (i) { vals.push(i); }); + ok(_.isEqual(vals, [0,1,2]), "is 0 indexed"); + // + vals = []; + _(3).times(function (i) { vals.push(i); }); + ok(_.isEqual(vals, [0,1,2]), "works as a wrapper"); + }); + + test("mixin", function() { + _.mixin({ + myReverse: function(string) { + return string.split('').reverse().join(''); + } + }); + equal(_.myReverse('panacea'), 'aecanap', 'mixed in a function to _'); + equal(_('champ').myReverse(), 'pmahc', 'mixed in a function to the OOP wrapper'); + }); + + test("_.escape", function() { + equal(_.escape("Curly & Moe"), "Curly & Moe"); + equal(_.escape("Curly & Moe"), "Curly &amp; Moe"); + equal(_.escape(null), ''); + }); + + test("_.unescape", function() { + var string = "Curly & Moe"; + equal(_.unescape("Curly & Moe"), string); + equal(_.unescape("Curly &amp; Moe"), "Curly & Moe"); + equal(_.unescape(null), ''); + equal(_.unescape(_.escape(string)), string); + }); + + test("template", function() { + var basicTemplate = _.template("<%= thing %> is gettin' on my noives!"); + var result = basicTemplate({thing : 'This'}); + equal(result, "This is gettin' on my noives!", 'can do basic attribute interpolation'); + + var sansSemicolonTemplate = _.template("A <% this %> B"); + equal(sansSemicolonTemplate(), "A B"); + + var backslashTemplate = _.template("<%= thing %> is \\ridanculous"); + equal(backslashTemplate({thing: 'This'}), "This is \\ridanculous"); + + var escapeTemplate = _.template('<%= a ? "checked=\\"checked\\"" : "" %>'); + equal(escapeTemplate({a: true}), 'checked="checked"', 'can handle slash escapes in interpolations.'); + + var fancyTemplate = _.template("
        <% \ + for (key in people) { \ + %>
      • <%= people[key] %>
      • <% } %>
      "); + result = fancyTemplate({people : {moe : "Moe", larry : "Larry", curly : "Curly"}}); + equal(result, "
      • Moe
      • Larry
      • Curly
      ", 'can run arbitrary javascript in templates'); + + var escapedCharsInJavascriptTemplate = _.template("
        <% _.each(numbers.split('\\n'), function(item) { %>
      • <%= item %>
      • <% }) %>
      "); + result = escapedCharsInJavascriptTemplate({numbers: "one\ntwo\nthree\nfour"}); + equal(result, "
      • one
      • two
      • three
      • four
      ", 'Can use escaped characters (e.g. \\n) in Javascript'); + + var namespaceCollisionTemplate = _.template("<%= pageCount %> <%= thumbnails[pageCount] %> <% _.each(thumbnails, function(p) { %>
      \">
      <% }); %>"); + result = namespaceCollisionTemplate({ + pageCount: 3, + thumbnails: { + 1: "p1-thumbnail.gif", + 2: "p2-thumbnail.gif", + 3: "p3-thumbnail.gif" + } + }); + equal(result, "3 p3-thumbnail.gif
      "); + + var noInterpolateTemplate = _.template("

      Just some text. Hey, I know this is silly but it aids consistency.

      "); + result = noInterpolateTemplate(); + equal(result, "

      Just some text. Hey, I know this is silly but it aids consistency.

      "); + + var quoteTemplate = _.template("It's its, not it's"); + equal(quoteTemplate({}), "It's its, not it's"); + + var quoteInStatementAndBody = _.template("<%\ + if(foo == 'bar'){ \ + %>Statement quotes and 'quotes'.<% } %>"); + equal(quoteInStatementAndBody({foo: "bar"}), "Statement quotes and 'quotes'."); + + var withNewlinesAndTabs = _.template('This\n\t\tis: <%= x %>.\n\tok.\nend.'); + equal(withNewlinesAndTabs({x: 'that'}), 'This\n\t\tis: that.\n\tok.\nend.'); + + var template = _.template("<%- value %>"); + var result = template({value: " - - - - - - Languages : CH -

      Javascript code prettifier

      - -

      Setup

      -
        -
      1. Download a distribution -
      2. Include the script and stylesheets in your document - (you will need to make sure the css and js file are on your server, and - adjust the paths in the script and link tag) -
        -<link href="prettify.css" type="text/css" rel="stylesheet" />
        -<script type="text/javascript" src="prettify.js"></script>
        -
      3. Add onload="prettyPrint()" to your - document's body tag. -
      4. Modify the stylesheet to get the coloring you prefer
      5. -
      - -

      Usage

      -

      Put code snippets in - <pre class="prettyprint">...</pre> - or <code class="prettyprint">...</code> - and it will automatically be pretty printed. - - - - -
      The original - Prettier -
      class Voila {
      -public:
      -  // Voila
      -  static const string VOILA = "Voila";
      -
      -  // will not interfere with embedded tags.
      -}
      - -
      class Voila {
      -public:
      -  // Voila
      -  static const string VOILA = "Voila";
      -
      -  // will not interfere with embedded tags.
      -}
      -
      - -

      FAQ

      -

      Which languages does it work for?

      -

      The comments in prettify.js are authoritative but the lexer - should work on a number of languages including C and friends, - Java, Python, Bash, SQL, HTML, XML, CSS, Javascript, and Makefiles. - It works passably on Ruby, PHP, VB, and Awk and a decent subset of Perl - and Ruby, but, because of commenting conventions, doesn't work on - Smalltalk, or CAML-like languages.

      - -

      LISPy languages are supported via an extension: - lang-lisp.js.

      -

      And similarly for - CSS, - Haskell, - Lua, - OCAML, SML, F#, - Visual Basic, - SQL, - Protocol Buffers, and - WikiText.. - -

      If you'd like to add an extension for your favorite language, please - look at src/lang-lisp.js and file an - issue including your language extension, and a testcase.

      - -

      How do I specify which language my code is in?

      -

      You don't need to specify the language since prettyprint() - will guess. You can specify a language by specifying the language extension - along with the prettyprint class like so:

      -
      <pre class="prettyprint lang-html">
      -  The lang-* class specifies the language file extensions.
      -  File extensions supported by default include
      -    "bsh", "c", "cc", "cpp", "cs", "csh", "cyc", "cv", "htm", "html",
      -    "java", "js", "m", "mxml", "perl", "pl", "pm", "py", "rb", "sh",
      -    "xhtml", "xml", "xsl".
      -</pre>
      - -

      It doesn't work on <obfuscated code sample>?

      -

      Yes. Prettifying obfuscated code is like putting lipstick on a pig - — i.e. outside the scope of this tool.

      - -

      Which browsers does it work with?

      -

      It's been tested with IE 6, Firefox 1.5 & 2, and Safari 2.0.4. - Look at the test page to see if it - works in your browser.

      - -

      What's changed?

      -

      See the change log

      - -

      Why doesn't Prettyprinting of strings work on WordPress?

      -

      Apparently wordpress does "smart quoting" which changes close quotes. - This causes end quotes to not match up with open quotes. -

      This breaks prettifying as well as copying and pasting of code samples. - See - WordPress's help center for info on how to stop smart quoting of code - snippets.

      - -

      How do I put line numbers in my code?

      -

      You can use the linenums class to turn on line - numbering. If your code doesn't start at line number 1, you can - add a colon and a line number to the end of that class as in - linenums:52. - -

      For example -

      <pre class="prettyprint linenums:4"
      ->// This is line 4.
      -foo();
      -bar();
      -baz();
      -boo();
      -far();
      -faz();
      -<pre>
      - produces -
      // This is line 4.
      -foo();
      -bar();
      -baz();
      -boo();
      -far();
      -faz();
      -
      - -

      How do I prevent a portion of markup from being marked as code?

      -

      You can use the nocode class to identify a span of markup - that is not code. -

      <pre class=prettyprint>
      -int x = foo();  /* This is a comment  <span class="nocode">This is not code</span>
      -  Continuation of comment */
      -int y = bar();
      -</pre>
      -produces -
      -int x = foo();  /* This is a comment  This is not code
      -  Continuation of comment */
      -int y = bar();
      -
      - -

      For a more complete example see the issue22 - testcase.

      - -

      I get an error message "a is not a function" or "opt_whenDone is not a function"

      -

      If you are calling prettyPrint via an event handler, wrap it in a function. - Instead of doing -

      - addEventListener('load', prettyPrint, false); -
      - wrap it in a closure like -
      - addEventListener('load', function (event) { prettyPrint() }, false); -
      - so that the browser does not pass an event object to prettyPrint which - will confuse it. - -


      - - - - diff --git a/htdocs/js/lib/webwork/out/assets/vendor/prettify/prettify-min.css b/htdocs/js/lib/webwork/out/assets/vendor/prettify/prettify-min.css deleted file mode 100644 index 9b554aac5..000000000 --- a/htdocs/js/lib/webwork/out/assets/vendor/prettify/prettify-min.css +++ /dev/null @@ -1 +0,0 @@ -.str{color:#080}.kwd{color:#008}.com{color:#800}.typ{color:#606}.lit{color:#066}.pun{color:#660}.pln{color:#000}.tag{color:#008}.atn{color:#606}.atv{color:#080}.dec{color:#606}ol.linenums{margin-top:0;margin-bottom:0}li.L0,li.L1,li.L2,li.L3,li.L5,li.L6,li.L7,li.L8{list-style:none}li.L1,li.L3,li.L5,li.L7,li.L9{background:#eee}@media print{.str{color:#060}.kwd{color:#006;font-weight:bold}.com{color:#600;font-style:italic}.typ{color:#404;font-weight:bold}.lit{color:#044}.pun{color:#440}.pln{color:#000}.tag{color:#006;font-weight:bold}.atn{color:#404}.atv{color:#060}} \ No newline at end of file diff --git a/htdocs/js/lib/webwork/out/assets/vendor/prettify/prettify-min.js b/htdocs/js/lib/webwork/out/assets/vendor/prettify/prettify-min.js deleted file mode 100644 index 3dec9931c..000000000 --- a/htdocs/js/lib/webwork/out/assets/vendor/prettify/prettify-min.js +++ /dev/null @@ -1,35 +0,0 @@ -window.PR_SHOULD_USE_CONTINUATION=true;window.PR_TAB_WIDTH=8;window.PR_normalizedHtml=window.PR=window.prettyPrintOne=window.prettyPrint=void 0;window._pr_isIE6=function(){var y=navigator&&navigator.userAgent&&navigator.userAgent.match(/\bMSIE ([678])\./);y=y?+y[1]:false;window._pr_isIE6=function(){return y};return y}; -(function(){function y(b){return b.replace(L,"&").replace(M,"<").replace(N,">")}function H(b,f,i){switch(b.nodeType){case 1:var o=b.tagName.toLowerCase();f.push("<",o);var l=b.attributes,n=l.length;if(n){if(i){for(var r=[],j=n;--j>=0;)r[j]=l[j];r.sort(function(q,m){return q.name"); -for(l=b.firstChild;l;l=l.nextSibling)H(l,f,i);if(b.firstChild||!/^(?:br|link|img)$/.test(o))f.push("");break;case 3:case 4:f.push(y(b.nodeValue));break}}function O(b){function f(c){if(c.charAt(0)!=="\\")return c.charCodeAt(0);switch(c.charAt(1)){case "b":return 8;case "t":return 9;case "n":return 10;case "v":return 11;case "f":return 12;case "r":return 13;case "u":case "x":return parseInt(c.substring(2),16)||c.charCodeAt(1);case "0":case "1":case "2":case "3":case "4":case "5":case "6":case "7":return parseInt(c.substring(1), -8);default:return c.charCodeAt(1)}}function i(c){if(c<32)return(c<16?"\\x0":"\\x")+c.toString(16);c=String.fromCharCode(c);if(c==="\\"||c==="-"||c==="["||c==="]")c="\\"+c;return c}function o(c){var d=c.substring(1,c.length-1).match(RegExp("\\\\u[0-9A-Fa-f]{4}|\\\\x[0-9A-Fa-f]{2}|\\\\[0-3][0-7]{0,2}|\\\\[0-7]{1,2}|\\\\[\\s\\S]|-|[^-\\\\]","g"));c=[];for(var a=[],k=d[0]==="^",e=k?1:0,h=d.length;e122)){s<65||g>90||a.push([Math.max(65,g)|32,Math.min(s,90)|32]);s<97||g>122||a.push([Math.max(97,g)&-33,Math.min(s,122)&-33])}}a.sort(function(v,w){return v[0]-w[0]||w[1]-v[1]});d=[];g=[NaN,NaN];for(e=0;eh[0]){h[1]+1>h[0]&&a.push("-"); -a.push(i(h[1]))}}a.push("]");return a.join("")}function l(c){for(var d=c.source.match(RegExp("(?:\\[(?:[^\\x5C\\x5D]|\\\\[\\s\\S])*\\]|\\\\u[A-Fa-f0-9]{4}|\\\\x[A-Fa-f0-9]{2}|\\\\[0-9]+|\\\\[^ux0-9]|\\(\\?[:!=]|[\\(\\)\\^]|[^\\x5B\\x5C\\(\\)\\^]+)","g")),a=d.length,k=[],e=0,h=0;e=2&&c==="[")d[e]=o(g);else if(c!=="\\")d[e]=g.replace(/[a-zA-Z]/g,function(s){s=s.charCodeAt(0);return"["+String.fromCharCode(s&-33,s|32)+"]"})}return d.join("")}for(var n=0,r=false,j=false,q=0,m=b.length;q=0;l-=16)o.push(" ".substring(0,l));l=n+1;break;case "\n":f=0;break;default:++f}if(!o)return i;o.push(i.substring(l));return o.join("")}}function I(b, -f,i,o){if(f){b={source:f,c:b};i(b);o.push.apply(o,b.d)}}function B(b,f){var i={},o;(function(){for(var r=b.concat(f),j=[],q={},m=0,t=r.length;m=0;)i[c.charAt(d)]=p;p=p[1];c=""+p;if(!q.hasOwnProperty(c)){j.push(p);q[c]=null}}j.push(/[\0-\uffff]/);o=O(j)})();var l=f.length;function n(r){for(var j=r.c,q=[j,z],m=0,t=r.source.match(o)||[],p={},c=0,d=t.length;c=5&&"lang-"===k.substring(0,5))&&!(e&&typeof e[1]==="string")){h=false;k=P}h||(p[a]=k)}g=m;m+=a.length;if(h){h=e[1];var s=a.indexOf(h),v=s+h.length;if(e[2]){v=a.length-e[2].length;s=v-h.length}k=k.substring(5);I(j+g,a.substring(0,s),n,q);I(j+g+s,h,Q(k,h),q);I(j+g+v,a.substring(v),n,q)}else q.push(j+g,k)}r.d=q}return n}function x(b){var f=[],i=[];if(b.tripleQuotedStrings)f.push([A,/^(?:\'\'\'(?:[^\'\\]|\\[\s\S]|\'{1,2}(?=[^\']))*(?:\'\'\'|$)|\"\"\"(?:[^\"\\]|\\[\s\S]|\"{1,2}(?=[^\"]))*(?:\"\"\"|$)|\'(?:[^\\\']|\\[\s\S])*(?:\'|$)|\"(?:[^\\\"]|\\[\s\S])*(?:\"|$))/, -null,"'\""]);else b.multiLineStrings?f.push([A,/^(?:\'(?:[^\\\']|\\[\s\S])*(?:\'|$)|\"(?:[^\\\"]|\\[\s\S])*(?:\"|$)|\`(?:[^\\\`]|\\[\s\S])*(?:\`|$))/,null,"'\"`"]):f.push([A,/^(?:\'(?:[^\\\'\r\n]|\\.)*(?:\'|$)|\"(?:[^\\\"\r\n]|\\.)*(?:\"|$))/,null,"\"'"]);b.verbatimStrings&&i.push([A,/^@\"(?:[^\"]|\"\")*(?:\"|$)/,null]);if(b.hashComments)if(b.cStyleComments){f.push([C,/^#(?:(?:define|elif|else|endif|error|ifdef|include|ifndef|line|pragma|undef|warning)\b|[^\r\n]*)/,null,"#"]);i.push([A,/^<(?:(?:(?:\.\.\/)*|\/?)(?:[\w-]+(?:\/[\w-]+)+)?[\w-]+\.h|[a-z]\w*)>/, -null])}else f.push([C,/^#[^\r\n]*/,null,"#"]);if(b.cStyleComments){i.push([C,/^\/\/[^\r\n]*/,null]);i.push([C,/^\/\*[\s\S]*?(?:\*\/|$)/,null])}b.regexLiterals&&i.push(["lang-regex",RegExp("^"+Z+"(/(?=[^/*])(?:[^/\\x5B\\x5C]|\\x5C[\\s\\S]|\\x5B(?:[^\\x5C\\x5D]|\\x5C[\\s\\S])*(?:\\x5D|$))+/)")]);b=b.keywords.replace(/^\s+|\s+$/g,"");b.length&&i.push([R,RegExp("^(?:"+b.replace(/\s+/g,"|")+")\\b"),null]);f.push([z,/^\s+/,null," \r\n\t\u00a0"]);i.push([J,/^@[a-z_$][a-z_$@0-9]*/i,null],[S,/^@?[A-Z]+[a-z][A-Za-z_$@0-9]*/, -null],[z,/^[a-z_$][a-z_$@0-9]*/i,null],[J,/^(?:0x[a-f0-9]+|(?:\d(?:_\d+)*\d*(?:\.\d*)?|\.\d\+)(?:e[+\-]?\d+)?)[a-z]*/i,null,"0123456789"],[E,/^.[^\s\w\.$@\'\"\`\/\#]*/,null]);return B(f,i)}function $(b){function f(D){if(D>r){if(j&&j!==q){n.push("");j=null}if(!j&&q){j=q;n.push('')}var T=y(p(i.substring(r,D))).replace(e?d:c,"$1 ");e=k.test(T);n.push(T.replace(a,s));r=D}}var i=b.source,o=b.g,l=b.d,n=[],r=0,j=null,q=null,m=0,t=0,p=Y(window.PR_TAB_WIDTH),c=/([\r\n ]) /g, -d=/(^| ) /gm,a=/\r\n?|\n/g,k=/[ \r\n]$/,e=true,h=window._pr_isIE6();h=h?b.b.tagName==="PRE"?h===6?" \r\n":h===7?" 
      \r":" \r":" 
      ":"
      ";var g=b.b.className.match(/\blinenums\b(?::(\d+))?/),s;if(g){for(var v=[],w=0;w<10;++w)v[w]=h+'
    7. ';var F=g[1]&&g[1].length?g[1]-1:0;n.push('
      1. ");s=function(){var D=v[++F%10];return j?""+D+'':D}}else s=h; -for(;;)if(m");j=null}n.push(o[m+1]);m+=2}else if(t");g&&n.push("
      ");b.a=n.join("")}function u(b,f){for(var i=f.length;--i>=0;){var o=f[i];if(G.hasOwnProperty(o))"console"in window&&console.warn("cannot override language handler %s",o);else G[o]=b}}function Q(b,f){b&&G.hasOwnProperty(b)||(b=/^\s*1&&m.charAt(0)==="<"){if(!ba.test(m))if(ca.test(m)){f.push(m.substring(9,m.length-3));n+=m.length-12}else if(da.test(m)){f.push("\n");++n}else if(m.indexOf(V)>=0&&m.replace(/\s(\w+)\s*=\s*(?:\"([^\"]*)\"|'([^\']*)'|(\S+))/g,' $1="$2$3$4"').match(/[cC][lL][aA][sS][sS]=\"[^\"]*\bnocode\b/)){var t=m.match(W)[2],p=1,c;c=j+1;a:for(;c=0;){var e=p.indexOf(";",k);if(e>=0){var h=p.substring(k+3,e),g=10;if(h&&h.charAt(0)==="x"){h=h.substring(1);g=16}var s=parseInt(h,g);isNaN(s)||(p=p.substring(0,k)+String.fromCharCode(s)+p.substring(e+1))}}a=p.replace(ea,"<").replace(fa,">").replace(ga,"'").replace(ha,'"').replace(ia," ").replace(ja, -"&")}f.push(a);n+=a.length}}o={source:f.join(""),h:r};var v=o.source;b.source=v;b.c=0;b.g=o.h;Q(i,v)(b);$(b)}catch(w){if("console"in window)console.log(w&&w.stack?w.stack:w)}}var A="str",R="kwd",C="com",S="typ",J="lit",E="pun",z="pln",P="src",V="nocode",Z=function(){for(var b=["!","!=","!==","#","%","%=","&","&&","&&=","&=","(","*","*=","+=",",","-=","->","/","/=",":","::",";","<","<<","<<=","<=","=","==","===",">",">=",">>",">>=",">>>",">>>=","?","@","[","^","^=","^^","^^=","{","|","|=","||","||=", -"~","break","case","continue","delete","do","else","finally","instanceof","return","throw","try","typeof"],f="(?:^^|[+-]",i=0;i:&a-z])/g,"\\$1");f+=")\\s*";return f}(),L=/&/g,M=//g,X=/\"/g,ea=/</g,fa=/>/g,ga=/'/g,ha=/"/g,ja=/&/g,ia=/ /g,ka=/[\r\n]/g,K=null,aa=RegExp("[^<]+|/js/lib/vendor/bootstrap/css/bootstrap-responsive.css"/> - - <!--#path style="text" text=" : " textonly="1"--> diff --git a/htdocs/themes/math3/lbtwo.template b/htdocs/themes/math3/lbtwo.template index 21c713b02..a3db4ab20 100755 --- a/htdocs/themes/math3/lbtwo.template +++ b/htdocs/themes/math3/lbtwo.template @@ -1,6 +1,4 @@ - + - + /js/lib/vendor/bootstrap/css/bootstrap.css"/> @@ -37,34 +35,33 @@ } .breadcrumb{ margin:0px; + background: none; + padding-left: 3px; } - #messages{ - position:absolute; - width:50%; - margin-left:25%; - margin-right:25%; - } + ul.breadcrumb li.active {font-size: 150%;} -/js/lib/vendor/bootstrap/css/bootstrap-responsive.css"/> - - <!--#path style="text" text=" : " textonly="1"--> - -
      + + + + + +
      diff --git a/htdocs/themes/math3/ur b/htdocs/themes/math3/ur index 21c713b02..650b9475e 100755 --- a/htdocs/themes/math3/ur +++ b/htdocs/themes/math3/ur @@ -45,9 +45,6 @@ margin-right:25%; } -/js/lib/vendor/bootstrap/css/bootstrap-responsive.css"/> - - <!--#path style="text" text=" : " textonly="1"--> diff --git a/htdocs/themes/ubc/lbtwo.template b/htdocs/themes/ubc/lbtwo.template index 21c713b02..650b9475e 100755 --- a/htdocs/themes/ubc/lbtwo.template +++ b/htdocs/themes/ubc/lbtwo.template @@ -45,9 +45,6 @@ margin-right:25%; } -/js/lib/vendor/bootstrap/css/bootstrap-responsive.css"/> - - <!--#path style="text" text=" : " textonly="1"--> diff --git a/lib/WeBWorK/Authen.pm b/lib/WeBWorK/Authen.pm index 680aa0450..952b687a4 100644 --- a/lib/WeBWorK/Authen.pm +++ b/lib/WeBWorK/Authen.pm @@ -232,10 +232,8 @@ sub verify { if (defined $log_error) { $self->write_log_entry("LOGIN FAILED $log_error"); } - if (defined($error) and $error=~/\S/) { # if error message has a least one non-space character. - if (defined($r->param("user")) or defined($r->param("user_id"))) { $error = $r->maketext("Your authentication failed. Please try again." . " Please speak with your instructor if you need help.") diff --git a/lib/WeBWorK/Authen/LTIBasic.pm b/lib/WeBWorK/Authen/LTIBasic.pm index 0628d8ebd..95595b1e1 100644 --- a/lib/WeBWorK/Authen/LTIBasic.pm +++ b/lib/WeBWorK/Authen/LTIBasic.pm @@ -299,7 +299,7 @@ sub verify_normal_user #debug("LTIBasic::verify_normal_user called for user |$user_id|"); - + # Call check_session in order to destroy any existing session cookies and Key table sessions my ($sessionExists, $keyMatches, $timestampValid) = $self->check_session($user_id, $session_key, 0); debug("sessionExists='", $sessionExists, "' keyMatches='", $keyMatches, "' timestampValid='", $timestampValid, "'"); diff --git a/lib/WeBWorK/Constants.pm b/lib/WeBWorK/Constants.pm index d110d43a8..c9cb2fba1 100644 --- a/lib/WeBWorK/Constants.pm +++ b/lib/WeBWorK/Constants.pm @@ -102,6 +102,7 @@ $WeBWorK::PG::ImageGenerator::TexPreamble = <<'EOF'; \usepackage{amsmath,amsfonts,amssymb} \def\gt{>} \def\lt{<} +\usepackage{color} \usepackage[active,textmath,displaymath]{preview} \begin{document} EOF diff --git a/lib/WeBWorK/ContentGenerator.pm b/lib/WeBWorK/ContentGenerator.pm index cf0166232..75f405a87 100644 --- a/lib/WeBWorK/ContentGenerator.pm +++ b/lib/WeBWorK/ContentGenerator.pm @@ -729,7 +729,11 @@ sub links { if $ce->{showeditors}->{homeworkseteditor1}; print "
      "; print &$makelink("${pfx}ProblemSetList2", urlpath_args=>{%args}, systemlink_args=>\%systemlink_args) - if $ce->{showeditors}->{homeworkseteditor2};; + if $ce->{showeditors}->{homeworkseteditor2}; + print "
      "; + print &$makelink("${pfx}ProblemSetList3", urlpath_args=>{%args}, systemlink_args=>\%systemlink_args) + if $ce->{showeditors}->{homeworkseteditor3}; + ## only show editor link for non-versioned sets if (defined $setID && $setID !~ /,v\d+$/ ) { @@ -767,6 +771,8 @@ sub links { if $ce->{showeditors}->{librarybrowser2}; print CGI::li(&$makelink("${pfx}SetMaker3", text=>$r->maketext("Library Browser 3"), urlpath_args=>{%args}, systemlink_args=>\%systemlink_args)) if $ce->{showeditors}->{librarybrowser3}; + print CGI::li(&$makelink("${pfx}SetMakernojs", text=>$r->maketext("Orig. Lib. Browser"), urlpath_args=>{%args}, systemlink_args=>\%systemlink_args)) + if $ce->{showeditors}->{librarybrowsernojs}; #print CGI::li(&$makelink("${pfx}Compare", text=>"Compare", urlpath_args=>{%args}, systemlink_args=>\%systemlink_args)); print CGI::start_li(); # Stats print &$makelink("${pfx}Stats", urlpath_args=>{%args}, systemlink_args=>\%systemlink_args); diff --git a/lib/WeBWorK/ContentGenerator/Instructor/Compare.pm b/lib/WeBWorK/ContentGenerator/Instructor/Compare.pm index 58d6f3bbb..84cfdb9ef 100644 --- a/lib/WeBWorK/ContentGenerator/Instructor/Compare.pm +++ b/lib/WeBWorK/ContentGenerator/Instructor/Compare.pm @@ -111,7 +111,7 @@ sub body { print '
      '; if (scalar(@pathlist)>1) { print CGI::h2('Diff output'); - my $use_hdiff = 0; + my $use_hdiff = 1; if($use_hdiff) { # If you have hdiff installed, you can get colorized diffs my $diffout = `hdiff -t " " -c "File 1" -C "File 2" -N $ce->{courseDirs}->{templates}/$pathlist[0] $ce->{courseDirs}->{templates}/$pathlist[1]`; diff --git a/lib/WeBWorK/ContentGenerator/Instructor/Config.pm b/lib/WeBWorK/ContentGenerator/Instructor/Config.pm index 59a451fbc..4eb7a1b05 100644 --- a/lib/WeBWorK/ContentGenerator/Instructor/Config.pm +++ b/lib/WeBWorK/ContentGenerator/Instructor/Config.pm @@ -485,12 +485,34 @@ sub getConfigValues { opendir(my $dh, $themeDir) || die "can't opendir $themeDir: $!"; my $themes =[grep {!/^\.{1,2}$/} sort readdir($dh)]; + # get list of localization dictionaries + my $localizeDir = $ce->{webworkDirs}{localize}; + opendir(my $dh2, $localizeDir) || die "can't opendir $localizeDir: $!"; + my %seen=(); # find the languages in the localize direction + my $languages =[ grep {!$seen{$_} ++} # remove duplicate items + map {$_=~s/\...$//; $_} # get rid of suffix + grep {/\.mo$|\.po$/; } sort readdir($dh2) #look at only .mo and .po files + + ]; + + # insert the anonymous array of theme folder names into ConfigValues - my $modifyThemes = sub { my $item=shift; if (ref($item)=~/HASH/ and $item->{var} eq 'defaultTheme' ) { $item->{values} =$themes } }; - + # FIXME? Is there a reason this is an array? Couldn't we replace this + # with a hash and conceptually simplify this routine? MEG + my $modifyThemes = sub { my $item=shift; + if (ref($item)=~/HASH/ and $item->{var} eq 'defaultTheme' ) { + $item->{values} =$themes + } + }; + my $modifyLanguages = sub { my $item=shift; + if (ref($item)=~/HASH/ and $item->{var} eq 'language' ) { + $item->{values} =$languages + } + }; foreach my $oneConfig (@$ConfigValues) { foreach my $hash (@$oneConfig) { &$modifyThemes($hash); + &$modifyLanguages($hash); } } diff --git a/lib/WeBWorK/ContentGenerator/Instructor/ProblemGrader.pm b/lib/WeBWorK/ContentGenerator/Instructor/ProblemGrader.pm index 1bdd35129..1e75bb2e4 100644 --- a/lib/WeBWorK/ContentGenerator/Instructor/ProblemGrader.pm +++ b/lib/WeBWorK/ContentGenerator/Instructor/ProblemGrader.pm @@ -91,7 +91,8 @@ sub initialize { foreach my $userID (@users) { my $userProblem = $db->getUserProblem($userID,$setID,$problemID); - + next unless $userProblem; + #update grades and set flags $userProblem->{flags} =~ s/needs_grading/graded/; if ($r->param("$userID.mark_correct")) { @@ -155,6 +156,7 @@ sub body { my $set = $db->getMergedSet($userID, $setID); # checked my $problem = $db->getMergedProblem($userID, $setID, $problemID); # checked my $user = $db->getUser($userID); + return CGI::div({class=>"ResultsWithError"}, CGI::p("This set needs to be assigned to you before you can grade it.")) unless $set && $problem; #set up a silly problem to render the problem text my $pg = WeBWorK::PG->new( @@ -221,7 +223,10 @@ sub body { my $userPastAnswerID = $db->latestProblemPastAnswer($courseName, $userID, $setID, $problemID); my $userAnswerString; - if ($userPastAnswerID) { + my $userProblem = $db->getUserProblem($userID,$setID,$problemID); + next unless $userProblem; + if ($userPastAnswerID && $userProblem) { + my $userPastAnswer = $db->getPastAnswer($userPastAnswerID); my @scores = split(//,$userPastAnswer->scores); my @answers = split(/\t/,$userPastAnswer->answer_string); @@ -287,10 +292,8 @@ sub body { } else { $userAnswerString = "There are no answers for this student."; } - - my $userProblem = $db->getUserProblem($userID,$setID,$problemID); - my $score = int(100*$userProblem->status); - + + my $score = int(100*$userProblem->status); my $prettyName = $userRecord->last_name . ", " . $userRecord->first_name; @@ -339,6 +342,7 @@ sub body { # ); print CGI::Tr(CGI::td([CGI::hr(),CGI::hr(),"",CGI::hr(),"",CGI::hr(),"",CGI::hr()])); + } print CGI::end_table(); diff --git a/lib/WeBWorK/ContentGenerator/Instructor/ProblemSetList3.pm b/lib/WeBWorK/ContentGenerator/Instructor/ProblemSetList3.pm new file mode 100644 index 000000000..7b7d81b5c --- /dev/null +++ b/lib/WeBWorK/ContentGenerator/Instructor/ProblemSetList3.pm @@ -0,0 +1,475 @@ +################################################################################ +# WeBWorK Online Homework Delivery System +# Copyright 2000-2007 The WeBWorK Project, http://openwebwork.sf.net/ +# $CVSHeader: +# +# This program is free software; you can redistribute it and/or modify it under +# the terms of either: (a) the GNU General Public License as published by the +# Free Software Foundation; either version 2, or (at your option) any later +# version, or (b) the "Artistic License" which comes with this package. +# +# This program is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +# FOR A PARTICULAR PURPOSE. See either the GNU General Public License or the +# Artistic License for more details. +################################################################################ + +package WeBWorK::ContentGenerator::Instructor::ProblemSetList3; +use base qw(WeBWorK); +use base qw(WeBWorK::ContentGenerator::Instructor); + +=head1 NAME + +WeBWorK::ContentGenerator::Instructor::ProblemSetList3 - Entry point for Set-specific +data editing/viewing + +=cut + +=for comment + +What do we want to be able to do here? + +filter sort edit publish import create delete + +Filter what sets are shown: + - none, all, selected + - matching set_id, visible to students, hidden from students + +Sort sets by: + - set name + - open date + - due date + - answer date + - header files + - visibility to students + +Switch from view mode to edit mode: + - showing visible sets + - showing selected sets +Switch from edit mode to view and save changes +Switch from edit mode to view and abandon changes + +Make sets visible to or hidden from students: + - all, selected + +Import sets: + - replace: + - any users + - visible users + - selected users + - no users + - add: + - any users + - no users + +Score sets: + - all + - visible + - selected + +Create a set with a given name + +Delete sets: + - visible + - selected + +This current version (as of Fall 2012) is a total rewrite of the Problem Set Editor (Homework Set Editor) to bring +the interface and usability up to date. + +=cut + +# FIXME: rather than having two types of boolean modes $editMode and $exportMode +# make one $mode variable that contains a string like "edit", "view", or "export" + +use strict; +use warnings; +#use CGI qw(-nosticky ); +use WeBWorK::CGI; +use WeBWorK::Debug; +use WeBWorK::Utils qw(timeToSec readFile listFilesRecursive cryptPassword sortByName); + +use constant HIDE_SETS_THRESHOLD => 500; +use constant DEFAULT_VISIBILITY_STATE => 1; +use constant DEFAULT_ENABLED_REDUCED_SCORING_STATE => 0; +use constant ONE_WEEK => 60*60*24*7; + +use constant EDIT_FORMS => [qw(cancelEdit saveEdit)]; +use constant VIEW_FORMS => [qw(filter sort edit publish import export score create delete)]; +use constant EXPORT_FORMS => [qw(cancelExport saveExport)]; + +use constant VIEW_FIELD_ORDER => [ qw( select set_id problems users visible enable_reduced_scoring open_date due_date answer_date) ]; +use constant EDIT_FIELD_ORDER => [ qw( set_id visible enable_reduced_scoring open_date due_date answer_date) ]; +use constant EXPORT_FIELD_ORDER => [ qw( select set_id filename) ]; + +# permissions needed to perform a given action +use constant FORM_PERMS => { + saveEdit => "modify_problem_sets", + edit => "modify_problem_sets", + publish => "modify_problem_sets", + import => "create_and_delete_problem_sets", + export => "modify_set_def_files", + saveExport => "modify_set_def_files", + score => "score_sets", + create => "create_and_delete_problem_sets", + delete => "create_and_delete_problem_sets", +}; + +# permissions needed to view a given field +use constant FIELD_PERMS => { + problems => "modify_problem_sets", + users => "assign_problem_sets", +}; + +use constant STATE_PARAMS => [qw(user effectiveUser key visible_sets no_visible_sets prev_visible_sets no_prev_visible_set editMode exportMode primarySortField secondarySortField)]; + +use constant SORT_SUBS => { + set_id => \&bySetID, +# set_header => \&bySetHeader, # can't figure out why these are useful +# hardcopy_header => \&byHardcopyHeader, # can't figure out why these are useful + open_date => \&byOpenDate, + due_date => \&byDueDate, + answer_date => \&byAnswerDate, + visible => \&byVisible, + +}; + +# note that field_properties for some fields, in particular, gateway +# parameters, are not currently shown in the edit or display tables +use constant FIELD_PROPERTIES => { + set_id => { + type => "text", + size => 8, + access => "readonly", + }, + set_header => { + type => "filelist", + size => 10, + access => "readonly", + }, + hardcopy_header => { + type => "filelist", + size => 10, + access => "readonly", + }, + open_date => { + type => "text", + size => 26, + access => "readwrite", + }, + due_date => { + type => "text", + size => 26, + access => "readwrite", + }, + answer_date => { + type => "text", + size => 26, + access => "readwrite", + }, + visible => { + type => "checked", + size => 4, + access => "readwrite", + }, + enable_reduced_scoring => { + type => "checked", + size => 4, + access => "readwrite", + }, + assignment_type => { + type => "text", + size => 20, + access => "readwrite", + }, + attempts_per_version => { + type => "text", + size => 4, + access => "readwrite", + }, + time_interval => { + type => "text", + size => 10, + access => "readwrite", + }, + versions_per_interval => { + type => "text", + size => 4, + access => "readwrite", + }, + version_time_limit => { + type => "text", + size => 10, + access => "readwrite", + }, + problem_randorder => { + type => "text", + size => 4, + access => "readwrite", + }, + problems_per_page => { + type => "text", + size => 4, + access => "readwrite", + }, + version_creation_time => { + type => "text", + size => 10, + access => "readonly", + }, + version_last_attempt_time => { + type => "text", + size => 10, + access => "readonly", + }, + # hide_score and hide_work should be drop down selects with + # options 'N', 'Y' and 'BeforeAnswerDate'. in that we don't + # allow editing of these fields in this module, this is moot. + hide_score => { + type => "text", + size => 16, + access => "readwrite", + }, + hide_work => { + type => "text", + size => 16, + access => "readwrite", + }, + time_limit_cap => { + type => "checked", + size => 4, + access => "readwrite", + }, + # this should be 'No', 'RestrictTo' or 'DenyFrom' + restrict_ip => { + type => "text", + size => 10, + access => "readwrite", + } +}; + +# template method +sub templateName { + return "lbtwo"; +} + +sub pre_header_initialize { + my ($self) = @_; + my $r = $self->r; + my $db = $r->db; + my $ce = $r->ce; + my $authz = $r->authz; + my $urlpath = $r->urlpath; + my $user = $r->param('user'); + my $courseName = $urlpath->arg("courseID"); + + + # Check permissions + return unless $authz->hasPermissions($user, "access_instructor_tools"); + + if (defined $r->param("action") and $r->param("action") eq "score" and $authz->hasPermissions($user, "score_sets")) { + my $scope = $r->param("action.score.scope"); + my @setsToScore = (); + + if ($scope eq "none") { + return $r->maketext("No sets selected for scoring"."."); + } elsif ($scope eq "all") { + @setsToScore = @{ $r->param("allSetIDs") }; + } elsif ($scope eq "visible") { + @setsToScore = @{ $r->param("visibleSetIDs") }; + } elsif ($scope eq "selected") { + @setsToScore = $r->param("selected_sets"); + } + + my $uri = $self->systemLink( $urlpath->newFromModule('WeBWorK::ContentGenerator::Instructor::Scoring', $r, courseID=>$courseName), + params=>{ + scoreSelected=>"ScoreSelected", + selectedSet=>\@setsToScore, +# recordSingleSetScores=>'' + } + ); + + $self->reply_with_redirect($uri); + } + +} + +sub initialize { + + my ($self) = @_; + my $r = $self->r; + my $urlpath = $r->urlpath; + my $db = $r->db; + my $ce = $r->ce; + my $authz = $r->authz; + my $courseName = $urlpath->arg("courseID"); + my $setID = $urlpath->arg("setID"); + my $user = $r->param('user'); + + + my $root = $ce->{webworkURLs}->{root}; + + # templates for getting field names + my $setTemplate = $self->{setTemplate} = $db->newGlobalSet; + + return CGI::div({class => "ResultsWithError"}, $r->maketext("You are not authorized to access the instructor tools.")) + unless $authz->hasPermissions($user, "access_instructor_tools"); + + ########## set initial values for state fields + + my @allSetIDs = $db->listGlobalSets; + # DBFIXME count would suffice here :P + my @users = $db->listUsers; + $self->{allSetIDs} = \@allSetIDs; + $self->{totalUsers} = scalar @users; + + if (defined $r->param("visible_sets")) { + $self->{visibleSetIDs} = [ $r->param("visible_sets") ]; + } elsif (defined $r->param("no_visible_sets")) { + $self->{visibleSetIDs} = []; + } else { + if (@allSetIDs > HIDE_SETS_THRESHOLD) { + $self->{visibleSetIDs} = []; + } else { + $self->{visibleSetIDs} = [ @allSetIDs ]; + } + } + + $self->{prevVisibleSetIDs} = $self->{visibleSetIDs}; + + if (defined $r->param("selected_sets")) { + $self->{selectedSetIDs} = [ $r->param("selected_sets") ]; + } else { + $self->{selectedSetIDs} = []; + } + + $self->{editMode} = $r->param("editMode") || 0; + + return CGI::div({class=>"ResultsWithError"}, CGI::p($r->maketext("You are not authorized to modify homework sets."))) + if $self->{editMode} and not $authz->hasPermissions($user, "modify_problem_sets"); + + $self->{exportMode} = $r->param("exportMode") || 0; + + return CGI::div({class=>"ResultsWithError"}, CGI::p($r->maketext("You are not authorized to modify set definition files."))) + if $self->{exportMode} and not $authz->hasPermissions($user, "modify_set_def_files"); + + $self->{primarySortField} = $r->param("primarySortField") || "due_date"; + $self->{secondarySortField} = $r->param("secondarySortField") || "open_date"; + + + ######################################### + # collect date information from sets + ######################################### + + my @allSets = $db->getGlobalSets(@allSetIDs); + + my (%open_dates, %due_dates, %answer_dates); + foreach my $Set (@allSets) { + push @{$open_dates{defined $Set->open_date ? $Set->open_date : ""}}, $Set->set_id; + push @{$due_dates{defined $Set->due_date ? $Set->due_date : ""}}, $Set->set_id; + push @{$answer_dates{defined $Set->answer_date ? $Set->answer_date : ""}}, $Set->set_id; + } + $self->{open_dates} = \%open_dates; + $self->{due_dates} = \%due_dates; + $self->{answer_dates} = \%answer_dates; + + ######################################### + # call action handler + ######################################### + + my $actionID = $r->param("action"); + $self->{actionID} = $actionID; + if ($actionID) { + unless (grep { $_ eq $actionID } @{ VIEW_FORMS() }, @{ EDIT_FORMS() }, @{ EXPORT_FORMS() }) { + die $r->maketext("Action [_1] not found", $actionID); + } + # Check permissions + if (not FORM_PERMS()->{$actionID} or $authz->hasPermissions($user, FORM_PERMS()->{$actionID})) { + my $actionHandler = "${actionID}_handler"; + my %genericParams; + foreach my $param (qw(selected_sets)) { + $genericParams{$param} = [ $r->param($param) ]; + } + my %actionParams = $self->getActionParams($actionID); + my %tableParams = $self->getTableParams(); + $self->addmessage(CGI::div({class=>"Message"}, $r->maketext("Results of last action performed").": ")); + $self->addmessage($self->$actionHandler(\%genericParams, \%actionParams, \%tableParams)); + } else { + return CGI::div({class=>"ResultsWithError"}, CGI::p($r->maketext("You are not authorized to perform this action."))); + } + + + + } else { + + $self->addgoodmessage($r->maketext("Please select action to be performed.")); + } + + +} + +sub body { + my ($self) = @_; + my $r = $self->r; + my $urlpath = $r->urlpath; + my $db = $r->db; + my $ce = $r->ce; + my $authz = $r->authz; + my $courseName = $urlpath->arg("courseID"); + my $setID = $urlpath->arg("setID"); + my $user = $r->param('user'); + + my $root = $ce->{webworkURLs}->{root}; + + # templates for getting field names + my $setTemplate = $self->{setTemplate} = $db->newGlobalSet; + + return CGI::div({class => "ResultsWithError"}, $r->maketext("You are not authorized to access the instructor tools.")) + unless $authz->hasPermissions($user, "access_instructor_tools"); + + + my $template = HTML::Template->new(filename => $WeBWorK::Constants::WEBWORK_DIRECTORY . '/htdocs/html-templates/homework-manager.html'); + print $template->output(); + + print $self->hidden_authen_fields; + print CGI::hidden({id=>'hidden_courseID',name=>'courseID',default=>$courseName }); + + + + return ""; +} + +sub head{ + my $self = shift; + my $r = $self->r; + my $ce = $r->ce; + + my $site_url = $ce->{webworkURLs}->{htdocs}; + print ""; + print " "; + #print " "; + return ""; +} + +# output_JS subroutine + +# prints out the necessary JS for this page + +sub output_JS{ + my $self = shift; + my $r = $self->r; + my $ce = $r->ce; + + my $site_url = $ce->{webworkURLs}->{htdocs}; + print qq!!; + + + + return ""; +} + +1; +=head1 AUTHOR + +Written by Peter Staab at (pstaab at fitchburgstate.edu) + +=cut diff --git a/lib/WeBWorK/ContentGenerator/Instructor/SetMaker.pm b/lib/WeBWorK/ContentGenerator/Instructor/SetMaker.pm index 6db5686fa..3064b2086 100644 --- a/lib/WeBWorK/ContentGenerator/Instructor/SetMaker.pm +++ b/lib/WeBWorK/ContentGenerator/Instructor/SetMaker.pm @@ -35,6 +35,7 @@ use WeBWorK::Form; use WeBWorK::Utils qw(readDirectory max sortByName); use WeBWorK::Utils::Tasks qw(renderProblems); use File::Find; +use MIME::Base64 qw(encode_base64); require WeBWorK::Utils::ListingDB; @@ -193,6 +194,44 @@ sub munge_pg_file_path { return($pg_path); } +## With MLT, problems come in groups, so we need to find next/prev +## problems. Return index, or -1 if there are no more. + +sub next_prob_group { + my $ind = shift; + my @pgfiles = @_; + my $len = scalar(@pgfiles); + return -1 if($ind >= $len-1); + my $mlt = $pgfiles[$ind]->{morelt} || 0; + return $ind+1 if($mlt == 0); + while($ind<$len and $pgfiles[$ind]->{morelt} == $mlt) { + $ind++; + } + return -1 if($ind==$len); + return $ind; +} + +sub prev_prob_group { + my $ind = shift; + my @pgfiles = @_; + return -1 if $ind==0; + $ind--; + my $mlt = $pgfiles[$ind]->{morelt}; + return $ind if $mlt==0; + # We have to search to the beginning of this group + while($ind>=0 and $mlt == $pgfiles[$ind]->{morelt}) { + $ind--; + } + return($ind+1); +} + +sub end_prob_group { + my $ind = shift; + my @pgfiles = @_; + my $next = next_prob_group($ind, @pgfiles); + return( ($next==-1) ? $#pgfiles : $next-1); +} + ## Read a set definition file. This could be abstracted since it happens ## elsewhere. Here we don't have to process so much of the file. @@ -321,6 +360,7 @@ sub view_problems_line { $result .= " ".CGI::checkbox(-name=>"showHints",-checked=>$defaultHints,-label=>"Hints"); my $defaultSolutions = $r->param('showSolutions') || SHOW_SOLUTIONS_DEFAULT; $result .= " ".CGI::checkbox(-name=>"showSolutions",-checked=>$defaultSolutions,-label=>"Solutions"); + $result .= "\n".CGI::hidden(-name=>"original_displayMode", -default=>$mydisplayMode)."\n"; return($result); } @@ -462,7 +502,7 @@ sub browse_library_panel1 { CGI::popup_menu(-name=> 'library_chapters', -values=>\@chaps, -default=> $chapter_selected, - -onchange=>"submit();return true" + -onchange=>"lib_update('sections', 'get');return true" ), CGI::submit(-name=>"lib_select_chapter", -value=>"Update Section List")])), CGI::Tr({}, @@ -515,31 +555,31 @@ sub browse_library_panel2 { CGI::popup_menu(-name=> 'library_subjects', -values=>\@subjs, -default=> $subject_selected, - -onchange=>"submit();return true" + -onchange=>"lib_update('chapters', 'get');return true" )]), +# CGI::td({-colspan=>2, -align=>"right"}, +# CGI::submit(-name=>"lib_select_subject", -value=>"Update Chapter/Section Lists")) CGI::td({-colspan=>2, -align=>"right"}, - CGI::submit(-name=>"lib_select_subject", -value=>"Update Chapter/Section Lists")) + CGI::submit(-name=>"library_advanced", -value=>"Advanced Search")) ), CGI::Tr({}, CGI::td(["Chapter:", CGI::popup_menu(-name=> 'library_chapters', -values=>\@chaps, -default=> $chapter_selected, - -onchange=>"submit();return true" + -onchange=>"lib_update('sections', 'get');return true" )]), - CGI::td({-colspan=>2, -align=>"right"}, - CGI::submit(-name=>"library_advanced", -value=>"Advanced Search")) ), CGI::Tr({}, CGI::td(["Section:", CGI::popup_menu(-name=> 'library_sections', -values=>\@sects, -default=> $section_selected, - -onchange=>"submit();return true" + -onchange=>"lib_update('count', 'clear');return true" )]), ), CGI::Tr(CGI::td({-colspan=>3}, $view_problem_line)), - CGI::Tr(CGI::td({-colspan=>3, -align=>"center"}, $count_line)), + CGI::Tr(CGI::td({-colspan=>3, -align=>"center", -id=>"library_count_line"}, $count_line)), CGI::end_table(), )); @@ -629,7 +669,7 @@ sub browse_library_panel2adv { CGI::popup_menu(-name=> 'library_subjects', -values=>\@subjs, -default=> $selected{dbsubject}, - -onchange=>"submit();return true" + -onchange=>"lib_update('chapters', 'get');return true" )]), CGI::td({-colspan=>2, -align=>"right"}, CGI::submit(-name=>"lib_select_subject", -value=>"Update Menus", @@ -639,7 +679,7 @@ sub browse_library_panel2adv { CGI::popup_menu(-name=> 'library_chapters', -values=>\@chaps, -default=> $selected{dbchapter}, - -onchange=>"submit();return true" + -onchange=>"lib_update('sections', 'get');return true" )]), CGI::td({-colspan=>2, -align=>"right"}, CGI::submit(-name=>"library_reset", -value=>"Reset", @@ -650,7 +690,7 @@ sub browse_library_panel2adv { CGI::popup_menu(-name=> 'library_sections', -values=>\@sects, -default=> $selected{dbsection}, - -onchange=>"submit();return true" + -onchange=>"lib_update('count', 'clear');return true" )]), CGI::td({-colspan=>2, -align=>"right"}, CGI::submit(-name=>"library_basic", -value=>"Basic Search", @@ -682,7 +722,7 @@ sub browse_library_panel2adv { -override=>1, -size=>40))), CGI::Tr(CGI::td({-colspan=>3}, $view_problem_line)), - CGI::Tr(CGI::td({-colspan=>3, -align=>"center"}, $count_line)), + CGI::Tr(CGI::td({-colspan=>3, -align=>"center", -id=>"library_count_line"}, $count_line)), CGI::end_table(), )); @@ -757,12 +797,14 @@ sub make_top_row { $set_selected = SELECT_SET_STRING; } #my $myjs = 'document.mainform.selfassign.value=confirm("Should I assign the new set to you now?\nUse OK for yes and Cancel for no.");true;'; + my $courseID = $self->r->urlpath->arg("courseID"); print CGI::Tr(CGI::td({-class=>"InfoPanel", -align=>"left"}, "Add problems to ", CGI::b("Target Set: "), CGI::popup_menu(-name=> 'local_sets', -values=>$list_of_local_sets, -default=> $set_selected, + -onchange=> "return markinset()", -override=>1), CGI::submit(-name=>"edit_local", -value=>"Edit Target Set"), CGI::hidden(-name=>"selfassign", -default=>0,-override=>1). @@ -811,15 +853,18 @@ sub make_top_row { print CGI::Tr(CGI::td({-bgcolor=>"black"})); # For next/previous buttons - my ($next_button, $prev_button, $shown_msg) = ("", "", ""); + my ($next_button, $prev_button) = ("", ""); my $first_shown = $self->{first_shown}; my $last_shown = $self->{last_shown}; + my $first_index = $self->{first_index}; + my $last_index = $self->{last_index}; my @pg_files = @{$self->{pg_files}}; - if ($first_shown > 0) { + if ($first_index > 0) { $prev_button = CGI::submit(-name=>"prev_page", -style=>"width:15ex", -value=>"Previous page"); } - if ((1+$last_shown)"next_page", -style=>"width:15ex", -value=>"Next page"); } @@ -828,35 +873,31 @@ sub make_top_row { CGI::td({-class=>"InfoPanel", -align=>"center"}, CGI::start_table({-border=>"0"}), CGI::Tr({}, CGI::td({ -align=>"center"}, - CGI::submit(-name=>"select_all", -style=>$these_widths, - -value=>"Mark All For Adding"), - CGI::submit(-name=>"select_none", -style=>$these_widths, - -value=>"Clear All Marks"), + CGI::button(-name=>"select_all", -style=>$these_widths, + -onClick=>'return addme("", "all")', + -value=>"Add All"), CGI::submit(-name=>"cleardisplay", -style=>$these_widths, - -value=>"Clear Problem Display") - )), - CGI::Tr({}, - CGI::td({}, - CGI::submit(-name=>"update", -style=>$these_widths. "; font-weight:bold", - -value=>"Update Set"), - + -value=>"Clear Problem Display"), $prev_button, " ", $next_button, + )), + # CGI::Tr({}, + # CGI::td({}, - CGI::submit(-name=>"rerandomize", - -style=>$these_widths, - -value=>"Rerandomize"), - )), + #CGI::submit(-name=>"rerandomize", + # -style=>$these_widths, + # -value=>"Rerandomize"), + #)), CGI::end_table())); } sub make_data_row { my $self = shift; my $r = $self->r; - my $sourceFileName = shift; + my $sourceFileData = shift; + my $sourceFileName = $sourceFileData->{filepath}; my $pg = shift; my $cnt = shift; - my $mark = shift || 0; $sourceFileName =~ s|^./||; # clean up top ugliness @@ -876,7 +917,7 @@ sub make_data_row { my $problem_output = $pg->{flags}->{error_flag} ? CGI::div({class=>"ResultsWithError"}, CGI::em("This problem produced an error")) - : CGI::div({class=>"RenderSolo"}, $pg->{body_text}); + : CGI::div({class=>"RenderSolo", id=>"render$cnt"}, $pg->{body_text}); $problem_output .= $pg->{flags}->{comment} if($pg->{flags}->{comment}); @@ -888,7 +929,7 @@ sub make_data_row { setID=>"Undefined_Set", problemID=>"1"), params=>{sourceFilePath => "$sourceFileName", problemSeed=> $problem_seed} - ), target=>"WW_Editor"}, "Edit it" ); + ), target=>"WW_Editor", title=>"Edit it"}, '' ); my $displayMode = $self->r->param("mydisplayMode"); $displayMode = $self->r->ce->{pg}->{options}->{displayMode} @@ -908,30 +949,53 @@ sub make_data_row { sourceFilePath => "$sourceFileName", displayMode => $displayMode, } - ), target=>"WW_View"}, "Try it"); - - my %add_box_data = ( -name=>"trial$cnt",-value=>1,-label=>"Add this problem to the target set on the next update"); - if($mark & SUCCESS) { - $add_box_data{ -label } .= " (just added this problem)"; - } elsif($mark & ADDED) { - $add_box_data{ -checked } = 1; + ), target=>"WW_View", + title=>"Try it", + style=>"text-decoration: none"}, ''); + + my $inSet = ($self->{isInSet}{$sourceFileName})?"(in target set)" : ""; + $inSet = CGI::span({-id=>"inset$cnt", -style=>"text-align: right"}, CGI::i(CGI::b($inSet))); + my $fpathpop = "$sourceFileName"; + + # saved CGI::span({-style=>"float:left ; text-align: left"},"File name: $sourceFileName "), + my $path_holder = "File..."; + my $mlt = ''; + my $noshowclass = 'NS'.$cnt; + $noshowclass = 'MLT'.$sourceFileData->{morelt} if $sourceFileData->{morelt}; + if($sourceFileData->{children}) { + #$mlt = join(',', @{$sourceFileData->{children}}); + #$mlt = "\"$mlt\""; + my $numchild = scalar(@{$sourceFileData->{children}}); + $mlt = "M"; + $noshowclass = "NS$cnt"; } - - my $inSet = ($self->{isInSet}{$sourceFileName})? - CGI::span({-style=>"float:right; text-align: right"}, - CGI::i(CGI::b("(This problem is in the target set)"))) : ""; - - print CGI::Tr({-align=>"left"}, CGI::td( - CGI::div({-style=>"background-color: #DDDDDD; margin: 0px auto"}, - CGI::span({-style=>"float:left ; text-align: left"},"File name: $sourceFileName "), - CGI::span({-style=>"float:right ; text-align: right"}, $edit_link, " ", $try_link) - ), CGI::br(), - CGI::checkbox(-name=>"hideme$cnt",-value=>1,-label=>"Don't show this problem on the next update",-override=>1), - CGI::br(), - $inSet, - CGI::checkbox((%add_box_data),-override=>1), + my $noshow = ''; + $noshow = 'display: none' if($sourceFileData->{noshow}); + my $rerand = ''; + + print CGI::Tr({-align=>"left", -id=>"pgrow$cnt", -style=>$noshow, class=>$noshowclass }, CGI::td( + CGI::div({-style=>"background-color: #FFFFFF; margin: 0px auto"}, + CGI::span({-style=>"text-align: left"},CGI::button(-name=>"add_me", + -value=>"Add", + -title=>"Add problem to target set", + -onClick=>"return addme(\'$sourceFileName\', \'one\')")), + #"\n",CGI::span({-style=>"text-align: left"},CGI::span({id=>"filepath$cnt"},"...")),"\n", + "\n",CGI::span({onclick=>qq!Tip("$sourceFileName",SHADOW, false, DELAY, 0, FADEIN, 300, FADEOUT, 300, STICKY, 1, OFFSETX, -20, CLOSEBTN, true, CLICKCLOSE, false, BGCOLOR, '#EEEEEE', TITLEBGCOLOR, '#EEEEEE', TITLEFONTCOLOR, '#000000')!}, 'Path...'), +# Next line is one to keep + #"\n",'', +# '', +#"\n", CGI::span({-style=>"float:left ; text-align: left"},"File..."), + CGI::span({-style=>"float:right ; text-align: right"}, + $inSet, $mlt, $rerand, + $edit_link, " ", $try_link, + CGI::button(-name=>"dont_show", + -value=>"x", + -title=>"Hide this problem", + -onClick=>"return delrow($cnt)"), + )), + #CGI::br(), CGI::hidden(-name=>"filetrial$cnt", -default=>$sourceFileName,-override=>1). - CGI::p($problem_output), + CGI::div($problem_output), )); } @@ -944,6 +1008,86 @@ sub clear_default { $r->param($param, $newvalue); } +### Mainly deal with more like this + +sub process_search { + my $r = shift; + my @dbsearch = @_; + # Build a hash of MLT entries keyed by morelt_id + my %mlt = (); + my $mltind; + for my $indx (0..$#dbsearch) { + $dbsearch[$indx]->{filepath} = "Library/".$dbsearch[$indx]->{path}."/".$dbsearch[$indx]->{filename}; +# For debugging +$dbsearch[$indx]->{oindex} = $indx; + if($mltind = $dbsearch[$indx]->{morelt}) { + if(defined($mlt{$mltind})) { + push @{$mlt{$mltind}}, $indx; + } else { + $mlt{$mltind} = [$indx]; + } + } + } + # Now filepath is set and we have a hash of mlt entries + + # Find MLT leaders, mark entries for no show, + # set up children array for leaders + for my $mltid (keys %mlt) { + my @idlist = @{$mlt{$mltid}}; + if(scalar(@idlist)>1) { + my $leader = WeBWorK::Utils::ListingDB::getMLTleader($r, $mltid); + my $hold = undef; + for my $subindx (@idlist) { + if($dbsearch[$subindx]->{pgid} == $leader) { + $dbsearch[$subindx]->{children}=[]; + $hold = $subindx; + } else { + $dbsearch[$subindx]->{noshow}=1; + } + } + do { # we did not find the leader + $hold = $idlist[0]; + $dbsearch[$hold]->{noshow} = undef; + $dbsearch[$hold]->{children}=[]; + } unless($hold); + $mlt{$mltid} = $dbsearch[$hold]; # store ref to leader + } else { # only one, no more + $dbsearch[$idlist[0]]->{morelt} = 0; + delete $mlt{$mltid}; + } + } + + # Put children in leader and delete them, record index of leaders + $mltind = 0; + while ($mltind < scalar(@dbsearch)) { + if($dbsearch[$mltind]->{noshow}) { + # move the entry to the leader + my $mltval = $dbsearch[$mltind]->{morelt}; + push @{$mlt{$mltval}->{children}}, $dbsearch[$mltind]; + splice @dbsearch, $mltind, 1; + } else { + if($dbsearch[$mltind]->{morelt}) { # a leader + for my $mltid (keys %mlt) { + if($mltid == $dbsearch[$mltind]->{morelt}) { + $mlt{$mltid}->{index} = $mltind; + last; + } + } + } + $mltind++; + } + } + # Last pass, reinsert children into dbsearch + my @leaders = keys(%mlt); + @leaders = reverse sort {$mlt{$a}->{index} <=> $mlt{$b}->{index}} @leaders; + for my $i (@leaders) { + my $base = $mlt{$i}->{index}; + splice @dbsearch, $base+1, 0, @{$mlt{$i}->{children}}; + } + + return @dbsearch; +} + sub pre_header_initialize { my ($self) = @_; my $r = $self->r; @@ -959,9 +1103,9 @@ sub pre_header_initialize { for my $key (keys(%{ LIB2_DATA() })) { clear_default($r, LIB2_DATA->{$key}->{name}, LIB2_DATA->{$key}->{all} ); } - ## Grab library sets to display from parameters list. We will modify this - ## as we go through the if/else tree - $self->{current_library_set} = $r->param('library_sets'); + ## Grab library sets to display from parameters list. We will + ## modify this as we go through the if/else tree + $self->{current_library_set} = $r->param('library_sets'); ## These directories will have individual buttons %problib = %{$ce->{courseFiles}{problibs}} if $ce->{courseFiles}{problibs}; @@ -997,7 +1141,6 @@ sub pre_header_initialize { $self->{past_problems} = get_past_problem_files($r); # if we don't end up reusing problems, this will be wiped out # if we do redisplay the same problems, we must adjust this accordingly - my @past_marks = map {$_->[1]} @{$self->{past_problems}}; my $none_shown = scalar(@{$self->{past_problems}})==0; my @pg_files=(); my $use_previous_problems = 1; @@ -1006,19 +1149,36 @@ sub pre_header_initialize { if (not defined($last_shown)) { $last_shown = -1; } + my $first_index = $r->param('first_index') || 0; + my $last_index = $r->param('last_index'); + if (not defined($last_index)) { + $last_index = -1; + } + my $total_probs = $r->param('total_probs') || 0; my @all_past_list = (); # these are include requested, but not shown - my $j = 0; + my ($j, $count, $omlt, $nmlt, $hold) = (0,0,-1,0,0); while (defined($r->param("all_past_list$j"))) { - push @all_past_list, $r->param("all_past_list$j"); + $nmlt = $r->param("all_past_mlt$j") || 0; + push @all_past_list, {'filepath' => $r->param("all_past_list$j"), 'morelt' => $nmlt}; + if($nmlt != $omlt or $nmlt == 0) { + $count++ if($j>0); + if($j>$hold+1) { + $all_past_list[$hold]->{children} = [2..($j-$hold)]; + } + $omlt = $nmlt; + $hold = $j; + } else { # equal and nonzero, so a child + $all_past_list[$j]->{noshow} = 1; + } $j++; } + if($nmlt && $j-$hold>1) { $all_past_list[$hold]->{children} = [ 2..($j-$hold)]; } + $count++ if($j>0); ############# Default of which problem selector to display my $browse_which = $r->param('browse_which') || 'browse_npl_library'; - - ## check for problem lib buttons my $browse_lib = ''; foreach my $lib (keys %problib) { @@ -1081,6 +1241,7 @@ sub pre_header_initialize { $set_to_display = substr($browse_which,7) if $set_to_display eq MAIN_PROBLEMS; @pg_files = list_pg_files($ce->{courseDirs}->{templates}, "$set_to_display"); + @pg_files = map {{'filepath'=> $_, 'morelt'=>0}} @pg_files; $use_previous_problems=0; } @@ -1107,6 +1268,7 @@ sub pre_header_initialize { } @pg_files = sortByName(undef,@pg_files); + @pg_files = map {{'filepath'=> $_, 'morelt'=>0}} @pg_files; $use_previous_problems=0; } @@ -1116,13 +1278,7 @@ sub pre_header_initialize { @pg_files=(); my @dbsearch = WeBWorK::Utils::ListingDB::getSectionListings($r); - my ($result, $tolibpath); - for $result (@dbsearch) { - $tolibpath = "Library/$result->{path}/$result->{filename}"; - - ## Too clunky!!!! - push @pg_files, $tolibpath; - } + @pg_files = process_search($r, @dbsearch); $use_previous_problems=0; ##### View a set from a set*.def @@ -1137,7 +1293,8 @@ sub pre_header_initialize { $self->addbadmessage("You need to select a set definition file to view."); } else { @pg_files= $self->read_set_def($set_to_display); - } + @pg_files = map {{'filepath'=> $_, 'morelt'=>0}} @pg_files; + } $use_previous_problems=0; ##### Edit the current local homework set @@ -1187,68 +1344,29 @@ sub pre_header_initialize { } } - ##### Add selected problems to the current local set - - } elsif ($r->param('update')) { - ## first handle problems to be added before we hide them - my($localSet, @selected); - - @pg_files = grep {($_->[1] & ADDED) != 0 } @{$self->{past_problems}}; - @selected = map {$_->[0]} @pg_files; - - my @action_files = grep {$_->[1] > 0 } @{$self->{past_problems}}; - # There are now good reasons to do an update without selecting anything. - #if(scalar(@action_files) == 0) { - # $self->addbadmessage('Update requested, but no problems were marked.'); - #} - - if (scalar(@selected)>0) { # if some are to be added, they need a place to go - $localSet = $r->param('local_sets'); - if (not defined($localSet) or - $localSet eq SELECT_SET_STRING or - $localSet eq NO_LOCAL_SET_STRING) { - $self->addbadmessage('You are trying to add problems to something, - but you did not select a "Target Set" name as a target.'); - } else { - my $newSetRecord = $db->getGlobalSet($localSet); - if (not defined($newSetRecord)) { - $self->addbadmessage("You are trying to add problems to $localSet, - but that set does not seem to exist! I bet you used your \"Back\" button."); - } else { - my $addcount = add_selected($self, $db, $localSet); - if($addcount > 0) { - $self->addgoodmessage("Added $addcount problem".(($addcount>1)?'s':''). - " to $localSet."); - } - } - } - } - ## now handle problems to be hidden - - ## only keep the ones which are not hidden - @pg_files = grep {($_->[1] & HIDDEN) ==0 } @{$self->{past_problems}}; - @past_marks = map {$_->[1]} @pg_files; - @pg_files = map {$_->[0]} @pg_files; - @all_past_list = (@all_past_list[0..($first_shown-1)], - @pg_files, - @all_past_list[($last_shown+1)..(scalar(@all_past_list)-1)]); - $last_shown = $first_shown+$maxShown -1; debug("last_shown 3: ", $last_shown); - $last_shown = (scalar(@all_past_list)-1) if($last_shown>=scalar(@all_past_list)); debug("last_shown 4: ", $last_shown); - } elsif ($r->param('next_page')) { - $first_shown = $last_shown+1; - $last_shown = $first_shown+$maxShown-1; debug("last_shown 5: ", $last_shown); - $last_shown = (scalar(@all_past_list)-1) if($last_shown>=scalar(@all_past_list)); debug("last_shown 6: ", $last_shown); - @past_marks = (); + # Can set first/last problem, but not index yet + $first_index = $last_index+1; + my $oli = 0; + my $cnt = 0; + while(($oli = next_prob_group($last_index, @all_past_list)) != -1 and $cnt<$maxShown) { + $cnt++; + $last_index = $oli; + } + $last_index = end_prob_group($last_index, @all_past_list); } elsif ($r->param('prev_page')) { - $last_shown = $first_shown-1; - $first_shown = $last_shown - $maxShown+1; - - $first_shown = 0 if($first_shown<0); - @past_marks = (); + # Can set first/last index, but not problem yet + $last_index = $first_index-1; + my $oli = 0; + my $cnt = 0; + while(($oli = prev_prob_group($first_index, @all_past_list)) != -1 and $cnt<$maxShown) { + $cnt++; + $first_index = $oli; + } + $first_index = 0 if($first_index<0); - } elsif ($r->param('select_all')) { - @past_marks = map {1} @past_marks; + #} elsif ($r->param('select_all')) { + #; } elsif ($r->param('library_basic')) { $library_basic = 1; for my $jj (qw(textchapter textsection textbook)) { @@ -1260,10 +1378,11 @@ sub pre_header_initialize { for my $jj (qw(chapters sections subjects textbook keywords)) { $r->param('library_'.$jj,''); } - } elsif ($r->param('select_none')) { - @past_marks = (); + #} elsif ($r->param('select_none')) { + # ; } else { ##### No action requested, probably our first time here + ; } ##### end of the if elsif ... @@ -1275,22 +1394,54 @@ sub pre_header_initialize { if ($use_previous_problems) { @pg_files = @all_past_list; + $first_shown = 0; + $last_shown = 0; + my ($oli, $cnt) = (0,0); + while($oli < $first_index and ($oli = next_prob_group($first_shown, @pg_files)) != -1) { + $cnt++; + $first_shown = $oli; + } + $first_shown = $cnt; + $last_shown = $oli; + while($oli <= $last_index and $oli != -1) { + $oli = next_prob_group($last_shown, @pg_files); + $cnt++; + $last_shown = $oli; + } + $last_shown = $cnt-1; + $total_probs = $count; } else { + ### Main place to set first/last shown for new problems $first_shown = 0; - $last_shown = scalar(@pg_files)<$maxShown ? scalar(@pg_files) : $maxShown; - $last_shown--; # to make it an array index - @past_marks = (); + $first_index = 0; + $last_index = 0; + $last_shown = 1; + $total_probs = 0; + my $oli = 0; + while(($oli = next_prob_group($last_index, @pg_files)) != -1 and $last_shown<$maxShown) { + $last_shown++; + $last_index = $oli; + } + $total_probs = $last_shown; + # $last_index points to start of last group + $last_shown--; # first_shown = 0 + $last_index = end_prob_group($last_index, @pg_files); + $oli = $last_index; + while(($oli = next_prob_group($oli, @pg_files)) != -1) { + $total_probs++; + } } ############# Now store data in self for retreival by body $self->{first_shown} = $first_shown; $self->{last_shown} = $last_shown; + $self->{first_index} = $first_index; + $self->{last_index} = $last_index; + $self->{total_probs} = $total_probs; $self->{browse_which} = $browse_which; #$self->{problem_seed} = $problem_seed; $self->{pg_files} = \@pg_files; - $self->{past_marks} = \@past_marks; $self->{all_db_sets} = \@all_db_sets; $self->{library_basic} = $library_basic; - debug("past_marks is ", join(" ", @{$self->{past_marks}})); } @@ -1303,6 +1454,30 @@ sub options { return ""; } +sub head { + my ($self) = @_; + my $ce = $self->r->ce; + my $webwork_htdocs_url = $ce->{webwork_htdocs_url}; + print qq!!; + + print qq!!; + print qq!!; + print qq!!; + print qq!!; + print qq!!; + print qq!!; + print qq!!; + #print qq!!; + #print qq!!; + #print qq!!; + print qq!!; + print "\n"; + print qq!!; + print "\n"; + return ''; +} + + sub body { my ($self) = @_; @@ -1334,17 +1509,21 @@ sub body { my $first_shown = $self->{first_shown}; my $last_shown = $self->{last_shown}; + my $first_index = $self->{first_index}; + my $last_index = $self->{last_index}; + my $total_probs = $self->{total_probs}; my $browse_which = $self->{browse_which}; my $problem_seed = $self->{problem_seed}||1234; my @pg_files = @{$self->{pg_files}}; my @all_db_sets = @{$self->{all_db_sets}}; my @pg_html; - if ($last_shown >= $first_shown) { + if ($last_index >= $first_index) { + my @plist = map {$_->{filepath}} @pg_files[$first_index..$last_index]; @pg_html = renderProblems( r=> $r, user => $user, - problem_list => [@pg_files[$first_shown..$last_shown]], + problem_list => [@plist], displayMode => $r->param('mydisplayMode'), showHints => $showHints, showSolutions => $showSolutions, @@ -1367,8 +1546,14 @@ sub body { $self->{isInSet} = \%isInSet; ########## Top part + my $courseID = $self->r->urlpath->arg("courseID"); + my $webwork_htdocs_url = $ce->{webwork_htdocs_url}; + print qq!!; print CGI::start_form({-method=>"POST", -action=>$r->uri, -name=>'mainform'}), $self->hidden_authen_fields, + CGI::hidden({id=>'hidden_courseID',name=>'courseID',default=>$courseID }), + #CGI::hidden({id=>'hidden_templatedir',name=>'templatedir',default=>encode_base64($ce->{courseDirs}->{templates})}), + CGI::hidden({id=>'hidden_templatedir',name=>'templatedir',default=>$ce->{courseDirs}->{templates}}), '
      ', CGI::start_table({-border=>2}); $self->make_top_row('all_db_sets'=>\@all_db_sets, @@ -1376,20 +1561,22 @@ sub body { print CGI::hidden(-name=>'browse_which', -value=>$browse_which,-override=>1), CGI::hidden(-name=>'problem_seed', -value=>$problem_seed, -override=>1); for ($j = 0 ; $j < scalar(@pg_files) ; $j++) { - print CGI::hidden(-name=>"all_past_list$j", -value=>$pg_files[$j],-override=>1); + print CGI::hidden(-name=>"all_past_list$j", -value=>$pg_files[$j]->{filepath}, -override=>1)."\n"; + print CGI::hidden(-name=>"all_past_mlt$j", -value=>($pg_files[$j]->{morelt} || 0), -override=>1)."\n"; } print CGI::hidden(-name=>'first_shown', -value=>$first_shown,-override=>1); print CGI::hidden(-name=>'last_shown', -value=>$last_shown, -override=>1); - + print CGI::hidden(-name=>'first_index', -value=>$first_index); + print CGI::hidden(-name=>'last_index', -value=>$last_index); + print CGI::hidden(-name=>'total_probs', -value=>$total_probs); ########## Now print problems my $jj; for ($jj=0; $jj{courseDirs}->{templates}/?||; - $self->make_data_row($pg_files[$jj+$first_shown], $pg_html[$jj], $jj+1, $self->{past_marks}->[$jj]); - #$self->make_data_row($pg_files[$jj+$first_shown], $pg_html[$jj], $jj+1, $self->{past_marks}->[$jj+$first_shown]); #MEG + $pg_files[$jj+$first_index]->{filepath} =~ s|^$ce->{courseDirs}->{templates}/?||; + $self->make_data_row($pg_files[$jj+$first_index], $pg_html[$jj], $jj+1); } ########## Finish things off @@ -1397,19 +1584,18 @@ sub body { print '
      '; # if($first_shown>0 or (1+$last_shown) 0) { + if ($first_index > 0) { $prev_button = CGI::submit(-name=>"prev_page", -style=>"width:15ex", -value=>"Previous page"); } - if ((1+$last_shown)"next_page", -style=>"width:15ex", -value=>"Next page"); } if (scalar(@pg_files)>0) { - print CGI::p(($first_shown+1)."-".($last_shown+1)." of ".scalar(@pg_files). + print CGI::p(CGI::span({-id=>'what_shown'}, CGI::span({-id=>'firstshown'}, $first_shown+1)."-".CGI::span({-id=>'lastshown'}, $last_shown+1))." of ".CGI::span({-id=>'totalshown'}, $total_probs). " shown.", $prev_button, " ", $next_button, - CGI::submit(-name=>"update", -style=>"width:15ex; font-weight:bold", - -value=>"Update Set")); + ); } # } print CGI::endform(), "\n"; diff --git a/lib/WeBWorK/ContentGenerator/Instructor/SetMaker3.pm b/lib/WeBWorK/ContentGenerator/Instructor/SetMaker3.pm index 6f0c72c65..2cd669236 100644 --- a/lib/WeBWorK/ContentGenerator/Instructor/SetMaker3.pm +++ b/lib/WeBWorK/ContentGenerator/Instructor/SetMaker3.pm @@ -97,24 +97,14 @@ sub head { my ($self) = @_; my $ce = $self->r->ce; my $webwork_htdocs_url = $ce->{webwork_htdocs_url}; - print qq!!; + print qq!!; + #print qq!!; + #print qq!!; + #print qq!!; + #print qq!!; - print qq!!; - print qq!!; - print qq!!; - print qq!!; - print qq!!; - print qq!!; - - - print qq!!; - print qq!!; - print qq!!; - print qq!!; - print qq!!; - print qq!!; - print qq!!; + print qq!!; #print qq!!; #print qq!!; diff --git a/lib/WeBWorK/ContentGenerator/Instructor/SetMakernojs.pm b/lib/WeBWorK/ContentGenerator/Instructor/SetMakernojs.pm new file mode 100644 index 000000000..20c217423 --- /dev/null +++ b/lib/WeBWorK/ContentGenerator/Instructor/SetMakernojs.pm @@ -0,0 +1,1426 @@ +################################################################################ +# WeBWorK Online Homework Delivery System +# Copyright 2000-2007 The WeBWorK Project, http://openwebwork.sf.net/ +# $CVSHeader: webwork2/lib/WeBWorK/ContentGenerator/Instructor/SetMaker.pm,v 1.85 2008/07/01 13:18:52 glarose Exp $ +# +# This program is free software; you can redistribute it and/or modify it under +# the terms of either: (a) the GNU General Public License as published by the +# Free Software Foundation; either version 2, or (at your option) any later +# version, or (b) the "Artistic License" which comes with this package. +# +# This program is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +# FOR A PARTICULAR PURPOSE. See either the GNU General Public License or the +# Artistic License for more details. +################################################################################ + + +package WeBWorK::ContentGenerator::Instructor::SetMakernojs; +use base qw(WeBWorK::ContentGenerator::Instructor); + +=head1 NAME + +WeBWorK::ContentGenerator::Instructor::SetMakernojs - Make homework sets. + +=cut + +use strict; +use warnings; + + +#use CGI qw(-nosticky); +use WeBWorK::CGI; +use WeBWorK::Debug; +use WeBWorK::Form; +use WeBWorK::Utils qw(readDirectory max sortByName); +use WeBWorK::Utils::Tasks qw(renderProblems); +use File::Find; + +require WeBWorK::Utils::ListingDB; + +use constant SHOW_HINTS_DEFAULT => 0; +use constant SHOW_SOLUTIONS_DEFAULT => 0; +use constant MAX_SHOW_DEFAULT => 20; +use constant NO_LOCAL_SET_STRING => 'No sets in this course yet'; +use constant SELECT_SET_STRING => 'Select a Set from this Course'; +use constant SELECT_LOCAL_STRING => 'Select a Problem Collection'; +use constant MY_PROBLEMS => ' My Problems '; +use constant MAIN_PROBLEMS => ' Unclassified Problems '; +use constant CREATE_SET_BUTTON => 'Create New Set'; +use constant ALL_CHAPTERS => 'All Chapters'; +use constant ALL_SUBJECTS => 'All Subjects'; +use constant ALL_SECTIONS => 'All Sections'; +use constant ALL_TEXTBOOKS => 'All Textbooks'; + +use constant LIB2_DATA => { + 'dbchapter' => {name => 'library_chapters', all => 'All Chapters'}, + 'dbsection' => {name => 'library_sections', all =>'All Sections' }, + 'dbsubject' => {name => 'library_subjects', all => 'All Subjects' }, + 'textbook' => {name => 'library_textbook', all => 'All Textbooks'}, + 'textchapter' => {name => 'library_textchapter', all => 'All Chapters'}, + 'textsection' => {name => 'library_textsection', all => 'All Sections'}, + 'keywords' => {name => 'library_keywords', all => '' }, + }; + +## Flags for operations on files + +use constant ADDED => 1; +use constant HIDDEN => (1 << 1); +use constant SUCCESS => (1 << 2); + +## for additional problib buttons +my %problib; ## This is configured in defaults.config +my %ignoredir = ( + '.' => 1, '..' => 1, 'Library' => 1, 'CVS' => 1, 'tmpEdit' => 1, + 'headers' => 1, 'macros' => 1, 'email' => 1, '.svn' => 1, +); + +sub prepare_activity_entry { + my $self=shift; + my $r = $self->r; + my $user = $self->r->param('user') || 'NO_USER'; + return("In SetMaker as user $user"); +} + +## This is for searching the disk for directories containing pg files. +## to make the recursion work, this returns an array where the first +## item is the number of pg files in the directory. The second is a +## list of directories which contain pg files. +## +## If a directory contains only one pg file and the directory name +## is the same as the file name, then the directory is considered +## to be part of the parent directory (it is probably in a separate +## directory only because it has auxiliary files that want to be +## kept together with the pg file). +## +## If a directory has a file named "=library-ignore", it is never +## included in the directory menu. If a directory contains a file +## called "=library-combine-up", then its pg are included with those +## in the parent directory (and the directory does not appear in the +## menu). If it has a file called "=library-no-combine" then it is +## always listed as a separate directory even if it contains only one +## pg file. + +sub get_library_sets { + my $top = shift; my $dir = shift; + # ignore directories that give us an error + my @lis = eval { readDirectory($dir) }; + if ($@) { + warn $@; + return (0); + } + return (0) if grep /^=library-ignore$/, @lis; + + my @pgfiles = grep { m/\.pg$/ and (not m/(Header|-text)\.pg$/) and -f "$dir/$_"} @lis; + my $pgcount = scalar(@pgfiles); + my $pgname = $dir; $pgname =~ s!.*/!!; $pgname .= '.pg'; + my $combineUp = ($pgcount == 1 && $pgname eq $pgfiles[0] && !(grep /^=library-no-combine$/, @lis)); + + my @pgdirs; + my @dirs = grep {!$ignoredir{$_} and -d "$dir/$_"} @lis; + if ($top == 1) {@dirs = grep {!$problib{$_}} @dirs} + foreach my $subdir (@dirs) { + my @results = get_library_sets(0, "$dir/$subdir"); + $pgcount += shift @results; push(@pgdirs,@results); + } + + return ($pgcount, @pgdirs) if $top || $combineUp || grep /^=library-combine-up$/, @lis; + return (0,@pgdirs,$dir); +} + +sub get_library_pgs { + my $top = shift; my $base = shift; my $dir = shift; + my @lis = readDirectory("$base/$dir"); + return () if grep /^=library-ignore$/, @lis; + return () if !$top && grep /^=library-no-combine$/, @lis; + + my @pgs = grep { m/\.pg$/ and (not m/(Header|-text)\.pg$/) and -f "$base/$dir/$_"} @lis; + my $others = scalar(grep { (!m/\.pg$/ || m/(Header|-text)\.pg$/) && + !m/(\.(tmp|bak)|~)$/ && -f "$base/$dir/$_" } @lis); + + my @dirs = grep {!$ignoredir{$_} and -d "$base/$dir/$_"} @lis; + if ($top == 1) {@dirs = grep {!$problib{$_}} @dirs} + foreach my $subdir (@dirs) {push(@pgs, get_library_pgs(0,"$base/$dir",$subdir))} + + return () unless $top || (scalar(@pgs) == 1 && $others) || grep /^=library-combine-up$/, @lis; + return (map {"$dir/$_"} @pgs); +} + +sub list_pg_files { + my ($templates,$dir) = @_; + my $top = ($dir eq '.')? 1 : 2; + my @pgs = get_library_pgs($top,$templates,$dir); + return sortByName(undef,@pgs); +} + +## Search for set definition files + +sub get_set_defs { + my $topdir = shift; + my @found_set_defs; + # get_set_defs_wanted is a closure over @found_set_defs + my $get_set_defs_wanted = sub { + #my $fn = $_; + #my $fdir = $File::Find::dir; + #return() if($fn !~ /^set.*\.def$/); + ##return() if(not -T $fn); + #push @found_set_defs, "$fdir/$fn"; + push @found_set_defs, $_ if m|/set[^/]*\.def$|; + }; + find({ wanted => $get_set_defs_wanted, follow_fast=>1, no_chdir=>1}, $topdir); + map { $_ =~ s|^$topdir/?|| } @found_set_defs; + return @found_set_defs; +} + +## Try to make reading of set defs more flexible. Additional strategies +## for fixing a path can be added here. + +sub munge_pg_file_path { + my $self = shift; + my $pg_path = shift; + my $path_to_set_def = shift; + my $end_path = $pg_path; + # if the path is ok, don't fix it + return($pg_path) if(-e $self->r->ce->{courseDirs}{templates}."/$pg_path"); + # if we have followed a link into a self contained course to get + # to the set.def file, we need to insert the start of the path to + # the set.def file + $end_path = "$path_to_set_def/$pg_path"; + return($end_path) if(-e $self->r->ce->{courseDirs}{templates}."/$end_path"); + # if we got this far, this path is bad, but we let it produce + # an error so the user knows there is a troublesome path in the + # set.def file. + return($pg_path); +} + +## Read a set definition file. This could be abstracted since it happens +## elsewhere. Here we don't have to process so much of the file. + +sub read_set_def { + my $self = shift; + my $r = $self->r; + my $filePathOrig = shift; + my $filePath = $r->ce->{courseDirs}{templates}."/$filePathOrig"; + $filePathOrig =~ s/set.*\.def$//; + $filePathOrig =~ s|/$||; + $filePathOrig = "." if ($filePathOrig !~ /\S/); + my @pg_files = (); + my ($line, $got_to_pgs, $name, @rest) = ("", 0, ""); + if ( open (SETFILENAME, "$filePath") ) { + while($line = ) { + chomp($line); + $line =~ s|(#.*)||; # don't read past comments + if($got_to_pgs) { + unless ($line =~ /\S/) {next;} # skip blank lines + ($name,@rest) = split (/\s*,\s*/,$line); + $name =~ s/\s*//g; + push @pg_files, $name; + } else { + $got_to_pgs = 1 if ($line =~ /problemList\s*=/); + } + } + } else { + $self->addbadmessage("Cannot open $filePath"); + } + # This is where we would potentially munge the pg file paths + # One possibility + @pg_files = map { $self->munge_pg_file_path($_, $filePathOrig) } @pg_files; + return(@pg_files); +} + +## go through past page getting a list of identifiers for the problems +## and whether or not they are selected, and whether or not they should +## be hidden + +sub get_past_problem_files { + my $r = shift; + my @found=(); + my $count =1; + while (defined($r->param("filetrial$count"))) { + my $val = 0; + $val |= ADDED if($r->param("trial$count")); + $val |= HIDDEN if($r->param("hideme$count")); + push @found, [$r->param("filetrial$count"), $val]; + $count++; + } + return(\@found); +} + +#### For adding new problems + +sub add_selected { + my $self = shift; + my $db = shift; + my $setName = shift; + my @past_problems = @{$self->{past_problems}}; + my @selected = @past_problems; + my (@path, $file, $selected, $freeProblemID); + # DBFIXME count would work just as well + $freeProblemID = max($db->listGlobalProblems($setName)) + 1; + my $addedcount=0; + + for $selected (@selected) { + if($selected->[1] & ADDED) { + $file = $selected->[0]; + my $problemRecord = $self->addProblemToSet(setName => $setName, + sourceFile => $file, problemID => $freeProblemID); + $freeProblemID++; + $self->assignProblemToAllSetUsers($problemRecord); + $selected->[1] |= SUCCESS; + $addedcount++; + } + } + return($addedcount); +} + + +############# List of sets of problems in templates directory + +sub get_problem_directories { + my $ce = shift; + my $lib = shift; + my $source = $ce->{courseDirs}{templates}; + my $main = MY_PROBLEMS; my $isTop = 1; + if ($lib) {$source .= "/$lib"; $main = MAIN_PROBLEMS; $isTop = 2} + my @all_problem_directories = get_library_sets($isTop, $source); + my $includetop = shift @all_problem_directories; + my $j; + for ($j=0; $j{courseDirs}->{templates}/?||; + } + @all_problem_directories = sortByName(undef, @all_problem_directories); + unshift @all_problem_directories, $main if($includetop); + return (\@all_problem_directories); +} + +############# Everyone has a view problems line. Abstract it +sub view_problems_line { + my $internal_name = shift; + my $label = shift; + my $r = shift; # so we can get parameter values + my $result = CGI::submit(-name=>"$internal_name", -value=>$label); + + my %display_modes = %{WeBWorK::PG::DISPLAY_MODES()}; + my @active_modes = grep { exists $display_modes{$_} } + @{$r->ce->{pg}->{displayModes}}; + push @active_modes, 'None'; + # We have our own displayMode since its value may be None, which is illegal + # in other modules. + my $mydisplayMode = $r->param('mydisplayMode') || $r->ce->{pg}->{options}->{displayMode}; + $result .= ' Display Mode: '.CGI::popup_menu(-name=> 'mydisplayMode', + -values=>\@active_modes, + -default=> $mydisplayMode); + # Now we give a choice of the number of problems to show + my $defaultMax = $r->param('max_shown') || MAX_SHOW_DEFAULT; + $result .= ' Max. Shown: '. + CGI::popup_menu(-name=> 'max_shown', + -values=>[5,10,15,20,25,30,50,'All'], + -default=> $defaultMax); + # Option of whether to show hints and solutions + my $defaultHints = $r->param('showHints') || SHOW_HINTS_DEFAULT; + $result .= " ".CGI::checkbox(-name=>"showHints",-checked=>$defaultHints,-label=>"Hints"); + my $defaultSolutions = $r->param('showSolutions') || SHOW_SOLUTIONS_DEFAULT; + $result .= " ".CGI::checkbox(-name=>"showSolutions",-checked=>$defaultSolutions,-label=>"Solutions"); + + return($result); +} + + +### The browsing panel has three versions +##### Version 1 is local problems +sub browse_local_panel { + my $self = shift; + my $library_selected = shift; + my $lib = shift || ''; $lib =~ s/^browse_//; + my $name = ($lib eq '')? 'Local' : $problib{$lib}; + + my $list_of_prob_dirs= get_problem_directories($self->r->ce,$lib); + if(scalar(@$list_of_prob_dirs) == 0) { + $library_selected = "Found no directories containing problems"; + unshift @{$list_of_prob_dirs}, $library_selected; + } else { + my $default_value = SELECT_LOCAL_STRING; + if (not $library_selected or $library_selected eq $default_value) { + unshift @{$list_of_prob_dirs}, $default_value; + $library_selected = $default_value; + } + } + debug("library is $lib and sets are $library_selected"); + my $view_problem_line = view_problems_line('view_local_set', 'View Problems', $self->r); + my @popup_menu_args = ( + -name => 'library_sets', + -values => $list_of_prob_dirs, + -default => $library_selected, + ); + # make labels without the $lib prefix -- reduces the width of the popup menu + if (length($lib)) { + my %labels = map { my($l)=$_=~/^$lib\/(.*)$/;$_=>$l } @$list_of_prob_dirs; + push @popup_menu_args, -labels => \%labels; + } + print CGI::Tr({}, CGI::td({-class=>"InfoPanel", -align=>"left"}, "$name Problems: ", + CGI::popup_menu(@popup_menu_args), + CGI::br(), + $view_problem_line, + )); +} + +##### Version 2 is local homework sets +sub browse_mysets_panel { + my $self = shift; + my $library_selected = shift; + my $list_of_local_sets = shift; + my $default_value = "Select a Homework Set"; + + if(scalar(@$list_of_local_sets) == 0) { + $list_of_local_sets = [NO_LOCAL_SET_STRING]; + } elsif (not $library_selected or $library_selected eq $default_value) { + unshift @{$list_of_local_sets}, $default_value; + $library_selected = $default_value; + } + + my $view_problem_line = view_problems_line('view_mysets_set', 'View Problems', $self->r); + print CGI::Tr({}, + CGI::td({-class=>"InfoPanel", -align=>"left"}, "Browse from: ", + CGI::popup_menu(-name=> 'library_sets', + -values=>$list_of_local_sets, + -default=> $library_selected), + CGI::br(), + $view_problem_line + )); +} + +##### Version 3 is the problem library +# +# This comes in 3 forms, problem library version 1, and for version 2 there +# is the basic, and the advanced interfaces. This function checks what we are +# supposed to do, or aborts if the problem library has not been installed. + +sub browse_library_panel { + my $self=shift; + my $r = $self->r; + my $ce = $r->ce; + + # See if the problem library is installed + my $libraryRoot = $r->{ce}->{problemLibrary}->{root}; + + unless($libraryRoot) { + print CGI::Tr(CGI::td(CGI::div({class=>'ResultsWithError', align=>"center"}, + "The problem library has not been installed."))); + return; + } + # Test if the Library directory link exists. If not, try to make it + unless(-d "$ce->{courseDirs}->{templates}/Library") { + unless(symlink($libraryRoot, "$ce->{courseDirs}->{templates}/Library")) { + my $msg = <<"HERE"; +You are missing the directory templates/Library, which is needed +for the Problem Library to function. It should be a link pointing to +$libraryRoot, which you set in conf/site.conf. +I tried to make the link for you, but that failed. Check the permissions +in your templates directory. +HERE + $self->addbadmessage($msg); + } + } + + # Now check what version we are supposed to use + my $libraryVersion = $r->{ce}->{problemLibrary}->{version} || 1; + if($libraryVersion == 1) { + return $self->browse_library_panel1; + } elsif($libraryVersion >= 2) { + return $self->browse_library_panel2 if($self->{library_basic}==1); + return $self->browse_library_panel2adv; + } else { + print CGI::Tr(CGI::td(CGI::div({class=>'ResultsWithError', align=>"center"}, + "The problem library version is set to an illegal value."))); + return; + } +} + +sub browse_library_panel1 { + my $self = shift; + my $r = $self->r; + my $ce = $r->ce; + + my @chaps = WeBWorK::Utils::ListingDB::getAllChapters($r->{ce}); + unshift @chaps, LIB2_DATA->{dbchapter}{all}; + my $chapter_selected = $r->param('library_chapters') || LIB2_DATA->{dbchapter}->{all}; + + my @sects=(); + if ($chapter_selected ne LIB2_DATA->{dbchapter}{all}) { + @sects = WeBWorK::Utils::ListingDB::getAllSections($r->{ce}, $chapter_selected); + } + + unshift @sects, ALL_SECTIONS; + my $section_selected = $r->param('library_sections') || LIB2_DATA->{dbsection}{all}; + + my $view_problem_line = view_problems_line('lib_view', 'View Problems', $self->r); + + print CGI::Tr(CGI::td({-class=>"InfoPanel", -align=>"left"}, + CGI::start_table(), + CGI::Tr({}, + CGI::td(["Chapter:", + CGI::popup_menu(-name=> 'library_chapters', + -values=>\@chaps, + -default=> $chapter_selected, + -onchange=>"submit();return true" + ), + CGI::submit(-name=>"lib_select_chapter", -value=>"Update Section List")])), + CGI::Tr({}, + CGI::td("Section:"), + CGI::td({-colspan=>2}, + CGI::popup_menu(-name=> 'library_sections', + -values=>\@sects, + -default=> $section_selected + ))), + + CGI::Tr(CGI::td({-colspan=>3}, $view_problem_line)), + CGI::end_table(), + )); +} + +sub browse_library_panel2 { + my $self = shift; + my $r = $self->r; + my $ce = $r->ce; + + my @subjs = WeBWorK::Utils::ListingDB::getAllDBsubjects($r); + unshift @subjs, LIB2_DATA->{dbsubject}{all}; + + my @chaps = WeBWorK::Utils::ListingDB::getAllDBchapters($r); + unshift @chaps, LIB2_DATA->{dbchapter}{all}; + + my @sects=(); + @sects = WeBWorK::Utils::ListingDB::getAllDBsections($r); + unshift @sects, LIB2_DATA->{dbsection}{all}; + + my $subject_selected = $r->param('library_subjects') || LIB2_DATA->{dbsubject}{all}; + my $chapter_selected = $r->param('library_chapters') || LIB2_DATA->{dbchapter}{all}; + my $section_selected = $r->param('library_sections') || LIB2_DATA->{dbsection}{all}; + + my $view_problem_line = view_problems_line('lib_view', 'View Problems', $self->r); + + my $count_line = WeBWorK::Utils::ListingDB::countDBListings($r); + if($count_line==0) { + $count_line = "There are no matching pg files"; + } else { + $count_line = "There are $count_line matching WeBWorK problem files"; + } + + print CGI::Tr({}, + CGI::td({-class=>"InfoPanel", -align=>"left"}, + CGI::hidden(-name=>"library_is_basic", -default=>1,-override=>1), + CGI::start_table({-width=>"100%"}), + CGI::Tr({}, + CGI::td(["Subject:", + CGI::popup_menu(-name=> 'library_subjects', + -values=>\@subjs, + -default=> $subject_selected, + -onchange=>"submit();return true" + )]), + CGI::td({-colspan=>2, -align=>"right"}, + CGI::submit(-name=>"lib_select_subject", -value=>"Update Chapter/Section Lists")) + ), + CGI::Tr({}, + CGI::td(["Chapter:", + CGI::popup_menu(-name=> 'library_chapters', + -values=>\@chaps, + -default=> $chapter_selected, + -onchange=>"submit();return true" + )]), + CGI::td({-colspan=>2, -align=>"right"}, + CGI::submit(-name=>"library_advanced", -value=>"Advanced Search")) + ), + CGI::Tr({}, + CGI::td(["Section:", + CGI::popup_menu(-name=> 'library_sections', + -values=>\@sects, + -default=> $section_selected, + -onchange=>"submit();return true" + )]), + ), + CGI::Tr(CGI::td({-colspan=>3}, $view_problem_line)), + CGI::Tr(CGI::td({-colspan=>3, -align=>"center"}, $count_line)), + CGI::end_table(), + )); + +} + +sub browse_library_panel2adv { + my $self = shift; + my $r = $self->r; + my $ce = $r->ce; + my $right_button_style = "width: 18ex"; + + my @subjs = WeBWorK::Utils::ListingDB::getAllDBsubjects($r); + if(! grep { $_ eq $r->param('library_subjects') } @subjs) { + $r->param('library_subjects', ''); + } + unshift @subjs, LIB2_DATA->{dbsubject}{all}; + + my @chaps = WeBWorK::Utils::ListingDB::getAllDBchapters($r); + if(! grep { $_ eq $r->param('library_chapters') } @chaps) { + $r->param('library_chapters', ''); + } + unshift @chaps, LIB2_DATA->{dbchapter}{all}; + + my @sects = WeBWorK::Utils::ListingDB::getAllDBsections($r); + if(! grep { $_ eq $r->param('library_sections') } @sects) { + $r->param('library_sections', ''); + } + unshift @sects, LIB2_DATA->{dbsection}{all}; + + my $texts = WeBWorK::Utils::ListingDB::getDBTextbooks($r); + my @textarray = map { $_->[0] } @{$texts}; + my %textlabels = (); + for my $ta (@{$texts}) { + $textlabels{$ta->[0]} = $ta->[1]." by ".$ta->[2]." (edition ".$ta->[3].")"; + } + if(! grep { $_ eq $r->param('library_textbook') } @textarray) { + $r->param('library_textbook', ''); + } + unshift @textarray, LIB2_DATA->{textbook}{all}; + my $atb = LIB2_DATA->{textbook}{all}; $textlabels{$atb} = LIB2_DATA->{textbook}{all}; + + my $textchap_ref = WeBWorK::Utils::ListingDB::getDBTextbooks($r, 'textchapter'); + my @textchaps = map { $_->[0] } @{$textchap_ref}; + if(! grep { $_ eq $r->param('library_textchapter') } @textchaps) { + $r->param('library_textchapter', ''); + } + unshift @textchaps, LIB2_DATA->{textchapter}{all}; + + my $textsec_ref = WeBWorK::Utils::ListingDB::getDBTextbooks($r, 'textsection'); + my @textsecs = map { $_->[0] } @{$textsec_ref}; + if(! grep { $_ eq $r->param('library_textsection') } @textsecs) { + $r->param('library_textsection', ''); + } + unshift @textsecs, LIB2_DATA->{textsection}{all}; + + my %selected = (); + for my $j (qw( dbsection dbchapter dbsubject textbook textchapter textsection )) { + $selected{$j} = $r->param(LIB2_DATA->{$j}{name}) || LIB2_DATA->{$j}{all}; + } + + my $text_popup = CGI::popup_menu(-name => 'library_textbook', + -values =>\@textarray, + -labels => \%textlabels, + -default=>$selected{textbook}, + -onchange=>"submit();return true"); + + + my $library_keywords = $r->param('library_keywords') || ''; + + my $view_problem_line = view_problems_line('lib_view', 'View Problems', $self->r); + + my $count_line = WeBWorK::Utils::ListingDB::countDBListings($r); + if($count_line==0) { + $count_line = "There are no matching pg files"; + } else { + $count_line = "There are $count_line matching WeBWorK problem files"; + } + + print CGI::Tr({}, + CGI::td({-class=>"InfoPanel", -align=>"left"}, + CGI::hidden(-name=>"library_is_basic", -default=>2,-override=>1), + CGI::start_table({-width=>"100%"}), + # Html done by hand since it is temporary + CGI::Tr(CGI::td({-colspan=>4, -align=>"center"}, 'All Selected Constraints Joined by "And"')), + CGI::Tr({}, + CGI::td(["Subject:", + CGI::popup_menu(-name=> 'library_subjects', + -values=>\@subjs, + -default=> $selected{dbsubject}, + -onchange=>"submit();return true" + )]), + CGI::td({-colspan=>2, -align=>"right"}, + CGI::submit(-name=>"lib_select_subject", -value=>"Update Menus", + -style=> $right_button_style))), + CGI::Tr({}, + CGI::td(["Chapter:", + CGI::popup_menu(-name=> 'library_chapters', + -values=>\@chaps, + -default=> $selected{dbchapter}, + -onchange=>"submit();return true" + )]), + CGI::td({-colspan=>2, -align=>"right"}, + CGI::submit(-name=>"library_reset", -value=>"Reset", + -style=>$right_button_style)) + ), + CGI::Tr({}, + CGI::td(["Section:", + CGI::popup_menu(-name=> 'library_sections', + -values=>\@sects, + -default=> $selected{dbsection}, + -onchange=>"submit();return true" + )]), + CGI::td({-colspan=>2, -align=>"right"}, + CGI::submit(-name=>"library_basic", -value=>"Basic Search", + -style=>$right_button_style)) + ), + CGI::Tr({}, + CGI::td(["Textbook:", $text_popup]), + ), + CGI::Tr({}, + CGI::td(["Text chapter:", + CGI::popup_menu(-name=> 'library_textchapter', + -values=>\@textchaps, + -default=> $selected{textchapter}, + -onchange=>"submit();return true" + )]), + ), + CGI::Tr({}, + CGI::td(["Text section:", + CGI::popup_menu(-name=> 'library_textsection', + -values=>\@textsecs, + -default=> $selected{textsection}, + -onchange=>"submit();return true" + )]), + ), + CGI::Tr({}, + CGI::td("Keywords:"),CGI::td({-colspan=>2}, + CGI::textfield(-name=>"library_keywords", + -default=>$library_keywords, + -override=>1, + -size=>40))), + CGI::Tr(CGI::td({-colspan=>3}, $view_problem_line)), + CGI::Tr(CGI::td({-colspan=>3, -align=>"center"}, $count_line)), + CGI::end_table(), + )); + +} + + +##### Version 4 is the set definition file panel + +sub browse_setdef_panel { + my $self = shift; + my $r = $self->r; + my $ce = $r->ce; + my $library_selected = shift; + my $default_value = "Select a Set Definition File"; + # in the following line, the parens after sort are important. if they are + # omitted, sort will interpret get_set_defs as the name of the comparison + # function, and ($ce->{courseDirs}{templates}) as a single element list to + # be sorted. *barf* + my @list_of_set_defs = sort(get_set_defs($ce->{courseDirs}{templates})); + if(scalar(@list_of_set_defs) == 0) { + @list_of_set_defs = (NO_LOCAL_SET_STRING); + } elsif (not $library_selected or $library_selected eq $default_value) { + unshift @list_of_set_defs, $default_value; + $library_selected = $default_value; + } + my $view_problem_line = view_problems_line('view_setdef_set', 'View Problems', $self->r); + my $popupetc = CGI::popup_menu(-name=> 'library_sets', + -values=>\@list_of_set_defs, + -default=> $library_selected). + CGI::br(). $view_problem_line; + if($list_of_set_defs[0] eq NO_LOCAL_SET_STRING) { + $popupetc = "there are no set definition files in this course to look at." + } + print CGI::Tr(CGI::td({-class=>"InfoPanel", -align=>"left"}, "Browse from: ", + $popupetc + )); +} + +sub make_top_row { + my $self = shift; + my $r = $self->r; + my $ce = $r->ce; + my %data = @_; + + my $list_of_local_sets = $data{all_db_sets}; + my $have_local_sets = scalar(@$list_of_local_sets); + my $browse_which = $data{browse_which}; + my $library_selected = $self->{current_library_set}; + my $set_selected = $r->param('local_sets'); + my (@dis1, @dis2, @dis3, @dis4) = (); + @dis1 = (-disabled=>1) if($browse_which eq 'browse_npl_library'); + @dis2 = (-disabled=>1) if($browse_which eq 'browse_local'); + @dis3 = (-disabled=>1) if($browse_which eq 'browse_mysets'); + @dis4 = (-disabled=>1) if($browse_which eq 'browse_setdefs'); + + ## Make buttons for additional problem libraries + my $libs = ''; + foreach my $lib (sort(keys(%problib))) { + $libs .= ' '. CGI::submit(-name=>"browse_$lib", -value=>$problib{$lib}, + ($browse_which eq "browse_$lib")? (-disabled=>1): ()) + if (-d "$ce->{courseDirs}{templates}/$lib"); + } + $libs = CGI::br()."or Problems from".$libs if $libs ne ''; + + my $these_widths = "width: 24ex"; + + if($have_local_sets ==0) { + $list_of_local_sets = [NO_LOCAL_SET_STRING]; + } elsif (not defined($set_selected) or $set_selected eq "" + or $set_selected eq SELECT_SET_STRING) { + unshift @{$list_of_local_sets}, SELECT_SET_STRING; + $set_selected = SELECT_SET_STRING; + } + #my $myjs = 'document.mainform.selfassign.value=confirm("Should I assign the new set to you now?\nUse OK for yes and Cancel for no.");true;'; + + print CGI::Tr(CGI::td({-class=>"InfoPanel", -align=>"left"}, "Add problems to ", + CGI::b("Target Set: "), + CGI::popup_menu(-name=> 'local_sets', + -values=>$list_of_local_sets, + -default=> $set_selected, + -override=>1), + CGI::submit(-name=>"edit_local", -value=>"Edit Target Set"), + CGI::hidden(-name=>"selfassign", -default=>0,-override=>1). + CGI::br(), + CGI::br(), + CGI::submit(-name=>"new_local_set", -value=>"Create a New Set in This Course:", + -onclick=>"document.mainform.selfassign.value=1" # $myjs + ), + " ", + CGI::textfield(-name=>"new_set_name", + -default=>"Name for new set here", + -override=>1, -size=>30), + )); + + print CGI::Tr(CGI::td({-bgcolor=>"black"})); + + # Tidy this list up since it is used in two different places + if ($list_of_local_sets->[0] eq SELECT_SET_STRING) { + shift @{$list_of_local_sets}; + } + + print CGI::Tr(CGI::td({-class=>"InfoPanel", -align=>"center"}, + "Browse ", + CGI::submit(-name=>"browse_npl_library", -value=>"National Problem Library", -style=>$these_widths, @dis1), + CGI::submit(-name=>"browse_local", -value=>"Local Problems", -style=>$these_widths, @dis2), + CGI::submit(-name=>"browse_mysets", -value=>"From This Course", -style=>$these_widths, @dis3), + CGI::submit(-name=>"browse_setdefs", -value=>"Set Definition Files", -style=>$these_widths, @dis4), + $libs, + )); + + #print CGI::Tr(CGI::td({-bgcolor=>"black"})); + print CGI::hr(); + + if ($browse_which eq 'browse_local') { + $self->browse_local_panel($library_selected); + } elsif ($browse_which eq 'browse_mysets') { + $self->browse_mysets_panel($library_selected, $list_of_local_sets); + } elsif ($browse_which eq 'browse_npl_library') { + $self->browse_library_panel(); + } elsif ($browse_which eq 'browse_setdefs') { + $self->browse_setdef_panel($library_selected); + } else { ## handle other problem libraries + $self->browse_local_panel($library_selected,$browse_which); + } + + print CGI::Tr(CGI::td({-bgcolor=>"black"})); + + # For next/previous buttons + my ($next_button, $prev_button, $shown_msg) = ("", "", ""); + my $first_shown = $self->{first_shown}; + my $last_shown = $self->{last_shown}; + my @pg_files = @{$self->{pg_files}}; + if ($first_shown > 0) { + $prev_button = CGI::submit(-name=>"prev_page", -style=>"width:15ex", + -value=>"Previous page"); + } + if ((1+$last_shown)"next_page", -style=>"width:15ex", + -value=>"Next page"); + } + + print CGI::Tr({}, + CGI::td({-class=>"InfoPanel", -align=>"center"}, + CGI::start_table({-border=>"0"}), + CGI::Tr({}, CGI::td({ -align=>"center"}, + CGI::submit(-name=>"select_all", -style=>$these_widths, + -value=>"Mark All For Adding"), + CGI::submit(-name=>"select_none", -style=>$these_widths, + -value=>"Clear All Marks"), + CGI::submit(-name=>"cleardisplay", + -style=>$these_widths, + -value=>"Clear Problem Display") + )), + CGI::Tr({}, + CGI::td({}, + CGI::submit(-name=>"update", -style=>$these_widths. "; font-weight:bold", + -value=>"Update Set"), + + $prev_button, " ", $next_button, + + CGI::submit(-name=>"rerandomize", + -style=>$these_widths, + -value=>"Rerandomize"), + )), + CGI::end_table())); +} + +sub make_data_row { + my $self = shift; + my $r = $self->r; + my $sourceFileName = shift; + my $pg = shift; + my $cnt = shift; + my $mark = shift || 0; + + $sourceFileName =~ s|^./||; # clean up top ugliness + + my $urlpath = $self->r->urlpath; + my $db = $self->r->db; + + ## to set up edit and try links elegantly we want to know if + ## any target set is a gateway assignment or not + my $localSet = $self->r->param('local_sets'); + my $setRecord; + if ( defined($localSet) && $localSet ne SELECT_SET_STRING && + $localSet ne NO_LOCAL_SET_STRING ) { + $setRecord = $db->getGlobalSet( $localSet ); + } + my $isGatewaySet = ( defined($setRecord) && + $setRecord->assignment_type =~ /gateway/ ); + + my $problem_output = $pg->{flags}->{error_flag} ? + CGI::div({class=>"ResultsWithError"}, CGI::em("This problem produced an error")) + : CGI::div({class=>"RenderSolo"}, $pg->{body_text}); + $problem_output .= $pg->{flags}->{comment} if($pg->{flags}->{comment}); + + + #if($self->{r}->param('browse_which') ne 'browse_npl_library') { + my $problem_seed = $self->{'problem_seed'} || 1234; + my $edit_link = CGI::a({href=>$self->systemLink( + $urlpath->newFromModule("WeBWorK::ContentGenerator::Instructor::PGProblemEditor", $r, + courseID =>$urlpath->arg("courseID"), + setID=>"Undefined_Set", + problemID=>"1"), + params=>{sourceFilePath => "$sourceFileName", problemSeed=> $problem_seed} + ), target=>"WW_Editor"}, "Edit it" ); + + my $displayMode = $self->r->param("mydisplayMode"); + $displayMode = $self->r->ce->{pg}->{options}->{displayMode} + if not defined $displayMode or $displayMode eq "None"; + my $module = ( $isGatewaySet ) ? "GatewayQuiz" : "Problem"; + my %pathArgs = ( courseID =>$urlpath->arg("courseID"), + setID=>"Undefined_Set" ); + $pathArgs{problemID} = "1" if ( ! $isGatewaySet ); + + my $try_link = CGI::a({href=>$self->systemLink( + $urlpath->newFromModule("WeBWorK::ContentGenerator::$module", $r, + %pathArgs ), + params =>{ + effectiveUser => scalar($self->r->param('user')), + editMode => "SetMaker", + problemSeed=> $problem_seed, + sourceFilePath => "$sourceFileName", + displayMode => $displayMode, + } + ), target=>"WW_View"}, "Try it"); + + my %add_box_data = ( -name=>"trial$cnt",-value=>1,-label=>"Add this problem to the target set on the next update"); + if($mark & SUCCESS) { + $add_box_data{ -label } .= " (just added this problem)"; + } elsif($mark & ADDED) { + $add_box_data{ -checked } = 1; + } + + my $inSet = ($self->{isInSet}{$sourceFileName})? + CGI::span({-style=>"float:right; text-align: right"}, + CGI::i(CGI::b("(This problem is in the target set)"))) : ""; + + print CGI::Tr({-align=>"left"}, CGI::td( + CGI::div({-style=>"background-color: #DDDDDD; margin: 0px auto"}, + CGI::span({-style=>"float:left ; text-align: left"},"File name: $sourceFileName "), + CGI::span({-style=>"float:right ; text-align: right"}, $edit_link, " ", $try_link) + ), CGI::br(), + CGI::checkbox(-name=>"hideme$cnt",-value=>1,-label=>"Don't show this problem on the next update",-override=>1), + CGI::br(), + $inSet, + CGI::checkbox((%add_box_data),-override=>1), + CGI::hidden(-name=>"filetrial$cnt", -default=>$sourceFileName,-override=>1). + CGI::p($problem_output), + )); +} + +sub clear_default { + my $r = shift; + my $param = shift; + my $default = shift; + my $newvalue = $r->param($param) || ''; + $newvalue = '' if($newvalue eq $default); + $r->param($param, $newvalue); +} + +sub pre_header_initialize { + my ($self) = @_; + my $r = $self->r; + ## For all cases, lets set some things + $self->{error}=0; + my $ce = $r->ce; + my $db = $r->db; + my $maxShown = $r->param('max_shown') || MAX_SHOW_DEFAULT; + $maxShown = 10000000 if($maxShown eq 'All'); # let's hope there aren't more + my $library_basic = $r->param('library_is_basic') || 1; + $self->{problem_seed} = $r->param('problem_seed') || 1234; + ## Fix some parameters + for my $key (keys(%{ LIB2_DATA() })) { + clear_default($r, LIB2_DATA->{$key}->{name}, LIB2_DATA->{$key}->{all} ); + } + ## Grab library sets to display from parameters list. We will modify this + ## as we go through the if/else tree + $self->{current_library_set} = $r->param('library_sets'); + + ## These directories will have individual buttons + %problib = %{$ce->{courseFiles}{problibs}} if $ce->{courseFiles}{problibs}; + + my $userName = $r->param('user'); + my $user = $db->getUser($userName); # checked + die "record for user $userName (real user) does not exist." + unless defined $user; + my $authz = $r->authz; + unless ($authz->hasPermissions($userName, "modify_problem_sets")) { + return(""); # Error message already produced in the body + } + + ## Now one action we have to deal with here + if ($r->param('edit_local')) { + my $urlpath = $r->urlpath; + my $db = $r->db; + my $checkset = $db->getGlobalSet($r->param('local_sets')); + if (not defined($checkset)) { + $self->{error} = 1; + $self->addbadmessage('You need to select a "Target Set" before you can edit it.'); + } else { + my $page = $urlpath->newFromModule('WeBWorK::ContentGenerator::Instructor::ProblemSetDetail', $r, setID=>$r->param('local_sets'), courseID=>$urlpath->arg("courseID")); + my $url = $self->systemLink($page); + $self->reply_with_redirect($url); + } + } + + ## Next, lots of set up so that errors can be reported with message() + + ############# List of problems we have already printed + + $self->{past_problems} = get_past_problem_files($r); + # if we don't end up reusing problems, this will be wiped out + # if we do redisplay the same problems, we must adjust this accordingly + my @past_marks = map {$_->[1]} @{$self->{past_problems}}; + my $none_shown = scalar(@{$self->{past_problems}})==0; + my @pg_files=(); + my $use_previous_problems = 1; + my $first_shown = $r->param('first_shown') || 0; + my $last_shown = $r->param('last_shown'); + if (not defined($last_shown)) { + $last_shown = -1; + } + my @all_past_list = (); # these are include requested, but not shown + my $j = 0; + while (defined($r->param("all_past_list$j"))) { + push @all_past_list, $r->param("all_past_list$j"); + $j++; + } + + ############# Default of which problem selector to display + + my $browse_which = $r->param('browse_which') || 'browse_npl_library'; + + + + ## check for problem lib buttons + my $browse_lib = ''; + foreach my $lib (keys %problib) { + if ($r->param("browse_$lib")) { + $browse_lib = "browse_$lib"; + last; + } + } + + ########### Start the logic through if elsif elsif ... + debug("browse_lib", $r->param("$browse_lib")); + debug("browse_npl_library", $r->param("browse_npl_library")); + debug("browse_mysets", $r->param("browse_mysets")); + debug("browse_setdefs", $r->param("browse_setdefs")); + ##### Asked to browse certain problems + if ($browse_lib ne '') { + $browse_which = $browse_lib; + $self->{current_library_set} = ""; + $use_previous_problems = 0; @pg_files = (); ## clear old problems + } elsif ($r->param('browse_npl_library')) { + $browse_which = 'browse_npl_library'; + $self->{current_library_set} = ""; + $use_previous_problems = 0; @pg_files = (); ## clear old problems + } elsif ($r->param('browse_local')) { + $browse_which = 'browse_local'; + #$self->{current_library_set} = ""; + $use_previous_problems = 0; @pg_files = (); ## clear old problems + } elsif ($r->param('browse_mysets')) { + $browse_which = 'browse_mysets'; + $self->{current_library_set} = ""; + $use_previous_problems = 0; @pg_files = (); ## clear old problems + } elsif ($r->param('browse_setdefs')) { + $browse_which = 'browse_setdefs'; + $self->{current_library_set} = ""; + $use_previous_problems = 0; @pg_files = (); ## clear old problems + + ##### Change the seed value + + } elsif ($r->param('rerandomize')) { + $self->{problem_seed}= 1+$self->{problem_seed}; + #$r->param('problem_seed', $problem_seed); + $self->addbadmessage('Changing the problem seed for display, but there are no problems showing.') if $none_shown; + + ##### Clear the display + + } elsif ($r->param('cleardisplay')) { + @pg_files = (); + $use_previous_problems=0; + $self->addbadmessage('The display was already cleared.') if $none_shown; + + ##### View problems selected from the local list + + } elsif ($r->param('view_local_set')) { + + my $set_to_display = $self->{current_library_set}; + if (not defined($set_to_display) or $set_to_display eq SELECT_LOCAL_STRING or $set_to_display eq "Found no directories containing problems") { + $self->addbadmessage('You need to select a set to view.'); + } else { + $set_to_display = '.' if $set_to_display eq MY_PROBLEMS; + $set_to_display = substr($browse_which,7) if $set_to_display eq MAIN_PROBLEMS; + @pg_files = list_pg_files($ce->{courseDirs}->{templates}, + "$set_to_display"); + $use_previous_problems=0; + } + + ##### View problems selected from the a set in this course + + } elsif ($r->param('view_mysets_set')) { + + my $set_to_display = $self->{current_library_set}; + debug("set_to_display is $set_to_display"); + if (not defined($set_to_display) + or $set_to_display eq "Select a Homework Set" + or $set_to_display eq NO_LOCAL_SET_STRING) { + $self->addbadmessage("You need to select a set from this course to view."); + } else { + # DBFIXME don't use ID list, use an iterator + my @problemList = $db->listGlobalProblems($set_to_display); + my $problem; + @pg_files=(); + for $problem (@problemList) { + my $problemRecord = $db->getGlobalProblem($set_to_display, $problem); # checked + die "global $problem for set $set_to_display not found." unless + $problemRecord; + push @pg_files, $problemRecord->source_file; + + } + @pg_files = sortByName(undef,@pg_files); + $use_previous_problems=0; + } + + ##### View from the library database + + } elsif ($r->param('lib_view')) { + + @pg_files=(); + my @dbsearch = WeBWorK::Utils::ListingDB::getSectionListings($r); + my ($result, $tolibpath); + for $result (@dbsearch) { + $tolibpath = "Library/$result->{path}/$result->{filename}"; + + ## Too clunky!!!! + push @pg_files, $tolibpath; + } + $use_previous_problems=0; + + ##### View a set from a set*.def + + } elsif ($r->param('view_setdef_set')) { + + my $set_to_display = $self->{current_library_set}; + debug("set_to_display is $set_to_display"); + if (not defined($set_to_display) + or $set_to_display eq "Select a Set Definition File" + or $set_to_display eq NO_LOCAL_SET_STRING) { + $self->addbadmessage("You need to select a set definition file to view."); + } else { + @pg_files= $self->read_set_def($set_to_display); + } + $use_previous_problems=0; + + ##### Edit the current local homework set + + } elsif ($r->param('edit_local')) { ## Jump to set edit page + + ; # already handled + + + ##### Make a new local homework set + + } elsif ($r->param('new_local_set')) { + if ($r->param('new_set_name') !~ /^[\w .-]*$/) { + $self->addbadmessage("The name ".$r->param('new_set_name')." is not a valid set name. Use only letters, digits, -, _, and ."); + } else { + my $newSetName = $r->param('new_set_name'); + # if we want to munge the input set name, do it here + $newSetName =~ s/\s/_/g; + debug("local_sets was ", $r->param('local_sets')); + $r->param('local_sets',$newSetName); ## use of two parameter param + debug("new value of local_sets is ", $r->param('local_sets')); + my $newSetRecord = $db->getGlobalSet($newSetName); + if (defined($newSetRecord)) { + $self->addbadmessage("The set name $newSetName is already in use. + Pick a different name if you would like to start a new set."); + } else { # Do it! + # DBFIXME use $db->newGlobalSet + $newSetRecord = $db->{set}->{record}->new(); + $newSetRecord->set_id($newSetName); + $newSetRecord->set_header("defaultHeader"); + $newSetRecord->hardcopy_header("defaultHeader"); + $newSetRecord->open_date(time()+60*60*24*7); # in one week + $newSetRecord->due_date(time()+60*60*24*7*2); # in two weeks + $newSetRecord->answer_date(time()+60*60*24*7*3); # in three weeks + eval {$db->addGlobalSet($newSetRecord)}; + if ($@) { + $self->addbadmessage("Problem creating set $newSetName
      $@"); + } else { + $self->addgoodmessage("Set $newSetName has been created."); + my $selfassign = $r->param('selfassign') || ""; + $selfassign = "" if($selfassign =~ /false/i); # deal with javascript false + if($selfassign) { + $self->assignSetToUser($userName, $newSetRecord); + $self->addgoodmessage("Set $newSetName was assigned to $userName."); + } + } + } + } + + ##### Add selected problems to the current local set + + } elsif ($r->param('update')) { + ## first handle problems to be added before we hide them + my($localSet, @selected); + + @pg_files = grep {($_->[1] & ADDED) != 0 } @{$self->{past_problems}}; + @selected = map {$_->[0]} @pg_files; + + my @action_files = grep {$_->[1] > 0 } @{$self->{past_problems}}; + # There are now good reasons to do an update without selecting anything. + #if(scalar(@action_files) == 0) { + # $self->addbadmessage('Update requested, but no problems were marked.'); + #} + + if (scalar(@selected)>0) { # if some are to be added, they need a place to go + $localSet = $r->param('local_sets'); + if (not defined($localSet) or + $localSet eq SELECT_SET_STRING or + $localSet eq NO_LOCAL_SET_STRING) { + $self->addbadmessage('You are trying to add problems to something, + but you did not select a "Target Set" name as a target.'); + } else { + my $newSetRecord = $db->getGlobalSet($localSet); + if (not defined($newSetRecord)) { + $self->addbadmessage("You are trying to add problems to $localSet, + but that set does not seem to exist! I bet you used your \"Back\" button."); + } else { + my $addcount = add_selected($self, $db, $localSet); + if($addcount > 0) { + $self->addgoodmessage("Added $addcount problem".(($addcount>1)?'s':''). + " to $localSet."); + } + } + } + } + ## now handle problems to be hidden + + ## only keep the ones which are not hidden + @pg_files = grep {($_->[1] & HIDDEN) ==0 } @{$self->{past_problems}}; + @past_marks = map {$_->[1]} @pg_files; + @pg_files = map {$_->[0]} @pg_files; + @all_past_list = (@all_past_list[0..($first_shown-1)], + @pg_files, + @all_past_list[($last_shown+1)..(scalar(@all_past_list)-1)]); + $last_shown = $first_shown+$maxShown -1; debug("last_shown 3: ", $last_shown); + $last_shown = (scalar(@all_past_list)-1) if($last_shown>=scalar(@all_past_list)); debug("last_shown 4: ", $last_shown); + + } elsif ($r->param('next_page')) { + $first_shown = $last_shown+1; + $last_shown = $first_shown+$maxShown-1; debug("last_shown 5: ", $last_shown); + $last_shown = (scalar(@all_past_list)-1) if($last_shown>=scalar(@all_past_list)); debug("last_shown 6: ", $last_shown); + @past_marks = (); + } elsif ($r->param('prev_page')) { + $last_shown = $first_shown-1; + $first_shown = $last_shown - $maxShown+1; + + $first_shown = 0 if($first_shown<0); + @past_marks = (); + + } elsif ($r->param('select_all')) { + @past_marks = map {1} @past_marks; + } elsif ($r->param('library_basic')) { + $library_basic = 1; + for my $jj (qw(textchapter textsection textbook)) { + $r->param('library_'.$jj,''); + } + } elsif ($r->param('library_advanced')) { + $library_basic = 2; + } elsif ($r->param('library_reset')) { + for my $jj (qw(chapters sections subjects textbook keywords)) { + $r->param('library_'.$jj,''); + } + } elsif ($r->param('select_none')) { + @past_marks = (); + } else { + ##### No action requested, probably our first time here + } ##### end of the if elsif ... + + + ############# List of local sets + + # DBFIXME sorting in database, please! + my @all_db_sets = $db->listGlobalSets; + @all_db_sets = sortByName(undef, @all_db_sets); + + if ($use_previous_problems) { + @pg_files = @all_past_list; + } else { + $first_shown = 0; + $last_shown = scalar(@pg_files)<$maxShown ? scalar(@pg_files) : $maxShown; + $last_shown--; # to make it an array index + @past_marks = (); + } + ############# Now store data in self for retreival by body + $self->{first_shown} = $first_shown; + $self->{last_shown} = $last_shown; + $self->{browse_which} = $browse_which; + #$self->{problem_seed} = $problem_seed; + $self->{pg_files} = \@pg_files; + $self->{past_marks} = \@past_marks; + $self->{all_db_sets} = \@all_db_sets; + $self->{library_basic} = $library_basic; + debug("past_marks is ", join(" ", @{$self->{past_marks}})); +} + + +sub title { + return "Library Browser"; +} + +# hide view options panel since it distracts from SetMaker's built-in view options +sub options { + return ""; +} + +sub body { + my ($self) = @_; + + my $r = $self->r; + my $ce = $r->ce; # course environment + my $db = $r->db; # database + my $j; # garden variety counter + + my $userName = $r->param('user'); + + my $user = $db->getUser($userName); # checked + die "record for user $userName (real user) does not exist." + unless defined $user; + + ### Check that this is a professor + my $authz = $r->authz; + unless ($authz->hasPermissions($userName, "modify_problem_sets")) { + print "User $userName returned " . + $authz->hasPermissions($user, "modify_problem_sets") . + " for permission"; + return(CGI::div({class=>'ResultsWithError'}, + CGI::em("You are not authorized to access the Instructor tools."))); + } + + my $showHints = $r->param('showHints'); + my $showSolutions = $r->param('showSolutions'); + + ########## Extract information computed in pre_header_initialize + + my $first_shown = $self->{first_shown}; + my $last_shown = $self->{last_shown}; + my $browse_which = $self->{browse_which}; + my $problem_seed = $self->{problem_seed}||1234; + my @pg_files = @{$self->{pg_files}}; + my @all_db_sets = @{$self->{all_db_sets}}; + + my @pg_html; + if ($last_shown >= $first_shown) { + @pg_html = renderProblems( + r=> $r, + user => $user, + problem_list => [@pg_files[$first_shown..$last_shown]], + displayMode => $r->param('mydisplayMode'), + showHints => $showHints, + showSolutions => $showSolutions, + ); + } + + my %isInSet; + my $setName = $r->param("local_sets"); + if ($setName) { + # DBFIXME where clause, iterator + # DBFIXME maybe instead of hashing here, query when checking source files? + # DBFIXME definitely don't need to be making full record objects + # DBFIXME SELECT source_file FROM whatever_problem WHERE set_id=? GROUP BY source_file ORDER BY NULL; + # DBFIXME (and stick result directly into hash) + foreach my $problem ($db->listGlobalProblems($setName)) { + my $problemRecord = $db->getGlobalProblem($setName, $problem); + $isInSet{$problemRecord->source_file} = 1; + } + } + $self->{isInSet} = \%isInSet; + + ########## Top part + print CGI::start_form({-method=>"POST", -action=>$r->uri, -name=>'mainform'}), + $self->hidden_authen_fields, + '
      ', + CGI::start_table({-border=>2}); + $self->make_top_row('all_db_sets'=>\@all_db_sets, + 'browse_which'=> $browse_which); + print CGI::hidden(-name=>'browse_which', -value=>$browse_which,-override=>1), + CGI::hidden(-name=>'problem_seed', -value=>$problem_seed, -override=>1); + for ($j = 0 ; $j < scalar(@pg_files) ; $j++) { + print CGI::hidden(-name=>"all_past_list$j", -value=>$pg_files[$j],-override=>1); + } + + print CGI::hidden(-name=>'first_shown', -value=>$first_shown,-override=>1); + + print CGI::hidden(-name=>'last_shown', -value=>$last_shown, -override=>1); + + + ########## Now print problems + my $jj; + for ($jj=0; $jj{courseDirs}->{templates}/?||; + $self->make_data_row($pg_files[$jj+$first_shown], $pg_html[$jj], $jj+1, $self->{past_marks}->[$jj]); + #$self->make_data_row($pg_files[$jj+$first_shown], $pg_html[$jj], $jj+1, $self->{past_marks}->[$jj+$first_shown]); #MEG + } + + ########## Finish things off + print CGI::end_table(); + print '
      '; + # if($first_shown>0 or (1+$last_shown) 0) { + $prev_button = CGI::submit(-name=>"prev_page", -style=>"width:15ex", + -value=>"Previous page"); + } + if ((1+$last_shown)"next_page", -style=>"width:15ex", + -value=>"Next page"); + } + if (scalar(@pg_files)>0) { + print CGI::p(($first_shown+1)."-".($last_shown+1)." of ".scalar(@pg_files). + " shown.", $prev_button, " ", $next_button, + CGI::submit(-name=>"update", -style=>"width:15ex; font-weight:bold", + -value=>"Update Set")); + } + # } + print CGI::endform(), "\n"; + + return ""; +} + +=head1 AUTHOR + +Written by John Jones, jj (at) asu.edu. + +=cut + +1; diff --git a/lib/WeBWorK/ContentGenerator/Instructor/UserList3.pm b/lib/WeBWorK/ContentGenerator/Instructor/UserList3.pm index f16d906a1..95e088b4d 100644 --- a/lib/WeBWorK/ContentGenerator/Instructor/UserList3.pm +++ b/lib/WeBWorK/ContentGenerator/Instructor/UserList3.pm @@ -59,14 +59,6 @@ use WeBWorK::DB qw(check_user_id); use WeBWorK::Utils qw(readFile readDirectory cryptPassword); use constant HIDE_USERS_THRESHHOLD => 200; -# permissions needed to view a given field -use constant FIELD_PERMS => { - act_as => "become_student", - sets => "assign_problem_sets", -}; - -use constant STATE_PARAMS => [qw(user effectiveUser key visible_users no_visible_users prev_visible_users no_prev_visible_users editMode passwordMode primarySortField secondarySortField ternarySortField labelSortMethod)]; - # template method @@ -191,13 +183,13 @@ sub body { #@allUserIDs = @{ $self->{allUserIDs} }; # do we need this one? # DBFIXME instead of re-listing, why not add added users to $self->{allUserIDs} ? # exclude set-level proctors - @allUserIDs = grep {$_ !~ /^set_id:/} $db->listUsers; # recompute value in case some were added + #@allUserIDs = grep {$_ !~ /^set_id:/} $db->listUsers; # recompute value in case some were added - my @visibleUserIDs = @{ $self->{visibleUserIDs} }; - my @prevVisibleUserIDs = @{ $self->{prevVisibleUserIDs} }; - my @selectedUserIDs = @{ $self->{selectedUserIDs} }; - my $editMode = $self->{editMode}; - my $passwordMode = $self->{passwordMode}; + #my @visibleUserIDs = @{ $self->{visibleUserIDs} }; + #my @prevVisibleUserIDs = @{ $self->{prevVisibleUserIDs} }; + #my @selectedUserIDs = @{ $self->{selectedUserIDs} }; + #my $editMode = $self->{editMode}; + #my $passwordMode = $self->{passwordMode}; my $template = HTML::Template->new(filename => $WeBWorK::Constants::WEBWORK_DIRECTORY . '/htdocs/html-templates/classlist3.html'); print $template->output(); @@ -205,7 +197,7 @@ sub body { ########## print end of form - print CGI::end_form(); + #print CGI::end_form(); print $self->hidden_authen_fields; print CGI::hidden({id=>'hidden_courseID',name=>'courseID',default=>$courseName }); @@ -227,10 +219,10 @@ sub head{ my $ce = $r->ce; my $site_url = $ce->{webworkURLs}->{htdocs}; - print ""; - print " "; - print " "; - ""; + print ""; + print " "; + print " "; + return ""; } # output_JS subroutine @@ -243,22 +235,29 @@ sub output_JS{ my $ce = $r->ce; my $site_url = $ce->{webworkURLs}->{htdocs}; - print CGI::start_script({type=>"text/javascript", src=>"$site_url/js/addOnLoadEvent.js"}), CGI::end_script(); + #print CGI::start_script({type=>"text/javascript", src=>"$site_url/js/addOnLoadEvent.js"}), CGI::end_script(); #print CGI::start_script({type=>"text/javascript", src=>"$site_url/js/show_hide.js"}), CGI::end_script(); - print CGI::start_script({type=>"text/javascript", src=>"$site_url/js/lib/vendor/editablegrid-2.0.1/editablegrid-2.0.1.js"}), CGI::end_script(); - - print CGI::start_script({type=>"text/javascript", src=>"$site_url/js/lib/vendor/jquery-1.7.2.min.js"}), CGI::end_script(); - print CGI::start_script({type=>"text/javascript", src=>"$site_url/js/lib/vendor/json2.js"}), CGI::end_script(); - print CGI::start_script({type=>"text/javascript", src=>"$site_url/js/lib/vendor/underscore.js"}), CGI::end_script(); - print CGI::start_script({type=>"text/javascript", src=>"$site_url/js/lib/vendor/backbone.js"}), CGI::end_script(); - print CGI::start_script({type=>"text/javascript", src=>"$site_url/js/lib/vendor/jquery-ui-for-classlist3/js/jquery-ui-1.8.21.custom.min.js"}), CGI::end_script(); - print CGI::start_script({type=>"text/javascript", src=>"$site_url/js/lib/webwork/WeBWorK.js"}), CGI::end_script(); - print CGI::start_script({type=>"text/javascript", src=>"$site_url/js/lib/webwork/WeBWorK-ui.js"}), CGI::end_script(); - print CGI::start_script({type=>"text/javascript", src=>"$site_url/js/lib/webwork/teacher/teacher.js"}), CGI::end_script(); - print CGI::start_script({type=>"text/javascript", src=>"$site_url/js/lib/webwork/teacher/User.js"}), CGI::end_script(); - print CGI::start_script({type=>"text/javascript", src=>"$site_url/js/lib/webwork/util.js"}), CGI::end_script(); - print CGI::start_script({type=>"text/javascript", src=>"$site_url/js/apps/UserList/userlist.js"}), CGI::end_script(); + #print CGI::start_script({type=>"text/javascript", src=>"$site_url/js/lib/vendor/editablegrid-2.0.1/editablegrid-2.0.1.js"}), CGI::end_script(); + + #print CGI::start_script({type=>"text/javascript", src=>"$site_url/js/lib/vendor/jquery-1.7.2.min.js"}), CGI::end_script(); + #print CGI::start_script({type=>"text/javascript", src=>"$site_url/js/lib/vendor/json2.js"}), CGI::end_script(); + #print CGI::start_script({type=>"text/javascript", src=>"$site_url/js/lib/vendor/underscore.js"}), CGI::end_script(); + #print CGI::start_script({type=>"text/javascript", src=>"$site_url/js/lib/vendor/backbone.js"}), CGI::end_script(); + #print CGI::start_script({type=>"text/javascript", src=>"$site_url/js/lib/vendor/backbone-validation.js"}), CGI::end_script(); + #print CGI::start_script({type=>"text/javascript", src=>"$site_url/js/lib/vendor/FileSaver.js"}), CGI::end_script(); + #print CGI::start_script({type=>"text/javascript", src=>"$site_url/js/lib/vendor/BlobBuilder.js"}), CGI::end_script(); + #print CGI::start_script({type=>"text/javascript", src=>"$site_url/js/lib/vendor/jquery-ui-for-classlist3/js/jquery-ui-1.8.21.custom.min.js"}), CGI::end_script(); + #print CGI::start_script({type=>"text/javascript", src=>"$site_url/js/lib/webwork/WeBWorK.js"}), CGI::end_script(); + #print CGI::start_script({type=>"text/javascript", src=>"$site_url/js/lib/webwork/WeBWorK-ui.js"}), CGI::end_script(); + #print CGI::start_script({type=>"text/javascript", src=>"$site_url/js/lib/webwork/teacher/teacher.js"}), CGI::end_script(); + #print CGI::start_script({type=>"text/javascript", src=>"$site_url/js/lib/webwork/teacher/User.js"}), CGI::end_script(); + #print CGI::start_script({type=>"text/javascript", src=>"$site_url/js/lib/webwork/util.js"}), CGI::end_script(); +# print CGI::start_script({type=>"text/javascript", src=>"$site_url/js/lib/vendor/fs.js"}), CGI::end_script(); +# print CGI::start_script({type=>"text/javascript", src=>"$site_url/js/lib/vendor/labs.min.js"}), CGI::end_script(); + #print CGI::start_script({type=>"text/javascript", src=>"$site_url/js/apps/UserList/userlist.js"}), CGI::end_script(); + print qq!!; + return ""; } diff --git a/lib/WeBWorK/ContentGenerator/Problem.pm b/lib/WeBWorK/ContentGenerator/Problem.pm index 1f5948ba3..fb54ecaa9 100644 --- a/lib/WeBWorK/ContentGenerator/Problem.pm +++ b/lib/WeBWorK/ContentGenerator/Problem.pm @@ -995,6 +995,7 @@ sub body { debug("end answer processing"); # output for templates that only use body instead of calling the body parts individually $self ->output_JS; + $self ->output_tag_info; $self ->output_custom_edit_message; $self ->output_summary; $self ->output_hidden_info; @@ -1443,6 +1444,20 @@ sub output_summary{ return ""; } +# output_tag_info +# Puts the tags in the page + +sub output_tag_info{ + my $self = shift; + my $r = $self->r; + my $authz = $r->authz; + my $user = $r->param('user'); + if ($authz->hasPermissions($user, "modify_tags")) { + print CGI::p(CGI::div("Tags go here")); + } + return ""; +} + # output_custom_edit_message # prints out a custom edit message diff --git a/lib/WeBWorK/ContentGenerator/ProblemSets-1.pm b/lib/WeBWorK/ContentGenerator/ProblemSets-1.pm new file mode 100644 index 000000000..bff29f05e --- /dev/null +++ b/lib/WeBWorK/ContentGenerator/ProblemSets-1.pm @@ -0,0 +1,624 @@ +################################################################################ +# WeBWorK Online Homework Delivery System +# Copyright 2000-2007 The WeBWorK Project, http://openwebwork.sf.net/ +# $CVSHeader: webwork2/lib/WeBWorK/ContentGenerator/ProblemSets.pm,v 1.94 2010/01/31 02:31:04 apizer Exp $ +# +# This program is free software; you can redistribute it and/or modify it under +# the terms of either: (a) the GNU General Public License as published by the +# Free Software Foundation; either version 2, or (at your option) any later +# version, or (b) the "Artistic License" which comes with this package. +# +# This program is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +# FOR A PARTICULAR PURPOSE. See either the GNU General Public License or the +# Artistic License for more details. +################################################################################ + +package WeBWorK::ContentGenerator::ProblemSets; +use base qw(WeBWorK); +use base qw(WeBWorK::ContentGenerator); + +=head1 NAME + +WeBWorK::ContentGenerator::ProblemSets - Display a list of built problem sets. + +=cut + +use strict; +use warnings; +#use CGI qw(-nosticky ); +use WeBWorK::CGI; +use WeBWorK::Debug; +use WeBWorK::Utils qw(readFile sortByName path_is_subdir); +use WeBWorK::Localize; +# what do we consider a "recent" problem set? +use constant RECENT => 2*7*24*60*60 ; # Two-Weeks in seconds + +sub info { + my ($self) = @_; + my $r = $self->r; + my $ce = $r->ce; + my $db = $r->db; + my $urlpath = $r->urlpath; + my $authz = $r->authz; + + my $courseID = $urlpath->arg("courseID"); + my $user = $r->param("user"); + + my $course_info = $ce->{courseFiles}->{course_info}; + + if (defined $course_info and $course_info) { + my $course_info_path = $ce->{courseDirs}->{templates} . "/$course_info"; + + print CGI::start_div({-class=>"info-wrapper"}); + print CGI::start_div({class=>"info-box", id=>"InfoPanel"}); + + # deal with instructor crap + my $editorURL; + if ($authz->hasPermissions($user, "access_instructor_tools")) { + if (defined $r->param("editMode") and $r->param("editMode") eq "temporaryFile") { + $course_info_path = $r->param("sourceFilePath"); + $course_info_path = $ce->{courseDirs}{templates}.'/'.$course_info_path unless $course_info_path =~ m!^/!; + die "sourceFilePath is unsafe!" unless path_is_subdir($course_info_path, $ce->{courseDirs}->{templates}); + $self->addmessage(CGI::div({class=>'temporaryFile'}, $r->maketext("Viewing temporary file: "), $course_info_path)); + } + + my $editorPage = $urlpath->newFromModule("WeBWorK::ContentGenerator::Instructor::PGProblemEditor", $r, courseID => $courseID); + $editorURL = $self->systemLink($editorPage, params => { file_type => "course_info" }); + } + + if ($editorURL) { + print CGI::h2($r->maketext("Course Info"), CGI::a({href=>$editorURL, target=>"WW_Editor"}, $r->maketext("~[edit~]"))); + } else { + print CGI::h2($r->maketext("Course Info")); + } + + if (-f $course_info_path) { #check that it's a plain file + my $text = eval { readFile($course_info_path) }; + if ($@) { + print CGI::div({class=>"ResultsWithError"}, + CGI::p("$@"), + ); + } else { + print $text; + } + } + + print CGI::end_div(); + print CGI::end_div(); + + return ""; + } +} +sub help { # non-standard help, since the file path includes the course name + my $self = shift; + my $args = shift; + my $name = $args->{name}; + $name = lc('course home') unless defined($name); + $name =~ s/\s/_/g; + $self->helpMacro($name); +} +# template method +sub templateName { + return "lbtwo"; +} + +sub initialize { + + + +# get result and send to message + my ($self) = @_; + my $r = $self->r; + my $authz = $r->authz; + my $urlpath = $r->urlpath; + + my $user = $r->param("user"); + my $effectiveUser = $r->param("effectiveUser"); + if ($authz->hasPermissions($user, "access_instructor_tools")) { + # get result and send to message + my $status_message = $r->param("status_message"); + $self->addmessage(CGI::p("$status_message")) if $status_message; + + + } +} + +sub head{ + my $self = shift; + my $r = $self->r; + my $ce = $r->ce; + + my $site_url = $ce->{webworkURLs}->{htdocs}; + print ""; + print " "; + #print " "; + return ""; +} + +sub body { + my ($self) = @_; + my $r = $self->r; + my $ce = $r->ce; + my $db = $r->db; + my $authz = $r->authz; + my $urlpath = $r->urlpath; + + my $user = $r->param("user"); + my $effectiveUser = $r->param("effectiveUser"); + my $sort = $r->param("sort") || "status"; + + my $courseName = $urlpath->arg("courseID"); + + my $hardcopyPage = $urlpath->newFromModule("WeBWorK::ContentGenerator::Hardcopy", $r, courseID => $courseName); + my $actionURL = $self->systemLink($hardcopyPage, authen => 0); # no authen info for form action + +# we have to get sets and versioned sets separately + # DBFIXME don't get ID lists, use WHERE clauses and iterators + my @setIDs = $db->listUserSets($effectiveUser); + my @userSetIDs = map {[$effectiveUser, $_]} @setIDs; + + debug("Begin collecting merged sets"); + my @sets = $db->getMergedSets( @userSetIDs ); + + debug("Begin fixing merged sets"); + + # Database fix (in case of undefined visible values) + # this may take some extra time the first time but should NEVER need to be run twice + # this is only necessary because some people keep holding to ww1.9 which did not have a visible field + # DBFIXME this should be in the database layer (along with other "fixes" of its ilk) + foreach my $set (@sets) { + # make sure visible is set to 0 or 1 + if ( $set and $set->visible ne "0" and $set->visible ne "1") { + my $globalSet = $db->getGlobalSet($set->set_id); + $globalSet->visible("1"); # defaults to visible + $db->putGlobalSet($globalSet); + $set = $db->getMergedSet($effectiveUser, $set->set_id); + } else { + die "set $set not defined" unless $set; + } + } + + foreach my $set (@sets) { + # make sure enable_reduced_scoring is set to 0 or 1 + if ( $set and $set->enable_reduced_scoring ne "0" and $set->enable_reduced_scoring ne "1") { + my $globalSet = $db->getGlobalSet($set->set_id); + $globalSet->enable_reduced_scoring("0"); # defaults to disabled + $db->putGlobalSet($globalSet); + $set = $db->getMergedSet($effectiveUser, $set->set_id); + } else { + die "set $set not defined" unless $set; + } + } + +# gateways/versioned sets require dealing with output data slightly +# differently, so check for those here + debug("Begin set-type check"); + my $existVersions = 0; + my @gwSets = (); + my @nonGWsets = (); + my %gwSetNames = (); # this is necessary because we get a setname + # for all versions of g/w tests + foreach ( @sets ) { + if ( defined( $_->assignment_type() ) && + $_->assignment_type() =~ /gateway/ ) { + $existVersions = 1; + + push( @gwSets, $_ ) if ( ! defined($gwSetNames{$_->set_id}) ); + $gwSetNames{$_->set_id} = 1; + } else { + push( @nonGWsets, $_ ); + } + } +# now get all user set versions that we need + my @vSets = (); +# we need the template sets below, so also make an indexed list of those + my %gwSetsBySetID = (); + foreach my $set ( @gwSets ) { + $gwSetsBySetID{$set->set_id} = $set; + + my @setVer = $db->listSetVersions( $effectiveUser, $set->set_id ); + my @setVerIDs = map { [ $effectiveUser, $set->set_id, $_ ] } @setVer; + push( @vSets, $db->getMergedSetVersions( @setVerIDs ) ); + } + +# set sort method + $sort = "status" unless $sort eq "status" or $sort eq "name"; + +# now set the headers for the table + my $nameHeader = $sort eq "name" + ? CGI::u($r->maketext("Name")) + : CGI::a({href=>$self->systemLink($urlpath, params=>{sort=>"name"})}, $r->maketext("Name")); + my $statusHeader = $sort eq "status" + ? CGI::u($r->maketext("Status")) + : CGI::a({href=>$self->systemLink($urlpath, params=>{sort=>"status"})}, $r->maketext("Status")); +# print the start of the form + + print CGI::start_form(-method=>"POST",-action=>$actionURL), + $self->hidden_authen_fields; + print CGI::hidden({id=>'hidden_courseID',name=>'courseID',default=>$courseName }); + +# and send the start of the table +# UPDATE - ghe3 +# This table now contains a summary and a caption, scope attributes for the column headers, and no longer prints a column for 'Sel.' (due to it having been merged with the second column for accessibility purposes). + print CGI::start_table({ -class=>"problem_set_table span7", -summary=>"This table lists out the available homework sets for this class, along with its current status. Click on the link on the name of the homework sets to take you to the problems in that homework set. Clicking on the links in the table headings will sort the table by the field it corresponds to. You can also select sets for download to PDF or TeX format using the radio buttons or checkboxes next to the problem set names, and then clicking on the 'Download PDF or TeX Hardcopy for Selected Sets' button at the end of the table. There is also a clear button and an Email instructor button at the end of the table."}); + print CGI::caption($r->maketext("Homework Sets")); + if ( ! $existVersions ) { + print CGI::Tr({}, + CGI::th({-scope=>"col"},$nameHeader), + CGI::th({-scope=>"col"},$statusHeader), + ); + } else { + print CGI::Tr( + CGI::th({-scope=>"col"},$nameHeader), + CGI::th({-scope=>"col"},$r->maketext("Test Score")), + CGI::th({-scope=>"col"},$r->maketext("Test Date")), + CGI::th({-scope=>"col"},$statusHeader), + ); + } + + debug("Begin sorting merged sets"); + +# before building final set lists, exclude proctored gateway sets +# for users without permission to view them + my $viewPr = $authz->hasPermissions( $user, "view_proctored_tests" ); + @gwSets = grep {$_->assignment_type !~ /proctored/ || $viewPr} @gwSets; + + if ( $sort eq 'name' ) { + @nonGWsets = sortByName("set_id", @nonGWsets); + @gwSets = sortByName("set_id", @gwSets); + } elsif ( $sort eq 'status' ) { + @nonGWsets = sort byUrgency @nonGWsets; + @gwSets = sort byUrgency @gwSets; + } +# we sort set versions by name + @vSets = sortByName(["set_id", "version_id"], @vSets); + +# put together a complete list of sorted sets to consider + @sets = (@nonGWsets, @gwSets ); + + debug("End preparing merged sets"); + +# we do regular sets and the gateway set templates separately +# from the actual set-versions, to avoid managing a tricky test +# for a version number that may not exist + foreach my $set (@sets) { + die "set $set not defined" unless $set; + + if ($set->visible || $authz->hasPermissions($user, "view_hidden_sets")) { + print $self->setListRow($set, $authz->hasPermissions($user, "view_multiple_sets"), $authz->hasPermissions($user, "view_unopened_sets"),$existVersions,$db); + } + } + foreach my $set (@vSets) { + die "set $set not defined" unless $set; + + if ($set->visible || $authz->hasPermissions($user, "view_hidden_sets")) { + print $self->setListRow($set, $authz->hasPermissions($user, "view_multiple_sets"), $authz->hasPermissions($user, "view_unopened_sets"),$existVersions,$db,1, $gwSetsBySetID{$set->{set_id}}, "ethet" ); # 1 = gateway, versioned set + } + } + + print CGI::end_table(); + my $pl = ($authz->hasPermissions($user, "view_multiple_sets") ? "s" : ""); +# print CGI::p(CGI::submit(-name=>"hardcopy", -label=>$r->maketext("Download Hardcopy for Selected [plural,_1,Set,Sets]",$pl))); + + # UPDATE - ghe3 + # Added reset button to form. + print CGI::start_div({-class=>"problem_set_options span6"}); + print CGI::p(WeBWorK::CGI_labeled_input(-type=>"reset", -input_attr=>{-value=>$r->maketext("Clear")})); + print CGI::p(WeBWorK::CGI_labeled_input(-type=>"submit", -input_attr=>{-name=>"hardcopy", -value=>$r->maketext("Download PDF or TeX Hardcopy for Selected Sets")})); + print CGI::end_div(); + print CGI::endform(); +my $template = HTML::Template->new(filename => $WeBWorK::Constants::WEBWORK_DIRECTORY . '/htdocs/html-templates/problemsetlist3.html'); + print $template->output(); + + print '
      '; + ## feedback form url + #my $feedbackPage = $urlpath->newFromModule("WeBWorK::ContentGenerator::Feedback", $r, courseID => $courseName); + #my $feedbackURL = $self->systemLink($feedbackPage, authen => 0); # no authen info for form action + # + ##print feedback form + #print + # CGI::start_form(-method=>"POST", -action=>$feedbackURL),"\n", + # $self->hidden_authen_fields,"\n", + # CGI::hidden("module", __PACKAGE__),"\n", + # CGI::hidden("set", ''),"\n", + # CGI::hidden("problem", ''),"\n", + # CGI::hidden("displayMode", ''),"\n", + # CGI::hidden("showOldAnswers", ''),"\n", + # CGI::hidden("showCorrectAnswers", ''),"\n", + # CGI::hidden("showHints", ''),"\n", + # CGI::hidden("showSolutions", ''),"\n", + # CGI::p({-align=>"left"}, + # CGI::submit(-name=>"feedbackForm", -label=>"Email instructor") + # ), + # CGI::endform(),"\n"; + + print $self->feedbackMacro( + module => __PACKAGE__, + set => "", + problem => "", + displayMode => "", + showOldAnswers => "", + showCorrectAnswers => "", + showHints => "", + showSolutions => "", + ); + + print CGI::end_div(); + + + + + + return ""; +} + +# UPDATE - ghe3 +# this subroutine now combines the $control and $interactive elements, by using the $interactive element as the $control element's label. + +sub setListRow { + my ($self, $set, $multiSet, $preOpenSets, $existVersions, $db, + $gwtype, $tmplSet) = @_; + my $r = $self->r; + my $ce = $r->ce; + my $authz = $r->authz; + my $user = $r->param("user"); + my $urlpath = $r->urlpath; + $gwtype = 0 if ( ! defined( $gwtype ) ); + $tmplSet = $set if ( ! defined( $tmplSet ) ); + + my $name = $set->set_id; + my $urlname = ( $gwtype == 1 ) ? "$name,v" . $set->version_id : $name; + + my $courseName = $urlpath->arg("courseID"); + + my $problemSetPage; + + if ( ! defined( $set->assignment_type() ) || + $set->assignment_type() !~ /gateway/ ) { + $problemSetPage = $urlpath->newFromModule("WeBWorK::ContentGenerator::ProblemSet", $r, + courseID => $courseName, setID => $urlname); + } elsif( $set->assignment_type() !~ /proctored/ ) { + + $problemSetPage = $urlpath->newFromModule("WeBWorK::ContentGenerator::GatewayQuiz", $r, + courseID => $courseName, setID => $urlname); + } else { + + $problemSetPage = $urlpath->newFromModule("WeBWorK::ContentGenerator::GatewayQuiz", $r, + courseID => $courseName, setID => $urlname); + } + + my $interactiveURL = $self->systemLink($problemSetPage, + params=>{ displayMode => $self->{displayMode}, + showOldAnswers => $self->{will}->{showOldAnswers} + } + ); + + # check to see if this is a template gateway assignment + $gwtype = 2 if ( defined( $set->assignment_type() ) && + $set->assignment_type() =~ /gateway/ && ! $gwtype ); + # and get problemRecords if we're dealing with a versioned set, so that + # we can test status and scores + # FIXME: should we really have to get the merged + # problem_versions here? it looks that way, because + # otherwise we don't inherit things like the problem + # value properly. + my @problemRecords = + $db->getAllProblemVersions($set->user_id(), $set->set_id(), + $set->version_id()) + if ( $gwtype == 1 ); + + # the conditional here should be redundant. ah well. + $interactiveURL =~ s|/quiz_mode/|/proctored_quiz_mode/| if + ( defined( $set->assignment_type() ) && + $set->assignment_type() eq 'proctored_gateway' ); + my $display_name = $name; + $display_name =~ s/_/ /g; +# this is the link to the homework assignment + my $interactive = CGI::a({-href=>$interactiveURL}, "$display_name"); + + my $control = ""; + + my $setIsOpen = 0; + my $status = ''; + if ( $gwtype ) { + if ( $gwtype == 1 ) { + unless (ref($problemRecords[0]) ) {warn "Error: problem not defined in set $display_name"; return()} + if ( $problemRecords[0]->num_correct() + + $problemRecords[0]->num_incorrect() >= + ( ( !($set->attempts_per_version()) ) ? 0 : $set->attempts_per_version() ) ) { + $status = $r->maketext("completed."); + } elsif ( time() > $set->due_date() + + $self->r->ce->{gatewayGracePeriod} ) { + $status = $r->maketext("over time: closed."); + } else { + $status = $r->maketext("open: complete by [_1]", + $self->formatDateTime($set->due_date(),undef,$ce->{studentDateDisplayFormat})); + } + # we let people go back to old tests + $setIsOpen = 1; + + # reset the link to give the test number + my $vnum = $set->version_id; + $interactive = CGI::a({-href=>$interactiveURL}, + $r->maketext("[_1] (test [_2])", $display_name, $vnum)); + } else { + my $t = time(); + if ( $t < $set->open_date() ) { + $status = $r->maketext("will open on [_1]", $self->formatDateTime($set->open_date,undef,$ce->{studentDateDisplayFormat})); + if ( $preOpenSets ) { + # reset the link + $interactive = CGI::a({-href=>$interactiveURL}, + $r->maketext("Take [_1] test", $display_name)); + } else { + $control = ""; + $interactive = $r->maketext("[_1] test", $display_name); + } + } elsif ( $t < $set->due_date() ) { + $status = $r->maketext("now open, due ") . $self->formatDateTime($set->due_date,undef,$ce->{studentDateDisplayFormat}); + $setIsOpen = 1; + $interactive = CGI::a({-href=>$interactiveURL}, + $r->maketext("Take [_1] test", $display_name)); + } else { + $status = $r->maketext("Closed"); + + if ( $authz->hasPermissions( $user, "record_answers_after_due_date" ) ) { + $interactive = CGI::a({-href=>$interactiveURL}, + $r->maketext("Take [_1] test", $display_name)); + } else { + $interactive = $r->maketext("[_1] test", $display_name); + } + } + } + +# old conditional + } elsif (time < $set->open_date) { + $status = $r->maketext("will open on [_1]", $self->formatDateTime($set->open_date,undef,$ce->{studentDateDisplayFormat})); + $control = "" unless $preOpenSets; + $interactive = $name unless $preOpenSets; + } elsif (time < $set->due_date) { + $status = $r->maketext("now open, due ") . $self->formatDateTime($set->due_date,undef,$ce->{studentDateDisplayFormat}); + my $enable_reduced_scoring = $set->enable_reduced_scoring; + my $reducedScoringPeriod = $ce->{pg}->{ansEvalDefaults}->{reducedScoringPeriod}; + if ($reducedScoringPeriod > 0 and $enable_reduced_scoring ) { + my $reducedScoringPeriodSec = $reducedScoringPeriod*60; # $reducedScoringPeriod is in minutes + my $beginReducedScoringPeriod = $self->formatDateTime($set->due_date() - $reducedScoringPeriodSec,undef,$ce->{studentDateDisplayFormat}); +# $status .= '. Reduced Credit starts ' . $beginReducedScoringPeriod . ''; + $status .= CGI::div({-class=>"ResultsAlert"}, $r->maketext("Reduced Credit Starts: [_1]", $beginReducedScoringPeriod)); + + } + $setIsOpen = 1; + } elsif (time < $set->answer_date) { + $status = $r->maketext("closed, answers on [_1]", $self->formatDateTime($set->answer_date,undef,$ce->{studentDateDisplayFormat})); + } elsif ($set->answer_date <= time and time < $set->answer_date +RECENT ) { + $status = $r->maketext("closed, answers recently available"); + } else { + $status = $r->maketext("closed, answers available"); + } + + if ($multiSet) { + if ( $gwtype < 2 ) { + $control = WeBWorK::CGI_labeled_input( + -type=>"checkbox", + -id=>$name . ($gwtype ? ",v" . $set->version_id : ''), + -label_text=>$interactive, + -input_attr=>{ + -name=>"selected_sets", + -value=>$name . ($gwtype ? ",v" . $set->version_id : '') + } + ); + } else { + $control = $interactive; + } + } else { + if ( $gwtype < 2 ) { + my $n = $name . ($gwtype ? ",v" . $set->version_id : ''); + $control = WeBWorK::CGI_labeled_input( + -type=>"radio", + -id=>$n, + -label_text=>$interactive, + -input_attr=>{ + -name=>"selected_sets", + -value=>$n + } + ); + } else { + $control = $interactive; + } + } + + my $visiblityStateClass = ($set->visible) ? "visible" : "hidden"; + + $status = CGI::font({class=>$visiblityStateClass}, $status) if $preOpenSets; + +# check to see if we need to return a score and a date column + if ( ! $existVersions ) { + return CGI::Tr(CGI::td([ + $control, + $status, + ])); + } else { + my ( $startTime, $score ); + + if ( defined( $set->assignment_type() ) && + $set->assignment_type() =~ /gateway/ && $gwtype == 1 ) { + $startTime = localtime($set->version_creation_time() || 0); #fixes error message for undefined creation_time + + if ( $authz->hasPermissions($user, "view_hidden_work") || + $set->hide_score_by_problem eq 'Y' || + $set->hide_score() eq 'N' || + ( $set->hide_score eq 'BeforeAnswerDate' && time > $tmplSet->answer_date() ) ) { + # find score + + # DBFIXME we can do this math in the database, i think + my $possible = 0; + $score = 0; + foreach my $pRec ( @problemRecords ) { + my $pval = $pRec->value() ? $pRec->value() : 1; + if ( defined( $pRec ) && + $score ne 'undef' ) { + $score += $pRec->status()*$pval || 0; + } else { + $score = 'undef'; + } + $possible += $pval; + } + $score = "$score/$possible"; + } else { + $score = "n/a"; + } + } else { + $startTime = ' '; + $score = $startTime; + } + return CGI::Tr(CGI::td([ + $control, + $score, + $startTime, + $status, + ])); + } +} + +sub byname { $a->set_id cmp $b->set_id; } + +sub byUrgency { + my $mytime = time; + my @a_parts = ($a->answer_date + RECENT <= $mytime) ? (4, $a->open_date, $a->due_date, $a->set_id) + : ($a->answer_date <= $mytime and $mytime < $a->answer_date + RECENT) ? (3, $a-> answer_date, $a-> due_date, $a->set_id) + : ($a->due_date <= $mytime and $mytime < $a->answer_date ) ? (2, $a->answer_date, $a->due_date, $a->set_id) + : ($mytime < $a->open_date) ? (1, $a->open_date, $a->due_date, $a->set_id) + : (0, $a->due_date, $a->open_date, $a->set_id); + my @b_parts = ($b->answer_date + RECENT <= $mytime) ? (4, $b->open_date, $b->due_date, $b->set_id) + : ($b->answer_date <= $mytime and $mytime < $b->answer_date + RECENT) ? (3, $b-> answer_date, $b-> due_date, $b->set_id) + : ($b->due_date <= $mytime and $mytime < $b->answer_date ) ? (2, $b->answer_date, $b->due_date, $b->set_id) + : ($mytime < $b->open_date) ? (1, $b->open_date, $b->due_date, $b->set_id) + : (0, $b->due_date, $b->open_date, $b->set_id); + my $returnIt=0; + while (scalar(@a_parts) > 1) { + if ($returnIt = ( (shift @a_parts) <=> (shift @b_parts) ) ) { + return($returnIt); + } + } + return ( $a_parts[0] cmp $b_parts[0] ); +} + +# output_JS subroutine + +# prints out the necessary JS for this page + +sub output_JS{ + my $self = shift; + my $r = $self->r; + my $ce = $r->ce; + + my $site_url = $ce->{webworkURLs}->{htdocs}; + print qq!!; + + + + return ""; +} + + +1; diff --git a/lib/WeBWorK/ContentGenerator/ProblemSets.pm b/lib/WeBWorK/ContentGenerator/ProblemSets.pm index bb48dd3e4..810c0e910 100644 --- a/lib/WeBWorK/ContentGenerator/ProblemSets.pm +++ b/lib/WeBWorK/ContentGenerator/ProblemSets.pm @@ -34,70 +34,11 @@ use WeBWorK::Localize; # what do we consider a "recent" problem set? use constant RECENT => 2*7*24*60*60 ; # Two-Weeks in seconds -sub info { - my ($self) = @_; - my $r = $self->r; - my $ce = $r->ce; - my $db = $r->db; - my $urlpath = $r->urlpath; - my $authz = $r->authz; - - my $courseID = $urlpath->arg("courseID"); - my $user = $r->param("user"); - - my $course_info = $ce->{courseFiles}->{course_info}; - - if (defined $course_info and $course_info) { - my $course_info_path = $ce->{courseDirs}->{templates} . "/$course_info"; - - print CGI::start_div({-class=>"info-wrapper"}); - print CGI::start_div({class=>"info-box", id=>"InfoPanel"}); - - # deal with instructor crap - my $editorURL; - if ($authz->hasPermissions($user, "access_instructor_tools")) { - if (defined $r->param("editMode") and $r->param("editMode") eq "temporaryFile") { - $course_info_path = $r->param("sourceFilePath"); - $course_info_path = $ce->{courseDirs}{templates}.'/'.$course_info_path unless $course_info_path =~ m!^/!; - die "sourceFilePath is unsafe!" unless path_is_subdir($course_info_path, $ce->{courseDirs}->{templates}); - $self->addmessage(CGI::div({class=>'temporaryFile'}, $r->maketext("Viewing temporary file: "), $course_info_path)); - } - - my $editorPage = $urlpath->newFromModule("WeBWorK::ContentGenerator::Instructor::PGProblemEditor", $r, courseID => $courseID); - $editorURL = $self->systemLink($editorPage, params => { file_type => "course_info" }); - } - - if ($editorURL) { - print CGI::h2($r->maketext("Course Info"), CGI::a({href=>$editorURL, target=>"WW_Editor"}, $r->maketext("~[edit~]"))); - } else { - print CGI::h2($r->maketext("Course Info")); - } - - if (-f $course_info_path) { #check that it's a plain file - my $text = eval { readFile($course_info_path) }; - if ($@) { - print CGI::div({class=>"ResultsWithError"}, - CGI::p("$@"), - ); - } else { - print $text; - } - } - - print CGI::end_div(); - print CGI::end_div(); - - return ""; - } -} -sub help { # non-standard help, since the file path includes the course name - my $self = shift; - my $args = shift; - my $name = $args->{name}; - $name = lc('course home') unless defined($name); - $name =~ s/\s/_/g; - $self->helpMacro($name); +# template method +sub templateName { + return "lbtwo"; } + sub initialize { @@ -118,6 +59,19 @@ sub initialize { } } + +sub head{ + my $self = shift; + my $r = $self->r; + my $ce = $r->ce; + + my $site_url = $ce->{webworkURLs}->{htdocs}; + print ""; + print " "; + #print " "; + return ""; +} + sub body { my ($self) = @_; my $r = $self->r; @@ -125,454 +79,38 @@ sub body { my $db = $r->db; my $authz = $r->authz; my $urlpath = $r->urlpath; + my $courseName = $urlpath->arg("courseID"); + my $setID = $urlpath->arg("setID"); + my $user = $r->param('user'); - my $user = $r->param("user"); - my $effectiveUser = $r->param("effectiveUser"); - my $sort = $r->param("sort") || "status"; - - my $courseName = $urlpath->arg("courseID"); - - my $hardcopyPage = $urlpath->newFromModule("WeBWorK::ContentGenerator::Hardcopy", $r, courseID => $courseName); - my $actionURL = $self->systemLink($hardcopyPage, authen => 0); # no authen info for form action - -# we have to get sets and versioned sets separately - # DBFIXME don't get ID lists, use WHERE clauses and iterators - my @setIDs = $db->listUserSets($effectiveUser); - my @userSetIDs = map {[$effectiveUser, $_]} @setIDs; + my $root = $ce->{webworkURLs}->{root}; - debug("Begin collecting merged sets"); - my @sets = $db->getMergedSets( @userSetIDs ); - - debug("Begin fixing merged sets"); - # Database fix (in case of undefined visible values) - # this may take some extra time the first time but should NEVER need to be run twice - # this is only necessary because some people keep holding to ww1.9 which did not have a visible field - # DBFIXME this should be in the database layer (along with other "fixes" of its ilk) - foreach my $set (@sets) { - # make sure visible is set to 0 or 1 - if ( $set and $set->visible ne "0" and $set->visible ne "1") { - my $globalSet = $db->getGlobalSet($set->set_id); - $globalSet->visible("1"); # defaults to visible - $db->putGlobalSet($globalSet); - $set = $db->getMergedSet($effectiveUser, $set->set_id); - } else { - die "set $set not defined" unless $set; - } - } - - foreach my $set (@sets) { - # make sure enable_reduced_scoring is set to 0 or 1 - if ( $set and $set->enable_reduced_scoring ne "0" and $set->enable_reduced_scoring ne "1") { - my $globalSet = $db->getGlobalSet($set->set_id); - $globalSet->enable_reduced_scoring("0"); # defaults to disabled - $db->putGlobalSet($globalSet); - $set = $db->getMergedSet($effectiveUser, $set->set_id); - } else { - die "set $set not defined" unless $set; - } - } - -# gateways/versioned sets require dealing with output data slightly -# differently, so check for those here - debug("Begin set-type check"); - my $existVersions = 0; - my @gwSets = (); - my @nonGWsets = (); - my %gwSetNames = (); # this is necessary because we get a setname - # for all versions of g/w tests - foreach ( @sets ) { - if ( defined( $_->assignment_type() ) && - $_->assignment_type() =~ /gateway/ ) { - $existVersions = 1; - - push( @gwSets, $_ ) if ( ! defined($gwSetNames{$_->set_id}) ); - $gwSetNames{$_->set_id} = 1; - } else { - push( @nonGWsets, $_ ); - } - } -# now get all user set versions that we need - my @vSets = (); -# we need the template sets below, so also make an indexed list of those - my %gwSetsBySetID = (); - foreach my $set ( @gwSets ) { - $gwSetsBySetID{$set->set_id} = $set; - - my @setVer = $db->listSetVersions( $effectiveUser, $set->set_id ); - my @setVerIDs = map { [ $effectiveUser, $set->set_id, $_ ] } @setVer; - push( @vSets, $db->getMergedSetVersions( @setVerIDs ) ); - } - -# set sort method - $sort = "status" unless $sort eq "status" or $sort eq "name"; - -# now set the headers for the table - my $nameHeader = $sort eq "name" - ? CGI::u($r->maketext("Name")) - : CGI::a({href=>$self->systemLink($urlpath, params=>{sort=>"name"})}, $r->maketext("Name")); - my $statusHeader = $sort eq "status" - ? CGI::u($r->maketext("Status")) - : CGI::a({href=>$self->systemLink($urlpath, params=>{sort=>"status"})}, $r->maketext("Status")); -# print the start of the form - - print CGI::start_form(-method=>"POST",-action=>$actionURL), - $self->hidden_authen_fields; - -# and send the start of the table -# UPDATE - ghe3 -# This table now contains a summary and a caption, scope attributes for the column headers, and no longer prints a column for 'Sel.' (due to it having been merged with the second column for accessibility purposes). - print CGI::start_table({ -class=>"problem_set_table", -summary=>"This table lists out the available homework sets for this class, along with its current status. Click on the link on the name of the homework sets to take you to the problems in that homework set. Clicking on the links in the table headings will sort the table by the field it corresponds to. You can also select sets for download to PDF or TeX format using the radio buttons or checkboxes next to the problem set names, and then clicking on the 'Download PDF or TeX Hardcopy for Selected Sets' button at the end of the table. There is also a clear button and an Email instructor button at the end of the table."}); - print CGI::caption($r->maketext("Homework Sets")); - if ( ! $existVersions ) { - print CGI::Tr({}, - CGI::th({-scope=>"col"},$nameHeader), - CGI::th({-scope=>"col"},$statusHeader), - ); - } else { - print CGI::Tr( - CGI::th({-scope=>"col"},$nameHeader), - CGI::th({-scope=>"col"},$r->maketext("Test Score")), - CGI::th({-scope=>"col"},$r->maketext("Test Date")), - CGI::th({-scope=>"col"},$statusHeader), - ); - } - - debug("Begin sorting merged sets"); +my $template = HTML::Template->new(filename => $WeBWorK::Constants::WEBWORK_DIRECTORY . '/htdocs/html-templates/frontPage.html'); + print $template->output(); -# before building final set lists, exclude proctored gateway sets -# for users without permission to view them - my $viewPr = $authz->hasPermissions( $user, "view_proctored_tests" ); - @gwSets = grep {$_->assignment_type !~ /proctored/ || $viewPr} @gwSets; - - if ( $sort eq 'name' ) { - @nonGWsets = sortByName("set_id", @nonGWsets); - @gwSets = sortByName("set_id", @gwSets); - } elsif ( $sort eq 'status' ) { - @nonGWsets = sort byUrgency @nonGWsets; - @gwSets = sort byUrgency @gwSets; - } -# we sort set versions by name - @vSets = sortByName(["set_id", "version_id"], @vSets); + print $self->hidden_authen_fields; + print CGI::hidden({id=>'hidden_courseID',name=>'courseID',default=>$courseName }); -# put together a complete list of sorted sets to consider - @sets = (@nonGWsets, @gwSets ); - - debug("End preparing merged sets"); -# we do regular sets and the gateway set templates separately -# from the actual set-versions, to avoid managing a tricky test -# for a version number that may not exist - foreach my $set (@sets) { - die "set $set not defined" unless $set; - - if ($set->visible || $authz->hasPermissions($user, "view_hidden_sets")) { - print $self->setListRow($set, $authz->hasPermissions($user, "view_multiple_sets"), $authz->hasPermissions($user, "view_unopened_sets"),$existVersions,$db); - } - } - foreach my $set (@vSets) { - die "set $set not defined" unless $set; - - if ($set->visible || $authz->hasPermissions($user, "view_hidden_sets")) { - print $self->setListRow($set, $authz->hasPermissions($user, "view_multiple_sets"), $authz->hasPermissions($user, "view_unopened_sets"),$existVersions,$db,1, $gwSetsBySetID{$set->{set_id}}, "ethet" ); # 1 = gateway, versioned set - } - } - - print CGI::end_table(); - my $pl = ($authz->hasPermissions($user, "view_multiple_sets") ? "s" : ""); -# print CGI::p(CGI::submit(-name=>"hardcopy", -label=>$r->maketext("Download Hardcopy for Selected [plural,_1,Set,Sets]",$pl))); - # UPDATE - ghe3 - # Added reset button to form. - print CGI::start_div({-class=>"problem_set_options"}); - print CGI::p(WeBWorK::CGI_labeled_input(-type=>"reset", -input_attr=>{-value=>$r->maketext("Clear")})); - print CGI::p(WeBWorK::CGI_labeled_input(-type=>"submit", -input_attr=>{-name=>"hardcopy", -value=>$r->maketext("Download PDF or TeX Hardcopy for Selected Sets")})); - print CGI::endform(); - - ## feedback form url - #my $feedbackPage = $urlpath->newFromModule("WeBWorK::ContentGenerator::Feedback", $r, courseID => $courseName); - #my $feedbackURL = $self->systemLink($feedbackPage, authen => 0); # no authen info for form action - # - ##print feedback form - #print - # CGI::start_form(-method=>"POST", -action=>$feedbackURL),"\n", - # $self->hidden_authen_fields,"\n", - # CGI::hidden("module", __PACKAGE__),"\n", - # CGI::hidden("set", ''),"\n", - # CGI::hidden("problem", ''),"\n", - # CGI::hidden("displayMode", ''),"\n", - # CGI::hidden("showOldAnswers", ''),"\n", - # CGI::hidden("showCorrectAnswers", ''),"\n", - # CGI::hidden("showHints", ''),"\n", - # CGI::hidden("showSolutions", ''),"\n", - # CGI::p({-align=>"left"}, - # CGI::submit(-name=>"feedbackForm", -label=>"Email instructor") - # ), - # CGI::endform(),"\n"; - - print $self->feedbackMacro( - module => __PACKAGE__, - set => "", - problem => "", - displayMode => "", - showOldAnswers => "", - showCorrectAnswers => "", - showHints => "", - showSolutions => "", - ); - print CGI::end_div(); - return ""; } -# UPDATE - ghe3 -# this subroutine now combines the $control and $interactive elements, by using the $interactive element as the $control element's label. +# prints out the necessary JS for this page -sub setListRow { - my ($self, $set, $multiSet, $preOpenSets, $existVersions, $db, - $gwtype, $tmplSet) = @_; +sub output_JS{ + my $self = shift; my $r = $self->r; my $ce = $r->ce; - my $authz = $r->authz; - my $user = $r->param("user"); - my $urlpath = $r->urlpath; - $gwtype = 0 if ( ! defined( $gwtype ) ); - $tmplSet = $set if ( ! defined( $tmplSet ) ); - - my $name = $set->set_id; - my $urlname = ( $gwtype == 1 ) ? "$name,v" . $set->version_id : $name; - - my $courseName = $urlpath->arg("courseID"); - - my $problemSetPage; - - if ( ! defined( $set->assignment_type() ) || - $set->assignment_type() !~ /gateway/ ) { - $problemSetPage = $urlpath->newFromModule("WeBWorK::ContentGenerator::ProblemSet", $r, - courseID => $courseName, setID => $urlname); - } elsif( $set->assignment_type() !~ /proctored/ ) { - - $problemSetPage = $urlpath->newFromModule("WeBWorK::ContentGenerator::GatewayQuiz", $r, - courseID => $courseName, setID => $urlname); - } else { - - $problemSetPage = $urlpath->newFromModule("WeBWorK::ContentGenerator::GatewayQuiz", $r, - courseID => $courseName, setID => $urlname); - } - my $interactiveURL = $self->systemLink($problemSetPage, - params=>{ displayMode => $self->{displayMode}, - showOldAnswers => $self->{will}->{showOldAnswers} - } - ); + my $site_url = $ce->{webworkURLs}->{htdocs}; + print qq!!; - # check to see if this is a template gateway assignment - $gwtype = 2 if ( defined( $set->assignment_type() ) && - $set->assignment_type() =~ /gateway/ && ! $gwtype ); - # and get problemRecords if we're dealing with a versioned set, so that - # we can test status and scores - # FIXME: should we really have to get the merged - # problem_versions here? it looks that way, because - # otherwise we don't inherit things like the problem - # value properly. - my @problemRecords = - $db->getAllProblemVersions($set->user_id(), $set->set_id(), - $set->version_id()) - if ( $gwtype == 1 ); - # the conditional here should be redundant. ah well. - $interactiveURL =~ s|/quiz_mode/|/proctored_quiz_mode/| if - ( defined( $set->assignment_type() ) && - $set->assignment_type() eq 'proctored_gateway' ); - my $display_name = $name; - $display_name =~ s/_/ /g; -# this is the link to the homework assignment - my $interactive = CGI::a({-href=>$interactiveURL}, "$display_name"); - my $control = ""; - - my $setIsOpen = 0; - my $status = ''; - if ( $gwtype ) { - if ( $gwtype == 1 ) { - unless (ref($problemRecords[0]) ) {warn "Error: problem not defined in set $display_name"; return()} - if ( $problemRecords[0]->num_correct() + - $problemRecords[0]->num_incorrect() >= - ( ( !($set->attempts_per_version()) ) ? 0 : $set->attempts_per_version() ) ) { - $status = $r->maketext("completed."); - } elsif ( time() > $set->due_date() + - $self->r->ce->{gatewayGracePeriod} ) { - $status = $r->maketext("over time: closed."); - } else { - $status = $r->maketext("open: complete by [_1]", - $self->formatDateTime($set->due_date(),undef,$ce->{studentDateDisplayFormat})); - } - # we let people go back to old tests - $setIsOpen = 1; - - # reset the link to give the test number - my $vnum = $set->version_id; - $interactive = CGI::a({-href=>$interactiveURL}, - $r->maketext("[_1] (test [_2])", $display_name, $vnum)); - } else { - my $t = time(); - if ( $t < $set->open_date() ) { - $status = $r->maketext("will open on [_1]", $self->formatDateTime($set->open_date,undef,$ce->{studentDateDisplayFormat})); - if ( $preOpenSets ) { - # reset the link - $interactive = CGI::a({-href=>$interactiveURL}, - $r->maketext("Take [_1] test", $display_name)); - } else { - $control = ""; - $interactive = $r->maketext("[_1] test", $display_name); - } - } elsif ( $t < $set->due_date() ) { - $status = $r->maketext("now open, due ") . $self->formatDateTime($set->due_date,undef,$ce->{studentDateDisplayFormat}); - $setIsOpen = 1; - $interactive = CGI::a({-href=>$interactiveURL}, - $r->maketext("Take [_1] test", $display_name)); - } else { - $status = $r->maketext("Closed"); - - if ( $authz->hasPermissions( $user, "record_answers_after_due_date" ) ) { - $interactive = CGI::a({-href=>$interactiveURL}, - $r->maketext("Take [_1] test", $display_name)); - } else { - $interactive = $r->maketext("[_1] test", $display_name); - } - } - } - -# old conditional - } elsif (time < $set->open_date) { - $status = $r->maketext("will open on [_1]", $self->formatDateTime($set->open_date,undef,$ce->{studentDateDisplayFormat})); - $control = "" unless $preOpenSets; - $interactive = $name unless $preOpenSets; - } elsif (time < $set->due_date) { - $status = $r->maketext("now open, due ") . $self->formatDateTime($set->due_date,undef,$ce->{studentDateDisplayFormat}); - my $enable_reduced_scoring = $set->enable_reduced_scoring; - my $reducedScoringPeriod = $ce->{pg}->{ansEvalDefaults}->{reducedScoringPeriod}; - if ($reducedScoringPeriod > 0 and $enable_reduced_scoring ) { - my $reducedScoringPeriodSec = $reducedScoringPeriod*60; # $reducedScoringPeriod is in minutes - my $beginReducedScoringPeriod = $self->formatDateTime($set->due_date() - $reducedScoringPeriodSec,undef,$ce->{studentDateDisplayFormat}); -# $status .= '. Reduced Credit starts ' . $beginReducedScoringPeriod . ''; - $status .= CGI::div({-class=>"ResultsAlert"}, $r->maketext("Reduced Credit Starts: [_1]", $beginReducedScoringPeriod)); - - } - $setIsOpen = 1; - } elsif (time < $set->answer_date) { - $status = $r->maketext("closed, answers on [_1]", $self->formatDateTime($set->answer_date,undef,$ce->{studentDateDisplayFormat})); - } elsif ($set->answer_date <= time and time < $set->answer_date +RECENT ) { - $status = $r->maketext("closed, answers recently available"); - } else { - $status = $r->maketext("closed, answers available"); - } - - if ($multiSet) { - if ( $gwtype < 2 ) { - $control = WeBWorK::CGI_labeled_input( - -type=>"checkbox", - -id=>$name . ($gwtype ? ",v" . $set->version_id : ''), - -label_text=>$interactive, - -input_attr=>{ - -name=>"selected_sets", - -value=>$name . ($gwtype ? ",v" . $set->version_id : '') - } - ); - } else { - $control = $interactive; - } - } else { - if ( $gwtype < 2 ) { - my $n = $name . ($gwtype ? ",v" . $set->version_id : ''); - $control = WeBWorK::CGI_labeled_input( - -type=>"radio", - -id=>$n, - -label_text=>$interactive, - -input_attr=>{ - -name=>"selected_sets", - -value=>$n - } - ); - } else { - $control = $interactive; - } - } - - my $visiblityStateClass = ($set->visible) ? "visible" : "hidden"; - - $status = CGI::font({class=>$visiblityStateClass}, $status) if $preOpenSets; - -# check to see if we need to return a score and a date column - if ( ! $existVersions ) { - return CGI::Tr(CGI::td([ - $control, - $status, - ])); - } else { - my ( $startTime, $score ); - - if ( defined( $set->assignment_type() ) && - $set->assignment_type() =~ /gateway/ && $gwtype == 1 ) { - $startTime = localtime($set->version_creation_time() || 0); #fixes error message for undefined creation_time - - if ( $authz->hasPermissions($user, "view_hidden_work") || - $set->hide_score_by_problem eq 'Y' || - $set->hide_score() eq 'N' || - ( $set->hide_score eq 'BeforeAnswerDate' && time > $tmplSet->answer_date() ) ) { - # find score - - # DBFIXME we can do this math in the database, i think - my $possible = 0; - $score = 0; - foreach my $pRec ( @problemRecords ) { - my $pval = $pRec->value() ? $pRec->value() : 1; - if ( defined( $pRec ) && - $score ne 'undef' ) { - $score += $pRec->status()*$pval || 0; - } else { - $score = 'undef'; - } - $possible += $pval; - } - $score = "$score/$possible"; - } else { - $score = "n/a"; - } - } else { - $startTime = ' '; - $score = $startTime; - } - return CGI::Tr(CGI::td([ - $control, - $score, - $startTime, - $status, - ])); - } + return ""; } -sub byname { $a->set_id cmp $b->set_id; } - -sub byUrgency { - my $mytime = time; - my @a_parts = ($a->answer_date + RECENT <= $mytime) ? (4, $a->open_date, $a->due_date, $a->set_id) - : ($a->answer_date <= $mytime and $mytime < $a->answer_date + RECENT) ? (3, $a-> answer_date, $a-> due_date, $a->set_id) - : ($a->due_date <= $mytime and $mytime < $a->answer_date ) ? (2, $a->answer_date, $a->due_date, $a->set_id) - : ($mytime < $a->open_date) ? (1, $a->open_date, $a->due_date, $a->set_id) - : (0, $a->due_date, $a->open_date, $a->set_id); - my @b_parts = ($b->answer_date + RECENT <= $mytime) ? (4, $b->open_date, $b->due_date, $b->set_id) - : ($b->answer_date <= $mytime and $mytime < $b->answer_date + RECENT) ? (3, $b-> answer_date, $b-> due_date, $b->set_id) - : ($b->due_date <= $mytime and $mytime < $b->answer_date ) ? (2, $b->answer_date, $b->due_date, $b->set_id) - : ($mytime < $b->open_date) ? (1, $b->open_date, $b->due_date, $b->set_id) - : (0, $b->due_date, $b->open_date, $b->set_id); - my $returnIt=0; - while (scalar(@a_parts) > 1) { - if ($returnIt = ( (shift @a_parts) <=> (shift @b_parts) ) ) { - return($returnIt); - } - } - return ( $a_parts[0] cmp $b_parts[0] ); -} 1; diff --git a/lib/WeBWorK/ContentGenerator/instructorXMLHandler.pm b/lib/WeBWorK/ContentGenerator/instructorXMLHandler.pm index 329953e5d..af48afa96 100644 --- a/lib/WeBWorK/ContentGenerator/instructorXMLHandler.pm +++ b/lib/WeBWorK/ContentGenerator/instructorXMLHandler.pm @@ -26,7 +26,7 @@ use warnings; package WeBWorK::ContentGenerator::instructorXMLHandler; use base qw(WeBWorK::ContentGenerator); use MIME::Base64 qw( encode_base64 decode_base64); -use JSON; # imports encode_json, decode_json, to_json and from_json. +use WeBWorK::Debug; our $UNIT_TESTS_ON = 0; # should be called DEBUG?? FIXME @@ -38,6 +38,7 @@ our $UNIT_TESTS_ON = 0; # should be called DEBUG?? FIXME use strict; use warnings; use WebworkClient; +use JSON; =head1 Description @@ -173,15 +174,8 @@ sub pre_header_initialize { $xmlrpc_client->{course} = $r->param('courseID'); # print STDERR WebworkClient::pretty_print($r->{paramcache}); - #create input table for the request - #my $input = { - # pw => $XML_PASSWORD, - # set => 'set0', - # library_name => 'Library', - # command => 'all', - #}; - my $input = {#can I just use $->param? it looks like a hash + pw => $r->param('pw') ||undef, session_key => $r->param("session_key") ||undef, userID => $r->param("user") ||undef, @@ -194,6 +188,9 @@ sub pre_header_initialize { command => $r->param("command") ||undef, subcommand => $r->param("subcommand") ||undef, maxdepth => $r->param("maxdepth") || 0, + problemSeed => $r->param("problemSeed") || 0, + displayMode => $r->param("displayMode") || undef, + noprepostambles => $r->param("noprepostambles") || undef, library_subjects => $r->param("library_subjects") ||undef, library_chapters => $r->param("library_chapters") ||undef, library_sections => $r->param("library_sections") ||undef, @@ -204,18 +201,47 @@ sub pre_header_initialize { source => '', #course stuff - first_name => $r->param('first_name') || undef, - last_name => $r->param('last_name') || undef, - student_id => $r->param('student_id') || undef, - id => $r->param('user_id') || undef, - email_address => $r->param('email_address') || undef, - permission => $r->param('permission') || 0, # valid values from %userRoles in defaults.config - status => $r->param('status') || undef,#'Enrolled, audit, proctor, drop - section => $r->param('section') || undef, - recitation => $r->param('recitation') || undef, - comment => $r->param('comment') || undef, - new_password => $r->param('new_password') || undef, - userpassword => $r->param('userpassword') || undef, # defaults to studentid if empty + first_name => $r->param('first_name') || undef, + last_name => $r->param('last_name') || undef, + student_id => $r->param('student_id') || undef, + id => $r->param('user_id') || undef, + email_address => $r->param('email_address') || undef, + permission => $r->param('permission') || 0, # valid values from %userRoles in defaults.config + status => $r->param('status') || undef,#'Enrolled, audit, proctor, drop + section => $r->param('section') || undef, + recitation => $r->param('recitation') || undef, + comment => $r->param('comment') || undef, + new_password => $r->param('new_password') || undef, + userpassword => $r->param('userpassword') || undef, # defaults to studentid if empty + set_props => $r->param('set_props') || undef, + set_id => $r->param('set_id') || undef, + due_date => $r->param('due_date') || undef, + set_header => $r->param('set_header') || undef, + hardcopy_header => $r->param('hardcopy_header') || undef, + open_date => $r->param('open_date') || undef, + due_date => $r->param('due_date') || undef, + answer_date => $r->param('answer_date') || undef, + visible => $r->param('visible') || undef, + enable_reduced_scoring => $r->param('enable_reduced_scoring') || undef, + assignment_type => $r->param('assignment_type') || undef, + attempts_per_version => $r->param('attempts_per_version') || undef, + time_interval => $r->param('time_interval') || undef, + versions_per_interval => $r->param('versions_per_interval') || undef, + version_time_limit => $r->param('version_time_limit') || undef, + version_creation_time => $r->param('version_creation_time') || undef, + problem_randorder => $r->param('problem_randorder') || undef, + version_last_attempt_time => $r->param('version_last_attempt_time') || undef, + problems_per_page => $r->param('problems_per_page') || undef, + hide_score => $r->param('hide_score') || undef, + hide_score_by_problem => $r->param('hide_score_by_problem') || undef, + hide_work => $r->param('hide_work') || undef, + time_limit_cap => $r->param('time_limit_cap') || undef, + restrict_ip => $r->param('restrict_ip') || undef, + relax_restrict_ip => $r->param('relax_restrict_ip') || undef, + restricted_login_proctor => $r->param('restricted_login_proctor') || undef, + var => $r->param('var') || undef, + value => $r->param('value') || undef, + users => $r->param('users') || undef }; if ($UNIT_TESTS_ON) { print STDERR "instructorXMLHandler.pm ".__LINE__." values obtained from form parameters\n\t", @@ -232,6 +258,8 @@ sub pre_header_initialize { my $std_input = standard_input(); $input = {%$std_input, %$input}; + # Fix the environment display mode + $input->{envir}->{displayMode} = $input->{displayMode} if($input->{displayMode}); ########################################## # FIXME hack to get fileName or filePath param("set") contains the path @@ -414,62 +442,63 @@ sub pretty_print_json { #$out .= " type = UNDEFINED; "; } return $out."" unless defined($rh); - - if ( ref($rh) =~/HASH/ or "$rh" =~/HASH/ ) { - $indent++; - foreach my $key (sort keys %{$rh}) { - $out .= " ".'"'.$key.'" : '. pretty_print_json( $rh->{$key}) . ","; - } - $indent--; - #get rid of the last comma - chop $out; - $out = "{\n$out\n"."}\n"; - - } elsif (ref($rh) =~ /ARRAY/ or "$rh" =~/ARRAY/) { - foreach my $elem ( @{$rh} ) { - $out .= pretty_print_json($elem).","; - - } - #get rid of the last comma - chop $out; - $out = "[\n$out\n"."]\n"; - #$out = '"'.$out.'"'; - } elsif ( ref($rh) =~ /SCALAR/ ) { - $out .= "scalar reference ". ${$rh}; - } elsif ( ref($rh) =~/Base64/ ) { - $out .= "base64 reference " .$$rh; - - } elsif ($rh =~ /^[+-]?\d+$/){ - $out .= $rh; - } else { - $out .= '"'.$rh.'"'; - } - - return $out.""; - + + if ( ref($rh) =~/HASH/ or "$rh" =~/HASH/ ) { + $indent++; + foreach my $key (sort keys %{$rh}) { + $out .= " ".'"'.$key.'" : '. pretty_print_json( $rh->{$key}) . ","; + } + $indent--; + #get rid of the last comma + chop $out; + $out = "{\n$out\n"."}\n"; + + } elsif (ref($rh) =~ /ARRAY/ or "$rh" =~/ARRAY/) { + foreach my $elem ( @{$rh} ) { + $out .= pretty_print_json($elem).","; + + } + #get rid of the last comma + chop $out; + $out = "[\n$out\n"."]\n"; + #$out = '"'.$out.'"'; + } elsif ( ref($rh) =~ /SCALAR/ ) { + $out .= "scalar reference ". ${$rh}; + } elsif ( ref($rh) =~/Base64/ ) { + $out .= "base64 reference " .$$rh; + + } elsif ($rh =~ /^[+-]?\d+$/){ + $out .= $rh; + } else { + $out .= '"'.$rh.'"'; + } + + return $out.""; } sub content { ########################### # Return content of rendered problem to the browser that requested it ########################### - my $self = shift; - #for handling errors...i'm to lazy to make it work right now - if($self->{output}->{problem_out}){ - print $self->{output}->{problem_out}->{text}; - } else { - my $out = {server_response => $self->{output}->{text}}; - #print '{"server_response":"'.$self->{output}->{text}.'",'; - if($self->{output}->{ra_out}){ - $out->{result_data} = $self->{output}->{ra_out}; - #print '"result_data":'.pretty_print_json($self->{output}->{ra_out}).'}'; - } else { - $out->{result_data} = ""; - } - print JSON->new->utf8->space_after->encode($out); - - } - #print "".pretty_print_json($self->{output}->{ra_out}); + my $self = shift; + + #for handling errors...i'm to lazy to make it work right now + if($self->{output}->{problem_out}){ + print $self->{output}->{problem_out}->{text}; + } else { + print '{"server_response":"'.$self->{output}->{text}.'",'; + if($self->{output}->{ra_out}){ + # print '"result_data":'.pretty_print_json($self->{output}->{ra_out}).'}'; + if (ref($self->{output}->{ra_out})) { + print '"result_data": ' . to_json($self->{output}->{ra_out}) .'}'; + } else { + print '"result_data": "' . $self->{output}->{ra_out} . '"}'; + } + } else { + print '"result_data":""}'; + } + } + #print "".pretty_print_json($self->{output}->{ra_out}); } diff --git a/lib/WeBWorK/URLPath.pm b/lib/WeBWorK/URLPath.pm index 7ab984ed6..e91787c61 100644 --- a/lib/WeBWorK/URLPath.pm +++ b/lib/WeBWorK/URLPath.pm @@ -86,6 +86,12 @@ PLEASE FOR THE LOVE OF GOD UPDATE THIS IF YOU CHANGE THE HEIRARCHY BELOW!!! instructor_users_assigned_to_set2 /$courseID/instructor/sets2/$setID/users/ #not created yet instructor_problem_grader /$courseID/instructor/grader/$setID/$problemID + + + instructor_set_list3 /$courseID/instructor/sets3/ + instructor_set_detail3 /$courseID/instructor/sets3/$setID/ #not created yet + instructor_users_assigned_to_set3 /$courseID/instructor/sets3/$setID/users/ #not created yet + instructor_add_users /$courseID/instructor/add_users/ instructor_set_assigner /$courseID/instructor/assigner/ @@ -94,6 +100,7 @@ PLEASE FOR THE LOVE OF GOD UPDATE THIS IF YOU CHANGE THE HEIRARCHY BELOW!!! instructor_set_maker /$courseID/instructor/setmaker/ instructor_set_maker2 /$courseID/instructor/setmaker2/ instructor_set_maker3 /$courseID/instructor/setmaker3/ + instructor_set_maker_no_js /$courseID/instructor/setmakernojs/ instructor_get_target_set_problems /$courseID/instructor/GetTargetSetProblems/ instructor_get_library_set_problems /$courseID/instructor/GetLibrarySetProblems/ instructor_config /$courseID/instructor/config/ @@ -322,11 +329,11 @@ our %pathTypes = ( instructor_tools => { name => 'Instructor Tools', parent => 'set_list', - kids => [ qw/instructor_user_list instructor_user_list2 instructor_user_list3 instructor_set_list instructor_set_list2 + kids => [ qw/instructor_user_list instructor_user_list2 instructor_user_list3 instructor_set_list instructor_set_list2 instructor_set_list3 instructor_add_users instructor_achievement_list instructor_set_assigner instructor_file_manager instructor_problem_editor instructor_problem_editor2 instructor_problem_editor3 - instructor_set_maker instructor_set_maker2 instructor_set_maker3 + instructor_set_maker instructor_set_maker_no_js instructor_set_maker2 instructor_set_maker3 instructor_get_target_set_problems instructor_get_library_set_problems instructor_compare instructor_config instructor_scoring instructor_scoring_download instructor_mail_merge @@ -408,6 +415,18 @@ our %pathTypes = ( produce => 'sets2/', display => 'WeBWorK::ContentGenerator::Instructor::ProblemSetList2', }, + + instructor_set_list3 => { + name => 'Homework Manager', + parent => 'instructor_tools', + kids => [ qw/instructor_set_detail/ ], + match => qr|^sets3/|, + capture => [ qw// ], + produce => 'sets3/', + display => 'WeBWorK::ContentGenerator::Instructor::ProblemSetList3', + }, + + instructor_set_detail => { name => 'Set Detail for set $setID', parent => 'instructor_set_list', @@ -486,6 +505,15 @@ our %pathTypes = ( produce => 'setmaker/', display => 'WeBWorK::ContentGenerator::Instructor::SetMaker', }, + instructor_set_maker_no_js => { + name => 'Library Browser no js', + parent => 'instructor_tools', + kids => [ qw// ], + match => qr|^setmakernojs/|, + capture => [ qw// ], + produce => 'setmakernojs/', + display => 'WeBWorK::ContentGenerator::Instructor::SetMakernojs', + }, instructor_set_maker2 => { name => 'Library Browser 2', parent => 'instructor_tools', diff --git a/lib/WeBWorK/Utils/ListingDB.pm b/lib/WeBWorK/Utils/ListingDB.pm index 68a3f740b..75d742e54 100644 --- a/lib/WeBWorK/Utils/ListingDB.pm +++ b/lib/WeBWorK/Utils/ListingDB.pm @@ -61,6 +61,8 @@ my %OPLtables = ( chapter => 'OPL_chapter', section => 'OPL_section', problem => 'OPL_problem', + morelt => 'OPL_morelt', + morelt_pgfile => 'OPL_morelt_pgfile', pgfile_problem => 'OPL_pgfile_problem', ); @@ -78,6 +80,8 @@ my %NPLtables = ( chapter => 'NPL-chapter', section => 'NPL-section', problem => 'NPL-problem', + morelt => 'NPL-morelt', + morelt_pgfile => 'NPL-morelt-pgfile', pgfile_problem => 'NPL-pgfile-problem', ); @@ -309,9 +313,9 @@ Here, we search on all known fields out of r sub getDBListings { my $r = shift; - my %tables = getTables($r->ce); my $amcounter = shift; my $ce = $r->ce; + my %tables = getTables($ce); my $subj = $r->param('library_subjects') || ""; my $chap = $r->param('library_chapters') || ""; my $sec = $r->param('library_sections') || ""; @@ -385,10 +389,10 @@ sub getDBListings { } my @results=(); for my $pgid (@pg_ids) { - $query = "SELECT path, filename FROM `$tables{pgfile}` pgf, `$tables{path}` p + $query = "SELECT path, filename, morelt_id, pgfile_id FROM `$tables{pgfile}` pgf, `$tables{path}` p WHERE p.path_id = pgf.path_id AND pgf.pgfile_id=\"$pgid\""; my $row = $dbh->selectrow_arrayref($query); - push @results, {'path' => $row->[0], 'filename' => $row->[1] }; + push @results, {'path' => $row->[0], 'filename' => $row->[1], 'morelt' => $row->[2], 'pgid'=> $row->[3] }; } return @results; @@ -399,6 +403,16 @@ sub countDBListings { return (getDBListings($r,1)); } +sub getMLTleader { + my $r = shift; + my $mltid = shift; + my %tables = getTables($r->ce); + my $dbh = getDB($r->ce); + my $query = "SELECT leader FROM `$tables{morelt}` WHERE morelt_id=\"$mltid\""; + my $row = $dbh->selectrow_arrayref($query); + return $row->[0]; +} + ############################################################################## # input expected: keywords,,chapter,,section,
      ,path,,filename,,author,,instituition,,history, # diff --git a/lib/WeBWorK/Utils/Tags.pm b/lib/WeBWorK/Utils/Tags.pm new file mode 100644 index 000000000..d8ba4ee21 --- /dev/null +++ b/lib/WeBWorK/Utils/Tags.pm @@ -0,0 +1,382 @@ +################################################################################ +# WeBWorK Online Homework Delivery System +# Copyright � 2000-1307 The WeBWorK Project, http://openwebwork.sf.net/ +# +# This program is free software; you can redistribute it and/or modify it under +# the terms of either: (a) the GNU General Public License as published by the +# Free Software Foundation; either version 2, or (at your option) any later +# version, or (b) the "Artistic License" which comes with this package. +# +# This program is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +# FOR A PARTICULAR PURPOSE. See either the GNU General Public License or the +# Artistic License for more details. +################################################################################ + + +########################### +# Utils::Tags +# +# Provides basic handling of OPL tags +########################### + +package WeBWorK::Utils::Tags; + +use base qw(Exporter); +use strict; +use warnings; +use Carp; +use IO::File; + +our @EXPORT = (); +our @EXPORT_OK = qw( +# list_set_versions +); + +use constant BASIC => qw( DBsubject DBchapter DBsection Date Institution Author MLT); +use constant NUMBERED => qw( TitleText AuthorText EditionText Section Problem ); + +my $basics = join('|', BASIC); +my $numbered = join('|', NUMBERED); +my $re = qr/#\s*\b($basics)\s*\(\s*'?(.*?)'?\s*\)/; + +sub istagline { + my $line = shift; + return 1 if($line =~ /$re/); + return 1 if($line =~ /#\s*\bKEYWORDS?\s*\(\s*'?(.*?)'?\s*\)/); + return 1 if($line =~ /#\s*\b$numbered\d+\s*\(\s*'?(.*?)'?\s*\)/); + return 0; +} + +sub kwtidy { + my $s = shift; + $s =~ s/\W//g; + $s =~ s/_//g; + $s = lc($s); + return($s); +} + +sub keywordcleaner { + my $string = shift; + my @spl1 = split /,/, $string; +# my @spl2 = map(kwtidy($_), @spl1); + return(@spl1); +} + +sub mergekeywords { + my $self=shift; + my $kws=shift; + if(not defined($self->{keywords})) { + $self->{keywords} = $kws; + return; + } + if(not defined($kws)) { + return; + } + my @kw = @{$self->{keywords}}; + for my $j (@{$kws}) { + my $old = 0; + for my $k (@kw) { + if(lc($k) eq lc($j)) { + $old = 1; + last; + } + } + push @kw, $j unless ($old); + } + $self->{keywords} = \@kw; +} + +# Note on texts, we store them in an array, but the index is one less than on +# the corresponding tag. +sub isnewtext { + my $self = shift; + my $ti = shift; + for my $j (@{$self->{textinfo}}) { + my $ok = 1; + for my $k ('TitleText', 'EditionText', 'AuthorText') { + if($ti->{$k} ne $j->{$k}) { + $ok = 0; + last; + } + } + return 0 if($ok); + } + return 1; +} + +sub mergetexts { + my $self=shift; + my $newti=shift; + for my $ti (@$newti) { + if($self->isnewtext($ti)) { + my @tia = @{$self->{textinfo}}; + push @tia, $ti; + $self->{textinfo} = \@tia; + } + } +} + +# Set a tag with a value +sub settag { + my $self = shift; + my $tagname = shift; + my $newval = shift; + + if(defined($newval) and $newval and ($newval ne $self->{$tagname})) { + $self->{modified}=1; + $self->{$tagname} = $newval; + } +} + +sub printtextinfo { + my $textref = shift; + print "{"; + for my $k (keys %{$textref}){ + print "$k -> ".$textref->{$k}.", "; + } + print "}\n"; +} + +sub printalltextinfo { + my $self = shift; + for my $j (@{$self->{textinfo}}) { + printtextinfo $j; + } +} + +sub maybenewtext { + my $textno = shift; + my $textinfo = shift ; + return $textinfo if defined($textinfo->[$textno-1]); + # So, not defined yet + $textinfo->[$textno-1] = { TitleText => '', AuthorText =>'', EditionText =>'', + section => '', chapter =>'', problems => [] }; + return $textinfo; +} + +sub gettextnos { + my $textinfo = shift; + return grep { defined $textinfo->[$_] } (0..(scalar(@{$textinfo})-1)); +} + +sub tidytextinfo { + my $self = shift; + my @textnos = gettextnos($self->{textinfo}); + my $ntxts = scalar(@textnos); + if($ntxts and ($ntxts-1) != $textnos[-1]) { + $self->{modified} = 1; + my @tmptexts = grep{ defined $_ } @{$self->{textinfo}}; + $self->{textinfo} = \@tmptexts; + } +} + + +# name is a path + +sub new { + my $class = shift; + my $name = shift; + my $self = {}; + + $self->{isplaceholder} = 0; + $self->{modified} = 0; + my $lasttag =0; + + my ($text, $edition, $textauthor, $textsection, $textproblem); + my $textno; + my $textinfo=[]; + my @textproblems = (-1); + + open(IN,"$name") or die "can not open $name: $!"; + if ($name !~ /pg$/) { + print "Not a pg file"; + $self->{file}= undef; + bless($self, $class); + return $self; + } + my $lineno = 0; + $self->{file} = $name; + + # Initialize some values + for my $tagname ( BASIC ) { + $self->{$tagname} = ''; + } + $self->{keywords} = []; + + + while () { + $lineno++; + SWITCH: { + if (/#\s*\bKEYWORDS\((.*)\)/i) { + my @keyword = keywordcleaner($1); + $self->{keywords} = [@keyword]; + $lasttag = $lineno; + last SWITCH; + } + if (/$re/) { # Checks all other un-numbered tags + my $tmp1 = $1; + my $tmp = $2; + $tmp =~ s/'/\'/g; + $self->{$tmp1} = $tmp; + $lasttag = $lineno; + last SWITCH; + } + + if (/#\s*\bTitleText(\d+)\(\s*'?(.*?)'?\s*\)/) { + $textno = $1; + $text = $2; + $text =~ s/'/\'/g; + if ($text =~ /\S/) { + $textinfo = maybenewtext($textno, $textinfo); + $textinfo->[$textno-1]->{TitleText} = $text; + } + $lasttag = $lineno; + last SWITCH; + } + if (/#\s*\bEditionText(\d+)\(\s*'?(.*?)'?\s*\)/) { + $textno = $1; + $edition = $2; + $edition =~ s/'/\'/g; + if ($edition =~ /\S/) { + $textinfo = maybenewtext($textno, $textinfo); + $textinfo->[$textno-1]->{EditionText} = $edition; + } + $lasttag = $lineno; + last SWITCH; + } + if (/#\s*\bAuthorText(\d+)\(\s*'?(.*?)'?\s*\)/) { + $textno = $1; + $textauthor = $2; + $textauthor =~ s/'/\'/g; + if ($textauthor =~ /\S/) { + $textinfo = maybenewtext($textno, $textinfo); + $textinfo->[$textno-1]->{AuthorText} = $textauthor; + } + $lasttag = $lineno; + last SWITCH; + } + if (/#\s*\bSection(\d+)\(\s*'?(.*?)'?\s*\)/) { + $textno = $1; + $textsection = $2; + $textsection =~ s/'/\'/g; + if ($textsection =~ /\S/) { + $textinfo = maybenewtext($textno, $textinfo); + if ($textsection =~ /(\d*?)\.(\d*)/) { + $textinfo->[$textno-1]->{chapter} = $1; + $textinfo->[$textno-1]->{section} = $2; + } else { + $textinfo->[$textno-1]->{chapter} = $textsection; + $textinfo->[$textno-1]->{section} = -1; + } + } + $lasttag = $lineno; + last SWITCH; + } + if (/#\s*\bProblem(\d+)\(\s*(.*?)\s*\)/) { + $textno = $1; + $textproblem = $2; + $textproblem =~ s/\D/ /g; + @textproblems = split /\s+/, $textproblem; + @textproblems = grep { $_ =~ /\S/ } @textproblems; + if (scalar(@textproblems) or defined($textinfo->[$textno])) { + @textproblems = (-1) unless(scalar(@textproblems)); + $textinfo = maybenewtext($textno, $textinfo); + $textinfo->[$textno-1]->{problems} = \@textproblems; + } + $lasttag = $lineno; + last SWITCH; + } + }} #end of SWITCH and while + $self->{textinfo} = $textinfo; + + if (defined($self->{DBchapter}) and $self->{DBchapter} eq 'ZZZ-Inserted Text') { + $self->{isplaceholder} = 1; + } + + + $self->{lasttagline}=$lasttag; + bless($self, $class); + $self->tidytextinfo(); +# $self->printalltextinfo(); + return $self; +} + +sub isplaceholder { + my $self = shift; + return $self->{isplaceholder}; +} + +# Try to copy in the contents of another Tag object. +# Return 1 if ok, 0 if not compatible +sub copyin { + my $self = shift; + my $ob = shift; +# for my $j (qw( DBsubject DBchapter DBsection )) { +# if($self->{$j} =~ /\S/ and $ob->{$j} =~ /\S/ and $self->{$j} ne $ob->{$j}) { +# # print "Incompatible $j: ".$self->{$j}." vs ".$ob->{$j} ."\n"; +# return 0; +# } +# } + # Just copy in all basic tags + for my $j (qw( DBsubject DBchapter DBsection Date Institution Author )) { + $self->settag($j, $ob->{$j}) if(defined($ob->{$j})); + } + # Now copy in keywords + $self->mergekeywords($ob->{keywords}); + # Finally, textbooks + $self->mergetexts($ob->{textinfo}); + return 1; +} + +sub dumptags { + my $self = shift; + my $fh = shift; + + for my $tagname ( BASIC ) { + print $fh "## $tagname('".$self->{$tagname}."')\n" if($self->{$tagname}); + } + my @textinfo = @{$self->{textinfo}}; + my $textno = 0; + for my $ti (@textinfo) { + $textno++; + for my $nw ( NUMBERED ) { + if($nw eq 'Problem') { + print $fh "## $nw$textno('".join(' ', @{$ti->{problems}})."')\n"; + next; + } + if($nw eq 'Section') { + if($ti->{section} eq '-1') { + print $fh "## Section$textno('".$ti->{chapter}."')\n"; + } else { + print $fh "## Section$textno('".$ti->{chapter}.".".$ti->{section}."')\n"; + } + next; + } + print $fh "## $nw$textno('".$ti->{$nw}."')\n"; + } + } + print $fh "## KEYWORDS(".join(',', @{$self->{keywords}}).")\n" if(scalar(@{$self->{keywords}})); +} + +# Write the file +sub write { + my $self=shift; + # First read it into an array + open(IN,$self->{file}) or die "can not open $self->{file}: $!"; + my @lines = ; + close(IN); + my $fh = IO::File->new(">".$self->{file}) or die "can not open $self->{file}: $!"; + my ($line, $lineno)=('', 0); + while($line = shift @lines) { + $lineno++; + $self->dumptags($fh) if($lineno == $self->{lasttagline}); + next if istagline($line); + print $fh $line; + } + + $fh->close(); +} + +1; + diff --git a/lib/WeBWorK/Utils/Tasks.pm b/lib/WeBWorK/Utils/Tasks.pm index cba582f34..501118c12 100644 --- a/lib/WeBWorK/Utils/Tasks.pm +++ b/lib/WeBWorK/Utils/Tasks.pm @@ -253,6 +253,7 @@ sub renderProblems { # special case for display mode 'None' -- we don't have to do anything # FIXME i think this should be handled in SetMaker.pm + # SetMaker is not the only user of 'None' if ($displayMode eq 'None') { return map { {body_text=>''} } @problem_list; } @@ -270,6 +271,7 @@ sub renderProblems { local $ce->{pg}{specialPGEnvironmentVars}{problemPreamble} = {TeX=>'',HTML=>''}; local $ce->{pg}{specialPGEnvironmentVars}{problemPostamble} = {TeX=>'',HTML=>''}; my $problem = fake_problem($db, 'problem_seed'=>$problem_seed); + $problem->{value} = 1; my $formFields = { WeBWorK::Form->new_from_paramable($r)->Vars }; my @output; diff --git a/lib/WebworkWebservice.pm b/lib/WebworkWebservice.pm index 2a92f71a7..da8b8f544 100644 --- a/lib/WebworkWebservice.pm +++ b/lib/WebworkWebservice.pm @@ -4,6 +4,7 @@ use WebworkSOAP; use WebworkSOAP::WSDL; + BEGIN { $main::VERSION = "2.4.9"; use Cwd; @@ -51,6 +52,7 @@ use strict; use warnings; use WeBWorK::Localize; + our $UNIT_TESTS_ON = 0; # error formatting @@ -115,6 +117,8 @@ use WebworkWebservice::CourseActions; package WebworkXMLRPC; use base qw(WebworkWebservice); use WeBWorK::Utils qw(runtime_use writeTimingLogEntry); +use WeBWorK::Debug; +use JSON; sub format_hash_ref { my $hash = shift; @@ -345,12 +349,36 @@ sub listLibraries { # returns a list of libraries for the default course #warn "incoming request to listLibraries: class is ",ref($self) if $UNIT_TESTS_ON ; return $self->do( WebworkWebservice::LibraryActions::listLibraries($self, $in) ); } + +sub getProblemDirectories { + my $class = shift; + my $in = shift; + my $self = $class->initiate_session($in); + return $self->do(WebworkWebservice::LibraryActions::getProblemDirectories($self,$in)); +} + +sub buildBrowseTree { + my $class = shift; + my $in = shift; + my $self = $class->initiate_session($in); + return $self->do(WebworkWebservice::LibraryActions::buildBrowseTree($self,$in)); +} + +sub assignSetToUsers { + my $class = shift; + my $in = shift; + my $self = $class->initiate_session($in); + return $self->do(WebworkWebservice::SetActions::assignSetToUsers($self,$in)); +} + + sub listSets { my $class = shift; my $in = shift; my $self = $class->initiate_session($in); return $self->do(WebworkWebservice::SetActions::listLocalSets($self)); } + sub listSetProblems { my $class = shift; my $in = shift; @@ -365,6 +393,13 @@ sub createNewSet{ return $self->do(WebworkWebservice::SetActions::createNewSet($self, $in)); } +sub deleteProblemSet{ + my $class = shift; + my $in = shift; + my $self = $class->initiate_session($in); + return $self->do(WebworkWebservice::SetActions::deleteProblemSet($self, $in)); +} + sub reorderProblems{ my $class = shift; my $in = shift; @@ -546,6 +581,49 @@ sub sendEmail{ } +sub getSets { + my $class = shift; + my $in = shift; + my $self = $class->initiate_session($in); + return $self->do(WebworkWebservice::SetActions::getSets($self, $in)); +} + +sub getSet { + my $class = shift; + my $in = shift; + my $self = $class->initiate_session($in); + return $self->do(WebworkWebservice::SetActions::getSet($self, $in)); +} + +sub updateSetProperties{ + my $class = shift; + my $in = shift; + my $self = $class->initiate_session($in); + return $self->do(WebworkWebservice::SetActions::updateSetProperties($self, $in)); +} + +sub listSetUsers { + my $class = shift; + my $in = shift; + my $self = $class->initiate_session($in); + return $self->do(WebworkWebservice::SetActions::listSetUsers($self,$in)); +} + + +sub getCourseSettings { + my $class = shift; + my $in = shift; + my $self = $class->initiate_session($in); + return $self->do(WebworkWebservice::CourseActions::getCourseSettings($self,$in)); +} + +sub updateSetting { + my $class = shift; + my $in = shift; + my $self = $class->initiate_session($in); + return $self->do(WebworkWebservice::CourseActions::updateSetting($self,$in)); +} + # -- SOAP::Lite -- guide.soaplite.com -- Copyright (C) 2001 Paul Kulchenko -- # test responses diff --git a/lib/WebworkWebservice/CourseActions.pm b/lib/WebworkWebservice/CourseActions.pm index 5f508d970..29fc2dcee 100644 --- a/lib/WebworkWebservice/CourseActions.pm +++ b/lib/WebworkWebservice/CourseActions.pm @@ -11,7 +11,7 @@ use WebworkWebservice; use base qw(WebworkWebservice); use WeBWorK::DB; use WeBWorK::DB::Utils qw(initializeUserProblem); -use WeBWorK::Utils qw(runtime_use cryptPassword); +use WeBWorK::Utils qw(runtime_use cryptPassword formatDateTime parseDateTime); use WeBWorK::Utils::CourseManagement qw(addCourse); use WeBWorK::Debug; use WeBWorK::ContentGenerator::Instructor::SendMail; @@ -106,6 +106,7 @@ sub listUsers { my $out = {}; my $db = $self->{db}; my $ce = $self->{ce}; + # make sure course actions are enabled #if (!$ce->{webservices}{enableCourseActions}) { @@ -156,9 +157,6 @@ sub addUser { $out->{text} = encode_base64(""); my $db = $self->{db}; my $ce = $self->{ce}; - debug("Webservices add user request."); - debug("Last Name:" . $params->{'last_name'}); - debug("First Name:" . $params->{'first_name'}); # make sure course actions are enabled #if (!$ce->{webservices}{enableCourseActions}) { @@ -321,10 +319,6 @@ sub deleteUser { # return $out #} - debug($params->{'id'}); - debug($params->{'user'}); - debug(($params->{'id'} eq $params->{'user'} )); - if ($params->{'id'} eq $params->{'user'} ) { $out->{status} = "failure"; @@ -465,8 +459,6 @@ sub changeUserPassword { $self->{passwordMode} = 0; $out->{text} = encode_base64("New passwords saved"); $out->{ra_out}= "password_change: success"; - debug($out->{text}); - debug($out->{ra_out}); return $out; } @@ -539,6 +531,148 @@ sub assignVisibleSets { return 0; } + + +sub getConfigValues { + my $ce = shift; + my $ConfigValues = $ce->{ConfigValues}; + + foreach my $oneConfig (@$ConfigValues) { + foreach my $hash (@$oneConfig) { + if (ref($hash) eq "HASH"){ + my $str = '$ce->' . $hash->{hashVar}; + $hash->{value} = eval($str); + } else { + debug($hash); + } + } + } + + # get the list of theme folders in the theme directory and remove . and .. + my $themeDir = $ce->{webworkDirs}{themes}; + opendir(my $dh, $themeDir) || die "can't opendir $themeDir: $!"; + my $themes =[grep {!/^\.{1,2}$/} sort readdir($dh)]; + + # insert the anonymous array of theme folder names into ConfigValues + my $modifyThemes = sub { my $item=shift; if (ref($item)=~/HASH/ and $item->{var} eq 'defaultTheme' ) { $item->{values} =$themes } }; + + foreach my $oneConfig (@$ConfigValues) { + foreach my $hash (@$oneConfig) { + &$modifyThemes($hash); + } + } + + $ConfigValues; +} + +sub getCourseSettings { + my ($self, $params) = @_; + my $ce = $self->ce; # course environment + my $db = $self->db; # database + my $ConfigValues = getConfigValues($ce); + + #debug(eval("$siteDefaults{timezone}")); + +## until I figure out how to get the default timezone from the $ConfigValues object, this is hard coded. + + my $tz = DateTime::TimeZone->new( name => $ce->{siteDefaults}->{timezone}); + my $dt = DateTime->now(); + + my @tzabbr = ("tz_abbr", $tz->short_name_for_datetime( $dt )); + + + debug($tz->short_name_for_datetime($dt)); + + push(@$ConfigValues, \@tzabbr); + + my $out = {}; + $out->{ra_out} = $ConfigValues; + $out->{text} = encode_base64("Successfully found the course settings"); + return $out; + +} + +sub updateSetting { + my ($self, $params) = @_; + my $ce = $self->ce; # course environment + my $db = $self->db; # database + + my $setVar = $params->{var}; + my $setValue = $params->{value}; + debug("in updateSetting"); + debug("var: " . $setVar); + debug("value: " . $setValue); + + my $filename = $ce->{courseDirs}->{root} . "/simple.conf"; + debug("Write to file: " . $filename); + + my $fileoutput = "#!perl +# This file is automatically generated by WeBWorK's web-based +# configuration module. Do not make changes directly to this +# file. It will be overwritten the next time configuration +# changes are saved.\n\n"; + + + # read in the file + + open(DAT, $filename) || die("Could not open file!"); + my @raw_data=; + close(DAT); + + + + + my $var; + my $line; + my $value; + my $varFound = 0; + + foreach $line (@raw_data) + { + chomp $line; + if ($line =~ /^\$/) { + my @tmp = split(/\$/,$line); + ($var,$value) = split(/\s+=\s+/,$tmp[1]); + if ($var eq $setVar){ + $fileoutput .= "\$" . $var . " = " . $setValue . "\n"; + $varFound = 1; + } else { + $fileoutput .= "\$" . $var . " = " . $value . "\n"; + } + } + } + + if (! $varFound) { + $fileoutput .= "\$" . $setVar . " = " . $setValue . ";\n"; + } + + debug ($fileoutput); + + + my $writeFileErrors; + eval { + local *OUTPUTFILE; + if( open OUTPUTFILE, ">", $filename) { + print OUTPUTFILE $fileoutput; + close OUTPUTFILE; + } else { + $writeFileErrors = "I could not open $fileoutput". + "We will not be able to make configuration changes unless the permissions are set so that the web server can write to this file."; + } + }; # any errors are caught in the next block + + $writeFileErrors = $@ if $@; + + debug("errors: ". $writeFileErrors); + + + my $out = {}; + $out->{ra_out} = ""; + $out->{text} = encode_base64("Successfully updated the course settings"); + return $out; +} + + ## pstaabp: This is currently not working. We need to look into a nice robust way to send email. It looks like the current ## way that WW sends mail is a bit archaic. The MIME::Lite looks fairly straightforward, but we may need to look into smtp settings a ## bit more. diff --git a/lib/WebworkWebservice/LibraryActions.pm b/lib/WebworkWebservice/LibraryActions.pm index be2b7875e..8fe1738e0 100644 --- a/lib/WebworkWebservice/LibraryActions.pm +++ b/lib/WebworkWebservice/LibraryActions.pm @@ -15,13 +15,15 @@ package WebworkWebservice::LibraryActions; use WebworkWebservice; use WeBWorK::Utils::ListingDB; use base qw(WebworkWebservice); +use WeBWorK::Debug; +use JSON; use strict; use sigtrap; use Carp; use WWSafe; #use Apache; -use WeBWorK::Utils; +use WeBWorK::Utils qw(readDirectory sortByName); use WeBWorK::CourseEnvironment; use WeBWorK::PG::Translator; use WeBWorK::PG::IO; @@ -38,6 +40,19 @@ our $HOST_NAME = $WebworkWebservice::HOST_NAME; our $PASSWORD = "we-don't-need-no-stinking-passowrd"; +use constant MY_PROBLEMS => ' My Problems '; +use constant MAIN_PROBLEMS => ' Unclassified Problems '; + +my %problib; ## This is configured in defaults.config + +# list of directories to ignore while search through the libraries. + +my %ignoredir = ( + '.' => 1, '..' => 1, 'Library' => 1, 'CVS' => 1, 'tmpEdit' => 1, + 'headers' => 1, 'macros' => 1, 'email' => 1, '.svn' => 1, +); + + #our $ce = WeBWorK::CourseEnvironment->new($WW_DIRECTORY, "", "", $COURSENAME); # warn "library ce \n ", WebworkWebservice::pretty_print_rh($ce); # warn "LibraryActions is ready"; @@ -142,6 +157,8 @@ sub listLib { my $dirPath = $self->{ce}->{courseDirs}{templates}."/".$rh->{library_name}; my $maxdepth= $rh->{maxdepth}; my $dirPath2 = $dirPath . ( ($rh->{dirPath}) ? '/'.$rh->{dirPath} : '' ) ; + + my @tare = $dirPath2=~m|/|g; my $tare = @tare; # counts number of "/" in dirPath prefix my @outListLib; @@ -176,6 +193,7 @@ sub listLib { }; my $command = $rh->{command}; + #warn "the command being executed is ' $command '"; $command = 'all' unless defined($command); @@ -223,6 +241,8 @@ sub listLib { $command eq 'files' && do { @outListLib=(); #my $separator = ($dirPath =~m|/$|) ?'' : '/'; #my $dirPath2 = $dirPath . $separator . $rh->{dirPath}; + + debug($dirPath2); if ( -e $dirPath2) { find($wanted, $dirPath2); @outListLib = sort @outListLib; @@ -241,65 +261,173 @@ sub listLib { } sub searchLib { #API for searching the NPL database + my $self = shift; my $rh = shift; my $out = {}; my $ce = $self->{ce}; - my $subcommand = $rh->{subcommand}; - 'getDBTextbooks' eq $subcommand && do { - $self->{library_subjects} = $rh->{library_subjects}; - $self->{library_chapters} = $rh->{library_chapters}; - $self->{library_sections} = $rh->{library_sections}; - $self->{library_textchapter} = $rh->{library_textchapter}; - my @textbooks = WeBWorK::Utils::ListingDB::getDBTextbooks($self); - $out->{ra_out} = \@textbooks; - return($out); - }; - 'getAllDBsubjects' eq $subcommand && do { - my @subjects = WeBWorK::Utils::ListingDB::getAllDBsubjects($self); - $out->{ra_out} = \@subjects; - $out->{text} = encode_base64("Subjects loaded."); - return($out); - }; - 'getAllDBchapters' eq $subcommand && do { - $self->{library_subjects} = $rh->{library_subjects}; - my @chaps = WeBWorK::Utils::ListingDB::getAllDBchapters($self); - $out->{ra_out} = \@chaps; - $out->{text} = encode_base64("Chapters loaded."); + my $subcommand = $rh->{command}; + + 'getDBTextbooks' eq $subcommand && do { + $self->{library_subjects} = $rh->{library_subjects}; + $self->{library_chapters} = $rh->{library_chapters}; + $self->{library_sections} = $rh->{library_sections}; + $self->{library_textchapter} = $rh->{library_textchapter}; + my @textbooks = WeBWorK::Utils::ListingDB::getDBTextbooks($self); + $out->{ra_out} = \@textbooks; + return($out); + }; + 'getAllDBsubjects' eq $subcommand && do { + my @subjects = WeBWorK::Utils::ListingDB::getAllDBsubjects($self); + $out->{ra_out} = \@subjects; + $out->{text} = encode_base64("Subjects loaded."); + return($out); + }; + 'getAllDBchapters' eq $subcommand && do { + $self->{library_subjects} = $rh->{library_subjects}; + my @chaps = WeBWorK::Utils::ListingDB::getAllDBchapters($self); + $out->{ra_out} = \@chaps; + $out->{text} = encode_base64("Chapters loaded."); - return($out); - }; - 'getDBListings' eq $subcommand && do { - my $templateDir = $self->{ce}->{courseDirs}->{templates}; - $self->{library_subjects} = $rh->{library_subjects}; - $self->{library_chapters} = $rh->{library_chapters}; - $self->{library_sections} = $rh->{library_sections}; - $self->{library_keywords} = $rh->{library_keywords}; - $self->{library_textbook} = $rh->{library_textbook}; - $self->{library_textchapter} = $rh->{library_textchapter}; - $self->{library_textsection} = $rh->{library_textsection}; - my @listings = WeBWorK::Utils::ListingDB::getDBListings($self); - my @output = map {$templateDir."/Library/".$_->{path}."/".$_->{filename}} @listings; - #change the hard coding!!!....just saying - $out->{ra_out} = \@output; - return($out); - }; - 'getSectionListings' eq $subcommand && do { - $self->{library_subjects} = $rh->{library_subjects}; - $self->{library_chapters} = $rh->{library_chapters}; - $self->{library_sections} = $rh->{library_sections}; + return($out); + }; + 'getDBListings' eq $subcommand && do { + + my $templateDir = $self->{ce}->{courseDirs}->{templates}; + $self->{library_subjects} = $rh->{library_subjects}; + $self->{library_chapters} = $rh->{library_chapters}; + $self->{library_sections} = $rh->{library_sections}; + $self->{library_keywords} = $rh->{library_keywords}; + $self->{library_textbook} = $rh->{library_textbook}; + $self->{library_textchapter} = $rh->{library_textchapter}; + $self->{library_textsection} = $rh->{library_textsection}; + debug(to_json($rh)); + my @listings = WeBWorK::Utils::ListingDB::getDBListings($self); + my @output = map {$templateDir."/Library/".$_->{path}."/".$_->{filename}} @listings; + #change the hard coding!!!....just saying + $out->{ra_out} = \@output; + return($out); + }; + 'getSectionListings' eq $subcommand && do { + $self->{library_subjects} = $rh->{library_subjects}; + $self->{library_chapters} = $rh->{library_chapters}; + $self->{library_sections} = $rh->{library_sections}; - my @section_listings = WeBWorK::Utils::ListingDB::getAllDBsections($self); - $out->{ra_out} = \@section_listings; - $out->{text} = encode_base64("Sections loaded."); + my @section_listings = WeBWorK::Utils::ListingDB::getAllDBsections($self); + $out->{ra_out} = \@section_listings; + $out->{text} = encode_base64("Sections loaded."); - return($out); - }; - # else + return($out); + }; + + 'countDBListings' eq $subcommand && do { + $self->{library_subjects} = $rh->{library_subjects}; + $self->{library_chapters} = $rh->{library_chapters}; + $self->{library_sections} = $rh->{library_sections}; + $self->{library_keywords} = $rh->{library_keywords}; + $self->{library_textbook} = $rh->{library_textbook}; + $self->{library_textchapter} = $rh->{library_textchapter}; + $self->{library_textsection} = $rh->{library_textsection}; + my $count = WeBWorK::Utils::ListingDB::countDBListings($self); + $out->{text} = encode_base64("Count done."); + $out->{ra_out} = [$count]; + return($out); + }; + + #else (no match ) $out->{error}="Unrecognized command $subcommand"; return( $out ); } +sub get_library_sets { + my $top = shift; my $dir = shift; + # ignore directories that give us an error + my @lis = eval { readDirectory($dir) }; + if ($@) { + warn $@; + return (0); + } + return (0) if grep /^=library-ignore$/, @lis; + + my @pgfiles = grep { m/\.pg$/ and (not m/(Header|-text)\.pg$/) and -f "$dir/$_"} @lis; + my $pgcount = scalar(@pgfiles); + my $pgname = $dir; $pgname =~ s!.*/!!; $pgname .= '.pg'; + my $combineUp = ($pgcount == 1 && $pgname eq $pgfiles[0] && !(grep /^=library-no-combine$/, @lis)); + + my @pgdirs; + my @dirs = grep {!$ignoredir{$_} and -d "$dir/$_"} @lis; + if ($top == 1) {@dirs = grep {!$problib{$_}} @dirs} + foreach my $subdir (@dirs) { + my @results = get_library_sets(0, "$dir/$subdir"); + $pgcount += shift @results; push(@pgdirs,@results); + } + + return ($pgcount, @pgdirs) if $top || $combineUp || grep /^=library-combine-up$/, @lis; + return (0,@pgdirs,$dir); +} + + +sub getProblemDirectories { + + my $self = shift; + my $rh = shift; + my $out = {}; + my $ce = $self->{ce}; + + my %libraries = %{$self->{ce}->{courseFiles}->{problibs}}; + + my $lib = "Library"; + my $source = $ce->{courseDirs}{templates}; + my $main = MY_PROBLEMS; my $isTop = 1; + if ($lib) {$source .= "/$lib"; $main = MAIN_PROBLEMS; $isTop = 2} + + my @all_problem_directories = get_library_sets($isTop, $source); + my $includetop = shift @all_problem_directories; + my $j; + for ($j=0; $j{courseDirs}->{templates}/?||; + } + @all_problem_directories = sortByName(undef, @all_problem_directories); + unshift @all_problem_directories, $main if($includetop); + + $out->{ra_out} = \@all_problem_directories; + $out->{text} = encode_base64("Problem Directories loaded."); + + return($out); +} + +## +# This subroutines outputs the entire library based on Subjects, chapters and sections. +# +# The output is an array in the form "Subject/Chapter/Section" +## + +sub buildBrowseTree { + my $self = shift; + my $rh = shift; + my $out = {}; + my $ce = $self->{ce}; + my @tree = (); + my @subjects = WeBWorK::Utils::ListingDB::getAllDBsubjects($self); + foreach my $sub (@subjects) { + $self->{library_subjects} = $sub; + push(@tree,"Subjects/" . $sub); + my @chapters = WeBWorK::Utils::ListingDB::getAllDBchapters($self); + foreach my $chap (@chapters){ + $self->{library_chapters} = $chap; + push(@tree, "Subjects/" .$sub . "/" . $chap); + my @sections = WeBWorK::Utils::ListingDB::getAllDBsections($self); + foreach my $sect (@sections){ + push(@tree, "Subjects/" .$sub . "/" . $chap . "/" . $sect); + } + } + } + $out->{ra_out} = \@tree; + $out->{text} = encode_base64("Subjects, Chapters and Sections loaded."); + return($out); +} + + sub pretty_print_rh { my $rh = shift; diff --git a/lib/WebworkWebservice/RenderProblem.pm b/lib/WebworkWebservice/RenderProblem.pm index 057f02356..a1be5ed19 100644 --- a/lib/WebworkWebservice/RenderProblem.pm +++ b/lib/WebworkWebservice/RenderProblem.pm @@ -272,6 +272,7 @@ sub renderProblem { my $setName = (defined($rh->{envir}->{setNumber}) ) ? $rh->{envir}->{setNumber} : ''; my $problemNumber = (defined($rh->{envir}->{probNum}) ) ? $rh->{envir}->{probNum} : 1 ; my $problemSeed = (defined($rh->{envir}->{problemSeed})) ? $rh->{envir}->{problemSeed} : 1 ; + $problemSeed = $rh->{problemSeed} || $problemSeed; my $psvn = (defined($rh->{envir}->{psvn}) ) ? $rh->{envir}->{psvn} : 1234 ; my $problemStatus = $rh->{problem_state}->{recorded_score}|| 0 ; my $problemValue = (defined($rh->{envir}->{problemValue})) ? $rh->{envir}->{problemValue} : 1 ; @@ -346,7 +347,7 @@ sub renderProblem { print STDERR "RenderProblem.pm: source file is ", $problemRecord->source_file,"\n"; print STDERR "RenderProblem.pm: problem source is included in the request \n" if defined($rh->{source}); } - #warn "problem Record is $problemRecord"; + # warn "problem Record is $problemRecord"; # now we're sure we have valid UserSet and UserProblem objects # yay! @@ -369,7 +370,9 @@ sub renderProblem { my $formFields = $rh->{envir}->{inputs_ref}; my $key = $rh->{envir}->{key} || ''; - + + local $ce->{pg}{specialPGEnvironmentVars}{problemPreamble} = {TeX=>'',HTML=>''} if($rh->{noprepostambles}); + local $ce->{pg}{specialPGEnvironmentVars}{problemPostamble} = {TeX=>'',HTML=>''} if($rh->{noprepostambles}); #check definitions #warn "setRecord is ", WebworkWebservice::pretty_print_rh($setRecord); diff --git a/lib/WebworkWebservice/SetActions.pm b/lib/WebworkWebservice/SetActions.pm index 1363ceff8..df471ee73 100644 --- a/lib/WebworkWebservice/SetActions.pm +++ b/lib/WebworkWebservice/SetActions.pm @@ -13,7 +13,7 @@ package WebworkWebservice::SetActions; use WebworkWebservice; use base qw(WebworkWebservice); -use WeBWorK::Utils qw(readDirectory max sortByName); +use WeBWorK::Utils qw(readDirectory max sortByName formatDateTime parseDateTime); use WeBWorK::Utils::Tasks qw(renderProblems); use strict; @@ -22,6 +22,8 @@ use Carp; use WWSafe; #use Apache; use WeBWorK::Utils; +use WeBWorK::Debug; +use JSON; use WeBWorK::CourseEnvironment; use WeBWorK::PG::Translator; use WeBWorK::DB::Utils qw(initializeUserProblem); @@ -43,47 +45,151 @@ our $ce = WeBWorK::CourseEnvironment->new({webwork_dir=>$WW_DIRECTORY, our $UNIT_TESTS_ON =1; sub listLocalSets{ + debug("in listLocalSets"); my $self = shift; my $db = $self->{db}; my @found_sets; @found_sets = $db->listGlobalSets; my $out = {}; $out->{ra_out} = \@found_sets; - $out->{text} = encode_base64("Sets for course: ".$self->{courseName}); + $out->{text} = encode_base64("Loaded sets for course: ".$self->{courseName}); return $out; } sub listLocalSetProblems{ - my $self = shift; - my $in = shift; + my ($self, $params) = @_; + my $db = $self->{db}; my @found_problems; - my $selectedSet = $in->{set}; - warn "Finding problems for set ", $in->{set} if $UNIT_TESTS_ON; + my $setName = $params->{set_id}; + # If there is a command, it means give relative paths + my $relativePaths = $params->{command}; + + debug("Loading problems for " . $setName); + my $templateDir = $self->{ce}->{courseDirs}->{templates}; - @found_problems = $db->listGlobalProblems($selectedSet); - my $problem; + $templateDir = '' if $relativePaths; + @found_problems = $db->listGlobalProblems($setName); + my @pg_files=(); - for $problem (@found_problems) { - my $problemRecord = $db->getGlobalProblem($selectedSet, $problem); # checked - die "global $problem for set $selectedSet not found." unless + for my $problem (@found_problems) { + my $problemRecord = $db->getGlobalProblem($setName, $problem); # checked + die "global $problem for set $setName not found." unless $problemRecord; push @pg_files, $templateDir."/".$problemRecord->source_file; } - #@pg_files = sortByName(undef,@pg_files); my $out = {}; $out->{ra_out} = \@pg_files; - $out->{text} = encode_base64("Sets for course: ".$self->{courseName}); + $out->{text} = encode_base64("Loaded Problems for set: " . $setName); return $out; } +# This returns all problem sets of a course. + +sub getSets{ + my $self = shift; + my $db = $self->{db}; + my @found_sets; + @found_sets = $db->listGlobalSets; + + my @all_sets = $db->getGlobalSets(@found_sets); + + # fix the timeDate + foreach my $set (@all_sets){ + $set->{due_date} = formatDateTime($set->{due_date},'local'); + $set->{open_date} = formatDateTime($set->{open_date},'local'); + $set->{answer_date} = formatDateTime($set->{answer_date},'local'); + } + + + my $out = {}; + $out->{ra_out} = \@all_sets; + $out->{text} = encode_base64("Sets for course: ".$self->{courseName}); + return $out; +} + + +# This returns a single problem set with name stored in set_id + +sub getSet { + my ($self, $params) = @_; + my $db = $self->{db}; + my $setName = $params->{set_id}; + my $set = $db->getGlobalSet($setName); + + # change the date/times to user readable strings. + + $set->{due_date} = formatDateTime($set->{due_date},'local'); + $set->{open_date} = formatDateTime($set->{open_date},'local'); + $set->{answer_date} = formatDateTime($set->{answer_date},'local'); + + my $out = {}; + $out->{ra_out} = $set; + $out->{text} = encode_base64("Sets for course: ".$self->{courseName}); + return $out; + } + +sub updateSetProperties { + my ($self, $params) = @_; + my $db = $self->{db}; + + #note some of the parameters are coming in as yes or no and need to be converted to 1 or 0. + + my $set = $db->getGlobalSet($params->{set_id}); + $set->set_header($params->{set_header}); + $set->hardcopy_header($params->{hardcopy_header}); + $set->open_date(parseDateTime($params->{open_date},"local")); + $set->due_date(parseDateTime($params->{due_date},"local")); + $set->answer_date(parseDateTime($params->{answer_date},"local")); + $set->visible(($params->{visible} eq "yes")?1:0); + $set->enable_reduced_scoring(($params->{enable_reduced_scoring} eq "yes")?1:0); + $set->assignment_type($params->{assignment_type}); + $set->attempts_per_version($params->{attempts_per_version}); + $set->time_interval($params->{time_interval}); + $set->versions_per_interval($params->{versions_per_interval}); + $set->version_time_limit($params->{version_time_limit}); + $set->version_creation_time($params->{version_creation_time}); + $set->problem_randorder($params->{problem_randorder}); + $set->version_last_attempt_time($params->{version_last_attempt_time}); + $set->problems_per_page($params->{problems_per_page}); + $set->hide_score($params->{hide_score}); + $set->hide_score_by_problem($params->{hide_score_by_problem}); + $set->hide_work($params->{hide_work}); + $set->time_limit_cap($params->{time_limit_cap}); + $set->restrict_ip($params->{restrict_ip}); + $set->relax_restrict_ip($params->{relax_restrict_ip}); + $set->restricted_login_proctor($params->{restricted_login_proctor}); + + $db->putGlobalSet($set); + + my $out = {}; + $out->{ra_out} = $set; + $out->{text} = encode_base64("Successfully updated set " . $params->{set_id}); + return $out; +} + +sub listSetUsers { + my ($self,$params) = @_; + my $db = $self->{db}; + + my $out = {}; + my @users = $db->listSetUsers($params->{set_id}); + $out->{ra_out} = \@users; + $out->{text} = encode_base64("Successfully found the number of users for " . $params->{set_id}); + return $out; + +} + sub createNewSet{ my $self = shift; my $in = shift; my $db = $self->{db}; my $out; + + + if ($in->{new_set_name} !~ /^[\w .-]*$/) { $out->{text} = "need a different name";#not sure the best way to handle and error } else { @@ -95,7 +201,8 @@ sub createNewSet{ #debug("new value of local_sets is ", $r->param('local_sets')); my $newSetRecord = $db->getGlobalSet($newSetName); if (defined($newSetRecord)) { - $out->{text} = encode_base64("Failed to create set, you may need to try another name."); + $out->{out}=encode_base64("Failed to create set, you may need to try another name."), + $out->{ra_out} = {'success' => 'false'}; } else { # Do it! # DBFIXME use $db->newGlobalSet $newSetRecord = $db->{set}->{record}->new(); @@ -123,65 +230,53 @@ sub createNewSet{ } } - -sub reorderProblems { - my $self = shift; - my $in = shift; +sub assignSetToUsers { + my ($self,$params) = @_; my $db = $self->{db}; - my $setID = $in->{set}; - my $problemListString = $in->{probList}; - my @problemList = split(/,/, $problemListString); - my $topdir = $self->{ce}->{courseDirs}{templates}; - #my (@problemIDList) = @_; - #my ($prob1, $prob2, $prob); - my $index = 1; - #get all the problems - my @problems = (); - foreach my $path (@problemList) { - $path =~ s|^$topdir/*||; - #this will work if i can get problems by name - my $problemRecord; # checked - foreach my $problem ($db->listGlobalProblems($setID)) { - my $tempProblem = $db->getGlobalProblem($setID, $problem); - if($tempProblem->source_file eq $path){ - $problemRecord = $tempProblem; - } + + my $setID = $params->{set_id}; + my $GlobalSet = $db->getGlobalSet($params->{set_id}); + + debug("users: " . $params->{users}); + my @users = split(',',$params->{users}); + #my @users = decode_json($params->{users}); + + my @results; + foreach my $userID (@users) { + my $UserSet = $db->newUserSet; + $UserSet->user_id($userID); + $UserSet->set_id($setID); + + + + my $set_assigned = 0; + + eval { $db->addUserSet($UserSet) }; + if ($@) { + if ($@ =~ m/user set exists/) { + push @results, "set $setID is already assigned to user $userID."; + $set_assigned = 1; + } else { + die $@; + } } - die "global " .$path ." for set $setID not found." unless $problemRecord; - #print "found this problem to be reordered: ".$problemRecord."\n"; - push @problems, $problemRecord; - $index = $index + 1; - } - #then change their info - my @setUsers = $db->listSetUsers($setID); - my $user; - $index = 1; - foreach my $problem (@problems) { - $problem->problem_id($index); - die "global $problem not found." unless $problem; - #print "problem to be reordered: ".$problem."\n"; - $db->putGlobalProblem($problem); - - #need to deal with users? - foreach $user (@setUsers) { - #my $prob1 = $db->getUserProblem($user, $setID, $index); - #die " problem $index for set $setID and effective user $user not found" unless $prob1; - #$prob1->problem_id($index); - #$db->putUserProblem($prob1); - } - $index = $index + 1; - } - my $out->{text} = encode_base64("Successfully reordered problems"); + + my @GlobalProblems = grep { defined $_ } $db->getAllGlobalProblems($setID); + foreach my $GlobalProblem (@GlobalProblems) { + my @result = assignProblemToUser($self,$userID, $GlobalProblem); + push @results, @result if @result and not $set_assigned; + } + } + + my $out = {}; + $out->{ra_out} = \@results; + $out->{text} = encode_base64("Successfully assigned users to set " . $params->{set_id}); return $out; } - #problem utils from Instructor.pm sub assignProblemToUser { - my $self = shift; - my $userID = shift; - my $GlobalProblem = shift; - my $seed = shift;; + my ($self,$userID,$GlobalProblem,$seed) = @_; my $db = $self->{db}; my $UserProblem = $db->newUserProblem; @@ -204,45 +299,165 @@ sub assignProblemToUser { return (); } -sub assignProblemToAllSetUsers { + +sub deleteProblemSet { my $self = shift; - my $GlobalProblem = shift; + my $params = shift; my $db = $self->{db}; - my $setID = $GlobalProblem->set_id; - my @userIDs = $db->listSetUsers($setID); - - my @results; - - foreach my $userID (@userIDs) { - my @result = assignProblemToUser($self, $userID, $GlobalProblem); - push @results, @result if @result; - } - - return @results; + my $setID = $params->{set_id}; + my $result = $db->deleteGlobalSet($setID); + + # check the result + debug("in deleteProblemSet"); + debug("deleted set: $setID"); + debug($result); + + my $out->{text} = encode_base64("Deleted Problem Set " . $setID); + + + + return $out; + } -sub addProblemToSet { - my $self = shift; - my $args = shift; + +sub reorderProblems { + my ($self,$params) = @_; + my $db = $self->{db}; - my $value_default = $self->{ce}->{problemDefaults}->{value}; - my $max_attempts_default = $self->{ce}->{problemDefaults}->{max_attempts}; + my $setID = $params->{set_id}; + my @problemList = split(/,/, $params->{probList}); + my $topdir = $self->{ce}->{courseDirs}{templates}; + + + # get all the problems + my @newProblems = (); + my @allProblems = $db->getAllGlobalProblems($setID); + + foreach my $problem (@allProblems) { + my $index =1; + debug($problem->{source_file}); + debug($problem->{problem_id}); + debug($problem->{set_id}); + debug($problem->{value}); + + my $recordFound = 0; + foreach my $path (@problemList) { + $path =~ s|^$topdir/*||; + + # this will work if i can get problems by name + if($problem->{source_file} eq $path){ + $problem->problem_id($index); + + #debug($problem->{source_file}); + #debug($problem->{problem_id}); + $db->putGlobalProblem($problem); + $recordFound = 1; + } + $index = $index +1; + } + die "global " .$problem->{source_file} ." for set $setID not found." unless $recordFound; + + } + + #foreach my $problem (@newProblems){ + # debug($problem->{source_file}); + #} + + #then change their info + # my @setUsers = $db->listSetUsers($setID); + # my $user; + # my $index = 1; + # foreach my $problem (@problems) { + # $problem->problem_id($index); + # die "global $problem not found." unless $problem; + # # #print "problem to be reordered: ".$problem."\n"; + # my $sourceFile = $problem->{source_file}; + # debug("before putGlobalProblem: $sourceFile"); + # my $probExists = $db->existsGlobalProblem($setID,$problem); + # debug("problem Exists: $probExists"); + # #$db->addGlobalProblem($problem); + + # # #need to deal with users? + # foreach $user (@setUsers) { + # my $prob1 = $db->getUserProblem($user, $setID, $index); + # die " problem $index for set $setID and effective user $user not found" unless $prob1; + # $prob1->problem_id($index); + # $db->putUserProblem($prob1); + # } + # $index = $index + 1; + # } + my $out; + + $out->{text} = encode_base64("Successfully reordered problems"); + return $out; +} + + + + +# sub assignProblemToAllSetUsers { +# my $self = shift; +# my $GlobalProblem = shift; +# my $db = $self->{db}; +# my $setID = $GlobalProblem->set_id; +# my @userIDs = $db->listSetUsers($setID); + +# my @results; +# foreach my $userID (@userIDs) { +# my @result = assignProblemToUser($self, $userID, $GlobalProblem); +# push @results, @result if @result; +# } + +# return @results; +# } + +# sub addProblemToSet { +# my ($self,$params) = @_; +# my $db = $self->{db}; +# my $value_default = $self->{ce}->{problemDefaults}->{value}; +# my $max_attempts_default = $self->{ce}->{problemDefaults}->{max_attempts}; + + - die "addProblemToSet called without specifying the set name." if $args->{setName} eq ""; - my $setName = $args->{setName}; +# die "addProblemToSet called without specifying the set name." if $params->{set_id} eq ""; +# my $setName = $params->{set_id}; - my $sourceFile = $args->{sourceFile} or - die "addProblemToSet called without specifying the sourceFile."; +# my $sourceFile = $params->{sourceFile} or die "addProblemToSet called without specifying the sourceFile."; - # The rest of the arguments are optional + +# debug("In addProblemToSet"); +# debug("setName: $setName"); +# debug("sourceFile: $sourceFile"); + +# # The rest of the arguments are optional -# my $value = $args{value} || $value_default; +# # my $value = $params{value} || $value_default; + +# my $out->{text} = encode_base64("Problem added to ".$setName); +# return $out; +# } + +sub addProblem { + my ($self,$params) = @_; + my $db = $self->{db}; + my $setName = $params->{set_id}; + + my $file = $params->{path}; + my $topdir = $self->{ce}->{courseDirs}{templates}; + $file =~ s|^$topdir/*||; + + # DBFIXME count would work just as well + my $freeProblemID = max($db->listGlobalProblems($setName)) + 1; + my $value_default = $self->{ce}->{problemDefaults}->{value}; + my $max_attempts_default = $self->{ce}->{problemDefaults}->{max_attempts}; + my $value = $value_default; - if (defined($args->{value})){$value = $args->{value};} # 0 is a valid value for $args{value} + if (defined($params->{value})){$value = $params->{value};} # 0 is a valid value for $params{value} - my $maxAttempts = $args->{maxAttempts} || $max_attempts_default; - my $problemID = $args->{problemID}; + my $maxAttempts = $params->{maxAttempts} || $max_attempts_default; + my $problemID = $params->{problemID}; unless ($problemID) { $problemID = WeBWorK::Utils::max($db->listGlobalProblems($setName)) + 1; @@ -251,38 +466,31 @@ sub addProblemToSet { my $problemRecord = $db->newGlobalProblem; $problemRecord->problem_id($problemID); $problemRecord->set_id($setName); - $problemRecord->source_file($sourceFile); + $problemRecord->source_file($file); $problemRecord->value($value); $problemRecord->max_attempts($maxAttempts); $db->addGlobalProblem($problemRecord); - return $problemRecord; -} + my @results; + my @userIDs = $db->listSetUsers($setName); + foreach my $userID (@userIDs) { + my @result = assignProblemToUser($self, $userID, $problemRecord); + push @results, @result if @result; + } + -sub addProblem { - my $self = shift; - my $in = shift; - my $db = $self->{db}; - my $setName = $in->{set}; - my $file = $in->{path}; - my $topdir = $self->{ce}->{courseDirs}{templates}; - $file =~ s|^$topdir/*||; - my $freeProblemID; - # DBFIXME count would work just as well - $freeProblemID = max($db->listGlobalProblems($setName)) + 1; - my $problemRecord = addProblemToSet($self, {setName => $setName, sourceFile => $file, problemID => $freeProblemID}); - assignProblemToAllSetUsers($self, $problemRecord); + #assignProblemToAllSetUsers($self, $problemRecord); my $out->{text} = encode_base64("Problem added to ".$setName); return $out; } sub deleteProblem { - my $self = shift; - my $in = shift; + my ($self,$params) = @_; + my $db = $self->{db}; - my $setName = $in->{set}; + my $setName = $params->{set_id}; - my $file = $in->{path}; + my $file = $params->{path}; my $topdir = $self->{ce}->{courseDirs}{templates}; $file =~ s|^$topdir/*||; # DBFIXME count would work just as well diff --git a/templates/dgage/lbtwo.template b/templates/dgage/lbtwo.template deleted file mode 100755 index 50b30bee1..000000000 --- a/templates/dgage/lbtwo.template +++ /dev/null @@ -1,128 +0,0 @@ - - - - - - - - -/js/lib/vendor/bootstrap/css/bootstrap.css"/> - -/js/lib/vendor/bootstrap/css/bootstrap-responsive.css"/> - - -<!--#path style="text" text=" : " textonly="1"--> - - - - - -
      - - - - - -
      -

      - Warning -- there may be something wrong with this question. Please inform your instructor - including the warning messages below. -

      - -
      - - - -
      - - - -
      - -
      - - - -
      - -
      - - -
      -

      -

      Page generated at

      -

      styled using twitter bootstrap

      - -
      - - diff --git a/templates/math/lbtwo.template b/templates/math/lbtwo.template deleted file mode 100755 index 50b30bee1..000000000 --- a/templates/math/lbtwo.template +++ /dev/null @@ -1,128 +0,0 @@ - - - - - - - - -/js/lib/vendor/bootstrap/css/bootstrap.css"/> - -/js/lib/vendor/bootstrap/css/bootstrap-responsive.css"/> - - -<!--#path style="text" text=" : " textonly="1"--> - - - - - -
      - - - - - -
      -

      - Warning -- there may be something wrong with this question. Please inform your instructor - including the warning messages below. -

      - -
      - - - -
      - - - -
      - -
      - - - -
      - -
      - - -
      -

      -

      Page generated at

      -

      styled using twitter bootstrap

      - -
      - - diff --git a/templates/math2/lbtwo.template b/templates/math2/lbtwo.template deleted file mode 100755 index 50b30bee1..000000000 --- a/templates/math2/lbtwo.template +++ /dev/null @@ -1,128 +0,0 @@ - - - - - - - - -/js/lib/vendor/bootstrap/css/bootstrap.css"/> - -/js/lib/vendor/bootstrap/css/bootstrap-responsive.css"/> - - -<!--#path style="text" text=" : " textonly="1"--> - - - - - -
      - - - - - -
      -

      - Warning -- there may be something wrong with this question. Please inform your instructor - including the warning messages below. -

      - -
      - - - -
      - - - -
      - -
      - - - -
      - -
      - - -
      -

      -

      Page generated at

      -

      styled using twitter bootstrap

      - -
      - - diff --git a/templates/math3/lbtwo.template b/templates/math3/lbtwo.template deleted file mode 100755 index cb57c734b..000000000 --- a/templates/math3/lbtwo.template +++ /dev/null @@ -1,133 +0,0 @@ - - - - - - - - -/js/lib/vendor/bootstrap/css/bootstrap.css"/> - -/js/lib/vendor/bootstrap/css/bootstrap-responsive.css"/> - - -<!--#path style="text" text=" : " textonly="1"--> - - - - - -
      - - - - - -
      -

      - Warning -- there may be something wrong with this question. Please inform your instructor - including the warning messages below. -

      - -
      - - - -
      - - - -
      - -
      - - - -
      - -
      - - -
      -

      -

      Page generated at

      -

      styled using twitter bootstrap

      - -
      - - - - - - - diff --git a/templates/moodle/lbtwo.template b/templates/moodle/lbtwo.template deleted file mode 100755 index 50b30bee1..000000000 --- a/templates/moodle/lbtwo.template +++ /dev/null @@ -1,128 +0,0 @@ - - - - - - - - -/js/lib/vendor/bootstrap/css/bootstrap.css"/> - -/js/lib/vendor/bootstrap/css/bootstrap-responsive.css"/> - - -<!--#path style="text" text=" : " textonly="1"--> - - - - - -
      - - - - - -
      -

      - Warning -- there may be something wrong with this question. Please inform your instructor - including the warning messages below. -

      - -
      - - - -
      - - - -
      - -
      - - - -
      - -
      - - -
      -

      -

      Page generated at

      -

      styled using twitter bootstrap

      - -
      - - diff --git a/templates/test/lbtwo.template b/templates/test/lbtwo.template deleted file mode 100755 index 50b30bee1..000000000 --- a/templates/test/lbtwo.template +++ /dev/null @@ -1,128 +0,0 @@ - - - - - - - - -/js/lib/vendor/bootstrap/css/bootstrap.css"/> - -/js/lib/vendor/bootstrap/css/bootstrap-responsive.css"/> - - -<!--#path style="text" text=" : " textonly="1"--> - - - - - -
      - - - - - -
      -

      - Warning -- there may be something wrong with this question. Please inform your instructor - including the warning messages below. -

      - -
      - - - -
      - - - -
      - -
      - - - -
      - -
      - - -
      -

      -

      Page generated at

      -

      styled using twitter bootstrap

      - -
      - - diff --git a/templates/union/lbtwo.template b/templates/union/lbtwo.template deleted file mode 100755 index 50b30bee1..000000000 --- a/templates/union/lbtwo.template +++ /dev/null @@ -1,128 +0,0 @@ - - - - - - - - -/js/lib/vendor/bootstrap/css/bootstrap.css"/> - -/js/lib/vendor/bootstrap/css/bootstrap-responsive.css"/> - - -<!--#path style="text" text=" : " textonly="1"--> - - - - - -
      - - - - - -
      -

      - Warning -- there may be something wrong with this question. Please inform your instructor - including the warning messages below. -

      - -
      - - - -
      - - - -
      - -
      - - - -
      - -
      - - - - -