├── source ├── stylesheets │ ├── quiz-curbed.css.scss │ ├── .DS_Store │ ├── quiz-eater.css.scss │ ├── quiz-polygon.css.scss │ ├── quiz-sbnation.css.scss │ ├── flowchart.css.scss │ ├── quiz-verge.css.scss │ ├── quiz-vox.css.scss │ ├── quiz-racked.css.scss │ ├── quiz-fashion.css.scss │ ├── quiz.css.scss │ └── quiz-generator.css.scss ├── images │ ├── qq.png │ ├── voxlogo.png │ └── quartetLOL.jpg ├── racked.html.erb ├── layouts │ ├── demo.erb │ └── layout.erb ├── index.html.erb ├── javascripts │ ├── fashion-quiz.js │ ├── getdata.js │ ├── binary.js │ ├── quiz.js │ ├── flowchart.js │ ├── tabletop.js │ └── jquery.min.js └── demo.html.erb ├── Rakefile ├── .gitignore ├── config.ru ├── Gemfile ├── config.rb ├── Gemfile.lock └── README.md /source/stylesheets/quiz-curbed.css.scss: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /Rakefile: -------------------------------------------------------------------------------- 1 | namespace :assets do 2 | task :precompile do 3 | sh 'middleman build' 4 | end 5 | end -------------------------------------------------------------------------------- /source/images/qq.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/voxmedia/quiz-generator/HEAD/source/images/qq.png -------------------------------------------------------------------------------- /source/images/voxlogo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/voxmedia/quiz-generator/HEAD/source/images/voxlogo.png -------------------------------------------------------------------------------- /source/images/quartetLOL.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/voxmedia/quiz-generator/HEAD/source/images/quartetLOL.jpg -------------------------------------------------------------------------------- /source/stylesheets/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/voxmedia/quiz-generator/HEAD/source/stylesheets/.DS_Store -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Ignore bundler config 2 | /.bundle 3 | 4 | # Ignore the build directory 5 | /build 6 | 7 | # Ignore Sass' cache 8 | /.sass-cache 9 | 10 | # Ignore this .cache 11 | /.cache 12 | # Dont ignore these apparently, dumb Tate /.ruby-version 13 | 14 | # Ignore .DS_store file 15 | .DS_Store 16 | source/.DS_Store 17 | 18 | /test -------------------------------------------------------------------------------- /config.ru: -------------------------------------------------------------------------------- 1 | require 'rack' 2 | require 'rack/contrib/try_static' 3 | 4 | # Serve files from the build directory 5 | use Rack::TryStatic, 6 | root: 'build', 7 | urls: %w[/], 8 | try: ['.html', 'index.html', '/index.html'] 9 | 10 | run lambda{ |env| 11 | four_oh_four_page = File.expand_path("../build/index.html", __FILE__) 12 | [ 404, { 'Content-Type' => 'text/html'}, [ File.read(four_oh_four_page) ]] 13 | } -------------------------------------------------------------------------------- /source/racked.html.erb: -------------------------------------------------------------------------------- 1 |
2 | 3 |
4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /Gemfile: -------------------------------------------------------------------------------- 1 | # If you have OpenSSL installed, we recommend updating 2 | # the following line to use "https" 3 | source 'http://rubygems.org' 4 | 5 | gem "middleman", "~>3.3.3" 6 | 7 | # Live-reloading plugin 8 | gem "middleman-livereload", "~> 3.1.0" 9 | 10 | # For faster file watcher updates on Windows: 11 | gem "wdm", "~> 0.1.0", :platforms => [:mswin, :mingw] 12 | 13 | # Windows does not come with time zone data 14 | gem "tzinfo-data", platforms: [:mswin, :mingw] 15 | gem "rack-contrib" -------------------------------------------------------------------------------- /source/layouts/demo.erb: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Test Page 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | <%= yield %> 13 | 14 | -------------------------------------------------------------------------------- /config.rb: -------------------------------------------------------------------------------- 1 | ### 2 | # Compass 3 | ### 4 | 5 | # Change Compass configuration 6 | # compass_config do |config| 7 | # config.output_style = :compact 8 | # end 9 | 10 | ### 11 | # Congif 12 | ### 13 | 14 | page "/demo.html", :layout => "demo" 15 | page "/racked.html", :layout => "demo" 16 | page "/flowchart.html", :layout => "flowchart" 17 | page "/flowchart-design.html", :layout => "flowchart" 18 | set :css_dir, 'stylesheets' 19 | set :js_dir, 'javascripts' 20 | set :images_dir, 'images' 21 | activate :directory_indexes 22 | # set :build_dir, "build" 23 | 24 | # Build-specific configuration 25 | configure :build do 26 | # activate :minify_css 27 | # activate :minify_javascript 28 | end 29 | -------------------------------------------------------------------------------- /source/layouts/layout.erb: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | <%= current_page.data.title || "Quiz Generator" %> 13 | 14 | <%= stylesheet_link_tag "quiz-generator" %> 15 | 16 | 17 | 18 | Fork me on GitHub 19 | <%= yield %> 20 | 21 | -------------------------------------------------------------------------------- /source/stylesheets/quiz-eater.css.scss: -------------------------------------------------------------------------------- 1 | $font-stack: 'Whitney Regular', Arial, sans-serif; 2 | $question-font: 'Glober', Georgia, serif; 3 | $purple: #6d0028; 4 | 5 | // Container for generated quiz 6 | .quiz-container { 7 | font-family: $font-stack; 8 | text-align: center; 9 | border-top: 7px solid $purple; 10 | padding-top: 20px; 11 | } 12 | 13 | // Text for each question 14 | .qq-question { 15 | font-family: $question-font; 16 | color: #000000; 17 | font-size: 1.5em; 18 | margin: 0% auto; 19 | margin-bottom: 20px; 20 | font-weight: bolder; 21 | } 22 | 23 | // Answer options for each question 24 | ol.answers > li { 25 | font-family: $font-stack; 26 | font-size: 1em; 27 | 28 | &:before { 29 | font-family: $question-font; 30 | font-weight: bold; 31 | color: #FFFFFF; 32 | background-color: $purple; 33 | width: 30px; 34 | } 35 | &:hover { 36 | background-color: #EEEDED; 37 | } 38 | } 39 | 40 | // Buttons 41 | .qq-button { 42 | font-family: ff-din-web-condensed, Helvetica, sans-serif; 43 | color: #FFFFFF; 44 | font-weight: 400; 45 | background-color: $purple; 46 | &:hover { 47 | background-color: $purple !important; 48 | } 49 | } 50 | 51 | // Submit button color when an answer is selected 52 | .submit-highlight { 53 | background-color: #e60000; 54 | } 55 | 56 | // Highlights selected answer 57 | .selected { 58 | background-color: #ffe8e1; 59 | } 60 | 61 | // Checking selected anhswer 62 | .answer p { 63 | font-family: $font-stack; 64 | font-size: 0.9em; 65 | &:first-child { 66 | font-family: $question-font; 67 | } 68 | } 69 | 70 | // Social media buttons on final scorecard 71 | #social-media ul li a svg { 72 | &:hover { 73 | fill: $purple; 74 | } 75 | path:hover { 76 | fill: #FFFFFF; 77 | } 78 | } 79 | 80 | // Hyperlinks 81 | .answer a { 82 | color: $purple; 83 | text-decoration: none; 84 | &:hover { 85 | color: #000000; 86 | } 87 | } -------------------------------------------------------------------------------- /source/stylesheets/quiz-polygon.css.scss: -------------------------------------------------------------------------------- 1 | $font-stack: 'Gotham SSm A', 'Gotham SSm B', Arial, sans-serif; 2 | $purple: #3F1E45; 3 | 4 | // Container for generated quiz 5 | .quiz-container { 6 | font-family: $font-stack; 7 | border-top: 3px solid #000000; 8 | } 9 | 10 | // Text for each question 11 | .qq-question { 12 | font-family: $font-stack; 13 | font-weight: bold; 14 | color: #000000; 15 | font-size: 1.5em; 16 | margin: 0% auto; 17 | margin-bottom: 20px; 18 | } 19 | 20 | // Description for each question 21 | .qq-description { 22 | font-family: $font-stack; 23 | padding: 20px 20px 0px 20px; 24 | } 25 | 26 | // Answer options for each question 27 | ol.answers > li { 28 | font-family: $font-stack; 29 | 30 | &:before { 31 | font-family: $font-stack; 32 | font-style: italic; 33 | color: #FFFFFF; 34 | background-color: $purple; 35 | width: 30px; 36 | } 37 | &:hover { 38 | background-color: #EBEBEC; 39 | } 40 | } 41 | 42 | // Buttons 43 | .qq-button { 44 | font-family: $font-stack; 45 | font-style: italic; 46 | font-weight: 800; 47 | color: #FFFFFF; 48 | background-color: #FF0052; 49 | width: 180px; 50 | &:hover { 51 | background-color: $purple !important; 52 | } 53 | } 54 | 55 | // Highlights selected answer 56 | .selected { 57 | background-color: #DFDFE0; 58 | } 59 | 60 | // Submit button color when an answer is selected 61 | .submit-highlight { 62 | background-color: #CD1949; 63 | } 64 | 65 | // Checking selected answer 66 | .answer p:first-child { 67 | font-family: $font-stack; 68 | } 69 | 70 | // Social media buttons on final scorecard 71 | #social-media ul li a svg { 72 | &:hover { 73 | fill: #ED1C55; 74 | } 75 | path:hover { 76 | fill: #FFFFFF; 77 | } 78 | fill: $purple; 79 | } 80 | 81 | // Hyperlinks 82 | .answer a { 83 | color: #FF0052; 84 | text-decoration: none; 85 | &:hover { 86 | text-decoration: underline; 87 | } 88 | } 89 | 90 | // FLowchart selection 91 | .flowchart-selected { 92 | background-color: $purple !important; 93 | color: #FFFFFF !important; 94 | } 95 | 96 | // Flowchart button hover 97 | .flowchart-button { 98 | &:hover { 99 | background-color: $purple; 100 | color: #FFFFFF; 101 | } 102 | } -------------------------------------------------------------------------------- /source/stylesheets/quiz-sbnation.css.scss: -------------------------------------------------------------------------------- 1 | $font-stack: 'Gotham SSm A', 'Gotham SSm B', Arial, sans-serif; 2 | $question-font: 'Sentinel SSm A', 'Sentinel SSm B', Georgia, serif; 3 | $red: #C52327; 4 | 5 | // Container for generated quiz 6 | .quiz-container { 7 | font-family: $font-stack; 8 | text-align: center; 9 | border-top: 7px solid $red; 10 | padding-top: 20px; 11 | } 12 | 13 | // Text for each question 14 | .qq-question { 15 | font-family: $question-font; 16 | color: #000000; 17 | font-size: 1.5em; 18 | margin: 0% auto; 19 | margin-bottom: 20px; 20 | } 21 | 22 | // Description for each question 23 | .qq-description { 24 | font-family: $font-stack; 25 | padding: 20px 10px 0px 10px; 26 | } 27 | 28 | // Answer options for each question 29 | ol.answers > li { 30 | font-family: $font-stack; 31 | font-size: 0.9em; 32 | 33 | &:before { 34 | font-family: $question-font; 35 | font-weight: bold; 36 | color: #FFFFFF; 37 | background-color: $red; 38 | width: 30px; 39 | } 40 | &:hover { 41 | background-color: #EEEDED; 42 | } 43 | } 44 | 45 | // Buttons 46 | .qq-button { 47 | font-family: ff-din-web-condensed, Helvetica, sans-serif; 48 | color: #FFFFFF; 49 | font-weight: 800; 50 | background-color: #000000; 51 | &:hover { 52 | background-color: $red !important; 53 | } 54 | } 55 | 56 | // Submit button color when an answer is selected 57 | .submit-highlight { 58 | background-color: #6D6E70; 59 | } 60 | 61 | // Checking selected answer 62 | .answer p { 63 | font-family: $font-stack; 64 | font-size: 0.9em; 65 | &:first-child { 66 | font-family: $question-font; 67 | } 68 | } 69 | 70 | // Social media buttons on final scorecard 71 | #social-media ul li a svg { 72 | &:hover { 73 | fill: $red; 74 | } 75 | path:hover { 76 | fill: #FFFFFF; 77 | } 78 | } 79 | 80 | // Hyperlinks 81 | .answer a { 82 | color: $red; 83 | text-decoration: none; 84 | &:hover { 85 | text-decoration: underline; 86 | } 87 | } 88 | 89 | // FLowchart selection 90 | .flowchart-selected { 91 | background-color: $red !important; 92 | color: #FFFFFF !important; 93 | } 94 | 95 | // Flowchart button hover 96 | .flowchart-button { 97 | &:hover { 98 | background-color: $red; 99 | color: #FFFFFF; 100 | } 101 | } -------------------------------------------------------------------------------- /source/stylesheets/flowchart.css.scss: -------------------------------------------------------------------------------- 1 | // Mixin for button hover transitions 2 | @mixin transition($transition-time) { 3 | -o-transition: $transition-time; 4 | -ms-transition: $transition-time; 5 | -moz-transition: $transition-time; 6 | -webkit-transition: $transition-time; 7 | transition: $transition-time; 8 | } 9 | 10 | $font-stack: 'Alight Sans', sans-serif; 11 | $question-font: 'Balto', sans-serif; 12 | 13 | .quiz-container { 14 | font-family: $font-stack; 15 | text-align: center; 16 | background-color: #FFFFFF; 17 | margin: 0 auto; 18 | max-width: 770px; 19 | width: 100%; 20 | padding-bottom: 1em; 21 | } 22 | 23 | .choices { 24 | text-align: center; 25 | } 26 | 27 | div.buttons { 28 | display:inline; 29 | } 30 | 31 | button.flowchart-button { 32 | @include transition(0.2s); 33 | font-family: Helvetica, sans-serif !important; 34 | font-size: .9em; 35 | font-weight: 100; 36 | color: #414141; 37 | background-color: #ececec; 38 | cursor: pointer; 39 | width: 120px; 40 | margin: 0.1em 1em 0.4em 0; 41 | border: 0; 42 | padding: 12px 0px; 43 | padding: 8px 10px; 44 | 45 | &:hover { 46 | background-color: #f37b21; 47 | } 48 | } 49 | 50 | p.down-arrow { 51 | margin: 0 auto; 52 | width: 100%; 53 | } 54 | 55 | .question { 56 | margin-top: 2.5em !important; 57 | margin-bottom: 0.4em; 58 | padding: 0 0.6em 0.6em; 59 | p { 60 | font-family: $question-font; 61 | font-size: 1.2em; 62 | font-weight: 400; 63 | } 64 | } 65 | 66 | .scorecard { 67 | margin-top: 15px; 68 | } 69 | 70 | .last { 71 | margin: 0 auto; 72 | margin-top: 2em; 73 | width: 70%; 74 | min-width: 200px; 75 | border-top: 1px solid #ececec; 76 | 77 | p { 78 | margin-top: 2em; 79 | margin-bottom: 0px; 80 | line-height: 1.5em; 81 | } 82 | } 83 | 84 | #social-media { 85 | padding: 10px; 86 | } 87 | 88 | // Social media buttons on final scorecard 89 | #social-media ul { 90 | text-align: center; 91 | list-style-type: none; 92 | margin: 0; 93 | padding: 0px; 94 | margin-bottom: 10px; 95 | li { 96 | display: inline-block; 97 | a { 98 | text-decoration: none; 99 | svg { 100 | height: 2em; 101 | width: 2em; 102 | margin-right: 1em; 103 | } 104 | } 105 | } 106 | } -------------------------------------------------------------------------------- /source/index.html.erb: -------------------------------------------------------------------------------- 1 | 2 | 3 |
4 |

Quiz Quartet

5 |
6 | 7 |
8 |

Write your quiz

9 | 10 |
Choose a Quiz Type
11 |
12 | 13 | 14 | 15 |
16 | 17 |

Use this Google Spreadsheet template to write your quiz.

18 |

Once you're done editing, publish the spreadsheet to the web. Under the "File" menu, select "Publish to the Web." Click "Start Publishing" and copy the URL to build the quiz.

19 |

Want to test it out? Try this spreadsheet:

20 | 21 |
Enter your spreadsheet
22 |

Copy and paste your spreadsheet's URL here:

23 | 24 |
Select your vertical
25 |
26 | 27 | 28 | 29 | 30 | 31 | 32 |
33 | 34 |
35 |
Generate, copy and paste this code into Chorus
36 |

37 |

38 |
39 | 40 |

Preview

41 | 42 |
43 | 44 |
45 |
46 |
47 | 48 | 49 | 50 | -------------------------------------------------------------------------------- /source/stylesheets/quiz-verge.css.scss: -------------------------------------------------------------------------------- 1 | $font-stack: ff-din-web-condensed, Helvetica, sans-serif; 2 | $bright-red: #FB4834; 3 | 4 | // Container for generated quiz 5 | .quiz-container { 6 | font-family: Helvetica, sans-serif; 7 | border-top: 8px solid $bright-red; 8 | padding-top: 20px; 9 | } 10 | 11 | // Text for each question 12 | .qq-question { 13 | font-family: $font-stack; 14 | font-weight: 800; 15 | font-size: 1.5em; 16 | font-style: italic; 17 | text-transform: uppercase; 18 | color: #000000; 19 | margin: 0% auto; 20 | max-width: 80%; 21 | margin-bottom: 20px; 22 | } 23 | 24 | // Description for each question 25 | .qq-description { 26 | padding: 20px 15px 0px 15px; 27 | font-family: Helvetica, sans-serif; 28 | } 29 | 30 | // Answer options for each question 31 | ol.answers > li { 32 | font-family: Helvetica, sans-serif; 33 | font-size: 0.9em; 34 | 35 | &:before { 36 | font-family: $font-stack; 37 | font-style: italic; 38 | font-weight: 800; 39 | font-size: 1em; 40 | color: #FFFFFF; 41 | line-height: 0.8em; 42 | background-color: $bright-red; 43 | width: 30px; 44 | padding: 8px 0px 5px 0px; 45 | } 46 | &:hover { 47 | background-color: #F4F0EE; 48 | } 49 | } 50 | 51 | // Buttons 52 | .qq-button { 53 | font-family: $font-stack !important; 54 | font-weight: 400; 55 | font-size: 1.02em; 56 | color: #FFFFFF; 57 | background-color: #000000; 58 | &:hover { 59 | background-color: $bright-red !important; 60 | } 61 | } 62 | 63 | // Highlights selected answer 64 | .selected { 65 | background-color: #DFDFE0; 66 | } 67 | 68 | // Submit button color when an answer is selected 69 | .submit-highlight { 70 | background-color: #6D6E70; 71 | } 72 | 73 | // Checking selected answer 74 | .answer p:first-child { 75 | font-family: $font-stack; 76 | text-transform: uppercase; 77 | } 78 | 79 | // Width of 'See Final Score' button 80 | .check-score { 81 | width: 35% 82 | } 83 | 84 | // Social media buttons on final scorecard 85 | #social-media ul li a svg { 86 | fill: #000000; 87 | &:hover { 88 | fill: $bright-red; 89 | } 90 | path:hover { 91 | fill: #FFFFFF; 92 | } 93 | } 94 | 95 | // Style for scorecard's final score 96 | .scorecard p:nth-child(2) { 97 | color: $bright-red; 98 | } 99 | 100 | // Hyperlinks 101 | .answer a { 102 | color: $bright-red; 103 | text-decoration: none; 104 | &:hover { 105 | text-decoration: underline; 106 | } 107 | } 108 | 109 | // FLowchart selection 110 | .flowchart-selected { 111 | background-color: $bright-red !important; 112 | color: #FFFFFF !important; 113 | } 114 | 115 | // Flowchart button hover 116 | .flowchart-button { 117 | &:hover { 118 | background-color: $bright-red; 119 | color: #FFFFFF; 120 | } 121 | } -------------------------------------------------------------------------------- /source/stylesheets/quiz-vox.css.scss: -------------------------------------------------------------------------------- 1 | $font-stack: 'Alight Sans', sans-serif; 2 | $question-font: 'Balto', sans-serif; 3 | $blue: #bfd1df; 4 | 5 | // Container for generated quiz 6 | .quiz-container { 7 | font-family: $font-stack; 8 | color: #4C4E4D; 9 | padding-top: 20px; 10 | } 11 | 12 | // Text for each question 13 | .qq-question { 14 | font-family: $question-font; 15 | font-weight: bold; 16 | color: #4C4E4D; 17 | font-size: 1.5em; 18 | margin: 0% auto; 19 | margin-bottom: 30px; 20 | margin-top: 0px; 21 | } 22 | 23 | // Description for each question 24 | .qq-description { 25 | font-family: $font-stack; 26 | padding: 20px 30px 0px 30px; 27 | } 28 | 29 | // Answer options for each question 30 | ol.answers > li { 31 | font-family: $font-stack; 32 | padding: 0px 0px 0px 10px; 33 | 34 | &:before { 35 | font-family: $question-font; 36 | font-weight: bold; 37 | color: #4c4e4d; 38 | background-color: $blue; 39 | width: 25px; 40 | padding: 2px 0px; 41 | } 42 | &:hover { 43 | background-color: #f1f3f2; 44 | } 45 | } 46 | 47 | // Buttons 48 | .qq-button { 49 | font-family: $font-stack; 50 | color: #4c4e4d; 51 | background-color: #f1f3f2; 52 | &:hover { 53 | background-color: $blue !important; 54 | } 55 | } 56 | 57 | // Highlights selected answer 58 | .selected { 59 | background-color: #f7f7f7; 60 | } 61 | 62 | // Submit button color when an answer is selected 63 | .submit-highlight { 64 | background-color: #cacbcc; 65 | } 66 | 67 | // Checking selected answer 68 | .answer p:first-child { 69 | font-family: $question-font; 70 | border-top: 1px solid #4c4e4d !important; 71 | } 72 | 73 | // Social media buttons on final scorecard 74 | #social-media { 75 | ul { 76 | text-align: center; 77 | list-style-type: none; 78 | margin: 0; 79 | padding: 0; 80 | li { 81 | display: inline-block; 82 | 83 | &:before { 84 | background-color:transparent !important; 85 | // display: none; 86 | } 87 | 88 | a { 89 | text-decoration: none; 90 | svg { 91 | fill: #4c4e4d; 92 | &:hover { 93 | fill: #fff200; 94 | } 95 | path:hover { 96 | fill: #ffffff; 97 | } 98 | } 99 | } 100 | } 101 | } 102 | } 103 | 104 | // Style for scorecard's final score 105 | .scorecard p:nth-child(2) { 106 | font-family: $question-font; 107 | } 108 | 109 | // Hyperlinks 110 | .answer a { 111 | color: #6d98a8; 112 | text-decoration: none; 113 | font-weight: 600; 114 | -webkit-font-smoothing: antialiased; 115 | &:hover { 116 | text-decoration:underline; 117 | } 118 | } 119 | 120 | // Flowchart selection 121 | .flowchart-selected { 122 | background-color: $blue !important; 123 | } -------------------------------------------------------------------------------- /source/stylesheets/quiz-racked.css.scss: -------------------------------------------------------------------------------- 1 | $font-stack: Georgia, serif; 2 | $question-font: "KnockoutHTF29-JuniorLiteweight", "Arial Narrow", serif; 3 | $red: #C92025; 4 | 5 | // Container for generated quiz 6 | .quiz-container { 7 | font-family: $font-stack; 8 | color: #4C4E4D; 9 | padding-top: 20px; 10 | border-top: 3px solid $red; 11 | } 12 | 13 | // Text for each question 14 | .qq-question { 15 | font-family: $question-font; 16 | font-weight: bold; 17 | color: #4C4E4D; 18 | font-size: 1.5em; 19 | margin: 0 0 30px 0; 20 | text-align: left; 21 | } 22 | 23 | // Description for each question 24 | .qq-description { 25 | font-family: $font-stack; 26 | text-align: left; 27 | } 28 | 29 | // Answer options for each question 30 | ol.answers { 31 | .dim { 32 | opacity: 0.3; 33 | } 34 | .selected { 35 | opacity: 1; 36 | } 37 | > li { 38 | min-height: 250px; 39 | font-family: $font-stack; 40 | overflow:hidden; 41 | display: inline-block; 42 | text-align: left; 43 | border: 1px solid #d3d3d3; 44 | margin: 0 10px 10px 0; 45 | padding: 20px; 46 | &:before { 47 | display: none; 48 | } 49 | &:hover { 50 | background-color: #ececec; 51 | } 52 | img { 53 | width: 160px; 54 | } 55 | p { 56 | font-family: $question-font; 57 | font-weight: bold; 58 | font-size: 18px; 59 | } 60 | } 61 | } 62 | 63 | // Buttons 64 | .qq-button { 65 | font-family: $font-stack; 66 | color: #FFFFFF; 67 | text-transform: none; 68 | background-color: #4C4E4D; 69 | &:hover { 70 | background-color: $red !important; 71 | } 72 | } 73 | 74 | // Highlights selected answer 75 | .selected { 76 | background-color: #ececec; 77 | color: #4C4E4D; 78 | } 79 | 80 | // Submit button color when an answer is selected 81 | .submit-highlight { 82 | background-color: #6F7170; 83 | } 84 | 85 | // Checking selected answer 86 | .answer p:first-child { 87 | font-family: $question-font; 88 | border-top: 1px solid #4c4e4d !important; 89 | } 90 | 91 | // Social media buttons on final scorecard 92 | #social-media { 93 | ul { 94 | text-align: center; 95 | list-style-type: none; 96 | margin: 0; 97 | padding: 0; 98 | li { 99 | display: inline-block; 100 | 101 | &:before { 102 | background-color:transparent !important; 103 | // display: none; 104 | } 105 | 106 | a { 107 | text-decoration: none; 108 | svg { 109 | fill: #4c4e4d; 110 | &:hover { 111 | fill: #fff200; 112 | } 113 | path:hover { 114 | fill: #ffffff; 115 | } 116 | } 117 | } 118 | } 119 | } 120 | } 121 | 122 | // Style for scorecard's final score 123 | .scorecard p:nth-child(2) { 124 | font-family: $question-font; 125 | } 126 | 127 | // Hyperlinks 128 | .answer a { 129 | color: #6d98a8; 130 | text-decoration: none; 131 | font-weight: 600; 132 | -webkit-font-smoothing: antialiased; 133 | &:hover { 134 | text-decoration:underline; 135 | } 136 | } 137 | 138 | // Flowchart selection 139 | .flowchart-selected { 140 | background-color: $red !important; 141 | } -------------------------------------------------------------------------------- /Gemfile.lock: -------------------------------------------------------------------------------- 1 | GEM 2 | remote: http://rubygems.org/ 3 | specs: 4 | activesupport (4.1.1) 5 | i18n (~> 0.6, >= 0.6.9) 6 | json (~> 1.7, >= 1.7.7) 7 | minitest (~> 5.1) 8 | thread_safe (~> 0.1) 9 | tzinfo (~> 1.1) 10 | chunky_png (1.3.1) 11 | coffee-script (2.2.0) 12 | coffee-script-source 13 | execjs 14 | coffee-script-source (1.7.0) 15 | compass (0.12.6) 16 | chunky_png (~> 1.2) 17 | fssm (>= 0.2.7) 18 | sass (~> 3.2.19) 19 | compass-import-once (1.0.4) 20 | sass (>= 3.2, < 3.5) 21 | em-websocket (0.5.1) 22 | eventmachine (>= 0.12.9) 23 | http_parser.rb (~> 0.6.0) 24 | erubis (2.7.0) 25 | eventmachine (1.0.3) 26 | execjs (2.2.0) 27 | ffi (1.9.3) 28 | fssm (0.2.10) 29 | haml (4.0.5) 30 | tilt 31 | hike (1.2.3) 32 | hooks (0.4.0) 33 | uber (~> 0.0.4) 34 | http_parser.rb (0.6.0) 35 | i18n (0.6.9) 36 | json (1.8.1) 37 | kramdown (1.4.0) 38 | listen (1.3.1) 39 | rb-fsevent (>= 0.9.3) 40 | rb-inotify (>= 0.9) 41 | rb-kqueue (>= 0.2) 42 | middleman (3.3.3) 43 | coffee-script (~> 2.2.0) 44 | compass (>= 0.12.4) 45 | compass-import-once (= 1.0.4) 46 | execjs (~> 2.0) 47 | haml (>= 4.0.5) 48 | kramdown (~> 1.2) 49 | middleman-core (= 3.3.3) 50 | middleman-sprockets (>= 3.1.2) 51 | sass (>= 3.2.17, < 4.0) 52 | uglifier (~> 2.5) 53 | middleman-core (3.3.3) 54 | activesupport (~> 4.1.0) 55 | bundler (~> 1.1) 56 | erubis 57 | hooks (~> 0.3) 58 | i18n (~> 0.6.9) 59 | listen (~> 1.1) 60 | padrino-helpers (~> 0.12.1) 61 | rack (>= 1.4.5, < 2.0) 62 | rack-test (~> 0.6.2) 63 | thor (>= 0.15.2, < 2.0) 64 | tilt (~> 1.4.1, < 2.0) 65 | middleman-livereload (3.1.1) 66 | em-websocket (>= 0.2.0) 67 | middleman-core (>= 3.0.2) 68 | multi_json (~> 1.0) 69 | rack-livereload 70 | middleman-sprockets (3.3.3) 71 | middleman-core (>= 3.2) 72 | sprockets (~> 2.2) 73 | sprockets-helpers (~> 1.1.0) 74 | sprockets-sass (~> 1.1.0) 75 | minitest (5.3.5) 76 | multi_json (1.10.1) 77 | padrino-helpers (0.12.2) 78 | i18n (~> 0.6, >= 0.6.7) 79 | padrino-support (= 0.12.2) 80 | tilt (~> 1.4.1) 81 | padrino-support (0.12.2) 82 | activesupport (>= 3.1) 83 | rack (1.5.2) 84 | rack-contrib (1.1.0) 85 | rack (>= 0.9.1) 86 | rack-livereload (0.3.15) 87 | rack 88 | rack-test (0.6.2) 89 | rack (>= 1.0) 90 | rb-fsevent (0.9.4) 91 | rb-inotify (0.9.5) 92 | ffi (>= 0.5.0) 93 | rb-kqueue (0.2.3) 94 | ffi (>= 0.5.0) 95 | sass (3.2.19) 96 | sprockets (2.12.1) 97 | hike (~> 1.2) 98 | multi_json (~> 1.0) 99 | rack (~> 1.0) 100 | tilt (~> 1.1, != 1.3.0) 101 | sprockets-helpers (1.1.0) 102 | sprockets (~> 2.0) 103 | sprockets-sass (1.1.0) 104 | sprockets (~> 2.0) 105 | tilt (~> 1.1) 106 | thor (0.19.1) 107 | thread_safe (0.3.4) 108 | tilt (1.4.1) 109 | tzinfo (1.2.1) 110 | thread_safe (~> 0.1) 111 | uber (0.0.6) 112 | uglifier (2.5.1) 113 | execjs (>= 0.3.0) 114 | json (>= 1.8.0) 115 | 116 | PLATFORMS 117 | ruby 118 | 119 | DEPENDENCIES 120 | middleman (~> 3.3.3) 121 | middleman-livereload (~> 3.1.0) 122 | rack-contrib 123 | tzinfo-data 124 | wdm (~> 0.1.0) 125 | -------------------------------------------------------------------------------- /source/javascripts/fashion-quiz.js: -------------------------------------------------------------------------------- 1 | var answer, 2 | qnumber, 3 | currentQuestion = 0, 4 | input; 5 | 6 | function getData() { 7 | getSpreadSheet(); 8 | } 9 | 10 | function getSpreadSheet() { 11 | Tabletop.init({ 12 | key: '1kVfAkLUXOxVgtTvw-Z4MSlvVfrNr8-6XdBPtQwHQ_lI', 13 | callback: function(data, tabletop) { 14 | console.log(data) 15 | input = data; 16 | buildQuiz(input); 17 | }, simpleSheet: true 18 | }) 19 | } 20 | 21 | function buildQuiz(input) { 22 | qnumber = currentQuestion + 1; 23 | anumber = qnumber; 24 | $(".quiz-container").html("
Question " + qnumber + " of " + input.length + "
" + input[currentQuestion].description + "

" + input[currentQuestion].question + "
" + 25 | "
    "); 26 | $(".answers").append( 27 | "
  1. " + '

    ' + input[currentQuestion].a + "

  2. " + 28 | "
  3. " + '

    ' + input[currentQuestion].b + "

  4. " + 29 | "
  5. " + '

    ' + input[currentQuestion].c + "

  6. " + 30 | "
  7. " + '

    ' + input[currentQuestion].d + "

  8. " + 31 | "
  9. " + '

    ' + input[currentQuestion].e + "

  10. " + 32 | "
  11. " + '

    ' + input[currentQuestion].f + "

  12. " 33 | ); 34 | selectAnswer(); 35 | if (currentQuestion != (input.length-1)) { 36 | $('.quiz-container').append(""); 37 | $('.submit-answer').on('click', checkAnswer); 38 | } else { 39 | $(".quiz-container").append(""); 40 | $('.check-score').on('click', finalScore); 41 | } 42 | } 43 | 44 | function selectAnswer() { 45 | $('li').click(function() { 46 | $(".selected").removeClass("selected"); 47 | $('li').addClass("dim"); 48 | $(this).addClass("selected"); 49 | $(".submit-answer").addClass("submit-highlight").fadeIn(); 50 | }) 51 | } 52 | 53 | var scores = []; 54 | function checkAnswer() { 55 | if ($(".selected").length > 0) { 56 | answer = $('.selected').data('score'); 57 | match = false; 58 | for (var i = 0; i < scores.length; i++) { 59 | if (scores[i].key == answer) { 60 | match = true; 61 | break; 62 | } else { 63 | match = false; 64 | } 65 | } 66 | if (match == true) { 67 | for (var i = 0; i < scores.length; i++) { 68 | if(scores[i].key == answer) { 69 | scores[i].value ++; 70 | } 71 | } 72 | } else if (match == false) { 73 | scores.push({ 74 | key: answer, 75 | value: 1 76 | }) 77 | } 78 | if (currentQuestion != (input.length-1)) { 79 | currentQuestion++; 80 | buildQuiz(input); 81 | } 82 | } 83 | } 84 | 85 | function finalScore() { 86 | checkAnswer(); 87 | $('.quiz-container').html("

    This is your score

    "); 88 | for (var i = 0; i < scores.length; i++) { 89 | var percentage = (scores[i].value / (currentQuestion + 1)) * 100; 90 | $(".quiz-container").append("

    You are " + percentage + "% " + scores[i].key + "

    "); 91 | } 92 | } 93 | 94 | $(document).ready(function(){ 95 | getSpreadSheet(); 96 | }); -------------------------------------------------------------------------------- /source/stylesheets/quiz-fashion.css.scss: -------------------------------------------------------------------------------- 1 | // Mixin for button hover transitions 2 | @mixin transition($transition-time) { 3 | -o-transition: $transition-time; 4 | -ms-transition: $transition-time; 5 | -moz-transition: $transition-time; 6 | -webkit-transition: $transition-time; 7 | transition: $transition-time; 8 | } 9 | 10 | // Container for generated quiz 11 | .quiz-container { 12 | text-align: center; 13 | background-color: #ffffff; 14 | margin: 0% auto; 15 | width: 100%; 16 | max-width: 770px; 17 | margin-top: 20px; 18 | margin-bottom: 10px; 19 | padding-bottom: 60px; 20 | padding-top: 20px; 21 | } 22 | 23 | // Each quiz question 24 | .qq-question { 25 | font-size: 1.17em; 26 | max-width: 80%; 27 | margin: 0% auto; 28 | margin-top: 20px !important; 29 | line-height: 1.2; 30 | } 31 | 32 | // Description for each question 33 | .qq-description { 34 | font-size: 0.6em; 35 | font-weight: 300; 36 | text-align: left; 37 | line-height: 1.5; 38 | text-transform: none; 39 | font-style: normal; 40 | 41 | } 42 | 43 | // Padding for question text 44 | .question { 45 | padding-top: 10px; 46 | } 47 | 48 | // Shows user's progress throughout quiz (i.e. question 3/5) 49 | .progress { 50 | font-size: 11px; 51 | text-align: right; 52 | position: relative; 53 | right: 30px; 54 | } 55 | 56 | // Answer options (A, B, C, D) 57 | ol.answers { 58 | font-size: 0.9em; 59 | list-style-type: none; 60 | cursor: pointer; 61 | counter-reset: li-counter; 62 | position: relative; 63 | // width: 80%; 64 | // max-width: 500px; 65 | margin-bottom: 50px; 66 | padding: 0px; 67 | > li { 68 | &:before { 69 | font-size: 1em; 70 | text-align: center; 71 | cursor: pointer; 72 | content: counter(li-counter); 73 | counter-increment: li-counter; 74 | display: inline-block; 75 | width: 30px; 76 | margin-right: 10px; 77 | padding: 5px 0px 5px 0px; 78 | } 79 | @include transition(0.2s); 80 | text-align: left; 81 | margin: 20px 0px; 82 | } 83 | } 84 | 85 | // Button styles 86 | .qq-button { 87 | @include transition(0.2s); 88 | font-size: .9em; 89 | text-transform: uppercase; 90 | line-height: 1; 91 | display: inline-block; 92 | cursor: pointer; 93 | width: 160px; 94 | margin: 2px 5px; 95 | padding: .7em .7em .6em; 96 | border: 0; 97 | } 98 | 99 | .next:hover { 100 | background: transparent; 101 | } 102 | 103 | // Highlights selected answer 104 | .selected { 105 | background-color: #dfdfe0; 106 | font-weight: bold; 107 | } 108 | 109 | // Displays final scorecard 110 | .scorecard { 111 | display:block !important; 112 | } 113 | 114 | .score { 115 | font-size: .8em; 116 | float: right; 117 | padding-right: 7%; 118 | } 119 | 120 | // Social media buttons on final scorecard 121 | #social-media ul { 122 | text-align: center; 123 | list-style-type: none; 124 | margin: 0; 125 | padding: 0; 126 | margin-bottom: 10px; 127 | li { 128 | display: inline-block; 129 | a { 130 | text-decoration: none; 131 | svg { 132 | height: 2em; 133 | width: 3.4em; 134 | margin-right: 1em; 135 | } 136 | } 137 | } 138 | } 139 | 140 | // Submitted answer and feedback 141 | .answer { 142 | margin: 0% auto; 143 | width: 90%; 144 | max-width: 550px; 145 | margin-top: 20px !important; 146 | p { 147 | &:first-child { 148 | font-weight: bold; 149 | font-size: 1.2em; 150 | display: inline-block; 151 | width: 100%; 152 | padding-top: 30px; 153 | padding-bottom: 0px; 154 | border-top: 1px solid #000000; 155 | } 156 | &:nth-child(2) { 157 | margin: 0% auto; 158 | display: block; 159 | width: 100%; 160 | padding-top: 0px; 161 | padding-bottom: 20px; 162 | } 163 | } 164 | } 165 | 166 | // Text for each submitted answer 167 | .answer > p { 168 | margin: 0px 0px 20px 0px !important; 169 | } 170 | 171 | // Text on final scorecard 172 | .scorecard p { 173 | &:nth-child(1) { 174 | font-size: 1.2em; 175 | font-weight: bold; 176 | line-height: 1em !important; 177 | display: inline-block; 178 | margin-top: 45px; 179 | } 180 | &:nth-child(2) { 181 | font-size: 3em; 182 | font-weight: bold; 183 | margin-bottom: 40px; 184 | margin-top: 5px; 185 | } 186 | } -------------------------------------------------------------------------------- /source/stylesheets/quiz.css.scss: -------------------------------------------------------------------------------- 1 | // Mixin for button hover transitions 2 | @mixin transition($transition-time) { 3 | -o-transition: $transition-time; 4 | -ms-transition: $transition-time; 5 | -moz-transition: $transition-time; 6 | -webkit-transition: $transition-time; 7 | transition: $transition-time; 8 | } 9 | 10 | // Container for generated quiz 11 | .quiz-container { 12 | text-align: center; 13 | background-color: #ffffff; 14 | margin: 0% auto; 15 | width: 100%; 16 | max-width: 770px; 17 | margin-top: 20px; 18 | margin-bottom: 10px; 19 | padding-bottom: 60px; 20 | padding-top: 20px; 21 | } 22 | 23 | // Each quiz question 24 | .qq-question { 25 | font-size: 1.17em; 26 | max-width: 80%; 27 | margin: 0% auto; 28 | margin-top: 20px !important; 29 | line-height: 1.2; 30 | } 31 | 32 | // Description for each question 33 | .qq-description { 34 | font-size: 0.6em; 35 | font-weight: 300; 36 | text-align: left; 37 | line-height: 1.5; 38 | text-transform: none; 39 | font-style: normal; 40 | 41 | } 42 | 43 | // Padding for question text 44 | .question { 45 | padding-top: 10px; 46 | } 47 | 48 | // Shows user's progress throughout quiz (i.e. question 3/5) 49 | .progress { 50 | font-size: 11px; 51 | text-align: right; 52 | position: relative; 53 | right: 30px; 54 | } 55 | 56 | // Answer options (A, B, C, D) 57 | ol.answers { 58 | font-size: 0.9em; 59 | list-style-type: none; 60 | cursor: pointer; 61 | counter-reset: li-counter; 62 | position: relative; 63 | margin: 0px auto; 64 | width: 80%; 65 | max-width: 500px; 66 | margin-bottom: 50px; 67 | padding: 0px; 68 | > li { 69 | &:before { 70 | font-size: 1em; 71 | text-align: center; 72 | cursor: pointer; 73 | content: counter(li-counter); 74 | counter-increment: li-counter; 75 | display: inline-block; 76 | width: 30px; 77 | margin-right: 10px; 78 | padding: 5px 0px 5px 0px; 79 | } 80 | @include transition(0.2s); 81 | text-align: left; 82 | margin: 20px 0px; 83 | } 84 | } 85 | 86 | // Button styles 87 | .qq-button { 88 | @include transition(0.2s); 89 | font-size: .9em; 90 | text-transform: uppercase; 91 | line-height: 1; 92 | display: inline-block; 93 | cursor: pointer; 94 | width: 160px; 95 | margin: 2px 5px; 96 | padding: .7em .7em .6em; 97 | border: 0; 98 | } 99 | 100 | .next:hover { 101 | background: transparent; 102 | } 103 | 104 | // Highlights selected answer 105 | .selected { 106 | background-color: #dfdfe0; 107 | font-weight: bold; 108 | } 109 | 110 | // Displays final scorecard 111 | .scorecard { 112 | display:block !important; 113 | } 114 | 115 | .score { 116 | font-size: .8em; 117 | float: right; 118 | padding-right: 7%; 119 | } 120 | 121 | // Social media buttons on final scorecard 122 | #social-media ul { 123 | text-align: center; 124 | list-style-type: none; 125 | margin: 0; 126 | padding: 0; 127 | margin-bottom: 10px; 128 | li { 129 | display: inline-block; 130 | a { 131 | text-decoration: none; 132 | svg { 133 | height: 2em; 134 | width: 3.4em; 135 | margin-right: 1em; 136 | } 137 | } 138 | } 139 | } 140 | 141 | // Submitted answer and feedback 142 | .answer { 143 | margin: 0% auto; 144 | width: 90%; 145 | max-width: 550px; 146 | margin-top: 20px !important; 147 | p { 148 | &:first-child { 149 | font-weight: bold; 150 | font-size: 1.2em; 151 | display: inline-block; 152 | width: 100%; 153 | padding-top: 30px; 154 | padding-bottom: 0px; 155 | border-top: 1px solid #000000; 156 | } 157 | &:nth-child(2) { 158 | margin: 0% auto; 159 | display: block; 160 | width: 100%; 161 | padding-top: 0px; 162 | padding-bottom: 20px; 163 | } 164 | } 165 | } 166 | 167 | // Text for each submitted answer 168 | .answer > p { 169 | margin: 0px 0px 20px 0px !important; 170 | } 171 | 172 | // Text on final scorecard 173 | .scorecard p { 174 | &:nth-child(1) { 175 | font-size: 1.2em; 176 | font-weight: bold; 177 | line-height: 1em !important; 178 | display: inline-block; 179 | margin-top: 45px; 180 | } 181 | &:nth-child(2) { 182 | font-size: 3em; 183 | font-weight: bold; 184 | margin-bottom: 40px; 185 | margin-top: 5px; 186 | } 187 | } -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Quiz Quartet 2 | ========== 3 | 4 | Quiz Quartet was built to automate the process for generating a quiz so no developer has to be involved and write repetitive code! Check out the project at [http://quiz-generator.herokuapp.com](http://quiz-generator.herokuapp.com) 5 | 6 | 7 | ## Running it locally 8 | 9 | This app uses Middleman, so cd to your project directory and just run: 10 | 11 | ##### Install Middleman 12 | 13 | `gem install middleman` 14 | 15 | ##### Install gems 16 | 17 | `bundle install` 18 | 19 | ##### Run server 20 | 21 | `bundle exec middleman server` 22 | 23 | ##### Generate static site 24 | 25 | `bundle exec middleman build` 26 | 27 | 28 | ## How does the tool work? 29 | 30 | The quiz tool is powered by (you guessed it!) Google Spreadsheets. Editors use a Google Spreadsheet Template to input the content of the quiz. For each question, they enter the question text, four choices, an optional question description, the correct answer, incorrect message, correct message and a hint. Once the editor is done, they publish the spreadsheet to the web and grab its public URL. 31 | 32 | The editor then feeds the spreadsheet URL into our authoring tool, which uses Tabletop.js to collect the spreadsheet data. In order to make the tool more reliable, the authoring tool uses Tabletop.js to collect the spreadsheet data into a JSON object, which is then attached to the embed code. This means that the quiz embed code will need to be regenerated every time a change is made in the spreadsheet, but the quiz will be more stable since it does not rely on accessing Google Spreadsheets every time it loads. 33 | 34 | Next, the editor picks from one of Vox Media’s verticals (the tool currently supports Vox.com, SB Nation, The Verge, Polygon, Eater and Racked). A vertical-specific stylesheet URL is then generated, e.g. quiz-vox.css. The stylesheet, together with the quiz data, is parsed together with a script tag using the quiz.js library. All of these files are currently hosted on Amazon S3. Now, editors can copy and paste the embed code into the CMS and voilà -- an interactive quiz without touching any code! 35 | 36 | 37 | 38 | ## How does the quiz work? 39 | The quiz dynamically generates an array of multiple choice questions from a JSON object. Users’ answers are highlighted when selected, then the chosen string is compared to the correct answer. Users can also see a hint for each question. Scores are incremented if the user answers correctly, and the final result is displayed at the end of the quiz for users to share on social media. 40 | 41 | 42 | 43 | ## What’s next? 44 | The app is fully functional, but we would like to add more options for creating different kinds of quizzes (true/false, flowchart-ish). We’d also like to make options for inserting images/video/audio within questions, answers, and hints (as our project is currently completely text-based). We’d also like to polish/write better Javascript! 45 | 46 | 47 | ## License 48 | 49 | Copyright (c) 2014 Vox Media Inc., KK Rebecca Lai, Nicole Zhu, Adam Baumgartner 50 | 51 | BSD license 52 | 53 | Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 54 | 55 | 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 56 | 57 | 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 58 | 59 | 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. 60 | 61 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 62 | -------------------------------------------------------------------------------- /source/stylesheets/quiz-generator.css.scss: -------------------------------------------------------------------------------- 1 | // Font variables 2 | $font-stack: 'Open Sans', Helvetica, sans-serif; 3 | $orange: #f37b21; 4 | $black: #323132; 5 | $subheading-size: 0.8em; 6 | $bold: 800; 7 | 8 | // Sets background image and fonts 9 | body { 10 | font-family: $font-stack; 11 | color: #ffffff; 12 | color: $black; 13 | top: 0; 14 | left: 0; 15 | background-image: url(https://farm3.staticflickr.com/2906/14334201187_ec89d42b0a_o.jpg); 16 | background-repeat: repeat; 17 | background-attachment: fixed; 18 | background-position: center bottom; 19 | background-size: 100%; 20 | margin: 0px !important; 21 | margin-right: 0px; 22 | padding: 0px; 23 | } 24 | 25 | // Positioning Vox logo in upper right corner 26 | .vox-logo { 27 | position: absolute; 28 | top: 20px; 29 | left: 20px; 30 | z-index: 6; 31 | &:hover { 32 | opacity: 0.7; 33 | } 34 | } 35 | 36 | // Quiz Quartet text and icon positioning 37 | .quiz-quartet h1 { 38 | font-family: $font-stack; 39 | font-weight: $bold; 40 | font-size: 4em; 41 | color: #ffffff; 42 | text-align: center; 43 | z-index: 3 !important; 44 | margin: 0; 45 | padding: 50px 0px 50px 0px; 46 | > img { 47 | width: 56px; 48 | margin-bottom: -9px; 49 | } 50 | } 51 | 52 | // Container for quiz generator 53 | .container { 54 | position: relative; 55 | z-index: 10!important; 56 | background-color: #ffffff; 57 | margin: 0px; 58 | padding: 0px !important; 59 | } 60 | 61 | // Subheadings for quiz generator steps 62 | h5 { 63 | font-family: $font-stack; 64 | font-weight: $bold; 65 | font-size: $subheading-size; 66 | color: #000000; 67 | text-align: left; 68 | text-transform: uppercase; 69 | display: block; 70 | width: 70%; 71 | margin: 0% auto; 72 | margin-top: 60px; 73 | margin-bottom: 30px; 74 | padding: 5px 0% 5px 0%; 75 | border-bottom: 2px solid $orange; 76 | } 77 | 78 | // Text dividers (create quiz, preview quiz) 79 | h4 { 80 | font-family: $font-stack; 81 | font-weight: $bold; 82 | text-transform: uppercase; 83 | font-size: $subheading-size; 84 | color: #ffffff; 85 | text-align: left; 86 | width: 85%; 87 | display: block; 88 | background-color: $orange; 89 | padding: 5px 0px 5px 15%; 90 | border: 0px; 91 | &:first-child { 92 | margin: 0px 0px 30px 0px; 93 | } 94 | &:last-child { 95 | margin: 60px 0px 0px 0px; 96 | } 97 | } 98 | 99 | // Text under each subheading 100 | p { 101 | color: $black; 102 | display: block; 103 | width: 70%; 104 | margin: 0% auto; 105 | margin-bottom: 15px; 106 | } 107 | 108 | // Options for different verticals' stylesheets 109 | form { 110 | color: $black; 111 | display: block; 112 | width: 70%; 113 | margin: 0% auto; 114 | margin-bottom: 15px; 115 | padding-bottom: 20px; 116 | } 117 | 118 | // Links style 119 | a { 120 | text-decoration: none; 121 | -o-transition: .1s; 122 | -ms-transition: .1s; 123 | -moz-transition: .1s; 124 | -webkit-transition: .1s; 125 | transition: .1s; 126 | &:hover { 127 | color: #404041; 128 | } 129 | } 130 | 131 | // Link to quiz templates 132 | .template { 133 | background-color: #F37B21; 134 | color: #FFFFFF; 135 | } 136 | 137 | // 'Generate Your Quiz' button 138 | button { 139 | font-family: Helvetica; 140 | font-weight: lighter; 141 | font-size: 0.9em; 142 | text-decoration: none; 143 | text-transform: uppercase; 144 | color: #fff; 145 | text-align: center; 146 | width: 225px; 147 | background-color: #f27421; 148 | display: inline-block; 149 | cursor: pointer; 150 | margin: 0% auto; 151 | margin-top: 15px; 152 | padding: 12px 0px; 153 | padding: 8px 20px; 154 | border: 0; 155 | -o-transition: .2s; 156 | -ms-transition: .2s; 157 | -moz-transition: .2s; 158 | -webkit-transition: .2s; 159 | transition: .2s; 160 | &:hover { 161 | background-color: #404041; 162 | } 163 | } 164 | 165 | label { 166 | margin: 0 10px 0 5px; 167 | } 168 | 169 | // Preview of generated quiz 170 | .quiz-preview { 171 | background-color: transparent; 172 | z-index: 6!important; 173 | padding: 75px 0px 30px 0px; 174 | } 175 | 176 | // Embed code textarea 177 | textarea { 178 | color: #ffffff; 179 | background-color: #58585b; 180 | width: 74%; 181 | padding: 10px; 182 | border: 0px; 183 | } 184 | 185 | // Input for public spreadsheet URL to generate quiz 186 | #url { 187 | color: #ffffff; 188 | background-color: #58585b; 189 | width: 200px; 190 | padding: 2px; 191 | border: 0px; 192 | } -------------------------------------------------------------------------------- /source/javascripts/getdata.js: -------------------------------------------------------------------------------- 1 | (function ($) { 2 | var key, pub, quizType; 3 | 4 | // initialize tabletop library 5 | function init() { 6 | Tabletop.init( { key: url, 7 | callback: readData, 8 | simpleSheet: true } ); 9 | } 10 | 11 | function readData(data, tabletop) { 12 | input = []; 13 | for ( var i = 0; i < data.length; i++ ) { 14 | input[i] = findUrlinObject( data[i] ); 15 | } 16 | console.log(input); 17 | embed(input); 18 | } 19 | 20 | function findUrlinObject ( data ) { 21 | $.each( data, function( key, value ){ 22 | if ( key == 'correct' || key == 'incorrect' || key == 'text') { 23 | data[key] = converttoHex( data[key] ); 24 | } 25 | } ); 26 | return data; 27 | } 28 | 29 | function converttoHex ( string ) { 30 | var hex, i; 31 | var result = ""; 32 | for ( i = 0; i < string.length; i++ ) { 33 | hex = string.charCodeAt( i ).toString( 16 ); 34 | result += ( "000" + hex ).slice( -4 ); 35 | } 36 | return result; 37 | } 38 | 39 | function addJS() { 40 | quizType = $('input[name="quiz-type"]:checked').val(); 41 | if (quizType == 'quiz') { 42 | $('body').append(''); 77 | pubStylesheet = "http://assets.sbnation.com.s3.amazonaws.com/features/quiz-generator/quiz-" + pub + ".css"; 78 | // pubStylesheet = "/stylesheets/quiz-" + pub + ".css"; 79 | } 80 | 81 | function embed(input) { 82 | $("#embedcode").html("<div class='quiz-container'><script type='text/javascript'>window.jQuery || document.write(\"<script src='//ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js'><\/script>\");</script><script type='text/javascript'>var input = " + JSON.stringify(input) + "; var pubStylesheet = '" + pubStylesheet + "'; var pub = '" + pub + "'; </script><script src='http://assets.sbnation.com.s3.amazonaws.com/features/quiz-generator/" + quizType + ".js'></script>"); 83 | // $("#embedcode").html("<div class='quiz-container'><script type='text/javascript'>window.jQuery || document.write('<script src='//ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js'><\/script>');</script><script type='text/javascript'>var input = " + JSON.stringify(input) + "; var pubStylesheet = '" + pubStylesheet + "';</script><script src='/javascripts/" + quizType + ".js'></script>"); 84 | addJS(); 85 | } 86 | 87 | function buildquiz(){ 88 | url = $('#url').val(); 89 | init(); 90 | getStylesheet(); 91 | } 92 | 93 | function buildflowchart() { 94 | url = $('#url').val(); 95 | init(); 96 | getStylesheet(); 97 | } 98 | 99 | $(document).ready(function() { 100 | $('input:radio[name=quiz-type]').click(function() { 101 | quizType = $('input:radio[name=quiz-type]:checked').val(); 102 | changeTemplate(); 103 | }); 104 | 105 | $('#build').on('click', function(){ 106 | if (quizType != undefined) { 107 | submitquiz(); 108 | } 109 | else { 110 | alert("Please choose a quiz type at the top of the page!"); 111 | } 112 | }) 113 | }) 114 | })(jQuery); -------------------------------------------------------------------------------- /source/demo.html.erb: -------------------------------------------------------------------------------- 1 |
    2 |

    Demo

    3 | 4 |
    -------------------------------------------------------------------------------- /source/javascripts/binary.js: -------------------------------------------------------------------------------- 1 | (function ($) { 2 | // make sure to attach json object 'var input' with quiz data 3 | 4 | //variables 5 | var answer, 6 | qnumber, 7 | score = 0, 8 | currentQuestion = 0; 9 | 10 | // social media icons 11 | var facebook = "Facebook"; 12 | var twitter = "Twitter"; 13 | var google = "Google+"; 14 | 15 | // twitter links 16 | var account; 17 | var voxdotcom = 'voxdotcom'; 18 | var theverge = 'verge'; 19 | var polygon = 'polygon'; 20 | var sbnation = 'SBNation'; 21 | var eater = 'Eater'; 22 | var racked = 'Racked'; 23 | 24 | var pageScroll = function(target) { 25 | $('html,body').animate({ 26 | scrollTop: $(target).offset().top - 30 27 | }, 1000); 28 | }; 29 | 30 | // write questions and answers on html 31 | var buildQuiz = function (input) { 32 | if (currentQuestion != 0) { 33 | pageScroll('.quiz-container'); 34 | } 35 | qnumber = currentQuestion + 1; 36 | $(".quiz-container").html("
    Question " + qnumber + " of " + input.length + "
    " + input[currentQuestion].description + "

    " + input[currentQuestion].question + "
    " + 37 | "
    1. " + input[currentQuestion].a + "
    2. " + 38 | "
    3. " + input[currentQuestion].b + "
    " + 39 | "" + 40 | "" + 41 | "
    "); 42 | selectAnswer(); 43 | $('.hint').on('click', showHint); 44 | $('.submit-answer').on('click', checkAnswer); 45 | trackEvent('q' + qnumber + '-displayed', 'Q' + qnumber + ' displayed'); 46 | } 47 | 48 | // shows (1) out of (3) questinos 49 | var displayProgress = function () { 50 | $('.progress').html("
    Question " + qnumber + " of " + input.length + "
    "); 51 | } 52 | 53 | // style changes when user selects answers 54 | var selectAnswer = function () { 55 | $("li").click(function() { 56 | trackEvent( 57 | 'q' + qnumber + '-selected-' + this.id, 58 | 'Q' + qnumber + ' selected ' + this.id); 59 | $(".selected").removeClass("selected"); 60 | $(this).addClass("selected"); 61 | $(".submit-answer").addClass("submit-highlight").fadeIn(); 62 | }); 63 | } 64 | 65 | // show hint 66 | var showHint = function () { 67 | trackEvent( 68 | 'q' + qnumber + '-hint-showed', 69 | 'Q' + qnumber + ' hint showed'); 70 | $(".answer").html(input[currentQuestion].hint); 71 | } 72 | 73 | // check answer by comparing selected html and correct answer from input 74 | var checkAnswer = function () { 75 | if ($(".selected").length > 0) { 76 | $('li').off('click'); 77 | $(".hint").off('click'); 78 | answer = $(".selected").html(); 79 | if (answer == input[currentQuestion].answer) { 80 | trackEvent( 81 | 'q' + qnumber + '-answered-correctly', 82 | 'Q' + qnumber + ' answered correctly'); 83 | score++; 84 | displayProgress(); 85 | $(".answer").html("

    Correct!

    " + input[currentQuestion].correct + "

    "); 86 | 87 | } else { 88 | trackEvent( 89 | 'q' + qnumber + '-answered-incorrectly', 90 | 'Q' + qnumber + ' answered incorrectly'); 91 | $(".answer").html("

    Sorry!

    " + input[currentQuestion].incorrect + " The correct answer is " + input[currentQuestion].answer + ".

    "); 92 | } 93 | if (currentQuestion != (input.length-1)) { 94 | $(".answer").append(""); 95 | $('.next').on('click', nextQuestion); 96 | } else { 97 | $(".answer").append(""); 98 | $('.check-score').on('click', finalScore); 99 | } 100 | } 101 | } 102 | 103 | // increment question count and built new question and answers 104 | var nextQuestion = function () { 105 | trackEvent( 106 | 'q' + qnumber + '-next', 107 | 'Q' + qnumber + ' clicked to next question'); 108 | currentQuestion++; 109 | buildQuiz(input); 110 | } 111 | 112 | function trackEvent(action, label) { 113 | if( typeof(ga) != 'undefined' ) { 114 | ga('send', 'event', 'quiz', action, label); 115 | } else if (typeof(_gaq) != 'undefined' ){ 116 | _gaq.push($.merge(['_trackEvent', 'quiz'], arguments)); 117 | } 118 | } 119 | 120 | // display final score card and social media sharing 121 | var link = document.URL 122 | var finalScore = function () { 123 | trackEvent( 124 | 'scored-' + score + '-of-' + input.length, 125 | 'Scored ' + score + ' of ' + input.length); 126 | trackEvent('completed', 'Quiz completed'); 127 | switch (pub) { 128 | case 'vox': 129 | account = voxdotcom; 130 | break; 131 | case 'sbnation': 132 | account = sbnation; 133 | break; 134 | case 'verge': 135 | account = theverge; 136 | break; 137 | case 'polygon': 138 | account = polygon; 139 | break; 140 | case 'eater': 141 | account = eater; 142 | break; 143 | case 'racked': 144 | account = racked; 145 | break; 146 | default: 147 | account = 'voxproduct'; 148 | } 149 | 150 | $(".quiz-container") 151 | .html("

    You correctly answered

    " + score + " out of " + input.length + "

    Challenge your friends!

    "); 152 | $('.quiz-container .fb-share').click(function() { 153 | trackEvent('shared-on-fb', 'Quiz shared on Facebook'); 154 | }); 155 | $('.quiz-container .twitter-share').click(function() { 156 | trackEvent('shared-on-twitter', 'Quiz shared on Twitter'); 157 | }); 158 | $('.quiz-container .gplus-share').click(function() { 159 | trackEvent('shared-on-gplus', 'Quiz shared on Google+'); 160 | }); 161 | } 162 | 163 | // attach quiz and vertical-specific stylesheets 164 | $('head').append(''); 165 | //$('head').append(''); 166 | $('head').append(''); 167 | 168 | function unpackQuizHack() { 169 | var newInput = []; 170 | for ( var i = 0; i < input.length; i++ ) { 171 | newInput[i] = convertUrlinJson( input[i] ); 172 | } 173 | input = newInput; 174 | buildQuiz(input); 175 | } 176 | 177 | function convertUrlinJson( data ) { 178 | $.each( data, function( key, value ) { 179 | if ( key == 'correct' || key == 'incorrect' ) { 180 | var j; 181 | var hexes = data[key].match(/.{1,4}/g) || []; 182 | var back = ""; 183 | for( j = 0; jQuestion " + qnumber + " of " + input.length + "
    " + input[currentQuestion].description + "

    " + input[currentQuestion].question + "
    " + 37 | "
    1. " + input[currentQuestion].a + "
    2. " + 38 | "
    3. " + input[currentQuestion].b + "
    4. " + 39 | "
    5. " + input[currentQuestion].c + "
    6. " + 40 | "
    7. " + input[currentQuestion].d + "
    " + 41 | "" + 42 | "" + 43 | "
    "); 44 | selectAnswer(); 45 | $('.hint').on('click', showHint); 46 | $('.submit-answer').on('click', checkAnswer); 47 | trackEvent('q' + qnumber + '-displayed', 'Q' + qnumber + ' displayed'); 48 | } 49 | 50 | // shows (1) out of (3) questinos 51 | var displayProgress = function () { 52 | $('.progress').html("
    Question " + qnumber + " of " + input.length + "
    "); 53 | } 54 | 55 | // style changes when user selects answers 56 | var selectAnswer = function () { 57 | $("li").click(function() { 58 | trackEvent( 59 | 'q' + qnumber + '-selected-' + this.id, 60 | 'Q' + qnumber + ' selected ' + this.id); 61 | $(".selected").removeClass("selected"); 62 | $(this).addClass("selected"); 63 | $(".submit-answer").addClass("submit-highlight").fadeIn(); 64 | }); 65 | } 66 | 67 | // show hint 68 | var showHint = function () { 69 | trackEvent( 70 | 'q' + qnumber + '-hint-showed', 71 | 'Q' + qnumber + ' hint showed'); 72 | $(".answer").html(input[currentQuestion].hint); 73 | } 74 | 75 | // check answer by comparing selected html and correct answer from input 76 | var checkAnswer = function () { 77 | if ($(".selected").length > 0) { 78 | $('li').off('click'); 79 | $(".hint").off('click'); 80 | answer = $(".selected").html(); 81 | if (answer == input[currentQuestion].answer) { 82 | trackEvent( 83 | 'q' + qnumber + '-answered-correctly', 84 | 'Q' + qnumber + ' answered correctly'); 85 | score++; 86 | displayProgress(); 87 | $(".answer").html("

    Correct!

    " + input[currentQuestion].correct + "

    "); 88 | 89 | } else { 90 | trackEvent( 91 | 'q' + qnumber + '-answered-incorrectly', 92 | 'Q' + qnumber + ' answered incorrectly'); 93 | $(".answer").html("

    Sorry!

    " + input[currentQuestion].incorrect + " The correct answer is " + input[currentQuestion].answer + ".

    "); 94 | } 95 | if (currentQuestion != (input.length-1)) { 96 | $(".answer").append(""); 97 | $('.next').on('click', nextQuestion); 98 | } else { 99 | $(".answer").append(""); 100 | $('.check-score').on('click', finalScore); 101 | } 102 | } 103 | } 104 | 105 | // increment question count and built new question and answers 106 | var nextQuestion = function () { 107 | trackEvent( 108 | 'q' + qnumber + '-next', 109 | 'Q' + qnumber + ' clicked to next question'); 110 | currentQuestion++; 111 | buildQuiz(input); 112 | } 113 | 114 | function trackEvent(action, label) { 115 | if( typeof(ga) != 'undefined' ) { 116 | ga('send', 'event', 'quiz', action, label); 117 | } else if (typeof(_gaq) != 'undefined' ){ 118 | _gaq.push($.merge(['_trackEvent', 'quiz'], arguments)); 119 | } 120 | } 121 | 122 | // display final score card and social media sharing 123 | var link = document.URL 124 | var finalScore = function () { 125 | trackEvent( 126 | 'scored-' + score + '-of-' + input.length, 127 | 'Scored ' + score + ' of ' + input.length); 128 | trackEvent('completed', 'Quiz completed'); 129 | switch (pub) { 130 | case 'vox': 131 | account = voxdotcom; 132 | break; 133 | case 'sbnation': 134 | account = sbnation; 135 | break; 136 | case 'verge': 137 | account = theverge; 138 | break; 139 | case 'polygon': 140 | account = polygon; 141 | break; 142 | case 'eater': 143 | account = eater; 144 | break; 145 | case 'racked': 146 | account = racked; 147 | break; 148 | default: 149 | account = 'voxproduct'; 150 | } 151 | 152 | $(".quiz-container") 153 | .html("

    You correctly answered

    " + score + " out of " + input.length + "

    Challenge your friends!

    "); 154 | $('.quiz-container .fb-share').click(function() { 155 | trackEvent('shared-on-fb', 'Quiz shared on Facebook'); 156 | }); 157 | $('.quiz-container .twitter-share').click(function() { 158 | trackEvent('shared-on-twitter', 'Quiz shared on Twitter'); 159 | }); 160 | $('.quiz-container .gplus-share').click(function() { 161 | trackEvent('shared-on-gplus', 'Quiz shared on Google+'); 162 | }); 163 | } 164 | 165 | // attach quiz and vertical-specific stylesheets 166 | $('head').append(''); 167 | //$('head').append(''); 168 | $('head').append(''); 169 | 170 | function unpackQuizHack() { 171 | var newInput = []; 172 | for ( var i = 0; i < input.length; i++ ) { 173 | newInput[i] = convertUrlinJson( input[i] ); 174 | } 175 | input = newInput; 176 | buildQuiz(input); 177 | } 178 | 179 | function convertUrlinJson( data ) { 180 | $.each( data, function( key, value ) { 181 | if ( key == 'correct' || key == 'incorrect' ) { 182 | var j; 183 | var hexes = data[key].match(/.{1,4}/g) || []; 184 | var back = ""; 185 | for( j = 0; j↓'); 36 | $('.flowchart-button').attr('disabled', true); 37 | slug = newslug; 38 | buildQuestion(slug); 39 | }; 40 | 41 | // clean slug 42 | var cleanSlug = function(slug) { 43 | slug = slug.replace(/[^a-zA-Z0-9]/g, '').toLowerCase(); 44 | return slug; 45 | }; 46 | 47 | var compareSlug = function(slug) { 48 | for (var i = 0; i < input.length; i++) { 49 | currentSlug = cleanSlug(input[i].slug); 50 | if (currentSlug == slug) { 51 | currentRow = i; 52 | break; 53 | } 54 | } 55 | }; 56 | 57 | // build question in flowchart - scrolldown enabled for all questions except the last one 58 | var buildQuestion = function(slug) { 59 | compareSlug(slug); 60 | if (currentRow === 0) { 61 | $(".quiz-container").append("
    " + input[currentRow].text + "
    "); 62 | } else { 63 | if ($(window).width() > 500) { 64 | $(".quiz-container").append(""); 65 | $(".question-" + (questionNumber)).fadeIn('slow'); 66 | } else { 67 | $(".quiz-container").append("
    " + input[currentRow].text + "
    "); 68 | pageScroll(".question-" + (questionNumber)); 69 | } 70 | } 71 | writeOptions(currentRow); 72 | trackEvent('q' + questionNumber + '-displayed', 'Q' + questionNumber + ' displayed'); 73 | }; 74 | 75 | // write possible options to each question, handles multiple options 76 | var writeOptions = function(currentRow) { 77 | var row = input[currentRow]; 78 | var connectsLabels = row.connectstext.split(separator); 79 | connectsTo = row.connectsto.split(separator); 80 | if (connectsTo[0] == 'End') { 81 | $('.question-' + questionNumber).fadeIn(400); 82 | lastQuestion(); 83 | } else { 84 | for (var i = 0; i < connectsLabels.length; i ++) { 85 | $('.question-' + questionNumber).append(""); 86 | $('.choice-' + questionNumber + '-' + i).on('click', getClass); 87 | } 88 | $('.question-' + questionNumber).fadeIn(400); 89 | questionNumber++; 90 | } 91 | }; 92 | 93 | var getClass = function () { 94 | var classes = $(this).attr('class').split(' '); 95 | number = classes[classes.length - 1].split('-'); 96 | getSlug(cleanSlug(connectsTo[number[number.length- 1]]), this); 97 | }; 98 | 99 | // handles last question and social media sharing buttons 100 | var lastQuestion = function() { 101 | for (var i = 0; i < input.length; i++) { 102 | input[i].slug = cleanSlug(input[i].slug); 103 | if (input[i].slug == 'end') { 104 | lastRow = i; 105 | break; 106 | } 107 | } 108 | $('.question-' + questionNumber).append('

    ' + input[lastRow].text + '


    '); 109 | $('.quiz-container').append('
    '); 110 | shareQuiz(); 111 | trackEvent('completed', 'Flowchart completed'); 112 | $('.restart').on('click', restart); 113 | }; 114 | 115 | // restarts flowchart from beginning 116 | var restart = function() { 117 | $('.quiz-container').empty(); 118 | pageScroll('.quiz-container'); 119 | questionNumber = 0; 120 | slug = input[0].slug; 121 | buildQuestion(slug); 122 | trackEvent('restart', 'Flowchart restarted'); 123 | }; 124 | 125 | function trackEvent(action, label) { 126 | if( typeof(ga) != 'undefined' ) { 127 | ga('send', 'event', 'flowchart', action, label); 128 | } else if (typeof(_gaq) != 'undefined' ){ 129 | _gaq.push($.merge(['_trackEvent', 'flowchart'], arguments)); 130 | } 131 | } 132 | 133 | // social media sharing 134 | var link = document.URL; 135 | var shareQuiz = function() { 136 | switch (pub) { 137 | case 'vox': 138 | account = voxdotcom; 139 | break; 140 | case 'sbnation': 141 | account = sbnation; 142 | break; 143 | case 'verge': 144 | account = theverge; 145 | break; 146 | case 'polygon': 147 | account = polygon; 148 | break; 149 | default: 150 | account = 'voxproduct'; 151 | } 152 | $(".quiz-container").append("
    "); 153 | 154 | $('.quiz-container .fb-share').click(function() { 155 | trackEvent('shared-on-fb', 'Quiz shared on Facebook'); 156 | }); 157 | $('.quiz-container .twitter-share').click(function() { 158 | trackEvent('shared-on-twitter', 'Quiz shared on Twitter'); 159 | }); 160 | $('.quiz-container .gplus-share').click(function() { 161 | trackEvent('shared-on-gplus', 'Quiz shared on Google+'); 162 | }); 163 | }; 164 | 165 | // attach quiz and vertical-specific stylesheets 166 | $('head').append(''); 167 | // $('head').append(''); 168 | $('head').append(''); 169 | 170 | function unpackQuizHack() { 171 | var newInput = []; 172 | for ( var i = 0; i < input.length; i++ ) { 173 | newInput[i] = convertUrlinJson( input[i] ); 174 | } 175 | input = newInput; 176 | slug = input[0].slug; 177 | slug = cleanSlug(slug); 178 | buildQuestion(slug); 179 | } 180 | 181 | function convertUrlinJson( data ) { 182 | $.each( data, function( key, value ) { 183 | if ( key == 'correct' || key == 'incorrect' || key =='text') { 184 | var j; 185 | var hexes = data[key].match(/.{1,4}/g) || []; 186 | var back = ""; 187 | for( j = 0; j 1 && this.debug) { 277 | this.log("WARNING You have more than one sheet but are using simple sheet mode! Don't blame me when something goes wrong."); 278 | } 279 | return this.models[ this.model_names[0] ].all(); 280 | } else { 281 | return this.models; 282 | } 283 | }, 284 | 285 | /* 286 | Add another sheet to the wanted list 287 | */ 288 | addWanted: function(sheet) { 289 | if(ttIndexOf(this.wanted, sheet) === -1) { 290 | this.wanted.push(sheet); 291 | } 292 | }, 293 | 294 | /* 295 | Load all worksheets of the spreadsheet, turning each into a Tabletop Model. 296 | Need to use injectScript because the worksheet view that you're working from 297 | doesn't actually include the data. The list-based feed (/feeds/list/key..) does, though. 298 | Calls back to loadSheet in order to get the real work done. 299 | 300 | Used as a callback for the worksheet-based JSON 301 | */ 302 | loadSheets: function(data) { 303 | var i, ilen; 304 | var toLoad = []; 305 | this.foundSheetNames = []; 306 | 307 | for(i = 0, ilen = data.feed.entry.length; i < ilen ; i++) { 308 | this.foundSheetNames.push(data.feed.entry[i].title.$t); 309 | // Only pull in desired sheets to reduce loading 310 | if( this.isWanted(data.feed.entry[i].content.$t) ) { 311 | var linkIdx = data.feed.entry[i].link.length-1; 312 | var sheet_id = data.feed.entry[i].link[linkIdx].href.split('/').pop(); 313 | var json_path = "/feeds/list/" + this.key + "/" + sheet_id + "/public/values?alt=" 314 | if (inNodeJS || supportsCORS) { 315 | json_path += 'json'; 316 | } else { 317 | json_path += 'json-in-script'; 318 | } 319 | if(this.query) { 320 | json_path += "&sq=" + this.query; 321 | } 322 | if(this.orderby) { 323 | json_path += "&orderby=column:" + this.orderby.toLowerCase(); 324 | } 325 | if(this.reverse) { 326 | json_path += "&reverse=true"; 327 | } 328 | toLoad.push(json_path); 329 | } 330 | } 331 | 332 | this.sheetsToLoad = toLoad.length; 333 | for(i = 0, ilen = toLoad.length; i < ilen; i++) { 334 | this.requestData(toLoad[i], this.loadSheet); 335 | } 336 | }, 337 | 338 | /* 339 | Access layer for the this.models 340 | .sheets() gets you all of the sheets 341 | .sheets('Sheet1') gets you the sheet named Sheet1 342 | */ 343 | sheets: function(sheetName) { 344 | if(typeof sheetName === "undefined") { 345 | return this.models; 346 | } else { 347 | if(typeof(this.models[ sheetName ]) === "undefined") { 348 | // alert( "Can't find " + sheetName ); 349 | return; 350 | } else { 351 | return this.models[ sheetName ]; 352 | } 353 | } 354 | }, 355 | 356 | /* 357 | Parse a single list-based worksheet, turning it into a Tabletop Model 358 | 359 | Used as a callback for the list-based JSON 360 | */ 361 | loadSheet: function(data) { 362 | var model = new Tabletop.Model( { data: data, 363 | parseNumbers: this.parseNumbers, 364 | postProcess: this.postProcess, 365 | tabletop: this } ); 366 | this.models[ model.name ] = model; 367 | if(ttIndexOf(this.model_names, model.name) === -1) { 368 | this.model_names.push(model.name); 369 | } 370 | this.sheetsToLoad--; 371 | if(this.sheetsToLoad === 0) 372 | this.doCallback(); 373 | }, 374 | 375 | /* 376 | Execute the callback upon loading! Rely on this.data() because you might 377 | only request certain pieces of data (i.e. simpleSheet mode) 378 | Tests this.sheetsToLoad just in case a race condition happens to show up 379 | */ 380 | doCallback: function() { 381 | if(this.sheetsToLoad === 0) { 382 | this.callback.apply(this.callbackContext || this, [this.data(), this]); 383 | } 384 | }, 385 | 386 | log: function(msg) { 387 | if(this.debug) { 388 | if(typeof console !== "undefined" && typeof console.log !== "undefined") { 389 | Function.prototype.apply.apply(console.log, [console, arguments]); 390 | } 391 | } 392 | } 393 | 394 | }; 395 | 396 | /* 397 | Tabletop.Model stores the attribute names and parses the worksheet data 398 | to turn it into something worthwhile 399 | 400 | Options should be in the format { data: XXX }, with XXX being the list-based worksheet 401 | */ 402 | Tabletop.Model = function(options) { 403 | var i, j, ilen, jlen; 404 | this.column_names = []; 405 | this.name = options.data.feed.title.$t; 406 | this.elements = []; 407 | this.raw = options.data; // A copy of the sheet's raw data, for accessing minutiae 408 | 409 | if(typeof(options.data.feed.entry) === 'undefined') { 410 | options.tabletop.log("Missing data for " + this.name + ", make sure you didn't forget column headers"); 411 | this.elements = []; 412 | return; 413 | } 414 | 415 | for(var key in options.data.feed.entry[0]){ 416 | if(/^gsx/.test(key)) 417 | this.column_names.push( key.replace("gsx$","") ); 418 | } 419 | 420 | for(i = 0, ilen = options.data.feed.entry.length ; i < ilen; i++) { 421 | var source = options.data.feed.entry[i]; 422 | var element = {}; 423 | for(var j = 0, jlen = this.column_names.length; j < jlen ; j++) { 424 | var cell = source[ "gsx$" + this.column_names[j] ]; 425 | if (typeof(cell) !== 'undefined') { 426 | if(options.parseNumbers && cell.$t !== '' && !isNaN(cell.$t)) 427 | element[ this.column_names[j] ] = +cell.$t; 428 | else 429 | element[ this.column_names[j] ] = cell.$t; 430 | } else { 431 | element[ this.column_names[j] ] = ''; 432 | } 433 | } 434 | if(element.rowNumber === undefined) 435 | element.rowNumber = i + 1; 436 | if( options.postProcess ) 437 | options.postProcess(element); 438 | this.elements.push(element); 439 | } 440 | 441 | }; 442 | 443 | Tabletop.Model.prototype = { 444 | /* 445 | Returns all of the elements (rows) of the worksheet as objects 446 | */ 447 | all: function() { 448 | return this.elements; 449 | }, 450 | 451 | /* 452 | Return the elements as an array of arrays, instead of an array of objects 453 | */ 454 | toArray: function() { 455 | var array = [], 456 | i, j, ilen, jlen; 457 | for(i = 0, ilen = this.elements.length; i < ilen; i++) { 458 | var row = []; 459 | for(j = 0, jlen = this.column_names.length; j < jlen ; j++) { 460 | row.push( this.elements[i][ this.column_names[j] ] ); 461 | } 462 | array.push(row); 463 | } 464 | return array; 465 | } 466 | }; 467 | 468 | if(inNodeJS) { 469 | module.exports = Tabletop; 470 | } else { 471 | global.Tabletop = Tabletop; 472 | } 473 | 474 | })(this); 475 | -------------------------------------------------------------------------------- /source/javascripts/jquery.min.js: -------------------------------------------------------------------------------- 1 | /*! jQuery v1.11.1 | (c) 2005, 2014 jQuery Foundation, Inc. | jquery.org/license */ 2 | !function(a,b){"object"==typeof module&&"object"==typeof module.exports?module.exports=a.document?b(a,!0):function(a){if(!a.document)throw new Error("jQuery requires a window with a document");return b(a)}:b(a)}("undefined"!=typeof window?window:this,function(a,b){var c=[],d=c.slice,e=c.concat,f=c.push,g=c.indexOf,h={},i=h.toString,j=h.hasOwnProperty,k={},l="1.11.1",m=function(a,b){return new m.fn.init(a,b)},n=/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,o=/^-ms-/,p=/-([\da-z])/gi,q=function(a,b){return b.toUpperCase()};m.fn=m.prototype={jquery:l,constructor:m,selector:"",length:0,toArray:function(){return d.call(this)},get:function(a){return null!=a?0>a?this[a+this.length]:this[a]:d.call(this)},pushStack:function(a){var b=m.merge(this.constructor(),a);return b.prevObject=this,b.context=this.context,b},each:function(a,b){return m.each(this,a,b)},map:function(a){return this.pushStack(m.map(this,function(b,c){return a.call(b,c,b)}))},slice:function(){return this.pushStack(d.apply(this,arguments))},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},eq:function(a){var b=this.length,c=+a+(0>a?b:0);return this.pushStack(c>=0&&b>c?[this[c]]:[])},end:function(){return this.prevObject||this.constructor(null)},push:f,sort:c.sort,splice:c.splice},m.extend=m.fn.extend=function(){var a,b,c,d,e,f,g=arguments[0]||{},h=1,i=arguments.length,j=!1;for("boolean"==typeof g&&(j=g,g=arguments[h]||{},h++),"object"==typeof g||m.isFunction(g)||(g={}),h===i&&(g=this,h--);i>h;h++)if(null!=(e=arguments[h]))for(d in e)a=g[d],c=e[d],g!==c&&(j&&c&&(m.isPlainObject(c)||(b=m.isArray(c)))?(b?(b=!1,f=a&&m.isArray(a)?a:[]):f=a&&m.isPlainObject(a)?a:{},g[d]=m.extend(j,f,c)):void 0!==c&&(g[d]=c));return g},m.extend({expando:"jQuery"+(l+Math.random()).replace(/\D/g,""),isReady:!0,error:function(a){throw new Error(a)},noop:function(){},isFunction:function(a){return"function"===m.type(a)},isArray:Array.isArray||function(a){return"array"===m.type(a)},isWindow:function(a){return null!=a&&a==a.window},isNumeric:function(a){return!m.isArray(a)&&a-parseFloat(a)>=0},isEmptyObject:function(a){var b;for(b in a)return!1;return!0},isPlainObject:function(a){var b;if(!a||"object"!==m.type(a)||a.nodeType||m.isWindow(a))return!1;try{if(a.constructor&&!j.call(a,"constructor")&&!j.call(a.constructor.prototype,"isPrototypeOf"))return!1}catch(c){return!1}if(k.ownLast)for(b in a)return j.call(a,b);for(b in a);return void 0===b||j.call(a,b)},type:function(a){return null==a?a+"":"object"==typeof a||"function"==typeof a?h[i.call(a)]||"object":typeof a},globalEval:function(b){b&&m.trim(b)&&(a.execScript||function(b){a.eval.call(a,b)})(b)},camelCase:function(a){return a.replace(o,"ms-").replace(p,q)},nodeName:function(a,b){return a.nodeName&&a.nodeName.toLowerCase()===b.toLowerCase()},each:function(a,b,c){var d,e=0,f=a.length,g=r(a);if(c){if(g){for(;f>e;e++)if(d=b.apply(a[e],c),d===!1)break}else for(e in a)if(d=b.apply(a[e],c),d===!1)break}else if(g){for(;f>e;e++)if(d=b.call(a[e],e,a[e]),d===!1)break}else for(e in a)if(d=b.call(a[e],e,a[e]),d===!1)break;return a},trim:function(a){return null==a?"":(a+"").replace(n,"")},makeArray:function(a,b){var c=b||[];return null!=a&&(r(Object(a))?m.merge(c,"string"==typeof a?[a]:a):f.call(c,a)),c},inArray:function(a,b,c){var d;if(b){if(g)return g.call(b,a,c);for(d=b.length,c=c?0>c?Math.max(0,d+c):c:0;d>c;c++)if(c in b&&b[c]===a)return c}return-1},merge:function(a,b){var c=+b.length,d=0,e=a.length;while(c>d)a[e++]=b[d++];if(c!==c)while(void 0!==b[d])a[e++]=b[d++];return a.length=e,a},grep:function(a,b,c){for(var d,e=[],f=0,g=a.length,h=!c;g>f;f++)d=!b(a[f],f),d!==h&&e.push(a[f]);return e},map:function(a,b,c){var d,f=0,g=a.length,h=r(a),i=[];if(h)for(;g>f;f++)d=b(a[f],f,c),null!=d&&i.push(d);else for(f in a)d=b(a[f],f,c),null!=d&&i.push(d);return e.apply([],i)},guid:1,proxy:function(a,b){var c,e,f;return"string"==typeof b&&(f=a[b],b=a,a=f),m.isFunction(a)?(c=d.call(arguments,2),e=function(){return a.apply(b||this,c.concat(d.call(arguments)))},e.guid=a.guid=a.guid||m.guid++,e):void 0},now:function(){return+new Date},support:k}),m.each("Boolean Number String Function Array Date RegExp Object Error".split(" "),function(a,b){h["[object "+b+"]"]=b.toLowerCase()});function r(a){var b=a.length,c=m.type(a);return"function"===c||m.isWindow(a)?!1:1===a.nodeType&&b?!0:"array"===c||0===b||"number"==typeof b&&b>0&&b-1 in a}var s=function(a){var b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u="sizzle"+-new Date,v=a.document,w=0,x=0,y=gb(),z=gb(),A=gb(),B=function(a,b){return a===b&&(l=!0),0},C="undefined",D=1<<31,E={}.hasOwnProperty,F=[],G=F.pop,H=F.push,I=F.push,J=F.slice,K=F.indexOf||function(a){for(var b=0,c=this.length;c>b;b++)if(this[b]===a)return b;return-1},L="checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped",M="[\\x20\\t\\r\\n\\f]",N="(?:\\\\.|[\\w-]|[^\\x00-\\xa0])+",O=N.replace("w","w#"),P="\\["+M+"*("+N+")(?:"+M+"*([*^$|!~]?=)"+M+"*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|("+O+"))|)"+M+"*\\]",Q=":("+N+")(?:\\((('((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\")|((?:\\\\.|[^\\\\()[\\]]|"+P+")*)|.*)\\)|)",R=new RegExp("^"+M+"+|((?:^|[^\\\\])(?:\\\\.)*)"+M+"+$","g"),S=new RegExp("^"+M+"*,"+M+"*"),T=new RegExp("^"+M+"*([>+~]|"+M+")"+M+"*"),U=new RegExp("="+M+"*([^\\]'\"]*?)"+M+"*\\]","g"),V=new RegExp(Q),W=new RegExp("^"+O+"$"),X={ID:new RegExp("^#("+N+")"),CLASS:new RegExp("^\\.("+N+")"),TAG:new RegExp("^("+N.replace("w","w*")+")"),ATTR:new RegExp("^"+P),PSEUDO:new RegExp("^"+Q),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+M+"*(even|odd|(([+-]|)(\\d*)n|)"+M+"*(?:([+-]|)"+M+"*(\\d+)|))"+M+"*\\)|)","i"),bool:new RegExp("^(?:"+L+")$","i"),needsContext:new RegExp("^"+M+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+M+"*((?:-\\d)?\\d*)"+M+"*\\)|)(?=[^-]|$)","i")},Y=/^(?:input|select|textarea|button)$/i,Z=/^h\d$/i,$=/^[^{]+\{\s*\[native \w/,_=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,ab=/[+~]/,bb=/'|\\/g,cb=new RegExp("\\\\([\\da-f]{1,6}"+M+"?|("+M+")|.)","ig"),db=function(a,b,c){var d="0x"+b-65536;return d!==d||c?b:0>d?String.fromCharCode(d+65536):String.fromCharCode(d>>10|55296,1023&d|56320)};try{I.apply(F=J.call(v.childNodes),v.childNodes),F[v.childNodes.length].nodeType}catch(eb){I={apply:F.length?function(a,b){H.apply(a,J.call(b))}:function(a,b){var c=a.length,d=0;while(a[c++]=b[d++]);a.length=c-1}}}function fb(a,b,d,e){var f,h,j,k,l,o,r,s,w,x;if((b?b.ownerDocument||b:v)!==n&&m(b),b=b||n,d=d||[],!a||"string"!=typeof a)return d;if(1!==(k=b.nodeType)&&9!==k)return[];if(p&&!e){if(f=_.exec(a))if(j=f[1]){if(9===k){if(h=b.getElementById(j),!h||!h.parentNode)return d;if(h.id===j)return d.push(h),d}else if(b.ownerDocument&&(h=b.ownerDocument.getElementById(j))&&t(b,h)&&h.id===j)return d.push(h),d}else{if(f[2])return I.apply(d,b.getElementsByTagName(a)),d;if((j=f[3])&&c.getElementsByClassName&&b.getElementsByClassName)return I.apply(d,b.getElementsByClassName(j)),d}if(c.qsa&&(!q||!q.test(a))){if(s=r=u,w=b,x=9===k&&a,1===k&&"object"!==b.nodeName.toLowerCase()){o=g(a),(r=b.getAttribute("id"))?s=r.replace(bb,"\\$&"):b.setAttribute("id",s),s="[id='"+s+"'] ",l=o.length;while(l--)o[l]=s+qb(o[l]);w=ab.test(a)&&ob(b.parentNode)||b,x=o.join(",")}if(x)try{return I.apply(d,w.querySelectorAll(x)),d}catch(y){}finally{r||b.removeAttribute("id")}}}return i(a.replace(R,"$1"),b,d,e)}function gb(){var a=[];function b(c,e){return a.push(c+" ")>d.cacheLength&&delete b[a.shift()],b[c+" "]=e}return b}function hb(a){return a[u]=!0,a}function ib(a){var b=n.createElement("div");try{return!!a(b)}catch(c){return!1}finally{b.parentNode&&b.parentNode.removeChild(b),b=null}}function jb(a,b){var c=a.split("|"),e=a.length;while(e--)d.attrHandle[c[e]]=b}function kb(a,b){var c=b&&a,d=c&&1===a.nodeType&&1===b.nodeType&&(~b.sourceIndex||D)-(~a.sourceIndex||D);if(d)return d;if(c)while(c=c.nextSibling)if(c===b)return-1;return a?1:-1}function lb(a){return function(b){var c=b.nodeName.toLowerCase();return"input"===c&&b.type===a}}function mb(a){return function(b){var c=b.nodeName.toLowerCase();return("input"===c||"button"===c)&&b.type===a}}function nb(a){return hb(function(b){return b=+b,hb(function(c,d){var e,f=a([],c.length,b),g=f.length;while(g--)c[e=f[g]]&&(c[e]=!(d[e]=c[e]))})})}function ob(a){return a&&typeof a.getElementsByTagName!==C&&a}c=fb.support={},f=fb.isXML=function(a){var b=a&&(a.ownerDocument||a).documentElement;return b?"HTML"!==b.nodeName:!1},m=fb.setDocument=function(a){var b,e=a?a.ownerDocument||a:v,g=e.defaultView;return e!==n&&9===e.nodeType&&e.documentElement?(n=e,o=e.documentElement,p=!f(e),g&&g!==g.top&&(g.addEventListener?g.addEventListener("unload",function(){m()},!1):g.attachEvent&&g.attachEvent("onunload",function(){m()})),c.attributes=ib(function(a){return a.className="i",!a.getAttribute("className")}),c.getElementsByTagName=ib(function(a){return a.appendChild(e.createComment("")),!a.getElementsByTagName("*").length}),c.getElementsByClassName=$.test(e.getElementsByClassName)&&ib(function(a){return a.innerHTML="
    ",a.firstChild.className="i",2===a.getElementsByClassName("i").length}),c.getById=ib(function(a){return o.appendChild(a).id=u,!e.getElementsByName||!e.getElementsByName(u).length}),c.getById?(d.find.ID=function(a,b){if(typeof b.getElementById!==C&&p){var c=b.getElementById(a);return c&&c.parentNode?[c]:[]}},d.filter.ID=function(a){var b=a.replace(cb,db);return function(a){return a.getAttribute("id")===b}}):(delete d.find.ID,d.filter.ID=function(a){var b=a.replace(cb,db);return function(a){var c=typeof a.getAttributeNode!==C&&a.getAttributeNode("id");return c&&c.value===b}}),d.find.TAG=c.getElementsByTagName?function(a,b){return typeof b.getElementsByTagName!==C?b.getElementsByTagName(a):void 0}:function(a,b){var c,d=[],e=0,f=b.getElementsByTagName(a);if("*"===a){while(c=f[e++])1===c.nodeType&&d.push(c);return d}return f},d.find.CLASS=c.getElementsByClassName&&function(a,b){return typeof b.getElementsByClassName!==C&&p?b.getElementsByClassName(a):void 0},r=[],q=[],(c.qsa=$.test(e.querySelectorAll))&&(ib(function(a){a.innerHTML="",a.querySelectorAll("[msallowclip^='']").length&&q.push("[*^$]="+M+"*(?:''|\"\")"),a.querySelectorAll("[selected]").length||q.push("\\["+M+"*(?:value|"+L+")"),a.querySelectorAll(":checked").length||q.push(":checked")}),ib(function(a){var b=e.createElement("input");b.setAttribute("type","hidden"),a.appendChild(b).setAttribute("name","D"),a.querySelectorAll("[name=d]").length&&q.push("name"+M+"*[*^$|!~]?="),a.querySelectorAll(":enabled").length||q.push(":enabled",":disabled"),a.querySelectorAll("*,:x"),q.push(",.*:")})),(c.matchesSelector=$.test(s=o.matches||o.webkitMatchesSelector||o.mozMatchesSelector||o.oMatchesSelector||o.msMatchesSelector))&&ib(function(a){c.disconnectedMatch=s.call(a,"div"),s.call(a,"[s!='']:x"),r.push("!=",Q)}),q=q.length&&new RegExp(q.join("|")),r=r.length&&new RegExp(r.join("|")),b=$.test(o.compareDocumentPosition),t=b||$.test(o.contains)?function(a,b){var c=9===a.nodeType?a.documentElement:a,d=b&&b.parentNode;return a===d||!(!d||1!==d.nodeType||!(c.contains?c.contains(d):a.compareDocumentPosition&&16&a.compareDocumentPosition(d)))}:function(a,b){if(b)while(b=b.parentNode)if(b===a)return!0;return!1},B=b?function(a,b){if(a===b)return l=!0,0;var d=!a.compareDocumentPosition-!b.compareDocumentPosition;return d?d:(d=(a.ownerDocument||a)===(b.ownerDocument||b)?a.compareDocumentPosition(b):1,1&d||!c.sortDetached&&b.compareDocumentPosition(a)===d?a===e||a.ownerDocument===v&&t(v,a)?-1:b===e||b.ownerDocument===v&&t(v,b)?1:k?K.call(k,a)-K.call(k,b):0:4&d?-1:1)}:function(a,b){if(a===b)return l=!0,0;var c,d=0,f=a.parentNode,g=b.parentNode,h=[a],i=[b];if(!f||!g)return a===e?-1:b===e?1:f?-1:g?1:k?K.call(k,a)-K.call(k,b):0;if(f===g)return kb(a,b);c=a;while(c=c.parentNode)h.unshift(c);c=b;while(c=c.parentNode)i.unshift(c);while(h[d]===i[d])d++;return d?kb(h[d],i[d]):h[d]===v?-1:i[d]===v?1:0},e):n},fb.matches=function(a,b){return fb(a,null,null,b)},fb.matchesSelector=function(a,b){if((a.ownerDocument||a)!==n&&m(a),b=b.replace(U,"='$1']"),!(!c.matchesSelector||!p||r&&r.test(b)||q&&q.test(b)))try{var d=s.call(a,b);if(d||c.disconnectedMatch||a.document&&11!==a.document.nodeType)return d}catch(e){}return fb(b,n,null,[a]).length>0},fb.contains=function(a,b){return(a.ownerDocument||a)!==n&&m(a),t(a,b)},fb.attr=function(a,b){(a.ownerDocument||a)!==n&&m(a);var e=d.attrHandle[b.toLowerCase()],f=e&&E.call(d.attrHandle,b.toLowerCase())?e(a,b,!p):void 0;return void 0!==f?f:c.attributes||!p?a.getAttribute(b):(f=a.getAttributeNode(b))&&f.specified?f.value:null},fb.error=function(a){throw new Error("Syntax error, unrecognized expression: "+a)},fb.uniqueSort=function(a){var b,d=[],e=0,f=0;if(l=!c.detectDuplicates,k=!c.sortStable&&a.slice(0),a.sort(B),l){while(b=a[f++])b===a[f]&&(e=d.push(f));while(e--)a.splice(d[e],1)}return k=null,a},e=fb.getText=function(a){var b,c="",d=0,f=a.nodeType;if(f){if(1===f||9===f||11===f){if("string"==typeof a.textContent)return a.textContent;for(a=a.firstChild;a;a=a.nextSibling)c+=e(a)}else if(3===f||4===f)return a.nodeValue}else while(b=a[d++])c+=e(b);return c},d=fb.selectors={cacheLength:50,createPseudo:hb,match:X,attrHandle:{},find:{},relative:{">":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(a){return a[1]=a[1].replace(cb,db),a[3]=(a[3]||a[4]||a[5]||"").replace(cb,db),"~="===a[2]&&(a[3]=" "+a[3]+" "),a.slice(0,4)},CHILD:function(a){return a[1]=a[1].toLowerCase(),"nth"===a[1].slice(0,3)?(a[3]||fb.error(a[0]),a[4]=+(a[4]?a[5]+(a[6]||1):2*("even"===a[3]||"odd"===a[3])),a[5]=+(a[7]+a[8]||"odd"===a[3])):a[3]&&fb.error(a[0]),a},PSEUDO:function(a){var b,c=!a[6]&&a[2];return X.CHILD.test(a[0])?null:(a[3]?a[2]=a[4]||a[5]||"":c&&V.test(c)&&(b=g(c,!0))&&(b=c.indexOf(")",c.length-b)-c.length)&&(a[0]=a[0].slice(0,b),a[2]=c.slice(0,b)),a.slice(0,3))}},filter:{TAG:function(a){var b=a.replace(cb,db).toLowerCase();return"*"===a?function(){return!0}:function(a){return a.nodeName&&a.nodeName.toLowerCase()===b}},CLASS:function(a){var b=y[a+" "];return b||(b=new RegExp("(^|"+M+")"+a+"("+M+"|$)"))&&y(a,function(a){return b.test("string"==typeof a.className&&a.className||typeof a.getAttribute!==C&&a.getAttribute("class")||"")})},ATTR:function(a,b,c){return function(d){var e=fb.attr(d,a);return null==e?"!="===b:b?(e+="","="===b?e===c:"!="===b?e!==c:"^="===b?c&&0===e.indexOf(c):"*="===b?c&&e.indexOf(c)>-1:"$="===b?c&&e.slice(-c.length)===c:"~="===b?(" "+e+" ").indexOf(c)>-1:"|="===b?e===c||e.slice(0,c.length+1)===c+"-":!1):!0}},CHILD:function(a,b,c,d,e){var f="nth"!==a.slice(0,3),g="last"!==a.slice(-4),h="of-type"===b;return 1===d&&0===e?function(a){return!!a.parentNode}:function(b,c,i){var j,k,l,m,n,o,p=f!==g?"nextSibling":"previousSibling",q=b.parentNode,r=h&&b.nodeName.toLowerCase(),s=!i&&!h;if(q){if(f){while(p){l=b;while(l=l[p])if(h?l.nodeName.toLowerCase()===r:1===l.nodeType)return!1;o=p="only"===a&&!o&&"nextSibling"}return!0}if(o=[g?q.firstChild:q.lastChild],g&&s){k=q[u]||(q[u]={}),j=k[a]||[],n=j[0]===w&&j[1],m=j[0]===w&&j[2],l=n&&q.childNodes[n];while(l=++n&&l&&l[p]||(m=n=0)||o.pop())if(1===l.nodeType&&++m&&l===b){k[a]=[w,n,m];break}}else if(s&&(j=(b[u]||(b[u]={}))[a])&&j[0]===w)m=j[1];else while(l=++n&&l&&l[p]||(m=n=0)||o.pop())if((h?l.nodeName.toLowerCase()===r:1===l.nodeType)&&++m&&(s&&((l[u]||(l[u]={}))[a]=[w,m]),l===b))break;return m-=e,m===d||m%d===0&&m/d>=0}}},PSEUDO:function(a,b){var c,e=d.pseudos[a]||d.setFilters[a.toLowerCase()]||fb.error("unsupported pseudo: "+a);return e[u]?e(b):e.length>1?(c=[a,a,"",b],d.setFilters.hasOwnProperty(a.toLowerCase())?hb(function(a,c){var d,f=e(a,b),g=f.length;while(g--)d=K.call(a,f[g]),a[d]=!(c[d]=f[g])}):function(a){return e(a,0,c)}):e}},pseudos:{not:hb(function(a){var b=[],c=[],d=h(a.replace(R,"$1"));return d[u]?hb(function(a,b,c,e){var f,g=d(a,null,e,[]),h=a.length;while(h--)(f=g[h])&&(a[h]=!(b[h]=f))}):function(a,e,f){return b[0]=a,d(b,null,f,c),!c.pop()}}),has:hb(function(a){return function(b){return fb(a,b).length>0}}),contains:hb(function(a){return function(b){return(b.textContent||b.innerText||e(b)).indexOf(a)>-1}}),lang:hb(function(a){return W.test(a||"")||fb.error("unsupported lang: "+a),a=a.replace(cb,db).toLowerCase(),function(b){var c;do if(c=p?b.lang:b.getAttribute("xml:lang")||b.getAttribute("lang"))return c=c.toLowerCase(),c===a||0===c.indexOf(a+"-");while((b=b.parentNode)&&1===b.nodeType);return!1}}),target:function(b){var c=a.location&&a.location.hash;return c&&c.slice(1)===b.id},root:function(a){return a===o},focus:function(a){return a===n.activeElement&&(!n.hasFocus||n.hasFocus())&&!!(a.type||a.href||~a.tabIndex)},enabled:function(a){return a.disabled===!1},disabled:function(a){return a.disabled===!0},checked:function(a){var b=a.nodeName.toLowerCase();return"input"===b&&!!a.checked||"option"===b&&!!a.selected},selected:function(a){return a.parentNode&&a.parentNode.selectedIndex,a.selected===!0},empty:function(a){for(a=a.firstChild;a;a=a.nextSibling)if(a.nodeType<6)return!1;return!0},parent:function(a){return!d.pseudos.empty(a)},header:function(a){return Z.test(a.nodeName)},input:function(a){return Y.test(a.nodeName)},button:function(a){var b=a.nodeName.toLowerCase();return"input"===b&&"button"===a.type||"button"===b},text:function(a){var b;return"input"===a.nodeName.toLowerCase()&&"text"===a.type&&(null==(b=a.getAttribute("type"))||"text"===b.toLowerCase())},first:nb(function(){return[0]}),last:nb(function(a,b){return[b-1]}),eq:nb(function(a,b,c){return[0>c?c+b:c]}),even:nb(function(a,b){for(var c=0;b>c;c+=2)a.push(c);return a}),odd:nb(function(a,b){for(var c=1;b>c;c+=2)a.push(c);return a}),lt:nb(function(a,b,c){for(var d=0>c?c+b:c;--d>=0;)a.push(d);return a}),gt:nb(function(a,b,c){for(var d=0>c?c+b:c;++db;b++)d+=a[b].value;return d}function rb(a,b,c){var d=b.dir,e=c&&"parentNode"===d,f=x++;return b.first?function(b,c,f){while(b=b[d])if(1===b.nodeType||e)return a(b,c,f)}:function(b,c,g){var h,i,j=[w,f];if(g){while(b=b[d])if((1===b.nodeType||e)&&a(b,c,g))return!0}else while(b=b[d])if(1===b.nodeType||e){if(i=b[u]||(b[u]={}),(h=i[d])&&h[0]===w&&h[1]===f)return j[2]=h[2];if(i[d]=j,j[2]=a(b,c,g))return!0}}}function sb(a){return a.length>1?function(b,c,d){var e=a.length;while(e--)if(!a[e](b,c,d))return!1;return!0}:a[0]}function tb(a,b,c){for(var d=0,e=b.length;e>d;d++)fb(a,b[d],c);return c}function ub(a,b,c,d,e){for(var f,g=[],h=0,i=a.length,j=null!=b;i>h;h++)(f=a[h])&&(!c||c(f,d,e))&&(g.push(f),j&&b.push(h));return g}function vb(a,b,c,d,e,f){return d&&!d[u]&&(d=vb(d)),e&&!e[u]&&(e=vb(e,f)),hb(function(f,g,h,i){var j,k,l,m=[],n=[],o=g.length,p=f||tb(b||"*",h.nodeType?[h]:h,[]),q=!a||!f&&b?p:ub(p,m,a,h,i),r=c?e||(f?a:o||d)?[]:g:q;if(c&&c(q,r,h,i),d){j=ub(r,n),d(j,[],h,i),k=j.length;while(k--)(l=j[k])&&(r[n[k]]=!(q[n[k]]=l))}if(f){if(e||a){if(e){j=[],k=r.length;while(k--)(l=r[k])&&j.push(q[k]=l);e(null,r=[],j,i)}k=r.length;while(k--)(l=r[k])&&(j=e?K.call(f,l):m[k])>-1&&(f[j]=!(g[j]=l))}}else r=ub(r===g?r.splice(o,r.length):r),e?e(null,g,r,i):I.apply(g,r)})}function wb(a){for(var b,c,e,f=a.length,g=d.relative[a[0].type],h=g||d.relative[" "],i=g?1:0,k=rb(function(a){return a===b},h,!0),l=rb(function(a){return K.call(b,a)>-1},h,!0),m=[function(a,c,d){return!g&&(d||c!==j)||((b=c).nodeType?k(a,c,d):l(a,c,d))}];f>i;i++)if(c=d.relative[a[i].type])m=[rb(sb(m),c)];else{if(c=d.filter[a[i].type].apply(null,a[i].matches),c[u]){for(e=++i;f>e;e++)if(d.relative[a[e].type])break;return vb(i>1&&sb(m),i>1&&qb(a.slice(0,i-1).concat({value:" "===a[i-2].type?"*":""})).replace(R,"$1"),c,e>i&&wb(a.slice(i,e)),f>e&&wb(a=a.slice(e)),f>e&&qb(a))}m.push(c)}return sb(m)}function xb(a,b){var c=b.length>0,e=a.length>0,f=function(f,g,h,i,k){var l,m,o,p=0,q="0",r=f&&[],s=[],t=j,u=f||e&&d.find.TAG("*",k),v=w+=null==t?1:Math.random()||.1,x=u.length;for(k&&(j=g!==n&&g);q!==x&&null!=(l=u[q]);q++){if(e&&l){m=0;while(o=a[m++])if(o(l,g,h)){i.push(l);break}k&&(w=v)}c&&((l=!o&&l)&&p--,f&&r.push(l))}if(p+=q,c&&q!==p){m=0;while(o=b[m++])o(r,s,g,h);if(f){if(p>0)while(q--)r[q]||s[q]||(s[q]=G.call(i));s=ub(s)}I.apply(i,s),k&&!f&&s.length>0&&p+b.length>1&&fb.uniqueSort(i)}return k&&(w=v,j=t),r};return c?hb(f):f}return h=fb.compile=function(a,b){var c,d=[],e=[],f=A[a+" "];if(!f){b||(b=g(a)),c=b.length;while(c--)f=wb(b[c]),f[u]?d.push(f):e.push(f);f=A(a,xb(e,d)),f.selector=a}return f},i=fb.select=function(a,b,e,f){var i,j,k,l,m,n="function"==typeof a&&a,o=!f&&g(a=n.selector||a);if(e=e||[],1===o.length){if(j=o[0]=o[0].slice(0),j.length>2&&"ID"===(k=j[0]).type&&c.getById&&9===b.nodeType&&p&&d.relative[j[1].type]){if(b=(d.find.ID(k.matches[0].replace(cb,db),b)||[])[0],!b)return e;n&&(b=b.parentNode),a=a.slice(j.shift().value.length)}i=X.needsContext.test(a)?0:j.length;while(i--){if(k=j[i],d.relative[l=k.type])break;if((m=d.find[l])&&(f=m(k.matches[0].replace(cb,db),ab.test(j[0].type)&&ob(b.parentNode)||b))){if(j.splice(i,1),a=f.length&&qb(j),!a)return I.apply(e,f),e;break}}}return(n||h(a,o))(f,b,!p,e,ab.test(a)&&ob(b.parentNode)||b),e},c.sortStable=u.split("").sort(B).join("")===u,c.detectDuplicates=!!l,m(),c.sortDetached=ib(function(a){return 1&a.compareDocumentPosition(n.createElement("div"))}),ib(function(a){return a.innerHTML="","#"===a.firstChild.getAttribute("href")})||jb("type|href|height|width",function(a,b,c){return c?void 0:a.getAttribute(b,"type"===b.toLowerCase()?1:2)}),c.attributes&&ib(function(a){return a.innerHTML="",a.firstChild.setAttribute("value",""),""===a.firstChild.getAttribute("value")})||jb("value",function(a,b,c){return c||"input"!==a.nodeName.toLowerCase()?void 0:a.defaultValue}),ib(function(a){return null==a.getAttribute("disabled")})||jb(L,function(a,b,c){var d;return c?void 0:a[b]===!0?b.toLowerCase():(d=a.getAttributeNode(b))&&d.specified?d.value:null}),fb}(a);m.find=s,m.expr=s.selectors,m.expr[":"]=m.expr.pseudos,m.unique=s.uniqueSort,m.text=s.getText,m.isXMLDoc=s.isXML,m.contains=s.contains;var t=m.expr.match.needsContext,u=/^<(\w+)\s*\/?>(?:<\/\1>|)$/,v=/^.[^:#\[\.,]*$/;function w(a,b,c){if(m.isFunction(b))return m.grep(a,function(a,d){return!!b.call(a,d,a)!==c});if(b.nodeType)return m.grep(a,function(a){return a===b!==c});if("string"==typeof b){if(v.test(b))return m.filter(b,a,c);b=m.filter(b,a)}return m.grep(a,function(a){return m.inArray(a,b)>=0!==c})}m.filter=function(a,b,c){var d=b[0];return c&&(a=":not("+a+")"),1===b.length&&1===d.nodeType?m.find.matchesSelector(d,a)?[d]:[]:m.find.matches(a,m.grep(b,function(a){return 1===a.nodeType}))},m.fn.extend({find:function(a){var b,c=[],d=this,e=d.length;if("string"!=typeof a)return this.pushStack(m(a).filter(function(){for(b=0;e>b;b++)if(m.contains(d[b],this))return!0}));for(b=0;e>b;b++)m.find(a,d[b],c);return c=this.pushStack(e>1?m.unique(c):c),c.selector=this.selector?this.selector+" "+a:a,c},filter:function(a){return this.pushStack(w(this,a||[],!1))},not:function(a){return this.pushStack(w(this,a||[],!0))},is:function(a){return!!w(this,"string"==typeof a&&t.test(a)?m(a):a||[],!1).length}});var x,y=a.document,z=/^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]*))$/,A=m.fn.init=function(a,b){var c,d;if(!a)return this;if("string"==typeof a){if(c="<"===a.charAt(0)&&">"===a.charAt(a.length-1)&&a.length>=3?[null,a,null]:z.exec(a),!c||!c[1]&&b)return!b||b.jquery?(b||x).find(a):this.constructor(b).find(a);if(c[1]){if(b=b instanceof m?b[0]:b,m.merge(this,m.parseHTML(c[1],b&&b.nodeType?b.ownerDocument||b:y,!0)),u.test(c[1])&&m.isPlainObject(b))for(c in b)m.isFunction(this[c])?this[c](b[c]):this.attr(c,b[c]);return this}if(d=y.getElementById(c[2]),d&&d.parentNode){if(d.id!==c[2])return x.find(a);this.length=1,this[0]=d}return this.context=y,this.selector=a,this}return a.nodeType?(this.context=this[0]=a,this.length=1,this):m.isFunction(a)?"undefined"!=typeof x.ready?x.ready(a):a(m):(void 0!==a.selector&&(this.selector=a.selector,this.context=a.context),m.makeArray(a,this))};A.prototype=m.fn,x=m(y);var B=/^(?:parents|prev(?:Until|All))/,C={children:!0,contents:!0,next:!0,prev:!0};m.extend({dir:function(a,b,c){var d=[],e=a[b];while(e&&9!==e.nodeType&&(void 0===c||1!==e.nodeType||!m(e).is(c)))1===e.nodeType&&d.push(e),e=e[b];return d},sibling:function(a,b){for(var c=[];a;a=a.nextSibling)1===a.nodeType&&a!==b&&c.push(a);return c}}),m.fn.extend({has:function(a){var b,c=m(a,this),d=c.length;return this.filter(function(){for(b=0;d>b;b++)if(m.contains(this,c[b]))return!0})},closest:function(a,b){for(var c,d=0,e=this.length,f=[],g=t.test(a)||"string"!=typeof a?m(a,b||this.context):0;e>d;d++)for(c=this[d];c&&c!==b;c=c.parentNode)if(c.nodeType<11&&(g?g.index(c)>-1:1===c.nodeType&&m.find.matchesSelector(c,a))){f.push(c);break}return this.pushStack(f.length>1?m.unique(f):f)},index:function(a){return a?"string"==typeof a?m.inArray(this[0],m(a)):m.inArray(a.jquery?a[0]:a,this):this[0]&&this[0].parentNode?this.first().prevAll().length:-1},add:function(a,b){return this.pushStack(m.unique(m.merge(this.get(),m(a,b))))},addBack:function(a){return this.add(null==a?this.prevObject:this.prevObject.filter(a))}});function D(a,b){do a=a[b];while(a&&1!==a.nodeType);return a}m.each({parent:function(a){var b=a.parentNode;return b&&11!==b.nodeType?b:null},parents:function(a){return m.dir(a,"parentNode")},parentsUntil:function(a,b,c){return m.dir(a,"parentNode",c)},next:function(a){return D(a,"nextSibling")},prev:function(a){return D(a,"previousSibling")},nextAll:function(a){return m.dir(a,"nextSibling")},prevAll:function(a){return m.dir(a,"previousSibling")},nextUntil:function(a,b,c){return m.dir(a,"nextSibling",c)},prevUntil:function(a,b,c){return m.dir(a,"previousSibling",c)},siblings:function(a){return m.sibling((a.parentNode||{}).firstChild,a)},children:function(a){return m.sibling(a.firstChild)},contents:function(a){return m.nodeName(a,"iframe")?a.contentDocument||a.contentWindow.document:m.merge([],a.childNodes)}},function(a,b){m.fn[a]=function(c,d){var e=m.map(this,b,c);return"Until"!==a.slice(-5)&&(d=c),d&&"string"==typeof d&&(e=m.filter(d,e)),this.length>1&&(C[a]||(e=m.unique(e)),B.test(a)&&(e=e.reverse())),this.pushStack(e)}});var E=/\S+/g,F={};function G(a){var b=F[a]={};return m.each(a.match(E)||[],function(a,c){b[c]=!0}),b}m.Callbacks=function(a){a="string"==typeof a?F[a]||G(a):m.extend({},a);var b,c,d,e,f,g,h=[],i=!a.once&&[],j=function(l){for(c=a.memory&&l,d=!0,f=g||0,g=0,e=h.length,b=!0;h&&e>f;f++)if(h[f].apply(l[0],l[1])===!1&&a.stopOnFalse){c=!1;break}b=!1,h&&(i?i.length&&j(i.shift()):c?h=[]:k.disable())},k={add:function(){if(h){var d=h.length;!function f(b){m.each(b,function(b,c){var d=m.type(c);"function"===d?a.unique&&k.has(c)||h.push(c):c&&c.length&&"string"!==d&&f(c)})}(arguments),b?e=h.length:c&&(g=d,j(c))}return this},remove:function(){return h&&m.each(arguments,function(a,c){var d;while((d=m.inArray(c,h,d))>-1)h.splice(d,1),b&&(e>=d&&e--,f>=d&&f--)}),this},has:function(a){return a?m.inArray(a,h)>-1:!(!h||!h.length)},empty:function(){return h=[],e=0,this},disable:function(){return h=i=c=void 0,this},disabled:function(){return!h},lock:function(){return i=void 0,c||k.disable(),this},locked:function(){return!i},fireWith:function(a,c){return!h||d&&!i||(c=c||[],c=[a,c.slice?c.slice():c],b?i.push(c):j(c)),this},fire:function(){return k.fireWith(this,arguments),this},fired:function(){return!!d}};return k},m.extend({Deferred:function(a){var b=[["resolve","done",m.Callbacks("once memory"),"resolved"],["reject","fail",m.Callbacks("once memory"),"rejected"],["notify","progress",m.Callbacks("memory")]],c="pending",d={state:function(){return c},always:function(){return e.done(arguments).fail(arguments),this},then:function(){var a=arguments;return m.Deferred(function(c){m.each(b,function(b,f){var g=m.isFunction(a[b])&&a[b];e[f[1]](function(){var a=g&&g.apply(this,arguments);a&&m.isFunction(a.promise)?a.promise().done(c.resolve).fail(c.reject).progress(c.notify):c[f[0]+"With"](this===d?c.promise():this,g?[a]:arguments)})}),a=null}).promise()},promise:function(a){return null!=a?m.extend(a,d):d}},e={};return d.pipe=d.then,m.each(b,function(a,f){var g=f[2],h=f[3];d[f[1]]=g.add,h&&g.add(function(){c=h},b[1^a][2].disable,b[2][2].lock),e[f[0]]=function(){return e[f[0]+"With"](this===e?d:this,arguments),this},e[f[0]+"With"]=g.fireWith}),d.promise(e),a&&a.call(e,e),e},when:function(a){var b=0,c=d.call(arguments),e=c.length,f=1!==e||a&&m.isFunction(a.promise)?e:0,g=1===f?a:m.Deferred(),h=function(a,b,c){return function(e){b[a]=this,c[a]=arguments.length>1?d.call(arguments):e,c===i?g.notifyWith(b,c):--f||g.resolveWith(b,c)}},i,j,k;if(e>1)for(i=new Array(e),j=new Array(e),k=new Array(e);e>b;b++)c[b]&&m.isFunction(c[b].promise)?c[b].promise().done(h(b,k,c)).fail(g.reject).progress(h(b,j,i)):--f;return f||g.resolveWith(k,c),g.promise()}});var H;m.fn.ready=function(a){return m.ready.promise().done(a),this},m.extend({isReady:!1,readyWait:1,holdReady:function(a){a?m.readyWait++:m.ready(!0)},ready:function(a){if(a===!0?!--m.readyWait:!m.isReady){if(!y.body)return setTimeout(m.ready);m.isReady=!0,a!==!0&&--m.readyWait>0||(H.resolveWith(y,[m]),m.fn.triggerHandler&&(m(y).triggerHandler("ready"),m(y).off("ready")))}}});function I(){y.addEventListener?(y.removeEventListener("DOMContentLoaded",J,!1),a.removeEventListener("load",J,!1)):(y.detachEvent("onreadystatechange",J),a.detachEvent("onload",J))}function J(){(y.addEventListener||"load"===event.type||"complete"===y.readyState)&&(I(),m.ready())}m.ready.promise=function(b){if(!H)if(H=m.Deferred(),"complete"===y.readyState)setTimeout(m.ready);else if(y.addEventListener)y.addEventListener("DOMContentLoaded",J,!1),a.addEventListener("load",J,!1);else{y.attachEvent("onreadystatechange",J),a.attachEvent("onload",J);var c=!1;try{c=null==a.frameElement&&y.documentElement}catch(d){}c&&c.doScroll&&!function e(){if(!m.isReady){try{c.doScroll("left")}catch(a){return setTimeout(e,50)}I(),m.ready()}}()}return H.promise(b)};var K="undefined",L;for(L in m(k))break;k.ownLast="0"!==L,k.inlineBlockNeedsLayout=!1,m(function(){var a,b,c,d;c=y.getElementsByTagName("body")[0],c&&c.style&&(b=y.createElement("div"),d=y.createElement("div"),d.style.cssText="position:absolute;border:0;width:0;height:0;top:0;left:-9999px",c.appendChild(d).appendChild(b),typeof b.style.zoom!==K&&(b.style.cssText="display:inline;margin:0;border:0;padding:1px;width:1px;zoom:1",k.inlineBlockNeedsLayout=a=3===b.offsetWidth,a&&(c.style.zoom=1)),c.removeChild(d))}),function(){var a=y.createElement("div");if(null==k.deleteExpando){k.deleteExpando=!0;try{delete a.test}catch(b){k.deleteExpando=!1}}a=null}(),m.acceptData=function(a){var b=m.noData[(a.nodeName+" ").toLowerCase()],c=+a.nodeType||1;return 1!==c&&9!==c?!1:!b||b!==!0&&a.getAttribute("classid")===b};var M=/^(?:\{[\w\W]*\}|\[[\w\W]*\])$/,N=/([A-Z])/g;function O(a,b,c){if(void 0===c&&1===a.nodeType){var d="data-"+b.replace(N,"-$1").toLowerCase();if(c=a.getAttribute(d),"string"==typeof c){try{c="true"===c?!0:"false"===c?!1:"null"===c?null:+c+""===c?+c:M.test(c)?m.parseJSON(c):c}catch(e){}m.data(a,b,c)}else c=void 0}return c}function P(a){var b;for(b in a)if(("data"!==b||!m.isEmptyObject(a[b]))&&"toJSON"!==b)return!1;return!0}function Q(a,b,d,e){if(m.acceptData(a)){var f,g,h=m.expando,i=a.nodeType,j=i?m.cache:a,k=i?a[h]:a[h]&&h; 3 | if(k&&j[k]&&(e||j[k].data)||void 0!==d||"string"!=typeof b)return k||(k=i?a[h]=c.pop()||m.guid++:h),j[k]||(j[k]=i?{}:{toJSON:m.noop}),("object"==typeof b||"function"==typeof b)&&(e?j[k]=m.extend(j[k],b):j[k].data=m.extend(j[k].data,b)),g=j[k],e||(g.data||(g.data={}),g=g.data),void 0!==d&&(g[m.camelCase(b)]=d),"string"==typeof b?(f=g[b],null==f&&(f=g[m.camelCase(b)])):f=g,f}}function R(a,b,c){if(m.acceptData(a)){var d,e,f=a.nodeType,g=f?m.cache:a,h=f?a[m.expando]:m.expando;if(g[h]){if(b&&(d=c?g[h]:g[h].data)){m.isArray(b)?b=b.concat(m.map(b,m.camelCase)):b in d?b=[b]:(b=m.camelCase(b),b=b in d?[b]:b.split(" ")),e=b.length;while(e--)delete d[b[e]];if(c?!P(d):!m.isEmptyObject(d))return}(c||(delete g[h].data,P(g[h])))&&(f?m.cleanData([a],!0):k.deleteExpando||g!=g.window?delete g[h]:g[h]=null)}}}m.extend({cache:{},noData:{"applet ":!0,"embed ":!0,"object ":"clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"},hasData:function(a){return a=a.nodeType?m.cache[a[m.expando]]:a[m.expando],!!a&&!P(a)},data:function(a,b,c){return Q(a,b,c)},removeData:function(a,b){return R(a,b)},_data:function(a,b,c){return Q(a,b,c,!0)},_removeData:function(a,b){return R(a,b,!0)}}),m.fn.extend({data:function(a,b){var c,d,e,f=this[0],g=f&&f.attributes;if(void 0===a){if(this.length&&(e=m.data(f),1===f.nodeType&&!m._data(f,"parsedAttrs"))){c=g.length;while(c--)g[c]&&(d=g[c].name,0===d.indexOf("data-")&&(d=m.camelCase(d.slice(5)),O(f,d,e[d])));m._data(f,"parsedAttrs",!0)}return e}return"object"==typeof a?this.each(function(){m.data(this,a)}):arguments.length>1?this.each(function(){m.data(this,a,b)}):f?O(f,a,m.data(f,a)):void 0},removeData:function(a){return this.each(function(){m.removeData(this,a)})}}),m.extend({queue:function(a,b,c){var d;return a?(b=(b||"fx")+"queue",d=m._data(a,b),c&&(!d||m.isArray(c)?d=m._data(a,b,m.makeArray(c)):d.push(c)),d||[]):void 0},dequeue:function(a,b){b=b||"fx";var c=m.queue(a,b),d=c.length,e=c.shift(),f=m._queueHooks(a,b),g=function(){m.dequeue(a,b)};"inprogress"===e&&(e=c.shift(),d--),e&&("fx"===b&&c.unshift("inprogress"),delete f.stop,e.call(a,g,f)),!d&&f&&f.empty.fire()},_queueHooks:function(a,b){var c=b+"queueHooks";return m._data(a,c)||m._data(a,c,{empty:m.Callbacks("once memory").add(function(){m._removeData(a,b+"queue"),m._removeData(a,c)})})}}),m.fn.extend({queue:function(a,b){var c=2;return"string"!=typeof a&&(b=a,a="fx",c--),arguments.lengthh;h++)b(a[h],c,g?d:d.call(a[h],h,b(a[h],c)));return e?a:j?b.call(a):i?b(a[0],c):f},W=/^(?:checkbox|radio)$/i;!function(){var a=y.createElement("input"),b=y.createElement("div"),c=y.createDocumentFragment();if(b.innerHTML="
    a",k.leadingWhitespace=3===b.firstChild.nodeType,k.tbody=!b.getElementsByTagName("tbody").length,k.htmlSerialize=!!b.getElementsByTagName("link").length,k.html5Clone="<:nav>"!==y.createElement("nav").cloneNode(!0).outerHTML,a.type="checkbox",a.checked=!0,c.appendChild(a),k.appendChecked=a.checked,b.innerHTML="",k.noCloneChecked=!!b.cloneNode(!0).lastChild.defaultValue,c.appendChild(b),b.innerHTML="",k.checkClone=b.cloneNode(!0).cloneNode(!0).lastChild.checked,k.noCloneEvent=!0,b.attachEvent&&(b.attachEvent("onclick",function(){k.noCloneEvent=!1}),b.cloneNode(!0).click()),null==k.deleteExpando){k.deleteExpando=!0;try{delete b.test}catch(d){k.deleteExpando=!1}}}(),function(){var b,c,d=y.createElement("div");for(b in{submit:!0,change:!0,focusin:!0})c="on"+b,(k[b+"Bubbles"]=c in a)||(d.setAttribute(c,"t"),k[b+"Bubbles"]=d.attributes[c].expando===!1);d=null}();var X=/^(?:input|select|textarea)$/i,Y=/^key/,Z=/^(?:mouse|pointer|contextmenu)|click/,$=/^(?:focusinfocus|focusoutblur)$/,_=/^([^.]*)(?:\.(.+)|)$/;function ab(){return!0}function bb(){return!1}function cb(){try{return y.activeElement}catch(a){}}m.event={global:{},add:function(a,b,c,d,e){var f,g,h,i,j,k,l,n,o,p,q,r=m._data(a);if(r){c.handler&&(i=c,c=i.handler,e=i.selector),c.guid||(c.guid=m.guid++),(g=r.events)||(g=r.events={}),(k=r.handle)||(k=r.handle=function(a){return typeof m===K||a&&m.event.triggered===a.type?void 0:m.event.dispatch.apply(k.elem,arguments)},k.elem=a),b=(b||"").match(E)||[""],h=b.length;while(h--)f=_.exec(b[h])||[],o=q=f[1],p=(f[2]||"").split(".").sort(),o&&(j=m.event.special[o]||{},o=(e?j.delegateType:j.bindType)||o,j=m.event.special[o]||{},l=m.extend({type:o,origType:q,data:d,handler:c,guid:c.guid,selector:e,needsContext:e&&m.expr.match.needsContext.test(e),namespace:p.join(".")},i),(n=g[o])||(n=g[o]=[],n.delegateCount=0,j.setup&&j.setup.call(a,d,p,k)!==!1||(a.addEventListener?a.addEventListener(o,k,!1):a.attachEvent&&a.attachEvent("on"+o,k))),j.add&&(j.add.call(a,l),l.handler.guid||(l.handler.guid=c.guid)),e?n.splice(n.delegateCount++,0,l):n.push(l),m.event.global[o]=!0);a=null}},remove:function(a,b,c,d,e){var f,g,h,i,j,k,l,n,o,p,q,r=m.hasData(a)&&m._data(a);if(r&&(k=r.events)){b=(b||"").match(E)||[""],j=b.length;while(j--)if(h=_.exec(b[j])||[],o=q=h[1],p=(h[2]||"").split(".").sort(),o){l=m.event.special[o]||{},o=(d?l.delegateType:l.bindType)||o,n=k[o]||[],h=h[2]&&new RegExp("(^|\\.)"+p.join("\\.(?:.*\\.|)")+"(\\.|$)"),i=f=n.length;while(f--)g=n[f],!e&&q!==g.origType||c&&c.guid!==g.guid||h&&!h.test(g.namespace)||d&&d!==g.selector&&("**"!==d||!g.selector)||(n.splice(f,1),g.selector&&n.delegateCount--,l.remove&&l.remove.call(a,g));i&&!n.length&&(l.teardown&&l.teardown.call(a,p,r.handle)!==!1||m.removeEvent(a,o,r.handle),delete k[o])}else for(o in k)m.event.remove(a,o+b[j],c,d,!0);m.isEmptyObject(k)&&(delete r.handle,m._removeData(a,"events"))}},trigger:function(b,c,d,e){var f,g,h,i,k,l,n,o=[d||y],p=j.call(b,"type")?b.type:b,q=j.call(b,"namespace")?b.namespace.split("."):[];if(h=l=d=d||y,3!==d.nodeType&&8!==d.nodeType&&!$.test(p+m.event.triggered)&&(p.indexOf(".")>=0&&(q=p.split("."),p=q.shift(),q.sort()),g=p.indexOf(":")<0&&"on"+p,b=b[m.expando]?b:new m.Event(p,"object"==typeof b&&b),b.isTrigger=e?2:3,b.namespace=q.join("."),b.namespace_re=b.namespace?new RegExp("(^|\\.)"+q.join("\\.(?:.*\\.|)")+"(\\.|$)"):null,b.result=void 0,b.target||(b.target=d),c=null==c?[b]:m.makeArray(c,[b]),k=m.event.special[p]||{},e||!k.trigger||k.trigger.apply(d,c)!==!1)){if(!e&&!k.noBubble&&!m.isWindow(d)){for(i=k.delegateType||p,$.test(i+p)||(h=h.parentNode);h;h=h.parentNode)o.push(h),l=h;l===(d.ownerDocument||y)&&o.push(l.defaultView||l.parentWindow||a)}n=0;while((h=o[n++])&&!b.isPropagationStopped())b.type=n>1?i:k.bindType||p,f=(m._data(h,"events")||{})[b.type]&&m._data(h,"handle"),f&&f.apply(h,c),f=g&&h[g],f&&f.apply&&m.acceptData(h)&&(b.result=f.apply(h,c),b.result===!1&&b.preventDefault());if(b.type=p,!e&&!b.isDefaultPrevented()&&(!k._default||k._default.apply(o.pop(),c)===!1)&&m.acceptData(d)&&g&&d[p]&&!m.isWindow(d)){l=d[g],l&&(d[g]=null),m.event.triggered=p;try{d[p]()}catch(r){}m.event.triggered=void 0,l&&(d[g]=l)}return b.result}},dispatch:function(a){a=m.event.fix(a);var b,c,e,f,g,h=[],i=d.call(arguments),j=(m._data(this,"events")||{})[a.type]||[],k=m.event.special[a.type]||{};if(i[0]=a,a.delegateTarget=this,!k.preDispatch||k.preDispatch.call(this,a)!==!1){h=m.event.handlers.call(this,a,j),b=0;while((f=h[b++])&&!a.isPropagationStopped()){a.currentTarget=f.elem,g=0;while((e=f.handlers[g++])&&!a.isImmediatePropagationStopped())(!a.namespace_re||a.namespace_re.test(e.namespace))&&(a.handleObj=e,a.data=e.data,c=((m.event.special[e.origType]||{}).handle||e.handler).apply(f.elem,i),void 0!==c&&(a.result=c)===!1&&(a.preventDefault(),a.stopPropagation()))}return k.postDispatch&&k.postDispatch.call(this,a),a.result}},handlers:function(a,b){var c,d,e,f,g=[],h=b.delegateCount,i=a.target;if(h&&i.nodeType&&(!a.button||"click"!==a.type))for(;i!=this;i=i.parentNode||this)if(1===i.nodeType&&(i.disabled!==!0||"click"!==a.type)){for(e=[],f=0;h>f;f++)d=b[f],c=d.selector+" ",void 0===e[c]&&(e[c]=d.needsContext?m(c,this).index(i)>=0:m.find(c,this,null,[i]).length),e[c]&&e.push(d);e.length&&g.push({elem:i,handlers:e})}return h]","i"),hb=/^\s+/,ib=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/gi,jb=/<([\w:]+)/,kb=/\s*$/g,rb={option:[1,""],legend:[1,"
    ","
    "],area:[1,"",""],param:[1,"",""],thead:[1,"","
    "],tr:[2,"","
    "],col:[2,"","
    "],td:[3,"","
    "],_default:k.htmlSerialize?[0,"",""]:[1,"X
    ","
    "]},sb=db(y),tb=sb.appendChild(y.createElement("div"));rb.optgroup=rb.option,rb.tbody=rb.tfoot=rb.colgroup=rb.caption=rb.thead,rb.th=rb.td;function ub(a,b){var c,d,e=0,f=typeof a.getElementsByTagName!==K?a.getElementsByTagName(b||"*"):typeof a.querySelectorAll!==K?a.querySelectorAll(b||"*"):void 0;if(!f)for(f=[],c=a.childNodes||a;null!=(d=c[e]);e++)!b||m.nodeName(d,b)?f.push(d):m.merge(f,ub(d,b));return void 0===b||b&&m.nodeName(a,b)?m.merge([a],f):f}function vb(a){W.test(a.type)&&(a.defaultChecked=a.checked)}function wb(a,b){return m.nodeName(a,"table")&&m.nodeName(11!==b.nodeType?b:b.firstChild,"tr")?a.getElementsByTagName("tbody")[0]||a.appendChild(a.ownerDocument.createElement("tbody")):a}function xb(a){return a.type=(null!==m.find.attr(a,"type"))+"/"+a.type,a}function yb(a){var b=pb.exec(a.type);return b?a.type=b[1]:a.removeAttribute("type"),a}function zb(a,b){for(var c,d=0;null!=(c=a[d]);d++)m._data(c,"globalEval",!b||m._data(b[d],"globalEval"))}function Ab(a,b){if(1===b.nodeType&&m.hasData(a)){var c,d,e,f=m._data(a),g=m._data(b,f),h=f.events;if(h){delete g.handle,g.events={};for(c in h)for(d=0,e=h[c].length;e>d;d++)m.event.add(b,c,h[c][d])}g.data&&(g.data=m.extend({},g.data))}}function Bb(a,b){var c,d,e;if(1===b.nodeType){if(c=b.nodeName.toLowerCase(),!k.noCloneEvent&&b[m.expando]){e=m._data(b);for(d in e.events)m.removeEvent(b,d,e.handle);b.removeAttribute(m.expando)}"script"===c&&b.text!==a.text?(xb(b).text=a.text,yb(b)):"object"===c?(b.parentNode&&(b.outerHTML=a.outerHTML),k.html5Clone&&a.innerHTML&&!m.trim(b.innerHTML)&&(b.innerHTML=a.innerHTML)):"input"===c&&W.test(a.type)?(b.defaultChecked=b.checked=a.checked,b.value!==a.value&&(b.value=a.value)):"option"===c?b.defaultSelected=b.selected=a.defaultSelected:("input"===c||"textarea"===c)&&(b.defaultValue=a.defaultValue)}}m.extend({clone:function(a,b,c){var d,e,f,g,h,i=m.contains(a.ownerDocument,a);if(k.html5Clone||m.isXMLDoc(a)||!gb.test("<"+a.nodeName+">")?f=a.cloneNode(!0):(tb.innerHTML=a.outerHTML,tb.removeChild(f=tb.firstChild)),!(k.noCloneEvent&&k.noCloneChecked||1!==a.nodeType&&11!==a.nodeType||m.isXMLDoc(a)))for(d=ub(f),h=ub(a),g=0;null!=(e=h[g]);++g)d[g]&&Bb(e,d[g]);if(b)if(c)for(h=h||ub(a),d=d||ub(f),g=0;null!=(e=h[g]);g++)Ab(e,d[g]);else Ab(a,f);return d=ub(f,"script"),d.length>0&&zb(d,!i&&ub(a,"script")),d=h=e=null,f},buildFragment:function(a,b,c,d){for(var e,f,g,h,i,j,l,n=a.length,o=db(b),p=[],q=0;n>q;q++)if(f=a[q],f||0===f)if("object"===m.type(f))m.merge(p,f.nodeType?[f]:f);else if(lb.test(f)){h=h||o.appendChild(b.createElement("div")),i=(jb.exec(f)||["",""])[1].toLowerCase(),l=rb[i]||rb._default,h.innerHTML=l[1]+f.replace(ib,"<$1>")+l[2],e=l[0];while(e--)h=h.lastChild;if(!k.leadingWhitespace&&hb.test(f)&&p.push(b.createTextNode(hb.exec(f)[0])),!k.tbody){f="table"!==i||kb.test(f)?""!==l[1]||kb.test(f)?0:h:h.firstChild,e=f&&f.childNodes.length;while(e--)m.nodeName(j=f.childNodes[e],"tbody")&&!j.childNodes.length&&f.removeChild(j)}m.merge(p,h.childNodes),h.textContent="";while(h.firstChild)h.removeChild(h.firstChild);h=o.lastChild}else p.push(b.createTextNode(f));h&&o.removeChild(h),k.appendChecked||m.grep(ub(p,"input"),vb),q=0;while(f=p[q++])if((!d||-1===m.inArray(f,d))&&(g=m.contains(f.ownerDocument,f),h=ub(o.appendChild(f),"script"),g&&zb(h),c)){e=0;while(f=h[e++])ob.test(f.type||"")&&c.push(f)}return h=null,o},cleanData:function(a,b){for(var d,e,f,g,h=0,i=m.expando,j=m.cache,l=k.deleteExpando,n=m.event.special;null!=(d=a[h]);h++)if((b||m.acceptData(d))&&(f=d[i],g=f&&j[f])){if(g.events)for(e in g.events)n[e]?m.event.remove(d,e):m.removeEvent(d,e,g.handle);j[f]&&(delete j[f],l?delete d[i]:typeof d.removeAttribute!==K?d.removeAttribute(i):d[i]=null,c.push(f))}}}),m.fn.extend({text:function(a){return V(this,function(a){return void 0===a?m.text(this):this.empty().append((this[0]&&this[0].ownerDocument||y).createTextNode(a))},null,a,arguments.length)},append:function(){return this.domManip(arguments,function(a){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var b=wb(this,a);b.appendChild(a)}})},prepend:function(){return this.domManip(arguments,function(a){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var b=wb(this,a);b.insertBefore(a,b.firstChild)}})},before:function(){return this.domManip(arguments,function(a){this.parentNode&&this.parentNode.insertBefore(a,this)})},after:function(){return this.domManip(arguments,function(a){this.parentNode&&this.parentNode.insertBefore(a,this.nextSibling)})},remove:function(a,b){for(var c,d=a?m.filter(a,this):this,e=0;null!=(c=d[e]);e++)b||1!==c.nodeType||m.cleanData(ub(c)),c.parentNode&&(b&&m.contains(c.ownerDocument,c)&&zb(ub(c,"script")),c.parentNode.removeChild(c));return this},empty:function(){for(var a,b=0;null!=(a=this[b]);b++){1===a.nodeType&&m.cleanData(ub(a,!1));while(a.firstChild)a.removeChild(a.firstChild);a.options&&m.nodeName(a,"select")&&(a.options.length=0)}return this},clone:function(a,b){return a=null==a?!1:a,b=null==b?a:b,this.map(function(){return m.clone(this,a,b)})},html:function(a){return V(this,function(a){var b=this[0]||{},c=0,d=this.length;if(void 0===a)return 1===b.nodeType?b.innerHTML.replace(fb,""):void 0;if(!("string"!=typeof a||mb.test(a)||!k.htmlSerialize&&gb.test(a)||!k.leadingWhitespace&&hb.test(a)||rb[(jb.exec(a)||["",""])[1].toLowerCase()])){a=a.replace(ib,"<$1>");try{for(;d>c;c++)b=this[c]||{},1===b.nodeType&&(m.cleanData(ub(b,!1)),b.innerHTML=a);b=0}catch(e){}}b&&this.empty().append(a)},null,a,arguments.length)},replaceWith:function(){var a=arguments[0];return this.domManip(arguments,function(b){a=this.parentNode,m.cleanData(ub(this)),a&&a.replaceChild(b,this)}),a&&(a.length||a.nodeType)?this:this.remove()},detach:function(a){return this.remove(a,!0)},domManip:function(a,b){a=e.apply([],a);var c,d,f,g,h,i,j=0,l=this.length,n=this,o=l-1,p=a[0],q=m.isFunction(p);if(q||l>1&&"string"==typeof p&&!k.checkClone&&nb.test(p))return this.each(function(c){var d=n.eq(c);q&&(a[0]=p.call(this,c,d.html())),d.domManip(a,b)});if(l&&(i=m.buildFragment(a,this[0].ownerDocument,!1,this),c=i.firstChild,1===i.childNodes.length&&(i=c),c)){for(g=m.map(ub(i,"script"),xb),f=g.length;l>j;j++)d=i,j!==o&&(d=m.clone(d,!0,!0),f&&m.merge(g,ub(d,"script"))),b.call(this[j],d,j);if(f)for(h=g[g.length-1].ownerDocument,m.map(g,yb),j=0;f>j;j++)d=g[j],ob.test(d.type||"")&&!m._data(d,"globalEval")&&m.contains(h,d)&&(d.src?m._evalUrl&&m._evalUrl(d.src):m.globalEval((d.text||d.textContent||d.innerHTML||"").replace(qb,"")));i=c=null}return this}}),m.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(a,b){m.fn[a]=function(a){for(var c,d=0,e=[],g=m(a),h=g.length-1;h>=d;d++)c=d===h?this:this.clone(!0),m(g[d])[b](c),f.apply(e,c.get());return this.pushStack(e)}});var Cb,Db={};function Eb(b,c){var d,e=m(c.createElement(b)).appendTo(c.body),f=a.getDefaultComputedStyle&&(d=a.getDefaultComputedStyle(e[0]))?d.display:m.css(e[0],"display");return e.detach(),f}function Fb(a){var b=y,c=Db[a];return c||(c=Eb(a,b),"none"!==c&&c||(Cb=(Cb||m("