{"semantics": [
{
"name": "interactiveVideo",
"type": "group",
"widget": "wizard",
"label": "Interactive Video Editor",
"importance": "high",
"fields": [
{
"name": "video",
"type": "group",
"label": "Upload/embed video",
"importance": "high",
"fields": [
{
"name": "files",
"type": "video",
"label": "Add a video",
"importance": "high",
"description": "Click below to add a video you wish to use in your interactive video. You can add a video link or upload video files. It is possible to add several versions of the video with different qualities. To ensure maximum support in browsers at least add a version in webm and mp4 formats.",
"extraAttributes": [
"metadata"
],
"enableCustomQualityLabel": true
},
{
"name": "startScreenOptions",
"type": "group",
"label": "Start screen options (unsupported for YouTube videos)",
"importance": "low",
"fields": [
{
"name": "title",
"type": "text",
"label": "The title of this interactive video",
"importance": "low",
"maxLength": 60,
"default": "Interactive Video",
"description": "Used in summaries, statistics etc."
},
{
"name": "hideStartTitle",
"type": "boolean",
"label": "Hide title on video start screen",
"importance": "low",
"optional": true,
"default": false
},
{
"name": "shortStartDescription",
"type": "text",
"label": "Short description (Optional)",
"importance": "low",
"optional": true,
"maxLength": 120,
"description": "Optional. Display a short description text on the video start screen. Does not work for YouTube videos."
},
{
"name": "poster",
"type": "image",
"label": "Poster image",
"importance": "low",
"optional": true,
"description": "Image displayed before the user launches the video. Does not work for YouTube Videos."
},
{
"name": "copyright",
"type": "text",
"widget": "html",
"enterMode": "p",
"label": "Video copyright information",
"importance": "low",
"optional": true,
"description": "Information regarding copyright of the video and elements used in the video.",
"tags": [
"strong",
"em",
"del",
"a"
]
}
]
},
{
"name": "textTracks",
"type": "group",
"label": "Text tracks (unsupported for YouTube videos)",
"importance": "low",
"fields": [
{
"name": "videoTrack",
"type": "list",
"label": "Available text tracks",
"importance": "low",
"optional": true,
"entity": "Track",
"min": 0,
"defaultNum": 1,
"field": {
"name": "track",
"type": "group",
"label": "Track",
"importance": "low",
"expanded": false,
"fields": [
{
"name": "label",
"type": "text",
"label": "Track label",
"description": "Used if you offer multiple tracks and the user has to choose a track. For instance 'Spanish subtitles' could be the label of a Spanish subtitle track.",
"importance": "low",
"default": "Subtitles",
"optional": true
},
{
"name": "kind",
"type": "select",
"label": "Type of text track",
"importance": "low",
"default": "subtitles",
"options": [
{
"value": "subtitles",
"label": "Subtitles"
},
{
"value": "captions",
"label": "Captions"
},
{
"value": "descriptions",
"label": "Descriptions"
}
]
},
{
"name": "srcLang",
"type": "text",
"label": "Source language, must be defined for subtitles",
"importance": "low",
"default": "en",
"description": "Must be a valid BCP 47 language tag. If 'Subtitles' is the type of text track selected, the source language of the track must be defined."
},
{
"name": "track",
"type": "file",
"label": "Track source (WebVTT file)",
"importance": "low"
}
]
}
}
]
}
]
},
{
"name": "assets",
"type": "group",
"label": "Add interactions",
"importance": "high",
"widget": "interactiveVideo",
"video": "video/files",
"poster": "video/startScreenOptions/poster",
"fields": [
{
"name": "interactions",
"type": "list",
"field": {
"name": "interaction",
"type": "group",
"fields": [
{
"name": "duration",
"type": "group",
"widget": "duration",
"label": "Display time",
"importance": "low",
"fields": [
{
"name": "from",
"type": "number"
},
{
"name": "to",
"type": "number"
}
]
},
{
"name": "pause",
"label": "Pause video",
"importance": "low",
"type": "boolean"
},
{
"name": "displayType",
"label": "Display as",
"importance": "low",
"description": "Button is a collapsed interaction the user must press to open. Poster is an expanded interaction displayed directly on top of the video",
"type": "select",
"widget": "imageRadioButtonGroup",
"options": [
{
"value": "button",
"label": "Button"
},
{
"value": "poster",
"label": "Poster"
}
],
"default": "button"
},
{
"name": "buttonOnMobile",
"label": "Turn into button on small screens",
"importance": "low",
"type": "boolean",
"default": false
},
{
"name": "label",
"type": "text",
"widget": "html",
"label": "Label",
"importance": "low",
"description": "Label displayed next to interaction icon.",
"optional": true,
"enterMode": "p",
"tags": [
"p"
]
},
{
"name": "x",
"type": "number",
"importance": "low",
"widget": "none"
},
{
"name": "y",
"type": "number",
"importance": "low",
"widget": "none"
},
{
"name": "width",
"type": "number",
"widget": "none",
"importance": "low",
"optional": true
},
{
"name": "height",
"type": "number",
"widget": "none",
"importance": "low",
"optional": true
},
{
"name": "libraryTitle",
"type": "text",
"importance": "low",
"optional": true,
"widget": "none"
},
{
"name": "action",
"type": "library",
"importance": "low",
"options": [
"H5P.Nil 1.0",
"H5P.Text 1.1",
"H5P.Table 1.1",
"H5P.Link 1.3",
"H5P.Image 1.0",
"H5P.Summary 1.8",
"H5P.SingleChoiceSet 1.9",
"H5P.MultiChoice 1.10",
"H5P.TrueFalse 1.2",
"H5P.Blanks 1.8",
"H5P.DragQuestion 1.11",
"H5P.MarkTheWords 1.7",
"H5P.DragText 1.6",
"H5P.GoToQuestion 1.3",
"H5P.IVHotspot 1.2",
"H5P.Questionnaire 1.2"
]
},
{
"name": "adaptivity",
"type": "group",
"label": "Adaptivity",
"importance": "low",
"optional": true,
"fields": [
{
"name": "correct",
"type": "group",
"label": "Action on all correct",
"fields": [
{
"name": "seekTo",
"type": "number",
"widget": "timecode",
"label": "Seek to",
"description": "Enter timecode in the format M:SS"
},
{
"name": "allowOptOut",
"type": "boolean",
"label": "Allow the user to opt out and continue"
},
{
"name": "message",
"type": "text",
"widget": "html",
"enterMode": "p",
"tags": [
"strong",
"em",
"del",
"a"
],
"label": "Message"
},
{
"name": "seekLabel",
"type": "text",
"label": "Label for seek button"
}
]
},
{
"name": "wrong",
"type": "group",
"label": "Action on wrong",
"fields": [
{
"name": "seekTo",
"type": "number",
"widget": "timecode",
"label": "Seek to",
"description": "Enter timecode in the format M:SS"
},
{
"name": "allowOptOut",
"type": "boolean",
"label": "Allow the user to opt out and continue"
},
{
"name": "message",
"type": "text",
"widget": "html",
"enterMode": "p",
"tags": [
"strong",
"em",
"del",
"a"
],
"label": "Message"
},
{
"name": "seekLabel",
"type": "text",
"label": "Label for seek button"
}
]
},
{
"name": "requireCompletion",
"type": "boolean",
"label": "Require full score for task before proceeding",
"description": "For best functionality this option should be used in conjunction with the \"Prevent skipping forward in a video\" option of Interactive Video."
}
]
},
{
"name": "visuals",
"label": "Visuals",
"importance": "low",
"type": "group",
"fields": [
{
"name": "backgroundColor",
"type": "text",
"label": "Background color",
"widget": "colorSelector",
"default": "rgb(255, 255, 255)",
"spectrum": {
"showInput": true,
"showAlpha": true,
"preferredFormat": "rgb",
"showPalette": true,
"palette": [
[
"rgba(0, 0, 0, 0)"
],
[
"rgb(67, 67, 67)",
"rgb(102, 102, 102)",
"rgb(204, 204, 204)",
"rgb(217, 217, 217)",
"rgb(255, 255, 255)"
],
[
"rgb(152, 0, 0)",
"rgb(255, 0, 0)",
"rgb(255, 153, 0)",
"rgb(255, 255, 0)",
"rgb(0, 255, 0)",
"rgb(0, 255, 255)",
"rgb(74, 134, 232)",
"rgb(0, 0, 255)",
"rgb(153, 0, 255)",
"rgb(255, 0, 255)"
],
[
"rgb(230, 184, 175)",
"rgb(244, 204, 204)",
"rgb(252, 229, 205)",
"rgb(255, 242, 204)",
"rgb(217, 234, 211)",
"rgb(208, 224, 227)",
"rgb(201, 218, 248)",
"rgb(207, 226, 243)",
"rgb(217, 210, 233)",
"rgb(234, 209, 220)",
"rgb(221, 126, 107)",
"rgb(234, 153, 153)",
"rgb(249, 203, 156)",
"rgb(255, 229, 153)",
"rgb(182, 215, 168)",
"rgb(162, 196, 201)",
"rgb(164, 194, 244)",
"rgb(159, 197, 232)",
"rgb(180, 167, 214)",
"rgb(213, 166, 189)",
"rgb(204, 65, 37)",
"rgb(224, 102, 102)",
"rgb(246, 178, 107)",
"rgb(255, 217, 102)",
"rgb(147, 196, 125)",
"rgb(118, 165, 175)",
"rgb(109, 158, 235)",
"rgb(111, 168, 220)",
"rgb(142, 124, 195)",
"rgb(194, 123, 160)",
"rgb(166, 28, 0)",
"rgb(204, 0, 0)",
"rgb(230, 145, 56)",
"rgb(241, 194, 50)",
"rgb(106, 168, 79)",
"rgb(69, 129, 142)",
"rgb(60, 120, 216)",
"rgb(61, 133, 198)",
"rgb(103, 78, 167)",
"rgb(166, 77, 121)",
"rgb(91, 15, 0)",
"rgb(102, 0, 0)",
"rgb(120, 63, 4)",
"rgb(127, 96, 0)",
"rgb(39, 78, 19)",
"rgb(12, 52, 61)",
"rgb(28, 69, 135)",
"rgb(7, 55, 99)",
"rgb(32, 18, 77)",
"rgb(76, 17, 48)"
]
]
}
},
{
"name": "boxShadow",
"type": "boolean",
"label": "Box shadow",
"default": true,
"description": "Adds a subtle shadow around the interaction. You might want to disable this for completely transparent interactions"
}
]
},
{
"name": "goto",
"label": "Go to on click",
"importance": "low",
"type": "group",
"fields": [
{
"name": "type",
"label": "Type",
"type": "select",
"widget": "selectToggleFields",
"options": [
{
"value": "timecode",
"label": "Timecode",
"hideFields": [
"url"
]
},
{
"value": "url",
"label": "Another page (URL)",
"hideFields": [
"time"
]
}
],
"optional": true
},
{
"name": "time",
"type": "number",
"widget": "timecode",
"label": "Go To",
"description": "The target time the user will be taken to upon pressing the hotspot. Enter timecode in the format M:SS.",
"optional": true
},
{
"name": "url",
"type": "group",
"label": "URL",
"widget": "linkWidget",
"optional": true,
"fields": [
{
"name": "protocol",
"type": "select",
"label": "Protocol",
"options": [
{
"value": "http://",
"label": "http://"
},
{
"value": "https://",
"label": "https://"
},
{
"value": "/",
"label": "(root relative)"
},
{
"value": "other",
"label": "other"
}
],
"optional": true,
"default": "http://"
},
{
"name": "url",
"type": "text",
"label": "URL",
"optional": true
}
]
},
{
"name": "visualize",
"type": "boolean",
"label": "Visualize",
"description": "Show that interaction can be clicked by adding a border and an icon"
}
]
}
]
}
},
{
"name": "bookmarks",
"importance": "low",
"type": "list",
"field": {
"name": "bookmark",
"type": "group",
"fields": [
{
"name": "time",
"type": "number"
},
{
"name": "label",
"type": "text"
}
]
}
}
]
},
{
"name": "summary",
"type": "group",
"label": "Summary task",
"importance": "high",
"fields": [
{
"name": "task",
"type": "library",
"options": [
"H5P.Summary 1.8"
],
"default": {
"library": "H5P.Summary 1.8",
"params": {}
}
},
{
"name": "displayAt",
"type": "number",
"label": "Display at",
"description": "Number of seconds before the video ends.",
"default": 3
}
]
}
]
},
{
"name": "override",
"type": "group",
"label": "Behavioural settings",
"importance": "low",
"optional": true,
"fields": [
{
"name": "startVideoAt",
"type": "number",
"widget": "timecode",
"label": "Start video at",
"importance": "low",
"optional": true,
"description": "Enter timecode in the format M:SS"
},
{
"name": "autoplay",
"type": "boolean",
"label": "Auto-play video",
"default": false,
"optional": true,
"description": "Start playing the video automatically"
},
{
"name": "loop",
"type": "boolean",
"label": "Loop the video",
"default": false,
"optional": true,
"description": "Check if video should run in a loop"
},
{
"name": "showSolutionButton",
"type": "select",
"label": "Override \"Show Solution\" button",
"importance": "low",
"description": "This option determines if the \"Show Solution\" button will be shown for all questions, disabled for all or configured for each question individually.",
"optional": true,
"options": [
{
"value": "on",
"label": "Enabled"
},
{
"value": "off",
"label": "Disabled"
}
]
},
{
"name": "retryButton",
"type": "select",
"label": "Override \"Retry\" button",
"importance": "low",
"description": "This option determines if the \"Retry\" button will be shown for all questions, disabled for all or configured for each question individually.",
"optional": true,
"options": [
{
"value": "on",
"label": "Enabled"
},
{
"value": "off",
"label": "Disabled"
}
]
},
{
"name": "showBookmarksmenuOnLoad",
"type": "boolean",
"label": "Start with bookmarks menu open",
"importance": "low",
"default": false,
"description": "This function is not available on iPad when using YouTube as video source."
},
{
"name": "showRewind10",
"type": "boolean",
"label": "Show button for rewinding 10 seconds",
"importance": "low",
"default": false
},
{
"name": "preventSkipping",
"type": "boolean",
"default": false,
"label": "Prevent skipping forward in a video",
"importance": "low",
"description": "Enabling this options will disable user video navigation through default controls."
},
{
"name": "deactivateSound",
"type": "boolean",
"default": false,
"label": "Deactivate sound",
"importance": "low",
"description": "Enabling this option will deactivate the video's sound and prevent it from being switched on."
}
]
},
{
"name": "l10n",
"type": "group",
"label": "Localize",
"importance": "low",
"common": true,
"optional": true,
"fields": [
{
"name": "interaction",
"type": "text",
"label": "Interaction title",
"importance": "low",
"default": "Interaction",
"optional": true
},
{
"name": "play",
"type": "text",
"label": "Play title",
"importance": "low",
"default": "Play",
"optional": true
},
{
"name": "pause",
"type": "text",
"label": "Pause title",
"importance": "low",
"default": "Pause",
"optional": true
},
{
"name": "mute",
"type": "text",
"label": "Mute title",
"importance": "low",
"default": "Mute",
"optional": true
},
{
"name": "unmute",
"type": "text",
"label": "Unmute title",
"importance": "low",
"default": "Unmute",
"optional": true
},
{
"name": "quality",
"type": "text",
"label": "Video quality title",
"importance": "low",
"default": "Video Quality",
"optional": true
},
{
"name": "captions",
"type": "text",
"label": "Video captions title",
"importance": "low",
"default": "Captions",
"optional": true
},
{
"name": "close",
"type": "text",
"label": "Close button text",
"importance": "low",
"default": "Close",
"optional": true
},
{
"name": "fullscreen",
"type": "text",
"label": "Fullscreen title",
"importance": "low",
"default": "Fullscreen",
"optional": true
},
{
"name": "exitFullscreen",
"type": "text",
"label": "Exit fullscreen title",
"importance": "low",
"default": "Exit Fullscreen",
"optional": true
},
{
"name": "summary",
"type": "text",
"label": "Summary title",
"importance": "low",
"default": "Summary",
"optional": true
},
{
"name": "bookmarks",
"type": "text",
"label": "Bookmarks title",
"importance": "low",
"default": "Bookmarks",
"optional": true
},
{
"name": "defaultAdaptivitySeekLabel",
"type": "text",
"label": "Default label for adaptivity seek button",
"importance": "low",
"default": "Continue",
"optional": true
},
{
"name": "continueWithVideo",
"type": "text",
"label": "Default label for continue video button",
"importance": "low",
"default": "Continue with video",
"optional": true
},
{
"name": "playbackRate",
"type": "text",
"label": "Set playback rate",
"importance": "low",
"default": "Playback Rate",
"optional": true
},
{
"name": "rewind10",
"type": "text",
"label": "Rewind 10 Seconds",
"importance": "low",
"default": "Rewind 10 Seconds",
"optional": true
},
{
"name": "navDisabled",
"type": "text",
"label": "Navigation is disabled text",
"importance": "low",
"default": "Navigation is disabled",
"optional": true
},
{
"name": "sndDisabled",
"type": "text",
"label": "Sound is disabled text",
"importance": "low",
"default": "Sound is disabled",
"optional": true
},
{
"name": "requiresCompletionWarning",
"type": "text",
"label": "Warning that the user must answer the question correctly before continuing",
"importance": "low",
"default": "You need to answer all the questions correctly before continuing.",
"optional": true
},
{
"name": "back",
"type": "text",
"label": "Back button",
"importance": "low",
"default": "Back",
"optional": true
},
{
"name": "hours",
"type": "text",
"label": "Passed time hours",
"importance": "low",
"default": "Hours",
"optional": true
},
{
"name": "minutes",
"type": "text",
"label": "Passed time minutes",
"importance": "low",
"default": "Minutes",
"optional": true
},
{
"name": "seconds",
"type": "text",
"label": "Passed time seconds",
"importance": "low",
"default": "Seconds",
"optional": true
},
{
"name": "currentTime",
"type": "text",
"label": "Label for current time",
"importance": "low",
"default": "Current time:",
"optional": true
},
{
"name": "totalTime",
"type": "text",
"label": "Label for total time",
"importance": "low",
"default": "Total time:",
"optional": true
},
{
"name": "navigationHotkeyInstructions",
"type": "text",
"label": "Text for explaining navigation hotkey",
"importance": "low",
"default": "Use key k for starting and stopping video at any time",
"optional": true
},
{
"name": "singleInteractionAnnouncement",
"type": "text",
"label": "Text explaining that a single interaction with a name has come into view",
"importance": "low",
"default": "Interaction appeared:",
"optional": true
},
{
"name": "multipleInteractionsAnnouncement",
"type": "text",
"label": "Text for explaining that multiple interactions have come into view",
"importance": "low",
"default": "Multiple interactions appeared.",
"optional": true
},
{
"name": "videoPausedAnnouncement",
"type": "text",
"label": "Video is paused announcement",
"importance": "low",
"default": "Video is paused",
"optional": true
},
{
"name": "content",
"type": "text",
"label": "Content label",
"importance": "low",
"default": "Content",
"optional": true
}
]
}
]
,"language": null,"javascript": {"Scripts/Wizard.js":"var H5PEditor = H5PEditor || {};\n\n/**\n * Wizard editor widget module\n *\n * @param {jQuery} $\n */\nH5PEditor.widgets.wizard = H5PEditor.Wizard = (function ($, EventDispatcher) {\n\n /**\n * Initialize wizard editor.\n *\n * @param {mixed} parent\n * @param {Object} field\n * @param {mixed} params\n * @param {function} setValue\n * @returns {_L8.C}\n */\n function C(parent, field, params, setValue) {\n var that = this;\n\n // Event support\n H5P.EventDispatcher.call(that);\n\n this.parent = parent;\n this.field = field;\n this.params = params;\n this.setValue = setValue;\n this.library = parent.library + \u0027/\u0027 + field.name;\n this.children = [];\n\n this.passReadies = true;\n parent.ready(function () {\n that.passReadies = false;\n });\n }\n\n // Inheritance\n C.prototype = Object.create(EventDispatcher.prototype);\n C.prototype.constructor = C;\n\n /**\n * Append field to wrapper.\n *\n * @param {jQuery} $wrapper\n * @returns {undefined}\n */\n C.prototype.appendTo = function ($wrapper) {\n var that = this;\n this.$item = $(this.createHtml()).appendTo($wrapper);\n this.$errors = this.$item.children(\u0027.h5p-errors\u0027);\n var $panesWrapper = $(\u0027\u003cdiv class=\"h5peditor-panes\"\u003e\u003c/div\u003e\u0027).insertBefore(this.$errors);\n\n if (this.params === undefined) {\n this.params = {};\n this.setValue(this.field, this.params);\n }\n H5PEditor.processSemanticsChunk(this.field.fields, this.params, $panesWrapper, this);\n\n this.$panes = $panesWrapper.children();\n this.$tabs = this.$item.find(\u0027ol \u003e li \u003e a\u0027).click(function () {\n that.showTab($(this));\n return false;\n });\n\n this.$panes.children(\u0027.h5peditor-label\u0027).hide();\n\n // Make sure first tab is selected as default\n this.$tabs.eq(0).click();\n\n // Create wizard navigation buttons and attach events\n var $prevButton = this.$item.find(\u0027.nav-button-prev\u0027).click(function () {\n var currentTabId = that.$item.find(\u0027.h5peditor-active\u0027).attr(\u0027data-id\u0027);\n that.showTab(that.$item.find(\u0027ol \u003e li \u003e a\u0027).eq(parseInt(currentTabId) - 1));\n });\n\n var $nextButton = this.$item.find(\u0027.nav-button-next\u0027).click(function () {\n var currentTabId = that.$item.find(\u0027.h5peditor-active\u0027).attr(\u0027data-id\u0027);\n that.showTab(that.$item.find(\u0027ol \u003e li \u003e a\u0027).eq(parseInt(currentTabId) + 1));\n });\n\n // Create wizard navigation wrapper and attach buttons\n var $navButtonsWrapper = $(\u0027\u003cdiv class=\"h5peditor-wizard-navigation-buttons\"\u003e\u003c/div\u003e\u0027)\n .append($prevButton)\n .append($nextButton)\n .appendTo(this.$item);\n };\n\n /**\n * Update the wizard navigation\n\n * @param {jQuery} $tab\n * @param {String} currentTabId\n */\n C.prototype.updateWizardNavigation = function ($tab, currentTabId) {\n currentTabId = parseInt(currentTabId, 10);\n var $prevButton = this.$item.find(\u0027.nav-button-prev\u0027);\n var $nextButton = this.$item.find(\u0027.nav-button-next\u0027);\n\n // If there is a previous tab, update navigation prev button\n if (currentTabId \u003e 0) {\n var $prevTab = this.$tabs.eq(currentTabId - 1);\n\n // Get the specific classname of the previous tab to mimic icon for navigation button\n var prevTabClasses = $prevTab.attr(\u0027class\u0027).split(\u0027 \u0027).filter(function (className) {\n return (className.match(/h5peditor-tab-[a-zA-z]{2,}/i) !== null);\n })[0];\n\n this.$item.find(\u0027.nav-button-prev .nav-button-label\u0027)\n .attr(\u0027class\u0027, \u0027nav-button-label \u0027 + prevTabClasses)\n .text($prevTab.find(\u0027.field-name\u0027).text());\n\n $prevButton.show();\n }\n else {\n $prevButton.hide();\n }\n\n // If there is a next tab, update navigation next button\n if (currentTabId \u003c this.$tabs.length - 1) {\n var $nextTab = this.$tabs.eq(currentTabId + 1);\n\n // Get the specific classname of the next tab to mimic icon for navigation button\n var nextTabClasses = $nextTab.attr(\u0027class\u0027).split(\u0027 \u0027).filter(function (className) {\n return (className.match(/h5peditor-tab-[a-zA-z]{2,}/i) !== null);\n })[0];\n\n this.$item.find(\u0027.nav-button-next .nav-button-label\u0027)\n .attr(\u0027class\u0027, \u0027nav-button-label \u0027 + nextTabClasses)\n .text($nextTab.find(\u0027.field-name\u0027).text());\n\n $nextButton.show();\n }\n else {\n $nextButton.hide();\n }\n };\n\n /**\n * Create HTML for the field.\n */\n C.prototype.createHtml = function () {\n // Create wizard tabs\n var html = \u0027\u003col class=\"h5peditor-tabs\"\u003e\u0027;\n for (var i = 0; i \u003c this.field.fields.length; i++) {\n var field = this.field.fields[i];\n html += C.createTab(i, field);\n }\n html += \u0027\u003c/ol\u003e\u0027;\n\n // Create wizard navigation buttons\n html += \u0027\u003cdiv class=\"nav-button-prev\"\u003e\u0027 +\n \u0027\u003cspan class=\"nav-button-icon\"\u003e\u003c/span\u003e\u0027 +\n \u0027\u003cdiv\u003e\u0027 +\n \u0027\u003cspan\u003e\u0027 + C.t(\u0027previousStep\u0027) + \u0027\u003c/span\u003e\u0027 +\n \u0027\u003cspan class=\"nav-button-label\"\u003e\u0027 + this.field.fields[0].label + \u0027\u003c/span\u003e\u0027 +\n \u0027\u003c/div\u003e\u0027 +\n \u0027\u003c/div\u003e\u0027 +\n \u0027\u003cdiv class=\"nav-button-next\"\u003e\u0027 +\n \u0027\u003cdiv\u003e\u0027 +\n \u0027\u003cspan\u003e\u0027 + C.t(\u0027nextStep\u0027) + \u0027\u003c/span\u003e\u0027 +\n \u0027\u003cspan class=\"nav-button-label\"\u003e\u0027 + this.field.fields[1].label + \u0027\u003c/span\u003e\u0027 +\n \u0027\u003c/div\u003e\u0027 +\n \u0027\u003cspan class=\"nav-button-icon\"\u003e\u003c/span\u003e\u0027 +\n \u0027\u003c/div\u003e\u0027;\n\n return H5PEditor.createFieldMarkup(this.field, html);\n };\n\n /**\n * Display tab.\n *\n * @param {jQuery} $tab\n * @returns {undefined}\n */\n C.prototype.showTab = function ($tab) {\n var id = $tab.attr(\u0027data-id\u0027);\n this.$panes.hide().eq(id).show();\n this.$tabs.removeClass(\u0027h5peditor-active\u0027);\n $tab.addClass(\u0027h5peditor-active\u0027);\n\n // Update wizard navigation to sync with tabs\n this.updateWizardNavigation($tab, id);\n\n // Give the poor child a chance to handle tab switching.\n if (this.children[id].setActive !== undefined) {\n this.children[id].setActive();\n }\n\n this.trigger(\u0027stepChanged\u0027, {\n id: parseInt(id),\n name: this.field.fields[id].name\n });\n };\n\n /**\n * Validate the current field.\n *\n * @returns {Boolean}\n */\n C.prototype.validate = function () {\n for (var i = 0; i \u003c this.children.length; i++) {\n if (!this.children[i].validate()) {\n return false;\n }\n }\n\n return true;\n };\n\n /**\n * Local translate function.\n *\n * @param {Atring} key\n * @param {Object} params\n * @returns {@exp;H5PEditor@call;t}\n */\n C.t = function (key, params) {\n return H5PEditor.t(\u0027H5PEditor.Wizard\u0027, key, params);\n };\n\n /**\n * Collect functions to execute once the tree is complete.\n *\n * @param {function} ready\n * @returns {undefined}\n */\n C.prototype.ready = function (ready) {\n if (this.passReadies) {\n this.parent.ready(ready);\n }\n else {\n this.readies.push(ready);\n }\n };\n\n /**\n * Remove this item.\n */\n C.prototype.remove = function () {\n H5PEditor.removeChildren(this.children);\n this.$item.remove();\n };\n\n /**\n * Create HTML for a tab.\n *\n * @param {type} id\n * @param {type} label\n * @returns {String}\n */\n C.createTab = function (id, field) {\n return \u0027\u003cli class=\"h5peditor-tab-li\"\u003e\u003ca href=\"#\" class=\"h5peditor-tab-a h5peditor-tab-\u0027 + field.name.toLowerCase() + \u0027\" data-id=\"\u0027 + id + \u0027\"\u003e\u0027 +\n \u0027\u003cspan class=\"field-step\"\u003e\u0027 + C.t(\u0027step\u0027, { \u0027:index\u0027: id + 1 }) + \u0027\u003c/span\u003e\u0027 +\n \u0027\u003cspan class=\"field-name\"\u003e\u0027 + field.label + \u0027\u003c/span\u003e\u0027 +\n \u0027\u003c/a\u003e\u003c/li\u003e\u0027;\n };\n\n return C;\n})(H5P.jQuery, H5P.EventDispatcher);\n\n// Default english translations\nH5PEditor.language[\u0027H5PEditor.Wizard\u0027] = {\n libraryStrings: {\n previousStep: \u0027Previous Step\u0027,\n nextStep: \u0027Next Step\u0027,\n step: \u0027Step :index\u0027\n }\n};\n"
,"drag-n-drop.js":"var H5P = H5P || {};\n\n/**\n * A class that easily helps your create awesome drag and drop.\n *\n * @param {H5P.DragNBar} DnB\n * @param {jQuery} $container\n * @returns {undefined}\n */\nH5P.DragNDrop = function (dnb, $container) {\n H5P.EventDispatcher.call(this);\n this.dnb = dnb;\n this.$container = $container;\n this.scrollLeft = 0;\n this.scrollTop = 0;\n};\n\n// Inherit support for events\nH5P.DragNDrop.prototype = Object.create(H5P.EventDispatcher.prototype);\nH5P.DragNDrop.prototype.constructor = H5P.DragNDrop;\n\n/**\n * Set the current element\n * \n * @method setElement\n * @param {j@uery} $element\n */\nH5P.DragNDrop.prototype.setElement = function ($element) {\n this.$element = $element;\n};\n\n/**\n * Start tracking the mouse.\n *\n * @param {jQuery} $element\n * @param {Number} x Start X coordinate\n * @param {Number} y Start Y coordinate\n * @returns {undefined}\n */\nH5P.DragNDrop.prototype.press = function ($element, x, y) {\n var that = this;\n var eventData = {\n instance: this\n };\n\n H5P.$window\n .mousemove(eventData, H5P.DragNDrop.moveHandler)\n .bind(\u0027mouseup\u0027, eventData, H5P.DragNDrop.release);\n\n H5P.$body\n // With user-select: none uncommented, after moving a drag and drop element, if I hover over something that changes transparancy on hover IE10 on WIN7 crashes\n // TODO: Add user-select and -ms-user-select later if IE10 stops bugging\n .css({\u0027-moz-user-select\u0027: \u0027none\u0027, \u0027-webkit-user-select\u0027: \u0027none\u0027/*, \u0027user-select\u0027: \u0027none\u0027, \u0027-ms-user-select\u0027: \u0027none\u0027*/})\n .attr(\u0027unselectable\u0027, \u0027on\u0027)[0]\n .onselectstart = H5P.$body[0].ondragstart = function () {\n return false;\n };\n\n that.containerOffset = $element.offsetParent().offset();\n\n this.$element = $element;\n this.moving = false;\n this.startX = x;\n this.startY = y;\n\n this.marginX = parseInt($element.css(\u0027marginLeft\u0027)) + parseInt($element.css(\u0027marginRight\u0027));\n this.marginY = parseInt($element.css(\u0027marginTop\u0027)) + parseInt($element.css(\u0027marginBottom\u0027));\n\n var offset = $element.offset();\n this.adjust = {\n x: x - offset.left + this.marginX,\n y: y - offset.top - this.marginY\n };\n\n if (that.dnb \u0026\u0026 that.dnb.newElement) {\n this.move(x, y);\n }\n};\n\n/**\n * Handles mouse move events.\n *\n * @param {Event} event\n */\nH5P.DragNDrop.moveHandler = function (event) {\n event.stopPropagation();\n event.data.instance.move(event.pageX, event.pageY);\n};\n\n/**\n * Handles mouse movements.\n *\n * @param {number} x\n * @param {number} y\n */\nH5P.DragNDrop.prototype.move = function (x, y) {\n var that = this;\n\n if (!that.moving) {\n if (that.startMovingCallback !== undefined \u0026\u0026 !that.startMovingCallback(x, y)) {\n return;\n }\n\n // Start moving\n that.moving = true;\n that.$element.addClass(\u0027h5p-moving\u0027);\n }\n\n x -= that.adjust.x;\n y -= that.adjust.y;\n\n var posX = x - that.containerOffset.left + that.scrollLeft;\n var posY = y - that.containerOffset.top + that.scrollTop;\n\n if (that.snap !== undefined) {\n posX = Math.round(posX / that.snap) * that.snap;\n posY = Math.round(posY / that.snap) * that.snap;\n }\n\n // Do not move outside of minimum values.\n if (that.min !== undefined) {\n if (posX \u003c that.min.x) {\n posX = that.min.x;\n x = that.min.x + that.containerOffset.left - that.scrollLeft;\n }\n if (posY \u003c that.min.y) {\n posY = that.min.y;\n y = that.min.y + that.containerOffset.top - that.scrollTop;\n }\n }\n\n\n if (that.dnb \u0026\u0026 that.dnb.newElement \u0026\u0026 posY \u003e= 0) {\n that.min.y = 0;\n }\n\n // Do not move outside of maximum values.\n if (that.max !== undefined) {\n if (posX \u003e that.max.x) {\n posX = that.max.x;\n x = that.max.x + that.containerOffset.left - that.scrollLeft;\n }\n if (posY \u003e that.max.y) {\n posY = that.max.y;\n y = that.max.y + that.containerOffset.top - that.scrollTop;\n }\n }\n\n // Show transform panel if element has moved\n var startX = that.startX - that.adjust.x - that.containerOffset.left + that.scrollLeft;\n var startY = that.startY - that.adjust.y - that.containerOffset.top + that.scrollTop;\n if (!that.snap \u0026\u0026 (posX !== startX || posY !== startY)) {\n that.trigger(\u0027showTransformPanel\u0027);\n }\n else if (that.snap) {\n var xChanged = (Math.round(posX / that.snap) * that.snap) !==\n (Math.round(startX / that.snap) * that.snap);\n var yChanged = (Math.round(posY / that.snap) * that.snap) !==\n (Math.round(startY / that.snap) * that.snap);\n if (xChanged || yChanged) {\n that.trigger(\u0027showTransformPanel\u0027);\n }\n }\n\n that.$element.css({left: posX, top: posY});\n\n if (that.dnb) {\n that.dnb.updateCoordinates();\n }\n\n if (that.moveCallback !== undefined) {\n that.moveCallback(x, y, that.$element);\n }\n};\n\n/**\n * Stop tracking the mouse.\n *\n * @param {Object} event\n * @returns {undefined}\n */\nH5P.DragNDrop.release = function (event) {\n var that = event.data.instance;\n\n H5P.$window\n .unbind(\u0027mousemove\u0027, H5P.DragNDrop.moveHandler)\n .unbind(\u0027mouseup\u0027, H5P.DragNDrop.release);\n\n H5P.$body\n .css({\u0027-moz-user-select\u0027: \u0027\u0027, \u0027-webkit-user-select\u0027: \u0027\u0027/*, \u0027user-select\u0027: \u0027\u0027, \u0027-ms-user-select\u0027: \u0027\u0027*/})\n .removeAttr(\u0027unselectable\u0027)[0]\n .onselectstart = H5P.$body[0].ondragstart = null;\n\n if (that.releaseCallback !== undefined) {\n that.releaseCallback();\n }\n\n if (that.moving) {\n that.$element.removeClass(\u0027h5p-moving\u0027);\n if (that.stopMovingCallback !== undefined) {\n that.stopMovingCallback(event);\n }\n }\n\n // trigger to hide the transform panel unless it was activated\n // through the context menu\n that.trigger(\u0027hideTransformPanel\u0027);\n};\n"
,"H5P.DragNResize.js":"/*global H5P*/\nH5P.DragNResize = (function ($, EventDispatcher) {\n\n /**\n * Constructor!\n *\n * @class H5P.DragNResize\n * @param {H5P.jQuery} $container\n */\n function C($container) {\n var self = this;\n this.$container = $container;\n self.disabledModifiers = false;\n\n EventDispatcher.call(this);\n\n // Override settings for snapping to grid, and locking aspect ratio.\n H5P.$body.keydown(function (event) {\n if (self.disabledModifiers) {\n return;\n }\n\n if (event.keyCode === 17) {\n // Ctrl\n self.revertSnap = true;\n }\n else if (event.keyCode === 16) {\n // Shift\n self.revertLock = true;\n }\n }).keyup(function (event) {\n if (self.disabledModifiers) {\n return;\n }\n\n if (event.keyCode === 17) {\n // Ctrl\n self.revertSnap = false;\n }\n else if (event.keyCode === 16) {\n // Shift\n self.revertLock = false;\n }\n });\n }\n\n // Inheritance\n C.prototype = Object.create(EventDispatcher.prototype);\n C.prototype.constructor = C;\n\n /**\n * Gives the given element a resize handle.\n *\n * @param {H5P.jQuery} $element\n * @param {Object} [options]\n * @param {boolean} [options.lock]\n * @param {boolean} [options.cornerLock]\n */\n C.prototype.add = function ($element, options) {\n var that = this;\n\n // Array with position of handles\n var cornerPositions = [\u0027nw\u0027, \u0027ne\u0027, \u0027sw\u0027, \u0027se\u0027];\n var edgePositions = [\u0027n\u0027, \u0027w\u0027, \u0027e\u0027, \u0027s\u0027];\n\n var addResizeHandle = function (position, corner) {\n $(\u0027\u003cdiv\u003e\u0027, {\n \u0027class\u0027: \u0027h5p-dragnresize-handle \u0027 + position\n }).mousedown(function (event) {\n that.lock = (options \u0026\u0026 (options.lock || corner \u0026\u0026 options.cornerLock));\n if (options.cornerLock) {\n that.isImage = true;\n }\n that.$element = $element;\n that.press(event.clientX, event.clientY, position);\n }).data(\u0027position\u0027, position)\n .appendTo($element);\n };\n\n cornerPositions.forEach(function (pos) {\n addResizeHandle(pos, true);\n });\n\n // Add edge handles\n if (!options || !options.lock) {\n edgePositions.forEach(function (pos) {\n addResizeHandle(pos);\n });\n }\n };\n\n /**\n * Get paddings for the element\n */\n C.prototype.getElementPaddings = function () {\n return {\n horizontal: Number(this.$element.css(\u0027padding-left\u0027).replace(\"px\", \"\")) + Number(this.$element.css(\u0027padding-right\u0027).replace(\"px\", \"\")),\n vertical: Number(this.$element.css(\u0027padding-top\u0027).replace(\"px\", \"\")) + Number(this.$element.css(\u0027padding-bottom\u0027).replace(\"px\", \"\"))\n };\n };\n\n /**\n * Get borders for the element\n * @returns {{horizontal: number, vertical: number}}\n */\n C.prototype.getElementBorders = function () {\n return {\n horizontal: Number(this.$element.css(\u0027border-left-width\u0027).replace(\u0027px\u0027, \u0027\u0027)) + Number(this.$element.css(\u0027border-right-width\u0027).replace(\u0027px\u0027, \u0027\u0027)),\n vertical: Number(this.$element.css(\u0027border-top-width\u0027).replace(\u0027px\u0027, \u0027\u0027)) + Number(this.$element.css(\u0027border-bottom-width\u0027).replace(\u0027px\u0027, \u0027\u0027))\n }\n };\n\n C.prototype.setContainerEm = function (containerEm) {\n this.containerEm = containerEm;\n };\n\n /**\n * Start resizing\n *\n * @param {number} x\n * @param {number} y\n * @param {String} [direction] Direction of resize\n */\n C.prototype.press = function (x, y, direction) {\n this.active = true;\n var eventData = {\n instance: this,\n direction: direction\n };\n\n H5P.$window\n .bind(\u0027mouseup\u0027, eventData, C.release)\n .mousemove(eventData, C.move);\n\n H5P.$body\n .css({\n \u0027-moz-user-select\u0027: \u0027none\u0027,\n \u0027-webkit-user-select\u0027: \u0027none\u0027,\n \u0027user-select\u0027: \u0027none\u0027,\n \u0027-ms-user-select\u0027: \u0027none\u0027\n })\n .attr(\u0027unselectable\u0027, \u0027on\u0027)[0]\n .onselectstart = H5P.$body[0].ondragstart = function () {\n return false;\n };\n\n this.startX = x;\n this.startY = y;\n this.padding = this.getElementPaddings();\n this.borders = this.getElementBorders();\n this.startWidth = this.$element.outerWidth();\n this.startHeight = this.$element.outerHeight();\n this.ratio = (this.startWidth / this.startHeight);\n var position = this.$element.position();\n this.left = position.left;\n this.top = position.top;\n this.containerWidth = this.$container.width();\n this.containerHeight = this.$container.height();\n\n // Set default values\n this.newLeft = this.left;\n this.newTop = this.top;\n this.newWidth = this.startWidth;\n this.newHeight = this.startHeight;\n\n this.trigger(\u0027startResizing\u0027, eventData);\n\n // Show transform panel\n this.trigger(\u0027showTransformPanel\u0027);\n };\n\n /**\n * Resize events\n *\n * @param {Event} event\n */\n C.move = function (event) {\n var direction = (event.data.direction ? event.data.direction : \u0027se\u0027);\n var that = event.data.instance;\n var moveW = (direction === \u0027nw\u0027 || direction === \u0027sw\u0027 || direction === \u0027w\u0027);\n var moveN = (direction === \u0027nw\u0027 || direction === \u0027ne\u0027 || direction === \u0027n\u0027);\n var moveDiagonally = (direction === \u0027nw\u0027 || direction === \u0027ne\u0027 || direction === \u0027sw\u0027 || direction === \u0027se\u0027);\n var movesHorizontal = (direction === \u0027w\u0027 || direction === \u0027e\u0027);\n var movesVertical = (direction === \u0027n\u0027 || direction === \u0027s\u0027);\n var deltaX = that.startX - event.clientX;\n var deltaY = that.startY - event.clientY;\n\n that.minLeft = that.left + that.startWidth - H5P.DragNResize.MIN_SIZE;\n that.minTop = that.top + that.startHeight - H5P.DragNResize.MIN_SIZE;\n\n // Moving west\n if (moveW) {\n that.newLeft = that.left - deltaX;\n that.newWidth = that.startWidth + deltaX;\n\n // Check edge cases\n if (that.newLeft \u003c 0) {\n that.newLeft = 0;\n that.newWidth = that.left + that.startWidth;\n }\n else if (that.newLeft \u003e that.minLeft) {\n that.newLeft = that.minLeft;\n that.newWidth = that.left - that.minLeft + that.startWidth;\n }\n\n // Snap west side\n if (that.snap \u0026\u0026 !that.revertSnap) {\n that.newLeft = Math.round(that.newLeft / that.snap) * that.snap;\n\n // Make sure element does not snap east\n if (that.newLeft \u003e that.minLeft) {\n that.newLeft = Math.floor(that.minLeft / that.snap) * that.snap;\n }\n\n that.newWidth = (that.left - that.newLeft) + that.startWidth;\n }\n }\n else if (!movesVertical) {\n that.newWidth = that.startWidth - deltaX;\n\n // Snap width\n if (that.snap \u0026\u0026 !that.revertSnap) {\n that.newWidth = Math.round(that.newWidth / that.snap) * that.snap;\n }\n\n if (that.left + that.newWidth \u003e that.containerWidth) {\n that.newWidth = that.containerWidth - that.left;\n }\n }\n\n // Moving north\n if (moveN) {\n that.newTop = that.top - deltaY;\n that.newHeight = that.startHeight + deltaY;\n\n // Check edge cases\n if (that.newTop \u003c 0) {\n that.newTop = 0;\n that.newHeight = that.top + that.startHeight;\n }\n else if (that.newTop \u003e that.minTop) {\n that.newTop = that.minTop;\n that.newHeight = that.top - that.minTop + that.startHeight;\n }\n\n // Snap north\n if (that.snap \u0026\u0026 !that.revertSnap) {\n that.newTop = Math.round(that.newTop / that.snap) * that.snap;\n\n // Make sure element does not snap south\n if (that.newTop \u003e that.minTop) {\n that.newTop = Math.floor(that.minTop / that.snap) * that.snap;\n }\n\n that.newHeight = (that.top - that.newTop) + that.startHeight;\n }\n }\n else if (!movesHorizontal) {\n that.newHeight = that.startHeight - deltaY;\n\n // Snap height\n if (that.snap \u0026\u0026 !that.revertSnap) {\n that.newHeight = Math.round(that.newHeight / that.snap) * that.snap;\n }\n\n if (that.top + that.newHeight \u003e that.containerHeight) {\n that.newHeight = that.containerHeight - that.top;\n }\n }\n\n // Set min size\n if (that.newWidth \u003c= H5P.DragNResize.MIN_SIZE) {\n that.newWidth = H5P.DragNResize.MIN_SIZE;\n }\n\n if (that.newHeight \u003c= H5P.DragNResize.MIN_SIZE) {\n that.newHeight = H5P.DragNResize.MIN_SIZE;\n }\n\n // Apply ratio lock for elements except images, they have a their own specific for corner cases\n var lock = (that.revertLock ? !that.lock : that.lock);\n if (lock \u0026\u0026 (moveDiagonally || !that.isImage)) {\n that.lockDimensions(moveW, moveN, movesVertical, movesHorizontal);\n }\n\n // Reduce size by padding and borders\n that.finalWidth = that.newWidth;\n that.finalHeight = that.newHeight;\n if (that.$element.css(\u0027boxSizing\u0027) !== \u0027border-box\u0027) {\n that.finalWidth -= (that.padding.horizontal + that.borders.horizontal);\n that.finalHeight -= (that.padding.vertical + that.borders.vertical);\n }\n\n that.$element.css({\n width: (that.finalWidth / that.containerEm) + \u0027em\u0027,\n height: (that.finalHeight / that.containerEm) + \u0027em\u0027,\n left: ((that.newLeft / that.containerWidth) * 100) + \u0027%\u0027,\n top: ((that.newTop / that.containerHeight) * 100) + \u0027%\u0027\n });\n\n that.trigger(\u0027moveResizing\u0027);\n };\n\n /**\n * Changes element values depending on moving direction of the element\n * @param isMovingWest\n * @param isMovingNorth\n * @param movesVertical\n * @param movesHorizontal\n */\n C.prototype.lockDimensions = function (isMovingWest, isMovingNorth, movesVertical, movesHorizontal) {\n var self = this;\n\n // Cap movement at top\n var lockTop = function (isMovingNorth) {\n if (!isMovingNorth) {\n return;\n }\n\n self.newTop = self.top - (self.newHeight - self.startHeight);\n\n // Edge case\n if (self.newTop \u003c= 0) {\n self.newTop = 0;\n }\n };\n\n // Expand to longest edge\n if (movesVertical) {\n this.newWidth = this.newHeight * this.ratio;\n\n // Make sure locked ratio does not cause size to go below min size\n if (this.newWidth \u003c H5P.DragNResize.MIN_SIZE) {\n this.newWidth = H5P.DragNResize.MIN_SIZE;\n this.newHeight = H5P.DragNResize.MIN_SIZE / this.ratio;\n }\n }\n else if (movesHorizontal) {\n this.newHeight = this.newWidth / this.ratio;\n\n // Make sure locked ratio does not cause size to go below min size\n if (this.newHeight \u003c H5P.DragNResize.MIN_SIZE) {\n this.newHeight = H5P.DragNResize.MIN_SIZE;\n this.newWidth = H5P.DragNResize.MIN_SIZE * this.ratio;\n }\n }\n else if (this.newWidth / this.startWidth \u003e this.newHeight / this.startHeight) {\n // Expand to width\n this.newHeight = this.newWidth / this.ratio;\n }\n else {\n // Expand to height\n this.newWidth = this.newHeight * this.ratio;\n }\n\n // Change top to match new height\n if (isMovingNorth) {\n lockTop(isMovingNorth);\n\n if (self.newTop \u003c= 0) {\n self.newHeight = self.top + self.startHeight;\n self.newWidth = self.newHeight * self.ratio;\n }\n }\n else {\n // Too high\n if (this.top + this.newHeight \u003e this.containerHeight) {\n this.newHeight = this.containerHeight - this.top;\n this.newWidth = this.newHeight * this.ratio;\n }\n }\n\n // Change left to match new width\n if (isMovingWest) {\n this.newLeft = this.left - (this.newWidth - this.startWidth);\n // Edge case\n if (this.newLeft \u003c= 0) {\n this.newLeft = 0;\n this.newWidth = this.left + this.startWidth;\n this.newHeight = this.newWidth / this.ratio;\n }\n }\n else {\n // Too wide\n if (this.left + this.newWidth \u003e this.containerWidth) {\n this.newWidth = this.containerWidth - this.left;\n this.newHeight = this.newWidth / this.ratio;\n }\n }\n\n // Need to re-lock top in case height changed\n lockTop(isMovingNorth);\n };\n\n /**\n * Stop resizing\n *\n * @param {Event} event\n */\n C.release = function (event) {\n var that = event.data.instance;\n that.active = false;\n\n H5P.$window\n .unbind(\u0027mouseup\u0027, C.release)\n .unbind(\u0027mousemove\u0027, C.move);\n\n H5P.$body\n .css({\n \u0027-moz-user-select\u0027: \u0027\u0027,\n \u0027-webkit-user-select\u0027: \u0027\u0027,\n \u0027user-select\u0027: \u0027\u0027,\n \u0027-ms-user-select\u0027: \u0027\u0027\n })\n .removeAttr(\u0027unselectable\u0027)[0]\n .onselectstart = H5P.$body[0].ondragstart = null;\n\n if (that.newWidth !== that.startWidth ||\n that.newHeight !== that.startHeight) {\n // Stopped resizing send width and height in Ems\n that.trigger(\u0027stoppedResizing\u0027, {\n left: that.newLeft,\n top: that.newTop,\n width: that.finalWidth / that.containerEm,\n height: that.finalHeight / that.containerEm\n });\n }\n\n // Refocus element after resizing it. Apply timeout since focus is lost at the end of mouse event.\n setTimeout(function () {\n that.$element.focus();\n }, 0);\n\n // trigger to hide the transform panel unless it was activated\n // through the context menu\n that.trigger(\u0027hideTransformPanel\u0027);\n };\n\n /**\n * Toggle modifiers when we are not interacting with drag objects.\n * @param {boolean} [enable]\n */\n C.prototype.toggleModifiers = function (enable) {\n this.disabledModifiers = enable === undefined ? !this.disabledModifiers : !enable;\n };\n\n /**\n * Convert px value to number.\n *\n * @param {String} px\n * @returns {Number}\n */\n var pxToNum = function (px) {\n return Number(px.replace(\u0027px\u0027, \u0027\u0027));\n };\n\n C.MIN_SIZE = 24;\n\n return C;\n})(H5P.jQuery, H5P.EventDispatcher);\n"
,"scripts/drag-n-bar.js":"H5P.DragNBar = (function (EventDispatcher) {\n var nextInstanceIndex = 0;\n\n /**\n * Constructor. Initializes the drag and drop menu bar.\n *\n * @class\n * @param {Array} buttons\n * @param {H5P.jQuery} $container\n * @param {H5P.jQuery} $dialogContainer\n * @param {object} [options] Collection of options\n * @param {boolean} [options.disableEditor=false] Determines if DragNBar should be displayed in view or editor mode\n * @param {H5P.jQuery} [options.$blurHandlers] When clicking these element(s) dnb focus will be lost\n */\n function DragNBar(buttons, $container, $dialogContainer, options) {\n var self = this;\n\n EventDispatcher.call(this);\n this.overflowThreshold = 13; // How many buttons to display before we add the more button.\n this.buttons = buttons;\n this.$container = $container;\n this.$dialogContainer = $dialogContainer;\n this.dnd = new H5P.DragNDrop(this, $container);\n this.dnd.snap = 10;\n this.newElement = false;\n var defaultOptions = {\n disableEditor: false\n };\n options = H5P.jQuery.extend(defaultOptions, options);\n this.isEditor = !options.disableEditor;\n this.$blurHandlers = options.$blurHandlers ? options.$blurHandlers : undefined;\n this.instanceIndex = nextInstanceIndex++;\n\n /**\n * Keeps track of created DragNBar elements\n * @type {Array}\n */\n this.elements = [];\n\n // Create a popup dialog\n this.dialog = new H5P.DragNBarDialog($dialogContainer, $container);\n\n // Fix for forcing redraw on $container, to avoid \"artifcats\" on safari\n this.$container.addClass(\u0027hardware-accelerated\u0027);\n\n if (this.isEditor) {\n this.transformButtonActive = false;\n this.initEditor();\n this.initClickListeners();\n\n H5P.$window.resize(function () {\n self.resize();\n });\n }\n }\n\n // Inherit support for events\n DragNBar.prototype = Object.create(EventDispatcher.prototype);\n DragNBar.prototype.constructor = DragNBar;\n\n return DragNBar;\n})(H5P.EventDispatcher);\n\n/**\n * Initializes editor functionality of DragNBar\n */\nH5P.DragNBar.prototype.initEditor = function () {\n var that = this;\n this.dnr = new H5P.DragNResize(this.$container);\n this.dnr.snap = 10;\n\n // Update coordinates when element is resized\n this.dnr.on(\u0027moveResizing\u0027, function () {\n var offset = that.$element.offset();\n var position = that.$element.position();\n that.updateCoordinates(offset.left, offset.top, position.left, position.top);\n });\n\n // Set pressed to not lose focus at the end of resize\n this.dnr.on(\u0027stoppedResizing\u0027, function () {\n that.pressed = true;\n\n // Delete pressed after dnbelement has been refocused so it will lose focus on single click.\n setTimeout(function () {\n delete that.pressed;\n }, 10);\n });\n\n /**\n * Show transform panel listeners\n */\n this.dnr.on(\u0027showTransformPanel\u0027, function () {\n transformPanel(true);\n });\n this.dnd.on(\u0027showTransformPanel\u0027, function () {\n transformPanel(true);\n });\n\n /**\n * Hide transform panel listeners\n */\n this.dnr.on(\u0027hideTransformPanel\u0027, function () {\n if(!that.transformButtonActive) {\n transformPanel(false);\n }\n });\n this.dnd.on(\u0027hideTransformPanel\u0027, function () {\n if(!that.transformButtonActive) {\n transformPanel(false);\n }\n });\n\n /**\n * Trigger a context menu transform to either show or hide\n * the transform panel.\n *\n * @param {boolean} show\n */\n function transformPanel(show) {\n if (that.focusedElement) {\n that.focusedElement.contextMenu.trigger(\u0027contextMenuTransform\u0027, {showTransformPanel: show});\n }\n }\n\n this.dnd.startMovingCallback = function (x, y) {\n that.dnd.min = {x: 0, y: 0};\n that.dnd.max = {\n x: that.$container.width() - that.$element.outerWidth(),\n y: that.$container.height() - that.$element.outerHeight()\n };\n\n if (that.newElement) {\n that.dnd.adjust.x = 10;\n that.dnd.adjust.y = 10;\n that.dnd.min.y -= that.$list.height();\n }\n\n return true;\n };\n\n this.dnd.stopMovingCallback = function (event) {\n var pos = {};\n\n if (that.newElement) {\n that.$container.css(\u0027overflow\u0027, \u0027\u0027);\n if (Math.round(parseFloat(that.$element.css(\u0027top\u0027))) \u003c 0) {\n // Try to center element, but avoid overlapping\n pos.x = (that.dnd.max.x / 2);\n pos.y = (that.dnd.max.y / 2);\n that.avoidOverlapping(pos, that.$element);\n }\n }\n\n if (pos.x === undefined || pos.y === undefined ) {\n pos.x = Math.round(parseFloat(that.$element.css(\u0027left\u0027)));\n pos.y = Math.round(parseFloat(that.$element.css(\u0027top\u0027)));\n }\n\n that.stopMoving(pos.x, pos.y);\n that.newElement = false;\n\n delete that.dnd.min;\n delete that.dnd.max;\n };\n};\n\n/**\n * Tries to position the given element close to the requested coordinates.\n * Element can be skipped to check if spot is available.\n *\n * @param {object} pos\n * @param {number} pos.x\n * @param {number} pos.y\n * @param {(H5P.jQuery|Object)} element object with width\u0026height if ran before insertion.\n */\nH5P.DragNBar.prototype.avoidOverlapping = function (pos, $element) {\n // Determine size of element\n var size = $element;\n if (size instanceof H5P.jQuery) {\n size = window.getComputedStyle(size[0]);\n size = {\n width: parseFloat(size.width),\n height: parseFloat(size.height)\n };\n }\n else {\n $element = undefined;\n }\n\n // Determine how much they can be manuvered\n var containerStyle = window.getComputedStyle(this.$container[0]);\n var manX = parseFloat(containerStyle.width) - size.width;\n var manY = parseFloat(containerStyle.height) - size.height;\n\n var limit = 16;\n var attempts = 0;\n\n while (attempts \u003c limit \u0026\u0026 this.elementOverlaps(pos.x, pos.y, $element)) {\n // Try to place randomly inside container\n if (manX \u003e 0) {\n pos.x = Math.floor(Math.random() * manX);\n }\n if (manY \u003e 0) {\n pos.y = Math.floor(Math.random() * manY);\n }\n attempts++;\n }\n};\n\n/**\n * Determine if moving the given element to its new position will cause it to\n * cover another element. This can make new or pasted elements difficult to see.\n * Element can be skipped to check if spot is available.\n *\n * @param {number} x\n * @param {number} y\n * @param {H5P.jQuery} [$element]\n * @returns {boolean}\n */\nH5P.DragNBar.prototype.elementOverlaps = function (x, y, $element) {\n var self = this;\n\n // Use snap grid\n x = Math.round(x / 10);\n y = Math.round(y / 10);\n\n for (var i = 0; i \u003c self.elements.length; i++) {\n var element = self.elements[i];\n if ($element !== undefined \u0026\u0026 element.$element === $element) {\n continue;\n }\n\n if (x === Math.round(parseFloat(element.$element.css(\u0027left\u0027)) / 10) \u0026\u0026\n y === Math.round(parseFloat(element.$element.css(\u0027top\u0027)) / 10)) {\n return true; // Stop loop\n }\n }\n\n return false;\n};\n\n// Key coordinates\nvar SHIFT = 16;\nvar CTRL = 17;\nvar DELETE = 46;\nvar BACKSPACE = 8;\nvar C = 67;\nvar V = 86;\nvar LEFT = 37;\nvar UP = 38;\nvar RIGHT = 39;\nvar DOWN = 40;\n\n// Keep track of key state\nvar ctrlDown = false;\nvar shiftDown = false;\n\n// How many pixels to move\nvar snapAmount = 1;\n\n/**\n * Handle keydown events for the entire frame\n */\nH5P.DragNBar.keydownHandler = function (event) {\n var self = event.data.instance;\n var activeElement = document.activeElement;\n\n if (event.which === CTRL) {\n ctrlDown = true;\n\n if (self.dnd.snap !== undefined) {\n // Disable snapping\n delete self.dnd.snap;\n }\n }\n\n if (event.which === SHIFT) {\n shiftDown = true;\n snapAmount = self.dnd.snap;\n }\n\n if (event.which === LEFT \u0026\u0026 self.focusedElement) {\n if (activeElement.contentEditable === \u0027true\u0027 || activeElement.value !== undefined) {\n return;\n }\n event.preventDefault();\n self.moveWithKeys(-snapAmount, 0);\n }\n else if (event.which === UP \u0026\u0026 self.focusedElement) {\n if (activeElement.contentEditable === \u0027true\u0027 || activeElement.value !== undefined) {\n return;\n }\n event.preventDefault();\n self.moveWithKeys(0, -snapAmount);\n }\n else if (event.which === RIGHT \u0026\u0026 self.focusedElement) {\n if (activeElement.contentEditable === \u0027true\u0027 || activeElement.value !== undefined) {\n return;\n }\n event.preventDefault();\n self.moveWithKeys(snapAmount, 0);\n }\n else if (event.which === DOWN \u0026\u0026 self.focusedElement) {\n if (activeElement.contentEditable === \u0027true\u0027 || activeElement.value !== undefined) {\n return;\n }\n event.preventDefault();\n self.moveWithKeys(0, snapAmount);\n }\n else if (event.which === C \u0026\u0026 ctrlDown \u0026\u0026 self.focusedElement \u0026\u0026 self.$container.is(\u0027:visible\u0027)) {\n // Copy element params to clipboard\n var elementSize = window.getComputedStyle(self.focusedElement.$element[0]);\n var width = parseFloat(elementSize.width);\n var height = parseFloat(elementSize.height) / width;\n width = width / (parseFloat(window.getComputedStyle(self.$container[0]).width) / 100);\n height *= width;\n\n self.focusedElement.toClipboard(width, height);\n }\n else if (event.which === V \u0026\u0026 ctrlDown \u0026\u0026 window.localStorage \u0026\u0026 self.$container.is(\u0027:visible\u0027)) {\n if (self.preventPaste || self.dialog.isOpen() || activeElement.contentEditable === \u0027true\u0027 || activeElement.value !== undefined) {\n // Don\u0027t allow paste if dialog is open or active element can be modified\n return;\n }\n\n var clipboardData = localStorage.getItem(\u0027h5pClipboard\u0027);\n if (clipboardData) {\n // Parse\n try {\n clipboardData = JSON.parse(clipboardData);\n }\n catch (err) {\n console.error(\u0027Unable to parse JSON from clipboard.\u0027, err);\n return;\n }\n\n // Update file URLs\n H5P.DragNBar.updateFileUrls(clipboardData.specific, function (path) {\n var isTmpFile = (path.substr(-4,4) === \u0027#tmp\u0027);\n if (!isTmpFile \u0026\u0026 clipboardData.contentId) {\n // Comes from existing content\n\n if (H5PEditor.contentId) {\n // .. to existing content\n return \u0027../\u0027 + clipboardData.contentId + \u0027/\u0027 + path;\n }\n else {\n // .. to new content\n return (H5PEditor.contentRelUrl ? H5PEditor.contentRelUrl : \u0027../content/\u0027) + clipboardData.contentId + \u0027/\u0027 + path;\n }\n }\n return path; // Will automatically be looked for in tmp folder\n });\n\n if (clipboardData.generic) {\n // Use reference instead of key\n clipboardData.generic = clipboardData.specific[clipboardData.generic];\n\n // Avoid multiple content with same ID\n delete clipboardData.generic.subContentId;\n }\n\n self.trigger(\u0027paste\u0027, clipboardData);\n }\n }\n else if ((event.which === DELETE || event.which === BACKSPACE) \u0026\u0026 self.focusedElement \u0026\u0026 self.$container.is(\u0027:visible\u0027) \u0026\u0026 activeElement.tagName.toLowerCase() !== \u0027input\u0027) {\n if (self.pressed === undefined) {\n self.focusedElement.contextMenu.trigger(\u0027contextMenuRemove\u0027);\n event.preventDefault(); // Prevent browser navigating back\n }\n }\n};\n\n/**\n * Handle keypress events for the entire frame\n */\nH5P.DragNBar.keypressHandler = function (event) {\n var self = event.data.instance;\n if (event.which === BACKSPACE \u0026\u0026 self.focusedElement \u0026\u0026 self.$container.is(\u0027:visible\u0027) \u0026\u0026 document.activeElement.tagName.toLowerCase() !== \u0027input\u0027) {\n event.preventDefault(); // Prevent browser navigating back\n }\n};\n\n/**\n * Handle keyup events for the entire frame\n */\nH5P.DragNBar.keyupHandler = function (event) {\n var self = event.data.instance;\n\n if (event.which === CTRL) {\n // Update key state\n ctrlDown = false;\n\n // Enable snapping\n self.dnd.snap = 10;\n }\n if (event.which === SHIFT) {\n shiftDown = false;\n snapAmount = 1;\n }\n\n if (self.focusedElement \u0026\u0026 (event.which === LEFT || event.which === UP || event.which === RIGHT || event.which === DOWN)) {\n // Store position of element after moving\n var position = self.getElementSizeNPosition();\n self.stopMoving(Math.round(position.left), Math.round(position.top));\n }\n};\n\n/**\n * Handle click events for the entire frame\n */\nH5P.DragNBar.clickHandler = function (event) {\n var self = event.data.instance;\n\n // Remove pressed on click\n delete self.pressed;\n};\n\n/**\n * Initialize click listeners\n */\nH5P.DragNBar.prototype.initClickListeners = function () {\n var self = this;\n var index = self.instanceIndex;\n\n // Register event listeners\n var eventData = {\n instance: self\n };\n H5P.$body.on(\u0027keydown.dnb\u0027 + index, eventData, H5P.DragNBar.keydownHandler)\n .on(\u0027keypress.dnb\u0027 + index, eventData, H5P.DragNBar.keypressHandler)\n .on(\u0027keyup.dnb\u0027 + index, eventData, H5P.DragNBar.keyupHandler)\n .on(\u0027click.dnb\u0027 + index,eventData, H5P.DragNBar.clickHandler);\n\n // Set blur handler element if option has been specified\n var $blurHandlers = this.$container;\n if (this.$blurHandlers) {\n $blurHandlers = this.$blurHandlers;\n }\n\n function handleBlur() {\n // Remove coordinates picker if we didn\u0027t press an element.\n if (self.pressed !== undefined) {\n delete self.pressed;\n }\n else {\n self.blurAll();\n if (self.focusedElement !== undefined) {\n delete self.focusedElement;\n }\n }\n }\n\n $blurHandlers\n .keydown(function (e) {\n if (e.which === 9) { // pressed tab\n handleBlur();\n }\n })\n .click(handleBlur);\n};\n\n/**\n * Update file URLs. Useful when copying between different contents.\n *\n * @param {object} params Reference\n * @param {function} handler Modifies the path to work when pasted\n */\nH5P.DragNBar.updateFileUrls = function (params, handler) {\n for (var prop in params) {\n if (params.hasOwnProperty(prop) \u0026\u0026 params[prop] instanceof Object) {\n var obj = params[prop];\n if (obj.path !== undefined \u0026\u0026 obj.mime !== undefined) {\n obj.path = handler(obj.path);\n }\n else {\n H5P.DragNBar.updateFileUrls(obj, handler);\n }\n }\n }\n};\n\n/**\n * Attaches the menu bar to the given wrapper.\n *\n * @param {jQuery} $wrapper\n * @returns {undefined}\n */\nH5P.DragNBar.prototype.attach = function ($wrapper) {\n var that = this;\n $wrapper.html(\u0027\u0027);\n $wrapper.addClass(\u0027h5peditor-dragnbar\u0027);\n\n var $list = H5P.jQuery(\u0027\u003cul class=\"h5p-dragnbar-ul\"\u003e\u003c/ul\u003e\u0027).appendTo($wrapper);\n this.$list = $list;\n\n for (var i = 0; i \u003c this.buttons.length; i++) {\n var button = this.buttons[i];\n\n if (i === this.overflowThreshold) {\n $list = H5P.jQuery(\u0027\u003cli class=\"h5p-dragnbar-li\"\u003e\u003ca href=\"#\" title=\"\u0027 + \u0027More elements\u0027 + \u0027\" class=\"h5p-dragnbar-a h5p-dragnbar-more-button\"\u003e\u003c/a\u003e\u003cul class=\"h5p-dragnbar-li-ul\"\u003e\u003c/ul\u003e\u003c/li\u003e\u0027)\n .appendTo($list)\n .click(function () {\n return false;\n })\n .hover(function () {\n $list.stop().slideToggle(300);\n }, function () {\n $list.stop().slideToggle(300);\n })\n .children(\u0027:first\u0027)\n .next();\n }\n\n this.addButton(button, $list);\n }\n\n this.containTooltips();\n};\n\n/**\n * Add button.\n *\n * @param {type} button\n * @param {Function} button.createElement Function for creating element\n * @param {type} $list\n * @returns {undefined}\n */\nH5P.DragNBar.prototype.addButton = function (button, $list) {\n var that = this;\n\n $button = ns.$(\n \u0027\u003cli class=\"h5p-dragnbar-li\" data-label=\"Image\"\u003e\u0027 +\n \u0027\u003ca href=\"#\" class=\"h5p-dragnbar-a h5p-dragnbar-\u0027 + button.id + \u0027-button\" aria-label=\"\u0027 + button.title + \u0027\"\u003e\u003c/a\u003e\u0027 +\n \u0027\u003c/li\u003e\u0027\n ).appendTo($list);\n\n $tooltip = ns.$(\u0027\u003cspan/\u003e\u0027, {\n \u0027class\u0027: \u0027h5p-dragnbar-tooltip\u0027,\n \u0027text\u0027: button.title\n }).appendTo($button);\n\n $button\n .hover(function() {\n that.containTooltips();\n })\n .children()\n .click(function () {\n return false;\n }).mousedown(function (event) {\n if (event.which !== 1) {\n return;\n }\n that.newElement = true;\n that.pressed = true;\n var createdElement = button.createElement();\n that.$element = createdElement;\n that.$container.css(\u0027overflow\u0027, \u0027visible\u0027);\n that.dnd.press(that.$element, event.pageX, event.pageY);\n that.focus(that.$element);\n });\n};\n\n/**\n * Contain tooltips.\n *\n * @returns {undefined}\n */\nH5P.DragNBar.prototype.containTooltips = function () {\n var that = this;\n\n var containerWidth = that.$container.outerWidth();\n\n this.$list.find(\u0027.h5p-dragnbar-tooltip\u0027).each(function() {\n // Get correct offset even if element is a child\n var width = ns.$(this).outerWidth();\n var parentWidth = ns.$(this).parents(\u0027.h5p-dragnbar-li\u0027).last().outerWidth();\n\n // Center the tooltip\n ns.$(this).css(\u0027left\u0027, -(width / 2) + (parentWidth / 2) + \u0027px\u0027);\n\n var offsetLeft = ns.$(this).position().left += ns.$(this).parents(\u0027.h5p-dragnbar-li\u0027).last().position().left;\n\n // If outside left edge\n if (offsetLeft \u003c= 0) {\n ns.$(this).css(\u0027left\u0027, 0);\n }\n\n // If outside right edge\n if (offsetLeft + width \u003e containerWidth) {\n ns.$(this).css(\u0027left\u0027, -(width - parentWidth));\n }\n });\n};\n\n/**\n * Change container.\n *\n * @param {jQuery} $container\n * @returns {undefined}\n */\nH5P.DragNBar.prototype.setContainer = function ($container) {\n this.$container = $container;\n if (this.dnd) {\n this.dnd.$container = $container;\n }\n if (this.dnr) {\n this.dnr.$container = $container;\n }\n};\n\n/**\n * Handler for when the dragging stops. Makes sure the element is inside its container.\n *\n * @param {Number} left\n * @param {Number} top\n * @returns {undefined}\n */\nH5P.DragNBar.prototype.stopMoving = function (left, top) {\n // Calculate percentage\n top = top / (this.$container.height() / 100);\n left = left / (this.$container.width() / 100);\n this.$element.css({top: top + \u0027%\u0027, left: left + \u0027%\u0027});\n\n // Give others the result\n if (this.stopMovingCallback !== undefined) {\n this.stopMovingCallback(left, top);\n }\n};\n\n/**\n * @typedef SizeNPosition\n * @type Object\n * @property {number} width Outer width of the element\n * @property {number} height Outer height of the element\n * @property {number} left The X Coordinate\n * @property {number} top The Y Coordinate\n * @property {number} containerWidth Inner width of the container\n * @property {number} containerHeight Inner height of the container\n */\n\n/**\n *\n * Only works when element is inside this.$container. This is assumed and no\n * are done.\n *\n * @param {H5P.jQuery} [$element] Defaults to focused element.\n * @throws \u0027No element given\u0027 if $element is missing\n * @return {SizeNPosition}\n */\nH5P.DragNBar.prototype.getElementSizeNPosition = function ($element) {\n $element = $element || this.focusedElement.$element;\n if (!$element || !$element.length) {\n throw \u0027No element given\u0027;\n }\n\n // Always use outer size for element\n var size = $element[0].getBoundingClientRect();\n\n // Always use position relative to container for element\n var position = window.getComputedStyle($element[0]);\n\n // We include container inner size as well\n var containerSize = window.getComputedStyle(this.$container[0]);\n\n // Start preparing return value\n var sizeNPosition = {\n width: parseFloat(size.width),\n height: parseFloat(size.height),\n left: parseFloat(position.left),\n top: parseFloat(position.top),\n containerWidth: parseFloat(containerSize.width),\n containerHeight: parseFloat(containerSize.height)\n };\n\n if (position.left.substr(-1, 1) === \u0027%\u0027 || position.top.substr(-1, 1) === \u0027%\u0027) {\n // Some browsers(Safari) gets percentage value instead of pixel value.\n // Container inner size must be used to calculate such values.\n sizeNPosition.left *= (sizeNPosition.containerWidth / 100);\n sizeNPosition.top *= (sizeNPosition.containerHeight / 100);\n }\n\n return sizeNPosition;\n};\n\n/**\n * Makes it possible to move dnb elements by adding to it\u0027s x and y\n *\n * @param {number} x Amount to move on x-axis.\n * @param {number} y Amount to move on y-axis.\n */\nH5P.DragNBar.prototype.moveWithKeys = function (x, y) {\n\n /**\n * Ensure that the given value is within the given boundaries.\n *\n * @private\n * @param {number} value\n * @param {number} min\n * @param {number} max\n * @return {number}\n */\n var withinBoundaries = function (value, min, max) {\n if (value \u003c min) {\n value = min;\n }\n if (value \u003e max) {\n value = max;\n }\n\n return value;\n };\n\n // Get size and position of current elemet in focus\n var sizeNPosition = this.getElementSizeNPosition();\n\n // Change position\n sizeNPosition.left += x;\n sizeNPosition.top += y;\n\n // Check that values are within boundaries\n sizeNPosition.left = withinBoundaries(sizeNPosition.left, 0, sizeNPosition.containerWidth - sizeNPosition.width);\n sizeNPosition.top = withinBoundaries(sizeNPosition.top, 0, sizeNPosition.containerHeight - sizeNPosition.height);\n\n // Determine new position style\n this.$element.css({\n left: sizeNPosition.left + \u0027px\u0027,\n top: sizeNPosition.top + \u0027px\u0027,\n });\n\n this.dnd.trigger(\u0027showTransformPanel\u0027);\n\n // Update position of context menu\n this.updateCoordinates(sizeNPosition.left, sizeNPosition.top, sizeNPosition.left, sizeNPosition.top);\n};\n\n/**\n * Makes it possible to focus and move the element around.\n * Must be inside $container.\n *\n * @param {H5P.jQuery} $element\n * @param {Object} [options]\n * @param {H5P.DragNBarElement} [options.dnbElement] Register new element with dnbelement\n * @param {boolean} [options.disableResize] Resize disabled\n * @param {boolean} [options.lock] Lock ratio during resize\n * @param {string} [clipboardData]\n * @returns {H5P.DragNBarElement} Reference to added dnbelement\n */\nH5P.DragNBar.prototype.add = function ($element, clipboardData, options) {\n var self = this;\n options = options || {};\n if (this.isEditor \u0026\u0026 !options.disableResize) {\n this.dnr.add($element, options);\n }\n var newElement = null;\n\n // Check if element already exist\n if (options.dnbElement) {\n // Set element as added element\n options.dnbElement.setElement($element);\n newElement = options.dnbElement;\n }\n else {\n options.element = $element;\n newElement = new H5P.DragNBarElement(this, clipboardData, options);\n this.elements.push(newElement);\n }\n\n $element.addClass(\u0027h5p-dragnbar-element\u0027);\n\n if (this.isEditor) {\n if ($element.attr(\u0027tabindex\u0027) === undefined) {\n // Make it possible to tab between elements.\n $element.attr(\u0027tabindex\u0027, \u00270\u0027);\n }\n\n $element.mousedown(function (event) {\n if (event.which !== 1) {\n return;\n }\n\n self.pressed = true;\n self.focus($element);\n if (self.dnr.active !== true) { // Moving can be stopped if the mousedown is doing something else\n self.dnd.press($element, event.pageX, event.pageY);\n }\n });\n }\n\n $element.focus(function () {\n self.focus($element);\n });\n\n return newElement;\n};\n\n/**\n * Remove given element in the UI.\n *\n * @param {H5P.DragNBarElement} dnbElement\n */\nH5P.DragNBar.prototype.removeElement = function (dnbElement) {\n dnbElement.removeElement();\n};\n\n/**\n * Select the given element in the UI.\n *\n * @param {jQuery} $element\n * @returns {undefined}\n */\nH5P.DragNBar.prototype.focus = function ($element) {\n var self = this;\n\n // Blur last focused\n if (this.focusedElement \u0026\u0026 this.focusedElement.$element !== $element) {\n this.focusedElement.blur();\n this.focusedElement.hideContextMenu();\n }\n\n // Keep track of the element we have in focus\n self.$element = $element;\n this.dnd.setElement($element);\n\n // Show and update coordinates picker\n this.focusedElement = this.getDragNBarElement($element);\n\n if (this.focusedElement) {\n this.focusedElement.showContextMenu();\n this.focusedElement.focus();\n self.updateCoordinates();\n }\n\n // Wait for potential recreation of element\n setTimeout(function () {\n self.updateCoordinates();\n if (self.focusedElement \u0026\u0026 self.focusedElement.contextMenu \u0026\u0026 self.focusedElement.contextMenu.canResize) {\n self.focusedElement.contextMenu.updateDimensions();\n }\n }, 0);\n};\n\n/**\n * Get dnbElement from $element\n * @param {jQuery} $element\n * @returns {H5P.DragNBarElement} dnbElement with matching $element\n */\nH5P.DragNBar.prototype.getDragNBarElement = function ($element) {\n var foundElement;\n // Find object with matching element\n this.elements.forEach(function (element) {\n if (element.getElement().is($element)) {\n foundElement = element;\n }\n });\n return foundElement;\n};\n\n/**\n * Deselect all elements in the UI.\n *\n * @returns {undefined}\n */\nH5P.DragNBar.prototype.blurAll = function () {\n this.elements.forEach(function (element) {\n element.blur();\n });\n delete this.focusedElement;\n};\n\n/**\n * Resize DnB, make sure context menu is positioned correctly.\n */\nH5P.DragNBar.prototype.resize = function () {\n var self = this;\n this.updateCoordinates();\n\n if (self.focusedElement) {\n self.focusedElement.resizeContextMenu(self.$element.offset().left - self.$element.parent().offset().left);\n }\n};\n\n/**\n * Update the coordinates of context menu.\n *\n * @param {Number} [left]\n * @param {Number} [top]\n * @param {Number} [x]\n * @param {Number} [y]\n * @returns {undefined}\n */\nH5P.DragNBar.prototype.updateCoordinates = function (left, top, x, y) {\n if (!this.focusedElement) {\n return;\n }\n\n var containerPosition = this.$container.position();\n\n if (left \u0026\u0026 top \u0026\u0026 x \u0026\u0026 y) {\n left = x + containerPosition.left;\n top = y + containerPosition.top;\n this.focusedElement.updateCoordinates(left, top, x, y);\n }\n else {\n var position = this.$element.position();\n this.focusedElement.updateCoordinates(position.left + containerPosition.left, position.top + containerPosition.top, position.left, position.top);\n }\n};\n\n/**\n * Creates element data to store in the clipboard.\n *\n * @param {string} from Source of the element\n * @param {object} params Element options\n * @param {string} [generic] Which part of the parameters can be used by other libraries\n * @returns {string} JSON\n */\nH5P.DragNBar.clipboardify = function (from, params, generic) {\n var clipboardData = {\n from: from,\n specific: params\n };\n\n if (H5PEditor.contentId) {\n clipboardData.contentId = H5PEditor.contentId;\n }\n\n // Add the generic part\n if (params[generic]) {\n clipboardData.generic = generic;\n }\n\n return clipboardData;\n};\n\n/**\n * Make sure the given element is inside the container.\n *\n * @param {SizeNPosition} sizeNPosition For the element\n * @returns {SizeNPosition} Only the properties which require change\n */\nH5P.DragNBar.fitElementInside = function (sizeNPosition) {\n var style = {};\n\n if (sizeNPosition.left \u003c 0) {\n // Element sticks out of the left side\n style.left = sizeNPosition.left = 0;\n }\n\n if (sizeNPosition.width + sizeNPosition.left \u003e sizeNPosition.containerWidth) {\n // Element sticks out of the right side\n style.left = sizeNPosition.containerWidth - sizeNPosition.width;\n if (style.left \u003c 0) {\n // Element is wider than the container\n style.left = 0;\n style.width = sizeNPosition.containerWidth;\n }\n }\n\n if (sizeNPosition.top \u003c 0) {\n // Element sticks out of the top side\n style.top = sizeNPosition.top = 0;\n }\n\n if (sizeNPosition.height + sizeNPosition.top \u003e sizeNPosition.containerHeight) {\n // Element sticks out of the bottom side\n style.top = sizeNPosition.containerHeight - sizeNPosition.height;\n if (style.top \u003c 0) {\n // Element is higher than the container\n style.top = 0;\n style.height = sizeNPosition.containerHeight;\n }\n }\n\n return style;\n};\n\n/**\n * Clean up any event listeners\n */\nH5P.DragNBar.prototype.remove = function () {\n var index = this.instanceIndex;\n\n H5P.$body.off(\u0027keydown.dnb\u0027 + index, H5P.DragNBar.keydownHandler)\n .off(\u0027keypress.dnb\u0027 + index, H5P.DragNBar.keypressHandler)\n .off(\u0027keyup.dnb\u0027 + index, H5P.DragNBar.keyupHandler)\n .off(\u0027click.dnb\u0027 + index, H5P.DragNBar.clickHandler);\n};\n\nif (window.H5PEditor) {\n // Add translations\n H5PEditor.language[\u0027H5P.DragNBar\u0027] = {\n libraryStrings: {\n transformLabel: \u0027Transform\u0027,\n editLabel: \u0027Edit\u0027,\n removeLabel: \u0027Remove\u0027,\n bringToFrontLabel: \u0027Bring to Front\u0027,\n sendToBackLabel: \u0027Send to Back\u0027,\n unableToPaste: \u0027Cannot paste this object. Unfortunately, the object you are trying to paste is not supported by this content type or version.\u0027,\n sizeLabel: \u0027Size\u0027,\n positionLabel: \u0027Position\u0027,\n heightLabel: \u0027Height\u0027,\n widthLabel: \u0027Width\u0027\n }\n };\n}\n"
,"scripts/context-menu.js":"/*global H5P*/\n\n/**\n * Create context menu\n */\nH5P.DragNBarContextMenu = (function ($, EventDispatcher) {\n\n /**\n * Constructor for context menu\n * @class\n * @param {jQuery} $container Parent container\n * @param {H5P.DragNBarElement} DragNBarElement\n * @param {boolean} [hasCoordinates] Decides if coordinates will be displayed\n * @param {boolean} [disableResize] No input for dimensions\n */\n function ContextMenu($container, DragNBarElement, hasCoordinates, disableResize) {\n var self = this;\n EventDispatcher.call(this);\n\n /**\n * Keeps track of DragNBar object\n *\n * @type {H5P.DragNBar}\n */\n this.dnb = DragNBarElement.dnb;\n\n /**\n * Keeps track of DnBElement object\n *\n * @type {H5P.DragNBarElement}\n */\n this.dnbElement = DragNBarElement;\n\n /**\n * Keeps track of context menu container\n *\n * @type {H5P.jQuery}\n */\n this.$contextMenu = $(\u0027\u003cdiv\u003e\u0027, {\n \u0027class\u0027: \u0027h5p-dragnbar-context-menu\u0027\n });\n\n /**\n * Keeps track of buttons container\n *\n * @type {H5P.jQuery}\n */\n this.$buttons = $(\u0027\u003cdiv\u003e\u0027, {\n \u0027class\u0027: \u0027h5p-context-menu-buttons\u0027\n });\n\n /**\n * Keeps track of transform panel\n *\n * @type {H5P.jQuery}\n */\n this.$transformPanel = $(\u0027\u003cdiv\u003e\u0027, {\n \u0027class\u0027: \u0027h5p-transform-panel hide\u0027\n });\n\n /**\n * Keeps track of context menu parent\n *\n * @type {jQuery}\n */\n this.$parent = $container;\n\n /**\n * Keeps track of whether the context menu should display coordinates\n * @type {Boolean}\n */\n this.hasCoordinates = (hasCoordinates !== undefined ? hasCoordinates : true);\n\n /**\n * Determines if the dimensions can be changed.\n * @type {boolean}\n */\n this.canResize = !disableResize;\n\n /**\n * Determines if the transform panel is showing.\n * @type {boolean}\n */\n this.showingTransformPanel = false;\n\n /**\n * Button containing button name and event name that will be fired.\n * @typedef {Object} ContextMenuButton\n * @property {String} name Machine readable\n * @property {String} label Human readable\n */\n\n /**\n * Keeps track of button objects\n * @type {ContextMenuButton[]}\n */\n this.buttons = [\n {name: \u0027Edit\u0027, label: H5PEditor.t(\u0027H5P.DragNBar\u0027, \u0027editLabel\u0027)},\n {name: \u0027BringToFront\u0027, label: H5PEditor.t(\u0027H5P.DragNBar\u0027, \u0027bringToFrontLabel\u0027)},\n {name: \u0027SendToBack\u0027, label: H5PEditor.t(\u0027H5P.DragNBar\u0027, \u0027sendToBackLabel\u0027)},\n {name: \u0027Remove\u0027, label: H5PEditor.t(\u0027H5P.DragNBar\u0027, \u0027removeLabel\u0027)}\n ];\n\n /**\n * Register transform listener\n *\n * @param {event} [e] event\n * @param {Object} [e.data] event data\n * @param {Boolean} [e.data.showTransformPanel] Show transform panel\n */\n self.on(\u0027contextMenuTransform\u0027, function (e) {\n if (e \u0026\u0026 e.data.showTransformPanel) {\n // Use event data\n self.showingTransformPanel = e.data.showTransformPanel;\n }\n else {\n // Toggle showing panel\n self.showingTransformPanel = !self.showingTransformPanel;\n }\n\n // Toggle sticky transform panel\n if (e.data.button === \u0027Transform\u0027) {\n if (self.dnb.transformButtonActive) {\n self.dnb.transformButtonActive = false;\n }\n else {\n self.dnb.transformButtonActive = true;\n }\n }\n\n // Remove sticky transform panel when focus is lost\n if (e.data.showTransformPanel == false) {\n self.dnb.transformButtonActive = false;\n }\n\n // Toggle buttons bar and transform panel\n self.toggleButtonsBar(!self.showingTransformPanel);\n self.toggleTransformPanel(self.showingTransformPanel);\n self.$transformButtonWrapper.toggleClass(\u0027active\u0027, self.showingTransformPanel);\n\n // Realign context menu\n self.dnb.updateCoordinates();\n });\n\n this.updateContextMenu();\n }\n\n // Inherit event dispatcher\n ContextMenu.prototype = Object.create(EventDispatcher.prototype);\n ContextMenu.prototype.constructor = ContextMenu;\n\n /**\n * Create coordinates in context menu\n */\n ContextMenu.prototype.addCoordinates = function () {\n // Coordinates disabled or exists\n if (!this.hasCoordinates || this.$coordinates) {\n return;\n }\n\n var self = this;\n\n // Add coordinates picker\n this.$coordinates = $(\n \u0027\u003cdiv class=\"h5p-dragnbar-coordinates\"\u003e\u0027 +\n \u0027\u003cdiv class=\"h5p-dragnbar-label\"\u003e\u0027 + H5PEditor.t(\u0027H5P.DragNBar\u0027, \u0027positionLabel\u0027) + \u0027\u003c/div\u003e\u0027 +\n \u0027\u003cdiv class=\"h5p-dragnbar-x-container\" aria-label=\"X position\"\u003e\u0027 +\n \u0027\u003cinput class=\"h5p-dragnbar-x\" type=\"text\" value=\"0\"\u003e\u0027 +\n \u0027\u003c/div\u003e\u0027 +\n \u0027\u003cspan class=\"h5p-dragnbar-coordinates-separater\"\u003e,\u003c/span\u003e\u0027 +\n \u0027\u003cdiv class=\"h5p-dragnbar-y-container\" aria-label=\"Y position\"\u003e\u0027 +\n \u0027\u003cinput class=\"h5p-dragnbar-y\" type=\"text\" value=\"0\"\u003e\u0027 +\n \u0027\u003c/div\u003e\u0027 +\n \u0027\u003c/div\u003e\u0027\n ).mousedown(function () {\n self.dnb.pressed = true;\n }).appendTo(this.$transformPanel);\n\n this.$x = this.$coordinates.find(\u0027.h5p-dragnbar-x\u0027);\n this.$y = this.$coordinates.find(\u0027.h5p-dragnbar-y\u0027);\n\n this.$x.add(this.$y).on(\u0027change keydown\u0027, function(event) {\n if (event.type === \u0027change\u0027 || event.which === 13) {\n\n // Get input\n var x = Number(self.$x.val());\n var y = Number(self.$y.val());\n\n if (!isNaN(x) \u0026\u0026 !isNaN(y)) {\n\n // Do not move outside of container\n var min = {x: 0 , y: 0};\n var max = {\n x: self.dnb.$container.width() - self.dnbElement.getElement().outerWidth(),\n y: self.dnb.$container.height() - self.dnbElement.getElement().outerHeight()\n };\n\n // Check min values\n if (x \u003c 0) {\n x = min.x;\n }\n if (y \u003c 0) {\n y = min.y;\n }\n\n // Check max values\n if (x \u003e max.x) {\n x = max.x;\n }\n if (y \u003e max.y) {\n y = max.y;\n }\n\n // Update and store location\n self.dnb.stopMoving(x, y);\n\n if (event.which === 13) {\n // Pressed enter, mark number for easy edit\n setTimeout(function () {\n event.target.focus();\n event.target.setSelectionRange(0, event.target.value.length);\n }, 0);\n }\n\n // Update context menu position\n self.dnb.updateCoordinates();\n }\n }\n }).click(function (event) {\n // Select coordinates numbers for easy edit\n event.target.focus();\n event.target.setSelectionRange(0, event.target.value.length);\n });\n };\n\n /**\n * Update the coordinates picker.\n *\n * @param {Number} left Left pos of context menu\n * @param {Number} top Top pos of context menu\n * @param {Number} x X value in coordinates\n * @param {Number} y Y value in coordinates\n */\n ContextMenu.prototype.updateCoordinates = function (left, top, x, y) {\n // Move it\n this.$contextMenu.css({\n left: left,\n top: top\n });\n\n // Set pos\n if (this.hasCoordinates) {\n this.$x.val(Math.round(x));\n this.$y.val(Math.round(y));\n }\n };\n\n /**\n * Create coordinates in context menu\n */\n ContextMenu.prototype.addDimensions = function () {\n var self = this;\n\n self.$dimensions = $(\u0027\u003cdiv/\u003e\u0027, {\n \u0027class\u0027: \u0027h5p-dragnbar-dimensions\u0027\n });\n\n // Add label\n $(\u0027\u003cdiv/\u003e\u0027, {\n \u0027class\u0027: \u0027h5p-dragnbar-label\u0027,\n appendTo: self.$dimensions,\n text: H5PEditor.t(\u0027H5P.DragNBar\u0027, \u0027sizeLabel\u0027)\n });\n\n var updateDimensions = function (type) {\n var target = parseFloat(this.value);\n if (isNaN(target)) {\n return;\n }\n\n // Get element\n var $element = self.dnbElement.getElement();\n\n // Determine min\u0026max values\n var min = H5P.DragNResize.MIN_SIZE;\n var containerSize = parseFloat(window.getComputedStyle(self.dnb.$container[0])[type]);\n var elementStyle = window.getComputedStyle($element[0]);\n var max = containerSize - parseFloat(elementStyle[type === \u0027width\u0027 ? \u0027left\u0027 : \u0027top\u0027]);\n\n if (target \u003c min) {\n target = min;\n }\n if (target \u003e max) {\n target = max;\n }\n\n // Set input field value\n self[\u0027$\u0027 + type].val(Math.round(target));\n\n // Remove any height padding before updating element\n var padding = $element[0].getBoundingClientRect()[type] - parseFloat(elementStyle[type]);\n target -= padding;\n\n $element.css(type, (target / (containerSize / 100)) + \u0027%\u0027);\n\n var eventData = {};\n eventData[type] = target / self.dnb.dnr.containerEm;\n self.dnb.dnr.trigger(\u0027stoppedResizing\u0027, eventData);\n };\n\n // Add input for width\n self.$width = self.getNewInput(\u0027width\u0027, H5PEditor.t(\u0027H5P.DragNBar\u0027, \u0027widthLabel\u0027), self.$dimensions, updateDimensions);\n\n $(\u0027\u003cspan/\u003e\u0027, {\n \u0027class\u0027: \u0027h5p-dragnbar-dimensions-separator\u0027,\n text: \u0027×\u0027,\n appendTo: self.$dimensions\n });\n\n self.$height = self.getNewInput(\u0027height\u0027, H5PEditor.t(\u0027H5P.DragNBar\u0027, \u0027heightLabel\u0027), self.$dimensions, updateDimensions);\n\n self.dnb.dnr.on(\u0027moveResizing\u0027, function () {\n self.updateDimensions();\n });\n\n self.$dimensions.appendTo(self.$transformPanel);\n };\n\n /**\n * Add transform functionality\n *\n * @param [enableTransform]\n */\n ContextMenu.prototype.addTransform = function (enableTransform) {\n var self = this;\n var transformButtonObject = {name: \u0027Transform\u0027, label: H5PEditor.t(\u0027H5P.DragNBar\u0027, \u0027transformLabel\u0027)};\n var $transformButtonWrapper = $(\u0027\u003cdiv\u003e\u0027, {\n \u0027class\u0027: \u0027h5p-transform-button-wrapper\u0027\n });\n\n // Attach button\n if (enableTransform) {\n self.createButton(transformButtonObject)\n .appendTo($transformButtonWrapper);\n }\n\n self.$transformButtonWrapper = $transformButtonWrapper;\n return $transformButtonWrapper;\n };\n\n /**\n * Updates the values in the input fields for width and height.\n */\n ContextMenu.prototype.updateDimensions = function () {\n var self = this;\n var $element = self.dnbElement.getElement();\n var elementSize = window.getComputedStyle($element[0]);\n self.$width.val(Math.round(parseFloat(elementSize.width)));\n self.$height.val(Math.round(parseFloat(elementSize.height)));\n };\n\n /**\n * Creates a new input field for modifying an element property.\n *\n * @param {string} type\n * @param {string} label\n * @param {H5P.jQuery} $container\n * @param {function} handler\n * @returns {H5P.jQuery}\n */\n ContextMenu.prototype.getNewInput = function (type, label, $container, handler) {\n // Wrap input element with label (implicit labeling)\n var $wrapper = $(\u0027\u003cdiv/\u003e\u0027, {\n \u0027class\u0027: \u0027h5p-dragnbar-input h5p-dragnbar-\u0027 + type,\n \u0027aria-label\u0027: label,\n appendTo: $container\n });\n\n // Create input field\n var $input = $(\u0027\u003cinput/\u003e\u0027, {\n maxLength: 5,\n on: {\n change: function () {\n handler.call(this, type);\n },\n keydown: function (event) {\n if (event.which === 13) { // Enter key\n handler.call(this, type);\n $input.focus().select();\n }\n else if (event.which === 38 || event.which === 40) { // Up key\n // Increase or decrease the number by using the arrows keys\n var currentValue = parseFloat($input.val());\n if (!isNaN(currentValue)) {\n $input.val(currentValue + (event.which === 38 ? 1 : -1));\n handler.call(this, type);\n }\n }\n },\n keyup: function (event) {\n if (event.which === 38 || event.which === 40) { // Up or Down key\n $input.select(); // Select again\n }\n },\n click: function (event) {\n $input.select();\n }\n },\n appendTo: $wrapper\n });\n return $input;\n };\n\n /**\n * Create button and add it to buttons bar\n * @param {object} button\n */\n ContextMenu.prototype.addToMenu = function (button) {\n var self = this;\n\n self.createButton(button).appendTo(this.$buttons);\n };\n\n /**\n * Create button\n *\n * @param button\n * @param {string} button.name\n * @param {string} button.label\n *\n * @returns {H5P.jQuery}\n */\n ContextMenu.prototype.createButton = function (button) {\n var self = this;\n\n var $newButton = $(\u0027\u003cdiv\u003e\u0027, {\n \u0027class\u0027: \u0027h5p-dragnbar-context-menu-button \u0027 + button.name.toLowerCase(),\n \u0027role\u0027: \u0027button\u0027,\n \u0027tabindex\u0027: 0,\n \u0027aria-label\u0027: button.label\n }).click(function () {\n self.dnb.pressed = true;\n self.trigger(\u0027contextMenu\u0027 + button.name, {button: button.name});\n }).keydown(function (e) {\n var keyPressed = e.which;\n // 32 - space\n if (keyPressed === 32) {\n $(this).click();\n }\n });\n\n return $newButton;\n };\n\n /**\n * Remove button from context menu\n * @param {String} buttonName\n */\n ContextMenu.prototype.removeFromMenu = function (buttonName) {\n var $removeButton = this.$buttons.children(\u0027.h5p-context-menu-button-\u0027 + buttonName);\n $removeButton.remove();\n };\n\n /**\n * Update context menu with current buttons. Useful when having added or removed buttons.\n */\n ContextMenu.prototype.updateContextMenu = function () {\n var self = this;\n\n // Clear context menu\n this.$buttons.children().remove();\n\n // Check if transform button should be enabled\n var enableTransform = false;\n\n // Add coordinates\n if (this.hasCoordinates) {\n this.addCoordinates();\n enableTransform = true;\n }\n\n // Add dimensions\n if (this.canResize) {\n this.addDimensions();\n enableTransform = true;\n }\n\n // Add menu elements\n this.buttons.forEach(function (button) {\n self.addToMenu(button);\n });\n\n // Add transform button\n this.addTransform(enableTransform)\n .appendTo(this.$contextMenu);\n\n this.$buttons.appendTo(this.$contextMenu);\n this.$transformPanel.appendTo(this.$contextMenu);\n };\n\n /**\n * Add button and update context menu.\n * @param {String} name\n * @param {String} label\n */\n ContextMenu.prototype.addButton = function (name, label) {\n this.buttons.push({name:name, label:label});\n this.updateContextMenu();\n };\n\n /**\n * Remove button from context menu\n * @param {string} name\n */\n ContextMenu.prototype.removeButton = function (name) {\n var self = this;\n\n // Check if button exists\n self.buttons.forEach(function (button, index) {\n if (button.name === name) {\n self.buttons.splice(index, 1);\n return;\n }\n });\n\n this.updateContextMenu();\n };\n\n /**\n * Toggle buttons visibility\n *\n * @param [showButtons] Show buttons\n */\n ContextMenu.prototype.toggleButtonsBar = function (showButtons) {\n var self = this;\n\n if (showButtons !== undefined) {\n self.$buttons.toggleClass(\u0027hide\u0027, !showButtons);\n }\n else {\n self.$buttons.toggleClass(\u0027hide\u0027);\n }\n };\n\n /**\n * Toggle transform panel visibility.\n *\n * @param [showTransformPanel] Show transform panel\n */\n ContextMenu.prototype.toggleTransformPanel = function (showTransformPanel) {\n var self = this;\n\n if (showTransformPanel !== undefined) {\n self.$transformPanel.toggleClass(\u0027hide\u0027, !showTransformPanel);\n }\n else {\n self.$transformPanel.toggleClass(\u0027hide\u0027);\n }\n };\n\n /**\n * Toggle if coordinates should show\n * @param {Boolean} [enableCoordinates] Enable coordinates\n */\n ContextMenu.prototype.toggleCoordinates = function (enableCoordinates) {\n if (enableCoordinates === undefined) {\n this.hasCoordinates = !this.hasCoordinates;\n }\n else {\n this.hasCoordinates = !!enableCoordinates;\n }\n\n this.updateContextMenu();\n };\n\n /**\n * Attach context menu to body.\n */\n ContextMenu.prototype.attach = function () {\n this.$contextMenu.appendTo(this.$parent);\n };\n\n /**\n * Detach context menu from DOM.\n */\n ContextMenu.prototype.detach = function () {\n this.$contextMenu.detach();\n };\n\n return ContextMenu;\n\n})(H5P.jQuery, H5P.EventDispatcher);\n"
,"scripts/dialog.js":"/*global H5P*/\nH5P.DragNBarDialog = (function ($, EventDispatcher) {\n\n /**\n * Controls the dialog in the interactive video.\n *\n * @class\n * @param {H5P.jQuery} $container for dialog\n * @param {H5P.jQuery} $videoWrapper needed for positioning of dialog\n */\n function Dialog($container, $videoWrapper) {\n var KEY_CODE_ESC = 27;\n var KEY_CODE_ENTER = 13;\n var KEY_CODE_SPACE = 32;\n\n var self = this;\n var titleId = \u0027dialog-title-\u0027 + H5P.createUUID();\n\n // Initialize event inheritance\n EventDispatcher.call(self);\n\n /**\n * Stops propagating an event\n *\n * @param {Event} event\n */\n var stopEventPropagation = function (event) {\n event.stopPropagation();\n };\n\n // Create DOM elements for dialog\n var $wrapper = $(\u0027\u003cdiv/\u003e\u0027, {\n \u0027class\u0027: \u0027h5p-dialog-wrapper h5p-ie-transparent-background h5p-hidden\u0027,\n on: {\n click: function (event) {\n if (!self.disableOverlay) {\n self.close();\n }\n else if ($dialog) {\n // set focus on dialog\n $dialog.focus();\n }\n },\n keyup: stopEventPropagation,\n keydown: stopEventPropagation\n }\n });\n var $dialog = $(\u0027\u003cdiv/\u003e\u0027, {\n role: \u0027dialog\u0027,\n \u0027class\u0027: \u0027h5p-dialog h5p-big\u0027,\n \u0027aria-labelledby\u0027: titleId,\n tabindex: \u0027-1\u0027,\n on: {\n click: function (event) {\n event.stopPropagation();\n },\n keydown: function (event) {\n var isClosable = $close.is(\u0027:visible\u0027);\n if (event.which === KEY_CODE_ESC \u0026\u0026 isClosable) {\n self.close();\n }\n }\n }\n }).appendTo($wrapper);\n\n // Create title bar\n var $titleBar = $(\u0027\u003cdiv/\u003e\u0027, {\n \u0027class\u0027: \u0027h5p-dialog-titlebar\u0027,\n appendTo: $dialog\n });\n var $title = $(\u0027\u003cdiv/\u003e\u0027, {\n \u0027class\u0027: \u0027h5p-dialog-title\u0027,\n id: titleId,\n appendTo: $titleBar\n });\n var $close = $(\u0027\u003cdiv/\u003e\u0027, {\n \u0027role\u0027: \u0027button\u0027,\n \u0027class\u0027: \u0027h5p-dialog-close\u0027,\n tabindex: \u00270\u0027,\n title: H5P.t(\u0027close\u0027),\n on: {\n click: function (event) {\n if (event.which === 1) {\n self.close();\n }\n },\n keypress: function (event) {\n if (event.which === KEY_CODE_SPACE || event.which === KEY_CODE_ENTER) {\n self.close();\n }\n }\n },\n appendTo: $titleBar\n });\n\n // Used instead of close\n var $customButtons;\n\n // Create inner DOM elements for dialog\n var $inner = $(\u0027\u003cdiv/\u003e\u0027, {\n \u0027class\u0027: \u0027h5p-dialog-inner\u0027\n }).appendTo($dialog);\n\n // Add all to DOM\n $wrapper.appendTo($container);\n\n /**\n * Reset the dialog\u0027s positioning\n *\n * @private\n */\n var resetPosition = function () {\n // Reset positioning\n $dialog.css({\n left: \u0027\u0027,\n top: \u0027\u0027,\n height: \u0027\u0027,\n width: \u0027\u0027,\n fontSize: \u0027\u0027,\n bottom: \u0027\u0027\n });\n $inner.css({\n width: \u0027\u0027,\n height: \u0027\u0027,\n overflow: \u0027\u0027\n });\n };\n\n /**\n * Display overlay.\n *\n * @private\n * @param {function} next callback\n */\n var showOverlay = function (next) {\n $wrapper.show();\n setTimeout(function () {\n // Remove class on next tick to ensure css animation\n $wrapper.removeClass(\u0027h5p-hidden\u0027);\n if (next) {\n next();\n }\n }, 0);\n };\n\n /**\n * Close overlay.\n *\n * @private\n * @param {function} next callback\n */\n var hideOverlay = function (next) {\n $wrapper.addClass(\u0027h5p-hidden\u0027);\n setTimeout(function () {\n // Hide when animation is done\n $wrapper.hide();\n if (next) {\n next();\n }\n }, 200);\n };\n\n /**\n * Opens a new dialog. Displays the given element.\n *\n * @param {H5P.jQuery} $element\n * @param {string} [title] Label for the dialog\n * @param {string} [classes] For styling\n * @param {H5P.jQuery} [$buttons] Use custom buttons for dialog\n */\n self.open = function ($element, title, classes, $buttons) {\n\n // Make all other elements in container not tabbable. When dialog is open,\n // it\u0027s like the elements behind does not exist.\n self.$tabbables = $container.find(\u0027a[href], area[href], input:not([disabled]), select:not([disabled]), textarea:not([disabled]), button:not([disabled]), iframe, object, embed, *[tabindex], *[contenteditable]\u0027).filter(function () {\n var $tabbable = $(this);\n if (!$.contains($wrapper.get(0), $tabbable.get(0))) {\n // Store current tabindex, so we can set it back when dialog closes\n $tabbable.data(\u0027tabindex\u0027, $tabbable.attr(\u0027tabindex\u0027));\n // Make it non tabbable\n $tabbable.attr(\u0027tabindex\u0027, \u0027-1\u0027);\n return true;\n }\n // If element is part of dialog wrapper, just ignore it\n return false;\n });\n\n showOverlay();\n $inner.children().detach().end().append($element);\n\n // Reset positioning\n resetPosition();\n $dialog.addClass(\u0027h5p-big\u0027);\n $title.attr(\u0027class\u0027, \u0027h5p-dialog-title\u0027 + (classes ? \u0027 \u0027 + classes : \u0027\u0027));\n\n // Add label\n if (!title) {\n title = \u0027\u0027;\n }\n $title.html(title);\n\n // Clean up after previous custom buttons\n if ($customButtons) {\n $customButtons.remove();\n $close.show();\n }\n\n // Add new custom buttons\n if ($buttons) {\n $customButtons = $buttons;\n\n // Hide default close button\n $close.hide();\n\n // Add custom buttons\n $buttons.appendTo($titleBar);\n }\n\n self.resize();\n\n self.trigger(\u0027open\u0027);\n\n $dialog.one(\u0027transitionend\u0027, function(event) {\n // Find visible enabled inputs:\n var $inputs = $inner.find(\u0027input:visible:not(:disabled)\u0027);\n if ($inputs.length) {\n $inputs.get(0).focus();\n }\n else {\n $dialog.focus();\n }\n });\n };\n\n self.resize = function () {\n if (!$dialog.hasClass(\u0027h5p-big\u0027)) {\n return;\n }\n\n var fontSize = toNum($inner.css(\u0027fontSize\u0027));\n var titleBarHeight = ($titleBar.outerHeight() / fontSize);\n\n // Same as height\n var maxHeight = $container.height();\n // minus dialog margins\n maxHeight -= Number($dialog.css(\u0027top\u0027).replace(\u0027px\u0027, \u0027\u0027)) * 2;\n\n $inner.css({\n width: \u0027100%\u0027,\n maxHeight: ((maxHeight / fontSize) - titleBarHeight) + \u0027em\u0027,\n marginTop: titleBarHeight + \u0027em\u0027\n });\n $dialog.css({\n bottom: \u0027auto\u0027,\n maxHeight: \u0027\u0027\n });\n };\n\n /**\n * Adds a name to the dialog for identifying what it contains.\n *\n * @param {string} machineName Name of library inside dialog.\n */\n self.addLibraryClass = function (machineName) {\n $dialog.attr(\u0027data-lib\u0027, machineName);\n };\n\n /**\n * Toggle class on the dialog Dom element\n * @method toggleClass\n * @param {String} cls Classname\n * @param {Boolean} toggle\n */\n self.toggleClass = function (cls, toggle) {\n $dialog.toggleClass(cls, toggle);\n };\n\n self.isOpen = function () {\n return $wrapper.is(\u0027:visible\u0027);\n };\n\n /**\n * Reposition the currently open dialog relative to the given button.\n *\n * @param {H5P.jQuery} $button\n * @param {Object} [size] Sets a size for the dialog, useful for images.\n * @param {boolean} [medium=false] Sets a min. size for medium dialogs.\n */\n self.position = function ($button, size, medium) {\n resetPosition();\n $dialog.removeClass(\u0027h5p-big h5p-medium\u0027);\n var titleBarHeight = Number($inner[0].style.marginTop.replace(\u0027em\u0027, \u0027\u0027));\n\n // Use a fixed size\n if (size) {\n var fontSizeRatio = 16 / toNum($container.css(\u0027fontSize\u0027));\n\n // Fixed width\n if (size.width) {\n size.width = (size.width * fontSizeRatio);\n $dialog.css(\u0027width\u0027, size.width + \u0027em\u0027);\n }\n\n // Fixed height\n if (size.height) {\n size.height = (size.height * fontSizeRatio) + titleBarHeight;\n $dialog.css(\u0027height\u0027, size.height + \u0027em\u0027);\n\n $inner.css({\n width: \u0027auto\u0027,\n overflow: \u0027hidden\u0027\n });\n }\n }\n\n if (medium) {\n $dialog.addClass(\u0027h5p-medium\u0027);\n }\n\n var buttonWidth = $button.outerWidth(true);\n var buttonPosition = $button.position();\n var containerWidth = $container.width();\n var containerHeight = $container.height();\n\n // Position dialog horizontally\n var left = buttonPosition.left;\n var dialogWidth = $dialog.outerWidth(true);\n if (medium \u0026\u0026 dialogWidth \u003e containerWidth) {\n // If dialog is too big to fit within the container, display as h5p-big instead.\n // Only medium dialogs can become big\n $dialog.addClass(\u0027h5p-big\u0027);\n return;\n }\n\n if (buttonPosition.left \u003e (containerWidth / 2) - (buttonWidth / 2)) {\n // Show on left\n left -= dialogWidth - buttonWidth;\n }\n\n // Make sure the dialog is within the video on the right.\n if ((left + dialogWidth) \u003e containerWidth) {\n left = containerWidth - dialogWidth;\n }\n\n var marginLeft = parseInt($videoWrapper.css(\u0027marginLeft\u0027));\n if (isNaN(marginLeft)) {\n marginLeft = 0;\n }\n\n // And finally, make sure we\u0027re within bounds on the left hand side too...\n if (left \u003c marginLeft) {\n left = marginLeft;\n }\n\n // Position dialog vertically\n var marginTop = parseInt($videoWrapper.css(\u0027marginTop\u0027));\n if (isNaN(marginTop)) {\n marginTop = 0;\n }\n\n var top = (medium ? 0 : (buttonPosition.top + marginTop));\n var totalHeight = top + $dialog.outerHeight(true);\n if (totalHeight \u003e containerHeight) {\n top -= totalHeight - containerHeight;\n }\n var maxHeight = $container.height() - top + $dialog.height() - $dialog.outerHeight(true);\n var fontSize = toNum($container.css(\u0027fontSize\u0027));\n // Set dialog size\n $dialog.css({\n top: (top / (containerHeight / 100)) + \u0027%\u0027,\n left: (left / (containerWidth / 100)) + \u0027%\u0027,\n width: (window.getComputedStyle($dialog[0]).width / fontSize) + \u0027em\u0027,\n maxHeight: (maxHeight / fontSize) + \u0027em\u0027\n });\n $inner.css(\u0027maxHeight\u0027, ((maxHeight - $titleBar.outerHeight(true)) / fontSize) + \u0027em\u0027);\n };\n\n /**\n * Find max available space inside dialog when positioning relative to\n * given button.\n *\n * @param {H5P.jQuery} $button\n * @param {Boolean} fullScreen True if dialog fills whole parent\n * @returns {Object} Attrs: width, height\n */\n self.getMaxSize = function ($button, fullScreen) {\n var buttonWidth = $button.outerWidth(true);\n var buttonPosition = $button.position();\n var containerWidth = $container.width();\n\n var max = {};\n max.height = Number($inner.css(\u0027maxHeight\u0027).replace(\u0027px\u0027, \u0027\u0027));\n\n // If border, extract that:\n max.height -= Number($inner.css(\u0027border-width\u0027).replace(\u0027px\u0027, \u0027\u0027)) * 2;\n\n if (fullScreen) {\n max.width = containerWidth;\n }\n else {\n if (buttonPosition.left \u003e (containerWidth / 2) - (buttonWidth / 2)) {\n // Space to the left of the button minus margin\n max.width = buttonPosition.left;\n }\n else {\n // Space to the right of the button minus margin\n max.width = (containerWidth - buttonPosition.left - buttonWidth);\n }\n }\n\n // Use em\n var fontSize = toNum($container.css(\u0027fontSize\u0027));\n max.width = (max.width / fontSize) * (fontSize / 16);\n max.height = (max.height / fontSize) * (fontSize / 16);\n\n return max;\n };\n\n /**\n * Scroll to given position in current dialog.\n *\n * @param {number} to Scroll position\n * @param {number} ms Time the animation takes.\n */\n self.scroll = function (to, ms) {\n $inner.stop().animate({\n scrollTop: to\n }, ms);\n };\n\n /**\n * Close the currently open dialog.\n */\n self.close = function (closeInstant) {\n $wrapper.addClass(\u0027h5p-hidden\u0027);\n\n // Resetting tabindex on background elements\n if (self.$tabbables) {\n self.$tabbables.each(function () {\n var $element = $(this);\n var tabindex = $element.data(\u0027tabindex\u0027);\n if (tabindex !== undefined) {\n $element.attr(\u0027tabindex\u0027, tabindex);\n $element.removeData(\u0027tabindex\u0027);\n }\n else {\n $element.removeAttr(\u0027tabindex\u0027);\n }\n });\n }\n\n if (closeInstant) {\n $wrapper.hide();\n self.disableOverlay = false;\n $close.show();\n }\n else {\n setTimeout(function () {\n $wrapper.hide();\n self.disableOverlay = false;\n $close.show();\n }, 201);\n }\n\n self.trigger(\u0027close\u0027);\n\n // Let others reach to the hiding of this dialog\n self.trigger(\u0027domHidden\u0027, {\n \u0027$dom\u0027: $wrapper,\n \u0027key\u0027: \u0027dialogClosed\u0027\n }, {\u0027bubbles\u0027: true, \u0027external\u0027: true});\n };\n\n /**\n * Open overlay only.\n */\n self.openOverlay = function () {\n self.disableOverlay = true;\n $dialog.hide();\n showOverlay();\n };\n\n /**\n * Close overlay only.\n */\n self.closeOverlay = function () {\n $wrapper.addClass(\u0027h5p-hidden\u0027);\n hideOverlay(function () {\n $dialog.show();\n self.disableOverlay = false;\n });\n };\n\n /**\n * Removes the close button from the current dialog.\n */\n self.hideCloseButton = function () {\n $close.hide();\n };\n\n /**\n * Get width of dialog\n * @returns {Number} Width of dialog\n */\n self.getDialogWidth = function () {\n return $dialog.width();\n };\n\n /**\n * Reset dialog width\n */\n self.removeStaticWidth = function () {\n $dialog.css(\u0027width\u0027, \u0027\u0027);\n };\n }\n\n // Extends the event dispatcher\n Dialog.prototype = Object.create(EventDispatcher.prototype);\n Dialog.prototype.constructor = Dialog;\n\n\n /**\n * Converts css px value to number.\n *\n * @private\n * @param {string} num\n * @returns {Number}\n */\n var toNum = function (num) {\n return Number(num.replace(\u0027px\u0027,\u0027\u0027));\n };\n\n return Dialog;\n})(H5P.jQuery, H5P.EventDispatcher);\n"
,"scripts/drag-n-bar-element.js":"/*global H5P*/\n\n/**\n * Create Drag N Bar Element. Connects a DragNBar element to a context menu\n */\nH5P.DragNBarElement = (function ($, ContextMenu, EventDispatcher) {\n\n /**\n * Constructor DragNBarElement\n *\n * @class\n * @param {H5P.DragNBar} dragNBar Parent dragNBar toolbar\n * @param {object} [clipboardData]\n * @param {Object} [options] Button object that the element is created from\n * @param {Boolean} [options.disableContextMenu] Decides if element should have editor functionality\n * @param {Function} [options.createElement] Function for creating element from button\n * @param {boolean} [options.hasCoordinates] Decides if element will display coordinates\n * @param {H5P.jQuery} [options.element] Element\n */\n function DragNBarElement(dragNBar, clipboardData, options) {\n var self = this;\n EventDispatcher.call(this);\n\n this.dnb = dragNBar;\n this.options = options || {};\n if (!this.options.disableContextMenu) {\n this.contextMenu = new ContextMenu(this.dnb.$dialogContainer, this, this.options.hasCoordinates, this.options.disableResize);\n }\n this.focused = false;\n\n if (this.options.createElement) {\n this.$element = this.options.createElement().appendTo(dragNBar.$container);\n this.focus();\n }\n else {\n this.$element = this.options.element;\n }\n\n // Let dnb know element has been pressed\n if (this.$element) {\n if (this.dnb.isEditor) {\n this.$element.mousedown(function () {\n self.dnb.pressed = true;\n });\n }\n\n // Run custom focus function on element focus\n this.$element.focus(function () {\n self.focus();\n });\n }\n\n /**\n * Store element paramets in the local storage.\n */\n self.toClipboard = function (width, height) {\n if (clipboardData \u0026\u0026 localStorage) {\n clipboardData.width = width;\n clipboardData.height = height;\n localStorage.setItem(\u0027h5pClipboard\u0027, JSON.stringify(clipboardData));\n }\n };\n }\n\n // Inheritance\n DragNBarElement.prototype = Object.create(EventDispatcher.prototype);\n DragNBarElement.prototype.constructor = DragNBarElement;\n\n /**\n * Add button to context menu.\n *\n * @param {string} name\n * @param {string} label\n */\n DragNBarElement.prototype.addButton = function (name, label) {\n this.contextMenu.addToMenu({name:name, label:label});\n };\n\n /**\n * Get element\n * @returns {H5P.jQuery}\n */\n DragNBarElement.prototype.getElement = function () {\n return this.$element;\n };\n\n /**\n * Set element\n * @param {H5P.jQuery} $element\n */\n DragNBarElement.prototype.setElement = function ($element) {\n var self = this;\n this.$element = $element;\n\n // Register custom focus function on new element focus\n this.$element.focus(function () {\n self.focus();\n });\n };\n\n /**\n * Show context menu\n */\n DragNBarElement.prototype.showContextMenu = function () {\n if (this.contextMenu) {\n this.contextMenu.attach();\n }\n };\n\n /**\n * Hide context menu\n */\n DragNBarElement.prototype.hideContextMenu = function () {\n if (this.contextMenu) {\n this.contextMenu.detach();\n }\n };\n\n /**\n * Update coordinates in context menu to current location\n *\n * @param {Number} left Left position of context menu\n * @param {Number} top Top position of context menu\n * @param {Number} x X coordinate of context menu\n * @param {Number} y Y coordinate of context menu\n */\n DragNBarElement.prototype.updateCoordinates = function (left, top, x, y) {\n if (this.contextMenu) {\n this.contextMenu.updateCoordinates(left, top, x, y);\n this.resizeContextMenu(x);\n }\n };\n\n /**\n * Float context menu left if width exceeds parent container.\n *\n * @param {Number} [left] Left position of context menu.\n */\n DragNBarElement.prototype.resizeContextMenu = function (left) {\n if (this.options.disableContextMenu) {\n return;\n }\n\n // Need to take into account the left padding of the contextmenu\u0027s parent\n var paddingLeft = Number(this.contextMenu.$parent.css(\u0027padding-left\u0027).replace(\u0027px\u0027, \u0027\u0027));\n left = (left || this.$element.position().left) + paddingLeft;\n var containerWidth = this.dnb.$container.width();\n var $cm = this.contextMenu.$contextMenu;\n\n // Measure full outer width\n $cm.css({\n position: \u0027absolute\u0027,\n left: 0\n });\n var contextMenuWidth = $cm.outerWidth(true);\n\n // Reset to default\n $cm.css({\n position: \u0027\u0027,\n left: left\n });\n\n var isTooWide = left + contextMenuWidth \u003e= containerWidth;\n\n if (isTooWide) {\n var newLeft = left - contextMenuWidth;\n this.contextMenu.$contextMenu.css(\u0027left\u0027, newLeft + \u0027px\u0027);\n this.contextMenu.$contextMenu.addClass(\u0027left-aligned\u0027);\n } else {\n this.contextMenu.$contextMenu.removeClass(\u0027left-aligned\u0027);\n }\n };\n\n /**\n * Blur element and hide context menu.\n */\n DragNBarElement.prototype.blur = function () {\n if (this.$element) {\n this.$element.removeClass(\u0027focused\u0027);\n this.focused = false;\n\n if (!this.options.disableContextMenu) {\n // Hide transform panel\n this.contextMenu.trigger(\u0027contextMenuTransform\u0027, {showTransformPanel: false});\n }\n }\n this.hideContextMenu();\n };\n\n /**\n * Focus element\n */\n DragNBarElement.prototype.focus = function () {\n this.$element.addClass(\u0027focused\u0027);\n this.focused = true;\n if (this.contextMenu) {\n this.resizeContextMenu(this.$element.position().left);\n }\n };\n\n /**\n * Remove element and hide context menu\n */\n DragNBarElement.prototype.removeElement = function () {\n this.$element.detach();\n this.hideContextMenu();\n };\n\n return DragNBarElement;\n\n})(H5P.jQuery, H5P.DragNBarContextMenu, H5P.EventDispatcher);\n"
,"image.js":"var H5P = H5P || {};\n\n/**\n * Constructor.\n *\n * @param {Object} params Options for this library.\n * @param {Number} id Content identifier\n * @returns {undefined}\n */\n(function ($) {\n H5P.Image = function (params, id) {\n H5P.EventDispatcher.call(this);\n\n if (params.file === undefined || !(params.file instanceof Object)) {\n this.placeholder = true;\n }\n else {\n this.source = H5P.getPath(params.file.path, id);\n this.width = params.file.width;\n this.height = params.file.height;\n\n // Use new copyright information if available. Fallback to old.\n if (params.file.copyright !== undefined) {\n this.copyright = params.file.copyright;\n }\n else if (params.copyright !== undefined) {\n this.copyright = params.copyright;\n }\n }\n\n this.alt = params.alt !== undefined ? params.alt : \u0027New image\u0027;\n\n if (params.title !== undefined) {\n this.title = params.title;\n }\n };\n\n H5P.Image.prototype = Object.create(H5P.EventDispatcher.prototype);\n H5P.Image.prototype.constructor = H5P.Image;\n\n /**\n * Wipe out the content of the wrapper and put our HTML in it.\n *\n * @param {jQuery} $wrapper\n * @returns {undefined}\n */\n H5P.Image.prototype.attach = function ($wrapper) {\n var self = this;\n var source = this.source;\n\n if (self.$img === undefined) {\n if(self.placeholder) {\n self.$img = $(\u0027\u003cdiv\u003e\u0027, {\n width: \u0027100%\u0027,\n height: \u0027100%\u0027,\n class: \u0027h5p-placeholder\u0027,\n title: this.title === undefined ? \u0027\u0027 : this.title,\n load: function () {\n self.trigger(\u0027loaded\u0027);\n }\n });\n } else {\n self.$img = $(\u0027\u003cimg\u003e\u0027, {\n width: \u0027100%\u0027,\n height: \u0027100%\u0027,\n src: source,\n alt: this.alt,\n title: this.title === undefined ? \u0027\u0027 : this.title,\n load: function () {\n self.trigger(\u0027loaded\u0027);\n }\n });\n }\n }\n\n $wrapper.addClass(\u0027h5p-image\u0027).html(self.$img);\n };\n\n /**\n * Gather copyright information for the current content.\n *\n * @returns {H5P.ContentCopyright}\n */\n H5P.Image.prototype.getCopyrights = function () {\n if (this.copyright === undefined) {\n return;\n }\n\n var info = new H5P.ContentCopyrights();\n\n var image = new H5P.MediaCopyright(this.copyright);\n image.setThumbnail(new H5P.Thumbnail(this.source, this.width, this.height));\n info.addMedia(image);\n\n return info;\n };\n\n return H5P.Image;\n}(H5P.jQuery));\n"
,"scripts/text.js":"var H5P = H5P || {};\n\n/**\n * Constructor.\n *\n * @param {object} params Options for this library.\n */\nH5P.Text = function (params) {\n this.text = params.text === undefined ? \u0027\u003cem\u003eNew text\u003c/em\u003e\u0027 : params.text;\n};\n\n/**\n * Wipe out the content of the wrapper and put our HTML in it.\n *\n * @param {jQuery} $wrapper\n */\nH5P.Text.prototype.attach = function ($wrapper) {\n $wrapper.addClass(\u0027h5p-text\u0027).html(this.text);\n};\n"
,"scripts/table.js":"var H5P = H5P || {};\n\n/**\n * Constructor.\n *\n * @param {object} params Options for this library.\n * @param {int} id Content identifier\n */\nH5P.Table = function (params, id) {\n this.text = params.text === undefined ? \u0027\u003ctable class=\"h5p-table\"\u003e\u003cthead\u003e\u003ctr\u003e\u003cth scope=\"col\"\u003eHeading Column 1\u003c/th\u003e\u003cth scope=\"col\"\u003eHeading Column 2\u003c/th\u003e\u003c/tr\u003e\u003c/thead\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd\u003eRow 1 Col 1\u003c/td\u003e\u003ctd\u003eRow 1 Col 2\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003eRow 2 Col 1\u003c/td\u003e\u003ctd\u003eRow 2 Col 2\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u0027 : params.text;\n};\n\n/**\n * Wipe out the content of the wrapper and put our HTML in it.\n *\n * @param {jQuery} $wrapper\n */\nH5P.Table.prototype.attach = function ($wrapper) {\n $wrapper.addClass(\u0027h5p-table\u0027).html(this.text);\n};"
,"link-widget.js":"/*global H5PEditor, H5P */\nH5PEditor.widgets.linkWidget = (function ($) {\n\n /**\n * Initialize link widget\n *\n * @param parent\n * @param field\n * @param params\n * @param setValue\n */\n function LinkWidget(parent, field, params, setValue) {\n var self = this;\n\n self.field = field;\n\n // Tell editor to handle passing readies.\n self.passReadies = false;\n\n // Create link widget container\n var $container = $(\u0027\u003cdiv\u003e\u0027, {\n \u0027class\u0027: \u0027h5p-link-widget\u0027\n });\n\n // Link fields\n var $linkFields = $(\u0027\u003cdiv\u003e\u0027, {\n \u0027class\u0027: \u0027h5p-link-fields\u0027\n }).appendTo($container);\n\n // Error field\n var $errorField = $(\u0027\u003cdiv\u003e\u0027, {\n \u0027class\u0027: \u0027h5p-link-errors\u0027\n }).appendTo($container);\n\n // Extend params with default values\n params = $.extend({}, params);\n setValue(field, params);\n\n // Process semantics and place them in container\n H5PEditor.processSemanticsChunk(field.fields, params, $linkFields, self);\n\n // Selector element\n var $selectElement = $linkFields.find(\u0027.field.select\u0027).addClass(\u0027h5p-link-protocol-selector\u0027);\n var $selector = $selectElement.find(\u0027select\u0027);\n\n // Url text element\n var $urlElement = $linkFields.find(\u0027.field.text\u0027).addClass(\u0027h5p-link-url\u0027);\n var $urlText = $urlElement.find(\u0027.h5peditor-text\u0027);\n\n // Move error messages\n $selectElement.find(\u0027.h5p-errors\u0027).appendTo($errorField);\n $urlElement.find(\u0027.h5p-errors\u0027).appendTo($errorField);\n\n // Register listener for changes in url field\n $urlText.on(\u0027input propertychange paste\u0027, function () {\n findUrlProtocol();\n });\n\n /**\n * Finds url protocol and sets it in selector if found.\n */\n var findUrlProtocol = function () {\n var $options = $(\u0027option\u0027, $selector);\n $options.each(function (idx, option) {\n if ($urlText.val().substr(0, option.value.length) === option.value) {\n $urlText.val($urlText.val().substr(option.value.length));\n $selector.val(option.value);\n }\n });\n\n // Make sure params are updated\n params.url = $urlText.val();\n params.protocol = $selector.val();\n };\n\n /**\n * Validate the url\n */\n self.validate = function () {\n // We only require the URL field to be non-empty if mandatory\n return field.optional === true || $urlText.val().trim().length \u003e= 1;\n };\n\n /**\n * Remove widget\n */\n self.remove = function () {\n $container.remove();\n };\n\n /**\n * Append link widget to wrapper\n *\n * @param {H5P.jQuery} $wrapper\n */\n self.appendTo = function ($wrapper) {\n $container.appendTo($wrapper);\n };\n\n self.getDomElement = function () {\n return $container;\n }\n }\n\n return LinkWidget;\n\n})(H5P.jQuery);\n"
,"link.js":"var H5P = H5P || {};\n\n/**\n * H5P Link Library Module.\n */\nH5P.Link = (function ($) {\n\n /**\n * Link constructor.\n *\n * @param {Object} parameters\n */\n function Link(parameters) {\n // Add default parameters\n parameters = $.extend(true, {\n title: \u0027New link\u0027,\n linkWidget: {\n protocol: \u0027\u0027,\n url: \u0027\u0027\n }\n }, parameters);\n\n var url = \u0027\u0027;\n if (parameters.linkWidget.protocol !== \u0027other\u0027) {\n url += parameters.linkWidget.protocol;\n }\n url += parameters.linkWidget.url;\n\n /**\n * Public. Attach.\n *\n * @param {jQuery} $container\n */\n this.attach = function ($container) {\n var sanitizedUrl = sanitizeUrlProtocol(url);\n $container.addClass(\u0027h5p-link\u0027).html(\u0027\u003ca href=\"\u0027 + sanitizedUrl + \u0027\" target=\"_blank\"\u003e\u0027 + parameters.title + \u0027\u003c/a\u003e\u0027)\n .keypress(function (event) {\n if (event.which === 32) {\n this.click();\n }\n });\n };\n\n /**\n * Return url\n *\n * @returns {string}\n */\n this.getUrl = function () {\n return url;\n };\n\n /**\n * Private. Remove illegal url protocols from uri\n */\n var sanitizeUrlProtocol = function(uri) {\n var allowedProtocols = [\u0027http\u0027, \u0027https\u0027, \u0027ftp\u0027, \u0027irc\u0027, \u0027mailto\u0027, \u0027news\u0027, \u0027nntp\u0027, \u0027rtsp\u0027, \u0027sftp\u0027, \u0027ssh\u0027, \u0027tel\u0027, \u0027telnet\u0027, \u0027webcal\u0027];\n\n var first = true;\n var before = \u0027\u0027;\n while (first || uri != before) {\n first = false;\n before = uri;\n var colonPos = uri.indexOf(\u0027:\u0027);\n if (colonPos \u003e 0) {\n // We found a possible protocol\n var protocol = uri.substr(0, colonPos);\n // If the colon is preceeded by a hash, slash or question mark it isn\u0027t a protocol\n if (protocol.match(/[/?#]/g)) {\n break;\n }\n // Is this a forbidden protocol?\n if (allowedProtocols.indexOf(protocol.toLowerCase()) == -1) {\n // If illegal, remove the protocol...\n uri = uri.substr(colonPos + 1);\n }\n }\n }\n return uri;\n };\n }\n\n return Link;\n})(H5P.jQuery);\n"
,"transition.js":"var H5P = H5P || {};\n/**\n * Transition contains helper function relevant for transitioning\n */\nH5P.Transition = (function ($) {\n\n /**\n * @class\n * @namespace H5P\n */\n Transition = {};\n\n /**\n * @private\n */\n Transition.transitionEndEventNames = {\n \u0027WebkitTransition\u0027: \u0027webkitTransitionEnd\u0027,\n \u0027transition\u0027: \u0027transitionend\u0027,\n \u0027MozTransition\u0027: \u0027transitionend\u0027,\n \u0027OTransition\u0027: \u0027oTransitionEnd\u0027,\n \u0027msTransition\u0027: \u0027MSTransitionEnd\u0027\n };\n\n /**\n * @private\n */\n Transition.cache = [];\n\n /**\n * Get the vendor property name for an event\n *\n * @function H5P.Transition.getVendorPropertyName\n * @static\n * @private\n * @param {string} prop Generic property name\n * @return {string} Vendor specific property name\n */\n Transition.getVendorPropertyName = function (prop) {\n\n if (Transition.cache[prop] !== undefined) {\n return Transition.cache[prop];\n }\n\n var div = document.createElement(\u0027div\u0027);\n\n // Handle unprefixed versions (FF16+, for example)\n if (prop in div.style) {\n Transition.cache[prop] = prop;\n }\n else {\n var prefixes = [\u0027Moz\u0027, \u0027Webkit\u0027, \u0027O\u0027, \u0027ms\u0027];\n var prop_ = prop.charAt(0).toUpperCase() + prop.substr(1);\n\n if (prop in div.style) {\n Transition.cache[prop] = prop;\n }\n else {\n for (var i = 0; i \u003c prefixes.length; ++i) {\n var vendorProp = prefixes[i] + prop_;\n if (vendorProp in div.style) {\n Transition.cache[prop] = vendorProp;\n break;\n }\n }\n }\n }\n\n return Transition.cache[prop];\n };\n\n /**\n * Get the name of the transition end event\n *\n * @static\n * @private\n * @return {string} description\n */\n Transition.getTransitionEndEventName = function () {\n return Transition.transitionEndEventNames[Transition.getVendorPropertyName(\u0027transition\u0027)] || undefined;\n };\n\n /**\n * Helper function for listening on transition end events\n *\n * @function H5P.Transition.onTransitionEnd\n * @static\n * @param {domElement} $element The element which is transitioned\n * @param {function} callback The callback to be invoked when transition is finished\n * @param {number} timeout Timeout in milliseconds. Fallback if transition event is never fired\n */\n Transition.onTransitionEnd = function ($element, callback, timeout) {\n // Fallback on 1 second if transition event is not supported/triggered\n timeout = timeout || 1000;\n Transition.transitionEndEventName = Transition.transitionEndEventName || Transition.getTransitionEndEventName();\n var callbackCalled = false;\n\n var doCallback = function () {\n if (callbackCalled) {\n return;\n }\n $element.off(Transition.transitionEndEventName, callback);\n callbackCalled = true;\n clearTimeout(timer);\n callback();\n };\n\n var timer = setTimeout(function () {\n doCallback();\n }, timeout);\n\n $element.on(Transition.transitionEndEventName, function () {\n doCallback();\n });\n };\n\n /**\n * Wait for a transition - when finished, invokes next in line\n *\n * @private\n *\n * @param {Object[]} transitions Array of transitions\n * @param {H5P.jQuery} transitions[].$element Dom element transition is performed on\n * @param {number=} transitions[].timeout Timeout fallback if transition end never is triggered\n * @param {bool=} transitions[].break If true, sequence breaks after this transition\n * @param {number} index The index for current transition\n */\n var runSequence = function (transitions, index) {\n if (index \u003e= transitions.length) {\n return;\n }\n\n var transition = transitions[index];\n H5P.Transition.onTransitionEnd(transition.$element, function () {\n if (transition.end) {\n transition.end();\n }\n if (transition.break !== true) {\n runSequence(transitions, index+1);\n }\n }, transition.timeout || undefined);\n };\n\n /**\n * Run a sequence of transitions\n *\n * @function H5P.Transition.sequence\n * @static\n * @param {Object[]} transitions Array of transitions\n * @param {H5P.jQuery} transitions[].$element Dom element transition is performed on\n * @param {number=} transitions[].timeout Timeout fallback if transition end never is triggered\n * @param {bool=} transitions[].break If true, sequence breaks after this transition\n */\n Transition.sequence = function (transitions) {\n runSequence(transitions, 0);\n };\n\n return Transition;\n})(H5P.jQuery);\n"
,"scripts/tether.min.js":"var oldTether = window.Tether;\n!function(t,e){\"function\"==typeof define\u0026\u0026define.amd?define(e):\"object\"==typeof exports?module.exports=e(require,exports,module):t.Tether=e()}(this,function(t,e,o){\"use strict\";function i(t,e){if(!(t instanceof e))throw new TypeError(\"Cannot call a class as a function\")}function n(t){var e=getComputedStyle(t),o=e.position;if(\"fixed\"===o)return t;for(var i=t;i=i.parentNode;){var n=void 0;try{n=getComputedStyle(i)}catch(r){}if(\"undefined\"==typeof n||null===n)return i;var s=n.overflow,a=n.overflowX,f=n.overflowY;if(/(auto|scroll)/.test(s+f+a)\u0026\u0026(\"absolute\"!==o||[\"relative\",\"absolute\",\"fixed\"].indexOf(n.position)\u003e=0))return i}return document.body}function r(t){var e=void 0;t===document?(e=document,t=document.documentElement):e=t.ownerDocument;var o=e.documentElement,i={},n=t.getBoundingClientRect();for(var r in n)i[r]=n[r];var s=x(e);return i.top-=s.top,i.left-=s.left,\"undefined\"==typeof i.width\u0026\u0026(i.width=document.body.scrollWidth-i.left-i.right),\"undefined\"==typeof i.height\u0026\u0026(i.height=document.body.scrollHeight-i.top-i.bottom),i.top=i.top-o.clientTop,i.left=i.left-o.clientLeft,i.right=e.body.clientWidth-i.width-i.left,i.bottom=e.body.clientHeight-i.height-i.top,i}function s(t){return t.offsetParent||document.documentElement}function a(){var t=document.createElement(\"div\");t.style.width=\"100%\",t.style.height=\"200px\";var e=document.createElement(\"div\");f(e.style,{position:\"absolute\",top:0,left:0,pointerEvents:\"none\",visibility:\"hidden\",width:\"200px\",height:\"150px\",overflow:\"hidden\"}),e.appendChild(t),document.body.appendChild(e);var o=t.offsetWidth;e.style.overflow=\"scroll\";var i=t.offsetWidth;o===i\u0026\u0026(i=e.clientWidth),document.body.removeChild(e);var n=o-i;return{width:n,height:n}}function f(){var t=void 0===arguments[0]?{}:arguments[0],e=[];return Array.prototype.push.apply(e,arguments),e.slice(1).forEach(function(e){if(e)for(var o in e)({}).hasOwnProperty.call(e,o)\u0026\u0026(t[o]=e[o])}),t}function h(t,e){if(\"undefined\"!=typeof t.classList)e.split(\" \").forEach(function(e){e.trim()\u0026\u0026t.classList.remove(e)});else{var o=new RegExp(\"(^| )\"+e.split(\" \").join(\"|\")+\"( |$)\",\"gi\"),i=u(t).replace(o,\" \");p(t,i)}}function l(t,e){if(\"undefined\"!=typeof t.classList)e.split(\" \").forEach(function(e){e.trim()\u0026\u0026t.classList.add(e)});else{h(t,e);var o=u(t)+(\" \"+e);p(t,o)}}function d(t,e){if(\"undefined\"!=typeof t.classList)return t.classList.contains(e);var o=u(t);return new RegExp(\"(^| )\"+e+\"( |$)\",\"gi\").test(o)}function u(t){return t.className instanceof SVGAnimatedString?t.className.baseVal:t.className}function p(t,e){t.setAttribute(\"class\",e)}function c(t,e,o){o.forEach(function(o){-1===e.indexOf(o)\u0026\u0026d(t,o)\u0026\u0026h(t,o)}),e.forEach(function(e){d(t,e)||l(t,e)})}function i(t,e){if(!(t instanceof e))throw new TypeError(\"Cannot call a class as a function\")}function g(t,e){var o=void 0===arguments[2]?1:arguments[2];return t+o\u003e=e\u0026\u0026e\u003e=t-o}function m(){return\"undefined\"!=typeof performance\u0026\u0026\"undefined\"!=typeof performance.now?performance.now():+new Date}function v(){for(var t={top:0,left:0},e=arguments.length,o=Array(e),i=0;e\u003ei;i++)o[i]=arguments[i];return o.forEach(function(e){var o=e.top,i=e.left;\"string\"==typeof o\u0026\u0026(o=parseFloat(o,10)),\"string\"==typeof i\u0026\u0026(i=parseFloat(i,10)),t.top+=o,t.left+=i}),t}function y(t,e){return\"string\"==typeof t.left\u0026\u0026-1!==t.left.indexOf(\"%\")\u0026\u0026(t.left=parseFloat(t.left,10)/100*e.width),\"string\"==typeof t.top\u0026\u0026-1!==t.top.indexOf(\"%\")\u0026\u0026(t.top=parseFloat(t.top,10)/100*e.height),t}function b(t,e){return\"scrollParent\"===e?e=t.scrollParent:\"window\"===e\u0026\u0026(e=[pageXOffset,pageYOffset,innerWidth+pageXOffset,innerHeight+pageYOffset]),e===document\u0026\u0026(e=e.documentElement),\"undefined\"!=typeof e.nodeType\u0026\u0026!function(){var t=r(e),o=t,i=getComputedStyle(e);e=[o.left,o.top,t.width+o.left,t.height+o.top],U.forEach(function(t,o){t=t[0].toUpperCase()+t.substr(1),\"Top\"===t||\"Left\"===t?e[o]+=parseFloat(i[\"border\"+t+\"Width\"]):e[o]-=parseFloat(i[\"border\"+t+\"Width\"])})}(),e}var w=function(){function t(t,e){for(var o=0;o\u003ce.length;o++){var i=e[o];i.enumerable=i.enumerable||!1,i.configurable=!0,\"value\"in i\u0026\u0026(i.writable=!0),Object.defineProperty(t,i.key,i)}}return function(e,o,i){return o\u0026\u0026t(e.prototype,o),i\u0026\u0026t(e,i),e}}(),C=void 0;\"undefined\"==typeof C\u0026\u0026(C={modules:[]});var O=function(){var t=0;return function(){return++t}}(),E={},x=function(t){var e=t._tetherZeroElement;\"undefined\"==typeof e\u0026\u0026(e=t.createElement(\"div\"),e.setAttribute(\"data-tether-id\",O()),f(e.style,{top:0,left:0,position:\"absolute\"}),t.body.appendChild(e),t._tetherZeroElement=e);var o=e.getAttribute(\"data-tether-id\");if(\"undefined\"==typeof E[o]){E[o]={};var i=e.getBoundingClientRect();for(var n in i)E[o][n]=i[n];T(function(){delete E[o]})}return E[o]},A=[],T=function(t){A.push(t)},S=function(){for(var t=void 0;t=A.pop();)t()},W=function(){function t(){i(this,t)}return w(t,[{key:\"on\",value:function(t,e,o){var i=void 0===arguments[3]?!1:arguments[3];\"undefined\"==typeof this.bindings\u0026\u0026(this.bindings={}),\"undefined\"==typeof this.bindings[t]\u0026\u0026(this.bindings[t]=[]),this.bindings[t].push({handler:e,ctx:o,once:i})}},{key:\"once\",value:function(t,e,o){this.on(t,e,o,!0)}},{key:\"off\",value:function(t,e){if(\"undefined\"==typeof this.bindings||\"undefined\"==typeof this.bindings[t])if(\"undefined\"==typeof e)delete this.bindings[t];else for(var o=0;o\u003cthis.bindings[t].length;)this.bindings[t][o].handler===e?this.bindings[t].splice(o,1):++o}},{key:\"trigger\",value:function(t){if(\"undefined\"!=typeof this.bindings\u0026\u0026this.bindings[t])for(var e=0;e\u003cthis.bindings[t].length;){var o=this.bindings[t][e],i=o.handler,n=o.ctx,r=o.once,s=n;\"undefined\"==typeof s\u0026\u0026(s=this);for(var a=arguments.length,f=Array(a\u003e1?a-1:0),h=1;a\u003eh;h++)f[h-1]=arguments[h];i.apply(s,f),r?this.bindings[t].splice(e,1):++e}}}]),t}();C.Utils={getScrollParent:n,getBounds:r,getOffsetParent:s,extend:f,addClass:l,removeClass:h,hasClass:d,updateClasses:c,defer:T,flush:S,uniqueId:O,Evented:W,getScrollBarSize:a};var M=function(){function t(t,e){var o=[],i=!0,n=!1,r=void 0;try{for(var s,a=t[Symbol.iterator]();!(i=(s=a.next()).done)\u0026\u0026(o.push(s.value),!e||o.length!==e);i=!0);}catch(f){n=!0,r=f}finally{try{!i\u0026\u0026a[\"return\"]\u0026\u0026a[\"return\"]()}finally{if(n)throw r}}return o}return function(e,o){if(Array.isArray(e))return e;if(Symbol.iterator in Object(e))return t(e,o);throw new TypeError(\"Invalid attempt to destructure non-iterable instance\")}}(),w=function(){function t(t,e){for(var o=0;o\u003ce.length;o++){var i=e[o];i.enumerable=i.enumerable||!1,i.configurable=!0,\"value\"in i\u0026\u0026(i.writable=!0),Object.defineProperty(t,i.key,i)}}return function(e,o,i){return o\u0026\u0026t(e.prototype,o),i\u0026\u0026t(e,i),e}}();if(\"undefined\"==typeof C)throw new Error(\"You must include the utils.js file before tether.js\");var P=C.Utils,n=P.getScrollParent,r=P.getBounds,s=P.getOffsetParent,f=P.extend,l=P.addClass,h=P.removeClass,c=P.updateClasses,T=P.defer,S=P.flush,a=P.getScrollBarSize,k=function(){for(var t=document.createElement(\"div\"),e=[\"transform\",\"webkitTransform\",\"OTransform\",\"MozTransform\",\"msTransform\"],o=0;o\u003ce.length;++o){var i=e[o];if(void 0!==t.style[i])return i}}(),B=[],_=function(){B.forEach(function(t){t.position(!1)}),S()};!function(){var t=null,e=null,o=null,i=function n(){return\"undefined\"!=typeof e\u0026\u0026e\u003e16?(e=Math.min(e-16,250),void(o=setTimeout(n,250))):void(\"undefined\"!=typeof t\u0026\u0026m()-t\u003c10||(\"undefined\"!=typeof o\u0026\u0026(clearTimeout(o),o=null),t=m(),_(),e=m()-t))};[\"resize\",\"scroll\",\"touchmove\"].forEach(function(t){window.addEventListener(t,i)})}();var z={center:\"center\",left:\"right\",right:\"left\"},F={middle:\"middle\",top:\"bottom\",bottom:\"top\"},L={top:0,left:0,middle:\"50%\",center:\"50%\",bottom:\"100%\",right:\"100%\"},Y=function(t,e){var o=t.left,i=t.top;return\"auto\"===o\u0026\u0026(o=z[e.left]),\"auto\"===i\u0026\u0026(i=F[e.top]),{left:o,top:i}},H=function(t){var e=t.left,o=t.top;return\"undefined\"!=typeof L[t.left]\u0026\u0026(e=L[t.left]),\"undefined\"!=typeof L[t.top]\u0026\u0026(o=L[t.top]),{left:e,top:o}},X=function(t){var e=t.split(\" \"),o=M(e,2),i=o[0],n=o[1];return{top:i,left:n}},j=X,N=function(){function t(e){var o=this;i(this,t),this.position=this.position.bind(this),B.push(this),this.history=[],this.setOptions(e,!1),C.modules.forEach(function(t){\"undefined\"!=typeof t.initialize\u0026\u0026t.initialize.call(o)}),this.position()}return w(t,[{key:\"getClass\",value:function(){var t=void 0===arguments[0]?\"\":arguments[0],e=this.options.classes;return\"undefined\"!=typeof e\u0026\u0026e[t]?this.options.classes[t]:this.options.classPrefix?this.options.classPrefix+\"-\"+t:t}},{key:\"setOptions\",value:function(t){var e=this,o=void 0===arguments[1]?!0:arguments[1],i={offset:\"0 0\",targetOffset:\"0 0\",targetAttachment:\"auto auto\",classPrefix:\"tether\"};this.options=f(i,t);var r=this.options,s=r.element,a=r.target,h=r.targetModifier;if(this.element=s,this.target=a,this.targetModifier=h,\"viewport\"===this.target?(this.target=document.body,this.targetModifier=\"visible\"):\"scroll-handle\"===this.target\u0026\u0026(this.target=document.body,this.targetModifier=\"scroll-handle\"),[\"element\",\"target\"].forEach(function(t){if(\"undefined\"==typeof e[t])throw new Error(\"Tether Error: Both element and target must be defined\");\"undefined\"!=typeof e[t].jquery?e[t]=e[t][0]:\"string\"==typeof e[t]\u0026\u0026(e[t]=document.querySelector(e[t]))}),l(this.element,this.getClass(\"element\")),this.options.addTargetClasses!==!1\u0026\u0026l(this.target,this.getClass(\"target\")),!this.options.attachment)throw new Error(\"Tether Error: You must provide an attachment\");this.targetAttachment=j(this.options.targetAttachment),this.attachment=j(this.options.attachment),this.offset=X(this.options.offset),this.targetOffset=X(this.options.targetOffset),\"undefined\"!=typeof this.scrollParent\u0026\u0026this.disable(),this.scrollParent=\"scroll-handle\"===this.targetModifier?this.target:n(this.target),this.options.enabled!==!1\u0026\u0026this.enable(o)}},{key:\"getTargetBounds\",value:function(){if(\"undefined\"==typeof this.targetModifier)return r(this.target);if(\"visible\"===this.targetModifier){if(this.target===document.body)return{top:pageYOffset,left:pageXOffset,height:innerHeight,width:innerWidth};var t=r(this.target),e={height:t.height,width:t.width,top:t.top,left:t.left};return e.height=Math.min(e.height,t.height-(pageYOffset-t.top)),e.height=Math.min(e.height,t.height-(t.top+t.height-(pageYOffset+innerHeight))),e.height=Math.min(innerHeight,e.height),e.height-=2,e.width=Math.min(e.width,t.width-(pageXOffset-t.left)),e.width=Math.min(e.width,t.width-(t.left+t.width-(pageXOffset+innerWidth))),e.width=Math.min(innerWidth,e.width),e.width-=2,e.top\u003cpageYOffset\u0026\u0026(e.top=pageYOffset),e.left\u003cpageXOffset\u0026\u0026(e.left=pageXOffset),e}if(\"scroll-handle\"===this.targetModifier){var t=void 0,o=this.target;o===document.body?(o=document.documentElement,t={left:pageXOffset,top:pageYOffset,height:innerHeight,width:innerWidth}):t=r(o);var i=getComputedStyle(o),n=o.scrollWidth\u003eo.clientWidth||[i.overflow,i.overflowX].indexOf(\"scroll\")\u003e=0||this.target!==document.body,s=0;n\u0026\u0026(s=15);var a=t.height-parseFloat(i.borderTopWidth)-parseFloat(i.borderBottomWidth)-s,e={width:15,height:.975*a*(a/o.scrollHeight),left:t.left+t.width-parseFloat(i.borderLeftWidth)-15},f=0;408\u003ea\u0026\u0026this.target===document.body\u0026\u0026(f=-11e-5*Math.pow(a,2)-.00727*a+22.58),this.target!==document.body\u0026\u0026(e.height=Math.max(e.height,24));var h=this.target.scrollTop/(o.scrollHeight-a);return e.top=h*(a-e.height-f)+t.top+parseFloat(i.borderTopWidth),this.target===document.body\u0026\u0026(e.height=Math.max(e.height,24)),e}}},{key:\"clearCache\",value:function(){this._cache={}}},{key:\"cache\",value:function(t,e){return\"undefined\"==typeof this._cache\u0026\u0026(this._cache={}),\"undefined\"==typeof this._cache[t]\u0026\u0026(this._cache[t]=e.call(this)),this._cache[t]}},{key:\"enable\",value:function(){var t=void 0===arguments[0]?!0:arguments[0];this.options.addTargetClasses!==!1\u0026\u0026l(this.target,this.getClass(\"enabled\")),l(this.element,this.getClass(\"enabled\")),this.enabled=!0,this.scrollParent!==document\u0026\u0026this.scrollParent.addEventListener(\"scroll\",this.position),t\u0026\u0026this.position()}},{key:\"disable\",value:function(){h(this.target,this.getClass(\"enabled\")),h(this.element,this.getClass(\"enabled\")),this.enabled=!1,\"undefined\"!=typeof this.scrollParent\u0026\u0026this.scrollParent.removeEventListener(\"scroll\",this.position)}},{key:\"destroy\",value:function(){var t=this;this.disable(),B.forEach(function(e,o){return e===t?void B.splice(o,1):void 0})}},{key:\"updateAttachClasses\",value:function(t,e){var o=this;t=t||this.attachment,e=e||this.targetAttachment;var i=[\"left\",\"top\",\"bottom\",\"right\",\"middle\",\"center\"];\"undefined\"!=typeof this._addAttachClasses\u0026\u0026this._addAttachClasses.length\u0026\u0026this._addAttachClasses.splice(0,this._addAttachClasses.length),\"undefined\"==typeof this._addAttachClasses\u0026\u0026(this._addAttachClasses=[]);var n=this._addAttachClasses;t.top\u0026\u0026n.push(this.getClass(\"element-attached\")+\"-\"+t.top),t.left\u0026\u0026n.push(this.getClass(\"element-attached\")+\"-\"+t.left),e.top\u0026\u0026n.push(this.getClass(\"target-attached\")+\"-\"+e.top),e.left\u0026\u0026n.push(this.getClass(\"target-attached\")+\"-\"+e.left);var r=[];i.forEach(function(t){r.push(o.getClass(\"element-attached\")+\"-\"+t),r.push(o.getClass(\"target-attached\")+\"-\"+t)}),T(function(){\"undefined\"!=typeof o._addAttachClasses\u0026\u0026(c(o.element,o._addAttachClasses,r),o.options.addTargetClasses!==!1\u0026\u0026c(o.target,o._addAttachClasses,r),delete o._addAttachClasses)})}},{key:\"position\",value:function(){var t=this,e=void 0===arguments[0]?!0:arguments[0];if(this.enabled){this.clearCache();var o=Y(this.targetAttachment,this.attachment);this.updateAttachClasses(this.attachment,o);var i=this.cache(\"element-bounds\",function(){return r(t.element)}),n=i.width,f=i.height;if(0===n\u0026\u00260===f\u0026\u0026\"undefined\"!=typeof this.lastSize){var h=this.lastSize;n=h.width,f=h.height}else this.lastSize={width:n,height:f};var l=this.cache(\"target-bounds\",function(){return t.getTargetBounds()}),d=l,u=y(H(this.attachment),{width:n,height:f}),p=y(H(o),d),c=y(this.offset,{width:n,height:f}),g=y(this.targetOffset,d);u=v(u,c),p=v(p,g);for(var m=l.left+p.left-u.left,b=l.top+p.top-u.top,w=0;w\u003cC.modules.length;++w){var O=C.modules[w],E=O.position.call(this,{left:m,top:b,targetAttachment:o,targetPos:l,elementPos:i,offset:u,targetOffset:p,manualOffset:c,manualTargetOffset:g,scrollbarSize:A,attachment:this.attachment});if(E===!1)return!1;\"undefined\"!=typeof E\u0026\u0026\"object\"==typeof E\u0026\u0026(b=E.top,m=E.left)}var x={page:{top:b,left:m},viewport:{top:b-pageYOffset,bottom:pageYOffset-b-f+innerHeight,left:m-pageXOffset,right:pageXOffset-m-n+innerWidth}},A=void 0;return document.body.scrollWidth\u003ewindow.innerWidth\u0026\u0026(A=this.cache(\"scrollbar-size\",a),x.viewport.bottom-=A.height),document.body.scrollHeight\u003ewindow.innerHeight\u0026\u0026(A=this.cache(\"scrollbar-size\",a),x.viewport.right-=A.width),(-1===[\"\",\"static\"].indexOf(document.body.style.position)||-1===[\"\",\"static\"].indexOf(document.body.parentElement.style.position))\u0026\u0026(x.page.bottom=document.body.scrollHeight-b-f,x.page.right=document.body.scrollWidth-m-n),\"undefined\"!=typeof this.options.optimizations\u0026\u0026this.options.optimizations.moveElement!==!1\u0026\u0026\"undefined\"==typeof this.targetModifier\u0026\u0026!function(){var e=t.cache(\"target-offsetparent\",function(){return s(t.target)}),o=t.cache(\"target-offsetparent-bounds\",function(){return r(e)}),i=getComputedStyle(e),n=o,a={};if([\"Top\",\"Left\",\"Bottom\",\"Right\"].forEach(function(t){a[t.toLowerCase()]=parseFloat(i[\"border\"+t+\"Width\"])}),o.right=document.body.scrollWidth-o.left-n.width+a.right,o.bottom=document.body.scrollHeight-o.top-n.height+a.bottom,x.page.top\u003e=o.top+a.top\u0026\u0026x.page.bottom\u003e=o.bottom\u0026\u0026x.page.left\u003e=o.left+a.left\u0026\u0026x.page.right\u003e=o.right){var f=e.scrollTop,h=e.scrollLeft;x.offset={top:x.page.top-o.top+f-a.top,left:x.page.left-o.left+h-a.left}}}(),this.move(x),this.history.unshift(x),this.history.length\u003e3\u0026\u0026this.history.pop(),e\u0026\u0026S(),!0}}},{key:\"move\",value:function(t){var e=this;if(\"undefined\"!=typeof this.element.parentNode){var o={};for(var i in t){o[i]={};for(var n in t[i]){for(var r=!1,a=0;a\u003cthis.history.length;++a){var h=this.history[a];if(\"undefined\"!=typeof h[i]\u0026\u0026!g(h[i][n],t[i][n])){r=!0;break}}r||(o[i][n]=!0)}}var l={top:\"\",left:\"\",right:\"\",bottom:\"\"},d=function(t,o){var i=\"undefined\"!=typeof e.options.optimizations,n=i?e.options.optimizations.gpu:null;if(n!==!1){var r=void 0,s=void 0;t.top?(l.top=0,r=o.top):(l.bottom=0,r=-o.bottom),t.left?(l.left=0,s=o.left):(l.right=0,s=-o.right),l[k]=\"translateX(\"+Math.round(s)+\"px) translateY(\"+Math.round(r)+\"px)\",\"msTransform\"!==k\u0026\u0026(l[k]+=\" translateZ(0)\")}else t.top?l.top=o.top+\"px\":l.bottom=o.bottom+\"px\",t.left?l.left=o.left+\"px\":l.right=o.right+\"px\"},u=!1;(o.page.top||o.page.bottom)\u0026\u0026(o.page.left||o.page.right)?(l.position=\"absolute\",d(o.page,t.page)):(o.viewport.top||o.viewport.bottom)\u0026\u0026(o.viewport.left||o.viewport.right)?(l.position=\"fixed\",d(o.viewport,t.viewport)):\"undefined\"!=typeof o.offset\u0026\u0026o.offset.top\u0026\u0026o.offset.left?!function(){l.position=\"absolute\";var i=e.cache(\"target-offsetparent\",function(){return s(e.target)});s(e.element)!==i\u0026\u0026T(function(){e.element.parentNode.removeChild(e.element),i.appendChild(e.element)}),d(o.offset,t.offset),u=!0}():(l.position=\"absolute\",d({top:!0,left:!0},t.page)),u||\"BODY\"===this.element.parentNode.tagName||(this.element.parentNode.removeChild(this.element),document.body.appendChild(this.element));var p={},c=!1;for(var n in l){var m=l[n],v=this.element.style[n];\"\"!==v\u0026\u0026\"\"!==m\u0026\u0026[\"top\",\"left\",\"bottom\",\"right\"].indexOf(n)\u003e=0\u0026\u0026(v=parseFloat(v),m=parseFloat(m)),v!==m\u0026\u0026(c=!0,p[n]=m)}c\u0026\u0026T(function(){f(e.element.style,p)})}}}]),t}();N.modules=[],C.position=_;var R=f(N,C),M=function(){function t(t,e){var o=[],i=!0,n=!1,r=void 0;try{for(var s,a=t[Symbol.iterator]();!(i=(s=a.next()).done)\u0026\u0026(o.push(s.value),!e||o.length!==e);i=!0);}catch(f){n=!0,r=f}finally{try{!i\u0026\u0026a[\"return\"]\u0026\u0026a[\"return\"]()}finally{if(n)throw r}}return o}return function(e,o){if(Array.isArray(e))return e;if(Symbol.iterator in Object(e))return t(e,o);throw new TypeError(\"Invalid attempt to destructure non-iterable instance\")}}(),P=C.Utils,r=P.getBounds,f=P.extend,c=P.updateClasses,T=P.defer,U=[\"left\",\"top\",\"right\",\"bottom\"];C.modules.push({position:function(t){var e=this,o=t.top,i=t.left,n=t.targetAttachment;if(!this.options.constraints)return!0;var s=this.cache(\"element-bounds\",function(){return r(e.element)}),a=s.height,h=s.width;if(0===h\u0026\u00260===a\u0026\u0026\"undefined\"!=typeof this.lastSize){var l=this.lastSize;h=l.width,a=l.height}var d=this.cache(\"target-bounds\",function(){return e.getTargetBounds()}),u=d.height,p=d.width,g=[this.getClass(\"pinned\"),this.getClass(\"out-of-bounds\")];this.options.constraints.forEach(function(t){var e=t.outOfBoundsClass,o=t.pinnedClass;e\u0026\u0026g.push(e),o\u0026\u0026g.push(o)}),g.forEach(function(t){[\"left\",\"top\",\"right\",\"bottom\"].forEach(function(e){g.push(t+\"-\"+e)})});var m=[],v=f({},n),y=f({},this.attachment);return this.options.constraints.forEach(function(t){var r=t.to,s=t.attachment,f=t.pin;\"undefined\"==typeof s\u0026\u0026(s=\"\");var l=void 0,d=void 0;if(s.indexOf(\" \")\u003e=0){var c=s.split(\" \"),g=M(c,2);d=g[0],l=g[1]}else l=d=s;var w=b(e,r);(\"target\"===d||\"both\"===d)\u0026\u0026(o\u003cw[1]\u0026\u0026\"top\"===v.top\u0026\u0026(o+=u,v.top=\"bottom\"),o+a\u003ew[3]\u0026\u0026\"bottom\"===v.top\u0026\u0026(o-=u,v.top=\"top\")),\"together\"===d\u0026\u0026(o\u003cw[1]\u0026\u0026\"top\"===v.top\u0026\u0026(\"bottom\"===y.top?(o+=u,v.top=\"bottom\",o+=a,y.top=\"top\"):\"top\"===y.top\u0026\u0026(o+=u,v.top=\"bottom\",o-=a,y.top=\"bottom\")),o+a\u003ew[3]\u0026\u0026\"bottom\"===v.top\u0026\u0026(\"top\"===y.top?(o-=u,v.top=\"top\",o-=a,y.top=\"bottom\"):\"bottom\"===y.top\u0026\u0026(o-=u,v.top=\"top\",o+=a,y.top=\"top\")),\"middle\"===v.top\u0026\u0026(o+a\u003ew[3]\u0026\u0026\"top\"===y.top?(o-=a,y.top=\"bottom\"):o\u003cw[1]\u0026\u0026\"bottom\"===y.top\u0026\u0026(o+=a,y.top=\"top\"))),(\"target\"===l||\"both\"===l)\u0026\u0026(i\u003cw[0]\u0026\u0026\"left\"===v.left\u0026\u0026(i+=p,v.left=\"right\"),i+h\u003ew[2]\u0026\u0026\"right\"===v.left\u0026\u0026(i-=p,v.left=\"left\")),\"together\"===l\u0026\u0026(i\u003cw[0]\u0026\u0026\"left\"===v.left?\"right\"===y.left?(i+=p,v.left=\"right\",i+=h,y.left=\"left\"):\"left\"===y.left\u0026\u0026(i+=p,v.left=\"right\",i-=h,y.left=\"right\"):i+h\u003ew[2]\u0026\u0026\"right\"===v.left?\"left\"===y.left?(i-=p,v.left=\"left\",i-=h,y.left=\"right\"):\"right\"===y.left\u0026\u0026(i-=p,v.left=\"left\",i+=h,y.left=\"left\"):\"center\"===v.left\u0026\u0026(i+h\u003ew[2]\u0026\u0026\"left\"===y.left?(i-=h,y.left=\"right\"):i\u003cw[0]\u0026\u0026\"right\"===y.left\u0026\u0026(i+=h,y.left=\"left\"))),(\"element\"===d||\"both\"===d)\u0026\u0026(o\u003cw[1]\u0026\u0026\"bottom\"===y.top\u0026\u0026(o+=a,y.top=\"top\"),o+a\u003ew[3]\u0026\u0026\"top\"===y.top\u0026\u0026(o-=a,y.top=\"bottom\")),(\"element\"===l||\"both\"===l)\u0026\u0026(i\u003cw[0]\u0026\u0026\"right\"===y.left\u0026\u0026(i+=h,y.left=\"left\"),i+h\u003ew[2]\u0026\u0026\"left\"===y.left\u0026\u0026(i-=h,y.left=\"right\")),\"string\"==typeof f?f=f.split(\",\").map(function(t){return t.trim()}):f===!0\u0026\u0026(f=[\"top\",\"left\",\"right\",\"bottom\"]),f=f||[];var C=[],O=[];o\u003cw[1]\u0026\u0026(f.indexOf(\"top\")\u003e=0?(o=w[1],C.push(\"top\")):O.push(\"top\")),o+a\u003ew[3]\u0026\u0026(f.indexOf(\"bottom\")\u003e=0?(o=w[3]-a,C.push(\"bottom\")):O.push(\"bottom\")),i\u003cw[0]\u0026\u0026(f.indexOf(\"left\")\u003e=0?(i=w[0],C.push(\"left\")):O.push(\"left\")),i+h\u003ew[2]\u0026\u0026(f.indexOf(\"right\")\u003e=0?(i=w[2]-h,C.push(\"right\")):O.push(\"right\")),C.length\u0026\u0026!function(){var t=void 0;t=\"undefined\"!=typeof e.options.pinnedClass?e.options.pinnedClass:e.getClass(\"pinned\"),m.push(t),C.forEach(function(e){m.push(t+\"-\"+e)})}(),O.length\u0026\u0026!function(){var t=void 0;t=\"undefined\"!=typeof e.options.outOfBoundsClass?e.options.outOfBoundsClass:e.getClass(\"out-of-bounds\"),m.push(t),O.forEach(function(e){m.push(t+\"-\"+e)})}(),(C.indexOf(\"left\")\u003e=0||C.indexOf(\"right\")\u003e=0)\u0026\u0026(y.left=v.left=!1),(C.indexOf(\"top\")\u003e=0||C.indexOf(\"bottom\")\u003e=0)\u0026\u0026(y.top=v.top=!1),(v.top!==n.top||v.left!==n.left||y.top!==e.attachment.top||y.left!==e.attachment.left)\u0026\u0026e.updateAttachClasses(y,v)}),T(function(){e.options.addTargetClasses!==!1\u0026\u0026c(e.target,m,g),c(e.element,m,g)}),{top:o,left:i}}});var P=C.Utils,r=P.getBounds,c=P.updateClasses,T=P.defer;C.modules.push({position:function(t){var e=this,o=t.top,i=t.left,n=this.cache(\"element-bounds\",function(){return r(e.element)}),s=n.height,a=n.width,f=this.getTargetBounds(),h=o+s,l=i+a,d=[];o\u003c=f.bottom\u0026\u0026h\u003e=f.top\u0026\u0026[\"left\",\"right\"].forEach(function(t){var e=f[t];(e===i||e===l)\u0026\u0026d.push(t)}),i\u003c=f.right\u0026\u0026l\u003e=f.left\u0026\u0026[\"top\",\"bottom\"].forEach(function(t){var e=f[t];(e===o||e===h)\u0026\u0026d.push(t)});var u=[],p=[],g=[\"left\",\"top\",\"right\",\"bottom\"];return u.push(this.getClass(\"abutted\")),g.forEach(function(t){u.push(e.getClass(\"abutted\")+\"-\"+t)}),d.length\u0026\u0026p.push(this.getClass(\"abutted\")),d.forEach(function(t){p.push(e.getClass(\"abutted\")+\"-\"+t)}),T(function(){e.options.addTargetClasses!==!1\u0026\u0026c(e.target,p,u),c(e.element,p,u)}),!0}});var M=function(){function t(t,e){var o=[],i=!0,n=!1,r=void 0;try{for(var s,a=t[Symbol.iterator]();!(i=(s=a.next()).done)\u0026\u0026(o.push(s.value),!e||o.length!==e);i=!0);}catch(f){n=!0,r=f}finally{try{!i\u0026\u0026a[\"return\"]\u0026\u0026a[\"return\"]()}finally{if(n)throw r}}return o}return function(e,o){if(Array.isArray(e))return e;if(Symbol.iterator in Object(e))return t(e,o);throw new TypeError(\"Invalid attempt to destructure non-iterable instance\")}}();return C.modules.push({position:function(t){var e=t.top,o=t.left;if(this.options.shift){var i=this.options.shift;\"function\"==typeof this.options.shift\u0026\u0026(i=this.options.shift.call(this,{top:e,left:o}));var n=void 0,r=void 0;if(\"string\"==typeof i){i=i.split(\" \"),i[1]=i[1]||i[0];var s=M(i,2);n=s[0],r=s[1],n=parseFloat(n,10),r=parseFloat(r,10)}else n=i.top,r=i.left;return e+=n,o+=r,{top:e,left:o}}}}),R});\nH5P.Tether = Tether;\nwindow.Tether = oldTether;\n"
,"js/drop.min.js":"var oldDrop = window.Drop;\nvar oldTether = window.Tether;\nTether = H5P.Tether;\n!function(t,e){\"function\"==typeof define\u0026\u0026define.amd?define([\"tether\"],e):\"object\"==typeof exports?module.exports=e(require(\"tether\")):t.Drop=e(t.Tether)}(this,function(t){\"use strict\";function e(t,e){if(!(t instanceof e))throw new TypeError(\"Cannot call a class as a function\")}function n(t,e){if(\"function\"!=typeof e\u0026\u0026null!==e)throw new TypeError(\"Super expression must either be null or a function, not \"+typeof e);t.prototype=Object.create(e\u0026\u0026e.prototype,{constructor:{value:t,enumerable:!1,writable:!0,configurable:!0}}),e\u0026\u0026(Object.setPrototypeOf?Object.setPrototypeOf(t,e):t.__proto__=e)}function o(t){var e=t.split(\" \"),n=a(e,2),o=n[0],i=n[1];if([\"left\",\"right\"].indexOf(o)\u003e=0){var s=[i,o];o=s[0],i=s[1]}return[o,i].join(\" \")}function i(t,e){for(var n=void 0,o=[];-1!==(n=t.indexOf(e));)o.push(t.splice(n,1));return o}function s(){var a=arguments.length\u003c=0||void 0===arguments[0]?{}:arguments[0],u=function(){for(var t=arguments.length,e=Array(t),n=0;t\u003en;n++)e[n]=arguments[n];return new(r.apply(b,[null].concat(e)))};p(u,{createContext:s,drops:[],defaults:{}});var g={classPrefix:\"drop\",defaults:{position:\"bottom left\",openOn:\"click\",beforeClose:null,constrainToScrollParent:!0,constrainToWindow:!0,classes:\"\",remove:!1,tetherOptions:{}}};p(u,g,a),p(u.defaults,g.defaults,a.defaults),\"undefined\"==typeof x[u.classPrefix]\u0026\u0026(x[u.classPrefix]=[]),u.updateBodyClasses=function(){for(var t=!1,e=x[u.classPrefix],n=e.length,o=0;n\u003eo;++o)if(e[o].isOpened()){t=!0;break}t?d(document.body,u.classPrefix+\"-open\"):c(document.body,u.classPrefix+\"-open\")};var b=function(s){function r(t){if(e(this,r),l(Object.getPrototypeOf(r.prototype),\"constructor\",this).call(this),this.options=p({},u.defaults,t),this.target=this.options.target,\"undefined\"==typeof this.target)throw new Error(\"Drop Error: You must provide a target.\");var n=\"data-\"+u.classPrefix,o=this.target.getAttribute(n);o\u0026\u0026(this.options.content=o);for(var i=[\"position\",\"openOn\"],s=0;s\u003ci.length;++s){var a=this.target.getAttribute(n+\"-\"+i[s]);a\u0026\u0026(this.options[i[s]]=a)}this.options.classes\u0026\u0026this.options.addTargetClasses!==!1\u0026\u0026d(this.target,this.options.classes),u.drops.push(this),x[u.classPrefix].push(this),this._boundEvents=[],this.bindMethods(),this.setupElements(),this.setupEvents(),this.setupTether()}return n(r,s),h(r,[{key:\"_on\",value:function(t,e,n){this._boundEvents.push({element:t,event:e,handler:n}),t.addEventListener(e,n)}},{key:\"bindMethods\",value:function(){this.transitionEndHandler=this._transitionEndHandler.bind(this)}},{key:\"setupElements\",value:function(){var t=this;if(this.drop=document.createElement(\"div\"),d(this.drop,u.classPrefix),this.options.classes\u0026\u0026d(this.drop,this.options.classes),this.content=document.createElement(\"div\"),d(this.content,u.classPrefix+\"-content\"),\"function\"==typeof this.options.content){var e=function(){var e=t.options.content.call(t,t);if(\"string\"==typeof e)t.content.innerHTML=e;else{if(\"object\"!=typeof e)throw new Error(\"Drop Error: Content function should return a string or HTMLElement.\");t.content.innerHTML=\"\",t.content.appendChild(e)}};e(),this.on(\"open\",e.bind(this))}else\"object\"==typeof this.options.content?this.content.appendChild(this.options.content):this.content.innerHTML=this.options.content;this.drop.appendChild(this.content)}},{key:\"setupTether\",value:function(){var e=this.options.position.split(\" \");e[0]=E[e[0]],e=e.join(\" \");var n=[];this.options.constrainToScrollParent?n.push({to:\"scrollParent\",pin:\"top, bottom\",attachment:\"together none\"}):n.push({to:\"scrollParent\"}),this.options.constrainToWindow!==!1?n.push({to:\"window\",attachment:\"together\"}):n.push({to:\"window\"});var i={element:this.drop,target:this.target,attachment:o(e),targetAttachment:o(this.options.position),classPrefix:u.classPrefix,offset:\"0 0\",targetOffset:\"0 0\",enabled:!1,constraints:n,addTargetClasses:this.options.addTargetClasses};this.options.tetherOptions!==!1\u0026\u0026(this.tether=new t(p({},i,this.options.tetherOptions)))}},{key:\"setupEvents\",value:function(){var t=this;if(this.options.openOn){if(\"always\"===this.options.openOn)return void setTimeout(this.open.bind(this));var e=this.options.openOn.split(\" \");if(e.indexOf(\"click\")\u003e=0)for(var n=function(e){t.toggle(e),e.preventDefault()},o=function(e){t.isOpened()\u0026\u0026(e.target===t.drop||t.drop.contains(e.target)||e.target===t.target||t.target.contains(e.target)||t.close(e))},i=0;i\u003cy.length;++i){var s=y[i];this._on(this.target,s,n),this._on(document,s,o)}var r=!1,a=null,h=function(e){r=!0,t.open(e)},l=function(e){r=!1,\"undefined\"!=typeof a\u0026\u0026clearTimeout(a),a=setTimeout(function(){r||t.close(e),a=null},50)};e.indexOf(\"hover\")\u003e=0\u0026\u0026(this._on(this.target,\"mouseover\",h),this._on(this.drop,\"mouseover\",h),this._on(this.target,\"mouseout\",l),this._on(this.drop,\"mouseout\",l)),e.indexOf(\"focus\")\u003e=0\u0026\u0026(this._on(this.target,\"focus\",h),this._on(this.drop,\"focus\",h),this._on(this.target,\"blur\",l),this._on(this.drop,\"blur\",l))}}},{key:\"isOpened\",value:function(){return this.drop?f(this.drop,u.classPrefix+\"-open\"):void 0}},{key:\"toggle\",value:function(t){this.isOpened()?this.close(t):this.open(t)}},{key:\"open\",value:function(t){var e=this;this.isOpened()||(this.drop.parentNode||document.body.appendChild(this.drop),\"undefined\"!=typeof this.tether\u0026\u0026this.tether.enable(),d(this.drop,u.classPrefix+\"-open\"),d(this.drop,u.classPrefix+\"-open-transitionend\"),setTimeout(function(){e.drop\u0026\u0026d(e.drop,u.classPrefix+\"-after-open\")}),\"undefined\"!=typeof this.tether\u0026\u0026this.tether.position(),this.trigger(\"open\"),u.updateBodyClasses())}},{key:\"_transitionEndHandler\",value:function(t){t.target===t.currentTarget\u0026\u0026(f(this.drop,u.classPrefix+\"-open\")||c(this.drop,u.classPrefix+\"-open-transitionend\"),this.drop.removeEventListener(m,this.transitionEndHandler))}},{key:\"beforeCloseHandler\",value:function(t){var e=!0;return this.isClosing||\"function\"!=typeof this.options.beforeClose||(this.isClosing=!0,e=this.options.beforeClose(t,this)!==!1),this.isClosing=!1,e}},{key:\"close\",value:function(t){this.isOpened()\u0026\u0026this.beforeCloseHandler(t)\u0026\u0026(c(this.drop,u.classPrefix+\"-open\"),c(this.drop,u.classPrefix+\"-after-open\"),this.drop.addEventListener(m,this.transitionEndHandler),this.trigger(\"close\"),\"undefined\"!=typeof this.tether\u0026\u0026this.tether.disable(),u.updateBodyClasses(),this.options.remove\u0026\u0026this.remove(t))}},{key:\"remove\",value:function(t){this.close(t),this.drop.parentNode\u0026\u0026this.drop.parentNode.removeChild(this.drop)}},{key:\"position\",value:function(){this.isOpened()\u0026\u0026\"undefined\"!=typeof this.tether\u0026\u0026this.tether.position()}},{key:\"destroy\",value:function(){this.remove(),\"undefined\"!=typeof this.tether\u0026\u0026this.tether.destroy();for(var t=0;t\u003cthis._boundEvents.length;++t){var e=this._boundEvents[t],n=e.element,o=e.event,s=e.handler;n.removeEventListener(o,s)}this._boundEvents=[],this.tether=null,this.drop=null,this.content=null,this.target=null,i(x[u.classPrefix],this),i(u.drops,this)}}]),r}(v);return u}var r=Function.prototype.bind,a=function(){function t(t,e){var n=[],o=!0,i=!1,s=void 0;try{for(var r,a=t[Symbol.iterator]();!(o=(r=a.next()).done)\u0026\u0026(n.push(r.value),!e||n.length!==e);o=!0);}catch(h){i=!0,s=h}finally{try{!o\u0026\u0026a[\"return\"]\u0026\u0026a[\"return\"]()}finally{if(i)throw s}}return n}return function(e,n){if(Array.isArray(e))return e;if(Symbol.iterator in Object(e))return t(e,n);throw new TypeError(\"Invalid attempt to destructure non-iterable instance\")}}(),h=function(){function t(t,e){for(var n=0;n\u003ce.length;n++){var o=e[n];o.enumerable=o.enumerable||!1,o.configurable=!0,\"value\"in o\u0026\u0026(o.writable=!0),Object.defineProperty(t,o.key,o)}}return function(e,n,o){return n\u0026\u0026t(e.prototype,n),o\u0026\u0026t(e,o),e}}(),l=function(t,e,n){for(var o=!0;o;){var i=t,s=e,r=n;a=l=h=void 0,o=!1,null===i\u0026\u0026(i=Function.prototype);var a=Object.getOwnPropertyDescriptor(i,s);if(void 0!==a){if(\"value\"in a)return a.value;var h=a.get;return void 0===h?void 0:h.call(r)}var l=Object.getPrototypeOf(i);if(null===l)return void 0;t=l,e=s,n=r,o=!0}},u=t.Utils,p=u.extend,d=u.addClass,c=u.removeClass,f=u.hasClass,v=u.Evented,y=[\"click\"];\"ontouchstart\"in document.documentElement\u0026\u0026y.push(\"touchstart\");var g={WebkitTransition:\"webkitTransitionEnd\",MozTransition:\"transitionend\",OTransition:\"otransitionend\",transition:\"transitionend\"},m=\"\";for(var b in g)if({}.hasOwnProperty.call(g,b)){var O=document.createElement(\"p\");\"undefined\"!=typeof O.style[b]\u0026\u0026(m=g[b])}var E={left:\"right\",right:\"left\",top:\"bottom\",bottom:\"top\",middle:\"middle\",center:\"center\"},x={},P=s();return document.addEventListener(\"DOMContentLoaded\",function(){P.updateBodyClasses()}),P});\nH5P.Drop = Drop;\nwindow.Drop = oldDrop;\nwindow.Tether = oldTether;\n"
,"js/joubel-help-dialog.js":"var H5P = H5P || {};\n\n/**\n * Class responsible for creating a help text dialog\n */\nH5P.JoubelHelpTextDialog = (function ($) {\n\n var numInstances = 0;\n /**\n * Display a pop-up containing a message.\n *\n * @param {H5P.jQuery} $container The container which message dialog will be appended to\n * @param {string} message The message\n * @param {string} closeButtonTitle The title for the close button\n * @return {H5P.jQuery}\n */\n function JoubelHelpTextDialog(header, message, closeButtonTitle) {\n H5P.EventDispatcher.call(this);\n\n var self = this;\n\n numInstances++;\n var headerId = \u0027joubel-help-text-header-\u0027 + numInstances;\n var helpTextId = \u0027joubel-help-text-body-\u0027 + numInstances;\n\n var $helpTextDialogBox = $(\u0027\u003cdiv\u003e\u0027, {\n \u0027class\u0027: \u0027joubel-help-text-dialog-box\u0027,\n \u0027role\u0027: \u0027dialog\u0027,\n \u0027aria-labelledby\u0027: headerId,\n \u0027aria-describedby\u0027: helpTextId\n });\n\n $(\u0027\u003cdiv\u003e\u0027, {\n \u0027class\u0027: \u0027joubel-help-text-dialog-background\u0027\n }).appendTo($helpTextDialogBox);\n\n var $helpTextDialogContainer = $(\u0027\u003cdiv\u003e\u0027, {\n \u0027class\u0027: \u0027joubel-help-text-dialog-container\u0027\n }).appendTo($helpTextDialogBox);\n\n $(\u0027\u003cdiv\u003e\u0027, {\n \u0027class\u0027: \u0027joubel-help-text-header\u0027,\n \u0027id\u0027: headerId,\n \u0027role\u0027: \u0027header\u0027,\n \u0027html\u0027: header\n }).appendTo($helpTextDialogContainer);\n\n $(\u0027\u003cdiv\u003e\u0027, {\n \u0027class\u0027: \u0027joubel-help-text-body\u0027,\n \u0027id\u0027: helpTextId,\n \u0027html\u0027: message,\n \u0027role\u0027: \u0027document\u0027,\n \u0027tabindex\u0027: 0\n }).appendTo($helpTextDialogContainer);\n\n var handleClose = function () {\n $helpTextDialogBox.remove();\n self.trigger(\u0027closed\u0027);\n };\n\n var $closeButton = $(\u0027\u003cdiv\u003e\u0027, {\n \u0027class\u0027: \u0027joubel-help-text-remove\u0027,\n \u0027role\u0027: \u0027button\u0027,\n \u0027title\u0027: closeButtonTitle,\n \u0027tabindex\u0027: 1,\n \u0027click\u0027: handleClose,\n \u0027keydown\u0027: function (event) {\n // 32 - space, 13 - enter\n if ([32, 13].indexOf(event.which) !== -1) {\n event.preventDefault();\n handleClose();\n }\n }\n }).appendTo($helpTextDialogContainer);\n\n /**\n * Get the DOM element\n * @return {HTMLElement}\n */\n self.getElement = function () {\n return $helpTextDialogBox;\n };\n\n self.focus = function () {\n $closeButton.focus();\n };\n }\n\n JoubelHelpTextDialog.prototype = Object.create(H5P.EventDispatcher.prototype);\n JoubelHelpTextDialog.prototype.constructor = JoubelHelpTextDialog;\n\n return JoubelHelpTextDialog;\n}(H5P.jQuery));\n"
,"js/joubel-message-dialog.js":"var H5P = H5P || {};\n\n/**\n * Class responsible for creating auto-disappearing dialogs\n */\nH5P.JoubelMessageDialog = (function ($) {\n\n /**\n * Display a pop-up containing a message.\n *\n * @param {H5P.jQuery} $container The container which message dialog will be appended to\n * @param {string} message The message\n * @return {H5P.jQuery}\n */\n function JoubelMessageDialog ($container, message) {\n var timeout;\n\n var removeDialog = function () {\n $warning.remove();\n clearTimeout(timeout);\n $container.off(\u0027click.messageDialog\u0027);\n };\n\n // Create warning popup:\n var $warning = $(\u0027\u003cdiv/\u003e\u0027, {\n \u0027class\u0027: \u0027joubel-message-dialog\u0027,\n text: message\n }).appendTo($container);\n\n // Remove after 3 seconds or if user clicks anywhere in $container:\n timeout = setTimeout(removeDialog, 3000);\n $container.on(\u0027click.messageDialog\u0027, removeDialog);\n\n return $warning;\n }\n\n return JoubelMessageDialog;\n})(H5P.jQuery);\n"
,"js/joubel-progress-circle.js":"var H5P = H5P || {};\n\n/**\n * Class responsible for creating a circular progress bar\n */\n\nH5P.JoubelProgressCircle = (function ($) {\n\n /**\n * Constructor for the Progress Circle\n *\n * @param {Number} number The amount of progress to display\n * @param {string} progressColor Color for the progress meter\n * @param {string} backgroundColor Color behind the progress meter\n */\n function ProgressCircle(number, progressColor, fillColor, backgroundColor) {\n progressColor = progressColor || \u0027#1a73d9\u0027;\n fillColor = fillColor || \u0027#f0f0f0\u0027;\n backgroundColor = backgroundColor || \u0027#ffffff\u0027;\n var progressColorRGB = this.hexToRgb(progressColor);\n\n //Verify number\n try {\n number = Number(number);\n if (number === \u0027\u0027) {\n throw \u0027is empty\u0027;\n }\n if (isNaN(number)) {\n throw \u0027is not a number\u0027;\n }\n } catch (e) {\n number = \u0027err\u0027;\n }\n\n //Draw circle\n if (number \u003e 100) {\n number = 100;\n }\n\n // We can not use rgba, since they will stack on top of each other.\n // Instead we create the equivalent of the rgba color\n // and applies this to the activeborder and background color.\n var progressColorString = \u0027rgb(\u0027 + parseInt(progressColorRGB.r, 10) +\n \u0027,\u0027 + parseInt(progressColorRGB.g, 10) +\n \u0027,\u0027 + parseInt(progressColorRGB.b, 10) + \u0027)\u0027;\n\n // Circle wrapper\n var $wrapper = $(\u0027\u003cdiv/\u003e\u0027, {\n \u0027class\u0027: \"joubel-progress-circle-wrapper\"\n });\n\n //Active border indicates progress\n var $activeBorder = $(\u0027\u003cdiv/\u003e\u0027, {\n \u0027class\u0027: \"joubel-progress-circle-active-border\"\n }).appendTo($wrapper);\n\n //Background circle\n var $backgroundCircle = $(\u0027\u003cdiv/\u003e\u0027, {\n \u0027class\u0027: \"joubel-progress-circle-circle\"\n }).appendTo($activeBorder);\n\n //Progress text/number\n $(\u0027\u003cspan/\u003e\u0027, {\n \u0027text\u0027: number + \u0027%\u0027,\n \u0027class\u0027: \"joubel-progress-circle-percentage\"\n }).appendTo($backgroundCircle);\n\n var deg = number * 3.6;\n if (deg \u003c= 180) {\n $activeBorder.css(\u0027background-image\u0027,\n \u0027linear-gradient(\u0027 + (90 + deg) + \u0027deg, transparent 50%, \u0027 + fillColor + \u0027 50%),\u0027 +\n \u0027linear-gradient(90deg, \u0027 + fillColor + \u0027 50%, transparent 50%)\u0027)\n .css(\u0027border\u0027, \u00272px solid\u0027 + backgroundColor)\n .css(\u0027background-color\u0027, progressColorString);\n } else {\n $activeBorder.css(\u0027background-image\u0027,\n \u0027linear-gradient(\u0027 + (deg - 90) + \u0027deg, transparent 50%, \u0027 + progressColorString + \u0027 50%),\u0027 +\n \u0027linear-gradient(90deg, \u0027 + fillColor + \u0027 50%, transparent 50%)\u0027)\n .css(\u0027border\u0027, \u00272px solid\u0027 + backgroundColor)\n .css(\u0027background-color\u0027, progressColorString);\n }\n\n this.$activeBorder = $activeBorder;\n this.$backgroundCircle = $backgroundCircle;\n this.$wrapper = $wrapper;\n\n this.initResizeFunctionality();\n\n return $wrapper;\n }\n\n /**\n * Initializes resize functionality for the progress circle\n */\n ProgressCircle.prototype.initResizeFunctionality = function () {\n var self = this;\n\n $(window).resize(function () {\n // Queue resize\n setTimeout(function () {\n self.resize();\n });\n });\n\n // First resize\n setTimeout(function () {\n self.resize();\n }, 0);\n };\n\n /**\n * Resize function makes progress circle grow or shrink relative to parent container\n */\n ProgressCircle.prototype.resize = function () {\n var $parent = this.$wrapper.parent();\n\n if ($parent !== undefined \u0026\u0026 $parent) {\n\n // Measurements\n var fontSize = parseInt($parent.css(\u0027font-size\u0027), 10);\n\n // Static sizes\n var fontSizeMultiplum = 3.75;\n var progressCircleWidthPx = parseInt((fontSize / 4.5), 10) % 2 === 0 ? parseInt((fontSize / 4.5), 10) + 4 : parseInt((fontSize / 4.5), 10) + 5;\n var progressCircleOffset = progressCircleWidthPx / 2;\n\n var width = fontSize * fontSizeMultiplum;\n var height = fontSize * fontSizeMultiplum;\n this.$activeBorder.css({\n \u0027width\u0027: width,\n \u0027height\u0027: height\n });\n\n this.$backgroundCircle.css({\n \u0027width\u0027: width - progressCircleWidthPx,\n \u0027height\u0027: height - progressCircleWidthPx,\n \u0027top\u0027: progressCircleOffset,\n \u0027left\u0027: progressCircleOffset\n });\n }\n };\n\n /**\n * Hex to RGB conversion\n * @param hex\n * @returns {{r: Number, g: Number, b: Number}}\n */\n ProgressCircle.prototype.hexToRgb = function (hex) {\n var result = /^#?([a-f\\d]{2})([a-f\\d]{2})([a-f\\d]{2})$/i.exec(hex);\n return result ? {\n r: parseInt(result[1], 16),\n g: parseInt(result[2], 16),\n b: parseInt(result[3], 16)\n } : null;\n };\n\n return ProgressCircle;\n\n}(H5P.jQuery));\n"
,"js/joubel-simple-rounded-button.js":"var H5P = H5P || {};\n\nH5P.SimpleRoundedButton = (function ($) {\n\n /**\n * Creates a new tip\n */\n function SimpleRoundedButton(text) {\n\n var $simpleRoundedButton = $(\u0027\u003cdiv\u003e\u0027, {\n \u0027class\u0027: \u0027joubel-simple-rounded-button\u0027,\n \u0027title\u0027: text,\n \u0027role\u0027: \u0027button\u0027,\n \u0027tabindex\u0027: \u00270\u0027\n }).keydown(function (e) {\n // 32 - space, 13 - enter\n if ([32, 13].indexOf(e.which) !== -1) {\n $(this).click();\n e.preventDefault();\n }\n });\n\n $(\u0027\u003cspan\u003e\u0027, {\n \u0027class\u0027: \u0027joubel-simple-rounded-button-text\u0027,\n \u0027html\u0027: text\n }).appendTo($simpleRoundedButton);\n\n return $simpleRoundedButton;\n }\n\n return SimpleRoundedButton;\n}(H5P.jQuery));\n"
,"js/joubel-speech-bubble.js":"var H5P = H5P || {};\n\n/**\n * Class responsible for creating speech bubbles\n */\nH5P.JoubelSpeechBubble = (function ($) {\n\n var $currentSpeechBubble;\n var $currentContainer;\n var removeSpeechBubbleTimeout;\n\n var DEFAULT_MAX_WIDTH = 400;\n\n var iDevice = navigator.userAgent.match(/iPod|iPhone|iPad/g) ? true : false;\n\n /**\n * Creates a new speech bubble\n *\n * @param {H5P.jQuery} $container The speaking object\n * @param {string} text The text to display\n * @param {number} maxWidth The maximum width of the bubble\n * @return {H5P.JoubelSpeechBubble}\n */\n function JoubelSpeechBubble($container, text, maxWidth) {\n maxWidth = maxWidth || DEFAULT_MAX_WIDTH;\n $currentContainer = $container;\n\n this.isCurrent = function ($tip) {\n return $tip.is($currentContainer);\n };\n\n this.remove = function () {\n remove();\n };\n\n var fadeOutSpeechBubble = function ($speechBubble) {\n if (!$speechBubble) {\n return;\n }\n\n // Stop removing bubble\n clearTimeout(removeSpeechBubbleTimeout);\n\n $speechBubble.removeClass(\u0027show\u0027);\n setTimeout(function () {\n if ($speechBubble) {\n $speechBubble.remove();\n $speechBubble = undefined;\n }\n }, 500);\n };\n\n if ($currentSpeechBubble !== undefined) {\n remove();\n }\n\n var $h5pContainer = $container.closest(\u0027.h5p-frame\u0027);\n\n // Check closest h5p frame first, then check for container in case there is no frame.\n if (!$h5pContainer.length) {\n $h5pContainer = $container.closest(\u0027.h5p-container\u0027);\n }\n\n // Make sure we fade out old speech bubble\n fadeOutSpeechBubble($currentSpeechBubble);\n\n // Create bubble\n var $tail = $(\u0027\u003cdiv class=\"joubel-speech-bubble-tail\"\u003e\u003c/div\u003e\u0027);\n var $innerTail = $(\u0027\u003cdiv class=\"joubel-speech-bubble-inner-tail\"\u003e\u003c/div\u003e\u0027);\n var $innerBubble = $(\n \u0027\u003cdiv class=\"joubel-speech-bubble-inner\"\u003e\u0027 +\n \u0027\u003cdiv class=\"joubel-speech-bubble-text\"\u003e\u0027 + text + \u0027\u003c/div\u003e\u0027 +\n \u0027\u003c/div\u003e\u0027\n ).prepend($innerTail);\n\n $currentSpeechBubble = $(\n \u0027\u003cdiv class=\"joubel-speech-bubble\" aria-live=\"assertive\"\u003e\u0027\n ).append([$tail, $innerBubble])\n .appendTo($h5pContainer);\n\n // Show speech bubble with transition\n setTimeout(function () {\n $currentSpeechBubble.addClass(\u0027show\u0027);\n }, 0);\n\n // Calculate offset between the button and the h5p frame\n var offset = getOffsetBetween($h5pContainer, $container);\n\n var direction = (offset.bottom \u003e offset.top ? \u0027bottom\u0027 : \u0027top\u0027);\n var tipWidth = offset.outerWidth * 0.9; // Var needs to be renamed to make sense\n var bubbleWidth = tipWidth \u003e maxWidth ? maxWidth : tipWidth;\n\n var bubblePosition = getBubblePosition(bubbleWidth, offset);\n var tailPosition = getTailPosition(bubbleWidth, bubblePosition, offset, $container.width());\n // Need to set font-size, since element is appended to body.\n // Using same font-size as parent. In that way it will grow accordingly\n // when resizing\n var fontSize = 16;//parseFloat($parent.css(\u0027font-size\u0027));\n\n // Set width and position of speech bubble\n $currentSpeechBubble.css(bubbleCSS(\n direction,\n bubbleWidth,\n bubblePosition,\n fontSize\n ));\n\n var preparedTailCSS = tailCSS(direction, tailPosition);\n $tail.css(preparedTailCSS);\n $innerTail.css(preparedTailCSS);\n\n // Handle click to close\n H5P.$body.on(\u0027mousedown.speechBubble\u0027, handleOutsideClick);\n\n // Handle clicks when inside IV which blocks bubbling.\n $container.parents(\u0027.h5p-dialog\u0027)\n .on(\u0027mousedown.speechBubble\u0027, handleOutsideClick);\n\n if (iDevice) {\n H5P.$body.css(\u0027cursor\u0027, \u0027pointer\u0027);\n }\n\n return this;\n }\n\n // Remove speechbubble if it belongs to a dom element that is about to be hidden\n H5P.externalDispatcher.on(\u0027domHidden\u0027, function (event) {\n if ($currentSpeechBubble !== undefined \u0026\u0026 event.data.$dom.find($currentContainer).length !== 0) {\n remove();\n }\n });\n\n /**\n * Static function for removing the speechbubble\n */\n var remove = function() {\n H5P.$body.off(\u0027mousedown.speechBubble\u0027);\n $currentContainer.parents(\u0027.h5p-dialog\u0027).off(\u0027mousedown.speechBubble\u0027);\n if (iDevice) {\n H5P.$body.css(\u0027cursor\u0027, \u0027\u0027);\n }\n if ($currentSpeechBubble !== undefined) {\n // Apply transition, then remove speech bubble\n $currentSpeechBubble.removeClass(\u0027show\u0027);\n\n // Make sure we remove any old timeout before reassignment\n clearTimeout(removeSpeechBubbleTimeout);\n removeSpeechBubbleTimeout = setTimeout(function () {\n $currentSpeechBubble.remove();\n $currentSpeechBubble = undefined;\n }, 500);\n }\n // Don\u0027t return false here. If the user e.g. clicks a button when the bubble is visible,\n // we want the bubble to disapear AND the button to receive the event\n };\n \n /**\n * Remove the speech bubble and container reference\n */\n function handleOutsideClick(event) {\n if (event.target === $currentContainer[0]) {\n return; // Button clicks are not outside clicks\n }\n\n remove();\n // There is no current container when a container isn\u0027t clicked\n $currentContainer = undefined;\n }\n\n /**\n * Calculate position for speech bubble\n *\n * @param {number} bubbleWidth The width of the speech bubble\n * @param {object} offset\n * @return {object} Return position for the speech bubble\n */\n function getBubblePosition(bubbleWidth, offset) {\n var bubblePosition = {};\n\n var tailOffset = 9;\n var widthOffset = bubbleWidth / 2;\n\n // Calculate top position\n bubblePosition.top = offset.top + offset.innerHeight;\n\n // Calculate bottom position\n bubblePosition.bottom = offset.bottom + offset.innerHeight + tailOffset;\n\n // Calculate left position\n if (offset.left \u003c widthOffset) {\n bubblePosition.left = 3;\n }\n else if ((offset.left + widthOffset) \u003e offset.outerWidth) {\n bubblePosition.left = offset.outerWidth - bubbleWidth - 3;\n }\n else {\n bubblePosition.left = offset.left - widthOffset + (offset.innerWidth / 2);\n }\n\n return bubblePosition;\n }\n\n /**\n * Calculate position for speech bubble tail\n *\n * @param {number} bubbleWidth The width of the speech bubble\n * @param {object} bubblePosition Speech bubble position\n * @param {object} offset\n * @param {number} iconWidth The width of the tip icon\n * @return {object} Return position for the tail\n */\n function getTailPosition(bubbleWidth, bubblePosition, offset, iconWidth) {\n var tailPosition = {};\n // Magic numbers. Tuned by hand so that the tail fits visually within\n // the bounds of the speech bubble.\n var leftBoundary = 9;\n var rightBoundary = bubbleWidth - 20;\n\n tailPosition.left = offset.left - bubblePosition.left + (iconWidth / 2) - 6;\n if (tailPosition.left \u003c leftBoundary) {\n tailPosition.left = leftBoundary;\n }\n if (tailPosition.left \u003e rightBoundary) {\n tailPosition.left = rightBoundary;\n }\n\n tailPosition.top = -6;\n tailPosition.bottom = -6;\n\n return tailPosition;\n }\n\n /**\n * Return bubble CSS for the desired growth direction\n *\n * @param {string} direction The direction the speech bubble will grow\n * @param {number} width The width of the speech bubble\n * @param {object} position Speech bubble position\n * @param {number} fontSize The size of the bubbles font\n * @return {object} Return CSS\n */\n function bubbleCSS(direction, width, position, fontSize) {\n if (direction === \u0027top\u0027) {\n return {\n width: width + \u0027px\u0027,\n bottom: position.bottom + \u0027px\u0027,\n left: position.left + \u0027px\u0027,\n fontSize: fontSize + \u0027px\u0027\n };\n }\n else {\n return {\n width: width + \u0027px\u0027,\n top: position.top + \u0027px\u0027,\n left: position.left + \u0027px\u0027,\n fontSize: fontSize + \u0027px\u0027\n };\n }\n }\n\n /**\n * Return tail CSS for the desired growth direction\n *\n * @param {string} direction The direction the speech bubble will grow\n * @param {object} position Tail position\n * @return {object} Return CSS\n */\n function tailCSS(direction, position) {\n if (direction === \u0027top\u0027) {\n return {\n bottom: position.bottom + \u0027px\u0027,\n left: position.left + \u0027px\u0027\n };\n }\n else {\n return {\n top: position.top + \u0027px\u0027,\n left: position.left + \u0027px\u0027\n };\n }\n }\n\n /**\n * Calculates the offset between an element inside a container and the\n * container. Only works if all the edges of the inner element is inside the\n * outer element.\n * Width/height of the elements is included as a convenience.\n *\n * @param {H5P.jQuery} $outer\n * @param {H5P.jQuery} $inner\n * @return {object} Position offset\n */\n function getOffsetBetween($outer, $inner) {\n var outer = $outer[0].getBoundingClientRect();\n var inner = $inner[0].getBoundingClientRect();\n\n return {\n top: inner.top - outer.top,\n right: outer.right - inner.right,\n bottom: outer.bottom - inner.bottom,\n left: inner.left - outer.left,\n innerWidth: inner.width,\n innerHeight: inner.height,\n outerWidth: outer.width,\n outerHeight: outer.height\n };\n }\n\n return JoubelSpeechBubble;\n})(H5P.jQuery);\n"
,"js/joubel-throbber.js":"var H5P = H5P || {};\n\nH5P.JoubelThrobber = (function ($) {\n\n /**\n * Creates a new tip\n */\n function JoubelThrobber() {\n\n // h5p-throbber css is described in core\n var $throbber = $(\u0027\u003cdiv/\u003e\u0027, {\n \u0027class\u0027: \u0027h5p-throbber\u0027\n });\n\n return $throbber;\n }\n\n return JoubelThrobber;\n}(H5P.jQuery));\n"
,"js/joubel-tip.js":"H5P.JoubelTip = (function ($) {\n var $conv = $(\u0027\u003cdiv/\u003e\u0027);\n\n /**\n * Creates a new tip element.\n *\n * NOTE that this may look like a class but it doesn\u0027t behave like one.\n * It returns a jQuery object.\n *\n * @param {string} tipHtml The text to display in the popup\n * @param {Object} [behaviour] Options\n * @param {string} [behaviour.tipLabel] Set to use a custom label for the tip button (you want this for good A11Y)\n * @param {boolean} [behaviour.helpIcon] Set to \u0027true\u0027 to Add help-icon classname to Tip button (changes the icon)\n * @param {boolean} [behaviour.showSpeechBubble] Set to \u0027false\u0027 to disable functionality (you may this in the editor)\n * @param {boolean} [behaviour.tabcontrol] Set to \u0027true\u0027 if you plan on controlling the tabindex in the parent (tabindex=\"-1\")\n * @return {H5P.jQuery|undefined} Tip button jQuery element or \u0027undefined\u0027 if invalid tip\n */\n function JoubelTip(tipHtml, behaviour) {\n\n // Keep track of the popup that appears when you click the Tip button\n var speechBubble;\n\n // Parse tip html to determine text\n var tipText = $conv.html(tipHtml).text().trim();\n if (tipText === \u0027\u0027) {\n return; // The tip has no textual content, i.e. it\u0027s invalid.\n }\n\n // Set default behaviour\n behaviour = $.extend({\n tipLabel: tipText,\n helpIcon: false,\n showSpeechBubble: true,\n tabcontrol: false\n }, behaviour);\n\n // Create Tip button\n var $tipButton = $(\u0027\u003cdiv/\u003e\u0027, {\n class: \u0027joubel-tip-container\u0027 + (behaviour.showSpeechBubble ? \u0027\u0027 : \u0027 be-quiet\u0027),\n title: behaviour.tipLabel,\n \u0027aria-label\u0027: behaviour.tipLabel,\n \u0027aria-expanded\u0027: false,\n role: \u0027button\u0027,\n tabindex: (behaviour.tabcontrol ? -1 : 0),\n click: function (event) {\n // Toggle show/hide popup\n toggleSpeechBubble();\n event.preventDefault();\n },\n keydown: function (event) {\n if (event.which === 32 || event.which === 13) { // Space \u0026 enter key\n // Toggle show/hide popup\n toggleSpeechBubble();\n event.stopPropagation();\n event.preventDefault();\n }\n else { // Any other key\n // Toggle hide popup\n toggleSpeechBubble(false);\n }\n },\n // Add markup to render icon\n html: \u0027\u003cspan class=\"joubel-icon-tip-normal \u0027 + (behaviour.helpIcon ? \u0027 help-icon\u0027: \u0027\u0027) + \u0027\"\u003e\u0027 +\n \u0027\u003cspan class=\"h5p-icon-shadow\"\u003e\u003c/span\u003e\u0027 +\n \u0027\u003cspan class=\"h5p-icon-speech-bubble\"\u003e\u003c/span\u003e\u0027 +\n \u0027\u003cspan class=\"h5p-icon-info\"\u003e\u003c/span\u003e\u0027 +\n \u0027\u003c/span\u003e\u0027\n // IMPORTANT: All of the markup elements must have \u0027pointer-events: none;\u0027\n });\n\n /**\n * Tip button interaction handler.\n * Toggle show or hide the speech bubble popup when interacting with the\n * Tip button.\n *\n * @private\n * @param {boolean} [force] \u0027true\u0027 shows and \u0027false\u0027 hides.\n */\n var toggleSpeechBubble = function (force) {\n if (speechBubble !== undefined \u0026\u0026 speechBubble.isCurrent($tipButton)) {\n // Hide current popup\n speechBubble.remove();\n speechBubble = undefined;\n\n $tipButton.attr(\u0027aria-expanded\u0027, false);\n }\n else if (force !== false \u0026\u0026 behaviour.showSpeechBubble) {\n // Create and show new popup\n speechBubble = H5P.JoubelSpeechBubble($tipButton, tipHtml);\n $tipButton.attr(\u0027aria-expanded\u0027, true);\n }\n };\n\n return $tipButton;\n }\n\n return JoubelTip;\n})(H5P.jQuery);\n"
,"js/joubel-slider.js":"var H5P = H5P || {};\n\nH5P.JoubelSlider = (function ($) {\n\n /**\n * Creates a new Slider\n *\n * @param {object} [params] Additional parameters\n */\n function JoubelSlider(params) {\n H5P.EventDispatcher.call(this);\n\n this.$slider = $(\u0027\u003cdiv\u003e\u0027, $.extend({\n \u0027class\u0027: \u0027h5p-joubel-ui-slider\u0027\n }, params));\n\n this.$slides = [];\n this.currentIndex = 0;\n this.numSlides = 0;\n }\n JoubelSlider.prototype = Object.create(H5P.EventDispatcher.prototype);\n JoubelSlider.prototype.constructor = JoubelSlider;\n\n JoubelSlider.prototype.addSlide = function ($content) {\n $content.addClass(\u0027h5p-joubel-ui-slide\u0027).css({\n \u0027left\u0027: (this.numSlides*100) + \u0027%\u0027\n });\n this.$slider.append($content);\n this.$slides.push($content);\n\n this.numSlides++;\n\n if(this.numSlides === 1) {\n $content.addClass(\u0027current\u0027);\n }\n };\n\n JoubelSlider.prototype.attach = function ($container) {\n $container.append(this.$slider);\n };\n\n JoubelSlider.prototype.move = function (index) {\n var self = this;\n\n if(index === 0) {\n self.trigger(\u0027first-slide\u0027);\n }\n if(index+1 === self.numSlides) {\n self.trigger(\u0027last-slide\u0027);\n }\n self.trigger(\u0027move\u0027);\n\n var $previousSlide = self.$slides[this.currentIndex];\n H5P.Transition.onTransitionEnd(this.$slider, function () {\n $previousSlide.removeClass(\u0027current\u0027);\n self.trigger(\u0027moved\u0027);\n });\n this.$slides[index].addClass(\u0027current\u0027);\n\n var translateX = \u0027translateX(\u0027 + (-index*100) + \u0027%)\u0027;\n this.$slider.css({\n \u0027-webkit-transform\u0027: translateX,\n \u0027-moz-transform\u0027: translateX,\n \u0027-ms-transform\u0027: translateX,\n \u0027transform\u0027: translateX\n });\n\n this.currentIndex = index;\n };\n\n JoubelSlider.prototype.remove = function () {\n this.$slider.remove();\n };\n\n JoubelSlider.prototype.next = function () {\n if(this.currentIndex+1 \u003e= this.numSlides) {\n return;\n }\n\n this.move(this.currentIndex+1);\n };\n\n JoubelSlider.prototype.previous = function () {\n this.move(this.currentIndex-1);\n };\n\n JoubelSlider.prototype.first = function () {\n this.move(0);\n };\n\n JoubelSlider.prototype.last = function () {\n this.move(this.numSlides-1);\n };\n\n return JoubelSlider;\n})(H5P.jQuery);\n"
,"js/joubel-score-bar.js":"var H5P = H5P || {};\n\n/**\n * @module\n */\nH5P.JoubelScoreBar = (function ($) {\n\n /* Need to use an id for the star SVG since that is the only way to reference\n SVG filters */\n var idCounter = 0;\n\n /**\n * Creates a score bar\n * @class H5P.JoubelScoreBar\n * @param {number} maxScore Maximum score\n * @param {string} [label] Makes it easier for readspeakers to identify the scorebar\n * @param {string} [helpText] Score explanation\n * @param {string} [scoreExplanationButtonLabel] Label for score explanation button\n */\n function JoubelScoreBar(maxScore, label, helpText, scoreExplanationButtonLabel) {\n var self = this;\n\n self.maxScore = maxScore;\n self.score = 0;\n idCounter++;\n\n /**\n * @const {string}\n */\n self.STAR_MARKUP = \u0027\u003csvg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 63.77 53.87\" aria-hidden=\"true\" focusable=\"false\"\u003e\u0027 +\n \u0027\u003ctitle\u003estar\u003c/title\u003e\u0027 +\n \u0027\u003cfilter id=\"h5p-joubelui-score-bar-star-inner-shadow-\u0027 + idCounter + \u0027\" x0=\"-50%\" y0=\"-50%\" width=\"200%\" height=\"200%\"\u003e\u0027 +\n \u0027\u003cfeGaussianBlur in=\"SourceAlpha\" stdDeviation=\"3\" result=\"blur\"\u003e\u003c/feGaussianBlur\u003e\u0027 +\n \u0027\u003cfeOffset dy=\"2\" dx=\"4\"\u003e\u003c/feOffset\u003e\u0027 +\n \u0027\u003cfeComposite in2=\"SourceAlpha\" operator=\"arithmetic\" k2=\"-1\" k3=\"1\" result=\"shadowDiff\"\u003e\u003c/feComposite\u003e\u0027 +\n \u0027\u003cfeFlood flood-color=\"#ffe95c\" flood-opacity=\"1\"\u003e\u003c/feFlood\u003e\u0027 +\n \u0027\u003cfeComposite in2=\"shadowDiff\" operator=\"in\"\u003e\u003c/feComposite\u003e\u0027 +\n \u0027\u003cfeComposite in2=\"SourceGraphic\" operator=\"over\" result=\"firstfilter\"\u003e\u003c/feComposite\u003e\u0027 +\n \u0027\u003cfeGaussianBlur in=\"firstfilter\" stdDeviation=\"3\" result=\"blur2\"\u003e\u003c/feGaussianBlur\u003e\u0027 +\n \u0027\u003cfeOffset dy=\"-2\" dx=\"-4\"\u003e\u003c/feOffset\u003e\u0027 +\n \u0027\u003cfeComposite in2=\"firstfilter\" operator=\"arithmetic\" k2=\"-1\" k3=\"1\" result=\"shadowDiff\"\u003e\u003c/feComposite\u003e\u0027 +\n \u0027\u003cfeFlood flood-color=\"#ffe95c\" flood-opacity=\"1\"\u003e\u003c/feFlood\u003e\u0027 +\n \u0027\u003cfeComposite in2=\"shadowDiff\" operator=\"in\"\u003e\u003c/feComposite\u003e\u0027 +\n \u0027\u003cfeComposite in2=\"firstfilter\" operator=\"over\"\u003e\u003c/feComposite\u003e\u0027 +\n \u0027\u003c/filter\u003e\u0027 +\n \u0027\u003cpath class=\"h5p-joubelui-score-bar-star-shadow\" d=\"M35.08,43.41V9.16H20.91v0L9.51,10.85,9,10.93C2.8,12.18,0,17,0,21.25a11.22,11.22,0,0,0,3,7.48l8.73,8.53-1.07,6.16Z\"/\u003e\u0027 +\n \u0027\u003cg\u003e\u0027 +\n \u0027\u003cpath class=\"h5p-joubelui-score-bar-star-border\" d=\"M61.36,22.8,49.72,34.11l2.78,16a2.6,2.6,0,0,1,.05.64c0,.85-.37,1.6-1.33,1.6A2.74,2.74,0,0,1,49.94,52L35.58,44.41,21.22,52a2.93,2.93,0,0,1-1.28.37c-.91,0-1.33-.75-1.33-1.6,0-.21.05-.43.05-.64l2.78-16L9.8,22.8A2.57,2.57,0,0,1,9,21.25c0-1,1-1.33,1.81-1.49l16.07-2.35L34.09,2.83c.27-.59.85-1.33,1.55-1.33s1.28.69,1.55,1.33l7.21,14.57,16.07,2.35c.75.11,1.81.53,1.81,1.49A3.07,3.07,0,0,1,61.36,22.8Z\"/\u003e\u0027 +\n \u0027\u003cpath class=\"h5p-joubelui-score-bar-star-fill\" d=\"M61.36,22.8,49.72,34.11l2.78,16a2.6,2.6,0,0,1,.05.64c0,.85-.37,1.6-1.33,1.6A2.74,2.74,0,0,1,49.94,52L35.58,44.41,21.22,52a2.93,2.93,0,0,1-1.28.37c-.91,0-1.33-.75-1.33-1.6,0-.21.05-.43.05-.64l2.78-16L9.8,22.8A2.57,2.57,0,0,1,9,21.25c0-1,1-1.33,1.81-1.49l16.07-2.35L34.09,2.83c.27-.59.85-1.33,1.55-1.33s1.28.69,1.55,1.33l7.21,14.57,16.07,2.35c.75.11,1.81.53,1.81,1.49A3.07,3.07,0,0,1,61.36,22.8Z\"/\u003e\u0027 +\n \u0027\u003cpath filter=\"url(#h5p-joubelui-score-bar-star-inner-shadow-\u0027 + idCounter + \u0027)\" class=\"h5p-joubelui-score-bar-star-fill-full-score\" d=\"M61.36,22.8,49.72,34.11l2.78,16a2.6,2.6,0,0,1,.05.64c0,.85-.37,1.6-1.33,1.6A2.74,2.74,0,0,1,49.94,52L35.58,44.41,21.22,52a2.93,2.93,0,0,1-1.28.37c-.91,0-1.33-.75-1.33-1.6,0-.21.05-.43.05-.64l2.78-16L9.8,22.8A2.57,2.57,0,0,1,9,21.25c0-1,1-1.33,1.81-1.49l16.07-2.35L34.09,2.83c.27-.59.85-1.33,1.55-1.33s1.28.69,1.55,1.33l7.21,14.57,16.07,2.35c.75.11,1.81.53,1.81,1.49A3.07,3.07,0,0,1,61.36,22.8Z\"/\u003e\u0027 +\n \u0027\u003c/g\u003e\u0027 +\n \u0027\u003c/svg\u003e\u0027;\n\n /**\n * @function appendTo\n * @memberOf H5P.JoubelScoreBar#\n * @param {H5P.jQuery} $wrapper Dom container\n */\n self.appendTo = function ($wrapper) {\n self.$scoreBar.appendTo($wrapper);\n };\n\n /**\n * Create the text representation of the scorebar .\n *\n * @private\n * @return {string}\n */\n var createLabel = function (score) {\n if (!label) {\n return \u0027\u0027;\n }\n\n return label.replace(\u0027:num\u0027, score).replace(\u0027:total\u0027, self.maxScore);\n };\n\n /**\n * Creates the html for this widget\n *\n * @method createHtml\n * @private\n */\n var createHtml = function () {\n // Container div\n self.$scoreBar = $(\u0027\u003cdiv\u003e\u0027, {\n \u0027class\u0027: \u0027h5p-joubelui-score-bar\u0027,\n });\n\n var $visuals = $(\u0027\u003cdiv\u003e\u0027, {\n \u0027class\u0027: \u0027h5p-joubelui-score-bar-visuals\u0027,\n appendTo: self.$scoreBar\n });\n\n // The progress bar wrapper\n self.$progressWrapper = $(\u0027\u003cdiv\u003e\u0027, {\n \u0027class\u0027: \u0027h5p-joubelui-score-bar-progress-wrapper\u0027,\n appendTo: $visuals\n });\n\n self.$progress = $(\u0027\u003cdiv\u003e\u0027, {\n \u0027class\u0027: \u0027h5p-joubelui-score-bar-progress\u0027,\n \u0027html\u0027: createLabel(self.score),\n appendTo: self.$progressWrapper\n });\n\n // The star\n $(\u0027\u003cdiv\u003e\u0027, {\n \u0027class\u0027: \u0027h5p-joubelui-score-bar-star\u0027,\n html: self.STAR_MARKUP\n }).appendTo($visuals);\n\n // The score container\n var $numerics = $(\u0027\u003cdiv\u003e\u0027, {\n \u0027class\u0027: \u0027h5p-joubelui-score-numeric\u0027,\n appendTo: self.$scoreBar,\n \u0027aria-hidden\u0027: true\n });\n\n // The current score\n self.$scoreCounter = $(\u0027\u003cspan\u003e\u0027, {\n \u0027class\u0027: \u0027h5p-joubelui-score-number h5p-joubelui-score-number-counter\u0027,\n text: 0,\n appendTo: $numerics\n });\n\n // The separator\n $(\u0027\u003cspan\u003e\u0027, {\n \u0027class\u0027: \u0027h5p-joubelui-score-number-separator\u0027,\n text: \u0027/\u0027,\n appendTo: $numerics\n });\n\n // Max score\n self.$maxScore = $(\u0027\u003cspan\u003e\u0027, {\n \u0027class\u0027: \u0027h5p-joubelui-score-number h5p-joubelui-score-max\u0027,\n text: self.maxScore,\n appendTo: $numerics\n });\n\n if (helpText) {\n H5P.JoubelUI.createTip(helpText, {\n tipLabel: scoreExplanationButtonLabel ? scoreExplanationButtonLabel : helpText,\n helpIcon: true\n }).appendTo(self.$scoreBar);\n self.$scoreBar.addClass(\u0027h5p-score-bar-has-help\u0027);\n }\n };\n\n /**\n * Set the current score\n * @method setScore\n * @memberOf H5P.JoubelScoreBar#\n * @param {number} score\n */\n self.setScore = function (score) {\n // Do nothing if score hasn\u0027t changed\n if (score === self.score) {\n return;\n }\n self.score = score \u003e self.maxScore ? self.maxScore : score;\n self.updateVisuals();\n };\n\n /**\n * Increment score\n * @method incrementScore\n * @memberOf H5P.JoubelScoreBar#\n * @param {number=} incrementBy Optional parameter, defaults to 1\n */\n self.incrementScore = function (incrementBy) {\n self.setScore(self.score + (incrementBy || 1));\n };\n\n /**\n * Set the max score\n * @method setMaxScore\n * @memberOf H5P.JoubelScoreBar#\n * @param {number} maxScore The max score\n */\n self.setMaxScore = function (maxScore) {\n self.maxScore = maxScore;\n };\n\n /**\n * Updates the progressbar visuals\n * @memberOf H5P.JoubelScoreBar#\n * @method updateVisuals\n */\n self.updateVisuals = function () {\n self.$progress.html(createLabel(self.score));\n self.$scoreCounter.text(self.score);\n\n setTimeout(function () {\n // Start the progressbar animation\n self.$progress.css({\n width: ((self.score / self.maxScore) * 100) + \u0027%\u0027\n });\n\n H5P.Transition.onTransitionEnd(self.$progress, function () {\n // If fullscore fill the star and start the animation\n self.$scoreBar.toggleClass(\u0027h5p-joubelui-score-bar-full-score\u0027, self.score === self.maxScore);\n self.$scoreBar.toggleClass(\u0027h5p-joubelui-score-bar-animation-active\u0027, self.score === self.maxScore);\n\n // Only allow the star animation to run once\n self.$scoreBar.one(\"animationend\", function() {\n self.$scoreBar.removeClass(\"h5p-joubelui-score-bar-animation-active\");\n });\n }, 600);\n }, 300);\n };\n\n /**\n * Removes all classes\n * @method reset\n */\n self.reset = function () {\n self.$scoreBar.removeClass(\u0027h5p-joubelui-score-bar-full-score\u0027);\n };\n\n createHtml();\n }\n\n return JoubelScoreBar;\n})(H5P.jQuery);\n"
,"js/joubel-progressbar.js":"var H5P = H5P || {};\n\nH5P.JoubelProgressbar = (function ($) {\n\n /**\n * Joubel progressbar class\n * @method JoubelProgressbar\n * @constructor\n * @param {number} steps Number of steps\n * @param {Object} [options] Additional options\n * @param {boolean} [options.disableAria] Disable readspeaker assistance\n * @param {string} [options.progressText] A progress text for describing\n * current progress out of total progress for readspeakers.\n * e.g. \"Slide :num of :total\"\n */\n function JoubelProgressbar(steps, options) {\n H5P.EventDispatcher.call(this);\n var self = this;\n this.options = $.extend({\n progressText: \u0027Slide :num of :total\u0027\n }, options);\n this.currentStep = 0;\n this.steps = steps;\n\n this.$progressbar = $(\u0027\u003cdiv\u003e\u0027, {\n \u0027class\u0027: \u0027h5p-joubelui-progressbar\u0027,\n on: {\n click: function () {\n self.toggleTooltip();\n return false;\n },\n mouseenter: function () {\n self.showTooltip();\n },\n mouseleave: function () {\n setTimeout(function () {\n self.hideTooltip();\n }, 1500);\n }\n }\n });\n this.$background = $(\u0027\u003cdiv\u003e\u0027, {\n \u0027class\u0027: \u0027h5p-joubelui-progressbar-background\u0027\n }).appendTo(this.$progressbar);\n\n $(\u0027body\u0027).click(function () {\n self.toggleTooltip(true);\n });\n }\n\n JoubelProgressbar.prototype = Object.create(H5P.EventDispatcher.prototype);\n JoubelProgressbar.prototype.constructor = JoubelProgressbar;\n\n /**\n * Display tooltip\n * @method showTooltip\n */\n JoubelProgressbar.prototype.showTooltip = function () {\n var self = this;\n\n if (this.currentStep === 0 || this.tooltip !== undefined) {\n return;\n }\n\n var parentWidth = self.$progressbar.offset().left + self.$progressbar.width();\n\n this.tooltip = new H5P.Drop({\n target: this.$background.get(0),\n content: this.currentStep + \u0027/\u0027 + this.steps,\n classes: \u0027drop-theme-arrows-bounce h5p-joubelui-drop\u0027,\n position: \u0027top right\u0027,\n openOn: \u0027always\u0027,\n tetherOptions: {\n attachment: \u0027bottom center\u0027,\n targetAttachment: \u0027top right\u0027\n }\n });\n this.tooltip.on(\u0027open\u0027, function () {\n var $drop = $(self.tooltip.drop);\n var left = $drop.position().left;\n var dropWidth = $drop.width();\n\n // Need to handle drops getting outside of the progressbar:\n if (left \u003c 0) {\n $drop.css({marginLeft: (-left) + \u0027px\u0027});\n }\n else if (left + dropWidth \u003e parentWidth) {\n $drop.css({marginLeft: (parentWidth - (left + dropWidth)) + \u0027px\u0027});\n }\n });\n };\n\n JoubelProgressbar.prototype.updateAria = function () {\n var self = this;\n if (this.options.disableAria) {\n return;\n }\n\n if (!this.$currentStatus) {\n this.$currentStatus = $(\u0027\u003cdiv\u003e\u0027, {\n \u0027class\u0027: \u0027h5p-joubelui-progressbar-slide-status-text\u0027,\n \u0027aria-live\u0027: \u0027assertive\u0027\n }).appendTo(this.$progressbar);\n }\n var interpolatedProgressText = self.options.progressText\n .replace(\u0027:num\u0027, self.currentStep)\n .replace(\u0027:total\u0027, self.steps);\n this.$currentStatus.html(interpolatedProgressText);\n };\n\n /**\n * Hides tooltip\n * @method hideTooltip\n */\n JoubelProgressbar.prototype.hideTooltip = function () {\n if (this.tooltip !== undefined) {\n this.tooltip.remove();\n this.tooltip.destroy();\n this.tooltip = undefined;\n }\n };\n\n /**\n * Toggles tooltip-visibility\n * @method toggleTooltip\n * @param {boolean} [closeOnly] Don\u0027t show, only close if open\n */\n JoubelProgressbar.prototype.toggleTooltip = function (closeOnly) {\n if (this.tooltip === undefined \u0026\u0026 !closeOnly) {\n this.showTooltip();\n }\n else if (this.tooltip !== undefined) {\n this.hideTooltip();\n }\n };\n\n /**\n * Appends to a container\n * @method appendTo\n * @param {H5P.jquery} $container\n */\n JoubelProgressbar.prototype.appendTo = function ($container) {\n this.$progressbar.appendTo($container);\n };\n\n /**\n * Update progress\n * @method setProgress\n * @param {number} step\n */\n JoubelProgressbar.prototype.setProgress = function (step) {\n // Check for valid value:\n if (step \u003e this.steps || step \u003c 0) {\n return;\n }\n this.currentStep = step;\n this.$background.css({\n width: ((this.currentStep/this.steps)*100) + \u0027%\u0027\n });\n\n this.updateAria();\n };\n\n /**\n * Increment progress with 1\n * @method next\n */\n JoubelProgressbar.prototype.next = function () {\n this.setProgress(this.currentStep+1);\n };\n\n /**\n * Reset progressbar\n * @method reset\n */\n JoubelProgressbar.prototype.reset = function () {\n this.setProgress(0);\n };\n\n /**\n * Check if last step is reached\n * @method isLastStep\n * @return {Boolean}\n */\n JoubelProgressbar.prototype.isLastStep = function () {\n return this.steps === this.currentStep;\n };\n\n return JoubelProgressbar;\n})(H5P.jQuery);\n"
,"js/joubel-ui.js":"var H5P = H5P || {};\n\n/**\n * H5P Joubel UI library.\n *\n * This is a utility library, which does not implement attach. I.e, it has to bee actively used by\n * other libraries\n * @module\n */\nH5P.JoubelUI = (function ($) {\n\n /**\n * The internal object to return\n * @class H5P.JoubelUI\n * @static\n */\n function JoubelUI() {}\n\n /* Public static functions */\n\n /**\n * Create a tip icon\n * @method H5P.JoubelUI.createTip\n * @param {string} text The textual tip\n * @param {Object} params Parameters\n * @return {H5P.JoubelTip}\n */\n JoubelUI.createTip = function (text, params) {\n return new H5P.JoubelTip(text, params);\n };\n\n /**\n * Create message dialog\n * @method H5P.JoubelUI.createMessageDialog\n * @param {H5P.jQuery} $container The dom container\n * @param {string} message The message\n * @return {H5P.JoubelMessageDialog}\n */\n JoubelUI.createMessageDialog = function ($container, message) {\n return new H5P.JoubelMessageDialog($container, message);\n };\n\n /**\n * Create help text dialog\n * @method H5P.JoubelUI.createHelpTextDialog\n * @param {string} header The textual header\n * @param {string} message The textual message\n * @param {string} closeButtonTitle The title for the close button\n * @return {H5P.JoubelHelpTextDialog}\n */\n JoubelUI.createHelpTextDialog = function (header, message, closeButtonTitle) {\n return new H5P.JoubelHelpTextDialog(header, message, closeButtonTitle);\n };\n\n /**\n * Create progress circle\n * @method H5P.JoubelUI.createProgressCircle\n * @param {number} number The progress (0 to 100)\n * @param {string} progressColor The progress color in hex value\n * @param {string} fillColor The fill color in hex value\n * @param {string} backgroundColor The background color in hex value\n * @return {H5P.JoubelProgressCircle}\n */\n JoubelUI.createProgressCircle = function (number, progressColor, fillColor, backgroundColor) {\n return new H5P.JoubelProgressCircle(number, progressColor, fillColor, backgroundColor);\n };\n\n /**\n * Create throbber for loading\n * @method H5P.JoubelUI.createThrobber\n * @return {H5P.JoubelThrobber}\n */\n JoubelUI.createThrobber = function () {\n return new H5P.JoubelThrobber();\n };\n\n /**\n * Create simple rounded button\n * @method H5P.JoubelUI.createSimpleRoundedButton\n * @param {string} text The button label\n * @return {H5P.SimpleRoundedButton}\n */\n JoubelUI.createSimpleRoundedButton = function (text) {\n return new H5P.SimpleRoundedButton(text);\n };\n\n /**\n * Create Slider\n * @method H5P.JoubelUI.createSlider\n * @param {Object} [params] Parameters\n * @return {H5P.JoubelSlider}\n */\n JoubelUI.createSlider = function (params) {\n return new H5P.JoubelSlider(params);\n };\n\n /**\n * Create Score Bar\n * @method H5P.JoubelUI.createScoreBar\n * @param {number=} maxScore The maximum score\n * @param {string} [label] Makes it easier for readspeakers to identify the scorebar\n * @return {H5P.JoubelScoreBar}\n */\n JoubelUI.createScoreBar = function (maxScore, label, helpText, scoreExplanationButtonLabel) {\n return new H5P.JoubelScoreBar(maxScore, label, helpText, scoreExplanationButtonLabel);\n };\n\n /**\n * Create Progressbar\n * @method H5P.JoubelUI.createProgressbar\n * @param {number=} numSteps The total numer of steps\n * @param {Object} [options] Additional options\n * @param {boolean} [options.disableAria] Disable readspeaker assistance\n * @param {string} [options.progressText] A progress text for describing\n * current progress out of total progress for readspeakers.\n * e.g. \"Slide :num of :total\"\n * @return {H5P.JoubelProgressbar}\n */\n JoubelUI.createProgressbar = function (numSteps, options) {\n return new H5P.JoubelProgressbar(numSteps, options);\n };\n\n /**\n * Create standard Joubel button\n *\n * @method H5P.JoubelUI.createButton\n * @param {object} params\n * May hold any properties allowed by jQuery. If href is set, an A tag\n * is used, if not a button tag is used.\n * @return {H5P.jQuery} The jquery element created\n */\n JoubelUI.createButton = function(params) {\n var type = \u0027button\u0027;\n if (params.href) {\n type = \u0027a\u0027;\n }\n else {\n params.type = \u0027button\u0027;\n }\n if (params.class) {\n params.class += \u0027 h5p-joubelui-button\u0027;\n }\n else {\n params.class = \u0027h5p-joubelui-button\u0027;\n }\n return $(\u0027\u003c\u0027 + type + \u0027/\u003e\u0027, params);\n };\n\n /**\n * Fix for iframe scoll bug in IOS. When focusing an element that doesn\u0027t have\n * focus support by default the iframe will scroll the parent frame so that\n * the focused element is out of view. This varies dependening on the elements\n * of the parent frame.\n */\n if (H5P.isFramed \u0026\u0026 !H5P.hasiOSiframeScrollFix \u0026\u0026\n /iPad|iPhone|iPod/.test(navigator.userAgent)) {\n H5P.hasiOSiframeScrollFix = true;\n\n // Keep track of original focus function\n var focus = HTMLElement.prototype.focus;\n\n // Override the original focus\n HTMLElement.prototype.focus = function () {\n // Only focus the element if it supports it natively\n if ( (this instanceof HTMLAnchorElement ||\n this instanceof HTMLInputElement ||\n this instanceof HTMLSelectElement ||\n this instanceof HTMLTextAreaElement ||\n this instanceof HTMLButtonElement ||\n this instanceof HTMLIFrameElement ||\n this instanceof HTMLAreaElement) \u0026\u0026 // HTMLAreaElement isn\u0027t supported by Safari yet.\n !this.getAttribute(\u0027role\u0027)) { // Focus breaks if a different role has been set\n // In theory this.isContentEditable should be able to recieve focus,\n // but it didn\u0027t work when tested.\n\n // Trigger the original focus with the proper context\n focus.call(this);\n }\n };\n }\n\n return JoubelUI;\n})(H5P.jQuery);\n"
,"soundjs-0.6.2.min.js":"/*!\n* @license SoundJS\n* Visit http://createjs.com/ for documentation, updates and examples.\n*\n* Copyright (c) 2011-2015 gskinner.com, inc.\n*\n* Distributed under the terms of the MIT license.\n* http://www.opensource.org/licenses/mit-license.html\n*\n* This notice shall be included in all copies or substantial portions of the Software.\n*/\n\n/**!\n * SoundJS FlashAudioPlugin also includes swfobject (http://code.google.com/p/swfobject/)\n */\n\nvar old = this.createjs;\n\nthis.createjs=this.createjs||{},function(){var a=createjs.SoundJS=createjs.SoundJS||{};a.version=\"0.6.2\",a.buildDate=\"Thu, 26 Nov 2015 20:44:31 GMT\"}(),this.createjs=this.createjs||{},createjs.extend=function(a,b){\"use strict\";function c(){this.constructor=a}return c.prototype=b.prototype,a.prototype=new c},this.createjs=this.createjs||{},createjs.promote=function(a,b){\"use strict\";var c=a.prototype,d=Object.getPrototypeOf\u0026\u0026Object.getPrototypeOf(c)||c.__proto__;if(d){c[(b+=\"_\")+\"constructor\"]=d.constructor;for(var e in d)c.hasOwnProperty(e)\u0026\u0026\"function\"==typeof d[e]\u0026\u0026(c[b+e]=d[e])}return a},this.createjs=this.createjs||{},createjs.indexOf=function(a,b){\"use strict\";for(var c=0,d=a.length;d\u003ec;c++)if(b===a[c])return c;return-1},this.createjs=this.createjs||{},function(){\"use strict\";createjs.proxy=function(a,b){var c=Array.prototype.slice.call(arguments,2);return function(){return a.apply(b,Array.prototype.slice.call(arguments,0).concat(c))}}}(),this.createjs=this.createjs||{},function(){\"use strict\";function BrowserDetect(){throw\"BrowserDetect cannot be instantiated\"}var a=BrowserDetect.agent=window.navigator.userAgent;BrowserDetect.isWindowPhone=a.indexOf(\"IEMobile\")\u003e-1||a.indexOf(\"Windows Phone\")\u003e-1,BrowserDetect.isFirefox=a.indexOf(\"Firefox\")\u003e-1,BrowserDetect.isOpera=null!=window.opera,BrowserDetect.isChrome=a.indexOf(\"Chrome\")\u003e-1,BrowserDetect.isIOS=(a.indexOf(\"iPod\")\u003e-1||a.indexOf(\"iPhone\")\u003e-1||a.indexOf(\"iPad\")\u003e-1)\u0026\u0026!BrowserDetect.isWindowPhone,BrowserDetect.isAndroid=a.indexOf(\"Android\")\u003e-1\u0026\u0026!BrowserDetect.isWindowPhone,BrowserDetect.isBlackberry=a.indexOf(\"Blackberry\")\u003e-1,createjs.BrowserDetect=BrowserDetect}(),this.createjs=this.createjs||{},function(){\"use strict\";function EventDispatcher(){this._listeners=null,this._captureListeners=null}var a=EventDispatcher.prototype;EventDispatcher.initialize=function(b){b.addEventListener=a.addEventListener,b.on=a.on,b.removeEventListener=b.off=a.removeEventListener,b.removeAllEventListeners=a.removeAllEventListeners,b.hasEventListener=a.hasEventListener,b.dispatchEvent=a.dispatchEvent,b._dispatchEvent=a._dispatchEvent,b.willTrigger=a.willTrigger},a.addEventListener=function(a,b,c){var d;d=c?this._captureListeners=this._captureListeners||{}:this._listeners=this._listeners||{};var e=d[a];return e\u0026\u0026this.removeEventListener(a,b,c),e=d[a],e?e.push(b):d[a]=[b],b},a.on=function(a,b,c,d,e,f){return b.handleEvent\u0026\u0026(c=c||b,b=b.handleEvent),c=c||this,this.addEventListener(a,function(a){b.call(c,a,e),d\u0026\u0026a.remove()},f)},a.removeEventListener=function(a,b,c){var d=c?this._captureListeners:this._listeners;if(d){var e=d[a];if(e)for(var f=0,g=e.length;g\u003ef;f++)if(e[f]==b){1==g?delete d[a]:e.splice(f,1);break}}},a.off=a.removeEventListener,a.removeAllEventListeners=function(a){a?(this._listeners\u0026\u0026delete this._listeners[a],this._captureListeners\u0026\u0026delete this._captureListeners[a]):this._listeners=this._captureListeners=null},a.dispatchEvent=function(a,b,c){if(\"string\"==typeof a){var d=this._listeners;if(!(b||d\u0026\u0026d[a]))return!0;a=new createjs.Event(a,b,c)}else a.target\u0026\u0026a.clone\u0026\u0026(a=a.clone());try{a.target=this}catch(e){}if(a.bubbles\u0026\u0026this.parent){for(var f=this,g=[f];f.parent;)g.push(f=f.parent);var h,i=g.length;for(h=i-1;h\u003e=0\u0026\u0026!a.propagationStopped;h--)g[h]._dispatchEvent(a,1+(0==h));for(h=1;i\u003eh\u0026\u0026!a.propagationStopped;h++)g[h]._dispatchEvent(a,3)}else this._dispatchEvent(a,2);return!a.defaultPrevented},a.hasEventListener=function(a){var b=this._listeners,c=this._captureListeners;return!!(b\u0026\u0026b[a]||c\u0026\u0026c[a])},a.willTrigger=function(a){for(var b=this;b;){if(b.hasEventListener(a))return!0;b=b.parent}return!1},a.toString=function(){return\"[EventDispatcher]\"},a._dispatchEvent=function(a,b){var c,d=1==b?this._captureListeners:this._listeners;if(a\u0026\u0026d){var e=d[a.type];if(!e||!(c=e.length))return;try{a.currentTarget=this}catch(f){}try{a.eventPhase=b}catch(f){}a.removed=!1,e=e.slice();for(var g=0;c\u003eg\u0026\u0026!a.immediatePropagationStopped;g++){var h=e[g];h.handleEvent?h.handleEvent(a):h(a),a.removed\u0026\u0026(this.off(a.type,h,1==b),a.removed=!1)}}},createjs.EventDispatcher=EventDispatcher}(),this.createjs=this.createjs||{},function(){\"use strict\";function Event(a,b,c){this.type=a,this.target=null,this.currentTarget=null,this.eventPhase=0,this.bubbles=!!b,this.cancelable=!!c,this.timeStamp=(new Date).getTime(),this.defaultPrevented=!1,this.propagationStopped=!1,this.immediatePropagationStopped=!1,this.removed=!1}var a=Event.prototype;a.preventDefault=function(){this.defaultPrevented=this.cancelable\u0026\u0026!0},a.stopPropagation=function(){this.propagationStopped=!0},a.stopImmediatePropagation=function(){this.immediatePropagationStopped=this.propagationStopped=!0},a.remove=function(){this.removed=!0},a.clone=function(){return new Event(this.type,this.bubbles,this.cancelable)},a.set=function(a){for(var b in a)this[b]=a[b];return this},a.toString=function(){return\"[Event (type=\"+this.type+\")]\"},createjs.Event=Event}(),this.createjs=this.createjs||{},function(){\"use strict\";function ErrorEvent(a,b,c){this.Event_constructor(\"error\"),this.title=a,this.message=b,this.data=c}var a=createjs.extend(ErrorEvent,createjs.Event);a.clone=function(){return new createjs.ErrorEvent(this.title,this.message,this.data)},createjs.ErrorEvent=createjs.promote(ErrorEvent,\"Event\")}(),this.createjs=this.createjs||{},function(){\"use strict\";function ProgressEvent(a,b){this.Event_constructor(\"progress\"),this.loaded=a,this.total=null==b?1:b,this.progress=0==b?0:this.loaded/this.total}var a=createjs.extend(ProgressEvent,createjs.Event);a.clone=function(){return new createjs.ProgressEvent(this.loaded,this.total)},createjs.ProgressEvent=createjs.promote(ProgressEvent,\"Event\")}(window),this.createjs=this.createjs||{},function(){\"use strict\";function LoadItem(){this.src=null,this.type=null,this.id=null,this.maintainOrder=!1,this.callback=null,this.data=null,this.method=createjs.LoadItem.GET,this.values=null,this.headers=null,this.withCredentials=!1,this.mimeType=null,this.crossOrigin=null,this.loadTimeout=b.LOAD_TIMEOUT_DEFAULT}var a=LoadItem.prototype={},b=LoadItem;b.LOAD_TIMEOUT_DEFAULT=8e3,b.create=function(a){if(\"string\"==typeof a){var c=new LoadItem;return c.src=a,c}if(a instanceof b)return a;if(a instanceof Object\u0026\u0026a.src)return null==a.loadTimeout\u0026\u0026(a.loadTimeout=b.LOAD_TIMEOUT_DEFAULT),a;throw new Error(\"Type not recognized.\")},a.set=function(a){for(var b in a)this[b]=a[b];return this},createjs.LoadItem=b}(),function(){var a={};a.ABSOLUTE_PATT=/^(?:\\w+:)?\\/{2}/i,a.RELATIVE_PATT=/^[.\\/]*?\\//i,a.EXTENSION_PATT=/\\/?[^\\/]+\\.(\\w{1,5})$/i,a.parseURI=function(b){var c={absolute:!1,relative:!1};if(null==b)return c;var d=b.indexOf(\"?\");d\u003e-1\u0026\u0026(b=b.substr(0,d));var e;return a.ABSOLUTE_PATT.test(b)?c.absolute=!0:a.RELATIVE_PATT.test(b)\u0026\u0026(c.relative=!0),(e=b.match(a.EXTENSION_PATT))\u0026\u0026(c.extension=e[1].toLowerCase()),c},a.formatQueryString=function(a,b){if(null==a)throw new Error(\"You must specify data.\");var c=[];for(var d in a)c.push(d+\"=\"+escape(a[d]));return b\u0026\u0026(c=c.concat(b)),c.join(\"\u0026\")},a.buildPath=function(a,b){if(null==b)return a;var c=[],d=a.indexOf(\"?\");if(-1!=d){var e=a.slice(d+1);c=c.concat(e.split(\"\u0026\"))}return-1!=d?a.slice(0,d)+\"?\"+this.formatQueryString(b,c):a+\"?\"+this.formatQueryString(b,c)},a.isCrossDomain=function(a){var b=document.createElement(\"a\");b.href=a.src;var c=document.createElement(\"a\");c.href=location.href;var d=\"\"!=b.hostname\u0026\u0026(b.port!=c.port||b.protocol!=c.protocol||b.hostname!=c.hostname);return d},a.isLocal=function(a){var b=document.createElement(\"a\");return b.href=a.src,\"\"==b.hostname\u0026\u0026\"file:\"==b.protocol},a.isBinary=function(a){switch(a){case createjs.AbstractLoader.IMAGE:case createjs.AbstractLoader.BINARY:return!0;default:return!1}},a.isImageTag=function(a){return a instanceof HTMLImageElement},a.isAudioTag=function(a){return window.HTMLAudioElement?a instanceof HTMLAudioElement:!1},a.isVideoTag=function(a){return window.HTMLVideoElement?a instanceof HTMLVideoElement:!1},a.isText=function(a){switch(a){case createjs.AbstractLoader.TEXT:case createjs.AbstractLoader.JSON:case createjs.AbstractLoader.MANIFEST:case createjs.AbstractLoader.XML:case createjs.AbstractLoader.CSS:case createjs.AbstractLoader.SVG:case createjs.AbstractLoader.JAVASCRIPT:case createjs.AbstractLoader.SPRITESHEET:return!0;default:return!1}},a.getTypeByExtension=function(a){if(null==a)return createjs.AbstractLoader.TEXT;switch(a.toLowerCase()){case\"jpeg\":case\"jpg\":case\"gif\":case\"png\":case\"webp\":case\"bmp\":return createjs.AbstractLoader.IMAGE;case\"ogg\":case\"mp3\":case\"webm\":return createjs.AbstractLoader.SOUND;case\"mp4\":case\"webm\":case\"ts\":return createjs.AbstractLoader.VIDEO;case\"json\":return createjs.AbstractLoader.JSON;case\"xml\":return createjs.AbstractLoader.XML;case\"css\":return createjs.AbstractLoader.CSS;case\"js\":return createjs.AbstractLoader.JAVASCRIPT;case\"svg\":return createjs.AbstractLoader.SVG;default:return createjs.AbstractLoader.TEXT}},createjs.RequestUtils=a}(),this.createjs=this.createjs||{},function(){\"use strict\";function AbstractLoader(a,b,c){this.EventDispatcher_constructor(),this.loaded=!1,this.canceled=!1,this.progress=0,this.type=c,this.resultFormatter=null,this._item=a?createjs.LoadItem.create(a):null,this._preferXHR=b,this._result=null,this._rawResult=null,this._loadedItems=null,this._tagSrcAttribute=null,this._tag=null}var a=createjs.extend(AbstractLoader,createjs.EventDispatcher),b=AbstractLoader;b.POST=\"POST\",b.GET=\"GET\",b.BINARY=\"binary\",b.CSS=\"css\",b.IMAGE=\"image\",b.JAVASCRIPT=\"javascript\",b.JSON=\"json\",b.JSONP=\"jsonp\",b.MANIFEST=\"manifest\",b.SOUND=\"sound\",b.VIDEO=\"video\",b.SPRITESHEET=\"spritesheet\",b.SVG=\"svg\",b.TEXT=\"text\",b.XML=\"xml\",a.getItem=function(){return this._item},a.getResult=function(a){return a?this._rawResult:this._result},a.getTag=function(){return this._tag},a.setTag=function(a){this._tag=a},a.load=function(){this._createRequest(),this._request.on(\"complete\",this,this),this._request.on(\"progress\",this,this),this._request.on(\"loadStart\",this,this),this._request.on(\"abort\",this,this),this._request.on(\"timeout\",this,this),this._request.on(\"error\",this,this);var a=new createjs.Event(\"initialize\");a.loader=this._request,this.dispatchEvent(a),this._request.load()},a.cancel=function(){this.canceled=!0,this.destroy()},a.destroy=function(){this._request\u0026\u0026(this._request.removeAllEventListeners(),this._request.destroy()),this._request=null,this._item=null,this._rawResult=null,this._result=null,this._loadItems=null,this.removeAllEventListeners()},a.getLoadedItems=function(){return this._loadedItems},a._createRequest=function(){this._request=this._preferXHR?new createjs.XHRRequest(this._item):new createjs.TagRequest(this._item,this._tag||this._createTag(),this._tagSrcAttribute)},a._createTag=function(){return null},a._sendLoadStart=function(){this._isCanceled()||this.dispatchEvent(\"loadstart\")},a._sendProgress=function(a){if(!this._isCanceled()){var b=null;\"number\"==typeof a?(this.progress=a,b=new createjs.ProgressEvent(this.progress)):(b=a,this.progress=a.loaded/a.total,b.progress=this.progress,(isNaN(this.progress)||1/0==this.progress)\u0026\u0026(this.progress=0)),this.hasEventListener(\"progress\")\u0026\u0026this.dispatchEvent(b)}},a._sendComplete=function(){if(!this._isCanceled()){this.loaded=!0;var a=new createjs.Event(\"complete\");a.rawResult=this._rawResult,null!=this._result\u0026\u0026(a.result=this._result),this.dispatchEvent(a)}},a._sendError=function(a){!this._isCanceled()\u0026\u0026this.hasEventListener(\"error\")\u0026\u0026(null==a\u0026\u0026(a=new createjs.ErrorEvent(\"PRELOAD_ERROR_EMPTY\")),this.dispatchEvent(a))},a._isCanceled=function(){return null==window.createjs||this.canceled?!0:!1},a.resultFormatter=null,a.handleEvent=function(a){switch(a.type){case\"complete\":this._rawResult=a.target._response;var b=this.resultFormatter\u0026\u0026this.resultFormatter(this);b instanceof Function?b.call(this,createjs.proxy(this._resultFormatSuccess,this),createjs.proxy(this._resultFormatFailed,this)):(this._result=b||this._rawResult,this._sendComplete());break;case\"progress\":this._sendProgress(a);break;case\"error\":this._sendError(a);break;case\"loadstart\":this._sendLoadStart();break;case\"abort\":case\"timeout\":this._isCanceled()||this.dispatchEvent(new createjs.ErrorEvent(\"PRELOAD_\"+a.type.toUpperCase()+\"_ERROR\"))}},a._resultFormatSuccess=function(a){this._result=a,this._sendComplete()},a._resultFormatFailed=function(a){this._sendError(a)},a.buildPath=function(a,b){return createjs.RequestUtils.buildPath(a,b)},a.toString=function(){return\"[PreloadJS AbstractLoader]\"},createjs.AbstractLoader=createjs.promote(AbstractLoader,\"EventDispatcher\")}(),this.createjs=this.createjs||{},function(){\"use strict\";function AbstractMediaLoader(a,b,c){this.AbstractLoader_constructor(a,b,c),this.resultFormatter=this._formatResult,this._tagSrcAttribute=\"src\",this.on(\"initialize\",this._updateXHR,this)}var a=createjs.extend(AbstractMediaLoader,createjs.AbstractLoader);a.load=function(){this._tag||(this._tag=this._createTag(this._item.src)),this._tag.preload=\"auto\",this._tag.load(),this.AbstractLoader_load()},a._createTag=function(){},a._createRequest=function(){this._request=this._preferXHR?new createjs.XHRRequest(this._item):new createjs.MediaTagRequest(this._item,this._tag||this._createTag(),this._tagSrcAttribute)},a._updateXHR=function(a){a.loader.setResponseType\u0026\u0026a.loader.setResponseType(\"blob\")},a._formatResult=function(a){if(this._tag.removeEventListener\u0026\u0026this._tag.removeEventListener(\"canplaythrough\",this._loadedHandler),this._tag.onstalled=null,this._preferXHR){var b=window.URL||window.webkitURL,c=a.getResult(!0);a.getTag().src=b.createObjectURL(c)}return a.getTag()},createjs.AbstractMediaLoader=createjs.promote(AbstractMediaLoader,\"AbstractLoader\")}(),this.createjs=this.createjs||{},function(){\"use strict\";var AbstractRequest=function(a){this._item=a},a=createjs.extend(AbstractRequest,createjs.EventDispatcher);a.load=function(){},a.destroy=function(){},a.cancel=function(){},createjs.AbstractRequest=createjs.promote(AbstractRequest,\"EventDispatcher\")}(),this.createjs=this.createjs||{},function(){\"use strict\";function TagRequest(a,b,c){this.AbstractRequest_constructor(a),this._tag=b,this._tagSrcAttribute=c,this._loadedHandler=createjs.proxy(this._handleTagComplete,this),this._addedToDOM=!1,this._startTagVisibility=null}var a=createjs.extend(TagRequest,createjs.AbstractRequest);a.load=function(){this._tag.onload=createjs.proxy(this._handleTagComplete,this),this._tag.onreadystatechange=createjs.proxy(this._handleReadyStateChange,this),this._tag.onerror=createjs.proxy(this._handleError,this);var a=new createjs.Event(\"initialize\");a.loader=this._tag,this.dispatchEvent(a),this._hideTag(),this._loadTimeout=setTimeout(createjs.proxy(this._handleTimeout,this),this._item.loadTimeout),this._tag[this._tagSrcAttribute]=this._item.src,null==this._tag.parentNode\u0026\u0026(window.document.body.appendChild(this._tag),this._addedToDOM=!0)},a.destroy=function(){this._clean(),this._tag=null,this.AbstractRequest_destroy()},a._handleReadyStateChange=function(){clearTimeout(this._loadTimeout);var a=this._tag;(\"loaded\"==a.readyState||\"complete\"==a.readyState)\u0026\u0026this._handleTagComplete()},a._handleError=function(){this._clean(),this.dispatchEvent(\"error\")},a._handleTagComplete=function(){this._rawResult=this._tag,this._result=this.resultFormatter\u0026\u0026this.resultFormatter(this)||this._rawResult,this._clean(),this._showTag(),this.dispatchEvent(\"complete\")},a._handleTimeout=function(){this._clean(),this.dispatchEvent(new createjs.Event(\"timeout\"))},a._clean=function(){this._tag.onload=null,this._tag.onreadystatechange=null,this._tag.onerror=null,this._addedToDOM\u0026\u0026null!=this._tag.parentNode\u0026\u0026this._tag.parentNode.removeChild(this._tag),clearTimeout(this._loadTimeout)},a._hideTag=function(){this._startTagVisibility=this._tag.style.visibility,this._tag.style.visibility=\"hidden\"},a._showTag=function(){this._tag.style.visibility=this._startTagVisibility},a._handleStalled=function(){},createjs.TagRequest=createjs.promote(TagRequest,\"AbstractRequest\")}(),this.createjs=this.createjs||{},function(){\"use strict\";function MediaTagRequest(a,b,c){this.AbstractRequest_constructor(a),this._tag=b,this._tagSrcAttribute=c,this._loadedHandler=createjs.proxy(this._handleTagComplete,this)}var a=createjs.extend(MediaTagRequest,createjs.TagRequest);a.load=function(){var a=createjs.proxy(this._handleStalled,this);this._stalledCallback=a;var b=createjs.proxy(this._handleProgress,this);this._handleProgress=b,this._tag.addEventListener(\"stalled\",a),this._tag.addEventListener(\"progress\",b),this._tag.addEventListener\u0026\u0026this._tag.addEventListener(\"canplaythrough\",this._loadedHandler,!1),this.TagRequest_load()},a._handleReadyStateChange=function(){clearTimeout(this._loadTimeout);var a=this._tag;(\"loaded\"==a.readyState||\"complete\"==a.readyState)\u0026\u0026this._handleTagComplete()},a._handleStalled=function(){},a._handleProgress=function(a){if(a\u0026\u0026!(a.loaded\u003e0\u0026\u00260==a.total)){var b=new createjs.ProgressEvent(a.loaded,a.total);this.dispatchEvent(b)}},a._clean=function(){this._tag.removeEventListener\u0026\u0026this._tag.removeEventListener(\"canplaythrough\",this._loadedHandler),this._tag.removeEventListener(\"stalled\",this._stalledCallback),this._tag.removeEventListener(\"progress\",this._progressCallback),this.TagRequest__clean()},createjs.MediaTagRequest=createjs.promote(MediaTagRequest,\"TagRequest\")}(),this.createjs=this.createjs||{},function(){\"use strict\";function XHRRequest(a){this.AbstractRequest_constructor(a),this._request=null,this._loadTimeout=null,this._xhrLevel=1,this._response=null,this._rawResponse=null,this._canceled=!1,this._handleLoadStartProxy=createjs.proxy(this._handleLoadStart,this),this._handleProgressProxy=createjs.proxy(this._handleProgress,this),this._handleAbortProxy=createjs.proxy(this._handleAbort,this),this._handleErrorProxy=createjs.proxy(this._handleError,this),this._handleTimeoutProxy=createjs.proxy(this._handleTimeout,this),this._handleLoadProxy=createjs.proxy(this._handleLoad,this),this._handleReadyStateChangeProxy=createjs.proxy(this._handleReadyStateChange,this),!this._createXHR(a)}var a=createjs.extend(XHRRequest,createjs.AbstractRequest);XHRRequest.ACTIVEX_VERSIONS=[\"Msxml2.XMLHTTP.6.0\",\"Msxml2.XMLHTTP.5.0\",\"Msxml2.XMLHTTP.4.0\",\"MSXML2.XMLHTTP.3.0\",\"MSXML2.XMLHTTP\",\"Microsoft.XMLHTTP\"],a.getResult=function(a){return a\u0026\u0026this._rawResponse?this._rawResponse:this._response},a.cancel=function(){this.canceled=!0,this._clean(),this._request.abort()},a.load=function(){if(null==this._request)return void this._handleError();null!=this._request.addEventListener?(this._request.addEventListener(\"loadstart\",this._handleLoadStartProxy,!1),this._request.addEventListener(\"progress\",this._handleProgressProxy,!1),this._request.addEventListener(\"abort\",this._handleAbortProxy,!1),this._request.addEventListener(\"error\",this._handleErrorProxy,!1),this._request.addEventListener(\"timeout\",this._handleTimeoutProxy,!1),this._request.addEventListener(\"load\",this._handleLoadProxy,!1),this._request.addEventListener(\"readystatechange\",this._handleReadyStateChangeProxy,!1)):(this._request.onloadstart=this._handleLoadStartProxy,this._request.onprogress=this._handleProgressProxy,this._request.onabort=this._handleAbortProxy,this._request.onerror=this._handleErrorProxy,this._request.ontimeout=this._handleTimeoutProxy,this._request.onload=this._handleLoadProxy,this._request.onreadystatechange=this._handleReadyStateChangeProxy),1==this._xhrLevel\u0026\u0026(this._loadTimeout=setTimeout(createjs.proxy(this._handleTimeout,this),this._item.loadTimeout));try{this._item.values\u0026\u0026this._item.method!=createjs.AbstractLoader.GET?this._item.method==createjs.AbstractLoader.POST\u0026\u0026this._request.send(createjs.RequestUtils.formatQueryString(this._item.values)):this._request.send()}catch(a){this.dispatchEvent(new createjs.ErrorEvent(\"XHR_SEND\",null,a))}},a.setResponseType=function(a){\"blob\"===a\u0026\u0026(a=window.URL?\"blob\":\"arraybuffer\",this._responseType=a),this._request.responseType=a},a.getAllResponseHeaders=function(){return this._request.getAllResponseHeaders instanceof Function?this._request.getAllResponseHeaders():null},a.getResponseHeader=function(a){return this._request.getResponseHeader instanceof Function?this._request.getResponseHeader(a):null},a._handleProgress=function(a){if(a\u0026\u0026!(a.loaded\u003e0\u0026\u00260==a.total)){var b=new createjs.ProgressEvent(a.loaded,a.total);this.dispatchEvent(b)}},a._handleLoadStart=function(){clearTimeout(this._loadTimeout),this.dispatchEvent(\"loadstart\")},a._handleAbort=function(a){this._clean(),this.dispatchEvent(new createjs.ErrorEvent(\"XHR_ABORTED\",null,a))},a._handleError=function(a){this._clean(),this.dispatchEvent(new createjs.ErrorEvent(a.message))},a._handleReadyStateChange=function(){4==this._request.readyState\u0026\u0026this._handleLoad()},a._handleLoad=function(){if(!this.loaded){this.loaded=!0;var a=this._checkError();if(a)return void this._handleError(a);if(this._response=this._getResponse(),\"arraybuffer\"===this._responseType)try{this._response=new Blob([this._response])}catch(b){if(window.BlobBuilder=window.BlobBuilder||window.WebKitBlobBuilder||window.MozBlobBuilder||window.MSBlobBuilder,\"TypeError\"===b.name\u0026\u0026window.BlobBuilder){var c=new BlobBuilder;c.append(this._response),this._response=c.getBlob()}}this._clean(),this.dispatchEvent(new createjs.Event(\"complete\"))}},a._handleTimeout=function(a){this._clean(),this.dispatchEvent(new createjs.ErrorEvent(\"PRELOAD_TIMEOUT\",null,a))},a._checkError=function(){var a=parseInt(this._request.status);switch(a){case 404:case 0:return new Error(a)}return null},a._getResponse=function(){if(null!=this._response)return this._response;if(null!=this._request.response)return this._request.response;try{if(null!=this._request.responseText)return this._request.responseText}catch(a){}try{if(null!=this._request.responseXML)return this._request.responseXML}catch(a){}return null},a._createXHR=function(a){var b=createjs.RequestUtils.isCrossDomain(a),c={},d=null;if(window.XMLHttpRequest)d=new XMLHttpRequest,b\u0026\u0026void 0===d.withCredentials\u0026\u0026window.XDomainRequest\u0026\u0026(d=new XDomainRequest);else{for(var e=0,f=s.ACTIVEX_VERSIONS.length;f\u003ee;e++){var g=s.ACTIVEX_VERSIONS[e];try{d=new ActiveXObject(g);break}catch(h){}}if(null==d)return!1}null==a.mimeType\u0026\u0026createjs.RequestUtils.isText(a.type)\u0026\u0026(a.mimeType=\"text/plain; charset=utf-8\"),a.mimeType\u0026\u0026d.overrideMimeType\u0026\u0026d.overrideMimeType(a.mimeType),this._xhrLevel=\"string\"==typeof d.responseType?2:1;var i=null;if(i=a.method==createjs.AbstractLoader.GET?createjs.RequestUtils.buildPath(a.src,a.values):a.src,d.open(a.method||createjs.AbstractLoader.GET,i,!0),b\u0026\u0026d instanceof XMLHttpRequest\u0026\u00261==this._xhrLevel\u0026\u0026(c.Origin=location.origin),a.values\u0026\u0026a.method==createjs.AbstractLoader.POST\u0026\u0026(c[\"Content-Type\"]=\"application/x-www-form-urlencoded\"),b||c[\"X-Requested-With\"]||(c[\"X-Requested-With\"]=\"XMLHttpRequest\"),a.headers)for(var j in a.headers)c[j]=a.headers[j];for(j in c)d.setRequestHeader(j,c[j]);return d instanceof XMLHttpRequest\u0026\u0026void 0!==a.withCredentials\u0026\u0026(d.withCredentials=a.withCredentials),this._request=d,!0},a._clean=function(){clearTimeout(this._loadTimeout),null!=this._request.removeEventListener?(this._request.removeEventListener(\"loadstart\",this._handleLoadStartProxy),this._request.removeEventListener(\"progress\",this._handleProgressProxy),this._request.removeEventListener(\"abort\",this._handleAbortProxy),this._request.removeEventListener(\"error\",this._handleErrorProxy),this._request.removeEventListener(\"timeout\",this._handleTimeoutProxy),this._request.removeEventListener(\"load\",this._handleLoadProxy),this._request.removeEventListener(\"readystatechange\",this._handleReadyStateChangeProxy)):(this._request.onloadstart=null,this._request.onprogress=null,this._request.onabort=null,this._request.onerror=null,this._request.ontimeout=null,this._request.onload=null,this._request.onreadystatechange=null)},a.toString=function(){return\"[PreloadJS XHRRequest]\"},createjs.XHRRequest=createjs.promote(XHRRequest,\"AbstractRequest\")}(),this.createjs=this.createjs||{},function(){\"use strict\";function SoundLoader(a,b){this.AbstractMediaLoader_constructor(a,b,createjs.AbstractLoader.SOUND),createjs.RequestUtils.isAudioTag(a)?this._tag=a:createjs.RequestUtils.isAudioTag(a.src)?this._tag=a:createjs.RequestUtils.isAudioTag(a.tag)\u0026\u0026(this._tag=createjs.RequestUtils.isAudioTag(a)?a:a.src),null!=this._tag\u0026\u0026(this._preferXHR=!1)}var a=createjs.extend(SoundLoader,createjs.AbstractMediaLoader),b=SoundLoader;b.canLoadItem=function(a){return a.type==createjs.AbstractLoader.SOUND},a._createTag=function(a){var b=document.createElement(\"audio\");return b.autoplay=!1,b.preload=\"none\",b.src=a,b},createjs.SoundLoader=createjs.promote(SoundLoader,\"AbstractMediaLoader\")}(),this.createjs=this.createjs||{},function(){\"use strict\";var PlayPropsConfig=function(){this.interrupt=null,this.delay=null,this.offset=null,this.loop=null,this.volume=null,this.pan=null,this.startTime=null,this.duration=null},a=PlayPropsConfig.prototype={},b=PlayPropsConfig;b.create=function(a){if(a instanceof b||a instanceof Object){var c=new createjs.PlayPropsConfig;return c.set(a),c}throw new Error(\"Type not recognized.\")},a.set=function(a){for(var b in a)this[b]=a[b];return this},a.toString=function(){return\"[PlayPropsConfig]\"},createjs.PlayPropsConfig=b}(),this.createjs=this.createjs||{},function(){\"use strict\";function Sound(){throw\"Sound cannot be instantiated\"}function a(a,b){this.init(a,b)}var b=Sound;b.INTERRUPT_ANY=\"any\",b.INTERRUPT_EARLY=\"early\",b.INTERRUPT_LATE=\"late\",b.INTERRUPT_NONE=\"none\",b.PLAY_INITED=\"playInited\",b.PLAY_SUCCEEDED=\"playSucceeded\",b.PLAY_INTERRUPTED=\"playInterrupted\",b.PLAY_FINISHED=\"playFinished\",b.PLAY_FAILED=\"playFailed\",b.SUPPORTED_EXTENSIONS=[\"mp3\",\"ogg\",\"opus\",\"mpeg\",\"wav\",\"m4a\",\"mp4\",\"aiff\",\"wma\",\"mid\"],b.EXTENSION_MAP={m4a:\"mp4\"},b.FILE_PATTERN=/^(?:(\\w+:)\\/{2}(\\w+(?:\\.\\w+)*\\/?))?([\\/.]*?(?:[^?]+)?\\/)?((?:[^\\/?]+)\\.(\\w+))(?:\\?(\\S+)?)?$/,b.defaultInterruptBehavior=b.INTERRUPT_NONE,b.alternateExtensions=[],b.activePlugin=null,b._masterVolume=1,Object.defineProperty(b,\"volume\",{get:function(){return this._masterVolume},set:function(a){if(null==Number(a))return!1;if(a=Math.max(0,Math.min(1,a)),b._masterVolume=a,!this.activePlugin||!this.activePlugin.setVolume||!this.activePlugin.setVolume(a))for(var c=this._instances,d=0,e=c.length;e\u003ed;d++)c[d].setMasterVolume(a)}}),b._masterMute=!1,Object.defineProperty(b,\"muted\",{get:function(){return this._masterMute},set:function(a){if(null==a)return!1;if(this._masterMute=a,!this.activePlugin||!this.activePlugin.setMute||!this.activePlugin.setMute(a))for(var b=this._instances,c=0,d=b.length;d\u003ec;c++)b[c].setMasterMute(a);return!0}}),Object.defineProperty(b,\"capabilities\",{get:function(){return null==b.activePlugin?null:b.activePlugin._capabilities},set:function(){return!1}}),b._pluginsRegistered=!1,b._lastID=0,b._instances=[],b._idHash={},b._preloadHash={},b._defaultPlayPropsHash={},b.addEventListener=null,b.removeEventListener=null,b.removeAllEventListeners=null,b.dispatchEvent=null,b.hasEventListener=null,b._listeners=null,createjs.EventDispatcher.initialize(b),b.getPreloadHandlers=function(){return{callback:createjs.proxy(b.initLoad,b),types:[\"sound\"],extensions:b.SUPPORTED_EXTENSIONS}},b._handleLoadComplete=function(a){var c=a.target.getItem().src;if(b._preloadHash[c])for(var d=0,e=b._preloadHash[c].length;e\u003ed;d++){var f=b._preloadHash[c][d];if(b._preloadHash[c][d]=!0,b.hasEventListener(\"fileload\")){var a=new createjs.Event(\"fileload\");a.src=f.src,a.id=f.id,a.data=f.data,a.sprite=f.sprite,b.dispatchEvent(a)}}},b._handleLoadError=function(a){var c=a.target.getItem().src;if(b._preloadHash[c])for(var d=0,e=b._preloadHash[c].length;e\u003ed;d++){var f=b._preloadHash[c][d];if(b._preloadHash[c][d]=!1,b.hasEventListener(\"fileerror\")){var a=new createjs.Event(\"fileerror\");a.src=f.src,a.id=f.id,a.data=f.data,a.sprite=f.sprite,b.dispatchEvent(a)}}},b._registerPlugin=function(a){return a.isSupported()?(b.activePlugin=new a,!0):!1},b.registerPlugins=function(a){b._pluginsRegistered=!0;for(var c=0,d=a.length;d\u003ec;c++)if(b._registerPlugin(a[c]))return!0;return!1},b.initializeDefaultPlugins=function(){return null!=b.activePlugin?!0:b._pluginsRegistered?!1:b.registerPlugins([createjs.WebAudioPlugin,createjs.HTMLAudioPlugin])?!0:!1},b.isReady=function(){return null!=b.activePlugin},b.getCapabilities=function(){return null==b.activePlugin?null:b.activePlugin._capabilities},b.getCapability=function(a){return null==b.activePlugin?null:b.activePlugin._capabilities[a]},b.initLoad=function(a){return b._registerSound(a)},b._registerSound=function(c){if(!b.initializeDefaultPlugins())return!1;var d;if(c.src instanceof Object?(d=b._parseSrc(c.src),d.src=c.path+d.src):d=b._parsePath(c.src),null==d)return!1;c.src=d.src,c.type=\"sound\";var e=c.data,f=null;if(null!=e\u0026\u0026(isNaN(e.channels)?isNaN(e)||(f=parseInt(e)):f=parseInt(e.channels),e.audioSprite))for(var g,h=e.audioSprite.length;h--;)g=e.audioSprite[h],b._idHash[g.id]={src:c.src,startTime:parseInt(g.startTime),duration:parseInt(g.duration)},g.defaultPlayProps\u0026\u0026(b._defaultPlayPropsHash[g.id]=createjs.PlayPropsConfig.create(g.defaultPlayProps));null!=c.id\u0026\u0026(b._idHash[c.id]={src:c.src});var i=b.activePlugin.register(c);return a.create(c.src,f),null!=e\u0026\u0026isNaN(e)?c.data.channels=f||a.maxPerChannel():c.data=f||a.maxPerChannel(),i.type\u0026\u0026(c.type=i.type),c.defaultPlayProps\u0026\u0026(b._defaultPlayPropsHash[c.src]=createjs.PlayPropsConfig.create(c.defaultPlayProps)),i},b.registerSound=function(a,c,d,e,f){var g={src:a,id:c,data:d,defaultPlayProps:f};a instanceof Object\u0026\u0026a.src\u0026\u0026(e=c,g=a),g=createjs.LoadItem.create(g),g.path=e,null==e||g.src instanceof Object||(g.src=e+a);var h=b._registerSound(g);if(!h)return!1;if(b._preloadHash[g.src]||(b._preloadHash[g.src]=[]),b._preloadHash[g.src].push(g),1==b._preloadHash[g.src].length)h.on(\"complete\",createjs.proxy(this._handleLoadComplete,this)),h.on(\"error\",createjs.proxy(this._handleLoadError,this)),b.activePlugin.preload(h);else if(1==b._preloadHash[g.src][0])return!0;return g},b.registerSounds=function(a,b){var c=[];a.path\u0026\u0026(b?b+=a.path:b=a.path,a=a.manifest);for(var d=0,e=a.length;e\u003ed;d++)c[d]=createjs.Sound.registerSound(a[d].src,a[d].id,a[d].data,b,a[d].defaultPlayProps);return c},b.removeSound=function(c,d){if(null==b.activePlugin)return!1;c instanceof Object\u0026\u0026c.src\u0026\u0026(c=c.src);var e;if(c instanceof Object?e=b._parseSrc(c):(c=b._getSrcById(c).src,e=b._parsePath(c)),null==e)return!1;c=e.src,null!=d\u0026\u0026(c=d+c);for(var f in b._idHash)b._idHash[f].src==c\u0026\u0026delete b._idHash[f];return a.removeSrc(c),delete b._preloadHash[c],b.activePlugin.removeSound(c),!0},b.removeSounds=function(a,b){var c=[];a.path\u0026\u0026(b?b+=a.path:b=a.path,a=a.manifest);for(var d=0,e=a.length;e\u003ed;d++)c[d]=createjs.Sound.removeSound(a[d].src,b);return c},b.removeAllSounds=function(){b._idHash={},b._preloadHash={},a.removeAll(),b.activePlugin\u0026\u0026b.activePlugin.removeAllSounds()},b.loadComplete=function(a){if(!b.isReady())return!1;var c=b._parsePath(a);return a=c?b._getSrcById(c.src).src:b._getSrcById(a).src,void 0==b._preloadHash[a]?!1:1==b._preloadHash[a][0]},b._parsePath=function(a){\"string\"!=typeof a\u0026\u0026(a=a.toString());var c=a.match(b.FILE_PATTERN);if(null==c)return!1;for(var d=c[4],e=c[5],f=b.capabilities,g=0;!f[e];)if(e=b.alternateExtensions[g++],g\u003eb.alternateExtensions.length)return null;a=a.replace(\".\"+c[5],\".\"+e);var h={name:d,src:a,extension:e};return h},b._parseSrc=function(a){var c={name:void 0,src:void 0,extension:void 0},d=b.capabilities;for(var e in a)if(a.hasOwnProperty(e)\u0026\u0026d[e]){c.src=a[e],c.extension=e;break}if(!c.src)return!1;var f=c.src.lastIndexOf(\"/\");return c.name=-1!=f?c.src.slice(f+1):c.src,c},b.play=function(a,c,d,e,f,g,h,i,j){var k;k=createjs.PlayPropsConfig.create(c instanceof Object||c instanceof createjs.PlayPropsConfig?c:{interrupt:c,delay:d,offset:e,loop:f,volume:g,pan:h,startTime:i,duration:j});var l=b.createInstance(a,k.startTime,k.duration),m=b._playInstance(l,k);return m||l._playFailed(),l},b.createInstance=function(c,d,e){if(!b.initializeDefaultPlugins())return new createjs.DefaultSoundInstance(c,d,e);var f=b._defaultPlayPropsHash[c];c=b._getSrcById(c);var g=b._parsePath(c.src),h=null;\nreturn null!=g\u0026\u0026null!=g.src?(a.create(g.src),null==d\u0026\u0026(d=c.startTime),h=b.activePlugin.create(g.src,d,e||c.duration),f=f||b._defaultPlayPropsHash[g.src],f\u0026\u0026h.applyPlayProps(f)):h=new createjs.DefaultSoundInstance(c,d,e),h.uniqueId=b._lastID++,h},b.stop=function(){for(var a=this._instances,b=a.length;b--;)a[b].stop()},b.setVolume=function(a){if(null==Number(a))return!1;if(a=Math.max(0,Math.min(1,a)),b._masterVolume=a,!this.activePlugin||!this.activePlugin.setVolume||!this.activePlugin.setVolume(a))for(var c=this._instances,d=0,e=c.length;e\u003ed;d++)c[d].setMasterVolume(a)},b.getVolume=function(){return this._masterVolume},b.setMute=function(a){if(null==a)return!1;if(this._masterMute=a,!this.activePlugin||!this.activePlugin.setMute||!this.activePlugin.setMute(a))for(var b=this._instances,c=0,d=b.length;d\u003ec;c++)b[c].setMasterMute(a);return!0},b.getMute=function(){return this._masterMute},b.setDefaultPlayProps=function(a,c){a=b._getSrcById(a),b._defaultPlayPropsHash[b._parsePath(a.src).src]=createjs.PlayPropsConfig.create(c)},b.getDefaultPlayProps=function(a){return a=b._getSrcById(a),b._defaultPlayPropsHash[b._parsePath(a.src).src]},b._playInstance=function(a,c){var d=b._defaultPlayPropsHash[a.src]||{};if(null==c.interrupt\u0026\u0026(c.interrupt=d.interrupt||b.defaultInterruptBehavior),null==c.delay\u0026\u0026(c.delay=d.delay||0),null==c.offset\u0026\u0026(c.offset=a.getPosition()),null==c.loop\u0026\u0026(c.loop=a.loop),null==c.volume\u0026\u0026(c.volume=a.volume),null==c.pan\u0026\u0026(c.pan=a.pan),0==c.delay){var e=b._beginPlaying(a,c);if(!e)return!1}else{var f=setTimeout(function(){b._beginPlaying(a,c)},c.delay);a.delayTimeoutId=f}return this._instances.push(a),!0},b._beginPlaying=function(b,c){if(!a.add(b,c.interrupt))return!1;var d=b._beginPlaying(c);if(!d){var e=createjs.indexOf(this._instances,b);return e\u003e-1\u0026\u0026this._instances.splice(e,1),!1}return!0},b._getSrcById=function(a){return b._idHash[a]||{src:a}},b._playFinished=function(b){a.remove(b);var c=createjs.indexOf(this._instances,b);c\u003e-1\u0026\u0026this._instances.splice(c,1)},createjs.Sound=Sound,a.channels={},a.create=function(b,c){var d=a.get(b);return null==d?(a.channels[b]=new a(b,c),!0):!1},a.removeSrc=function(b){var c=a.get(b);return null==c?!1:(c._removeAll(),delete a.channels[b],!0)},a.removeAll=function(){for(var b in a.channels)a.channels[b]._removeAll();a.channels={}},a.add=function(b,c){var d=a.get(b.src);return null==d?!1:d._add(b,c)},a.remove=function(b){var c=a.get(b.src);return null==c?!1:(c._remove(b),!0)},a.maxPerChannel=function(){return c.maxDefault},a.get=function(b){return a.channels[b]};var c=a.prototype;c.constructor=a,c.src=null,c.max=null,c.maxDefault=100,c.length=0,c.init=function(a,b){this.src=a,this.max=b||this.maxDefault,-1==this.max\u0026\u0026(this.max=this.maxDefault),this._instances=[]},c._get=function(a){return this._instances[a]},c._add=function(a,b){return this._getSlot(b,a)?(this._instances.push(a),this.length++,!0):!1},c._remove=function(a){var b=createjs.indexOf(this._instances,a);return-1==b?!1:(this._instances.splice(b,1),this.length--,!0)},c._removeAll=function(){for(var a=this.length-1;a\u003e=0;a--)this._instances[a].stop()},c._getSlot=function(a){var b,c;if(a!=Sound.INTERRUPT_NONE\u0026\u0026(c=this._get(0),null==c))return!0;for(var d=0,e=this.max;e\u003ed;d++){if(b=this._get(d),null==b)return!0;if(b.playState==Sound.PLAY_FINISHED||b.playState==Sound.PLAY_INTERRUPTED||b.playState==Sound.PLAY_FAILED){c=b;break}a!=Sound.INTERRUPT_NONE\u0026\u0026(a==Sound.INTERRUPT_EARLY\u0026\u0026b.getPosition()\u003cc.getPosition()||a==Sound.INTERRUPT_LATE\u0026\u0026b.getPosition()\u003ec.getPosition())\u0026\u0026(c=b)}return null!=c?(c._interrupt(),this._remove(c),!0):!1},c.toString=function(){return\"[Sound SoundChannel]\"}}(),this.createjs=this.createjs||{},function(){\"use strict\";var AbstractSoundInstance=function(a,b,c,d){this.EventDispatcher_constructor(),this.src=a,this.uniqueId=-1,this.playState=null,this.delayTimeoutId=null,this._volume=1,Object.defineProperty(this,\"volume\",{get:this.getVolume,set:this.setVolume}),this._pan=0,Object.defineProperty(this,\"pan\",{get:this.getPan,set:this.setPan}),this._startTime=Math.max(0,b||0),Object.defineProperty(this,\"startTime\",{get:this.getStartTime,set:this.setStartTime}),this._duration=Math.max(0,c||0),Object.defineProperty(this,\"duration\",{get:this.getDuration,set:this.setDuration}),this._playbackResource=null,Object.defineProperty(this,\"playbackResource\",{get:this.getPlaybackResource,set:this.setPlaybackResource}),d!==!1\u0026\u0026d!==!0\u0026\u0026this.setPlaybackResource(d),this._position=0,Object.defineProperty(this,\"position\",{get:this.getPosition,set:this.setPosition}),this._loop=0,Object.defineProperty(this,\"loop\",{get:this.getLoop,set:this.setLoop}),this._muted=!1,Object.defineProperty(this,\"muted\",{get:this.getMuted,set:this.setMuted}),this._paused=!1,Object.defineProperty(this,\"paused\",{get:this.getPaused,set:this.setPaused})},a=createjs.extend(AbstractSoundInstance,createjs.EventDispatcher);a.play=function(a,b,c,d,e,f){var g;return g=createjs.PlayPropsConfig.create(a instanceof Object||a instanceof createjs.PlayPropsConfig?a:{interrupt:a,delay:b,offset:c,loop:d,volume:e,pan:f}),this.playState==createjs.Sound.PLAY_SUCCEEDED?(this.applyPlayProps(g),void(this._paused\u0026\u0026this.setPaused(!1))):(this._cleanUp(),createjs.Sound._playInstance(this,g),this)},a.stop=function(){return this._position=0,this._paused=!1,this._handleStop(),this._cleanUp(),this.playState=createjs.Sound.PLAY_FINISHED,this},a.destroy=function(){this._cleanUp(),this.src=null,this.playbackResource=null,this.removeAllEventListeners()},a.applyPlayProps=function(a){return null!=a.offset\u0026\u0026this.setPosition(a.offset),null!=a.loop\u0026\u0026this.setLoop(a.loop),null!=a.volume\u0026\u0026this.setVolume(a.volume),null!=a.pan\u0026\u0026this.setPan(a.pan),null!=a.startTime\u0026\u0026(this.setStartTime(a.startTime),this.setDuration(a.duration)),this},a.toString=function(){return\"[AbstractSoundInstance]\"},a.getPaused=function(){return this._paused},a.setPaused=function(a){return a!==!0\u0026\u0026a!==!1||this._paused==a||1==a\u0026\u0026this.playState!=createjs.Sound.PLAY_SUCCEEDED?void 0:(this._paused=a,a?this._pause():this._resume(),clearTimeout(this.delayTimeoutId),this)},a.setVolume=function(a){return a==this._volume?this:(this._volume=Math.max(0,Math.min(1,a)),this._muted||this._updateVolume(),this)},a.getVolume=function(){return this._volume},a.setMuted=function(a){return a===!0||a===!1?(this._muted=a,this._updateVolume(),this):void 0},a.getMuted=function(){return this._muted},a.setPan=function(a){return a==this._pan?this:(this._pan=Math.max(-1,Math.min(1,a)),this._updatePan(),this)},a.getPan=function(){return this._pan},a.getPosition=function(){return this._paused||this.playState!=createjs.Sound.PLAY_SUCCEEDED||(this._position=this._calculateCurrentPosition()),this._position},a.setPosition=function(a){return this._position=Math.max(0,a),this.playState==createjs.Sound.PLAY_SUCCEEDED\u0026\u0026this._updatePosition(),this},a.getStartTime=function(){return this._startTime},a.setStartTime=function(a){return a==this._startTime?this:(this._startTime=Math.max(0,a||0),this._updateStartTime(),this)},a.getDuration=function(){return this._duration},a.setDuration=function(a){return a==this._duration?this:(this._duration=Math.max(0,a||0),this._updateDuration(),this)},a.setPlaybackResource=function(a){return this._playbackResource=a,0==this._duration\u0026\u0026this._setDurationFromSource(),this},a.getPlaybackResource=function(){return this._playbackResource},a.getLoop=function(){return this._loop},a.setLoop=function(a){null!=this._playbackResource\u0026\u0026(0!=this._loop\u0026\u00260==a?this._removeLooping(a):0==this._loop\u0026\u00260!=a\u0026\u0026this._addLooping(a)),this._loop=a},a._sendEvent=function(a){var b=new createjs.Event(a);this.dispatchEvent(b)},a._cleanUp=function(){clearTimeout(this.delayTimeoutId),this._handleCleanUp(),this._paused=!1,createjs.Sound._playFinished(this)},a._interrupt=function(){this._cleanUp(),this.playState=createjs.Sound.PLAY_INTERRUPTED,this._sendEvent(\"interrupted\")},a._beginPlaying=function(a){return this.setPosition(a.offset),this.setLoop(a.loop),this.setVolume(a.volume),this.setPan(a.pan),null!=a.startTime\u0026\u0026(this.setStartTime(a.startTime),this.setDuration(a.duration)),null!=this._playbackResource\u0026\u0026this._position\u003cthis._duration?(this._paused=!1,this._handleSoundReady(),this.playState=createjs.Sound.PLAY_SUCCEEDED,this._sendEvent(\"succeeded\"),!0):(this._playFailed(),!1)},a._playFailed=function(){this._cleanUp(),this.playState=createjs.Sound.PLAY_FAILED,this._sendEvent(\"failed\")},a._handleSoundComplete=function(){return this._position=0,0!=this._loop?(this._loop--,this._handleLoop(),void this._sendEvent(\"loop\")):(this._cleanUp(),this.playState=createjs.Sound.PLAY_FINISHED,void this._sendEvent(\"complete\"))},a._handleSoundReady=function(){},a._updateVolume=function(){},a._updatePan=function(){},a._updateStartTime=function(){},a._updateDuration=function(){},a._setDurationFromSource=function(){},a._calculateCurrentPosition=function(){},a._updatePosition=function(){},a._removeLooping=function(){},a._addLooping=function(){},a._pause=function(){},a._resume=function(){},a._handleStop=function(){},a._handleCleanUp=function(){},a._handleLoop=function(){},createjs.AbstractSoundInstance=createjs.promote(AbstractSoundInstance,\"EventDispatcher\"),createjs.DefaultSoundInstance=createjs.AbstractSoundInstance}(),this.createjs=this.createjs||{},function(){\"use strict\";var AbstractPlugin=function(){this._capabilities=null,this._loaders={},this._audioSources={},this._soundInstances={},this._volume=1,this._loaderClass,this._soundInstanceClass},a=AbstractPlugin.prototype;AbstractPlugin._capabilities=null,AbstractPlugin.isSupported=function(){return!0},a.register=function(a){var b=this._loaders[a.src];return b\u0026\u0026!b.canceled?this._loaders[a.src]:(this._audioSources[a.src]=!0,this._soundInstances[a.src]=[],b=new this._loaderClass(a),b.on(\"complete\",this._handlePreloadComplete,this),this._loaders[a.src]=b,b)},a.preload=function(a){a.on(\"error\",this._handlePreloadError,this),a.load()},a.isPreloadStarted=function(a){return null!=this._audioSources[a]},a.isPreloadComplete=function(a){return!(null==this._audioSources[a]||1==this._audioSources[a])},a.removeSound=function(a){if(this._soundInstances[a]){for(var b=this._soundInstances[a].length;b--;){var c=this._soundInstances[a][b];c.destroy()}delete this._soundInstances[a],delete this._audioSources[a],this._loaders[a]\u0026\u0026this._loaders[a].destroy(),delete this._loaders[a]}},a.removeAllSounds=function(){for(var a in this._audioSources)this.removeSound(a)},a.create=function(a,b,c){this.isPreloadStarted(a)||this.preload(this.register(a));var d=new this._soundInstanceClass(a,b,c,this._audioSources[a]);return this._soundInstances[a].push(d),d},a.setVolume=function(a){return this._volume=a,this._updateVolume(),!0},a.getVolume=function(){return this._volume},a.setMute=function(){return this._updateVolume(),!0},a.toString=function(){return\"[AbstractPlugin]\"},a._handlePreloadComplete=function(a){var b=a.target.getItem().src;this._audioSources[b]=a.result;for(var c=0,d=this._soundInstances[b].length;d\u003ec;c++){var e=this._soundInstances[b][c];e.setPlaybackResource(this._audioSources[b])}},a._handlePreloadError=function(){},a._updateVolume=function(){},createjs.AbstractPlugin=AbstractPlugin}(),this.createjs=this.createjs||{},function(){\"use strict\";function a(a){this.AbstractLoader_constructor(a,!0,createjs.AbstractLoader.SOUND)}var b=createjs.extend(a,createjs.AbstractLoader);a.context=null,b.toString=function(){return\"[WebAudioLoader]\"},b._createRequest=function(){this._request=new createjs.XHRRequest(this._item,!1),this._request.setResponseType(\"arraybuffer\")},b._sendComplete=function(){a.context.decodeAudioData(this._rawResult,createjs.proxy(this._handleAudioDecoded,this),createjs.proxy(this._sendError,this))},b._handleAudioDecoded=function(a){this._result=a,this.AbstractLoader__sendComplete()},createjs.WebAudioLoader=createjs.promote(a,\"AbstractLoader\")}(),this.createjs=this.createjs||{},function(){\"use strict\";function WebAudioSoundInstance(a,c,d,e){this.AbstractSoundInstance_constructor(a,c,d,e),this.gainNode=b.context.createGain(),this.panNode=b.context.createPanner(),this.panNode.panningModel=b._panningModel,this.panNode.connect(this.gainNode),this._updatePan(),this.sourceNode=null,this._soundCompleteTimeout=null,this._sourceNodeNext=null,this._playbackStartTime=0,this._endedHandler=createjs.proxy(this._handleSoundComplete,this)}var a=createjs.extend(WebAudioSoundInstance,createjs.AbstractSoundInstance),b=WebAudioSoundInstance;b.context=null,b._scratchBuffer=null,b.destinationNode=null,b._panningModel=\"equalpower\",a.destroy=function(){this.AbstractSoundInstance_destroy(),this.panNode.disconnect(0),this.panNode=null,this.gainNode.disconnect(0),this.gainNode=null},a.toString=function(){return\"[WebAudioSoundInstance]\"},a._updatePan=function(){this.panNode.setPosition(this._pan,0,-.5)},a._removeLooping=function(){this._sourceNodeNext=this._cleanUpAudioNode(this._sourceNodeNext)},a._addLooping=function(){this.playState==createjs.Sound.PLAY_SUCCEEDED\u0026\u0026(this._sourceNodeNext=this._createAndPlayAudioNode(this._playbackStartTime,0))},a._setDurationFromSource=function(){this._duration=1e3*this.playbackResource.duration},a._handleCleanUp=function(){this.sourceNode\u0026\u0026this.playState==createjs.Sound.PLAY_SUCCEEDED\u0026\u0026(this.sourceNode=this._cleanUpAudioNode(this.sourceNode),this._sourceNodeNext=this._cleanUpAudioNode(this._sourceNodeNext)),0!=this.gainNode.numberOfOutputs\u0026\u0026this.gainNode.disconnect(0),clearTimeout(this._soundCompleteTimeout),this._playbackStartTime=0},a._cleanUpAudioNode=function(a){if(a){a.stop(0),a.disconnect(0);try{a.buffer=b._scratchBuffer}catch(c){}a=null}return a},a._handleSoundReady=function(){this.gainNode.connect(b.destinationNode);var a=.001*this._duration,c=.001*this._position;c\u003ea\u0026\u0026(c=a),this.sourceNode=this._createAndPlayAudioNode(b.context.currentTime-a,c),this._playbackStartTime=this.sourceNode.startTime-c,this._soundCompleteTimeout=setTimeout(this._endedHandler,1e3*(a-c)),0!=this._loop\u0026\u0026(this._sourceNodeNext=this._createAndPlayAudioNode(this._playbackStartTime,0))},a._createAndPlayAudioNode=function(a,c){var d=b.context.createBufferSource();d.buffer=this.playbackResource,d.connect(this.panNode);var e=.001*this._duration;return d.startTime=a+e,d.start(d.startTime,c+.001*this._startTime,e-c),d},a._pause=function(){this._position=1e3*(b.context.currentTime-this._playbackStartTime),this.sourceNode=this._cleanUpAudioNode(this.sourceNode),this._sourceNodeNext=this._cleanUpAudioNode(this._sourceNodeNext),0!=this.gainNode.numberOfOutputs\u0026\u0026this.gainNode.disconnect(0),clearTimeout(this._soundCompleteTimeout)},a._resume=function(){this._handleSoundReady()},a._updateVolume=function(){var a=this._muted?0:this._volume;a!=this.gainNode.gain.value\u0026\u0026(this.gainNode.gain.value=a)},a._calculateCurrentPosition=function(){return 1e3*(b.context.currentTime-this._playbackStartTime)},a._updatePosition=function(){this.sourceNode=this._cleanUpAudioNode(this.sourceNode),this._sourceNodeNext=this._cleanUpAudioNode(this._sourceNodeNext),clearTimeout(this._soundCompleteTimeout),this._paused||this._handleSoundReady()},a._handleLoop=function(){this._cleanUpAudioNode(this.sourceNode),this.sourceNode=this._sourceNodeNext,this._playbackStartTime=this.sourceNode.startTime,this._sourceNodeNext=this._createAndPlayAudioNode(this._playbackStartTime,0),this._soundCompleteTimeout=setTimeout(this._endedHandler,this._duration)},a._updateDuration=function(){this.playState==createjs.Sound.PLAY_SUCCEEDED\u0026\u0026(this._pause(),this._resume())},createjs.WebAudioSoundInstance=createjs.promote(WebAudioSoundInstance,\"AbstractSoundInstance\")}(),this.createjs=this.createjs||{},function(){\"use strict\";function WebAudioPlugin(){this.AbstractPlugin_constructor(),this._panningModel=b._panningModel,this.context=b.context,this.dynamicsCompressorNode=this.context.createDynamicsCompressor(),this.dynamicsCompressorNode.connect(this.context.destination),this.gainNode=this.context.createGain(),this.gainNode.connect(this.dynamicsCompressorNode),createjs.WebAudioSoundInstance.destinationNode=this.gainNode,this._capabilities=b._capabilities,this._loaderClass=createjs.WebAudioLoader,this._soundInstanceClass=createjs.WebAudioSoundInstance,this._addPropsToClasses()}var a=createjs.extend(WebAudioPlugin,createjs.AbstractPlugin),b=WebAudioPlugin;b._capabilities=null,b._panningModel=\"equalpower\",b.context=null,b._scratchBuffer=null,b._unlocked=!1,b.isSupported=function(){var a=createjs.BrowserDetect.isIOS||createjs.BrowserDetect.isAndroid||createjs.BrowserDetect.isBlackberry;return\"file:\"!=location.protocol||a||this._isFileXHRSupported()?(b._generateCapabilities(),null==b.context?!1:!0):!1},b.playEmptySound=function(){if(null!=b.context){var a=b.context.createBufferSource();a.buffer=b._scratchBuffer,a.connect(b.context.destination),a.start(0,0,0)}},b._isFileXHRSupported=function(){var a=!0,b=new XMLHttpRequest;try{b.open(\"GET\",\"WebAudioPluginTest.fail\",!1)}catch(c){return a=!1}b.onerror=function(){a=!1},b.onload=function(){a=404==this.status||200==this.status||0==this.status\u0026\u0026\"\"!=this.response};try{b.send()}catch(c){a=!1}return a},b._generateCapabilities=function(){if(null==b._capabilities){var a=document.createElement(\"audio\");if(null==a.canPlayType)return null;if(null==b.context)if(window.AudioContext)b.context=new AudioContext;else{if(!window.webkitAudioContext)return null;b.context=new webkitAudioContext}null==b._scratchBuffer\u0026\u0026(b._scratchBuffer=b.context.createBuffer(1,1,22050)),b._compatibilitySetUp(),\"ontouchstart\"in window\u0026\u0026\"running\"!=b.context.state\u0026\u0026(b._unlock(),document.addEventListener(\"mousedown\",b._unlock,!0),document.addEventListener(\"touchend\",b._unlock,!0)),b._capabilities={panning:!0,volume:!0,tracks:-1};for(var c=createjs.Sound.SUPPORTED_EXTENSIONS,d=createjs.Sound.EXTENSION_MAP,e=0,f=c.length;f\u003ee;e++){var g=c[e],h=d[g]||g;b._capabilities[g]=\"no\"!=a.canPlayType(\"audio/\"+g)\u0026\u0026\"\"!=a.canPlayType(\"audio/\"+g)||\"no\"!=a.canPlayType(\"audio/\"+h)\u0026\u0026\"\"!=a.canPlayType(\"audio/\"+h)}b.context.destination.numberOfChannels\u003c2\u0026\u0026(b._capabilities.panning=!1)}},b._compatibilitySetUp=function(){if(b._panningModel=\"equalpower\",!b.context.createGain){b.context.createGain=b.context.createGainNode;var a=b.context.createBufferSource();a.__proto__.start=a.__proto__.noteGrainOn,a.__proto__.stop=a.__proto__.noteOff,b._panningModel=0}},b._unlock=function(){b._unlocked||(b.playEmptySound(),\"running\"==b.context.state\u0026\u0026(document.removeEventListener(\"mousedown\",b._unlock,!0),document.removeEventListener(\"touchend\",b._unlock,!0),b._unlocked=!0))},a.toString=function(){return\"[WebAudioPlugin]\"},a._addPropsToClasses=function(){var a=this._soundInstanceClass;a.context=this.context,a._scratchBuffer=b._scratchBuffer,a.destinationNode=this.gainNode,a._panningModel=this._panningModel,this._loaderClass.context=this.context},a._updateVolume=function(){var a=createjs.Sound._masterMute?0:this._volume;a!=this.gainNode.gain.value\u0026\u0026(this.gainNode.gain.value=a)},createjs.WebAudioPlugin=createjs.promote(WebAudioPlugin,\"AbstractPlugin\")}(),this.createjs=this.createjs||{},function(){\"use strict\";function HTMLAudioTagPool(){throw\"HTMLAudioTagPool cannot be instantiated\"}function a(){this._tags=[]}var b=HTMLAudioTagPool;b._tags={},b._tagPool=new a,b._tagUsed={},b.get=function(a){var c=b._tags[a];return null==c?(c=b._tags[a]=b._tagPool.get(),c.src=a):b._tagUsed[a]?(c=b._tagPool.get(),c.src=a):b._tagUsed[a]=!0,c},b.set=function(a,c){c==b._tags[a]?b._tagUsed[a]=!1:b._tagPool.set(c)},b.remove=function(a){var c=b._tags[a];return null==c?!1:(b._tagPool.set(c),delete b._tags[a],delete b._tagUsed[a],!0)},b.getDuration=function(a){var c=b._tags[a];return null!=c\u0026\u0026c.duration?1e3*c.duration:0},createjs.HTMLAudioTagPool=HTMLAudioTagPool;var c=a.prototype;c.constructor=a,c.get=function(){var a;return a=0==this._tags.length?this._createTag():this._tags.pop(),null==a.parentNode\u0026\u0026document.body.appendChild(a),a},c.set=function(a){var b=createjs.indexOf(this._tags,a);-1==b\u0026\u0026(this._tags.src=null,this._tags.push(a))},c.toString=function(){return\"[TagPool]\"},c._createTag=function(){var a=document.createElement(\"audio\");return a.autoplay=!1,a.preload=\"none\",a}}(),this.createjs=this.createjs||{},function(){\"use strict\";function HTMLAudioSoundInstance(a,b,c,d){this.AbstractSoundInstance_constructor(a,b,c,d),this._audioSpriteStopTime=null,this._delayTimeoutId=null,this._endedHandler=createjs.proxy(this._handleSoundComplete,this),this._readyHandler=createjs.proxy(this._handleTagReady,this),this._stalledHandler=createjs.proxy(this._playFailed,this),this._audioSpriteEndHandler=createjs.proxy(this._handleAudioSpriteLoop,this),this._loopHandler=createjs.proxy(this._handleSoundComplete,this),c?this._audioSpriteStopTime=.001*(b+c):this._duration=createjs.HTMLAudioTagPool.getDuration(this.src)}var a=createjs.extend(HTMLAudioSoundInstance,createjs.AbstractSoundInstance);a.setMasterVolume=function(){this._updateVolume()},a.setMasterMute=function(){this._updateVolume()},a.toString=function(){return\"[HTMLAudioSoundInstance]\"},a._removeLooping=function(){null!=this._playbackResource\u0026\u0026(this._playbackResource.loop=!1,this._playbackResource.removeEventListener(createjs.HTMLAudioPlugin._AUDIO_SEEKED,this._loopHandler,!1))},a._addLooping=function(){null==this._playbackResource||this._audioSpriteStopTime||(this._playbackResource.addEventListener(createjs.HTMLAudioPlugin._AUDIO_SEEKED,this._loopHandler,!1),this._playbackResource.loop=!0)},a._handleCleanUp=function(){var a=this._playbackResource;if(null!=a){a.pause(),a.loop=!1,a.removeEventListener(createjs.HTMLAudioPlugin._AUDIO_ENDED,this._endedHandler,!1),a.removeEventListener(createjs.HTMLAudioPlugin._AUDIO_READY,this._readyHandler,!1),a.removeEventListener(createjs.HTMLAudioPlugin._AUDIO_STALLED,this._stalledHandler,!1),a.removeEventListener(createjs.HTMLAudioPlugin._AUDIO_SEEKED,this._loopHandler,!1),a.removeEventListener(createjs.HTMLAudioPlugin._TIME_UPDATE,this._audioSpriteEndHandler,!1);try{a.currentTime=this._startTime}catch(b){}createjs.HTMLAudioTagPool.set(this.src,a),this._playbackResource=null}},a._beginPlaying=function(a){return this._playbackResource=createjs.HTMLAudioTagPool.get(this.src),this.AbstractSoundInstance__beginPlaying(a)},a._handleSoundReady=function(){if(4!==this._playbackResource.readyState){var a=this._playbackResource;return a.addEventListener(createjs.HTMLAudioPlugin._AUDIO_READY,this._readyHandler,!1),a.addEventListener(createjs.HTMLAudioPlugin._AUDIO_STALLED,this._stalledHandler,!1),a.preload=\"auto\",void a.load()}this._updateVolume(),this._playbackResource.currentTime=.001*(this._startTime+this._position),this._audioSpriteStopTime?this._playbackResource.addEventListener(createjs.HTMLAudioPlugin._TIME_UPDATE,this._audioSpriteEndHandler,!1):(this._playbackResource.addEventListener(createjs.HTMLAudioPlugin._AUDIO_ENDED,this._endedHandler,!1),0!=this._loop\u0026\u0026(this._playbackResource.addEventListener(createjs.HTMLAudioPlugin._AUDIO_SEEKED,this._loopHandler,!1),this._playbackResource.loop=!0)),this._playbackResource.play()},a._handleTagReady=function(){this._playbackResource.removeEventListener(createjs.HTMLAudioPlugin._AUDIO_READY,this._readyHandler,!1),this._playbackResource.removeEventListener(createjs.HTMLAudioPlugin._AUDIO_STALLED,this._stalledHandler,!1),this._handleSoundReady()},a._pause=function(){this._playbackResource.pause()},a._resume=function(){this._playbackResource.play()},a._updateVolume=function(){if(null!=this._playbackResource){var a=this._muted||createjs.Sound._masterMute?0:this._volume*createjs.Sound._masterVolume;a!=this._playbackResource.volume\u0026\u0026(this._playbackResource.volume=a)}},a._calculateCurrentPosition=function(){return 1e3*this._playbackResource.currentTime-this._startTime},a._updatePosition=function(){this._playbackResource.removeEventListener(createjs.HTMLAudioPlugin._AUDIO_SEEKED,this._loopHandler,!1),this._playbackResource.addEventListener(createjs.HTMLAudioPlugin._AUDIO_SEEKED,this._handleSetPositionSeek,!1);try{this._playbackResource.currentTime=.001*(this._position+this._startTime)}catch(a){this._handleSetPositionSeek(null)}},a._handleSetPositionSeek=function(){null!=this._playbackResource\u0026\u0026(this._playbackResource.removeEventListener(createjs.HTMLAudioPlugin._AUDIO_SEEKED,this._handleSetPositionSeek,!1),this._playbackResource.addEventListener(createjs.HTMLAudioPlugin._AUDIO_SEEKED,this._loopHandler,!1))},a._handleAudioSpriteLoop=function(){this._playbackResource.currentTime\u003c=this._audioSpriteStopTime||(this._playbackResource.pause(),0==this._loop?this._handleSoundComplete(null):(this._position=0,this._loop--,this._playbackResource.currentTime=.001*this._startTime,this._paused||this._playbackResource.play(),this._sendEvent(\"loop\")))},a._handleLoop=function(){0==this._loop\u0026\u0026(this._playbackResource.loop=!1,this._playbackResource.removeEventListener(createjs.HTMLAudioPlugin._AUDIO_SEEKED,this._loopHandler,!1))},a._updateStartTime=function(){this._audioSpriteStopTime=.001*(this._startTime+this._duration),this.playState==createjs.Sound.PLAY_SUCCEEDED\u0026\u0026(this._playbackResource.removeEventListener(createjs.HTMLAudioPlugin._AUDIO_ENDED,this._endedHandler,!1),this._playbackResource.addEventListener(createjs.HTMLAudioPlugin._TIME_UPDATE,this._audioSpriteEndHandler,!1))},a._updateDuration=function(){this._audioSpriteStopTime=.001*(this._startTime+this._duration),this.playState==createjs.Sound.PLAY_SUCCEEDED\u0026\u0026(this._playbackResource.removeEventListener(createjs.HTMLAudioPlugin._AUDIO_ENDED,this._endedHandler,!1),this._playbackResource.addEventListener(createjs.HTMLAudioPlugin._TIME_UPDATE,this._audioSpriteEndHandler,!1))},a._setDurationFromSource=function(){this._duration=createjs.HTMLAudioTagPool.getDuration(this.src),this._playbackResource=null},createjs.HTMLAudioSoundInstance=createjs.promote(HTMLAudioSoundInstance,\"AbstractSoundInstance\")}(),this.createjs=this.createjs||{},function(){\"use strict\";function HTMLAudioPlugin(){this.AbstractPlugin_constructor(),this.defaultNumChannels=2,this._capabilities=b._capabilities,this._loaderClass=createjs.SoundLoader,this._soundInstanceClass=createjs.HTMLAudioSoundInstance}var a=createjs.extend(HTMLAudioPlugin,createjs.AbstractPlugin),b=HTMLAudioPlugin;b.MAX_INSTANCES=30,b._AUDIO_READY=\"canplaythrough\",b._AUDIO_ENDED=\"ended\",b._AUDIO_SEEKED=\"seeked\",b._AUDIO_STALLED=\"stalled\",b._TIME_UPDATE=\"timeupdate\",b._capabilities=null,b.isSupported=function(){return b._generateCapabilities(),null!=b._capabilities},b._generateCapabilities=function(){if(null==b._capabilities){var a=document.createElement(\"audio\");if(null==a.canPlayType)return null;b._capabilities={panning:!1,volume:!0,tracks:-1};for(var c=createjs.Sound.SUPPORTED_EXTENSIONS,d=createjs.Sound.EXTENSION_MAP,e=0,f=c.length;f\u003ee;e++){var g=c[e],h=d[g]||g;b._capabilities[g]=\"no\"!=a.canPlayType(\"audio/\"+g)\u0026\u0026\"\"!=a.canPlayType(\"audio/\"+g)||\"no\"!=a.canPlayType(\"audio/\"+h)\u0026\u0026\"\"!=a.canPlayType(\"audio/\"+h)}}},a.register=function(a){var b=createjs.HTMLAudioTagPool.get(a.src),c=this.AbstractPlugin_register(a);return c.setTag(b),c},a.removeSound=function(a){this.AbstractPlugin_removeSound(a),createjs.HTMLAudioTagPool.remove(a)},a.create=function(a,b,c){var d=this.AbstractPlugin_create(a,b,c);return d.setPlaybackResource(null),d},a.toString=function(){return\"[HTMLAudioPlugin]\"},a.setVolume=a.getVolume=a.setMute=null,createjs.HTMLAudioPlugin=createjs.promote(HTMLAudioPlugin,\"AbstractPlugin\")}();\n\nH5P.SoundJS = this.createjs.Sound;\n\nthis.createjs = old || this.createjs;\n"
,"scripts/question.js":"H5P.Question = (function ($, EventDispatcher, JoubelUI) {\n\n /**\n * Extending this class make it alot easier to create tasks for other\n * content types.\n *\n * @class H5P.Question\n * @extends H5P.EventDispatcher\n * @param {string} type\n */\n function Question(type) {\n var self = this;\n\n // Inheritance\n EventDispatcher.call(self);\n\n // Register default section order\n self.order = [\u0027video\u0027, \u0027image\u0027, \u0027introduction\u0027, \u0027content\u0027, \u0027explanation\u0027, \u0027feedback\u0027, \u0027buttons\u0027, \u0027read\u0027];\n\n // Keep track of registered sections\n var sections = {};\n\n // Buttons\n var buttons = {};\n var buttonOrder = [];\n\n // Wrapper when attached\n var $wrapper;\n\n // Click element\n var clickElement;\n\n // ScoreBar\n var scoreBar;\n\n // Keep track of the feedback\u0027s visual status.\n var showFeedback;\n\n // Keep track of which buttons are scheduled for hiding.\n var buttonsToHide = [];\n\n // Keep track of which buttons are scheduled for showing.\n var buttonsToShow = [];\n\n // Keep track of the hiding and showing of buttons.\n var toggleButtonsTimer;\n var toggleButtonsTransitionTimer;\n var buttonTruncationTimer;\n\n // Keeps track of initialization of question\n var initialized = false;\n\n /**\n * @type {Object} behaviour Behaviour of Question\n * @property {Boolean} behaviour.disableFeedback Set to true to disable feedback section\n */\n var behaviour = {\n disableFeedback: false,\n disableReadSpeaker: false\n };\n\n // Keeps track of thumb state\n var imageThumb = true;\n\n // Keeps track of image transitions\n var imageTransitionTimer;\n\n // Keep track of whether sections is transitioning.\n var sectionsIsTransitioning = false;\n\n // Keep track of auto play state\n var disableAutoPlay = false;\n\n // Feedback transition timer\n var feedbackTransitionTimer;\n\n // Used when reading messages to the user\n var $read, readText;\n\n /**\n * Register section with given content.\n *\n * @private\n * @param {string} section ID of the section\n * @param {(string|H5P.jQuery)} [content]\n */\n var register = function (section, content) {\n sections[section] = {};\n var $e = sections[section].$element = $(\u0027\u003cdiv/\u003e\u0027, {\n \u0027class\u0027: \u0027h5p-question-\u0027 + section,\n });\n if (content) {\n $e[content instanceof $ ? \u0027append\u0027 : \u0027html\u0027](content);\n }\n };\n\n /**\n * Update registered section with content.\n *\n * @private\n * @param {string} section ID of the section\n * @param {(string|H5P.jQuery)} content\n */\n var update = function (section, content) {\n if (content instanceof $) {\n sections[section].$element.html(\u0027\u0027).append(content);\n }\n else {\n sections[section].$element.html(content);\n }\n };\n\n /**\n * Insert element with given ID into the DOM.\n *\n * @private\n * @param {array|Array|string[]} order\n * List with ordered element IDs\n * @param {string} id\n * ID of the element to be inserted\n * @param {Object} elements\n * Maps ID to the elements\n * @param {H5P.jQuery} $container\n * Parent container of the elements\n */\n var insert = function (order, id, elements, $container) {\n // Try to find an element id should be after\n for (var i = 0; i \u003c order.length; i++) {\n if (order[i] === id) {\n // Found our pos\n while (i \u003e 0 \u0026\u0026\n (elements[order[i - 1]] === undefined ||\n !elements[order[i - 1]].isVisible)) {\n i--;\n }\n if (i === 0) {\n // We are on top.\n elements[id].$element.prependTo($container);\n }\n else {\n // Add after element\n elements[id].$element.insertAfter(elements[order[i - 1]].$element);\n }\n elements[id].isVisible = true;\n break;\n }\n }\n };\n\n /**\n * Make feedback into a popup and position relative to click.\n *\n * @private\n * @param {string} [closeText] Text for the close button\n */\n var makeFeedbackPopup = function (closeText) {\n var $element = sections.feedback.$element;\n var $click = (clickElement != null ? clickElement.$element : null);\n\n $element\n .appendTo(sections.content.$element)\n .addClass(\u0027h5p-question-popup\u0027);\n\n $element.parent()\n .addClass(\u0027h5p-has-question-popup\u0027);\n\n // Draw the tail\n var $tail = $(\u0027\u003cdiv/\u003e\u0027, {\n \u0027class\u0027: \u0027h5p-question-feedback-tail\u0027\n }).hide()\n .appendTo($element.parent());\n\n // Draw the close button\n var $close = $(\u0027\u003cdiv/\u003e\u0027, {\n \u0027class\u0027: \u0027h5p-question-feedback-close\u0027,\n \u0027tabindex\u0027: 0,\n \u0027title\u0027: closeText,\n on: {\n click: function (event) {\n $element.remove();\n $tail.remove();\n event.preventDefault();\n },\n keydown: function (event) {\n switch (event.which) {\n case 13: // Enter\n case 32: // Space\n $element.remove();\n $tail.remove();\n event.preventDefault();\n }\n }\n }\n })\n .hide()\n .appendTo($element);\n\n if ($click != null) {\n if ($click.hasClass(\u0027correct\u0027)) {\n $element.addClass(\u0027h5p-question-feedback-correct\u0027);\n $close.show();\n sections.buttons.$element.hide();\n } else {\n sections.buttons.$element.appendTo(sections.feedback.$element);\n }\n }\n\n positionFeedbackPopup($element, $click);\n };\n\n /**\n * Position the feedback popup.\n *\n * @private\n * @param {H5P.jQuery} $element Feedback div\n * @param {H5P.jQuery} $click Visual click div\n */\n var positionFeedbackPopup = function ($element, $click) {\n var $container = $element.parent();\n var $tail = $element.siblings(\u0027.h5p-question-feedback-tail\u0027);\n var popupWidth = $element.outerWidth();\n var popupHeight = setElementHeight($element);\n var space = 15;\n var disableTail = false;\n var positionY = $container.height() / 2 - popupHeight / 2;\n var positionX = $container.width() / 2 - popupWidth / 2;\n var tailX = 0;\n var tailY = 0;\n var tailRotation = 0;\n\n if ($click != null) {\n // Edge detection for click, takes space into account\n var clickNearTop = ($click[0].offsetTop \u003c space);\n var clickNearBottom = ($click[0].offsetTop + $click.height() \u003e $container.height() - space);\n var clickNearLeft = ($click[0].offsetLeft \u003c space);\n var clickNearRight = ($click[0].offsetLeft + $click.width() \u003e $container.width() - space);\n\n // Click is not in a corner or close to edge, calculate position normally\n positionX = $click[0].offsetLeft - popupWidth / 2 + $click.width() / 2;\n positionY = $click[0].offsetTop - popupHeight - space;\n tailX = positionX + popupWidth / 2 - $tail.width() / 2;\n tailY = positionY + popupHeight - ($tail.height() / 2);\n tailRotation = 225;\n\n // If popup is outside top edge, position under click instead\n if (popupHeight + space \u003e $click[0].offsetTop) {\n positionY = $click[0].offsetTop + $click.height() + space;\n tailY = positionY - $tail.height() / 2 ;\n tailRotation = 45;\n }\n\n // If popup is outside left edge, position left\n if (positionX \u003c 0) {\n positionX = 0;\n }\n\n // If popup is outside right edge, position right\n if (positionX + popupWidth \u003e $container.width()) {\n positionX = $container.width() - popupWidth;\n }\n\n // Special cases such as corner clicks, or close to an edge, they override X and Y positions if met\n if (clickNearTop \u0026\u0026 (clickNearLeft || clickNearRight)) {\n positionX = $click[0].offsetLeft + (clickNearLeft ? $click.width() : -popupWidth);\n positionY = $click[0].offsetTop + $click.height();\n disableTail = true;\n }\n else if (clickNearBottom \u0026\u0026 (clickNearLeft || clickNearRight)) {\n positionX = $click[0].offsetLeft + (clickNearLeft ? $click.width() : -popupWidth);\n positionY = $click[0].offsetTop - popupHeight;\n disableTail = true;\n }\n else if (!clickNearTop \u0026\u0026 !clickNearBottom) {\n if (clickNearLeft || clickNearRight) {\n positionY = $click[0].offsetTop - popupHeight / 2 + $click.width() / 2;\n positionX = $click[0].offsetLeft + (clickNearLeft ? $click.width() + space : -popupWidth + -space);\n // Make sure this does not position the popup off screen\n if (positionX \u003c 0) {\n positionX = 0;\n disableTail = true;\n }\n else {\n tailX = positionX + (clickNearLeft ? - $tail.width() / 2 : popupWidth - $tail.width() / 2);\n tailY = positionY + popupHeight / 2 - $tail.height() / 2;\n tailRotation = (clickNearLeft ? 315 : 135);\n }\n }\n }\n\n // Contain popup from overflowing bottom edge\n if (positionY + popupHeight \u003e $container.height()) {\n positionY = $container.height() - popupHeight;\n\n if (popupHeight \u003e $container.height() - ($click[0].offsetTop + $click.height() + space)) {\n disableTail = true;\n }\n }\n }\n else {\n disableTail = true;\n }\n\n // Contain popup from ovreflowing top edge\n if (positionY \u003c 0) {\n positionY = 0;\n }\n\n $element.css({top: positionY, left: positionX});\n $tail.css({top: tailY, left: tailX});\n\n if (!disableTail) {\n $tail.css({\n \u0027left\u0027: tailX,\n \u0027top\u0027: tailY,\n \u0027transform\u0027: \u0027rotate(\u0027 + tailRotation + \u0027deg)\u0027\n }).show();\n }\n else {\n $tail.hide();\n }\n };\n\n /**\n * Set element max height, used for animations.\n *\n * @param {H5P.jQuery} $element\n */\n var setElementHeight = function ($element) {\n if (!$element.is(\u0027:visible\u0027)) {\n // No animation\n $element.css(\u0027max-height\u0027, \u0027none\u0027);\n return;\n }\n\n // If this element is shown in the popup, we can\u0027t set width to 100%,\n // since it already has a width set in CSS\n var isFeedbackPopup = $element.hasClass(\u0027h5p-question-popup\u0027);\n\n // Get natural element height\n var $tmp = $element.clone()\n .css({\n \u0027position\u0027: \u0027absolute\u0027,\n \u0027max-height\u0027: \u0027none\u0027,\n \u0027width\u0027: isFeedbackPopup ? \u0027\u0027 : \u0027100%\u0027\n })\n .appendTo($element.parent());\n\n // Need to take margins into account when calculating available space\n var sideMargins = parseFloat($element.css(\u0027margin-left\u0027))\n + parseFloat($element.css(\u0027margin-right\u0027));\n var tmpElWidth = $tmp.css(\u0027width\u0027) ? $tmp.css(\u0027width\u0027) : \u0027100%\u0027;\n $tmp.css(\u0027width\u0027, \u0027calc(\u0027 + tmpElWidth + \u0027 - \u0027 + sideMargins + \u0027px)\u0027);\n\n // Apply height to element\n var h = Math.round($tmp.get(0).getBoundingClientRect().height);\n var fontSize = parseFloat($element.css(\u0027fontSize\u0027));\n var relativeH = h / fontSize;\n $element.css(\u0027max-height\u0027, relativeH + \u0027em\u0027);\n $tmp.remove();\n\n if (h \u003e 0 \u0026\u0026 sections.buttons \u0026\u0026 sections.buttons.$element === $element) {\n\n // Make sure buttons section is visible\n sections.buttons.$element.addClass(\u0027h5p-question-visible\u0027);\n\n // Resize buttons after resizing button section\n setTimeout(function () {\n resizeButtons();\n }, 150);\n }\n return h;\n };\n\n /**\n * Does the actual job of hiding the buttons scheduled for hiding.\n *\n * @private\n * @param {boolean} [relocateFocus] Find a new button to focus\n */\n var hideButtons = function (relocateFocus) {\n for (var i = 0; i \u003c buttonsToHide.length; i++) {\n hideButton(buttonsToHide[i].id);\n }\n buttonsToHide = [];\n\n if (relocateFocus) {\n self.focusButton();\n }\n };\n\n /**\n * Does the actual hiding.\n * @private\n * @param {string} buttonId\n */\n var hideButton = function (buttonId) {\n // Using detach() vs hide() makes it harder to cheat.\n buttons[buttonId].$element.detach();\n buttons[buttonId].isVisible = false;\n };\n\n /**\n * Shows the buttons on the next tick. This is to avoid buttons flickering\n * If they\u0027re both added and removed on the same tick.\n *\n * @private\n */\n var toggleButtons = function () {\n\n // Clear transition timer, reevaluate if buttons will be detached\n clearTimeout(toggleButtonsTransitionTimer);\n\n // Show buttons\n for (var i = 0; i \u003c buttonsToShow.length; i++) {\n insert(buttonOrder, buttonsToShow[i].id, buttons, sections.buttons.$element);\n buttons[buttonsToShow[i].id].isVisible = true;\n }\n buttonsToShow = [];\n\n // Hide buttons\n var numToHide = 0;\n var relocateFocus = false;\n for (var j = 0; j \u003c buttonsToHide.length; j++) {\n var button = buttons[buttonsToHide[j].id];\n if (button.isVisible) {\n numToHide += 1;\n }\n if (button.$element.is(\u0027:focus\u0027)) {\n // Move focus to the first visible button.\n relocateFocus = true;\n }\n }\n\n var animationTimer = 150;\n if (sections.feedback \u0026\u0026 sections.feedback.$element.hasClass(\u0027h5p-question-popup\u0027)) {\n animationTimer = 0;\n }\n\n if (sections.buttons \u0026\u0026 numToHide === sections.buttons.$element.children().length) {\n // All buttons are going to be hidden. Hide container using transition.\n sections.buttons.$element.removeClass(\u0027h5p-question-visible\u0027);\n sections.buttons.$element.css(\u0027max-height\u0027, \u0027\u0027);\n sectionsIsTransitioning = true;\n\n // Wait for animations before detaching buttons\n toggleButtonsTransitionTimer = setTimeout(function () {\n hideButtons(relocateFocus);\n sectionsIsTransitioning = false;\n }, animationTimer);\n }\n else {\n hideButtons(relocateFocus);\n\n // Show button section\n if (!sections.buttons.$element.is(\u0027:empty\u0027)) {\n sections.buttons.$element.addClass(\u0027h5p-question-visible\u0027);\n setElementHeight(sections.buttons.$element);\n\n // Trigger resize after animation\n toggleButtonsTransitionTimer = setTimeout(function () {\n self.trigger(\u0027resize\u0027);\n }, animationTimer);\n }\n }\n\n // Resize buttons to fit container\n resizeButtons();\n\n toggleButtonsTimer = undefined;\n };\n\n /**\n * Allows for scaling of the question image.\n */\n var scaleImage = function () {\n var $imgSection = sections.image.$element;\n clearTimeout(imageTransitionTimer);\n\n // Add this here to avoid initial transition of the image making\n // content overflow. Alternatively we need to trigger a resize.\n $imgSection.addClass(\u0027animatable\u0027);\n\n if (imageThumb) {\n\n // Expand image\n $(this).attr(\u0027aria-expanded\u0027, true);\n $imgSection.addClass(\u0027h5p-question-image-fill-width\u0027);\n imageThumb = false;\n\n imageTransitionTimer = setTimeout(function () {\n self.trigger(\u0027resize\u0027);\n }, 600);\n }\n else {\n\n // Scale down image\n $(this).attr(\u0027aria-expanded\u0027, false);\n $imgSection.removeClass(\u0027h5p-question-image-fill-width\u0027);\n imageThumb = true;\n\n imageTransitionTimer = setTimeout(function () {\n self.trigger(\u0027resize\u0027);\n }, 600);\n }\n };\n\n /**\n * Get scrollable ancestor of element\n *\n * @private\n * @param {H5P.jQuery} $element\n * @param {Number} [currDepth=0] Current recursive calls to ancestor, stop at maxDepth\n * @param {Number} [maxDepth=5] Maximum depth for finding ancestor.\n * @returns {H5P.jQuery} Parent element that is scrollable\n */\n var findScrollableAncestor = function ($element, currDepth, maxDepth) {\n if (!currDepth) {\n currDepth = 0;\n }\n if (!maxDepth) {\n maxDepth = 5;\n }\n // Check validation of element or if we have reached document root\n if (!$element || !($element instanceof $) || document === $element.get(0) || currDepth \u003e= maxDepth) {\n return;\n }\n\n if ($element.css(\u0027overflow-y\u0027) === \u0027auto\u0027) {\n return $element;\n }\n else {\n return findScrollableAncestor($element.parent(), currDepth + 1, maxDepth);\n }\n };\n\n /**\n * Scroll to bottom of Question.\n *\n * @private\n */\n var scrollToBottom = function () {\n if (!$wrapper || ($wrapper.hasClass(\u0027h5p-standalone\u0027) \u0026\u0026 !H5P.isFullscreen)) {\n return; // No scroll\n }\n\n var scrollableAncestor = findScrollableAncestor($wrapper);\n\n // Scroll to bottom of scrollable ancestor\n if (scrollableAncestor) {\n scrollableAncestor.animate({\n scrollTop: $wrapper.css(\u0027height\u0027)\n }, \"slow\");\n }\n };\n\n /**\n * Resize buttons to fit container width\n *\n * @private\n */\n var resizeButtons = function () {\n if (!buttons || !sections.buttons) {\n return;\n }\n\n // Clear button truncation timer if within a button truncation function\n if (buttonTruncationTimer) {\n clearTimeout(buttonTruncationTimer);\n }\n\n // Allow button section to attach before getting width\n buttonTruncationTimer = setTimeout(function () {\n\n // A static margin is added as buffer for smoother transitions\n var buttonsWidth = 0;\n for (var i in buttons) {\n var $element = buttons[i].$element;\n if (buttons[i].isVisible) {\n\n //Calculate exact button width\n var buttonInstanceWidth = $element.get(0).offsetWidth +\n parseFloat($element.css(\u0027margin-left\u0027)) +\n parseFloat($element.css(\u0027margin-right\u0027));\n buttonsWidth += Math.ceil(buttonInstanceWidth) + 1;\n }\n }\n\n\n // Button section reduced by 1 pixel for cross-broswer consistency.\n var buttonSectionWidth = Math.floor($(sections.buttons.$element).width()) - 1;\n\n // Remove button labels if width of buttons are too wide\n if (buttonsWidth \u003e= buttonSectionWidth) {\n removeButtonLabels(buttonsWidth, buttonSectionWidth);\n }\n else {\n restoreButtonLabels(buttonsWidth, buttonSectionWidth);\n }\n buttonTruncationTimer = undefined;\n }, 0);\n };\n\n /**\n * Remove button labels until they use less than max width.\n *\n * @private\n * @param {Number} buttonsWidth Total width of all buttons\n * @param {Number} maxButtonsWidth Max width allowed for buttons\n */\n var removeButtonLabels = function (buttonsWidth, maxButtonsWidth) {\n // Reverse traversal\n for (var i = buttonOrder.length - 1; i \u003e= 0; i--) {\n var buttonId = buttonOrder[i];\n if (!buttons[buttonId].isTruncated \u0026\u0026 buttons[buttonId].isVisible) {\n var $button = buttons[buttonId].$element;\n var $tmp = $button.clone()\n .css({\n \u0027position\u0027: \u0027absolute\u0027,\n \u0027white-space\u0027: \u0027nowrap\u0027,\n \u0027max-width\u0027: \u0027none\u0027\n })\n .addClass(\u0027truncated\u0027)\n .html(\u0027\u0027)\n .appendTo($button.parent());\n\n // Calculate new total width of buttons\n buttonsWidth = buttonsWidth - $button.outerWidth(true) + $tmp.outerWidth(true);\n\n // Remove label\n $button.attr(\u0027aria-label\u0027, $button.text());\n $button.html(\u0027\u0027);\n $button.addClass(\u0027truncated\u0027);\n buttons[buttonId].isTruncated = true;\n $tmp.remove();\n if (buttonsWidth \u003c maxButtonsWidth) {\n // Buttons are small enough.\n return;\n }\n }\n }\n };\n\n /**\n * Restore button labels until it fills maximum possible width without exceeding the max width.\n *\n * @private\n * @param {Number} buttonsWidth Total width of all buttons\n * @param {Number} maxButtonsWidth Max width allowed for buttons\n */\n var restoreButtonLabels = function (buttonsWidth, maxButtonsWidth) {\n for (var i = 0; i \u003c buttonOrder.length; i++) {\n var buttonId = buttonOrder[i];\n if (buttons[buttonId].isTruncated \u0026\u0026 buttons[buttonId].isVisible) {\n\n // Check if adding label exceeds allowed width\n var $button = buttons[buttonId].$element;\n var $tmp = $button.clone()\n .css({\n \u0027position\u0027: \u0027absolute\u0027,\n \u0027white-space\u0027: \u0027nowrap\u0027,\n \u0027max-width\u0027: \u0027none\u0027\n }).removeClass(\u0027truncated\u0027)\n .html(buttons[buttonId].text)\n .appendTo($button.parent());\n\n // Make sure clone was successfull\n if(!$button.length || !$tmp.length) {\n return;\n }\n\n var oldButtonSize = Math.floor($button.get(0).offsetWidth) - 1;\n var newButtonSize = Math.ceil($tmp.get(0).offsetWidth) + 1;\n\n // Calculate new total width of buttons with a static pixel for consistency cross-browser\n buttonsWidth = buttonsWidth - Math.floor(oldButtonSize) + Math.ceil(newButtonSize) + 1;\n\n $tmp.remove();\n if (buttonsWidth \u003e= maxButtonsWidth) {\n return;\n }\n // Restore label\n $button.html(buttons[buttonId].text);\n $button.removeClass(\u0027truncated\u0027);\n buttons[buttonId].isTruncated = false;\n }\n }\n };\n\n /**\n * Helper function for finding index of keyValue in array\n *\n * @param {String} keyValue Value to be found\n * @param {String} key In key\n * @param {Array} array In array\n * @returns {number}\n */\n var existsInArray = function (keyValue, key, array) {\n var i;\n for (i = 0; i \u003c array.length; i++) {\n if (array[i][key] === keyValue) {\n return i;\n }\n }\n return -1;\n };\n\n /**\n * Set behaviour for question.\n *\n * @param {Object} options An object containing behaviour that will be extended by Question\n */\n self.setBehaviour = function (options) {\n $.extend(behaviour, options);\n };\n\n /**\n * A video to display above the task.\n *\n * @param {object} params\n */\n self.setVideo = function (params) {\n sections.video = {\n $element: $(\u0027\u003cdiv/\u003e\u0027, {\n \u0027class\u0027: \u0027h5p-question-video\u0027\n })\n };\n\n if (disableAutoPlay \u0026\u0026 params.params.playback) {\n params.params.playback.autoplay = false;\n }\n\n // Never fit to wrapper\n if (!params.params.visuals) {\n params.params.visuals = {};\n }\n params.params.visuals.fit = false;\n sections.video.instance = H5P.newRunnable(params, self.contentId, sections.video.$element, true);\n var fromVideo = false; // Hack to avoid never ending loop\n sections.video.instance.on(\u0027resize\u0027, function () {\n fromVideo = true;\n self.trigger(\u0027resize\u0027);\n fromVideo = false;\n });\n self.on(\u0027resize\u0027, function () {\n if (!fromVideo) {\n sections.video.instance.trigger(\u0027resize\u0027);\n }\n });\n\n return self;\n };\n\n /**\n * Will stop any playback going on in the task.\n */\n self.pause = function () {\n if (sections.video \u0026\u0026 sections.video.isVisible) {\n sections.video.instance.pause();\n }\n };\n\n /**\n * Start playback of video\n */\n self.play = function () {\n if (sections.video \u0026\u0026 sections.video.isVisible) {\n sections.video.instance.play();\n }\n };\n\n /**\n * Disable auto play, useful in editors.\n */\n self.disableAutoPlay = function () {\n disableAutoPlay = true;\n };\n\n /**\n * Add task image.\n *\n * @param {string} path Relative\n * @param {Object} [options] Options object\n * @param {string} [options.alt] Text representation\n * @param {Boolean} [options.disableImageZooming] Set as true to disable image zooming\n */\n self.setImage = function (path, options) {\n options = options ? options : {};\n sections.image = {};\n // Image container\n sections.image.$element = $(\u0027\u003cdiv/\u003e\u0027, {\n \u0027class\u0027: \u0027h5p-question-image h5p-question-image-fill-width\u0027\n });\n\n // Inner wrap\n var $imgWrap = $(\u0027\u003cdiv/\u003e\u0027, {\n \u0027class\u0027: \u0027h5p-question-image-wrap\u0027,\n appendTo: sections.image.$element\n });\n\n // Image element\n var $img = $(\u0027\u003cimg/\u003e\u0027, {\n src: H5P.getPath(path, self.contentId),\n alt: (options.alt === undefined ? \u0027\u0027 : options.alt),\n on: {\n load: function () {\n self.trigger(\u0027imageLoaded\u0027, this);\n self.trigger(\u0027resize\u0027);\n }\n },\n appendTo: $imgWrap\n });\n\n // Disable image zooming\n if (options.disableImageZooming) {\n $img.css(\u0027maxHeight\u0027, \u0027none\u0027);\n\n // Make sure we are using the correct amount of width at all times\n var determineImgWidth = function () {\n\n // Remove margins if natural image width is bigger than section width\n var imageSectionWidth = sections.image.$element.get(0).getBoundingClientRect().width;\n\n // Do not transition, for instant measurements\n $imgWrap.css({\n \u0027-webkit-transition\u0027: \u0027none\u0027,\n \u0027transition\u0027: \u0027none\u0027\n });\n\n // Margin as translateX on both sides of image.\n var diffX = 2 * ($imgWrap.get(0).getBoundingClientRect().left -\n sections.image.$element.get(0).getBoundingClientRect().left);\n\n if ($img.get(0).naturalWidth \u003e= imageSectionWidth - diffX) {\n sections.image.$element.addClass(\u0027h5p-question-image-fill-width\u0027);\n }\n else { // Use margin for small res images\n sections.image.$element.removeClass(\u0027h5p-question-image-fill-width\u0027);\n }\n\n // Reset transition rules\n $imgWrap.css({\n \u0027-webkit-transition\u0027: \u0027\u0027,\n \u0027transition\u0027: \u0027\u0027\n });\n };\n\n // Determine image width\n if ($img.is(\u0027:visible\u0027)) {\n determineImgWidth();\n }\n else {\n $img.load(function () {\n determineImgWidth();\n });\n }\n\n // Skip adding zoom functionality\n return;\n }\n\n var sizeDetermined = false;\n var determineSize = function () {\n if (sizeDetermined || !$img.is(\u0027:visible\u0027)) {\n return; // Try again next time.\n }\n\n $imgWrap.addClass(\u0027h5p-question-image-scalable\u0027)\n .attr(\u0027aria-expanded\u0027, false)\n .attr(\u0027role\u0027, \u0027button\u0027)\n .attr(\u0027tabIndex\u0027, \u00270\u0027)\n .on(\u0027click\u0027, function (event) {\n if (event.which === 1) {\n scaleImage.apply(this); // Left mouse button click\n }\n }).on(\u0027keypress\u0027, function (event) {\n if (event.which === 32) {\n scaleImage.apply(this); // Space bar pressed\n }\n });\n sections.image.$element.removeClass(\u0027h5p-question-image-fill-width\u0027);\n\n sizeDetermined = true; // Prevent any futher events\n };\n\n self.on(\u0027resize\u0027, determineSize);\n\n return self;\n };\n\n /**\n * Add the introduction section.\n *\n * @param {(string|H5P.jQuery)} content\n */\n self.setIntroduction = function (content) {\n register(\u0027introduction\u0027, content);\n\n return self;\n };\n\n /**\n * Add the content section.\n *\n * @param {(string|H5P.jQuery)} content\n * @param {Object} [options]\n * @param {string} [options.class]\n */\n self.setContent = function (content, options) {\n register(\u0027content\u0027, content);\n\n if (options \u0026\u0026 options.class) {\n sections.content.$element.addClass(options.class);\n }\n\n return self;\n };\n\n /**\n * Force readspeaker to read text. Useful when you have to use\n * setTimeout for animations.\n */\n self.read = function (content) {\n if (!$read) {\n return; // Not ready yet\n }\n\n if (readText) {\n // Combine texts if called multiple times\n readText += (readText.substr(-1, 1) === \u0027.\u0027 ? \u0027 \u0027 : \u0027. \u0027) + content;\n }\n else {\n readText = content;\n }\n\n // Set text\n $read.html(readText);\n\n setTimeout(function () {\n // Stop combining when done reading\n readText = null;\n $read.html(\u0027\u0027);\n }, 100);\n };\n\n /**\n * Read feedback\n */\n self.readFeedback = function () {\n var invalidFeedback =\n behaviour.disableReadSpeaker ||\n !showFeedback ||\n !sections.feedback ||\n !sections.feedback.$element;\n\n if (invalidFeedback) {\n return;\n }\n\n var $feedbackText = $(\u0027.h5p-question-feedback-content-text\u0027, sections.feedback.$element);\n if ($feedbackText \u0026\u0026 $feedbackText.html() \u0026\u0026 $feedbackText.html().length) {\n self.read($feedbackText.html());\n }\n };\n\n /**\n * Remove feedback\n *\n * @return {H5P.Question}\n */\n self.removeFeedback = function () {\n\n clearTimeout(feedbackTransitionTimer);\n\n if (sections.feedback \u0026\u0026 showFeedback) {\n\n showFeedback = false;\n\n // Hide feedback section\n sections.feedback.$element.removeClass(\u0027h5p-question-visible\u0027);\n sections.feedback.$element.css(\u0027max-height\u0027, \u0027\u0027);\n sectionsIsTransitioning = true;\n\n // Detach after transition\n feedbackTransitionTimer = setTimeout(function () {\n // Avoiding Transition.onTransitionEnd since it will register multiple events, and there\u0027s no way to cancel it if the transition changes back to \"show\" while the animation is happening.\n if (!showFeedback) {\n sections.feedback.$element.children().detach();\n\n // Trigger resize after animation\n self.trigger(\u0027resize\u0027);\n }\n sectionsIsTransitioning = false;\n scoreBar.setScore(0);\n }, 150);\n\n if ($wrapper) {\n $wrapper.find(\u0027.h5p-question-feedback-tail\u0027).remove();\n }\n }\n\n return self;\n };\n\n /**\n * Set feedback message.\n *\n * @param {string} [content]\n * @param {number} score The score\n * @param {number} maxScore The maximum score for this question\n * @param {string} [scoreBarLabel] Makes it easier for readspeakers to identify the scorebar\n * @param {string} [helpText] Help text that describes the score inside a tip icon\n * @param {object} [popupSettings] Extra settings for popup feedback\n * @param {boolean} [popupSettings.showAsPopup] Should the feedback display as popup?\n * @param {string} [popupSettings.closeText] Translation for close button text\n * @param {object} [popupSettings.click] Element representing where user clicked on screen\n */\n self.setFeedback = function (content, score, maxScore, scoreBarLabel, helpText, popupSettings, scoreExplanationButtonLabel) {\n // Feedback is disabled\n if (behaviour.disableFeedback) {\n return self;\n }\n\n clickElement = (popupSettings != null \u0026\u0026 popupSettings.click != null ? popupSettings.click : null);\n clearTimeout(feedbackTransitionTimer);\n\n var $feedback = $(\u0027\u003cdiv\u003e\u0027, {\n \u0027class\u0027: \u0027h5p-question-feedback-container\u0027\n });\n\n var $feedbackContent = $(\u0027\u003cdiv\u003e\u0027, {\n \u0027class\u0027: \u0027h5p-question-feedback-content\u0027\n }).appendTo($feedback);\n\n // Feedback text\n $(\u0027\u003cdiv\u003e\u0027, {\n \u0027class\u0027: \u0027h5p-question-feedback-content-text\u0027,\n \u0027html\u0027: content\n }).appendTo($feedbackContent);\n\n if (scoreBar === undefined) {\n scoreBar = JoubelUI.createScoreBar(maxScore, scoreBarLabel, helpText, scoreExplanationButtonLabel);\n }\n scoreBar.appendTo($feedback);\n\n $feedbackContent.toggleClass(\u0027has-content\u0027, content !== undefined \u0026\u0026 content.length \u003e 0);\n\n // Feedback for readspeakers\n if (!behaviour.disableReadSpeaker \u0026\u0026 scoreBarLabel) {\n self.read(scoreBarLabel.replace(\u0027:num\u0027, score).replace(\u0027:total\u0027, maxScore) + \u0027. \u0027 + (content ? content : \u0027\u0027));\n }\n\n showFeedback = true;\n if (sections.feedback) {\n // Update section\n update(\u0027feedback\u0027, $feedback);\n }\n else {\n // Create section\n register(\u0027feedback\u0027, $feedback);\n if (initialized \u0026\u0026 $wrapper) {\n insert(self.order, \u0027feedback\u0027, sections, $wrapper);\n }\n }\n\n sections.feedback.$element.addClass(\u0027h5p-question-visible\u0027);\n if (popupSettings != null \u0026\u0026 popupSettings.showAsPopup == true) {\n makeFeedbackPopup(popupSettings.closeText);\n scoreBar.setScore(score);\n }\n else {\n // Show feedback section\n feedbackTransitionTimer = setTimeout(function () {\n setElementHeight(sections.feedback.$element);\n sectionsIsTransitioning = true;\n\n // Scroll to bottom after showing feedback\n scrollToBottom();\n\n // Trigger resize after animation\n feedbackTransitionTimer = setTimeout(function () {\n sectionsIsTransitioning = false;\n self.trigger(\u0027resize\u0027);\n scoreBar.setScore(score);\n }, 150);\n }, 0);\n }\n\n return self;\n };\n\n /**\n * Set feedback content (no animation).\n *\n * @param {string} content\n * @param {boolean} [extendContent] True will extend content, instead of replacing it\n */\n self.updateFeedbackContent = function (content, extendContent) {\n if (sections.feedback \u0026\u0026 sections.feedback.$element) {\n\n if (extendContent) {\n content = $(\u0027.h5p-question-feedback-content\u0027, sections.feedback.$element).html() + \u0027 \u0027 + content;\n }\n\n // Update feedback content html\n $(\u0027.h5p-question-feedback-content\u0027, sections.feedback.$element).html(content).addClass(\u0027has-content\u0027);\n\n // Make sure the height is correct\n setElementHeight(sections.feedback.$element);\n }\n\n return self;\n };\n\n /**\n * Set the content of the explanation / feedback panel\n *\n * @param {Object} data\n * @param {string} data.correct\n * @param {string} data.wrong\n * @param {string} data.text\n * @param {string} title Title for explanation panel\n *\n * @return {H5P.Question}\n */\n self.setExplanation = function (data, title) {\n if (data) {\n var explainer = new H5P.Question.Explainer(title, data);\n\n if (sections.explanation) {\n // Update section\n update(\u0027explanation\u0027, explainer.getElement());\n }\n else {\n register(\u0027explanation\u0027, explainer.getElement());\n\n if (initialized \u0026\u0026 $wrapper) {\n insert(self.order, \u0027explanation\u0027, sections, $wrapper);\n }\n }\n }\n else if (sections.explanation) {\n // Hide explanation section\n sections.explanation.$element.children().detach();\n }\n\n return self;\n };\n\n /**\n * Checks to see if button is registered.\n *\n * @param {string} id\n * @returns {boolean}\n */\n self.hasButton = function (id) {\n return (buttons[id] !== undefined);\n };\n\n /**\n * @typedef {Object} ConfirmationDialog\n * @property {boolean} [enable] Must be true to show confirmation dialog\n * @property {Object} [instance] Instance that uses confirmation dialog\n * @property {jQuery} [$parentElement] Append to this element.\n * @property {Object} [l10n] Translatable fields\n * @property {string} [l10n.header] Header text\n * @property {string} [l10n.body] Body text\n * @property {string} [l10n.cancelLabel]\n * @property {string} [l10n.confirmLabel]\n */\n\n /**\n * Register buttons for the task.\n *\n * @param {string} id\n * @param {string} text label\n * @param {function} clicked\n * @param {boolean} [visible=true]\n * @param {Object} [options] Options for button\n * @param {Object} [extras] Extra options\n * @param {ConfirmationDialog} [extras.confirmationDialog] Confirmation dialog\n */\n self.addButton = function (id, text, clicked, visible, options, extras) {\n if (buttons[id]) {\n return self; // Already registered\n }\n\n if (sections.buttons === undefined) {\n // We have buttons, register wrapper\n register(\u0027buttons\u0027);\n if (initialized) {\n insert(self.order, \u0027buttons\u0027, sections, $wrapper);\n }\n }\n\n extras = extras || {};\n extras.confirmationDialog = extras.confirmationDialog || {};\n options = options || {};\n\n var confirmationDialog =\n self.addConfirmationDialogToButton(extras.confirmationDialog, clicked);\n\n /**\n * Handle button clicks through both mouse and keyboard\n * @private\n */\n var handleButtonClick = function () {\n if (extras.confirmationDialog.enable \u0026\u0026 confirmationDialog) {\n // Show popups section if used\n if (!extras.confirmationDialog.$parentElement) {\n sections.popups.$element.removeClass(\u0027hidden\u0027);\n }\n confirmationDialog.show($e.position().top);\n }\n else {\n clicked();\n }\n };\n\n buttons[id] = {\n isTruncated: false,\n text: text\n };\n var $e = buttons[id].$element = JoubelUI.createButton($.extend({\n \u0027class\u0027: \u0027h5p-question-\u0027 + id,\n html: text,\n on: {\n click: function (event) {\n handleButtonClick();\n if (options.href !== undefined) {\n event.preventDefault();\n }\n },\n keydown: function (event) {\n switch (event.which) {\n case 13: // Enter\n case 32: // Space\n handleButtonClick();\n event.preventDefault();\n }\n }\n }\n }, options));\n buttonOrder.push(id);\n\n if (visible === undefined || visible) {\n // Button should be visible\n $e.appendTo(sections.buttons.$element);\n buttons[id].isVisible = true;\n sections.buttons.$element.addClass(\u0027h5p-question-visible\u0027);\n }\n\n return self;\n };\n\n /**\n * Add confirmation dialog to button\n * @param {ConfirmationDialog} options\n * A confirmation dialog that will be shown before click handler of button\n * is triggered\n * @param {function} clicked\n * Click handler of button\n * @return {H5P.ConfirmationDialog|undefined}\n * Confirmation dialog if enabled\n */\n self.addConfirmationDialogToButton = function (options, clicked) {\n options = options || {};\n\n if (!options.enable) {\n return;\n }\n\n // Confirmation dialog\n var confirmationDialog = new H5P.ConfirmationDialog({\n instance: options.instance,\n headerText: options.l10n.header,\n dialogText: options.l10n.body,\n cancelText: options.l10n.cancelLabel,\n confirmText: options.l10n.confirmLabel\n });\n\n // Determine parent element\n if (options.$parentElement) {\n confirmationDialog.appendTo(options.$parentElement.get(0));\n }\n else {\n\n // Create popup section and append to that\n if (sections.popups === undefined) {\n register(\u0027popups\u0027);\n if (initialized) {\n insert(self.order, \u0027popups\u0027, sections, $wrapper);\n }\n sections.popups.$element.addClass(\u0027hidden\u0027);\n self.order.push(\u0027popups\u0027);\n }\n confirmationDialog.appendTo(sections.popups.$element.get(0));\n }\n\n // Add event listeners\n confirmationDialog.on(\u0027confirmed\u0027, function () {\n if (!options.$parentElement) {\n sections.popups.$element.addClass(\u0027hidden\u0027);\n }\n clicked();\n\n // Trigger to content type\n self.trigger(\u0027confirmed\u0027);\n });\n\n confirmationDialog.on(\u0027canceled\u0027, function () {\n if (!options.$parentElement) {\n sections.popups.$element.addClass(\u0027hidden\u0027);\n }\n // Trigger to content type\n self.trigger(\u0027canceled\u0027);\n });\n\n return confirmationDialog;\n };\n\n /**\n * Show registered button with given identifier.\n *\n * @param {string} id\n * @param {Number} [priority]\n */\n self.showButton = function (id, priority) {\n if (buttons[id] === undefined) {\n return self;\n }\n\n priority = priority || 0;\n\n // Skip if already being shown\n var indexToShow = existsInArray(id, \u0027id\u0027, buttonsToShow);\n if (indexToShow !== -1) {\n\n // Update priority\n if (buttonsToShow[indexToShow].priority \u003c priority) {\n buttonsToShow[indexToShow].priority = priority;\n }\n\n return self;\n }\n\n // Check if button is going to be hidden on next tick\n var exists = existsInArray(id, \u0027id\u0027, buttonsToHide);\n if (exists !== -1) {\n\n // Skip hiding if higher priority\n if (buttonsToHide[exists].priority \u003c= priority) {\n buttonsToHide.splice(exists, 1);\n buttonsToShow.push({id: id, priority: priority});\n }\n\n } // If button is not shown\n else if (!buttons[id].$element.is(\u0027:visible\u0027)) {\n\n // Show button on next tick\n buttonsToShow.push({id: id, priority: priority});\n }\n\n if (!toggleButtonsTimer) {\n toggleButtonsTimer = setTimeout(toggleButtons, 0);\n }\n\n return self;\n };\n\n /**\n * Hide registered button with given identifier.\n *\n * @param {string} id\n * @param {number} [priority]\n */\n self.hideButton = function (id, priority) {\n if (buttons[id] === undefined) {\n return self;\n }\n\n priority = priority || 0;\n\n // Skip if already being hidden\n var indexToHide = existsInArray(id, \u0027id\u0027, buttonsToHide);\n if (indexToHide !== -1) {\n\n // Update priority\n if (buttonsToHide[indexToHide].priority \u003c priority) {\n buttonsToHide[indexToHide].priority = priority;\n }\n\n return self;\n }\n\n // Check if buttons is going to be shown on next tick\n var exists = existsInArray(id, \u0027id\u0027, buttonsToShow);\n if (exists !== -1) {\n\n // Skip showing if higher priority\n if (buttonsToShow[exists].priority \u003c= priority) {\n buttonsToShow.splice(exists, 1);\n buttonsToHide.push({id: id, priority: priority});\n }\n }\n else if (!buttons[id].$element.is(\u0027:visible\u0027)) {\n\n // Make sure it is detached in case the container is hidden.\n hideButton(id);\n }\n else {\n\n // Hide button on next tick.\n buttonsToHide.push({id: id, priority: priority});\n }\n\n if (!toggleButtonsTimer) {\n toggleButtonsTimer = setTimeout(toggleButtons, 0);\n }\n\n return self;\n };\n\n /**\n * Set focus to the given button. If no button is given the first visible\n * button gets focused. This is useful if you lose focus.\n *\n * @param {string} [id]\n */\n self.focusButton = function (id) {\n if (id === undefined) {\n // Find first button that is visible.\n for (var i = 0; i \u003c buttonOrder.length; i++) {\n var button = buttons[buttonOrder[i]];\n if (button \u0026\u0026 button.isVisible) {\n // Give that button focus\n button.$element.focus();\n break;\n }\n }\n }\n else if (buttons[id] \u0026\u0026 buttons[id].$element.is(\u0027:visible\u0027)) {\n // Set focus to requested button\n buttons[id].$element.focus();\n }\n\n return self;\n };\n\n /**\n * Toggle readspeaker functionality\n * @param {boolean} [disable] True to disable, false to enable.\n */\n self.toggleReadSpeaker = function (disable) {\n behaviour.disableReadSpeaker = disable || !behaviour.disableReadSpeaker;\n };\n\n /**\n * Set new element for section.\n *\n * @param {String} id\n * @param {H5P.jQuery} $element\n */\n self.insertSectionAtElement = function (id, $element) {\n if (sections[id] === undefined) {\n register(id);\n }\n sections[id].parent = $element;\n\n // Insert section if question is not initialized\n if (!initialized) {\n insert([id], id, sections, $element);\n }\n\n return self;\n };\n\n /**\n * Attach content to given container.\n *\n * @param {H5P.jQuery} $container\n */\n self.attach = function ($container) {\n if (self.isRoot()) {\n self.setActivityStarted();\n }\n\n // The first time we attach we also create our DOM elements.\n if ($wrapper === undefined) {\n if (self.registerDomElements !== undefined \u0026\u0026\n (self.registerDomElements instanceof Function ||\n typeof self.registerDomElements === \u0027function\u0027)) {\n\n // Give the question type a chance to register before attaching\n self.registerDomElements();\n }\n\n // Create section for reading messages\n $read = $(\u0027\u003cdiv/\u003e\u0027, {\n \u0027aria-live\u0027: \u0027polite\u0027,\n \u0027class\u0027: \u0027h5p-hidden-read\u0027\n });\n register(\u0027read\u0027, $read);\n self.trigger(\u0027registerDomElements\u0027);\n }\n\n // Prepare container\n $wrapper = $container;\n $container.html(\u0027\u0027)\n .addClass(\u0027h5p-question h5p-\u0027 + type);\n\n // Add sections in given order\n var $sections = [];\n for (var i = 0; i \u003c self.order.length; i++) {\n var section = self.order[i];\n if (sections[section]) {\n if (sections[section].parent) {\n // Section has a different parent\n sections[section].$element.appendTo(sections[section].parent);\n }\n else {\n $sections.push(sections[section].$element);\n }\n sections[section].isVisible = true;\n }\n }\n\n // Only append once to DOM for optimal performance\n $container.append($sections);\n\n // Let others react to dom changes\n self.trigger(\u0027domChanged\u0027, {\n \u0027$target\u0027: $container,\n \u0027library\u0027: self.libraryInfo.machineName,\n \u0027contentId\u0027: self.contentId,\n \u0027key\u0027: \u0027newLibrary\u0027\n }, {\u0027bubbles\u0027: true, \u0027external\u0027: true});\n\n // ??\n initialized = true;\n\n return self;\n };\n\n /**\n * Detach all sections from their parents\n */\n self.detachSections = function () {\n // Deinit Question\n initialized = false;\n\n // Detach sections\n for (var section in sections) {\n sections[section].$element.detach();\n }\n\n return self;\n };\n\n // Listen for resize\n self.on(\u0027resize\u0027, function () {\n // Allow elements to attach and set their height before resizing\n if (!sectionsIsTransitioning \u0026\u0026 sections.feedback \u0026\u0026 showFeedback) {\n // Resize feedback to fit\n setElementHeight(sections.feedback.$element);\n }\n\n // Re-position feedback popup if in use\n var $element = sections.feedback;\n var $click = clickElement;\n\n if ($element != null \u0026\u0026 $element.$element != null \u0026\u0026 $click != null \u0026\u0026 $click.$element != null) {\n setTimeout(function() {\n positionFeedbackPopup($element.$element, $click.$element);\n }, 10);\n }\n\n resizeButtons();\n });\n }\n\n // Inheritance\n Question.prototype = Object.create(EventDispatcher.prototype);\n Question.prototype.constructor = Question;\n\n /**\n * Determine the overall feedback to display for the question.\n * Returns empty string if no matching range is found.\n *\n * @param {Object[]} feedbacks\n * @param {number} scoreRatio\n * @return {string}\n */\n Question.determineOverallFeedback = function (feedbacks, scoreRatio) {\n scoreRatio = Math.floor(scoreRatio * 100);\n\n for (var i = 0; i \u003c feedbacks.length; i++) {\n var feedback = feedbacks[i];\n var hasFeedback = (feedback.feedback !== undefined \u0026\u0026 feedback.feedback.trim().length !== 0);\n\n if (feedback.from \u003c= scoreRatio \u0026\u0026 feedback.to \u003e= scoreRatio \u0026\u0026 hasFeedback) {\n return feedback.feedback;\n }\n }\n\n return \u0027\u0027;\n };\n\n return Question;\n})(H5P.jQuery, H5P.EventDispatcher, H5P.JoubelUI);\n"
,"scripts/explainer.js":"H5P.Question.Explainer = (function ($) {\n /**\n * Constructor\n *\n * @class\n * @param {string} title\n * @param {array} explanations\n */\n function Explainer(title, explanations) {\n var self = this;\n\n /**\n * Create the DOM structure\n */\n var createHTML = function () {\n self.$explanation = $(\u0027\u003cdiv\u003e\u0027, {\n \u0027class\u0027: \u0027h5p-question-explanation-container\u0027\n });\n\n // Add title:\n $(\u0027\u003cdiv\u003e\u0027, {\n \u0027class\u0027: \u0027h5p-question-explanation-title\u0027,\n role: \u0027heading\u0027,\n html: title,\n appendTo: self.$explanation\n });\n\n var $explanationList = $(\u0027\u003cul\u003e\u0027, {\n \u0027class\u0027: \u0027h5p-question-explanation-list\u0027,\n appendTo: self.$explanation\n });\n\n for (var i = 0; i \u003c explanations.length; i++) {\n var feedback = explanations[i];\n var $explanationItem = $(\u0027\u003cli\u003e\u0027, {\n \u0027class\u0027: \u0027h5p-question-explanation-item\u0027,\n appendTo: $explanationList\n });\n\n var $content = $(\u0027\u003cdiv\u003e\u0027, {\n \u0027class\u0027: \u0027h5p-question-explanation-status\u0027\n });\n\n if (feedback.correct) {\n $(\u0027\u003cspan\u003e\u0027, {\n \u0027class\u0027: \u0027h5p-question-explanation-correct\u0027,\n html: feedback.correct,\n appendTo: $content\n });\n }\n if (feedback.wrong) {\n $(\u0027\u003cspan\u003e\u0027, {\n \u0027class\u0027: \u0027h5p-question-explanation-wrong\u0027,\n html: feedback.wrong,\n appendTo: $content\n });\n }\n $content.appendTo($explanationItem);\n\n if (feedback.text) {\n $(\u0027\u003cdiv\u003e\u0027, {\n \u0027class\u0027: \u0027h5p-question-explanation-text\u0027,\n html: feedback.text,\n appendTo: $explanationItem\n });\n }\n }\n };\n\n createHTML();\n\n /**\n * Return the container HTMLElement\n *\n * @return {HTMLElement}\n */\n self.getElement = function () {\n return self.$explanation;\n };\n }\n\n return Explainer;\n\n})(H5P.jQuery);\n"
,"scripts/score-points.js":"(function (Question) {\n\n /**\n * Makes it easy to add animated score points for your question type.\n *\n * @class H5P.Question.ScorePoints\n */\n Question.ScorePoints = function () {\n var self = this;\n\n var elements = [];\n var showElementsTimer;\n\n /**\n * Create the element that displays the score point element for questions.\n *\n * @param {boolean} isCorrect\n * @return {HTMLElement}\n */\n self.getElement = function (isCorrect) {\n var element = document.createElement(\u0027div\u0027);\n element.classList.add(isCorrect ? \u0027h5p-question-plus-one\u0027 : \u0027h5p-question-minus-one\u0027);\n element.classList.add(\u0027h5p-question-hidden-one\u0027);\n elements.push(element);\n\n // Schedule display animation of all added elements\n if (showElementsTimer) {\n clearTimeout(showElementsTimer);\n }\n showElementsTimer = setTimeout(showElements, 0);\n\n return element;\n };\n\n /**\n * @private\n */\n var showElements = function () {\n // Determine delay between triggering animations\n var delay = 0;\n var increment = 150;\n var maxTime = 1000;\n\n if (elements.length \u0026\u0026 elements.length \u003e Math.ceil(maxTime / increment)) {\n // Animations will run for more than ~1 second, reduce it.\n increment = maxTime / elements.length;\n }\n\n for (var i = 0; i \u003c elements.length; i++) {\n // Use timer to trigger show\n setTimeout(showElement(elements[i]), delay);\n\n // Increse delay for next element\n delay += increment;\n }\n };\n\n /**\n * Trigger transition animation for the given element\n *\n * @private\n * @param {HTMLElement} element\n * @return {function}\n */\n var showElement = function (element) {\n return function () {\n element.classList.remove(\u0027h5p-question-hidden-one\u0027);\n };\n };\n };\n\n})(H5P.Question);\n"
,"vertical-tabs.js":"/** @namespace H5PEditor */\nvar H5PEditor = H5PEditor || {};\n\nH5PEditor.VerticalTabs = (function ($) {\n\n /**\n * Draws the list.\n *\n * @class\n * @param {List} list\n */\n function VerticalTabs(list) {\n var self = this;\n var entity = list.getEntity();\n\n // Make first letter upper case.\n entity = entity.substr(0,1).toUpperCase() + entity.substr(1);\n\n // Create DOM elements\n var $wrapper = $(\u0027\u003cdiv/\u003e\u0027, {\n \u0027class\u0027: \u0027h5p-vtab-wrapper\u0027\n });\n var $inner = $(\u0027\u003cdiv/\u003e\u0027, {\n \u0027class\u0027: \u0027h5p-vtabs\u0027\n }).appendTo($wrapper);\n var $tabs = $(\u0027\u003col/\u003e\u0027, {\n \u0027role\u0027: \u0027tablist\u0027,\n \u0027class\u0027: \u0027h5p-ul\u0027\n }).appendTo($inner);\n H5PEditor.createButton(\u0027add-entity\u0027, H5PEditor.t(\u0027core\u0027, \u0027addEntity\u0027, {\u0027:entity\u0027: entity}), function () {\n if (list.addItem()) {\n $tabs.children(\u0027:last\u0027).trigger(\u0027open\u0027);\n toggleOrderButtonsState();\n }\n }, true).appendTo($inner);\n var $forms = $(\u0027\u003cdiv/\u003e\u0027, {\n \u0027class\u0027: \u0027h5p-vtab-forms\u0027\n }).appendTo($wrapper);\n\n // Once all items have been added we toggle the state of the order buttons\n list.once(\u0027changeWidget\u0027, function () {\n toggleOrderButtonsState();\n });\n\n // Used when dragging items around\n var adjustX, adjustY, marginTop, formOffset, $currentTab;\n\n /**\n * @private\n * @param {jQuery} $item\n * @param {jQuery} $placeholder\n * @param {Number} x\n * @param {Number} y\n */\n var moveItem = function ($item, $placeholder, x, y) {\n var currentIndex;\n\n // Adjust so the mouse is placed on top of the icon.\n x = x - adjustX;\n y = y - adjustY;\n\n $item.css({\n top: y - marginTop - formOffset.top,\n left: x - formOffset.left\n });\n\n // Try to move up.\n var $prev = $item.prev().prev();\n if ($prev.length \u0026\u0026 y \u003c $prev.offset().top + ($prev.height() / 2)) {\n $prev.insertAfter($item);\n\n\n currentIndex = $item.index();\n list.moveItem(currentIndex, currentIndex - 1);\n\n return;\n }\n\n // Try to move down.\n var $next = $item.next();\n if ($next.length \u0026\u0026 y + $item.height() \u003e $next.offset().top + ($next.height() / 2)) {\n $next.insertBefore($placeholder);\n\n currentIndex = $item.index() - 2;\n list.moveItem(currentIndex, currentIndex + 1);\n }\n };\n\n /**\n * Re-index labels. Necessary after tabs are sorted or removed.\n *\n * @private\n */\n var reindexLabels = function () {\n $tabs.find(\u0027.h5p-index-label\u0027).each(function (index, element) {\n $(element).text(index + 1);\n });\n toggleOrderButtonsState();\n };\n\n /**\n * Always run after reordering, adding or removing to ensure correct\n * state of the order buttons.\n *\n * @private\n */\n var toggleOrderButtonsState = function () {\n $tabs.children().each(function (index, element) {\n var $tab = $(element);\n var isTopTab = !$tab.prev().length;\n $tab.find(\u0027.order-up\u0027).attr(\u0027aria-disabled\u0027, isTopTab).attr(\u0027tabindex\u0027, isTopTab ? \u0027-1\u0027 : \u00270\u0027);\n var isBottomTab = !$tab.next().length;\n $tab.find(\u0027.order-down\u0027).attr(\u0027aria-disabled\u0027, isBottomTab).attr(\u0027tabindex\u0027, isBottomTab ? \u0027-1\u0027 : \u00270\u0027);\n });\n };\n\n /**\n * Opens the given tab.\n *\n * @private\n * @param {jQuery} $newTab\n */\n var openTab = function ($newTab) {\n if ($currentTab !== undefined) {\n H5PEditor.Html.removeWysiwyg();\n $currentTab.removeClass(\u0027h5p-current\u0027);\n }\n $newTab.addClass(\u0027h5p-current\u0027);\n $currentTab = $newTab;\n };\n\n /**\n * Adds UI items to the widget.\n *\n * @public\n * @param {Object} item\n */\n self.addItem = function (item) {\n var $placeholder;\n var $tab = $(\u0027\u003cli/\u003e\u0027, {\n \u0027class\u0027: \u0027h5p-vtab-li\u0027\n }).appendTo($tabs);\n\n /**\n * Mouse move callback\n *\n * @private\n * @param {Object} event\n */\n var move = function (event) {\n moveItem($tab, $placeholder, event.pageX, event.pageY);\n };\n\n /**\n * Mouse button release callback\n *\n * @private\n */\n var up = function () {\n H5P.$window\n .unbind(\u0027mousemove\u0027, move)\n .unbind(\u0027mouseup\u0027, up);\n\n H5P.$body\n .attr(\u0027unselectable\u0027, \u0027off\u0027)\n .css({\n \u0027-moz-user-select\u0027: \u0027\u0027,\n \u0027-webkit-user-select\u0027: \u0027\u0027,\n \u0027user-select\u0027: \u0027\u0027,\n \u0027-ms-user-select\u0027: \u0027\u0027,\n \u0027overflow\u0027: \u0027\u0027,\n })[0].onselectstart = H5P.$body[0].ondragstart = null;\n\n $tab.removeClass(\u0027h5p-moving\u0027).css({\n width: \u0027auto\u0027,\n height: \u0027auto\u0027,\n top: \u0027\u0027,\n left: \u0027\u0027\n });\n $placeholder.remove();\n reindexLabels();\n };\n\n /**\n * Mouse button down callback\n *\n * @private\n */\n var down = function (event) {\n if (event.which !== 1) {\n return; // Only allow left mouse button\n }\n\n H5P.$window\n .mousemove(move)\n .mouseup(up);\n\n // Start tracking mouse\n H5P.$body\n .attr(\u0027unselectable\u0027, \u0027on\u0027)\n .css({\n \u0027-moz-user-select\u0027: \u0027none\u0027,\n \u0027-webkit-user-select\u0027: \u0027none\u0027,\n \u0027user-select\u0027: \u0027none\u0027,\n \u0027-ms-user-select\u0027: \u0027none\u0027,\n \u0027overflow\u0027: \u0027hidden\u0027\n })[0].onselectstart = H5P.$body[0].ondragstart = function () {\n return false;\n };\n\n var offset = $tab.offset();\n adjustX = event.pageX - offset.left;\n adjustY = event.pageY - offset.top;\n marginTop = parseInt($tab.css(\u0027marginTop\u0027));\n formOffset = $tabs.offsetParent().offset();\n // TODO: Couldn\u0027t formOffset and margin be added?\n\n var width = $tab.width();\n var height = $tab.height();\n\n $tab.addClass(\u0027h5p-moving\u0027).css({\n width: width,\n height: height\n });\n $placeholder = $(\u0027\u003cli/\u003e\u0027, {\n \u0027class\u0027: \u0027h5p-placeholder\u0027\n }).insertBefore($tab);\n\n $(\u0027\u003cdiv/\u003e\u0027, {\n class: \u0027h5p-vtab-a\u0027,\n }).appendTo($placeholder);\n\n move(event);\n };\n\n /**\n * Order current list item up\n *\n * @private\n */\n var moveItemUp = function () {\n var $prev = $tab.prev();\n if (!$prev.length) {\n return; // Cannot move item further up\n }\n\n var currentIndex = $tab.index();\n $prev.insertAfter($tab);\n list.moveItem(currentIndex, currentIndex - 1);\n reindexLabels();\n };\n\n /**\n * Order current ist item down\n *\n * @private\n */\n var moveItemDown = function () {\n var $next = $tab.next();\n if (!$next.length) {\n return; // Cannot move item further down\n }\n\n var currentIndex = $tab.index();\n $next.insertBefore($tab);\n list.moveItem(currentIndex, currentIndex + 1);\n reindexLabels();\n };\n\n // Handle opening of the tab\n $tab.on(\u0027open\u0027, function () {\n openTab($tab.add($form));\n });\n\n var mouseDownPos;\n\n // Add clickable label\n $(\u0027\u003cdiv/\u003e\u0027, {\n \u0027class\u0027 : \u0027h5p-vtab-a\u0027,\n html: \u0027\u003cspan class=\"h5p-index-label\"\u003e\u0027 + ($tab.index() + 1) + \u0027\u003c/span\u003e. \u003cspan class=\"h5p-label\" title=\"\u0027 + entity + \u0027\"\u003e\u0027 + entity + \u0027\u003c/span\u003e\u0027,\n role: \u0027tab\u0027,\n tabIndex: 0,\n on: {\n mouseup: function (e) {\n\n if (!mouseDownPos) {\n return;\n }\n // Determine movement\n var xDiff = Math.abs(mouseDownPos.x - e.pageX);\n var yDiff = Math.abs(mouseDownPos.y - e.pageY);\n var moveThreshold = 20;\n\n // Open tab if moved less than threshold\n if (xDiff \u003c moveThreshold \u0026\u0026 yDiff \u003c moveThreshold) {\n $tab.trigger(\u0027open\u0027);\n }\n },\n mousedown: function (e) {\n // Start position\n mouseDownPos = {\n x: e.pageX,\n y: e.pageY\n };\n\n // Order element\n down(e);\n },\n keypress: function (e) {\n if (e.which === 32) {\n e.preventDefault();\n $tab.trigger(\u0027open\u0027);\n }\n }\n }\n }).appendTo($tab);\n\n var $tabLabel = $tab.find(\u0027.h5p-label\u0027);\n\n var setTabLabel = function (label) {\n $tabLabel.text(label).attr(\u0027title\u0027, label);\n };\n\n // Add buttons for ordering\n var $orderWrapper = $(\u0027\u003cdiv/\u003e\u0027, {\n \u0027class\u0027: \u0027vtab-order-wrapper\u0027,\n appendTo: $tab\n });\n H5PEditor.createButton(\u0027order-up\u0027, H5PEditor.t(\u0027core\u0027, \u0027orderItemUp\u0027), moveItemUp).appendTo($orderWrapper);\n H5PEditor.createButton(\u0027order-down\u0027, H5PEditor.t(\u0027core\u0027, \u0027orderItemDown\u0027), moveItemDown).appendTo($orderWrapper);\n\n // Add remove button\n var $removeWrapper = $(\u0027\u003cdiv/\u003e\u0027, {\n \u0027class\u0027: \u0027vtab-remove-wrapper\u0027,\n appendTo: $tab\n });\n H5PEditor.createButton(\u0027remove\u0027, H5PEditor.t(\u0027core\u0027, \u0027removeItem\u0027), function () {\n confirmRemovalDialog.show($(this).offset().top);\n }).appendTo($removeWrapper);\n\n // Create confirmation dialog for removing list item\n var confirmRemovalDialog = new H5P.ConfirmationDialog({\n dialogText: H5PEditor.t(\u0027core\u0027, \u0027confirmRemoval\u0027, {\u0027:type\u0027: entity.toLocaleLowerCase()})\n }).appendTo(document.body);\n\n // Remove list item on confirmation\n confirmRemovalDialog.on(\u0027confirmed\u0027, function () {\n var $next, index = $tab.index();\n\n if ($tab.hasClass(\u0027h5p-current\u0027)) {\n if (index) {\n // Go to previous tab\n $next = $tab.prev().add($form.prev());\n }\n else {\n // Go to next tab\n $next = $tab.next().add($form.next());\n }\n\n if ($next.length) {\n // Open another tab\n $next.trigger(\u0027open\u0027);\n }\n }\n\n list.removeItem(index);\n $tab.remove();\n $form.remove();\n reindexLabels();\n });\n\n // Create form wrapper\n var $form = $(\u0027\u003cfieldset/\u003e\u0027, {\n \u0027role\u0027: \u0027tabpanel\u0027,\n \u0027class\u0027: \u0027h5p-vtab-form\u0027\n });\n\n if (item instanceof H5PEditor.Group) {\n item.on(\u0027summary\u0027, function (event) {\n if (event.data) {\n // Update tab with summary\n setTabLabel(event.data.substr(0, 32));\n }\n });\n }\n\n // Append new field item to forms wrapper\n item.appendTo($form);\n\n // Append form wrapper to forms list\n $form.appendTo($forms);\n\n // Good UX: automatically expand groups\n if (item instanceof H5PEditor.Group) {\n item.expand();\n\n // Remove group title\n item.$group.children(\u0027.title\u0027).remove();\n }\n else if (item instanceof H5PEditor.Library) {\n $form.addClass(\u0027content\u0027);\n\n // Use selected library as title\n item.changes.push(function (library) {\n setTabLabel(library.title);\n });\n if (item.currentLibrary) {\n for (var i = 0; i \u003c item.libraries.length; i++) {\n if (item.libraries[i].uberName === item.currentLibrary) {\n setTabLabel(item.libraries[i].title);\n break;\n }\n }\n }\n }\n else if (item instanceof H5PEditor.Select) {\n // Use selected value as title\n var change = function () {\n var value = item.$select.val();\n setTabLabel(value === \u0027-\u0027 ? entity : item.$select.children(\u0027option[value=\"\u0027 + value + \u0027\"]\u0027).text());\n };\n item.$select.change(change);\n change();\n }\n\n if ($currentTab === undefined) {\n // Open tab if there are none open\n $tab.trigger(\u0027open\u0027);\n }\n\n $tabs.find(\u0027.h5p-vtab-li .h5p-vtab-a\u0027).first().focus();\n };\n\n /**\n * Puts this widget at the end of the given container.\n *\n * @public\n * @param {jQuery} $container\n */\n self.appendTo = function ($container) {\n $wrapper.appendTo($container);\n };\n\n /**\n * Remove this widget from the editor DOM.\n *\n * @public\n */\n self.remove = function () {\n $wrapper.remove();\n };\n }\n\n return VerticalTabs;\n})(H5P.jQuery);\n"
,"h5p-editor-table-list.js":"H5PEditor.TableList = (function ($, EventDispatcher) {\n\n /**\n * Renders UI for the table list.\n *\n * @class\n * @extends H5P.EventDispatcher\n * @param {List} list\n * @param {string} [extraClass]\n */\n function TableList(list, extraClass) {\n var self = this;\n\n // Initialize inheritance\n EventDispatcher.call(self);\n\n // Grab entity and make first letter upper case\n var entity = list.getEntity();\n entity = entity.substr(0,1).toLocaleUpperCase() + entity.substr(1);\n\n // Create DOM structure elements for the table\n var $wrapper = $(\u0027\u003ctable/\u003e\u0027, {\n \u0027class\u0027: \u0027h5p-editor-table-list\u0027 + (extraClass ? \u0027 \u0027 + extraClass : \u0027\u0027)\n });\n var $thead = $(\u0027\u003cthead/\u003e\u0027, {\n appendTo: $wrapper\n });\n var $headRow;\n var $tbody = $(\u0027\u003ctbody/\u003e\u0027, {\n appendTo: $wrapper\n });\n var $tfoot = $(\u0027\u003ctfoot/\u003e\u0027, {\n appendTo: $wrapper\n });\n\n /**\n * Adds UI items to the widget.\n *\n * @public\n * @param {Object} item\n */\n self.addItem = function (item) {\n if (!(item instanceof H5PEditor.Group)) {\n return; // Only support multiple fields\n }\n\n if (!$headRow) {\n var group = list.getField();\n addHeader(group.fields);\n addFooter(group.fields.length);\n\n self.trigger(\u0027tableprepared\u0027, {\n thead: $thead[0],\n tfoot: $tfoot[0],\n tbody: $tbody[0],\n fields: group.fields\n });\n }\n\n // Set default params in case item has no params\n if (item.params === undefined) {\n item.params = {};\n item.setValue(item.field, item.params);\n }\n\n addRow(item);\n };\n\n /**\n * Add table headers\n *\n * @private\n * @param {Array} fields\n */\n var addHeader = function (fields) {\n $headRow = $(\u0027\u003ctr/\u003e\u0027, {\n appendTo: $thead\n });\n for (var i = 0; i \u003c fields.length; i++) {\n var $th = $(\u0027\u003cth/\u003e\u0027, {\n \u0027class\u0027: \u0027h5peditor-type-\u0027 + fields[i].type,\n html: (fields[i].label ? fields[i].label : \u0027\u0027),\n appendTo: $headRow\n });\n fields[i].label = 0; // No labels inside table rows\n }\n $(\u0027\u003cth/\u003e\u0027, {\n \u0027class\u0027: \u0027h5peditor-remove-header\u0027,\n appendTo: $headRow\n });\n\n self.trigger(\u0027headeradd\u0027, {\n element: $headRow[0],\n fields: fields\n });\n };\n\n /**\n * Add table footer\n *\n * @private\n * @param {number} length\n */\n var addFooter = function (length) {\n var $footRow = $(\u0027\u003ctr/\u003e\u0027, {\n appendTo: $tfoot\n });\n var $footCell = $(\u0027\u003ctd/\u003e\u0027, {\n colspan: length,\n appendTo: $footRow\n });\n H5PEditor.createButton(list.getImportance(), H5PEditor.t(\u0027core\u0027, \u0027addEntity\u0027, {\u0027:entity\u0027: entity}), function () {\n list.addItem();\n }, true).appendTo($footCell);\n\n self.trigger(\u0027footeradd\u0027, {\n footerCell: $footCell[0],\n fields: list.getField().fields,\n tbody: $tbody[0]\n });\n };\n\n /**\n * Add a new table row with data using the given group as source\n *\n * @private\n * @param {H5PEditor.Group} item\n */\n var addRow = function (item) {\n // Keep track of field instances\n item.children = [];\n\n // Create row element\n var $tableRow = $(\u0027\u003ctr/\u003e\u0027, {\n appendTo: $tbody\n });\n\n // Process semantics to create row fields\n var fields = item.getFields();\n for (var i = 0; i \u003c fields.length; i++) {\n fields[i].label = 0;\n var $cell = $(\u0027\u003ctd/\u003e\u0027, {\n appendTo: $tableRow\n });\n\n var fieldInstance = processSemanticsField(item, fields[i]);\n fieldInstance.appendTo($cell);\n\n item.children.push(fieldInstance);\n }\n\n // Add remove button\n var $removeButtonCell = $(\u0027\u003ctd/\u003e\u0027, {\n \u0027class\u0027: \u0027h5peditor-remove-button\u0027,\n appendTo: $tableRow\n });\n\n H5PEditor.createButton(\u0027remove\u0027, H5PEditor.t(\u0027core\u0027, \u0027removeItem\u0027), function () {\n if (this.getAttribute(\u0027aria-disabled\u0027) !== \u0027true\u0027) {\n confirmRemovalDialog.show($(this).offset().top);\n }\n }).appendTo($removeButtonCell);\n\n // Create confirmation dialog for removing list item\n var confirmRemovalDialog = new H5P.ConfirmationDialog({\n dialogText: H5PEditor.t(\u0027core\u0027, \u0027confirmRemoval\u0027, {\u0027:type\u0027: entity.toLocaleLowerCase()})\n }).appendTo(document.body);\n confirmRemovalDialog.on(\u0027confirmed\u0027, function () {\n // Remove him!\n self.trigger(\u0027rowremove\u0027, {\n element: $tableRow[0],\n fields: fields\n });\n var index = $tableRow.index();\n list.removeItem(index);\n $tableRow.remove(); // Bye, bye\n self.trigger(\u0027rowremoved\u0027);\n });\n\n // Allow overriding / customization\n self.trigger(\u0027rowadd\u0027, {\n element: $tableRow[0],\n fields: fields,\n instances: item.children\n });\n };\n\n /**\n * Convert semantics into widgets.\n *\n * @private\n * @param {H5PEditor.Group} parent\n * @param {Object} field\n */\n var processSemanticsField = function (parent, field) {\n // Check required field properties\n if (field.name === undefined || field.type === undefined) {\n throw ns.t(\u0027core\u0027, \u0027missingProperty\u0027, {\u0027:index\u0027: i, \u0027:property\u0027: \u0027name/type\u0027});\n }\n\n // Set default value\n if (parent.params[field.name] === undefined \u0026\u0026 field[\u0027default\u0027] !== undefined) {\n parent.params[field.name] = field[\u0027default\u0027];\n }\n\n // Locate widget\n var widget = ns.getWidgetName(field);\n\n // Create new field instance\n return new ns.widgets[widget](parent, field, parent.params[field.name], function (field, value) {\n if (value === undefined) {\n delete parent.params[field.name];\n }\n else {\n parent.params[field.name] = value;\n }\n });\n };\n\n /**\n * Puts this widget at the end of the given container.\n *\n * @public\n * @param {jQuery} $container\n */\n self.appendTo = function ($container) {\n $wrapper.appendTo($container);\n };\n\n /**\n * Remove this widget from the editor DOM.\n *\n * @public\n */\n self.remove = function () {\n $wrapper.remove();\n };\n }\n\n // Extend the prototype\n TableList.prototype = Object.create(EventDispatcher.prototype);\n TableList.prototype.constructor = TableList;\n\n return TableList;\n})(H5P.jQuery, H5P.EventDispatcher);\n"
,"h5p-editor-range-list.js":"H5PEditor.RangeList = (function ($, TableList) {\n\n /**\n * Renders UI for the table list.\n *\n * @class\n * @extends H5PEditor.TableList\n * @param {List} list\n */\n function RangeList(list) {\n var self = this;\n\n // Initialize inheritance\n TableList.call(self, list, \u0027h5p-editor-range-list\u0027);\n\n // Keep track of the widget state\n var initialized = false;\n list.once(\u0027changeWidget\u0027, function () {\n initialized = true;\n validateSequence();\n });\n\n // Global elements\n var distributeButton;\n var tbody;\n\n // Customize table header and footer\n self.once(\u0027tableprepared\u0027, function (event) {\n var headRow = event.data.thead.firstElementChild;\n var footCell = event.data.tfoot.firstElementChild.firstElementChild;\n tbody = event.data.tbody;\n var fields = event.data.fields;\n\n // Add dash between \u0027from\u0027 and \u0027to\u0027 values\n addDashCol(headRow, \u0027th\u0027);\n\n // Mark score range label as required\n headRow.children[0].classList.add(\u0027h5peditor-required\u0027);\n\n // Create button to evenly distribute ranges\n distributeButton = createDistributeButton(\n H5PEditor.t(\u0027H5PEditor.RangeList\u0027, \u0027distributeButtonLabel\u0027),\n H5PEditor.t(\u0027H5PEditor.RangeList\u0027, \u0027distributeButtonWarning\u0027),\n \u0027h5peditor-range-distribute\u0027,\n distributeEvenlyHandler(fields[0].min, fields[1].max)\n );\n\n // Increase footer size and insert button\n footCell.colSpan += 2;\n footCell.appendChild(distributeButton);\n\n // Create message area and insert before buttons\n self.messageArea = document.createElement(\u0027div\u0027);\n self.messageArea.className = \u0027h5p-editor-range-list-message-area\u0027;\n footCell.insertBefore(self.messageArea, footCell.firstElementChild);\n });\n\n // Customize rows as they\u0027re added\n self.on(\u0027rowadd\u0027, function (event) {\n var row = event.data.element;\n var fields = event.data.fields;\n var instances = event.data.instances;\n\n // Customize the \u0027from\u0027 input part\n var fromInput = getFirst(\u0027input\u0027, row);\n makeReadOnly(fromInput);\n\n // Customize each row by adding a separation dash between \u0027from\u0027 and \u0027to\u0027\n addDashCol(row, \u0027td\u0027, \u0027–\u0027);\n\n // Customize the \u0027to\u0027 input part\n var toInput = getSecond(\u0027input\u0027, row);\n\n // Create textual representation to display if this is the last row\n addInputText(toInput);\n\n // Set min value of \u0027to\u0027 field to equal the \u0027from\u0027 field value\n linkPropertyValue(\u0027min\u0027, instances[1], fromInput);\n\n // Update the next row\u0027s \u0027from\u0027 input when this row\u0027s \u0027to\u0027 input changes\n toInput.addEventListener(\u0027change\u0027, updateInputHandler(fields[0]));\n\n var isFirstRow = !row.previousElementSibling;\n if (isFirstRow) {\n // This is the first row, disable buttons\n toggleButtons(false, row);\n }\n else {\n // Show the preivous field\u0027s second input when adding a new row\n makeEditable(row.previousElementSibling);\n\n // More than one row, enable buttons\n toggleButtons(true, row.previousElementSibling);\n }\n\n if (initialized) {\n validateSequence();\n }\n });\n\n // Handle row being removed from the table\n self.on(\u0027rowremove\u0027, function (event) {\n var row = event.data.element;\n var fields = event.data.fields;\n\n if (!row.nextElementSibling) {\n // This was the last row\n if (row.previousElementSibling) {\n getSecond(\u0027.h5peditor-input-text\u0027, row.previousElementSibling).style.display = \u0027\u0027;\n var prevToInput = getSecond(\u0027input\u0027, row.previousElementSibling);\n prevToInput.style.display = \u0027none\u0027;\n setValue(prevToInput, fields[1].max);\n\n if (!row.previousElementSibling.previousElementSibling) {\n // Only one row left, disable buttons\n toggleButtons(false, row.previousElementSibling);\n }\n }\n }\n else if (!row.previousElementSibling) {\n // This was the first row\n setValue(getFirst(\u0027input\u0027, row.nextElementSibling), fields[0].min);\n if (!row.nextElementSibling.nextElementSibling) {\n // Only one row left, disable buttons\n toggleButtons(false, row.nextElementSibling);\n }\n }\n else {\n // Set first input of next row to match the second input of previous row.\n setValue(getFirst(\u0027input\u0027, row.nextElementSibling), getSecond(\u0027input\u0027, row.previousElementSibling).value);\n }\n });\n\n // When row is removed we check for overlapping sequences\n self.on(\u0027rowremoved\u0027, function (event) {\n validateSequence();\n });\n\n /**\n * Convert the given input field into a read-only type field that is\n * updated programmatically.\n *\n * @private\n * @param {HTMLInputElement} input\n */\n var makeReadOnly = function (input) {\n // Default value for newly added row is set to blank when this\n // is a row added by the user\n var isFirstRow = !input.parentElement.parentElement.parentElement.previousElementSibling;\n if (!isFirstRow \u0026\u0026 initialized) {\n setValue(input, \u0027\u0027);\n }\n\n // Add textual representation of input\n addInputText(input);\n\n // Hide all errors since the input is updated programmatically\n input.parentElement.querySelector(\u0027.h5p-errors\u0027).style.display = \u0027none\u0027;\n };\n\n /**\n * The given row is no longer the last row and the \u0027to\u0027 input should\n * now be editable.\n *\n * @private\n * @param {HTMLTableRowElement} row\n */\n var makeEditable = function (row) {\n getSecond(\u0027.h5peditor-input-text\u0027, row).style.display = \u0027none\u0027;\n var prevToInput = getSecond(\u0027input\u0027, row);\n prevToInput.style.display = \u0027\u0027;\n\n if (initialized) {\n // User action, use no value as default\n setValue(prevToInput, \u0027\u0027);\n\n // Override / clear \u0027field is mandatory\u0027 error messages\n prevToInput.parentNode.querySelector(\u0027.h5p-errors\u0027).innerHTML = \u0027\u0027;\n prevToInput.classList.remove(\u0027error\u0027);\n }\n };\n\n /**\n * Set the given field property to equal the value the given input field\n *\n * @private\n * @param {string} property\n * @param {Object} fieldInstance\n * @param {HTMLInputElement} input\n */\n var linkPropertyValue = function (property, fieldInstance, input) {\n // Update the current value to equal that of the input\n fieldInstance.field[property] = parseInt(input.value);\n\n // Update the value if the value of the field changes\n input.addEventListener(\u0027change\u0027, function () {\n fieldInstance.field[property] = parseInt(input.value);\n fieldInstance.$input[0].dispatchEvent(createNewEvent(\u0027change\u0027));\n });\n };\n\n /**\n * Update the next row\u0027s \u0027from\u0027 input when this \u0027to\u0027 input change.\n *\n * @private\n * @param {Object} field\n * @return {function} Event handler\n */\n var updateInputHandler = function (field) {\n return function () {\n var nextRow = this.parentElement.parentElement.parentElement.nextElementSibling;\n if (!nextRow) {\n // This is the last row, nothing to update\n return;\n }\n\n var targetInput = getFirst(\u0027input\u0027, nextRow);\n if (this.value === \u0027\u0027) {\n // No value has been set\n setValue(targetInput, \u0027\u0027);\n return;\n }\n\n var value = parseInt(this.value);\n if (!isNaN(value)) {\n // Increment next from value\n value += 1;\n if (field.max \u0026\u0026 value \u003e= field.max) {\n value = field.max; // Respect max limit\n }\n setValue(targetInput, value);\n }\n\n validateSequence();\n };\n };\n\n /**\n * Add dash column to the given row.\n *\n * @private\n * @param {HTMLTableRowElement} row\n * @param {string} type \u0027td\u0027 or \u0027th\u0027\n * @param {string} [symbol] The \u0027text\u0027 to display\n */\n var addDashCol = function (row, type, symbol) {\n var dash = document.createElement(type);\n dash.classList.add(\u0027h5peditor-dash\u0027);\n if (symbol) {\n dash.innerText = \u0027–\u0027;\n }\n row.insertBefore(dash, row.children[1]);\n };\n\n /**\n * Add text element displaying input value and hide input.\n *\n * @private\n * @param {HTMLInputElement} input\n */\n var addInputText = function (input) {\n // Add static text\n var text = document.createElement(\u0027div\u0027);\n text.classList.add(\u0027h5peditor-input-text\u0027);\n text.innerHTML = input.value;\n input.parentElement.insertBefore(text, input);\n\n // Hide input\n input.style.display = \u0027none\u0027;\n\n // Update static on changes\n input.addEventListener(\u0027change\u0027, function () {\n text.innerHTML = input.value;\n });\n };\n\n /**\n * Look for the given selector/type in the first cell of the given row.\n *\n * @private\n * @param {string} type selector\n * @param {HTMLTableRowElement} row to look in\n */\n var getFirst = function (type, row) {\n return row.children[0].querySelector(type);\n };\n\n /**\n * Look for the given selector/type in the second cell of the given row.\n *\n * @private\n * @param {string} type selector\n * @param {HTMLTableRowElement} row to look in\n */\n var getSecond = function (type, row) {\n return row.children[2].querySelector(type);\n };\n\n /**\n * Set the given value for the given input and trigger the change event.\n *\n * @private\n * @param {HTMLInputElement} input\n * @param {string} value\n */\n var setValue = function (input, value) {\n input.value = value;\n input.dispatchEvent(createNewEvent(\u0027change\u0027));\n };\n\n /**\n * Create a new event, using a fallback for older browsers (IE11)\n *\n * @param {string} type\n * @return {Event}\n */\n var createNewEvent = function (type) {\n if (typeof Event !== \u0027function\u0027) {\n var event = document.createEvent(\u0027Event\u0027);\n event.initEvent(type, true, true);\n return event;\n }\n else {\n return new Event(type)\n }\n };\n\n /**\n * Identify any overlapping ranges and provide an error message.\n *\n * @private\n */\n var validateSequence = function () {\n var prevTo, error;\n for (var i = 0; i \u003c tbody.children.length; i++) {\n var row = tbody.children[i];\n var to = parseInt(getSecond(\u0027input\u0027, row).value);\n\n if (prevTo !== undefined \u0026\u0026 !isNaN(to) \u0026\u0026 to \u003c= prevTo) {\n error = true;\n row.classList.add(\u0027h5p-error-range-overlap\u0027);\n }\n else {\n row.classList.remove(\u0027h5p-error-range-overlap\u0027);\n }\n prevTo = to;\n }\n\n // Display a message\n self.messageArea.innerText = error ? H5PEditor.t(\u0027H5PEditor.RangeList\u0027, \u0027rangeOutOfSequenceWarning\u0027) : \u0027\u0027;\n self.messageArea.classList[error ? \u0027add\u0027 : \u0027remove\u0027](\u0027problem-found\u0027);\n };\n\n /**\n * Create distribute button\n *\n * @private\n * @param {string} label\n * @param {string} warning\n * @param {string} classname\n * @param {function} action\n * @return {HTMLElement}\n */\n var createDistributeButton = function (label, warning, classname, action) {\n\n // Create confirmation dialog\n var confirmDialog = new H5P.ConfirmationDialog({\n dialogText: warning\n }).appendTo(document.body);\n\n confirmDialog.on(\u0027confirmed\u0027, action);\n\n // Create and return button element\n return H5PEditor.createButton(classname, label, function () {\n if (this.getAttribute(\u0027aria-disabled\u0027) !== \u0027true\u0027) {\n // The button has been clicked, activate confirmation dialog if\n // the author has defined any ranges\n if (authorHasDefinedRanges()) {\n confirmDialog.show(this.getBoundingClientRect().top);\n }\n else {\n action();\n }\n }\n }, true)[0];\n };\n\n /**\n * Check if any input fields have gotten values by the author\n *\n * @private\n * @return {boolean}\n */\n var authorHasDefinedRanges = function () {\n for (var i = 0; i \u003c tbody.children.length - 1; i++) {\n var to = parseInt(getSecond(\u0027input\u0027, tbody.children[i]).value);\n if (!isNaN(to)) {\n return true;\n }\n }\n return false;\n };\n\n /**\n * Generate an event handler for distributing ranges equally.\n *\n * @private\n * @param {number} start The minimum value\n * @param {number} end The maximum value\n * @return {function} Event handler\n */\n var distributeEvenlyHandler = function (start, end) {\n return function () {\n // Distribute percentages evenly\n var rowRange = (end - start) / tbody.children.length;\n\n // Go though all the rows\n for (var i = 0; i \u003c tbody.children.length; i++) {\n var row = tbody.children[i];\n var from = start + (rowRange * i);\n setValue(getFirst(\u0027input\u0027, row), Math.floor(from) + (i === 0 ? 0 : 1));\n var secondInput = getSecond(\u0027input\u0027, row);\n setValue(secondInput, Math.floor(from + rowRange));\n secondInput.dispatchEvent(createNewEvent(\u0027keyup\u0027)); // Workaround to remove error messages\n }\n\n validateSequence();\n };\n };\n\n /**\n * Toggle buttons disabled / enabled\n *\n * @private\n * @param {boolean} state true to enable buttons, false to disable\n * @param {HTMLTableRowElement} row to look in\n */\n var toggleButtons = function (state, row) {\n var removeButton = row.children[row.children.length - 1].children[0];\n if (state) {\n enableButton(distributeButton);\n enableButton(removeButton);\n }\n else {\n disableButton(distributeButton);\n disableButton(removeButton);\n }\n };\n\n /**\n * Disables the given button\n *\n * @private\n * @param {HTMLElement} button to look in\n */\n var disableButton = function (button) {\n button.setAttribute(\u0027aria-disabled\u0027, \u0027true\u0027);\n button.removeAttribute(\u0027tabindex\u0027);\n };\n\n /**\n * Enables the given button\n *\n * @private\n * @param {HTMLElement} button to look in\n */\n var enableButton = function (button) {\n button.removeAttribute(\u0027aria-disabled\u0027);\n button.setAttribute(\u0027tabindex\u0027, \u00270\u0027);\n };\n }\n\n // Extend TableList prototype\n RangeList.prototype = Object.create(TableList.prototype);\n RangeList.prototype.constructor = RangeList;\n\n return RangeList;\n})(H5P.jQuery, H5PEditor.TableList);\n\n// Add translations\nH5PEditor.language[\u0027H5PEditor.RangeList\u0027] = {\n \u0027libraryStrings\u0027: {\n \u0027distributeButtonLabel\u0027: \u0027Distribute Evenly\u0027,\n \u0027distributeButtonWarning\u0027: \u0027Values will be changed for all of the ranges. Do you wish to proceed?\u0027,\n \u0027rangeOutOfSequenceWarning\u0027: \u0027The score ranges are out of sequence\u0027\n }\n};\n"
,"h5p-show-when.js":"H5PEditor.ShowWhen = (function ($) {\n\n // Handler for the \u0027select\u0027 semantics type\n function SelectHandler(field, equals) {\n this.satisfied = function () {\n return (equals.indexOf(field.value) !== -1);\n };\n }\n\n // Handler for the \u0027library\u0027 semantics type\n function LibraryHandler(field, equals) {\n this.satisfied = function () {\n var value;\n if (field.currentLibrary !== undefined) {\n value = field.currentLibrary.split(\u0027 \u0027)[0];\n }\n return (equals.indexOf(value) !== -1);\n };\n }\n\n function BooleanHandler(field, equals) {\n this.satisfied = function () {\n return field.value === equals;\n };\n }\n\n // Factory method for creating handlers\n // \"library\", \"select\" and \"boolean\" semantics types supported so far\n function createFieldHandler(field, equals) {\n if (field instanceof H5PEditor.Library) {\n return new LibraryHandler(field, equals);\n }\n else if (field instanceof H5PEditor.Select) {\n return new SelectHandler(field, equals);\n }\n else if (field instanceof H5PEditor.Boolean) {\n return new BooleanHandler(field, equals);\n }\n }\n\n // Handling rules\n function RuleHandler(type) {\n var TYPE_AND = \u0027and\u0027;\n var TYPE_OR = \u0027or\u0027;\n var handlers = [];\n\n type = type || TYPE_OR;\n\n this.add = function (handler) {\n handlers.push(handler);\n };\n\n // Check if rules are satisfied\n this.rulesSatisfied = function () {\n for (var i = 0; i \u003c handlers.length; i++) {\n // check if rule was hit\n var ruleHit = handlers[i].satisfied();\n\n if (ruleHit \u0026\u0026 type === TYPE_OR) {\n return true;\n }\n else if (type === TYPE_AND \u0026\u0026 !ruleHit) {\n return false;\n }\n }\n\n return false;\n };\n }\n\n // Main widget class constructor\n function ShowWhen(parent, field, params, setValue) {\n var self = this;\n\n self.field = field;\n // Outsource readies\n self.passReadies = true;\n self.value = params;\n\n // Create the wrapper:\n var $wrapper = $(\u0027\u003cdiv\u003e\u0027, {\n \u0027class\u0027: \u0027field h5p-editor-widget-show-when\u0027\n });\n var showing = false;\n var config = self.field.showWhen;\n\n if (config === undefined) {\n throw new Error(\u0027You need to set the showWhen in semantics.json property when using the showWhen widget\u0027);\n }\n\n var ruleHandler = new RuleHandler(config.type);\n\n for (var i = 0; i \u003c config.rules.length; i++) {\n var rule = config.rules[i];\n var targetField = H5PEditor.findField(rule.field, parent);\n var handler = createFieldHandler(targetField, rule.equals);\n\n if (handler !== undefined) {\n ruleHandler.add(handler);\n H5PEditor.followField(parent, rule.field, config.detach ? function () {\n if (showing != ruleHandler.rulesSatisfied()) {\n showing = !showing;\n if (showing) {\n $wrapper.appendTo(self.$container);\n }\n else {\n $wrapper.detach();\n }\n }\n } : function () {\n showing = ruleHandler.rulesSatisfied();\n $wrapper.toggleClass(\u0027hidden\u0027, !showing);\n });\n }\n }\n\n // Create the real field:\n var widgetName = config.widget || field.type;\n var fieldInstance = new H5PEditor.widgets[widgetName](parent, field, params, setValue);\n fieldInstance.appendTo($wrapper);\n\n /**\n * Add myself to the DOM\n *\n * @public\n * @param {H5P.jQuery} $container\n */\n self.appendTo = function ($container) {\n if (!config.detach) {\n $wrapper.appendTo($container);\n }\n self.$container = $container;\n };\n\n /**\n * Validate\n *\n * @public\n * @return {boolean}\n */\n self.validate = function () {\n // Only validate if field is shown!\n return showing ? fieldInstance.validate() : true;\n };\n\n self.remove = function () {};\n }\n\n return ShowWhen;\n})(H5PEditor.$);\n\n// Register widget\nH5PEditor.widgets.showWhen = H5PEditor.ShowWhen;\n"
,"scripts/stop-watch.js":"var H5P = H5P || {};\nH5P.SingleChoiceSet = H5P.SingleChoiceSet || {};\n\nH5P.SingleChoiceSet.StopWatch = (function () {\n /**\n * @class {H5P.SingleChoiceSet.StopWatch}\n * @constructor\n */\n function StopWatch() {\n /**\n * @property {number} duration in ms\n */\n this.duration = 0;\n }\n\n /**\n * Starts the stop watch\n *\n * @public\n * @return {H5P.SingleChoiceSet.StopWatch}\n */\n StopWatch.prototype.start = function(){\n /**\n * @property {number}\n */\n this.startTime = Date.now();\n return this;\n };\n\n /**\n * Stops the stopwatch, and returns the duration in seconds.\n *\n * @public\n * @return {number}\n */\n StopWatch.prototype.stop = function(){\n this.duration = this.duration + Date.now() - this.startTime;\n return this.passedTime();\n };\n\n /**\n * Sets the duration to 0\n *\n * @public\n */\n StopWatch.prototype.reset = function(){\n this.duration = 0;\n };\n\n /**\n * Returns the passed time in seconds\n *\n * @public\n * @return {number}\n */\n StopWatch.prototype.passedTime = function(){\n return Math.round(this.duration / 10) / 100;\n };\n\n return StopWatch;\n})();\n"
,"scripts/sound-effects.js":"H5P.SingleChoiceSet = H5P.SingleChoiceSet || {};\n\nH5P.SingleChoiceSet.SoundEffects = (function () {\n var isDefined = false;\n\n var SoundEffects = {\n types: [\n \u0027positive-short\u0027,\n \u0027negative-short\u0027\n ]\n };\n\n /**\n * Setup defined sounds\n *\n * @param {string} libraryPath\n * @return {boolean} True if setup was successfull, otherwise false\n */\n SoundEffects.setup = function (libraryPath) {\n if (isDefined || !H5P.SoundJS.initializeDefaultPlugins()) {\n return false;\n }\n\n H5P.SoundJS.alternateExtensions = [\u0027mp3\u0027];\n for (var i = 0; i \u003c SoundEffects.types.length; i++) {\n var type = SoundEffects.types[i];\n H5P.SoundJS.registerSound(libraryPath + \u0027sounds/\u0027 + type + \u0027.ogg\u0027, type);\n }\n isDefined = true;\n\n return true;\n };\n\n /**\n * Play a sound\n *\n * @param {string} type Name of the sound as defined in [SoundEffects.types]{@link H5P.SoundEffects.SoundEffects#types}\n * @param {number} delay Delay in milliseconds\n */\n SoundEffects.play = function (type, delay) {\n H5P.SoundJS.play(type, H5P.SoundJS.INTERRUPT_NONE, (delay || 0));\n };\n\n return SoundEffects;\n})();\n"
,"scripts/xapi-event-builder.js":"var H5P = H5P || {};\nH5P.SingleChoiceSet = H5P.SingleChoiceSet || {};\n\nH5P.SingleChoiceSet.XApiEventBuilder = (function ($, EventDispatcher) {\n /**\n * @typedef {object} LocalizedString\n * @property {string} en-US\n */\n\n /**\n * @class {H5P.SingleChoiceSet.XApiEventDefinitionBuilder}\n * @constructor\n */\n function XApiEventDefinitionBuilder(){\n EventDispatcher.call(this);\n /**\n * @property {object} attributes\n * @property {string} attributes.name\n * @property {string} attributes.description\n * @property {string} attributes.interactionType\n * @property {string} attributes.correctResponsesPattern\n * @property {object} attributes.optional\n */\n this.attributes = {};\n }\n\n XApiEventDefinitionBuilder.prototype = Object.create(EventDispatcher.prototype);\n XApiEventDefinitionBuilder.prototype.constructor = XApiEventDefinitionBuilder;\n\n\n /**\n * Sets name\n * @param {string} name\n * @return {XApiEventDefinitionBuilder}\n */\n XApiEventDefinitionBuilder.prototype.name = function (name) {\n this.attributes.name = name;\n return this;\n };\n\n /**\n * Question text and any additional information to generate the report.\n * @param {string} description\n * @return {XApiEventDefinitionBuilder}\n */\n XApiEventDefinitionBuilder.prototype.description = function (description) {\n this.attributes.description = description;\n return this;\n };\n\n /**\n * Type of the interaction.\n * @param {string} interactionType\n * @see {@link https://github.com/adlnet/xAPI-Spec/blob/master/xAPI-Data.md#interaction-types|xAPI Spec}\n * @return {XApiEventDefinitionBuilder}\n */\n XApiEventDefinitionBuilder.prototype.interactionType = function (interactionType) {\n this.attributes.interactionType = interactionType;\n return this;\n };\n\n /**\n * A pattern for determining the correct answers of the interaction\n * @param {string[]} correctResponsesPattern\n * @see {@link https://github.com/adlnet/xAPI-Spec/blob/master/xAPI-Data.md#response-patterns|xAPI Spec}\n * @return {XApiEventDefinitionBuilder}\n */\n XApiEventDefinitionBuilder.prototype.correctResponsesPattern = function (correctResponsesPattern) {\n this.attributes.correctResponsesPattern = correctResponsesPattern;\n return this;\n };\n\n /**\n * Sets optional attributes\n * @param {object} optional Can have one of the following configuration objects: choices, scale, source, target, steps\n * @return {XApiEventDefinitionBuilder}\n */\n XApiEventDefinitionBuilder.prototype.optional = function (optional) {\n this.attributes.optional = optional;\n return this;\n };\n\n /**\n * @return {object}\n */\n XApiEventDefinitionBuilder.prototype.build = function () {\n var definition = {};\n\n // sets attributes\n setAttribute(definition, \u0027name\u0027, localizeToEnUS(this.attributes.name));\n setAttribute(definition, \u0027description\u0027, localizeToEnUS(this.attributes.description));\n setAttribute(definition, \u0027interactionType\u0027, this.attributes.interactionType);\n setAttribute(definition, \u0027correctResponsesPattern\u0027, this.attributes.correctResponsesPattern);\n setAttribute(definition, \u0027type\u0027, \u0027http://adlnet.gov/expapi/activities/cmi.interaction\u0027);\n\n // adds the optional object to the definition\n if(this.attributes.optional){\n $.extend(definition, this.attributes.optional);\n }\n\n return definition;\n };\n\n // -----------------------------------------------------\n\n /**\n *\n * @constructor\n */\n function XApiEventResultBuilder(){\n EventDispatcher.call(this);\n /**\n * @property {object} attributes\n * @property {string} attributes.completion\n * @property {boolean} attributes.success\n * @property {boolean} attributes.response\n * @property {number} attributes.rawScore\n * @property {number} attributes.maxScore\n */\n this.attributes = {};\n }\n\n XApiEventResultBuilder.prototype = Object.create(EventDispatcher.prototype);\n XApiEventResultBuilder.prototype.constructor = XApiEventResultBuilder;\n\n /**\n * @param {boolean} completion\n * @return {XApiEventResultBuilder}\n */\n XApiEventResultBuilder.prototype.completion = function (completion) {\n this.attributes.completion = completion;\n return this;\n };\n\n /**\n * @param {boolean} success\n * @return {XApiEventResultBuilder}\n */\n XApiEventResultBuilder.prototype.success = function (success) {\n this.attributes.success = success;\n return this;\n };\n\n /**\n * @param {number} duration The duraction in seconds\n * @return {XApiEventResultBuilder}\n */\n XApiEventResultBuilder.prototype.duration = function (duration) {\n this.attributes.duration = duration;\n return this;\n };\n\n /**\n * Sets response\n * @param {string|string[]} response\n * @return {XApiEventResultBuilder}\n */\n XApiEventResultBuilder.prototype.response = function (response) {\n this.attributes.response = (typeof response === \u0027string\u0027) ? response : response.join(\u0027[,]\u0027);\n return this;\n };\n\n /**\n * Sets the score, and max score\n * @param {number} score\n * @param {number} maxScore\n * @return {XApiEventResultBuilder}\n */\n XApiEventResultBuilder.prototype.score = function (score, maxScore) {\n this.attributes.rawScore = score;\n this.attributes.maxScore = maxScore;\n return this;\n };\n\n /**\n * Builds the result object\n * @return {object}\n */\n XApiEventResultBuilder.prototype.build = function () {\n var result = {};\n\n setAttribute(result, \u0027response\u0027, this.attributes.response);\n setAttribute(result, \u0027completion\u0027, this.attributes.completion);\n setAttribute(result, \u0027success\u0027, this.attributes.success);\n\n if(isDefined(this.attributes.duration)){\n setAttribute(result, \u0027duration\u0027,\u0027PT\u0027 + this.attributes.duration + \u0027S\u0027);\n }\n\n // sets score\n if (isDefined(this.attributes.rawScore)) {\n result.score = {};\n setAttribute(result.score, \u0027raw\u0027, this.attributes.rawScore);\n\n if (isDefined(this.attributes.maxScore) \u0026\u0026 this.attributes.maxScore \u003e 0) {\n setAttribute(result.score, \u0027min\u0027, 0);\n setAttribute(result.score, \u0027max\u0027, this.attributes.maxScore);\n setAttribute(result.score, \u0027min\u0027, 0);\n setAttribute(result.score, \u0027scaled\u0027, Math.round(this.attributes.rawScore / this.attributes.maxScore * 10000) / 10000);\n }\n }\n\n return result;\n };\n\n // -----------------------------------------------------\n\n /**\n * @class {H5P.SingleChoiceSet.XApiEventBuilder}\n */\n function XApiEventBuilder() {\n EventDispatcher.call(this);\n /**\n * @property {object} attributes\n * @property {string} attributes.contentId\n * @property {string} attributes.subContentId\n */\n this.attributes = {};\n }\n\n XApiEventBuilder.prototype = Object.create(EventDispatcher.prototype);\n XApiEventBuilder.prototype.constructor = XApiEventBuilder;\n\n\n /**\n * @param {object} verb\n *\n * @public\n * @return {H5P.SingleChoiceSet.XApiEventBuilder}\n */\n XApiEventBuilder.prototype.verb = function (verb) {\n this.attributes.verb = verb;\n return this;\n };\n\n /**\n * @param {string} name\n * @param {string} mbox\n * @param {string} objectType\n *\n * @public\n * @return {H5P.SingleChoiceSet.XApiEventBuilder}\n */\n XApiEventBuilder.prototype.actor = function (name, mbox, objectType) {\n this.attributes.actor = {\n name: name,\n mbox: mbox,\n objectType: objectType\n };\n\n return this;\n };\n\n /**\n * Sets contentId\n * @param {string} contentId\n * @param {string} [subContentId]\n * @return {H5P.SingleChoiceSet.XApiEventBuilder}\n */\n XApiEventBuilder.prototype.contentId = function (contentId, subContentId) {\n this.attributes.contentId = contentId;\n this.attributes.subContentId = subContentId;\n return this;\n };\n\n /**\n * Sets parent in context\n *\n * @param {string} parentContentId\n * @param {string} [parentSubContentId]\n * @return {H5P.SingleChoiceSet.XApiEventBuilder}\n */\n XApiEventBuilder.prototype.context = function (parentContentId, parentSubContentId) {\n this.attributes.parentContentId = parentContentId;\n this.attributes.parentSubContentId = parentSubContentId;\n return this;\n };\n\n /**\n * @param {object} result\n *\n * @public\n * @return {H5P.SingleChoiceSet.XApiEventBuilder}\n */\n XApiEventBuilder.prototype.result = function (result) {\n this.attributes.result = result;\n return this;\n };\n\n /**\n * @param {object} objectDefinition\n *\n * @public\n * @return {H5P.SingleChoiceSet.XApiEventBuilder}\n */\n XApiEventBuilder.prototype.objectDefinition = function (objectDefinition) {\n this.attributes.objectDefinition = objectDefinition;\n return this;\n };\n\n /**\n * Returns the buildt event\n * @public\n * @return {H5P.XAPIEvent}\n */\n XApiEventBuilder.prototype.build = function(){\n var event = new H5P.XAPIEvent();\n\n event.setActor();\n event.setVerb(this.attributes.verb);\n\n // sets context\n if(this.attributes.parentContentId || this.attributes.parentSubContentId){\n event.data.statement.context = {\n \u0027contextActivities\u0027: {\n \u0027parent\u0027: [\n {\n \u0027id\u0027: getContentXAPIId(this.attributes.parentContentId, this.attributes.parentSubContentId),\n \u0027objectType\u0027: \"Activity\"\n }\n ]\n }\n };\n }\n\n event.data.statement.object = {\n \u0027id\u0027: getContentXAPIId(this.attributes.contentId, this.attributes.subContentId),\n \u0027objectType\u0027: \u0027Activity\u0027\n };\n\n setAttribute(event.data, \u0027actor\u0027, this.attributes.actor);\n setAttribute(event.data.statement, \u0027result\u0027, this.attributes.result);\n setAttribute(event.data.statement.object, \u0027definition\u0027, this.attributes.objectDefinition);\n\n // sets h5p specific attributes\n if(event.data.statement.object.definition \u0026\u0026 (this.attributes.contentId || this.attributes.subContentId)) {\n var extensions = event.data.statement.object.definition.extensions = {};\n setAttribute(extensions, \u0027http://h5p.org/x-api/h5p-local-content-id\u0027, this.attributes.contentId);\n setAttribute(extensions, \u0027http://h5p.org/x-api/h5p-subContentId\u0027, this.attributes.subContentId);\n }\n\n return event;\n };\n\n /**\n * Creates a Localized String object for en-US\n *\n * @param str\n * @return {LocalizedString}\n */\n var localizeToEnUS = function(str){\n if(str != undefined){\n return {\n \u0027en-US\u0027: cleanString(str)\n };\n }\n };\n\n /**\n * Generates an id for the content\n * @param {string} contentId\n * @param {string} [subContentId]\n *\n * @see {@link https://github.com/h5p/h5p-php-library/blob/master/js/h5p-x-api-event.js#L240-L249}\n * @return {string}\n */\n var getContentXAPIId = function (contentId, subContentId) {\n if (contentId \u0026\u0026 H5PIntegration \u0026\u0026 H5PIntegration.contents) {\n var id = H5PIntegration.contents[\u0027cid-\u0027 + contentId].url;\n\n if (subContentId) {\n id += \u0027?subContentId=\u0027 + subContentId;\n }\n\n return id;\n }\n };\n\n /**\n * Removes html elements from string\n *\n * @param {string} str\n * @return {string}\n */\n var cleanString = function (str) {\n return $(\u0027\u003cdiv\u003e\u0027 + str + \u0027\u003c/div\u003e\u0027).text().trim();\n };\n\n var isDefined = function(val){\n return typeof val !== \u0027undefined\u0027;\n };\n\n function setAttribute(obj, key, value, required){\n if(isDefined(value)){\n obj[key] = value;\n } else if (required) {\n console.error(\"xApiEventBuilder: No value for [\" + key + \"] in\", obj);\n }\n }\n\n /**\n * Creates a new XApiEventBuilder\n *\n * @public\n * @static\n * @return {H5P.SingleChoiceSet.XApiEventBuilder}\n */\n XApiEventBuilder.create = function(){\n return new XApiEventBuilder();\n };\n\n /**\n * Creates a new XApiEventDefinitionBuilder\n *\n * @public\n * @static\n * @return {XApiEventDefinitionBuilder}\n */\n XApiEventBuilder.createDefinition = function(){\n return new XApiEventDefinitionBuilder();\n };\n\n /**\n * Creates a new XApiEventDefinitionBuilder\n *\n * @public\n * @static\n * @return {XApiEventResultBuilder}\n */\n XApiEventBuilder.createResult = function(){\n return new XApiEventResultBuilder();\n };\n\n /**\n * Returns choice to be used with \u0027cmi.interaction\u0027 for Activity of type \u0027choice\u0027\n *\n * @param {string} id\n * @param {string} description\n *\n * @public\n * @static\n * @see {@link https://github.com/adlnet/xAPI-Spec/blob/master/xAPI-Data.md#choice|xAPI-Spec}\n * @return {object}\n */\n XApiEventBuilder.createChoice = function(id, description){\n return {\n id: id,\n description: localizeToEnUS(description)\n };\n };\n\n /**\n * Takes an array of correct ids, and joins them to a \u0027correct response pattern\u0027\n *\n * @param {string[]} ids\n *\n * @public\n * @static\n * @see {@link https://github.com/adlnet/xAPI-Spec/blob/master/xAPI-Data.md#choice|xAPI-Spec}\n * @return {string}\n */\n XApiEventBuilder.createCorrectResponsePattern = function(ids){\n return ids.join(\u0027[,]\u0027);\n };\n\n /**\n * Interaction types\n *\n * @readonly\n * @enum {String}\n */\n XApiEventBuilder.interactionTypes = {\n CHOICE: \u0027choice\u0027,\n COMPOUND: \u0027compound\u0027,\n FILL_IN: \u0027fill-in\u0027,\n MATCHING: \u0027matching\u0027,\n TRUE_FALSE: \u0027true-false\u0027\n };\n\n /**\n * Verbs\n *\n * @readonly\n * @enum {String}\n */\n XApiEventBuilder.verbs = {\n ANSWERED: \u0027answered\u0027\n };\n\n return XApiEventBuilder;\n})(H5P.jQuery, H5P.EventDispatcher);\n"
,"scripts/result-slide.js":"var H5P = H5P || {};\nH5P.SingleChoiceSet = H5P.SingleChoiceSet || {};\n/**\n * SingleChoiceResultSlide - Represents the result slide\n */\nH5P.SingleChoiceSet.ResultSlide = (function ($, EventDispatcher) {\n\n /**\n * @constructor\n * @param {number} maxscore Max score\n */\n function ResultSlide(maxscore) {\n EventDispatcher.call(this);\n\n this.$feedbackContainer = $(\u0027\u003cdiv\u003e\u0027, {\n \u0027class\u0027: \u0027h5p-sc-feedback-container\u0027,\n \u0027tabindex\u0027: \u0027-1\u0027\n });\n\n this.$buttonContainer = $(\u0027\u003cdiv/\u003e\u0027, {\n \u0027class\u0027: \u0027h5p-sc-button-container\u0027\n });\n\n var $resultContainer = $(\u0027\u003cdiv/\u003e\u0027, {\n \u0027class\u0027: \u0027h5p-sc-result-container\u0027\n }).append(this.$feedbackContainer)\n .append(this.$buttonContainer);\n\n this.$resultSlide = $(\u0027\u003cdiv\u003e\u0027, {\n \u0027class\u0027: \u0027h5p-sc-slide h5p-sc-set-results\u0027,\n \u0027css\u0027: {left: (maxscore * 100) + \u0027%\u0027}\n }).append($resultContainer);\n }\n\n // inherits from EventDispatchers prototype\n ResultSlide.prototype = Object.create(EventDispatcher.prototype);\n\n // set the constructor\n ResultSlide.prototype.constructor = ResultSlide;\n\n /**\n * Focus feedback container.\n */\n ResultSlide.prototype.focusScore = function () {\n this.$feedbackContainer.focus();\n };\n\n /**\n * Append the resultslide to a container\n *\n * @param {jQuery} $container The container\n * @return {jQuery} This dom element\n */\n ResultSlide.prototype.appendTo = function ($container) {\n this.$resultSlide.appendTo($container);\n return this.$resultSlide;\n };\n\n return ResultSlide;\n})(H5P.jQuery, H5P.EventDispatcher);\n"
,"scripts/solution-view.js":"var H5P = H5P || {};\nH5P.SingleChoiceSet = H5P.SingleChoiceSet || {};\n\nH5P.SingleChoiceSet.SolutionView = (function ($, EventDispatcher) {\n /**\n * Constructor function.\n */\n function SolutionView(id, choices, l10n) {\n EventDispatcher.call(this);\n var self = this;\n self.id = id;\n this.choices = choices;\n\n this.$solutionView = $(\u0027\u003cdiv\u003e\u0027, {\n \u0027class\u0027: \u0027h5p-sc-solution-view\u0027\n });\n\n // Add header\n this.$header = $(\u0027\u003cdiv\u003e\u0027, {\n \u0027class\u0027: \u0027h5p-sc-solution-view-header\u0027\n }).appendTo(this.$solutionView);\n\n this.$title = $(\u0027\u003cdiv\u003e\u0027, {\n \u0027class\u0027: \u0027h5p-sc-solution-view-title\u0027,\n \u0027html\u0027: l10n.solutionViewTitle,\n \u0027tabindex\u0027: \u0027-1\u0027\n });\n this.$title = this.addAriaPunctuation(this.$title);\n this.$header.append(this.$title);\n\n // Close solution view button\n $(\u0027\u003cbutton\u003e\u0027, {\n \u0027role\u0027: \u0027button\u0027,\n \u0027aria-label\u0027: l10n.closeButtonLabel + \u0027.\u0027,\n \u0027class\u0027: \u0027h5p-joubelui-button h5p-sc-close-solution-view\u0027,\n \u0027click\u0027: function () {\n self.hide();\n }\n }).appendTo(this.$header);\n\n self.populate();\n }\n\n /**\n * Will append the solution view to a container DOM\n * @param {jQuery} $container The DOM object to append to\n */\n SolutionView.prototype.appendTo = function ($container) {\n this.$solutionView.appendTo($container);\n };\n\n /**\n * Shows the solution view\n */\n SolutionView.prototype.show = function () {\n var self = this;\n self.$solutionView.addClass(\u0027visible\u0027);\n self.$title.focus();\n\n $(document).on(\u0027keyup.solutionview\u0027, function (event) {\n if (event.keyCode === 27) { // Escape\n self.hide();\n $(document).off(\u0027keyup.solutionview\u0027);\n }\n });\n };\n\n /**\n * Hides the solution view\n */\n SolutionView.prototype.hide = function () {\n this.$solutionView.removeClass(\u0027visible\u0027);\n this.trigger(\u0027hide\u0027, this);\n };\n\n\n /**\n * Populates the solution view\n */\n SolutionView.prototype.populate = function () {\n var self = this;\n self.$choices = $(\u0027\u003cdl\u003e\u0027, {\n \u0027class\u0027: \u0027h5p-sc-solution-choices\u0027,\n \u0027tabindex\u0027: -1,\n });\n\n this.choices.forEach(function (choice) {\n if (choice.question \u0026\u0026 choice.answers \u0026\u0026 choice.answers.length !== 0) {\n var $question = self.addAriaPunctuation($(\u0027\u003cdt\u003e\u0027, {\n \u0027class\u0027: \u0027h5p-sc-solution-question\u0027,\n html: choice.question\n }));\n\n self.$choices.append($question);\n\n var $answer = self.addAriaPunctuation($(\u0027\u003cdd\u003e\u0027, {\n \u0027class\u0027: \u0027h5p-sc-solution-answer\u0027,\n html: choice.answers[0]\n }));\n\n self.$choices.append($answer);\n }\n });\n self.$choices.appendTo(this.$solutionView);\n };\n\n /**\n * If a jQuery elements text is missing punctuation, add an aria-label to the element\n * containing the text, and adding an extra \"period\"-symbol at the end.\n *\n * @param {jQuery} $element A jQuery-element\n * @returns {jQuery} The mutated jQuery-element\n */\n SolutionView.prototype.addAriaPunctuation = function ($element) {\n var text = $element.text().trim();\n\n if (!this.hasPunctuation(text)) {\n $element.attr(\u0027aria-label\u0027, text + \u0027.\u0027);\n }\n\n return $element;\n };\n\n /**\n * Checks if a string ends with punctuation\n *\n * @private\n * @param {String} text Input string\n */\n SolutionView.prototype.hasPunctuation = function (text) {\n return /[,.?!]$/.test(text);\n };\n\n return SolutionView;\n})(H5P.jQuery, H5P.EventDispatcher);\n"
,"scripts/single-choice-alternative.js":"var H5P = H5P || {};\nH5P.SingleChoiceSet = H5P.SingleChoiceSet || {};\n\nH5P.SingleChoiceSet.Alternative = (function ($, EventDispatcher) {\n\n /**\n * @constructor\n *\n * @param {object} options Options for the alternative\n */\n function Alternative(options) {\n EventDispatcher.call(this);\n var self = this;\n\n this.options = options;\n\n var triggerAlternativeSelected = function (event) {\n self.trigger(\u0027alternative-selected\u0027, {\n correct: self.options.correct,\n $element: self.$alternative,\n answerIndex: self.options.answerIndex\n });\n\n event.preventDefault();\n };\n\n this.$alternative = $(\u0027\u003cli\u003e\u0027, {\n \u0027class\u0027: \u0027h5p-sc-alternative h5p-sc-is-\u0027 + (this.options.correct ? \u0027correct\u0027 : \u0027wrong\u0027),\n \u0027role\u0027: \u0027button\u0027,\n \u0027tabindex\u0027: -1,\n \u0027on\u0027: {\n \u0027keydown\u0027: function (event) {\n switch (event.which) {\n case 13: // Enter\n case 32: // Space\n // Answer question\n triggerAlternativeSelected(event);\n break;\n\n case 35: // End button\n // Go to previous Option\n self.trigger(\u0027lastOption\u0027, event);\n event.preventDefault();\n break;\n\n case 36: // Home button\n // Go to previous Option\n self.trigger(\u0027firstOption\u0027, event);\n event.preventDefault();\n break;\n\n case 37: // Left Arrow\n case 38: // Up Arrow\n // Go to previous Option\n self.trigger(\u0027previousOption\u0027, event);\n event.preventDefault();\n break;\n\n case 39: // Right Arrow\n case 40: // Down Arrow\n // Go to next Option\n self.trigger(\u0027nextOption\u0027, event);\n event.preventDefault();\n break;\n }\n }\n },\n \u0027focus\u0027: function (event) {\n self.trigger(\u0027focus\u0027, event);\n },\n \u0027click\u0027: triggerAlternativeSelected\n });\n\n this.$alternative.append($(\u0027\u003cdiv\u003e\u0027, {\n \u0027class\u0027: \u0027h5p-sc-progressbar\u0027\n }));\n\n this.$alternative.append($(\u0027\u003cdiv\u003e\u0027, {\n \u0027class\u0027: \u0027h5p-sc-label\u0027,\n \u0027html\u0027: this.options.text\n }));\n\n this.$alternative.append($(\u0027\u003cdiv\u003e\u0027, {\n \u0027class\u0027: \u0027h5p-sc-status\u0027\n }));\n }\n\n Alternative.prototype = Object.create(EventDispatcher.prototype);\n Alternative.prototype.constructor = Alternative;\n\n /**\n * Is this alternative the correct one?\n *\n * @return {boolean} Correct or not?\n */\n Alternative.prototype.isCorrect = function () {\n return this.options.correct;\n };\n\n /**\n * Move focus to this option.\n */\n Alternative.prototype.focus = function () {\n this.$alternative.focus();\n };\n\n /**\n * Makes it possible to tab your way to this option.\n */\n Alternative.prototype.tabbable = function () {\n this.$alternative.attr(\u0027tabindex\u0027, 0);\n };\n\n /**\n * Make sure it\u0027s NOT possible to tab your way to this option.\n */\n Alternative.prototype.notTabbable = function () {\n this.$alternative.attr(\u0027tabindex\u0027, -1);\n };\n\n /**\n * Append the alternative to a DOM container\n *\n * @param {jQuery} $container The Dom element to append to\n * @return {jQuery} This dom element\n */\n Alternative.prototype.appendTo = function ($container) {\n $container.append(this.$alternative);\n return this.$alternative;\n };\n\n return Alternative;\n\n})(H5P.jQuery, H5P.EventDispatcher);\n"
,"scripts/single-choice.js":"var H5P = H5P || {};\nH5P.SingleChoiceSet = H5P.SingleChoiceSet || {};\n\nH5P.SingleChoiceSet.SingleChoice = (function ($, EventDispatcher, Alternative) {\n /**\n * Constructor function.\n */\n function SingleChoice(options, index, id) {\n EventDispatcher.call(this);\n // Extend defaults with provided options\n this.options = $.extend(true, {}, {\n question: \u0027\u0027,\n answers: []\n }, options);\n // Keep provided id.\n this.index = index;\n this.id = id;\n this.answered = false;\n\n for (var i = 0; i \u003c this.options.answers.length; i++) {\n this.options.answers[i] = {\n text: this.options.answers[i],\n correct: i === 0,\n answerIndex: i\n };\n }\n // Randomize alternatives\n this.options.answers = H5P.shuffleArray(this.options.answers);\n }\n\n SingleChoice.prototype = Object.create(EventDispatcher.prototype);\n SingleChoice.prototype.constructor = SingleChoice;\n\n /**\n * appendTo function invoked to append SingleChoice to container\n *\n * @param {jQuery} $container\n * @param {boolean} isCurrent Current slide we are on\n */\n SingleChoice.prototype.appendTo = function ($container, isCurrent) {\n var self = this;\n this.$container = $container;\n\n // Index of the currently focused option.\n var focusedOption;\n\n this.$choice = $(\u0027\u003cdiv\u003e\u0027, {\n \u0027class\u0027: \u0027h5p-sc-slide h5p-sc\u0027 + (isCurrent ? \u0027 h5p-sc-current-slide\u0027 : \u0027\u0027),\n css: {\u0027left\u0027: (self.index * 100) + \u0027%\u0027}\n });\n\n var questionId = \u0027single-choice-\u0027 + self.id + \u0027-question-\u0027 + self.index;\n\n this.$choice.append($(\u0027\u003cdiv\u003e\u0027, {\n \u0027id\u0027: questionId,\n \u0027class\u0027: \u0027h5p-sc-question\u0027,\n \u0027html\u0027: this.options.question\n }));\n\n var $alternatives = $(\u0027\u003cul\u003e\u0027, {\n \u0027class\u0027: \u0027h5p-sc-alternatives\u0027,\n \u0027role\u0027: \u0027application\u0027,\n \u0027aria-labelledby\u0027: questionId\n });\n\n /**\n * List of Alternatives\n *\n * @type {Alternative[]}\n */\n this.alternatives = self.options.answers.map(function (opts) {\n return new Alternative(opts);\n });\n\n /**\n * Handles click on an alternative\n */\n var handleAlternativeSelected = function (event) {\n var $element = event.data.$element;\n var correct = event.data.correct;\n var answerIndex = event.data.answerIndex;\n\n if ($element.parent().hasClass(\u0027h5p-sc-selected\u0027)) {\n return;\n }\n\n self.trigger(\u0027alternative-selected\u0027, {\n correct: correct,\n index: self.index,\n answerIndex: answerIndex\n });\n\n H5P.Transition.onTransitionEnd($element.find(\u0027.h5p-sc-progressbar\u0027), function () {\n $element.addClass(\u0027h5p-sc-drummed\u0027);\n self.showResult(correct, answerIndex);\n }, 700);\n\n $element.addClass(\u0027h5p-sc-selected\u0027).parent().addClass(\u0027h5p-sc-selected\u0027);\n\n // indicate that this question is anwered\n this.setAnswered(true);\n };\n\n /**\n * Handles focusing one of the options, making the rest non-tabbable.\n * @private\n */\n var handleFocus = function (answer, index) {\n // Keep track of currently focused option\n focusedOption = index;\n\n // remove tabbable all alternatives\n self.alternatives.forEach(function (alternative) {\n alternative.notTabbable();\n });\n answer.tabbable();\n };\n\n /**\n * Handles moving the focus from the current option to the previous option.\n * @private\n */\n var handlePreviousOption = function () {\n if (focusedOption === 0) {\n // wrap around to last\n this.focusOnAlternative(self.alternatives.length - 1);\n }\n else {\n this.focusOnAlternative(focusedOption - 1);\n }\n };\n\n /**\n * Handles moving the focus from the current option to the next option.\n * @private\n */\n var handleNextOption = function () {\n if ((focusedOption === this.alternatives.length - 1)) {\n // wrap around to first\n this.focusOnAlternative(0);\n }\n else {\n this.focusOnAlternative(focusedOption + 1);\n }\n };\n\n /**\n * Handles moving the focus to the first option\n * @private\n */\n var handleFirstOption = function () {\n this.focusOnAlternative(0);\n };\n\n /**\n * Handles moving the focus to the last option\n * @private\n */\n var handleLastOption = function () {\n this.focusOnAlternative(self.alternatives.length - 1);\n };\n\n for (var i = 0; i \u003c this.alternatives.length; i++) {\n var alternative = this.alternatives[i];\n\n if (i === 0) {\n alternative.tabbable();\n }\n\n alternative.appendTo($alternatives);\n alternative.on(\u0027focus\u0027, handleFocus.bind(this, alternative, i), this);\n alternative.on(\u0027alternative-selected\u0027, handleAlternativeSelected, this);\n alternative.on(\u0027previousOption\u0027, handlePreviousOption, this);\n alternative.on(\u0027nextOption\u0027, handleNextOption, this);\n alternative.on(\u0027firstOption\u0027, handleFirstOption, this);\n alternative.on(\u0027lastOption\u0027, handleLastOption, this);\n\n }\n\n this.$choice.append($alternatives);\n $container.append(this.$choice);\n return this.$choice;\n };\n\n /**\n * Focus on an alternative by index\n *\n * @param {Number} index The index of the alternative to focus on\n */\n SingleChoice.prototype.focusOnAlternative = function (index) {\n if (!this.answered) {\n this.alternatives[index].focus();\n }\n };\n\n /**\n * Sets if the question was answered\n *\n * @param {Boolean} answered If this question was answered\n */\n SingleChoice.prototype.setAnswered = function (answered) {\n this.answered = answered;\n };\n\n /**\n * Reveals the result for a question\n *\n * @param {boolean} correct True uf answer was correct, otherwise false\n * @param {number} answerIndex Original index of answer\n */\n SingleChoice.prototype.showResult = function (correct, answerIndex) {\n var self = this;\n\n var $correctAlternative = self.$choice.find(\u0027.h5p-sc-is-correct\u0027);\n\n H5P.Transition.onTransitionEnd($correctAlternative, function () {\n self.trigger(\u0027finished\u0027, {\n correct: correct,\n index: self.index,\n answerIndex: answerIndex\n });\n }, 600);\n\n // Reveal corrects and wrong\n self.$choice.find(\u0027.h5p-sc-is-wrong\u0027).addClass(\u0027h5p-sc-reveal-wrong\u0027);\n $correctAlternative.addClass(\u0027h5p-sc-reveal-correct\u0027);\n };\n\n return SingleChoice;\n\n})(H5P.jQuery, H5P.EventDispatcher, H5P.SingleChoiceSet.Alternative);\n"
,"scripts/single-choice-set.js":"var H5P = H5P || {};\n\nH5P.SingleChoiceSet = (function ($, UI, Question, SingleChoice, SolutionView, ResultSlide, SoundEffects, XApiEventBuilder, StopWatch) {\n /**\n * @constructor\n * @extends Question\n * @param {object} options Options for single choice set\n * @param {string} contentId H5P instance id\n * @param {Object} contentData H5P instance data\n */\n function SingleChoiceSet(options, contentId, contentData) {\n var self = this;\n\n // Extend defaults with provided options\n this.contentId = contentId;\n Question.call(this, \u0027single-choice-set\u0027);\n this.options = $.extend(true, {}, {\n choices: [],\n overallFeedback: [],\n behaviour: {\n autoContinue: true,\n timeoutCorrect: 2000,\n timeoutWrong: 3000,\n soundEffectsEnabled: true,\n enableRetry: true,\n enableSolutionsButton: true,\n passPercentage: 100\n }\n }, options);\n if (contentData \u0026\u0026 contentData.previousState !== undefined) {\n this.currentIndex = contentData.previousState.progress;\n this.results = contentData.previousState.answers;\n }\n this.currentIndex = this.currentIndex || 0;\n this.results = this.results || {\n corrects: 0,\n wrongs: 0\n };\n\n if (!this.options.behaviour.autoContinue) {\n this.options.behaviour.timeoutCorrect = 0;\n this.options.behaviour.timeoutWrong = 0;\n }\n\n /**\n * @property {StopWatch[]} Stop watches for tracking duration of slides\n */\n this.stopWatches = [];\n this.startStopWatch(this.currentIndex);\n\n /**\n * The users input on the questions. Uses the same index as this.options.choices\n * @type {number[]}\n */\n this.userResponses = [];\n\n this.muted = (this.options.behaviour.soundEffectsEnabled === false);\n\n this.l10n = H5P.jQuery.extend({\n correctText: \u0027Correct!\u0027,\n incorrectText: \u0027Incorrect! Correct answer was: :text\u0027,\n nextButtonLabel: \u0027Next question\u0027,\n showSolutionButtonLabel: \u0027Show solution\u0027,\n retryButtonLabel: \u0027Retry\u0027,\n closeButtonLabel: \u0027Close\u0027,\n solutionViewTitle: \u0027Solution\u0027,\n slideOfTotal: \u0027Slide :num of :total\u0027,\n muteButtonLabel: \"Mute feedback sound\",\n scoreBarLabel: \u0027You got :num out of :total points\u0027\n }, options.l10n !== undefined ? options.l10n : {});\n\n this.$container = $(\u0027\u003cdiv\u003e\u0027, {\n \u0027class\u0027: \u0027h5p-sc-set-wrapper navigatable\u0027 + (!this.options.behaviour.autoContinue ? \u0027 next-button-mode\u0027 : \u0027\u0027)\n });\n\n this.$slides = [];\n // An array containing the SingleChoice instances\n this.choices = [];\n\n /**\n * Keeps track of buttons that will be hidden\n * @type {Array}\n */\n self.buttonsToBeHidden = [];\n\n /**\n * The solution dialog\n * @type {SolutionView}\n */\n this.solutionView = new SolutionView(contentId, this.options.choices, this.l10n);\n\n this.$choices = $(\u0027\u003cdiv\u003e\u0027, {\n \u0027class\u0027: \u0027h5p-sc-set h5p-sc-animate\u0027\n });\n\n // sometimes an empty object is in the choices\n this.options.choices = this.options.choices.filter(function (choice) {\n return choice !== undefined \u0026\u0026 !!choice.answers;\n });\n\n var numQuestions = this.options.choices.length;\n\n // Create progressbar\n self.progressbar = UI.createProgressbar(numQuestions + 1, {\n progressText: this.l10n.slideOfTotal\n });\n self.progressbar.setProgress(this.currentIndex);\n\n for (var i = 0; i \u003c this.options.choices.length; i++) {\n var choice = new SingleChoice(this.options.choices[i], i, this.contentId);\n choice.on(\u0027finished\u0027, this.handleQuestionFinished, this);\n choice.on(\u0027alternative-selected\u0027, this.handleAlternativeSelected, this);\n choice.appendTo(this.$choices, (i === this.currentIndex));\n this.choices.push(choice);\n this.$slides.push(choice.$choice);\n }\n\n this.resultSlide = new ResultSlide(this.options.choices.length);\n this.resultSlide.appendTo(this.$choices);\n this.resultSlide.on(\u0027retry\u0027, this.resetTask, this);\n this.resultSlide.on(\u0027view-solution\u0027, this.handleViewSolution, this);\n this.$slides.push(this.resultSlide.$resultSlide);\n this.on(\u0027resize\u0027, this.resize, this);\n\n // Use the correct starting slide\n this.recklessJump(this.currentIndex);\n\n if (this.options.choices.length === this.currentIndex) {\n // Make sure results slide is displayed\n this.resultSlide.$resultSlide.addClass(\u0027h5p-sc-current-slide\u0027);\n this.setScore(this.results.corrects, true);\n }\n\n if (!this.muted) {\n setTimeout(function () {\n SoundEffects.setup(self.getLibraryFilePath(\u0027\u0027));\n }, 1);\n }\n\n /**\n * Override Question\u0027s hideButton function\n * to be able to hide buttons after delay\n *\n * @override\n * @param {string} id\n */\n this.superHideButton = self.hideButton;\n this.hideButton = (function () {\n return function (id) {\n\n if (!self.scoreTimeout) {\n return self.superHideButton(id);\n }\n\n self.buttonsToBeHidden.push(id);\n return this;\n };\n })();\n }\n\n SingleChoiceSet.prototype = Object.create(Question.prototype);\n SingleChoiceSet.prototype.constructor = SingleChoiceSet;\n\n /**\n * Set if a element is tabbable or not\n *\n * @param {jQuery} $element The element\n * @param {boolean} tabbable If element should be tabbable\n * @returns {jQuery} The element\n */\n SingleChoiceSet.prototype.setTabbable = function ($element, tabbable) {\n if ($element) {\n $element.attr(\u0027tabindex\u0027, tabbable ? 0 : -1);\n }\n };\n\n /**\n * Handle alternative selected, i.e play sound if sound effects are enabled\n *\n * @method handleAlternativeSelected\n * @param {Object} event Event that was fired\n */\n SingleChoiceSet.prototype.handleAlternativeSelected = function (event) {\n var self = this;\n this.lastAnswerIsCorrect = event.data.correct;\n\n self.toggleNextButton(true);\n\n self.triggerXAPI(\u0027interacted\u0027);\n\n // correct answer\n var correctAnswer = self.$choices.find(\u0027.h5p-sc-is-correct\u0027).text();\n\n // Announce by ARIA if answer is correct or incorrect\n var text = this.lastAnswerIsCorrect ? self.l10n.correctText : (self.l10n.incorrectText.replace(\u0027:text\u0027, correctAnswer));\n self.read(text);\n\n if (!this.muted) {\n // Can\u0027t play it after the transition end is received, since this is not\n // accepted on iPad. Therefore we are playing it here with a delay instead\n SoundEffects.play(this.lastAnswerIsCorrect ? \u0027positive-short\u0027 : \u0027negative-short\u0027, 700);\n }\n };\n\n /**\n * Handler invoked when question is done\n *\n * @param {object} event An object containing a single boolean property: \"correct\".\n */\n SingleChoiceSet.prototype.handleQuestionFinished = function (event) {\n var self = this;\n\n var index = event.data.index;\n\n // saves user response\n var userResponse = self.userResponses[index] = event.data.answerIndex;\n\n // trigger answered event\n var duration = this.stopStopWatch(index);\n var xapiEvent = self.createXApiAnsweredEvent(self.options.choices[index], userResponse, duration);\n\n self.trigger(xapiEvent);\n\n self.continue();\n };\n\n /**\n * Setup auto continue\n */\n SingleChoiceSet.prototype.continue = function () {\n var self = this;\n\n if (!self.options.behaviour.autoContinue) {\n // Set focus to next button\n self.$nextButton.focus();\n return;\n }\n\n var timeout;\n var letsMove = function () {\n // Handle impatient users\n self.$container.off(\u0027click.impatient keydown.impatient\u0027);\n clearTimeout(timeout);\n self.next();\n };\n\n timeout = setTimeout(function () {\n letsMove();\n }, self.lastAnswerIsCorrect ? self.options.behaviour.timeoutCorrect : self.options.behaviour.timeoutWrong);\n\n self.onImpatientUser(letsMove);\n };\n\n /**\n * Listen to impatience\n * @param {Function} action Callback\n */\n SingleChoiceSet.prototype.onImpatientUser = function (action) {\n this.$container.off(\u0027click.impatient keydown.impatient\u0027);\n\n this.$container.one(\u0027click.impatient\u0027, action);\n this.$container.one(\u0027keydown.impatient\u0027, function (event) {\n // If return, space or right arrow\n if ([13,32,39].indexOf(event.which)) {\n action();\n }\n });\n };\n\n /**\n * Go to next slide\n */\n SingleChoiceSet.prototype.next = function () {\n // Keep track of num correct/wrong answers\n this.results[this.lastAnswerIsCorrect ? \u0027corrects\u0027 : \u0027wrongs\u0027]++;\n\n this.move(this.currentIndex + 1);\n };\n\n /**\n * Creates an xAPI answered event\n *\n * @param {object} question\n * @param {number} userAnswer\n * @param {number} duration\n *\n * @return {H5P.XAPIEvent}\n */\n SingleChoiceSet.prototype.createXApiAnsweredEvent = function (question, userAnswer, duration) {\n var self = this;\n var types = XApiEventBuilder.interactionTypes;\n\n // creates the definition object\n var definition = XApiEventBuilder.createDefinition()\n .interactionType(types.CHOICE)\n .description(question.question)\n .correctResponsesPattern(self.getXApiCorrectResponsePattern())\n .optional( self.getXApiChoices(question.answers))\n .build();\n\n // create the result object\n var result = XApiEventBuilder.createResult()\n .response(userAnswer.toString())\n .duration(duration)\n .score((userAnswer === 0) ? 1 : 0, 1)\n .completion(true)\n .success(userAnswer === 0)\n .build();\n\n return XApiEventBuilder.create()\n .verb(XApiEventBuilder.verbs.ANSWERED)\n .objectDefinition(definition)\n .context(self.contentId, self.subContentId)\n .contentId(self.contentId, question.subContentId)\n .result(result)\n .build();\n };\n\n /**\n * Returns the \u0027correct response pattern\u0027 for xApi\n *\n * @return {string[]}\n */\n SingleChoiceSet.prototype.getXApiCorrectResponsePattern = function () {\n return [XApiEventBuilder.createCorrectResponsePattern([(0).toString()])]; // is always \u00270\u0027 for SCS\n };\n\n /**\n * Returns the choices array for xApi statements\n *\n * @param {String[]} answers\n *\n * @return {{ choices: []}}\n */\n SingleChoiceSet.prototype.getXApiChoices = function (answers) {\n var choices = answers.map(function(answer, index){\n return XApiEventBuilder.createChoice(index.toString(), answer);\n });\n\n return {\n choices: choices\n };\n };\n\n /**\n * Handles buttons that are queued for hiding\n */\n SingleChoiceSet.prototype.handleQueuedButtonChanges = function () {\n var self = this;\n\n if (self.buttonsToBeHidden.length) {\n self.buttonsToBeHidden.forEach(function (id) {\n self.superHideButton(id);\n });\n }\n self.buttonsToBeHidden = [];\n };\n\n /**\n * Set score and feedback\n *\n * @params {Number} score Number of correct answers\n */\n SingleChoiceSet.prototype.setScore = function (score, noXAPI) {\n var self = this;\n\n if (!self.choices.length) {\n return;\n }\n\n self.setFeedback(determineOverallFeedback(self.options.overallFeedback , score / self.options.choices.length)\n .replace(\u0027:numcorrect\u0027, score)\n .replace(\u0027:maxscore\u0027, self.options.choices.length.toString()),\n score, self.options.choices.length, self.l10n.scoreBarLabel);\n\n if (score === self.options.choices.length) {\n self.hideButton(\u0027try-again\u0027);\n self.hideButton(\u0027show-solution\u0027);\n }\n else {\n self.showButton(\u0027try-again\u0027);\n self.showButton(\u0027show-solution\u0027);\n }\n self.handleQueuedButtonChanges();\n self.scoreTimeout = undefined;\n\n if (!noXAPI) {\n self.triggerXAPIScored(score, self.options.choices.length, \u0027completed\u0027, true, (100 * score / self.options.choices.length) \u003e= self.options.behaviour.passPercentage);\n }\n\n self.trigger(\u0027resize\u0027);\n };\n\n /**\n * Handler invoked when view solution is selected\n */\n SingleChoiceSet.prototype.handleViewSolution = function () {\n var self = this;\n\n var $tryAgainButton = $(\u0027.h5p-question-try-again\u0027, self.$container);\n var $showSolutionButton = $(\u0027.h5p-question-show-solution\u0027, self.$container);\n var buttons = [self.$muteButton, $tryAgainButton, $showSolutionButton];\n\n // remove tabbable for buttons in result view\n buttons.forEach(function (button) {\n self.setTabbable(button, false);\n });\n\n self.solutionView.on(\u0027hide\u0027, function () {\n // re-add tabbable for buttons in result view\n buttons.forEach(function (button) {\n self.setTabbable(button, true);\n });\n self.toggleAriaVisibility(true);\n // Focus on first button when closing solution view\n self.focusButton();\n });\n\n self.solutionView.show();\n self.toggleAriaVisibility(false);\n };\n\n /**\n * Toggle elements visibility to Assistive Technologies\n *\n * @param {boolean} enable Make elements visible\n */\n SingleChoiceSet.prototype.toggleAriaVisibility = function (enable) {\n var self = this;\n var ariaHidden = enable ? \u0027\u0027 : \u0027true\u0027;\n if (self.$muteButton) {\n self.$muteButton.attr(\u0027aria-hidden\u0027, ariaHidden);\n }\n self.progressbar.$progressbar.attr(\u0027aria-hidden\u0027, ariaHidden);\n self.$choices.attr(\u0027aria-hidden\u0027, ariaHidden);\n };\n\n /**\n * Register DOM elements before they are attached.\n * Called from H5P.Question.\n */\n SingleChoiceSet.prototype.registerDomElements = function () {\n // Register task content area.\n this.setContent(this.createQuestion());\n\n // Register buttons with question.\n this.addButtons();\n\n // Insert feedback and buttons section on the result slide\n this.insertSectionAtElement(\u0027feedback\u0027, this.resultSlide.$feedbackContainer);\n this.insertSectionAtElement(\u0027buttons\u0027, this.resultSlide.$buttonContainer);\n\n // Question is finished\n if (this.options.choices.length === this.currentIndex) {\n this.trigger(\u0027question-finished\u0027);\n }\n\n this.trigger(\u0027resize\u0027);\n };\n\n /**\n * Add Buttons to question.\n */\n SingleChoiceSet.prototype.addButtons = function () {\n var self = this;\n\n if (this.options.behaviour.enableRetry) {\n this.addButton(\u0027try-again\u0027, this.l10n.retryButtonLabel, function () {\n self.resetTask();\n }, self.results.corrects !== self.options.choices.length);\n }\n\n if (this.options.behaviour.enableSolutionsButton) {\n this.addButton(\u0027show-solution\u0027, this.l10n.showSolutionButtonLabel, function () {\n self.showSolutions();\n }, self.results.corrects !== self.options.choices.length);\n }\n };\n\n /**\n * Create main content\n */\n SingleChoiceSet.prototype.createQuestion = function () {\n var self = this;\n\n self.progressbar.appendTo(self.$container);\n self.$container.append(self.$choices);\n\n function toggleMute(event) {\n var $button = $(event.target);\n event.preventDefault();\n self.muted = !self.muted;\n $button.attr(\u0027aria-pressed\u0027, self.muted);\n }\n\n // Keep this out of H5P.Question, since we are moving the button \u0026 feedback\n // region to the last slide\n if (!this.options.behaviour.autoContinue) {\n\n var handleNextClick = function () {\n if(self.$nextButton.attr(\u0027aria-disabled\u0027) !== \u0027true\u0027) {\n self.next();\n }\n };\n\n self.$nextButton = UI.createButton({\n \u0027class\u0027: \u0027h5p-ssc-next-button\u0027,\n \u0027aria-label\u0027: self.l10n.nextButtonLabel,\n click: handleNextClick,\n keydown: function (event) {\n switch (event.which) {\n case 13: // Enter\n case 32: // Space\n handleNextClick();\n event.preventDefault();\n }\n },\n appendTo: self.$container\n });\n self.toggleNextButton(false);\n }\n\n if (self.options.behaviour.soundEffectsEnabled) {\n self.$muteButton = $(\u0027\u003cdiv\u003e\u0027, {\n \u0027class\u0027: \u0027h5p-sc-sound-control\u0027,\n \u0027tabindex\u0027: 0,\n \u0027role\u0027: \u0027button\u0027,\n \u0027aria-label\u0027: self.l10n.muteButtonLabel,\n \u0027aria-pressed\u0027: false,\n \u0027on\u0027: {\n \u0027keydown\u0027: function (event) {\n switch (event.which) {\n case 13: // Enter\n case 32: // Space\n toggleMute(event);\n break;\n }\n }\n },\n \u0027click\u0027: toggleMute,\n appendTo: self.$container\n });\n }\n\n // Append solution view - hidden by default:\n self.solutionView.appendTo(self.$container);\n\n self.resize();\n\n // Hide all other slides than the current one:\n self.$container.addClass(\u0027initialized\u0027);\n\n return self.$container;\n };\n\n /**\n * Resize if something outside resizes\n */\n SingleChoiceSet.prototype.resize = function () {\n var self = this;\n var maxHeight = 0;\n self.choices.forEach(function (choice) {\n var choiceHeight = choice.$choice.outerHeight();\n maxHeight = choiceHeight \u003e maxHeight ? choiceHeight : maxHeight;\n });\n\n // Set minimum height for choices\n self.$choices.css({minHeight: maxHeight + \u0027px\u0027});\n };\n\n /**\n * Disable/enable the next button\n * @param {boolean} enable\n */\n SingleChoiceSet.prototype.toggleNextButton = function(enable) {\n if (this.$nextButton) {\n this.$nextButton.attr(\u0027aria-disabled\u0027, !enable);\n }\n };\n\n /**\n * Will jump to the given slide without any though to animations,\n * current slide etc.\n *\n * @public\n */\n SingleChoiceSet.prototype.recklessJump = function (index) {\n var tX = \u0027translateX(\u0027 + (-index * 100) + \u0027%)\u0027;\n this.$choices.css({\n \u0027-webkit-transform\u0027: tX,\n \u0027-moz-transform\u0027: tX,\n \u0027-ms-transform\u0027: tX,\n \u0027transform\u0027: tX\n });\n this.progressbar.setProgress(index + 1);\n };\n\n /**\n * Move to slide n\n * @param {number} index The slide number to move to\n */\n SingleChoiceSet.prototype.move = function (index) {\n var self = this;\n if (index === this.currentIndex || index \u003e self.$slides.length-1) {\n return;\n }\n\n var $previousSlide = self.$slides[self.currentIndex];\n var $currentChoice = self.choices[index];\n var $currentSlide = self.$slides[index];\n var isResultSlide = (index \u003e= self.choices.length);\n\n self.toggleNextButton(false);\n\n H5P.Transition.onTransitionEnd(self.$choices, function () {\n $previousSlide.removeClass(\u0027h5p-sc-current-slide\u0027);\n\n // on slides with answers focus on first alternative\n if (!isResultSlide) {\n $currentChoice.focusOnAlternative(0);\n }\n // on last slide, focus on try again button\n else {\n self.resultSlide.focusScore();\n }\n }, 600);\n\n // if should show result slide\n if (isResultSlide) {\n self.setScore(self.results.corrects);\n }\n\n self.$container.toggleClass(\u0027navigatable\u0027, !isResultSlide);\n\n // start timing of new slide\n this.startStopWatch(index);\n\n // move to slide\n $currentSlide.addClass(\u0027h5p-sc-current-slide\u0027);\n self.recklessJump(index);\n\n self.currentIndex = index;\n };\n\n /**\n * Starts a stopwatch for indexed slide\n *\n * @param {number} index\n */\n SingleChoiceSet.prototype.startStopWatch = function (index) {\n this.stopWatches[index] = this.stopWatches[index] || new StopWatch();\n this.stopWatches[index].start();\n };\n\n /**\n * Stops a stopwatch for indexed slide\n *\n * @param {number} index\n */\n SingleChoiceSet.prototype.stopStopWatch = function (index) {\n if(this.stopWatches[index]){\n this.stopWatches[index].stop();\n }\n };\n\n /**\n * Returns the passed time in seconds of a stopwatch on an indexed slide,\n * or 0 if not existing\n *\n * @param {number} index\n * @return {number}\n */\n SingleChoiceSet.prototype.timePassedInStopWatch = function (index) {\n if(this.stopWatches[index] !== undefined){\n return this.stopWatches[index].passedTime();\n }\n else {\n // if not created, return no passed time,\n return 0;\n }\n };\n\n /**\n * Returns the time the user has spent on all questions so far\n *\n * @return {number}\n */\n SingleChoiceSet.prototype.getTotalPassedTime = function () {\n return this.stopWatches\n .filter(function(watch){\n return watch != undefined;\n })\n .reduce(function(sum, watch){\n return sum + watch.passedTime();\n }, 0);\n };\n\n /**\n * The following functions implements the CP and IV - Contracts v 1.0 documented here:\n * http://h5p.org/node/1009\n */\n SingleChoiceSet.prototype.getScore = function () {\n return this.results.corrects;\n };\n\n SingleChoiceSet.prototype.getMaxScore = function () {\n return this.options.choices.length;\n };\n\n SingleChoiceSet.prototype.getAnswerGiven = function () {\n return (this.results.corrects + this.results.wrongs) \u003e 0;\n };\n\n SingleChoiceSet.prototype.getTitle = function () {\n return (this.options.choices[0] ? H5P.createTitle(this.options.choices[0].question) : \u0027\u0027);\n };\n\n /**\n * Retrieves the xAPI data necessary for generating result reports.\n *\n * @return {object}\n */\n SingleChoiceSet.prototype.getXAPIData = function(){\n var self = this;\n\n // create array with userAnswer\n var children = self.options.choices.map(function(question, index) {\n var userResponse = self.userResponses[index] \u003e= 0 ? self.userResponses[index] : \u0027\u0027;\n var duration = self.timePassedInStopWatch(index);\n var event = self.createXApiAnsweredEvent(question, userResponse, duration);\n\n return {\n statement: event.data.statement\n };\n });\n\n var result = XApiEventBuilder.createResult()\n .score(self.getScore(), self.getMaxScore())\n .duration(self.getTotalPassedTime())\n .build();\n\n // creates the definition object\n var definition = XApiEventBuilder.createDefinition()\n .interactionType(XApiEventBuilder.interactionTypes.COMPOUND)\n .build();\n\n var xAPIEvent = XApiEventBuilder.create()\n .verb(XApiEventBuilder.verbs.ANSWERED)\n .contentId(self.contentId, self.subContentId)\n .context(self.getParentAttribute(\u0027contentId\u0027), self.getParentAttribute(\u0027subContentId\u0027))\n .objectDefinition(definition)\n .result(result)\n .build();\n\n return {\n statement: xAPIEvent.data.statement,\n children: children\n };\n };\n\n /**\n * Returns an attribute from this.parent if it exists\n *\n * @param {string} attributeName\n * @return {*|undefined}\n */\n SingleChoiceSet.prototype.getParentAttribute = function (attributeName) {\n var self = this;\n\n if(self.parent !== undefined){\n return self.parent[attributeName];\n }\n };\n\n SingleChoiceSet.prototype.showSolutions = function () {\n this.handleViewSolution();\n };\n\n /**\n * Reset all answers. This is equal to refreshing the quiz\n */\n SingleChoiceSet.prototype.resetTask = function () {\n var self = this;\n\n // Close solution view if visible:\n this.solutionView.hide();\n\n // Reset the user\u0027s answers\n var classes = [\u0027h5p-sc-reveal-wrong\u0027, \u0027h5p-sc-reveal-correct\u0027, \u0027h5p-sc-selected\u0027, \u0027h5p-sc-drummed\u0027, \u0027h5p-sc-correct-answer\u0027];\n for (var i = 0; i \u003c classes.length; i++) {\n this.$choices.find(\u0027.\u0027 + classes[i]).removeClass(classes[i]);\n }\n this.results = {\n corrects: 0,\n wrongs: 0\n };\n\n this.choices.forEach(function (choice) {\n choice.setAnswered(false);\n });\n\n this.stopWatches.forEach(function(stopWatch){\n if(stopWatch){\n stopWatch.reset();\n }\n });\n\n this.move(0);\n\n // Wait for transition, then remove feedback.\n H5P.Transition.onTransitionEnd(this.$choices, function () {\n self.removeFeedback();\n }, 600);\n };\n\n /**\n * Clever comment.\n *\n * @public\n * @returns {object}\n */\n SingleChoiceSet.prototype.getCurrentState = function () {\n return {\n progress: this.currentIndex,\n answers: this.results\n };\n };\n\n /**\n * Determine the overall feedback to display for the question.\n * Returns empty string if no matching range is found.\n *\n * @param {Object[]} feedbacks\n * @param {number} scoreRatio\n * @return {string}\n */\n var determineOverallFeedback = function (feedbacks, scoreRatio) {\n scoreRatio = Math.floor(scoreRatio * 100);\n\n for (var i = 0; i \u003c feedbacks.length; i++) {\n var feedback = feedbacks[i];\n var hasFeedback = (feedback.feedback !== undefined \u0026\u0026 feedback.feedback.trim().length !== 0);\n\n if (feedback.from \u003c= scoreRatio \u0026\u0026 feedback.to \u003e= scoreRatio \u0026\u0026 hasFeedback) {\n return feedback.feedback;\n }\n }\n\n return \u0027\u0027;\n };\n\n return SingleChoiceSet;\n})(H5P.jQuery, H5P.JoubelUI, H5P.Question, H5P.SingleChoiceSet.SingleChoice, H5P.SingleChoiceSet.SolutionView, H5P.SingleChoiceSet.ResultSlide, H5P.SingleChoiceSet.SoundEffects, H5P.SingleChoiceSet.XApiEventBuilder, H5P.SingleChoiceSet.StopWatch);\n"
,"js/ejs_production.js":"(function(){var rsplit=function(string,regex){var result=regex.exec(string),retArr=new Array(),first_idx,last_idx,first_bit;while(result!=null){first_idx=result.index;last_idx=regex.lastIndex;if((first_idx)!=0){first_bit=string.substring(0,first_idx);retArr.push(string.substring(0,first_idx));string=string.slice(first_idx)}retArr.push(result[0]);string=string.slice(result[0].length);result=regex.exec(string)}if(!string==\"\"){retArr.push(string)}return retArr},chop=function(string){return string.substr(0,string.length-1)},extend=function(d,s){for(var n in s){if(s.hasOwnProperty(n)){d[n]=s[n]}}};EJS=function(options){options=typeof options==\"string\"?{view:options}:options;this.set_options(options);if(options.precompiled){this.template={};this.template.process=options.precompiled;EJS.update(this.name,this);return }if(options.element){if(typeof options.element==\"string\"){var name=options.element;options.element=document.getElementById(options.element);if(options.element==null){throw name+\"does not exist!\"}}if(options.element.value){this.text=options.element.value}else{this.text=options.element.innerHTML}this.name=options.element.id;this.type=\"[\"}else{if(options.url){options.url=EJS.endExt(options.url,this.extMatch);this.name=this.name?this.name:options.url;var url=options.url;var template=EJS.get(this.name,this.cache);if(template){return template}if(template==EJS.INVALID_PATH){return null}try{this.text=EJS.request(url+(this.cache?\"\":\"?\"+Math.random()))}catch(e){}if(this.text==null){throw ({type:\"EJS\",message:\"There is no template at \"+url})}}}var template=new EJS.Compiler(this.text,this.type);template.compile(options,this.name);EJS.update(this.name,this);this.template=template};EJS.prototype={render:function(object,extra_helpers){object=object||{};this._extra_helpers=extra_helpers;var v=new EJS.Helpers(object,extra_helpers||{});return this.template.process.call(object,object,v)},update:function(element,options){if(typeof element==\"string\"){element=document.getElementById(element)}if(options==null){_template=this;return function(object){EJS.prototype.update.call(_template,element,object)}}if(typeof options==\"string\"){params={};params.url=options;_template=this;params.onComplete=function(request){var object=eval(request.responseText);EJS.prototype.update.call(_template,element,object)};EJS.ajax_request(params)}else{element.innerHTML=this.render(options)}},out:function(){return this.template.out},set_options:function(options){this.type=options.type||EJS.type;this.cache=options.cache!=null?options.cache:EJS.cache;this.text=options.text||null;this.name=options.name||null;this.ext=options.ext||EJS.ext;this.extMatch=new RegExp(this.ext.replace(/\\./,\".\"))}};EJS.endExt=function(path,match){if(!path){return null}match.lastIndex=0;return path+(match.test(path)?\"\":this.ext)};EJS.Scanner=function(source,left,right){extend(this,{left_delimiter:left+\"%\",right_delimiter:\"%\"+right,double_left:left+\"%%\",double_right:\"%%\"+right,left_equal:left+\"%=\",left_comment:left+\"%#\"});this.SplitRegexp=left==\"[\"?/(\\[%%)|(%%\\])|(\\[%=)|(\\[%#)|(\\[%)|(%\\]\\n)|(%\\])|(\\n)/:new RegExp(\"(\"+this.double_left+\")|(%%\"+this.double_right+\")|(\"+this.left_equal+\")|(\"+this.left_comment+\")|(\"+this.left_delimiter+\")|(\"+this.right_delimiter+\"\\n)|(\"+this.right_delimiter+\")|(\\n)\");this.source=source;this.stag=null;this.lines=0};EJS.Scanner.to_text=function(input){if(input==null||input===undefined){return\"\"}if(input instanceof Date){return input.toDateString()}if(input.toString){return input.toString()}return\"\"};EJS.Scanner.prototype={scan:function(block){scanline=this.scanline;regex=this.SplitRegexp;if(!this.source==\"\"){var source_split=rsplit(this.source,/\\n/);for(var i=0;i\u003csource_split.length;i++){var item=source_split[i];this.scanline(item,regex,block)}}},scanline:function(line,regex,block){this.lines++;var line_split=rsplit(line,regex);for(var i=0;i\u003cline_split.length;i++){var token=line_split[i];if(token!=null){try{block(token,this)}catch(e){throw {type:\"EJS.Scanner\",line:this.lines}}}}}};EJS.Buffer=function(pre_cmd,post_cmd){this.line=new Array();this.script=\"\";this.pre_cmd=pre_cmd;this.post_cmd=post_cmd;for(var i=0;i\u003cthis.pre_cmd.length;i++){this.push(pre_cmd[i])}};EJS.Buffer.prototype={push:function(cmd){this.line.push(cmd)},cr:function(){this.script=this.script+this.line.join(\"; \");this.line=new Array();this.script=this.script+\"\\n\"},close:function(){if(this.line.length\u003e0){for(var i=0;i\u003cthis.post_cmd.length;i++){this.push(pre_cmd[i])}this.script=this.script+this.line.join(\"; \");line=null}}};EJS.Compiler=function(source,left){this.pre_cmd=[\"var ___ViewO = [];\"];this.post_cmd=new Array();this.source=\" \";if(source!=null){if(typeof source==\"string\"){source=source.replace(/\\r\\n/g,\"\\n\");source=source.replace(/\\r/g,\"\\n\");this.source=source}else{if(source.innerHTML){this.source=source.innerHTML}}if(typeof this.source!=\"string\"){this.source=\"\"}}left=left||\"\u003c\";var right=\"\u003e\";switch(left){case\"[\":right=\"]\";break;case\"\u003c\":break;default:throw left+\" is not a supported deliminator\";break}this.scanner=new EJS.Scanner(this.source,left,right);this.out=\"\"};EJS.Compiler.prototype={compile:function(options,name){options=options||{};this.out=\"\";var put_cmd=\"___ViewO.push(\";var insert_cmd=put_cmd;var buff=new EJS.Buffer(this.pre_cmd,this.post_cmd);var content=\"\";var clean=function(content){content=content.replace(/\\\\/g,\"\\\\\\\\\");content=content.replace(/\\n/g,\"\\\\n\");content=content.replace(/\"/g,\u0027\\\\\"\u0027);return content};this.scanner.scan(function(token,scanner){if(scanner.stag==null){switch(token){case\"\\n\":content=content+\"\\n\";buff.push(put_cmd+\u0027\"\u0027+clean(content)+\u0027\");\u0027);buff.cr();content=\"\";break;case scanner.left_delimiter:case scanner.left_equal:case scanner.left_comment:scanner.stag=token;if(content.length\u003e0){buff.push(put_cmd+\u0027\"\u0027+clean(content)+\u0027\")\u0027)}content=\"\";break;case scanner.double_left:content=content+scanner.left_delimiter;break;default:content=content+token;break}}else{switch(token){case scanner.right_delimiter:switch(scanner.stag){case scanner.left_delimiter:if(content[content.length-1]==\"\\n\"){content=chop(content);buff.push(content);buff.cr()}else{buff.push(content)}break;case scanner.left_equal:buff.push(insert_cmd+\"(EJS.Scanner.to_text(\"+content+\")))\");break}scanner.stag=null;content=\"\";break;case scanner.double_right:content=content+scanner.right_delimiter;break;default:content=content+token;break}}});if(content.length\u003e0){buff.push(put_cmd+\u0027\"\u0027+clean(content)+\u0027\")\u0027)}buff.close();this.out=buff.script+\";\";var to_be_evaled=\"/*\"+name+\"*/this.process = function(_CONTEXT,_VIEW) { try { with(_VIEW) { with (_CONTEXT) {\"+this.out+\" return ___ViewO.join(\u0027\u0027);}}}catch(e){e.lineNumber=null;throw e;}};\";try{eval(to_be_evaled)}catch(e){if(typeof JSLINT!=\"undefined\"){JSLINT(this.out);for(var i=0;i\u003cJSLINT.errors.length;i++){var error=JSLINT.errors[i];if(error.reason!=\"Unnecessary semicolon.\"){error.line++;var e=new Error();e.lineNumber=error.line;e.message=error.reason;if(options.view){e.fileName=options.view}throw e}}}else{throw e}}}};EJS.config=function(options){EJS.cache=options.cache!=null?options.cache:EJS.cache;EJS.type=options.type!=null?options.type:EJS.type;EJS.ext=options.ext!=null?options.ext:EJS.ext;var templates_directory=EJS.templates_directory||{};EJS.templates_directory=templates_directory;EJS.get=function(path,cache){if(cache==false){return null}if(templates_directory[path]){return templates_directory[path]}return null};EJS.update=function(path,template){if(path==null){return }templates_directory[path]=template};EJS.INVALID_PATH=-1};EJS.config({cache:true,type:\"\u003c\",ext:\".ejs\"});EJS.Helpers=function(data,extras){this._data=data;this._extras=extras;extend(this,extras)};EJS.Helpers.prototype={view:function(options,data,helpers){if(!helpers){helpers=this._extras}if(!data){data=this._data}return new EJS(options).render(data,helpers)},to_text:function(input,null_text){if(input==null||input===undefined){return null_text||\"\"}if(input instanceof Date){return input.toDateString()}if(input.toString){return input.toString().replace(/\\n/g,\"\u003cbr /\u003e\").replace(/\u0027\u0027/g,\"\u0027\")}return\"\"}};EJS.newRequest=function(){var factories=[function(){return new ActiveXObject(\"Msxml2.XMLHTTP\")},function(){return new XMLHttpRequest()},function(){return new ActiveXObject(\"Microsoft.XMLHTTP\")}];for(var i=0;i\u003cfactories.length;i++){try{var request=factories[i]();if(request!=null){return request}}catch(e){continue}}};EJS.request=function(path){var request=new EJS.newRequest();request.open(\"GET\",path,false);try{request.send(null)}catch(e){return null}if(request.status==404||request.status==2||(request.status==0\u0026\u0026request.responseText==\"\")){return null}return request.responseText};EJS.ajax_request=function(params){params.method=(params.method?params.method:\"GET\");var request=new EJS.newRequest();request.onreadystatechange=function(){if(request.readyState==4){if(request.status==200){params.onComplete(request)}else{params.onComplete(request)}}};request.open(params.method,params.url);request.send(null)}})();EJS.Helpers.prototype.date_tag=function(C,O,A){if(!(O instanceof Date)){O=new Date()}var B=[\"January\",\"February\",\"March\",\"April\",\"May\",\"June\",\"July\",\"August\",\"September\",\"October\",\"November\",\"December\"];var G=[],D=[],P=[];var J=O.getFullYear();var H=O.getMonth();var N=O.getDate();for(var M=J-15;M\u003cJ+15;M++){G.push({value:M,text:M})}for(var E=0;E\u003c12;E++){D.push({value:(E),text:B[E]})}for(var I=0;I\u003c31;I++){P.push({value:(I+1),text:(I+1)})}var L=this.select_tag(C+\"[year]\",J,G,{id:C+\"[year]\"});var F=this.select_tag(C+\"[month]\",H,D,{id:C+\"[month]\"});var K=this.select_tag(C+\"[day]\",N,P,{id:C+\"[day]\"});return L+F+K};EJS.Helpers.prototype.form_tag=function(B,A){A=A||{};A.action=B;if(A.multipart==true){A.method=\"post\";A.enctype=\"multipart/form-data\"}return this.start_tag_for(\"form\",A)};EJS.Helpers.prototype.form_tag_end=function(){return this.tag_end(\"form\")};EJS.Helpers.prototype.hidden_field_tag=function(A,C,B){return this.input_field_tag(A,C,\"hidden\",B)};EJS.Helpers.prototype.input_field_tag=function(A,D,C,B){B=B||{};B.id=B.id||A;B.value=D||\"\";B.type=C||\"text\";B.name=A;return this.single_tag_for(\"input\",B)};EJS.Helpers.prototype.is_current_page=function(A){return(window.location.href==A||window.location.pathname==A?true:false)};EJS.Helpers.prototype.link_to=function(B,A,C){if(!B){var B=\"null\"}if(!C){var C={}}if(C.confirm){C.onclick=\u0027 var ret_confirm = confirm(\"\u0027+C.confirm+\u0027\"); if(!ret_confirm){ return false;} \u0027;C.confirm=null}C.href=A;return this.start_tag_for(\"a\",C)+B+this.tag_end(\"a\")};EJS.Helpers.prototype.submit_link_to=function(B,A,C){if(!B){var B=\"null\"}if(!C){var C={}}C.onclick=C.onclick||\"\";if(C.confirm){C.onclick=\u0027 var ret_confirm = confirm(\"\u0027+C.confirm+\u0027\"); if(!ret_confirm){ return false;} \u0027;C.confirm=null}C.value=B;C.type=\"submit\";C.onclick=C.onclick+(A?this.url_for(A):\"\")+\"return false;\";return this.start_tag_for(\"input\",C)};EJS.Helpers.prototype.link_to_if=function(F,B,A,D,C,E){return this.link_to_unless((F==false),B,A,D,C,E)};EJS.Helpers.prototype.link_to_unless=function(E,B,A,C,D){C=C||{};if(E){if(D\u0026\u0026typeof D==\"function\"){return D(B,A,C,D)}else{return B}}else{return this.link_to(B,A,C)}};EJS.Helpers.prototype.link_to_unless_current=function(B,A,C,D){C=C||{};return this.link_to_unless(this.is_current_page(A),B,A,C,D)};EJS.Helpers.prototype.password_field_tag=function(A,C,B){return this.input_field_tag(A,C,\"password\",B)};EJS.Helpers.prototype.select_tag=function(D,G,H,F){F=F||{};F.id=F.id||D;F.value=G;F.name=D;var B=\"\";B+=this.start_tag_for(\"select\",F);for(var E=0;E\u003cH.length;E++){var C=H[E];var A={value:C.value};if(C.value==G){A.selected=\"selected\"}B+=this.start_tag_for(\"option\",A)+C.text+this.tag_end(\"option\")}B+=this.tag_end(\"select\");return B};EJS.Helpers.prototype.single_tag_for=function(A,B){return this.tag(A,B,\"/\u003e\")};EJS.Helpers.prototype.start_tag_for=function(A,B){return this.tag(A,B)};EJS.Helpers.prototype.submit_tag=function(A,B){B=B||{};B.type=B.type||\"submit\";B.value=A||\"Submit\";return this.single_tag_for(\"input\",B)};EJS.Helpers.prototype.tag=function(C,E,D){if(!D){var D=\"\u003e\"}var B=\" \";for(var A in E){if(E[A]!=null){var F=E[A].toString()}else{var F=\"\"}if(A==\"Class\"){A=\"class\"}if(F.indexOf(\"\u0027\")!=-1){B+=A+\u0027=\"\u0027+F+\u0027\" \u0027}else{B+=A+\"=\u0027\"+F+\"\u0027 \"}}return\"\u003c\"+C+B+D};EJS.Helpers.prototype.tag_end=function(A){return\"\u003c/\"+A+\"\u003e\"};EJS.Helpers.prototype.text_area_tag=function(A,C,B){B=B||{};B.id=B.id||A;B.name=B.name||A;C=C||\"\";if(B.size){B.cols=B.size.split(\"x\")[0];B.rows=B.size.split(\"x\")[1];delete B.size}B.cols=B.cols||50;B.rows=B.rows||4;return this.start_tag_for(\"textarea\",B)+C+this.tag_end(\"textarea\")};EJS.Helpers.prototype.text_tag=EJS.Helpers.prototype.text_area_tag;EJS.Helpers.prototype.text_field_tag=function(A,C,B){return this.input_field_tag(A,C,\"text\",B)};EJS.Helpers.prototype.url_for=function(A){return\u0027window.location=\"\u0027+A+\u0027\";\u0027};EJS.Helpers.prototype.img_tag=function(B,C,A){A=A||{};A.src=B;A.alt=C;return this.single_tag_for(\"img\",A)}"
,"js/ejs_viewhelpers.js":"EJS.Helpers.prototype.date_tag = function(name, value , html_options) {\n if(! (value instanceof Date))\n\t\tvalue = new Date()\n\t\n\tvar month_names = [\"January\", \"February\", \"March\", \"April\", \"May\", \"June\", \"July\", \"August\", \"September\", \"October\", \"November\", \"December\"];\n\tvar years = [], months = [], days =[];\n\tvar year = value.getFullYear();\n\tvar month = value.getMonth();\n\tvar day = value.getDate();\n\tfor(var y = year - 15; y \u003c year+15 ; y++)\n\t{\n\t\tyears.push({value: y, text: y})\n\t}\n\tfor(var m = 0; m \u003c 12; m++)\n\t{\n\t\tmonths.push({value: (m), text: month_names[m]})\n\t}\n\tfor(var d = 0; d \u003c 31; d++)\n\t{\n\t\tdays.push({value: (d+1), text: (d+1)})\n\t}\n\tvar year_select = this.select_tag(name+\u0027[year]\u0027, year, years, {id: name+\u0027[year]\u0027} )\n\tvar month_select = this.select_tag(name+\u0027[month]\u0027, month, months, {id: name+\u0027[month]\u0027})\n\tvar day_select = this.select_tag(name+\u0027[day]\u0027, day, days, {id: name+\u0027[day]\u0027})\n\t\n return year_select+month_select+day_select;\n}\n\nEJS.Helpers.prototype.form_tag = function(action, html_options) {\n \n \n html_options = html_options || {};\n\thtml_options.action = action\n if(html_options.multipart == true) {\n html_options.method = \u0027post\u0027;\n html_options.enctype = \u0027multipart/form-data\u0027;\n }\n \n return this.start_tag_for(\u0027form\u0027, html_options)\n}\n\nEJS.Helpers.prototype.form_tag_end = function() { return this.tag_end(\u0027form\u0027); }\n\nEJS.Helpers.prototype.hidden_field_tag = function(name, value, html_options) { \n return this.input_field_tag(name, value, \u0027hidden\u0027, html_options); \n}\n\nEJS.Helpers.prototype.input_field_tag = function(name, value , inputType, html_options) {\n \n html_options = html_options || {};\n html_options.id = html_options.id || name;\n html_options.value = value || \u0027\u0027;\n html_options.type = inputType || \u0027text\u0027;\n html_options.name = name;\n \n return this.single_tag_for(\u0027input\u0027, html_options)\n}\n\nEJS.Helpers.prototype.is_current_page = function(url) {\n\treturn (window.location.href == url || window.location.pathname == url ? true : false);\n}\n\nEJS.Helpers.prototype.link_to = function(name, url, html_options) {\n if(!name) var name = \u0027null\u0027;\n if(!html_options) var html_options = {}\n\t\n\tif(html_options.confirm){\n\t\thtml_options.onclick = \n\t\t\" var ret_confirm = confirm(\\\"\"+html_options.confirm+\"\\\"); if(!ret_confirm){ return false;} \"\n\t\thtml_options.confirm = null;\n\t}\n html_options.href=url\n return this.start_tag_for(\u0027a\u0027, html_options)+name+ this.tag_end(\u0027a\u0027);\n}\n\nEJS.Helpers.prototype.submit_link_to = function(name, url, html_options){\n\tif(!name) var name = \u0027null\u0027;\n if(!html_options) var html_options = {}\n html_options.onclick = html_options.onclick || \u0027\u0027 ;\n\t\n\tif(html_options.confirm){\n\t\thtml_options.onclick = \n\t\t\" var ret_confirm = confirm(\\\"\"+html_options.confirm+\"\\\"); if(!ret_confirm){ return false;} \"\n\t\thtml_options.confirm = null;\n\t}\n\t\n html_options.value = name;\n\thtml_options.type = \u0027submit\u0027\n html_options.onclick=html_options.onclick+\n\t\t(url ? this.url_for(url) : \u0027\u0027)+\u0027return false;\u0027;\n //html_options.href=\u0027#\u0027+(options ? Routes.url_for(options) : \u0027\u0027)\n\treturn this.start_tag_for(\u0027input\u0027, html_options)\n}\n\nEJS.Helpers.prototype.link_to_if = function(condition, name, url, html_options, post, block) {\n\treturn this.link_to_unless((condition == false), name, url, html_options, post, block);\n}\n\nEJS.Helpers.prototype.link_to_unless = function(condition, name, url, html_options, block) {\n\thtml_options = html_options || {};\n\tif(condition) {\n\t\tif(block \u0026\u0026 typeof block == \u0027function\u0027) {\n\t\t\treturn block(name, url, html_options, block);\n\t\t} else {\n\t\t\treturn name;\n\t\t}\n\t} else\n\t\treturn this.link_to(name, url, html_options);\n}\n\nEJS.Helpers.prototype.link_to_unless_current = function(name, url, html_options, block) {\n\thtml_options = html_options || {};\n\treturn this.link_to_unless(this.is_current_page(url), name, url, html_options, block)\n}\n\n\nEJS.Helpers.prototype.password_field_tag = function(name, value, html_options) { return this.input_field_tag(name, value, \u0027password\u0027, html_options); }\n\nEJS.Helpers.prototype.select_tag = function(name, value, choices, html_options) { \n html_options = html_options || {};\n html_options.id = html_options.id || name;\n html_options.value = value;\n\thtml_options.name = name;\n \n var txt = \u0027\u0027\n txt += this.start_tag_for(\u0027select\u0027, html_options)\n \n for(var i = 0; i \u003c choices.length; i++)\n {\n var choice = choices[i];\n var optionOptions = {value: choice.value}\n if(choice.value == value)\n optionOptions.selected =\u0027selected\u0027\n txt += this.start_tag_for(\u0027option\u0027, optionOptions )+choice.text+this.tag_end(\u0027option\u0027)\n }\n txt += this.tag_end(\u0027select\u0027);\n return txt;\n}\n\nEJS.Helpers.prototype.single_tag_for = function(tag, html_options) { return this.tag(tag, html_options, \u0027/\u003e\u0027);}\n\nEJS.Helpers.prototype.start_tag_for = function(tag, html_options) { return this.tag(tag, html_options); }\n\nEJS.Helpers.prototype.submit_tag = function(name, html_options) { \n html_options = html_options || {};\n //html_options.name = html_options.id || \u0027commit\u0027;\n html_options.type = html_options.type || \u0027submit\u0027;\n html_options.value = name || \u0027Submit\u0027;\n return this.single_tag_for(\u0027input\u0027, html_options);\n}\n\nEJS.Helpers.prototype.tag = function(tag, html_options, end) {\n if(!end) var end = \u0027\u003e\u0027\n var txt = \u0027 \u0027\n for(var attr in html_options) { \n\t if(html_options[attr] != null)\n var value = html_options[attr].toString();\n else\n var value=\u0027\u0027\n if(attr == \"Class\") // special case because \"class\" is a reserved word in IE\n attr = \"class\";\n if( value.indexOf(\"\u0027\") != -1 )\n txt += attr+\u0027=\\\"\u0027+value+\u0027\\\" \u0027 \n else\n txt += attr+\"=\u0027\"+value+\"\u0027 \" \n }\n return \u0027\u003c\u0027+tag+txt+end;\n}\n\nEJS.Helpers.prototype.tag_end = function(tag) { return \u0027\u003c/\u0027+tag+\u0027\u003e\u0027; }\n\nEJS.Helpers.prototype.text_area_tag = function(name, value, html_options) { \n html_options = html_options || {};\n html_options.id = html_options.id || name;\n html_options.name = html_options.name || name;\n\tvalue = value || \u0027\u0027\n if(html_options.size) {\n html_options.cols = html_options.size.split(\u0027x\u0027)[0]\n html_options.rows = html_options.size.split(\u0027x\u0027)[1];\n delete html_options.size\n }\n \n html_options.cols = html_options.cols || 50;\n html_options.rows = html_options.rows || 4;\n \n return this.start_tag_for(\u0027textarea\u0027, html_options)+value+this.tag_end(\u0027textarea\u0027)\n}\nEJS.Helpers.prototype.text_tag = EJS.Helpers.prototype.text_area_tag\n\nEJS.Helpers.prototype.text_field_tag = function(name, value, html_options) { return this.input_field_tag(name, value, \u0027text\u0027, html_options); }\n\nEJS.Helpers.prototype.url_for = function(url) {\n return \u0027window.location=\"\u0027+url+\u0027\";\u0027\n}\nEJS.Helpers.prototype.img_tag = function(image_location, alt, options){\n\toptions = options || {};\n\toptions.src = image_location\n\toptions.alt = alt\n\treturn this.single_tag_for(\u0027img\u0027, options)\n}\n"
,"js/multichoice.js":"/*global EJS*/\n// Will render a Question with multiple choices for answers.\n\n// Options format:\n// {\n// title: \"Optional title for question box\",\n// question: \"Question text\",\n// answers: [{text: \"Answer text\", correct: false}, ...],\n// singleAnswer: true, // or false, will change rendered output slightly.\n// singlePoint: true, // True if question give a single point score only\n// // if all are correct, false to give 1 point per\n// // correct answer. (Only for singleAnswer=false)\n// randomAnswers: false // Whether to randomize the order of answers.\n// }\n//\n// Events provided:\n// - h5pQuestionAnswered: Triggered when a question has been answered.\n\nvar H5P = H5P || {};\n\n/**\n * @typedef {Object} Options\n * Options for multiple choice\n *\n * @property {Object} behaviour\n * @property {boolean} behaviour.confirmCheckDialog\n * @property {boolean} behaviour.confirmRetryDialog\n *\n * @property {Object} UI\n * @property {string} UI.tipsLabel\n *\n * @property {Object} [confirmRetry]\n * @property {string} [confirmRetry.header]\n * @property {string} [confirmRetry.body]\n * @property {string} [confirmRetry.cancelLabel]\n * @property {string} [confirmRetry.confirmLabel]\n *\n * @property {Object} [confirmCheck]\n * @property {string} [confirmCheck.header]\n * @property {string} [confirmCheck.body]\n * @property {string} [confirmCheck.cancelLabel]\n * @property {string} [confirmCheck.confirmLabel]\n */\n\n/**\n * Module for creating a multiple choice question\n *\n * @param {Options} options\n * @param {number} contentId\n * @param {Object} contentData\n * @returns {H5P.MultiChoice}\n * @constructor\n */\nH5P.MultiChoice = function (options, contentId, contentData) {\n if (!(this instanceof H5P.MultiChoice))\n return new H5P.MultiChoice(options, contentId, contentData);\n var self = this;\n this.contentId = contentId;\n H5P.Question.call(self, \u0027multichoice\u0027);\n var $ = H5P.jQuery;\n\n // checkbox or radiobutton\n var texttemplate =\n \u0027\u003cul class=\"h5p-answers\" role=\"\u003c%= role %\u003e\" aria-labelledby=\"\u003c%= label %\u003e\"\u003e\u0027 +\n \u0027 \u003c% for (var i=0; i \u003c answers.length; i++) { %\u003e\u0027 +\n \u0027 \u003cli class=\"h5p-answer\" role=\"\u003c%= answers[i].role %\u003e\" tabindex=\"\u003c%= answers[i].tabindex %\u003e\" aria-checked=\"\u003c%= answers[i].checked %\u003e\" data-id=\"\u003c%= i %\u003e\"\u003e\u0027 +\n \u0027 \u003cdiv class=\"h5p-alternative-container\"\u003e\u0027 +\n \u0027 \u003cspan class=\"h5p-alternative-inner\"\u003e\u003c%= answers[i].text %\u003e\u003c/span\u003e\u003cspan class=\"h5p-hidden-read\"\u003e.\u003c/span\u003e\u0027 +\n \u0027 \u003c/div\u003e\u0027 +\n \u0027 \u003cdiv class=\"h5p-clearfix\"\u003e\u003c/div\u003e\u0027 +\n \u0027 \u003c/li\u003e\u0027 +\n \u0027 \u003c% } %\u003e\u0027 +\n \u0027\u003c/ul\u003e\u0027;\n\n var defaults = {\n image: null,\n question: \"No question text provided\",\n answers: [\n {\n tipsAndFeedback: {\n tip: \u0027\u0027,\n chosenFeedback: \u0027\u0027,\n notChosenFeedback: \u0027\u0027\n },\n text: \"Answer 1\",\n correct: true\n }\n ],\n overallFeedback: [],\n weight: 1,\n userAnswers: [],\n UI: {\n checkAnswerButton: \u0027Check\u0027,\n showSolutionButton: \u0027Show solution\u0027,\n tryAgainButton: \u0027Try again\u0027,\n scoreBarLabel: \u0027You got :num out of :total points\u0027,\n tipAvailable: \"Tip available\",\n feedbackAvailable: \"Feedback available\",\n readFeedback: \u0027Read feedback\u0027,\n shouldCheck: \"Should have been checked\",\n shouldNotCheck: \"Should not have been checked\",\n noInput: \u0027Input is required before viewing the solution\u0027\n },\n behaviour: {\n enableRetry: true,\n enableSolutionsButton: true,\n type: \u0027auto\u0027,\n singlePoint: true,\n randomAnswers: false,\n showSolutionsRequiresInput: true,\n disableImageZooming: false,\n autoCheck: false,\n passPercentage: 100,\n showScorePoints: true\n }\n };\n var template = new EJS({text: texttemplate});\n var params = $.extend(true, defaults, options);\n // Keep track of number of correct choices\n var numCorrect = 0;\n\n // Loop through choices\n for (var i = 0; i \u003c params.answers.length; i++) {\n var answer = params.answers[i];\n\n // Make sure tips and feedback exists\n answer.tipsAndFeedback = answer.tipsAndFeedback || {};\n\n if (params.answers[i].correct) {\n // Update number of correct choices\n numCorrect++;\n }\n }\n\n // Determine if no choices is the correct\n var blankIsCorrect = (numCorrect === 0);\n\n // Determine task type\n if (params.behaviour.type === \u0027auto\u0027) {\n // Use single choice if only one choice is correct\n params.behaviour.singleAnswer = (numCorrect === 1);\n }\n else {\n params.behaviour.singleAnswer = (params.behaviour.type === \u0027single\u0027);\n }\n\n var getCheckboxOrRadioIcon = function (radio, selected) {\n var icon;\n if (radio) {\n icon = selected ? \u0027\u0026#xe603;\u0027 : \u0027\u0026#xe600;\u0027;\n }\n else {\n icon = selected ? \u0027\u0026#xe601;\u0027 : \u0027\u0026#xe602;\u0027;\n }\n return icon;\n };\n\n // Initialize buttons and elements.\n var $myDom;\n var $feedbackDialog;\n\n /**\n * Remove all feedback dialogs\n */\n var removeFeedbackDialog = function () {\n // Remove the open feedback dialogs.\n $myDom.unbind(\u0027click\u0027, removeFeedbackDialog);\n $myDom.find(\u0027.h5p-feedback-button, .h5p-feedback-dialog\u0027).remove();\n $myDom.find(\u0027.h5p-has-feedback\u0027).removeClass(\u0027h5p-has-feedback\u0027);\n if ($feedbackDialog) {\n $feedbackDialog.remove();\n }\n };\n\n var score = 0;\n var solutionsVisible = false;\n\n /**\n * Add feedback to element\n * @param {jQuery} $element Element that feedback will be added to\n * @param {string} feedback Feedback string\n */\n var addFeedback = function ($element, feedback) {\n $feedbackDialog = $(\u0027\u0027 +\n \u0027\u003cdiv class=\"h5p-feedback-dialog\"\u003e\u0027 +\n \u0027\u003cdiv class=\"h5p-feedback-inner\"\u003e\u0027 +\n \u0027\u003cdiv class=\"h5p-feedback-text\" aria-hidden=\"true\"\u003e\u0027 + feedback + \u0027\u003c/div\u003e\u0027 +\n \u0027\u003c/div\u003e\u0027 +\n \u0027\u003c/div\u003e\u0027);\n\n //make sure feedback is only added once\n if (!$element.find($(\u0027.h5p-feedback-dialog\u0027)).length) {\n $feedbackDialog.appendTo($element.addClass(\u0027h5p-has-feedback\u0027));\n }\n };\n\n /**\n * Register the different parts of the task with the H5P.Question structure.\n */\n self.registerDomElements = function () {\n if (params.media \u0026\u0026 params.media.library) {\n var type = params.media.library.split(\u0027 \u0027)[0];\n if (type === \u0027H5P.Image\u0027) {\n if (params.media.params.file) {\n // Register task image\n self.setImage(params.media.params.file.path, {\n disableImageZooming: params.behaviour.disableImageZooming,\n alt: params.media.params.alt\n });\n }\n }\n else if (type === \u0027H5P.Video\u0027) {\n if (params.media.params.sources) {\n // Register task video\n self.setVideo(params.media);\n }\n }\n }\n\n // Determine if we\u0027re using checkboxes or radio buttons\n for (var i = 0; i \u003c params.answers.length; i++) {\n params.answers[i].checkboxOrRadioIcon = getCheckboxOrRadioIcon(params.behaviour.singleAnswer, params.userAnswers.indexOf(i) \u003e -1);\n }\n\n // Register Introduction\n self.setIntroduction(\u0027\u003cdiv id=\"\u0027 + params.label + \u0027\"\u003e\u0027 + params.question + \u0027\u003c/div\u003e\u0027);\n\n // Register task content area\n $myDom = $(template.render(params));\n self.setContent($myDom, {\n \u0027class\u0027: params.behaviour.singleAnswer ? \u0027h5p-radio\u0027 : \u0027h5p-check\u0027\n });\n\n // Create tips:\n var $answers = $(\u0027.h5p-answer\u0027, $myDom).each(function (i) {\n\n var tip = params.answers[i].tipsAndFeedback.tip;\n if (tip === undefined) {\n return; // No tip\n }\n\n tip = tip.trim();\n var tipContent = tip\n .replace(/\u0026nbsp;/g, \u0027\u0027)\n .replace(/\u003cp\u003e/g, \u0027\u0027)\n .replace(/\u003c\\/p\u003e/g, \u0027\u0027)\n .trim();\n if (!tipContent.length) {\n return; // Empty tip\n }\n else {\n $(this).addClass(\u0027h5p-has-tip\u0027);\n }\n\n // Add tip\n var $wrap = $(\u0027\u003cdiv/\u003e\u0027, {\n \u0027class\u0027: \u0027h5p-multichoice-tipwrap\u0027,\n \u0027aria-label\u0027: params.UI.tipAvailable + \u0027.\u0027\n });\n\n var $multichoiceTip = $(\u0027\u003cdiv\u003e\u0027, {\n \u0027role\u0027: \u0027button\u0027,\n \u0027tabindex\u0027: 0,\n \u0027title\u0027: params.UI.tipsLabel,\n \u0027aria-label\u0027: params.UI.tipsLabel,\n \u0027aria-expanded\u0027: false,\n \u0027class\u0027: \u0027multichoice-tip\u0027,\n appendTo: $wrap\n });\n\n var tipIconHtml = \u0027\u003cspan class=\"joubel-icon-tip-normal\"\u003e\u0027 +\n \u0027\u003cspan class=\"h5p-icon-shadow\"\u003e\u003c/span\u003e\u0027 +\n \u0027\u003cspan class=\"h5p-icon-speech-bubble\"\u003e\u003c/span\u003e\u0027 +\n \u0027\u003cspan class=\"h5p-icon-info\"\u003e\u003c/span\u003e\u0027 +\n \u0027\u003c/span\u003e\u0027;\n\n $multichoiceTip.append(tipIconHtml);\n\n $multichoiceTip.click(function () {\n var $tipContainer = $multichoiceTip.parents(\u0027.h5p-answer\u0027);\n var openFeedback = !$tipContainer.children(\u0027.h5p-feedback-dialog\u0027).is($feedbackDialog);\n removeFeedbackDialog();\n\n // Do not open feedback if it was open\n if (openFeedback) {\n $multichoiceTip.attr(\u0027aria-expanded\u0027, true);\n\n // Add tip dialog\n addFeedback($tipContainer, tip);\n $feedbackDialog.addClass(\u0027h5p-has-tip\u0027);\n\n // Tip for readspeaker\n self.read(tip);\n }\n else {\n $multichoiceTip.attr(\u0027aria-expanded\u0027, false);\n }\n\n self.trigger(\u0027resize\u0027);\n\n // Remove tip dialog on dom click\n setTimeout(function () {\n $myDom.click(removeFeedbackDialog);\n }, 100);\n\n // Do not propagate\n return false;\n }).keydown(function (e) {\n if (e.which === 32) {\n $(this).click();\n return false;\n }\n });\n\n $(\u0027.h5p-alternative-container\u0027, this).append($wrap);\n });\n\n // Set event listeners.\n var toggleCheck = function ($ans) {\n if ($ans.attr(\u0027aria-disabled\u0027) === \u0027true\u0027) {\n return;\n }\n self.answered = true;\n var num = parseInt($ans.data(\u0027id\u0027));\n if (params.behaviour.singleAnswer) {\n // Store answer\n params.userAnswers[0] = num;\n\n // Calculate score\n score = (params.answers[num].correct ? 1 : 0);\n\n // De-select previous answer\n $answers.not($ans).removeClass(\u0027h5p-selected\u0027).attr(\u0027tabindex\u0027, \u0027-1\u0027).attr(\u0027aria-checked\u0027, \u0027false\u0027);\n\n // Select new answer\n $ans.addClass(\u0027h5p-selected\u0027).attr(\u0027tabindex\u0027, \u00270\u0027).attr(\u0027aria-checked\u0027, \u0027true\u0027);\n }\n else {\n if ($ans.attr(\u0027aria-checked\u0027) === \u0027true\u0027) {\n\n // Do not allow un-checking when retry disabled and auto check\n if (params.behaviour.autoCheck \u0026\u0026 !params.behaviour.enableRetry) {\n return;\n }\n\n // Remove check\n $ans.removeClass(\u0027h5p-selected\u0027).attr(\u0027aria-checked\u0027, \u0027false\u0027);\n }\n else {\n $ans.addClass(\u0027h5p-selected\u0027).attr(\u0027aria-checked\u0027, \u0027true\u0027);\n }\n\n // Calculate score\n calcScore();\n }\n\n self.triggerXAPI(\u0027interacted\u0027);\n hideSolution($ans);\n\n if (params.userAnswers.length) {\n self.showButton(\u0027check-answer\u0027);\n self.hideButton(\u0027try-again\u0027);\n self.hideButton(\u0027show-solution\u0027);\n\n if (params.behaviour.autoCheck) {\n if (params.behaviour.singleAnswer) {\n // Only a single answer allowed\n checkAnswer();\n }\n else {\n // Show feedback for selected alternatives\n self.showCheckSolution(true);\n\n // Always finish task if it was completed successfully\n if (score === self.getMaxScore()) {\n checkAnswer();\n }\n }\n }\n }\n };\n\n $answers.click(function () {\n toggleCheck($(this));\n }).keydown(function (e) {\n if (e.keyCode === 32) { // Space bar\n // Select current item\n toggleCheck($(this));\n return false;\n }\n\n if (params.behaviour.singleAnswer) {\n switch (e.keyCode) {\n case 38: // Up\n case 37: { // Left\n // Try to select previous item\n var $prev = $(this).prev();\n if ($prev.length) {\n toggleCheck($prev.focus());\n }\n return false;\n }\n case 40: // Down\n case 39: { // Right\n // Try to select next item\n var $next = $(this).next();\n if ($next.length) {\n toggleCheck($next.focus());\n }\n return false;\n }\n }\n }\n });\n\n if (params.behaviour.singleAnswer) {\n // Special focus handler for radio buttons\n $answers.focus(function () {\n if ($(this).attr(\u0027aria-disabled\u0027) !== \u0027true\u0027) {\n $answers.not(this).attr(\u0027tabindex\u0027, \u0027-1\u0027);\n }\n }).blur(function () {\n if (!$answers.filter(\u0027.h5p-selected\u0027).length) {\n $answers.first().add($answers.last()).attr(\u0027tabindex\u0027, \u00270\u0027);\n }\n });\n }\n\n // Adds check and retry button\n addButtons();\n if (!params.behaviour.singleAnswer) {\n\n calcScore();\n }\n else {\n if (params.userAnswers.length \u0026\u0026 params.answers[params.userAnswers[0]].correct) {\n score = 1;\n }\n else {\n score = 0;\n }\n }\n\n // Has answered through auto-check in a previous session\n if (hasCheckedAnswer \u0026\u0026 params.behaviour.autoCheck) {\n\n // Check answers if answer has been given or max score reached\n if (params.behaviour.singleAnswer || score === self.getMaxScore()) {\n checkAnswer();\n }\n else {\n // Show feedback for checked checkboxes\n self.showCheckSolution(true);\n }\n }\n };\n\n this.showAllSolutions = function () {\n if (solutionsVisible) {\n return;\n }\n solutionsVisible = true;\n\n $myDom.find(\u0027.h5p-answer\u0027).each(function (i, e) {\n var $e = $(e);\n var a = params.answers[i];\n if (a.correct) {\n $e.addClass(\u0027h5p-should\u0027).append($(\u0027\u003cspan/\u003e\u0027, {\n \u0027class\u0027: \u0027h5p-solution-icon\u0027,\n html: params.UI.shouldCheck + \u0027.\u0027\n }));\n }\n else {\n $e.addClass(\u0027h5p-should-not\u0027).append($(\u0027\u003cspan/\u003e\u0027, {\n \u0027class\u0027: \u0027h5p-solution-icon\u0027,\n html: params.UI.shouldNotCheck + \u0027.\u0027\n }));\n }\n }).find(\u0027.h5p-question-plus-one, .h5p-question-minus-one\u0027).remove();\n\n // Make sure input is disabled in solution mode\n disableInput();\n\n //Hide buttons and retry depending on settings.\n self.hideButton(\u0027check-answer\u0027);\n self.hideButton(\u0027show-solution\u0027);\n if (params.behaviour.enableRetry) {\n self.showButton(\u0027try-again\u0027);\n }\n self.trigger(\u0027resize\u0027);\n };\n\n /**\n * Used in contracts.\n * Shows the solution for the task and hides all buttons.\n */\n this.showSolutions = function () {\n removeFeedbackDialog();\n self.showCheckSolution();\n self.showAllSolutions();\n disableInput();\n self.hideButton(\u0027try-again\u0027);\n };\n\n /**\n * Hide solution for the given answer(s)\n *\n * @private\n * @param {H5P.jQuery} $answer\n */\n var hideSolution = function ($answer) {\n $answer\n .removeClass(\u0027h5p-correct\u0027)\n .removeClass(\u0027h5p-wrong\u0027)\n .removeClass(\u0027h5p-should\u0027)\n .removeClass(\u0027h5p-should-not\u0027)\n .removeClass(\u0027h5p-has-feedback\u0027)\n .find(\u0027.h5p-question-plus-one, .h5p-question-minus-one, .h5p-answer-icon, .h5p-solution-icon, .h5p-feedback-dialog\u0027).remove();\n };\n\n /**\n *\n */\n this.hideSolutions = function () {\n solutionsVisible = false;\n\n hideSolution($(\u0027.h5p-answer\u0027, $myDom));\n\n this.removeFeedback(); // Reset feedback\n\n self.trigger(\u0027resize\u0027);\n };\n\n /**\n * Resets the whole task.\n * Used in contracts with integrated content.\n * @private\n */\n this.resetTask = function () {\n self.answered = false;\n self.hideSolutions();\n params.userAnswers = [];\n removeSelections();\n self.showButton(\u0027check-answer\u0027);\n self.hideButton(\u0027try-again\u0027);\n self.hideButton(\u0027show-solution\u0027);\n enableInput();\n $myDom.find(\u0027.h5p-feedback-available\u0027).remove();\n };\n\n var calculateMaxScore = function () {\n if (blankIsCorrect) {\n return params.weight;\n }\n var maxScore = 0;\n for (var i = 0; i \u003c params.answers.length; i++) {\n var choice = params.answers[i];\n if (choice.correct) {\n maxScore += (choice.weight !== undefined ? choice.weight : 1);\n }\n }\n return maxScore;\n };\n\n this.getMaxScore = function () {\n return (!params.behaviour.singleAnswer \u0026\u0026 !params.behaviour.singlePoint ? calculateMaxScore() : params.weight);\n };\n\n /**\n * Check answer\n */\n var checkAnswer = function () {\n // Unbind removal of feedback dialogs on click\n $myDom.unbind(\u0027click\u0027, removeFeedbackDialog);\n\n // Remove all tip dialogs\n removeFeedbackDialog();\n\n self.hideButton(\u0027check-answer\u0027);\n if (params.behaviour.enableSolutionsButton) {\n self.showButton(\u0027show-solution\u0027);\n }\n if (params.behaviour.enableRetry) {\n self.showButton(\u0027try-again\u0027);\n }\n\n self.showCheckSolution();\n disableInput();\n\n var xAPIEvent = self.createXAPIEventTemplate(\u0027answered\u0027);\n addQuestionToXAPI(xAPIEvent);\n addResponseToXAPI(xAPIEvent);\n self.trigger(xAPIEvent);\n self.trigger(\u0027resize\u0027);\n };\n\n /**\n * Determine if any of the radios or checkboxes have been checked.\n *\n * @return {boolean}\n */\n var isAnswerSelected = function () {\n return !!$(\u0027.h5p-answer[aria-checked=\"true\"]\u0027, $myDom).length;\n };\n\n /**\n * Adds the ui buttons.\n * @private\n */\n var addButtons = function () {\n var $content = $(\u0027[data-content-id=\"\u0027 + self.contentId + \u0027\"].h5p-content\u0027);\n var $containerParents = $content.parents(\u0027.h5p-container\u0027);\n\n // select find container to attach dialogs to\n var $container;\n if($containerParents.length !== 0) {\n // use parent highest up if any\n $container = $containerParents.last();\n }\n else if($content.length !== 0){\n $container = $content;\n }\n else {\n $container = $(document.body);\n }\n\n // Show solution button\n self.addButton(\u0027show-solution\u0027, params.UI.showSolutionButton, function () {\n\n if (params.behaviour.showSolutionsRequiresInput \u0026\u0026 !isAnswerSelected()) {\n // Require answer before solution can be viewed\n self.updateFeedbackContent(params.UI.noInput);\n self.read(params.UI.noInput);\n }\n else {\n calcScore();\n self.showAllSolutions();\n }\n\n }, false);\n\n // Check solution button\n if (!params.behaviour.autoCheck || !params.behaviour.singleAnswer) {\n self.addButton(\u0027check-answer\u0027, params.UI.checkAnswerButton,\n function () {\n self.answered = true;\n checkAnswer();\n },\n true,\n {},\n {\n confirmationDialog: {\n enable: params.behaviour.confirmCheckDialog,\n l10n: params.confirmCheck,\n instance: self,\n $parentElement: $container\n }\n }\n );\n }\n\n // Try Again button\n self.addButton(\u0027try-again\u0027, params.UI.tryAgainButton, function () {\n self.showButton(\u0027check-answer\u0027);\n self.hideButton(\u0027try-again\u0027);\n self.hideButton(\u0027show-solution\u0027);\n self.hideSolutions();\n removeSelections();\n enableInput();\n $myDom.find(\u0027.h5p-feedback-available\u0027).remove();\n self.answered = false;\n if (params.behaviour.randomAnswers) {\n // reshuffle answers\n var oldIdMap = idMap;\n idMap = getShuffleMap();\n var answersDisplayed = $myDom.find(\u0027.h5p-answer\u0027);\n // remember tips\n var tip = [];\n for (i = 0; i \u003c answersDisplayed.length; i++) {\n tip[i] = $(answersDisplayed[i]).find(\u0027.h5p-multichoice-tipwrap\u0027);\n }\n // Those two loops cannot be merged or you\u0027ll screw up your tips\n for (i = 0; i \u003c answersDisplayed.length; i++) {\n // move tips and answers on display\n $(answersDisplayed[i]).find(\u0027.h5p-alternative-inner\u0027).html(params.answers[i].text);\n $(tip[i]).detach().appendTo($(answersDisplayed[idMap.indexOf(oldIdMap[i])]).find(\u0027.h5p-alternative-container\u0027));\n }\n }\n }, false, {}, {\n confirmationDialog: {\n enable: params.behaviour.confirmRetryDialog,\n l10n: params.confirmRetry,\n instance: self,\n $parentElement: $container\n }\n });\n };\n\n /**\n * @private\n */\n var insertFeedback = function ($e, feedback) {\n // Add visuals\n addFeedback($e, feedback);\n\n // Add button for readspeakers\n var $wrap = $(\u0027\u003cdiv/\u003e\u0027, {\n \u0027class\u0027: \u0027h5p-hidden-read h5p-feedback-available\u0027,\n \u0027aria-label\u0027: params.UI.feedbackAvailable + \u0027.\u0027\n });\n $(\u0027\u003cdiv/\u003e\u0027, {\n \u0027role\u0027: \u0027button\u0027,\n \u0027tabindex\u0027: 0,\n \u0027aria-label\u0027: params.UI.readFeedback + \u0027.\u0027,\n appendTo: $wrap,\n on: {\n keydown: function (e) {\n if (e.which === 32) { // Space\n self.read(feedback);\n return false;\n }\n }\n }\n });\n $wrap.appendTo($e);\n };\n\n /**\n * Determine which feedback text to display\n *\n * @param {number} score\n * @param {number} max\n * @return {string}\n */\n var getFeedbackText = function (score, max) {\n var ratio = (score / max);\n\n var feedback = H5P.Question.determineOverallFeedback(params.overallFeedback, ratio);\n\n return feedback.replace(\u0027@score\u0027, score).replace(\u0027@total\u0027, max);\n };\n\n /**\n * Shows feedback on the selected fields.\n * @public\n * @param {boolean} [skipFeedback] Skip showing feedback if true\n */\n this.showCheckSolution = function (skipFeedback) {\n var scorePoints;\n if (!(params.behaviour.singleAnswer || params.behaviour.singlePoint || !params.behaviour.showScorePoints)) {\n scorePoints = new H5P.Question.ScorePoints();\n }\n\n $myDom.find(\u0027.h5p-answer\u0027).each(function (i, e) {\n var $e = $(e);\n var a = params.answers[i];\n var chosen = ($e.attr(\u0027aria-checked\u0027) === \u0027true\u0027);\n if (chosen) {\n if (a.correct) {\n $e.addClass(\u0027h5p-correct\u0027).append($(\u0027\u003cspan/\u003e\u0027, {\n \u0027class\u0027: \u0027h5p-answer-icon\u0027,\n html: params.UI.correctAnswer + \u0027.\u0027\n }));\n }\n else {\n $e.addClass(\u0027h5p-wrong\u0027).append($(\u0027\u003cspan/\u003e\u0027, {\n \u0027class\u0027: \u0027h5p-answer-icon\u0027,\n html: params.UI.wrongAnswer + \u0027.\u0027\n }));\n }\n\n if (scorePoints) {\n var alternativeContainer = $e[0].querySelector(\u0027.h5p-alternative-container\u0027);\n\n if (!params.behaviour.autoCheck || alternativeContainer.querySelector(\u0027.h5p-question-plus-one, .h5p-question-minus-one\u0027) === null) {\n alternativeContainer.appendChild(scorePoints.getElement(a.correct));\n }\n }\n }\n\n if (!skipFeedback) {\n if (chosen \u0026\u0026 a.tipsAndFeedback.chosenFeedback !== undefined \u0026\u0026 a.tipsAndFeedback.chosenFeedback !== \u0027\u0027) {\n insertFeedback($e, a.tipsAndFeedback.chosenFeedback);\n }\n else if (!chosen \u0026\u0026 a.tipsAndFeedback.notChosenFeedback !== undefined \u0026\u0026 a.tipsAndFeedback.notChosenFeedback !== \u0027\u0027) {\n insertFeedback($e, a.tipsAndFeedback.notChosenFeedback);\n }\n }\n });\n\n // Determine feedback\n var max = self.getMaxScore();\n\n // Show feedback\n if (!skipFeedback) {\n this.setFeedback(getFeedbackText(score, max), score, max, params.UI.scoreBarLabel);\n }\n\n // Disable task if maxscore is achieved\n var fullScore = (score === max);\n if (fullScore) {\n finishedTask();\n }\n\n self.trigger(\u0027resize\u0027);\n };\n\n /**\n * Method to use when the task is correctly answered, removes all buttons and disables input.\n */\n var finishedTask = function () {\n self.hideButton(\u0027check-answer\u0027);\n self.hideButton(\u0027try-again\u0027);\n self.hideButton(\u0027show-solution\u0027);\n self.trigger(\u0027resize\u0027);\n };\n\n /**\n * Disables choosing new input.\n */\n var disableInput = function () {\n $(\u0027.h5p-answer\u0027, $myDom).attr({\n \u0027aria-disabled\u0027: \u0027true\u0027,\n \u0027tabindex\u0027: \u0027-1\u0027\n });\n };\n\n /**\n * Enables new input.\n */\n var enableInput = function () {\n $(\u0027.h5p-answer\u0027, $myDom).attr(\u0027aria-disabled\u0027, \u0027false\u0027);\n };\n\n var calcScore = function () {\n score = 0;\n params.userAnswers = [];\n $(\u0027.h5p-answer\u0027, $myDom).each(function (idx, el) {\n var $el = $(el);\n if ($el.attr(\u0027aria-checked\u0027) === \u0027true\u0027) {\n var choice = params.answers[idx];\n var weight = (choice.weight !== undefined ? choice.weight : 1);\n if (choice.correct) {\n score += weight;\n }\n else {\n score -= weight;\n }\n var num = parseInt($(el).data(\u0027id\u0027));\n params.userAnswers.push(num);\n }\n });\n if (score \u003c 0) {\n score = 0;\n }\n if (!params.userAnswers.length \u0026\u0026 blankIsCorrect) {\n score = params.weight;\n }\n if (params.behaviour.singlePoint) {\n score = (100 * score / calculateMaxScore()) \u003e= params.behaviour.passPercentage ? params.weight : 0;\n }\n };\n\n /**\n * Removes selections from task.\n */\n var removeSelections = function () {\n var $answers = $(\u0027.h5p-answer\u0027, $myDom)\n .removeClass(\u0027h5p-selected\u0027)\n .attr(\u0027aria-checked\u0027, \u0027false\u0027);\n\n if (!params.behaviour.singleAnswer) {\n $answers.attr(\u0027tabindex\u0027, \u00270\u0027);\n }\n else {\n $answers.first().attr(\u0027tabindex\u0027, \u00270\u0027);\n }\n\n // Set focus to first option\n $answers.first().focus();\n\n calcScore();\n };\n\n /**\n * Get xAPI data.\n * Contract used by report rendering engine.\n *\n * @see contract at {@link https://h5p.org/documentation/developers/contracts#guides-header-6}\n */\n this.getXAPIData = function(){\n var xAPIEvent = this.createXAPIEventTemplate(\u0027answered\u0027);\n addQuestionToXAPI(xAPIEvent);\n addResponseToXAPI(xAPIEvent);\n return {\n statement: xAPIEvent.data.statement\n };\n };\n\n /**\n * Add the question itself to the definition part of an xAPIEvent\n */\n var addQuestionToXAPI = function (xAPIEvent) {\n var definition = xAPIEvent.getVerifiedStatementValue([\u0027object\u0027, \u0027definition\u0027]);\n definition.description = {\n // Remove tags, must wrap in div tag because jQuery 1.9 will crash if the string isn\u0027t wrapped in a tag.\n \u0027en-US\u0027: $(\u0027\u003cdiv\u003e\u0027 + params.question + \u0027\u003c/div\u003e\u0027).text()\n };\n definition.type = \u0027http://adlnet.gov/expapi/activities/cmi.interaction\u0027;\n definition.interactionType = \u0027choice\u0027;\n definition.correctResponsesPattern = [];\n definition.choices = [];\n for (var i = 0; i \u003c params.answers.length; i++) {\n definition.choices[i] = {\n \u0027id\u0027: params.answers[i].originalOrder + \u0027\u0027,\n \u0027description\u0027: {\n // Remove tags, must wrap in div tag because jQuery 1.9 will crash if the string isn\u0027t wrapped in a tag.\n \u0027en-US\u0027: $(\u0027\u003cdiv\u003e\u0027 + params.answers[i].text + \u0027\u003c/div\u003e\u0027).text()\n }\n };\n if (params.answers[i].correct) {\n if (!params.singleAnswer) {\n if (definition.correctResponsesPattern.length) {\n definition.correctResponsesPattern[0] += \u0027[,]\u0027;\n // This looks insane, but it\u0027s how you separate multiple answers\n // that must all be chosen to achieve perfect score...\n }\n else {\n definition.correctResponsesPattern.push(\u0027\u0027);\n }\n definition.correctResponsesPattern[0] += params.answers[i].originalOrder;\n }\n else {\n definition.correctResponsesPattern.push(\u0027\u0027 + params.answers[i].originalOrder);\n }\n }\n }\n };\n\n /**\n * Add the response part to an xAPI event\n *\n * @param {H5P.XAPIEvent} xAPIEvent\n * The xAPI event we will add a response to\n */\n var addResponseToXAPI = function (xAPIEvent) {\n var maxScore = self.getMaxScore();\n var success = (100 * score / maxScore) \u003e= params.behaviour.passPercentage;\n\n xAPIEvent.setScoredResult(score, maxScore, self, true, success);\n if (params.userAnswers === undefined) {\n calcScore();\n }\n\n // Add the response\n var response = \u0027\u0027;\n for (var i = 0; i \u003c params.userAnswers.length; i++) {\n if (response !== \u0027\u0027) {\n response += \u0027[,]\u0027;\n }\n response += idMap === undefined ? params.userAnswers[i] : idMap[params.userAnswers[i]];\n }\n xAPIEvent.data.statement.result.response = response;\n };\n\n /**\n * Create a map pointing from original answers to shuffled answers\n *\n * @return {number[]} map pointing from original answers to shuffled answers\n */\n var getShuffleMap = function() {\n params.answers = H5P.shuffleArray(params.answers);\n\n // Create a map from the new id to the old one\n var idMap = [];\n for (i = 0; i \u003c params.answers.length; i++) {\n idMap[i] = params.answers[i].originalOrder;\n }\n return idMap;\n };\n\n // Initialization code\n // Randomize order, if requested\n var idMap;\n // Store original order in answers\n for (i = 0; i \u003c params.answers.length; i++) {\n params.answers[i].originalOrder = i;\n }\n if (params.behaviour.randomAnswers) {\n idMap = getShuffleMap();\n }\n\n // Start with an empty set of user answers.\n params.userAnswers = [];\n\n // Restore previous state\n if (contentData \u0026\u0026 contentData.previousState !== undefined) {\n\n // Restore answers\n if (contentData.previousState.answers) {\n if (!idMap) {\n params.userAnswers = contentData.previousState.answers;\n }\n else {\n // The answers have been shuffled, and we must use the id mapping.\n for (i = 0; i \u003c contentData.previousState.answers.length; i++) {\n for (var k = 0; k \u003c idMap.length; k++) {\n if (idMap[k] === contentData.previousState.answers[i]) {\n params.userAnswers.push(k);\n }\n }\n }\n }\n }\n }\n\n var hasCheckedAnswer = false;\n\n // Loop through choices\n for (var j = 0; j \u003c params.answers.length; j++) {\n var ans = params.answers[j];\n\n if (!params.behaviour.singleAnswer) {\n // Set role\n ans.role = \u0027checkbox\u0027;\n ans.tabindex = \u00270\u0027;\n if (params.userAnswers.indexOf(j) !== -1) {\n ans.checked = \u0027true\u0027;\n hasCheckedAnswer = true;\n }\n }\n else {\n // Set role\n ans.role = \u0027radio\u0027;\n\n // Determine tabindex, checked and extra classes\n if (params.userAnswers.length === 0) {\n // No correct answers\n if (i === 0 || i === params.answers.length) {\n ans.tabindex = \u00270\u0027;\n }\n }\n else if (params.userAnswers.indexOf(j) !== -1) {\n // This is the correct choice\n ans.tabindex = \u00270\u0027;\n ans.checked = \u0027true\u0027;\n hasCheckedAnswer = true;\n }\n }\n\n // Set default\n if (ans.tabindex === undefined) {\n ans.tabindex = \u0027-1\u0027;\n }\n if (ans.checked === undefined) {\n ans.checked = \u0027false\u0027;\n }\n }\n\n H5P.MultiChoice.counter = (H5P.MultiChoice.counter === undefined ? 0 : H5P.MultiChoice.counter + 1);\n params.role = (params.behaviour.singleAnswer ? \u0027radiogroup\u0027 : \u0027group\u0027);\n params.label = \u0027h5p-mcq\u0027 + H5P.MultiChoice.counter;\n\n /**\n * Pack the current state of the interactivity into a object that can be\n * serialized.\n *\n * @public\n */\n this.getCurrentState = function () {\n var state = {};\n if (!idMap) {\n state.answers = params.userAnswers;\n }\n else {\n // The answers have been shuffled and must be mapped back to their\n // original ID.\n state.answers = [];\n for (var i = 0; i \u003c params.userAnswers.length; i++) {\n state.answers.push(idMap[params.userAnswers[i]]);\n }\n }\n return state;\n };\n\n /**\n * Check if user has given an answer.\n *\n * @param {boolean} [ignoreCheck] Ignore returning true from pressing \"check-answer\" button.\n * @return {boolean} True if answer is given\n */\n this.getAnswerGiven = function (ignoreCheck) {\n var answered = ignoreCheck ? false : this.answered;\n return answered || params.userAnswers.length \u003e 0 || blankIsCorrect;\n };\n\n this.getScore = function () {\n return score;\n };\n\n this.getTitle = function () {\n return H5P.createTitle(params.question);\n };\n};\n\nH5P.MultiChoice.prototype = Object.create(H5P.Question.prototype);\nH5P.MultiChoice.prototype.constructor = H5P.MultiChoice;\n"
,"radio-group.js":"/**\n * RadioGroup widget\n *\n * @param {H5P.jQuery} $\n */\nH5PEditor.RadioGroup = H5PEditor.widgets.radioGroup = (function ($) {\n\n var groupCounter = 0;\n /**\n * Creates an radio button group.\n *\n * @class H5PEditor.ImageRadioButtonGroup\n * @param {Object} parent\n * @param {Object} field\n * @param {Object} params\n * @param {function} setValue\n */\n function RadioGroup(parent, field, params, setValue) {\n this.parent = parent;\n this.field = field;\n this.params = params;\n this.setValue = setValue;\n\n this.alignment = this.field.alignment || \u0027vertical\u0027;\n\n groupCounter++;\n }\n\n /**\n * Append the field to the wrapper.\n * @public\n * @param {H5P.jQuery} $wrapper\n */\n RadioGroup.prototype.appendTo = function ($wrapper) {\n var self = this;\n\n self.$container = $(H5PEditor.createFieldMarkup(\n self.field,\n \u0027\u003cdiv class=\"h5p-editor-radio-group-container \u0027 + self.alignment + \u0027\" role=\"radiogroup\"\u003e\u003c/div\u003e\u0027\n ));\n\n var $buttonGroup = self.$container.find(\u0027.h5p-editor-radio-group-container\u0027);\n\n for (var i = 0; i \u003c self.field.options.length; i++) {\n var option = self.field.options[i];\n var inputId = \u0027h5p-editor-radio-group-button-\u0027 + groupCounter + \u0027-\u0027 + i;\n\n var $button = $(\u0027\u003cdiv\u003e\u0027, {\n \u0027class\u0027: \u0027h5p-editor-radio-group-button \u0027 + option.value\n }).appendTo($buttonGroup);\n\n $(\u0027\u003cinput\u003e\u0027, {\n type: \u0027radio\u0027,\n name: self.field.name + groupCounter,\n value: option.value,\n role: \u0027radio\u0027,\n id: inputId,\n checked: (self.params === option.value) || (self.params === undefined \u0026\u0026 this.field.default === option.value),\n change: function () {\n self.params = $(\u0027input:checked\u0027, $buttonGroup).val();\n self.setValue(self.field, self.params);\n }\n }).appendTo($button);\n\n $(\u0027\u003clabel\u003e\u0027, {\n \u0027for\u0027: inputId\n }).append($(\u0027\u003cspan\u003e\u0027, {\n html: option.label\n })).appendTo($button);\n\n if (option.description) {\n $(\u0027\u003cdiv\u003e\u0027, {\n \u0027class\u0027: \u0027h5p-option-description\u0027,\n html: option.description\n }).appendTo($button);\n }\n }\n\n self.$container.appendTo($wrapper);\n };\n\n\n /**\n * Validate the current values.\n */\n RadioGroup.prototype.validate = function () {\n return true;\n };\n\n RadioGroup.prototype.remove = function () {};\n\n return RadioGroup;\n})(H5P.jQuery);\n"
,"scripts/h5p-true-false.js":"H5P.TrueFalse = (function ($, Question) {\n \u0027use strict\u0027;\n\n // Maximum score for True False\n var MAX_SCORE = 1;\n\n /**\n * Enum containing the different states this content type can exist in\n *\n * @enum\n */\n var State = Object.freeze({\n ONGOING: 1,\n FINISHED_WRONG: 2,\n FINISHED_CORRECT: 3,\n INTERNAL_SOLUTION: 4,\n EXTERNAL_SOLUTION: 5\n });\n\n /**\n * Button IDs\n */\n var Button = Object.freeze({\n CHECK: \u0027check-answer\u0027,\n TRYAGAIN: \u0027try-again\u0027,\n SHOW_SOLUTION: \u0027show-solution\u0027\n });\n\n /**\n * Initialize module.\n *\n * @class H5P.TrueFalse\n * @extends H5P.Question\n * @param {Object} options\n * @param {number} id Content identification\n * @param {Object} contentData Task specific content data\n */\n function TrueFalse(options, id, contentData) {\n var self = this;\n\n // Inheritance\n Question.call(self, \u0027true-false\u0027);\n\n var params = $.extend(true, {\n question: \u0027No question text provided\u0027,\n correct: \u0027true\u0027,\n l10n: {\n trueText: \u0027True\u0027,\n falseText: \u0027False\u0027,\n score: \u0027You got @score of @total points\u0027,\n checkAnswer: \u0027Check\u0027,\n showSolutionButton: \u0027Show solution\u0027,\n tryAgain: \u0027Retry\u0027,\n wrongAnswerMessage: \u0027Wrong answer\u0027,\n correctAnswerMessage: \u0027Correct answer\u0027,\n scoreBarLabel: \u0027You got :num out of :total points\u0027\n },\n behaviour: {\n enableRetry: true,\n enableSolutionsButton: true,\n disableImageZooming: false,\n confirmCheckDialog: false,\n confirmRetryDialog: false,\n autoCheck: false\n }\n }, options);\n\n // Counter used to create unique id for this question\n TrueFalse.counter = (TrueFalse.counter === undefined ? 0 : TrueFalse.counter + 1);\n\n // A unique ID is needed for aria label\n var domId = \u0027h5p-tfq\u0027 + H5P.TrueFalse.counter;\n\n // saves the content id\n this.contentId = id;\n\n // The radio group\n var answerGroup = new H5P.TrueFalse.AnswerGroup(domId, params.correct, params.l10n);\n if (contentData.previousState !== undefined \u0026\u0026 contentData.previousState.answer !== undefined) {\n answerGroup.check(contentData.previousState.answer);\n }\n answerGroup.on(\u0027selected\u0027, function () {\n self.triggerXAPI(\u0027interacted\u0027);\n\n if (params.behaviour.autoCheck) {\n checkAnswer();\n triggerXAPIAnswered();\n }\n });\n\n\n /**\n * Create the answers\n *\n * @method createAnswers\n * @private\n * @return {H5P.jQuery}\n */\n var createAnswers = function () {\n return answerGroup.getDomElement();\n };\n\n /**\n * Register buttons\n *\n * @method registerButtons\n * @private\n */\n var registerButtons = function () {\n var $content = $(\u0027[data-content-id=\"\u0027 + self.contentId + \u0027\"].h5p-content\u0027);\n var $containerParents = $content.parents(\u0027.h5p-container\u0027);\n\n // select find container to attach dialogs to\n var $container;\n if($containerParents.length !== 0) {\n // use parent highest up if any\n $container = $containerParents.last();\n }\n else if($content.length !== 0){\n $container = $content;\n }\n else {\n $container = $(document.body);\n }\n\n // Show solution button\n if (params.behaviour.enableSolutionsButton === true) {\n self.addButton(Button.SHOW_SOLUTION, params.l10n.showSolutionButton, function () {\n self.showSolutions(true);\n }, false);\n }\n\n // Check button\n if (!params.behaviour.autoCheck) {\n self.addButton(Button.CHECK, params.l10n.checkAnswer, function () {\n checkAnswer();\n triggerXAPIAnswered();\n }, true, {}, {\n confirmationDialog: {\n enable: params.behaviour.confirmCheckDialog,\n l10n: params.confirmCheck,\n instance: self,\n $parentElement: $container\n }\n });\n }\n\n // Try again button\n if (params.behaviour.enableRetry === true) {\n self.addButton(Button.TRYAGAIN, params.l10n.tryAgain, function () {\n self.resetTask();\n }, true, {}, {\n confirmationDialog: {\n enable: params.behaviour.confirmRetryDialog,\n l10n: params.confirmRetry,\n instance: self,\n $parentElement: $container\n }\n });\n }\n\n toggleButtonState(State.ONGOING);\n };\n\n /**\n * Creates and triggers the xAPI answered event\n *\n * @method triggerXAPIAnswered\n * @private\n * @fires xAPIEvent\n */\n var triggerXAPIAnswered = function () {\n var xAPIEvent = self.createXAPIEventTemplate(\u0027answered\u0027);\n addQuestionToXAPI(xAPIEvent);\n addResponseToXAPI(xAPIEvent);\n self.trigger(xAPIEvent);\n };\n\n /**\n * Add the question itself to the definition part of an xAPIEvent\n *\n * @method addQuestionToXAPI\n * @param {XAPIEvent} xAPIEvent\n * @private\n */\n var addQuestionToXAPI = function(xAPIEvent) {\n var definition = xAPIEvent.getVerifiedStatementValue([\u0027object\u0027, \u0027definition\u0027]);\n definition.description = {\n // Remove tags, must wrap in div tag because jQuery 1.9 will crash if the string isn\u0027t wrapped in a tag.\n \u0027en-US\u0027: $(\u0027\u003cdiv\u003e\u0027 + params.question + \u0027\u003c/div\u003e\u0027).text()\n };\n definition.type = \u0027http://adlnet.gov/expapi/activities/cmi.interaction\u0027;\n definition.interactionType = \u0027true-false\u0027;\n definition.correctResponsesPattern = [getCorrectAnswer()];\n };\n\n /**\n * Returns the correct answer\n *\n * @method getCorrectAnswer\n * @private\n * @return {String}\n */\n var getCorrectAnswer = function () {\n return (params.correct === \u0027true\u0027 ? \u0027true\u0027 : \u0027false\u0027);\n };\n\n /**\n * Returns the wrong answer\n *\n * @method getWrongAnswer\n * @private\n * @return {String}\n */\n var getWrongAnswer = function () {\n return (params.correct === \u0027false\u0027 ? \u0027true\u0027 : \u0027false\u0027);\n };\n\n /**\n * Add the response part to an xAPI event\n *\n * @method addResponseToXAPI\n * @private\n * @param {H5P.XAPIEvent} xAPIEvent\n * The xAPI event we will add a response to\n */\n var addResponseToXAPI = function(xAPIEvent) {\n var isCorrect = answerGroup.isCorrect();\n xAPIEvent.setScoredResult(isCorrect ? MAX_SCORE : 0, MAX_SCORE, self, true, isCorrect);\n xAPIEvent.data.statement.result.response = (isCorrect ? getCorrectAnswer() : getWrongAnswer());\n };\n\n /**\n * Toggles btton visibility dependent of current state\n *\n * @method toggleButtonVisibility\n * @private\n * @param {String} buttonId\n * @param {Boolean} visible\n */\n var toggleButtonVisibility = function (buttonId, visible) {\n if (visible === true) {\n self.showButton(buttonId);\n }\n else {\n self.hideButton(buttonId);\n }\n };\n\n /**\n * Toggles buttons state\n *\n * @method toggleButtonState\n * @private\n * @param {String} state\n */\n var toggleButtonState = function (state) {\n toggleButtonVisibility(Button.SHOW_SOLUTION, state === State.FINISHED_WRONG);\n toggleButtonVisibility(Button.CHECK, state === State.ONGOING);\n toggleButtonVisibility(Button.TRYAGAIN, state === State.FINISHED_WRONG || state === State.INTERNAL_SOLUTION);\n };\n\n /**\n * Check if answer is correct or wrong, and update visuals accordingly\n *\n * @method checkAnswer\n * @private\n */\n var checkAnswer = function () {\n // Create feedback widget\n var score = self.getScore();\n var scoreText;\n\n toggleButtonState(score === MAX_SCORE ? State.FINISHED_CORRECT : State.FINISHED_WRONG);\n\n if (score === MAX_SCORE \u0026\u0026 params.behaviour.feedbackOnCorrect) {\n scoreText = params.behaviour.feedbackOnCorrect;\n }\n else if (score === 0 \u0026\u0026 params.behaviour.feedbackOnWrong) {\n scoreText = params.behaviour.feedbackOnWrong;\n }\n else {\n scoreText = params.l10n.score;\n }\n // Replace relevant variables:\n scoreText = scoreText.replace(\u0027@score\u0027, score).replace(\u0027@total\u0027, MAX_SCORE);\n self.setFeedback(scoreText, score, MAX_SCORE, params.l10n.scoreBarLabel);\n answerGroup.reveal();\n };\n\n /**\n * Registers this question type\u0027s DOM elements before they are attached.\n * Called from H5P.Question.\n *\n * @method registerDomElements\n * @private\n */\n self.registerDomElements = function () {\n var self = this;\n\n // Check for task media\n var media = params.media;\n if (media \u0026\u0026 media.library) {\n var type = media.library.split(\u0027 \u0027)[0];\n if (type === \u0027H5P.Image\u0027) {\n if (media.params.file) {\n // Register task image\n self.setImage(media.params.file.path, {\n disableImageZooming: params.behaviour.disableImageZooming,\n alt: media.params.alt\n });\n }\n }\n else if (type === \u0027H5P.Video\u0027) {\n if (media.params.sources) {\n // Register task video\n self.setVideo(media);\n }\n }\n }\n\n // Add task question text\n self.setIntroduction(\u0027\u003cdiv id=\"\u0027 + domId + \u0027\"\u003e\u0027 + params.question + \u0027\u003c/div\u003e\u0027);\n\n // Register task content area\n self.$content = createAnswers();\n self.setContent(self.$content);\n\n // ... and buttons\n registerButtons();\n };\n\n /**\n * Implements resume (save content state)\n *\n * @method getCurrentState\n * @public\n * @returns {object} object containing answer\n */\n self.getCurrentState = function () {\n return {answer: answerGroup.getAnswer()};\n };\n\n /**\n * Used for contracts.\n * Checks if the parent program can proceed. Always true.\n *\n * @method getAnswerGiven\n * @public\n * @returns {Boolean} true\n */\n self.getAnswerGiven = function () {\n return answerGroup.hasAnswered();\n };\n\n /**\n * Used for contracts.\n * Checks the current score for this task.\n *\n * @method getScore\n * @public\n * @returns {Number} The current score.\n */\n self.getScore = function () {\n return answerGroup.isCorrect() ? MAX_SCORE : 0;\n };\n\n /**\n * Used for contracts.\n * Checks the maximum score for this task.\n *\n * @method getMaxScore\n * @public\n * @returns {Number} The maximum score.\n */\n self.getMaxScore = function () {\n return MAX_SCORE;\n };\n\n /**\n * Get title of task\n *\n * @method getTitle\n * @upblic\n * @returns {string} title\n */\n self.getTitle = function () {\n return H5P.createTitle(params.question);\n };\n\n /**\n * Used for contracts.\n * Show the solution.\n *\n * @method showSolutions\n * @public\n */\n self.showSolutions = function (internal) {\n checkAnswer();\n answerGroup.showSolution();\n toggleButtonState(internal ? State.INTERNAL_SOLUTION : State.EXTERNAL_SOLUTION);\n };\n\n /**\n * Used for contracts.\n * Resets the complete task back to its\u0027 initial state.\n *\n * @method resetTask\n * @public\n */\n self.resetTask = function () {\n answerGroup.reset();\n self.removeFeedback();\n toggleButtonState(State.ONGOING);\n };\n\n /**\n * Get xAPI data.\n * Contract used by report rendering engine.\n *\n * @see contract at {@link https://h5p.org/documentation/developers/contracts#guides-header-6}\n */\n self.getXAPIData = function(){\n var xAPIEvent = this.createXAPIEventTemplate(\u0027answered\u0027);\n this.addQuestionToXAPI(xAPIEvent);\n this.addResponseToXAPI(xAPIEvent);\n return {\n statement: xAPIEvent.data.statement\n };\n };\n\n /**\n * Add the question itself to the definition part of an xAPIEvent\n */\n self.addQuestionToXAPI = function(xAPIEvent) {\n var definition = xAPIEvent.getVerifiedStatementValue([\u0027object\u0027, \u0027definition\u0027]);\n $.extend(definition, this.getxAPIDefinition());\n };\n\n /**\n * Generate xAPI object definition used in xAPI statements.\n * @return {Object}\n */\n self.getxAPIDefinition = function () {\n var definition = {};\n definition.interactionType = \u0027true-false\u0027;\n definition.type = \u0027http://adlnet.gov/expapi/activities/cmi.interaction\u0027;\n definition.description = {\n \u0027en-US\u0027: $(\u0027\u003cdiv\u003e\u0027 + params.question + \u0027\u003c/div\u003e\u0027).text()\n };\n definition.correctResponsesPattern = [getCorrectAnswer()];\n\n return definition;\n };\n\n /**\n * Add the response part to an xAPI event\n *\n * @param {H5P.XAPIEvent} xAPIEvent\n * The xAPI event we will add a response to\n */\n self.addResponseToXAPI = function (xAPIEvent) {\n var isCorrect = answerGroup.isCorrect();\n var rawUserScore = isCorrect ? MAX_SCORE : 0;\n var currentResponse = \u0027\u0027;\n\n xAPIEvent.setScoredResult(rawUserScore, MAX_SCORE, self, true, isCorrect);\n\n if(self.getCurrentState().answer !== undefined) {\n currentResponse += answerGroup.isCorrect() ? getCorrectAnswer() : getWrongAnswer();\n }\n xAPIEvent.data.statement.result.response = currentResponse;\n };\n }\n\n // Inheritance\n TrueFalse.prototype = Object.create(Question.prototype);\n TrueFalse.prototype.constructor = TrueFalse;\n\n return TrueFalse;\n})(H5P.jQuery, H5P.Question);\n"
,"scripts/h5p-true-false-answer-group.js":"H5P.TrueFalse.AnswerGroup = (function ($, EventDispatcher) {\n \u0027use strict\u0027;\n\n /**\n * Initialize module.\n *\n * @class H5P.TrueFalse.AnswerGroup\n * @extends H5P.EventDispatcher\n * @param {String} domId Id for label\n * @param {String} correctOption Correct option (\u0027true\u0027 or \u0027false\u0027)\n * @param {Object} l10n Object containing all interface translations\n */\n function AnswerGroup(domId, correctOption, l10n) {\n var self = this;\n\n EventDispatcher.call(self);\n\n var $answers = $(\u0027\u003cdiv\u003e\u0027, {\n \u0027class\u0027: \u0027h5p-true-false-answers\u0027,\n role: \u0027radiogroup\u0027,\n \u0027aria-labelledby\u0027: domId\n });\n\n var answer;\n var trueAnswer = new H5P.TrueFalse.Answer(l10n.trueText, l10n.correctAnswerMessage, l10n.wrongAnswerMessage);\n var falseAnswer = new H5P.TrueFalse.Answer(l10n.falseText, l10n.correctAnswerMessage, l10n.wrongAnswerMessage);\n var correctAnswer = (correctOption === \u0027true\u0027 ? trueAnswer : falseAnswer);\n var wrongAnswer = (correctOption === \u0027false\u0027 ? trueAnswer : falseAnswer);\n\n // Handle checked\n var handleChecked = function (newAnswer, other) {\n return function () {\n answer = newAnswer;\n other.uncheck();\n self.trigger(\u0027selected\u0027);\n };\n };\n trueAnswer.on(\u0027checked\u0027, handleChecked(true, falseAnswer));\n falseAnswer.on(\u0027checked\u0027, handleChecked(false, trueAnswer));\n\n // Handle switches (using arrow keys)\n var handleInvert = function (newAnswer, other) {\n return function () {\n answer = newAnswer;\n other.check();\n self.trigger(\u0027selected\u0027);\n };\n };\n trueAnswer.on(\u0027invert\u0027, handleInvert(false, falseAnswer));\n falseAnswer.on(\u0027invert\u0027, handleInvert(true, trueAnswer));\n\n // Handle tabbing\n var handleTabable = function(other, tabable) {\n return function () {\n // If one of them are checked, that one should get tabfocus\n if (!tabable || !self.hasAnswered() || other.isChecked()) {\n other.tabable(tabable);\n }\n };\n };\n // Need to remove tabIndex on the other alternative on focus\n trueAnswer.on(\u0027focus\u0027, handleTabable(falseAnswer, false));\n falseAnswer.on(\u0027focus\u0027, handleTabable(trueAnswer, false));\n // Need to make both alternatives tabable on blur:\n trueAnswer.on(\u0027blur\u0027, handleTabable(falseAnswer, true));\n falseAnswer.on(\u0027blur\u0027, handleTabable(trueAnswer, true));\n\n $answers.append(trueAnswer.getDomElement());\n $answers.append(falseAnswer.getDomElement());\n\n /**\n * Get hold of the DOM element representing this thingy\n * @method getDomElement\n * @return {jQuery}\n */\n self.getDomElement = function () {\n return $answers;\n };\n\n /**\n * Programatic check\n * @method check\n * @param {[type]} answer [description]\n */\n self.check = function (answer) {\n if (answer) {\n trueAnswer.check();\n }\n else {\n falseAnswer.check();\n }\n };\n\n /**\n * Return current answer\n * @method getAnswer\n * @return {Boolean} undefined if no answer if given\n */\n self.getAnswer = function () {\n return answer;\n };\n\n /**\n * Check if user has answered question yet\n * @method hasAnswered\n * @return {Boolean}\n */\n self.hasAnswered = function () {\n return answer !== undefined;\n };\n\n /**\n * Is answer correct?\n * @method isCorrect\n * @return {Boolean}\n */\n self.isCorrect = function () {\n return correctAnswer.isChecked();\n };\n\n /**\n * Enable user input\n *\n * @method enable\n */\n self.enable = function () {\n trueAnswer.enable().tabable(true);\n falseAnswer.enable();\n };\n\n /**\n * Disable user input\n *\n * @method disable\n */\n self.disable = function () {\n trueAnswer.disable();\n falseAnswer.disable();\n };\n\n /**\n * Reveal correct/wrong answer\n *\n * @method reveal\n */\n self.reveal = function () {\n if (self.hasAnswered()) {\n if (self.isCorrect()) {\n correctAnswer.markCorrect();\n }\n else {\n wrongAnswer.markWrong();\n }\n }\n\n self.disable();\n };\n\n /**\n * Reset task\n * @method reset\n */\n self.reset = function () {\n trueAnswer.reset();\n falseAnswer.reset();\n self.enable();\n answer = undefined;\n };\n\n /**\n * Show the solution\n * @method showSolution\n * @return {[type]}\n */\n self.showSolution = function () {\n correctAnswer.markCorrect();\n wrongAnswer.unmark();\n };\n }\n\n // Inheritance\n AnswerGroup.prototype = Object.create(EventDispatcher.prototype);\n AnswerGroup.prototype.constructor = AnswerGroup;\n\n return AnswerGroup;\n})(H5P.jQuery, H5P.EventDispatcher);\n"
,"scripts/h5p-true-false-answer.js":"H5P.TrueFalse.Answer = (function ($, EventDispatcher) {\n \u0027use strict\u0027;\n\n var Keys = {\n ENTER: 13,\n SPACE: 32,\n LEFT_ARROW: 37,\n UP_ARROW: 38,\n RIGHT_ARROW: 39,\n DOWN_ARROW: 40\n };\n\n /**\n * Initialize module.\n *\n * @class H5P.TrueFalse.Answer\n * @extends H5P.EventDispatcher\n * @param {String} text Label\n * @param {String} correctMessage Message read by readspeaker when correct alternative is chosen\n * @param {String} wrongMessage Message read by readspeaker when wrong alternative is chosen\n */\n function Answer (text, correctMessage, wrongMessage) {\n var self = this;\n\n EventDispatcher.call(self);\n\n var checked = false;\n var enabled = true;\n\n var $answer = $(\u0027\u003cdiv\u003e\u0027, {\n \u0027class\u0027: \u0027h5p-true-false-answer\u0027,\n role: \u0027radio\u0027,\n \u0027aria-checked\u0027: false,\n html: text + \u0027\u003cspan class=\"aria-label\"\u003e\u003c/span\u003e\u0027,\n tabindex: 0, // Tabable by default\n click: function (event) {\n // Handle left mouse (or tap on touch devices)\n if (event.which === 1) {\n self.check();\n }\n },\n keydown: function (event) {\n if (!enabled) {\n return;\n }\n if ([Keys.SPACE, Keys.ENTER].indexOf(event.keyCode) !== -1) {\n self.check();\n }\n else if ([Keys.LEFT_ARROW, Keys.UP_ARROW, Keys.RIGHT_ARROW, Keys.DOWN_ARROW].indexOf(event.keyCode) !== -1) {\n self.uncheck();\n self.trigger(\u0027invert\u0027);\n }\n },\n focus: function () {\n self.trigger(\u0027focus\u0027);\n },\n blur: function () {\n self.trigger(\u0027blur\u0027);\n }\n });\n\n var $ariaLabel = $answer.find(\u0027.aria-label\u0027);\n\n // A bug in Chrome 54 makes the :after icons (V and X) not beeing rendered.\n // Doing this in a timeout solves this\n // Might be removed when Chrome 56 is out\n var chromeBugFixer = function (callback) {\n setTimeout(function () {\n callback();\n }, 0);\n };\n\n /**\n * Return the dom element representing the alternative\n *\n * @public\n * @method getDomElement\n * @return {H5P.jQuery}\n */\n self.getDomElement = function () {\n return $answer;\n };\n\n /**\n * Unchecks the alternative\n *\n * @public\n * @method uncheck\n * @return {H5P.TrueFalse.Answer}\n */\n self.uncheck = function () {\n if (enabled) {\n $answer.blur();\n checked = false;\n chromeBugFixer(function () {\n $answer.attr(\u0027aria-checked\u0027, checked);\n });\n }\n return self;\n };\n\n /**\n * Set tabable or not\n * @method tabable\n * @param {Boolean} enabled\n * @return {H5P.TrueFalse.Answer}\n */\n self.tabable = function (enabled) {\n $answer.attr(\u0027tabIndex\u0027, enabled ? 0 : null);\n return self;\n };\n\n /**\n * Checks the alternative\n *\n * @method check\n * @return {H5P.TrueFalse.Answer}\n */\n self.check = function () {\n if (enabled) {\n checked = true;\n chromeBugFixer(function () {\n $answer.attr(\u0027aria-checked\u0027, checked);\n });\n self.trigger(\u0027checked\u0027);\n $answer.focus();\n }\n return self;\n };\n\n /**\n * Is this alternative checked?\n *\n * @method isChecked\n * @return {boolean}\n */\n self.isChecked = function () {\n return checked;\n };\n\n /**\n * Enable alternative\n *\n * @method enable\n * @return {H5P.TrueFalse.Answer}\n */\n self.enable = function () {\n $answer.attr({\n \u0027aria-disabled\u0027: \u0027\u0027,\n tabIndex: 0\n });\n enabled = true;\n\n return self;\n };\n\n /**\n * Disables alternative\n *\n * @method disable\n * @return {H5P.TrueFalse.Answer}\n */\n self.disable = function () {\n $answer.attr({\n \u0027aria-disabled\u0027: true,\n tabIndex: null\n });\n enabled = false;\n\n return self;\n };\n\n /**\n * Reset alternative\n *\n * @method reset\n * @return {H5P.TrueFalse.Answer}\n */\n self.reset = function () {\n self.enable();\n self.uncheck();\n self.unmark();\n $ariaLabel.html(\u0027\u0027);\n\n return self;\n };\n\n /**\n * Marks this alternative as the wrong one\n *\n * @method markWrong\n * @return {H5P.TrueFalse.Answer}\n */\n self.markWrong = function () {\n chromeBugFixer(function () {\n $answer.addClass(\u0027wrong\u0027);\n });\n $ariaLabel.html(\u0027.\u0027 + wrongMessage);\n\n return self;\n };\n\n /**\n * Marks this alternative as the wrong one\n *\n * @method markCorrect\n * @return {H5P.TrueFalse.Answer}\n */\n self.markCorrect = function () {\n chromeBugFixer(function () {\n $answer.addClass(\u0027correct\u0027);\n });\n $ariaLabel.html(\u0027.\u0027 + correctMessage);\n\n return self;\n };\n\n self.unmark = function () {\n chromeBugFixer(function () {\n $answer.removeClass(\u0027wrong correct\u0027);\n });\n\n return self;\n };\n }\n\n // Inheritance\n Answer.prototype = Object.create(EventDispatcher.prototype);\n Answer.prototype.constructor = Answer;\n\n return Answer;\n\n})(H5P.jQuery, H5P.EventDispatcher);\n"
,"h5p-jquery-ui.js":"var oldJQuery = jQuery;\njQuery = H5P.jQuery;\n\n/*! jQuery UI - v1.10.2 - 2013-03-14\n* http://jqueryui.com\n* Includes: jquery.ui.core.js, jquery.ui.widget.js, jquery.ui.mouse.js, jquery.ui.draggable.js, jquery.ui.droppable.js, jquery.ui.resizable.js, jquery.ui.selectable.js, jquery.ui.sortable.js, jquery.ui.effect.js, jquery.ui.accordion.js, jquery.ui.autocomplete.js, jquery.ui.button.js, jquery.ui.datepicker.js, jquery.ui.dialog.js, jquery.ui.effect-blind.js, jquery.ui.effect-bounce.js, jquery.ui.effect-clip.js, jquery.ui.effect-drop.js, jquery.ui.effect-explode.js, jquery.ui.effect-fade.js, jquery.ui.effect-fold.js, jquery.ui.effect-highlight.js, jquery.ui.effect-pulsate.js, jquery.ui.effect-scale.js, jquery.ui.effect-shake.js, jquery.ui.effect-slide.js, jquery.ui.effect-transfer.js, jquery.ui.menu.js, jquery.ui.position.js, jquery.ui.progressbar.js, jquery.ui.slider.js, jquery.ui.spinner.js, jquery.ui.tabs.js, jquery.ui.tooltip.js\n* Copyright 2013 jQuery Foundation and other contributors; Licensed MIT */\n(function( $, undefined ) {\n\nvar uuid = 0,\n\truniqueId = /^ui-id-\\d+$/;\n\n// $.ui might exist from components with no dependencies, e.g., $.ui.position\n$.ui = $.ui || {};\n\n$.extend( $.ui, {\n\tversion: \"1.10.2\",\n\n\tkeyCode: {\n\t\tBACKSPACE: 8,\n\t\tCOMMA: 188,\n\t\tDELETE: 46,\n\t\tDOWN: 40,\n\t\tEND: 35,\n\t\tENTER: 13,\n\t\tESCAPE: 27,\n\t\tHOME: 36,\n\t\tLEFT: 37,\n\t\tNUMPAD_ADD: 107,\n\t\tNUMPAD_DECIMAL: 110,\n\t\tNUMPAD_DIVIDE: 111,\n\t\tNUMPAD_ENTER: 108,\n\t\tNUMPAD_MULTIPLY: 106,\n\t\tNUMPAD_SUBTRACT: 109,\n\t\tPAGE_DOWN: 34,\n\t\tPAGE_UP: 33,\n\t\tPERIOD: 190,\n\t\tRIGHT: 39,\n\t\tSPACE: 32,\n\t\tTAB: 9,\n\t\tUP: 38\n\t}\n});\n\n// plugins\n$.fn.extend({\n\tfocus: (function( orig ) {\n\t\treturn function( delay, fn ) {\n\t\t\treturn typeof delay === \"number\" ?\n\t\t\t\tthis.each(function() {\n\t\t\t\t\tvar elem = this;\n\t\t\t\t\tsetTimeout(function() {\n\t\t\t\t\t\t$( elem ).focus();\n\t\t\t\t\t\tif ( fn ) {\n\t\t\t\t\t\t\tfn.call( elem );\n\t\t\t\t\t\t}\n\t\t\t\t\t}, delay );\n\t\t\t\t}) :\n\t\t\t\torig.apply( this, arguments );\n\t\t};\n\t})( $.fn.focus ),\n\n\tscrollParent: function() {\n\t\tvar scrollParent;\n\t\tif (($.ui.ie \u0026\u0026 (/(static|relative)/).test(this.css(\"position\"))) || (/absolute/).test(this.css(\"position\"))) {\n\t\t\tscrollParent = this.parents().filter(function() {\n\t\t\t\treturn (/(relative|absolute|fixed)/).test($.css(this,\"position\")) \u0026\u0026 (/(auto|scroll)/).test($.css(this,\"overflow\")+$.css(this,\"overflow-y\")+$.css(this,\"overflow-x\"));\n\t\t\t}).eq(0);\n\t\t} else {\n\t\t\tscrollParent = this.parents().filter(function() {\n\t\t\t\treturn (/(auto|scroll)/).test($.css(this,\"overflow\")+$.css(this,\"overflow-y\")+$.css(this,\"overflow-x\"));\n\t\t\t}).eq(0);\n\t\t}\n\n\t\treturn (/fixed/).test(this.css(\"position\")) || !scrollParent.length ? $(document) : scrollParent;\n\t},\n\n\tzIndex: function( zIndex ) {\n\t\tif ( zIndex !== undefined ) {\n\t\t\treturn this.css( \"zIndex\", zIndex );\n\t\t}\n\n\t\tif ( this.length ) {\n\t\t\tvar elem = $( this[ 0 ] ), position, value;\n\t\t\twhile ( elem.length \u0026\u0026 elem[ 0 ] !== document ) {\n\t\t\t\t// Ignore z-index if position is set to a value where z-index is ignored by the browser\n\t\t\t\t// This makes behavior of this function consistent across browsers\n\t\t\t\t// WebKit always returns auto if the element is positioned\n\t\t\t\tposition = elem.css( \"position\" );\n\t\t\t\tif ( position === \"absolute\" || position === \"relative\" || position === \"fixed\" ) {\n\t\t\t\t\t// IE returns 0 when zIndex is not specified\n\t\t\t\t\t// other browsers return a string\n\t\t\t\t\t// we ignore the case of nested elements with an explicit value of 0\n\t\t\t\t\t// \u003cdiv style=\"z-index: -10;\"\u003e\u003cdiv style=\"z-index: 0;\"\u003e\u003c/div\u003e\u003c/div\u003e\n\t\t\t\t\tvalue = parseInt( elem.css( \"zIndex\" ), 10 );\n\t\t\t\t\tif ( !isNaN( value ) \u0026\u0026 value !== 0 ) {\n\t\t\t\t\t\treturn value;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\telem = elem.parent();\n\t\t\t}\n\t\t}\n\n\t\treturn 0;\n\t},\n\n\tuniqueId: function() {\n\t\treturn this.each(function() {\n\t\t\tif ( !this.id ) {\n\t\t\t\tthis.id = \"ui-id-\" + (++uuid);\n\t\t\t}\n\t\t});\n\t},\n\n\tremoveUniqueId: function() {\n\t\treturn this.each(function() {\n\t\t\tif ( runiqueId.test( this.id ) ) {\n\t\t\t\t$( this ).removeAttr( \"id\" );\n\t\t\t}\n\t\t});\n\t}\n});\n\n// selectors\nfunction focusable( element, isTabIndexNotNaN ) {\n\tvar map, mapName, img,\n\t\tnodeName = element.nodeName.toLowerCase();\n\tif ( \"area\" === nodeName ) {\n\t\tmap = element.parentNode;\n\t\tmapName = map.name;\n\t\tif ( !element.href || !mapName || map.nodeName.toLowerCase() !== \"map\" ) {\n\t\t\treturn false;\n\t\t}\n\t\timg = $( \"img[usemap=#\" + mapName + \"]\" )[0];\n\t\treturn !!img \u0026\u0026 visible( img );\n\t}\n\treturn ( /input|select|textarea|button|object/.test( nodeName ) ?\n\t\t!element.disabled :\n\t\t\"a\" === nodeName ?\n\t\t\telement.href || isTabIndexNotNaN :\n\t\t\tisTabIndexNotNaN) \u0026\u0026\n\t\t// the element and all of its ancestors must be visible\n\t\tvisible( element );\n}\n\nfunction visible( element ) {\n\treturn $.expr.filters.visible( element ) \u0026\u0026\n\t\t!$( element ).parents().addBack().filter(function() {\n\t\t\treturn $.css( this, \"visibility\" ) === \"hidden\";\n\t\t}).length;\n}\n\n$.extend( $.expr[ \":\" ], {\n\tdata: $.expr.createPseudo ?\n\t\t$.expr.createPseudo(function( dataName ) {\n\t\t\treturn function( elem ) {\n\t\t\t\treturn !!$.data( elem, dataName );\n\t\t\t};\n\t\t}) :\n\t\t// support: jQuery \u003c1.8\n\t\tfunction( elem, i, match ) {\n\t\t\treturn !!$.data( elem, match[ 3 ] );\n\t\t},\n\n\tfocusable: function( element ) {\n\t\treturn focusable( element, !isNaN( $.attr( element, \"tabindex\" ) ) );\n\t},\n\n\ttabbable: function( element ) {\n\t\tvar tabIndex = $.attr( element, \"tabindex\" ),\n\t\t\tisTabIndexNaN = isNaN( tabIndex );\n\t\treturn ( isTabIndexNaN || tabIndex \u003e= 0 ) \u0026\u0026 focusable( element, !isTabIndexNaN );\n\t}\n});\n\n// support: jQuery \u003c1.8\nif ( !$( \"\u003ca\u003e\" ).outerWidth( 1 ).jquery ) {\n\t$.each( [ \"Width\", \"Height\" ], function( i, name ) {\n\t\tvar side = name === \"Width\" ? [ \"Left\", \"Right\" ] : [ \"Top\", \"Bottom\" ],\n\t\t\ttype = name.toLowerCase(),\n\t\t\torig = {\n\t\t\t\tinnerWidth: $.fn.innerWidth,\n\t\t\t\tinnerHeight: $.fn.innerHeight,\n\t\t\t\touterWidth: $.fn.outerWidth,\n\t\t\t\touterHeight: $.fn.outerHeight\n\t\t\t};\n\n\t\tfunction reduce( elem, size, border, margin ) {\n\t\t\t$.each( side, function() {\n\t\t\t\tsize -= parseFloat( $.css( elem, \"padding\" + this ) ) || 0;\n\t\t\t\tif ( border ) {\n\t\t\t\t\tsize -= parseFloat( $.css( elem, \"border\" + this + \"Width\" ) ) || 0;\n\t\t\t\t}\n\t\t\t\tif ( margin ) {\n\t\t\t\t\tsize -= parseFloat( $.css( elem, \"margin\" + this ) ) || 0;\n\t\t\t\t}\n\t\t\t});\n\t\t\treturn size;\n\t\t}\n\n\t\t$.fn[ \"inner\" + name ] = function( size ) {\n\t\t\tif ( size === undefined ) {\n\t\t\t\treturn orig[ \"inner\" + name ].call( this );\n\t\t\t}\n\n\t\t\treturn this.each(function() {\n\t\t\t\t$( this ).css( type, reduce( this, size ) + \"px\" );\n\t\t\t});\n\t\t};\n\n\t\t$.fn[ \"outer\" + name] = function( size, margin ) {\n\t\t\tif ( typeof size !== \"number\" ) {\n\t\t\t\treturn orig[ \"outer\" + name ].call( this, size );\n\t\t\t}\n\n\t\t\treturn this.each(function() {\n\t\t\t\t$( this).css( type, reduce( this, size, true, margin ) + \"px\" );\n\t\t\t});\n\t\t};\n\t});\n}\n\n// support: jQuery \u003c1.8\nif ( !$.fn.addBack ) {\n\t$.fn.addBack = function( selector ) {\n\t\treturn this.add( selector == null ?\n\t\t\tthis.prevObject : this.prevObject.filter( selector )\n\t\t);\n\t};\n}\n\n// support: jQuery 1.6.1, 1.6.2 (http://bugs.jquery.com/ticket/9413)\nif ( $( \"\u003ca\u003e\" ).data( \"a-b\", \"a\" ).removeData( \"a-b\" ).data( \"a-b\" ) ) {\n\t$.fn.removeData = (function( removeData ) {\n\t\treturn function( key ) {\n\t\t\tif ( arguments.length ) {\n\t\t\t\treturn removeData.call( this, $.camelCase( key ) );\n\t\t\t} else {\n\t\t\t\treturn removeData.call( this );\n\t\t\t}\n\t\t};\n\t})( $.fn.removeData );\n}\n\n\n\n\n\n// deprecated\n$.ui.ie = !!/msie [\\w.]+/.exec( navigator.userAgent.toLowerCase() );\n\n$.support.selectstart = \"onselectstart\" in document.createElement( \"div\" );\n$.fn.extend({\n\tdisableSelection: function() {\n\t\treturn this.bind( ( $.support.selectstart ? \"selectstart\" : \"mousedown\" ) +\n\t\t\t\".ui-disableSelection\", function( event ) {\n\t\t\t\tevent.preventDefault();\n\t\t\t});\n\t},\n\n\tenableSelection: function() {\n\t\treturn this.unbind( \".ui-disableSelection\" );\n\t}\n});\n\n$.extend( $.ui, {\n\t// $.ui.plugin is deprecated. Use the proxy pattern instead.\n\tplugin: {\n\t\tadd: function( module, option, set ) {\n\t\t\tvar i,\n\t\t\t\tproto = $.ui[ module ].prototype;\n\t\t\tfor ( i in set ) {\n\t\t\t\tproto.plugins[ i ] = proto.plugins[ i ] || [];\n\t\t\t\tproto.plugins[ i ].push( [ option, set[ i ] ] );\n\t\t\t}\n\t\t},\n\t\tcall: function( instance, name, args ) {\n\t\t\tvar i,\n\t\t\t\tset = instance.plugins[ name ];\n\t\t\tif ( !set || !instance.element[ 0 ].parentNode || instance.element[ 0 ].parentNode.nodeType === 11 ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tfor ( i = 0; i \u003c set.length; i++ ) {\n\t\t\t\tif ( instance.options[ set[ i ][ 0 ] ] ) {\n\t\t\t\t\tset[ i ][ 1 ].apply( instance.element, args );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t},\n\n\t// only used by resizable\n\thasScroll: function( el, a ) {\n\n\t\t//If overflow is hidden, the element might have extra content, but the user wants to hide it\n\t\tif ( $( el ).css( \"overflow\" ) === \"hidden\") {\n\t\t\treturn false;\n\t\t}\n\n\t\tvar scroll = ( a \u0026\u0026 a === \"left\" ) ? \"scrollLeft\" : \"scrollTop\",\n\t\t\thas = false;\n\n\t\tif ( el[ scroll ] \u003e 0 ) {\n\t\t\treturn true;\n\t\t}\n\n\t\t// TODO: determine which cases actually cause this to happen\n\t\t// if the element doesn\u0027t have the scroll set, see if it\u0027s possible to\n\t\t// set the scroll\n\t\tel[ scroll ] = 1;\n\t\thas = ( el[ scroll ] \u003e 0 );\n\t\tel[ scroll ] = 0;\n\t\treturn has;\n\t}\n});\n\n})( jQuery );\n\n(function( $, undefined ) {\n\nvar uuid = 0,\n\tslice = Array.prototype.slice,\n\t_cleanData = $.cleanData;\n$.cleanData = function( elems ) {\n\tfor ( var i = 0, elem; (elem = elems[i]) != null; i++ ) {\n\t\ttry {\n\t\t\t$( elem ).triggerHandler( \"remove\" );\n\t\t// http://bugs.jquery.com/ticket/8235\n\t\t} catch( e ) {}\n\t}\n\t_cleanData( elems );\n};\n\n$.widget = function( name, base, prototype ) {\n\tvar fullName, existingConstructor, constructor, basePrototype,\n\t\t// proxiedPrototype allows the provided prototype to remain unmodified\n\t\t// so that it can be used as a mixin for multiple widgets (#8876)\n\t\tproxiedPrototype = {},\n\t\tnamespace = name.split( \".\" )[ 0 ];\n\n\tname = name.split( \".\" )[ 1 ];\n\tfullName = namespace + \"-\" + name;\n\n\tif ( !prototype ) {\n\t\tprototype = base;\n\t\tbase = $.Widget;\n\t}\n\n\t// create selector for plugin\n\t$.expr[ \":\" ][ fullName.toLowerCase() ] = function( elem ) {\n\t\treturn !!$.data( elem, fullName );\n\t};\n\n\t$[ namespace ] = $[ namespace ] || {};\n\texistingConstructor = $[ namespace ][ name ];\n\tconstructor = $[ namespace ][ name ] = function( options, element ) {\n\t\t// allow instantiation without \"new\" keyword\n\t\tif ( !this._createWidget ) {\n\t\t\treturn new constructor( options, element );\n\t\t}\n\n\t\t// allow instantiation without initializing for simple inheritance\n\t\t// must use \"new\" keyword (the code above always passes args)\n\t\tif ( arguments.length ) {\n\t\t\tthis._createWidget( options, element );\n\t\t}\n\t};\n\t// extend with the existing constructor to carry over any static properties\n\t$.extend( constructor, existingConstructor, {\n\t\tversion: prototype.version,\n\t\t// copy the object used to create the prototype in case we need to\n\t\t// redefine the widget later\n\t\t_proto: $.extend( {}, prototype ),\n\t\t// track widgets that inherit from this widget in case this widget is\n\t\t// redefined after a widget inherits from it\n\t\t_childConstructors: []\n\t});\n\n\tbasePrototype = new base();\n\t// we need to make the options hash a property directly on the new instance\n\t// otherwise we\u0027ll modify the options hash on the prototype that we\u0027re\n\t// inheriting from\n\tbasePrototype.options = $.widget.extend( {}, basePrototype.options );\n\t$.each( prototype, function( prop, value ) {\n\t\tif ( !$.isFunction( value ) ) {\n\t\t\tproxiedPrototype[ prop ] = value;\n\t\t\treturn;\n\t\t}\n\t\tproxiedPrototype[ prop ] = (function() {\n\t\t\tvar _super = function() {\n\t\t\t\t\treturn base.prototype[ prop ].apply( this, arguments );\n\t\t\t\t},\n\t\t\t\t_superApply = function( args ) {\n\t\t\t\t\treturn base.prototype[ prop ].apply( this, args );\n\t\t\t\t};\n\t\t\treturn function() {\n\t\t\t\tvar __super = this._super,\n\t\t\t\t\t__superApply = this._superApply,\n\t\t\t\t\treturnValue;\n\n\t\t\t\tthis._super = _super;\n\t\t\t\tthis._superApply = _superApply;\n\n\t\t\t\treturnValue = value.apply( this, arguments );\n\n\t\t\t\tthis._super = __super;\n\t\t\t\tthis._superApply = __superApply;\n\n\t\t\t\treturn returnValue;\n\t\t\t};\n\t\t})();\n\t});\n\tconstructor.prototype = $.widget.extend( basePrototype, {\n\t\t// TODO: remove support for widgetEventPrefix\n\t\t// always use the name + a colon as the prefix, e.g., draggable:start\n\t\t// don\u0027t prefix for widgets that aren\u0027t DOM-based\n\t\twidgetEventPrefix: existingConstructor ? basePrototype.widgetEventPrefix : name\n\t}, proxiedPrototype, {\n\t\tconstructor: constructor,\n\t\tnamespace: namespace,\n\t\twidgetName: name,\n\t\twidgetFullName: fullName\n\t});\n\n\t// If this widget is being redefined then we need to find all widgets that\n\t// are inheriting from it and redefine all of them so that they inherit from\n\t// the new version of this widget. We\u0027re essentially trying to replace one\n\t// level in the prototype chain.\n\tif ( existingConstructor ) {\n\t\t$.each( existingConstructor._childConstructors, function( i, child ) {\n\t\t\tvar childPrototype = child.prototype;\n\n\t\t\t// redefine the child widget using the same prototype that was\n\t\t\t// originally used, but inherit from the new version of the base\n\t\t\t$.widget( childPrototype.namespace + \".\" + childPrototype.widgetName, constructor, child._proto );\n\t\t});\n\t\t// remove the list of existing child constructors from the old constructor\n\t\t// so the old child constructors can be garbage collected\n\t\tdelete existingConstructor._childConstructors;\n\t} else {\n\t\tbase._childConstructors.push( constructor );\n\t}\n\n\t$.widget.bridge( name, constructor );\n};\n\n$.widget.extend = function( target ) {\n\tvar input = slice.call( arguments, 1 ),\n\t\tinputIndex = 0,\n\t\tinputLength = input.length,\n\t\tkey,\n\t\tvalue;\n\tfor ( ; inputIndex \u003c inputLength; inputIndex++ ) {\n\t\tfor ( key in input[ inputIndex ] ) {\n\t\t\tvalue = input[ inputIndex ][ key ];\n\t\t\tif ( input[ inputIndex ].hasOwnProperty( key ) \u0026\u0026 value !== undefined ) {\n\t\t\t\t// Clone objects\n\t\t\t\tif ( $.isPlainObject( value ) ) {\n\t\t\t\t\ttarget[ key ] = $.isPlainObject( target[ key ] ) ?\n\t\t\t\t\t\t$.widget.extend( {}, target[ key ], value ) :\n\t\t\t\t\t\t// Don\u0027t extend strings, arrays, etc. with objects\n\t\t\t\t\t\t$.widget.extend( {}, value );\n\t\t\t\t// Copy everything else by reference\n\t\t\t\t} else {\n\t\t\t\t\ttarget[ key ] = value;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\treturn target;\n};\n\n$.widget.bridge = function( name, object ) {\n\tvar fullName = object.prototype.widgetFullName || name;\n\t$.fn[ name ] = function( options ) {\n\t\tvar isMethodCall = typeof options === \"string\",\n\t\t\targs = slice.call( arguments, 1 ),\n\t\t\treturnValue = this;\n\n\t\t// allow multiple hashes to be passed on init\n\t\toptions = !isMethodCall \u0026\u0026 args.length ?\n\t\t\t$.widget.extend.apply( null, [ options ].concat(args) ) :\n\t\t\toptions;\n\n\t\tif ( isMethodCall ) {\n\t\t\tthis.each(function() {\n\t\t\t\tvar methodValue,\n\t\t\t\t\tinstance = $.data( this, fullName );\n\t\t\t\tif ( !instance ) {\n\t\t\t\t\treturn $.error( \"cannot call methods on \" + name + \" prior to initialization; \" +\n\t\t\t\t\t\t\"attempted to call method \u0027\" + options + \"\u0027\" );\n\t\t\t\t}\n\t\t\t\tif ( !$.isFunction( instance[options] ) || options.charAt( 0 ) === \"_\" ) {\n\t\t\t\t\treturn $.error( \"no such method \u0027\" + options + \"\u0027 for \" + name + \" widget instance\" );\n\t\t\t\t}\n\t\t\t\tmethodValue = instance[ options ].apply( instance, args );\n\t\t\t\tif ( methodValue !== instance \u0026\u0026 methodValue !== undefined ) {\n\t\t\t\t\treturnValue = methodValue \u0026\u0026 methodValue.jquery ?\n\t\t\t\t\t\treturnValue.pushStack( methodValue.get() ) :\n\t\t\t\t\t\tmethodValue;\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t});\n\t\t} else {\n\t\t\tthis.each(function() {\n\t\t\t\tvar instance = $.data( this, fullName );\n\t\t\t\tif ( instance ) {\n\t\t\t\t\tinstance.option( options || {} )._init();\n\t\t\t\t} else {\n\t\t\t\t\t$.data( this, fullName, new object( options, this ) );\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\n\t\treturn returnValue;\n\t};\n};\n\n$.Widget = function( /* options, element */ ) {};\n$.Widget._childConstructors = [];\n\n$.Widget.prototype = {\n\twidgetName: \"widget\",\n\twidgetEventPrefix: \"\",\n\tdefaultElement: \"\u003cdiv\u003e\",\n\toptions: {\n\t\tdisabled: false,\n\n\t\t// callbacks\n\t\tcreate: null\n\t},\n\t_createWidget: function( options, element ) {\n\t\telement = $( element || this.defaultElement || this )[ 0 ];\n\t\tthis.element = $( element );\n\t\tthis.uuid = uuid++;\n\t\tthis.eventNamespace = \".\" + this.widgetName + this.uuid;\n\t\tthis.options = $.widget.extend( {},\n\t\t\tthis.options,\n\t\t\tthis._getCreateOptions(),\n\t\t\toptions );\n\n\t\tthis.bindings = $();\n\t\tthis.hoverable = $();\n\t\tthis.focusable = $();\n\n\t\tif ( element !== this ) {\n\t\t\t$.data( element, this.widgetFullName, this );\n\t\t\tthis._on( true, this.element, {\n\t\t\t\tremove: function( event ) {\n\t\t\t\t\tif ( event.target === element ) {\n\t\t\t\t\t\tthis.destroy();\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t});\n\t\t\tthis.document = $( element.style ?\n\t\t\t\t// element within the document\n\t\t\t\telement.ownerDocument :\n\t\t\t\t// element is window or document\n\t\t\t\telement.document || element );\n\t\t\tthis.window = $( this.document[0].defaultView || this.document[0].parentWindow );\n\t\t}\n\n\t\tthis._create();\n\t\tthis._trigger( \"create\", null, this._getCreateEventData() );\n\t\tthis._init();\n\t},\n\t_getCreateOptions: $.noop,\n\t_getCreateEventData: $.noop,\n\t_create: $.noop,\n\t_init: $.noop,\n\n\tdestroy: function() {\n\t\tthis._destroy();\n\t\t// we can probably remove the unbind calls in 2.0\n\t\t// all event bindings should go through this._on()\n\t\tthis.element\n\t\t\t.unbind( this.eventNamespace )\n\t\t\t// 1.9 BC for #7810\n\t\t\t// TODO remove dual storage\n\t\t\t.removeData( this.widgetName )\n\t\t\t.removeData( this.widgetFullName )\n\t\t\t// support: jquery \u003c1.6.3\n\t\t\t// http://bugs.jquery.com/ticket/9413\n\t\t\t.removeData( $.camelCase( this.widgetFullName ) );\n\t\tthis.widget()\n\t\t\t.unbind( this.eventNamespace )\n\t\t\t.removeAttr( \"aria-disabled\" )\n\t\t\t.removeClass(\n\t\t\t\tthis.widgetFullName + \"-disabled \" +\n\t\t\t\t\"ui-state-disabled\" );\n\n\t\t// clean up events and states\n\t\tthis.bindings.unbind( this.eventNamespace );\n\t\tthis.hoverable.removeClass( \"ui-state-hover\" );\n\t\tthis.focusable.removeClass( \"ui-state-focus\" );\n\t},\n\t_destroy: $.noop,\n\n\twidget: function() {\n\t\treturn this.element;\n\t},\n\n\toption: function( key, value ) {\n\t\tvar options = key,\n\t\t\tparts,\n\t\t\tcurOption,\n\t\t\ti;\n\n\t\tif ( arguments.length === 0 ) {\n\t\t\t// don\u0027t return a reference to the internal hash\n\t\t\treturn $.widget.extend( {}, this.options );\n\t\t}\n\n\t\tif ( typeof key === \"string\" ) {\n\t\t\t// handle nested keys, e.g., \"foo.bar\" =\u003e { foo: { bar: ___ } }\n\t\t\toptions = {};\n\t\t\tparts = key.split( \".\" );\n\t\t\tkey = parts.shift();\n\t\t\tif ( parts.length ) {\n\t\t\t\tcurOption = options[ key ] = $.widget.extend( {}, this.options[ key ] );\n\t\t\t\tfor ( i = 0; i \u003c parts.length - 1; i++ ) {\n\t\t\t\t\tcurOption[ parts[ i ] ] = curOption[ parts[ i ] ] || {};\n\t\t\t\t\tcurOption = curOption[ parts[ i ] ];\n\t\t\t\t}\n\t\t\t\tkey = parts.pop();\n\t\t\t\tif ( value === undefined ) {\n\t\t\t\t\treturn curOption[ key ] === undefined ? null : curOption[ key ];\n\t\t\t\t}\n\t\t\t\tcurOption[ key ] = value;\n\t\t\t} else {\n\t\t\t\tif ( value === undefined ) {\n\t\t\t\t\treturn this.options[ key ] === undefined ? null : this.options[ key ];\n\t\t\t\t}\n\t\t\t\toptions[ key ] = value;\n\t\t\t}\n\t\t}\n\n\t\tthis._setOptions( options );\n\n\t\treturn this;\n\t},\n\t_setOptions: function( options ) {\n\t\tvar key;\n\n\t\tfor ( key in options ) {\n\t\t\tthis._setOption( key, options[ key ] );\n\t\t}\n\n\t\treturn this;\n\t},\n\t_setOption: function( key, value ) {\n\t\tthis.options[ key ] = value;\n\n\t\tif ( key === \"disabled\" ) {\n\t\t\tthis.widget()\n\t\t\t\t.toggleClass( this.widgetFullName + \"-disabled ui-state-disabled\", !!value )\n\t\t\t\t.attr( \"aria-disabled\", value );\n\t\t\tthis.hoverable.removeClass( \"ui-state-hover\" );\n\t\t\tthis.focusable.removeClass( \"ui-state-focus\" );\n\t\t}\n\n\t\treturn this;\n\t},\n\n\tenable: function() {\n\t\treturn this._setOption( \"disabled\", false );\n\t},\n\tdisable: function() {\n\t\treturn this._setOption( \"disabled\", true );\n\t},\n\n\t_on: function( suppressDisabledCheck, element, handlers ) {\n\t\tvar delegateElement,\n\t\t\tinstance = this;\n\n\t\t// no suppressDisabledCheck flag, shuffle arguments\n\t\tif ( typeof suppressDisabledCheck !== \"boolean\" ) {\n\t\t\thandlers = element;\n\t\t\telement = suppressDisabledCheck;\n\t\t\tsuppressDisabledCheck = false;\n\t\t}\n\n\t\t// no element argument, shuffle and use this.element\n\t\tif ( !handlers ) {\n\t\t\thandlers = element;\n\t\t\telement = this.element;\n\t\t\tdelegateElement = this.widget();\n\t\t} else {\n\t\t\t// accept selectors, DOM elements\n\t\t\telement = delegateElement = $( element );\n\t\t\tthis.bindings = this.bindings.add( element );\n\t\t}\n\n\t\t$.each( handlers, function( event, handler ) {\n\t\t\tfunction handlerProxy() {\n\t\t\t\t// allow widgets to customize the disabled handling\n\t\t\t\t// - disabled as an array instead of boolean\n\t\t\t\t// - disabled class as method for disabling individual parts\n\t\t\t\tif ( !suppressDisabledCheck \u0026\u0026\n\t\t\t\t\t\t( instance.options.disabled === true ||\n\t\t\t\t\t\t\t$( this ).hasClass( \"ui-state-disabled\" ) ) ) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\treturn ( typeof handler === \"string\" ? instance[ handler ] : handler )\n\t\t\t\t\t.apply( instance, arguments );\n\t\t\t}\n\n\t\t\t// copy the guid so direct unbinding works\n\t\t\tif ( typeof handler !== \"string\" ) {\n\t\t\t\thandlerProxy.guid = handler.guid =\n\t\t\t\t\thandler.guid || handlerProxy.guid || $.guid++;\n\t\t\t}\n\n\t\t\tvar match = event.match( /^(\\w+)\\s*(.*)$/ ),\n\t\t\t\teventName = match[1] + instance.eventNamespace,\n\t\t\t\tselector = match[2];\n\t\t\tif ( selector ) {\n\t\t\t\tdelegateElement.delegate( selector, eventName, handlerProxy );\n\t\t\t} else {\n\t\t\t\telement.bind( eventName, handlerProxy );\n\t\t\t}\n\t\t});\n\t},\n\n\t_off: function( element, eventName ) {\n\t\teventName = (eventName || \"\").split( \" \" ).join( this.eventNamespace + \" \" ) + this.eventNamespace;\n\t\telement.unbind( eventName ).undelegate( eventName );\n\t},\n\n\t_delay: function( handler, delay ) {\n\t\tfunction handlerProxy() {\n\t\t\treturn ( typeof handler === \"string\" ? instance[ handler ] : handler )\n\t\t\t\t.apply( instance, arguments );\n\t\t}\n\t\tvar instance = this;\n\t\treturn setTimeout( handlerProxy, delay || 0 );\n\t},\n\n\t_hoverable: function( element ) {\n\t\tthis.hoverable = this.hoverable.add( element );\n\t\tthis._on( element, {\n\t\t\tmouseenter: function( event ) {\n\t\t\t\t$( event.currentTarget ).addClass( \"ui-state-hover\" );\n\t\t\t},\n\t\t\tmouseleave: function( event ) {\n\t\t\t\t$( event.currentTarget ).removeClass( \"ui-state-hover\" );\n\t\t\t}\n\t\t});\n\t},\n\n\t_focusable: function( element ) {\n\t\tthis.focusable = this.focusable.add( element );\n\t\tthis._on( element, {\n\t\t\tfocusin: function( event ) {\n\t\t\t\t$( event.currentTarget ).addClass( \"ui-state-focus\" );\n\t\t\t},\n\t\t\tfocusout: function( event ) {\n\t\t\t\t$( event.currentTarget ).removeClass( \"ui-state-focus\" );\n\t\t\t}\n\t\t});\n\t},\n\n\t_trigger: function( type, event, data ) {\n\t\tvar prop, orig,\n\t\t\tcallback = this.options[ type ];\n\n\t\tdata = data || {};\n\t\tevent = $.Event( event );\n\t\tevent.type = ( type === this.widgetEventPrefix ?\n\t\t\ttype :\n\t\t\tthis.widgetEventPrefix + type ).toLowerCase();\n\t\t// the original event may come from any element\n\t\t// so we need to reset the target on the new event\n\t\tevent.target = this.element[ 0 ];\n\n\t\t// copy original event properties over to the new event\n\t\torig = event.originalEvent;\n\t\tif ( orig ) {\n\t\t\tfor ( prop in orig ) {\n\t\t\t\tif ( !( prop in event ) ) {\n\t\t\t\t\tevent[ prop ] = orig[ prop ];\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tthis.element.trigger( event, data );\n\t\treturn !( $.isFunction( callback ) \u0026\u0026\n\t\t\tcallback.apply( this.element[0], [ event ].concat( data ) ) === false ||\n\t\t\tevent.isDefaultPrevented() );\n\t}\n};\n\n$.each( { show: \"fadeIn\", hide: \"fadeOut\" }, function( method, defaultEffect ) {\n\t$.Widget.prototype[ \"_\" + method ] = function( element, options, callback ) {\n\t\tif ( typeof options === \"string\" ) {\n\t\t\toptions = { effect: options };\n\t\t}\n\t\tvar hasOptions,\n\t\t\teffectName = !options ?\n\t\t\t\tmethod :\n\t\t\t\toptions === true || typeof options === \"number\" ?\n\t\t\t\t\tdefaultEffect :\n\t\t\t\t\toptions.effect || defaultEffect;\n\t\toptions = options || {};\n\t\tif ( typeof options === \"number\" ) {\n\t\t\toptions = { duration: options };\n\t\t}\n\t\thasOptions = !$.isEmptyObject( options );\n\t\toptions.complete = callback;\n\t\tif ( options.delay ) {\n\t\t\telement.delay( options.delay );\n\t\t}\n\t\tif ( hasOptions \u0026\u0026 $.effects \u0026\u0026 $.effects.effect[ effectName ] ) {\n\t\t\telement[ method ]( options );\n\t\t} else if ( effectName !== method \u0026\u0026 element[ effectName ] ) {\n\t\t\telement[ effectName ]( options.duration, options.easing, callback );\n\t\t} else {\n\t\t\telement.queue(function( next ) {\n\t\t\t\t$( this )[ method ]();\n\t\t\t\tif ( callback ) {\n\t\t\t\t\tcallback.call( element[ 0 ] );\n\t\t\t\t}\n\t\t\t\tnext();\n\t\t\t});\n\t\t}\n\t};\n});\n\n})( jQuery );\n\n(function( $, undefined ) {\n\nvar mouseHandled = false;\n$( document ).mouseup( function() {\n\tmouseHandled = false;\n});\n\n$.widget(\"ui.mouse\", {\n\tversion: \"1.10.2\",\n\toptions: {\n\t\tcancel: \"input,textarea,button,select,option\",\n\t\tdistance: 1,\n\t\tdelay: 0\n\t},\n\t_mouseInit: function() {\n\t\tvar that = this;\n\n\t\tthis.element\n\t\t\t.bind(\"mousedown.\"+this.widgetName, function(event) {\n\t\t\t\treturn that._mouseDown(event);\n\t\t\t})\n\t\t\t.bind(\"click.\"+this.widgetName, function(event) {\n\t\t\t\tif (true === $.data(event.target, that.widgetName + \".preventClickEvent\")) {\n\t\t\t\t\t$.removeData(event.target, that.widgetName + \".preventClickEvent\");\n\t\t\t\t\tevent.stopImmediatePropagation();\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t});\n\n\t\tthis.started = false;\n\t},\n\n\t// TODO: make sure destroying one instance of mouse doesn\u0027t mess with\n\t// other instances of mouse\n\t_mouseDestroy: function() {\n\t\tthis.element.unbind(\".\"+this.widgetName);\n\t\tif ( this._mouseMoveDelegate ) {\n\t\t\t$(document)\n\t\t\t\t.unbind(\"mousemove.\"+this.widgetName, this._mouseMoveDelegate)\n\t\t\t\t.unbind(\"mouseup.\"+this.widgetName, this._mouseUpDelegate);\n\t\t}\n\t},\n\n\t_mouseDown: function(event) {\n\t\t// don\u0027t let more than one widget handle mouseStart\n\t\tif( mouseHandled ) { return; }\n\n\t\t// we may have missed mouseup (out of window)\n\t\t(this._mouseStarted \u0026\u0026 this._mouseUp(event));\n\n\t\tthis._mouseDownEvent = event;\n\n\t\tvar that = this,\n\t\t\tbtnIsLeft = (event.which === 1),\n\t\t\t// event.target.nodeName works around a bug in IE 8 with\n\t\t\t// disabled inputs (#7620)\n\t\t\telIsCancel = (typeof this.options.cancel === \"string\" \u0026\u0026 event.target.nodeName ? $(event.target).closest(this.options.cancel).length : false);\n\t\tif (!btnIsLeft || elIsCancel || !this._mouseCapture(event)) {\n\t\t\treturn true;\n\t\t}\n\n\t\tthis.mouseDelayMet = !this.options.delay;\n\t\tif (!this.mouseDelayMet) {\n\t\t\tthis._mouseDelayTimer = setTimeout(function() {\n\t\t\t\tthat.mouseDelayMet = true;\n\t\t\t}, this.options.delay);\n\t\t}\n\n\t\tif (this._mouseDistanceMet(event) \u0026\u0026 this._mouseDelayMet(event)) {\n\t\t\tthis._mouseStarted = (this._mouseStart(event) !== false);\n\t\t\tif (!this._mouseStarted) {\n\t\t\t\tevent.preventDefault();\n\t\t\t\treturn true;\n\t\t\t}\n\t\t}\n\n\t\t// Click event may never have fired (Gecko \u0026 Opera)\n\t\tif (true === $.data(event.target, this.widgetName + \".preventClickEvent\")) {\n\t\t\t$.removeData(event.target, this.widgetName + \".preventClickEvent\");\n\t\t}\n\n\t\t// these delegates are required to keep context\n\t\tthis._mouseMoveDelegate = function(event) {\n\t\t\treturn that._mouseMove(event);\n\t\t};\n\t\tthis._mouseUpDelegate = function(event) {\n\t\t\treturn that._mouseUp(event);\n\t\t};\n\t\t$(document)\n\t\t\t.bind(\"mousemove.\"+this.widgetName, this._mouseMoveDelegate)\n\t\t\t.bind(\"mouseup.\"+this.widgetName, this._mouseUpDelegate);\n\n\t\tif (this.widgetName === \u0027slider\u0027) {\n\t\t\t// Prevent tragging of slider handle(anchor) in Firefox\n\t\t\tevent.preventDefault();\n\t\t}\n\n\t\tmouseHandled = true;\n\t\treturn true;\n\t},\n\n\t_mouseMove: function(event) {\n\t\t// IE mouseup check - mouseup happened when mouse was out of window\n\t\tif ($.ui.ie \u0026\u0026 ( !document.documentMode || document.documentMode \u003c 9 ) \u0026\u0026 !event.button) {\n\t\t\treturn this._mouseUp(event);\n\t\t}\n\n\t\tif (this._mouseStarted) {\n\t\t\tthis._mouseDrag(event);\n\t\t\treturn event.preventDefault();\n\t\t}\n\n\t\tif (this._mouseDistanceMet(event) \u0026\u0026 this._mouseDelayMet(event)) {\n\t\t\tthis._mouseStarted =\n\t\t\t\t(this._mouseStart(this._mouseDownEvent, event) !== false);\n\t\t\t(this._mouseStarted ? this._mouseDrag(event) : this._mouseUp(event));\n\t\t}\n\n\t\treturn !this._mouseStarted;\n\t},\n\n\t_mouseUp: function(event) {\n\t\t$(document)\n\t\t\t.unbind(\"mousemove.\"+this.widgetName, this._mouseMoveDelegate)\n\t\t\t.unbind(\"mouseup.\"+this.widgetName, this._mouseUpDelegate);\n\n\t\tif (this._mouseStarted) {\n\t\t\tthis._mouseStarted = false;\n\n\t\t\tif (event.target === this._mouseDownEvent.target) {\n\t\t\t\t$.data(event.target, this.widgetName + \".preventClickEvent\", true);\n\t\t\t}\n\n\t\t\tthis._mouseStop(event);\n\t\t}\n\n\t\treturn false;\n\t},\n\n\t_mouseDistanceMet: function(event) {\n\t\treturn (Math.max(\n\t\t\t\tMath.abs(this._mouseDownEvent.pageX - event.pageX),\n\t\t\t\tMath.abs(this._mouseDownEvent.pageY - event.pageY)\n\t\t\t) \u003e= this.options.distance\n\t\t);\n\t},\n\n\t_mouseDelayMet: function(/* event */) {\n\t\treturn this.mouseDelayMet;\n\t},\n\n\t// These are placeholder methods, to be overriden by extending plugin\n\t_mouseStart: function(/* event */) {},\n\t_mouseDrag: function(/* event */) {},\n\t_mouseStop: function(/* event */) {},\n\t_mouseCapture: function(/* event */) { return true; }\n});\n\n})(jQuery);\n\n(function( $, undefined ) {\n\n$.widget(\"ui.draggable\", $.ui.mouse, {\n\tversion: \"1.10.2\",\n\twidgetEventPrefix: \"drag\",\n\toptions: {\n\t\taddClasses: true,\n\t\tappendTo: \"parent\",\n\t\taxis: false,\n\t\tconnectToSortable: false,\n\t\tcontainment: false,\n\t\tcursor: \"auto\",\n\t\tcursorAt: false,\n\t\tgrid: false,\n\t\thandle: false,\n\t\thelper: \"original\",\n\t\tiframeFix: false,\n\t\topacity: false,\n\t\trefreshPositions: false,\n\t\trevert: false,\n\t\trevertDuration: 500,\n\t\tscope: \"default\",\n\t\tscroll: true,\n\t\tscrollSensitivity: 20,\n\t\tscrollSpeed: 20,\n\t\tsnap: false,\n\t\tsnapMode: \"both\",\n\t\tsnapTolerance: 20,\n\t\tstack: false,\n\t\tzIndex: false,\n\n\t\t// callbacks\n\t\tdrag: null,\n\t\tstart: null,\n\t\tstop: null\n\t},\n\t_create: function() {\n\n\t\tif (this.options.helper === \"original\" \u0026\u0026 !(/^(?:r|a|f)/).test(this.element.css(\"position\"))) {\n\t\t\tthis.element[0].style.position = \"relative\";\n\t\t}\n\t\tif (this.options.addClasses){\n\t\t\tthis.element.addClass(\"ui-draggable\");\n\t\t}\n\t\tif (this.options.disabled){\n\t\t\tthis.element.addClass(\"ui-draggable-disabled\");\n\t\t}\n this.element[0].style.msTouchAction = this.element[0].style.touchAction = \u0027none\u0027;\n\n\t\tthis._mouseInit();\n\n\t},\n\n\t_destroy: function() {\n\t\tthis.element.removeClass( \"ui-draggable ui-draggable-dragging ui-draggable-disabled\" );\n\t\tthis._mouseDestroy();\n\t},\n\n\t_mouseCapture: function(event) {\n\n\t\tvar o = this.options;\n\n\t\t// among others, prevent a drag on a resizable-handle\n\t\tif (this.helper || o.disabled || $(event.target).closest(\".ui-resizable-handle\").length \u003e 0) {\n\t\t\treturn false;\n\t\t}\n\n\t\t//Quit if we\u0027re not on a valid handle\n\t\tthis.handle = this._getHandle(event);\n\t\tif (!this.handle) {\n\t\t\treturn false;\n\t\t}\n\n\t\t$(o.iframeFix === true ? \"iframe\" : o.iframeFix).each(function() {\n\t\t\t$(\"\u003cdiv class=\u0027ui-draggable-iframeFix\u0027 style=\u0027background: #fff;\u0027\u003e\u003c/div\u003e\")\n\t\t\t.css({\n\t\t\t\twidth: this.offsetWidth+\"px\", height: this.offsetHeight+\"px\",\n\t\t\t\tposition: \"absolute\", opacity: \"0.001\", zIndex: 1000\n\t\t\t})\n\t\t\t.css($(this).offset())\n\t\t\t.appendTo(\"body\");\n\t\t});\n\n\t\treturn true;\n\n\t},\n\n\t_mouseStart: function(event) {\n\n\t\tvar o = this.options;\n\n\t\t//Create and append the visible helper\n\t\tthis.helper = this._createHelper(event);\n\n\t\tthis.helper.addClass(\"ui-draggable-dragging\");\n\n\t\t//Cache the helper size\n\t\tthis._cacheHelperProportions();\n\n\t\t//If ddmanager is used for droppables, set the global draggable\n\t\tif($.ui.ddmanager) {\n\t\t\t$.ui.ddmanager.current = this;\n\t\t}\n\n\t\t/*\n\t\t * - Position generation -\n\t\t * This block generates everything position related - it\u0027s the core of draggables.\n\t\t */\n\n\t\t//Cache the margins of the original element\n\t\tthis._cacheMargins();\n\n\t\t//Store the helper\u0027s css position\n\t\tthis.cssPosition = this.helper.css(\"position\");\n\t\tthis.scrollParent = this.helper.scrollParent();\n\n\t\t//The element\u0027s absolute position on the page minus margins\n\t\tthis.offset = this.positionAbs = this.element.offset();\n\t\tthis.offset = {\n\t\t\ttop: this.offset.top - this.margins.top,\n\t\t\tleft: this.offset.left - this.margins.left\n\t\t};\n\n\t\t$.extend(this.offset, {\n\t\t\tclick: { //Where the click happened, relative to the element\n\t\t\t\tleft: event.pageX - this.offset.left,\n\t\t\t\ttop: event.pageY - this.offset.top\n\t\t\t},\n\t\t\tparent: this._getParentOffset(),\n\t\t\trelative: this._getRelativeOffset() //This is a relative to absolute position minus the actual position calculation - only used for relative positioned helper\n\t\t});\n\n\t\t//Generate the original position\n\t\tthis.originalPosition = this.position = this._generatePosition(event);\n\t\tthis.originalPageX = event.pageX;\n\t\tthis.originalPageY = event.pageY;\n\n\t\t//Adjust the mouse offset relative to the helper if \"cursorAt\" is supplied\n\t\t(o.cursorAt \u0026\u0026 this._adjustOffsetFromHelper(o.cursorAt));\n\n\t\t//Set a containment if given in the options\n\t\tif(o.containment) {\n\t\t\tthis._setContainment();\n\t\t}\n\n\t\t//Trigger event + callbacks\n\t\tif(this._trigger(\"start\", event) === false) {\n\t\t\tthis._clear();\n\t\t\treturn false;\n\t\t}\n\n\t\t//Recache the helper size\n\t\tthis._cacheHelperProportions();\n\n\t\t//Prepare the droppable offsets\n\t\tif ($.ui.ddmanager \u0026\u0026 !o.dropBehaviour) {\n\t\t\t$.ui.ddmanager.prepareOffsets(this, event);\n\t\t}\n\n\n\t\tthis._mouseDrag(event, true); //Execute the drag once - this causes the helper not to be visible before getting its correct position\n\n\t\t//If the ddmanager is used for droppables, inform the manager that dragging has started (see #5003)\n\t\tif ( $.ui.ddmanager ) {\n\t\t\t$.ui.ddmanager.dragStart(this, event);\n\t\t}\n\n\t\treturn true;\n\t},\n\n\t_mouseDrag: function(event, noPropagation) {\n\n\t\t//Compute the helpers position\n\t\tthis.position = this._generatePosition(event);\n\t\tthis.positionAbs = this._convertPositionTo(\"absolute\");\n\n\t\t//Call plugins and callbacks and use the resulting position if something is returned\n\t\tif (!noPropagation) {\n\t\t\tvar ui = this._uiHash();\n\t\t\tif(this._trigger(\"drag\", event, ui) === false) {\n\t\t\t\tthis._mouseUp({});\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\tthis.position = ui.position;\n\t\t}\n\n\t\tif(!this.options.axis || this.options.axis !== \"y\") {\n\t\t\tthis.helper[0].style.left = this.position.left+\"px\";\n\t\t}\n\t\tif(!this.options.axis || this.options.axis !== \"x\") {\n\t\t\tthis.helper[0].style.top = this.position.top+\"px\";\n\t\t}\n\t\tif($.ui.ddmanager) {\n\t\t\t$.ui.ddmanager.drag(this, event);\n\t\t}\n\n\t\treturn false;\n\t},\n\n\t_mouseStop: function(event) {\n\n\t\t//If we are using droppables, inform the manager about the drop\n\t\tvar element,\n\t\t\tthat = this,\n\t\t\telementInDom = false,\n\t\t\tdropped = false;\n\t\tif ($.ui.ddmanager \u0026\u0026 !this.options.dropBehaviour) {\n\t\t\tdropped = $.ui.ddmanager.drop(this, event);\n\t\t}\n\n\t\t//if a drop comes from outside (a sortable)\n\t\tif(this.dropped) {\n\t\t\tdropped = this.dropped;\n\t\t\tthis.dropped = false;\n\t\t}\n\n\t\t//if the original element is no longer in the DOM don\u0027t bother to continue (see #8269)\n\t\telement = this.element[0];\n\t\twhile ( element \u0026\u0026 (element = element.parentNode) ) {\n\t\t\tif (element === document ) {\n\t\t\t\telementInDom = true;\n\t\t\t}\n\t\t}\n\t\tif ( !elementInDom \u0026\u0026 this.options.helper === \"original\" ) {\n\t\t\treturn false;\n\t\t}\n\n\t\tif((this.options.revert === \"invalid\" \u0026\u0026 !dropped) || (this.options.revert === \"valid\" \u0026\u0026 dropped) || this.options.revert === true || ($.isFunction(this.options.revert) \u0026\u0026 this.options.revert.call(this.element, dropped))) {\n\t\t\t$(this.helper).animate(this.originalPosition, parseInt(this.options.revertDuration, 10), function() {\n\t\t\t\tif(that._trigger(\"stop\", event) !== false) {\n\t\t\t\t\tthat._clear();\n\t\t\t\t}\n\t\t\t});\n\t\t} else {\n\t\t\tif(this._trigger(\"stop\", event) !== false) {\n\t\t\t\tthis._clear();\n\t\t\t}\n\t\t}\n\n\t\treturn false;\n\t},\n\n\t_mouseUp: function(event) {\n\t\t//Remove frame helpers\n\t\t$(\"div.ui-draggable-iframeFix\").each(function() {\n\t\t\tthis.parentNode.removeChild(this);\n\t\t});\n\n\t\t//If the ddmanager is used for droppables, inform the manager that dragging has stopped (see #5003)\n\t\tif( $.ui.ddmanager ) {\n\t\t\t$.ui.ddmanager.dragStop(this, event);\n\t\t}\n\n\t\treturn $.ui.mouse.prototype._mouseUp.call(this, event);\n\t},\n\n\tcancel: function() {\n\n\t\tif(this.helper.is(\".ui-draggable-dragging\")) {\n\t\t\tthis._mouseUp({});\n\t\t} else {\n\t\t\tthis._clear();\n\t\t}\n\n\t\treturn this;\n\n\t},\n\n\t_getHandle: function(event) {\n\t\treturn this.options.handle ?\n\t\t\t!!$( event.target ).closest( this.element.find( this.options.handle ) ).length :\n\t\t\ttrue;\n\t},\n\n\t_createHelper: function(event) {\n\n\t\tvar o = this.options,\n\t\t\thelper = $.isFunction(o.helper) ? $(o.helper.apply(this.element[0], [event])) : (o.helper === \"clone\" ? this.element.clone().removeAttr(\"id\") : this.element);\n\n\t\tif(!helper.parents(\"body\").length) {\n\t\t\thelper.appendTo((o.appendTo === \"parent\" ? this.element[0].parentNode : o.appendTo));\n\t\t}\n\n\t\tif(helper[0] !== this.element[0] \u0026\u0026 !(/(fixed|absolute)/).test(helper.css(\"position\"))) {\n\t\t\thelper.css(\"position\", \"absolute\");\n\t\t}\n\n\t\treturn helper;\n\n\t},\n\n\t_adjustOffsetFromHelper: function(obj) {\n\t\tif (typeof obj === \"string\") {\n\t\t\tobj = obj.split(\" \");\n\t\t}\n\t\tif ($.isArray(obj)) {\n\t\t\tobj = {left: +obj[0], top: +obj[1] || 0};\n\t\t}\n\t\tif (\"left\" in obj) {\n\t\t\tthis.offset.click.left = obj.left + this.margins.left;\n\t\t}\n\t\tif (\"right\" in obj) {\n\t\t\tthis.offset.click.left = this.helperProportions.width - obj.right + this.margins.left;\n\t\t}\n\t\tif (\"top\" in obj) {\n\t\t\tthis.offset.click.top = obj.top + this.margins.top;\n\t\t}\n\t\tif (\"bottom\" in obj) {\n\t\t\tthis.offset.click.top = this.helperProportions.height - obj.bottom + this.margins.top;\n\t\t}\n\t},\n\n\t_getParentOffset: function() {\n\n\t\t//Get the offsetParent and cache its position\n\t\tthis.offsetParent = this.helper.offsetParent();\n\t\tvar po = this.offsetParent.offset();\n\n\t\t// This is a special case where we need to modify a offset calculated on start, since the following happened:\n\t\t// 1. The position of the helper is absolute, so it\u0027s position is calculated based on the next positioned parent\n\t\t// 2. The actual offset parent is a child of the scroll parent, and the scroll parent isn\u0027t the document, which means that\n\t\t// the scroll is included in the initial calculation of the offset of the parent, and never recalculated upon drag\n\t\tif(this.cssPosition === \"absolute\" \u0026\u0026 this.scrollParent[0] !== document \u0026\u0026 $.contains(this.scrollParent[0], this.offsetParent[0])) {\n\t\t\tpo.left += this.scrollParent.scrollLeft();\n\t\t\tpo.top += this.scrollParent.scrollTop();\n\t\t}\n\n\t\t//This needs to be actually done for all browsers, since pageX/pageY includes this information\n\t\t//Ugly IE fix\n\t\tif((this.offsetParent[0] === document.body) ||\n\t\t\t(this.offsetParent[0].tagName \u0026\u0026 this.offsetParent[0].tagName.toLowerCase() === \"html\" \u0026\u0026 $.ui.ie)) {\n\t\t\tpo = { top: 0, left: 0 };\n\t\t}\n\n\t\treturn {\n\t\t\ttop: po.top + (parseInt(this.offsetParent.css(\"borderTopWidth\"),10) || 0),\n\t\t\tleft: po.left + (parseInt(this.offsetParent.css(\"borderLeftWidth\"),10) || 0)\n\t\t};\n\n\t},\n\n\t_getRelativeOffset: function() {\n\n\t\tif(this.cssPosition === \"relative\") {\n\t\t\tvar p = this.element.position();\n\t\t\treturn {\n\t\t\t\ttop: p.top - (parseInt(this.helper.css(\"top\"),10) || 0) + this.scrollParent.scrollTop(),\n\t\t\t\tleft: p.left - (parseInt(this.helper.css(\"left\"),10) || 0) + this.scrollParent.scrollLeft()\n\t\t\t};\n\t\t} else {\n\t\t\treturn { top: 0, left: 0 };\n\t\t}\n\n\t},\n\n\t_cacheMargins: function() {\n\t\tthis.margins = {\n\t\t\tleft: (parseInt(this.element.css(\"marginLeft\"),10) || 0),\n\t\t\ttop: (parseInt(this.element.css(\"marginTop\"),10) || 0),\n\t\t\tright: (parseInt(this.element.css(\"marginRight\"),10) || 0),\n\t\t\tbottom: (parseInt(this.element.css(\"marginBottom\"),10) || 0)\n\t\t};\n\t},\n\n\t_cacheHelperProportions: function() {\n\t\tthis.helperProportions = {\n\t\t\twidth: this.helper.outerWidth(),\n\t\t\theight: this.helper.outerHeight()\n\t\t};\n\t},\n\n\t_setContainment: function() {\n\n\t\tvar over, c, ce,\n\t\t\to = this.options;\n\n\t\tif(o.containment === \"parent\") {\n\t\t\to.containment = this.helper[0].parentNode;\n\t\t}\n\t\tif(o.containment === \"document\" || o.containment === \"window\") {\n\t\t\tthis.containment = [\n\t\t\t\to.containment === \"document\" ? 0 : $(window).scrollLeft() - this.offset.relative.left - this.offset.parent.left,\n\t\t\t\to.containment === \"document\" ? 0 : $(window).scrollTop() - this.offset.relative.top - this.offset.parent.top,\n\t\t\t\t(o.containment === \"document\" ? 0 : $(window).scrollLeft()) + $(o.containment === \"document\" ? document : window).width() - this.helperProportions.width - this.margins.left,\n\t\t\t\t(o.containment === \"document\" ? 0 : $(window).scrollTop()) + ($(o.containment === \"document\" ? document : window).height() || document.body.parentNode.scrollHeight) - this.helperProportions.height - this.margins.top\n\t\t\t];\n\t\t}\n\n\t\tif(!(/^(document|window|parent)$/).test(o.containment) \u0026\u0026 o.containment.constructor !== Array) {\n\t\t\tc = $(o.containment);\n\t\t\tce = c[0];\n\n\t\t\tif(!ce) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tover = ($(ce).css(\"overflow\") !== \"hidden\");\n\n\t\t\tthis.containment = [\n\t\t\t\t(parseInt($(ce).css(\"borderLeftWidth\"),10) || 0) + (parseInt($(ce).css(\"paddingLeft\"),10) || 0),\n\t\t\t\t(parseInt($(ce).css(\"borderTopWidth\"),10) || 0) + (parseInt($(ce).css(\"paddingTop\"),10) || 0),\n\t\t\t\t(over ? Math.max(ce.scrollWidth,ce.offsetWidth) : ce.offsetWidth) - (parseInt($(ce).css(\"borderRightWidth\"),10) || 0) - (parseInt($(ce).css(\"paddingRight\"),10) || 0) - this.helperProportions.width - this.margins.left - this.margins.right,\n\t\t\t\t(over ? Math.max(ce.scrollHeight,ce.offsetHeight) : ce.offsetHeight) - (parseInt($(ce).css(\"borderBottomWidth\"),10) || 0) - (parseInt($(ce).css(\"paddingBottom\"),10) || 0) - this.helperProportions.height - this.margins.top - this.margins.bottom\n\t\t\t];\n\t\t\tthis.relative_container = c;\n\n\t\t} else if(o.containment.constructor === Array) {\n\t\t\tthis.containment = o.containment;\n\t\t}\n\n\t},\n\n\t_convertPositionTo: function(d, pos) {\n\n\t\tif(!pos) {\n\t\t\tpos = this.position;\n\t\t}\n\n\t\tvar mod = d === \"absolute\" ? 1 : -1,\n\t\t\tscroll = this.cssPosition === \"absolute\" \u0026\u0026 !(this.scrollParent[0] !== document \u0026\u0026 $.contains(this.scrollParent[0], this.offsetParent[0])) ? this.offsetParent : this.scrollParent, scrollIsRootNode = (/(html|body)/i).test(scroll[0].tagName);\n\n\t\treturn {\n\t\t\ttop: (\n\t\t\t\tpos.top\t+\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t// The absolute mouse position\n\t\t\t\tthis.offset.relative.top * mod +\t\t\t\t\t\t\t\t\t\t// Only for relative positioned nodes: Relative offset from element to offset parent\n\t\t\t\tthis.offset.parent.top * mod -\t\t\t\t\t\t\t\t\t\t// The offsetParent\u0027s offset without borders (offset + border)\n\t\t\t\t( ( this.cssPosition === \"fixed\" ? -this.scrollParent.scrollTop() : ( scrollIsRootNode ? 0 : scroll.scrollTop() ) ) * mod)\n\t\t\t),\n\t\t\tleft: (\n\t\t\t\tpos.left +\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t// The absolute mouse position\n\t\t\t\tthis.offset.relative.left * mod +\t\t\t\t\t\t\t\t\t\t// Only for relative positioned nodes: Relative offset from element to offset parent\n\t\t\t\tthis.offset.parent.left * mod\t-\t\t\t\t\t\t\t\t\t\t// The offsetParent\u0027s offset without borders (offset + border)\n\t\t\t\t( ( this.cssPosition === \"fixed\" ? -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : scroll.scrollLeft() ) * mod)\n\t\t\t)\n\t\t};\n\n\t},\n\n\t_generatePosition: function(event) {\n\n\t\tvar containment, co, top, left,\n\t\t\to = this.options,\n\t\t\tscroll = this.cssPosition === \"absolute\" \u0026\u0026 !(this.scrollParent[0] !== document \u0026\u0026 $.contains(this.scrollParent[0], this.offsetParent[0])) ? this.offsetParent : this.scrollParent,\n\t\t\tscrollIsRootNode = (/(html|body)/i).test(scroll[0].tagName),\n\t\t\tpageX = event.pageX,\n\t\t\tpageY = event.pageY;\n\n\t\t/*\n\t\t * - Position constraining -\n\t\t * Constrain the position to a mix of grid, containment.\n\t\t */\n\n\t\tif(this.originalPosition) { //If we are not dragging yet, we won\u0027t check for options\n\t\t\tif(this.containment) {\n\t\t\tif (this.relative_container){\n\t\t\t\tco = this.relative_container.offset();\n\t\t\t\tcontainment = [ this.containment[0] + co.left,\n\t\t\t\t\tthis.containment[1] + co.top,\n\t\t\t\t\tthis.containment[2] + co.left,\n\t\t\t\t\tthis.containment[3] + co.top ];\n\t\t\t}\n\t\t\telse {\n\t\t\t\tcontainment = this.containment;\n\t\t\t}\n\n\t\t\t\tif(event.pageX - this.offset.click.left \u003c containment[0]) {\n\t\t\t\t\tpageX = containment[0] + this.offset.click.left;\n\t\t\t\t}\n\t\t\t\tif(event.pageY - this.offset.click.top \u003c containment[1]) {\n\t\t\t\t\tpageY = containment[1] + this.offset.click.top;\n\t\t\t\t}\n\t\t\t\tif(event.pageX - this.offset.click.left \u003e containment[2]) {\n\t\t\t\t\tpageX = containment[2] + this.offset.click.left;\n\t\t\t\t}\n\t\t\t\tif(event.pageY - this.offset.click.top \u003e containment[3]) {\n\t\t\t\t\tpageY = containment[3] + this.offset.click.top;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif(o.grid) {\n\t\t\t\t//Check for grid elements set to 0 to prevent divide by 0 error causing invalid argument errors in IE (see ticket #6950)\n\t\t\t\ttop = o.grid[1] ? this.originalPageY + Math.round((pageY - this.originalPageY) / o.grid[1]) * o.grid[1] : this.originalPageY;\n\t\t\t\tpageY = containment ? ((top - this.offset.click.top \u003e= containment[1] || top - this.offset.click.top \u003e containment[3]) ? top : ((top - this.offset.click.top \u003e= containment[1]) ? top - o.grid[1] : top + o.grid[1])) : top;\n\n\t\t\t\tleft = o.grid[0] ? this.originalPageX + Math.round((pageX - this.originalPageX) / o.grid[0]) * o.grid[0] : this.originalPageX;\n\t\t\t\tpageX = containment ? ((left - this.offset.click.left \u003e= containment[0] || left - this.offset.click.left \u003e containment[2]) ? left : ((left - this.offset.click.left \u003e= containment[0]) ? left - o.grid[0] : left + o.grid[0])) : left;\n\t\t\t}\n\n\t\t}\n\n\t\treturn {\n\t\t\ttop: (\n\t\t\t\tpageY -\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t// The absolute mouse position\n\t\t\t\tthis.offset.click.top\t-\t\t\t\t\t\t\t\t\t\t\t\t// Click offset (relative to the element)\n\t\t\t\tthis.offset.relative.top -\t\t\t\t\t\t\t\t\t\t\t\t// Only for relative positioned nodes: Relative offset from element to offset parent\n\t\t\t\tthis.offset.parent.top +\t\t\t\t\t\t\t\t\t\t\t\t// The offsetParent\u0027s offset without borders (offset + border)\n\t\t\t\t( ( this.cssPosition === \"fixed\" ? -this.scrollParent.scrollTop() : ( scrollIsRootNode ? 0 : scroll.scrollTop() ) ))\n\t\t\t),\n\t\t\tleft: (\n\t\t\t\tpageX -\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t// The absolute mouse position\n\t\t\t\tthis.offset.click.left -\t\t\t\t\t\t\t\t\t\t\t\t// Click offset (relative to the element)\n\t\t\t\tthis.offset.relative.left -\t\t\t\t\t\t\t\t\t\t\t\t// Only for relative positioned nodes: Relative offset from element to offset parent\n\t\t\t\tthis.offset.parent.left +\t\t\t\t\t\t\t\t\t\t\t\t// The offsetParent\u0027s offset without borders (offset + border)\n\t\t\t\t( ( this.cssPosition === \"fixed\" ? -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : scroll.scrollLeft() ))\n\t\t\t)\n\t\t};\n\n\t},\n\n\t_clear: function() {\n\t\tthis.helper.removeClass(\"ui-draggable-dragging\");\n\t\tif(this.helper[0] !== this.element[0] \u0026\u0026 !this.cancelHelperRemoval) {\n\t\t\tthis.helper.remove();\n\t\t}\n\t\tthis.helper = null;\n\t\tthis.cancelHelperRemoval = false;\n\t},\n\n\t// From now on bulk stuff - mainly helpers\n\n\t_trigger: function(type, event, ui) {\n\t\tui = ui || this._uiHash();\n\t\t$.ui.plugin.call(this, type, [event, ui]);\n\t\t//The absolute position has to be recalculated after plugins\n\t\tif(type === \"drag\") {\n\t\t\tthis.positionAbs = this._convertPositionTo(\"absolute\");\n\t\t}\n\t\treturn $.Widget.prototype._trigger.call(this, type, event, ui);\n\t},\n\n\tplugins: {},\n\n\t_uiHash: function() {\n\t\treturn {\n\t\t\thelper: this.helper,\n\t\t\tposition: this.position,\n\t\t\toriginalPosition: this.originalPosition,\n\t\t\toffset: this.positionAbs\n\t\t};\n\t}\n\n});\n\n$.ui.plugin.add(\"draggable\", \"connectToSortable\", {\n\tstart: function(event, ui) {\n\n\t\tvar inst = $(this).data(\"ui-draggable\"), o = inst.options,\n\t\t\tuiSortable = $.extend({}, ui, { item: inst.element });\n\t\tinst.sortables = [];\n\t\t$(o.connectToSortable).each(function() {\n\t\t\tvar sortable = $.data(this, \"ui-sortable\");\n\t\t\tif (sortable \u0026\u0026 !sortable.options.disabled) {\n\t\t\t\tinst.sortables.push({\n\t\t\t\t\tinstance: sortable,\n\t\t\t\t\tshouldRevert: sortable.options.revert\n\t\t\t\t});\n\t\t\t\tsortable.refreshPositions();\t// Call the sortable\u0027s refreshPositions at drag start to refresh the containerCache since the sortable container cache is used in drag and needs to be up to date (this will ensure it\u0027s initialised as well as being kept in step with any changes that might have happened on the page).\n\t\t\t\tsortable._trigger(\"activate\", event, uiSortable);\n\t\t\t}\n\t\t});\n\n\t},\n\tstop: function(event, ui) {\n\n\t\t//If we are still over the sortable, we fake the stop event of the sortable, but also remove helper\n\t\tvar inst = $(this).data(\"ui-draggable\"),\n\t\t\tuiSortable = $.extend({}, ui, { item: inst.element });\n\n\t\t$.each(inst.sortables, function() {\n\t\t\tif(this.instance.isOver) {\n\n\t\t\t\tthis.instance.isOver = 0;\n\n\t\t\t\tinst.cancelHelperRemoval = true; //Don\u0027t remove the helper in the draggable instance\n\t\t\t\tthis.instance.cancelHelperRemoval = false; //Remove it in the sortable instance (so sortable plugins like revert still work)\n\n\t\t\t\t//The sortable revert is supported, and we have to set a temporary dropped variable on the draggable to support revert: \"valid/invalid\"\n\t\t\t\tif(this.shouldRevert) {\n\t\t\t\t\tthis.instance.options.revert = this.shouldRevert;\n\t\t\t\t}\n\n\t\t\t\t//Trigger the stop of the sortable\n\t\t\t\tthis.instance._mouseStop(event);\n\n\t\t\t\tthis.instance.options.helper = this.instance.options._helper;\n\n\t\t\t\t//If the helper has been the original item, restore properties in the sortable\n\t\t\t\tif(inst.options.helper === \"original\") {\n\t\t\t\t\tthis.instance.currentItem.css({ top: \"auto\", left: \"auto\" });\n\t\t\t\t}\n\n\t\t\t} else {\n\t\t\t\tthis.instance.cancelHelperRemoval = false; //Remove the helper in the sortable instance\n\t\t\t\tthis.instance._trigger(\"deactivate\", event, uiSortable);\n\t\t\t}\n\n\t\t});\n\n\t},\n\tdrag: function(event, ui) {\n\n\t\tvar inst = $(this).data(\"ui-draggable\"), that = this;\n\n\t\t$.each(inst.sortables, function() {\n\n\t\t\tvar innermostIntersecting = false,\n\t\t\t\tthisSortable = this;\n\n\t\t\t//Copy over some variables to allow calling the sortable\u0027s native _intersectsWith\n\t\t\tthis.instance.positionAbs = inst.positionAbs;\n\t\t\tthis.instance.helperProportions = inst.helperProportions;\n\t\t\tthis.instance.offset.click = inst.offset.click;\n\n\t\t\tif(this.instance._intersectsWith(this.instance.containerCache)) {\n\t\t\t\tinnermostIntersecting = true;\n\t\t\t\t$.each(inst.sortables, function () {\n\t\t\t\t\tthis.instance.positionAbs = inst.positionAbs;\n\t\t\t\t\tthis.instance.helperProportions = inst.helperProportions;\n\t\t\t\t\tthis.instance.offset.click = inst.offset.click;\n\t\t\t\t\tif (this !== thisSortable \u0026\u0026\n\t\t\t\t\t\tthis.instance._intersectsWith(this.instance.containerCache) \u0026\u0026\n\t\t\t\t\t\t$.contains(thisSortable.instance.element[0], this.instance.element[0])\n\t\t\t\t\t) {\n\t\t\t\t\t\tinnermostIntersecting = false;\n\t\t\t\t\t}\n\t\t\t\t\treturn innermostIntersecting;\n\t\t\t\t});\n\t\t\t}\n\n\n\t\t\tif(innermostIntersecting) {\n\t\t\t\t//If it intersects, we use a little isOver variable and set it once, so our move-in stuff gets fired only once\n\t\t\t\tif(!this.instance.isOver) {\n\n\t\t\t\t\tthis.instance.isOver = 1;\n\t\t\t\t\t//Now we fake the start of dragging for the sortable instance,\n\t\t\t\t\t//by cloning the list group item, appending it to the sortable and using it as inst.currentItem\n\t\t\t\t\t//We can then fire the start event of the sortable with our passed browser event, and our own helper (so it doesn\u0027t create a new one)\n\t\t\t\t\tthis.instance.currentItem = $(that).clone().removeAttr(\"id\").appendTo(this.instance.element).data(\"ui-sortable-item\", true);\n\t\t\t\t\tthis.instance.options._helper = this.instance.options.helper; //Store helper option to later restore it\n\t\t\t\t\tthis.instance.options.helper = function() { return ui.helper[0]; };\n\n\t\t\t\t\tevent.target = this.instance.currentItem[0];\n\t\t\t\t\tthis.instance._mouseCapture(event, true);\n\t\t\t\t\tthis.instance._mouseStart(event, true, true);\n\n\t\t\t\t\t//Because the browser event is way off the new appended portlet, we modify a couple of variables to reflect the changes\n\t\t\t\t\tthis.instance.offset.click.top = inst.offset.click.top;\n\t\t\t\t\tthis.instance.offset.click.left = inst.offset.click.left;\n\t\t\t\t\tthis.instance.offset.parent.left -= inst.offset.parent.left - this.instance.offset.parent.left;\n\t\t\t\t\tthis.instance.offset.parent.top -= inst.offset.parent.top - this.instance.offset.parent.top;\n\n\t\t\t\t\tinst._trigger(\"toSortable\", event);\n\t\t\t\t\tinst.dropped = this.instance.element; //draggable revert needs that\n\t\t\t\t\t//hack so receive/update callbacks work (mostly)\n\t\t\t\t\tinst.currentItem = inst.element;\n\t\t\t\t\tthis.instance.fromOutside = inst;\n\n\t\t\t\t}\n\n\t\t\t\t//Provided we did all the previous steps, we can fire the drag event of the sortable on every draggable drag, when it intersects with the sortable\n\t\t\t\tif(this.instance.currentItem) {\n\t\t\t\t\tthis.instance._mouseDrag(event);\n\t\t\t\t}\n\n\t\t\t} else {\n\n\t\t\t\t//If it doesn\u0027t intersect with the sortable, and it intersected before,\n\t\t\t\t//we fake the drag stop of the sortable, but make sure it doesn\u0027t remove the helper by using cancelHelperRemoval\n\t\t\t\tif(this.instance.isOver) {\n\n\t\t\t\t\tthis.instance.isOver = 0;\n\t\t\t\t\tthis.instance.cancelHelperRemoval = true;\n\n\t\t\t\t\t//Prevent reverting on this forced stop\n\t\t\t\t\tthis.instance.options.revert = false;\n\n\t\t\t\t\t// The out event needs to be triggered independently\n\t\t\t\t\tthis.instance._trigger(\"out\", event, this.instance._uiHash(this.instance));\n\n\t\t\t\t\tthis.instance._mouseStop(event, true);\n\t\t\t\t\tthis.instance.options.helper = this.instance.options._helper;\n\n\t\t\t\t\t//Now we remove our currentItem, the list group clone again, and the placeholder, and animate the helper back to it\u0027s original size\n\t\t\t\t\tthis.instance.currentItem.remove();\n\t\t\t\t\tif(this.instance.placeholder) {\n\t\t\t\t\t\tthis.instance.placeholder.remove();\n\t\t\t\t\t}\n\n\t\t\t\t\tinst._trigger(\"fromSortable\", event);\n\t\t\t\t\tinst.dropped = false; //draggable revert needs that\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t});\n\n\t}\n});\n\n$.ui.plugin.add(\"draggable\", \"cursor\", {\n\tstart: function() {\n\t\tvar t = $(\"body\"), o = $(this).data(\"ui-draggable\").options;\n\t\tif (t.css(\"cursor\")) {\n\t\t\to._cursor = t.css(\"cursor\");\n\t\t}\n\t\tt.css(\"cursor\", o.cursor);\n\t},\n\tstop: function() {\n\t\tvar o = $(this).data(\"ui-draggable\").options;\n\t\tif (o._cursor) {\n\t\t\t$(\"body\").css(\"cursor\", o._cursor);\n\t\t}\n\t}\n});\n\n$.ui.plugin.add(\"draggable\", \"opacity\", {\n\tstart: function(event, ui) {\n\t\tvar t = $(ui.helper), o = $(this).data(\"ui-draggable\").options;\n\t\tif(t.css(\"opacity\")) {\n\t\t\to._opacity = t.css(\"opacity\");\n\t\t}\n\t\tt.css(\"opacity\", o.opacity);\n\t},\n\tstop: function(event, ui) {\n\t\tvar o = $(this).data(\"ui-draggable\").options;\n\t\tif(o._opacity) {\n\t\t\t$(ui.helper).css(\"opacity\", o._opacity);\n\t\t}\n\t}\n});\n\n$.ui.plugin.add(\"draggable\", \"scroll\", {\n\tstart: function() {\n\t\tvar i = $(this).data(\"ui-draggable\");\n\t\tif(i.scrollParent[0] !== document \u0026\u0026 i.scrollParent[0].tagName !== \"HTML\") {\n\t\t\ti.overflowOffset = i.scrollParent.offset();\n\t\t}\n\t},\n\tdrag: function( event ) {\n\n\t\tvar i = $(this).data(\"ui-draggable\"), o = i.options, scrolled = false;\n\n\t\tif(i.scrollParent[0] !== document \u0026\u0026 i.scrollParent[0].tagName !== \"HTML\") {\n\n\t\t\tif(!o.axis || o.axis !== \"x\") {\n\t\t\t\tif((i.overflowOffset.top + i.scrollParent[0].offsetHeight) - event.pageY \u003c o.scrollSensitivity) {\n\t\t\t\t\ti.scrollParent[0].scrollTop = scrolled = i.scrollParent[0].scrollTop + o.scrollSpeed;\n\t\t\t\t} else if(event.pageY - i.overflowOffset.top \u003c o.scrollSensitivity) {\n\t\t\t\t\ti.scrollParent[0].scrollTop = scrolled = i.scrollParent[0].scrollTop - o.scrollSpeed;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif(!o.axis || o.axis !== \"y\") {\n\t\t\t\tif((i.overflowOffset.left + i.scrollParent[0].offsetWidth) - event.pageX \u003c o.scrollSensitivity) {\n\t\t\t\t\ti.scrollParent[0].scrollLeft = scrolled = i.scrollParent[0].scrollLeft + o.scrollSpeed;\n\t\t\t\t} else if(event.pageX - i.overflowOffset.left \u003c o.scrollSensitivity) {\n\t\t\t\t\ti.scrollParent[0].scrollLeft = scrolled = i.scrollParent[0].scrollLeft - o.scrollSpeed;\n\t\t\t\t}\n\t\t\t}\n\n\t\t} else {\n\n\t\t\tif(!o.axis || o.axis !== \"x\") {\n\t\t\t\tif(event.pageY - $(document).scrollTop() \u003c o.scrollSensitivity) {\n\t\t\t\t\tscrolled = $(document).scrollTop($(document).scrollTop() - o.scrollSpeed);\n\t\t\t\t} else if($(window).height() - (event.pageY - $(document).scrollTop()) \u003c o.scrollSensitivity) {\n\t\t\t\t\tscrolled = $(document).scrollTop($(document).scrollTop() + o.scrollSpeed);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif(!o.axis || o.axis !== \"y\") {\n\t\t\t\tif(event.pageX - $(document).scrollLeft() \u003c o.scrollSensitivity) {\n\t\t\t\t\tscrolled = $(document).scrollLeft($(document).scrollLeft() - o.scrollSpeed);\n\t\t\t\t} else if($(window).width() - (event.pageX - $(document).scrollLeft()) \u003c o.scrollSensitivity) {\n\t\t\t\t\tscrolled = $(document).scrollLeft($(document).scrollLeft() + o.scrollSpeed);\n\t\t\t\t}\n\t\t\t}\n\n\t\t}\n\n\t\tif(scrolled !== false \u0026\u0026 $.ui.ddmanager \u0026\u0026 !o.dropBehaviour) {\n\t\t\t$.ui.ddmanager.prepareOffsets(i, event);\n\t\t}\n\n\t}\n});\n\n$.ui.plugin.add(\"draggable\", \"snap\", {\n\tstart: function() {\n\n\t\tvar i = $(this).data(\"ui-draggable\"),\n\t\t\to = i.options;\n\n\t\ti.snapElements = [];\n\n\t\t$(o.snap.constructor !== String ? ( o.snap.items || \":data(ui-draggable)\" ) : o.snap).each(function() {\n\t\t\tvar $t = $(this),\n\t\t\t\t$o = $t.offset();\n\t\t\tif(this !== i.element[0]) {\n\t\t\t\ti.snapElements.push({\n\t\t\t\t\titem: this,\n\t\t\t\t\twidth: $t.outerWidth(), height: $t.outerHeight(),\n\t\t\t\t\ttop: $o.top, left: $o.left\n\t\t\t\t});\n\t\t\t}\n\t\t});\n\n\t},\n\tdrag: function(event, ui) {\n\n\t\tvar ts, bs, ls, rs, l, r, t, b, i, first,\n\t\t\tinst = $(this).data(\"ui-draggable\"),\n\t\t\to = inst.options,\n\t\t\td = o.snapTolerance,\n\t\t\tx1 = ui.offset.left, x2 = x1 + inst.helperProportions.width,\n\t\t\ty1 = ui.offset.top, y2 = y1 + inst.helperProportions.height;\n\n\t\tfor (i = inst.snapElements.length - 1; i \u003e= 0; i--){\n\n\t\t\tl = inst.snapElements[i].left;\n\t\t\tr = l + inst.snapElements[i].width;\n\t\t\tt = inst.snapElements[i].top;\n\t\t\tb = t + inst.snapElements[i].height;\n\n\t\t\t//Yes, I know, this is insane ;)\n\t\t\tif(!((l-d \u003c x1 \u0026\u0026 x1 \u003c r+d \u0026\u0026 t-d \u003c y1 \u0026\u0026 y1 \u003c b+d) || (l-d \u003c x1 \u0026\u0026 x1 \u003c r+d \u0026\u0026 t-d \u003c y2 \u0026\u0026 y2 \u003c b+d) || (l-d \u003c x2 \u0026\u0026 x2 \u003c r+d \u0026\u0026 t-d \u003c y1 \u0026\u0026 y1 \u003c b+d) || (l-d \u003c x2 \u0026\u0026 x2 \u003c r+d \u0026\u0026 t-d \u003c y2 \u0026\u0026 y2 \u003c b+d))) {\n\t\t\t\tif(inst.snapElements[i].snapping) {\n\t\t\t\t\t(inst.options.snap.release \u0026\u0026 inst.options.snap.release.call(inst.element, event, $.extend(inst._uiHash(), { snapItem: inst.snapElements[i].item })));\n\t\t\t\t}\n\t\t\t\tinst.snapElements[i].snapping = false;\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tif(o.snapMode !== \"inner\") {\n\t\t\t\tts = Math.abs(t - y2) \u003c= d;\n\t\t\t\tbs = Math.abs(b - y1) \u003c= d;\n\t\t\t\tls = Math.abs(l - x2) \u003c= d;\n\t\t\t\trs = Math.abs(r - x1) \u003c= d;\n\t\t\t\tif(ts) {\n\t\t\t\t\tui.position.top = inst._convertPositionTo(\"relative\", { top: t - inst.helperProportions.height, left: 0 }).top - inst.margins.top;\n\t\t\t\t}\n\t\t\t\tif(bs) {\n\t\t\t\t\tui.position.top = inst._convertPositionTo(\"relative\", { top: b, left: 0 }).top - inst.margins.top;\n\t\t\t\t}\n\t\t\t\tif(ls) {\n\t\t\t\t\tui.position.left = inst._convertPositionTo(\"relative\", { top: 0, left: l - inst.helperProportions.width }).left - inst.margins.left;\n\t\t\t\t}\n\t\t\t\tif(rs) {\n\t\t\t\t\tui.position.left = inst._convertPositionTo(\"relative\", { top: 0, left: r }).left - inst.margins.left;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tfirst = (ts || bs || ls || rs);\n\n\t\t\tif(o.snapMode !== \"outer\") {\n\t\t\t\tts = Math.abs(t - y1) \u003c= d;\n\t\t\t\tbs = Math.abs(b - y2) \u003c= d;\n\t\t\t\tls = Math.abs(l - x1) \u003c= d;\n\t\t\t\trs = Math.abs(r - x2) \u003c= d;\n\t\t\t\tif(ts) {\n\t\t\t\t\tui.position.top = inst._convertPositionTo(\"relative\", { top: t, left: 0 }).top - inst.margins.top;\n\t\t\t\t}\n\t\t\t\tif(bs) {\n\t\t\t\t\tui.position.top = inst._convertPositionTo(\"relative\", { top: b - inst.helperProportions.height, left: 0 }).top - inst.margins.top;\n\t\t\t\t}\n\t\t\t\tif(ls) {\n\t\t\t\t\tui.position.left = inst._convertPositionTo(\"relative\", { top: 0, left: l }).left - inst.margins.left;\n\t\t\t\t}\n\t\t\t\tif(rs) {\n\t\t\t\t\tui.position.left = inst._convertPositionTo(\"relative\", { top: 0, left: r - inst.helperProportions.width }).left - inst.margins.left;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif(!inst.snapElements[i].snapping \u0026\u0026 (ts || bs || ls || rs || first)) {\n\t\t\t\t(inst.options.snap.snap \u0026\u0026 inst.options.snap.snap.call(inst.element, event, $.extend(inst._uiHash(), { snapItem: inst.snapElements[i].item })));\n\t\t\t}\n\t\t\tinst.snapElements[i].snapping = (ts || bs || ls || rs || first);\n\n\t\t}\n\n\t}\n});\n\n$.ui.plugin.add(\"draggable\", \"stack\", {\n\tstart: function() {\n\t\tvar min,\n\t\t\to = this.data(\"ui-draggable\").options,\n\t\t\tgroup = $.makeArray($(o.stack)).sort(function(a,b) {\n\t\t\t\treturn (parseInt($(a).css(\"zIndex\"),10) || 0) - (parseInt($(b).css(\"zIndex\"),10) || 0);\n\t\t\t});\n\n\t\tif (!group.length) { return; }\n\n\t\tmin = parseInt($(group[0]).css(\"zIndex\"), 10) || 0;\n\t\t$(group).each(function(i) {\n\t\t\t$(this).css(\"zIndex\", min + i);\n\t\t});\n\t\tthis.css(\"zIndex\", (min + group.length));\n\t}\n});\n\n$.ui.plugin.add(\"draggable\", \"zIndex\", {\n\tstart: function(event, ui) {\n\t\tvar t = $(ui.helper), o = $(this).data(\"ui-draggable\").options;\n\t\tif(t.css(\"zIndex\")) {\n\t\t\to._zIndex = t.css(\"zIndex\");\n\t\t}\n\t\tt.css(\"zIndex\", o.zIndex);\n\t},\n\tstop: function(event, ui) {\n\t\tvar o = $(this).data(\"ui-draggable\").options;\n\t\tif(o._zIndex) {\n\t\t\t$(ui.helper).css(\"zIndex\", o._zIndex);\n\t\t}\n\t}\n});\n\n})(jQuery);\n\n(function( $, undefined ) {\n\nfunction isOverAxis( x, reference, size ) {\n\treturn ( x \u003e reference ) \u0026\u0026 ( x \u003c ( reference + size ) );\n}\n\n$.widget(\"ui.droppable\", {\n\tversion: \"1.10.2\",\n\twidgetEventPrefix: \"drop\",\n\toptions: {\n\t\taccept: \"*\",\n\t\tactiveClass: false,\n\t\taddClasses: true,\n\t\tgreedy: false,\n\t\thoverClass: false,\n\t\tscope: \"default\",\n\t\ttolerance: \"intersect\",\n\n\t\t// callbacks\n\t\tactivate: null,\n\t\tdeactivate: null,\n\t\tdrop: null,\n\t\tout: null,\n\t\tover: null\n\t},\n\t_create: function() {\n\n\t\tvar o = this.options,\n\t\t\taccept = o.accept;\n\n\t\tthis.isover = false;\n\t\tthis.isout = true;\n\n\t\tthis.accept = $.isFunction(accept) ? accept : function(d) {\n\t\t\treturn d.is(accept);\n\t\t};\n\n\t\t//Store the droppable\u0027s proportions\n\t\tthis.proportions = { width: this.element[0].offsetWidth, height: this.element[0].offsetHeight };\n\n\t\t// Add the reference and positions to the manager\n\t\t$.ui.ddmanager.droppables[o.scope] = $.ui.ddmanager.droppables[o.scope] || [];\n\t\t$.ui.ddmanager.droppables[o.scope].push(this);\n\n\t\t(o.addClasses \u0026\u0026 this.element.addClass(\"ui-droppable\"));\n\n\t},\n\n\t_destroy: function() {\n\t\tvar i = 0,\n\t\t\tdrop = $.ui.ddmanager.droppables[this.options.scope];\n\n\t\tfor ( ; i \u003c drop.length; i++ ) {\n\t\t\tif ( drop[i] === this ) {\n\t\t\t\tdrop.splice(i, 1);\n\t\t\t}\n\t\t}\n\n\t\tthis.element.removeClass(\"ui-droppable ui-droppable-disabled\");\n\t},\n\n\t_setOption: function(key, value) {\n\n\t\tif(key === \"accept\") {\n\t\t\tthis.accept = $.isFunction(value) ? value : function(d) {\n\t\t\t\treturn d.is(value);\n\t\t\t};\n\t\t}\n\t\t$.Widget.prototype._setOption.apply(this, arguments);\n\t},\n\n\t_activate: function(event) {\n\t\tvar draggable = $.ui.ddmanager.current;\n\t\tif(this.options.activeClass) {\n\t\t\tthis.element.addClass(this.options.activeClass);\n\t\t}\n\t\tif(draggable){\n\t\t\tthis._trigger(\"activate\", event, this.ui(draggable));\n\t\t}\n\t},\n\n\t_deactivate: function(event) {\n\t\tvar draggable = $.ui.ddmanager.current;\n\t\tif(this.options.activeClass) {\n\t\t\tthis.element.removeClass(this.options.activeClass);\n\t\t}\n\t\tif(draggable){\n\t\t\tthis._trigger(\"deactivate\", event, this.ui(draggable));\n\t\t}\n\t},\n\n\t_over: function(event) {\n\n\t\tvar draggable = $.ui.ddmanager.current;\n\n\t\t// Bail if draggable and droppable are same element\n\t\tif (!draggable || (draggable.currentItem || draggable.element)[0] === this.element[0]) {\n\t\t\treturn;\n\t\t}\n\n\t\tif (this.accept.call(this.element[0],(draggable.currentItem || draggable.element))) {\n\t\t\tif(this.options.hoverClass) {\n\t\t\t\tthis.element.addClass(this.options.hoverClass);\n\t\t\t}\n\t\t\tthis._trigger(\"over\", event, this.ui(draggable));\n\t\t}\n\n\t},\n\n\t_out: function(event) {\n\n\t\tvar draggable = $.ui.ddmanager.current;\n\n\t\t// Bail if draggable and droppable are same element\n\t\tif (!draggable || (draggable.currentItem || draggable.element)[0] === this.element[0]) {\n\t\t\treturn;\n\t\t}\n\n\t\tif (this.accept.call(this.element[0],(draggable.currentItem || draggable.element))) {\n\t\t\tif(this.options.hoverClass) {\n\t\t\t\tthis.element.removeClass(this.options.hoverClass);\n\t\t\t}\n\t\t\tthis._trigger(\"out\", event, this.ui(draggable));\n\t\t}\n\n\t},\n\n\t_drop: function(event,custom) {\n\n\t\tvar draggable = custom || $.ui.ddmanager.current,\n\t\t\tchildrenIntersection = false;\n\n\t\t// Bail if draggable and droppable are same element\n\t\tif (!draggable || (draggable.currentItem || draggable.element)[0] === this.element[0]) {\n\t\t\treturn false;\n\t\t}\n\n\t\tthis.element.find(\":data(ui-droppable)\").not(\".ui-draggable-dragging\").each(function() {\n\t\t\tvar inst = $.data(this, \"ui-droppable\");\n\t\t\tif(\n\t\t\t\tinst.options.greedy \u0026\u0026\n\t\t\t\t!inst.options.disabled \u0026\u0026\n\t\t\t\tinst.options.scope === draggable.options.scope \u0026\u0026\n\t\t\t\tinst.accept.call(inst.element[0], (draggable.currentItem || draggable.element)) \u0026\u0026\n\t\t\t\t$.ui.intersect(draggable, $.extend(inst, { offset: inst.element.offset() }), inst.options.tolerance)\n\t\t\t) { childrenIntersection = true; return false; }\n\t\t});\n\t\tif(childrenIntersection) {\n\t\t\treturn false;\n\t\t}\n\n\t\tif(this.accept.call(this.element[0],(draggable.currentItem || draggable.element))) {\n\t\t\tif(this.options.activeClass) {\n\t\t\t\tthis.element.removeClass(this.options.activeClass);\n\t\t\t}\n\t\t\tif(this.options.hoverClass) {\n\t\t\t\tthis.element.removeClass(this.options.hoverClass);\n\t\t\t}\n\t\t\tthis._trigger(\"drop\", event, this.ui(draggable));\n\t\t\treturn this.element;\n\t\t}\n\n\t\treturn false;\n\n\t},\n\n\tui: function(c) {\n\t\treturn {\n\t\t\tdraggable: (c.currentItem || c.element),\n\t\t\thelper: c.helper,\n\t\t\tposition: c.position,\n\t\t\toffset: c.positionAbs\n\t\t};\n\t}\n\n});\n\n$.ui.intersect = function(draggable, droppable, toleranceMode) {\n\n\tif (!droppable.offset) {\n\t\treturn false;\n\t}\n\n\tvar draggableLeft, draggableTop,\n\t\tx1 = (draggable.positionAbs || draggable.position.absolute).left, x2 = x1 + draggable.helperProportions.width,\n\t\ty1 = (draggable.positionAbs || draggable.position.absolute).top, y2 = y1 + draggable.helperProportions.height,\n\t\tl = droppable.offset.left, r = l + droppable.proportions.width,\n\t\tt = droppable.offset.top, b = t + droppable.proportions.height;\n\n\tswitch (toleranceMode) {\n\t\tcase \"fit\":\n\t\t\treturn (l \u003c= x1 \u0026\u0026 x2 \u003c= r \u0026\u0026 t \u003c= y1 \u0026\u0026 y2 \u003c= b);\n\t\tcase \"intersect\":\n\t\t\treturn (l \u003c x1 + (draggable.helperProportions.width / 2) \u0026\u0026 // Right Half\n\t\t\t\tx2 - (draggable.helperProportions.width / 2) \u003c r \u0026\u0026 // Left Half\n\t\t\t\tt \u003c y1 + (draggable.helperProportions.height / 2) \u0026\u0026 // Bottom Half\n\t\t\t\ty2 - (draggable.helperProportions.height / 2) \u003c b ); // Top Half\n\t\tcase \"pointer\":\n\t\t\tdraggableLeft = ((draggable.positionAbs || draggable.position.absolute).left + (draggable.clickOffset || draggable.offset.click).left);\n\t\t\tdraggableTop = ((draggable.positionAbs || draggable.position.absolute).top + (draggable.clickOffset || draggable.offset.click).top);\n\t\t\treturn isOverAxis( draggableTop, t, droppable.proportions.height ) \u0026\u0026 isOverAxis( draggableLeft, l, droppable.proportions.width );\n\t\tcase \"touch\":\n\t\t\treturn (\n\t\t\t\t(y1 \u003e= t \u0026\u0026 y1 \u003c= b) ||\t// Top edge touching\n\t\t\t\t(y2 \u003e= t \u0026\u0026 y2 \u003c= b) ||\t// Bottom edge touching\n\t\t\t\t(y1 \u003c t \u0026\u0026 y2 \u003e b)\t\t// Surrounded vertically\n\t\t\t) \u0026\u0026 (\n\t\t\t\t(x1 \u003e= l \u0026\u0026 x1 \u003c= r) ||\t// Left edge touching\n\t\t\t\t(x2 \u003e= l \u0026\u0026 x2 \u003c= r) ||\t// Right edge touching\n\t\t\t\t(x1 \u003c l \u0026\u0026 x2 \u003e r)\t\t// Surrounded horizontally\n\t\t\t);\n\t\tdefault:\n\t\t\treturn false;\n\t\t}\n\n};\n\n/*\n\tThis manager tracks offsets of draggables and droppables\n*/\n$.ui.ddmanager = {\n\tcurrent: null,\n\tdroppables: { \"default\": [] },\n\tprepareOffsets: function(t, event) {\n\n\t\tvar i, j,\n\t\t\tm = $.ui.ddmanager.droppables[t.options.scope] || [],\n\t\t\ttype = event ? event.type : null, // workaround for #2317\n\t\t\tlist = (t.currentItem || t.element).find(\":data(ui-droppable)\").addBack();\n\n\t\tdroppablesLoop: for (i = 0; i \u003c m.length; i++) {\n\n\t\t\t//No disabled and non-accepted\n\t\t\tif(m[i].options.disabled || (t \u0026\u0026 !m[i].accept.call(m[i].element[0],(t.currentItem || t.element)))) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\t// Filter out elements in the current dragged item\n\t\t\tfor (j=0; j \u003c list.length; j++) {\n\t\t\t\tif(list[j] === m[i].element[0]) {\n\t\t\t\t\tm[i].proportions.height = 0;\n\t\t\t\t\tcontinue droppablesLoop;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tm[i].visible = m[i].element.css(\"display\") !== \"none\";\n\t\t\tif(!m[i].visible) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\t//Activate the droppable if used directly from draggables\n\t\t\tif(type === \"mousedown\") {\n\t\t\t\tm[i]._activate.call(m[i], event);\n\t\t\t}\n\n\t\t\tm[i].offset = m[i].element.offset();\n\t\t\tm[i].proportions = { width: m[i].element[0].offsetWidth, height: m[i].element[0].offsetHeight };\n\n\t\t}\n\n\t},\n\tdrop: function(draggable, event) {\n\n\t\tvar dropped = false;\n\t\t// Create a copy of the droppables in case the list changes during the drop (#9116)\n\t\t$.each(($.ui.ddmanager.droppables[draggable.options.scope] || []).slice(), function() {\n\n\t\t\tif(!this.options) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tif (!this.options.disabled \u0026\u0026 this.visible \u0026\u0026 $.ui.intersect(draggable, this, this.options.tolerance)) {\n\t\t\t\tdropped = this._drop.call(this, event) || dropped;\n\t\t\t}\n\n\t\t\tif (!this.options.disabled \u0026\u0026 this.visible \u0026\u0026 this.accept.call(this.element[0],(draggable.currentItem || draggable.element))) {\n\t\t\t\tthis.isout = true;\n\t\t\t\tthis.isover = false;\n\t\t\t\tthis._deactivate.call(this, event);\n\t\t\t}\n\n\t\t});\n\t\treturn dropped;\n\n\t},\n\tdragStart: function( draggable, event ) {\n\t\t//Listen for scrolling so that if the dragging causes scrolling the position of the droppables can be recalculated (see #5003)\n\t\tdraggable.element.parentsUntil( \"body\" ).bind( \"scroll.droppable\", function() {\n\t\t\tif( !draggable.options.refreshPositions ) {\n\t\t\t\t$.ui.ddmanager.prepareOffsets( draggable, event );\n\t\t\t}\n\t\t});\n\t},\n\tdrag: function(draggable, event) {\n\n\t\t//If you have a highly dynamic page, you might try this option. It renders positions every time you move the mouse.\n\t\tif(draggable.options.refreshPositions) {\n\t\t\t$.ui.ddmanager.prepareOffsets(draggable, event);\n\t\t}\n\n\t\t//Run through all droppables and check their positions based on specific tolerance options\n\t\t$.each($.ui.ddmanager.droppables[draggable.options.scope] || [], function() {\n\n\t\t\tif(this.options.disabled || this.greedyChild || !this.visible) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tvar parentInstance, scope, parent,\n\t\t\t\tintersects = $.ui.intersect(draggable, this, this.options.tolerance),\n\t\t\t\tc = !intersects \u0026\u0026 this.isover ? \"isout\" : (intersects \u0026\u0026 !this.isover ? \"isover\" : null);\n\t\t\tif(!c) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif (this.options.greedy) {\n\t\t\t\t// find droppable parents with same scope\n\t\t\t\tscope = this.options.scope;\n\t\t\t\tparent = this.element.parents(\":data(ui-droppable)\").filter(function () {\n\t\t\t\t\treturn $.data(this, \"ui-droppable\").options.scope === scope;\n\t\t\t\t});\n\n\t\t\t\tif (parent.length) {\n\t\t\t\t\tparentInstance = $.data(parent[0], \"ui-droppable\");\n\t\t\t\t\tparentInstance.greedyChild = (c === \"isover\");\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// we just moved into a greedy child\n\t\t\tif (parentInstance \u0026\u0026 c === \"isover\") {\n\t\t\t\tparentInstance.isover = false;\n\t\t\t\tparentInstance.isout = true;\n\t\t\t\tparentInstance._out.call(parentInstance, event);\n\t\t\t}\n\n\t\t\tthis[c] = true;\n\t\t\tthis[c === \"isout\" ? \"isover\" : \"isout\"] = false;\n\t\t\tthis[c === \"isover\" ? \"_over\" : \"_out\"].call(this, event);\n\n\t\t\t// we just moved out of a greedy child\n\t\t\tif (parentInstance \u0026\u0026 c === \"isout\") {\n\t\t\t\tparentInstance.isout = false;\n\t\t\t\tparentInstance.isover = true;\n\t\t\t\tparentInstance._over.call(parentInstance, event);\n\t\t\t}\n\t\t});\n\n\t},\n\tdragStop: function( draggable, event ) {\n\t\tdraggable.element.parentsUntil( \"body\" ).unbind( \"scroll.droppable\" );\n\t\t//Call prepareOffsets one final time since IE does not fire return scroll events when overflow was caused by drag (see #5003)\n\t\tif( !draggable.options.refreshPositions ) {\n\t\t\t$.ui.ddmanager.prepareOffsets( draggable, event );\n\t\t}\n\t}\n};\n\n})(jQuery);\n\n(function( $, undefined ) {\n\nfunction num(v) {\n\treturn parseInt(v, 10) || 0;\n}\n\nfunction isNumber(value) {\n\treturn !isNaN(parseInt(value, 10));\n}\n\n$.widget(\"ui.resizable\", $.ui.mouse, {\n\tversion: \"1.10.2\",\n\twidgetEventPrefix: \"resize\",\n\toptions: {\n\t\talsoResize: false,\n\t\tanimate: false,\n\t\tanimateDuration: \"slow\",\n\t\tanimateEasing: \"swing\",\n\t\taspectRatio: false,\n\t\tautoHide: false,\n\t\tcontainment: false,\n\t\tghost: false,\n\t\tgrid: false,\n\t\thandles: \"e,s,se\",\n\t\thelper: false,\n\t\tmaxHeight: null,\n\t\tmaxWidth: null,\n\t\tminHeight: 10,\n\t\tminWidth: 10,\n\t\t// See #7960\n\t\tzIndex: 90,\n\n\t\t// callbacks\n\t\tresize: null,\n\t\tstart: null,\n\t\tstop: null\n\t},\n\t_create: function() {\n\n\t\tvar n, i, handle, axis, hname,\n\t\t\tthat = this,\n\t\t\to = this.options;\n\t\tthis.element.addClass(\"ui-resizable\");\n\n\t\t$.extend(this, {\n\t\t\t_aspectRatio: !!(o.aspectRatio),\n\t\t\taspectRatio: o.aspectRatio,\n\t\t\toriginalElement: this.element,\n\t\t\t_proportionallyResizeElements: [],\n\t\t\t_helper: o.helper || o.ghost || o.animate ? o.helper || \"ui-resizable-helper\" : null\n\t\t});\n\n\t\t//Wrap the element if it cannot hold child nodes\n\t\tif(this.element[0].nodeName.match(/canvas|textarea|input|select|button|img/i)) {\n\n\t\t\t//Create a wrapper element and set the wrapper to the new current internal element\n\t\t\tthis.element.wrap(\n\t\t\t\t$(\"\u003cdiv class=\u0027ui-wrapper\u0027 style=\u0027overflow: hidden;\u0027\u003e\u003c/div\u003e\").css({\n\t\t\t\t\tposition: this.element.css(\"position\"),\n\t\t\t\t\twidth: this.element.outerWidth(),\n\t\t\t\t\theight: this.element.outerHeight(),\n\t\t\t\t\ttop: this.element.css(\"top\"),\n\t\t\t\t\tleft: this.element.css(\"left\")\n\t\t\t\t})\n\t\t\t);\n\n\t\t\t//Overwrite the original this.element\n\t\t\tthis.element = this.element.parent().data(\n\t\t\t\t\"ui-resizable\", this.element.data(\"ui-resizable\")\n\t\t\t);\n\n\t\t\tthis.elementIsWrapper = true;\n\n\t\t\t//Move margins to the wrapper\n\t\t\tthis.element.css({ marginLeft: this.originalElement.css(\"marginLeft\"), marginTop: this.originalElement.css(\"marginTop\"), marginRight: this.originalElement.css(\"marginRight\"), marginBottom: this.originalElement.css(\"marginBottom\") });\n\t\t\tthis.originalElement.css({ marginLeft: 0, marginTop: 0, marginRight: 0, marginBottom: 0});\n\n\t\t\t//Prevent Safari textarea resize\n\t\t\tthis.originalResizeStyle = this.originalElement.css(\"resize\");\n\t\t\tthis.originalElement.css(\"resize\", \"none\");\n\n\t\t\t//Push the actual element to our proportionallyResize internal array\n\t\t\tthis._proportionallyResizeElements.push(this.originalElement.css({ position: \"static\", zoom: 1, display: \"block\" }));\n\n\t\t\t// avoid IE jump (hard set the margin)\n\t\t\tthis.originalElement.css({ margin: this.originalElement.css(\"margin\") });\n\n\t\t\t// fix handlers offset\n\t\t\tthis._proportionallyResize();\n\n\t\t}\n\n\t\tthis.handles = o.handles || (!$(\".ui-resizable-handle\", this.element).length ? \"e,s,se\" : { n: \".ui-resizable-n\", e: \".ui-resizable-e\", s: \".ui-resizable-s\", w: \".ui-resizable-w\", se: \".ui-resizable-se\", sw: \".ui-resizable-sw\", ne: \".ui-resizable-ne\", nw: \".ui-resizable-nw\" });\n\t\tif(this.handles.constructor === String) {\n\n\t\t\tif ( this.handles === \"all\") {\n\t\t\t\tthis.handles = \"n,e,s,w,se,sw,ne,nw\";\n\t\t\t}\n\n\t\t\tn = this.handles.split(\",\");\n\t\t\tthis.handles = {};\n\n\t\t\tfor(i = 0; i \u003c n.length; i++) {\n\n\t\t\t\thandle = $.trim(n[i]);\n\t\t\t\thname = \"ui-resizable-\"+handle;\n\t\t\t\taxis = $(\"\u003cdiv class=\u0027ui-resizable-handle \" + hname + \"\u0027\u003e\u003c/div\u003e\");\n\n\t\t\t\t// Apply zIndex to all handles - see #7960\n\t\t\t\taxis.css({ zIndex: o.zIndex });\n\n\t\t\t\t//TODO : What\u0027s going on here?\n\t\t\t\tif (\"se\" === handle) {\n\t\t\t\t\taxis.addClass(\"ui-icon ui-icon-gripsmall-diagonal-se\");\n\t\t\t\t}\n\n\t\t\t\t//Insert into internal handles object and append to element\n\t\t\t\tthis.handles[handle] = \".ui-resizable-\"+handle;\n\t\t\t\tthis.element.append(axis);\n\t\t\t}\n\n\t\t}\n\n\t\tthis._renderAxis = function(target) {\n\n\t\t\tvar i, axis, padPos, padWrapper;\n\n\t\t\ttarget = target || this.element;\n\n\t\t\tfor(i in this.handles) {\n\n\t\t\t\tif(this.handles[i].constructor === String) {\n\t\t\t\t\tthis.handles[i] = $(this.handles[i], this.element).show();\n\t\t\t\t}\n\n\t\t\t\t//Apply pad to wrapper element, needed to fix axis position (textarea, inputs, scrolls)\n\t\t\t\tif (this.elementIsWrapper \u0026\u0026 this.originalElement[0].nodeName.match(/textarea|input|select|button/i)) {\n\n\t\t\t\t\taxis = $(this.handles[i], this.element);\n\n\t\t\t\t\t//Checking the correct pad and border\n\t\t\t\t\tpadWrapper = /sw|ne|nw|se|n|s/.test(i) ? axis.outerHeight() : axis.outerWidth();\n\n\t\t\t\t\t//The padding type i have to apply...\n\t\t\t\t\tpadPos = [ \"padding\",\n\t\t\t\t\t\t/ne|nw|n/.test(i) ? \"Top\" :\n\t\t\t\t\t\t/se|sw|s/.test(i) ? \"Bottom\" :\n\t\t\t\t\t\t/^e$/.test(i) ? \"Right\" : \"Left\" ].join(\"\");\n\n\t\t\t\t\ttarget.css(padPos, padWrapper);\n\n\t\t\t\t\tthis._proportionallyResize();\n\n\t\t\t\t}\n\n\t\t\t\t//TODO: What\u0027s that good for? There\u0027s not anything to be executed left\n\t\t\t\tif(!$(this.handles[i]).length) {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t}\n\t\t};\n\n\t\t//TODO: make renderAxis a prototype function\n\t\tthis._renderAxis(this.element);\n\n\t\tthis._handles = $(\".ui-resizable-handle\", this.element)\n\t\t\t.disableSelection();\n\n\t\t//Matching axis name\n\t\tthis._handles.mouseover(function() {\n\t\t\tif (!that.resizing) {\n\t\t\t\tif (this.className) {\n\t\t\t\t\taxis = this.className.match(/ui-resizable-(se|sw|ne|nw|n|e|s|w)/i);\n\t\t\t\t}\n\t\t\t\t//Axis, default = se\n\t\t\t\tthat.axis = axis \u0026\u0026 axis[1] ? axis[1] : \"se\";\n\t\t\t}\n\t\t});\n\n\t\t//If we want to auto hide the elements\n\t\tif (o.autoHide) {\n\t\t\tthis._handles.hide();\n\t\t\t$(this.element)\n\t\t\t\t.addClass(\"ui-resizable-autohide\")\n\t\t\t\t.mouseenter(function() {\n\t\t\t\t\tif (o.disabled) {\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t\t$(this).removeClass(\"ui-resizable-autohide\");\n\t\t\t\t\tthat._handles.show();\n\t\t\t\t})\n\t\t\t\t.mouseleave(function(){\n\t\t\t\t\tif (o.disabled) {\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t\tif (!that.resizing) {\n\t\t\t\t\t\t$(this).addClass(\"ui-resizable-autohide\");\n\t\t\t\t\t\tthat._handles.hide();\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t}\n\n\t\t//Initialize the mouse interaction\n\t\tthis._mouseInit();\n\n\t},\n\n\t_destroy: function() {\n\n\t\tthis._mouseDestroy();\n\n\t\tvar wrapper,\n\t\t\t_destroy = function(exp) {\n\t\t\t\t$(exp).removeClass(\"ui-resizable ui-resizable-disabled ui-resizable-resizing\")\n\t\t\t\t\t.removeData(\"resizable\").removeData(\"ui-resizable\").unbind(\".resizable\").find(\".ui-resizable-handle\").remove();\n\t\t\t};\n\n\t\t//TODO: Unwrap at same DOM position\n\t\tif (this.elementIsWrapper) {\n\t\t\t_destroy(this.element);\n\t\t\twrapper = this.element;\n\t\t\tthis.originalElement.css({\n\t\t\t\tposition: wrapper.css(\"position\"),\n\t\t\t\twidth: wrapper.outerWidth(),\n\t\t\t\theight: wrapper.outerHeight(),\n\t\t\t\ttop: wrapper.css(\"top\"),\n\t\t\t\tleft: wrapper.css(\"left\")\n\t\t\t}).insertAfter( wrapper );\n\t\t\twrapper.remove();\n\t\t}\n\n\t\tthis.originalElement.css(\"resize\", this.originalResizeStyle);\n\t\t_destroy(this.originalElement);\n\n\t\treturn this;\n\t},\n\n\t_mouseCapture: function(event) {\n\t\tvar i, handle,\n\t\t\tcapture = false;\n\n\t\tfor (i in this.handles) {\n\t\t\thandle = $(this.handles[i])[0];\n\t\t\tif (handle === event.target || $.contains(handle, event.target)) {\n\t\t\t\tcapture = true;\n\t\t\t}\n\t\t}\n\n\t\treturn !this.options.disabled \u0026\u0026 capture;\n\t},\n\n\t_mouseStart: function(event) {\n\n\t\tvar curleft, curtop, cursor,\n\t\t\to = this.options,\n\t\t\tiniPos = this.element.position(),\n\t\t\tel = this.element;\n\n\t\tthis.resizing = true;\n\n\t\t// bugfix for http://dev.jquery.com/ticket/1749\n\t\tif ( (/absolute/).test( el.css(\"position\") ) ) {\n\t\t\tel.css({ position: \"absolute\", top: el.css(\"top\"), left: el.css(\"left\") });\n\t\t} else if (el.is(\".ui-draggable\")) {\n\t\t\tel.css({ position: \"absolute\", top: iniPos.top, left: iniPos.left });\n\t\t}\n\n\t\tthis._renderProxy();\n\n\t\tcurleft = num(this.helper.css(\"left\"));\n\t\tcurtop = num(this.helper.css(\"top\"));\n\n\t\tif (o.containment) {\n\t\t\tcurleft += $(o.containment).scrollLeft() || 0;\n\t\t\tcurtop += $(o.containment).scrollTop() || 0;\n\t\t}\n\n\t\t//Store needed variables\n\t\tthis.offset = this.helper.offset();\n\t\tthis.position = { left: curleft, top: curtop };\n\t\tthis.size = this._helper ? { width: el.outerWidth(), height: el.outerHeight() } : { width: el.width(), height: el.height() };\n\t\tthis.originalSize = this._helper ? { width: el.outerWidth(), height: el.outerHeight() } : { width: el.width(), height: el.height() };\n\t\tthis.originalPosition = { left: curleft, top: curtop };\n\t\tthis.sizeDiff = { width: el.outerWidth() - el.width(), height: el.outerHeight() - el.height() };\n\t\tthis.originalMousePosition = { left: event.pageX, top: event.pageY };\n\n\t\t//Aspect Ratio\n\t\tthis.aspectRatio = (typeof o.aspectRatio === \"number\") ? o.aspectRatio : ((this.originalSize.width / this.originalSize.height) || 1);\n\n\t\tcursor = $(\".ui-resizable-\" + this.axis).css(\"cursor\");\n\t\t$(\"body\").css(\"cursor\", cursor === \"auto\" ? this.axis + \"-resize\" : cursor);\n\n\t\tel.addClass(\"ui-resizable-resizing\");\n\t\tthis._propagate(\"start\", event);\n\t\treturn true;\n\t},\n\n\t_mouseDrag: function(event) {\n\n\t\t//Increase performance, avoid regex\n\t\tvar data,\n\t\t\tel = this.helper, props = {},\n\t\t\tsmp = this.originalMousePosition,\n\t\t\ta = this.axis,\n\t\t\tprevTop = this.position.top,\n\t\t\tprevLeft = this.position.left,\n\t\t\tprevWidth = this.size.width,\n\t\t\tprevHeight = this.size.height,\n\t\t\tdx = (event.pageX-smp.left)||0,\n\t\t\tdy = (event.pageY-smp.top)||0,\n\t\t\ttrigger = this._change[a];\n\n\t\tif (!trigger) {\n\t\t\treturn false;\n\t\t}\n\n\t\t// Calculate the attrs that will be change\n\t\tdata = trigger.apply(this, [event, dx, dy]);\n\n\t\t// Put this in the mouseDrag handler since the user can start pressing shift while resizing\n\t\tthis._updateVirtualBoundaries(event.shiftKey);\n\t\tif (this._aspectRatio || event.shiftKey) {\n\t\t\tdata = this._updateRatio(data, event);\n\t\t}\n\n\t\tdata = this._respectSize(data, event);\n\n\t\tthis._updateCache(data);\n\n\t\t// plugins callbacks need to be called first\n\t\tthis._propagate(\"resize\", event);\n\n\t\tif (this.position.top !== prevTop) {\n\t\t\tprops.top = this.position.top + \"px\";\n\t\t}\n\t\tif (this.position.left !== prevLeft) {\n\t\t\tprops.left = this.position.left + \"px\";\n\t\t}\n\t\tif (this.size.width !== prevWidth) {\n\t\t\tprops.width = this.size.width + \"px\";\n\t\t}\n\t\tif (this.size.height !== prevHeight) {\n\t\t\tprops.height = this.size.height + \"px\";\n\t\t}\n\t\tel.css(props);\n\n\t\tif (!this._helper \u0026\u0026 this._proportionallyResizeElements.length) {\n\t\t\tthis._proportionallyResize();\n\t\t}\n\n\t\t// Call the user callback if the element was resized\n\t\tif ( ! $.isEmptyObject(props) ) {\n\t\t\tthis._trigger(\"resize\", event, this.ui());\n\t\t}\n\n\t\treturn false;\n\t},\n\n\t_mouseStop: function(event) {\n\n\t\tthis.resizing = false;\n\t\tvar pr, ista, soffseth, soffsetw, s, left, top,\n\t\t\to = this.options, that = this;\n\n\t\tif(this._helper) {\n\n\t\t\tpr = this._proportionallyResizeElements;\n\t\t\tista = pr.length \u0026\u0026 (/textarea/i).test(pr[0].nodeName);\n\t\t\tsoffseth = ista \u0026\u0026 $.ui.hasScroll(pr[0], \"left\") /* TODO - jump height */ ? 0 : that.sizeDiff.height;\n\t\t\tsoffsetw = ista ? 0 : that.sizeDiff.width;\n\n\t\t\ts = { width: (that.helper.width() - soffsetw), height: (that.helper.height() - soffseth) };\n\t\t\tleft = (parseInt(that.element.css(\"left\"), 10) + (that.position.left - that.originalPosition.left)) || null;\n\t\t\ttop = (parseInt(that.element.css(\"top\"), 10) + (that.position.top - that.originalPosition.top)) || null;\n\n\t\t\tif (!o.animate) {\n\t\t\t\tthis.element.css($.extend(s, { top: top, left: left }));\n\t\t\t}\n\n\t\t\tthat.helper.height(that.size.height);\n\t\t\tthat.helper.width(that.size.width);\n\n\t\t\tif (this._helper \u0026\u0026 !o.animate) {\n\t\t\t\tthis._proportionallyResize();\n\t\t\t}\n\t\t}\n\n\t\t$(\"body\").css(\"cursor\", \"auto\");\n\n\t\tthis.element.removeClass(\"ui-resizable-resizing\");\n\n\t\tthis._propagate(\"stop\", event);\n\n\t\tif (this._helper) {\n\t\t\tthis.helper.remove();\n\t\t}\n\n\t\treturn false;\n\n\t},\n\n\t_updateVirtualBoundaries: function(forceAspectRatio) {\n\t\tvar pMinWidth, pMaxWidth, pMinHeight, pMaxHeight, b,\n\t\t\to = this.options;\n\n\t\tb = {\n\t\t\tminWidth: isNumber(o.minWidth) ? o.minWidth : 0,\n\t\t\tmaxWidth: isNumber(o.maxWidth) ? o.maxWidth : Infinity,\n\t\t\tminHeight: isNumber(o.minHeight) ? o.minHeight : 0,\n\t\t\tmaxHeight: isNumber(o.maxHeight) ? o.maxHeight : Infinity\n\t\t};\n\n\t\tif(this._aspectRatio || forceAspectRatio) {\n\t\t\t// We want to create an enclosing box whose aspect ration is the requested one\n\t\t\t// First, compute the \"projected\" size for each dimension based on the aspect ratio and other dimension\n\t\t\tpMinWidth = b.minHeight * this.aspectRatio;\n\t\t\tpMinHeight = b.minWidth / this.aspectRatio;\n\t\t\tpMaxWidth = b.maxHeight * this.aspectRatio;\n\t\t\tpMaxHeight = b.maxWidth / this.aspectRatio;\n\n\t\t\tif(pMinWidth \u003e b.minWidth) {\n\t\t\t\tb.minWidth = pMinWidth;\n\t\t\t}\n\t\t\tif(pMinHeight \u003e b.minHeight) {\n\t\t\t\tb.minHeight = pMinHeight;\n\t\t\t}\n\t\t\tif(pMaxWidth \u003c b.maxWidth) {\n\t\t\t\tb.maxWidth = pMaxWidth;\n\t\t\t}\n\t\t\tif(pMaxHeight \u003c b.maxHeight) {\n\t\t\t\tb.maxHeight = pMaxHeight;\n\t\t\t}\n\t\t}\n\t\tthis._vBoundaries = b;\n\t},\n\n\t_updateCache: function(data) {\n\t\tthis.offset = this.helper.offset();\n\t\tif (isNumber(data.left)) {\n\t\t\tthis.position.left = data.left;\n\t\t}\n\t\tif (isNumber(data.top)) {\n\t\t\tthis.position.top = data.top;\n\t\t}\n\t\tif (isNumber(data.height)) {\n\t\t\tthis.size.height = data.height;\n\t\t}\n\t\tif (isNumber(data.width)) {\n\t\t\tthis.size.width = data.width;\n\t\t}\n\t},\n\n\t_updateRatio: function( data ) {\n\n\t\tvar cpos = this.position,\n\t\t\tcsize = this.size,\n\t\t\ta = this.axis;\n\n\t\tif (isNumber(data.height)) {\n\t\t\tdata.width = (data.height * this.aspectRatio);\n\t\t} else if (isNumber(data.width)) {\n\t\t\tdata.height = (data.width / this.aspectRatio);\n\t\t}\n\n\t\tif (a === \"sw\") {\n\t\t\tdata.left = cpos.left + (csize.width - data.width);\n\t\t\tdata.top = null;\n\t\t}\n\t\tif (a === \"nw\") {\n\t\t\tdata.top = cpos.top + (csize.height - data.height);\n\t\t\tdata.left = cpos.left + (csize.width - data.width);\n\t\t}\n\n\t\treturn data;\n\t},\n\n\t_respectSize: function( data ) {\n\n\t\tvar o = this._vBoundaries,\n\t\t\ta = this.axis,\n\t\t\tismaxw = isNumber(data.width) \u0026\u0026 o.maxWidth \u0026\u0026 (o.maxWidth \u003c data.width), ismaxh = isNumber(data.height) \u0026\u0026 o.maxHeight \u0026\u0026 (o.maxHeight \u003c data.height),\n\t\t\tisminw = isNumber(data.width) \u0026\u0026 o.minWidth \u0026\u0026 (o.minWidth \u003e data.width), isminh = isNumber(data.height) \u0026\u0026 o.minHeight \u0026\u0026 (o.minHeight \u003e data.height),\n\t\t\tdw = this.originalPosition.left + this.originalSize.width,\n\t\t\tdh = this.position.top + this.size.height,\n\t\t\tcw = /sw|nw|w/.test(a), ch = /nw|ne|n/.test(a);\n\t\tif (isminw) {\n\t\t\tdata.width = o.minWidth;\n\t\t}\n\t\tif (isminh) {\n\t\t\tdata.height = o.minHeight;\n\t\t}\n\t\tif (ismaxw) {\n\t\t\tdata.width = o.maxWidth;\n\t\t}\n\t\tif (ismaxh) {\n\t\t\tdata.height = o.maxHeight;\n\t\t}\n\n\t\tif (isminw \u0026\u0026 cw) {\n\t\t\tdata.left = dw - o.minWidth;\n\t\t}\n\t\tif (ismaxw \u0026\u0026 cw) {\n\t\t\tdata.left = dw - o.maxWidth;\n\t\t}\n\t\tif (isminh \u0026\u0026 ch) {\n\t\t\tdata.top = dh - o.minHeight;\n\t\t}\n\t\tif (ismaxh \u0026\u0026 ch) {\n\t\t\tdata.top = dh - o.maxHeight;\n\t\t}\n\n\t\t// fixing jump error on top/left - bug #2330\n\t\tif (!data.width \u0026\u0026 !data.height \u0026\u0026 !data.left \u0026\u0026 data.top) {\n\t\t\tdata.top = null;\n\t\t} else if (!data.width \u0026\u0026 !data.height \u0026\u0026 !data.top \u0026\u0026 data.left) {\n\t\t\tdata.left = null;\n\t\t}\n\n\t\treturn data;\n\t},\n\n\t_proportionallyResize: function() {\n\n\t\tif (!this._proportionallyResizeElements.length) {\n\t\t\treturn;\n\t\t}\n\n\t\tvar i, j, borders, paddings, prel,\n\t\t\telement = this.helper || this.element;\n\n\t\tfor ( i=0; i \u003c this._proportionallyResizeElements.length; i++) {\n\n\t\t\tprel = this._proportionallyResizeElements[i];\n\n\t\t\tif (!this.borderDif) {\n\t\t\t\tthis.borderDif = [];\n\t\t\t\tborders = [prel.css(\"borderTopWidth\"), prel.css(\"borderRightWidth\"), prel.css(\"borderBottomWidth\"), prel.css(\"borderLeftWidth\")];\n\t\t\t\tpaddings = [prel.css(\"paddingTop\"), prel.css(\"paddingRight\"), prel.css(\"paddingBottom\"), prel.css(\"paddingLeft\")];\n\n\t\t\t\tfor ( j = 0; j \u003c borders.length; j++ ) {\n\t\t\t\t\tthis.borderDif[ j ] = ( parseInt( borders[ j ], 10 ) || 0 ) + ( parseInt( paddings[ j ], 10 ) || 0 );\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tprel.css({\n\t\t\t\theight: (element.height() - this.borderDif[0] - this.borderDif[2]) || 0,\n\t\t\t\twidth: (element.width() - this.borderDif[1] - this.borderDif[3]) || 0\n\t\t\t});\n\n\t\t}\n\n\t},\n\n\t_renderProxy: function() {\n\n\t\tvar el = this.element, o = this.options;\n\t\tthis.elementOffset = el.offset();\n\n\t\tif(this._helper) {\n\n\t\t\tthis.helper = this.helper || $(\"\u003cdiv style=\u0027overflow:hidden;\u0027\u003e\u003c/div\u003e\");\n\n\t\t\tthis.helper.addClass(this._helper).css({\n\t\t\t\twidth: this.element.outerWidth() - 1,\n\t\t\t\theight: this.element.outerHeight() - 1,\n\t\t\t\tposition: \"absolute\",\n\t\t\t\tleft: this.elementOffset.left +\"px\",\n\t\t\t\ttop: this.elementOffset.top +\"px\",\n\t\t\t\tzIndex: ++o.zIndex //TODO: Don\u0027t modify option\n\t\t\t});\n\n\t\t\tthis.helper\n\t\t\t\t.appendTo(\"body\")\n\t\t\t\t.disableSelection();\n\n\t\t} else {\n\t\t\tthis.helper = this.element;\n\t\t}\n\n\t},\n\n\t_change: {\n\t\te: function(event, dx) {\n\t\t\treturn { width: this.originalSize.width + dx };\n\t\t},\n\t\tw: function(event, dx) {\n\t\t\tvar cs = this.originalSize, sp = this.originalPosition;\n\t\t\treturn { left: sp.left + dx, width: cs.width - dx };\n\t\t},\n\t\tn: function(event, dx, dy) {\n\t\t\tvar cs = this.originalSize, sp = this.originalPosition;\n\t\t\treturn { top: sp.top + dy, height: cs.height - dy };\n\t\t},\n\t\ts: function(event, dx, dy) {\n\t\t\treturn { height: this.originalSize.height + dy };\n\t\t},\n\t\tse: function(event, dx, dy) {\n\t\t\treturn $.extend(this._change.s.apply(this, arguments), this._change.e.apply(this, [event, dx, dy]));\n\t\t},\n\t\tsw: function(event, dx, dy) {\n\t\t\treturn $.extend(this._change.s.apply(this, arguments), this._change.w.apply(this, [event, dx, dy]));\n\t\t},\n\t\tne: function(event, dx, dy) {\n\t\t\treturn $.extend(this._change.n.apply(this, arguments), this._change.e.apply(this, [event, dx, dy]));\n\t\t},\n\t\tnw: function(event, dx, dy) {\n\t\t\treturn $.extend(this._change.n.apply(this, arguments), this._change.w.apply(this, [event, dx, dy]));\n\t\t}\n\t},\n\n\t_propagate: function(n, event) {\n\t\t$.ui.plugin.call(this, n, [event, this.ui()]);\n\t\t(n !== \"resize\" \u0026\u0026 this._trigger(n, event, this.ui()));\n\t},\n\n\tplugins: {},\n\n\tui: function() {\n\t\treturn {\n\t\t\toriginalElement: this.originalElement,\n\t\t\telement: this.element,\n\t\t\thelper: this.helper,\n\t\t\tposition: this.position,\n\t\t\tsize: this.size,\n\t\t\toriginalSize: this.originalSize,\n\t\t\toriginalPosition: this.originalPosition\n\t\t};\n\t}\n\n});\n\n/*\n * Resizable Extensions\n */\n\n$.ui.plugin.add(\"resizable\", \"animate\", {\n\n\tstop: function( event ) {\n\t\tvar that = $(this).data(\"ui-resizable\"),\n\t\t\to = that.options,\n\t\t\tpr = that._proportionallyResizeElements,\n\t\t\tista = pr.length \u0026\u0026 (/textarea/i).test(pr[0].nodeName),\n\t\t\tsoffseth = ista \u0026\u0026 $.ui.hasScroll(pr[0], \"left\") /* TODO - jump height */ ? 0 : that.sizeDiff.height,\n\t\t\tsoffsetw = ista ? 0 : that.sizeDiff.width,\n\t\t\tstyle = { width: (that.size.width - soffsetw), height: (that.size.height - soffseth) },\n\t\t\tleft = (parseInt(that.element.css(\"left\"), 10) + (that.position.left - that.originalPosition.left)) || null,\n\t\t\ttop = (parseInt(that.element.css(\"top\"), 10) + (that.position.top - that.originalPosition.top)) || null;\n\n\t\tthat.element.animate(\n\t\t\t$.extend(style, top \u0026\u0026 left ? { top: top, left: left } : {}), {\n\t\t\t\tduration: o.animateDuration,\n\t\t\t\teasing: o.animateEasing,\n\t\t\t\tstep: function() {\n\n\t\t\t\t\tvar data = {\n\t\t\t\t\t\twidth: parseInt(that.element.css(\"width\"), 10),\n\t\t\t\t\t\theight: parseInt(that.element.css(\"height\"), 10),\n\t\t\t\t\t\ttop: parseInt(that.element.css(\"top\"), 10),\n\t\t\t\t\t\tleft: parseInt(that.element.css(\"left\"), 10)\n\t\t\t\t\t};\n\n\t\t\t\t\tif (pr \u0026\u0026 pr.length) {\n\t\t\t\t\t\t$(pr[0]).css({ width: data.width, height: data.height });\n\t\t\t\t\t}\n\n\t\t\t\t\t// propagating resize, and updating values for each animation step\n\t\t\t\t\tthat._updateCache(data);\n\t\t\t\t\tthat._propagate(\"resize\", event);\n\n\t\t\t\t}\n\t\t\t}\n\t\t);\n\t}\n\n});\n\n$.ui.plugin.add(\"resizable\", \"containment\", {\n\n\tstart: function() {\n\t\tvar element, p, co, ch, cw, width, height,\n\t\t\tthat = $(this).data(\"ui-resizable\"),\n\t\t\to = that.options,\n\t\t\tel = that.element,\n\t\t\toc = o.containment,\n\t\t\tce = (oc instanceof $) ? oc.get(0) : (/parent/.test(oc)) ? el.parent().get(0) : oc;\n\n\t\tif (!ce) {\n\t\t\treturn;\n\t\t}\n\n\t\tthat.containerElement = $(ce);\n\n\t\tif (/document/.test(oc) || oc === document) {\n\t\t\tthat.containerOffset = { left: 0, top: 0 };\n\t\t\tthat.containerPosition = { left: 0, top: 0 };\n\n\t\t\tthat.parentData = {\n\t\t\t\telement: $(document), left: 0, top: 0,\n\t\t\t\twidth: $(document).width(), height: $(document).height() || document.body.parentNode.scrollHeight\n\t\t\t};\n\t\t}\n\n\t\t// i\u0027m a node, so compute top, left, right, bottom\n\t\telse {\n\t\t\telement = $(ce);\n\t\t\tp = [];\n\t\t\t$([ \"Top\", \"Right\", \"Left\", \"Bottom\" ]).each(function(i, name) { p[i] = num(element.css(\"padding\" + name)); });\n\n\t\t\tthat.containerOffset = element.offset();\n\t\t\tthat.containerPosition = element.position();\n\t\t\tthat.containerSize = { height: (element.innerHeight() - p[3]), width: (element.innerWidth() - p[1]) };\n\n\t\t\tco = that.containerOffset;\n\t\t\tch = that.containerSize.height;\n\t\t\tcw = that.containerSize.width;\n\t\t\twidth = ($.ui.hasScroll(ce, \"left\") ? ce.scrollWidth : cw );\n\t\t\theight = ($.ui.hasScroll(ce) ? ce.scrollHeight : ch);\n\n\t\t\tthat.parentData = {\n\t\t\t\telement: ce, left: co.left, top: co.top, width: width, height: height\n\t\t\t};\n\t\t}\n\t},\n\n\tresize: function( event ) {\n\t\tvar woset, hoset, isParent, isOffsetRelative,\n\t\t\tthat = $(this).data(\"ui-resizable\"),\n\t\t\to = that.options,\n\t\t\tco = that.containerOffset, cp = that.position,\n\t\t\tpRatio = that._aspectRatio || event.shiftKey,\n\t\t\tcop = { top:0, left:0 }, ce = that.containerElement;\n\n\t\tif (ce[0] !== document \u0026\u0026 (/static/).test(ce.css(\"position\"))) {\n\t\t\tcop = co;\n\t\t}\n\n\t\tif (cp.left \u003c (that._helper ? co.left : 0)) {\n\t\t\tthat.size.width = that.size.width + (that._helper ? (that.position.left - co.left) : (that.position.left - cop.left));\n\t\t\tif (pRatio) {\n\t\t\t\tthat.size.height = that.size.width / that.aspectRatio;\n\t\t\t}\n\t\t\tthat.position.left = o.helper ? co.left : 0;\n\t\t}\n\n\t\tif (cp.top \u003c (that._helper ? co.top : 0)) {\n\t\t\tthat.size.height = that.size.height + (that._helper ? (that.position.top - co.top) : that.position.top);\n\t\t\tif (pRatio) {\n\t\t\t\tthat.size.width = that.size.height * that.aspectRatio;\n\t\t\t}\n\t\t\tthat.position.top = that._helper ? co.top : 0;\n\t\t}\n\n\t\tthat.offset.left = that.parentData.left+that.position.left;\n\t\tthat.offset.top = that.parentData.top+that.position.top;\n\n\t\twoset = Math.abs( (that._helper ? that.offset.left - cop.left : (that.offset.left - cop.left)) + that.sizeDiff.width );\n\t\thoset = Math.abs( (that._helper ? that.offset.top - cop.top : (that.offset.top - co.top)) + that.sizeDiff.height );\n\n\t\tisParent = that.containerElement.get(0) === that.element.parent().get(0);\n\t\tisOffsetRelative = /relative|absolute/.test(that.containerElement.css(\"position\"));\n\n\t\tif(isParent \u0026\u0026 isOffsetRelative) {\n\t\t\twoset -= that.parentData.left;\n\t\t}\n\n\t\tif (woset + that.size.width \u003e= that.parentData.width) {\n\t\t\tthat.size.width = that.parentData.width - woset;\n\t\t\tif (pRatio) {\n\t\t\t\tthat.size.height = that.size.width / that.aspectRatio;\n\t\t\t}\n\t\t}\n\n\t\tif (hoset + that.size.height \u003e= that.parentData.height) {\n\t\t\tthat.size.height = that.parentData.height - hoset;\n\t\t\tif (pRatio) {\n\t\t\t\tthat.size.width = that.size.height * that.aspectRatio;\n\t\t\t}\n\t\t}\n\t},\n\n\tstop: function(){\n\t\tvar that = $(this).data(\"ui-resizable\"),\n\t\t\to = that.options,\n\t\t\tco = that.containerOffset,\n\t\t\tcop = that.containerPosition,\n\t\t\tce = that.containerElement,\n\t\t\thelper = $(that.helper),\n\t\t\tho = helper.offset(),\n\t\t\tw = helper.outerWidth() - that.sizeDiff.width,\n\t\t\th = helper.outerHeight() - that.sizeDiff.height;\n\n\t\tif (that._helper \u0026\u0026 !o.animate \u0026\u0026 (/relative/).test(ce.css(\"position\"))) {\n\t\t\t$(this).css({ left: ho.left - cop.left - co.left, width: w, height: h });\n\t\t}\n\n\t\tif (that._helper \u0026\u0026 !o.animate \u0026\u0026 (/static/).test(ce.css(\"position\"))) {\n\t\t\t$(this).css({ left: ho.left - cop.left - co.left, width: w, height: h });\n\t\t}\n\n\t}\n});\n\n$.ui.plugin.add(\"resizable\", \"alsoResize\", {\n\n\tstart: function () {\n\t\tvar that = $(this).data(\"ui-resizable\"),\n\t\t\to = that.options,\n\t\t\t_store = function (exp) {\n\t\t\t\t$(exp).each(function() {\n\t\t\t\t\tvar el = $(this);\n\t\t\t\t\tel.data(\"ui-resizable-alsoresize\", {\n\t\t\t\t\t\twidth: parseInt(el.width(), 10), height: parseInt(el.height(), 10),\n\t\t\t\t\t\tleft: parseInt(el.css(\"left\"), 10), top: parseInt(el.css(\"top\"), 10)\n\t\t\t\t\t});\n\t\t\t\t});\n\t\t\t};\n\n\t\tif (typeof(o.alsoResize) === \"object\" \u0026\u0026 !o.alsoResize.parentNode) {\n\t\t\tif (o.alsoResize.length) { o.alsoResize = o.alsoResize[0]; _store(o.alsoResize); }\n\t\t\telse { $.each(o.alsoResize, function (exp) { _store(exp); }); }\n\t\t}else{\n\t\t\t_store(o.alsoResize);\n\t\t}\n\t},\n\n\tresize: function (event, ui) {\n\t\tvar that = $(this).data(\"ui-resizable\"),\n\t\t\to = that.options,\n\t\t\tos = that.originalSize,\n\t\t\top = that.originalPosition,\n\t\t\tdelta = {\n\t\t\t\theight: (that.size.height - os.height) || 0, width: (that.size.width - os.width) || 0,\n\t\t\t\ttop: (that.position.top - op.top) || 0, left: (that.position.left - op.left) || 0\n\t\t\t},\n\n\t\t\t_alsoResize = function (exp, c) {\n\t\t\t\t$(exp).each(function() {\n\t\t\t\t\tvar el = $(this), start = $(this).data(\"ui-resizable-alsoresize\"), style = {},\n\t\t\t\t\t\tcss = c \u0026\u0026 c.length ? c : el.parents(ui.originalElement[0]).length ? [\"width\", \"height\"] : [\"width\", \"height\", \"top\", \"left\"];\n\n\t\t\t\t\t$.each(css, function (i, prop) {\n\t\t\t\t\t\tvar sum = (start[prop]||0) + (delta[prop]||0);\n\t\t\t\t\t\tif (sum \u0026\u0026 sum \u003e= 0) {\n\t\t\t\t\t\t\tstyle[prop] = sum || null;\n\t\t\t\t\t\t}\n\t\t\t\t\t});\n\n\t\t\t\t\tel.css(style);\n\t\t\t\t});\n\t\t\t};\n\n\t\tif (typeof(o.alsoResize) === \"object\" \u0026\u0026 !o.alsoResize.nodeType) {\n\t\t\t$.each(o.alsoResize, function (exp, c) { _alsoResize(exp, c); });\n\t\t}else{\n\t\t\t_alsoResize(o.alsoResize);\n\t\t}\n\t},\n\n\tstop: function () {\n\t\t$(this).removeData(\"resizable-alsoresize\");\n\t}\n});\n\n$.ui.plugin.add(\"resizable\", \"ghost\", {\n\n\tstart: function() {\n\n\t\tvar that = $(this).data(\"ui-resizable\"), o = that.options, cs = that.size;\n\n\t\tthat.ghost = that.originalElement.clone();\n\t\tthat.ghost\n\t\t\t.css({ opacity: 0.25, display: \"block\", position: \"relative\", height: cs.height, width: cs.width, margin: 0, left: 0, top: 0 })\n\t\t\t.addClass(\"ui-resizable-ghost\")\n\t\t\t.addClass(typeof o.ghost === \"string\" ? o.ghost : \"\");\n\n\t\tthat.ghost.appendTo(that.helper);\n\n\t},\n\n\tresize: function(){\n\t\tvar that = $(this).data(\"ui-resizable\");\n\t\tif (that.ghost) {\n\t\t\tthat.ghost.css({ position: \"relative\", height: that.size.height, width: that.size.width });\n\t\t}\n\t},\n\n\tstop: function() {\n\t\tvar that = $(this).data(\"ui-resizable\");\n\t\tif (that.ghost \u0026\u0026 that.helper) {\n\t\t\tthat.helper.get(0).removeChild(that.ghost.get(0));\n\t\t}\n\t}\n\n});\n\n$.ui.plugin.add(\"resizable\", \"grid\", {\n\n\tresize: function() {\n\t\tvar that = $(this).data(\"ui-resizable\"),\n\t\t\to = that.options,\n\t\t\tcs = that.size,\n\t\t\tos = that.originalSize,\n\t\t\top = that.originalPosition,\n\t\t\ta = that.axis,\n\t\t\tgrid = typeof o.grid === \"number\" ? [o.grid, o.grid] : o.grid,\n\t\t\tgridX = (grid[0]||1),\n\t\t\tgridY = (grid[1]||1),\n\t\t\tox = Math.round((cs.width - os.width) / gridX) * gridX,\n\t\t\toy = Math.round((cs.height - os.height) / gridY) * gridY,\n\t\t\tnewWidth = os.width + ox,\n\t\t\tnewHeight = os.height + oy,\n\t\t\tisMaxWidth = o.maxWidth \u0026\u0026 (o.maxWidth \u003c newWidth),\n\t\t\tisMaxHeight = o.maxHeight \u0026\u0026 (o.maxHeight \u003c newHeight),\n\t\t\tisMinWidth = o.minWidth \u0026\u0026 (o.minWidth \u003e newWidth),\n\t\t\tisMinHeight = o.minHeight \u0026\u0026 (o.minHeight \u003e newHeight);\n\n\t\to.grid = grid;\n\n\t\tif (isMinWidth) {\n\t\t\tnewWidth = newWidth + gridX;\n\t\t}\n\t\tif (isMinHeight) {\n\t\t\tnewHeight = newHeight + gridY;\n\t\t}\n\t\tif (isMaxWidth) {\n\t\t\tnewWidth = newWidth - gridX;\n\t\t}\n\t\tif (isMaxHeight) {\n\t\t\tnewHeight = newHeight - gridY;\n\t\t}\n\n\t\tif (/^(se|s|e)$/.test(a)) {\n\t\t\tthat.size.width = newWidth;\n\t\t\tthat.size.height = newHeight;\n\t\t} else if (/^(ne)$/.test(a)) {\n\t\t\tthat.size.width = newWidth;\n\t\t\tthat.size.height = newHeight;\n\t\t\tthat.position.top = op.top - oy;\n\t\t} else if (/^(sw)$/.test(a)) {\n\t\t\tthat.size.width = newWidth;\n\t\t\tthat.size.height = newHeight;\n\t\t\tthat.position.left = op.left - ox;\n\t\t} else {\n\t\t\tthat.size.width = newWidth;\n\t\t\tthat.size.height = newHeight;\n\t\t\tthat.position.top = op.top - oy;\n\t\t\tthat.position.left = op.left - ox;\n\t\t}\n\t}\n\n});\n\n})(jQuery);\n\n(function( $, undefined ) {\n\n$.widget(\"ui.selectable\", $.ui.mouse, {\n\tversion: \"1.10.2\",\n\toptions: {\n\t\tappendTo: \"body\",\n\t\tautoRefresh: true,\n\t\tdistance: 0,\n\t\tfilter: \"*\",\n\t\ttolerance: \"touch\",\n\n\t\t// callbacks\n\t\tselected: null,\n\t\tselecting: null,\n\t\tstart: null,\n\t\tstop: null,\n\t\tunselected: null,\n\t\tunselecting: null\n\t},\n\t_create: function() {\n\t\tvar selectees,\n\t\t\tthat = this;\n\n\t\tthis.element.addClass(\"ui-selectable\");\n\n\t\tthis.dragged = false;\n\n\t\t// cache selectee children based on filter\n\t\tthis.refresh = function() {\n\t\t\tselectees = $(that.options.filter, that.element[0]);\n\t\t\tselectees.addClass(\"ui-selectee\");\n\t\t\tselectees.each(function() {\n\t\t\t\tvar $this = $(this),\n\t\t\t\t\tpos = $this.offset();\n\t\t\t\t$.data(this, \"selectable-item\", {\n\t\t\t\t\telement: this,\n\t\t\t\t\t$element: $this,\n\t\t\t\t\tleft: pos.left,\n\t\t\t\t\ttop: pos.top,\n\t\t\t\t\tright: pos.left + $this.outerWidth(),\n\t\t\t\t\tbottom: pos.top + $this.outerHeight(),\n\t\t\t\t\tstartselected: false,\n\t\t\t\t\tselected: $this.hasClass(\"ui-selected\"),\n\t\t\t\t\tselecting: $this.hasClass(\"ui-selecting\"),\n\t\t\t\t\tunselecting: $this.hasClass(\"ui-unselecting\")\n\t\t\t\t});\n\t\t\t});\n\t\t};\n\t\tthis.refresh();\n\n\t\tthis.selectees = selectees.addClass(\"ui-selectee\");\n\n\t\tthis._mouseInit();\n\n\t\tthis.helper = $(\"\u003cdiv class=\u0027ui-selectable-helper\u0027\u003e\u003c/div\u003e\");\n\t},\n\n\t_destroy: function() {\n\t\tthis.selectees\n\t\t\t.removeClass(\"ui-selectee\")\n\t\t\t.removeData(\"selectable-item\");\n\t\tthis.element\n\t\t\t.removeClass(\"ui-selectable ui-selectable-disabled\");\n\t\tthis._mouseDestroy();\n\t},\n\n\t_mouseStart: function(event) {\n\t\tvar that = this,\n\t\t\toptions = this.options;\n\n\t\tthis.opos = [event.pageX, event.pageY];\n\n\t\tif (this.options.disabled) {\n\t\t\treturn;\n\t\t}\n\n\t\tthis.selectees = $(options.filter, this.element[0]);\n\n\t\tthis._trigger(\"start\", event);\n\n\t\t$(options.appendTo).append(this.helper);\n\t\t// position helper (lasso)\n\t\tthis.helper.css({\n\t\t\t\"left\": event.pageX,\n\t\t\t\"top\": event.pageY,\n\t\t\t\"width\": 0,\n\t\t\t\"height\": 0\n\t\t});\n\n\t\tif (options.autoRefresh) {\n\t\t\tthis.refresh();\n\t\t}\n\n\t\tthis.selectees.filter(\".ui-selected\").each(function() {\n\t\t\tvar selectee = $.data(this, \"selectable-item\");\n\t\t\tselectee.startselected = true;\n\t\t\tif (!event.metaKey \u0026\u0026 !event.ctrlKey) {\n\t\t\t\tselectee.$element.removeClass(\"ui-selected\");\n\t\t\t\tselectee.selected = false;\n\t\t\t\tselectee.$element.addClass(\"ui-unselecting\");\n\t\t\t\tselectee.unselecting = true;\n\t\t\t\t// selectable UNSELECTING callback\n\t\t\t\tthat._trigger(\"unselecting\", event, {\n\t\t\t\t\tunselecting: selectee.element\n\t\t\t\t});\n\t\t\t}\n\t\t});\n\n\t\t$(event.target).parents().addBack().each(function() {\n\t\t\tvar doSelect,\n\t\t\t\tselectee = $.data(this, \"selectable-item\");\n\t\t\tif (selectee) {\n\t\t\t\tdoSelect = (!event.metaKey \u0026\u0026 !event.ctrlKey) || !selectee.$element.hasClass(\"ui-selected\");\n\t\t\t\tselectee.$element\n\t\t\t\t\t.removeClass(doSelect ? \"ui-unselecting\" : \"ui-selected\")\n\t\t\t\t\t.addClass(doSelect ? \"ui-selecting\" : \"ui-unselecting\");\n\t\t\t\tselectee.unselecting = !doSelect;\n\t\t\t\tselectee.selecting = doSelect;\n\t\t\t\tselectee.selected = doSelect;\n\t\t\t\t// selectable (UN)SELECTING callback\n\t\t\t\tif (doSelect) {\n\t\t\t\t\tthat._trigger(\"selecting\", event, {\n\t\t\t\t\t\tselecting: selectee.element\n\t\t\t\t\t});\n\t\t\t\t} else {\n\t\t\t\t\tthat._trigger(\"unselecting\", event, {\n\t\t\t\t\t\tunselecting: selectee.element\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t\treturn false;\n\t\t\t}\n\t\t});\n\n\t},\n\n\t_mouseDrag: function(event) {\n\n\t\tthis.dragged = true;\n\n\t\tif (this.options.disabled) {\n\t\t\treturn;\n\t\t}\n\n\t\tvar tmp,\n\t\t\tthat = this,\n\t\t\toptions = this.options,\n\t\t\tx1 = this.opos[0],\n\t\t\ty1 = this.opos[1],\n\t\t\tx2 = event.pageX,\n\t\t\ty2 = event.pageY;\n\n\t\tif (x1 \u003e x2) { tmp = x2; x2 = x1; x1 = tmp; }\n\t\tif (y1 \u003e y2) { tmp = y2; y2 = y1; y1 = tmp; }\n\t\tthis.helper.css({left: x1, top: y1, width: x2-x1, height: y2-y1});\n\n\t\tthis.selectees.each(function() {\n\t\t\tvar selectee = $.data(this, \"selectable-item\"),\n\t\t\t\thit = false;\n\n\t\t\t//prevent helper from being selected if appendTo: selectable\n\t\t\tif (!selectee || selectee.element === that.element[0]) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif (options.tolerance === \"touch\") {\n\t\t\t\thit = ( !(selectee.left \u003e x2 || selectee.right \u003c x1 || selectee.top \u003e y2 || selectee.bottom \u003c y1) );\n\t\t\t} else if (options.tolerance === \"fit\") {\n\t\t\t\thit = (selectee.left \u003e x1 \u0026\u0026 selectee.right \u003c x2 \u0026\u0026 selectee.top \u003e y1 \u0026\u0026 selectee.bottom \u003c y2);\n\t\t\t}\n\n\t\t\tif (hit) {\n\t\t\t\t// SELECT\n\t\t\t\tif (selectee.selected) {\n\t\t\t\t\tselectee.$element.removeClass(\"ui-selected\");\n\t\t\t\t\tselectee.selected = false;\n\t\t\t\t}\n\t\t\t\tif (selectee.unselecting) {\n\t\t\t\t\tselectee.$element.removeClass(\"ui-unselecting\");\n\t\t\t\t\tselectee.unselecting = false;\n\t\t\t\t}\n\t\t\t\tif (!selectee.selecting) {\n\t\t\t\t\tselectee.$element.addClass(\"ui-selecting\");\n\t\t\t\t\tselectee.selecting = true;\n\t\t\t\t\t// selectable SELECTING callback\n\t\t\t\t\tthat._trigger(\"selecting\", event, {\n\t\t\t\t\t\tselecting: selectee.element\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\t// UNSELECT\n\t\t\t\tif (selectee.selecting) {\n\t\t\t\t\tif ((event.metaKey || event.ctrlKey) \u0026\u0026 selectee.startselected) {\n\t\t\t\t\t\tselectee.$element.removeClass(\"ui-selecting\");\n\t\t\t\t\t\tselectee.selecting = false;\n\t\t\t\t\t\tselectee.$element.addClass(\"ui-selected\");\n\t\t\t\t\t\tselectee.selected = true;\n\t\t\t\t\t} else {\n\t\t\t\t\t\tselectee.$element.removeClass(\"ui-selecting\");\n\t\t\t\t\t\tselectee.selecting = false;\n\t\t\t\t\t\tif (selectee.startselected) {\n\t\t\t\t\t\t\tselectee.$element.addClass(\"ui-unselecting\");\n\t\t\t\t\t\t\tselectee.unselecting = true;\n\t\t\t\t\t\t}\n\t\t\t\t\t\t// selectable UNSELECTING callback\n\t\t\t\t\t\tthat._trigger(\"unselecting\", event, {\n\t\t\t\t\t\t\tunselecting: selectee.element\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif (selectee.selected) {\n\t\t\t\t\tif (!event.metaKey \u0026\u0026 !event.ctrlKey \u0026\u0026 !selectee.startselected) {\n\t\t\t\t\t\tselectee.$element.removeClass(\"ui-selected\");\n\t\t\t\t\t\tselectee.selected = false;\n\n\t\t\t\t\t\tselectee.$element.addClass(\"ui-unselecting\");\n\t\t\t\t\t\tselectee.unselecting = true;\n\t\t\t\t\t\t// selectable UNSELECTING callback\n\t\t\t\t\t\tthat._trigger(\"unselecting\", event, {\n\t\t\t\t\t\t\tunselecting: selectee.element\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\n\t\treturn false;\n\t},\n\n\t_mouseStop: function(event) {\n\t\tvar that = this;\n\n\t\tthis.dragged = false;\n\n\t\t$(\".ui-unselecting\", this.element[0]).each(function() {\n\t\t\tvar selectee = $.data(this, \"selectable-item\");\n\t\t\tselectee.$element.removeClass(\"ui-unselecting\");\n\t\t\tselectee.unselecting = false;\n\t\t\tselectee.startselected = false;\n\t\t\tthat._trigger(\"unselected\", event, {\n\t\t\t\tunselected: selectee.element\n\t\t\t});\n\t\t});\n\t\t$(\".ui-selecting\", this.element[0]).each(function() {\n\t\t\tvar selectee = $.data(this, \"selectable-item\");\n\t\t\tselectee.$element.removeClass(\"ui-selecting\").addClass(\"ui-selected\");\n\t\t\tselectee.selecting = false;\n\t\t\tselectee.selected = true;\n\t\t\tselectee.startselected = true;\n\t\t\tthat._trigger(\"selected\", event, {\n\t\t\t\tselected: selectee.element\n\t\t\t});\n\t\t});\n\t\tthis._trigger(\"stop\", event);\n\n\t\tthis.helper.remove();\n\n\t\treturn false;\n\t}\n\n});\n\n})(jQuery);\n\n(function( $, undefined ) {\n\n/*jshint loopfunc: true */\n\nfunction isOverAxis( x, reference, size ) {\n\treturn ( x \u003e reference ) \u0026\u0026 ( x \u003c ( reference + size ) );\n}\n\nfunction isFloating(item) {\n\treturn (/left|right/).test(item.css(\"float\")) || (/inline|table-cell/).test(item.css(\"display\"));\n}\n\n$.widget(\"ui.sortable\", $.ui.mouse, {\n\tversion: \"1.10.2\",\n\twidgetEventPrefix: \"sort\",\n\tready: false,\n\toptions: {\n\t\tappendTo: \"parent\",\n\t\taxis: false,\n\t\tconnectWith: false,\n\t\tcontainment: false,\n\t\tcursor: \"auto\",\n\t\tcursorAt: false,\n\t\tdropOnEmpty: true,\n\t\tforcePlaceholderSize: false,\n\t\tforceHelperSize: false,\n\t\tgrid: false,\n\t\thandle: false,\n\t\thelper: \"original\",\n\t\titems: \"\u003e *\",\n\t\topacity: false,\n\t\tplaceholder: false,\n\t\trevert: false,\n\t\tscroll: true,\n\t\tscrollSensitivity: 20,\n\t\tscrollSpeed: 20,\n\t\tscope: \"default\",\n\t\ttolerance: \"intersect\",\n\t\tzIndex: 1000,\n\n\t\t// callbacks\n\t\tactivate: null,\n\t\tbeforeStop: null,\n\t\tchange: null,\n\t\tdeactivate: null,\n\t\tout: null,\n\t\tover: null,\n\t\treceive: null,\n\t\tremove: null,\n\t\tsort: null,\n\t\tstart: null,\n\t\tstop: null,\n\t\tupdate: null\n\t},\n\t_create: function() {\n\n\t\tvar o = this.options;\n\t\tthis.containerCache = {};\n\t\tthis.element.addClass(\"ui-sortable\");\n\n\t\t//Get the items\n\t\tthis.refresh();\n\n\t\t//Let\u0027s determine if the items are being displayed horizontally\n\t\tthis.floating = this.items.length ? o.axis === \"x\" || isFloating(this.items[0].item) : false;\n\n\t\t//Let\u0027s determine the parent\u0027s offset\n\t\tthis.offset = this.element.offset();\n\n\t\t//Initialize mouse events for interaction\n\t\tthis._mouseInit();\n\n\t\t//We\u0027re ready to go\n\t\tthis.ready = true;\n\n\t},\n\n\t_destroy: function() {\n\t\tthis.element\n\t\t\t.removeClass(\"ui-sortable ui-sortable-disabled\");\n\t\tthis._mouseDestroy();\n\n\t\tfor ( var i = this.items.length - 1; i \u003e= 0; i-- ) {\n\t\t\tthis.items[i].item.removeData(this.widgetName + \"-item\");\n\t\t}\n\n\t\treturn this;\n\t},\n\n\t_setOption: function(key, value){\n\t\tif ( key === \"disabled\" ) {\n\t\t\tthis.options[ key ] = value;\n\n\t\t\tthis.widget().toggleClass( \"ui-sortable-disabled\", !!value );\n\t\t} else {\n\t\t\t// Don\u0027t call widget base _setOption for disable as it adds ui-state-disabled class\n\t\t\t$.Widget.prototype._setOption.apply(this, arguments);\n\t\t}\n\t},\n\n\t_mouseCapture: function(event, overrideHandle) {\n\t\tvar currentItem = null,\n\t\t\tvalidHandle = false,\n\t\t\tthat = this;\n\n\t\tif (this.reverting) {\n\t\t\treturn false;\n\t\t}\n\n\t\tif(this.options.disabled || this.options.type === \"static\") {\n\t\t\treturn false;\n\t\t}\n\n\t\t//We have to refresh the items data once first\n\t\tthis._refreshItems(event);\n\n\t\t//Find out if the clicked node (or one of its parents) is a actual item in this.items\n\t\t$(event.target).parents().each(function() {\n\t\t\tif($.data(this, that.widgetName + \"-item\") === that) {\n\t\t\t\tcurrentItem = $(this);\n\t\t\t\treturn false;\n\t\t\t}\n\t\t});\n\t\tif($.data(event.target, that.widgetName + \"-item\") === that) {\n\t\t\tcurrentItem = $(event.target);\n\t\t}\n\n\t\tif(!currentItem) {\n\t\t\treturn false;\n\t\t}\n\t\tif(this.options.handle \u0026\u0026 !overrideHandle) {\n\t\t\t$(this.options.handle, currentItem).find(\"*\").addBack().each(function() {\n\t\t\t\tif(this === event.target) {\n\t\t\t\t\tvalidHandle = true;\n\t\t\t\t}\n\t\t\t});\n\t\t\tif(!validHandle) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\n\t\tthis.currentItem = currentItem;\n\t\tthis._removeCurrentsFromItems();\n\t\treturn true;\n\n\t},\n\n\t_mouseStart: function(event, overrideHandle, noActivation) {\n\n\t\tvar i, body,\n\t\t\to = this.options;\n\n\t\tthis.currentContainer = this;\n\n\t\t//We only need to call refreshPositions, because the refreshItems call has been moved to mouseCapture\n\t\tthis.refreshPositions();\n\n\t\t//Create and append the visible helper\n\t\tthis.helper = this._createHelper(event);\n\n\t\t//Cache the helper size\n\t\tthis._cacheHelperProportions();\n\n\t\t/*\n\t\t * - Position generation -\n\t\t * This block generates everything position related - it\u0027s the core of draggables.\n\t\t */\n\n\t\t//Cache the margins of the original element\n\t\tthis._cacheMargins();\n\n\t\t//Get the next scrolling parent\n\t\tthis.scrollParent = this.helper.scrollParent();\n\n\t\t//The element\u0027s absolute position on the page minus margins\n\t\tthis.offset = this.currentItem.offset();\n\t\tthis.offset = {\n\t\t\ttop: this.offset.top - this.margins.top,\n\t\t\tleft: this.offset.left - this.margins.left\n\t\t};\n\n\t\t$.extend(this.offset, {\n\t\t\tclick: { //Where the click happened, relative to the element\n\t\t\t\tleft: event.pageX - this.offset.left,\n\t\t\t\ttop: event.pageY - this.offset.top\n\t\t\t},\n\t\t\tparent: this._getParentOffset(),\n\t\t\trelative: this._getRelativeOffset() //This is a relative to absolute position minus the actual position calculation - only used for relative positioned helper\n\t\t});\n\n\t\t// Only after we got the offset, we can change the helper\u0027s position to absolute\n\t\t// TODO: Still need to figure out a way to make relative sorting possible\n\t\tthis.helper.css(\"position\", \"absolute\");\n\t\tthis.cssPosition = this.helper.css(\"position\");\n\n\t\t//Generate the original position\n\t\tthis.originalPosition = this._generatePosition(event);\n\t\tthis.originalPageX = event.pageX;\n\t\tthis.originalPageY = event.pageY;\n\n\t\t//Adjust the mouse offset relative to the helper if \"cursorAt\" is supplied\n\t\t(o.cursorAt \u0026\u0026 this._adjustOffsetFromHelper(o.cursorAt));\n\n\t\t//Cache the former DOM position\n\t\tthis.domPosition = { prev: this.currentItem.prev()[0], parent: this.currentItem.parent()[0] };\n\n\t\t//If the helper is not the original, hide the original so it\u0027s not playing any role during the drag, won\u0027t cause anything bad this way\n\t\tif(this.helper[0] !== this.currentItem[0]) {\n\t\t\tthis.currentItem.hide();\n\t\t}\n\n\t\t//Create the placeholder\n\t\tthis._createPlaceholder();\n\n\t\t//Set a containment if given in the options\n\t\tif(o.containment) {\n\t\t\tthis._setContainment();\n\t\t}\n\n\t\tif( o.cursor \u0026\u0026 o.cursor !== \"auto\" ) { // cursor option\n\t\t\tbody = this.document.find( \"body\" );\n\n\t\t\t// support: IE\n\t\t\tthis.storedCursor = body.css( \"cursor\" );\n\t\t\tbody.css( \"cursor\", o.cursor );\n\n\t\t\tthis.storedStylesheet = $( \"\u003cstyle\u003e*{ cursor: \"+o.cursor+\" !important; }\u003c/style\u003e\" ).appendTo( body );\n\t\t}\n\n\t\tif(o.opacity) { // opacity option\n\t\t\tif (this.helper.css(\"opacity\")) {\n\t\t\t\tthis._storedOpacity = this.helper.css(\"opacity\");\n\t\t\t}\n\t\t\tthis.helper.css(\"opacity\", o.opacity);\n\t\t}\n\n\t\tif(o.zIndex) { // zIndex option\n\t\t\tif (this.helper.css(\"zIndex\")) {\n\t\t\t\tthis._storedZIndex = this.helper.css(\"zIndex\");\n\t\t\t}\n\t\t\tthis.helper.css(\"zIndex\", o.zIndex);\n\t\t}\n\n\t\t//Prepare scrolling\n\t\tif(this.scrollParent[0] !== document \u0026\u0026 this.scrollParent[0].tagName !== \"HTML\") {\n\t\t\tthis.overflowOffset = this.scrollParent.offset();\n\t\t}\n\n\t\t//Call callbacks\n\t\tthis._trigger(\"start\", event, this._uiHash());\n\n\t\t//Recache the helper size\n\t\tif(!this._preserveHelperProportions) {\n\t\t\tthis._cacheHelperProportions();\n\t\t}\n\n\n\t\t//Post \"activate\" events to possible containers\n\t\tif( !noActivation ) {\n\t\t\tfor ( i = this.containers.length - 1; i \u003e= 0; i-- ) {\n\t\t\t\tthis.containers[ i ]._trigger( \"activate\", event, this._uiHash( this ) );\n\t\t\t}\n\t\t}\n\n\t\t//Prepare possible droppables\n\t\tif($.ui.ddmanager) {\n\t\t\t$.ui.ddmanager.current = this;\n\t\t}\n\n\t\tif ($.ui.ddmanager \u0026\u0026 !o.dropBehaviour) {\n\t\t\t$.ui.ddmanager.prepareOffsets(this, event);\n\t\t}\n\n\t\tthis.dragging = true;\n\n\t\tthis.helper.addClass(\"ui-sortable-helper\");\n\t\tthis._mouseDrag(event); //Execute the drag once - this causes the helper not to be visible before getting its correct position\n\t\treturn true;\n\n\t},\n\n\t_mouseDrag: function(event) {\n\t\tvar i, item, itemElement, intersection,\n\t\t\to = this.options,\n\t\t\tscrolled = false;\n\n\t\t//Compute the helpers position\n\t\tthis.position = this._generatePosition(event);\n\t\tthis.positionAbs = this._convertPositionTo(\"absolute\");\n\n\t\tif (!this.lastPositionAbs) {\n\t\t\tthis.lastPositionAbs = this.positionAbs;\n\t\t}\n\n\t\t//Do scrolling\n\t\tif(this.options.scroll) {\n\t\t\tif(this.scrollParent[0] !== document \u0026\u0026 this.scrollParent[0].tagName !== \"HTML\") {\n\n\t\t\t\tif((this.overflowOffset.top + this.scrollParent[0].offsetHeight) - event.pageY \u003c o.scrollSensitivity) {\n\t\t\t\t\tthis.scrollParent[0].scrollTop = scrolled = this.scrollParent[0].scrollTop + o.scrollSpeed;\n\t\t\t\t} else if(event.pageY - this.overflowOffset.top \u003c o.scrollSensitivity) {\n\t\t\t\t\tthis.scrollParent[0].scrollTop = scrolled = this.scrollParent[0].scrollTop - o.scrollSpeed;\n\t\t\t\t}\n\n\t\t\t\tif((this.overflowOffset.left + this.scrollParent[0].offsetWidth) - event.pageX \u003c o.scrollSensitivity) {\n\t\t\t\t\tthis.scrollParent[0].scrollLeft = scrolled = this.scrollParent[0].scrollLeft + o.scrollSpeed;\n\t\t\t\t} else if(event.pageX - this.overflowOffset.left \u003c o.scrollSensitivity) {\n\t\t\t\t\tthis.scrollParent[0].scrollLeft = scrolled = this.scrollParent[0].scrollLeft - o.scrollSpeed;\n\t\t\t\t}\n\n\t\t\t} else {\n\n\t\t\t\tif(event.pageY - $(document).scrollTop() \u003c o.scrollSensitivity) {\n\t\t\t\t\tscrolled = $(document).scrollTop($(document).scrollTop() - o.scrollSpeed);\n\t\t\t\t} else if($(window).height() - (event.pageY - $(document).scrollTop()) \u003c o.scrollSensitivity) {\n\t\t\t\t\tscrolled = $(document).scrollTop($(document).scrollTop() + o.scrollSpeed);\n\t\t\t\t}\n\n\t\t\t\tif(event.pageX - $(document).scrollLeft() \u003c o.scrollSensitivity) {\n\t\t\t\t\tscrolled = $(document).scrollLeft($(document).scrollLeft() - o.scrollSpeed);\n\t\t\t\t} else if($(window).width() - (event.pageX - $(document).scrollLeft()) \u003c o.scrollSensitivity) {\n\t\t\t\t\tscrolled = $(document).scrollLeft($(document).scrollLeft() + o.scrollSpeed);\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tif(scrolled !== false \u0026\u0026 $.ui.ddmanager \u0026\u0026 !o.dropBehaviour) {\n\t\t\t\t$.ui.ddmanager.prepareOffsets(this, event);\n\t\t\t}\n\t\t}\n\n\t\t//Regenerate the absolute position used for position checks\n\t\tthis.positionAbs = this._convertPositionTo(\"absolute\");\n\n\t\t//Set the helper position\n\t\tif(!this.options.axis || this.options.axis !== \"y\") {\n\t\t\tthis.helper[0].style.left = this.position.left+\"px\";\n\t\t}\n\t\tif(!this.options.axis || this.options.axis !== \"x\") {\n\t\t\tthis.helper[0].style.top = this.position.top+\"px\";\n\t\t}\n\n\t\t//Rearrange\n\t\tfor (i = this.items.length - 1; i \u003e= 0; i--) {\n\n\t\t\t//Cache variables and intersection, continue if no intersection\n\t\t\titem = this.items[i];\n\t\t\titemElement = item.item[0];\n\t\t\tintersection = this._intersectsWithPointer(item);\n\t\t\tif (!intersection) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\t// Only put the placeholder inside the current Container, skip all\n\t\t\t// items form other containers. This works because when moving\n\t\t\t// an item from one container to another the\n\t\t\t// currentContainer is switched before the placeholder is moved.\n\t\t\t//\n\t\t\t// Without this moving items in \"sub-sortables\" can cause the placeholder to jitter\n\t\t\t// beetween the outer and inner container.\n\t\t\tif (item.instance !== this.currentContainer) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\t// cannot intersect with itself\n\t\t\t// no useless actions that have been done before\n\t\t\t// no action if the item moved is the parent of the item checked\n\t\t\tif (itemElement !== this.currentItem[0] \u0026\u0026\n\t\t\t\tthis.placeholder[intersection === 1 ? \"next\" : \"prev\"]()[0] !== itemElement \u0026\u0026\n\t\t\t\t!$.contains(this.placeholder[0], itemElement) \u0026\u0026\n\t\t\t\t(this.options.type === \"semi-dynamic\" ? !$.contains(this.element[0], itemElement) : true)\n\t\t\t) {\n\n\t\t\t\tthis.direction = intersection === 1 ? \"down\" : \"up\";\n\n\t\t\t\tif (this.options.tolerance === \"pointer\" || this._intersectsWithSides(item)) {\n\t\t\t\t\tthis._rearrange(event, item);\n\t\t\t\t} else {\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\n\t\t\t\tthis._trigger(\"change\", event, this._uiHash());\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\n\t\t//Post events to containers\n\t\tthis._contactContainers(event);\n\n\t\t//Interconnect with droppables\n\t\tif($.ui.ddmanager) {\n\t\t\t$.ui.ddmanager.drag(this, event);\n\t\t}\n\n\t\t//Call callbacks\n\t\tthis._trigger(\"sort\", event, this._uiHash());\n\n\t\tthis.lastPositionAbs = this.positionAbs;\n\t\treturn false;\n\n\t},\n\n\t_mouseStop: function(event, noPropagation) {\n\n\t\tif(!event) {\n\t\t\treturn;\n\t\t}\n\n\t\t//If we are using droppables, inform the manager about the drop\n\t\tif ($.ui.ddmanager \u0026\u0026 !this.options.dropBehaviour) {\n\t\t\t$.ui.ddmanager.drop(this, event);\n\t\t}\n\n\t\tif(this.options.revert) {\n\t\t\tvar that = this,\n\t\t\t\tcur = this.placeholder.offset(),\n\t\t\t\taxis = this.options.axis,\n\t\t\t\tanimation = {};\n\n\t\t\tif ( !axis || axis === \"x\" ) {\n\t\t\t\tanimation.left = cur.left - this.offset.parent.left - this.margins.left + (this.offsetParent[0] === document.body ? 0 : this.offsetParent[0].scrollLeft);\n\t\t\t}\n\t\t\tif ( !axis || axis === \"y\" ) {\n\t\t\t\tanimation.top = cur.top - this.offset.parent.top - this.margins.top + (this.offsetParent[0] === document.body ? 0 : this.offsetParent[0].scrollTop);\n\t\t\t}\n\t\t\tthis.reverting = true;\n\t\t\t$(this.helper).animate( animation, parseInt(this.options.revert, 10) || 500, function() {\n\t\t\t\tthat._clear(event);\n\t\t\t});\n\t\t} else {\n\t\t\tthis._clear(event, noPropagation);\n\t\t}\n\n\t\treturn false;\n\n\t},\n\n\tcancel: function() {\n\n\t\tif(this.dragging) {\n\n\t\t\tthis._mouseUp({ target: null });\n\n\t\t\tif(this.options.helper === \"original\") {\n\t\t\t\tthis.currentItem.css(this._storedCSS).removeClass(\"ui-sortable-helper\");\n\t\t\t} else {\n\t\t\t\tthis.currentItem.show();\n\t\t\t}\n\n\t\t\t//Post deactivating events to containers\n\t\t\tfor (var i = this.containers.length - 1; i \u003e= 0; i--){\n\t\t\t\tthis.containers[i]._trigger(\"deactivate\", null, this._uiHash(this));\n\t\t\t\tif(this.containers[i].containerCache.over) {\n\t\t\t\t\tthis.containers[i]._trigger(\"out\", null, this._uiHash(this));\n\t\t\t\t\tthis.containers[i].containerCache.over = 0;\n\t\t\t\t}\n\t\t\t}\n\n\t\t}\n\n\t\tif (this.placeholder) {\n\t\t\t//$(this.placeholder[0]).remove(); would have been the jQuery way - unfortunately, it unbinds ALL events from the original node!\n\t\t\tif(this.placeholder[0].parentNode) {\n\t\t\t\tthis.placeholder[0].parentNode.removeChild(this.placeholder[0]);\n\t\t\t}\n\t\t\tif(this.options.helper !== \"original\" \u0026\u0026 this.helper \u0026\u0026 this.helper[0].parentNode) {\n\t\t\t\tthis.helper.remove();\n\t\t\t}\n\n\t\t\t$.extend(this, {\n\t\t\t\thelper: null,\n\t\t\t\tdragging: false,\n\t\t\t\treverting: false,\n\t\t\t\t_noFinalSort: null\n\t\t\t});\n\n\t\t\tif(this.domPosition.prev) {\n\t\t\t\t$(this.domPosition.prev).after(this.currentItem);\n\t\t\t} else {\n\t\t\t\t$(this.domPosition.parent).prepend(this.currentItem);\n\t\t\t}\n\t\t}\n\n\t\treturn this;\n\n\t},\n\n\tserialize: function(o) {\n\n\t\tvar items = this._getItemsAsjQuery(o \u0026\u0026 o.connected),\n\t\t\tstr = [];\n\t\to = o || {};\n\n\t\t$(items).each(function() {\n\t\t\tvar res = ($(o.item || this).attr(o.attribute || \"id\") || \"\").match(o.expression || (/(.+)[\\-=_](.+)/));\n\t\t\tif (res) {\n\t\t\t\tstr.push((o.key || res[1]+\"[]\")+\"=\"+(o.key \u0026\u0026 o.expression ? res[1] : res[2]));\n\t\t\t}\n\t\t});\n\n\t\tif(!str.length \u0026\u0026 o.key) {\n\t\t\tstr.push(o.key + \"=\");\n\t\t}\n\n\t\treturn str.join(\"\u0026\");\n\n\t},\n\n\ttoArray: function(o) {\n\n\t\tvar items = this._getItemsAsjQuery(o \u0026\u0026 o.connected),\n\t\t\tret = [];\n\n\t\to = o || {};\n\n\t\titems.each(function() { ret.push($(o.item || this).attr(o.attribute || \"id\") || \"\"); });\n\t\treturn ret;\n\n\t},\n\n\t/* Be careful with the following core functions */\n\t_intersectsWith: function(item) {\n\n\t\tvar x1 = this.positionAbs.left,\n\t\t\tx2 = x1 + this.helperProportions.width,\n\t\t\ty1 = this.positionAbs.top,\n\t\t\ty2 = y1 + this.helperProportions.height,\n\t\t\tl = item.left,\n\t\t\tr = l + item.width,\n\t\t\tt = item.top,\n\t\t\tb = t + item.height,\n\t\t\tdyClick = this.offset.click.top,\n\t\t\tdxClick = this.offset.click.left,\n\t\t\tisOverElement = (y1 + dyClick) \u003e t \u0026\u0026 (y1 + dyClick) \u003c b \u0026\u0026 (x1 + dxClick) \u003e l \u0026\u0026 (x1 + dxClick) \u003c r;\n\n\t\tif ( this.options.tolerance === \"pointer\" ||\n\t\t\tthis.options.forcePointerForContainers ||\n\t\t\t(this.options.tolerance !== \"pointer\" \u0026\u0026 this.helperProportions[this.floating ? \"width\" : \"height\"] \u003e item[this.floating ? \"width\" : \"height\"])\n\t\t) {\n\t\t\treturn isOverElement;\n\t\t} else {\n\n\t\t\treturn (l \u003c x1 + (this.helperProportions.width / 2) \u0026\u0026 // Right Half\n\t\t\t\tx2 - (this.helperProportions.width / 2) \u003c r \u0026\u0026 // Left Half\n\t\t\t\tt \u003c y1 + (this.helperProportions.height / 2) \u0026\u0026 // Bottom Half\n\t\t\t\ty2 - (this.helperProportions.height / 2) \u003c b ); // Top Half\n\n\t\t}\n\t},\n\n\t_intersectsWithPointer: function(item) {\n\n\t\tvar isOverElementHeight = (this.options.axis === \"x\") || isOverAxis(this.positionAbs.top + this.offset.click.top, item.top, item.height),\n\t\t\tisOverElementWidth = (this.options.axis === \"y\") || isOverAxis(this.positionAbs.left + this.offset.click.left, item.left, item.width),\n\t\t\tisOverElement = isOverElementHeight \u0026\u0026 isOverElementWidth,\n\t\t\tverticalDirection = this._getDragVerticalDirection(),\n\t\t\thorizontalDirection = this._getDragHorizontalDirection();\n\n\t\tif (!isOverElement) {\n\t\t\treturn false;\n\t\t}\n\n\t\treturn this.floating ?\n\t\t\t( ((horizontalDirection \u0026\u0026 horizontalDirection === \"right\") || verticalDirection === \"down\") ? 2 : 1 )\n\t\t\t: ( verticalDirection \u0026\u0026 (verticalDirection === \"down\" ? 2 : 1) );\n\n\t},\n\n\t_intersectsWithSides: function(item) {\n\n\t\tvar isOverBottomHalf = isOverAxis(this.positionAbs.top + this.offset.click.top, item.top + (item.height/2), item.height),\n\t\t\tisOverRightHalf = isOverAxis(this.positionAbs.left + this.offset.click.left, item.left + (item.width/2), item.width),\n\t\t\tverticalDirection = this._getDragVerticalDirection(),\n\t\t\thorizontalDirection = this._getDragHorizontalDirection();\n\n\t\tif (this.floating \u0026\u0026 horizontalDirection) {\n\t\t\treturn ((horizontalDirection === \"right\" \u0026\u0026 isOverRightHalf) || (horizontalDirection === \"left\" \u0026\u0026 !isOverRightHalf));\n\t\t} else {\n\t\t\treturn verticalDirection \u0026\u0026 ((verticalDirection === \"down\" \u0026\u0026 isOverBottomHalf) || (verticalDirection === \"up\" \u0026\u0026 !isOverBottomHalf));\n\t\t}\n\n\t},\n\n\t_getDragVerticalDirection: function() {\n\t\tvar delta = this.positionAbs.top - this.lastPositionAbs.top;\n\t\treturn delta !== 0 \u0026\u0026 (delta \u003e 0 ? \"down\" : \"up\");\n\t},\n\n\t_getDragHorizontalDirection: function() {\n\t\tvar delta = this.positionAbs.left - this.lastPositionAbs.left;\n\t\treturn delta !== 0 \u0026\u0026 (delta \u003e 0 ? \"right\" : \"left\");\n\t},\n\n\trefresh: function(event) {\n\t\tthis._refreshItems(event);\n\t\tthis.refreshPositions();\n\t\treturn this;\n\t},\n\n\t_connectWith: function() {\n\t\tvar options = this.options;\n\t\treturn options.connectWith.constructor === String ? [options.connectWith] : options.connectWith;\n\t},\n\n\t_getItemsAsjQuery: function(connected) {\n\n\t\tvar i, j, cur, inst,\n\t\t\titems = [],\n\t\t\tqueries = [],\n\t\t\tconnectWith = this._connectWith();\n\n\t\tif(connectWith \u0026\u0026 connected) {\n\t\t\tfor (i = connectWith.length - 1; i \u003e= 0; i--){\n\t\t\t\tcur = $(connectWith[i]);\n\t\t\t\tfor ( j = cur.length - 1; j \u003e= 0; j--){\n\t\t\t\t\tinst = $.data(cur[j], this.widgetFullName);\n\t\t\t\t\tif(inst \u0026\u0026 inst !== this \u0026\u0026 !inst.options.disabled) {\n\t\t\t\t\t\tqueries.push([$.isFunction(inst.options.items) ? inst.options.items.call(inst.element) : $(inst.options.items, inst.element).not(\".ui-sortable-helper\").not(\".ui-sortable-placeholder\"), inst]);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tqueries.push([$.isFunction(this.options.items) ? this.options.items.call(this.element, null, { options: this.options, item: this.currentItem }) : $(this.options.items, this.element).not(\".ui-sortable-helper\").not(\".ui-sortable-placeholder\"), this]);\n\n\t\tfor (i = queries.length - 1; i \u003e= 0; i--){\n\t\t\tqueries[i][0].each(function() {\n\t\t\t\titems.push(this);\n\t\t\t});\n\t\t}\n\n\t\treturn $(items);\n\n\t},\n\n\t_removeCurrentsFromItems: function() {\n\n\t\tvar list = this.currentItem.find(\":data(\" + this.widgetName + \"-item)\");\n\n\t\tthis.items = $.grep(this.items, function (item) {\n\t\t\tfor (var j=0; j \u003c list.length; j++) {\n\t\t\t\tif(list[j] === item.item[0]) {\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn true;\n\t\t});\n\n\t},\n\n\t_refreshItems: function(event) {\n\n\t\tthis.items = [];\n\t\tthis.containers = [this];\n\n\t\tvar i, j, cur, inst, targetData, _queries, item, queriesLength,\n\t\t\titems = this.items,\n\t\t\tqueries = [[$.isFunction(this.options.items) ? this.options.items.call(this.element[0], event, { item: this.currentItem }) : $(this.options.items, this.element), this]],\n\t\t\tconnectWith = this._connectWith();\n\n\t\tif(connectWith \u0026\u0026 this.ready) { //Shouldn\u0027t be run the first time through due to massive slow-down\n\t\t\tfor (i = connectWith.length - 1; i \u003e= 0; i--){\n\t\t\t\tcur = $(connectWith[i]);\n\t\t\t\tfor (j = cur.length - 1; j \u003e= 0; j--){\n\t\t\t\t\tinst = $.data(cur[j], this.widgetFullName);\n\t\t\t\t\tif(inst \u0026\u0026 inst !== this \u0026\u0026 !inst.options.disabled) {\n\t\t\t\t\t\tqueries.push([$.isFunction(inst.options.items) ? inst.options.items.call(inst.element[0], event, { item: this.currentItem }) : $(inst.options.items, inst.element), inst]);\n\t\t\t\t\t\tthis.containers.push(inst);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tfor (i = queries.length - 1; i \u003e= 0; i--) {\n\t\t\ttargetData = queries[i][1];\n\t\t\t_queries = queries[i][0];\n\n\t\t\tfor (j=0, queriesLength = _queries.length; j \u003c queriesLength; j++) {\n\t\t\t\titem = $(_queries[j]);\n\n\t\t\t\titem.data(this.widgetName + \"-item\", targetData); // Data for target checking (mouse manager)\n\n\t\t\t\titems.push({\n\t\t\t\t\titem: item,\n\t\t\t\t\tinstance: targetData,\n\t\t\t\t\twidth: 0, height: 0,\n\t\t\t\t\tleft: 0, top: 0\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\n\t},\n\n\trefreshPositions: function(fast) {\n\n\t\t//This has to be redone because due to the item being moved out/into the offsetParent, the offsetParent\u0027s position will change\n\t\tif(this.offsetParent \u0026\u0026 this.helper) {\n\t\t\tthis.offset.parent = this._getParentOffset();\n\t\t}\n\n\t\tvar i, item, t, p;\n\n\t\tfor (i = this.items.length - 1; i \u003e= 0; i--){\n\t\t\titem = this.items[i];\n\n\t\t\t//We ignore calculating positions of all connected containers when we\u0027re not over them\n\t\t\tif(item.instance !== this.currentContainer \u0026\u0026 this.currentContainer \u0026\u0026 item.item[0] !== this.currentItem[0]) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tt = this.options.toleranceElement ? $(this.options.toleranceElement, item.item) : item.item;\n\n\t\t\tif (!fast) {\n\t\t\t\titem.width = t.outerWidth();\n\t\t\t\titem.height = t.outerHeight();\n\t\t\t}\n\n\t\t\tp = t.offset();\n\t\t\titem.left = p.left;\n\t\t\titem.top = p.top;\n\t\t}\n\n\t\tif(this.options.custom \u0026\u0026 this.options.custom.refreshContainers) {\n\t\t\tthis.options.custom.refreshContainers.call(this);\n\t\t} else {\n\t\t\tfor (i = this.containers.length - 1; i \u003e= 0; i--){\n\t\t\t\tp = this.containers[i].element.offset();\n\t\t\t\tthis.containers[i].containerCache.left = p.left;\n\t\t\t\tthis.containers[i].containerCache.top = p.top;\n\t\t\t\tthis.containers[i].containerCache.width\t= this.containers[i].element.outerWidth();\n\t\t\t\tthis.containers[i].containerCache.height = this.containers[i].element.outerHeight();\n\t\t\t}\n\t\t}\n\n\t\treturn this;\n\t},\n\n\t_createPlaceholder: function(that) {\n\t\tthat = that || this;\n\t\tvar className,\n\t\t\to = that.options;\n\n\t\tif(!o.placeholder || o.placeholder.constructor === String) {\n\t\t\tclassName = o.placeholder;\n\t\t\to.placeholder = {\n\t\t\t\telement: function() {\n\n\t\t\t\t\tvar nodeName = that.currentItem[0].nodeName.toLowerCase(),\n\t\t\t\t\t\telement = $( that.document[0].createElement( nodeName ) )\n\t\t\t\t\t\t\t.addClass(className || that.currentItem[0].className+\" ui-sortable-placeholder\")\n\t\t\t\t\t\t\t.removeClass(\"ui-sortable-helper\");\n\n\t\t\t\t\tif ( nodeName === \"tr\" ) {\n\t\t\t\t\t\t// Use a high colspan to force the td to expand the full\n\t\t\t\t\t\t// width of the table (browsers are smart enough to\n\t\t\t\t\t\t// handle this properly)\n\t\t\t\t\t\telement.append( \"\u003ctd colspan=\u002799\u0027\u003e\u0026#160;\u003c/td\u003e\" );\n\t\t\t\t\t} else if ( nodeName === \"img\" ) {\n\t\t\t\t\t\telement.attr( \"src\", that.currentItem.attr( \"src\" ) );\n\t\t\t\t\t}\n\n\t\t\t\t\tif ( !className ) {\n\t\t\t\t\t\telement.css( \"visibility\", \"hidden\" );\n\t\t\t\t\t}\n\n\t\t\t\t\treturn element;\n\t\t\t\t},\n\t\t\t\tupdate: function(container, p) {\n\n\t\t\t\t\t// 1. If a className is set as \u0027placeholder option, we don\u0027t force sizes - the class is responsible for that\n\t\t\t\t\t// 2. The option \u0027forcePlaceholderSize can be enabled to force it even if a class name is specified\n\t\t\t\t\tif(className \u0026\u0026 !o.forcePlaceholderSize) {\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\n\t\t\t\t\t//If the element doesn\u0027t have a actual height by itself (without styles coming from a stylesheet), it receives the inline height from the dragged item\n\t\t\t\t\tif(!p.height()) { p.height(that.currentItem.innerHeight() - parseInt(that.currentItem.css(\"paddingTop\")||0, 10) - parseInt(that.currentItem.css(\"paddingBottom\")||0, 10)); }\n\t\t\t\t\tif(!p.width()) { p.width(that.currentItem.innerWidth() - parseInt(that.currentItem.css(\"paddingLeft\")||0, 10) - parseInt(that.currentItem.css(\"paddingRight\")||0, 10)); }\n\t\t\t\t}\n\t\t\t};\n\t\t}\n\n\t\t//Create the placeholder\n\t\tthat.placeholder = $(o.placeholder.element.call(that.element, that.currentItem));\n\n\t\t//Append it after the actual current item\n\t\tthat.currentItem.after(that.placeholder);\n\n\t\t//Update the size of the placeholder (TODO: Logic to fuzzy, see line 316/317)\n\t\to.placeholder.update(that, that.placeholder);\n\n\t},\n\n\t_contactContainers: function(event) {\n\t\tvar i, j, dist, itemWithLeastDistance, posProperty, sizeProperty, base, cur, nearBottom, floating,\n\t\t\tinnermostContainer = null,\n\t\t\tinnermostIndex = null;\n\n\t\t// get innermost container that intersects with item\n\t\tfor (i = this.containers.length - 1; i \u003e= 0; i--) {\n\n\t\t\t// never consider a container that\u0027s located within the item itself\n\t\t\tif($.contains(this.currentItem[0], this.containers[i].element[0])) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tif(this._intersectsWith(this.containers[i].containerCache)) {\n\n\t\t\t\t// if we\u0027ve already found a container and it\u0027s more \"inner\" than this, then continue\n\t\t\t\tif(innermostContainer \u0026\u0026 $.contains(this.containers[i].element[0], innermostContainer.element[0])) {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\n\t\t\t\tinnermostContainer = this.containers[i];\n\t\t\t\tinnermostIndex = i;\n\n\t\t\t} else {\n\t\t\t\t// container doesn\u0027t intersect. trigger \"out\" event if necessary\n\t\t\t\tif(this.containers[i].containerCache.over) {\n\t\t\t\t\tthis.containers[i]._trigger(\"out\", event, this._uiHash(this));\n\t\t\t\t\tthis.containers[i].containerCache.over = 0;\n\t\t\t\t}\n\t\t\t}\n\n\t\t}\n\n\t\t// if no intersecting containers found, return\n\t\tif(!innermostContainer) {\n\t\t\treturn;\n\t\t}\n\n\t\t// move the item into the container if it\u0027s not there already\n\t\tif(this.containers.length === 1) {\n\t\t\tif (!this.containers[innermostIndex].containerCache.over) {\n\t\t\t\tthis.containers[innermostIndex]._trigger(\"over\", event, this._uiHash(this));\n\t\t\t\tthis.containers[innermostIndex].containerCache.over = 1;\n\t\t\t}\n\t\t} else {\n\n\t\t\t//When entering a new container, we will find the item with the least distance and append our item near it\n\t\t\tdist = 10000;\n\t\t\titemWithLeastDistance = null;\n\t\t\tfloating = innermostContainer.floating || isFloating(this.currentItem);\n\t\t\tposProperty = floating ? \"left\" : \"top\";\n\t\t\tsizeProperty = floating ? \"width\" : \"height\";\n\t\t\tbase = this.positionAbs[posProperty] + this.offset.click[posProperty];\n\t\t\tfor (j = this.items.length - 1; j \u003e= 0; j--) {\n\t\t\t\tif(!$.contains(this.containers[innermostIndex].element[0], this.items[j].item[0])) {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\tif(this.items[j].item[0] === this.currentItem[0]) {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\tif (floating \u0026\u0026 !isOverAxis(this.positionAbs.top + this.offset.click.top, this.items[j].top, this.items[j].height)) {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\tcur = this.items[j].item.offset()[posProperty];\n\t\t\t\tnearBottom = false;\n\t\t\t\tif(Math.abs(cur - base) \u003e Math.abs(cur + this.items[j][sizeProperty] - base)){\n\t\t\t\t\tnearBottom = true;\n\t\t\t\t\tcur += this.items[j][sizeProperty];\n\t\t\t\t}\n\n\t\t\t\tif(Math.abs(cur - base) \u003c dist) {\n\t\t\t\t\tdist = Math.abs(cur - base); itemWithLeastDistance = this.items[j];\n\t\t\t\t\tthis.direction = nearBottom ? \"up\": \"down\";\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t//Check if dropOnEmpty is enabled\n\t\t\tif(!itemWithLeastDistance \u0026\u0026 !this.options.dropOnEmpty) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif(this.currentContainer === this.containers[innermostIndex]) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\titemWithLeastDistance ? this._rearrange(event, itemWithLeastDistance, null, true) : this._rearrange(event, null, this.containers[innermostIndex].element, true);\n\t\t\tthis._trigger(\"change\", event, this._uiHash());\n\t\t\tthis.containers[innermostIndex]._trigger(\"change\", event, this._uiHash(this));\n\t\t\tthis.currentContainer = this.containers[innermostIndex];\n\n\t\t\t//Update the placeholder\n\t\t\tthis.options.placeholder.update(this.currentContainer, this.placeholder);\n\n\t\t\tthis.containers[innermostIndex]._trigger(\"over\", event, this._uiHash(this));\n\t\t\tthis.containers[innermostIndex].containerCache.over = 1;\n\t\t}\n\n\n\t},\n\n\t_createHelper: function(event) {\n\n\t\tvar o = this.options,\n\t\t\thelper = $.isFunction(o.helper) ? $(o.helper.apply(this.element[0], [event, this.currentItem])) : (o.helper === \"clone\" ? this.currentItem.clone() : this.currentItem);\n\n\t\t//Add the helper to the DOM if that didn\u0027t happen already\n\t\tif(!helper.parents(\"body\").length) {\n\t\t\t$(o.appendTo !== \"parent\" ? o.appendTo : this.currentItem[0].parentNode)[0].appendChild(helper[0]);\n\t\t}\n\n\t\tif(helper[0] === this.currentItem[0]) {\n\t\t\tthis._storedCSS = { width: this.currentItem[0].style.width, height: this.currentItem[0].style.height, position: this.currentItem.css(\"position\"), top: this.currentItem.css(\"top\"), left: this.currentItem.css(\"left\") };\n\t\t}\n\n\t\tif(!helper[0].style.width || o.forceHelperSize) {\n\t\t\thelper.width(this.currentItem.width());\n\t\t}\n\t\tif(!helper[0].style.height || o.forceHelperSize) {\n\t\t\thelper.height(this.currentItem.height());\n\t\t}\n\n\t\treturn helper;\n\n\t},\n\n\t_adjustOffsetFromHelper: function(obj) {\n\t\tif (typeof obj === \"string\") {\n\t\t\tobj = obj.split(\" \");\n\t\t}\n\t\tif ($.isArray(obj)) {\n\t\t\tobj = {left: +obj[0], top: +obj[1] || 0};\n\t\t}\n\t\tif (\"left\" in obj) {\n\t\t\tthis.offset.click.left = obj.left + this.margins.left;\n\t\t}\n\t\tif (\"right\" in obj) {\n\t\t\tthis.offset.click.left = this.helperProportions.width - obj.right + this.margins.left;\n\t\t}\n\t\tif (\"top\" in obj) {\n\t\t\tthis.offset.click.top = obj.top + this.margins.top;\n\t\t}\n\t\tif (\"bottom\" in obj) {\n\t\t\tthis.offset.click.top = this.helperProportions.height - obj.bottom + this.margins.top;\n\t\t}\n\t},\n\n\t_getParentOffset: function() {\n\n\n\t\t//Get the offsetParent and cache its position\n\t\tthis.offsetParent = this.helper.offsetParent();\n\t\tvar po = this.offsetParent.offset();\n\n\t\t// This is a special case where we need to modify a offset calculated on start, since the following happened:\n\t\t// 1. The position of the helper is absolute, so it\u0027s position is calculated based on the next positioned parent\n\t\t// 2. The actual offset parent is a child of the scroll parent, and the scroll parent isn\u0027t the document, which means that\n\t\t// the scroll is included in the initial calculation of the offset of the parent, and never recalculated upon drag\n\t\tif(this.cssPosition === \"absolute\" \u0026\u0026 this.scrollParent[0] !== document \u0026\u0026 $.contains(this.scrollParent[0], this.offsetParent[0])) {\n\t\t\tpo.left += this.scrollParent.scrollLeft();\n\t\t\tpo.top += this.scrollParent.scrollTop();\n\t\t}\n\n\t\t// This needs to be actually done for all browsers, since pageX/pageY includes this information\n\t\t// with an ugly IE fix\n\t\tif( this.offsetParent[0] === document.body || (this.offsetParent[0].tagName \u0026\u0026 this.offsetParent[0].tagName.toLowerCase() === \"html\" \u0026\u0026 $.ui.ie)) {\n\t\t\tpo = { top: 0, left: 0 };\n\t\t}\n\n\t\treturn {\n\t\t\ttop: po.top + (parseInt(this.offsetParent.css(\"borderTopWidth\"),10) || 0),\n\t\t\tleft: po.left + (parseInt(this.offsetParent.css(\"borderLeftWidth\"),10) || 0)\n\t\t};\n\n\t},\n\n\t_getRelativeOffset: function() {\n\n\t\tif(this.cssPosition === \"relative\") {\n\t\t\tvar p = this.currentItem.position();\n\t\t\treturn {\n\t\t\t\ttop: p.top - (parseInt(this.helper.css(\"top\"),10) || 0) + this.scrollParent.scrollTop(),\n\t\t\t\tleft: p.left - (parseInt(this.helper.css(\"left\"),10) || 0) + this.scrollParent.scrollLeft()\n\t\t\t};\n\t\t} else {\n\t\t\treturn { top: 0, left: 0 };\n\t\t}\n\n\t},\n\n\t_cacheMargins: function() {\n\t\tthis.margins = {\n\t\t\tleft: (parseInt(this.currentItem.css(\"marginLeft\"),10) || 0),\n\t\t\ttop: (parseInt(this.currentItem.css(\"marginTop\"),10) || 0)\n\t\t};\n\t},\n\n\t_cacheHelperProportions: function() {\n\t\tthis.helperProportions = {\n\t\t\twidth: this.helper.outerWidth(),\n\t\t\theight: this.helper.outerHeight()\n\t\t};\n\t},\n\n\t_setContainment: function() {\n\n\t\tvar ce, co, over,\n\t\t\to = this.options;\n\t\tif(o.containment === \"parent\") {\n\t\t\to.containment = this.helper[0].parentNode;\n\t\t}\n\t\tif(o.containment === \"document\" || o.containment === \"window\") {\n\t\t\tthis.containment = [\n\t\t\t\t0 - this.offset.relative.left - this.offset.parent.left,\n\t\t\t\t0 - this.offset.relative.top - this.offset.parent.top,\n\t\t\t\t$(o.containment === \"document\" ? document : window).width() - this.helperProportions.width - this.margins.left,\n\t\t\t\t($(o.containment === \"document\" ? document : window).height() || document.body.parentNode.scrollHeight) - this.helperProportions.height - this.margins.top\n\t\t\t];\n\t\t}\n\n\t\tif(!(/^(document|window|parent)$/).test(o.containment)) {\n\t\t\tce = $(o.containment)[0];\n\t\t\tco = $(o.containment).offset();\n\t\t\tover = ($(ce).css(\"overflow\") !== \"hidden\");\n\n\t\t\tthis.containment = [\n\t\t\t\tco.left + (parseInt($(ce).css(\"borderLeftWidth\"),10) || 0) + (parseInt($(ce).css(\"paddingLeft\"),10) || 0) - this.margins.left,\n\t\t\t\tco.top + (parseInt($(ce).css(\"borderTopWidth\"),10) || 0) + (parseInt($(ce).css(\"paddingTop\"),10) || 0) - this.margins.top,\n\t\t\t\tco.left+(over ? Math.max(ce.scrollWidth,ce.offsetWidth) : ce.offsetWidth) - (parseInt($(ce).css(\"borderLeftWidth\"),10) || 0) - (parseInt($(ce).css(\"paddingRight\"),10) || 0) - this.helperProportions.width - this.margins.left,\n\t\t\t\tco.top+(over ? Math.max(ce.scrollHeight,ce.offsetHeight) : ce.offsetHeight) - (parseInt($(ce).css(\"borderTopWidth\"),10) || 0) - (parseInt($(ce).css(\"paddingBottom\"),10) || 0) - this.helperProportions.height - this.margins.top\n\t\t\t];\n\t\t}\n\n\t},\n\n\t_convertPositionTo: function(d, pos) {\n\n\t\tif(!pos) {\n\t\t\tpos = this.position;\n\t\t}\n\t\tvar mod = d === \"absolute\" ? 1 : -1,\n\t\t\tscroll = this.cssPosition === \"absolute\" \u0026\u0026 !(this.scrollParent[0] !== document \u0026\u0026 $.contains(this.scrollParent[0], this.offsetParent[0])) ? this.offsetParent : this.scrollParent,\n\t\t\tscrollIsRootNode = (/(html|body)/i).test(scroll[0].tagName);\n\n\t\treturn {\n\t\t\ttop: (\n\t\t\t\tpos.top\t+\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t// The absolute mouse position\n\t\t\t\tthis.offset.relative.top * mod +\t\t\t\t\t\t\t\t\t\t// Only for relative positioned nodes: Relative offset from element to offset parent\n\t\t\t\tthis.offset.parent.top * mod -\t\t\t\t\t\t\t\t\t\t\t// The offsetParent\u0027s offset without borders (offset + border)\n\t\t\t\t( ( this.cssPosition === \"fixed\" ? -this.scrollParent.scrollTop() : ( scrollIsRootNode ? 0 : scroll.scrollTop() ) ) * mod)\n\t\t\t),\n\t\t\tleft: (\n\t\t\t\tpos.left +\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t// The absolute mouse position\n\t\t\t\tthis.offset.relative.left * mod +\t\t\t\t\t\t\t\t\t\t// Only for relative positioned nodes: Relative offset from element to offset parent\n\t\t\t\tthis.offset.parent.left * mod\t-\t\t\t\t\t\t\t\t\t\t// The offsetParent\u0027s offset without borders (offset + border)\n\t\t\t\t( ( this.cssPosition === \"fixed\" ? -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : scroll.scrollLeft() ) * mod)\n\t\t\t)\n\t\t};\n\n\t},\n\n\t_generatePosition: function(event) {\n\n\t\tvar top, left,\n\t\t\to = this.options,\n\t\t\tpageX = event.pageX,\n\t\t\tpageY = event.pageY,\n\t\t\tscroll = this.cssPosition === \"absolute\" \u0026\u0026 !(this.scrollParent[0] !== document \u0026\u0026 $.contains(this.scrollParent[0], this.offsetParent[0])) ? this.offsetParent : this.scrollParent, scrollIsRootNode = (/(html|body)/i).test(scroll[0].tagName);\n\n\t\t// This is another very weird special case that only happens for relative elements:\n\t\t// 1. If the css position is relative\n\t\t// 2. and the scroll parent is the document or similar to the offset parent\n\t\t// we have to refresh the relative offset during the scroll so there are no jumps\n\t\tif(this.cssPosition === \"relative\" \u0026\u0026 !(this.scrollParent[0] !== document \u0026\u0026 this.scrollParent[0] !== this.offsetParent[0])) {\n\t\t\tthis.offset.relative = this._getRelativeOffset();\n\t\t}\n\n\t\t/*\n\t\t * - Position constraining -\n\t\t * Constrain the position to a mix of grid, containment.\n\t\t */\n\n\t\tif(this.originalPosition) { //If we are not dragging yet, we won\u0027t check for options\n\n\t\t\tif(this.containment) {\n\t\t\t\tif(event.pageX - this.offset.click.left \u003c this.containment[0]) {\n\t\t\t\t\tpageX = this.containment[0] + this.offset.click.left;\n\t\t\t\t}\n\t\t\t\tif(event.pageY - this.offset.click.top \u003c this.containment[1]) {\n\t\t\t\t\tpageY = this.containment[1] + this.offset.click.top;\n\t\t\t\t}\n\t\t\t\tif(event.pageX - this.offset.click.left \u003e this.containment[2]) {\n\t\t\t\t\tpageX = this.containment[2] + this.offset.click.left;\n\t\t\t\t}\n\t\t\t\tif(event.pageY - this.offset.click.top \u003e this.containment[3]) {\n\t\t\t\t\tpageY = this.containment[3] + this.offset.click.top;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif(o.grid) {\n\t\t\t\ttop = this.originalPageY + Math.round((pageY - this.originalPageY) / o.grid[1]) * o.grid[1];\n\t\t\t\tpageY = this.containment ? ( (top - this.offset.click.top \u003e= this.containment[1] \u0026\u0026 top - this.offset.click.top \u003c= this.containment[3]) ? top : ((top - this.offset.click.top \u003e= this.containment[1]) ? top - o.grid[1] : top + o.grid[1])) : top;\n\n\t\t\t\tleft = this.originalPageX + Math.round((pageX - this.originalPageX) / o.grid[0]) * o.grid[0];\n\t\t\t\tpageX = this.containment ? ( (left - this.offset.click.left \u003e= this.containment[0] \u0026\u0026 left - this.offset.click.left \u003c= this.containment[2]) ? left : ((left - this.offset.click.left \u003e= this.containment[0]) ? left - o.grid[0] : left + o.grid[0])) : left;\n\t\t\t}\n\n\t\t}\n\n\t\treturn {\n\t\t\ttop: (\n\t\t\t\tpageY -\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t// The absolute mouse position\n\t\t\t\tthis.offset.click.top -\t\t\t\t\t\t\t\t\t\t\t\t\t// Click offset (relative to the element)\n\t\t\t\tthis.offset.relative.top\t-\t\t\t\t\t\t\t\t\t\t\t// Only for relative positioned nodes: Relative offset from element to offset parent\n\t\t\t\tthis.offset.parent.top +\t\t\t\t\t\t\t\t\t\t\t\t// The offsetParent\u0027s offset without borders (offset + border)\n\t\t\t\t( ( this.cssPosition === \"fixed\" ? -this.scrollParent.scrollTop() : ( scrollIsRootNode ? 0 : scroll.scrollTop() ) ))\n\t\t\t),\n\t\t\tleft: (\n\t\t\t\tpageX -\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t// The absolute mouse position\n\t\t\t\tthis.offset.click.left -\t\t\t\t\t\t\t\t\t\t\t\t// Click offset (relative to the element)\n\t\t\t\tthis.offset.relative.left\t-\t\t\t\t\t\t\t\t\t\t\t// Only for relative positioned nodes: Relative offset from element to offset parent\n\t\t\t\tthis.offset.parent.left +\t\t\t\t\t\t\t\t\t\t\t\t// The offsetParent\u0027s offset without borders (offset + border)\n\t\t\t\t( ( this.cssPosition === \"fixed\" ? -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : scroll.scrollLeft() ))\n\t\t\t)\n\t\t};\n\n\t},\n\n\t_rearrange: function(event, i, a, hardRefresh) {\n\n\t\ta ? a[0].appendChild(this.placeholder[0]) : i.item[0].parentNode.insertBefore(this.placeholder[0], (this.direction === \"down\" ? i.item[0] : i.item[0].nextSibling));\n\n\t\t//Various things done here to improve the performance:\n\t\t// 1. we create a setTimeout, that calls refreshPositions\n\t\t// 2. on the instance, we have a counter variable, that get\u0027s higher after every append\n\t\t// 3. on the local scope, we copy the counter variable, and check in the timeout, if it\u0027s still the same\n\t\t// 4. this lets only the last addition to the timeout stack through\n\t\tthis.counter = this.counter ? ++this.counter : 1;\n\t\tvar counter = this.counter;\n\n\t\tthis._delay(function() {\n\t\t\tif(counter === this.counter) {\n\t\t\t\tthis.refreshPositions(!hardRefresh); //Precompute after each DOM insertion, NOT on mousemove\n\t\t\t}\n\t\t});\n\n\t},\n\n\t_clear: function(event, noPropagation) {\n\n\t\tthis.reverting = false;\n\t\t// We delay all events that have to be triggered to after the point where the placeholder has been removed and\n\t\t// everything else normalized again\n\t\tvar i,\n\t\t\tdelayedTriggers = [];\n\n\t\t// We first have to update the dom position of the actual currentItem\n\t\t// Note: don\u0027t do it if the current item is already removed (by a user), or it gets reappended (see #4088)\n\t\tif(!this._noFinalSort \u0026\u0026 this.currentItem.parent().length) {\n\t\t\tthis.placeholder.before(this.currentItem);\n\t\t}\n\t\tthis._noFinalSort = null;\n\n\t\tif(this.helper[0] === this.currentItem[0]) {\n\t\t\tfor(i in this._storedCSS) {\n\t\t\t\tif(this._storedCSS[i] === \"auto\" || this._storedCSS[i] === \"static\") {\n\t\t\t\t\tthis._storedCSS[i] = \"\";\n\t\t\t\t}\n\t\t\t}\n\t\t\tthis.currentItem.css(this._storedCSS).removeClass(\"ui-sortable-helper\");\n\t\t} else {\n\t\t\tthis.currentItem.show();\n\t\t}\n\n\t\tif(this.fromOutside \u0026\u0026 !noPropagation) {\n\t\t\tdelayedTriggers.push(function(event) { this._trigger(\"receive\", event, this._uiHash(this.fromOutside)); });\n\t\t}\n\t\tif((this.fromOutside || this.domPosition.prev !== this.currentItem.prev().not(\".ui-sortable-helper\")[0] || this.domPosition.parent !== this.currentItem.parent()[0]) \u0026\u0026 !noPropagation) {\n\t\t\tdelayedTriggers.push(function(event) { this._trigger(\"update\", event, this._uiHash()); }); //Trigger update callback if the DOM position has changed\n\t\t}\n\n\t\t// Check if the items Container has Changed and trigger appropriate\n\t\t// events.\n\t\tif (this !== this.currentContainer) {\n\t\t\tif(!noPropagation) {\n\t\t\t\tdelayedTriggers.push(function(event) { this._trigger(\"remove\", event, this._uiHash()); });\n\t\t\t\tdelayedTriggers.push((function(c) { return function(event) { c._trigger(\"receive\", event, this._uiHash(this)); }; }).call(this, this.currentContainer));\n\t\t\t\tdelayedTriggers.push((function(c) { return function(event) { c._trigger(\"update\", event, this._uiHash(this)); }; }).call(this, this.currentContainer));\n\t\t\t}\n\t\t}\n\n\n\t\t//Post events to containers\n\t\tfor (i = this.containers.length - 1; i \u003e= 0; i--){\n\t\t\tif(!noPropagation) {\n\t\t\t\tdelayedTriggers.push((function(c) { return function(event) { c._trigger(\"deactivate\", event, this._uiHash(this)); }; }).call(this, this.containers[i]));\n\t\t\t}\n\t\t\tif(this.containers[i].containerCache.over) {\n\t\t\t\tdelayedTriggers.push((function(c) { return function(event) { c._trigger(\"out\", event, this._uiHash(this)); }; }).call(this, this.containers[i]));\n\t\t\t\tthis.containers[i].containerCache.over = 0;\n\t\t\t}\n\t\t}\n\n\t\t//Do what was originally in plugins\n\t\tif ( this.storedCursor ) {\n\t\t\tthis.document.find( \"body\" ).css( \"cursor\", this.storedCursor );\n\t\t\tthis.storedStylesheet.remove();\n\t\t}\n\t\tif(this._storedOpacity) {\n\t\t\tthis.helper.css(\"opacity\", this._storedOpacity);\n\t\t}\n\t\tif(this._storedZIndex) {\n\t\t\tthis.helper.css(\"zIndex\", this._storedZIndex === \"auto\" ? \"\" : this._storedZIndex);\n\t\t}\n\n\t\tthis.dragging = false;\n\t\tif(this.cancelHelperRemoval) {\n\t\t\tif(!noPropagation) {\n\t\t\t\tthis._trigger(\"beforeStop\", event, this._uiHash());\n\t\t\t\tfor (i=0; i \u003c delayedTriggers.length; i++) {\n\t\t\t\t\tdelayedTriggers[i].call(this, event);\n\t\t\t\t} //Trigger all delayed events\n\t\t\t\tthis._trigger(\"stop\", event, this._uiHash());\n\t\t\t}\n\n\t\t\tthis.fromOutside = false;\n\t\t\treturn false;\n\t\t}\n\n\t\tif(!noPropagation) {\n\t\t\tthis._trigger(\"beforeStop\", event, this._uiHash());\n\t\t}\n\n\t\t//$(this.placeholder[0]).remove(); would have been the jQuery way - unfortunately, it unbinds ALL events from the original node!\n\t\tthis.placeholder[0].parentNode.removeChild(this.placeholder[0]);\n\n\t\tif(this.helper[0] !== this.currentItem[0]) {\n\t\t\tthis.helper.remove();\n\t\t}\n\t\tthis.helper = null;\n\n\t\tif(!noPropagation) {\n\t\t\tfor (i=0; i \u003c delayedTriggers.length; i++) {\n\t\t\t\tdelayedTriggers[i].call(this, event);\n\t\t\t} //Trigger all delayed events\n\t\t\tthis._trigger(\"stop\", event, this._uiHash());\n\t\t}\n\n\t\tthis.fromOutside = false;\n\t\treturn true;\n\n\t},\n\n\t_trigger: function() {\n\t\tif ($.Widget.prototype._trigger.apply(this, arguments) === false) {\n\t\t\tthis.cancel();\n\t\t}\n\t},\n\n\t_uiHash: function(_inst) {\n\t\tvar inst = _inst || this;\n\t\treturn {\n\t\t\thelper: inst.helper,\n\t\t\tplaceholder: inst.placeholder || $([]),\n\t\t\tposition: inst.position,\n\t\t\toriginalPosition: inst.originalPosition,\n\t\t\toffset: inst.positionAbs,\n\t\t\titem: inst.currentItem,\n\t\t\tsender: _inst ? _inst.element : null\n\t\t};\n\t}\n\n});\n\n})(jQuery);\n\n(function($, undefined) {\n\nvar dataSpace = \"ui-effects-\";\n\n$.effects = {\n\teffect: {}\n};\n\n/*!\n * jQuery Color Animations v2.1.2\n * https://github.com/jquery/jquery-color\n *\n * Copyright 2013 jQuery Foundation and other contributors\n * Released under the MIT license.\n * http://jquery.org/license\n *\n * Date: Wed Jan 16 08:47:09 2013 -0600\n */\n(function( jQuery, undefined ) {\n\n\tvar stepHooks = \"backgroundColor borderBottomColor borderLeftColor borderRightColor borderTopColor color columnRuleColor outlineColor textDecorationColor textEmphasisColor\",\n\n\t// plusequals test for += 100 -= 100\n\trplusequals = /^([\\-+])=\\s*(\\d+\\.?\\d*)/,\n\t// a set of RE\u0027s that can match strings and generate color tuples.\n\tstringParsers = [{\n\t\t\tre: /rgba?\\(\\s*(\\d{1,3})\\s*,\\s*(\\d{1,3})\\s*,\\s*(\\d{1,3})\\s*(?:,\\s*(\\d?(?:\\.\\d+)?)\\s*)?\\)/,\n\t\t\tparse: function( execResult ) {\n\t\t\t\treturn [\n\t\t\t\t\texecResult[ 1 ],\n\t\t\t\t\texecResult[ 2 ],\n\t\t\t\t\texecResult[ 3 ],\n\t\t\t\t\texecResult[ 4 ]\n\t\t\t\t];\n\t\t\t}\n\t\t}, {\n\t\t\tre: /rgba?\\(\\s*(\\d+(?:\\.\\d+)?)\\%\\s*,\\s*(\\d+(?:\\.\\d+)?)\\%\\s*,\\s*(\\d+(?:\\.\\d+)?)\\%\\s*(?:,\\s*(\\d?(?:\\.\\d+)?)\\s*)?\\)/,\n\t\t\tparse: function( execResult ) {\n\t\t\t\treturn [\n\t\t\t\t\texecResult[ 1 ] * 2.55,\n\t\t\t\t\texecResult[ 2 ] * 2.55,\n\t\t\t\t\texecResult[ 3 ] * 2.55,\n\t\t\t\t\texecResult[ 4 ]\n\t\t\t\t];\n\t\t\t}\n\t\t}, {\n\t\t\t// this regex ignores A-F because it\u0027s compared against an already lowercased string\n\t\t\tre: /#([a-f0-9]{2})([a-f0-9]{2})([a-f0-9]{2})/,\n\t\t\tparse: function( execResult ) {\n\t\t\t\treturn [\n\t\t\t\t\tparseInt( execResult[ 1 ], 16 ),\n\t\t\t\t\tparseInt( execResult[ 2 ], 16 ),\n\t\t\t\t\tparseInt( execResult[ 3 ], 16 )\n\t\t\t\t];\n\t\t\t}\n\t\t}, {\n\t\t\t// this regex ignores A-F because it\u0027s compared against an already lowercased string\n\t\t\tre: /#([a-f0-9])([a-f0-9])([a-f0-9])/,\n\t\t\tparse: function( execResult ) {\n\t\t\t\treturn [\n\t\t\t\t\tparseInt( execResult[ 1 ] + execResult[ 1 ], 16 ),\n\t\t\t\t\tparseInt( execResult[ 2 ] + execResult[ 2 ], 16 ),\n\t\t\t\t\tparseInt( execResult[ 3 ] + execResult[ 3 ], 16 )\n\t\t\t\t];\n\t\t\t}\n\t\t}, {\n\t\t\tre: /hsla?\\(\\s*(\\d+(?:\\.\\d+)?)\\s*,\\s*(\\d+(?:\\.\\d+)?)\\%\\s*,\\s*(\\d+(?:\\.\\d+)?)\\%\\s*(?:,\\s*(\\d?(?:\\.\\d+)?)\\s*)?\\)/,\n\t\t\tspace: \"hsla\",\n\t\t\tparse: function( execResult ) {\n\t\t\t\treturn [\n\t\t\t\t\texecResult[ 1 ],\n\t\t\t\t\texecResult[ 2 ] / 100,\n\t\t\t\t\texecResult[ 3 ] / 100,\n\t\t\t\t\texecResult[ 4 ]\n\t\t\t\t];\n\t\t\t}\n\t\t}],\n\n\t// jQuery.Color( )\n\tcolor = jQuery.Color = function( color, green, blue, alpha ) {\n\t\treturn new jQuery.Color.fn.parse( color, green, blue, alpha );\n\t},\n\tspaces = {\n\t\trgba: {\n\t\t\tprops: {\n\t\t\t\tred: {\n\t\t\t\t\tidx: 0,\n\t\t\t\t\ttype: \"byte\"\n\t\t\t\t},\n\t\t\t\tgreen: {\n\t\t\t\t\tidx: 1,\n\t\t\t\t\ttype: \"byte\"\n\t\t\t\t},\n\t\t\t\tblue: {\n\t\t\t\t\tidx: 2,\n\t\t\t\t\ttype: \"byte\"\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\n\t\thsla: {\n\t\t\tprops: {\n\t\t\t\thue: {\n\t\t\t\t\tidx: 0,\n\t\t\t\t\ttype: \"degrees\"\n\t\t\t\t},\n\t\t\t\tsaturation: {\n\t\t\t\t\tidx: 1,\n\t\t\t\t\ttype: \"percent\"\n\t\t\t\t},\n\t\t\t\tlightness: {\n\t\t\t\t\tidx: 2,\n\t\t\t\t\ttype: \"percent\"\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t},\n\tpropTypes = {\n\t\t\"byte\": {\n\t\t\tfloor: true,\n\t\t\tmax: 255\n\t\t},\n\t\t\"percent\": {\n\t\t\tmax: 1\n\t\t},\n\t\t\"degrees\": {\n\t\t\tmod: 360,\n\t\t\tfloor: true\n\t\t}\n\t},\n\tsupport = color.support = {},\n\n\t// element for support tests\n\tsupportElem = jQuery( \"\u003cp\u003e\" )[ 0 ],\n\n\t// colors = jQuery.Color.names\n\tcolors,\n\n\t// local aliases of functions called often\n\teach = jQuery.each;\n\n// determine rgba support immediately\nsupportElem.style.cssText = \"background-color:rgba(1,1,1,.5)\";\nsupport.rgba = supportElem.style.backgroundColor.indexOf( \"rgba\" ) \u003e -1;\n\n// define cache name and alpha properties\n// for rgba and hsla spaces\neach( spaces, function( spaceName, space ) {\n\tspace.cache = \"_\" + spaceName;\n\tspace.props.alpha = {\n\t\tidx: 3,\n\t\ttype: \"percent\",\n\t\tdef: 1\n\t};\n});\n\nfunction clamp( value, prop, allowEmpty ) {\n\tvar type = propTypes[ prop.type ] || {};\n\n\tif ( value == null ) {\n\t\treturn (allowEmpty || !prop.def) ? null : prop.def;\n\t}\n\n\t// ~~ is an short way of doing floor for positive numbers\n\tvalue = type.floor ? ~~value : parseFloat( value );\n\n\t// IE will pass in empty strings as value for alpha,\n\t// which will hit this case\n\tif ( isNaN( value ) ) {\n\t\treturn prop.def;\n\t}\n\n\tif ( type.mod ) {\n\t\t// we add mod before modding to make sure that negatives values\n\t\t// get converted properly: -10 -\u003e 350\n\t\treturn (value + type.mod) % type.mod;\n\t}\n\n\t// for now all property types without mod have min and max\n\treturn 0 \u003e value ? 0 : type.max \u003c value ? type.max : value;\n}\n\nfunction stringParse( string ) {\n\tvar inst = color(),\n\t\trgba = inst._rgba = [];\n\n\tstring = string.toLowerCase();\n\n\teach( stringParsers, function( i, parser ) {\n\t\tvar parsed,\n\t\t\tmatch = parser.re.exec( string ),\n\t\t\tvalues = match \u0026\u0026 parser.parse( match ),\n\t\t\tspaceName = parser.space || \"rgba\";\n\n\t\tif ( values ) {\n\t\t\tparsed = inst[ spaceName ]( values );\n\n\t\t\t// if this was an rgba parse the assignment might happen twice\n\t\t\t// oh well....\n\t\t\tinst[ spaces[ spaceName ].cache ] = parsed[ spaces[ spaceName ].cache ];\n\t\t\trgba = inst._rgba = parsed._rgba;\n\n\t\t\t// exit each( stringParsers ) here because we matched\n\t\t\treturn false;\n\t\t}\n\t});\n\n\t// Found a stringParser that handled it\n\tif ( rgba.length ) {\n\n\t\t// if this came from a parsed string, force \"transparent\" when alpha is 0\n\t\t// chrome, (and maybe others) return \"transparent\" as rgba(0,0,0,0)\n\t\tif ( rgba.join() === \"0,0,0,0\" ) {\n\t\t\tjQuery.extend( rgba, colors.transparent );\n\t\t}\n\t\treturn inst;\n\t}\n\n\t// named colors\n\treturn colors[ string ];\n}\n\ncolor.fn = jQuery.extend( color.prototype, {\n\tparse: function( red, green, blue, alpha ) {\n\t\tif ( red === undefined ) {\n\t\t\tthis._rgba = [ null, null, null, null ];\n\t\t\treturn this;\n\t\t}\n\t\tif ( red.jquery || red.nodeType ) {\n\t\t\tred = jQuery( red ).css( green );\n\t\t\tgreen = undefined;\n\t\t}\n\n\t\tvar inst = this,\n\t\t\ttype = jQuery.type( red ),\n\t\t\trgba = this._rgba = [];\n\n\t\t// more than 1 argument specified - assume ( red, green, blue, alpha )\n\t\tif ( green !== undefined ) {\n\t\t\tred = [ red, green, blue, alpha ];\n\t\t\ttype = \"array\";\n\t\t}\n\n\t\tif ( type === \"string\" ) {\n\t\t\treturn this.parse( stringParse( red ) || colors._default );\n\t\t}\n\n\t\tif ( type === \"array\" ) {\n\t\t\teach( spaces.rgba.props, function( key, prop ) {\n\t\t\t\trgba[ prop.idx ] = clamp( red[ prop.idx ], prop );\n\t\t\t});\n\t\t\treturn this;\n\t\t}\n\n\t\tif ( type === \"object\" ) {\n\t\t\tif ( red instanceof color ) {\n\t\t\t\teach( spaces, function( spaceName, space ) {\n\t\t\t\t\tif ( red[ space.cache ] ) {\n\t\t\t\t\t\tinst[ space.cache ] = red[ space.cache ].slice();\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t} else {\n\t\t\t\teach( spaces, function( spaceName, space ) {\n\t\t\t\t\tvar cache = space.cache;\n\t\t\t\t\teach( space.props, function( key, prop ) {\n\n\t\t\t\t\t\t// if the cache doesn\u0027t exist, and we know how to convert\n\t\t\t\t\t\tif ( !inst[ cache ] \u0026\u0026 space.to ) {\n\n\t\t\t\t\t\t\t// if the value was null, we don\u0027t need to copy it\n\t\t\t\t\t\t\t// if the key was alpha, we don\u0027t need to copy it either\n\t\t\t\t\t\t\tif ( key === \"alpha\" || red[ key ] == null ) {\n\t\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tinst[ cache ] = space.to( inst._rgba );\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// this is the only case where we allow nulls for ALL properties.\n\t\t\t\t\t\t// call clamp with alwaysAllowEmpty\n\t\t\t\t\t\tinst[ cache ][ prop.idx ] = clamp( red[ key ], prop, true );\n\t\t\t\t\t});\n\n\t\t\t\t\t// everything defined but alpha?\n\t\t\t\t\tif ( inst[ cache ] \u0026\u0026 jQuery.inArray( null, inst[ cache ].slice( 0, 3 ) ) \u003c 0 ) {\n\t\t\t\t\t\t// use the default of 1\n\t\t\t\t\t\tinst[ cache ][ 3 ] = 1;\n\t\t\t\t\t\tif ( space.from ) {\n\t\t\t\t\t\t\tinst._rgba = space.from( inst[ cache ] );\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t}\n\t\t\treturn this;\n\t\t}\n\t},\n\tis: function( compare ) {\n\t\tvar is = color( compare ),\n\t\t\tsame = true,\n\t\t\tinst = this;\n\n\t\teach( spaces, function( _, space ) {\n\t\t\tvar localCache,\n\t\t\t\tisCache = is[ space.cache ];\n\t\t\tif (isCache) {\n\t\t\t\tlocalCache = inst[ space.cache ] || space.to \u0026\u0026 space.to( inst._rgba ) || [];\n\t\t\t\teach( space.props, function( _, prop ) {\n\t\t\t\t\tif ( isCache[ prop.idx ] != null ) {\n\t\t\t\t\t\tsame = ( isCache[ prop.idx ] === localCache[ prop.idx ] );\n\t\t\t\t\t\treturn same;\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t}\n\t\t\treturn same;\n\t\t});\n\t\treturn same;\n\t},\n\t_space: function() {\n\t\tvar used = [],\n\t\t\tinst = this;\n\t\teach( spaces, function( spaceName, space ) {\n\t\t\tif ( inst[ space.cache ] ) {\n\t\t\t\tused.push( spaceName );\n\t\t\t}\n\t\t});\n\t\treturn used.pop();\n\t},\n\ttransition: function( other, distance ) {\n\t\tvar end = color( other ),\n\t\t\tspaceName = end._space(),\n\t\t\tspace = spaces[ spaceName ],\n\t\t\tstartColor = this.alpha() === 0 ? color( \"transparent\" ) : this,\n\t\t\tstart = startColor[ space.cache ] || space.to( startColor._rgba ),\n\t\t\tresult = start.slice();\n\n\t\tend = end[ space.cache ];\n\t\teach( space.props, function( key, prop ) {\n\t\t\tvar index = prop.idx,\n\t\t\t\tstartValue = start[ index ],\n\t\t\t\tendValue = end[ index ],\n\t\t\t\ttype = propTypes[ prop.type ] || {};\n\n\t\t\t// if null, don\u0027t override start value\n\t\t\tif ( endValue === null ) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\t// if null - use end\n\t\t\tif ( startValue === null ) {\n\t\t\t\tresult[ index ] = endValue;\n\t\t\t} else {\n\t\t\t\tif ( type.mod ) {\n\t\t\t\t\tif ( endValue - startValue \u003e type.mod / 2 ) {\n\t\t\t\t\t\tstartValue += type.mod;\n\t\t\t\t\t} else if ( startValue - endValue \u003e type.mod / 2 ) {\n\t\t\t\t\t\tstartValue -= type.mod;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tresult[ index ] = clamp( ( endValue - startValue ) * distance + startValue, prop );\n\t\t\t}\n\t\t});\n\t\treturn this[ spaceName ]( result );\n\t},\n\tblend: function( opaque ) {\n\t\t// if we are already opaque - return ourself\n\t\tif ( this._rgba[ 3 ] === 1 ) {\n\t\t\treturn this;\n\t\t}\n\n\t\tvar rgb = this._rgba.slice(),\n\t\t\ta = rgb.pop(),\n\t\t\tblend = color( opaque )._rgba;\n\n\t\treturn color( jQuery.map( rgb, function( v, i ) {\n\t\t\treturn ( 1 - a ) * blend[ i ] + a * v;\n\t\t}));\n\t},\n\ttoRgbaString: function() {\n\t\tvar prefix = \"rgba(\",\n\t\t\trgba = jQuery.map( this._rgba, function( v, i ) {\n\t\t\t\treturn v == null ? ( i \u003e 2 ? 1 : 0 ) : v;\n\t\t\t});\n\n\t\tif ( rgba[ 3 ] === 1 ) {\n\t\t\trgba.pop();\n\t\t\tprefix = \"rgb(\";\n\t\t}\n\n\t\treturn prefix + rgba.join() + \")\";\n\t},\n\ttoHslaString: function() {\n\t\tvar prefix = \"hsla(\",\n\t\t\thsla = jQuery.map( this.hsla(), function( v, i ) {\n\t\t\t\tif ( v == null ) {\n\t\t\t\t\tv = i \u003e 2 ? 1 : 0;\n\t\t\t\t}\n\n\t\t\t\t// catch 1 and 2\n\t\t\t\tif ( i \u0026\u0026 i \u003c 3 ) {\n\t\t\t\t\tv = Math.round( v * 100 ) + \"%\";\n\t\t\t\t}\n\t\t\t\treturn v;\n\t\t\t});\n\n\t\tif ( hsla[ 3 ] === 1 ) {\n\t\t\thsla.pop();\n\t\t\tprefix = \"hsl(\";\n\t\t}\n\t\treturn prefix + hsla.join() + \")\";\n\t},\n\ttoHexString: function( includeAlpha ) {\n\t\tvar rgba = this._rgba.slice(),\n\t\t\talpha = rgba.pop();\n\n\t\tif ( includeAlpha ) {\n\t\t\trgba.push( ~~( alpha * 255 ) );\n\t\t}\n\n\t\treturn \"#\" + jQuery.map( rgba, function( v ) {\n\n\t\t\t// default to 0 when nulls exist\n\t\t\tv = ( v || 0 ).toString( 16 );\n\t\t\treturn v.length === 1 ? \"0\" + v : v;\n\t\t}).join(\"\");\n\t},\n\ttoString: function() {\n\t\treturn this._rgba[ 3 ] === 0 ? \"transparent\" : this.toRgbaString();\n\t}\n});\ncolor.fn.parse.prototype = color.fn;\n\n// hsla conversions adapted from:\n// https://code.google.com/p/maashaack/source/browse/packages/graphics/trunk/src/graphics/colors/HUE2RGB.as?r=5021\n\nfunction hue2rgb( p, q, h ) {\n\th = ( h + 1 ) % 1;\n\tif ( h * 6 \u003c 1 ) {\n\t\treturn p + (q - p) * h * 6;\n\t}\n\tif ( h * 2 \u003c 1) {\n\t\treturn q;\n\t}\n\tif ( h * 3 \u003c 2 ) {\n\t\treturn p + (q - p) * ((2/3) - h) * 6;\n\t}\n\treturn p;\n}\n\nspaces.hsla.to = function ( rgba ) {\n\tif ( rgba[ 0 ] == null || rgba[ 1 ] == null || rgba[ 2 ] == null ) {\n\t\treturn [ null, null, null, rgba[ 3 ] ];\n\t}\n\tvar r = rgba[ 0 ] / 255,\n\t\tg = rgba[ 1 ] / 255,\n\t\tb = rgba[ 2 ] / 255,\n\t\ta = rgba[ 3 ],\n\t\tmax = Math.max( r, g, b ),\n\t\tmin = Math.min( r, g, b ),\n\t\tdiff = max - min,\n\t\tadd = max + min,\n\t\tl = add * 0.5,\n\t\th, s;\n\n\tif ( min === max ) {\n\t\th = 0;\n\t} else if ( r === max ) {\n\t\th = ( 60 * ( g - b ) / diff ) + 360;\n\t} else if ( g === max ) {\n\t\th = ( 60 * ( b - r ) / diff ) + 120;\n\t} else {\n\t\th = ( 60 * ( r - g ) / diff ) + 240;\n\t}\n\n\t// chroma (diff) == 0 means greyscale which, by definition, saturation = 0%\n\t// otherwise, saturation is based on the ratio of chroma (diff) to lightness (add)\n\tif ( diff === 0 ) {\n\t\ts = 0;\n\t} else if ( l \u003c= 0.5 ) {\n\t\ts = diff / add;\n\t} else {\n\t\ts = diff / ( 2 - add );\n\t}\n\treturn [ Math.round(h) % 360, s, l, a == null ? 1 : a ];\n};\n\nspaces.hsla.from = function ( hsla ) {\n\tif ( hsla[ 0 ] == null || hsla[ 1 ] == null || hsla[ 2 ] == null ) {\n\t\treturn [ null, null, null, hsla[ 3 ] ];\n\t}\n\tvar h = hsla[ 0 ] / 360,\n\t\ts = hsla[ 1 ],\n\t\tl = hsla[ 2 ],\n\t\ta = hsla[ 3 ],\n\t\tq = l \u003c= 0.5 ? l * ( 1 + s ) : l + s - l * s,\n\t\tp = 2 * l - q;\n\n\treturn [\n\t\tMath.round( hue2rgb( p, q, h + ( 1 / 3 ) ) * 255 ),\n\t\tMath.round( hue2rgb( p, q, h ) * 255 ),\n\t\tMath.round( hue2rgb( p, q, h - ( 1 / 3 ) ) * 255 ),\n\t\ta\n\t];\n};\n\n\neach( spaces, function( spaceName, space ) {\n\tvar props = space.props,\n\t\tcache = space.cache,\n\t\tto = space.to,\n\t\tfrom = space.from;\n\n\t// makes rgba() and hsla()\n\tcolor.fn[ spaceName ] = function( value ) {\n\n\t\t// generate a cache for this space if it doesn\u0027t exist\n\t\tif ( to \u0026\u0026 !this[ cache ] ) {\n\t\t\tthis[ cache ] = to( this._rgba );\n\t\t}\n\t\tif ( value === undefined ) {\n\t\t\treturn this[ cache ].slice();\n\t\t}\n\n\t\tvar ret,\n\t\t\ttype = jQuery.type( value ),\n\t\t\tarr = ( type === \"array\" || type === \"object\" ) ? value : arguments,\n\t\t\tlocal = this[ cache ].slice();\n\n\t\teach( props, function( key, prop ) {\n\t\t\tvar val = arr[ type === \"object\" ? key : prop.idx ];\n\t\t\tif ( val == null ) {\n\t\t\t\tval = local[ prop.idx ];\n\t\t\t}\n\t\t\tlocal[ prop.idx ] = clamp( val, prop );\n\t\t});\n\n\t\tif ( from ) {\n\t\t\tret = color( from( local ) );\n\t\t\tret[ cache ] = local;\n\t\t\treturn ret;\n\t\t} else {\n\t\t\treturn color( local );\n\t\t}\n\t};\n\n\t// makes red() green() blue() alpha() hue() saturation() lightness()\n\teach( props, function( key, prop ) {\n\t\t// alpha is included in more than one space\n\t\tif ( color.fn[ key ] ) {\n\t\t\treturn;\n\t\t}\n\t\tcolor.fn[ key ] = function( value ) {\n\t\t\tvar vtype = jQuery.type( value ),\n\t\t\t\tfn = ( key === \"alpha\" ? ( this._hsla ? \"hsla\" : \"rgba\" ) : spaceName ),\n\t\t\t\tlocal = this[ fn ](),\n\t\t\t\tcur = local[ prop.idx ],\n\t\t\t\tmatch;\n\n\t\t\tif ( vtype === \"undefined\" ) {\n\t\t\t\treturn cur;\n\t\t\t}\n\n\t\t\tif ( vtype === \"function\" ) {\n\t\t\t\tvalue = value.call( this, cur );\n\t\t\t\tvtype = jQuery.type( value );\n\t\t\t}\n\t\t\tif ( value == null \u0026\u0026 prop.empty ) {\n\t\t\t\treturn this;\n\t\t\t}\n\t\t\tif ( vtype === \"string\" ) {\n\t\t\t\tmatch = rplusequals.exec( value );\n\t\t\t\tif ( match ) {\n\t\t\t\t\tvalue = cur + parseFloat( match[ 2 ] ) * ( match[ 1 ] === \"+\" ? 1 : -1 );\n\t\t\t\t}\n\t\t\t}\n\t\t\tlocal[ prop.idx ] = value;\n\t\t\treturn this[ fn ]( local );\n\t\t};\n\t});\n});\n\n// add cssHook and .fx.step function for each named hook.\n// accept a space separated string of properties\ncolor.hook = function( hook ) {\n\tvar hooks = hook.split( \" \" );\n\teach( hooks, function( i, hook ) {\n\t\tjQuery.cssHooks[ hook ] = {\n\t\t\tset: function( elem, value ) {\n\t\t\t\tvar parsed, curElem,\n\t\t\t\t\tbackgroundColor = \"\";\n\n\t\t\t\tif ( value !== \"transparent\" \u0026\u0026 ( jQuery.type( value ) !== \"string\" || ( parsed = stringParse( value ) ) ) ) {\n\t\t\t\t\tvalue = color( parsed || value );\n\t\t\t\t\tif ( !support.rgba \u0026\u0026 value._rgba[ 3 ] !== 1 ) {\n\t\t\t\t\t\tcurElem = hook === \"backgroundColor\" ? elem.parentNode : elem;\n\t\t\t\t\t\twhile (\n\t\t\t\t\t\t\t(backgroundColor === \"\" || backgroundColor === \"transparent\") \u0026\u0026\n\t\t\t\t\t\t\tcurElem \u0026\u0026 curElem.style\n\t\t\t\t\t\t) {\n\t\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\t\tbackgroundColor = jQuery.css( curElem, \"backgroundColor\" );\n\t\t\t\t\t\t\t\tcurElem = curElem.parentNode;\n\t\t\t\t\t\t\t} catch ( e ) {\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tvalue = value.blend( backgroundColor \u0026\u0026 backgroundColor !== \"transparent\" ?\n\t\t\t\t\t\t\tbackgroundColor :\n\t\t\t\t\t\t\t\"_default\" );\n\t\t\t\t\t}\n\n\t\t\t\t\tvalue = value.toRgbaString();\n\t\t\t\t}\n\t\t\t\ttry {\n\t\t\t\t\telem.style[ hook ] = value;\n\t\t\t\t} catch( e ) {\n\t\t\t\t\t// wrapped to prevent IE from throwing errors on \"invalid\" values like \u0027auto\u0027 or \u0027inherit\u0027\n\t\t\t\t}\n\t\t\t}\n\t\t};\n\t\tjQuery.fx.step[ hook ] = function( fx ) {\n\t\t\tif ( !fx.colorInit ) {\n\t\t\t\tfx.start = color( fx.elem, hook );\n\t\t\t\tfx.end = color( fx.end );\n\t\t\t\tfx.colorInit = true;\n\t\t\t}\n\t\t\tjQuery.cssHooks[ hook ].set( fx.elem, fx.start.transition( fx.end, fx.pos ) );\n\t\t};\n\t});\n\n};\n\ncolor.hook( stepHooks );\n\njQuery.cssHooks.borderColor = {\n\texpand: function( value ) {\n\t\tvar expanded = {};\n\n\t\teach( [ \"Top\", \"Right\", \"Bottom\", \"Left\" ], function( i, part ) {\n\t\t\texpanded[ \"border\" + part + \"Color\" ] = value;\n\t\t});\n\t\treturn expanded;\n\t}\n};\n\n// Basic color names only.\n// Usage of any of the other color names requires adding yourself or including\n// jquery.color.svg-names.js.\ncolors = jQuery.Color.names = {\n\t// 4.1. Basic color keywords\n\taqua: \"#00ffff\",\n\tblack: \"#000000\",\n\tblue: \"#0000ff\",\n\tfuchsia: \"#ff00ff\",\n\tgray: \"#808080\",\n\tgreen: \"#008000\",\n\tlime: \"#00ff00\",\n\tmaroon: \"#800000\",\n\tnavy: \"#000080\",\n\tolive: \"#808000\",\n\tpurple: \"#800080\",\n\tred: \"#ff0000\",\n\tsilver: \"#c0c0c0\",\n\tteal: \"#008080\",\n\twhite: \"#ffffff\",\n\tyellow: \"#ffff00\",\n\n\t// 4.2.3. \"transparent\" color keyword\n\ttransparent: [ null, null, null, 0 ],\n\n\t_default: \"#ffffff\"\n};\n\n})( jQuery );\n\n\n/******************************************************************************/\n/****************************** CLASS ANIMATIONS ******************************/\n/******************************************************************************/\n(function() {\n\nvar classAnimationActions = [ \"add\", \"remove\", \"toggle\" ],\n\tshorthandStyles = {\n\t\tborder: 1,\n\t\tborderBottom: 1,\n\t\tborderColor: 1,\n\t\tborderLeft: 1,\n\t\tborderRight: 1,\n\t\tborderTop: 1,\n\t\tborderWidth: 1,\n\t\tmargin: 1,\n\t\tpadding: 1\n\t};\n\n$.each([ \"borderLeftStyle\", \"borderRightStyle\", \"borderBottomStyle\", \"borderTopStyle\" ], function( _, prop ) {\n\t$.fx.step[ prop ] = function( fx ) {\n\t\tif ( fx.end !== \"none\" \u0026\u0026 !fx.setAttr || fx.pos === 1 \u0026\u0026 !fx.setAttr ) {\n\t\t\tjQuery.style( fx.elem, prop, fx.end );\n\t\t\tfx.setAttr = true;\n\t\t}\n\t};\n});\n\nfunction getElementStyles( elem ) {\n\tvar key, len,\n\t\tstyle = elem.ownerDocument.defaultView ?\n\t\t\telem.ownerDocument.defaultView.getComputedStyle( elem, null ) :\n\t\t\telem.currentStyle,\n\t\tstyles = {};\n\n\tif ( style \u0026\u0026 style.length \u0026\u0026 style[ 0 ] \u0026\u0026 style[ style[ 0 ] ] ) {\n\t\tlen = style.length;\n\t\twhile ( len-- ) {\n\t\t\tkey = style[ len ];\n\t\t\tif ( typeof style[ key ] === \"string\" ) {\n\t\t\t\tstyles[ $.camelCase( key ) ] = style[ key ];\n\t\t\t}\n\t\t}\n\t// support: Opera, IE \u003c9\n\t} else {\n\t\tfor ( key in style ) {\n\t\t\tif ( typeof style[ key ] === \"string\" ) {\n\t\t\t\tstyles[ key ] = style[ key ];\n\t\t\t}\n\t\t}\n\t}\n\n\treturn styles;\n}\n\n\nfunction styleDifference( oldStyle, newStyle ) {\n\tvar diff = {},\n\t\tname, value;\n\n\tfor ( name in newStyle ) {\n\t\tvalue = newStyle[ name ];\n\t\tif ( oldStyle[ name ] !== value ) {\n\t\t\tif ( !shorthandStyles[ name ] ) {\n\t\t\t\tif ( $.fx.step[ name ] || !isNaN( parseFloat( value ) ) ) {\n\t\t\t\t\tdiff[ name ] = value;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\treturn diff;\n}\n\n// support: jQuery \u003c1.8\nif ( !$.fn.addBack ) {\n\t$.fn.addBack = function( selector ) {\n\t\treturn this.add( selector == null ?\n\t\t\tthis.prevObject : this.prevObject.filter( selector )\n\t\t);\n\t};\n}\n\n$.effects.animateClass = function( value, duration, easing, callback ) {\n\tvar o = $.speed( duration, easing, callback );\n\n\treturn this.queue( function() {\n\t\tvar animated = $( this ),\n\t\t\tbaseClass = animated.attr( \"class\" ) || \"\",\n\t\t\tapplyClassChange,\n\t\t\tallAnimations = o.children ? animated.find( \"*\" ).addBack() : animated;\n\n\t\t// map the animated objects to store the original styles.\n\t\tallAnimations = allAnimations.map(function() {\n\t\t\tvar el = $( this );\n\t\t\treturn {\n\t\t\t\tel: el,\n\t\t\t\tstart: getElementStyles( this )\n\t\t\t};\n\t\t});\n\n\t\t// apply class change\n\t\tapplyClassChange = function() {\n\t\t\t$.each( classAnimationActions, function(i, action) {\n\t\t\t\tif ( value[ action ] ) {\n\t\t\t\t\tanimated[ action + \"Class\" ]( value[ action ] );\n\t\t\t\t}\n\t\t\t});\n\t\t};\n\t\tapplyClassChange();\n\n\t\t// map all animated objects again - calculate new styles and diff\n\t\tallAnimations = allAnimations.map(function() {\n\t\t\tthis.end = getElementStyles( this.el[ 0 ] );\n\t\t\tthis.diff = styleDifference( this.start, this.end );\n\t\t\treturn this;\n\t\t});\n\n\t\t// apply original class\n\t\tanimated.attr( \"class\", baseClass );\n\n\t\t// map all animated objects again - this time collecting a promise\n\t\tallAnimations = allAnimations.map(function() {\n\t\t\tvar styleInfo = this,\n\t\t\t\tdfd = $.Deferred(),\n\t\t\t\topts = $.extend({}, o, {\n\t\t\t\t\tqueue: false,\n\t\t\t\t\tcomplete: function() {\n\t\t\t\t\t\tdfd.resolve( styleInfo );\n\t\t\t\t\t}\n\t\t\t\t});\n\n\t\t\tthis.el.animate( this.diff, opts );\n\t\t\treturn dfd.promise();\n\t\t});\n\n\t\t// once all animations have completed:\n\t\t$.when.apply( $, allAnimations.get() ).done(function() {\n\n\t\t\t// set the final class\n\t\t\tapplyClassChange();\n\n\t\t\t// for each animated element,\n\t\t\t// clear all css properties that were animated\n\t\t\t$.each( arguments, function() {\n\t\t\t\tvar el = this.el;\n\t\t\t\t$.each( this.diff, function(key) {\n\t\t\t\t\tel.css( key, \"\" );\n\t\t\t\t});\n\t\t\t});\n\n\t\t\t// this is guarnteed to be there if you use jQuery.speed()\n\t\t\t// it also handles dequeuing the next anim...\n\t\t\to.complete.call( animated[ 0 ] );\n\t\t});\n\t});\n};\n\n$.fn.extend({\n\taddClass: (function( orig ) {\n\t\treturn function( classNames, speed, easing, callback ) {\n\t\t\treturn speed ?\n\t\t\t\t$.effects.animateClass.call( this,\n\t\t\t\t\t{ add: classNames }, speed, easing, callback ) :\n\t\t\t\torig.apply( this, arguments );\n\t\t};\n\t})( $.fn.addClass ),\n\n\tremoveClass: (function( orig ) {\n\t\treturn function( classNames, speed, easing, callback ) {\n\t\t\treturn arguments.length \u003e 1 ?\n\t\t\t\t$.effects.animateClass.call( this,\n\t\t\t\t\t{ remove: classNames }, speed, easing, callback ) :\n\t\t\t\torig.apply( this, arguments );\n\t\t};\n\t})( $.fn.removeClass ),\n\n\ttoggleClass: (function( orig ) {\n\t\treturn function( classNames, force, speed, easing, callback ) {\n\t\t\tif ( typeof force === \"boolean\" || force === undefined ) {\n\t\t\t\tif ( !speed ) {\n\t\t\t\t\t// without speed parameter\n\t\t\t\t\treturn orig.apply( this, arguments );\n\t\t\t\t} else {\n\t\t\t\t\treturn $.effects.animateClass.call( this,\n\t\t\t\t\t\t(force ? { add: classNames } : { remove: classNames }),\n\t\t\t\t\t\tspeed, easing, callback );\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\t// without force parameter\n\t\t\t\treturn $.effects.animateClass.call( this,\n\t\t\t\t\t{ toggle: classNames }, force, speed, easing );\n\t\t\t}\n\t\t};\n\t})( $.fn.toggleClass ),\n\n\tswitchClass: function( remove, add, speed, easing, callback) {\n\t\treturn $.effects.animateClass.call( this, {\n\t\t\tadd: add,\n\t\t\tremove: remove\n\t\t}, speed, easing, callback );\n\t}\n});\n\n})();\n\n/******************************************************************************/\n/*********************************** EFFECTS **********************************/\n/******************************************************************************/\n\n(function() {\n\n$.extend( $.effects, {\n\tversion: \"1.10.2\",\n\n\t// Saves a set of properties in a data storage\n\tsave: function( element, set ) {\n\t\tfor( var i=0; i \u003c set.length; i++ ) {\n\t\t\tif ( set[ i ] !== null ) {\n\t\t\t\telement.data( dataSpace + set[ i ], element[ 0 ].style[ set[ i ] ] );\n\t\t\t}\n\t\t}\n\t},\n\n\t// Restores a set of previously saved properties from a data storage\n\trestore: function( element, set ) {\n\t\tvar val, i;\n\t\tfor( i=0; i \u003c set.length; i++ ) {\n\t\t\tif ( set[ i ] !== null ) {\n\t\t\t\tval = element.data( dataSpace + set[ i ] );\n\t\t\t\t// support: jQuery 1.6.2\n\t\t\t\t// http://bugs.jquery.com/ticket/9917\n\t\t\t\t// jQuery 1.6.2 incorrectly returns undefined for any falsy value.\n\t\t\t\t// We can\u0027t differentiate between \"\" and 0 here, so we just assume\n\t\t\t\t// empty string since it\u0027s likely to be a more common value...\n\t\t\t\tif ( val === undefined ) {\n\t\t\t\t\tval = \"\";\n\t\t\t\t}\n\t\t\t\telement.css( set[ i ], val );\n\t\t\t}\n\t\t}\n\t},\n\n\tsetMode: function( el, mode ) {\n\t\tif (mode === \"toggle\") {\n\t\t\tmode = el.is( \":hidden\" ) ? \"show\" : \"hide\";\n\t\t}\n\t\treturn mode;\n\t},\n\n\t// Translates a [top,left] array into a baseline value\n\t// this should be a little more flexible in the future to handle a string \u0026 hash\n\tgetBaseline: function( origin, original ) {\n\t\tvar y, x;\n\t\tswitch ( origin[ 0 ] ) {\n\t\t\tcase \"top\": y = 0; break;\n\t\t\tcase \"middle\": y = 0.5; break;\n\t\t\tcase \"bottom\": y = 1; break;\n\t\t\tdefault: y = origin[ 0 ] / original.height;\n\t\t}\n\t\tswitch ( origin[ 1 ] ) {\n\t\t\tcase \"left\": x = 0; break;\n\t\t\tcase \"center\": x = 0.5; break;\n\t\t\tcase \"right\": x = 1; break;\n\t\t\tdefault: x = origin[ 1 ] / original.width;\n\t\t}\n\t\treturn {\n\t\t\tx: x,\n\t\t\ty: y\n\t\t};\n\t},\n\n\t// Wraps the element around a wrapper that copies position properties\n\tcreateWrapper: function( element ) {\n\n\t\t// if the element is already wrapped, return it\n\t\tif ( element.parent().is( \".ui-effects-wrapper\" )) {\n\t\t\treturn element.parent();\n\t\t}\n\n\t\t// wrap the element\n\t\tvar props = {\n\t\t\t\twidth: element.outerWidth(true),\n\t\t\t\theight: element.outerHeight(true),\n\t\t\t\t\"float\": element.css( \"float\" )\n\t\t\t},\n\t\t\twrapper = $( \"\u003cdiv\u003e\u003c/div\u003e\" )\n\t\t\t\t.addClass( \"ui-effects-wrapper\" )\n\t\t\t\t.css({\n\t\t\t\t\tfontSize: \"100%\",\n\t\t\t\t\tbackground: \"transparent\",\n\t\t\t\t\tborder: \"none\",\n\t\t\t\t\tmargin: 0,\n\t\t\t\t\tpadding: 0\n\t\t\t\t}),\n\t\t\t// Store the size in case width/height are defined in % - Fixes #5245\n\t\t\tsize = {\n\t\t\t\twidth: element.width(),\n\t\t\t\theight: element.height()\n\t\t\t},\n\t\t\tactive = document.activeElement;\n\n\t\t// support: Firefox\n\t\t// Firefox incorrectly exposes anonymous content\n\t\t// https://bugzilla.mozilla.org/show_bug.cgi?id=561664\n\t\ttry {\n\t\t\tactive.id;\n\t\t} catch( e ) {\n\t\t\tactive = document.body;\n\t\t}\n\n\t\telement.wrap( wrapper );\n\n\t\t// Fixes #7595 - Elements lose focus when wrapped.\n\t\tif ( element[ 0 ] === active || $.contains( element[ 0 ], active ) ) {\n\t\t\t$( active ).focus();\n\t\t}\n\n\t\twrapper = element.parent(); //Hotfix for jQuery 1.4 since some change in wrap() seems to actually lose the reference to the wrapped element\n\n\t\t// transfer positioning properties to the wrapper\n\t\tif ( element.css( \"position\" ) === \"static\" ) {\n\t\t\twrapper.css({ position: \"relative\" });\n\t\t\telement.css({ position: \"relative\" });\n\t\t} else {\n\t\t\t$.extend( props, {\n\t\t\t\tposition: element.css( \"position\" ),\n\t\t\t\tzIndex: element.css( \"z-index\" )\n\t\t\t});\n\t\t\t$.each([ \"top\", \"left\", \"bottom\", \"right\" ], function(i, pos) {\n\t\t\t\tprops[ pos ] = element.css( pos );\n\t\t\t\tif ( isNaN( parseInt( props[ pos ], 10 ) ) ) {\n\t\t\t\t\tprops[ pos ] = \"auto\";\n\t\t\t\t}\n\t\t\t});\n\t\t\telement.css({\n\t\t\t\tposition: \"relative\",\n\t\t\t\ttop: 0,\n\t\t\t\tleft: 0,\n\t\t\t\tright: \"auto\",\n\t\t\t\tbottom: \"auto\"\n\t\t\t});\n\t\t}\n\t\telement.css(size);\n\n\t\treturn wrapper.css( props ).show();\n\t},\n\n\tremoveWrapper: function( element ) {\n\t\tvar active = document.activeElement;\n\n\t\tif ( element.parent().is( \".ui-effects-wrapper\" ) ) {\n\t\t\telement.parent().replaceWith( element );\n\n\t\t\t// Fixes #7595 - Elements lose focus when wrapped.\n\t\t\tif ( element[ 0 ] === active || $.contains( element[ 0 ], active ) ) {\n\t\t\t\t$( active ).focus();\n\t\t\t}\n\t\t}\n\n\n\t\treturn element;\n\t},\n\n\tsetTransition: function( element, list, factor, value ) {\n\t\tvalue = value || {};\n\t\t$.each( list, function( i, x ) {\n\t\t\tvar unit = element.cssUnit( x );\n\t\t\tif ( unit[ 0 ] \u003e 0 ) {\n\t\t\t\tvalue[ x ] = unit[ 0 ] * factor + unit[ 1 ];\n\t\t\t}\n\t\t});\n\t\treturn value;\n\t}\n});\n\n// return an effect options object for the given parameters:\nfunction _normalizeArguments( effect, options, speed, callback ) {\n\n\t// allow passing all options as the first parameter\n\tif ( $.isPlainObject( effect ) ) {\n\t\toptions = effect;\n\t\teffect = effect.effect;\n\t}\n\n\t// convert to an object\n\teffect = { effect: effect };\n\n\t// catch (effect, null, ...)\n\tif ( options == null ) {\n\t\toptions = {};\n\t}\n\n\t// catch (effect, callback)\n\tif ( $.isFunction( options ) ) {\n\t\tcallback = options;\n\t\tspeed = null;\n\t\toptions = {};\n\t}\n\n\t// catch (effect, speed, ?)\n\tif ( typeof options === \"number\" || $.fx.speeds[ options ] ) {\n\t\tcallback = speed;\n\t\tspeed = options;\n\t\toptions = {};\n\t}\n\n\t// catch (effect, options, callback)\n\tif ( $.isFunction( speed ) ) {\n\t\tcallback = speed;\n\t\tspeed = null;\n\t}\n\n\t// add options to effect\n\tif ( options ) {\n\t\t$.extend( effect, options );\n\t}\n\n\tspeed = speed || options.duration;\n\teffect.duration = $.fx.off ? 0 :\n\t\ttypeof speed === \"number\" ? speed :\n\t\tspeed in $.fx.speeds ? $.fx.speeds[ speed ] :\n\t\t$.fx.speeds._default;\n\n\teffect.complete = callback || options.complete;\n\n\treturn effect;\n}\n\nfunction standardAnimationOption( option ) {\n\t// Valid standard speeds (nothing, number, named speed)\n\tif ( !option || typeof option === \"number\" || $.fx.speeds[ option ] ) {\n\t\treturn true;\n\t}\n\n\t// Invalid strings - treat as \"normal\" speed\n\tif ( typeof option === \"string\" \u0026\u0026 !$.effects.effect[ option ] ) {\n\t\treturn true;\n\t}\n\n\t// Complete callback\n\tif ( $.isFunction( option ) ) {\n\t\treturn true;\n\t}\n\n\t// Options hash (but not naming an effect)\n\tif ( typeof option === \"object\" \u0026\u0026 !option.effect ) {\n\t\treturn true;\n\t}\n\n\t// Didn\u0027t match any standard API\n\treturn false;\n}\n\n$.fn.extend({\n\teffect: function( /* effect, options, speed, callback */ ) {\n\t\tvar args = _normalizeArguments.apply( this, arguments ),\n\t\t\tmode = args.mode,\n\t\t\tqueue = args.queue,\n\t\t\teffectMethod = $.effects.effect[ args.effect ];\n\n\t\tif ( $.fx.off || !effectMethod ) {\n\t\t\t// delegate to the original method (e.g., .show()) if possible\n\t\t\tif ( mode ) {\n\t\t\t\treturn this[ mode ]( args.duration, args.complete );\n\t\t\t} else {\n\t\t\t\treturn this.each( function() {\n\t\t\t\t\tif ( args.complete ) {\n\t\t\t\t\t\targs.complete.call( this );\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\n\t\tfunction run( next ) {\n\t\t\tvar elem = $( this ),\n\t\t\t\tcomplete = args.complete,\n\t\t\t\tmode = args.mode;\n\n\t\t\tfunction done() {\n\t\t\t\tif ( $.isFunction( complete ) ) {\n\t\t\t\t\tcomplete.call( elem[0] );\n\t\t\t\t}\n\t\t\t\tif ( $.isFunction( next ) ) {\n\t\t\t\t\tnext();\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// If the element already has the correct final state, delegate to\n\t\t\t// the core methods so the internal tracking of \"olddisplay\" works.\n\t\t\tif ( elem.is( \":hidden\" ) ? mode === \"hide\" : mode === \"show\" ) {\n\t\t\t\telem[ mode ]();\n\t\t\t\tdone();\n\t\t\t} else {\n\t\t\t\teffectMethod.call( elem[0], args, done );\n\t\t\t}\n\t\t}\n\n\t\treturn queue === false ? this.each( run ) : this.queue( queue || \"fx\", run );\n\t},\n\n\tshow: (function( orig ) {\n\t\treturn function( option ) {\n\t\t\tif ( standardAnimationOption( option ) ) {\n\t\t\t\treturn orig.apply( this, arguments );\n\t\t\t} else {\n\t\t\t\tvar args = _normalizeArguments.apply( this, arguments );\n\t\t\t\targs.mode = \"show\";\n\t\t\t\treturn this.effect.call( this, args );\n\t\t\t}\n\t\t};\n\t})( $.fn.show ),\n\n\thide: (function( orig ) {\n\t\treturn function( option ) {\n\t\t\tif ( standardAnimationOption( option ) ) {\n\t\t\t\treturn orig.apply( this, arguments );\n\t\t\t} else {\n\t\t\t\tvar args = _normalizeArguments.apply( this, arguments );\n\t\t\t\targs.mode = \"hide\";\n\t\t\t\treturn this.effect.call( this, args );\n\t\t\t}\n\t\t};\n\t})( $.fn.hide ),\n\n\ttoggle: (function( orig ) {\n\t\treturn function( option ) {\n\t\t\tif ( standardAnimationOption( option ) || typeof option === \"boolean\" ) {\n\t\t\t\treturn orig.apply( this, arguments );\n\t\t\t} else {\n\t\t\t\tvar args = _normalizeArguments.apply( this, arguments );\n\t\t\t\targs.mode = \"toggle\";\n\t\t\t\treturn this.effect.call( this, args );\n\t\t\t}\n\t\t};\n\t})( $.fn.toggle ),\n\n\t// helper functions\n\tcssUnit: function(key) {\n\t\tvar style = this.css( key ),\n\t\t\tval = [];\n\n\t\t$.each( [ \"em\", \"px\", \"%\", \"pt\" ], function( i, unit ) {\n\t\t\tif ( style.indexOf( unit ) \u003e 0 ) {\n\t\t\t\tval = [ parseFloat( style ), unit ];\n\t\t\t}\n\t\t});\n\t\treturn val;\n\t}\n});\n\n})();\n\n/******************************************************************************/\n/*********************************** EASING ***********************************/\n/******************************************************************************/\n\n(function() {\n\n// based on easing equations from Robert Penner (http://www.robertpenner.com/easing)\n\nvar baseEasings = {};\n\n$.each( [ \"Quad\", \"Cubic\", \"Quart\", \"Quint\", \"Expo\" ], function( i, name ) {\n\tbaseEasings[ name ] = function( p ) {\n\t\treturn Math.pow( p, i + 2 );\n\t};\n});\n\n$.extend( baseEasings, {\n\tSine: function ( p ) {\n\t\treturn 1 - Math.cos( p * Math.PI / 2 );\n\t},\n\tCirc: function ( p ) {\n\t\treturn 1 - Math.sqrt( 1 - p * p );\n\t},\n\tElastic: function( p ) {\n\t\treturn p === 0 || p === 1 ? p :\n\t\t\t-Math.pow( 2, 8 * (p - 1) ) * Math.sin( ( (p - 1) * 80 - 7.5 ) * Math.PI / 15 );\n\t},\n\tBack: function( p ) {\n\t\treturn p * p * ( 3 * p - 2 );\n\t},\n\tBounce: function ( p ) {\n\t\tvar pow2,\n\t\t\tbounce = 4;\n\n\t\twhile ( p \u003c ( ( pow2 = Math.pow( 2, --bounce ) ) - 1 ) / 11 ) {}\n\t\treturn 1 / Math.pow( 4, 3 - bounce ) - 7.5625 * Math.pow( ( pow2 * 3 - 2 ) / 22 - p, 2 );\n\t}\n});\n\n$.each( baseEasings, function( name, easeIn ) {\n\t$.easing[ \"easeIn\" + name ] = easeIn;\n\t$.easing[ \"easeOut\" + name ] = function( p ) {\n\t\treturn 1 - easeIn( 1 - p );\n\t};\n\t$.easing[ \"easeInOut\" + name ] = function( p ) {\n\t\treturn p \u003c 0.5 ?\n\t\t\teaseIn( p * 2 ) / 2 :\n\t\t\t1 - easeIn( p * -2 + 2 ) / 2;\n\t};\n});\n\n})();\n\n})(jQuery);\n\n(function( $, undefined ) {\n\nvar uid = 0,\n\thideProps = {},\n\tshowProps = {};\n\nhideProps.height = hideProps.paddingTop = hideProps.paddingBottom =\n\thideProps.borderTopWidth = hideProps.borderBottomWidth = \"hide\";\nshowProps.height = showProps.paddingTop = showProps.paddingBottom =\n\tshowProps.borderTopWidth = showProps.borderBottomWidth = \"show\";\n\n$.widget( \"ui.accordion\", {\n\tversion: \"1.10.2\",\n\toptions: {\n\t\tactive: 0,\n\t\tanimate: {},\n\t\tcollapsible: false,\n\t\tevent: \"click\",\n\t\theader: \"\u003e li \u003e :first-child,\u003e :not(li):even\",\n\t\theightStyle: \"auto\",\n\t\ticons: {\n\t\t\tactiveHeader: \"ui-icon-triangle-1-s\",\n\t\t\theader: \"ui-icon-triangle-1-e\"\n\t\t},\n\n\t\t// callbacks\n\t\tactivate: null,\n\t\tbeforeActivate: null\n\t},\n\n\t_create: function() {\n\t\tvar options = this.options;\n\t\tthis.prevShow = this.prevHide = $();\n\t\tthis.element.addClass( \"ui-accordion ui-widget ui-helper-reset\" )\n\t\t\t// ARIA\n\t\t\t.attr( \"role\", \"tablist\" );\n\n\t\t// don\u0027t allow collapsible: false and active: false / null\n\t\tif ( !options.collapsible \u0026\u0026 (options.active === false || options.active == null) ) {\n\t\t\toptions.active = 0;\n\t\t}\n\n\t\tthis._processPanels();\n\t\t// handle negative values\n\t\tif ( options.active \u003c 0 ) {\n\t\t\toptions.active += this.headers.length;\n\t\t}\n\t\tthis._refresh();\n\t},\n\n\t_getCreateEventData: function() {\n\t\treturn {\n\t\t\theader: this.active,\n\t\t\tpanel: !this.active.length ? $() : this.active.next(),\n\t\t\tcontent: !this.active.length ? $() : this.active.next()\n\t\t};\n\t},\n\n\t_createIcons: function() {\n\t\tvar icons = this.options.icons;\n\t\tif ( icons ) {\n\t\t\t$( \"\u003cspan\u003e\" )\n\t\t\t\t.addClass( \"ui-accordion-header-icon ui-icon \" + icons.header )\n\t\t\t\t.prependTo( this.headers );\n\t\t\tthis.active.children( \".ui-accordion-header-icon\" )\n\t\t\t\t.removeClass( icons.header )\n\t\t\t\t.addClass( icons.activeHeader );\n\t\t\tthis.headers.addClass( \"ui-accordion-icons\" );\n\t\t}\n\t},\n\n\t_destroyIcons: function() {\n\t\tthis.headers\n\t\t\t.removeClass( \"ui-accordion-icons\" )\n\t\t\t.children( \".ui-accordion-header-icon\" )\n\t\t\t\t.remove();\n\t},\n\n\t_destroy: function() {\n\t\tvar contents;\n\n\t\t// clean up main element\n\t\tthis.element\n\t\t\t.removeClass( \"ui-accordion ui-widget ui-helper-reset\" )\n\t\t\t.removeAttr( \"role\" );\n\n\t\t// clean up headers\n\t\tthis.headers\n\t\t\t.removeClass( \"ui-accordion-header ui-accordion-header-active ui-helper-reset ui-state-default ui-corner-all ui-state-active ui-state-disabled ui-corner-top\" )\n\t\t\t.removeAttr( \"role\" )\n\t\t\t.removeAttr( \"aria-selected\" )\n\t\t\t.removeAttr( \"aria-controls\" )\n\t\t\t.removeAttr( \"tabIndex\" )\n\t\t\t.each(function() {\n\t\t\t\tif ( /^ui-accordion/.test( this.id ) ) {\n\t\t\t\t\tthis.removeAttribute( \"id\" );\n\t\t\t\t}\n\t\t\t});\n\t\tthis._destroyIcons();\n\n\t\t// clean up content panels\n\t\tcontents = this.headers.next()\n\t\t\t.css( \"display\", \"\" )\n\t\t\t.removeAttr( \"role\" )\n\t\t\t.removeAttr( \"aria-expanded\" )\n\t\t\t.removeAttr( \"aria-hidden\" )\n\t\t\t.removeAttr( \"aria-labelledby\" )\n\t\t\t.removeClass( \"ui-helper-reset ui-widget-content ui-corner-bottom ui-accordion-content ui-accordion-content-active ui-state-disabled\" )\n\t\t\t.each(function() {\n\t\t\t\tif ( /^ui-accordion/.test( this.id ) ) {\n\t\t\t\t\tthis.removeAttribute( \"id\" );\n\t\t\t\t}\n\t\t\t});\n\t\tif ( this.options.heightStyle !== \"content\" ) {\n\t\t\tcontents.css( \"height\", \"\" );\n\t\t}\n\t},\n\n\t_setOption: function( key, value ) {\n\t\tif ( key === \"active\" ) {\n\t\t\t// _activate() will handle invalid values and update this.options\n\t\t\tthis._activate( value );\n\t\t\treturn;\n\t\t}\n\n\t\tif ( key === \"event\" ) {\n\t\t\tif ( this.options.event ) {\n\t\t\t\tthis._off( this.headers, this.options.event );\n\t\t\t}\n\t\t\tthis._setupEvents( value );\n\t\t}\n\n\t\tthis._super( key, value );\n\n\t\t// setting collapsible: false while collapsed; open first panel\n\t\tif ( key === \"collapsible\" \u0026\u0026 !value \u0026\u0026 this.options.active === false ) {\n\t\t\tthis._activate( 0 );\n\t\t}\n\n\t\tif ( key === \"icons\" ) {\n\t\t\tthis._destroyIcons();\n\t\t\tif ( value ) {\n\t\t\t\tthis._createIcons();\n\t\t\t}\n\t\t}\n\n\t\t// #5332 - opacity doesn\u0027t cascade to positioned elements in IE\n\t\t// so we need to add the disabled class to the headers and panels\n\t\tif ( key === \"disabled\" ) {\n\t\t\tthis.headers.add( this.headers.next() )\n\t\t\t\t.toggleClass( \"ui-state-disabled\", !!value );\n\t\t}\n\t},\n\n\t_keydown: function( event ) {\n\t\t/*jshint maxcomplexity:15*/\n\t\tif ( event.altKey || event.ctrlKey ) {\n\t\t\treturn;\n\t\t}\n\n\t\tvar keyCode = $.ui.keyCode,\n\t\t\tlength = this.headers.length,\n\t\t\tcurrentIndex = this.headers.index( event.target ),\n\t\t\ttoFocus = false;\n\n\t\tswitch ( event.keyCode ) {\n\t\t\tcase keyCode.RIGHT:\n\t\t\tcase keyCode.DOWN:\n\t\t\t\ttoFocus = this.headers[ ( currentIndex + 1 ) % length ];\n\t\t\t\tbreak;\n\t\t\tcase keyCode.LEFT:\n\t\t\tcase keyCode.UP:\n\t\t\t\ttoFocus = this.headers[ ( currentIndex - 1 + length ) % length ];\n\t\t\t\tbreak;\n\t\t\tcase keyCode.SPACE:\n\t\t\tcase keyCode.ENTER:\n\t\t\t\tthis._eventHandler( event );\n\t\t\t\tbreak;\n\t\t\tcase keyCode.HOME:\n\t\t\t\ttoFocus = this.headers[ 0 ];\n\t\t\t\tbreak;\n\t\t\tcase keyCode.END:\n\t\t\t\ttoFocus = this.headers[ length - 1 ];\n\t\t\t\tbreak;\n\t\t}\n\n\t\tif ( toFocus ) {\n\t\t\t$( event.target ).attr( \"tabIndex\", -1 );\n\t\t\t$( toFocus ).attr( \"tabIndex\", 0 );\n\t\t\ttoFocus.focus();\n\t\t\tevent.preventDefault();\n\t\t}\n\t},\n\n\t_panelKeyDown : function( event ) {\n\t\tif ( event.keyCode === $.ui.keyCode.UP \u0026\u0026 event.ctrlKey ) {\n\t\t\t$( event.currentTarget ).prev().focus();\n\t\t}\n\t},\n\n\trefresh: function() {\n\t\tvar options = this.options;\n\t\tthis._processPanels();\n\n\t\t// was collapsed or no panel\n\t\tif ( ( options.active === false \u0026\u0026 options.collapsible === true ) || !this.headers.length ) {\n\t\t\toptions.active = false;\n\t\t\tthis.active = $();\n\t\t// active false only when collapsible is true\n\t\t} if ( options.active === false ) {\n\t\t\tthis._activate( 0 );\n\t\t// was active, but active panel is gone\n\t\t} else if ( this.active.length \u0026\u0026 !$.contains( this.element[ 0 ], this.active[ 0 ] ) ) {\n\t\t\t// all remaining panel are disabled\n\t\t\tif ( this.headers.length === this.headers.find(\".ui-state-disabled\").length ) {\n\t\t\t\toptions.active = false;\n\t\t\t\tthis.active = $();\n\t\t\t// activate previous panel\n\t\t\t} else {\n\t\t\t\tthis._activate( Math.max( 0, options.active - 1 ) );\n\t\t\t}\n\t\t// was active, active panel still exists\n\t\t} else {\n\t\t\t// make sure active index is correct\n\t\t\toptions.active = this.headers.index( this.active );\n\t\t}\n\n\t\tthis._destroyIcons();\n\n\t\tthis._refresh();\n\t},\n\n\t_processPanels: function() {\n\t\tthis.headers = this.element.find( this.options.header )\n\t\t\t.addClass( \"ui-accordion-header ui-helper-reset ui-state-default ui-corner-all\" );\n\n\t\tthis.headers.next()\n\t\t\t.addClass( \"ui-accordion-content ui-helper-reset ui-widget-content ui-corner-bottom\" )\n\t\t\t.filter(\":not(.ui-accordion-content-active)\")\n\t\t\t.hide();\n\t},\n\n\t_refresh: function() {\n\t\tvar maxHeight,\n\t\t\toptions = this.options,\n\t\t\theightStyle = options.heightStyle,\n\t\t\tparent = this.element.parent(),\n\t\t\taccordionId = this.accordionId = \"ui-accordion-\" +\n\t\t\t\t(this.element.attr( \"id\" ) || ++uid);\n\n\t\tthis.active = this._findActive( options.active )\n\t\t\t.addClass( \"ui-accordion-header-active ui-state-active ui-corner-top\" )\n\t\t\t.removeClass( \"ui-corner-all\" );\n\t\tthis.active.next()\n\t\t\t.addClass( \"ui-accordion-content-active\" )\n\t\t\t.show();\n\n\t\tthis.headers\n\t\t\t.attr( \"role\", \"tab\" )\n\t\t\t.each(function( i ) {\n\t\t\t\tvar header = $( this ),\n\t\t\t\t\theaderId = header.attr( \"id\" ),\n\t\t\t\t\tpanel = header.next(),\n\t\t\t\t\tpanelId = panel.attr( \"id\" );\n\t\t\t\tif ( !headerId ) {\n\t\t\t\t\theaderId = accordionId + \"-header-\" + i;\n\t\t\t\t\theader.attr( \"id\", headerId );\n\t\t\t\t}\n\t\t\t\tif ( !panelId ) {\n\t\t\t\t\tpanelId = accordionId + \"-panel-\" + i;\n\t\t\t\t\tpanel.attr( \"id\", panelId );\n\t\t\t\t}\n\t\t\t\theader.attr( \"aria-controls\", panelId );\n\t\t\t\tpanel.attr( \"aria-labelledby\", headerId );\n\t\t\t})\n\t\t\t.next()\n\t\t\t\t.attr( \"role\", \"tabpanel\" );\n\n\t\tthis.headers\n\t\t\t.not( this.active )\n\t\t\t.attr({\n\t\t\t\t\"aria-selected\": \"false\",\n\t\t\t\ttabIndex: -1\n\t\t\t})\n\t\t\t.next()\n\t\t\t\t.attr({\n\t\t\t\t\t\"aria-expanded\": \"false\",\n\t\t\t\t\t\"aria-hidden\": \"true\"\n\t\t\t\t})\n\t\t\t\t.hide();\n\n\t\t// make sure at least one header is in the tab order\n\t\tif ( !this.active.length ) {\n\t\t\tthis.headers.eq( 0 ).attr( \"tabIndex\", 0 );\n\t\t} else {\n\t\t\tthis.active.attr({\n\t\t\t\t\"aria-selected\": \"true\",\n\t\t\t\ttabIndex: 0\n\t\t\t})\n\t\t\t.next()\n\t\t\t\t.attr({\n\t\t\t\t\t\"aria-expanded\": \"true\",\n\t\t\t\t\t\"aria-hidden\": \"false\"\n\t\t\t\t});\n\t\t}\n\n\t\tthis._createIcons();\n\n\t\tthis._setupEvents( options.event );\n\n\t\tif ( heightStyle === \"fill\" ) {\n\t\t\tmaxHeight = parent.height();\n\t\t\tthis.element.siblings( \":visible\" ).each(function() {\n\t\t\t\tvar elem = $( this ),\n\t\t\t\t\tposition = elem.css( \"position\" );\n\n\t\t\t\tif ( position === \"absolute\" || position === \"fixed\" ) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tmaxHeight -= elem.outerHeight( true );\n\t\t\t});\n\n\t\t\tthis.headers.each(function() {\n\t\t\t\tmaxHeight -= $( this ).outerHeight( true );\n\t\t\t});\n\n\t\t\tthis.headers.next()\n\t\t\t\t.each(function() {\n\t\t\t\t\t$( this ).height( Math.max( 0, maxHeight -\n\t\t\t\t\t\t$( this ).innerHeight() + $( this ).height() ) );\n\t\t\t\t})\n\t\t\t\t.css( \"overflow\", \"auto\" );\n\t\t} else if ( heightStyle === \"auto\" ) {\n\t\t\tmaxHeight = 0;\n\t\t\tthis.headers.next()\n\t\t\t\t.each(function() {\n\t\t\t\t\tmaxHeight = Math.max( maxHeight, $( this ).css( \"height\", \"\" ).height() );\n\t\t\t\t})\n\t\t\t\t.height( maxHeight );\n\t\t}\n\t},\n\n\t_activate: function( index ) {\n\t\tvar active = this._findActive( index )[ 0 ];\n\n\t\t// trying to activate the already active panel\n\t\tif ( active === this.active[ 0 ] ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// trying to collapse, simulate a click on the currently active header\n\t\tactive = active || this.active[ 0 ];\n\n\t\tthis._eventHandler({\n\t\t\ttarget: active,\n\t\t\tcurrentTarget: active,\n\t\t\tpreventDefault: $.noop\n\t\t});\n\t},\n\n\t_findActive: function( selector ) {\n\t\treturn typeof selector === \"number\" ? this.headers.eq( selector ) : $();\n\t},\n\n\t_setupEvents: function( event ) {\n\t\tvar events = {\n\t\t\tkeydown: \"_keydown\"\n\t\t};\n\t\tif ( event ) {\n\t\t\t$.each( event.split(\" \"), function( index, eventName ) {\n\t\t\t\tevents[ eventName ] = \"_eventHandler\";\n\t\t\t});\n\t\t}\n\n\t\tthis._off( this.headers.add( this.headers.next() ) );\n\t\tthis._on( this.headers, events );\n\t\tthis._on( this.headers.next(), { keydown: \"_panelKeyDown\" });\n\t\tthis._hoverable( this.headers );\n\t\tthis._focusable( this.headers );\n\t},\n\n\t_eventHandler: function( event ) {\n\t\tvar options = this.options,\n\t\t\tactive = this.active,\n\t\t\tclicked = $( event.currentTarget ),\n\t\t\tclickedIsActive = clicked[ 0 ] === active[ 0 ],\n\t\t\tcollapsing = clickedIsActive \u0026\u0026 options.collapsible,\n\t\t\ttoShow = collapsing ? $() : clicked.next(),\n\t\t\ttoHide = active.next(),\n\t\t\teventData = {\n\t\t\t\toldHeader: active,\n\t\t\t\toldPanel: toHide,\n\t\t\t\tnewHeader: collapsing ? $() : clicked,\n\t\t\t\tnewPanel: toShow\n\t\t\t};\n\n\t\tevent.preventDefault();\n\n\t\tif (\n\t\t\t\t// click on active header, but not collapsible\n\t\t\t\t( clickedIsActive \u0026\u0026 !options.collapsible ) ||\n\t\t\t\t// allow canceling activation\n\t\t\t\t( this._trigger( \"beforeActivate\", event, eventData ) === false ) ) {\n\t\t\treturn;\n\t\t}\n\n\t\toptions.active = collapsing ? false : this.headers.index( clicked );\n\n\t\t// when the call to ._toggle() comes after the class changes\n\t\t// it causes a very odd bug in IE 8 (see #6720)\n\t\tthis.active = clickedIsActive ? $() : clicked;\n\t\tthis._toggle( eventData );\n\n\t\t// switch classes\n\t\t// corner classes on the previously active header stay after the animation\n\t\tactive.removeClass( \"ui-accordion-header-active ui-state-active\" );\n\t\tif ( options.icons ) {\n\t\t\tactive.children( \".ui-accordion-header-icon\" )\n\t\t\t\t.removeClass( options.icons.activeHeader )\n\t\t\t\t.addClass( options.icons.header );\n\t\t}\n\n\t\tif ( !clickedIsActive ) {\n\t\t\tclicked\n\t\t\t\t.removeClass( \"ui-corner-all\" )\n\t\t\t\t.addClass( \"ui-accordion-header-active ui-state-active ui-corner-top\" );\n\t\t\tif ( options.icons ) {\n\t\t\t\tclicked.children( \".ui-accordion-header-icon\" )\n\t\t\t\t\t.removeClass( options.icons.header )\n\t\t\t\t\t.addClass( options.icons.activeHeader );\n\t\t\t}\n\n\t\t\tclicked\n\t\t\t\t.next()\n\t\t\t\t.addClass( \"ui-accordion-content-active\" );\n\t\t}\n\t},\n\n\t_toggle: function( data ) {\n\t\tvar toShow = data.newPanel,\n\t\t\ttoHide = this.prevShow.length ? this.prevShow : data.oldPanel;\n\n\t\t// handle activating a panel during the animation for another activation\n\t\tthis.prevShow.add( this.prevHide ).stop( true, true );\n\t\tthis.prevShow = toShow;\n\t\tthis.prevHide = toHide;\n\n\t\tif ( this.options.animate ) {\n\t\t\tthis._animate( toShow, toHide, data );\n\t\t} else {\n\t\t\ttoHide.hide();\n\t\t\ttoShow.show();\n\t\t\tthis._toggleComplete( data );\n\t\t}\n\n\t\ttoHide.attr({\n\t\t\t\"aria-expanded\": \"false\",\n\t\t\t\"aria-hidden\": \"true\"\n\t\t});\n\t\ttoHide.prev().attr( \"aria-selected\", \"false\" );\n\t\t// if we\u0027re switching panels, remove the old header from the tab order\n\t\t// if we\u0027re opening from collapsed state, remove the previous header from the tab order\n\t\t// if we\u0027re collapsing, then keep the collapsing header in the tab order\n\t\tif ( toShow.length \u0026\u0026 toHide.length ) {\n\t\t\ttoHide.prev().attr( \"tabIndex\", -1 );\n\t\t} else if ( toShow.length ) {\n\t\t\tthis.headers.filter(function() {\n\t\t\t\treturn $( this ).attr( \"tabIndex\" ) === 0;\n\t\t\t})\n\t\t\t.attr( \"tabIndex\", -1 );\n\t\t}\n\n\t\ttoShow\n\t\t\t.attr({\n\t\t\t\t\"aria-expanded\": \"true\",\n\t\t\t\t\"aria-hidden\": \"false\"\n\t\t\t})\n\t\t\t.prev()\n\t\t\t\t.attr({\n\t\t\t\t\t\"aria-selected\": \"true\",\n\t\t\t\t\ttabIndex: 0\n\t\t\t\t});\n\t},\n\n\t_animate: function( toShow, toHide, data ) {\n\t\tvar total, easing, duration,\n\t\t\tthat = this,\n\t\t\tadjust = 0,\n\t\t\tdown = toShow.length \u0026\u0026\n\t\t\t\t( !toHide.length || ( toShow.index() \u003c toHide.index() ) ),\n\t\t\tanimate = this.options.animate || {},\n\t\t\toptions = down \u0026\u0026 animate.down || animate,\n\t\t\tcomplete = function() {\n\t\t\t\tthat._toggleComplete( data );\n\t\t\t};\n\n\t\tif ( typeof options === \"number\" ) {\n\t\t\tduration = options;\n\t\t}\n\t\tif ( typeof options === \"string\" ) {\n\t\t\teasing = options;\n\t\t}\n\t\t// fall back from options to animation in case of partial down settings\n\t\teasing = easing || options.easing || animate.easing;\n\t\tduration = duration || options.duration || animate.duration;\n\n\t\tif ( !toHide.length ) {\n\t\t\treturn toShow.animate( showProps, duration, easing, complete );\n\t\t}\n\t\tif ( !toShow.length ) {\n\t\t\treturn toHide.animate( hideProps, duration, easing, complete );\n\t\t}\n\n\t\ttotal = toShow.show().outerHeight();\n\t\ttoHide.animate( hideProps, {\n\t\t\tduration: duration,\n\t\t\teasing: easing,\n\t\t\tstep: function( now, fx ) {\n\t\t\t\tfx.now = Math.round( now );\n\t\t\t}\n\t\t});\n\t\ttoShow\n\t\t\t.hide()\n\t\t\t.animate( showProps, {\n\t\t\t\tduration: duration,\n\t\t\t\teasing: easing,\n\t\t\t\tcomplete: complete,\n\t\t\t\tstep: function( now, fx ) {\n\t\t\t\t\tfx.now = Math.round( now );\n\t\t\t\t\tif ( fx.prop !== \"height\" ) {\n\t\t\t\t\t\tadjust += fx.now;\n\t\t\t\t\t} else if ( that.options.heightStyle !== \"content\" ) {\n\t\t\t\t\t\tfx.now = Math.round( total - toHide.outerHeight() - adjust );\n\t\t\t\t\t\tadjust = 0;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t});\n\t},\n\n\t_toggleComplete: function( data ) {\n\t\tvar toHide = data.oldPanel;\n\n\t\ttoHide\n\t\t\t.removeClass( \"ui-accordion-content-active\" )\n\t\t\t.prev()\n\t\t\t\t.removeClass( \"ui-corner-top\" )\n\t\t\t\t.addClass( \"ui-corner-all\" );\n\n\t\t// Work around for rendering bug in IE (#5421)\n\t\tif ( toHide.length ) {\n\t\t\ttoHide.parent()[0].className = toHide.parent()[0].className;\n\t\t}\n\n\t\tthis._trigger( \"activate\", null, data );\n\t}\n});\n\n})( jQuery );\n\n(function( $, undefined ) {\n\n// used to prevent race conditions with remote data sources\nvar requestIndex = 0;\n\n$.widget( \"ui.autocomplete\", {\n\tversion: \"1.10.2\",\n\tdefaultElement: \"\u003cinput\u003e\",\n\toptions: {\n\t\tappendTo: null,\n\t\tautoFocus: false,\n\t\tdelay: 300,\n\t\tminLength: 1,\n\t\tposition: {\n\t\t\tmy: \"left top\",\n\t\t\tat: \"left bottom\",\n\t\t\tcollision: \"none\"\n\t\t},\n\t\tsource: null,\n\n\t\t// callbacks\n\t\tchange: null,\n\t\tclose: null,\n\t\tfocus: null,\n\t\topen: null,\n\t\tresponse: null,\n\t\tsearch: null,\n\t\tselect: null\n\t},\n\n\tpending: 0,\n\n\t_create: function() {\n\t\t// Some browsers only repeat keydown events, not keypress events,\n\t\t// so we use the suppressKeyPress flag to determine if we\u0027ve already\n\t\t// handled the keydown event. #7269\n\t\t// Unfortunately the code for \u0026 in keypress is the same as the up arrow,\n\t\t// so we use the suppressKeyPressRepeat flag to avoid handling keypress\n\t\t// events when we know the keydown event was used to modify the\n\t\t// search term. #7799\n\t\tvar suppressKeyPress, suppressKeyPressRepeat, suppressInput,\n\t\t\tnodeName = this.element[0].nodeName.toLowerCase(),\n\t\t\tisTextarea = nodeName === \"textarea\",\n\t\t\tisInput = nodeName === \"input\";\n\n\t\tthis.isMultiLine =\n\t\t\t// Textareas are always multi-line\n\t\t\tisTextarea ? true :\n\t\t\t// Inputs are always single-line, even if inside a contentEditable element\n\t\t\t// IE also treats inputs as contentEditable\n\t\t\tisInput ? false :\n\t\t\t// All other element types are determined by whether or not they\u0027re contentEditable\n\t\t\tthis.element.prop( \"isContentEditable\" );\n\n\t\tthis.valueMethod = this.element[ isTextarea || isInput ? \"val\" : \"text\" ];\n\t\tthis.isNewMenu = true;\n\n\t\tthis.element\n\t\t\t.addClass( \"ui-autocomplete-input\" )\n\t\t\t.attr( \"autocomplete\", \"off\" );\n\n\t\tthis._on( this.element, {\n\t\t\tkeydown: function( event ) {\n\t\t\t\t/*jshint maxcomplexity:15*/\n\t\t\t\tif ( this.element.prop( \"readOnly\" ) ) {\n\t\t\t\t\tsuppressKeyPress = true;\n\t\t\t\t\tsuppressInput = true;\n\t\t\t\t\tsuppressKeyPressRepeat = true;\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tsuppressKeyPress = false;\n\t\t\t\tsuppressInput = false;\n\t\t\t\tsuppressKeyPressRepeat = false;\n\t\t\t\tvar keyCode = $.ui.keyCode;\n\t\t\t\tswitch( event.keyCode ) {\n\t\t\t\tcase keyCode.PAGE_UP:\n\t\t\t\t\tsuppressKeyPress = true;\n\t\t\t\t\tthis._move( \"previousPage\", event );\n\t\t\t\t\tbreak;\n\t\t\t\tcase keyCode.PAGE_DOWN:\n\t\t\t\t\tsuppressKeyPress = true;\n\t\t\t\t\tthis._move( \"nextPage\", event );\n\t\t\t\t\tbreak;\n\t\t\t\tcase keyCode.UP:\n\t\t\t\t\tsuppressKeyPress = true;\n\t\t\t\t\tthis._keyEvent( \"previous\", event );\n\t\t\t\t\tbreak;\n\t\t\t\tcase keyCode.DOWN:\n\t\t\t\t\tsuppressKeyPress = true;\n\t\t\t\t\tthis._keyEvent( \"next\", event );\n\t\t\t\t\tbreak;\n\t\t\t\tcase keyCode.ENTER:\n\t\t\t\tcase keyCode.NUMPAD_ENTER:\n\t\t\t\t\t// when menu is open and has focus\n\t\t\t\t\tif ( this.menu.active ) {\n\t\t\t\t\t\t// #6055 - Opera still allows the keypress to occur\n\t\t\t\t\t\t// which causes forms to submit\n\t\t\t\t\t\tsuppressKeyPress = true;\n\t\t\t\t\t\tevent.preventDefault();\n\t\t\t\t\t\tthis.menu.select( event );\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t\tcase keyCode.TAB:\n\t\t\t\t\tif ( this.menu.active ) {\n\t\t\t\t\t\tthis.menu.select( event );\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t\tcase keyCode.ESCAPE:\n\t\t\t\t\tif ( this.menu.element.is( \":visible\" ) ) {\n\t\t\t\t\t\tthis._value( this.term );\n\t\t\t\t\t\tthis.close( event );\n\t\t\t\t\t\t// Different browsers have different default behavior for escape\n\t\t\t\t\t\t// Single press can mean undo or clear\n\t\t\t\t\t\t// Double press in IE means clear the whole form\n\t\t\t\t\t\tevent.preventDefault();\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t\tdefault:\n\t\t\t\t\tsuppressKeyPressRepeat = true;\n\t\t\t\t\t// search timeout should be triggered before the input value is changed\n\t\t\t\t\tthis._searchTimeout( event );\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t},\n\t\t\tkeypress: function( event ) {\n\t\t\t\tif ( suppressKeyPress ) {\n\t\t\t\t\tsuppressKeyPress = false;\n\t\t\t\t\tevent.preventDefault();\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tif ( suppressKeyPressRepeat ) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\t// replicate some key handlers to allow them to repeat in Firefox and Opera\n\t\t\t\tvar keyCode = $.ui.keyCode;\n\t\t\t\tswitch( event.keyCode ) {\n\t\t\t\tcase keyCode.PAGE_UP:\n\t\t\t\t\tthis._move( \"previousPage\", event );\n\t\t\t\t\tbreak;\n\t\t\t\tcase keyCode.PAGE_DOWN:\n\t\t\t\t\tthis._move( \"nextPage\", event );\n\t\t\t\t\tbreak;\n\t\t\t\tcase keyCode.UP:\n\t\t\t\t\tthis._keyEvent( \"previous\", event );\n\t\t\t\t\tbreak;\n\t\t\t\tcase keyCode.DOWN:\n\t\t\t\t\tthis._keyEvent( \"next\", event );\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t},\n\t\t\tinput: function( event ) {\n\t\t\t\tif ( suppressInput ) {\n\t\t\t\t\tsuppressInput = false;\n\t\t\t\t\tevent.preventDefault();\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tthis._searchTimeout( event );\n\t\t\t},\n\t\t\tfocus: function() {\n\t\t\t\tthis.selectedItem = null;\n\t\t\t\tthis.previous = this._value();\n\t\t\t},\n\t\t\tblur: function( event ) {\n\t\t\t\tif ( this.cancelBlur ) {\n\t\t\t\t\tdelete this.cancelBlur;\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tclearTimeout( this.searching );\n\t\t\t\tthis.close( event );\n\t\t\t\tthis._change( event );\n\t\t\t}\n\t\t});\n\n\t\tthis._initSource();\n\t\tthis.menu = $( \"\u003cul\u003e\" )\n\t\t\t.addClass( \"ui-autocomplete ui-front\" )\n\t\t\t.appendTo( this._appendTo() )\n\t\t\t.menu({\n\t\t\t\t// custom key handling for now\n\t\t\t\tinput: $(),\n\t\t\t\t// disable ARIA support, the live region takes care of that\n\t\t\t\trole: null\n\t\t\t})\n\t\t\t.hide()\n\t\t\t.data( \"ui-menu\" );\n\n\t\tthis._on( this.menu.element, {\n\t\t\tmousedown: function( event ) {\n\t\t\t\t// prevent moving focus out of the text field\n\t\t\t\tevent.preventDefault();\n\n\t\t\t\t// IE doesn\u0027t prevent moving focus even with event.preventDefault()\n\t\t\t\t// so we set a flag to know when we should ignore the blur event\n\t\t\t\tthis.cancelBlur = true;\n\t\t\t\tthis._delay(function() {\n\t\t\t\t\tdelete this.cancelBlur;\n\t\t\t\t});\n\n\t\t\t\t// clicking on the scrollbar causes focus to shift to the body\n\t\t\t\t// but we can\u0027t detect a mouseup or a click immediately afterward\n\t\t\t\t// so we have to track the next mousedown and close the menu if\n\t\t\t\t// the user clicks somewhere outside of the autocomplete\n\t\t\t\tvar menuElement = this.menu.element[ 0 ];\n\t\t\t\tif ( !$( event.target ).closest( \".ui-menu-item\" ).length ) {\n\t\t\t\t\tthis._delay(function() {\n\t\t\t\t\t\tvar that = this;\n\t\t\t\t\t\tthis.document.one( \"mousedown\", function( event ) {\n\t\t\t\t\t\t\tif ( event.target !== that.element[ 0 ] \u0026\u0026\n\t\t\t\t\t\t\t\t\tevent.target !== menuElement \u0026\u0026\n\t\t\t\t\t\t\t\t\t!$.contains( menuElement, event.target ) ) {\n\t\t\t\t\t\t\t\tthat.close();\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t});\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t},\n\t\t\tmenufocus: function( event, ui ) {\n\t\t\t\t// support: Firefox\n\t\t\t\t// Prevent accidental activation of menu items in Firefox (#7024 #9118)\n\t\t\t\tif ( this.isNewMenu ) {\n\t\t\t\t\tthis.isNewMenu = false;\n\t\t\t\t\tif ( event.originalEvent \u0026\u0026 /^mouse/.test( event.originalEvent.type ) ) {\n\t\t\t\t\t\tthis.menu.blur();\n\n\t\t\t\t\t\tthis.document.one( \"mousemove\", function() {\n\t\t\t\t\t\t\t$( event.target ).trigger( event.originalEvent );\n\t\t\t\t\t\t});\n\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tvar item = ui.item.data( \"ui-autocomplete-item\" );\n\t\t\t\tif ( false !== this._trigger( \"focus\", event, { item: item } ) ) {\n\t\t\t\t\t// use value to match what will end up in the input, if it was a key event\n\t\t\t\t\tif ( event.originalEvent \u0026\u0026 /^key/.test( event.originalEvent.type ) ) {\n\t\t\t\t\t\tthis._value( item.value );\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\t// Normally the input is populated with the item\u0027s value as the\n\t\t\t\t\t// menu is navigated, causing screen readers to notice a change and\n\t\t\t\t\t// announce the item. Since the focus event was canceled, this doesn\u0027t\n\t\t\t\t\t// happen, so we update the live region so that screen readers can\n\t\t\t\t\t// still notice the change and announce it.\n\t\t\t\t\tthis.liveRegion.text( item.value );\n\t\t\t\t}\n\t\t\t},\n\t\t\tmenuselect: function( event, ui ) {\n\t\t\t\tvar item = ui.item.data( \"ui-autocomplete-item\" ),\n\t\t\t\t\tprevious = this.previous;\n\n\t\t\t\t// only trigger when focus was lost (click on menu)\n\t\t\t\tif ( this.element[0] !== this.document[0].activeElement ) {\n\t\t\t\t\tthis.element.focus();\n\t\t\t\t\tthis.previous = previous;\n\t\t\t\t\t// #6109 - IE triggers two focus events and the second\n\t\t\t\t\t// is asynchronous, so we need to reset the previous\n\t\t\t\t\t// term synchronously and asynchronously :-(\n\t\t\t\t\tthis._delay(function() {\n\t\t\t\t\t\tthis.previous = previous;\n\t\t\t\t\t\tthis.selectedItem = item;\n\t\t\t\t\t});\n\t\t\t\t}\n\n\t\t\t\tif ( false !== this._trigger( \"select\", event, { item: item } ) ) {\n\t\t\t\t\tthis._value( item.value );\n\t\t\t\t}\n\t\t\t\t// reset the term after the select event\n\t\t\t\t// this allows custom select handling to work properly\n\t\t\t\tthis.term = this._value();\n\n\t\t\t\tthis.close( event );\n\t\t\t\tthis.selectedItem = item;\n\t\t\t}\n\t\t});\n\n\t\tthis.liveRegion = $( \"\u003cspan\u003e\", {\n\t\t\t\trole: \"status\",\n\t\t\t\t\"aria-live\": \"polite\"\n\t\t\t})\n\t\t\t.addClass( \"ui-helper-hidden-accessible\" )\n\t\t\t.insertAfter( this.element );\n\n\t\t// turning off autocomplete prevents the browser from remembering the\n\t\t// value when navigating through history, so we re-enable autocomplete\n\t\t// if the page is unloaded before the widget is destroyed. #7790\n\t\tthis._on( this.window, {\n\t\t\tbeforeunload: function() {\n\t\t\t\tthis.element.removeAttr( \"autocomplete\" );\n\t\t\t}\n\t\t});\n\t},\n\n\t_destroy: function() {\n\t\tclearTimeout( this.searching );\n\t\tthis.element\n\t\t\t.removeClass( \"ui-autocomplete-input\" )\n\t\t\t.removeAttr( \"autocomplete\" );\n\t\tthis.menu.element.remove();\n\t\tthis.liveRegion.remove();\n\t},\n\n\t_setOption: function( key, value ) {\n\t\tthis._super( key, value );\n\t\tif ( key === \"source\" ) {\n\t\t\tthis._initSource();\n\t\t}\n\t\tif ( key === \"appendTo\" ) {\n\t\t\tthis.menu.element.appendTo( this._appendTo() );\n\t\t}\n\t\tif ( key === \"disabled\" \u0026\u0026 value \u0026\u0026 this.xhr ) {\n\t\t\tthis.xhr.abort();\n\t\t}\n\t},\n\n\t_appendTo: function() {\n\t\tvar element = this.options.appendTo;\n\n\t\tif ( element ) {\n\t\t\telement = element.jquery || element.nodeType ?\n\t\t\t\t$( element ) :\n\t\t\t\tthis.document.find( element ).eq( 0 );\n\t\t}\n\n\t\tif ( !element ) {\n\t\t\telement = this.element.closest( \".ui-front\" );\n\t\t}\n\n\t\tif ( !element.length ) {\n\t\t\telement = this.document[0].body;\n\t\t}\n\n\t\treturn element;\n\t},\n\n\t_initSource: function() {\n\t\tvar array, url,\n\t\t\tthat = this;\n\t\tif ( $.isArray(this.options.source) ) {\n\t\t\tarray = this.options.source;\n\t\t\tthis.source = function( request, response ) {\n\t\t\t\tresponse( $.ui.autocomplete.filter( array, request.term ) );\n\t\t\t};\n\t\t} else if ( typeof this.options.source === \"string\" ) {\n\t\t\turl = this.options.source;\n\t\t\tthis.source = function( request, response ) {\n\t\t\t\tif ( that.xhr ) {\n\t\t\t\t\tthat.xhr.abort();\n\t\t\t\t}\n\t\t\t\tthat.xhr = $.ajax({\n\t\t\t\t\turl: url,\n\t\t\t\t\tdata: request,\n\t\t\t\t\tdataType: \"json\",\n\t\t\t\t\tsuccess: function( data ) {\n\t\t\t\t\t\tresponse( data );\n\t\t\t\t\t},\n\t\t\t\t\terror: function() {\n\t\t\t\t\t\tresponse( [] );\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t};\n\t\t} else {\n\t\t\tthis.source = this.options.source;\n\t\t}\n\t},\n\n\t_searchTimeout: function( event ) {\n\t\tclearTimeout( this.searching );\n\t\tthis.searching = this._delay(function() {\n\t\t\t// only search if the value has changed\n\t\t\tif ( this.term !== this._value() ) {\n\t\t\t\tthis.selectedItem = null;\n\t\t\t\tthis.search( null, event );\n\t\t\t}\n\t\t}, this.options.delay );\n\t},\n\n\tsearch: function( value, event ) {\n\t\tvalue = value != null ? value : this._value();\n\n\t\t// always save the actual value, not the one passed as an argument\n\t\tthis.term = this._value();\n\n\t\tif ( value.length \u003c this.options.minLength ) {\n\t\t\treturn this.close( event );\n\t\t}\n\n\t\tif ( this._trigger( \"search\", event ) === false ) {\n\t\t\treturn;\n\t\t}\n\n\t\treturn this._search( value );\n\t},\n\n\t_search: function( value ) {\n\t\tthis.pending++;\n\t\tthis.element.addClass( \"ui-autocomplete-loading\" );\n\t\tthis.cancelSearch = false;\n\n\t\tthis.source( { term: value }, this._response() );\n\t},\n\n\t_response: function() {\n\t\tvar that = this,\n\t\t\tindex = ++requestIndex;\n\n\t\treturn function( content ) {\n\t\t\tif ( index === requestIndex ) {\n\t\t\t\tthat.__response( content );\n\t\t\t}\n\n\t\t\tthat.pending--;\n\t\t\tif ( !that.pending ) {\n\t\t\t\tthat.element.removeClass( \"ui-autocomplete-loading\" );\n\t\t\t}\n\t\t};\n\t},\n\n\t__response: function( content ) {\n\t\tif ( content ) {\n\t\t\tcontent = this._normalize( content );\n\t\t}\n\t\tthis._trigger( \"response\", null, { content: content } );\n\t\tif ( !this.options.disabled \u0026\u0026 content \u0026\u0026 content.length \u0026\u0026 !this.cancelSearch ) {\n\t\t\tthis._suggest( content );\n\t\t\tthis._trigger( \"open\" );\n\t\t} else {\n\t\t\t// use ._close() instead of .close() so we don\u0027t cancel future searches\n\t\t\tthis._close();\n\t\t}\n\t},\n\n\tclose: function( event ) {\n\t\tthis.cancelSearch = true;\n\t\tthis._close( event );\n\t},\n\n\t_close: function( event ) {\n\t\tif ( this.menu.element.is( \":visible\" ) ) {\n\t\t\tthis.menu.element.hide();\n\t\t\tthis.menu.blur();\n\t\t\tthis.isNewMenu = true;\n\t\t\tthis._trigger( \"close\", event );\n\t\t}\n\t},\n\n\t_change: function( event ) {\n\t\tif ( this.previous !== this._value() ) {\n\t\t\tthis._trigger( \"change\", event, { item: this.selectedItem } );\n\t\t}\n\t},\n\n\t_normalize: function( items ) {\n\t\t// assume all items have the right format when the first item is complete\n\t\tif ( items.length \u0026\u0026 items[0].label \u0026\u0026 items[0].value ) {\n\t\t\treturn items;\n\t\t}\n\t\treturn $.map( items, function( item ) {\n\t\t\tif ( typeof item === \"string\" ) {\n\t\t\t\treturn {\n\t\t\t\t\tlabel: item,\n\t\t\t\t\tvalue: item\n\t\t\t\t};\n\t\t\t}\n\t\t\treturn $.extend({\n\t\t\t\tlabel: item.label || item.value,\n\t\t\t\tvalue: item.value || item.label\n\t\t\t}, item );\n\t\t});\n\t},\n\n\t_suggest: function( items ) {\n\t\tvar ul = this.menu.element.empty();\n\t\tthis._renderMenu( ul, items );\n\t\tthis.isNewMenu = true;\n\t\tthis.menu.refresh();\n\n\t\t// size and position menu\n\t\tul.show();\n\t\tthis._resizeMenu();\n\t\tul.position( $.extend({\n\t\t\tof: this.element\n\t\t}, this.options.position ));\n\n\t\tif ( this.options.autoFocus ) {\n\t\t\tthis.menu.next();\n\t\t}\n\t},\n\n\t_resizeMenu: function() {\n\t\tvar ul = this.menu.element;\n\t\tul.outerWidth( Math.max(\n\t\t\t// Firefox wraps long text (possibly a rounding bug)\n\t\t\t// so we add 1px to avoid the wrapping (#7513)\n\t\t\tul.width( \"\" ).outerWidth() + 1,\n\t\t\tthis.element.outerWidth()\n\t\t) );\n\t},\n\n\t_renderMenu: function( ul, items ) {\n\t\tvar that = this;\n\t\t$.each( items, function( index, item ) {\n\t\t\tthat._renderItemData( ul, item );\n\t\t});\n\t},\n\n\t_renderItemData: function( ul, item ) {\n\t\treturn this._renderItem( ul, item ).data( \"ui-autocomplete-item\", item );\n\t},\n\n\t_renderItem: function( ul, item ) {\n\t\treturn $( \"\u003cli\u003e\" )\n\t\t\t.append( $( \"\u003ca\u003e\" ).text( item.label ) )\n\t\t\t.appendTo( ul );\n\t},\n\n\t_move: function( direction, event ) {\n\t\tif ( !this.menu.element.is( \":visible\" ) ) {\n\t\t\tthis.search( null, event );\n\t\t\treturn;\n\t\t}\n\t\tif ( this.menu.isFirstItem() \u0026\u0026 /^previous/.test( direction ) ||\n\t\t\t\tthis.menu.isLastItem() \u0026\u0026 /^next/.test( direction ) ) {\n\t\t\tthis._value( this.term );\n\t\t\tthis.menu.blur();\n\t\t\treturn;\n\t\t}\n\t\tthis.menu[ direction ]( event );\n\t},\n\n\twidget: function() {\n\t\treturn this.menu.element;\n\t},\n\n\t_value: function() {\n\t\treturn this.valueMethod.apply( this.element, arguments );\n\t},\n\n\t_keyEvent: function( keyEvent, event ) {\n\t\tif ( !this.isMultiLine || this.menu.element.is( \":visible\" ) ) {\n\t\t\tthis._move( keyEvent, event );\n\n\t\t\t// prevents moving cursor to beginning/end of the text field in some browsers\n\t\t\tevent.preventDefault();\n\t\t}\n\t}\n});\n\n$.extend( $.ui.autocomplete, {\n\tescapeRegex: function( value ) {\n\t\treturn value.replace(/[\\-\\[\\]{}()*+?.,\\\\\\^$|#\\s]/g, \"\\\\$\u0026\");\n\t},\n\tfilter: function(array, term) {\n\t\tvar matcher = new RegExp( $.ui.autocomplete.escapeRegex(term), \"i\" );\n\t\treturn $.grep( array, function(value) {\n\t\t\treturn matcher.test( value.label || value.value || value );\n\t\t});\n\t}\n});\n\n\n// live region extension, adding a `messages` option\n// NOTE: This is an experimental API. We are still investigating\n// a full solution for string manipulation and internationalization.\n$.widget( \"ui.autocomplete\", $.ui.autocomplete, {\n\toptions: {\n\t\tmessages: {\n\t\t\tnoResults: \"No search results.\",\n\t\t\tresults: function( amount ) {\n\t\t\t\treturn amount + ( amount \u003e 1 ? \" results are\" : \" result is\" ) +\n\t\t\t\t\t\" available, use up and down arrow keys to navigate.\";\n\t\t\t}\n\t\t}\n\t},\n\n\t__response: function( content ) {\n\t\tvar message;\n\t\tthis._superApply( arguments );\n\t\tif ( this.options.disabled || this.cancelSearch ) {\n\t\t\treturn;\n\t\t}\n\t\tif ( content \u0026\u0026 content.length ) {\n\t\t\tmessage = this.options.messages.results( content.length );\n\t\t} else {\n\t\t\tmessage = this.options.messages.noResults;\n\t\t}\n\t\tthis.liveRegion.text( message );\n\t}\n});\n\n}( jQuery ));\n\n(function( $, undefined ) {\n\nvar lastActive, startXPos, startYPos, clickDragged,\n\tbaseClasses = \"ui-button ui-widget ui-state-default ui-corner-all\",\n\tstateClasses = \"ui-state-hover ui-state-active \",\n\ttypeClasses = \"ui-button-icons-only ui-button-icon-only ui-button-text-icons ui-button-text-icon-primary ui-button-text-icon-secondary ui-button-text-only\",\n\tformResetHandler = function() {\n\t\tvar buttons = $( this ).find( \":ui-button\" );\n\t\tsetTimeout(function() {\n\t\t\tbuttons.button( \"refresh\" );\n\t\t}, 1 );\n\t},\n\tradioGroup = function( radio ) {\n\t\tvar name = radio.name,\n\t\t\tform = radio.form,\n\t\t\tradios = $( [] );\n\t\tif ( name ) {\n\t\t\tname = name.replace( /\u0027/g, \"\\\\\u0027\" );\n\t\t\tif ( form ) {\n\t\t\t\tradios = $( form ).find( \"[name=\u0027\" + name + \"\u0027]\" );\n\t\t\t} else {\n\t\t\t\tradios = $( \"[name=\u0027\" + name + \"\u0027]\", radio.ownerDocument )\n\t\t\t\t\t.filter(function() {\n\t\t\t\t\t\treturn !this.form;\n\t\t\t\t\t});\n\t\t\t}\n\t\t}\n\t\treturn radios;\n\t};\n\n$.widget( \"ui.button\", {\n\tversion: \"1.10.2\",\n\tdefaultElement: \"\u003cbutton\u003e\",\n\toptions: {\n\t\tdisabled: null,\n\t\ttext: true,\n\t\tlabel: null,\n\t\ticons: {\n\t\t\tprimary: null,\n\t\t\tsecondary: null\n\t\t}\n\t},\n\t_create: function() {\n\t\tthis.element.closest( \"form\" )\n\t\t\t.unbind( \"reset\" + this.eventNamespace )\n\t\t\t.bind( \"reset\" + this.eventNamespace, formResetHandler );\n\n\t\tif ( typeof this.options.disabled !== \"boolean\" ) {\n\t\t\tthis.options.disabled = !!this.element.prop( \"disabled\" );\n\t\t} else {\n\t\t\tthis.element.prop( \"disabled\", this.options.disabled );\n\t\t}\n\n\t\tthis._determineButtonType();\n\t\tthis.hasTitle = !!this.buttonElement.attr( \"title\" );\n\n\t\tvar that = this,\n\t\t\toptions = this.options,\n\t\t\ttoggleButton = this.type === \"checkbox\" || this.type === \"radio\",\n\t\t\tactiveClass = !toggleButton ? \"ui-state-active\" : \"\",\n\t\t\tfocusClass = \"ui-state-focus\";\n\n\t\tif ( options.label === null ) {\n\t\t\toptions.label = (this.type === \"input\" ? this.buttonElement.val() : this.buttonElement.html());\n\t\t}\n\n\t\tthis._hoverable( this.buttonElement );\n\n\t\tthis.buttonElement\n\t\t\t.addClass( baseClasses )\n\t\t\t.attr( \"role\", \"button\" )\n\t\t\t.bind( \"mouseenter\" + this.eventNamespace, function() {\n\t\t\t\tif ( options.disabled ) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tif ( this === lastActive ) {\n\t\t\t\t\t$( this ).addClass( \"ui-state-active\" );\n\t\t\t\t}\n\t\t\t})\n\t\t\t.bind( \"mouseleave\" + this.eventNamespace, function() {\n\t\t\t\tif ( options.disabled ) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\t$( this ).removeClass( activeClass );\n\t\t\t})\n\t\t\t.bind( \"click\" + this.eventNamespace, function( event ) {\n\t\t\t\tif ( options.disabled ) {\n\t\t\t\t\tevent.preventDefault();\n\t\t\t\t\tevent.stopImmediatePropagation();\n\t\t\t\t}\n\t\t\t});\n\n\t\tthis.element\n\t\t\t.bind( \"focus\" + this.eventNamespace, function() {\n\t\t\t\t// no need to check disabled, focus won\u0027t be triggered anyway\n\t\t\t\tthat.buttonElement.addClass( focusClass );\n\t\t\t})\n\t\t\t.bind( \"blur\" + this.eventNamespace, function() {\n\t\t\t\tthat.buttonElement.removeClass( focusClass );\n\t\t\t});\n\n\t\tif ( toggleButton ) {\n\t\t\tthis.element.bind( \"change\" + this.eventNamespace, function() {\n\t\t\t\tif ( clickDragged ) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tthat.refresh();\n\t\t\t});\n\t\t\t// if mouse moves between mousedown and mouseup (drag) set clickDragged flag\n\t\t\t// prevents issue where button state changes but checkbox/radio checked state\n\t\t\t// does not in Firefox (see ticket #6970)\n\t\t\tthis.buttonElement\n\t\t\t\t.bind( \"mousedown\" + this.eventNamespace, function( event ) {\n\t\t\t\t\tif ( options.disabled ) {\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t\tclickDragged = false;\n\t\t\t\t\tstartXPos = event.pageX;\n\t\t\t\t\tstartYPos = event.pageY;\n\t\t\t\t})\n\t\t\t\t.bind( \"mouseup\" + this.eventNamespace, function( event ) {\n\t\t\t\t\tif ( options.disabled ) {\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t\tif ( startXPos !== event.pageX || startYPos !== event.pageY ) {\n\t\t\t\t\t\tclickDragged = true;\n\t\t\t\t\t}\n\t\t\t});\n\t\t}\n\n\t\tif ( this.type === \"checkbox\" ) {\n\t\t\tthis.buttonElement.bind( \"click\" + this.eventNamespace, function() {\n\t\t\t\tif ( options.disabled || clickDragged ) {\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t});\n\t\t} else if ( this.type === \"radio\" ) {\n\t\t\tthis.buttonElement.bind( \"click\" + this.eventNamespace, function() {\n\t\t\t\tif ( options.disabled || clickDragged ) {\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t\t$( this ).addClass( \"ui-state-active\" );\n\t\t\t\tthat.buttonElement.attr( \"aria-pressed\", \"true\" );\n\n\t\t\t\tvar radio = that.element[ 0 ];\n\t\t\t\tradioGroup( radio )\n\t\t\t\t\t.not( radio )\n\t\t\t\t\t.map(function() {\n\t\t\t\t\t\treturn $( this ).button( \"widget\" )[ 0 ];\n\t\t\t\t\t})\n\t\t\t\t\t.removeClass( \"ui-state-active\" )\n\t\t\t\t\t.attr( \"aria-pressed\", \"false\" );\n\t\t\t});\n\t\t} else {\n\t\t\tthis.buttonElement\n\t\t\t\t.bind( \"mousedown\" + this.eventNamespace, function() {\n\t\t\t\t\tif ( options.disabled ) {\n\t\t\t\t\t\treturn false;\n\t\t\t\t\t}\n\t\t\t\t\t$( this ).addClass( \"ui-state-active\" );\n\t\t\t\t\tlastActive = this;\n\t\t\t\t\tthat.document.one( \"mouseup\", function() {\n\t\t\t\t\t\tlastActive = null;\n\t\t\t\t\t});\n\t\t\t\t})\n\t\t\t\t.bind( \"mouseup\" + this.eventNamespace, function() {\n\t\t\t\t\tif ( options.disabled ) {\n\t\t\t\t\t\treturn false;\n\t\t\t\t\t}\n\t\t\t\t\t$( this ).removeClass( \"ui-state-active\" );\n\t\t\t\t})\n\t\t\t\t.bind( \"keydown\" + this.eventNamespace, function(event) {\n\t\t\t\t\tif ( options.disabled ) {\n\t\t\t\t\t\treturn false;\n\t\t\t\t\t}\n\t\t\t\t\tif ( event.keyCode === $.ui.keyCode.SPACE || event.keyCode === $.ui.keyCode.ENTER ) {\n\t\t\t\t\t\t$( this ).addClass( \"ui-state-active\" );\n\t\t\t\t\t}\n\t\t\t\t})\n\t\t\t\t// see #8559, we bind to blur here in case the button element loses\n\t\t\t\t// focus between keydown and keyup, it would be left in an \"active\" state\n\t\t\t\t.bind( \"keyup\" + this.eventNamespace + \" blur\" + this.eventNamespace, function() {\n\t\t\t\t\t$( this ).removeClass( \"ui-state-active\" );\n\t\t\t\t});\n\n\t\t\tif ( this.buttonElement.is(\"a\") ) {\n\t\t\t\tthis.buttonElement.keyup(function(event) {\n\t\t\t\t\tif ( event.keyCode === $.ui.keyCode.SPACE ) {\n\t\t\t\t\t\t// TODO pass through original event correctly (just as 2nd argument doesn\u0027t work)\n\t\t\t\t\t\t$( this ).click();\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\n\t\t// TODO: pull out $.Widget\u0027s handling for the disabled option into\n\t\t// $.Widget.prototype._setOptionDisabled so it\u0027s easy to proxy and can\n\t\t// be overridden by individual plugins\n\t\tthis._setOption( \"disabled\", options.disabled );\n\t\tthis._resetButton();\n\t},\n\n\t_determineButtonType: function() {\n\t\tvar ancestor, labelSelector, checked;\n\n\t\tif ( this.element.is(\"[type=checkbox]\") ) {\n\t\t\tthis.type = \"checkbox\";\n\t\t} else if ( this.element.is(\"[type=radio]\") ) {\n\t\t\tthis.type = \"radio\";\n\t\t} else if ( this.element.is(\"input\") ) {\n\t\t\tthis.type = \"input\";\n\t\t} else {\n\t\t\tthis.type = \"button\";\n\t\t}\n\n\t\tif ( this.type === \"checkbox\" || this.type === \"radio\" ) {\n\t\t\t// we don\u0027t search against the document in case the element\n\t\t\t// is disconnected from the DOM\n\t\t\tancestor = this.element.parents().last();\n\t\t\tlabelSelector = \"label[for=\u0027\" + this.element.attr(\"id\") + \"\u0027]\";\n\t\t\tthis.buttonElement = ancestor.find( labelSelector );\n\t\t\tif ( !this.buttonElement.length ) {\n\t\t\t\tancestor = ancestor.length ? ancestor.siblings() : this.element.siblings();\n\t\t\t\tthis.buttonElement = ancestor.filter( labelSelector );\n\t\t\t\tif ( !this.buttonElement.length ) {\n\t\t\t\t\tthis.buttonElement = ancestor.find( labelSelector );\n\t\t\t\t}\n\t\t\t}\n\t\t\tthis.element.addClass( \"ui-helper-hidden-accessible\" );\n\n\t\t\tchecked = this.element.is( \":checked\" );\n\t\t\tif ( checked ) {\n\t\t\t\tthis.buttonElement.addClass( \"ui-state-active\" );\n\t\t\t}\n\t\t\tthis.buttonElement.prop( \"aria-pressed\", checked );\n\t\t} else {\n\t\t\tthis.buttonElement = this.element;\n\t\t}\n\t},\n\n\twidget: function() {\n\t\treturn this.buttonElement;\n\t},\n\n\t_destroy: function() {\n\t\tthis.element\n\t\t\t.removeClass( \"ui-helper-hidden-accessible\" );\n\t\tthis.buttonElement\n\t\t\t.removeClass( baseClasses + \" \" + stateClasses + \" \" + typeClasses )\n\t\t\t.removeAttr( \"role\" )\n\t\t\t.removeAttr( \"aria-pressed\" )\n\t\t\t.html( this.buttonElement.find(\".ui-button-text\").html() );\n\n\t\tif ( !this.hasTitle ) {\n\t\t\tthis.buttonElement.removeAttr( \"title\" );\n\t\t}\n\t},\n\n\t_setOption: function( key, value ) {\n\t\tthis._super( key, value );\n\t\tif ( key === \"disabled\" ) {\n\t\t\tif ( value ) {\n\t\t\t\tthis.element.prop( \"disabled\", true );\n\t\t\t} else {\n\t\t\t\tthis.element.prop( \"disabled\", false );\n\t\t\t}\n\t\t\treturn;\n\t\t}\n\t\tthis._resetButton();\n\t},\n\n\trefresh: function() {\n\t\t//See #8237 \u0026 #8828\n\t\tvar isDisabled = this.element.is( \"input, button\" ) ? this.element.is( \":disabled\" ) : this.element.hasClass( \"ui-button-disabled\" );\n\n\t\tif ( isDisabled !== this.options.disabled ) {\n\t\t\tthis._setOption( \"disabled\", isDisabled );\n\t\t}\n\t\tif ( this.type === \"radio\" ) {\n\t\t\tradioGroup( this.element[0] ).each(function() {\n\t\t\t\tif ( $( this ).is( \":checked\" ) ) {\n\t\t\t\t\t$( this ).button( \"widget\" )\n\t\t\t\t\t\t.addClass( \"ui-state-active\" )\n\t\t\t\t\t\t.attr( \"aria-pressed\", \"true\" );\n\t\t\t\t} else {\n\t\t\t\t\t$( this ).button( \"widget\" )\n\t\t\t\t\t\t.removeClass( \"ui-state-active\" )\n\t\t\t\t\t\t.attr( \"aria-pressed\", \"false\" );\n\t\t\t\t}\n\t\t\t});\n\t\t} else if ( this.type === \"checkbox\" ) {\n\t\t\tif ( this.element.is( \":checked\" ) ) {\n\t\t\t\tthis.buttonElement\n\t\t\t\t\t.addClass( \"ui-state-active\" )\n\t\t\t\t\t.attr( \"aria-pressed\", \"true\" );\n\t\t\t} else {\n\t\t\t\tthis.buttonElement\n\t\t\t\t\t.removeClass( \"ui-state-active\" )\n\t\t\t\t\t.attr( \"aria-pressed\", \"false\" );\n\t\t\t}\n\t\t}\n\t},\n\n\t_resetButton: function() {\n\t\tif ( this.type === \"input\" ) {\n\t\t\tif ( this.options.label ) {\n\t\t\t\tthis.element.val( this.options.label );\n\t\t\t}\n\t\t\treturn;\n\t\t}\n\t\tvar buttonElement = this.buttonElement.removeClass( typeClasses ),\n\t\t\tbuttonText = $( \"\u003cspan\u003e\u003c/span\u003e\", this.document[0] )\n\t\t\t\t.addClass( \"ui-button-text\" )\n\t\t\t\t.html( this.options.label )\n\t\t\t\t.appendTo( buttonElement.empty() )\n\t\t\t\t.text(),\n\t\t\ticons = this.options.icons,\n\t\t\tmultipleIcons = icons.primary \u0026\u0026 icons.secondary,\n\t\t\tbuttonClasses = [];\n\n\t\tif ( icons.primary || icons.secondary ) {\n\t\t\tif ( this.options.text ) {\n\t\t\t\tbuttonClasses.push( \"ui-button-text-icon\" + ( multipleIcons ? \"s\" : ( icons.primary ? \"-primary\" : \"-secondary\" ) ) );\n\t\t\t}\n\n\t\t\tif ( icons.primary ) {\n\t\t\t\tbuttonElement.prepend( \"\u003cspan class=\u0027ui-button-icon-primary ui-icon \" + icons.primary + \"\u0027\u003e\u003c/span\u003e\" );\n\t\t\t}\n\n\t\t\tif ( icons.secondary ) {\n\t\t\t\tbuttonElement.append( \"\u003cspan class=\u0027ui-button-icon-secondary ui-icon \" + icons.secondary + \"\u0027\u003e\u003c/span\u003e\" );\n\t\t\t}\n\n\t\t\tif ( !this.options.text ) {\n\t\t\t\tbuttonClasses.push( multipleIcons ? \"ui-button-icons-only\" : \"ui-button-icon-only\" );\n\n\t\t\t\tif ( !this.hasTitle ) {\n\t\t\t\t\tbuttonElement.attr( \"title\", $.trim( buttonText ) );\n\t\t\t\t}\n\t\t\t}\n\t\t} else {\n\t\t\tbuttonClasses.push( \"ui-button-text-only\" );\n\t\t}\n\t\tbuttonElement.addClass( buttonClasses.join( \" \" ) );\n\t}\n});\n\n$.widget( \"ui.buttonset\", {\n\tversion: \"1.10.2\",\n\toptions: {\n\t\titems: \"button, input[type=button], input[type=submit], input[type=reset], input[type=checkbox], input[type=radio], a, :data(ui-button)\"\n\t},\n\n\t_create: function() {\n\t\tthis.element.addClass( \"ui-buttonset\" );\n\t},\n\n\t_init: function() {\n\t\tthis.refresh();\n\t},\n\n\t_setOption: function( key, value ) {\n\t\tif ( key === \"disabled\" ) {\n\t\t\tthis.buttons.button( \"option\", key, value );\n\t\t}\n\n\t\tthis._super( key, value );\n\t},\n\n\trefresh: function() {\n\t\tvar rtl = this.element.css( \"direction\" ) === \"rtl\";\n\n\t\tthis.buttons = this.element.find( this.options.items )\n\t\t\t.filter( \":ui-button\" )\n\t\t\t\t.button( \"refresh\" )\n\t\t\t.end()\n\t\t\t.not( \":ui-button\" )\n\t\t\t\t.button()\n\t\t\t.end()\n\t\t\t.map(function() {\n\t\t\t\treturn $( this ).button( \"widget\" )[ 0 ];\n\t\t\t})\n\t\t\t\t.removeClass( \"ui-corner-all ui-corner-left ui-corner-right\" )\n\t\t\t\t.filter( \":first\" )\n\t\t\t\t\t.addClass( rtl ? \"ui-corner-right\" : \"ui-corner-left\" )\n\t\t\t\t.end()\n\t\t\t\t.filter( \":last\" )\n\t\t\t\t\t.addClass( rtl ? \"ui-corner-left\" : \"ui-corner-right\" )\n\t\t\t\t.end()\n\t\t\t.end();\n\t},\n\n\t_destroy: function() {\n\t\tthis.element.removeClass( \"ui-buttonset\" );\n\t\tthis.buttons\n\t\t\t.map(function() {\n\t\t\t\treturn $( this ).button( \"widget\" )[ 0 ];\n\t\t\t})\n\t\t\t\t.removeClass( \"ui-corner-left ui-corner-right\" )\n\t\t\t.end()\n\t\t\t.button( \"destroy\" );\n\t}\n});\n\n}( jQuery ) );\n\n(function( $, undefined ) {\n\n$.extend($.ui, { datepicker: { version: \"1.10.2\" } });\n\nvar PROP_NAME = \"datepicker\",\n\tdpuuid = new Date().getTime(),\n\tinstActive;\n\n/* Date picker manager.\n Use the singleton instance of this class, $.datepicker, to interact with the date picker.\n Settings for (groups of) date pickers are maintained in an instance object,\n allowing multiple different settings on the same page. */\n\nfunction Datepicker() {\n\tthis._curInst = null; // The current instance in use\n\tthis._keyEvent = false; // If the last event was a key event\n\tthis._disabledInputs = []; // List of date picker inputs that have been disabled\n\tthis._datepickerShowing = false; // True if the popup picker is showing , false if not\n\tthis._inDialog = false; // True if showing within a \"dialog\", false if not\n\tthis._mainDivId = \"ui-datepicker-div\"; // The ID of the main datepicker division\n\tthis._inlineClass = \"ui-datepicker-inline\"; // The name of the inline marker class\n\tthis._appendClass = \"ui-datepicker-append\"; // The name of the append marker class\n\tthis._triggerClass = \"ui-datepicker-trigger\"; // The name of the trigger marker class\n\tthis._dialogClass = \"ui-datepicker-dialog\"; // The name of the dialog marker class\n\tthis._disableClass = \"ui-datepicker-disabled\"; // The name of the disabled covering marker class\n\tthis._unselectableClass = \"ui-datepicker-unselectable\"; // The name of the unselectable cell marker class\n\tthis._currentClass = \"ui-datepicker-current-day\"; // The name of the current day marker class\n\tthis._dayOverClass = \"ui-datepicker-days-cell-over\"; // The name of the day hover marker class\n\tthis.regional = []; // Available regional settings, indexed by language code\n\tthis.regional[\"\"] = { // Default regional settings\n\t\tcloseText: \"Done\", // Display text for close link\n\t\tprevText: \"Prev\", // Display text for previous month link\n\t\tnextText: \"Next\", // Display text for next month link\n\t\tcurrentText: \"Today\", // Display text for current month link\n\t\tmonthNames: [\"January\",\"February\",\"March\",\"April\",\"May\",\"June\",\n\t\t\t\"July\",\"August\",\"September\",\"October\",\"November\",\"December\"], // Names of months for drop-down and formatting\n\t\tmonthNamesShort: [\"Jan\", \"Feb\", \"Mar\", \"Apr\", \"May\", \"Jun\", \"Jul\", \"Aug\", \"Sep\", \"Oct\", \"Nov\", \"Dec\"], // For formatting\n\t\tdayNames: [\"Sunday\", \"Monday\", \"Tuesday\", \"Wednesday\", \"Thursday\", \"Friday\", \"Saturday\"], // For formatting\n\t\tdayNamesShort: [\"Sun\", \"Mon\", \"Tue\", \"Wed\", \"Thu\", \"Fri\", \"Sat\"], // For formatting\n\t\tdayNamesMin: [\"Su\",\"Mo\",\"Tu\",\"We\",\"Th\",\"Fr\",\"Sa\"], // Column headings for days starting at Sunday\n\t\tweekHeader: \"Wk\", // Column header for week of the year\n\t\tdateFormat: \"mm/dd/yy\", // See format options on parseDate\n\t\tfirstDay: 0, // The first day of the week, Sun = 0, Mon = 1, ...\n\t\tisRTL: false, // True if right-to-left language, false if left-to-right\n\t\tshowMonthAfterYear: false, // True if the year select precedes month, false for month then year\n\t\tyearSuffix: \"\" // Additional text to append to the year in the month headers\n\t};\n\tthis._defaults = { // Global defaults for all the date picker instances\n\t\tshowOn: \"focus\", // \"focus\" for popup on focus,\n\t\t\t// \"button\" for trigger button, or \"both\" for either\n\t\tshowAnim: \"fadeIn\", // Name of jQuery animation for popup\n\t\tshowOptions: {}, // Options for enhanced animations\n\t\tdefaultDate: null, // Used when field is blank: actual date,\n\t\t\t// +/-number for offset from today, null for today\n\t\tappendText: \"\", // Display text following the input box, e.g. showing the format\n\t\tbuttonText: \"...\", // Text for trigger button\n\t\tbuttonImage: \"\", // URL for trigger button image\n\t\tbuttonImageOnly: false, // True if the image appears alone, false if it appears on a button\n\t\thideIfNoPrevNext: false, // True to hide next/previous month links\n\t\t\t// if not applicable, false to just disable them\n\t\tnavigationAsDateFormat: false, // True if date formatting applied to prev/today/next links\n\t\tgotoCurrent: false, // True if today link goes back to current selection instead\n\t\tchangeMonth: false, // True if month can be selected directly, false if only prev/next\n\t\tchangeYear: false, // True if year can be selected directly, false if only prev/next\n\t\tyearRange: \"c-10:c+10\", // Range of years to display in drop-down,\n\t\t\t// either relative to today\u0027s year (-nn:+nn), relative to currently displayed year\n\t\t\t// (c-nn:c+nn), absolute (nnnn:nnnn), or a combination of the above (nnnn:-n)\n\t\tshowOtherMonths: false, // True to show dates in other months, false to leave blank\n\t\tselectOtherMonths: false, // True to allow selection of dates in other months, false for unselectable\n\t\tshowWeek: false, // True to show week of the year, false to not show it\n\t\tcalculateWeek: this.iso8601Week, // How to calculate the week of the year,\n\t\t\t// takes a Date and returns the number of the week for it\n\t\tshortYearCutoff: \"+10\", // Short year values \u003c this are in the current century,\n\t\t\t// \u003e this are in the previous century,\n\t\t\t// string value starting with \"+\" for current year + value\n\t\tminDate: null, // The earliest selectable date, or null for no limit\n\t\tmaxDate: null, // The latest selectable date, or null for no limit\n\t\tduration: \"fast\", // Duration of display/closure\n\t\tbeforeShowDay: null, // Function that takes a date and returns an array with\n\t\t\t// [0] = true if selectable, false if not, [1] = custom CSS class name(s) or \"\",\n\t\t\t// [2] = cell title (optional), e.g. $.datepicker.noWeekends\n\t\tbeforeShow: null, // Function that takes an input field and\n\t\t\t// returns a set of custom settings for the date picker\n\t\tonSelect: null, // Define a callback function when a date is selected\n\t\tonChangeMonthYear: null, // Define a callback function when the month or year is changed\n\t\tonClose: null, // Define a callback function when the datepicker is closed\n\t\tnumberOfMonths: 1, // Number of months to show at a time\n\t\tshowCurrentAtPos: 0, // The position in multipe months at which to show the current month (starting at 0)\n\t\tstepMonths: 1, // Number of months to step back/forward\n\t\tstepBigMonths: 12, // Number of months to step back/forward for the big links\n\t\taltField: \"\", // Selector for an alternate field to store selected dates into\n\t\taltFormat: \"\", // The date format to use for the alternate field\n\t\tconstrainInput: true, // The input is constrained by the current date format\n\t\tshowButtonPanel: false, // True to show button panel, false to not show it\n\t\tautoSize: false, // True to size the input for the date format, false to leave as is\n\t\tdisabled: false // The initial disabled state\n\t};\n\t$.extend(this._defaults, this.regional[\"\"]);\n\tthis.dpDiv = bindHover($(\"\u003cdiv id=\u0027\" + this._mainDivId + \"\u0027 class=\u0027ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all\u0027\u003e\u003c/div\u003e\"));\n}\n\n$.extend(Datepicker.prototype, {\n\t/* Class name added to elements to indicate already configured with a date picker. */\n\tmarkerClassName: \"hasDatepicker\",\n\n\t//Keep track of the maximum number of rows displayed (see #7043)\n\tmaxRows: 4,\n\n\t// TODO rename to \"widget\" when switching to widget factory\n\t_widgetDatepicker: function() {\n\t\treturn this.dpDiv;\n\t},\n\n\t/* Override the default settings for all instances of the date picker.\n\t * @param settings object - the new settings to use as defaults (anonymous object)\n\t * @return the manager object\n\t */\n\tsetDefaults: function(settings) {\n\t\textendRemove(this._defaults, settings || {});\n\t\treturn this;\n\t},\n\n\t/* Attach the date picker to a jQuery selection.\n\t * @param target\telement - the target input field or division or span\n\t * @param settings object - the new settings to use for this date picker instance (anonymous)\n\t */\n\t_attachDatepicker: function(target, settings) {\n\t\tvar nodeName, inline, inst;\n\t\tnodeName = target.nodeName.toLowerCase();\n\t\tinline = (nodeName === \"div\" || nodeName === \"span\");\n\t\tif (!target.id) {\n\t\t\tthis.uuid += 1;\n\t\t\ttarget.id = \"dp\" + this.uuid;\n\t\t}\n\t\tinst = this._newInst($(target), inline);\n\t\tinst.settings = $.extend({}, settings || {});\n\t\tif (nodeName === \"input\") {\n\t\t\tthis._connectDatepicker(target, inst);\n\t\t} else if (inline) {\n\t\t\tthis._inlineDatepicker(target, inst);\n\t\t}\n\t},\n\n\t/* Create a new instance object. */\n\t_newInst: function(target, inline) {\n\t\tvar id = target[0].id.replace(/([^A-Za-z0-9_\\-])/g, \"\\\\\\\\$1\"); // escape jQuery meta chars\n\t\treturn {id: id, input: target, // associated target\n\t\t\tselectedDay: 0, selectedMonth: 0, selectedYear: 0, // current selection\n\t\t\tdrawMonth: 0, drawYear: 0, // month being drawn\n\t\t\tinline: inline, // is datepicker inline or not\n\t\t\tdpDiv: (!inline ? this.dpDiv : // presentation div\n\t\t\tbindHover($(\"\u003cdiv class=\u0027\" + this._inlineClass + \" ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all\u0027\u003e\u003c/div\u003e\")))};\n\t},\n\n\t/* Attach the date picker to an input field. */\n\t_connectDatepicker: function(target, inst) {\n\t\tvar input = $(target);\n\t\tinst.append = $([]);\n\t\tinst.trigger = $([]);\n\t\tif (input.hasClass(this.markerClassName)) {\n\t\t\treturn;\n\t\t}\n\t\tthis._attachments(input, inst);\n\t\tinput.addClass(this.markerClassName).keydown(this._doKeyDown).\n\t\t\tkeypress(this._doKeyPress).keyup(this._doKeyUp);\n\t\tthis._autoSize(inst);\n\t\t$.data(target, PROP_NAME, inst);\n\t\t//If disabled option is true, disable the datepicker once it has been attached to the input (see ticket #5665)\n\t\tif( inst.settings.disabled ) {\n\t\t\tthis._disableDatepicker( target );\n\t\t}\n\t},\n\n\t/* Make attachments based on settings. */\n\t_attachments: function(input, inst) {\n\t\tvar showOn, buttonText, buttonImage,\n\t\t\tappendText = this._get(inst, \"appendText\"),\n\t\t\tisRTL = this._get(inst, \"isRTL\");\n\n\t\tif (inst.append) {\n\t\t\tinst.append.remove();\n\t\t}\n\t\tif (appendText) {\n\t\t\tinst.append = $(\"\u003cspan class=\u0027\" + this._appendClass + \"\u0027\u003e\" + appendText + \"\u003c/span\u003e\");\n\t\t\tinput[isRTL ? \"before\" : \"after\"](inst.append);\n\t\t}\n\n\t\tinput.unbind(\"focus\", this._showDatepicker);\n\n\t\tif (inst.trigger) {\n\t\t\tinst.trigger.remove();\n\t\t}\n\n\t\tshowOn = this._get(inst, \"showOn\");\n\t\tif (showOn === \"focus\" || showOn === \"both\") { // pop-up date picker when in the marked field\n\t\t\tinput.focus(this._showDatepicker);\n\t\t}\n\t\tif (showOn === \"button\" || showOn === \"both\") { // pop-up date picker when button clicked\n\t\t\tbuttonText = this._get(inst, \"buttonText\");\n\t\t\tbuttonImage = this._get(inst, \"buttonImage\");\n\t\t\tinst.trigger = $(this._get(inst, \"buttonImageOnly\") ?\n\t\t\t\t$(\"\u003cimg/\u003e\").addClass(this._triggerClass).\n\t\t\t\t\tattr({ src: buttonImage, alt: buttonText, title: buttonText }) :\n\t\t\t\t$(\"\u003cbutton type=\u0027button\u0027\u003e\u003c/button\u003e\").addClass(this._triggerClass).\n\t\t\t\t\thtml(!buttonImage ? buttonText : $(\"\u003cimg/\u003e\").attr(\n\t\t\t\t\t{ src:buttonImage, alt:buttonText, title:buttonText })));\n\t\t\tinput[isRTL ? \"before\" : \"after\"](inst.trigger);\n\t\t\tinst.trigger.click(function() {\n\t\t\t\tif ($.datepicker._datepickerShowing \u0026\u0026 $.datepicker._lastInput === input[0]) {\n\t\t\t\t\t$.datepicker._hideDatepicker();\n\t\t\t\t} else if ($.datepicker._datepickerShowing \u0026\u0026 $.datepicker._lastInput !== input[0]) {\n\t\t\t\t\t$.datepicker._hideDatepicker();\n\t\t\t\t\t$.datepicker._showDatepicker(input[0]);\n\t\t\t\t} else {\n\t\t\t\t\t$.datepicker._showDatepicker(input[0]);\n\t\t\t\t}\n\t\t\t\treturn false;\n\t\t\t});\n\t\t}\n\t},\n\n\t/* Apply the maximum length for the date format. */\n\t_autoSize: function(inst) {\n\t\tif (this._get(inst, \"autoSize\") \u0026\u0026 !inst.inline) {\n\t\t\tvar findMax, max, maxI, i,\n\t\t\t\tdate = new Date(2009, 12 - 1, 20), // Ensure double digits\n\t\t\t\tdateFormat = this._get(inst, \"dateFormat\");\n\n\t\t\tif (dateFormat.match(/[DM]/)) {\n\t\t\t\tfindMax = function(names) {\n\t\t\t\t\tmax = 0;\n\t\t\t\t\tmaxI = 0;\n\t\t\t\t\tfor (i = 0; i \u003c names.length; i++) {\n\t\t\t\t\t\tif (names[i].length \u003e max) {\n\t\t\t\t\t\t\tmax = names[i].length;\n\t\t\t\t\t\t\tmaxI = i;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\treturn maxI;\n\t\t\t\t};\n\t\t\t\tdate.setMonth(findMax(this._get(inst, (dateFormat.match(/MM/) ?\n\t\t\t\t\t\"monthNames\" : \"monthNamesShort\"))));\n\t\t\t\tdate.setDate(findMax(this._get(inst, (dateFormat.match(/DD/) ?\n\t\t\t\t\t\"dayNames\" : \"dayNamesShort\"))) + 20 - date.getDay());\n\t\t\t}\n\t\t\tinst.input.attr(\"size\", this._formatDate(inst, date).length);\n\t\t}\n\t},\n\n\t/* Attach an inline date picker to a div. */\n\t_inlineDatepicker: function(target, inst) {\n\t\tvar divSpan = $(target);\n\t\tif (divSpan.hasClass(this.markerClassName)) {\n\t\t\treturn;\n\t\t}\n\t\tdivSpan.addClass(this.markerClassName).append(inst.dpDiv);\n\t\t$.data(target, PROP_NAME, inst);\n\t\tthis._setDate(inst, this._getDefaultDate(inst), true);\n\t\tthis._updateDatepicker(inst);\n\t\tthis._updateAlternate(inst);\n\t\t//If disabled option is true, disable the datepicker before showing it (see ticket #5665)\n\t\tif( inst.settings.disabled ) {\n\t\t\tthis._disableDatepicker( target );\n\t\t}\n\t\t// Set display:block in place of inst.dpDiv.show() which won\u0027t work on disconnected elements\n\t\t// http://bugs.jqueryui.com/ticket/7552 - A Datepicker created on a detached div has zero height\n\t\tinst.dpDiv.css( \"display\", \"block\" );\n\t},\n\n\t/* Pop-up the date picker in a \"dialog\" box.\n\t * @param input element - ignored\n\t * @param date\tstring or Date - the initial date to display\n\t * @param onSelect function - the function to call when a date is selected\n\t * @param settings object - update the dialog date picker instance\u0027s settings (anonymous object)\n\t * @param pos int[2] - coordinates for the dialog\u0027s position within the screen or\n\t *\t\t\t\t\tevent - with x/y coordinates or\n\t *\t\t\t\t\tleave empty for default (screen centre)\n\t * @return the manager object\n\t */\n\t_dialogDatepicker: function(input, date, onSelect, settings, pos) {\n\t\tvar id, browserWidth, browserHeight, scrollX, scrollY,\n\t\t\tinst = this._dialogInst; // internal instance\n\n\t\tif (!inst) {\n\t\t\tthis.uuid += 1;\n\t\t\tid = \"dp\" + this.uuid;\n\t\t\tthis._dialogInput = $(\"\u003cinput type=\u0027text\u0027 id=\u0027\" + id +\n\t\t\t\t\"\u0027 style=\u0027position: absolute; top: -100px; width: 0px;\u0027/\u003e\");\n\t\t\tthis._dialogInput.keydown(this._doKeyDown);\n\t\t\t$(\"body\").append(this._dialogInput);\n\t\t\tinst = this._dialogInst = this._newInst(this._dialogInput, false);\n\t\t\tinst.settings = {};\n\t\t\t$.data(this._dialogInput[0], PROP_NAME, inst);\n\t\t}\n\t\textendRemove(inst.settings, settings || {});\n\t\tdate = (date \u0026\u0026 date.constructor === Date ? this._formatDate(inst, date) : date);\n\t\tthis._dialogInput.val(date);\n\n\t\tthis._pos = (pos ? (pos.length ? pos : [pos.pageX, pos.pageY]) : null);\n\t\tif (!this._pos) {\n\t\t\tbrowserWidth = document.documentElement.clientWidth;\n\t\t\tbrowserHeight = document.documentElement.clientHeight;\n\t\t\tscrollX = document.documentElement.scrollLeft || document.body.scrollLeft;\n\t\t\tscrollY = document.documentElement.scrollTop || document.body.scrollTop;\n\t\t\tthis._pos = // should use actual width/height below\n\t\t\t\t[(browserWidth / 2) - 100 + scrollX, (browserHeight / 2) - 150 + scrollY];\n\t\t}\n\n\t\t// move input on screen for focus, but hidden behind dialog\n\t\tthis._dialogInput.css(\"left\", (this._pos[0] + 20) + \"px\").css(\"top\", this._pos[1] + \"px\");\n\t\tinst.settings.onSelect = onSelect;\n\t\tthis._inDialog = true;\n\t\tthis.dpDiv.addClass(this._dialogClass);\n\t\tthis._showDatepicker(this._dialogInput[0]);\n\t\tif ($.blockUI) {\n\t\t\t$.blockUI(this.dpDiv);\n\t\t}\n\t\t$.data(this._dialogInput[0], PROP_NAME, inst);\n\t\treturn this;\n\t},\n\n\t/* Detach a datepicker from its control.\n\t * @param target\telement - the target input field or division or span\n\t */\n\t_destroyDatepicker: function(target) {\n\t\tvar nodeName,\n\t\t\t$target = $(target),\n\t\t\tinst = $.data(target, PROP_NAME);\n\n\t\tif (!$target.hasClass(this.markerClassName)) {\n\t\t\treturn;\n\t\t}\n\n\t\tnodeName = target.nodeName.toLowerCase();\n\t\t$.removeData(target, PROP_NAME);\n\t\tif (nodeName === \"input\") {\n\t\t\tinst.append.remove();\n\t\t\tinst.trigger.remove();\n\t\t\t$target.removeClass(this.markerClassName).\n\t\t\t\tunbind(\"focus\", this._showDatepicker).\n\t\t\t\tunbind(\"keydown\", this._doKeyDown).\n\t\t\t\tunbind(\"keypress\", this._doKeyPress).\n\t\t\t\tunbind(\"keyup\", this._doKeyUp);\n\t\t} else if (nodeName === \"div\" || nodeName === \"span\") {\n\t\t\t$target.removeClass(this.markerClassName).empty();\n\t\t}\n\t},\n\n\t/* Enable the date picker to a jQuery selection.\n\t * @param target\telement - the target input field or division or span\n\t */\n\t_enableDatepicker: function(target) {\n\t\tvar nodeName, inline,\n\t\t\t$target = $(target),\n\t\t\tinst = $.data(target, PROP_NAME);\n\n\t\tif (!$target.hasClass(this.markerClassName)) {\n\t\t\treturn;\n\t\t}\n\n\t\tnodeName = target.nodeName.toLowerCase();\n\t\tif (nodeName === \"input\") {\n\t\t\ttarget.disabled = false;\n\t\t\tinst.trigger.filter(\"button\").\n\t\t\t\teach(function() { this.disabled = false; }).end().\n\t\t\t\tfilter(\"img\").css({opacity: \"1.0\", cursor: \"\"});\n\t\t} else if (nodeName === \"div\" || nodeName === \"span\") {\n\t\t\tinline = $target.children(\".\" + this._inlineClass);\n\t\t\tinline.children().removeClass(\"ui-state-disabled\");\n\t\t\tinline.find(\"select.ui-datepicker-month, select.ui-datepicker-year\").\n\t\t\t\tprop(\"disabled\", false);\n\t\t}\n\t\tthis._disabledInputs = $.map(this._disabledInputs,\n\t\t\tfunction(value) { return (value === target ? null : value); }); // delete entry\n\t},\n\n\t/* Disable the date picker to a jQuery selection.\n\t * @param target\telement - the target input field or division or span\n\t */\n\t_disableDatepicker: function(target) {\n\t\tvar nodeName, inline,\n\t\t\t$target = $(target),\n\t\t\tinst = $.data(target, PROP_NAME);\n\n\t\tif (!$target.hasClass(this.markerClassName)) {\n\t\t\treturn;\n\t\t}\n\n\t\tnodeName = target.nodeName.toLowerCase();\n\t\tif (nodeName === \"input\") {\n\t\t\ttarget.disabled = true;\n\t\t\tinst.trigger.filter(\"button\").\n\t\t\t\teach(function() { this.disabled = true; }).end().\n\t\t\t\tfilter(\"img\").css({opacity: \"0.5\", cursor: \"default\"});\n\t\t} else if (nodeName === \"div\" || nodeName === \"span\") {\n\t\t\tinline = $target.children(\".\" + this._inlineClass);\n\t\t\tinline.children().addClass(\"ui-state-disabled\");\n\t\t\tinline.find(\"select.ui-datepicker-month, select.ui-datepicker-year\").\n\t\t\t\tprop(\"disabled\", true);\n\t\t}\n\t\tthis._disabledInputs = $.map(this._disabledInputs,\n\t\t\tfunction(value) { return (value === target ? null : value); }); // delete entry\n\t\tthis._disabledInputs[this._disabledInputs.length] = target;\n\t},\n\n\t/* Is the first field in a jQuery collection disabled as a datepicker?\n\t * @param target\telement - the target input field or division or span\n\t * @return boolean - true if disabled, false if enabled\n\t */\n\t_isDisabledDatepicker: function(target) {\n\t\tif (!target) {\n\t\t\treturn false;\n\t\t}\n\t\tfor (var i = 0; i \u003c this._disabledInputs.length; i++) {\n\t\t\tif (this._disabledInputs[i] === target) {\n\t\t\t\treturn true;\n\t\t\t}\n\t\t}\n\t\treturn false;\n\t},\n\n\t/* Retrieve the instance data for the target control.\n\t * @param target element - the target input field or division or span\n\t * @return object - the associated instance data\n\t * @throws error if a jQuery problem getting data\n\t */\n\t_getInst: function(target) {\n\t\ttry {\n\t\t\treturn $.data(target, PROP_NAME);\n\t\t}\n\t\tcatch (err) {\n\t\t\tthrow \"Missing instance data for this datepicker\";\n\t\t}\n\t},\n\n\t/* Update or retrieve the settings for a date picker attached to an input field or division.\n\t * @param target element - the target input field or division or span\n\t * @param name\tobject - the new settings to update or\n\t *\t\t\t\tstring - the name of the setting to change or retrieve,\n\t *\t\t\t\twhen retrieving also \"all\" for all instance settings or\n\t *\t\t\t\t\"defaults\" for all global defaults\n\t * @param value any - the new value for the setting\n\t *\t\t\t\t(omit if above is an object or to retrieve a value)\n\t */\n\t_optionDatepicker: function(target, name, value) {\n\t\tvar settings, date, minDate, maxDate,\n\t\t\tinst = this._getInst(target);\n\n\t\tif (arguments.length === 2 \u0026\u0026 typeof name === \"string\") {\n\t\t\treturn (name === \"defaults\" ? $.extend({}, $.datepicker._defaults) :\n\t\t\t\t(inst ? (name === \"all\" ? $.extend({}, inst.settings) :\n\t\t\t\tthis._get(inst, name)) : null));\n\t\t}\n\n\t\tsettings = name || {};\n\t\tif (typeof name === \"string\") {\n\t\t\tsettings = {};\n\t\t\tsettings[name] = value;\n\t\t}\n\n\t\tif (inst) {\n\t\t\tif (this._curInst === inst) {\n\t\t\t\tthis._hideDatepicker();\n\t\t\t}\n\n\t\t\tdate = this._getDateDatepicker(target, true);\n\t\t\tminDate = this._getMinMaxDate(inst, \"min\");\n\t\t\tmaxDate = this._getMinMaxDate(inst, \"max\");\n\t\t\textendRemove(inst.settings, settings);\n\t\t\t// reformat the old minDate/maxDate values if dateFormat changes and a new minDate/maxDate isn\u0027t provided\n\t\t\tif (minDate !== null \u0026\u0026 settings.dateFormat !== undefined \u0026\u0026 settings.minDate === undefined) {\n\t\t\t\tinst.settings.minDate = this._formatDate(inst, minDate);\n\t\t\t}\n\t\t\tif (maxDate !== null \u0026\u0026 settings.dateFormat !== undefined \u0026\u0026 settings.maxDate === undefined) {\n\t\t\t\tinst.settings.maxDate = this._formatDate(inst, maxDate);\n\t\t\t}\n\t\t\tif ( \"disabled\" in settings ) {\n\t\t\t\tif ( settings.disabled ) {\n\t\t\t\t\tthis._disableDatepicker(target);\n\t\t\t\t} else {\n\t\t\t\t\tthis._enableDatepicker(target);\n\t\t\t\t}\n\t\t\t}\n\t\t\tthis._attachments($(target), inst);\n\t\t\tthis._autoSize(inst);\n\t\t\tthis._setDate(inst, date);\n\t\t\tthis._updateAlternate(inst);\n\t\t\tthis._updateDatepicker(inst);\n\t\t}\n\t},\n\n\t// change method deprecated\n\t_changeDatepicker: function(target, name, value) {\n\t\tthis._optionDatepicker(target, name, value);\n\t},\n\n\t/* Redraw the date picker attached to an input field or division.\n\t * @param target element - the target input field or division or span\n\t */\n\t_refreshDatepicker: function(target) {\n\t\tvar inst = this._getInst(target);\n\t\tif (inst) {\n\t\t\tthis._updateDatepicker(inst);\n\t\t}\n\t},\n\n\t/* Set the dates for a jQuery selection.\n\t * @param target element - the target input field or division or span\n\t * @param date\tDate - the new date\n\t */\n\t_setDateDatepicker: function(target, date) {\n\t\tvar inst = this._getInst(target);\n\t\tif (inst) {\n\t\t\tthis._setDate(inst, date);\n\t\t\tthis._updateDatepicker(inst);\n\t\t\tthis._updateAlternate(inst);\n\t\t}\n\t},\n\n\t/* Get the date(s) for the first entry in a jQuery selection.\n\t * @param target element - the target input field or division or span\n\t * @param noDefault boolean - true if no default date is to be used\n\t * @return Date - the current date\n\t */\n\t_getDateDatepicker: function(target, noDefault) {\n\t\tvar inst = this._getInst(target);\n\t\tif (inst \u0026\u0026 !inst.inline) {\n\t\t\tthis._setDateFromField(inst, noDefault);\n\t\t}\n\t\treturn (inst ? this._getDate(inst) : null);\n\t},\n\n\t/* Handle keystrokes. */\n\t_doKeyDown: function(event) {\n\t\tvar onSelect, dateStr, sel,\n\t\t\tinst = $.datepicker._getInst(event.target),\n\t\t\thandled = true,\n\t\t\tisRTL = inst.dpDiv.is(\".ui-datepicker-rtl\");\n\n\t\tinst._keyEvent = true;\n\t\tif ($.datepicker._datepickerShowing) {\n\t\t\tswitch (event.keyCode) {\n\t\t\t\tcase 9: $.datepicker._hideDatepicker();\n\t\t\t\t\t\thandled = false;\n\t\t\t\t\t\tbreak; // hide on tab out\n\t\t\t\tcase 13: sel = $(\"td.\" + $.datepicker._dayOverClass + \":not(.\" +\n\t\t\t\t\t\t\t\t\t$.datepicker._currentClass + \")\", inst.dpDiv);\n\t\t\t\t\t\tif (sel[0]) {\n\t\t\t\t\t\t\t$.datepicker._selectDay(event.target, inst.selectedMonth, inst.selectedYear, sel[0]);\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tonSelect = $.datepicker._get(inst, \"onSelect\");\n\t\t\t\t\t\tif (onSelect) {\n\t\t\t\t\t\t\tdateStr = $.datepicker._formatDate(inst);\n\n\t\t\t\t\t\t\t// trigger custom callback\n\t\t\t\t\t\t\tonSelect.apply((inst.input ? inst.input[0] : null), [dateStr, inst]);\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t$.datepicker._hideDatepicker();\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\treturn false; // don\u0027t submit the form\n\t\t\t\tcase 27: $.datepicker._hideDatepicker();\n\t\t\t\t\t\tbreak; // hide on escape\n\t\t\t\tcase 33: $.datepicker._adjustDate(event.target, (event.ctrlKey ?\n\t\t\t\t\t\t\t-$.datepicker._get(inst, \"stepBigMonths\") :\n\t\t\t\t\t\t\t-$.datepicker._get(inst, \"stepMonths\")), \"M\");\n\t\t\t\t\t\tbreak; // previous month/year on page up/+ ctrl\n\t\t\t\tcase 34: $.datepicker._adjustDate(event.target, (event.ctrlKey ?\n\t\t\t\t\t\t\t+$.datepicker._get(inst, \"stepBigMonths\") :\n\t\t\t\t\t\t\t+$.datepicker._get(inst, \"stepMonths\")), \"M\");\n\t\t\t\t\t\tbreak; // next month/year on page down/+ ctrl\n\t\t\t\tcase 35: if (event.ctrlKey || event.metaKey) {\n\t\t\t\t\t\t\t$.datepicker._clearDate(event.target);\n\t\t\t\t\t\t}\n\t\t\t\t\t\thandled = event.ctrlKey || event.metaKey;\n\t\t\t\t\t\tbreak; // clear on ctrl or command +end\n\t\t\t\tcase 36: if (event.ctrlKey || event.metaKey) {\n\t\t\t\t\t\t\t$.datepicker._gotoToday(event.target);\n\t\t\t\t\t\t}\n\t\t\t\t\t\thandled = event.ctrlKey || event.metaKey;\n\t\t\t\t\t\tbreak; // current on ctrl or command +home\n\t\t\t\tcase 37: if (event.ctrlKey || event.metaKey) {\n\t\t\t\t\t\t\t$.datepicker._adjustDate(event.target, (isRTL ? +1 : -1), \"D\");\n\t\t\t\t\t\t}\n\t\t\t\t\t\thandled = event.ctrlKey || event.metaKey;\n\t\t\t\t\t\t// -1 day on ctrl or command +left\n\t\t\t\t\t\tif (event.originalEvent.altKey) {\n\t\t\t\t\t\t\t$.datepicker._adjustDate(event.target, (event.ctrlKey ?\n\t\t\t\t\t\t\t\t-$.datepicker._get(inst, \"stepBigMonths\") :\n\t\t\t\t\t\t\t\t-$.datepicker._get(inst, \"stepMonths\")), \"M\");\n\t\t\t\t\t\t}\n\t\t\t\t\t\t// next month/year on alt +left on Mac\n\t\t\t\t\t\tbreak;\n\t\t\t\tcase 38: if (event.ctrlKey || event.metaKey) {\n\t\t\t\t\t\t\t$.datepicker._adjustDate(event.target, -7, \"D\");\n\t\t\t\t\t\t}\n\t\t\t\t\t\thandled = event.ctrlKey || event.metaKey;\n\t\t\t\t\t\tbreak; // -1 week on ctrl or command +up\n\t\t\t\tcase 39: if (event.ctrlKey || event.metaKey) {\n\t\t\t\t\t\t\t$.datepicker._adjustDate(event.target, (isRTL ? -1 : +1), \"D\");\n\t\t\t\t\t\t}\n\t\t\t\t\t\thandled = event.ctrlKey || event.metaKey;\n\t\t\t\t\t\t// +1 day on ctrl or command +right\n\t\t\t\t\t\tif (event.originalEvent.altKey) {\n\t\t\t\t\t\t\t$.datepicker._adjustDate(event.target, (event.ctrlKey ?\n\t\t\t\t\t\t\t\t+$.datepicker._get(inst, \"stepBigMonths\") :\n\t\t\t\t\t\t\t\t+$.datepicker._get(inst, \"stepMonths\")), \"M\");\n\t\t\t\t\t\t}\n\t\t\t\t\t\t// next month/year on alt +right\n\t\t\t\t\t\tbreak;\n\t\t\t\tcase 40: if (event.ctrlKey || event.metaKey) {\n\t\t\t\t\t\t\t$.datepicker._adjustDate(event.target, +7, \"D\");\n\t\t\t\t\t\t}\n\t\t\t\t\t\thandled = event.ctrlKey || event.metaKey;\n\t\t\t\t\t\tbreak; // +1 week on ctrl or command +down\n\t\t\t\tdefault: handled = false;\n\t\t\t}\n\t\t} else if (event.keyCode === 36 \u0026\u0026 event.ctrlKey) { // display the date picker on ctrl+home\n\t\t\t$.datepicker._showDatepicker(this);\n\t\t} else {\n\t\t\thandled = false;\n\t\t}\n\n\t\tif (handled) {\n\t\t\tevent.preventDefault();\n\t\t\tevent.stopPropagation();\n\t\t}\n\t},\n\n\t/* Filter entered characters - based on date format. */\n\t_doKeyPress: function(event) {\n\t\tvar chars, chr,\n\t\t\tinst = $.datepicker._getInst(event.target);\n\n\t\tif ($.datepicker._get(inst, \"constrainInput\")) {\n\t\t\tchars = $.datepicker._possibleChars($.datepicker._get(inst, \"dateFormat\"));\n\t\t\tchr = String.fromCharCode(event.charCode == null ? event.keyCode : event.charCode);\n\t\t\treturn event.ctrlKey || event.metaKey || (chr \u003c \" \" || !chars || chars.indexOf(chr) \u003e -1);\n\t\t}\n\t},\n\n\t/* Synchronise manual entry and field/alternate field. */\n\t_doKeyUp: function(event) {\n\t\tvar date,\n\t\t\tinst = $.datepicker._getInst(event.target);\n\n\t\tif (inst.input.val() !== inst.lastVal) {\n\t\t\ttry {\n\t\t\t\tdate = $.datepicker.parseDate($.datepicker._get(inst, \"dateFormat\"),\n\t\t\t\t\t(inst.input ? inst.input.val() : null),\n\t\t\t\t\t$.datepicker._getFormatConfig(inst));\n\n\t\t\t\tif (date) { // only if valid\n\t\t\t\t\t$.datepicker._setDateFromField(inst);\n\t\t\t\t\t$.datepicker._updateAlternate(inst);\n\t\t\t\t\t$.datepicker._updateDatepicker(inst);\n\t\t\t\t}\n\t\t\t}\n\t\t\tcatch (err) {\n\t\t\t}\n\t\t}\n\t\treturn true;\n\t},\n\n\t/* Pop-up the date picker for a given input field.\n\t * If false returned from beforeShow event handler do not show.\n\t * @param input element - the input field attached to the date picker or\n\t *\t\t\t\t\tevent - if triggered by focus\n\t */\n\t_showDatepicker: function(input) {\n\t\tinput = input.target || input;\n\t\tif (input.nodeName.toLowerCase() !== \"input\") { // find from button/image trigger\n\t\t\tinput = $(\"input\", input.parentNode)[0];\n\t\t}\n\n\t\tif ($.datepicker._isDisabledDatepicker(input) || $.datepicker._lastInput === input) { // already here\n\t\t\treturn;\n\t\t}\n\n\t\tvar inst, beforeShow, beforeShowSettings, isFixed,\n\t\t\toffset, showAnim, duration;\n\n\t\tinst = $.datepicker._getInst(input);\n\t\tif ($.datepicker._curInst \u0026\u0026 $.datepicker._curInst !== inst) {\n\t\t\t$.datepicker._curInst.dpDiv.stop(true, true);\n\t\t\tif ( inst \u0026\u0026 $.datepicker._datepickerShowing ) {\n\t\t\t\t$.datepicker._hideDatepicker( $.datepicker._curInst.input[0] );\n\t\t\t}\n\t\t}\n\n\t\tbeforeShow = $.datepicker._get(inst, \"beforeShow\");\n\t\tbeforeShowSettings = beforeShow ? beforeShow.apply(input, [input, inst]) : {};\n\t\tif(beforeShowSettings === false){\n\t\t\treturn;\n\t\t}\n\t\textendRemove(inst.settings, beforeShowSettings);\n\n\t\tinst.lastVal = null;\n\t\t$.datepicker._lastInput = input;\n\t\t$.datepicker._setDateFromField(inst);\n\n\t\tif ($.datepicker._inDialog) { // hide cursor\n\t\t\tinput.value = \"\";\n\t\t}\n\t\tif (!$.datepicker._pos) { // position below input\n\t\t\t$.datepicker._pos = $.datepicker._findPos(input);\n\t\t\t$.datepicker._pos[1] += input.offsetHeight; // add the height\n\t\t}\n\n\t\tisFixed = false;\n\t\t$(input).parents().each(function() {\n\t\t\tisFixed |= $(this).css(\"position\") === \"fixed\";\n\t\t\treturn !isFixed;\n\t\t});\n\n\t\toffset = {left: $.datepicker._pos[0], top: $.datepicker._pos[1]};\n\t\t$.datepicker._pos = null;\n\t\t//to avoid flashes on Firefox\n\t\tinst.dpDiv.empty();\n\t\t// determine sizing offscreen\n\t\tinst.dpDiv.css({position: \"absolute\", display: \"block\", top: \"-1000px\"});\n\t\t$.datepicker._updateDatepicker(inst);\n\t\t// fix width for dynamic number of date pickers\n\t\t// and adjust position before showing\n\t\toffset = $.datepicker._checkOffset(inst, offset, isFixed);\n\t\tinst.dpDiv.css({position: ($.datepicker._inDialog \u0026\u0026 $.blockUI ?\n\t\t\t\"static\" : (isFixed ? \"fixed\" : \"absolute\")), display: \"none\",\n\t\t\tleft: offset.left + \"px\", top: offset.top + \"px\"});\n\n\t\tif (!inst.inline) {\n\t\t\tshowAnim = $.datepicker._get(inst, \"showAnim\");\n\t\t\tduration = $.datepicker._get(inst, \"duration\");\n\t\t\tinst.dpDiv.zIndex($(input).zIndex()+1);\n\t\t\t$.datepicker._datepickerShowing = true;\n\n\t\t\tif ( $.effects \u0026\u0026 $.effects.effect[ showAnim ] ) {\n\t\t\t\tinst.dpDiv.show(showAnim, $.datepicker._get(inst, \"showOptions\"), duration);\n\t\t\t} else {\n\t\t\t\tinst.dpDiv[showAnim || \"show\"](showAnim ? duration : null);\n\t\t\t}\n\n\t\t\tif (inst.input.is(\":visible\") \u0026\u0026 !inst.input.is(\":disabled\")) {\n\t\t\t\tinst.input.focus();\n\t\t\t}\n\t\t\t$.datepicker._curInst = inst;\n\t\t}\n\t},\n\n\t/* Generate the date picker content. */\n\t_updateDatepicker: function(inst) {\n\t\tthis.maxRows = 4; //Reset the max number of rows being displayed (see #7043)\n\t\tinstActive = inst; // for delegate hover events\n\t\tinst.dpDiv.empty().append(this._generateHTML(inst));\n\t\tthis._attachHandlers(inst);\n\t\tinst.dpDiv.find(\".\" + this._dayOverClass + \" a\").mouseover();\n\n\t\tvar origyearshtml,\n\t\t\tnumMonths = this._getNumberOfMonths(inst),\n\t\t\tcols = numMonths[1],\n\t\t\twidth = 17;\n\n\t\tinst.dpDiv.removeClass(\"ui-datepicker-multi-2 ui-datepicker-multi-3 ui-datepicker-multi-4\").width(\"\");\n\t\tif (cols \u003e 1) {\n\t\t\tinst.dpDiv.addClass(\"ui-datepicker-multi-\" + cols).css(\"width\", (width * cols) + \"em\");\n\t\t}\n\t\tinst.dpDiv[(numMonths[0] !== 1 || numMonths[1] !== 1 ? \"add\" : \"remove\") +\n\t\t\t\"Class\"](\"ui-datepicker-multi\");\n\t\tinst.dpDiv[(this._get(inst, \"isRTL\") ? \"add\" : \"remove\") +\n\t\t\t\"Class\"](\"ui-datepicker-rtl\");\n\n\t\t// #6694 - don\u0027t focus the input if it\u0027s already focused\n\t\t// this breaks the change event in IE\n\t\tif (inst === $.datepicker._curInst \u0026\u0026 $.datepicker._datepickerShowing \u0026\u0026 inst.input \u0026\u0026\n\t\t\tinst.input.is(\":visible\") \u0026\u0026 !inst.input.is(\":disabled\") \u0026\u0026 inst.input[0] !== document.activeElement) {\n\t\t\tinst.input.focus();\n\t\t}\n\n\t\t// deffered render of the years select (to avoid flashes on Firefox)\n\t\tif( inst.yearshtml ){\n\t\t\torigyearshtml = inst.yearshtml;\n\t\t\tsetTimeout(function(){\n\t\t\t\t//assure that inst.yearshtml didn\u0027t change.\n\t\t\t\tif( origyearshtml === inst.yearshtml \u0026\u0026 inst.yearshtml ){\n\t\t\t\t\tinst.dpDiv.find(\"select.ui-datepicker-year:first\").replaceWith(inst.yearshtml);\n\t\t\t\t}\n\t\t\t\torigyearshtml = inst.yearshtml = null;\n\t\t\t}, 0);\n\t\t}\n\t},\n\n\t/* Retrieve the size of left and top borders for an element.\n\t * @param elem (jQuery object) the element of interest\n\t * @return (number[2]) the left and top borders\n\t */\n\t_getBorders: function(elem) {\n\t\tvar convert = function(value) {\n\t\t\treturn {thin: 1, medium: 2, thick: 3}[value] || value;\n\t\t};\n\t\treturn [parseFloat(convert(elem.css(\"border-left-width\"))),\n\t\t\tparseFloat(convert(elem.css(\"border-top-width\")))];\n\t},\n\n\t/* Check positioning to remain on screen. */\n\t_checkOffset: function(inst, offset, isFixed) {\n\t\tvar dpWidth = inst.dpDiv.outerWidth(),\n\t\t\tdpHeight = inst.dpDiv.outerHeight(),\n\t\t\tinputWidth = inst.input ? inst.input.outerWidth() : 0,\n\t\t\tinputHeight = inst.input ? inst.input.outerHeight() : 0,\n\t\t\tviewWidth = document.documentElement.clientWidth + (isFixed ? 0 : $(document).scrollLeft()),\n\t\t\tviewHeight = document.documentElement.clientHeight + (isFixed ? 0 : $(document).scrollTop());\n\n\t\toffset.left -= (this._get(inst, \"isRTL\") ? (dpWidth - inputWidth) : 0);\n\t\toffset.left -= (isFixed \u0026\u0026 offset.left === inst.input.offset().left) ? $(document).scrollLeft() : 0;\n\t\toffset.top -= (isFixed \u0026\u0026 offset.top === (inst.input.offset().top + inputHeight)) ? $(document).scrollTop() : 0;\n\n\t\t// now check if datepicker is showing outside window viewport - move to a better place if so.\n\t\toffset.left -= Math.min(offset.left, (offset.left + dpWidth \u003e viewWidth \u0026\u0026 viewWidth \u003e dpWidth) ?\n\t\t\tMath.abs(offset.left + dpWidth - viewWidth) : 0);\n\t\toffset.top -= Math.min(offset.top, (offset.top + dpHeight \u003e viewHeight \u0026\u0026 viewHeight \u003e dpHeight) ?\n\t\t\tMath.abs(dpHeight + inputHeight) : 0);\n\n\t\treturn offset;\n\t},\n\n\t/* Find an object\u0027s position on the screen. */\n\t_findPos: function(obj) {\n\t\tvar position,\n\t\t\tinst = this._getInst(obj),\n\t\t\tisRTL = this._get(inst, \"isRTL\");\n\n\t\twhile (obj \u0026\u0026 (obj.type === \"hidden\" || obj.nodeType !== 1 || $.expr.filters.hidden(obj))) {\n\t\t\tobj = obj[isRTL ? \"previousSibling\" : \"nextSibling\"];\n\t\t}\n\n\t\tposition = $(obj).offset();\n\t\treturn [position.left, position.top];\n\t},\n\n\t/* Hide the date picker from view.\n\t * @param input element - the input field attached to the date picker\n\t */\n\t_hideDatepicker: function(input) {\n\t\tvar showAnim, duration, postProcess, onClose,\n\t\t\tinst = this._curInst;\n\n\t\tif (!inst || (input \u0026\u0026 inst !== $.data(input, PROP_NAME))) {\n\t\t\treturn;\n\t\t}\n\n\t\tif (this._datepickerShowing) {\n\t\t\tshowAnim = this._get(inst, \"showAnim\");\n\t\t\tduration = this._get(inst, \"duration\");\n\t\t\tpostProcess = function() {\n\t\t\t\t$.datepicker._tidyDialog(inst);\n\t\t\t};\n\n\t\t\t// DEPRECATED: after BC for 1.8.x $.effects[ showAnim ] is not needed\n\t\t\tif ( $.effects \u0026\u0026 ( $.effects.effect[ showAnim ] || $.effects[ showAnim ] ) ) {\n\t\t\t\tinst.dpDiv.hide(showAnim, $.datepicker._get(inst, \"showOptions\"), duration, postProcess);\n\t\t\t} else {\n\t\t\t\tinst.dpDiv[(showAnim === \"slideDown\" ? \"slideUp\" :\n\t\t\t\t\t(showAnim === \"fadeIn\" ? \"fadeOut\" : \"hide\"))]((showAnim ? duration : null), postProcess);\n\t\t\t}\n\n\t\t\tif (!showAnim) {\n\t\t\t\tpostProcess();\n\t\t\t}\n\t\t\tthis._datepickerShowing = false;\n\n\t\t\tonClose = this._get(inst, \"onClose\");\n\t\t\tif (onClose) {\n\t\t\t\tonClose.apply((inst.input ? inst.input[0] : null), [(inst.input ? inst.input.val() : \"\"), inst]);\n\t\t\t}\n\n\t\t\tthis._lastInput = null;\n\t\t\tif (this._inDialog) {\n\t\t\t\tthis._dialogInput.css({ position: \"absolute\", left: \"0\", top: \"-100px\" });\n\t\t\t\tif ($.blockUI) {\n\t\t\t\t\t$.unblockUI();\n\t\t\t\t\t$(\"body\").append(this.dpDiv);\n\t\t\t\t}\n\t\t\t}\n\t\t\tthis._inDialog = false;\n\t\t}\n\t},\n\n\t/* Tidy up after a dialog display. */\n\t_tidyDialog: function(inst) {\n\t\tinst.dpDiv.removeClass(this._dialogClass).unbind(\".ui-datepicker-calendar\");\n\t},\n\n\t/* Close date picker if clicked elsewhere. */\n\t_checkExternalClick: function(event) {\n\t\tif (!$.datepicker._curInst) {\n\t\t\treturn;\n\t\t}\n\n\t\tvar $target = $(event.target),\n\t\t\tinst = $.datepicker._getInst($target[0]);\n\n\t\tif ( ( ( $target[0].id !== $.datepicker._mainDivId \u0026\u0026\n\t\t\t\t$target.parents(\"#\" + $.datepicker._mainDivId).length === 0 \u0026\u0026\n\t\t\t\t!$target.hasClass($.datepicker.markerClassName) \u0026\u0026\n\t\t\t\t!$target.closest(\".\" + $.datepicker._triggerClass).length \u0026\u0026\n\t\t\t\t$.datepicker._datepickerShowing \u0026\u0026 !($.datepicker._inDialog \u0026\u0026 $.blockUI) ) ) ||\n\t\t\t( $target.hasClass($.datepicker.markerClassName) \u0026\u0026 $.datepicker._curInst !== inst ) ) {\n\t\t\t\t$.datepicker._hideDatepicker();\n\t\t}\n\t},\n\n\t/* Adjust one of the date sub-fields. */\n\t_adjustDate: function(id, offset, period) {\n\t\tvar target = $(id),\n\t\t\tinst = this._getInst(target[0]);\n\n\t\tif (this._isDisabledDatepicker(target[0])) {\n\t\t\treturn;\n\t\t}\n\t\tthis._adjustInstDate(inst, offset +\n\t\t\t(period === \"M\" ? this._get(inst, \"showCurrentAtPos\") : 0), // undo positioning\n\t\t\tperiod);\n\t\tthis._updateDatepicker(inst);\n\t},\n\n\t/* Action for current link. */\n\t_gotoToday: function(id) {\n\t\tvar date,\n\t\t\ttarget = $(id),\n\t\t\tinst = this._getInst(target[0]);\n\n\t\tif (this._get(inst, \"gotoCurrent\") \u0026\u0026 inst.currentDay) {\n\t\t\tinst.selectedDay = inst.currentDay;\n\t\t\tinst.drawMonth = inst.selectedMonth = inst.currentMonth;\n\t\t\tinst.drawYear = inst.selectedYear = inst.currentYear;\n\t\t} else {\n\t\t\tdate = new Date();\n\t\t\tinst.selectedDay = date.getDate();\n\t\t\tinst.drawMonth = inst.selectedMonth = date.getMonth();\n\t\t\tinst.drawYear = inst.selectedYear = date.getFullYear();\n\t\t}\n\t\tthis._notifyChange(inst);\n\t\tthis._adjustDate(target);\n\t},\n\n\t/* Action for selecting a new month/year. */\n\t_selectMonthYear: function(id, select, period) {\n\t\tvar target = $(id),\n\t\t\tinst = this._getInst(target[0]);\n\n\t\tinst[\"selected\" + (period === \"M\" ? \"Month\" : \"Year\")] =\n\t\tinst[\"draw\" + (period === \"M\" ? \"Month\" : \"Year\")] =\n\t\t\tparseInt(select.options[select.selectedIndex].value,10);\n\n\t\tthis._notifyChange(inst);\n\t\tthis._adjustDate(target);\n\t},\n\n\t/* Action for selecting a day. */\n\t_selectDay: function(id, month, year, td) {\n\t\tvar inst,\n\t\t\ttarget = $(id);\n\n\t\tif ($(td).hasClass(this._unselectableClass) || this._isDisabledDatepicker(target[0])) {\n\t\t\treturn;\n\t\t}\n\n\t\tinst = this._getInst(target[0]);\n\t\tinst.selectedDay = inst.currentDay = $(\"a\", td).html();\n\t\tinst.selectedMonth = inst.currentMonth = month;\n\t\tinst.selectedYear = inst.currentYear = year;\n\t\tthis._selectDate(id, this._formatDate(inst,\n\t\t\tinst.currentDay, inst.currentMonth, inst.currentYear));\n\t},\n\n\t/* Erase the input field and hide the date picker. */\n\t_clearDate: function(id) {\n\t\tvar target = $(id);\n\t\tthis._selectDate(target, \"\");\n\t},\n\n\t/* Update the input field with the selected date. */\n\t_selectDate: function(id, dateStr) {\n\t\tvar onSelect,\n\t\t\ttarget = $(id),\n\t\t\tinst = this._getInst(target[0]);\n\n\t\tdateStr = (dateStr != null ? dateStr : this._formatDate(inst));\n\t\tif (inst.input) {\n\t\t\tinst.input.val(dateStr);\n\t\t}\n\t\tthis._updateAlternate(inst);\n\n\t\tonSelect = this._get(inst, \"onSelect\");\n\t\tif (onSelect) {\n\t\t\tonSelect.apply((inst.input ? inst.input[0] : null), [dateStr, inst]); // trigger custom callback\n\t\t} else if (inst.input) {\n\t\t\tinst.input.trigger(\"change\"); // fire the change event\n\t\t}\n\n\t\tif (inst.inline){\n\t\t\tthis._updateDatepicker(inst);\n\t\t} else {\n\t\t\tthis._hideDatepicker();\n\t\t\tthis._lastInput = inst.input[0];\n\t\t\tif (typeof(inst.input[0]) !== \"object\") {\n\t\t\t\tinst.input.focus(); // restore focus\n\t\t\t}\n\t\t\tthis._lastInput = null;\n\t\t}\n\t},\n\n\t/* Update any alternate field to synchronise with the main field. */\n\t_updateAlternate: function(inst) {\n\t\tvar altFormat, date, dateStr,\n\t\t\taltField = this._get(inst, \"altField\");\n\n\t\tif (altField) { // update alternate field too\n\t\t\taltFormat = this._get(inst, \"altFormat\") || this._get(inst, \"dateFormat\");\n\t\t\tdate = this._getDate(inst);\n\t\t\tdateStr = this.formatDate(altFormat, date, this._getFormatConfig(inst));\n\t\t\t$(altField).each(function() { $(this).val(dateStr); });\n\t\t}\n\t},\n\n\t/* Set as beforeShowDay function to prevent selection of weekends.\n\t * @param date Date - the date to customise\n\t * @return [boolean, string] - is this date selectable?, what is its CSS class?\n\t */\n\tnoWeekends: function(date) {\n\t\tvar day = date.getDay();\n\t\treturn [(day \u003e 0 \u0026\u0026 day \u003c 6), \"\"];\n\t},\n\n\t/* Set as calculateWeek to determine the week of the year based on the ISO 8601 definition.\n\t * @param date Date - the date to get the week for\n\t * @return number - the number of the week within the year that contains this date\n\t */\n\tiso8601Week: function(date) {\n\t\tvar time,\n\t\t\tcheckDate = new Date(date.getTime());\n\n\t\t// Find Thursday of this week starting on Monday\n\t\tcheckDate.setDate(checkDate.getDate() + 4 - (checkDate.getDay() || 7));\n\n\t\ttime = checkDate.getTime();\n\t\tcheckDate.setMonth(0); // Compare with Jan 1\n\t\tcheckDate.setDate(1);\n\t\treturn Math.floor(Math.round((time - checkDate) / 86400000) / 7) + 1;\n\t},\n\n\t/* Parse a string value into a date object.\n\t * See formatDate below for the possible formats.\n\t *\n\t * @param format string - the expected format of the date\n\t * @param value string - the date in the above format\n\t * @param settings Object - attributes include:\n\t *\t\t\t\t\tshortYearCutoff number - the cutoff year for determining the century (optional)\n\t *\t\t\t\t\tdayNamesShort\tstring[7] - abbreviated names of the days from Sunday (optional)\n\t *\t\t\t\t\tdayNames\t\tstring[7] - names of the days from Sunday (optional)\n\t *\t\t\t\t\tmonthNamesShort string[12] - abbreviated names of the months (optional)\n\t *\t\t\t\t\tmonthNames\t\tstring[12] - names of the months (optional)\n\t * @return Date - the extracted date value or null if value is blank\n\t */\n\tparseDate: function (format, value, settings) {\n\t\tif (format == null || value == null) {\n\t\t\tthrow \"Invalid arguments\";\n\t\t}\n\n\t\tvalue = (typeof value === \"object\" ? value.toString() : value + \"\");\n\t\tif (value === \"\") {\n\t\t\treturn null;\n\t\t}\n\n\t\tvar iFormat, dim, extra,\n\t\t\tiValue = 0,\n\t\t\tshortYearCutoffTemp = (settings ? settings.shortYearCutoff : null) || this._defaults.shortYearCutoff,\n\t\t\tshortYearCutoff = (typeof shortYearCutoffTemp !== \"string\" ? shortYearCutoffTemp :\n\t\t\t\tnew Date().getFullYear() % 100 + parseInt(shortYearCutoffTemp, 10)),\n\t\t\tdayNamesShort = (settings ? settings.dayNamesShort : null) || this._defaults.dayNamesShort,\n\t\t\tdayNames = (settings ? settings.dayNames : null) || this._defaults.dayNames,\n\t\t\tmonthNamesShort = (settings ? settings.monthNamesShort : null) || this._defaults.monthNamesShort,\n\t\t\tmonthNames = (settings ? settings.monthNames : null) || this._defaults.monthNames,\n\t\t\tyear = -1,\n\t\t\tmonth = -1,\n\t\t\tday = -1,\n\t\t\tdoy = -1,\n\t\t\tliteral = false,\n\t\t\tdate,\n\t\t\t// Check whether a format character is doubled\n\t\t\tlookAhead = function(match) {\n\t\t\t\tvar matches = (iFormat + 1 \u003c format.length \u0026\u0026 format.charAt(iFormat + 1) === match);\n\t\t\t\tif (matches) {\n\t\t\t\t\tiFormat++;\n\t\t\t\t}\n\t\t\t\treturn matches;\n\t\t\t},\n\t\t\t// Extract a number from the string value\n\t\t\tgetNumber = function(match) {\n\t\t\t\tvar isDoubled = lookAhead(match),\n\t\t\t\t\tsize = (match === \"@\" ? 14 : (match === \"!\" ? 20 :\n\t\t\t\t\t(match === \"y\" \u0026\u0026 isDoubled ? 4 : (match === \"o\" ? 3 : 2)))),\n\t\t\t\t\tdigits = new RegExp(\"^\\\\d{1,\" + size + \"}\"),\n\t\t\t\t\tnum = value.substring(iValue).match(digits);\n\t\t\t\tif (!num) {\n\t\t\t\t\tthrow \"Missing number at position \" + iValue;\n\t\t\t\t}\n\t\t\t\tiValue += num[0].length;\n\t\t\t\treturn parseInt(num[0], 10);\n\t\t\t},\n\t\t\t// Extract a name from the string value and convert to an index\n\t\t\tgetName = function(match, shortNames, longNames) {\n\t\t\t\tvar index = -1,\n\t\t\t\t\tnames = $.map(lookAhead(match) ? longNames : shortNames, function (v, k) {\n\t\t\t\t\t\treturn [ [k, v] ];\n\t\t\t\t\t}).sort(function (a, b) {\n\t\t\t\t\t\treturn -(a[1].length - b[1].length);\n\t\t\t\t\t});\n\n\t\t\t\t$.each(names, function (i, pair) {\n\t\t\t\t\tvar name = pair[1];\n\t\t\t\t\tif (value.substr(iValue, name.length).toLowerCase() === name.toLowerCase()) {\n\t\t\t\t\t\tindex = pair[0];\n\t\t\t\t\t\tiValue += name.length;\n\t\t\t\t\t\treturn false;\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t\tif (index !== -1) {\n\t\t\t\t\treturn index + 1;\n\t\t\t\t} else {\n\t\t\t\t\tthrow \"Unknown name at position \" + iValue;\n\t\t\t\t}\n\t\t\t},\n\t\t\t// Confirm that a literal character matches the string value\n\t\t\tcheckLiteral = function() {\n\t\t\t\tif (value.charAt(iValue) !== format.charAt(iFormat)) {\n\t\t\t\t\tthrow \"Unexpected literal at position \" + iValue;\n\t\t\t\t}\n\t\t\t\tiValue++;\n\t\t\t};\n\n\t\tfor (iFormat = 0; iFormat \u003c format.length; iFormat++) {\n\t\t\tif (literal) {\n\t\t\t\tif (format.charAt(iFormat) === \"\u0027\" \u0026\u0026 !lookAhead(\"\u0027\")) {\n\t\t\t\t\tliteral = false;\n\t\t\t\t} else {\n\t\t\t\t\tcheckLiteral();\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tswitch (format.charAt(iFormat)) {\n\t\t\t\t\tcase \"d\":\n\t\t\t\t\t\tday = getNumber(\"d\");\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase \"D\":\n\t\t\t\t\t\tgetName(\"D\", dayNamesShort, dayNames);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase \"o\":\n\t\t\t\t\t\tdoy = getNumber(\"o\");\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase \"m\":\n\t\t\t\t\t\tmonth = getNumber(\"m\");\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase \"M\":\n\t\t\t\t\t\tmonth = getName(\"M\", monthNamesShort, monthNames);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase \"y\":\n\t\t\t\t\t\tyear = getNumber(\"y\");\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase \"@\":\n\t\t\t\t\t\tdate = new Date(getNumber(\"@\"));\n\t\t\t\t\t\tyear = date.getFullYear();\n\t\t\t\t\t\tmonth = date.getMonth() + 1;\n\t\t\t\t\t\tday = date.getDate();\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase \"!\":\n\t\t\t\t\t\tdate = new Date((getNumber(\"!\") - this._ticksTo1970) / 10000);\n\t\t\t\t\t\tyear = date.getFullYear();\n\t\t\t\t\t\tmonth = date.getMonth() + 1;\n\t\t\t\t\t\tday = date.getDate();\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase \"\u0027\":\n\t\t\t\t\t\tif (lookAhead(\"\u0027\")){\n\t\t\t\t\t\t\tcheckLiteral();\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tliteral = true;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tdefault:\n\t\t\t\t\t\tcheckLiteral();\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif (iValue \u003c value.length){\n\t\t\textra = value.substr(iValue);\n\t\t\tif (!/^\\s+/.test(extra)) {\n\t\t\t\tthrow \"Extra/unparsed characters found in date: \" + extra;\n\t\t\t}\n\t\t}\n\n\t\tif (year === -1) {\n\t\t\tyear = new Date().getFullYear();\n\t\t} else if (year \u003c 100) {\n\t\t\tyear += new Date().getFullYear() - new Date().getFullYear() % 100 +\n\t\t\t\t(year \u003c= shortYearCutoff ? 0 : -100);\n\t\t}\n\n\t\tif (doy \u003e -1) {\n\t\t\tmonth = 1;\n\t\t\tday = doy;\n\t\t\tdo {\n\t\t\t\tdim = this._getDaysInMonth(year, month - 1);\n\t\t\t\tif (day \u003c= dim) {\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tmonth++;\n\t\t\t\tday -= dim;\n\t\t\t} while (true);\n\t\t}\n\n\t\tdate = this._daylightSavingAdjust(new Date(year, month - 1, day));\n\t\tif (date.getFullYear() !== year || date.getMonth() + 1 !== month || date.getDate() !== day) {\n\t\t\tthrow \"Invalid date\"; // E.g. 31/02/00\n\t\t}\n\t\treturn date;\n\t},\n\n\t/* Standard date formats. */\n\tATOM: \"yy-mm-dd\", // RFC 3339 (ISO 8601)\n\tCOOKIE: \"D, dd M yy\",\n\tISO_8601: \"yy-mm-dd\",\n\tRFC_822: \"D, d M y\",\n\tRFC_850: \"DD, dd-M-y\",\n\tRFC_1036: \"D, d M y\",\n\tRFC_1123: \"D, d M yy\",\n\tRFC_2822: \"D, d M yy\",\n\tRSS: \"D, d M y\", // RFC 822\n\tTICKS: \"!\",\n\tTIMESTAMP: \"@\",\n\tW3C: \"yy-mm-dd\", // ISO 8601\n\n\t_ticksTo1970: (((1970 - 1) * 365 + Math.floor(1970 / 4) - Math.floor(1970 / 100) +\n\t\tMath.floor(1970 / 400)) * 24 * 60 * 60 * 10000000),\n\n\t/* Format a date object into a string value.\n\t * The format can be combinations of the following:\n\t * d - day of month (no leading zero)\n\t * dd - day of month (two digit)\n\t * o - day of year (no leading zeros)\n\t * oo - day of year (three digit)\n\t * D - day name short\n\t * DD - day name long\n\t * m - month of year (no leading zero)\n\t * mm - month of year (two digit)\n\t * M - month name short\n\t * MM - month name long\n\t * y - year (two digit)\n\t * yy - year (four digit)\n\t * @ - Unix timestamp (ms since 01/01/1970)\n\t * ! - Windows ticks (100ns since 01/01/0001)\n\t * \"...\" - literal text\n\t * \u0027\u0027 - single quote\n\t *\n\t * @param format string - the desired format of the date\n\t * @param date Date - the date value to format\n\t * @param settings Object - attributes include:\n\t *\t\t\t\t\tdayNamesShort\tstring[7] - abbreviated names of the days from Sunday (optional)\n\t *\t\t\t\t\tdayNames\t\tstring[7] - names of the days from Sunday (optional)\n\t *\t\t\t\t\tmonthNamesShort string[12] - abbreviated names of the months (optional)\n\t *\t\t\t\t\tmonthNames\t\tstring[12] - names of the months (optional)\n\t * @return string - the date in the above format\n\t */\n\tformatDate: function (format, date, settings) {\n\t\tif (!date) {\n\t\t\treturn \"\";\n\t\t}\n\n\t\tvar iFormat,\n\t\t\tdayNamesShort = (settings ? settings.dayNamesShort : null) || this._defaults.dayNamesShort,\n\t\t\tdayNames = (settings ? settings.dayNames : null) || this._defaults.dayNames,\n\t\t\tmonthNamesShort = (settings ? settings.monthNamesShort : null) || this._defaults.monthNamesShort,\n\t\t\tmonthNames = (settings ? settings.monthNames : null) || this._defaults.monthNames,\n\t\t\t// Check whether a format character is doubled\n\t\t\tlookAhead = function(match) {\n\t\t\t\tvar matches = (iFormat + 1 \u003c format.length \u0026\u0026 format.charAt(iFormat + 1) === match);\n\t\t\t\tif (matches) {\n\t\t\t\t\tiFormat++;\n\t\t\t\t}\n\t\t\t\treturn matches;\n\t\t\t},\n\t\t\t// Format a number, with leading zero if necessary\n\t\t\tformatNumber = function(match, value, len) {\n\t\t\t\tvar num = \"\" + value;\n\t\t\t\tif (lookAhead(match)) {\n\t\t\t\t\twhile (num.length \u003c len) {\n\t\t\t\t\t\tnum = \"0\" + num;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn num;\n\t\t\t},\n\t\t\t// Format a name, short or long as requested\n\t\t\tformatName = function(match, value, shortNames, longNames) {\n\t\t\t\treturn (lookAhead(match) ? longNames[value] : shortNames[value]);\n\t\t\t},\n\t\t\toutput = \"\",\n\t\t\tliteral = false;\n\n\t\tif (date) {\n\t\t\tfor (iFormat = 0; iFormat \u003c format.length; iFormat++) {\n\t\t\t\tif (literal) {\n\t\t\t\t\tif (format.charAt(iFormat) === \"\u0027\" \u0026\u0026 !lookAhead(\"\u0027\")) {\n\t\t\t\t\t\tliteral = false;\n\t\t\t\t\t} else {\n\t\t\t\t\t\toutput += format.charAt(iFormat);\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tswitch (format.charAt(iFormat)) {\n\t\t\t\t\t\tcase \"d\":\n\t\t\t\t\t\t\toutput += formatNumber(\"d\", date.getDate(), 2);\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase \"D\":\n\t\t\t\t\t\t\toutput += formatName(\"D\", date.getDay(), dayNamesShort, dayNames);\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase \"o\":\n\t\t\t\t\t\t\toutput += formatNumber(\"o\",\n\t\t\t\t\t\t\t\tMath.round((new Date(date.getFullYear(), date.getMonth(), date.getDate()).getTime() - new Date(date.getFullYear(), 0, 0).getTime()) / 86400000), 3);\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase \"m\":\n\t\t\t\t\t\t\toutput += formatNumber(\"m\", date.getMonth() + 1, 2);\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase \"M\":\n\t\t\t\t\t\t\toutput += formatName(\"M\", date.getMonth(), monthNamesShort, monthNames);\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase \"y\":\n\t\t\t\t\t\t\toutput += (lookAhead(\"y\") ? date.getFullYear() :\n\t\t\t\t\t\t\t\t(date.getYear() % 100 \u003c 10 ? \"0\" : \"\") + date.getYear() % 100);\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase \"@\":\n\t\t\t\t\t\t\toutput += date.getTime();\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase \"!\":\n\t\t\t\t\t\t\toutput += date.getTime() * 10000 + this._ticksTo1970;\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase \"\u0027\":\n\t\t\t\t\t\t\tif (lookAhead(\"\u0027\")) {\n\t\t\t\t\t\t\t\toutput += \"\u0027\";\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tliteral = true;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tdefault:\n\t\t\t\t\t\t\toutput += format.charAt(iFormat);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\treturn output;\n\t},\n\n\t/* Extract all possible characters from the date format. */\n\t_possibleChars: function (format) {\n\t\tvar iFormat,\n\t\t\tchars = \"\",\n\t\t\tliteral = false,\n\t\t\t// Check whether a format character is doubled\n\t\t\tlookAhead = function(match) {\n\t\t\t\tvar matches = (iFormat + 1 \u003c format.length \u0026\u0026 format.charAt(iFormat + 1) === match);\n\t\t\t\tif (matches) {\n\t\t\t\t\tiFormat++;\n\t\t\t\t}\n\t\t\t\treturn matches;\n\t\t\t};\n\n\t\tfor (iFormat = 0; iFormat \u003c format.length; iFormat++) {\n\t\t\tif (literal) {\n\t\t\t\tif (format.charAt(iFormat) === \"\u0027\" \u0026\u0026 !lookAhead(\"\u0027\")) {\n\t\t\t\t\tliteral = false;\n\t\t\t\t} else {\n\t\t\t\t\tchars += format.charAt(iFormat);\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tswitch (format.charAt(iFormat)) {\n\t\t\t\t\tcase \"d\": case \"m\": case \"y\": case \"@\":\n\t\t\t\t\t\tchars += \"0123456789\";\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase \"D\": case \"M\":\n\t\t\t\t\t\treturn null; // Accept anything\n\t\t\t\t\tcase \"\u0027\":\n\t\t\t\t\t\tif (lookAhead(\"\u0027\")) {\n\t\t\t\t\t\t\tchars += \"\u0027\";\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tliteral = true;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tdefault:\n\t\t\t\t\t\tchars += format.charAt(iFormat);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\treturn chars;\n\t},\n\n\t/* Get a setting value, defaulting if necessary. */\n\t_get: function(inst, name) {\n\t\treturn inst.settings[name] !== undefined ?\n\t\t\tinst.settings[name] : this._defaults[name];\n\t},\n\n\t/* Parse existing date and initialise date picker. */\n\t_setDateFromField: function(inst, noDefault) {\n\t\tif (inst.input.val() === inst.lastVal) {\n\t\t\treturn;\n\t\t}\n\n\t\tvar dateFormat = this._get(inst, \"dateFormat\"),\n\t\t\tdates = inst.lastVal = inst.input ? inst.input.val() : null,\n\t\t\tdefaultDate = this._getDefaultDate(inst),\n\t\t\tdate = defaultDate,\n\t\t\tsettings = this._getFormatConfig(inst);\n\n\t\ttry {\n\t\t\tdate = this.parseDate(dateFormat, dates, settings) || defaultDate;\n\t\t} catch (event) {\n\t\t\tdates = (noDefault ? \"\" : dates);\n\t\t}\n\t\tinst.selectedDay = date.getDate();\n\t\tinst.drawMonth = inst.selectedMonth = date.getMonth();\n\t\tinst.drawYear = inst.selectedYear = date.getFullYear();\n\t\tinst.currentDay = (dates ? date.getDate() : 0);\n\t\tinst.currentMonth = (dates ? date.getMonth() : 0);\n\t\tinst.currentYear = (dates ? date.getFullYear() : 0);\n\t\tthis._adjustInstDate(inst);\n\t},\n\n\t/* Retrieve the default date shown on opening. */\n\t_getDefaultDate: function(inst) {\n\t\treturn this._restrictMinMax(inst,\n\t\t\tthis._determineDate(inst, this._get(inst, \"defaultDate\"), new Date()));\n\t},\n\n\t/* A date may be specified as an exact value or a relative one. */\n\t_determineDate: function(inst, date, defaultDate) {\n\t\tvar offsetNumeric = function(offset) {\n\t\t\t\tvar date = new Date();\n\t\t\t\tdate.setDate(date.getDate() + offset);\n\t\t\t\treturn date;\n\t\t\t},\n\t\t\toffsetString = function(offset) {\n\t\t\t\ttry {\n\t\t\t\t\treturn $.datepicker.parseDate($.datepicker._get(inst, \"dateFormat\"),\n\t\t\t\t\t\toffset, $.datepicker._getFormatConfig(inst));\n\t\t\t\t}\n\t\t\t\tcatch (e) {\n\t\t\t\t\t// Ignore\n\t\t\t\t}\n\n\t\t\t\tvar date = (offset.toLowerCase().match(/^c/) ?\n\t\t\t\t\t$.datepicker._getDate(inst) : null) || new Date(),\n\t\t\t\t\tyear = date.getFullYear(),\n\t\t\t\t\tmonth = date.getMonth(),\n\t\t\t\t\tday = date.getDate(),\n\t\t\t\t\tpattern = /([+\\-]?[0-9]+)\\s*(d|D|w|W|m|M|y|Y)?/g,\n\t\t\t\t\tmatches = pattern.exec(offset);\n\n\t\t\t\twhile (matches) {\n\t\t\t\t\tswitch (matches[2] || \"d\") {\n\t\t\t\t\t\tcase \"d\" : case \"D\" :\n\t\t\t\t\t\t\tday += parseInt(matches[1],10); break;\n\t\t\t\t\t\tcase \"w\" : case \"W\" :\n\t\t\t\t\t\t\tday += parseInt(matches[1],10) * 7; break;\n\t\t\t\t\t\tcase \"m\" : case \"M\" :\n\t\t\t\t\t\t\tmonth += parseInt(matches[1],10);\n\t\t\t\t\t\t\tday = Math.min(day, $.datepicker._getDaysInMonth(year, month));\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase \"y\": case \"Y\" :\n\t\t\t\t\t\t\tyear += parseInt(matches[1],10);\n\t\t\t\t\t\t\tday = Math.min(day, $.datepicker._getDaysInMonth(year, month));\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t\tmatches = pattern.exec(offset);\n\t\t\t\t}\n\t\t\t\treturn new Date(year, month, day);\n\t\t\t},\n\t\t\tnewDate = (date == null || date === \"\" ? defaultDate : (typeof date === \"string\" ? offsetString(date) :\n\t\t\t\t(typeof date === \"number\" ? (isNaN(date) ? defaultDate : offsetNumeric(date)) : new Date(date.getTime()))));\n\n\t\tnewDate = (newDate \u0026\u0026 newDate.toString() === \"Invalid Date\" ? defaultDate : newDate);\n\t\tif (newDate) {\n\t\t\tnewDate.setHours(0);\n\t\t\tnewDate.setMinutes(0);\n\t\t\tnewDate.setSeconds(0);\n\t\t\tnewDate.setMilliseconds(0);\n\t\t}\n\t\treturn this._daylightSavingAdjust(newDate);\n\t},\n\n\t/* Handle switch to/from daylight saving.\n\t * Hours may be non-zero on daylight saving cut-over:\n\t * \u003e 12 when midnight changeover, but then cannot generate\n\t * midnight datetime, so jump to 1AM, otherwise reset.\n\t * @param date (Date) the date to check\n\t * @return (Date) the corrected date\n\t */\n\t_daylightSavingAdjust: function(date) {\n\t\tif (!date) {\n\t\t\treturn null;\n\t\t}\n\t\tdate.setHours(date.getHours() \u003e 12 ? date.getHours() + 2 : 0);\n\t\treturn date;\n\t},\n\n\t/* Set the date(s) directly. */\n\t_setDate: function(inst, date, noChange) {\n\t\tvar clear = !date,\n\t\t\torigMonth = inst.selectedMonth,\n\t\t\torigYear = inst.selectedYear,\n\t\t\tnewDate = this._restrictMinMax(inst, this._determineDate(inst, date, new Date()));\n\n\t\tinst.selectedDay = inst.currentDay = newDate.getDate();\n\t\tinst.drawMonth = inst.selectedMonth = inst.currentMonth = newDate.getMonth();\n\t\tinst.drawYear = inst.selectedYear = inst.currentYear = newDate.getFullYear();\n\t\tif ((origMonth !== inst.selectedMonth || origYear !== inst.selectedYear) \u0026\u0026 !noChange) {\n\t\t\tthis._notifyChange(inst);\n\t\t}\n\t\tthis._adjustInstDate(inst);\n\t\tif (inst.input) {\n\t\t\tinst.input.val(clear ? \"\" : this._formatDate(inst));\n\t\t}\n\t},\n\n\t/* Retrieve the date(s) directly. */\n\t_getDate: function(inst) {\n\t\tvar startDate = (!inst.currentYear || (inst.input \u0026\u0026 inst.input.val() === \"\") ? null :\n\t\t\tthis._daylightSavingAdjust(new Date(\n\t\t\tinst.currentYear, inst.currentMonth, inst.currentDay)));\n\t\t\treturn startDate;\n\t},\n\n\t/* Attach the onxxx handlers. These are declared statically so\n\t * they work with static code transformers like Caja.\n\t */\n\t_attachHandlers: function(inst) {\n\t\tvar stepMonths = this._get(inst, \"stepMonths\"),\n\t\t\tid = \"#\" + inst.id.replace( /\\\\\\\\/g, \"\\\\\" );\n\t\tinst.dpDiv.find(\"[data-handler]\").map(function () {\n\t\t\tvar handler = {\n\t\t\t\tprev: function () {\n\t\t\t\t\twindow[\"DP_jQuery_\" + dpuuid].datepicker._adjustDate(id, -stepMonths, \"M\");\n\t\t\t\t},\n\t\t\t\tnext: function () {\n\t\t\t\t\twindow[\"DP_jQuery_\" + dpuuid].datepicker._adjustDate(id, +stepMonths, \"M\");\n\t\t\t\t},\n\t\t\t\thide: function () {\n\t\t\t\t\twindow[\"DP_jQuery_\" + dpuuid].datepicker._hideDatepicker();\n\t\t\t\t},\n\t\t\t\ttoday: function () {\n\t\t\t\t\twindow[\"DP_jQuery_\" + dpuuid].datepicker._gotoToday(id);\n\t\t\t\t},\n\t\t\t\tselectDay: function () {\n\t\t\t\t\twindow[\"DP_jQuery_\" + dpuuid].datepicker._selectDay(id, +this.getAttribute(\"data-month\"), +this.getAttribute(\"data-year\"), this);\n\t\t\t\t\treturn false;\n\t\t\t\t},\n\t\t\t\tselectMonth: function () {\n\t\t\t\t\twindow[\"DP_jQuery_\" + dpuuid].datepicker._selectMonthYear(id, this, \"M\");\n\t\t\t\t\treturn false;\n\t\t\t\t},\n\t\t\t\tselectYear: function () {\n\t\t\t\t\twindow[\"DP_jQuery_\" + dpuuid].datepicker._selectMonthYear(id, this, \"Y\");\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t};\n\t\t\t$(this).bind(this.getAttribute(\"data-event\"), handler[this.getAttribute(\"data-handler\")]);\n\t\t});\n\t},\n\n\t/* Generate the HTML for the current state of the date picker. */\n\t_generateHTML: function(inst) {\n\t\tvar maxDraw, prevText, prev, nextText, next, currentText, gotoDate,\n\t\t\tcontrols, buttonPanel, firstDay, showWeek, dayNames, dayNamesMin,\n\t\t\tmonthNames, monthNamesShort, beforeShowDay, showOtherMonths,\n\t\t\tselectOtherMonths, defaultDate, html, dow, row, group, col, selectedDate,\n\t\t\tcornerClass, calender, thead, day, daysInMonth, leadDays, curRows, numRows,\n\t\t\tprintDate, dRow, tbody, daySettings, otherMonth, unselectable,\n\t\t\ttempDate = new Date(),\n\t\t\ttoday = this._daylightSavingAdjust(\n\t\t\t\tnew Date(tempDate.getFullYear(), tempDate.getMonth(), tempDate.getDate())), // clear time\n\t\t\tisRTL = this._get(inst, \"isRTL\"),\n\t\t\tshowButtonPanel = this._get(inst, \"showButtonPanel\"),\n\t\t\thideIfNoPrevNext = this._get(inst, \"hideIfNoPrevNext\"),\n\t\t\tnavigationAsDateFormat = this._get(inst, \"navigationAsDateFormat\"),\n\t\t\tnumMonths = this._getNumberOfMonths(inst),\n\t\t\tshowCurrentAtPos = this._get(inst, \"showCurrentAtPos\"),\n\t\t\tstepMonths = this._get(inst, \"stepMonths\"),\n\t\t\tisMultiMonth = (numMonths[0] !== 1 || numMonths[1] !== 1),\n\t\t\tcurrentDate = this._daylightSavingAdjust((!inst.currentDay ? new Date(9999, 9, 9) :\n\t\t\t\tnew Date(inst.currentYear, inst.currentMonth, inst.currentDay))),\n\t\t\tminDate = this._getMinMaxDate(inst, \"min\"),\n\t\t\tmaxDate = this._getMinMaxDate(inst, \"max\"),\n\t\t\tdrawMonth = inst.drawMonth - showCurrentAtPos,\n\t\t\tdrawYear = inst.drawYear;\n\n\t\tif (drawMonth \u003c 0) {\n\t\t\tdrawMonth += 12;\n\t\t\tdrawYear--;\n\t\t}\n\t\tif (maxDate) {\n\t\t\tmaxDraw = this._daylightSavingAdjust(new Date(maxDate.getFullYear(),\n\t\t\t\tmaxDate.getMonth() - (numMonths[0] * numMonths[1]) + 1, maxDate.getDate()));\n\t\t\tmaxDraw = (minDate \u0026\u0026 maxDraw \u003c minDate ? minDate : maxDraw);\n\t\t\twhile (this._daylightSavingAdjust(new Date(drawYear, drawMonth, 1)) \u003e maxDraw) {\n\t\t\t\tdrawMonth--;\n\t\t\t\tif (drawMonth \u003c 0) {\n\t\t\t\t\tdrawMonth = 11;\n\t\t\t\t\tdrawYear--;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tinst.drawMonth = drawMonth;\n\t\tinst.drawYear = drawYear;\n\n\t\tprevText = this._get(inst, \"prevText\");\n\t\tprevText = (!navigationAsDateFormat ? prevText : this.formatDate(prevText,\n\t\t\tthis._daylightSavingAdjust(new Date(drawYear, drawMonth - stepMonths, 1)),\n\t\t\tthis._getFormatConfig(inst)));\n\n\t\tprev = (this._canAdjustMonth(inst, -1, drawYear, drawMonth) ?\n\t\t\t\"\u003ca class=\u0027ui-datepicker-prev ui-corner-all\u0027 data-handler=\u0027prev\u0027 data-event=\u0027click\u0027\" +\n\t\t\t\" title=\u0027\" + prevText + \"\u0027\u003e\u003cspan class=\u0027ui-icon ui-icon-circle-triangle-\" + ( isRTL ? \"e\" : \"w\") + \"\u0027\u003e\" + prevText + \"\u003c/span\u003e\u003c/a\u003e\" :\n\t\t\t(hideIfNoPrevNext ? \"\" : \"\u003ca class=\u0027ui-datepicker-prev ui-corner-all ui-state-disabled\u0027 title=\u0027\"+ prevText +\"\u0027\u003e\u003cspan class=\u0027ui-icon ui-icon-circle-triangle-\" + ( isRTL ? \"e\" : \"w\") + \"\u0027\u003e\" + prevText + \"\u003c/span\u003e\u003c/a\u003e\"));\n\n\t\tnextText = this._get(inst, \"nextText\");\n\t\tnextText = (!navigationAsDateFormat ? nextText : this.formatDate(nextText,\n\t\t\tthis._daylightSavingAdjust(new Date(drawYear, drawMonth + stepMonths, 1)),\n\t\t\tthis._getFormatConfig(inst)));\n\n\t\tnext = (this._canAdjustMonth(inst, +1, drawYear, drawMonth) ?\n\t\t\t\"\u003ca class=\u0027ui-datepicker-next ui-corner-all\u0027 data-handler=\u0027next\u0027 data-event=\u0027click\u0027\" +\n\t\t\t\" title=\u0027\" + nextText + \"\u0027\u003e\u003cspan class=\u0027ui-icon ui-icon-circle-triangle-\" + ( isRTL ? \"w\" : \"e\") + \"\u0027\u003e\" + nextText + \"\u003c/span\u003e\u003c/a\u003e\" :\n\t\t\t(hideIfNoPrevNext ? \"\" : \"\u003ca class=\u0027ui-datepicker-next ui-corner-all ui-state-disabled\u0027 title=\u0027\"+ nextText + \"\u0027\u003e\u003cspan class=\u0027ui-icon ui-icon-circle-triangle-\" + ( isRTL ? \"w\" : \"e\") + \"\u0027\u003e\" + nextText + \"\u003c/span\u003e\u003c/a\u003e\"));\n\n\t\tcurrentText = this._get(inst, \"currentText\");\n\t\tgotoDate = (this._get(inst, \"gotoCurrent\") \u0026\u0026 inst.currentDay ? currentDate : today);\n\t\tcurrentText = (!navigationAsDateFormat ? currentText :\n\t\t\tthis.formatDate(currentText, gotoDate, this._getFormatConfig(inst)));\n\n\t\tcontrols = (!inst.inline ? \"\u003cbutton type=\u0027button\u0027 class=\u0027ui-datepicker-close ui-state-default ui-priority-primary ui-corner-all\u0027 data-handler=\u0027hide\u0027 data-event=\u0027click\u0027\u003e\" +\n\t\t\tthis._get(inst, \"closeText\") + \"\u003c/button\u003e\" : \"\");\n\n\t\tbuttonPanel = (showButtonPanel) ? \"\u003cdiv class=\u0027ui-datepicker-buttonpane ui-widget-content\u0027\u003e\" + (isRTL ? controls : \"\") +\n\t\t\t(this._isInRange(inst, gotoDate) ? \"\u003cbutton type=\u0027button\u0027 class=\u0027ui-datepicker-current ui-state-default ui-priority-secondary ui-corner-all\u0027 data-handler=\u0027today\u0027 data-event=\u0027click\u0027\" +\n\t\t\t\"\u003e\" + currentText + \"\u003c/button\u003e\" : \"\") + (isRTL ? \"\" : controls) + \"\u003c/div\u003e\" : \"\";\n\n\t\tfirstDay = parseInt(this._get(inst, \"firstDay\"),10);\n\t\tfirstDay = (isNaN(firstDay) ? 0 : firstDay);\n\n\t\tshowWeek = this._get(inst, \"showWeek\");\n\t\tdayNames = this._get(inst, \"dayNames\");\n\t\tdayNamesMin = this._get(inst, \"dayNamesMin\");\n\t\tmonthNames = this._get(inst, \"monthNames\");\n\t\tmonthNamesShort = this._get(inst, \"monthNamesShort\");\n\t\tbeforeShowDay = this._get(inst, \"beforeShowDay\");\n\t\tshowOtherMonths = this._get(inst, \"showOtherMonths\");\n\t\tselectOtherMonths = this._get(inst, \"selectOtherMonths\");\n\t\tdefaultDate = this._getDefaultDate(inst);\n\t\thtml = \"\";\n\t\tdow;\n\t\tfor (row = 0; row \u003c numMonths[0]; row++) {\n\t\t\tgroup = \"\";\n\t\t\tthis.maxRows = 4;\n\t\t\tfor (col = 0; col \u003c numMonths[1]; col++) {\n\t\t\t\tselectedDate = this._daylightSavingAdjust(new Date(drawYear, drawMonth, inst.selectedDay));\n\t\t\t\tcornerClass = \" ui-corner-all\";\n\t\t\t\tcalender = \"\";\n\t\t\t\tif (isMultiMonth) {\n\t\t\t\t\tcalender += \"\u003cdiv class=\u0027ui-datepicker-group\";\n\t\t\t\t\tif (numMonths[1] \u003e 1) {\n\t\t\t\t\t\tswitch (col) {\n\t\t\t\t\t\t\tcase 0: calender += \" ui-datepicker-group-first\";\n\t\t\t\t\t\t\t\tcornerClass = \" ui-corner-\" + (isRTL ? \"right\" : \"left\"); break;\n\t\t\t\t\t\t\tcase numMonths[1]-1: calender += \" ui-datepicker-group-last\";\n\t\t\t\t\t\t\t\tcornerClass = \" ui-corner-\" + (isRTL ? \"left\" : \"right\"); break;\n\t\t\t\t\t\t\tdefault: calender += \" ui-datepicker-group-middle\"; cornerClass = \"\"; break;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tcalender += \"\u0027\u003e\";\n\t\t\t\t}\n\t\t\t\tcalender += \"\u003cdiv class=\u0027ui-datepicker-header ui-widget-header ui-helper-clearfix\" + cornerClass + \"\u0027\u003e\" +\n\t\t\t\t\t(/all|left/.test(cornerClass) \u0026\u0026 row === 0 ? (isRTL ? next : prev) : \"\") +\n\t\t\t\t\t(/all|right/.test(cornerClass) \u0026\u0026 row === 0 ? (isRTL ? prev : next) : \"\") +\n\t\t\t\t\tthis._generateMonthYearHeader(inst, drawMonth, drawYear, minDate, maxDate,\n\t\t\t\t\trow \u003e 0 || col \u003e 0, monthNames, monthNamesShort) + // draw month headers\n\t\t\t\t\t\"\u003c/div\u003e\u003ctable class=\u0027ui-datepicker-calendar\u0027\u003e\u003cthead\u003e\" +\n\t\t\t\t\t\"\u003ctr\u003e\";\n\t\t\t\tthead = (showWeek ? \"\u003cth class=\u0027ui-datepicker-week-col\u0027\u003e\" + this._get(inst, \"weekHeader\") + \"\u003c/th\u003e\" : \"\");\n\t\t\t\tfor (dow = 0; dow \u003c 7; dow++) { // days of the week\n\t\t\t\t\tday = (dow + firstDay) % 7;\n\t\t\t\t\tthead += \"\u003cth\" + ((dow + firstDay + 6) % 7 \u003e= 5 ? \" class=\u0027ui-datepicker-week-end\u0027\" : \"\") + \"\u003e\" +\n\t\t\t\t\t\t\"\u003cspan title=\u0027\" + dayNames[day] + \"\u0027\u003e\" + dayNamesMin[day] + \"\u003c/span\u003e\u003c/th\u003e\";\n\t\t\t\t}\n\t\t\t\tcalender += thead + \"\u003c/tr\u003e\u003c/thead\u003e\u003ctbody\u003e\";\n\t\t\t\tdaysInMonth = this._getDaysInMonth(drawYear, drawMonth);\n\t\t\t\tif (drawYear === inst.selectedYear \u0026\u0026 drawMonth === inst.selectedMonth) {\n\t\t\t\t\tinst.selectedDay = Math.min(inst.selectedDay, daysInMonth);\n\t\t\t\t}\n\t\t\t\tleadDays = (this._getFirstDayOfMonth(drawYear, drawMonth) - firstDay + 7) % 7;\n\t\t\t\tcurRows = Math.ceil((leadDays + daysInMonth) / 7); // calculate the number of rows to generate\n\t\t\t\tnumRows = (isMultiMonth ? this.maxRows \u003e curRows ? this.maxRows : curRows : curRows); //If multiple months, use the higher number of rows (see #7043)\n\t\t\t\tthis.maxRows = numRows;\n\t\t\t\tprintDate = this._daylightSavingAdjust(new Date(drawYear, drawMonth, 1 - leadDays));\n\t\t\t\tfor (dRow = 0; dRow \u003c numRows; dRow++) { // create date picker rows\n\t\t\t\t\tcalender += \"\u003ctr\u003e\";\n\t\t\t\t\ttbody = (!showWeek ? \"\" : \"\u003ctd class=\u0027ui-datepicker-week-col\u0027\u003e\" +\n\t\t\t\t\t\tthis._get(inst, \"calculateWeek\")(printDate) + \"\u003c/td\u003e\");\n\t\t\t\t\tfor (dow = 0; dow \u003c 7; dow++) { // create date picker days\n\t\t\t\t\t\tdaySettings = (beforeShowDay ?\n\t\t\t\t\t\t\tbeforeShowDay.apply((inst.input ? inst.input[0] : null), [printDate]) : [true, \"\"]);\n\t\t\t\t\t\totherMonth = (printDate.getMonth() !== drawMonth);\n\t\t\t\t\t\tunselectable = (otherMonth \u0026\u0026 !selectOtherMonths) || !daySettings[0] ||\n\t\t\t\t\t\t\t(minDate \u0026\u0026 printDate \u003c minDate) || (maxDate \u0026\u0026 printDate \u003e maxDate);\n\t\t\t\t\t\ttbody += \"\u003ctd class=\u0027\" +\n\t\t\t\t\t\t\t((dow + firstDay + 6) % 7 \u003e= 5 ? \" ui-datepicker-week-end\" : \"\") + // highlight weekends\n\t\t\t\t\t\t\t(otherMonth ? \" ui-datepicker-other-month\" : \"\") + // highlight days from other months\n\t\t\t\t\t\t\t((printDate.getTime() === selectedDate.getTime() \u0026\u0026 drawMonth === inst.selectedMonth \u0026\u0026 inst._keyEvent) || // user pressed key\n\t\t\t\t\t\t\t(defaultDate.getTime() === printDate.getTime() \u0026\u0026 defaultDate.getTime() === selectedDate.getTime()) ?\n\t\t\t\t\t\t\t// or defaultDate is current printedDate and defaultDate is selectedDate\n\t\t\t\t\t\t\t\" \" + this._dayOverClass : \"\") + // highlight selected day\n\t\t\t\t\t\t\t(unselectable ? \" \" + this._unselectableClass + \" ui-state-disabled\": \"\") + // highlight unselectable days\n\t\t\t\t\t\t\t(otherMonth \u0026\u0026 !showOtherMonths ? \"\" : \" \" + daySettings[1] + // highlight custom dates\n\t\t\t\t\t\t\t(printDate.getTime() === currentDate.getTime() ? \" \" + this._currentClass : \"\") + // highlight selected day\n\t\t\t\t\t\t\t(printDate.getTime() === today.getTime() ? \" ui-datepicker-today\" : \"\")) + \"\u0027\" + // highlight today (if different)\n\t\t\t\t\t\t\t((!otherMonth || showOtherMonths) \u0026\u0026 daySettings[2] ? \" title=\u0027\" + daySettings[2].replace(/\u0027/g, \"\u0026#39;\") + \"\u0027\" : \"\") + // cell title\n\t\t\t\t\t\t\t(unselectable ? \"\" : \" data-handler=\u0027selectDay\u0027 data-event=\u0027click\u0027 data-month=\u0027\" + printDate.getMonth() + \"\u0027 data-year=\u0027\" + printDate.getFullYear() + \"\u0027\") + \"\u003e\" + // actions\n\t\t\t\t\t\t\t(otherMonth \u0026\u0026 !showOtherMonths ? \"\u0026#xa0;\" : // display for other months\n\t\t\t\t\t\t\t(unselectable ? \"\u003cspan class=\u0027ui-state-default\u0027\u003e\" + printDate.getDate() + \"\u003c/span\u003e\" : \"\u003ca class=\u0027ui-state-default\" +\n\t\t\t\t\t\t\t(printDate.getTime() === today.getTime() ? \" ui-state-highlight\" : \"\") +\n\t\t\t\t\t\t\t(printDate.getTime() === currentDate.getTime() ? \" ui-state-active\" : \"\") + // highlight selected day\n\t\t\t\t\t\t\t(otherMonth ? \" ui-priority-secondary\" : \"\") + // distinguish dates from other months\n\t\t\t\t\t\t\t\"\u0027 href=\u0027#\u0027\u003e\" + printDate.getDate() + \"\u003c/a\u003e\")) + \"\u003c/td\u003e\"; // display selectable date\n\t\t\t\t\t\tprintDate.setDate(printDate.getDate() + 1);\n\t\t\t\t\t\tprintDate = this._daylightSavingAdjust(printDate);\n\t\t\t\t\t}\n\t\t\t\t\tcalender += tbody + \"\u003c/tr\u003e\";\n\t\t\t\t}\n\t\t\t\tdrawMonth++;\n\t\t\t\tif (drawMonth \u003e 11) {\n\t\t\t\t\tdrawMonth = 0;\n\t\t\t\t\tdrawYear++;\n\t\t\t\t}\n\t\t\t\tcalender += \"\u003c/tbody\u003e\u003c/table\u003e\" + (isMultiMonth ? \"\u003c/div\u003e\" +\n\t\t\t\t\t\t\t((numMonths[0] \u003e 0 \u0026\u0026 col === numMonths[1]-1) ? \"\u003cdiv class=\u0027ui-datepicker-row-break\u0027\u003e\u003c/div\u003e\" : \"\") : \"\");\n\t\t\t\tgroup += calender;\n\t\t\t}\n\t\t\thtml += group;\n\t\t}\n\t\thtml += buttonPanel;\n\t\tinst._keyEvent = false;\n\t\treturn html;\n\t},\n\n\t/* Generate the month and year header. */\n\t_generateMonthYearHeader: function(inst, drawMonth, drawYear, minDate, maxDate,\n\t\t\tsecondary, monthNames, monthNamesShort) {\n\n\t\tvar inMinYear, inMaxYear, month, years, thisYear, determineYear, year, endYear,\n\t\t\tchangeMonth = this._get(inst, \"changeMonth\"),\n\t\t\tchangeYear = this._get(inst, \"changeYear\"),\n\t\t\tshowMonthAfterYear = this._get(inst, \"showMonthAfterYear\"),\n\t\t\thtml = \"\u003cdiv class=\u0027ui-datepicker-title\u0027\u003e\",\n\t\t\tmonthHtml = \"\";\n\n\t\t// month selection\n\t\tif (secondary || !changeMonth) {\n\t\t\tmonthHtml += \"\u003cspan class=\u0027ui-datepicker-month\u0027\u003e\" + monthNames[drawMonth] + \"\u003c/span\u003e\";\n\t\t} else {\n\t\t\tinMinYear = (minDate \u0026\u0026 minDate.getFullYear() === drawYear);\n\t\t\tinMaxYear = (maxDate \u0026\u0026 maxDate.getFullYear() === drawYear);\n\t\t\tmonthHtml += \"\u003cselect class=\u0027ui-datepicker-month\u0027 data-handler=\u0027selectMonth\u0027 data-event=\u0027change\u0027\u003e\";\n\t\t\tfor ( month = 0; month \u003c 12; month++) {\n\t\t\t\tif ((!inMinYear || month \u003e= minDate.getMonth()) \u0026\u0026 (!inMaxYear || month \u003c= maxDate.getMonth())) {\n\t\t\t\t\tmonthHtml += \"\u003coption value=\u0027\" + month + \"\u0027\" +\n\t\t\t\t\t\t(month === drawMonth ? \" selected=\u0027selected\u0027\" : \"\") +\n\t\t\t\t\t\t\"\u003e\" + monthNamesShort[month] + \"\u003c/option\u003e\";\n\t\t\t\t}\n\t\t\t}\n\t\t\tmonthHtml += \"\u003c/select\u003e\";\n\t\t}\n\n\t\tif (!showMonthAfterYear) {\n\t\t\thtml += monthHtml + (secondary || !(changeMonth \u0026\u0026 changeYear) ? \"\u0026#xa0;\" : \"\");\n\t\t}\n\n\t\t// year selection\n\t\tif ( !inst.yearshtml ) {\n\t\t\tinst.yearshtml = \"\";\n\t\t\tif (secondary || !changeYear) {\n\t\t\t\thtml += \"\u003cspan class=\u0027ui-datepicker-year\u0027\u003e\" + drawYear + \"\u003c/span\u003e\";\n\t\t\t} else {\n\t\t\t\t// determine range of years to display\n\t\t\t\tyears = this._get(inst, \"yearRange\").split(\":\");\n\t\t\t\tthisYear = new Date().getFullYear();\n\t\t\t\tdetermineYear = function(value) {\n\t\t\t\t\tvar year = (value.match(/c[+\\-].*/) ? drawYear + parseInt(value.substring(1), 10) :\n\t\t\t\t\t\t(value.match(/[+\\-].*/) ? thisYear + parseInt(value, 10) :\n\t\t\t\t\t\tparseInt(value, 10)));\n\t\t\t\t\treturn (isNaN(year) ? thisYear : year);\n\t\t\t\t};\n\t\t\t\tyear = determineYear(years[0]);\n\t\t\t\tendYear = Math.max(year, determineYear(years[1] || \"\"));\n\t\t\t\tyear = (minDate ? Math.max(year, minDate.getFullYear()) : year);\n\t\t\t\tendYear = (maxDate ? Math.min(endYear, maxDate.getFullYear()) : endYear);\n\t\t\t\tinst.yearshtml += \"\u003cselect class=\u0027ui-datepicker-year\u0027 data-handler=\u0027selectYear\u0027 data-event=\u0027change\u0027\u003e\";\n\t\t\t\tfor (; year \u003c= endYear; year++) {\n\t\t\t\t\tinst.yearshtml += \"\u003coption value=\u0027\" + year + \"\u0027\" +\n\t\t\t\t\t\t(year === drawYear ? \" selected=\u0027selected\u0027\" : \"\") +\n\t\t\t\t\t\t\"\u003e\" + year + \"\u003c/option\u003e\";\n\t\t\t\t}\n\t\t\t\tinst.yearshtml += \"\u003c/select\u003e\";\n\n\t\t\t\thtml += inst.yearshtml;\n\t\t\t\tinst.yearshtml = null;\n\t\t\t}\n\t\t}\n\n\t\thtml += this._get(inst, \"yearSuffix\");\n\t\tif (showMonthAfterYear) {\n\t\t\thtml += (secondary || !(changeMonth \u0026\u0026 changeYear) ? \"\u0026#xa0;\" : \"\") + monthHtml;\n\t\t}\n\t\thtml += \"\u003c/div\u003e\"; // Close datepicker_header\n\t\treturn html;\n\t},\n\n\t/* Adjust one of the date sub-fields. */\n\t_adjustInstDate: function(inst, offset, period) {\n\t\tvar year = inst.drawYear + (period === \"Y\" ? offset : 0),\n\t\t\tmonth = inst.drawMonth + (period === \"M\" ? offset : 0),\n\t\t\tday = Math.min(inst.selectedDay, this._getDaysInMonth(year, month)) + (period === \"D\" ? offset : 0),\n\t\t\tdate = this._restrictMinMax(inst, this._daylightSavingAdjust(new Date(year, month, day)));\n\n\t\tinst.selectedDay = date.getDate();\n\t\tinst.drawMonth = inst.selectedMonth = date.getMonth();\n\t\tinst.drawYear = inst.selectedYear = date.getFullYear();\n\t\tif (period === \"M\" || period === \"Y\") {\n\t\t\tthis._notifyChange(inst);\n\t\t}\n\t},\n\n\t/* Ensure a date is within any min/max bounds. */\n\t_restrictMinMax: function(inst, date) {\n\t\tvar minDate = this._getMinMaxDate(inst, \"min\"),\n\t\t\tmaxDate = this._getMinMaxDate(inst, \"max\"),\n\t\t\tnewDate = (minDate \u0026\u0026 date \u003c minDate ? minDate : date);\n\t\treturn (maxDate \u0026\u0026 newDate \u003e maxDate ? maxDate : newDate);\n\t},\n\n\t/* Notify change of month/year. */\n\t_notifyChange: function(inst) {\n\t\tvar onChange = this._get(inst, \"onChangeMonthYear\");\n\t\tif (onChange) {\n\t\t\tonChange.apply((inst.input ? inst.input[0] : null),\n\t\t\t\t[inst.selectedYear, inst.selectedMonth + 1, inst]);\n\t\t}\n\t},\n\n\t/* Determine the number of months to show. */\n\t_getNumberOfMonths: function(inst) {\n\t\tvar numMonths = this._get(inst, \"numberOfMonths\");\n\t\treturn (numMonths == null ? [1, 1] : (typeof numMonths === \"number\" ? [1, numMonths] : numMonths));\n\t},\n\n\t/* Determine the current maximum date - ensure no time components are set. */\n\t_getMinMaxDate: function(inst, minMax) {\n\t\treturn this._determineDate(inst, this._get(inst, minMax + \"Date\"), null);\n\t},\n\n\t/* Find the number of days in a given month. */\n\t_getDaysInMonth: function(year, month) {\n\t\treturn 32 - this._daylightSavingAdjust(new Date(year, month, 32)).getDate();\n\t},\n\n\t/* Find the day of the week of the first of a month. */\n\t_getFirstDayOfMonth: function(year, month) {\n\t\treturn new Date(year, month, 1).getDay();\n\t},\n\n\t/* Determines if we should allow a \"next/prev\" month display change. */\n\t_canAdjustMonth: function(inst, offset, curYear, curMonth) {\n\t\tvar numMonths = this._getNumberOfMonths(inst),\n\t\t\tdate = this._daylightSavingAdjust(new Date(curYear,\n\t\t\tcurMonth + (offset \u003c 0 ? offset : numMonths[0] * numMonths[1]), 1));\n\n\t\tif (offset \u003c 0) {\n\t\t\tdate.setDate(this._getDaysInMonth(date.getFullYear(), date.getMonth()));\n\t\t}\n\t\treturn this._isInRange(inst, date);\n\t},\n\n\t/* Is the given date in the accepted range? */\n\t_isInRange: function(inst, date) {\n\t\tvar yearSplit, currentYear,\n\t\t\tminDate = this._getMinMaxDate(inst, \"min\"),\n\t\t\tmaxDate = this._getMinMaxDate(inst, \"max\"),\n\t\t\tminYear = null,\n\t\t\tmaxYear = null,\n\t\t\tyears = this._get(inst, \"yearRange\");\n\t\t\tif (years){\n\t\t\t\tyearSplit = years.split(\":\");\n\t\t\t\tcurrentYear = new Date().getFullYear();\n\t\t\t\tminYear = parseInt(yearSplit[0], 10);\n\t\t\t\tmaxYear = parseInt(yearSplit[1], 10);\n\t\t\t\tif ( yearSplit[0].match(/[+\\-].*/) ) {\n\t\t\t\t\tminYear += currentYear;\n\t\t\t\t}\n\t\t\t\tif ( yearSplit[1].match(/[+\\-].*/) ) {\n\t\t\t\t\tmaxYear += currentYear;\n\t\t\t\t}\n\t\t\t}\n\n\t\treturn ((!minDate || date.getTime() \u003e= minDate.getTime()) \u0026\u0026\n\t\t\t(!maxDate || date.getTime() \u003c= maxDate.getTime()) \u0026\u0026\n\t\t\t(!minYear || date.getFullYear() \u003e= minYear) \u0026\u0026\n\t\t\t(!maxYear || date.getFullYear() \u003c= maxYear));\n\t},\n\n\t/* Provide the configuration settings for formatting/parsing. */\n\t_getFormatConfig: function(inst) {\n\t\tvar shortYearCutoff = this._get(inst, \"shortYearCutoff\");\n\t\tshortYearCutoff = (typeof shortYearCutoff !== \"string\" ? shortYearCutoff :\n\t\t\tnew Date().getFullYear() % 100 + parseInt(shortYearCutoff, 10));\n\t\treturn {shortYearCutoff: shortYearCutoff,\n\t\t\tdayNamesShort: this._get(inst, \"dayNamesShort\"), dayNames: this._get(inst, \"dayNames\"),\n\t\t\tmonthNamesShort: this._get(inst, \"monthNamesShort\"), monthNames: this._get(inst, \"monthNames\")};\n\t},\n\n\t/* Format the given date for display. */\n\t_formatDate: function(inst, day, month, year) {\n\t\tif (!day) {\n\t\t\tinst.currentDay = inst.selectedDay;\n\t\t\tinst.currentMonth = inst.selectedMonth;\n\t\t\tinst.currentYear = inst.selectedYear;\n\t\t}\n\t\tvar date = (day ? (typeof day === \"object\" ? day :\n\t\t\tthis._daylightSavingAdjust(new Date(year, month, day))) :\n\t\t\tthis._daylightSavingAdjust(new Date(inst.currentYear, inst.currentMonth, inst.currentDay)));\n\t\treturn this.formatDate(this._get(inst, \"dateFormat\"), date, this._getFormatConfig(inst));\n\t}\n});\n\n/*\n * Bind hover events for datepicker elements.\n * Done via delegate so the binding only occurs once in the lifetime of the parent div.\n * Global instActive, set by _updateDatepicker allows the handlers to find their way back to the active picker.\n */\nfunction bindHover(dpDiv) {\n\tvar selector = \"button, .ui-datepicker-prev, .ui-datepicker-next, .ui-datepicker-calendar td a\";\n\treturn dpDiv.delegate(selector, \"mouseout\", function() {\n\t\t\t$(this).removeClass(\"ui-state-hover\");\n\t\t\tif (this.className.indexOf(\"ui-datepicker-prev\") !== -1) {\n\t\t\t\t$(this).removeClass(\"ui-datepicker-prev-hover\");\n\t\t\t}\n\t\t\tif (this.className.indexOf(\"ui-datepicker-next\") !== -1) {\n\t\t\t\t$(this).removeClass(\"ui-datepicker-next-hover\");\n\t\t\t}\n\t\t})\n\t\t.delegate(selector, \"mouseover\", function(){\n\t\t\tif (!$.datepicker._isDisabledDatepicker( instActive.inline ? dpDiv.parent()[0] : instActive.input[0])) {\n\t\t\t\t$(this).parents(\".ui-datepicker-calendar\").find(\"a\").removeClass(\"ui-state-hover\");\n\t\t\t\t$(this).addClass(\"ui-state-hover\");\n\t\t\t\tif (this.className.indexOf(\"ui-datepicker-prev\") !== -1) {\n\t\t\t\t\t$(this).addClass(\"ui-datepicker-prev-hover\");\n\t\t\t\t}\n\t\t\t\tif (this.className.indexOf(\"ui-datepicker-next\") !== -1) {\n\t\t\t\t\t$(this).addClass(\"ui-datepicker-next-hover\");\n\t\t\t\t}\n\t\t\t}\n\t\t});\n}\n\n/* jQuery extend now ignores nulls! */\nfunction extendRemove(target, props) {\n\t$.extend(target, props);\n\tfor (var name in props) {\n\t\tif (props[name] == null) {\n\t\t\ttarget[name] = props[name];\n\t\t}\n\t}\n\treturn target;\n}\n\n/* Invoke the datepicker functionality.\n @param options string - a command, optionally followed by additional parameters or\n\t\t\t\t\tObject - settings for attaching new datepicker functionality\n @return jQuery object */\n$.fn.datepicker = function(options){\n\n\t/* Verify an empty collection wasn\u0027t passed - Fixes #6976 */\n\tif ( !this.length ) {\n\t\treturn this;\n\t}\n\n\t/* Initialise the date picker. */\n\tif (!$.datepicker.initialized) {\n\t\t$(document).mousedown($.datepicker._checkExternalClick);\n\t\t$.datepicker.initialized = true;\n\t}\n\n\t/* Append datepicker main container to body if not exist. */\n\tif ($(\"#\"+$.datepicker._mainDivId).length === 0) {\n\t\t$(\"body\").append($.datepicker.dpDiv);\n\t}\n\n\tvar otherArgs = Array.prototype.slice.call(arguments, 1);\n\tif (typeof options === \"string\" \u0026\u0026 (options === \"isDisabled\" || options === \"getDate\" || options === \"widget\")) {\n\t\treturn $.datepicker[\"_\" + options + \"Datepicker\"].\n\t\t\tapply($.datepicker, [this[0]].concat(otherArgs));\n\t}\n\tif (options === \"option\" \u0026\u0026 arguments.length === 2 \u0026\u0026 typeof arguments[1] === \"string\") {\n\t\treturn $.datepicker[\"_\" + options + \"Datepicker\"].\n\t\t\tapply($.datepicker, [this[0]].concat(otherArgs));\n\t}\n\treturn this.each(function() {\n\t\ttypeof options === \"string\" ?\n\t\t\t$.datepicker[\"_\" + options + \"Datepicker\"].\n\t\t\t\tapply($.datepicker, [this].concat(otherArgs)) :\n\t\t\t$.datepicker._attachDatepicker(this, options);\n\t});\n};\n\n$.datepicker = new Datepicker(); // singleton instance\n$.datepicker.initialized = false;\n$.datepicker.uuid = new Date().getTime();\n$.datepicker.version = \"1.10.2\";\n\n// Workaround for #4055\n// Add another global to avoid noConflict issues with inline event handlers\nwindow[\"DP_jQuery_\" + dpuuid] = $;\n\n})(jQuery);\n\n(function( $, undefined ) {\n\nvar sizeRelatedOptions = {\n\t\tbuttons: true,\n\t\theight: true,\n\t\tmaxHeight: true,\n\t\tmaxWidth: true,\n\t\tminHeight: true,\n\t\tminWidth: true,\n\t\twidth: true\n\t},\n\tresizableRelatedOptions = {\n\t\tmaxHeight: true,\n\t\tmaxWidth: true,\n\t\tminHeight: true,\n\t\tminWidth: true\n\t};\n\n$.widget( \"ui.dialog\", {\n\tversion: \"1.10.2\",\n\toptions: {\n\t\tappendTo: \"body\",\n\t\tautoOpen: true,\n\t\tbuttons: [],\n\t\tcloseOnEscape: true,\n\t\tcloseText: \"close\",\n\t\tdialogClass: \"\",\n\t\tdraggable: true,\n\t\thide: null,\n\t\theight: \"auto\",\n\t\tmaxHeight: null,\n\t\tmaxWidth: null,\n\t\tminHeight: 150,\n\t\tminWidth: 150,\n\t\tmodal: false,\n\t\tposition: {\n\t\t\tmy: \"center\",\n\t\t\tat: \"center\",\n\t\t\tof: window,\n\t\t\tcollision: \"fit\",\n\t\t\t// Ensure the titlebar is always visible\n\t\t\tusing: function( pos ) {\n\t\t\t\tvar topOffset = $( this ).css( pos ).offset().top;\n\t\t\t\tif ( topOffset \u003c 0 ) {\n\t\t\t\t\t$( this ).css( \"top\", pos.top - topOffset );\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t\tresizable: true,\n\t\tshow: null,\n\t\ttitle: null,\n\t\twidth: 300,\n\n\t\t// callbacks\n\t\tbeforeClose: null,\n\t\tclose: null,\n\t\tdrag: null,\n\t\tdragStart: null,\n\t\tdragStop: null,\n\t\tfocus: null,\n\t\topen: null,\n\t\tresize: null,\n\t\tresizeStart: null,\n\t\tresizeStop: null\n\t},\n\n\t_create: function() {\n\t\tthis.originalCss = {\n\t\t\tdisplay: this.element[0].style.display,\n\t\t\twidth: this.element[0].style.width,\n\t\t\tminHeight: this.element[0].style.minHeight,\n\t\t\tmaxHeight: this.element[0].style.maxHeight,\n\t\t\theight: this.element[0].style.height\n\t\t};\n\t\tthis.originalPosition = {\n\t\t\tparent: this.element.parent(),\n\t\t\tindex: this.element.parent().children().index( this.element )\n\t\t};\n\t\tthis.originalTitle = this.element.attr(\"title\");\n\t\tthis.options.title = this.options.title || this.originalTitle;\n\n\t\tthis._createWrapper();\n\n\t\tthis.element\n\t\t\t.show()\n\t\t\t.removeAttr(\"title\")\n\t\t\t.addClass(\"ui-dialog-content ui-widget-content\")\n\t\t\t.appendTo( this.uiDialog );\n\n\t\tthis._createTitlebar();\n\t\tthis._createButtonPane();\n\n\t\tif ( this.options.draggable \u0026\u0026 $.fn.draggable ) {\n\t\t\tthis._makeDraggable();\n\t\t}\n\t\tif ( this.options.resizable \u0026\u0026 $.fn.resizable ) {\n\t\t\tthis._makeResizable();\n\t\t}\n\n\t\tthis._isOpen = false;\n\t},\n\n\t_init: function() {\n\t\tif ( this.options.autoOpen ) {\n\t\t\tthis.open();\n\t\t}\n\t},\n\n\t_appendTo: function() {\n\t\tvar element = this.options.appendTo;\n\t\tif ( element \u0026\u0026 (element.jquery || element.nodeType) ) {\n\t\t\treturn $( element );\n\t\t}\n\t\treturn this.document.find( element || \"body\" ).eq( 0 );\n\t},\n\n\t_destroy: function() {\n\t\tvar next,\n\t\t\toriginalPosition = this.originalPosition;\n\n\t\tthis._destroyOverlay();\n\n\t\tthis.element\n\t\t\t.removeUniqueId()\n\t\t\t.removeClass(\"ui-dialog-content ui-widget-content\")\n\t\t\t.css( this.originalCss )\n\t\t\t// Without detaching first, the following becomes really slow\n\t\t\t.detach();\n\n\t\tthis.uiDialog.stop( true, true ).remove();\n\n\t\tif ( this.originalTitle ) {\n\t\t\tthis.element.attr( \"title\", this.originalTitle );\n\t\t}\n\n\t\tnext = originalPosition.parent.children().eq( originalPosition.index );\n\t\t// Don\u0027t try to place the dialog next to itself (#8613)\n\t\tif ( next.length \u0026\u0026 next[0] !== this.element[0] ) {\n\t\t\tnext.before( this.element );\n\t\t} else {\n\t\t\toriginalPosition.parent.append( this.element );\n\t\t}\n\t},\n\n\twidget: function() {\n\t\treturn this.uiDialog;\n\t},\n\n\tdisable: $.noop,\n\tenable: $.noop,\n\n\tclose: function( event ) {\n\t\tvar that = this;\n\n\t\tif ( !this._isOpen || this._trigger( \"beforeClose\", event ) === false ) {\n\t\t\treturn;\n\t\t}\n\n\t\tthis._isOpen = false;\n\t\tthis._destroyOverlay();\n\n\t\tif ( !this.opener.filter(\":focusable\").focus().length ) {\n\t\t\t// Hiding a focused element doesn\u0027t trigger blur in WebKit\n\t\t\t// so in case we have nothing to focus on, explicitly blur the active element\n\t\t\t// https://bugs.webkit.org/show_bug.cgi?id=47182\n\t\t\t$( this.document[0].activeElement ).blur();\n\t\t}\n\n\t\tthis._hide( this.uiDialog, this.options.hide, function() {\n\t\t\tthat._trigger( \"close\", event );\n\t\t});\n\t},\n\n\tisOpen: function() {\n\t\treturn this._isOpen;\n\t},\n\n\tmoveToTop: function() {\n\t\tthis._moveToTop();\n\t},\n\n\t_moveToTop: function( event, silent ) {\n\t\tvar moved = !!this.uiDialog.nextAll(\":visible\").insertBefore( this.uiDialog ).length;\n\t\tif ( moved \u0026\u0026 !silent ) {\n\t\t\tthis._trigger( \"focus\", event );\n\t\t}\n\t\treturn moved;\n\t},\n\n\topen: function() {\n\t\tvar that = this;\n\t\tif ( this._isOpen ) {\n\t\t\tif ( this._moveToTop() ) {\n\t\t\t\tthis._focusTabbable();\n\t\t\t}\n\t\t\treturn;\n\t\t}\n\n\t\tthis._isOpen = true;\n\t\tthis.opener = $( this.document[0].activeElement );\n\n\t\tthis._size();\n\t\tthis._position();\n\t\tthis._createOverlay();\n\t\tthis._moveToTop( null, true );\n\t\tthis._show( this.uiDialog, this.options.show, function() {\n\t\t\tthat._focusTabbable();\n\t\t\tthat._trigger(\"focus\");\n\t\t});\n\n\t\tthis._trigger(\"open\");\n\t},\n\n\t_focusTabbable: function() {\n\t\t// Set focus to the first match:\n\t\t// 1. First element inside the dialog matching [autofocus]\n\t\t// 2. Tabbable element inside the content element\n\t\t// 3. Tabbable element inside the buttonpane\n\t\t// 4. The close button\n\t\t// 5. The dialog itself\n\t\tvar hasFocus = this.element.find(\"[autofocus]\");\n\t\tif ( !hasFocus.length ) {\n\t\t\thasFocus = this.element.find(\":tabbable\");\n\t\t}\n\t\tif ( !hasFocus.length ) {\n\t\t\thasFocus = this.uiDialogButtonPane.find(\":tabbable\");\n\t\t}\n\t\tif ( !hasFocus.length ) {\n\t\t\thasFocus = this.uiDialogTitlebarClose.filter(\":tabbable\");\n\t\t}\n\t\tif ( !hasFocus.length ) {\n\t\t\thasFocus = this.uiDialog;\n\t\t}\n\t\thasFocus.eq( 0 ).focus();\n\t},\n\n\t_keepFocus: function( event ) {\n\t\tfunction checkFocus() {\n\t\t\tvar activeElement = this.document[0].activeElement,\n\t\t\t\tisActive = this.uiDialog[0] === activeElement ||\n\t\t\t\t\t$.contains( this.uiDialog[0], activeElement );\n\t\t\tif ( !isActive ) {\n\t\t\t\tthis._focusTabbable();\n\t\t\t}\n\t\t}\n\t\tevent.preventDefault();\n\t\tcheckFocus.call( this );\n\t\t// support: IE\n\t\t// IE \u003c= 8 doesn\u0027t prevent moving focus even with event.preventDefault()\n\t\t// so we check again later\n\t\tthis._delay( checkFocus );\n\t},\n\n\t_createWrapper: function() {\n\t\tthis.uiDialog = $(\"\u003cdiv\u003e\")\n\t\t\t.addClass( \"ui-dialog ui-widget ui-widget-content ui-corner-all ui-front \" +\n\t\t\t\tthis.options.dialogClass )\n\t\t\t.hide()\n\t\t\t.attr({\n\t\t\t\t// Setting tabIndex makes the div focusable\n\t\t\t\ttabIndex: -1,\n\t\t\t\trole: \"dialog\"\n\t\t\t})\n\t\t\t.appendTo( this._appendTo() );\n\n\t\tthis._on( this.uiDialog, {\n\t\t\tkeydown: function( event ) {\n\t\t\t\tif ( this.options.closeOnEscape \u0026\u0026 !event.isDefaultPrevented() \u0026\u0026 event.keyCode \u0026\u0026\n\t\t\t\t\t\tevent.keyCode === $.ui.keyCode.ESCAPE ) {\n\t\t\t\t\tevent.preventDefault();\n\t\t\t\t\tthis.close( event );\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\t// prevent tabbing out of dialogs\n\t\t\t\tif ( event.keyCode !== $.ui.keyCode.TAB ) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tvar tabbables = this.uiDialog.find(\":tabbable\"),\n\t\t\t\t\tfirst = tabbables.filter(\":first\"),\n\t\t\t\t\tlast = tabbables.filter(\":last\");\n\n\t\t\t\tif ( ( event.target === last[0] || event.target === this.uiDialog[0] ) \u0026\u0026 !event.shiftKey ) {\n\t\t\t\t\tfirst.focus( 1 );\n\t\t\t\t\tevent.preventDefault();\n\t\t\t\t} else if ( ( event.target === first[0] || event.target === this.uiDialog[0] ) \u0026\u0026 event.shiftKey ) {\n\t\t\t\t\tlast.focus( 1 );\n\t\t\t\t\tevent.preventDefault();\n\t\t\t\t}\n\t\t\t},\n\t\t\tmousedown: function( event ) {\n\t\t\t\tif ( this._moveToTop( event ) ) {\n\t\t\t\t\tthis._focusTabbable();\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\n\t\t// We assume that any existing aria-describedby attribute means\n\t\t// that the dialog content is marked up properly\n\t\t// otherwise we brute force the content as the description\n\t\tif ( !this.element.find(\"[aria-describedby]\").length ) {\n\t\t\tthis.uiDialog.attr({\n\t\t\t\t\"aria-describedby\": this.element.uniqueId().attr(\"id\")\n\t\t\t});\n\t\t}\n\t},\n\n\t_createTitlebar: function() {\n\t\tvar uiDialogTitle;\n\n\t\tthis.uiDialogTitlebar = $(\"\u003cdiv\u003e\")\n\t\t\t.addClass(\"ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix\")\n\t\t\t.prependTo( this.uiDialog );\n\t\tthis._on( this.uiDialogTitlebar, {\n\t\t\tmousedown: function( event ) {\n\t\t\t\t// Don\u0027t prevent click on close button (#8838)\n\t\t\t\t// Focusing a dialog that is partially scrolled out of view\n\t\t\t\t// causes the browser to scroll it into view, preventing the click event\n\t\t\t\tif ( !$( event.target ).closest(\".ui-dialog-titlebar-close\") ) {\n\t\t\t\t\t// Dialog isn\u0027t getting focus when dragging (#8063)\n\t\t\t\t\tthis.uiDialog.focus();\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\n\t\tthis.uiDialogTitlebarClose = $(\"\u003cbutton\u003e\u003c/button\u003e\")\n\t\t\t.button({\n\t\t\t\tlabel: this.options.closeText,\n\t\t\t\ticons: {\n\t\t\t\t\tprimary: \"ui-icon-closethick\"\n\t\t\t\t},\n\t\t\t\ttext: false\n\t\t\t})\n\t\t\t.addClass(\"ui-dialog-titlebar-close\")\n\t\t\t.appendTo( this.uiDialogTitlebar );\n\t\tthis._on( this.uiDialogTitlebarClose, {\n\t\t\tclick: function( event ) {\n\t\t\t\tevent.preventDefault();\n\t\t\t\tthis.close( event );\n\t\t\t}\n\t\t});\n\n\t\tuiDialogTitle = $(\"\u003cspan\u003e\")\n\t\t\t.uniqueId()\n\t\t\t.addClass(\"ui-dialog-title\")\n\t\t\t.prependTo( this.uiDialogTitlebar );\n\t\tthis._title( uiDialogTitle );\n\n\t\tthis.uiDialog.attr({\n\t\t\t\"aria-labelledby\": uiDialogTitle.attr(\"id\")\n\t\t});\n\t},\n\n\t_title: function( title ) {\n\t\tif ( !this.options.title ) {\n\t\t\ttitle.html(\"\u0026#160;\");\n\t\t}\n\t\ttitle.text( this.options.title );\n\t},\n\n\t_createButtonPane: function() {\n\t\tthis.uiDialogButtonPane = $(\"\u003cdiv\u003e\")\n\t\t\t.addClass(\"ui-dialog-buttonpane ui-widget-content ui-helper-clearfix\");\n\n\t\tthis.uiButtonSet = $(\"\u003cdiv\u003e\")\n\t\t\t.addClass(\"ui-dialog-buttonset\")\n\t\t\t.appendTo( this.uiDialogButtonPane );\n\n\t\tthis._createButtons();\n\t},\n\n\t_createButtons: function() {\n\t\tvar that = this,\n\t\t\tbuttons = this.options.buttons;\n\n\t\t// if we already have a button pane, remove it\n\t\tthis.uiDialogButtonPane.remove();\n\t\tthis.uiButtonSet.empty();\n\n\t\tif ( $.isEmptyObject( buttons ) || ($.isArray( buttons ) \u0026\u0026 !buttons.length) ) {\n\t\t\tthis.uiDialog.removeClass(\"ui-dialog-buttons\");\n\t\t\treturn;\n\t\t}\n\n\t\t$.each( buttons, function( name, props ) {\n\t\t\tvar click, buttonOptions;\n\t\t\tprops = $.isFunction( props ) ?\n\t\t\t\t{ click: props, text: name } :\n\t\t\t\tprops;\n\t\t\t// Default to a non-submitting button\n\t\t\tprops = $.extend( { type: \"button\" }, props );\n\t\t\t// Change the context for the click callback to be the main element\n\t\t\tclick = props.click;\n\t\t\tprops.click = function() {\n\t\t\t\tclick.apply( that.element[0], arguments );\n\t\t\t};\n\t\t\tbuttonOptions = {\n\t\t\t\ticons: props.icons,\n\t\t\t\ttext: props.showText\n\t\t\t};\n\t\t\tdelete props.icons;\n\t\t\tdelete props.showText;\n\t\t\t$( \"\u003cbutton\u003e\u003c/button\u003e\", props )\n\t\t\t\t.button( buttonOptions )\n\t\t\t\t.appendTo( that.uiButtonSet );\n\t\t});\n\t\tthis.uiDialog.addClass(\"ui-dialog-buttons\");\n\t\tthis.uiDialogButtonPane.appendTo( this.uiDialog );\n\t},\n\n\t_makeDraggable: function() {\n\t\tvar that = this,\n\t\t\toptions = this.options;\n\n\t\tfunction filteredUi( ui ) {\n\t\t\treturn {\n\t\t\t\tposition: ui.position,\n\t\t\t\toffset: ui.offset\n\t\t\t};\n\t\t}\n\n\t\tthis.uiDialog.draggable({\n\t\t\tcancel: \".ui-dialog-content, .ui-dialog-titlebar-close\",\n\t\t\thandle: \".ui-dialog-titlebar\",\n\t\t\tcontainment: \"document\",\n\t\t\tstart: function( event, ui ) {\n\t\t\t\t$( this ).addClass(\"ui-dialog-dragging\");\n\t\t\t\tthat._blockFrames();\n\t\t\t\tthat._trigger( \"dragStart\", event, filteredUi( ui ) );\n\t\t\t},\n\t\t\tdrag: function( event, ui ) {\n\t\t\t\tthat._trigger( \"drag\", event, filteredUi( ui ) );\n\t\t\t},\n\t\t\tstop: function( event, ui ) {\n\t\t\t\toptions.position = [\n\t\t\t\t\tui.position.left - that.document.scrollLeft(),\n\t\t\t\t\tui.position.top - that.document.scrollTop()\n\t\t\t\t];\n\t\t\t\t$( this ).removeClass(\"ui-dialog-dragging\");\n\t\t\t\tthat._unblockFrames();\n\t\t\t\tthat._trigger( \"dragStop\", event, filteredUi( ui ) );\n\t\t\t}\n\t\t});\n\t},\n\n\t_makeResizable: function() {\n\t\tvar that = this,\n\t\t\toptions = this.options,\n\t\t\thandles = options.resizable,\n\t\t\t// .ui-resizable has position: relative defined in the stylesheet\n\t\t\t// but dialogs have to use absolute or fixed positioning\n\t\t\tposition = this.uiDialog.css(\"position\"),\n\t\t\tresizeHandles = typeof handles === \"string\" ?\n\t\t\t\thandles\t:\n\t\t\t\t\"n,e,s,w,se,sw,ne,nw\";\n\n\t\tfunction filteredUi( ui ) {\n\t\t\treturn {\n\t\t\t\toriginalPosition: ui.originalPosition,\n\t\t\t\toriginalSize: ui.originalSize,\n\t\t\t\tposition: ui.position,\n\t\t\t\tsize: ui.size\n\t\t\t};\n\t\t}\n\n\t\tthis.uiDialog.resizable({\n\t\t\tcancel: \".ui-dialog-content\",\n\t\t\tcontainment: \"document\",\n\t\t\talsoResize: this.element,\n\t\t\tmaxWidth: options.maxWidth,\n\t\t\tmaxHeight: options.maxHeight,\n\t\t\tminWidth: options.minWidth,\n\t\t\tminHeight: this._minHeight(),\n\t\t\thandles: resizeHandles,\n\t\t\tstart: function( event, ui ) {\n\t\t\t\t$( this ).addClass(\"ui-dialog-resizing\");\n\t\t\t\tthat._blockFrames();\n\t\t\t\tthat._trigger( \"resizeStart\", event, filteredUi( ui ) );\n\t\t\t},\n\t\t\tresize: function( event, ui ) {\n\t\t\t\tthat._trigger( \"resize\", event, filteredUi( ui ) );\n\t\t\t},\n\t\t\tstop: function( event, ui ) {\n\t\t\t\toptions.height = $( this ).height();\n\t\t\t\toptions.width = $( this ).width();\n\t\t\t\t$( this ).removeClass(\"ui-dialog-resizing\");\n\t\t\t\tthat._unblockFrames();\n\t\t\t\tthat._trigger( \"resizeStop\", event, filteredUi( ui ) );\n\t\t\t}\n\t\t})\n\t\t.css( \"position\", position );\n\t},\n\n\t_minHeight: function() {\n\t\tvar options = this.options;\n\n\t\treturn options.height === \"auto\" ?\n\t\t\toptions.minHeight :\n\t\t\tMath.min( options.minHeight, options.height );\n\t},\n\n\t_position: function() {\n\t\t// Need to show the dialog to get the actual offset in the position plugin\n\t\tvar isVisible = this.uiDialog.is(\":visible\");\n\t\tif ( !isVisible ) {\n\t\t\tthis.uiDialog.show();\n\t\t}\n\t\tthis.uiDialog.position( this.options.position );\n\t\tif ( !isVisible ) {\n\t\t\tthis.uiDialog.hide();\n\t\t}\n\t},\n\n\t_setOptions: function( options ) {\n\t\tvar that = this,\n\t\t\tresize = false,\n\t\t\tresizableOptions = {};\n\n\t\t$.each( options, function( key, value ) {\n\t\t\tthat._setOption( key, value );\n\n\t\t\tif ( key in sizeRelatedOptions ) {\n\t\t\t\tresize = true;\n\t\t\t}\n\t\t\tif ( key in resizableRelatedOptions ) {\n\t\t\t\tresizableOptions[ key ] = value;\n\t\t\t}\n\t\t});\n\n\t\tif ( resize ) {\n\t\t\tthis._size();\n\t\t\tthis._position();\n\t\t}\n\t\tif ( this.uiDialog.is(\":data(ui-resizable)\") ) {\n\t\t\tthis.uiDialog.resizable( \"option\", resizableOptions );\n\t\t}\n\t},\n\n\t_setOption: function( key, value ) {\n\t\t/*jshint maxcomplexity:15*/\n\t\tvar isDraggable, isResizable,\n\t\t\tuiDialog = this.uiDialog;\n\n\t\tif ( key === \"dialogClass\" ) {\n\t\t\tuiDialog\n\t\t\t\t.removeClass( this.options.dialogClass )\n\t\t\t\t.addClass( value );\n\t\t}\n\n\t\tif ( key === \"disabled\" ) {\n\t\t\treturn;\n\t\t}\n\n\t\tthis._super( key, value );\n\n\t\tif ( key === \"appendTo\" ) {\n\t\t\tthis.uiDialog.appendTo( this._appendTo() );\n\t\t}\n\n\t\tif ( key === \"buttons\" ) {\n\t\t\tthis._createButtons();\n\t\t}\n\n\t\tif ( key === \"closeText\" ) {\n\t\t\tthis.uiDialogTitlebarClose.button({\n\t\t\t\t// Ensure that we always pass a string\n\t\t\t\tlabel: \"\" + value\n\t\t\t});\n\t\t}\n\n\t\tif ( key === \"draggable\" ) {\n\t\t\tisDraggable = uiDialog.is(\":data(ui-draggable)\");\n\t\t\tif ( isDraggable \u0026\u0026 !value ) {\n\t\t\t\tuiDialog.draggable(\"destroy\");\n\t\t\t}\n\n\t\t\tif ( !isDraggable \u0026\u0026 value ) {\n\t\t\t\tthis._makeDraggable();\n\t\t\t}\n\t\t}\n\n\t\tif ( key === \"position\" ) {\n\t\t\tthis._position();\n\t\t}\n\n\t\tif ( key === \"resizable\" ) {\n\t\t\t// currently resizable, becoming non-resizable\n\t\t\tisResizable = uiDialog.is(\":data(ui-resizable)\");\n\t\t\tif ( isResizable \u0026\u0026 !value ) {\n\t\t\t\tuiDialog.resizable(\"destroy\");\n\t\t\t}\n\n\t\t\t// currently resizable, changing handles\n\t\t\tif ( isResizable \u0026\u0026 typeof value === \"string\" ) {\n\t\t\t\tuiDialog.resizable( \"option\", \"handles\", value );\n\t\t\t}\n\n\t\t\t// currently non-resizable, becoming resizable\n\t\t\tif ( !isResizable \u0026\u0026 value !== false ) {\n\t\t\t\tthis._makeResizable();\n\t\t\t}\n\t\t}\n\n\t\tif ( key === \"title\" ) {\n\t\t\tthis._title( this.uiDialogTitlebar.find(\".ui-dialog-title\") );\n\t\t}\n\t},\n\n\t_size: function() {\n\t\t// If the user has resized the dialog, the .ui-dialog and .ui-dialog-content\n\t\t// divs will both have width and height set, so we need to reset them\n\t\tvar nonContentHeight, minContentHeight, maxContentHeight,\n\t\t\toptions = this.options;\n\n\t\t// Reset content sizing\n\t\tthis.element.show().css({\n\t\t\twidth: \"auto\",\n\t\t\tminHeight: 0,\n\t\t\tmaxHeight: \"none\",\n\t\t\theight: 0\n\t\t});\n\n\t\tif ( options.minWidth \u003e options.width ) {\n\t\t\toptions.width = options.minWidth;\n\t\t}\n\n\t\t// reset wrapper sizing\n\t\t// determine the height of all the non-content elements\n\t\tnonContentHeight = this.uiDialog.css({\n\t\t\t\theight: \"auto\",\n\t\t\t\twidth: options.width\n\t\t\t})\n\t\t\t.outerHeight();\n\t\tminContentHeight = Math.max( 0, options.minHeight - nonContentHeight );\n\t\tmaxContentHeight = typeof options.maxHeight === \"number\" ?\n\t\t\tMath.max( 0, options.maxHeight - nonContentHeight ) :\n\t\t\t\"none\";\n\n\t\tif ( options.height === \"auto\" ) {\n\t\t\tthis.element.css({\n\t\t\t\tminHeight: minContentHeight,\n\t\t\t\tmaxHeight: maxContentHeight,\n\t\t\t\theight: \"auto\"\n\t\t\t});\n\t\t} else {\n\t\t\tthis.element.height( Math.max( 0, options.height - nonContentHeight ) );\n\t\t}\n\n\t\tif (this.uiDialog.is(\":data(ui-resizable)\") ) {\n\t\t\tthis.uiDialog.resizable( \"option\", \"minHeight\", this._minHeight() );\n\t\t}\n\t},\n\n\t_blockFrames: function() {\n\t\tthis.iframeBlocks = this.document.find( \"iframe\" ).map(function() {\n\t\t\tvar iframe = $( this );\n\n\t\t\treturn $( \"\u003cdiv\u003e\" )\n\t\t\t\t.css({\n\t\t\t\t\tposition: \"absolute\",\n\t\t\t\t\twidth: iframe.outerWidth(),\n\t\t\t\t\theight: iframe.outerHeight()\n\t\t\t\t})\n\t\t\t\t.appendTo( iframe.parent() )\n\t\t\t\t.offset( iframe.offset() )[0];\n\t\t});\n\t},\n\n\t_unblockFrames: function() {\n\t\tif ( this.iframeBlocks ) {\n\t\t\tthis.iframeBlocks.remove();\n\t\t\tdelete this.iframeBlocks;\n\t\t}\n\t},\n\n\t_allowInteraction: function( event ) {\n\t\tif ( $( event.target ).closest(\".ui-dialog\").length ) {\n\t\t\treturn true;\n\t\t}\n\n\t\t// TODO: Remove hack when datepicker implements\n\t\t// the .ui-front logic (#8989)\n\t\treturn !!$( event.target ).closest(\".ui-datepicker\").length;\n\t},\n\n\t_createOverlay: function() {\n\t\tif ( !this.options.modal ) {\n\t\t\treturn;\n\t\t}\n\n\t\tvar that = this,\n\t\t\twidgetFullName = this.widgetFullName;\n\t\tif ( !$.ui.dialog.overlayInstances ) {\n\t\t\t// Prevent use of anchors and inputs.\n\t\t\t// We use a delay in case the overlay is created from an\n\t\t\t// event that we\u0027re going to be cancelling. (#2804)\n\t\t\tthis._delay(function() {\n\t\t\t\t// Handle .dialog().dialog(\"close\") (#4065)\n\t\t\t\tif ( $.ui.dialog.overlayInstances ) {\n\t\t\t\t\tthis.document.bind( \"focusin.dialog\", function( event ) {\n\t\t\t\t\t\tif ( !that._allowInteraction( event ) ) {\n\t\t\t\t\t\t\tevent.preventDefault();\n\t\t\t\t\t\t\t$(\".ui-dialog:visible:last .ui-dialog-content\")\n\t\t\t\t\t\t\t\t.data( widgetFullName )._focusTabbable();\n\t\t\t\t\t\t}\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\n\t\tthis.overlay = $(\"\u003cdiv\u003e\")\n\t\t\t.addClass(\"ui-widget-overlay ui-front\")\n\t\t\t.appendTo( this._appendTo() );\n\t\tthis._on( this.overlay, {\n\t\t\tmousedown: \"_keepFocus\"\n\t\t});\n\t\t$.ui.dialog.overlayInstances++;\n\t},\n\n\t_destroyOverlay: function() {\n\t\tif ( !this.options.modal ) {\n\t\t\treturn;\n\t\t}\n\n\t\tif ( this.overlay ) {\n\t\t\t$.ui.dialog.overlayInstances--;\n\n\t\t\tif ( !$.ui.dialog.overlayInstances ) {\n\t\t\t\tthis.document.unbind( \"focusin.dialog\" );\n\t\t\t}\n\t\t\tthis.overlay.remove();\n\t\t\tthis.overlay = null;\n\t\t}\n\t}\n});\n\n$.ui.dialog.overlayInstances = 0;\n\n// DEPRECATED\nif ( $.uiBackCompat !== false ) {\n\t// position option with array notation\n\t// just override with old implementation\n\t$.widget( \"ui.dialog\", $.ui.dialog, {\n\t\t_position: function() {\n\t\t\tvar position = this.options.position,\n\t\t\t\tmyAt = [],\n\t\t\t\toffset = [ 0, 0 ],\n\t\t\t\tisVisible;\n\n\t\t\tif ( position ) {\n\t\t\t\tif ( typeof position === \"string\" || (typeof position === \"object\" \u0026\u0026 \"0\" in position ) ) {\n\t\t\t\t\tmyAt = position.split ? position.split(\" \") : [ position[0], position[1] ];\n\t\t\t\t\tif ( myAt.length === 1 ) {\n\t\t\t\t\t\tmyAt[1] = myAt[0];\n\t\t\t\t\t}\n\n\t\t\t\t\t$.each( [ \"left\", \"top\" ], function( i, offsetPosition ) {\n\t\t\t\t\t\tif ( +myAt[ i ] === myAt[ i ] ) {\n\t\t\t\t\t\t\toffset[ i ] = myAt[ i ];\n\t\t\t\t\t\t\tmyAt[ i ] = offsetPosition;\n\t\t\t\t\t\t}\n\t\t\t\t\t});\n\n\t\t\t\t\tposition = {\n\t\t\t\t\t\tmy: myAt[0] + (offset[0] \u003c 0 ? offset[0] : \"+\" + offset[0]) + \" \" +\n\t\t\t\t\t\t\tmyAt[1] + (offset[1] \u003c 0 ? offset[1] : \"+\" + offset[1]),\n\t\t\t\t\t\tat: myAt.join(\" \")\n\t\t\t\t\t};\n\t\t\t\t}\n\n\t\t\t\tposition = $.extend( {}, $.ui.dialog.prototype.options.position, position );\n\t\t\t} else {\n\t\t\t\tposition = $.ui.dialog.prototype.options.position;\n\t\t\t}\n\n\t\t\t// need to show the dialog to get the actual offset in the position plugin\n\t\t\tisVisible = this.uiDialog.is(\":visible\");\n\t\t\tif ( !isVisible ) {\n\t\t\t\tthis.uiDialog.show();\n\t\t\t}\n\t\t\tthis.uiDialog.position( position );\n\t\t\tif ( !isVisible ) {\n\t\t\t\tthis.uiDialog.hide();\n\t\t\t}\n\t\t}\n\t});\n}\n\n}( jQuery ) );\n\n(function( $, undefined ) {\n\nvar rvertical = /up|down|vertical/,\n\trpositivemotion = /up|left|vertical|horizontal/;\n\n$.effects.effect.blind = function( o, done ) {\n\t// Create element\n\tvar el = $( this ),\n\t\tprops = [ \"position\", \"top\", \"bottom\", \"left\", \"right\", \"height\", \"width\" ],\n\t\tmode = $.effects.setMode( el, o.mode || \"hide\" ),\n\t\tdirection = o.direction || \"up\",\n\t\tvertical = rvertical.test( direction ),\n\t\tref = vertical ? \"height\" : \"width\",\n\t\tref2 = vertical ? \"top\" : \"left\",\n\t\tmotion = rpositivemotion.test( direction ),\n\t\tanimation = {},\n\t\tshow = mode === \"show\",\n\t\twrapper, distance, margin;\n\n\t// if already wrapped, the wrapper\u0027s properties are my property. #6245\n\tif ( el.parent().is( \".ui-effects-wrapper\" ) ) {\n\t\t$.effects.save( el.parent(), props );\n\t} else {\n\t\t$.effects.save( el, props );\n\t}\n\tel.show();\n\twrapper = $.effects.createWrapper( el ).css({\n\t\toverflow: \"hidden\"\n\t});\n\n\tdistance = wrapper[ ref ]();\n\tmargin = parseFloat( wrapper.css( ref2 ) ) || 0;\n\n\tanimation[ ref ] = show ? distance : 0;\n\tif ( !motion ) {\n\t\tel\n\t\t\t.css( vertical ? \"bottom\" : \"right\", 0 )\n\t\t\t.css( vertical ? \"top\" : \"left\", \"auto\" )\n\t\t\t.css({ position: \"absolute\" });\n\n\t\tanimation[ ref2 ] = show ? margin : distance + margin;\n\t}\n\n\t// start at 0 if we are showing\n\tif ( show ) {\n\t\twrapper.css( ref, 0 );\n\t\tif ( ! motion ) {\n\t\t\twrapper.css( ref2, margin + distance );\n\t\t}\n\t}\n\n\t// Animate\n\twrapper.animate( animation, {\n\t\tduration: o.duration,\n\t\teasing: o.easing,\n\t\tqueue: false,\n\t\tcomplete: function() {\n\t\t\tif ( mode === \"hide\" ) {\n\t\t\t\tel.hide();\n\t\t\t}\n\t\t\t$.effects.restore( el, props );\n\t\t\t$.effects.removeWrapper( el );\n\t\t\tdone();\n\t\t}\n\t});\n\n};\n\n})(jQuery);\n\n(function( $, undefined ) {\n\n$.effects.effect.bounce = function( o, done ) {\n\tvar el = $( this ),\n\t\tprops = [ \"position\", \"top\", \"bottom\", \"left\", \"right\", \"height\", \"width\" ],\n\n\t\t// defaults:\n\t\tmode = $.effects.setMode( el, o.mode || \"effect\" ),\n\t\thide = mode === \"hide\",\n\t\tshow = mode === \"show\",\n\t\tdirection = o.direction || \"up\",\n\t\tdistance = o.distance,\n\t\ttimes = o.times || 5,\n\n\t\t// number of internal animations\n\t\tanims = times * 2 + ( show || hide ? 1 : 0 ),\n\t\tspeed = o.duration / anims,\n\t\teasing = o.easing,\n\n\t\t// utility:\n\t\tref = ( direction === \"up\" || direction === \"down\" ) ? \"top\" : \"left\",\n\t\tmotion = ( direction === \"up\" || direction === \"left\" ),\n\t\ti,\n\t\tupAnim,\n\t\tdownAnim,\n\n\t\t// we will need to re-assemble the queue to stack our animations in place\n\t\tqueue = el.queue(),\n\t\tqueuelen = queue.length;\n\n\t// Avoid touching opacity to prevent clearType and PNG issues in IE\n\tif ( show || hide ) {\n\t\tprops.push( \"opacity\" );\n\t}\n\n\t$.effects.save( el, props );\n\tel.show();\n\t$.effects.createWrapper( el ); // Create Wrapper\n\n\t// default distance for the BIGGEST bounce is the outer Distance / 3\n\tif ( !distance ) {\n\t\tdistance = el[ ref === \"top\" ? \"outerHeight\" : \"outerWidth\" ]() / 3;\n\t}\n\n\tif ( show ) {\n\t\tdownAnim = { opacity: 1 };\n\t\tdownAnim[ ref ] = 0;\n\n\t\t// if we are showing, force opacity 0 and set the initial position\n\t\t// then do the \"first\" animation\n\t\tel.css( \"opacity\", 0 )\n\t\t\t.css( ref, motion ? -distance * 2 : distance * 2 )\n\t\t\t.animate( downAnim, speed, easing );\n\t}\n\n\t// start at the smallest distance if we are hiding\n\tif ( hide ) {\n\t\tdistance = distance / Math.pow( 2, times - 1 );\n\t}\n\n\tdownAnim = {};\n\tdownAnim[ ref ] = 0;\n\t// Bounces up/down/left/right then back to 0 -- times * 2 animations happen here\n\tfor ( i = 0; i \u003c times; i++ ) {\n\t\tupAnim = {};\n\t\tupAnim[ ref ] = ( motion ? \"-=\" : \"+=\" ) + distance;\n\n\t\tel.animate( upAnim, speed, easing )\n\t\t\t.animate( downAnim, speed, easing );\n\n\t\tdistance = hide ? distance * 2 : distance / 2;\n\t}\n\n\t// Last Bounce when Hiding\n\tif ( hide ) {\n\t\tupAnim = { opacity: 0 };\n\t\tupAnim[ ref ] = ( motion ? \"-=\" : \"+=\" ) + distance;\n\n\t\tel.animate( upAnim, speed, easing );\n\t}\n\n\tel.queue(function() {\n\t\tif ( hide ) {\n\t\t\tel.hide();\n\t\t}\n\t\t$.effects.restore( el, props );\n\t\t$.effects.removeWrapper( el );\n\t\tdone();\n\t});\n\n\t// inject all the animations we just queued to be first in line (after \"inprogress\")\n\tif ( queuelen \u003e 1) {\n\t\tqueue.splice.apply( queue,\n\t\t\t[ 1, 0 ].concat( queue.splice( queuelen, anims + 1 ) ) );\n\t}\n\tel.dequeue();\n\n};\n\n})(jQuery);\n\n(function( $, undefined ) {\n\n$.effects.effect.clip = function( o, done ) {\n\t// Create element\n\tvar el = $( this ),\n\t\tprops = [ \"position\", \"top\", \"bottom\", \"left\", \"right\", \"height\", \"width\" ],\n\t\tmode = $.effects.setMode( el, o.mode || \"hide\" ),\n\t\tshow = mode === \"show\",\n\t\tdirection = o.direction || \"vertical\",\n\t\tvert = direction === \"vertical\",\n\t\tsize = vert ? \"height\" : \"width\",\n\t\tposition = vert ? \"top\" : \"left\",\n\t\tanimation = {},\n\t\twrapper, animate, distance;\n\n\t// Save \u0026 Show\n\t$.effects.save( el, props );\n\tel.show();\n\n\t// Create Wrapper\n\twrapper = $.effects.createWrapper( el ).css({\n\t\toverflow: \"hidden\"\n\t});\n\tanimate = ( el[0].tagName === \"IMG\" ) ? wrapper : el;\n\tdistance = animate[ size ]();\n\n\t// Shift\n\tif ( show ) {\n\t\tanimate.css( size, 0 );\n\t\tanimate.css( position, distance / 2 );\n\t}\n\n\t// Create Animation Object:\n\tanimation[ size ] = show ? distance : 0;\n\tanimation[ position ] = show ? 0 : distance / 2;\n\n\t// Animate\n\tanimate.animate( animation, {\n\t\tqueue: false,\n\t\tduration: o.duration,\n\t\teasing: o.easing,\n\t\tcomplete: function() {\n\t\t\tif ( !show ) {\n\t\t\t\tel.hide();\n\t\t\t}\n\t\t\t$.effects.restore( el, props );\n\t\t\t$.effects.removeWrapper( el );\n\t\t\tdone();\n\t\t}\n\t});\n\n};\n\n})(jQuery);\n\n(function( $, undefined ) {\n\n$.effects.effect.drop = function( o, done ) {\n\n\tvar el = $( this ),\n\t\tprops = [ \"position\", \"top\", \"bottom\", \"left\", \"right\", \"opacity\", \"height\", \"width\" ],\n\t\tmode = $.effects.setMode( el, o.mode || \"hide\" ),\n\t\tshow = mode === \"show\",\n\t\tdirection = o.direction || \"left\",\n\t\tref = ( direction === \"up\" || direction === \"down\" ) ? \"top\" : \"left\",\n\t\tmotion = ( direction === \"up\" || direction === \"left\" ) ? \"pos\" : \"neg\",\n\t\tanimation = {\n\t\t\topacity: show ? 1 : 0\n\t\t},\n\t\tdistance;\n\n\t// Adjust\n\t$.effects.save( el, props );\n\tel.show();\n\t$.effects.createWrapper( el );\n\n\tdistance = o.distance || el[ ref === \"top\" ? \"outerHeight\": \"outerWidth\" ]( true ) / 2;\n\n\tif ( show ) {\n\t\tel\n\t\t\t.css( \"opacity\", 0 )\n\t\t\t.css( ref, motion === \"pos\" ? -distance : distance );\n\t}\n\n\t// Animation\n\tanimation[ ref ] = ( show ?\n\t\t( motion === \"pos\" ? \"+=\" : \"-=\" ) :\n\t\t( motion === \"pos\" ? \"-=\" : \"+=\" ) ) +\n\t\tdistance;\n\n\t// Animate\n\tel.animate( animation, {\n\t\tqueue: false,\n\t\tduration: o.duration,\n\t\teasing: o.easing,\n\t\tcomplete: function() {\n\t\t\tif ( mode === \"hide\" ) {\n\t\t\t\tel.hide();\n\t\t\t}\n\t\t\t$.effects.restore( el, props );\n\t\t\t$.effects.removeWrapper( el );\n\t\t\tdone();\n\t\t}\n\t});\n};\n\n})(jQuery);\n\n(function( $, undefined ) {\n\n$.effects.effect.explode = function( o, done ) {\n\n\tvar rows = o.pieces ? Math.round( Math.sqrt( o.pieces ) ) : 3,\n\t\tcells = rows,\n\t\tel = $( this ),\n\t\tmode = $.effects.setMode( el, o.mode || \"hide\" ),\n\t\tshow = mode === \"show\",\n\n\t\t// show and then visibility:hidden the element before calculating offset\n\t\toffset = el.show().css( \"visibility\", \"hidden\" ).offset(),\n\n\t\t// width and height of a piece\n\t\twidth = Math.ceil( el.outerWidth() / cells ),\n\t\theight = Math.ceil( el.outerHeight() / rows ),\n\t\tpieces = [],\n\n\t\t// loop\n\t\ti, j, left, top, mx, my;\n\n\t// children animate complete:\n\tfunction childComplete() {\n\t\tpieces.push( this );\n\t\tif ( pieces.length === rows * cells ) {\n\t\t\tanimComplete();\n\t\t}\n\t}\n\n\t// clone the element for each row and cell.\n\tfor( i = 0; i \u003c rows ; i++ ) { // ===\u003e\n\t\ttop = offset.top + i * height;\n\t\tmy = i - ( rows - 1 ) / 2 ;\n\n\t\tfor( j = 0; j \u003c cells ; j++ ) { // |||\n\t\t\tleft = offset.left + j * width;\n\t\t\tmx = j - ( cells - 1 ) / 2 ;\n\n\t\t\t// Create a clone of the now hidden main element that will be absolute positioned\n\t\t\t// within a wrapper div off the -left and -top equal to size of our pieces\n\t\t\tel\n\t\t\t\t.clone()\n\t\t\t\t.appendTo( \"body\" )\n\t\t\t\t.wrap( \"\u003cdiv\u003e\u003c/div\u003e\" )\n\t\t\t\t.css({\n\t\t\t\t\tposition: \"absolute\",\n\t\t\t\t\tvisibility: \"visible\",\n\t\t\t\t\tleft: -j * width,\n\t\t\t\t\ttop: -i * height\n\t\t\t\t})\n\n\t\t\t// select the wrapper - make it overflow: hidden and absolute positioned based on\n\t\t\t// where the original was located +left and +top equal to the size of pieces\n\t\t\t\t.parent()\n\t\t\t\t.addClass( \"ui-effects-explode\" )\n\t\t\t\t.css({\n\t\t\t\t\tposition: \"absolute\",\n\t\t\t\t\toverflow: \"hidden\",\n\t\t\t\t\twidth: width,\n\t\t\t\t\theight: height,\n\t\t\t\t\tleft: left + ( show ? mx * width : 0 ),\n\t\t\t\t\ttop: top + ( show ? my * height : 0 ),\n\t\t\t\t\topacity: show ? 0 : 1\n\t\t\t\t}).animate({\n\t\t\t\t\tleft: left + ( show ? 0 : mx * width ),\n\t\t\t\t\ttop: top + ( show ? 0 : my * height ),\n\t\t\t\t\topacity: show ? 1 : 0\n\t\t\t\t}, o.duration || 500, o.easing, childComplete );\n\t\t}\n\t}\n\n\tfunction animComplete() {\n\t\tel.css({\n\t\t\tvisibility: \"visible\"\n\t\t});\n\t\t$( pieces ).remove();\n\t\tif ( !show ) {\n\t\t\tel.hide();\n\t\t}\n\t\tdone();\n\t}\n};\n\n})(jQuery);\n\n(function( $, undefined ) {\n\n$.effects.effect.fade = function( o, done ) {\n\tvar el = $( this ),\n\t\tmode = $.effects.setMode( el, o.mode || \"toggle\" );\n\n\tel.animate({\n\t\topacity: mode\n\t}, {\n\t\tqueue: false,\n\t\tduration: o.duration,\n\t\teasing: o.easing,\n\t\tcomplete: done\n\t});\n};\n\n})( jQuery );\n\n(function( $, undefined ) {\n\n$.effects.effect.fold = function( o, done ) {\n\n\t// Create element\n\tvar el = $( this ),\n\t\tprops = [ \"position\", \"top\", \"bottom\", \"left\", \"right\", \"height\", \"width\" ],\n\t\tmode = $.effects.setMode( el, o.mode || \"hide\" ),\n\t\tshow = mode === \"show\",\n\t\thide = mode === \"hide\",\n\t\tsize = o.size || 15,\n\t\tpercent = /([0-9]+)%/.exec( size ),\n\t\thorizFirst = !!o.horizFirst,\n\t\twidthFirst = show !== horizFirst,\n\t\tref = widthFirst ? [ \"width\", \"height\" ] : [ \"height\", \"width\" ],\n\t\tduration = o.duration / 2,\n\t\twrapper, distance,\n\t\tanimation1 = {},\n\t\tanimation2 = {};\n\n\t$.effects.save( el, props );\n\tel.show();\n\n\t// Create Wrapper\n\twrapper = $.effects.createWrapper( el ).css({\n\t\toverflow: \"hidden\"\n\t});\n\tdistance = widthFirst ?\n\t\t[ wrapper.width(), wrapper.height() ] :\n\t\t[ wrapper.height(), wrapper.width() ];\n\n\tif ( percent ) {\n\t\tsize = parseInt( percent[ 1 ], 10 ) / 100 * distance[ hide ? 0 : 1 ];\n\t}\n\tif ( show ) {\n\t\twrapper.css( horizFirst ? {\n\t\t\theight: 0,\n\t\t\twidth: size\n\t\t} : {\n\t\t\theight: size,\n\t\t\twidth: 0\n\t\t});\n\t}\n\n\t// Animation\n\tanimation1[ ref[ 0 ] ] = show ? distance[ 0 ] : size;\n\tanimation2[ ref[ 1 ] ] = show ? distance[ 1 ] : 0;\n\n\t// Animate\n\twrapper\n\t\t.animate( animation1, duration, o.easing )\n\t\t.animate( animation2, duration, o.easing, function() {\n\t\t\tif ( hide ) {\n\t\t\t\tel.hide();\n\t\t\t}\n\t\t\t$.effects.restore( el, props );\n\t\t\t$.effects.removeWrapper( el );\n\t\t\tdone();\n\t\t});\n\n};\n\n})(jQuery);\n\n(function( $, undefined ) {\n\n$.effects.effect.highlight = function( o, done ) {\n\tvar elem = $( this ),\n\t\tprops = [ \"backgroundImage\", \"backgroundColor\", \"opacity\" ],\n\t\tmode = $.effects.setMode( elem, o.mode || \"show\" ),\n\t\tanimation = {\n\t\t\tbackgroundColor: elem.css( \"backgroundColor\" )\n\t\t};\n\n\tif (mode === \"hide\") {\n\t\tanimation.opacity = 0;\n\t}\n\n\t$.effects.save( elem, props );\n\n\telem\n\t\t.show()\n\t\t.css({\n\t\t\tbackgroundImage: \"none\",\n\t\t\tbackgroundColor: o.color || \"#ffff99\"\n\t\t})\n\t\t.animate( animation, {\n\t\t\tqueue: false,\n\t\t\tduration: o.duration,\n\t\t\teasing: o.easing,\n\t\t\tcomplete: function() {\n\t\t\t\tif ( mode === \"hide\" ) {\n\t\t\t\t\telem.hide();\n\t\t\t\t}\n\t\t\t\t$.effects.restore( elem, props );\n\t\t\t\tdone();\n\t\t\t}\n\t\t});\n};\n\n})(jQuery);\n\n(function( $, undefined ) {\n\n$.effects.effect.pulsate = function( o, done ) {\n\tvar elem = $( this ),\n\t\tmode = $.effects.setMode( elem, o.mode || \"show\" ),\n\t\tshow = mode === \"show\",\n\t\thide = mode === \"hide\",\n\t\tshowhide = ( show || mode === \"hide\" ),\n\n\t\t// showing or hiding leaves of the \"last\" animation\n\t\tanims = ( ( o.times || 5 ) * 2 ) + ( showhide ? 1 : 0 ),\n\t\tduration = o.duration / anims,\n\t\tanimateTo = 0,\n\t\tqueue = elem.queue(),\n\t\tqueuelen = queue.length,\n\t\ti;\n\n\tif ( show || !elem.is(\":visible\")) {\n\t\telem.css( \"opacity\", 0 ).show();\n\t\tanimateTo = 1;\n\t}\n\n\t// anims - 1 opacity \"toggles\"\n\tfor ( i = 1; i \u003c anims; i++ ) {\n\t\telem.animate({\n\t\t\topacity: animateTo\n\t\t}, duration, o.easing );\n\t\tanimateTo = 1 - animateTo;\n\t}\n\n\telem.animate({\n\t\topacity: animateTo\n\t}, duration, o.easing);\n\n\telem.queue(function() {\n\t\tif ( hide ) {\n\t\t\telem.hide();\n\t\t}\n\t\tdone();\n\t});\n\n\t// We just queued up \"anims\" animations, we need to put them next in the queue\n\tif ( queuelen \u003e 1 ) {\n\t\tqueue.splice.apply( queue,\n\t\t\t[ 1, 0 ].concat( queue.splice( queuelen, anims + 1 ) ) );\n\t}\n\telem.dequeue();\n};\n\n})(jQuery);\n\n(function( $, undefined ) {\n\n$.effects.effect.puff = function( o, done ) {\n\tvar elem = $( this ),\n\t\tmode = $.effects.setMode( elem, o.mode || \"hide\" ),\n\t\thide = mode === \"hide\",\n\t\tpercent = parseInt( o.percent, 10 ) || 150,\n\t\tfactor = percent / 100,\n\t\toriginal = {\n\t\t\theight: elem.height(),\n\t\t\twidth: elem.width(),\n\t\t\touterHeight: elem.outerHeight(),\n\t\t\touterWidth: elem.outerWidth()\n\t\t};\n\n\t$.extend( o, {\n\t\teffect: \"scale\",\n\t\tqueue: false,\n\t\tfade: true,\n\t\tmode: mode,\n\t\tcomplete: done,\n\t\tpercent: hide ? percent : 100,\n\t\tfrom: hide ?\n\t\t\toriginal :\n\t\t\t{\n\t\t\t\theight: original.height * factor,\n\t\t\t\twidth: original.width * factor,\n\t\t\t\touterHeight: original.outerHeight * factor,\n\t\t\t\touterWidth: original.outerWidth * factor\n\t\t\t}\n\t});\n\n\telem.effect( o );\n};\n\n$.effects.effect.scale = function( o, done ) {\n\n\t// Create element\n\tvar el = $( this ),\n\t\toptions = $.extend( true, {}, o ),\n\t\tmode = $.effects.setMode( el, o.mode || \"effect\" ),\n\t\tpercent = parseInt( o.percent, 10 ) ||\n\t\t\t( parseInt( o.percent, 10 ) === 0 ? 0 : ( mode === \"hide\" ? 0 : 100 ) ),\n\t\tdirection = o.direction || \"both\",\n\t\torigin = o.origin,\n\t\toriginal = {\n\t\t\theight: el.height(),\n\t\t\twidth: el.width(),\n\t\t\touterHeight: el.outerHeight(),\n\t\t\touterWidth: el.outerWidth()\n\t\t},\n\t\tfactor = {\n\t\t\ty: direction !== \"horizontal\" ? (percent / 100) : 1,\n\t\t\tx: direction !== \"vertical\" ? (percent / 100) : 1\n\t\t};\n\n\t// We are going to pass this effect to the size effect:\n\toptions.effect = \"size\";\n\toptions.queue = false;\n\toptions.complete = done;\n\n\t// Set default origin and restore for show/hide\n\tif ( mode !== \"effect\" ) {\n\t\toptions.origin = origin || [\"middle\",\"center\"];\n\t\toptions.restore = true;\n\t}\n\n\toptions.from = o.from || ( mode === \"show\" ? {\n\t\theight: 0,\n\t\twidth: 0,\n\t\touterHeight: 0,\n\t\touterWidth: 0\n\t} : original );\n\toptions.to = {\n\t\theight: original.height * factor.y,\n\t\twidth: original.width * factor.x,\n\t\touterHeight: original.outerHeight * factor.y,\n\t\touterWidth: original.outerWidth * factor.x\n\t};\n\n\t// Fade option to support puff\n\tif ( options.fade ) {\n\t\tif ( mode === \"show\" ) {\n\t\t\toptions.from.opacity = 0;\n\t\t\toptions.to.opacity = 1;\n\t\t}\n\t\tif ( mode === \"hide\" ) {\n\t\t\toptions.from.opacity = 1;\n\t\t\toptions.to.opacity = 0;\n\t\t}\n\t}\n\n\t// Animate\n\tel.effect( options );\n\n};\n\n$.effects.effect.size = function( o, done ) {\n\n\t// Create element\n\tvar original, baseline, factor,\n\t\tel = $( this ),\n\t\tprops0 = [ \"position\", \"top\", \"bottom\", \"left\", \"right\", \"width\", \"height\", \"overflow\", \"opacity\" ],\n\n\t\t// Always restore\n\t\tprops1 = [ \"position\", \"top\", \"bottom\", \"left\", \"right\", \"overflow\", \"opacity\" ],\n\n\t\t// Copy for children\n\t\tprops2 = [ \"width\", \"height\", \"overflow\" ],\n\t\tcProps = [ \"fontSize\" ],\n\t\tvProps = [ \"borderTopWidth\", \"borderBottomWidth\", \"paddingTop\", \"paddingBottom\" ],\n\t\thProps = [ \"borderLeftWidth\", \"borderRightWidth\", \"paddingLeft\", \"paddingRight\" ],\n\n\t\t// Set options\n\t\tmode = $.effects.setMode( el, o.mode || \"effect\" ),\n\t\trestore = o.restore || mode !== \"effect\",\n\t\tscale = o.scale || \"both\",\n\t\torigin = o.origin || [ \"middle\", \"center\" ],\n\t\tposition = el.css( \"position\" ),\n\t\tprops = restore ? props0 : props1,\n\t\tzero = {\n\t\t\theight: 0,\n\t\t\twidth: 0,\n\t\t\touterHeight: 0,\n\t\t\touterWidth: 0\n\t\t};\n\n\tif ( mode === \"show\" ) {\n\t\tel.show();\n\t}\n\toriginal = {\n\t\theight: el.height(),\n\t\twidth: el.width(),\n\t\touterHeight: el.outerHeight(),\n\t\touterWidth: el.outerWidth()\n\t};\n\n\tif ( o.mode === \"toggle\" \u0026\u0026 mode === \"show\" ) {\n\t\tel.from = o.to || zero;\n\t\tel.to = o.from || original;\n\t} else {\n\t\tel.from = o.from || ( mode === \"show\" ? zero : original );\n\t\tel.to = o.to || ( mode === \"hide\" ? zero : original );\n\t}\n\n\t// Set scaling factor\n\tfactor = {\n\t\tfrom: {\n\t\t\ty: el.from.height / original.height,\n\t\t\tx: el.from.width / original.width\n\t\t},\n\t\tto: {\n\t\t\ty: el.to.height / original.height,\n\t\t\tx: el.to.width / original.width\n\t\t}\n\t};\n\n\t// Scale the css box\n\tif ( scale === \"box\" || scale === \"both\" ) {\n\n\t\t// Vertical props scaling\n\t\tif ( factor.from.y !== factor.to.y ) {\n\t\t\tprops = props.concat( vProps );\n\t\t\tel.from = $.effects.setTransition( el, vProps, factor.from.y, el.from );\n\t\t\tel.to = $.effects.setTransition( el, vProps, factor.to.y, el.to );\n\t\t}\n\n\t\t// Horizontal props scaling\n\t\tif ( factor.from.x !== factor.to.x ) {\n\t\t\tprops = props.concat( hProps );\n\t\t\tel.from = $.effects.setTransition( el, hProps, factor.from.x, el.from );\n\t\t\tel.to = $.effects.setTransition( el, hProps, factor.to.x, el.to );\n\t\t}\n\t}\n\n\t// Scale the content\n\tif ( scale === \"content\" || scale === \"both\" ) {\n\n\t\t// Vertical props scaling\n\t\tif ( factor.from.y !== factor.to.y ) {\n\t\t\tprops = props.concat( cProps ).concat( props2 );\n\t\t\tel.from = $.effects.setTransition( el, cProps, factor.from.y, el.from );\n\t\t\tel.to = $.effects.setTransition( el, cProps, factor.to.y, el.to );\n\t\t}\n\t}\n\n\t$.effects.save( el, props );\n\tel.show();\n\t$.effects.createWrapper( el );\n\tel.css( \"overflow\", \"hidden\" ).css( el.from );\n\n\t// Adjust\n\tif (origin) { // Calculate baseline shifts\n\t\tbaseline = $.effects.getBaseline( origin, original );\n\t\tel.from.top = ( original.outerHeight - el.outerHeight() ) * baseline.y;\n\t\tel.from.left = ( original.outerWidth - el.outerWidth() ) * baseline.x;\n\t\tel.to.top = ( original.outerHeight - el.to.outerHeight ) * baseline.y;\n\t\tel.to.left = ( original.outerWidth - el.to.outerWidth ) * baseline.x;\n\t}\n\tel.css( el.from ); // set top \u0026 left\n\n\t// Animate\n\tif ( scale === \"content\" || scale === \"both\" ) { // Scale the children\n\n\t\t// Add margins/font-size\n\t\tvProps = vProps.concat([ \"marginTop\", \"marginBottom\" ]).concat(cProps);\n\t\thProps = hProps.concat([ \"marginLeft\", \"marginRight\" ]);\n\t\tprops2 = props0.concat(vProps).concat(hProps);\n\n\t\tel.find( \"*[width]\" ).each( function(){\n\t\t\tvar child = $( this ),\n\t\t\t\tc_original = {\n\t\t\t\t\theight: child.height(),\n\t\t\t\t\twidth: child.width(),\n\t\t\t\t\touterHeight: child.outerHeight(),\n\t\t\t\t\touterWidth: child.outerWidth()\n\t\t\t\t};\n\t\t\tif (restore) {\n\t\t\t\t$.effects.save(child, props2);\n\t\t\t}\n\n\t\t\tchild.from = {\n\t\t\t\theight: c_original.height * factor.from.y,\n\t\t\t\twidth: c_original.width * factor.from.x,\n\t\t\t\touterHeight: c_original.outerHeight * factor.from.y,\n\t\t\t\touterWidth: c_original.outerWidth * factor.from.x\n\t\t\t};\n\t\t\tchild.to = {\n\t\t\t\theight: c_original.height * factor.to.y,\n\t\t\t\twidth: c_original.width * factor.to.x,\n\t\t\t\touterHeight: c_original.height * factor.to.y,\n\t\t\t\touterWidth: c_original.width * factor.to.x\n\t\t\t};\n\n\t\t\t// Vertical props scaling\n\t\t\tif ( factor.from.y !== factor.to.y ) {\n\t\t\t\tchild.from = $.effects.setTransition( child, vProps, factor.from.y, child.from );\n\t\t\t\tchild.to = $.effects.setTransition( child, vProps, factor.to.y, child.to );\n\t\t\t}\n\n\t\t\t// Horizontal props scaling\n\t\t\tif ( factor.from.x !== factor.to.x ) {\n\t\t\t\tchild.from = $.effects.setTransition( child, hProps, factor.from.x, child.from );\n\t\t\t\tchild.to = $.effects.setTransition( child, hProps, factor.to.x, child.to );\n\t\t\t}\n\n\t\t\t// Animate children\n\t\t\tchild.css( child.from );\n\t\t\tchild.animate( child.to, o.duration, o.easing, function() {\n\n\t\t\t\t// Restore children\n\t\t\t\tif ( restore ) {\n\t\t\t\t\t$.effects.restore( child, props2 );\n\t\t\t\t}\n\t\t\t});\n\t\t});\n\t}\n\n\t// Animate\n\tel.animate( el.to, {\n\t\tqueue: false,\n\t\tduration: o.duration,\n\t\teasing: o.easing,\n\t\tcomplete: function() {\n\t\t\tif ( el.to.opacity === 0 ) {\n\t\t\t\tel.css( \"opacity\", el.from.opacity );\n\t\t\t}\n\t\t\tif( mode === \"hide\" ) {\n\t\t\t\tel.hide();\n\t\t\t}\n\t\t\t$.effects.restore( el, props );\n\t\t\tif ( !restore ) {\n\n\t\t\t\t// we need to calculate our new positioning based on the scaling\n\t\t\t\tif ( position === \"static\" ) {\n\t\t\t\t\tel.css({\n\t\t\t\t\t\tposition: \"relative\",\n\t\t\t\t\t\ttop: el.to.top,\n\t\t\t\t\t\tleft: el.to.left\n\t\t\t\t\t});\n\t\t\t\t} else {\n\t\t\t\t\t$.each([ \"top\", \"left\" ], function( idx, pos ) {\n\t\t\t\t\t\tel.css( pos, function( _, str ) {\n\t\t\t\t\t\t\tvar val = parseInt( str, 10 ),\n\t\t\t\t\t\t\t\ttoRef = idx ? el.to.left : el.to.top;\n\n\t\t\t\t\t\t\t// if original was \"auto\", recalculate the new value from wrapper\n\t\t\t\t\t\t\tif ( str === \"auto\" ) {\n\t\t\t\t\t\t\t\treturn toRef + \"px\";\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\treturn val + toRef + \"px\";\n\t\t\t\t\t\t});\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t$.effects.removeWrapper( el );\n\t\t\tdone();\n\t\t}\n\t});\n\n};\n\n})(jQuery);\n\n(function( $, undefined ) {\n\n$.effects.effect.shake = function( o, done ) {\n\n\tvar el = $( this ),\n\t\tprops = [ \"position\", \"top\", \"bottom\", \"left\", \"right\", \"height\", \"width\" ],\n\t\tmode = $.effects.setMode( el, o.mode || \"effect\" ),\n\t\tdirection = o.direction || \"left\",\n\t\tdistance = o.distance || 20,\n\t\ttimes = o.times || 3,\n\t\tanims = times * 2 + 1,\n\t\tspeed = Math.round(o.duration/anims),\n\t\tref = (direction === \"up\" || direction === \"down\") ? \"top\" : \"left\",\n\t\tpositiveMotion = (direction === \"up\" || direction === \"left\"),\n\t\tanimation = {},\n\t\tanimation1 = {},\n\t\tanimation2 = {},\n\t\ti,\n\n\t\t// we will need to re-assemble the queue to stack our animations in place\n\t\tqueue = el.queue(),\n\t\tqueuelen = queue.length;\n\n\t$.effects.save( el, props );\n\tel.show();\n\t$.effects.createWrapper( el );\n\n\t// Animation\n\tanimation[ ref ] = ( positiveMotion ? \"-=\" : \"+=\" ) + distance;\n\tanimation1[ ref ] = ( positiveMotion ? \"+=\" : \"-=\" ) + distance * 2;\n\tanimation2[ ref ] = ( positiveMotion ? \"-=\" : \"+=\" ) + distance * 2;\n\n\t// Animate\n\tel.animate( animation, speed, o.easing );\n\n\t// Shakes\n\tfor ( i = 1; i \u003c times; i++ ) {\n\t\tel.animate( animation1, speed, o.easing ).animate( animation2, speed, o.easing );\n\t}\n\tel\n\t\t.animate( animation1, speed, o.easing )\n\t\t.animate( animation, speed / 2, o.easing )\n\t\t.queue(function() {\n\t\t\tif ( mode === \"hide\" ) {\n\t\t\t\tel.hide();\n\t\t\t}\n\t\t\t$.effects.restore( el, props );\n\t\t\t$.effects.removeWrapper( el );\n\t\t\tdone();\n\t\t});\n\n\t// inject all the animations we just queued to be first in line (after \"inprogress\")\n\tif ( queuelen \u003e 1) {\n\t\tqueue.splice.apply( queue,\n\t\t\t[ 1, 0 ].concat( queue.splice( queuelen, anims + 1 ) ) );\n\t}\n\tel.dequeue();\n\n};\n\n})(jQuery);\n\n(function( $, undefined ) {\n\n$.effects.effect.slide = function( o, done ) {\n\n\t// Create element\n\tvar el = $( this ),\n\t\tprops = [ \"position\", \"top\", \"bottom\", \"left\", \"right\", \"width\", \"height\" ],\n\t\tmode = $.effects.setMode( el, o.mode || \"show\" ),\n\t\tshow = mode === \"show\",\n\t\tdirection = o.direction || \"left\",\n\t\tref = (direction === \"up\" || direction === \"down\") ? \"top\" : \"left\",\n\t\tpositiveMotion = (direction === \"up\" || direction === \"left\"),\n\t\tdistance,\n\t\tanimation = {};\n\n\t// Adjust\n\t$.effects.save( el, props );\n\tel.show();\n\tdistance = o.distance || el[ ref === \"top\" ? \"outerHeight\" : \"outerWidth\" ]( true );\n\n\t$.effects.createWrapper( el ).css({\n\t\toverflow: \"hidden\"\n\t});\n\n\tif ( show ) {\n\t\tel.css( ref, positiveMotion ? (isNaN(distance) ? \"-\" + distance : -distance) : distance );\n\t}\n\n\t// Animation\n\tanimation[ ref ] = ( show ?\n\t\t( positiveMotion ? \"+=\" : \"-=\") :\n\t\t( positiveMotion ? \"-=\" : \"+=\")) +\n\t\tdistance;\n\n\t// Animate\n\tel.animate( animation, {\n\t\tqueue: false,\n\t\tduration: o.duration,\n\t\teasing: o.easing,\n\t\tcomplete: function() {\n\t\t\tif ( mode === \"hide\" ) {\n\t\t\t\tel.hide();\n\t\t\t}\n\t\t\t$.effects.restore( el, props );\n\t\t\t$.effects.removeWrapper( el );\n\t\t\tdone();\n\t\t}\n\t});\n};\n\n})(jQuery);\n\n(function( $, undefined ) {\n\n$.effects.effect.transfer = function( o, done ) {\n\tvar elem = $( this ),\n\t\ttarget = $( o.to ),\n\t\ttargetFixed = target.css( \"position\" ) === \"fixed\",\n\t\tbody = $(\"body\"),\n\t\tfixTop = targetFixed ? body.scrollTop() : 0,\n\t\tfixLeft = targetFixed ? body.scrollLeft() : 0,\n\t\tendPosition = target.offset(),\n\t\tanimation = {\n\t\t\ttop: endPosition.top - fixTop ,\n\t\t\tleft: endPosition.left - fixLeft ,\n\t\t\theight: target.innerHeight(),\n\t\t\twidth: target.innerWidth()\n\t\t},\n\t\tstartPosition = elem.offset(),\n\t\ttransfer = $( \"\u003cdiv class=\u0027ui-effects-transfer\u0027\u003e\u003c/div\u003e\" )\n\t\t\t.appendTo( document.body )\n\t\t\t.addClass( o.className )\n\t\t\t.css({\n\t\t\t\ttop: startPosition.top - fixTop ,\n\t\t\t\tleft: startPosition.left - fixLeft ,\n\t\t\t\theight: elem.innerHeight(),\n\t\t\t\twidth: elem.innerWidth(),\n\t\t\t\tposition: targetFixed ? \"fixed\" : \"absolute\"\n\t\t\t})\n\t\t\t.animate( animation, o.duration, o.easing, function() {\n\t\t\t\ttransfer.remove();\n\t\t\t\tdone();\n\t\t\t});\n};\n\n})(jQuery);\n\n(function( $, undefined ) {\n\n$.widget( \"ui.menu\", {\n\tversion: \"1.10.2\",\n\tdefaultElement: \"\u003cul\u003e\",\n\tdelay: 300,\n\toptions: {\n\t\ticons: {\n\t\t\tsubmenu: \"ui-icon-carat-1-e\"\n\t\t},\n\t\tmenus: \"ul\",\n\t\tposition: {\n\t\t\tmy: \"left top\",\n\t\t\tat: \"right top\"\n\t\t},\n\t\trole: \"menu\",\n\n\t\t// callbacks\n\t\tblur: null,\n\t\tfocus: null,\n\t\tselect: null\n\t},\n\n\t_create: function() {\n\t\tthis.activeMenu = this.element;\n\t\t// flag used to prevent firing of the click handler\n\t\t// as the event bubbles up through nested menus\n\t\tthis.mouseHandled = false;\n\t\tthis.element\n\t\t\t.uniqueId()\n\t\t\t.addClass( \"ui-menu ui-widget ui-widget-content ui-corner-all\" )\n\t\t\t.toggleClass( \"ui-menu-icons\", !!this.element.find( \".ui-icon\" ).length )\n\t\t\t.attr({\n\t\t\t\trole: this.options.role,\n\t\t\t\ttabIndex: 0\n\t\t\t})\n\t\t\t// need to catch all clicks on disabled menu\n\t\t\t// not possible through _on\n\t\t\t.bind( \"click\" + this.eventNamespace, $.proxy(function( event ) {\n\t\t\t\tif ( this.options.disabled ) {\n\t\t\t\t\tevent.preventDefault();\n\t\t\t\t}\n\t\t\t}, this ));\n\n\t\tif ( this.options.disabled ) {\n\t\t\tthis.element\n\t\t\t\t.addClass( \"ui-state-disabled\" )\n\t\t\t\t.attr( \"aria-disabled\", \"true\" );\n\t\t}\n\n\t\tthis._on({\n\t\t\t// Prevent focus from sticking to links inside menu after clicking\n\t\t\t// them (focus should always stay on UL during navigation).\n\t\t\t\"mousedown .ui-menu-item \u003e a\": function( event ) {\n\t\t\t\tevent.preventDefault();\n\t\t\t},\n\t\t\t\"click .ui-state-disabled \u003e a\": function( event ) {\n\t\t\t\tevent.preventDefault();\n\t\t\t},\n\t\t\t\"click .ui-menu-item:has(a)\": function( event ) {\n\t\t\t\tvar target = $( event.target ).closest( \".ui-menu-item\" );\n\t\t\t\tif ( !this.mouseHandled \u0026\u0026 target.not( \".ui-state-disabled\" ).length ) {\n\t\t\t\t\tthis.mouseHandled = true;\n\n\t\t\t\t\tthis.select( event );\n\t\t\t\t\t// Open submenu on click\n\t\t\t\t\tif ( target.has( \".ui-menu\" ).length ) {\n\t\t\t\t\t\tthis.expand( event );\n\t\t\t\t\t} else if ( !this.element.is( \":focus\" ) ) {\n\t\t\t\t\t\t// Redirect focus to the menu\n\t\t\t\t\t\tthis.element.trigger( \"focus\", [ true ] );\n\n\t\t\t\t\t\t// If the active item is on the top level, let it stay active.\n\t\t\t\t\t\t// Otherwise, blur the active item since it is no longer visible.\n\t\t\t\t\t\tif ( this.active \u0026\u0026 this.active.parents( \".ui-menu\" ).length === 1 ) {\n\t\t\t\t\t\t\tclearTimeout( this.timer );\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t},\n\t\t\t\"mouseenter .ui-menu-item\": function( event ) {\n\t\t\t\tvar target = $( event.currentTarget );\n\t\t\t\t// Remove ui-state-active class from siblings of the newly focused menu item\n\t\t\t\t// to avoid a jump caused by adjacent elements both having a class with a border\n\t\t\t\ttarget.siblings().children( \".ui-state-active\" ).removeClass( \"ui-state-active\" );\n\t\t\t\tthis.focus( event, target );\n\t\t\t},\n\t\t\tmouseleave: \"collapseAll\",\n\t\t\t\"mouseleave .ui-menu\": \"collapseAll\",\n\t\t\tfocus: function( event, keepActiveItem ) {\n\t\t\t\t// If there\u0027s already an active item, keep it active\n\t\t\t\t// If not, activate the first item\n\t\t\t\tvar item = this.active || this.element.children( \".ui-menu-item\" ).eq( 0 );\n\n\t\t\t\tif ( !keepActiveItem ) {\n\t\t\t\t\tthis.focus( event, item );\n\t\t\t\t}\n\t\t\t},\n\t\t\tblur: function( event ) {\n\t\t\t\tthis._delay(function() {\n\t\t\t\t\tif ( !$.contains( this.element[0], this.document[0].activeElement ) ) {\n\t\t\t\t\t\tthis.collapseAll( event );\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t},\n\t\t\tkeydown: \"_keydown\"\n\t\t});\n\n\t\tthis.refresh();\n\n\t\t// Clicks outside of a menu collapse any open menus\n\t\tthis._on( this.document, {\n\t\t\tclick: function( event ) {\n\t\t\t\tif ( !$( event.target ).closest( \".ui-menu\" ).length ) {\n\t\t\t\t\tthis.collapseAll( event );\n\t\t\t\t}\n\n\t\t\t\t// Reset the mouseHandled flag\n\t\t\t\tthis.mouseHandled = false;\n\t\t\t}\n\t\t});\n\t},\n\n\t_destroy: function() {\n\t\t// Destroy (sub)menus\n\t\tthis.element\n\t\t\t.removeAttr( \"aria-activedescendant\" )\n\t\t\t.find( \".ui-menu\" ).addBack()\n\t\t\t\t.removeClass( \"ui-menu ui-widget ui-widget-content ui-corner-all ui-menu-icons\" )\n\t\t\t\t.removeAttr( \"role\" )\n\t\t\t\t.removeAttr( \"tabIndex\" )\n\t\t\t\t.removeAttr( \"aria-labelledby\" )\n\t\t\t\t.removeAttr( \"aria-expanded\" )\n\t\t\t\t.removeAttr( \"aria-hidden\" )\n\t\t\t\t.removeAttr( \"aria-disabled\" )\n\t\t\t\t.removeUniqueId()\n\t\t\t\t.show();\n\n\t\t// Destroy menu items\n\t\tthis.element.find( \".ui-menu-item\" )\n\t\t\t.removeClass( \"ui-menu-item\" )\n\t\t\t.removeAttr( \"role\" )\n\t\t\t.removeAttr( \"aria-disabled\" )\n\t\t\t.children( \"a\" )\n\t\t\t\t.removeUniqueId()\n\t\t\t\t.removeClass( \"ui-corner-all ui-state-hover\" )\n\t\t\t\t.removeAttr( \"tabIndex\" )\n\t\t\t\t.removeAttr( \"role\" )\n\t\t\t\t.removeAttr( \"aria-haspopup\" )\n\t\t\t\t.children().each( function() {\n\t\t\t\t\tvar elem = $( this );\n\t\t\t\t\tif ( elem.data( \"ui-menu-submenu-carat\" ) ) {\n\t\t\t\t\t\telem.remove();\n\t\t\t\t\t}\n\t\t\t\t});\n\n\t\t// Destroy menu dividers\n\t\tthis.element.find( \".ui-menu-divider\" ).removeClass( \"ui-menu-divider ui-widget-content\" );\n\t},\n\n\t_keydown: function( event ) {\n\t\t/*jshint maxcomplexity:20*/\n\t\tvar match, prev, character, skip, regex,\n\t\t\tpreventDefault = true;\n\n\t\tfunction escape( value ) {\n\t\t\treturn value.replace( /[\\-\\[\\]{}()*+?.,\\\\\\^$|#\\s]/g, \"\\\\$\u0026\" );\n\t\t}\n\n\t\tswitch ( event.keyCode ) {\n\t\tcase $.ui.keyCode.PAGE_UP:\n\t\t\tthis.previousPage( event );\n\t\t\tbreak;\n\t\tcase $.ui.keyCode.PAGE_DOWN:\n\t\t\tthis.nextPage( event );\n\t\t\tbreak;\n\t\tcase $.ui.keyCode.HOME:\n\t\t\tthis._move( \"first\", \"first\", event );\n\t\t\tbreak;\n\t\tcase $.ui.keyCode.END:\n\t\t\tthis._move( \"last\", \"last\", event );\n\t\t\tbreak;\n\t\tcase $.ui.keyCode.UP:\n\t\t\tthis.previous( event );\n\t\t\tbreak;\n\t\tcase $.ui.keyCode.DOWN:\n\t\t\tthis.next( event );\n\t\t\tbreak;\n\t\tcase $.ui.keyCode.LEFT:\n\t\t\tthis.collapse( event );\n\t\t\tbreak;\n\t\tcase $.ui.keyCode.RIGHT:\n\t\t\tif ( this.active \u0026\u0026 !this.active.is( \".ui-state-disabled\" ) ) {\n\t\t\t\tthis.expand( event );\n\t\t\t}\n\t\t\tbreak;\n\t\tcase $.ui.keyCode.ENTER:\n\t\tcase $.ui.keyCode.SPACE:\n\t\t\tthis._activate( event );\n\t\t\tbreak;\n\t\tcase $.ui.keyCode.ESCAPE:\n\t\t\tthis.collapse( event );\n\t\t\tbreak;\n\t\tdefault:\n\t\t\tpreventDefault = false;\n\t\t\tprev = this.previousFilter || \"\";\n\t\t\tcharacter = String.fromCharCode( event.keyCode );\n\t\t\tskip = false;\n\n\t\t\tclearTimeout( this.filterTimer );\n\n\t\t\tif ( character === prev ) {\n\t\t\t\tskip = true;\n\t\t\t} else {\n\t\t\t\tcharacter = prev + character;\n\t\t\t}\n\n\t\t\tregex = new RegExp( \"^\" + escape( character ), \"i\" );\n\t\t\tmatch = this.activeMenu.children( \".ui-menu-item\" ).filter(function() {\n\t\t\t\treturn regex.test( $( this ).children( \"a\" ).text() );\n\t\t\t});\n\t\t\tmatch = skip \u0026\u0026 match.index( this.active.next() ) !== -1 ?\n\t\t\t\tthis.active.nextAll( \".ui-menu-item\" ) :\n\t\t\t\tmatch;\n\n\t\t\t// If no matches on the current filter, reset to the last character pressed\n\t\t\t// to move down the menu to the first item that starts with that character\n\t\t\tif ( !match.length ) {\n\t\t\t\tcharacter = String.fromCharCode( event.keyCode );\n\t\t\t\tregex = new RegExp( \"^\" + escape( character ), \"i\" );\n\t\t\t\tmatch = this.activeMenu.children( \".ui-menu-item\" ).filter(function() {\n\t\t\t\t\treturn regex.test( $( this ).children( \"a\" ).text() );\n\t\t\t\t});\n\t\t\t}\n\n\t\t\tif ( match.length ) {\n\t\t\t\tthis.focus( event, match );\n\t\t\t\tif ( match.length \u003e 1 ) {\n\t\t\t\t\tthis.previousFilter = character;\n\t\t\t\t\tthis.filterTimer = this._delay(function() {\n\t\t\t\t\t\tdelete this.previousFilter;\n\t\t\t\t\t}, 1000 );\n\t\t\t\t} else {\n\t\t\t\t\tdelete this.previousFilter;\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tdelete this.previousFilter;\n\t\t\t}\n\t\t}\n\n\t\tif ( preventDefault ) {\n\t\t\tevent.preventDefault();\n\t\t}\n\t},\n\n\t_activate: function( event ) {\n\t\tif ( !this.active.is( \".ui-state-disabled\" ) ) {\n\t\t\tif ( this.active.children( \"a[aria-haspopup=\u0027true\u0027]\" ).length ) {\n\t\t\t\tthis.expand( event );\n\t\t\t} else {\n\t\t\t\tthis.select( event );\n\t\t\t}\n\t\t}\n\t},\n\n\trefresh: function() {\n\t\tvar menus,\n\t\t\ticon = this.options.icons.submenu,\n\t\t\tsubmenus = this.element.find( this.options.menus );\n\n\t\t// Initialize nested menus\n\t\tsubmenus.filter( \":not(.ui-menu)\" )\n\t\t\t.addClass( \"ui-menu ui-widget ui-widget-content ui-corner-all\" )\n\t\t\t.hide()\n\t\t\t.attr({\n\t\t\t\trole: this.options.role,\n\t\t\t\t\"aria-hidden\": \"true\",\n\t\t\t\t\"aria-expanded\": \"false\"\n\t\t\t})\n\t\t\t.each(function() {\n\t\t\t\tvar menu = $( this ),\n\t\t\t\t\titem = menu.prev( \"a\" ),\n\t\t\t\t\tsubmenuCarat = $( \"\u003cspan\u003e\" )\n\t\t\t\t\t\t.addClass( \"ui-menu-icon ui-icon \" + icon )\n\t\t\t\t\t\t.data( \"ui-menu-submenu-carat\", true );\n\n\t\t\t\titem\n\t\t\t\t\t.attr( \"aria-haspopup\", \"true\" )\n\t\t\t\t\t.prepend( submenuCarat );\n\t\t\t\tmenu.attr( \"aria-labelledby\", item.attr( \"id\" ) );\n\t\t\t});\n\n\t\tmenus = submenus.add( this.element );\n\n\t\t// Don\u0027t refresh list items that are already adapted\n\t\tmenus.children( \":not(.ui-menu-item):has(a)\" )\n\t\t\t.addClass( \"ui-menu-item\" )\n\t\t\t.attr( \"role\", \"presentation\" )\n\t\t\t.children( \"a\" )\n\t\t\t\t.uniqueId()\n\t\t\t\t.addClass( \"ui-corner-all\" )\n\t\t\t\t.attr({\n\t\t\t\t\ttabIndex: -1,\n\t\t\t\t\trole: this._itemRole()\n\t\t\t\t});\n\n\t\t// Initialize unlinked menu-items containing spaces and/or dashes only as dividers\n\t\tmenus.children( \":not(.ui-menu-item)\" ).each(function() {\n\t\t\tvar item = $( this );\n\t\t\t// hyphen, em dash, en dash\n\t\t\tif ( !/[^\\-\\u2014\\u2013\\s]/.test( item.text() ) ) {\n\t\t\t\titem.addClass( \"ui-widget-content ui-menu-divider\" );\n\t\t\t}\n\t\t});\n\n\t\t// Add aria-disabled attribute to any disabled menu item\n\t\tmenus.children( \".ui-state-disabled\" ).attr( \"aria-disabled\", \"true\" );\n\n\t\t// If the active item has been removed, blur the menu\n\t\tif ( this.active \u0026\u0026 !$.contains( this.element[ 0 ], this.active[ 0 ] ) ) {\n\t\t\tthis.blur();\n\t\t}\n\t},\n\n\t_itemRole: function() {\n\t\treturn {\n\t\t\tmenu: \"menuitem\",\n\t\t\tlistbox: \"option\"\n\t\t}[ this.options.role ];\n\t},\n\n\t_setOption: function( key, value ) {\n\t\tif ( key === \"icons\" ) {\n\t\t\tthis.element.find( \".ui-menu-icon\" )\n\t\t\t\t.removeClass( this.options.icons.submenu )\n\t\t\t\t.addClass( value.submenu );\n\t\t}\n\t\tthis._super( key, value );\n\t},\n\n\tfocus: function( event, item ) {\n\t\tvar nested, focused;\n\t\tthis.blur( event, event \u0026\u0026 event.type === \"focus\" );\n\n\t\tthis._scrollIntoView( item );\n\n\t\tthis.active = item.first();\n\t\tfocused = this.active.children( \"a\" ).addClass( \"ui-state-focus\" );\n\t\t// Only update aria-activedescendant if there\u0027s a role\n\t\t// otherwise we assume focus is managed elsewhere\n\t\tif ( this.options.role ) {\n\t\t\tthis.element.attr( \"aria-activedescendant\", focused.attr( \"id\" ) );\n\t\t}\n\n\t\t// Highlight active parent menu item, if any\n\t\tthis.active\n\t\t\t.parent()\n\t\t\t.closest( \".ui-menu-item\" )\n\t\t\t.children( \"a:first\" )\n\t\t\t.addClass( \"ui-state-active\" );\n\n\t\tif ( event \u0026\u0026 event.type === \"keydown\" ) {\n\t\t\tthis._close();\n\t\t} else {\n\t\t\tthis.timer = this._delay(function() {\n\t\t\t\tthis._close();\n\t\t\t}, this.delay );\n\t\t}\n\n\t\tnested = item.children( \".ui-menu\" );\n\t\tif ( nested.length \u0026\u0026 ( /^mouse/.test( event.type ) ) ) {\n\t\t\tthis._startOpening(nested);\n\t\t}\n\t\tthis.activeMenu = item.parent();\n\n\t\tthis._trigger( \"focus\", event, { item: item } );\n\t},\n\n\t_scrollIntoView: function( item ) {\n\t\tvar borderTop, paddingTop, offset, scroll, elementHeight, itemHeight;\n\t\tif ( this._hasScroll() ) {\n\t\t\tborderTop = parseFloat( $.css( this.activeMenu[0], \"borderTopWidth\" ) ) || 0;\n\t\t\tpaddingTop = parseFloat( $.css( this.activeMenu[0], \"paddingTop\" ) ) || 0;\n\t\t\toffset = item.offset().top - this.activeMenu.offset().top - borderTop - paddingTop;\n\t\t\tscroll = this.activeMenu.scrollTop();\n\t\t\telementHeight = this.activeMenu.height();\n\t\t\titemHeight = item.height();\n\n\t\t\tif ( offset \u003c 0 ) {\n\t\t\t\tthis.activeMenu.scrollTop( scroll + offset );\n\t\t\t} else if ( offset + itemHeight \u003e elementHeight ) {\n\t\t\t\tthis.activeMenu.scrollTop( scroll + offset - elementHeight + itemHeight );\n\t\t\t}\n\t\t}\n\t},\n\n\tblur: function( event, fromFocus ) {\n\t\tif ( !fromFocus ) {\n\t\t\tclearTimeout( this.timer );\n\t\t}\n\n\t\tif ( !this.active ) {\n\t\t\treturn;\n\t\t}\n\n\t\tthis.active.children( \"a\" ).removeClass( \"ui-state-focus\" );\n\t\tthis.active = null;\n\n\t\tthis._trigger( \"blur\", event, { item: this.active } );\n\t},\n\n\t_startOpening: function( submenu ) {\n\t\tclearTimeout( this.timer );\n\n\t\t// Don\u0027t open if already open fixes a Firefox bug that caused a .5 pixel\n\t\t// shift in the submenu position when mousing over the carat icon\n\t\tif ( submenu.attr( \"aria-hidden\" ) !== \"true\" ) {\n\t\t\treturn;\n\t\t}\n\n\t\tthis.timer = this._delay(function() {\n\t\t\tthis._close();\n\t\t\tthis._open( submenu );\n\t\t}, this.delay );\n\t},\n\n\t_open: function( submenu ) {\n\t\tvar position = $.extend({\n\t\t\tof: this.active\n\t\t}, this.options.position );\n\n\t\tclearTimeout( this.timer );\n\t\tthis.element.find( \".ui-menu\" ).not( submenu.parents( \".ui-menu\" ) )\n\t\t\t.hide()\n\t\t\t.attr( \"aria-hidden\", \"true\" );\n\n\t\tsubmenu\n\t\t\t.show()\n\t\t\t.removeAttr( \"aria-hidden\" )\n\t\t\t.attr( \"aria-expanded\", \"true\" )\n\t\t\t.position( position );\n\t},\n\n\tcollapseAll: function( event, all ) {\n\t\tclearTimeout( this.timer );\n\t\tthis.timer = this._delay(function() {\n\t\t\t// If we were passed an event, look for the submenu that contains the event\n\t\t\tvar currentMenu = all ? this.element :\n\t\t\t\t$( event \u0026\u0026 event.target ).closest( this.element.find( \".ui-menu\" ) );\n\n\t\t\t// If we found no valid submenu ancestor, use the main menu to close all sub menus anyway\n\t\t\tif ( !currentMenu.length ) {\n\t\t\t\tcurrentMenu = this.element;\n\t\t\t}\n\n\t\t\tthis._close( currentMenu );\n\n\t\t\tthis.blur( event );\n\t\t\tthis.activeMenu = currentMenu;\n\t\t}, this.delay );\n\t},\n\n\t// With no arguments, closes the currently active menu - if nothing is active\n\t// it closes all menus. If passed an argument, it will search for menus BELOW\n\t_close: function( startMenu ) {\n\t\tif ( !startMenu ) {\n\t\t\tstartMenu = this.active ? this.active.parent() : this.element;\n\t\t}\n\n\t\tstartMenu\n\t\t\t.find( \".ui-menu\" )\n\t\t\t\t.hide()\n\t\t\t\t.attr( \"aria-hidden\", \"true\" )\n\t\t\t\t.attr( \"aria-expanded\", \"false\" )\n\t\t\t.end()\n\t\t\t.find( \"a.ui-state-active\" )\n\t\t\t\t.removeClass( \"ui-state-active\" );\n\t},\n\n\tcollapse: function( event ) {\n\t\tvar newItem = this.active \u0026\u0026\n\t\t\tthis.active.parent().closest( \".ui-menu-item\", this.element );\n\t\tif ( newItem \u0026\u0026 newItem.length ) {\n\t\t\tthis._close();\n\t\t\tthis.focus( event, newItem );\n\t\t}\n\t},\n\n\texpand: function( event ) {\n\t\tvar newItem = this.active \u0026\u0026\n\t\t\tthis.active\n\t\t\t\t.children( \".ui-menu \" )\n\t\t\t\t.children( \".ui-menu-item\" )\n\t\t\t\t.first();\n\n\t\tif ( newItem \u0026\u0026 newItem.length ) {\n\t\t\tthis._open( newItem.parent() );\n\n\t\t\t// Delay so Firefox will not hide activedescendant change in expanding submenu from AT\n\t\t\tthis._delay(function() {\n\t\t\t\tthis.focus( event, newItem );\n\t\t\t});\n\t\t}\n\t},\n\n\tnext: function( event ) {\n\t\tthis._move( \"next\", \"first\", event );\n\t},\n\n\tprevious: function( event ) {\n\t\tthis._move( \"prev\", \"last\", event );\n\t},\n\n\tisFirstItem: function() {\n\t\treturn this.active \u0026\u0026 !this.active.prevAll( \".ui-menu-item\" ).length;\n\t},\n\n\tisLastItem: function() {\n\t\treturn this.active \u0026\u0026 !this.active.nextAll( \".ui-menu-item\" ).length;\n\t},\n\n\t_move: function( direction, filter, event ) {\n\t\tvar next;\n\t\tif ( this.active ) {\n\t\t\tif ( direction === \"first\" || direction === \"last\" ) {\n\t\t\t\tnext = this.active\n\t\t\t\t\t[ direction === \"first\" ? \"prevAll\" : \"nextAll\" ]( \".ui-menu-item\" )\n\t\t\t\t\t.eq( -1 );\n\t\t\t} else {\n\t\t\t\tnext = this.active\n\t\t\t\t\t[ direction + \"All\" ]( \".ui-menu-item\" )\n\t\t\t\t\t.eq( 0 );\n\t\t\t}\n\t\t}\n\t\tif ( !next || !next.length || !this.active ) {\n\t\t\tnext = this.activeMenu.children( \".ui-menu-item\" )[ filter ]();\n\t\t}\n\n\t\tthis.focus( event, next );\n\t},\n\n\tnextPage: function( event ) {\n\t\tvar item, base, height;\n\n\t\tif ( !this.active ) {\n\t\t\tthis.next( event );\n\t\t\treturn;\n\t\t}\n\t\tif ( this.isLastItem() ) {\n\t\t\treturn;\n\t\t}\n\t\tif ( this._hasScroll() ) {\n\t\t\tbase = this.active.offset().top;\n\t\t\theight = this.element.height();\n\t\t\tthis.active.nextAll( \".ui-menu-item\" ).each(function() {\n\t\t\t\titem = $( this );\n\t\t\t\treturn item.offset().top - base - height \u003c 0;\n\t\t\t});\n\n\t\t\tthis.focus( event, item );\n\t\t} else {\n\t\t\tthis.focus( event, this.activeMenu.children( \".ui-menu-item\" )\n\t\t\t\t[ !this.active ? \"first\" : \"last\" ]() );\n\t\t}\n\t},\n\n\tpreviousPage: function( event ) {\n\t\tvar item, base, height;\n\t\tif ( !this.active ) {\n\t\t\tthis.next( event );\n\t\t\treturn;\n\t\t}\n\t\tif ( this.isFirstItem() ) {\n\t\t\treturn;\n\t\t}\n\t\tif ( this._hasScroll() ) {\n\t\t\tbase = this.active.offset().top;\n\t\t\theight = this.element.height();\n\t\t\tthis.active.prevAll( \".ui-menu-item\" ).each(function() {\n\t\t\t\titem = $( this );\n\t\t\t\treturn item.offset().top - base + height \u003e 0;\n\t\t\t});\n\n\t\t\tthis.focus( event, item );\n\t\t} else {\n\t\t\tthis.focus( event, this.activeMenu.children( \".ui-menu-item\" ).first() );\n\t\t}\n\t},\n\n\t_hasScroll: function() {\n\t\treturn this.element.outerHeight() \u003c this.element.prop( \"scrollHeight\" );\n\t},\n\n\tselect: function( event ) {\n\t\t// TODO: It should never be possible to not have an active item at this\n\t\t// point, but the tests don\u0027t trigger mouseenter before click.\n\t\tthis.active = this.active || $( event.target ).closest( \".ui-menu-item\" );\n\t\tvar ui = { item: this.active };\n\t\tif ( !this.active.has( \".ui-menu\" ).length ) {\n\t\t\tthis.collapseAll( event, true );\n\t\t}\n\t\tthis._trigger( \"select\", event, ui );\n\t}\n});\n\n}( jQuery ));\n\n(function( $, undefined ) {\n\n$.ui = $.ui || {};\n\nvar cachedScrollbarWidth,\n\tmax = Math.max,\n\tabs = Math.abs,\n\tround = Math.round,\n\trhorizontal = /left|center|right/,\n\trvertical = /top|center|bottom/,\n\troffset = /[\\+\\-]\\d+(\\.[\\d]+)?%?/,\n\trposition = /^\\w+/,\n\trpercent = /%$/,\n\t_position = $.fn.position;\n\nfunction getOffsets( offsets, width, height ) {\n\treturn [\n\t\tparseFloat( offsets[ 0 ] ) * ( rpercent.test( offsets[ 0 ] ) ? width / 100 : 1 ),\n\t\tparseFloat( offsets[ 1 ] ) * ( rpercent.test( offsets[ 1 ] ) ? height / 100 : 1 )\n\t];\n}\n\nfunction parseCss( element, property ) {\n\treturn parseInt( $.css( element, property ), 10 ) || 0;\n}\n\nfunction getDimensions( elem ) {\n\tvar raw = elem[0];\n\tif ( raw.nodeType === 9 ) {\n\t\treturn {\n\t\t\twidth: elem.width(),\n\t\t\theight: elem.height(),\n\t\t\toffset: { top: 0, left: 0 }\n\t\t};\n\t}\n\tif ( $.isWindow( raw ) ) {\n\t\treturn {\n\t\t\twidth: elem.width(),\n\t\t\theight: elem.height(),\n\t\t\toffset: { top: elem.scrollTop(), left: elem.scrollLeft() }\n\t\t};\n\t}\n\tif ( raw.preventDefault ) {\n\t\treturn {\n\t\t\twidth: 0,\n\t\t\theight: 0,\n\t\t\toffset: { top: raw.pageY, left: raw.pageX }\n\t\t};\n\t}\n\treturn {\n\t\twidth: elem.outerWidth(),\n\t\theight: elem.outerHeight(),\n\t\toffset: elem.offset()\n\t};\n}\n\n$.position = {\n\tscrollbarWidth: function() {\n\t\tif ( cachedScrollbarWidth !== undefined ) {\n\t\t\treturn cachedScrollbarWidth;\n\t\t}\n\t\tvar w1, w2,\n\t\t\tdiv = $( \"\u003cdiv style=\u0027display:block;width:50px;height:50px;overflow:hidden;\u0027\u003e\u003cdiv style=\u0027height:100px;width:auto;\u0027\u003e\u003c/div\u003e\u003c/div\u003e\" ),\n\t\t\tinnerDiv = div.children()[0];\n\n\t\t$( \"body\" ).append( div );\n\t\tw1 = innerDiv.offsetWidth;\n\t\tdiv.css( \"overflow\", \"scroll\" );\n\n\t\tw2 = innerDiv.offsetWidth;\n\n\t\tif ( w1 === w2 ) {\n\t\t\tw2 = div[0].clientWidth;\n\t\t}\n\n\t\tdiv.remove();\n\n\t\treturn (cachedScrollbarWidth = w1 - w2);\n\t},\n\tgetScrollInfo: function( within ) {\n\t\tvar overflowX = within.isWindow ? \"\" : within.element.css( \"overflow-x\" ),\n\t\t\toverflowY = within.isWindow ? \"\" : within.element.css( \"overflow-y\" ),\n\t\t\thasOverflowX = overflowX === \"scroll\" ||\n\t\t\t\t( overflowX === \"auto\" \u0026\u0026 within.width \u003c within.element[0].scrollWidth ),\n\t\t\thasOverflowY = overflowY === \"scroll\" ||\n\t\t\t\t( overflowY === \"auto\" \u0026\u0026 within.height \u003c within.element[0].scrollHeight );\n\t\treturn {\n\t\t\twidth: hasOverflowY ? $.position.scrollbarWidth() : 0,\n\t\t\theight: hasOverflowX ? $.position.scrollbarWidth() : 0\n\t\t};\n\t},\n\tgetWithinInfo: function( element ) {\n\t\tvar withinElement = $( element || window ),\n\t\t\tisWindow = $.isWindow( withinElement[0] );\n\t\treturn {\n\t\t\telement: withinElement,\n\t\t\tisWindow: isWindow,\n\t\t\toffset: withinElement.offset() || { left: 0, top: 0 },\n\t\t\tscrollLeft: withinElement.scrollLeft(),\n\t\t\tscrollTop: withinElement.scrollTop(),\n\t\t\twidth: isWindow ? withinElement.width() : withinElement.outerWidth(),\n\t\t\theight: isWindow ? withinElement.height() : withinElement.outerHeight()\n\t\t};\n\t}\n};\n\n$.fn.position = function( options ) {\n\tif ( !options || !options.of ) {\n\t\treturn _position.apply( this, arguments );\n\t}\n\n\t// make a copy, we don\u0027t want to modify arguments\n\toptions = $.extend( {}, options );\n\n\tvar atOffset, targetWidth, targetHeight, targetOffset, basePosition, dimensions,\n\t\ttarget = $( options.of ),\n\t\twithin = $.position.getWithinInfo( options.within ),\n\t\tscrollInfo = $.position.getScrollInfo( within ),\n\t\tcollision = ( options.collision || \"flip\" ).split( \" \" ),\n\t\toffsets = {};\n\n\tdimensions = getDimensions( target );\n\tif ( target[0].preventDefault ) {\n\t\t// force left top to allow flipping\n\t\toptions.at = \"left top\";\n\t}\n\ttargetWidth = dimensions.width;\n\ttargetHeight = dimensions.height;\n\ttargetOffset = dimensions.offset;\n\t// clone to reuse original targetOffset later\n\tbasePosition = $.extend( {}, targetOffset );\n\n\t// force my and at to have valid horizontal and vertical positions\n\t// if a value is missing or invalid, it will be converted to center\n\t$.each( [ \"my\", \"at\" ], function() {\n\t\tvar pos = ( options[ this ] || \"\" ).split( \" \" ),\n\t\t\thorizontalOffset,\n\t\t\tverticalOffset;\n\n\t\tif ( pos.length === 1) {\n\t\t\tpos = rhorizontal.test( pos[ 0 ] ) ?\n\t\t\t\tpos.concat( [ \"center\" ] ) :\n\t\t\t\trvertical.test( pos[ 0 ] ) ?\n\t\t\t\t\t[ \"center\" ].concat( pos ) :\n\t\t\t\t\t[ \"center\", \"center\" ];\n\t\t}\n\t\tpos[ 0 ] = rhorizontal.test( pos[ 0 ] ) ? pos[ 0 ] : \"center\";\n\t\tpos[ 1 ] = rvertical.test( pos[ 1 ] ) ? pos[ 1 ] : \"center\";\n\n\t\t// calculate offsets\n\t\thorizontalOffset = roffset.exec( pos[ 0 ] );\n\t\tverticalOffset = roffset.exec( pos[ 1 ] );\n\t\toffsets[ this ] = [\n\t\t\thorizontalOffset ? horizontalOffset[ 0 ] : 0,\n\t\t\tverticalOffset ? verticalOffset[ 0 ] : 0\n\t\t];\n\n\t\t// reduce to just the positions without the offsets\n\t\toptions[ this ] = [\n\t\t\trposition.exec( pos[ 0 ] )[ 0 ],\n\t\t\trposition.exec( pos[ 1 ] )[ 0 ]\n\t\t];\n\t});\n\n\t// normalize collision option\n\tif ( collision.length === 1 ) {\n\t\tcollision[ 1 ] = collision[ 0 ];\n\t}\n\n\tif ( options.at[ 0 ] === \"right\" ) {\n\t\tbasePosition.left += targetWidth;\n\t} else if ( options.at[ 0 ] === \"center\" ) {\n\t\tbasePosition.left += targetWidth / 2;\n\t}\n\n\tif ( options.at[ 1 ] === \"bottom\" ) {\n\t\tbasePosition.top += targetHeight;\n\t} else if ( options.at[ 1 ] === \"center\" ) {\n\t\tbasePosition.top += targetHeight / 2;\n\t}\n\n\tatOffset = getOffsets( offsets.at, targetWidth, targetHeight );\n\tbasePosition.left += atOffset[ 0 ];\n\tbasePosition.top += atOffset[ 1 ];\n\n\treturn this.each(function() {\n\t\tvar collisionPosition, using,\n\t\t\telem = $( this ),\n\t\t\telemWidth = elem.outerWidth(),\n\t\t\telemHeight = elem.outerHeight(),\n\t\t\tmarginLeft = parseCss( this, \"marginLeft\" ),\n\t\t\tmarginTop = parseCss( this, \"marginTop\" ),\n\t\t\tcollisionWidth = elemWidth + marginLeft + parseCss( this, \"marginRight\" ) + scrollInfo.width,\n\t\t\tcollisionHeight = elemHeight + marginTop + parseCss( this, \"marginBottom\" ) + scrollInfo.height,\n\t\t\tposition = $.extend( {}, basePosition ),\n\t\t\tmyOffset = getOffsets( offsets.my, elem.outerWidth(), elem.outerHeight() );\n\n\t\tif ( options.my[ 0 ] === \"right\" ) {\n\t\t\tposition.left -= elemWidth;\n\t\t} else if ( options.my[ 0 ] === \"center\" ) {\n\t\t\tposition.left -= elemWidth / 2;\n\t\t}\n\n\t\tif ( options.my[ 1 ] === \"bottom\" ) {\n\t\t\tposition.top -= elemHeight;\n\t\t} else if ( options.my[ 1 ] === \"center\" ) {\n\t\t\tposition.top -= elemHeight / 2;\n\t\t}\n\n\t\tposition.left += myOffset[ 0 ];\n\t\tposition.top += myOffset[ 1 ];\n\n\t\t// if the browser doesn\u0027t support fractions, then round for consistent results\n\t\tif ( !$.support.offsetFractions ) {\n\t\t\tposition.left = round( position.left );\n\t\t\tposition.top = round( position.top );\n\t\t}\n\n\t\tcollisionPosition = {\n\t\t\tmarginLeft: marginLeft,\n\t\t\tmarginTop: marginTop\n\t\t};\n\n\t\t$.each( [ \"left\", \"top\" ], function( i, dir ) {\n\t\t\tif ( $.ui.position[ collision[ i ] ] ) {\n\t\t\t\t$.ui.position[ collision[ i ] ][ dir ]( position, {\n\t\t\t\t\ttargetWidth: targetWidth,\n\t\t\t\t\ttargetHeight: targetHeight,\n\t\t\t\t\telemWidth: elemWidth,\n\t\t\t\t\telemHeight: elemHeight,\n\t\t\t\t\tcollisionPosition: collisionPosition,\n\t\t\t\t\tcollisionWidth: collisionWidth,\n\t\t\t\t\tcollisionHeight: collisionHeight,\n\t\t\t\t\toffset: [ atOffset[ 0 ] + myOffset[ 0 ], atOffset [ 1 ] + myOffset[ 1 ] ],\n\t\t\t\t\tmy: options.my,\n\t\t\t\t\tat: options.at,\n\t\t\t\t\twithin: within,\n\t\t\t\t\telem : elem\n\t\t\t\t});\n\t\t\t}\n\t\t});\n\n\t\tif ( options.using ) {\n\t\t\t// adds feedback as second argument to using callback, if present\n\t\t\tusing = function( props ) {\n\t\t\t\tvar left = targetOffset.left - position.left,\n\t\t\t\t\tright = left + targetWidth - elemWidth,\n\t\t\t\t\ttop = targetOffset.top - position.top,\n\t\t\t\t\tbottom = top + targetHeight - elemHeight,\n\t\t\t\t\tfeedback = {\n\t\t\t\t\t\ttarget: {\n\t\t\t\t\t\t\telement: target,\n\t\t\t\t\t\t\tleft: targetOffset.left,\n\t\t\t\t\t\t\ttop: targetOffset.top,\n\t\t\t\t\t\t\twidth: targetWidth,\n\t\t\t\t\t\t\theight: targetHeight\n\t\t\t\t\t\t},\n\t\t\t\t\t\telement: {\n\t\t\t\t\t\t\telement: elem,\n\t\t\t\t\t\t\tleft: position.left,\n\t\t\t\t\t\t\ttop: position.top,\n\t\t\t\t\t\t\twidth: elemWidth,\n\t\t\t\t\t\t\theight: elemHeight\n\t\t\t\t\t\t},\n\t\t\t\t\t\thorizontal: right \u003c 0 ? \"left\" : left \u003e 0 ? \"right\" : \"center\",\n\t\t\t\t\t\tvertical: bottom \u003c 0 ? \"top\" : top \u003e 0 ? \"bottom\" : \"middle\"\n\t\t\t\t\t};\n\t\t\t\tif ( targetWidth \u003c elemWidth \u0026\u0026 abs( left + right ) \u003c targetWidth ) {\n\t\t\t\t\tfeedback.horizontal = \"center\";\n\t\t\t\t}\n\t\t\t\tif ( targetHeight \u003c elemHeight \u0026\u0026 abs( top + bottom ) \u003c targetHeight ) {\n\t\t\t\t\tfeedback.vertical = \"middle\";\n\t\t\t\t}\n\t\t\t\tif ( max( abs( left ), abs( right ) ) \u003e max( abs( top ), abs( bottom ) ) ) {\n\t\t\t\t\tfeedback.important = \"horizontal\";\n\t\t\t\t} else {\n\t\t\t\t\tfeedback.important = \"vertical\";\n\t\t\t\t}\n\t\t\t\toptions.using.call( this, props, feedback );\n\t\t\t};\n\t\t}\n\n\t\telem.offset( $.extend( position, { using: using } ) );\n\t});\n};\n\n$.ui.position = {\n\tfit: {\n\t\tleft: function( position, data ) {\n\t\t\tvar within = data.within,\n\t\t\t\twithinOffset = within.isWindow ? within.scrollLeft : within.offset.left,\n\t\t\t\touterWidth = within.width,\n\t\t\t\tcollisionPosLeft = position.left - data.collisionPosition.marginLeft,\n\t\t\t\toverLeft = withinOffset - collisionPosLeft,\n\t\t\t\toverRight = collisionPosLeft + data.collisionWidth - outerWidth - withinOffset,\n\t\t\t\tnewOverRight;\n\n\t\t\t// element is wider than within\n\t\t\tif ( data.collisionWidth \u003e outerWidth ) {\n\t\t\t\t// element is initially over the left side of within\n\t\t\t\tif ( overLeft \u003e 0 \u0026\u0026 overRight \u003c= 0 ) {\n\t\t\t\t\tnewOverRight = position.left + overLeft + data.collisionWidth - outerWidth - withinOffset;\n\t\t\t\t\tposition.left += overLeft - newOverRight;\n\t\t\t\t// element is initially over right side of within\n\t\t\t\t} else if ( overRight \u003e 0 \u0026\u0026 overLeft \u003c= 0 ) {\n\t\t\t\t\tposition.left = withinOffset;\n\t\t\t\t// element is initially over both left and right sides of within\n\t\t\t\t} else {\n\t\t\t\t\tif ( overLeft \u003e overRight ) {\n\t\t\t\t\t\tposition.left = withinOffset + outerWidth - data.collisionWidth;\n\t\t\t\t\t} else {\n\t\t\t\t\t\tposition.left = withinOffset;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t// too far left -\u003e align with left edge\n\t\t\t} else if ( overLeft \u003e 0 ) {\n\t\t\t\tposition.left += overLeft;\n\t\t\t// too far right -\u003e align with right edge\n\t\t\t} else if ( overRight \u003e 0 ) {\n\t\t\t\tposition.left -= overRight;\n\t\t\t// adjust based on position and margin\n\t\t\t} else {\n\t\t\t\tposition.left = max( position.left - collisionPosLeft, position.left );\n\t\t\t}\n\t\t},\n\t\ttop: function( position, data ) {\n\t\t\tvar within = data.within,\n\t\t\t\twithinOffset = within.isWindow ? within.scrollTop : within.offset.top,\n\t\t\t\touterHeight = data.within.height,\n\t\t\t\tcollisionPosTop = position.top - data.collisionPosition.marginTop,\n\t\t\t\toverTop = withinOffset - collisionPosTop,\n\t\t\t\toverBottom = collisionPosTop + data.collisionHeight - outerHeight - withinOffset,\n\t\t\t\tnewOverBottom;\n\n\t\t\t// element is taller than within\n\t\t\tif ( data.collisionHeight \u003e outerHeight ) {\n\t\t\t\t// element is initially over the top of within\n\t\t\t\tif ( overTop \u003e 0 \u0026\u0026 overBottom \u003c= 0 ) {\n\t\t\t\t\tnewOverBottom = position.top + overTop + data.collisionHeight - outerHeight - withinOffset;\n\t\t\t\t\tposition.top += overTop - newOverBottom;\n\t\t\t\t// element is initially over bottom of within\n\t\t\t\t} else if ( overBottom \u003e 0 \u0026\u0026 overTop \u003c= 0 ) {\n\t\t\t\t\tposition.top = withinOffset;\n\t\t\t\t// element is initially over both top and bottom of within\n\t\t\t\t} else {\n\t\t\t\t\tif ( overTop \u003e overBottom ) {\n\t\t\t\t\t\tposition.top = withinOffset + outerHeight - data.collisionHeight;\n\t\t\t\t\t} else {\n\t\t\t\t\t\tposition.top = withinOffset;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t// too far up -\u003e align with top\n\t\t\t} else if ( overTop \u003e 0 ) {\n\t\t\t\tposition.top += overTop;\n\t\t\t// too far down -\u003e align with bottom edge\n\t\t\t} else if ( overBottom \u003e 0 ) {\n\t\t\t\tposition.top -= overBottom;\n\t\t\t// adjust based on position and margin\n\t\t\t} else {\n\t\t\t\tposition.top = max( position.top - collisionPosTop, position.top );\n\t\t\t}\n\t\t}\n\t},\n\tflip: {\n\t\tleft: function( position, data ) {\n\t\t\tvar within = data.within,\n\t\t\t\twithinOffset = within.offset.left + within.scrollLeft,\n\t\t\t\touterWidth = within.width,\n\t\t\t\toffsetLeft = within.isWindow ? within.scrollLeft : within.offset.left,\n\t\t\t\tcollisionPosLeft = position.left - data.collisionPosition.marginLeft,\n\t\t\t\toverLeft = collisionPosLeft - offsetLeft,\n\t\t\t\toverRight = collisionPosLeft + data.collisionWidth - outerWidth - offsetLeft,\n\t\t\t\tmyOffset = data.my[ 0 ] === \"left\" ?\n\t\t\t\t\t-data.elemWidth :\n\t\t\t\t\tdata.my[ 0 ] === \"right\" ?\n\t\t\t\t\t\tdata.elemWidth :\n\t\t\t\t\t\t0,\n\t\t\t\tatOffset = data.at[ 0 ] === \"left\" ?\n\t\t\t\t\tdata.targetWidth :\n\t\t\t\t\tdata.at[ 0 ] === \"right\" ?\n\t\t\t\t\t\t-data.targetWidth :\n\t\t\t\t\t\t0,\n\t\t\t\toffset = -2 * data.offset[ 0 ],\n\t\t\t\tnewOverRight,\n\t\t\t\tnewOverLeft;\n\n\t\t\tif ( overLeft \u003c 0 ) {\n\t\t\t\tnewOverRight = position.left + myOffset + atOffset + offset + data.collisionWidth - outerWidth - withinOffset;\n\t\t\t\tif ( newOverRight \u003c 0 || newOverRight \u003c abs( overLeft ) ) {\n\t\t\t\t\tposition.left += myOffset + atOffset + offset;\n\t\t\t\t}\n\t\t\t}\n\t\t\telse if ( overRight \u003e 0 ) {\n\t\t\t\tnewOverLeft = position.left - data.collisionPosition.marginLeft + myOffset + atOffset + offset - offsetLeft;\n\t\t\t\tif ( newOverLeft \u003e 0 || abs( newOverLeft ) \u003c overRight ) {\n\t\t\t\t\tposition.left += myOffset + atOffset + offset;\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t\ttop: function( position, data ) {\n\t\t\tvar within = data.within,\n\t\t\t\twithinOffset = within.offset.top + within.scrollTop,\n\t\t\t\touterHeight = within.height,\n\t\t\t\toffsetTop = within.isWindow ? within.scrollTop : within.offset.top,\n\t\t\t\tcollisionPosTop = position.top - data.collisionPosition.marginTop,\n\t\t\t\toverTop = collisionPosTop - offsetTop,\n\t\t\t\toverBottom = collisionPosTop + data.collisionHeight - outerHeight - offsetTop,\n\t\t\t\ttop = data.my[ 1 ] === \"top\",\n\t\t\t\tmyOffset = top ?\n\t\t\t\t\t-data.elemHeight :\n\t\t\t\t\tdata.my[ 1 ] === \"bottom\" ?\n\t\t\t\t\t\tdata.elemHeight :\n\t\t\t\t\t\t0,\n\t\t\t\tatOffset = data.at[ 1 ] === \"top\" ?\n\t\t\t\t\tdata.targetHeight :\n\t\t\t\t\tdata.at[ 1 ] === \"bottom\" ?\n\t\t\t\t\t\t-data.targetHeight :\n\t\t\t\t\t\t0,\n\t\t\t\toffset = -2 * data.offset[ 1 ],\n\t\t\t\tnewOverTop,\n\t\t\t\tnewOverBottom;\n\t\t\tif ( overTop \u003c 0 ) {\n\t\t\t\tnewOverBottom = position.top + myOffset + atOffset + offset + data.collisionHeight - outerHeight - withinOffset;\n\t\t\t\tif ( ( position.top + myOffset + atOffset + offset) \u003e overTop \u0026\u0026 ( newOverBottom \u003c 0 || newOverBottom \u003c abs( overTop ) ) ) {\n\t\t\t\t\tposition.top += myOffset + atOffset + offset;\n\t\t\t\t}\n\t\t\t}\n\t\t\telse if ( overBottom \u003e 0 ) {\n\t\t\t\tnewOverTop = position.top - data.collisionPosition.marginTop + myOffset + atOffset + offset - offsetTop;\n\t\t\t\tif ( ( position.top + myOffset + atOffset + offset) \u003e overBottom \u0026\u0026 ( newOverTop \u003e 0 || abs( newOverTop ) \u003c overBottom ) ) {\n\t\t\t\t\tposition.top += myOffset + atOffset + offset;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t},\n\tflipfit: {\n\t\tleft: function() {\n\t\t\t$.ui.position.flip.left.apply( this, arguments );\n\t\t\t$.ui.position.fit.left.apply( this, arguments );\n\t\t},\n\t\ttop: function() {\n\t\t\t$.ui.position.flip.top.apply( this, arguments );\n\t\t\t$.ui.position.fit.top.apply( this, arguments );\n\t\t}\n\t}\n};\n\n// fraction support test\n(function () {\n\tvar testElement, testElementParent, testElementStyle, offsetLeft, i,\n\t\tbody = document.getElementsByTagName( \"body\" )[ 0 ],\n\t\tdiv = document.createElement( \"div\" );\n\n\t//Create a \"fake body\" for testing based on method used in jQuery.support\n\ttestElement = document.createElement( body ? \"div\" : \"body\" );\n\ttestElementStyle = {\n\t\tvisibility: \"hidden\",\n\t\twidth: 0,\n\t\theight: 0,\n\t\tborder: 0,\n\t\tmargin: 0,\n\t\tbackground: \"none\"\n\t};\n\tif ( body ) {\n\t\t$.extend( testElementStyle, {\n\t\t\tposition: \"absolute\",\n\t\t\tleft: \"-1000px\",\n\t\t\ttop: \"-1000px\"\n\t\t});\n\t}\n\tfor ( i in testElementStyle ) {\n\t\ttestElement.style[ i ] = testElementStyle[ i ];\n\t}\n\ttestElement.appendChild( div );\n\ttestElementParent = body || document.documentElement;\n\ttestElementParent.insertBefore( testElement, testElementParent.firstChild );\n\n\tdiv.style.cssText = \"position: absolute; left: 10.7432222px;\";\n\n\toffsetLeft = $( div ).offset().left;\n\t$.support.offsetFractions = offsetLeft \u003e 10 \u0026\u0026 offsetLeft \u003c 11;\n\n\ttestElement.innerHTML = \"\";\n\ttestElementParent.removeChild( testElement );\n})();\n\n}( jQuery ) );\n\n(function( $, undefined ) {\n\n$.widget( \"ui.progressbar\", {\n\tversion: \"1.10.2\",\n\toptions: {\n\t\tmax: 100,\n\t\tvalue: 0,\n\n\t\tchange: null,\n\t\tcomplete: null\n\t},\n\n\tmin: 0,\n\n\t_create: function() {\n\t\t// Constrain initial value\n\t\tthis.oldValue = this.options.value = this._constrainedValue();\n\n\t\tthis.element\n\t\t\t.addClass( \"ui-progressbar ui-widget ui-widget-content ui-corner-all\" )\n\t\t\t.attr({\n\t\t\t\t// Only set static values, aria-valuenow and aria-valuemax are\n\t\t\t\t// set inside _refreshValue()\n\t\t\t\trole: \"progressbar\",\n\t\t\t\t\"aria-valuemin\": this.min\n\t\t\t});\n\n\t\tthis.valueDiv = $( \"\u003cdiv class=\u0027ui-progressbar-value ui-widget-header ui-corner-left\u0027\u003e\u003c/div\u003e\" )\n\t\t\t.appendTo( this.element );\n\n\t\tthis._refreshValue();\n\t},\n\n\t_destroy: function() {\n\t\tthis.element\n\t\t\t.removeClass( \"ui-progressbar ui-widget ui-widget-content ui-corner-all\" )\n\t\t\t.removeAttr( \"role\" )\n\t\t\t.removeAttr( \"aria-valuemin\" )\n\t\t\t.removeAttr( \"aria-valuemax\" )\n\t\t\t.removeAttr( \"aria-valuenow\" );\n\n\t\tthis.valueDiv.remove();\n\t},\n\n\tvalue: function( newValue ) {\n\t\tif ( newValue === undefined ) {\n\t\t\treturn this.options.value;\n\t\t}\n\n\t\tthis.options.value = this._constrainedValue( newValue );\n\t\tthis._refreshValue();\n\t},\n\n\t_constrainedValue: function( newValue ) {\n\t\tif ( newValue === undefined ) {\n\t\t\tnewValue = this.options.value;\n\t\t}\n\n\t\tthis.indeterminate = newValue === false;\n\n\t\t// sanitize value\n\t\tif ( typeof newValue !== \"number\" ) {\n\t\t\tnewValue = 0;\n\t\t}\n\n\t\treturn this.indeterminate ? false :\n\t\t\tMath.min( this.options.max, Math.max( this.min, newValue ) );\n\t},\n\n\t_setOptions: function( options ) {\n\t\t// Ensure \"value\" option is set after other values (like max)\n\t\tvar value = options.value;\n\t\tdelete options.value;\n\n\t\tthis._super( options );\n\n\t\tthis.options.value = this._constrainedValue( value );\n\t\tthis._refreshValue();\n\t},\n\n\t_setOption: function( key, value ) {\n\t\tif ( key === \"max\" ) {\n\t\t\t// Don\u0027t allow a max less than min\n\t\t\tvalue = Math.max( this.min, value );\n\t\t}\n\n\t\tthis._super( key, value );\n\t},\n\n\t_percentage: function() {\n\t\treturn this.indeterminate ? 100 : 100 * ( this.options.value - this.min ) / ( this.options.max - this.min );\n\t},\n\n\t_refreshValue: function() {\n\t\tvar value = this.options.value,\n\t\t\tpercentage = this._percentage();\n\n\t\tthis.valueDiv\n\t\t\t.toggle( this.indeterminate || value \u003e this.min )\n\t\t\t.toggleClass( \"ui-corner-right\", value === this.options.max )\n\t\t\t.width( percentage.toFixed(0) + \"%\" );\n\n\t\tthis.element.toggleClass( \"ui-progressbar-indeterminate\", this.indeterminate );\n\n\t\tif ( this.indeterminate ) {\n\t\t\tthis.element.removeAttr( \"aria-valuenow\" );\n\t\t\tif ( !this.overlayDiv ) {\n\t\t\t\tthis.overlayDiv = $( \"\u003cdiv class=\u0027ui-progressbar-overlay\u0027\u003e\u003c/div\u003e\" ).appendTo( this.valueDiv );\n\t\t\t}\n\t\t} else {\n\t\t\tthis.element.attr({\n\t\t\t\t\"aria-valuemax\": this.options.max,\n\t\t\t\t\"aria-valuenow\": value\n\t\t\t});\n\t\t\tif ( this.overlayDiv ) {\n\t\t\t\tthis.overlayDiv.remove();\n\t\t\t\tthis.overlayDiv = null;\n\t\t\t}\n\t\t}\n\n\t\tif ( this.oldValue !== value ) {\n\t\t\tthis.oldValue = value;\n\t\t\tthis._trigger( \"change\" );\n\t\t}\n\t\tif ( value === this.options.max ) {\n\t\t\tthis._trigger( \"complete\" );\n\t\t}\n\t}\n});\n\n})( jQuery );\n\n(function( $, undefined ) {\n\n// number of pages in a slider\n// (how many times can you page up/down to go through the whole range)\nvar numPages = 5;\n\n$.widget( \"ui.slider\", $.ui.mouse, {\n\tversion: \"1.10.2\",\n\twidgetEventPrefix: \"slide\",\n\n\toptions: {\n\t\tanimate: false,\n\t\tdistance: 0,\n\t\tmax: 100,\n\t\tmin: 0,\n\t\torientation: \"horizontal\",\n\t\trange: false,\n\t\tstep: 1,\n\t\tvalue: 0,\n\t\tvalues: null,\n\n\t\t// callbacks\n\t\tchange: null,\n\t\tslide: null,\n\t\tstart: null,\n\t\tstop: null\n\t},\n\n\t_create: function() {\n\t\tthis._keySliding = false;\n\t\tthis._mouseSliding = false;\n\t\tthis._animateOff = true;\n\t\tthis._handleIndex = null;\n\t\tthis._detectOrientation();\n\t\tthis._mouseInit();\n\n\t\tthis.element\n\t\t\t.addClass( \"ui-slider\" +\n\t\t\t\t\" ui-slider-\" + this.orientation +\n\t\t\t\t\" ui-widget\" +\n\t\t\t\t\" ui-widget-content\" +\n\t\t\t\t\" ui-corner-all\");\n\n\t\tthis._refresh();\n\t\tthis._setOption( \"disabled\", this.options.disabled );\n\n\t\tthis._animateOff = false;\n\t},\n\n\t_refresh: function() {\n\t\tthis._createRange();\n\t\tthis._createHandles();\n\t\tthis._setupEvents();\n\t\tthis._refreshValue();\n\t},\n\n\t_createHandles: function() {\n\t\tvar i, handleCount,\n\t\t\toptions = this.options,\n\t\t\texistingHandles = this.element.find( \".ui-slider-handle\" ).addClass( \"ui-state-default ui-corner-all\" ),\n\t\t\thandle = \"\u003ca class=\u0027ui-slider-handle ui-state-default ui-corner-all\u0027 href=\u0027#\u0027\u003e\u003c/a\u003e\",\n\t\t\thandles = [];\n\n\t\thandleCount = ( options.values \u0026\u0026 options.values.length ) || 1;\n\n\t\tif ( existingHandles.length \u003e handleCount ) {\n\t\t\texistingHandles.slice( handleCount ).remove();\n\t\t\texistingHandles = existingHandles.slice( 0, handleCount );\n\t\t}\n\n\t\tfor ( i = existingHandles.length; i \u003c handleCount; i++ ) {\n\t\t\thandles.push( handle );\n\t\t}\n\n\t\tthis.handles = existingHandles.add( $( handles.join( \"\" ) ).appendTo( this.element ) );\n\n\t\tthis.handle = this.handles.eq( 0 );\n\n\t\tthis.handles.each(function( i ) {\n\t\t\t$( this ).data( \"ui-slider-handle-index\", i );\n\t\t});\n\t},\n\n\t_createRange: function() {\n\t\tvar options = this.options,\n\t\t\tclasses = \"\";\n\n\t\tif ( options.range ) {\n\t\t\tif ( options.range === true ) {\n\t\t\t\tif ( !options.values ) {\n\t\t\t\t\toptions.values = [ this._valueMin(), this._valueMin() ];\n\t\t\t\t} else if ( options.values.length \u0026\u0026 options.values.length !== 2 ) {\n\t\t\t\t\toptions.values = [ options.values[0], options.values[0] ];\n\t\t\t\t} else if ( $.isArray( options.values ) ) {\n\t\t\t\t\toptions.values = options.values.slice(0);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif ( !this.range || !this.range.length ) {\n\t\t\t\tthis.range = $( \"\u003cdiv\u003e\u003c/div\u003e\" )\n\t\t\t\t\t.appendTo( this.element );\n\n\t\t\t\tclasses = \"ui-slider-range\" +\n\t\t\t\t// note: this isn\u0027t the most fittingly semantic framework class for this element,\n\t\t\t\t// but worked best visually with a variety of themes\n\t\t\t\t\" ui-widget-header ui-corner-all\";\n\t\t\t} else {\n\t\t\t\tthis.range.removeClass( \"ui-slider-range-min ui-slider-range-max\" )\n\t\t\t\t\t// Handle range switching from true to min/max\n\t\t\t\t\t.css({\n\t\t\t\t\t\t\"left\": \"\",\n\t\t\t\t\t\t\"bottom\": \"\"\n\t\t\t\t\t});\n\t\t\t}\n\n\t\t\tthis.range.addClass( classes +\n\t\t\t\t( ( options.range === \"min\" || options.range === \"max\" ) ? \" ui-slider-range-\" + options.range : \"\" ) );\n\t\t} else {\n\t\t\tthis.range = $([]);\n\t\t}\n\t},\n\n\t_setupEvents: function() {\n\t\tvar elements = this.handles.add( this.range ).filter( \"a\" );\n\t\tthis._off( elements );\n\t\tthis._on( elements, this._handleEvents );\n\t\tthis._hoverable( elements );\n\t\tthis._focusable( elements );\n\t},\n\n\t_destroy: function() {\n\t\tthis.handles.remove();\n\t\tthis.range.remove();\n\n\t\tthis.element\n\t\t\t.removeClass( \"ui-slider\" +\n\t\t\t\t\" ui-slider-horizontal\" +\n\t\t\t\t\" ui-slider-vertical\" +\n\t\t\t\t\" ui-widget\" +\n\t\t\t\t\" ui-widget-content\" +\n\t\t\t\t\" ui-corner-all\" );\n\n\t\tthis._mouseDestroy();\n\t},\n\n\t_mouseCapture: function( event ) {\n\t\tvar position, normValue, distance, closestHandle, index, allowed, offset, mouseOverHandle,\n\t\t\tthat = this,\n\t\t\to = this.options;\n\n\t\tif ( o.disabled ) {\n\t\t\treturn false;\n\t\t}\n\n\t\tthis.elementSize = {\n\t\t\twidth: this.element.outerWidth(),\n\t\t\theight: this.element.outerHeight()\n\t\t};\n\t\tthis.elementOffset = this.element.offset();\n\n\t\tposition = { x: event.pageX, y: event.pageY };\n\t\tnormValue = this._normValueFromMouse( position );\n\t\tdistance = this._valueMax() - this._valueMin() + 1;\n\t\tthis.handles.each(function( i ) {\n\t\t\tvar thisDistance = Math.abs( normValue - that.values(i) );\n\t\t\tif (( distance \u003e thisDistance ) ||\n\t\t\t\t( distance === thisDistance \u0026\u0026\n\t\t\t\t\t(i === that._lastChangedValue || that.values(i) === o.min ))) {\n\t\t\t\tdistance = thisDistance;\n\t\t\t\tclosestHandle = $( this );\n\t\t\t\tindex = i;\n\t\t\t}\n\t\t});\n\n\t\tallowed = this._start( event, index );\n\t\tif ( allowed === false ) {\n\t\t\treturn false;\n\t\t}\n\t\tthis._mouseSliding = true;\n\n\t\tthis._handleIndex = index;\n\n\t\tclosestHandle\n\t\t\t.addClass( \"ui-state-active\" )\n\t\t\t.focus();\n\n\t\toffset = closestHandle.offset();\n\t\tmouseOverHandle = !$( event.target ).parents().addBack().is( \".ui-slider-handle\" );\n\t\tthis._clickOffset = mouseOverHandle ? { left: 0, top: 0 } : {\n\t\t\tleft: event.pageX - offset.left - ( closestHandle.width() / 2 ),\n\t\t\ttop: event.pageY - offset.top -\n\t\t\t\t( closestHandle.height() / 2 ) -\n\t\t\t\t( parseInt( closestHandle.css(\"borderTopWidth\"), 10 ) || 0 ) -\n\t\t\t\t( parseInt( closestHandle.css(\"borderBottomWidth\"), 10 ) || 0) +\n\t\t\t\t( parseInt( closestHandle.css(\"marginTop\"), 10 ) || 0)\n\t\t};\n\n\t\tif ( !this.handles.hasClass( \"ui-state-hover\" ) ) {\n\t\t\tthis._slide( event, index, normValue );\n\t\t}\n\t\tthis._animateOff = true;\n\t\treturn true;\n\t},\n\n\t_mouseStart: function() {\n\t\treturn true;\n\t},\n\n\t_mouseDrag: function( event ) {\n\t\tvar position = { x: event.pageX, y: event.pageY },\n\t\t\tnormValue = this._normValueFromMouse( position );\n\n\t\tthis._slide( event, this._handleIndex, normValue );\n\n\t\treturn false;\n\t},\n\n\t_mouseStop: function( event ) {\n\t\tthis.handles.removeClass( \"ui-state-active\" );\n\t\tthis._mouseSliding = false;\n\n\t\tthis._stop( event, this._handleIndex );\n\t\tthis._change( event, this._handleIndex );\n\n\t\tthis._handleIndex = null;\n\t\tthis._clickOffset = null;\n\t\tthis._animateOff = false;\n\n\t\treturn false;\n\t},\n\n\t_detectOrientation: function() {\n\t\tthis.orientation = ( this.options.orientation === \"vertical\" ) ? \"vertical\" : \"horizontal\";\n\t},\n\n\t_normValueFromMouse: function( position ) {\n\t\tvar pixelTotal,\n\t\t\tpixelMouse,\n\t\t\tpercentMouse,\n\t\t\tvalueTotal,\n\t\t\tvalueMouse;\n\n\t\tif ( this.orientation === \"horizontal\" ) {\n\t\t\tpixelTotal = this.elementSize.width;\n\t\t\tpixelMouse = position.x - this.elementOffset.left - ( this._clickOffset ? this._clickOffset.left : 0 );\n\t\t} else {\n\t\t\tpixelTotal = this.elementSize.height;\n\t\t\tpixelMouse = position.y - this.elementOffset.top - ( this._clickOffset ? this._clickOffset.top : 0 );\n\t\t}\n\n\t\tpercentMouse = ( pixelMouse / pixelTotal );\n\t\tif ( percentMouse \u003e 1 ) {\n\t\t\tpercentMouse = 1;\n\t\t}\n\t\tif ( percentMouse \u003c 0 ) {\n\t\t\tpercentMouse = 0;\n\t\t}\n\t\tif ( this.orientation === \"vertical\" ) {\n\t\t\tpercentMouse = 1 - percentMouse;\n\t\t}\n\n\t\tvalueTotal = this._valueMax() - this._valueMin();\n\t\tvalueMouse = this._valueMin() + percentMouse * valueTotal;\n\n\t\treturn this._trimAlignValue( valueMouse );\n\t},\n\n\t_start: function( event, index ) {\n\t\tvar uiHash = {\n\t\t\thandle: this.handles[ index ],\n\t\t\tvalue: this.value()\n\t\t};\n\t\tif ( this.options.values \u0026\u0026 this.options.values.length ) {\n\t\t\tuiHash.value = this.values( index );\n\t\t\tuiHash.values = this.values();\n\t\t}\n\t\treturn this._trigger( \"start\", event, uiHash );\n\t},\n\n\t_slide: function( event, index, newVal ) {\n\t\tvar otherVal,\n\t\t\tnewValues,\n\t\t\tallowed;\n\n\t\tif ( this.options.values \u0026\u0026 this.options.values.length ) {\n\t\t\totherVal = this.values( index ? 0 : 1 );\n\n\t\t\tif ( ( this.options.values.length === 2 \u0026\u0026 this.options.range === true ) \u0026\u0026\n\t\t\t\t\t( ( index === 0 \u0026\u0026 newVal \u003e otherVal) || ( index === 1 \u0026\u0026 newVal \u003c otherVal ) )\n\t\t\t\t) {\n\t\t\t\tnewVal = otherVal;\n\t\t\t}\n\n\t\t\tif ( newVal !== this.values( index ) ) {\n\t\t\t\tnewValues = this.values();\n\t\t\t\tnewValues[ index ] = newVal;\n\t\t\t\t// A slide can be canceled by returning false from the slide callback\n\t\t\t\tallowed = this._trigger( \"slide\", event, {\n\t\t\t\t\thandle: this.handles[ index ],\n\t\t\t\t\tvalue: newVal,\n\t\t\t\t\tvalues: newValues\n\t\t\t\t} );\n\t\t\t\totherVal = this.values( index ? 0 : 1 );\n\t\t\t\tif ( allowed !== false ) {\n\t\t\t\t\tthis.values( index, newVal, true );\n\t\t\t\t}\n\t\t\t}\n\t\t} else {\n\t\t\tif ( newVal !== this.value() ) {\n\t\t\t\t// A slide can be canceled by returning false from the slide callback\n\t\t\t\tallowed = this._trigger( \"slide\", event, {\n\t\t\t\t\thandle: this.handles[ index ],\n\t\t\t\t\tvalue: newVal\n\t\t\t\t} );\n\t\t\t\tif ( allowed !== false ) {\n\t\t\t\t\tthis.value( newVal );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t},\n\n\t_stop: function( event, index ) {\n\t\tvar uiHash = {\n\t\t\thandle: this.handles[ index ],\n\t\t\tvalue: this.value()\n\t\t};\n\t\tif ( this.options.values \u0026\u0026 this.options.values.length ) {\n\t\t\tuiHash.value = this.values( index );\n\t\t\tuiHash.values = this.values();\n\t\t}\n\n\t\tthis._trigger( \"stop\", event, uiHash );\n\t},\n\n\t_change: function( event, index ) {\n\t\tif ( !this._keySliding \u0026\u0026 !this._mouseSliding ) {\n\t\t\tvar uiHash = {\n\t\t\t\thandle: this.handles[ index ],\n\t\t\t\tvalue: this.value()\n\t\t\t};\n\t\t\tif ( this.options.values \u0026\u0026 this.options.values.length ) {\n\t\t\t\tuiHash.value = this.values( index );\n\t\t\t\tuiHash.values = this.values();\n\t\t\t}\n\n\t\t\t//store the last changed value index for reference when handles overlap\n\t\t\tthis._lastChangedValue = index;\n\n\t\t\tthis._trigger( \"change\", event, uiHash );\n\t\t}\n\t},\n\n\tvalue: function( newValue ) {\n\t\tif ( arguments.length ) {\n\t\t\tthis.options.value = this._trimAlignValue( newValue );\n\t\t\tthis._refreshValue();\n\t\t\tthis._change( null, 0 );\n\t\t\treturn;\n\t\t}\n\n\t\treturn this._value();\n\t},\n\n\tvalues: function( index, newValue ) {\n\t\tvar vals,\n\t\t\tnewValues,\n\t\t\ti;\n\n\t\tif ( arguments.length \u003e 1 ) {\n\t\t\tthis.options.values[ index ] = this._trimAlignValue( newValue );\n\t\t\tthis._refreshValue();\n\t\t\tthis._change( null, index );\n\t\t\treturn;\n\t\t}\n\n\t\tif ( arguments.length ) {\n\t\t\tif ( $.isArray( arguments[ 0 ] ) ) {\n\t\t\t\tvals = this.options.values;\n\t\t\t\tnewValues = arguments[ 0 ];\n\t\t\t\tfor ( i = 0; i \u003c vals.length; i += 1 ) {\n\t\t\t\t\tvals[ i ] = this._trimAlignValue( newValues[ i ] );\n\t\t\t\t\tthis._change( null, i );\n\t\t\t\t}\n\t\t\t\tthis._refreshValue();\n\t\t\t} else {\n\t\t\t\tif ( this.options.values \u0026\u0026 this.options.values.length ) {\n\t\t\t\t\treturn this._values( index );\n\t\t\t\t} else {\n\t\t\t\t\treturn this.value();\n\t\t\t\t}\n\t\t\t}\n\t\t} else {\n\t\t\treturn this._values();\n\t\t}\n\t},\n\n\t_setOption: function( key, value ) {\n\t\tvar i,\n\t\t\tvalsLength = 0;\n\n\t\tif ( key === \"range\" \u0026\u0026 this.options.range === true ) {\n\t\t\tif ( value === \"min\" ) {\n\t\t\t\tthis.options.value = this._values( 0 );\n\t\t\t\tthis.options.values = null;\n\t\t\t} else if ( value === \"max\" ) {\n\t\t\t\tthis.options.value = this._values( this.options.values.length-1 );\n\t\t\t\tthis.options.values = null;\n\t\t\t}\n\t\t}\n\n\t\tif ( $.isArray( this.options.values ) ) {\n\t\t\tvalsLength = this.options.values.length;\n\t\t}\n\n\t\t$.Widget.prototype._setOption.apply( this, arguments );\n\n\t\tswitch ( key ) {\n\t\t\tcase \"orientation\":\n\t\t\t\tthis._detectOrientation();\n\t\t\t\tthis.element\n\t\t\t\t\t.removeClass( \"ui-slider-horizontal ui-slider-vertical\" )\n\t\t\t\t\t.addClass( \"ui-slider-\" + this.orientation );\n\t\t\t\tthis._refreshValue();\n\t\t\t\tbreak;\n\t\t\tcase \"value\":\n\t\t\t\tthis._animateOff = true;\n\t\t\t\tthis._refreshValue();\n\t\t\t\tthis._change( null, 0 );\n\t\t\t\tthis._animateOff = false;\n\t\t\t\tbreak;\n\t\t\tcase \"values\":\n\t\t\t\tthis._animateOff = true;\n\t\t\t\tthis._refreshValue();\n\t\t\t\tfor ( i = 0; i \u003c valsLength; i += 1 ) {\n\t\t\t\t\tthis._change( null, i );\n\t\t\t\t}\n\t\t\t\tthis._animateOff = false;\n\t\t\t\tbreak;\n\t\t\tcase \"min\":\n\t\t\tcase \"max\":\n\t\t\t\tthis._animateOff = true;\n\t\t\t\tthis._refreshValue();\n\t\t\t\tthis._animateOff = false;\n\t\t\t\tbreak;\n\t\t\tcase \"range\":\n\t\t\t\tthis._animateOff = true;\n\t\t\t\tthis._refresh();\n\t\t\t\tthis._animateOff = false;\n\t\t\t\tbreak;\n\t\t}\n\t},\n\n\t//internal value getter\n\t// _value() returns value trimmed by min and max, aligned by step\n\t_value: function() {\n\t\tvar val = this.options.value;\n\t\tval = this._trimAlignValue( val );\n\n\t\treturn val;\n\t},\n\n\t//internal values getter\n\t// _values() returns array of values trimmed by min and max, aligned by step\n\t// _values( index ) returns single value trimmed by min and max, aligned by step\n\t_values: function( index ) {\n\t\tvar val,\n\t\t\tvals,\n\t\t\ti;\n\n\t\tif ( arguments.length ) {\n\t\t\tval = this.options.values[ index ];\n\t\t\tval = this._trimAlignValue( val );\n\n\t\t\treturn val;\n\t\t} else if ( this.options.values \u0026\u0026 this.options.values.length ) {\n\t\t\t// .slice() creates a copy of the array\n\t\t\t// this copy gets trimmed by min and max and then returned\n\t\t\tvals = this.options.values.slice();\n\t\t\tfor ( i = 0; i \u003c vals.length; i+= 1) {\n\t\t\t\tvals[ i ] = this._trimAlignValue( vals[ i ] );\n\t\t\t}\n\n\t\t\treturn vals;\n\t\t} else {\n\t\t\treturn [];\n\t\t}\n\t},\n\n\t// returns the step-aligned value that val is closest to, between (inclusive) min and max\n\t_trimAlignValue: function( val ) {\n\t\tif ( val \u003c= this._valueMin() ) {\n\t\t\treturn this._valueMin();\n\t\t}\n\t\tif ( val \u003e= this._valueMax() ) {\n\t\t\treturn this._valueMax();\n\t\t}\n\t\tvar step = ( this.options.step \u003e 0 ) ? this.options.step : 1,\n\t\t\tvalModStep = (val - this._valueMin()) % step,\n\t\t\talignValue = val - valModStep;\n\n\t\tif ( Math.abs(valModStep) * 2 \u003e= step ) {\n\t\t\talignValue += ( valModStep \u003e 0 ) ? step : ( -step );\n\t\t}\n\n\t\t// Since JavaScript has problems with large floats, round\n\t\t// the final value to 5 digits after the decimal point (see #4124)\n\t\treturn parseFloat( alignValue.toFixed(5) );\n\t},\n\n\t_valueMin: function() {\n\t\treturn this.options.min;\n\t},\n\n\t_valueMax: function() {\n\t\treturn this.options.max;\n\t},\n\n\t_refreshValue: function() {\n\t\tvar lastValPercent, valPercent, value, valueMin, valueMax,\n\t\t\toRange = this.options.range,\n\t\t\to = this.options,\n\t\t\tthat = this,\n\t\t\tanimate = ( !this._animateOff ) ? o.animate : false,\n\t\t\t_set = {};\n\n\t\tif ( this.options.values \u0026\u0026 this.options.values.length ) {\n\t\t\tthis.handles.each(function( i ) {\n\t\t\t\tvalPercent = ( that.values(i) - that._valueMin() ) / ( that._valueMax() - that._valueMin() ) * 100;\n\t\t\t\t_set[ that.orientation === \"horizontal\" ? \"left\" : \"bottom\" ] = valPercent + \"%\";\n\t\t\t\t$( this ).stop( 1, 1 )[ animate ? \"animate\" : \"css\" ]( _set, o.animate );\n\t\t\t\tif ( that.options.range === true ) {\n\t\t\t\t\tif ( that.orientation === \"horizontal\" ) {\n\t\t\t\t\t\tif ( i === 0 ) {\n\t\t\t\t\t\t\tthat.range.stop( 1, 1 )[ animate ? \"animate\" : \"css\" ]( { left: valPercent + \"%\" }, o.animate );\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif ( i === 1 ) {\n\t\t\t\t\t\t\tthat.range[ animate ? \"animate\" : \"css\" ]( { width: ( valPercent - lastValPercent ) + \"%\" }, { queue: false, duration: o.animate } );\n\t\t\t\t\t\t}\n\t\t\t\t\t} else {\n\t\t\t\t\t\tif ( i === 0 ) {\n\t\t\t\t\t\t\tthat.range.stop( 1, 1 )[ animate ? \"animate\" : \"css\" ]( { bottom: ( valPercent ) + \"%\" }, o.animate );\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif ( i === 1 ) {\n\t\t\t\t\t\t\tthat.range[ animate ? \"animate\" : \"css\" ]( { height: ( valPercent - lastValPercent ) + \"%\" }, { queue: false, duration: o.animate } );\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tlastValPercent = valPercent;\n\t\t\t});\n\t\t} else {\n\t\t\tvalue = this.value();\n\t\t\tvalueMin = this._valueMin();\n\t\t\tvalueMax = this._valueMax();\n\t\t\tvalPercent = ( valueMax !== valueMin ) ?\n\t\t\t\t\t( value - valueMin ) / ( valueMax - valueMin ) * 100 :\n\t\t\t\t\t0;\n\t\t\t_set[ this.orientation === \"horizontal\" ? \"left\" : \"bottom\" ] = valPercent + \"%\";\n\t\t\tthis.handle.stop( 1, 1 )[ animate ? \"animate\" : \"css\" ]( _set, o.animate );\n\n\t\t\tif ( oRange === \"min\" \u0026\u0026 this.orientation === \"horizontal\" ) {\n\t\t\t\tthis.range.stop( 1, 1 )[ animate ? \"animate\" : \"css\" ]( { width: valPercent + \"%\" }, o.animate );\n\t\t\t}\n\t\t\tif ( oRange === \"max\" \u0026\u0026 this.orientation === \"horizontal\" ) {\n\t\t\t\tthis.range[ animate ? \"animate\" : \"css\" ]( { width: ( 100 - valPercent ) + \"%\" }, { queue: false, duration: o.animate } );\n\t\t\t}\n\t\t\tif ( oRange === \"min\" \u0026\u0026 this.orientation === \"vertical\" ) {\n\t\t\t\tthis.range.stop( 1, 1 )[ animate ? \"animate\" : \"css\" ]( { height: valPercent + \"%\" }, o.animate );\n\t\t\t}\n\t\t\tif ( oRange === \"max\" \u0026\u0026 this.orientation === \"vertical\" ) {\n\t\t\t\tthis.range[ animate ? \"animate\" : \"css\" ]( { height: ( 100 - valPercent ) + \"%\" }, { queue: false, duration: o.animate } );\n\t\t\t}\n\t\t}\n\t},\n\n\t_handleEvents: {\n\t\tkeydown: function( event ) {\n\t\t\t/*jshint maxcomplexity:25*/\n\t\t\tvar allowed, curVal, newVal, step,\n\t\t\t\tindex = $( event.target ).data( \"ui-slider-handle-index\" );\n\n\t\t\tswitch ( event.keyCode ) {\n\t\t\t\tcase $.ui.keyCode.HOME:\n\t\t\t\tcase $.ui.keyCode.END:\n\t\t\t\tcase $.ui.keyCode.PAGE_UP:\n\t\t\t\tcase $.ui.keyCode.PAGE_DOWN:\n\t\t\t\tcase $.ui.keyCode.UP:\n\t\t\t\tcase $.ui.keyCode.RIGHT:\n\t\t\t\tcase $.ui.keyCode.DOWN:\n\t\t\t\tcase $.ui.keyCode.LEFT:\n\t\t\t\t\tevent.preventDefault();\n\t\t\t\t\tif ( !this._keySliding ) {\n\t\t\t\t\t\tthis._keySliding = true;\n\t\t\t\t\t\t$( event.target ).addClass( \"ui-state-active\" );\n\t\t\t\t\t\tallowed = this._start( event, index );\n\t\t\t\t\t\tif ( allowed === false ) {\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tstep = this.options.step;\n\t\t\tif ( this.options.values \u0026\u0026 this.options.values.length ) {\n\t\t\t\tcurVal = newVal = this.values( index );\n\t\t\t} else {\n\t\t\t\tcurVal = newVal = this.value();\n\t\t\t}\n\n\t\t\tswitch ( event.keyCode ) {\n\t\t\t\tcase $.ui.keyCode.HOME:\n\t\t\t\t\tnewVal = this._valueMin();\n\t\t\t\t\tbreak;\n\t\t\t\tcase $.ui.keyCode.END:\n\t\t\t\t\tnewVal = this._valueMax();\n\t\t\t\t\tbreak;\n\t\t\t\tcase $.ui.keyCode.PAGE_UP:\n\t\t\t\t\tnewVal = this._trimAlignValue( curVal + ( (this._valueMax() - this._valueMin()) / numPages ) );\n\t\t\t\t\tbreak;\n\t\t\t\tcase $.ui.keyCode.PAGE_DOWN:\n\t\t\t\t\tnewVal = this._trimAlignValue( curVal - ( (this._valueMax() - this._valueMin()) / numPages ) );\n\t\t\t\t\tbreak;\n\t\t\t\tcase $.ui.keyCode.UP:\n\t\t\t\tcase $.ui.keyCode.RIGHT:\n\t\t\t\t\tif ( curVal === this._valueMax() ) {\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t\tnewVal = this._trimAlignValue( curVal + step );\n\t\t\t\t\tbreak;\n\t\t\t\tcase $.ui.keyCode.DOWN:\n\t\t\t\tcase $.ui.keyCode.LEFT:\n\t\t\t\t\tif ( curVal === this._valueMin() ) {\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t\tnewVal = this._trimAlignValue( curVal - step );\n\t\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tthis._slide( event, index, newVal );\n\t\t},\n\t\tclick: function( event ) {\n\t\t\tevent.preventDefault();\n\t\t},\n\t\tkeyup: function( event ) {\n\t\t\tvar index = $( event.target ).data( \"ui-slider-handle-index\" );\n\n\t\t\tif ( this._keySliding ) {\n\t\t\t\tthis._keySliding = false;\n\t\t\t\tthis._stop( event, index );\n\t\t\t\tthis._change( event, index );\n\t\t\t\t$( event.target ).removeClass( \"ui-state-active\" );\n\t\t\t}\n\t\t}\n\t}\n\n});\n\n}(jQuery));\n\n(function( $ ) {\n\nfunction modifier( fn ) {\n\treturn function() {\n\t\tvar previous = this.element.val();\n\t\tfn.apply( this, arguments );\n\t\tthis._refresh();\n\t\tif ( previous !== this.element.val() ) {\n\t\t\tthis._trigger( \"change\" );\n\t\t}\n\t};\n}\n\n$.widget( \"ui.spinner\", {\n\tversion: \"1.10.2\",\n\tdefaultElement: \"\u003cinput\u003e\",\n\twidgetEventPrefix: \"spin\",\n\toptions: {\n\t\tculture: null,\n\t\ticons: {\n\t\t\tdown: \"ui-icon-triangle-1-s\",\n\t\t\tup: \"ui-icon-triangle-1-n\"\n\t\t},\n\t\tincremental: true,\n\t\tmax: null,\n\t\tmin: null,\n\t\tnumberFormat: null,\n\t\tpage: 10,\n\t\tstep: 1,\n\n\t\tchange: null,\n\t\tspin: null,\n\t\tstart: null,\n\t\tstop: null\n\t},\n\n\t_create: function() {\n\t\t// handle string values that need to be parsed\n\t\tthis._setOption( \"max\", this.options.max );\n\t\tthis._setOption( \"min\", this.options.min );\n\t\tthis._setOption( \"step\", this.options.step );\n\n\t\t// format the value, but don\u0027t constrain\n\t\tthis._value( this.element.val(), true );\n\n\t\tthis._draw();\n\t\tthis._on( this._events );\n\t\tthis._refresh();\n\n\t\t// turning off autocomplete prevents the browser from remembering the\n\t\t// value when navigating through history, so we re-enable autocomplete\n\t\t// if the page is unloaded before the widget is destroyed. #7790\n\t\tthis._on( this.window, {\n\t\t\tbeforeunload: function() {\n\t\t\t\tthis.element.removeAttr( \"autocomplete\" );\n\t\t\t}\n\t\t});\n\t},\n\n\t_getCreateOptions: function() {\n\t\tvar options = {},\n\t\t\telement = this.element;\n\n\t\t$.each( [ \"min\", \"max\", \"step\" ], function( i, option ) {\n\t\t\tvar value = element.attr( option );\n\t\t\tif ( value !== undefined \u0026\u0026 value.length ) {\n\t\t\t\toptions[ option ] = value;\n\t\t\t}\n\t\t});\n\n\t\treturn options;\n\t},\n\n\t_events: {\n\t\tkeydown: function( event ) {\n\t\t\tif ( this._start( event ) \u0026\u0026 this._keydown( event ) ) {\n\t\t\t\tevent.preventDefault();\n\t\t\t}\n\t\t},\n\t\tkeyup: \"_stop\",\n\t\tfocus: function() {\n\t\t\tthis.previous = this.element.val();\n\t\t},\n\t\tblur: function( event ) {\n\t\t\tif ( this.cancelBlur ) {\n\t\t\t\tdelete this.cancelBlur;\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tthis._stop();\n\t\t\tthis._refresh();\n\t\t\tif ( this.previous !== this.element.val() ) {\n\t\t\t\tthis._trigger( \"change\", event );\n\t\t\t}\n\t\t},\n\t\tmousewheel: function( event, delta ) {\n\t\t\tif ( !delta ) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tif ( !this.spinning \u0026\u0026 !this._start( event ) ) {\n\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\tthis._spin( (delta \u003e 0 ? 1 : -1) * this.options.step, event );\n\t\t\tclearTimeout( this.mousewheelTimer );\n\t\t\tthis.mousewheelTimer = this._delay(function() {\n\t\t\t\tif ( this.spinning ) {\n\t\t\t\t\tthis._stop( event );\n\t\t\t\t}\n\t\t\t}, 100 );\n\t\t\tevent.preventDefault();\n\t\t},\n\t\t\"mousedown .ui-spinner-button\": function( event ) {\n\t\t\tvar previous;\n\n\t\t\t// We never want the buttons to have focus; whenever the user is\n\t\t\t// interacting with the spinner, the focus should be on the input.\n\t\t\t// If the input is focused then this.previous is properly set from\n\t\t\t// when the input first received focus. If the input is not focused\n\t\t\t// then we need to set this.previous based on the value before spinning.\n\t\t\tprevious = this.element[0] === this.document[0].activeElement ?\n\t\t\t\tthis.previous : this.element.val();\n\t\t\tfunction checkFocus() {\n\t\t\t\tvar isActive = this.element[0] === this.document[0].activeElement;\n\t\t\t\tif ( !isActive ) {\n\t\t\t\t\tthis.element.focus();\n\t\t\t\t\tthis.previous = previous;\n\t\t\t\t\t// support: IE\n\t\t\t\t\t// IE sets focus asynchronously, so we need to check if focus\n\t\t\t\t\t// moved off of the input because the user clicked on the button.\n\t\t\t\t\tthis._delay(function() {\n\t\t\t\t\t\tthis.previous = previous;\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// ensure focus is on (or stays on) the text field\n\t\t\tevent.preventDefault();\n\t\t\tcheckFocus.call( this );\n\n\t\t\t// support: IE\n\t\t\t// IE doesn\u0027t prevent moving focus even with event.preventDefault()\n\t\t\t// so we set a flag to know when we should ignore the blur event\n\t\t\t// and check (again) if focus moved off of the input.\n\t\t\tthis.cancelBlur = true;\n\t\t\tthis._delay(function() {\n\t\t\t\tdelete this.cancelBlur;\n\t\t\t\tcheckFocus.call( this );\n\t\t\t});\n\n\t\t\tif ( this._start( event ) === false ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tthis._repeat( null, $( event.currentTarget ).hasClass( \"ui-spinner-up\" ) ? 1 : -1, event );\n\t\t},\n\t\t\"mouseup .ui-spinner-button\": \"_stop\",\n\t\t\"mouseenter .ui-spinner-button\": function( event ) {\n\t\t\t// button will add ui-state-active if mouse was down while mouseleave and kept down\n\t\t\tif ( !$( event.currentTarget ).hasClass( \"ui-state-active\" ) ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif ( this._start( event ) === false ) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\tthis._repeat( null, $( event.currentTarget ).hasClass( \"ui-spinner-up\" ) ? 1 : -1, event );\n\t\t},\n\t\t// TODO: do we really want to consider this a stop?\n\t\t// shouldn\u0027t we just stop the repeater and wait until mouseup before\n\t\t// we trigger the stop event?\n\t\t\"mouseleave .ui-spinner-button\": \"_stop\"\n\t},\n\n\t_draw: function() {\n\t\tvar uiSpinner = this.uiSpinner = this.element\n\t\t\t.addClass( \"ui-spinner-input\" )\n\t\t\t.attr( \"autocomplete\", \"off\" )\n\t\t\t.wrap( this._uiSpinnerHtml() )\n\t\t\t.parent()\n\t\t\t\t// add buttons\n\t\t\t\t.append( this._buttonHtml() );\n\n\t\tthis.element.attr( \"role\", \"spinbutton\" );\n\n\t\t// button bindings\n\t\tthis.buttons = uiSpinner.find( \".ui-spinner-button\" )\n\t\t\t.attr( \"tabIndex\", -1 )\n\t\t\t.button()\n\t\t\t.removeClass( \"ui-corner-all\" );\n\n\t\t// IE 6 doesn\u0027t understand height: 50% for the buttons\n\t\t// unless the wrapper has an explicit height\n\t\tif ( this.buttons.height() \u003e Math.ceil( uiSpinner.height() * 0.5 ) \u0026\u0026\n\t\t\t\tuiSpinner.height() \u003e 0 ) {\n\t\t\tuiSpinner.height( uiSpinner.height() );\n\t\t}\n\n\t\t// disable spinner if element was already disabled\n\t\tif ( this.options.disabled ) {\n\t\t\tthis.disable();\n\t\t}\n\t},\n\n\t_keydown: function( event ) {\n\t\tvar options = this.options,\n\t\t\tkeyCode = $.ui.keyCode;\n\n\t\tswitch ( event.keyCode ) {\n\t\tcase keyCode.UP:\n\t\t\tthis._repeat( null, 1, event );\n\t\t\treturn true;\n\t\tcase keyCode.DOWN:\n\t\t\tthis._repeat( null, -1, event );\n\t\t\treturn true;\n\t\tcase keyCode.PAGE_UP:\n\t\t\tthis._repeat( null, options.page, event );\n\t\t\treturn true;\n\t\tcase keyCode.PAGE_DOWN:\n\t\t\tthis._repeat( null, -options.page, event );\n\t\t\treturn true;\n\t\t}\n\n\t\treturn false;\n\t},\n\n\t_uiSpinnerHtml: function() {\n\t\treturn \"\u003cspan class=\u0027ui-spinner ui-widget ui-widget-content ui-corner-all\u0027\u003e\u003c/span\u003e\";\n\t},\n\n\t_buttonHtml: function() {\n\t\treturn \"\" +\n\t\t\t\"\u003ca class=\u0027ui-spinner-button ui-spinner-up ui-corner-tr\u0027\u003e\" +\n\t\t\t\t\"\u003cspan class=\u0027ui-icon \" + this.options.icons.up + \"\u0027\u003e\u0026#9650;\u003c/span\u003e\" +\n\t\t\t\"\u003c/a\u003e\" +\n\t\t\t\"\u003ca class=\u0027ui-spinner-button ui-spinner-down ui-corner-br\u0027\u003e\" +\n\t\t\t\t\"\u003cspan class=\u0027ui-icon \" + this.options.icons.down + \"\u0027\u003e\u0026#9660;\u003c/span\u003e\" +\n\t\t\t\"\u003c/a\u003e\";\n\t},\n\n\t_start: function( event ) {\n\t\tif ( !this.spinning \u0026\u0026 this._trigger( \"start\", event ) === false ) {\n\t\t\treturn false;\n\t\t}\n\n\t\tif ( !this.counter ) {\n\t\t\tthis.counter = 1;\n\t\t}\n\t\tthis.spinning = true;\n\t\treturn true;\n\t},\n\n\t_repeat: function( i, steps, event ) {\n\t\ti = i || 500;\n\n\t\tclearTimeout( this.timer );\n\t\tthis.timer = this._delay(function() {\n\t\t\tthis._repeat( 40, steps, event );\n\t\t}, i );\n\n\t\tthis._spin( steps * this.options.step, event );\n\t},\n\n\t_spin: function( step, event ) {\n\t\tvar value = this.value() || 0;\n\n\t\tif ( !this.counter ) {\n\t\t\tthis.counter = 1;\n\t\t}\n\n\t\tvalue = this._adjustValue( value + step * this._increment( this.counter ) );\n\n\t\tif ( !this.spinning || this._trigger( \"spin\", event, { value: value } ) !== false) {\n\t\t\tthis._value( value );\n\t\t\tthis.counter++;\n\t\t}\n\t},\n\n\t_increment: function( i ) {\n\t\tvar incremental = this.options.incremental;\n\n\t\tif ( incremental ) {\n\t\t\treturn $.isFunction( incremental ) ?\n\t\t\t\tincremental( i ) :\n\t\t\t\tMath.floor( i*i*i/50000 - i*i/500 + 17*i/200 + 1 );\n\t\t}\n\n\t\treturn 1;\n\t},\n\n\t_precision: function() {\n\t\tvar precision = this._precisionOf( this.options.step );\n\t\tif ( this.options.min !== null ) {\n\t\t\tprecision = Math.max( precision, this._precisionOf( this.options.min ) );\n\t\t}\n\t\treturn precision;\n\t},\n\n\t_precisionOf: function( num ) {\n\t\tvar str = num.toString(),\n\t\t\tdecimal = str.indexOf( \".\" );\n\t\treturn decimal === -1 ? 0 : str.length - decimal - 1;\n\t},\n\n\t_adjustValue: function( value ) {\n\t\tvar base, aboveMin,\n\t\t\toptions = this.options;\n\n\t\t// make sure we\u0027re at a valid step\n\t\t// - find out where we are relative to the base (min or 0)\n\t\tbase = options.min !== null ? options.min : 0;\n\t\taboveMin = value - base;\n\t\t// - round to the nearest step\n\t\taboveMin = Math.round(aboveMin / options.step) * options.step;\n\t\t// - rounding is based on 0, so adjust back to our base\n\t\tvalue = base + aboveMin;\n\n\t\t// fix precision from bad JS floating point math\n\t\tvalue = parseFloat( value.toFixed( this._precision() ) );\n\n\t\t// clamp the value\n\t\tif ( options.max !== null \u0026\u0026 value \u003e options.max) {\n\t\t\treturn options.max;\n\t\t}\n\t\tif ( options.min !== null \u0026\u0026 value \u003c options.min ) {\n\t\t\treturn options.min;\n\t\t}\n\n\t\treturn value;\n\t},\n\n\t_stop: function( event ) {\n\t\tif ( !this.spinning ) {\n\t\t\treturn;\n\t\t}\n\n\t\tclearTimeout( this.timer );\n\t\tclearTimeout( this.mousewheelTimer );\n\t\tthis.counter = 0;\n\t\tthis.spinning = false;\n\t\tthis._trigger( \"stop\", event );\n\t},\n\n\t_setOption: function( key, value ) {\n\t\tif ( key === \"culture\" || key === \"numberFormat\" ) {\n\t\t\tvar prevValue = this._parse( this.element.val() );\n\t\t\tthis.options[ key ] = value;\n\t\t\tthis.element.val( this._format( prevValue ) );\n\t\t\treturn;\n\t\t}\n\n\t\tif ( key === \"max\" || key === \"min\" || key === \"step\" ) {\n\t\t\tif ( typeof value === \"string\" ) {\n\t\t\t\tvalue = this._parse( value );\n\t\t\t}\n\t\t}\n\t\tif ( key === \"icons\" ) {\n\t\t\tthis.buttons.first().find( \".ui-icon\" )\n\t\t\t\t.removeClass( this.options.icons.up )\n\t\t\t\t.addClass( value.up );\n\t\t\tthis.buttons.last().find( \".ui-icon\" )\n\t\t\t\t.removeClass( this.options.icons.down )\n\t\t\t\t.addClass( value.down );\n\t\t}\n\n\t\tthis._super( key, value );\n\n\t\tif ( key === \"disabled\" ) {\n\t\t\tif ( value ) {\n\t\t\t\tthis.element.prop( \"disabled\", true );\n\t\t\t\tthis.buttons.button( \"disable\" );\n\t\t\t} else {\n\t\t\t\tthis.element.prop( \"disabled\", false );\n\t\t\t\tthis.buttons.button( \"enable\" );\n\t\t\t}\n\t\t}\n\t},\n\n\t_setOptions: modifier(function( options ) {\n\t\tthis._super( options );\n\t\tthis._value( this.element.val() );\n\t}),\n\n\t_parse: function( val ) {\n\t\tif ( typeof val === \"string\" \u0026\u0026 val !== \"\" ) {\n\t\t\tval = window.Globalize \u0026\u0026 this.options.numberFormat ?\n\t\t\t\tGlobalize.parseFloat( val, 10, this.options.culture ) : +val;\n\t\t}\n\t\treturn val === \"\" || isNaN( val ) ? null : val;\n\t},\n\n\t_format: function( value ) {\n\t\tif ( value === \"\" ) {\n\t\t\treturn \"\";\n\t\t}\n\t\treturn window.Globalize \u0026\u0026 this.options.numberFormat ?\n\t\t\tGlobalize.format( value, this.options.numberFormat, this.options.culture ) :\n\t\t\tvalue;\n\t},\n\n\t_refresh: function() {\n\t\tthis.element.attr({\n\t\t\t\"aria-valuemin\": this.options.min,\n\t\t\t\"aria-valuemax\": this.options.max,\n\t\t\t// TODO: what should we do with values that can\u0027t be parsed?\n\t\t\t\"aria-valuenow\": this._parse( this.element.val() )\n\t\t});\n\t},\n\n\t// update the value without triggering change\n\t_value: function( value, allowAny ) {\n\t\tvar parsed;\n\t\tif ( value !== \"\" ) {\n\t\t\tparsed = this._parse( value );\n\t\t\tif ( parsed !== null ) {\n\t\t\t\tif ( !allowAny ) {\n\t\t\t\t\tparsed = this._adjustValue( parsed );\n\t\t\t\t}\n\t\t\t\tvalue = this._format( parsed );\n\t\t\t}\n\t\t}\n\t\tthis.element.val( value );\n\t\tthis._refresh();\n\t},\n\n\t_destroy: function() {\n\t\tthis.element\n\t\t\t.removeClass( \"ui-spinner-input\" )\n\t\t\t.prop( \"disabled\", false )\n\t\t\t.removeAttr( \"autocomplete\" )\n\t\t\t.removeAttr( \"role\" )\n\t\t\t.removeAttr( \"aria-valuemin\" )\n\t\t\t.removeAttr( \"aria-valuemax\" )\n\t\t\t.removeAttr( \"aria-valuenow\" );\n\t\tthis.uiSpinner.replaceWith( this.element );\n\t},\n\n\tstepUp: modifier(function( steps ) {\n\t\tthis._stepUp( steps );\n\t}),\n\t_stepUp: function( steps ) {\n\t\tif ( this._start() ) {\n\t\t\tthis._spin( (steps || 1) * this.options.step );\n\t\t\tthis._stop();\n\t\t}\n\t},\n\n\tstepDown: modifier(function( steps ) {\n\t\tthis._stepDown( steps );\n\t}),\n\t_stepDown: function( steps ) {\n\t\tif ( this._start() ) {\n\t\t\tthis._spin( (steps || 1) * -this.options.step );\n\t\t\tthis._stop();\n\t\t}\n\t},\n\n\tpageUp: modifier(function( pages ) {\n\t\tthis._stepUp( (pages || 1) * this.options.page );\n\t}),\n\n\tpageDown: modifier(function( pages ) {\n\t\tthis._stepDown( (pages || 1) * this.options.page );\n\t}),\n\n\tvalue: function( newVal ) {\n\t\tif ( !arguments.length ) {\n\t\t\treturn this._parse( this.element.val() );\n\t\t}\n\t\tmodifier( this._value ).call( this, newVal );\n\t},\n\n\twidget: function() {\n\t\treturn this.uiSpinner;\n\t}\n});\n\n}( jQuery ) );\n\n(function( $, undefined ) {\n\nvar tabId = 0,\n\trhash = /#.*$/;\n\nfunction getNextTabId() {\n\treturn ++tabId;\n}\n\nfunction isLocal( anchor ) {\n\treturn anchor.hash.length \u003e 1 \u0026\u0026\n\t\tdecodeURIComponent( anchor.href.replace( rhash, \"\" ) ) ===\n\t\t\tdecodeURIComponent( location.href.replace( rhash, \"\" ) );\n}\n\n$.widget( \"ui.tabs\", {\n\tversion: \"1.10.2\",\n\tdelay: 300,\n\toptions: {\n\t\tactive: null,\n\t\tcollapsible: false,\n\t\tevent: \"click\",\n\t\theightStyle: \"content\",\n\t\thide: null,\n\t\tshow: null,\n\n\t\t// callbacks\n\t\tactivate: null,\n\t\tbeforeActivate: null,\n\t\tbeforeLoad: null,\n\t\tload: null\n\t},\n\n\t_create: function() {\n\t\tvar that = this,\n\t\t\toptions = this.options;\n\n\t\tthis.running = false;\n\n\t\tthis.element\n\t\t\t.addClass( \"ui-tabs ui-widget ui-widget-content ui-corner-all\" )\n\t\t\t.toggleClass( \"ui-tabs-collapsible\", options.collapsible )\n\t\t\t// Prevent users from focusing disabled tabs via click\n\t\t\t.delegate( \".ui-tabs-nav \u003e li\", \"mousedown\" + this.eventNamespace, function( event ) {\n\t\t\t\tif ( $( this ).is( \".ui-state-disabled\" ) ) {\n\t\t\t\t\tevent.preventDefault();\n\t\t\t\t}\n\t\t\t})\n\t\t\t// support: IE \u003c9\n\t\t\t// Preventing the default action in mousedown doesn\u0027t prevent IE\n\t\t\t// from focusing the element, so if the anchor gets focused, blur.\n\t\t\t// We don\u0027t have to worry about focusing the previously focused\n\t\t\t// element since clicking on a non-focusable element should focus\n\t\t\t// the body anyway.\n\t\t\t.delegate( \".ui-tabs-anchor\", \"focus\" + this.eventNamespace, function() {\n\t\t\t\tif ( $( this ).closest( \"li\" ).is( \".ui-state-disabled\" ) ) {\n\t\t\t\t\tthis.blur();\n\t\t\t\t}\n\t\t\t});\n\n\t\tthis._processTabs();\n\t\toptions.active = this._initialActive();\n\n\t\t// Take disabling tabs via class attribute from HTML\n\t\t// into account and update option properly.\n\t\tif ( $.isArray( options.disabled ) ) {\n\t\t\toptions.disabled = $.unique( options.disabled.concat(\n\t\t\t\t$.map( this.tabs.filter( \".ui-state-disabled\" ), function( li ) {\n\t\t\t\t\treturn that.tabs.index( li );\n\t\t\t\t})\n\t\t\t) ).sort();\n\t\t}\n\n\t\t// check for length avoids error when initializing empty list\n\t\tif ( this.options.active !== false \u0026\u0026 this.anchors.length ) {\n\t\t\tthis.active = this._findActive( options.active );\n\t\t} else {\n\t\t\tthis.active = $();\n\t\t}\n\n\t\tthis._refresh();\n\n\t\tif ( this.active.length ) {\n\t\t\tthis.load( options.active );\n\t\t}\n\t},\n\n\t_initialActive: function() {\n\t\tvar active = this.options.active,\n\t\t\tcollapsible = this.options.collapsible,\n\t\t\tlocationHash = location.hash.substring( 1 );\n\n\t\tif ( active === null ) {\n\t\t\t// check the fragment identifier in the URL\n\t\t\tif ( locationHash ) {\n\t\t\t\tthis.tabs.each(function( i, tab ) {\n\t\t\t\t\tif ( $( tab ).attr( \"aria-controls\" ) === locationHash ) {\n\t\t\t\t\t\tactive = i;\n\t\t\t\t\t\treturn false;\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t}\n\n\t\t\t// check for a tab marked active via a class\n\t\t\tif ( active === null ) {\n\t\t\t\tactive = this.tabs.index( this.tabs.filter( \".ui-tabs-active\" ) );\n\t\t\t}\n\n\t\t\t// no active tab, set to false\n\t\t\tif ( active === null || active === -1 ) {\n\t\t\t\tactive = this.tabs.length ? 0 : false;\n\t\t\t}\n\t\t}\n\n\t\t// handle numbers: negative, out of range\n\t\tif ( active !== false ) {\n\t\t\tactive = this.tabs.index( this.tabs.eq( active ) );\n\t\t\tif ( active === -1 ) {\n\t\t\t\tactive = collapsible ? false : 0;\n\t\t\t}\n\t\t}\n\n\t\t// don\u0027t allow collapsible: false and active: false\n\t\tif ( !collapsible \u0026\u0026 active === false \u0026\u0026 this.anchors.length ) {\n\t\t\tactive = 0;\n\t\t}\n\n\t\treturn active;\n\t},\n\n\t_getCreateEventData: function() {\n\t\treturn {\n\t\t\ttab: this.active,\n\t\t\tpanel: !this.active.length ? $() : this._getPanelForTab( this.active )\n\t\t};\n\t},\n\n\t_tabKeydown: function( event ) {\n\t\t/*jshint maxcomplexity:15*/\n\t\tvar focusedTab = $( this.document[0].activeElement ).closest( \"li\" ),\n\t\t\tselectedIndex = this.tabs.index( focusedTab ),\n\t\t\tgoingForward = true;\n\n\t\tif ( this._handlePageNav( event ) ) {\n\t\t\treturn;\n\t\t}\n\n\t\tswitch ( event.keyCode ) {\n\t\t\tcase $.ui.keyCode.RIGHT:\n\t\t\tcase $.ui.keyCode.DOWN:\n\t\t\t\tselectedIndex++;\n\t\t\t\tbreak;\n\t\t\tcase $.ui.keyCode.UP:\n\t\t\tcase $.ui.keyCode.LEFT:\n\t\t\t\tgoingForward = false;\n\t\t\t\tselectedIndex--;\n\t\t\t\tbreak;\n\t\t\tcase $.ui.keyCode.END:\n\t\t\t\tselectedIndex = this.anchors.length - 1;\n\t\t\t\tbreak;\n\t\t\tcase $.ui.keyCode.HOME:\n\t\t\t\tselectedIndex = 0;\n\t\t\t\tbreak;\n\t\t\tcase $.ui.keyCode.SPACE:\n\t\t\t\t// Activate only, no collapsing\n\t\t\t\tevent.preventDefault();\n\t\t\t\tclearTimeout( this.activating );\n\t\t\t\tthis._activate( selectedIndex );\n\t\t\t\treturn;\n\t\t\tcase $.ui.keyCode.ENTER:\n\t\t\t\t// Toggle (cancel delayed activation, allow collapsing)\n\t\t\t\tevent.preventDefault();\n\t\t\t\tclearTimeout( this.activating );\n\t\t\t\t// Determine if we should collapse or activate\n\t\t\t\tthis._activate( selectedIndex === this.options.active ? false : selectedIndex );\n\t\t\t\treturn;\n\t\t\tdefault:\n\t\t\t\treturn;\n\t\t}\n\n\t\t// Focus the appropriate tab, based on which key was pressed\n\t\tevent.preventDefault();\n\t\tclearTimeout( this.activating );\n\t\tselectedIndex = this._focusNextTab( selectedIndex, goingForward );\n\n\t\t// Navigating with control key will prevent automatic activation\n\t\tif ( !event.ctrlKey ) {\n\t\t\t// Update aria-selected immediately so that AT think the tab is already selected.\n\t\t\t// Otherwise AT may confuse the user by stating that they need to activate the tab,\n\t\t\t// but the tab will already be activated by the time the announcement finishes.\n\t\t\tfocusedTab.attr( \"aria-selected\", \"false\" );\n\t\t\tthis.tabs.eq( selectedIndex ).attr( \"aria-selected\", \"true\" );\n\n\t\t\tthis.activating = this._delay(function() {\n\t\t\t\tthis.option( \"active\", selectedIndex );\n\t\t\t}, this.delay );\n\t\t}\n\t},\n\n\t_panelKeydown: function( event ) {\n\t\tif ( this._handlePageNav( event ) ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Ctrl+up moves focus to the current tab\n\t\tif ( event.ctrlKey \u0026\u0026 event.keyCode === $.ui.keyCode.UP ) {\n\t\t\tevent.preventDefault();\n\t\t\tthis.active.focus();\n\t\t}\n\t},\n\n\t// Alt+page up/down moves focus to the previous/next tab (and activates)\n\t_handlePageNav: function( event ) {\n\t\tif ( event.altKey \u0026\u0026 event.keyCode === $.ui.keyCode.PAGE_UP ) {\n\t\t\tthis._activate( this._focusNextTab( this.options.active - 1, false ) );\n\t\t\treturn true;\n\t\t}\n\t\tif ( event.altKey \u0026\u0026 event.keyCode === $.ui.keyCode.PAGE_DOWN ) {\n\t\t\tthis._activate( this._focusNextTab( this.options.active + 1, true ) );\n\t\t\treturn true;\n\t\t}\n\t},\n\n\t_findNextTab: function( index, goingForward ) {\n\t\tvar lastTabIndex = this.tabs.length - 1;\n\n\t\tfunction constrain() {\n\t\t\tif ( index \u003e lastTabIndex ) {\n\t\t\t\tindex = 0;\n\t\t\t}\n\t\t\tif ( index \u003c 0 ) {\n\t\t\t\tindex = lastTabIndex;\n\t\t\t}\n\t\t\treturn index;\n\t\t}\n\n\t\twhile ( $.inArray( constrain(), this.options.disabled ) !== -1 ) {\n\t\t\tindex = goingForward ? index + 1 : index - 1;\n\t\t}\n\n\t\treturn index;\n\t},\n\n\t_focusNextTab: function( index, goingForward ) {\n\t\tindex = this._findNextTab( index, goingForward );\n\t\tthis.tabs.eq( index ).focus();\n\t\treturn index;\n\t},\n\n\t_setOption: function( key, value ) {\n\t\tif ( key === \"active\" ) {\n\t\t\t// _activate() will handle invalid values and update this.options\n\t\t\tthis._activate( value );\n\t\t\treturn;\n\t\t}\n\n\t\tif ( key === \"disabled\" ) {\n\t\t\t// don\u0027t use the widget factory\u0027s disabled handling\n\t\t\tthis._setupDisabled( value );\n\t\t\treturn;\n\t\t}\n\n\t\tthis._super( key, value);\n\n\t\tif ( key === \"collapsible\" ) {\n\t\t\tthis.element.toggleClass( \"ui-tabs-collapsible\", value );\n\t\t\t// Setting collapsible: false while collapsed; open first panel\n\t\t\tif ( !value \u0026\u0026 this.options.active === false ) {\n\t\t\t\tthis._activate( 0 );\n\t\t\t}\n\t\t}\n\n\t\tif ( key === \"event\" ) {\n\t\t\tthis._setupEvents( value );\n\t\t}\n\n\t\tif ( key === \"heightStyle\" ) {\n\t\t\tthis._setupHeightStyle( value );\n\t\t}\n\t},\n\n\t_tabId: function( tab ) {\n\t\treturn tab.attr( \"aria-controls\" ) || \"ui-tabs-\" + getNextTabId();\n\t},\n\n\t_sanitizeSelector: function( hash ) {\n\t\treturn hash ? hash.replace( /[!\"$%\u0026\u0027()*+,.\\/:;\u003c=\u003e?@\\[\\]\\^`{|}~]/g, \"\\\\$\u0026\" ) : \"\";\n\t},\n\n\trefresh: function() {\n\t\tvar options = this.options,\n\t\t\tlis = this.tablist.children( \":has(a[href])\" );\n\n\t\t// get disabled tabs from class attribute from HTML\n\t\t// this will get converted to a boolean if needed in _refresh()\n\t\toptions.disabled = $.map( lis.filter( \".ui-state-disabled\" ), function( tab ) {\n\t\t\treturn lis.index( tab );\n\t\t});\n\n\t\tthis._processTabs();\n\n\t\t// was collapsed or no tabs\n\t\tif ( options.active === false || !this.anchors.length ) {\n\t\t\toptions.active = false;\n\t\t\tthis.active = $();\n\t\t// was active, but active tab is gone\n\t\t} else if ( this.active.length \u0026\u0026 !$.contains( this.tablist[ 0 ], this.active[ 0 ] ) ) {\n\t\t\t// all remaining tabs are disabled\n\t\t\tif ( this.tabs.length === options.disabled.length ) {\n\t\t\t\toptions.active = false;\n\t\t\t\tthis.active = $();\n\t\t\t// activate previous tab\n\t\t\t} else {\n\t\t\t\tthis._activate( this._findNextTab( Math.max( 0, options.active - 1 ), false ) );\n\t\t\t}\n\t\t// was active, active tab still exists\n\t\t} else {\n\t\t\t// make sure active index is correct\n\t\t\toptions.active = this.tabs.index( this.active );\n\t\t}\n\n\t\tthis._refresh();\n\t},\n\n\t_refresh: function() {\n\t\tthis._setupDisabled( this.options.disabled );\n\t\tthis._setupEvents( this.options.event );\n\t\tthis._setupHeightStyle( this.options.heightStyle );\n\n\t\tthis.tabs.not( this.active ).attr({\n\t\t\t\"aria-selected\": \"false\",\n\t\t\ttabIndex: -1\n\t\t});\n\t\tthis.panels.not( this._getPanelForTab( this.active ) )\n\t\t\t.hide()\n\t\t\t.attr({\n\t\t\t\t\"aria-expanded\": \"false\",\n\t\t\t\t\"aria-hidden\": \"true\"\n\t\t\t});\n\n\t\t// Make sure one tab is in the tab order\n\t\tif ( !this.active.length ) {\n\t\t\tthis.tabs.eq( 0 ).attr( \"tabIndex\", 0 );\n\t\t} else {\n\t\t\tthis.active\n\t\t\t\t.addClass( \"ui-tabs-active ui-state-active\" )\n\t\t\t\t.attr({\n\t\t\t\t\t\"aria-selected\": \"true\",\n\t\t\t\t\ttabIndex: 0\n\t\t\t\t});\n\t\t\tthis._getPanelForTab( this.active )\n\t\t\t\t.show()\n\t\t\t\t.attr({\n\t\t\t\t\t\"aria-expanded\": \"true\",\n\t\t\t\t\t\"aria-hidden\": \"false\"\n\t\t\t\t});\n\t\t}\n\t},\n\n\t_processTabs: function() {\n\t\tvar that = this;\n\n\t\tthis.tablist = this._getList()\n\t\t\t.addClass( \"ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all\" )\n\t\t\t.attr( \"role\", \"tablist\" );\n\n\t\tthis.tabs = this.tablist.find( \"\u003e li:has(a[href])\" )\n\t\t\t.addClass( \"ui-state-default ui-corner-top\" )\n\t\t\t.attr({\n\t\t\t\trole: \"tab\",\n\t\t\t\ttabIndex: -1\n\t\t\t});\n\n\t\tthis.anchors = this.tabs.map(function() {\n\t\t\t\treturn $( \"a\", this )[ 0 ];\n\t\t\t})\n\t\t\t.addClass( \"ui-tabs-anchor\" )\n\t\t\t.attr({\n\t\t\t\trole: \"presentation\",\n\t\t\t\ttabIndex: -1\n\t\t\t});\n\n\t\tthis.panels = $();\n\n\t\tthis.anchors.each(function( i, anchor ) {\n\t\t\tvar selector, panel, panelId,\n\t\t\t\tanchorId = $( anchor ).uniqueId().attr( \"id\" ),\n\t\t\t\ttab = $( anchor ).closest( \"li\" ),\n\t\t\t\toriginalAriaControls = tab.attr( \"aria-controls\" );\n\n\t\t\t// inline tab\n\t\t\tif ( isLocal( anchor ) ) {\n\t\t\t\tselector = anchor.hash;\n\t\t\t\tpanel = that.element.find( that._sanitizeSelector( selector ) );\n\t\t\t// remote tab\n\t\t\t} else {\n\t\t\t\tpanelId = that._tabId( tab );\n\t\t\t\tselector = \"#\" + panelId;\n\t\t\t\tpanel = that.element.find( selector );\n\t\t\t\tif ( !panel.length ) {\n\t\t\t\t\tpanel = that._createPanel( panelId );\n\t\t\t\t\tpanel.insertAfter( that.panels[ i - 1 ] || that.tablist );\n\t\t\t\t}\n\t\t\t\tpanel.attr( \"aria-live\", \"polite\" );\n\t\t\t}\n\n\t\t\tif ( panel.length) {\n\t\t\t\tthat.panels = that.panels.add( panel );\n\t\t\t}\n\t\t\tif ( originalAriaControls ) {\n\t\t\t\ttab.data( \"ui-tabs-aria-controls\", originalAriaControls );\n\t\t\t}\n\t\t\ttab.attr({\n\t\t\t\t\"aria-controls\": selector.substring( 1 ),\n\t\t\t\t\"aria-labelledby\": anchorId\n\t\t\t});\n\t\t\tpanel.attr( \"aria-labelledby\", anchorId );\n\t\t});\n\n\t\tthis.panels\n\t\t\t.addClass( \"ui-tabs-panel ui-widget-content ui-corner-bottom\" )\n\t\t\t.attr( \"role\", \"tabpanel\" );\n\t},\n\n\t// allow overriding how to find the list for rare usage scenarios (#7715)\n\t_getList: function() {\n\t\treturn this.element.find( \"ol,ul\" ).eq( 0 );\n\t},\n\n\t_createPanel: function( id ) {\n\t\treturn $( \"\u003cdiv\u003e\" )\n\t\t\t.attr( \"id\", id )\n\t\t\t.addClass( \"ui-tabs-panel ui-widget-content ui-corner-bottom\" )\n\t\t\t.data( \"ui-tabs-destroy\", true );\n\t},\n\n\t_setupDisabled: function( disabled ) {\n\t\tif ( $.isArray( disabled ) ) {\n\t\t\tif ( !disabled.length ) {\n\t\t\t\tdisabled = false;\n\t\t\t} else if ( disabled.length === this.anchors.length ) {\n\t\t\t\tdisabled = true;\n\t\t\t}\n\t\t}\n\n\t\t// disable tabs\n\t\tfor ( var i = 0, li; ( li = this.tabs[ i ] ); i++ ) {\n\t\t\tif ( disabled === true || $.inArray( i, disabled ) !== -1 ) {\n\t\t\t\t$( li )\n\t\t\t\t\t.addClass( \"ui-state-disabled\" )\n\t\t\t\t\t.attr( \"aria-disabled\", \"true\" );\n\t\t\t} else {\n\t\t\t\t$( li )\n\t\t\t\t\t.removeClass( \"ui-state-disabled\" )\n\t\t\t\t\t.removeAttr( \"aria-disabled\" );\n\t\t\t}\n\t\t}\n\n\t\tthis.options.disabled = disabled;\n\t},\n\n\t_setupEvents: function( event ) {\n\t\tvar events = {\n\t\t\tclick: function( event ) {\n\t\t\t\tevent.preventDefault();\n\t\t\t}\n\t\t};\n\t\tif ( event ) {\n\t\t\t$.each( event.split(\" \"), function( index, eventName ) {\n\t\t\t\tevents[ eventName ] = \"_eventHandler\";\n\t\t\t});\n\t\t}\n\n\t\tthis._off( this.anchors.add( this.tabs ).add( this.panels ) );\n\t\tthis._on( this.anchors, events );\n\t\tthis._on( this.tabs, { keydown: \"_tabKeydown\" } );\n\t\tthis._on( this.panels, { keydown: \"_panelKeydown\" } );\n\n\t\tthis._focusable( this.tabs );\n\t\tthis._hoverable( this.tabs );\n\t},\n\n\t_setupHeightStyle: function( heightStyle ) {\n\t\tvar maxHeight,\n\t\t\tparent = this.element.parent();\n\n\t\tif ( heightStyle === \"fill\" ) {\n\t\t\tmaxHeight = parent.height();\n\t\t\tmaxHeight -= this.element.outerHeight() - this.element.height();\n\n\t\t\tthis.element.siblings( \":visible\" ).each(function() {\n\t\t\t\tvar elem = $( this ),\n\t\t\t\t\tposition = elem.css( \"position\" );\n\n\t\t\t\tif ( position === \"absolute\" || position === \"fixed\" ) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tmaxHeight -= elem.outerHeight( true );\n\t\t\t});\n\n\t\t\tthis.element.children().not( this.panels ).each(function() {\n\t\t\t\tmaxHeight -= $( this ).outerHeight( true );\n\t\t\t});\n\n\t\t\tthis.panels.each(function() {\n\t\t\t\t$( this ).height( Math.max( 0, maxHeight -\n\t\t\t\t\t$( this ).innerHeight() + $( this ).height() ) );\n\t\t\t})\n\t\t\t.css( \"overflow\", \"auto\" );\n\t\t} else if ( heightStyle === \"auto\" ) {\n\t\t\tmaxHeight = 0;\n\t\t\tthis.panels.each(function() {\n\t\t\t\tmaxHeight = Math.max( maxHeight, $( this ).height( \"\" ).height() );\n\t\t\t}).height( maxHeight );\n\t\t}\n\t},\n\n\t_eventHandler: function( event ) {\n\t\tvar options = this.options,\n\t\t\tactive = this.active,\n\t\t\tanchor = $( event.currentTarget ),\n\t\t\ttab = anchor.closest( \"li\" ),\n\t\t\tclickedIsActive = tab[ 0 ] === active[ 0 ],\n\t\t\tcollapsing = clickedIsActive \u0026\u0026 options.collapsible,\n\t\t\ttoShow = collapsing ? $() : this._getPanelForTab( tab ),\n\t\t\ttoHide = !active.length ? $() : this._getPanelForTab( active ),\n\t\t\teventData = {\n\t\t\t\toldTab: active,\n\t\t\t\toldPanel: toHide,\n\t\t\t\tnewTab: collapsing ? $() : tab,\n\t\t\t\tnewPanel: toShow\n\t\t\t};\n\n\t\tevent.preventDefault();\n\n\t\tif ( tab.hasClass( \"ui-state-disabled\" ) ||\n\t\t\t\t// tab is already loading\n\t\t\t\ttab.hasClass( \"ui-tabs-loading\" ) ||\n\t\t\t\t// can\u0027t switch durning an animation\n\t\t\t\tthis.running ||\n\t\t\t\t// click on active header, but not collapsible\n\t\t\t\t( clickedIsActive \u0026\u0026 !options.collapsible ) ||\n\t\t\t\t// allow canceling activation\n\t\t\t\t( this._trigger( \"beforeActivate\", event, eventData ) === false ) ) {\n\t\t\treturn;\n\t\t}\n\n\t\toptions.active = collapsing ? false : this.tabs.index( tab );\n\n\t\tthis.active = clickedIsActive ? $() : tab;\n\t\tif ( this.xhr ) {\n\t\t\tthis.xhr.abort();\n\t\t}\n\n\t\tif ( !toHide.length \u0026\u0026 !toShow.length ) {\n\t\t\t$.error( \"jQuery UI Tabs: Mismatching fragment identifier.\" );\n\t\t}\n\n\t\tif ( toShow.length ) {\n\t\t\tthis.load( this.tabs.index( tab ), event );\n\t\t}\n\t\tthis._toggle( event, eventData );\n\t},\n\n\t// handles show/hide for selecting tabs\n\t_toggle: function( event, eventData ) {\n\t\tvar that = this,\n\t\t\ttoShow = eventData.newPanel,\n\t\t\ttoHide = eventData.oldPanel;\n\n\t\tthis.running = true;\n\n\t\tfunction complete() {\n\t\t\tthat.running = false;\n\t\t\tthat._trigger( \"activate\", event, eventData );\n\t\t}\n\n\t\tfunction show() {\n\t\t\teventData.newTab.closest( \"li\" ).addClass( \"ui-tabs-active ui-state-active\" );\n\n\t\t\tif ( toShow.length \u0026\u0026 that.options.show ) {\n\t\t\t\tthat._show( toShow, that.options.show, complete );\n\t\t\t} else {\n\t\t\t\ttoShow.show();\n\t\t\t\tcomplete();\n\t\t\t}\n\t\t}\n\n\t\t// start out by hiding, then showing, then completing\n\t\tif ( toHide.length \u0026\u0026 this.options.hide ) {\n\t\t\tthis._hide( toHide, this.options.hide, function() {\n\t\t\t\teventData.oldTab.closest( \"li\" ).removeClass( \"ui-tabs-active ui-state-active\" );\n\t\t\t\tshow();\n\t\t\t});\n\t\t} else {\n\t\t\teventData.oldTab.closest( \"li\" ).removeClass( \"ui-tabs-active ui-state-active\" );\n\t\t\ttoHide.hide();\n\t\t\tshow();\n\t\t}\n\n\t\ttoHide.attr({\n\t\t\t\"aria-expanded\": \"false\",\n\t\t\t\"aria-hidden\": \"true\"\n\t\t});\n\t\teventData.oldTab.attr( \"aria-selected\", \"false\" );\n\t\t// If we\u0027re switching tabs, remove the old tab from the tab order.\n\t\t// If we\u0027re opening from collapsed state, remove the previous tab from the tab order.\n\t\t// If we\u0027re collapsing, then keep the collapsing tab in the tab order.\n\t\tif ( toShow.length \u0026\u0026 toHide.length ) {\n\t\t\teventData.oldTab.attr( \"tabIndex\", -1 );\n\t\t} else if ( toShow.length ) {\n\t\t\tthis.tabs.filter(function() {\n\t\t\t\treturn $( this ).attr( \"tabIndex\" ) === 0;\n\t\t\t})\n\t\t\t.attr( \"tabIndex\", -1 );\n\t\t}\n\n\t\ttoShow.attr({\n\t\t\t\"aria-expanded\": \"true\",\n\t\t\t\"aria-hidden\": \"false\"\n\t\t});\n\t\teventData.newTab.attr({\n\t\t\t\"aria-selected\": \"true\",\n\t\t\ttabIndex: 0\n\t\t});\n\t},\n\n\t_activate: function( index ) {\n\t\tvar anchor,\n\t\t\tactive = this._findActive( index );\n\n\t\t// trying to activate the already active panel\n\t\tif ( active[ 0 ] === this.active[ 0 ] ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// trying to collapse, simulate a click on the current active header\n\t\tif ( !active.length ) {\n\t\t\tactive = this.active;\n\t\t}\n\n\t\tanchor = active.find( \".ui-tabs-anchor\" )[ 0 ];\n\t\tthis._eventHandler({\n\t\t\ttarget: anchor,\n\t\t\tcurrentTarget: anchor,\n\t\t\tpreventDefault: $.noop\n\t\t});\n\t},\n\n\t_findActive: function( index ) {\n\t\treturn index === false ? $() : this.tabs.eq( index );\n\t},\n\n\t_getIndex: function( index ) {\n\t\t// meta-function to give users option to provide a href string instead of a numerical index.\n\t\tif ( typeof index === \"string\" ) {\n\t\t\tindex = this.anchors.index( this.anchors.filter( \"[href$=\u0027\" + index + \"\u0027]\" ) );\n\t\t}\n\n\t\treturn index;\n\t},\n\n\t_destroy: function() {\n\t\tif ( this.xhr ) {\n\t\t\tthis.xhr.abort();\n\t\t}\n\n\t\tthis.element.removeClass( \"ui-tabs ui-widget ui-widget-content ui-corner-all ui-tabs-collapsible\" );\n\n\t\tthis.tablist\n\t\t\t.removeClass( \"ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all\" )\n\t\t\t.removeAttr( \"role\" );\n\n\t\tthis.anchors\n\t\t\t.removeClass( \"ui-tabs-anchor\" )\n\t\t\t.removeAttr( \"role\" )\n\t\t\t.removeAttr( \"tabIndex\" )\n\t\t\t.removeUniqueId();\n\n\t\tthis.tabs.add( this.panels ).each(function() {\n\t\t\tif ( $.data( this, \"ui-tabs-destroy\" ) ) {\n\t\t\t\t$( this ).remove();\n\t\t\t} else {\n\t\t\t\t$( this )\n\t\t\t\t\t.removeClass( \"ui-state-default ui-state-active ui-state-disabled \" +\n\t\t\t\t\t\t\"ui-corner-top ui-corner-bottom ui-widget-content ui-tabs-active ui-tabs-panel\" )\n\t\t\t\t\t.removeAttr( \"tabIndex\" )\n\t\t\t\t\t.removeAttr( \"aria-live\" )\n\t\t\t\t\t.removeAttr( \"aria-busy\" )\n\t\t\t\t\t.removeAttr( \"aria-selected\" )\n\t\t\t\t\t.removeAttr( \"aria-labelledby\" )\n\t\t\t\t\t.removeAttr( \"aria-hidden\" )\n\t\t\t\t\t.removeAttr( \"aria-expanded\" )\n\t\t\t\t\t.removeAttr( \"role\" );\n\t\t\t}\n\t\t});\n\n\t\tthis.tabs.each(function() {\n\t\t\tvar li = $( this ),\n\t\t\t\tprev = li.data( \"ui-tabs-aria-controls\" );\n\t\t\tif ( prev ) {\n\t\t\t\tli\n\t\t\t\t\t.attr( \"aria-controls\", prev )\n\t\t\t\t\t.removeData( \"ui-tabs-aria-controls\" );\n\t\t\t} else {\n\t\t\t\tli.removeAttr( \"aria-controls\" );\n\t\t\t}\n\t\t});\n\n\t\tthis.panels.show();\n\n\t\tif ( this.options.heightStyle !== \"content\" ) {\n\t\t\tthis.panels.css( \"height\", \"\" );\n\t\t}\n\t},\n\n\tenable: function( index ) {\n\t\tvar disabled = this.options.disabled;\n\t\tif ( disabled === false ) {\n\t\t\treturn;\n\t\t}\n\n\t\tif ( index === undefined ) {\n\t\t\tdisabled = false;\n\t\t} else {\n\t\t\tindex = this._getIndex( index );\n\t\t\tif ( $.isArray( disabled ) ) {\n\t\t\t\tdisabled = $.map( disabled, function( num ) {\n\t\t\t\t\treturn num !== index ? num : null;\n\t\t\t\t});\n\t\t\t} else {\n\t\t\t\tdisabled = $.map( this.tabs, function( li, num ) {\n\t\t\t\t\treturn num !== index ? num : null;\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\t\tthis._setupDisabled( disabled );\n\t},\n\n\tdisable: function( index ) {\n\t\tvar disabled = this.options.disabled;\n\t\tif ( disabled === true ) {\n\t\t\treturn;\n\t\t}\n\n\t\tif ( index === undefined ) {\n\t\t\tdisabled = true;\n\t\t} else {\n\t\t\tindex = this._getIndex( index );\n\t\t\tif ( $.inArray( index, disabled ) !== -1 ) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tif ( $.isArray( disabled ) ) {\n\t\t\t\tdisabled = $.merge( [ index ], disabled ).sort();\n\t\t\t} else {\n\t\t\t\tdisabled = [ index ];\n\t\t\t}\n\t\t}\n\t\tthis._setupDisabled( disabled );\n\t},\n\n\tload: function( index, event ) {\n\t\tindex = this._getIndex( index );\n\t\tvar that = this,\n\t\t\ttab = this.tabs.eq( index ),\n\t\t\tanchor = tab.find( \".ui-tabs-anchor\" ),\n\t\t\tpanel = this._getPanelForTab( tab ),\n\t\t\teventData = {\n\t\t\t\ttab: tab,\n\t\t\t\tpanel: panel\n\t\t\t};\n\n\t\t// not remote\n\t\tif ( isLocal( anchor[ 0 ] ) ) {\n\t\t\treturn;\n\t\t}\n\n\t\tthis.xhr = $.ajax( this._ajaxSettings( anchor, event, eventData ) );\n\n\t\t// support: jQuery \u003c1.8\n\t\t// jQuery \u003c1.8 returns false if the request is canceled in beforeSend,\n\t\t// but as of 1.8, $.ajax() always returns a jqXHR object.\n\t\tif ( this.xhr \u0026\u0026 this.xhr.statusText !== \"canceled\" ) {\n\t\t\ttab.addClass( \"ui-tabs-loading\" );\n\t\t\tpanel.attr( \"aria-busy\", \"true\" );\n\n\t\t\tthis.xhr\n\t\t\t\t.success(function( response ) {\n\t\t\t\t\t// support: jQuery \u003c1.8\n\t\t\t\t\t// http://bugs.jquery.com/ticket/11778\n\t\t\t\t\tsetTimeout(function() {\n\t\t\t\t\t\tpanel.html( response );\n\t\t\t\t\t\tthat._trigger( \"load\", event, eventData );\n\t\t\t\t\t}, 1 );\n\t\t\t\t})\n\t\t\t\t.complete(function( jqXHR, status ) {\n\t\t\t\t\t// support: jQuery \u003c1.8\n\t\t\t\t\t// http://bugs.jquery.com/ticket/11778\n\t\t\t\t\tsetTimeout(function() {\n\t\t\t\t\t\tif ( status === \"abort\" ) {\n\t\t\t\t\t\t\tthat.panels.stop( false, true );\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\ttab.removeClass( \"ui-tabs-loading\" );\n\t\t\t\t\t\tpanel.removeAttr( \"aria-busy\" );\n\n\t\t\t\t\t\tif ( jqXHR === that.xhr ) {\n\t\t\t\t\t\t\tdelete that.xhr;\n\t\t\t\t\t\t}\n\t\t\t\t\t}, 1 );\n\t\t\t\t});\n\t\t}\n\t},\n\n\t_ajaxSettings: function( anchor, event, eventData ) {\n\t\tvar that = this;\n\t\treturn {\n\t\t\turl: anchor.attr( \"href\" ),\n\t\t\tbeforeSend: function( jqXHR, settings ) {\n\t\t\t\treturn that._trigger( \"beforeLoad\", event,\n\t\t\t\t\t$.extend( { jqXHR : jqXHR, ajaxSettings: settings }, eventData ) );\n\t\t\t}\n\t\t};\n\t},\n\n\t_getPanelForTab: function( tab ) {\n\t\tvar id = $( tab ).attr( \"aria-controls\" );\n\t\treturn this.element.find( this._sanitizeSelector( \"#\" + id ) );\n\t}\n});\n\n})( jQuery );\n\n(function( $ ) {\n\nvar increments = 0;\n\nfunction addDescribedBy( elem, id ) {\n\tvar describedby = (elem.attr( \"aria-describedby\" ) || \"\").split( /\\s+/ );\n\tdescribedby.push( id );\n\telem\n\t\t.data( \"ui-tooltip-id\", id )\n\t\t.attr( \"aria-describedby\", $.trim( describedby.join( \" \" ) ) );\n}\n\nfunction removeDescribedBy( elem ) {\n\tvar id = elem.data( \"ui-tooltip-id\" ),\n\t\tdescribedby = (elem.attr( \"aria-describedby\" ) || \"\").split( /\\s+/ ),\n\t\tindex = $.inArray( id, describedby );\n\tif ( index !== -1 ) {\n\t\tdescribedby.splice( index, 1 );\n\t}\n\n\telem.removeData( \"ui-tooltip-id\" );\n\tdescribedby = $.trim( describedby.join( \" \" ) );\n\tif ( describedby ) {\n\t\telem.attr( \"aria-describedby\", describedby );\n\t} else {\n\t\telem.removeAttr( \"aria-describedby\" );\n\t}\n}\n\n$.widget( \"ui.tooltip\", {\n\tversion: \"1.10.2\",\n\toptions: {\n\t\tcontent: function() {\n\t\t\t// support: IE\u003c9, Opera in jQuery \u003c1.7\n\t\t\t// .text() can\u0027t accept undefined, so coerce to a string\n\t\t\tvar title = $( this ).attr( \"title\" ) || \"\";\n\t\t\t// Escape title, since we\u0027re going from an attribute to raw HTML\n\t\t\treturn $( \"\u003ca\u003e\" ).text( title ).html();\n\t\t},\n\t\thide: true,\n\t\t// Disabled elements have inconsistent behavior across browsers (#8661)\n\t\titems: \"[title]:not([disabled])\",\n\t\tposition: {\n\t\t\tmy: \"left top+15\",\n\t\t\tat: \"left bottom\",\n\t\t\tcollision: \"flipfit flip\"\n\t\t},\n\t\tshow: true,\n\t\ttooltipClass: null,\n\t\ttrack: false,\n\n\t\t// callbacks\n\t\tclose: null,\n\t\topen: null\n\t},\n\n\t_create: function() {\n\t\tthis._on({\n\t\t\tmouseover: \"open\",\n\t\t\tfocusin: \"open\"\n\t\t});\n\n\t\t// IDs of generated tooltips, needed for destroy\n\t\tthis.tooltips = {};\n\t\t// IDs of parent tooltips where we removed the title attribute\n\t\tthis.parents = {};\n\n\t\tif ( this.options.disabled ) {\n\t\t\tthis._disable();\n\t\t}\n\t},\n\n\t_setOption: function( key, value ) {\n\t\tvar that = this;\n\n\t\tif ( key === \"disabled\" ) {\n\t\t\tthis[ value ? \"_disable\" : \"_enable\" ]();\n\t\t\tthis.options[ key ] = value;\n\t\t\t// disable element style changes\n\t\t\treturn;\n\t\t}\n\n\t\tthis._super( key, value );\n\n\t\tif ( key === \"content\" ) {\n\t\t\t$.each( this.tooltips, function( id, element ) {\n\t\t\t\tthat._updateContent( element );\n\t\t\t});\n\t\t}\n\t},\n\n\t_disable: function() {\n\t\tvar that = this;\n\n\t\t// close open tooltips\n\t\t$.each( this.tooltips, function( id, element ) {\n\t\t\tvar event = $.Event( \"blur\" );\n\t\t\tevent.target = event.currentTarget = element[0];\n\t\t\tthat.close( event, true );\n\t\t});\n\n\t\t// remove title attributes to prevent native tooltips\n\t\tthis.element.find( this.options.items ).addBack().each(function() {\n\t\t\tvar element = $( this );\n\t\t\tif ( element.is( \"[title]\" ) ) {\n\t\t\t\telement\n\t\t\t\t\t.data( \"ui-tooltip-title\", element.attr( \"title\" ) )\n\t\t\t\t\t.attr( \"title\", \"\" );\n\t\t\t}\n\t\t});\n\t},\n\n\t_enable: function() {\n\t\t// restore title attributes\n\t\tthis.element.find( this.options.items ).addBack().each(function() {\n\t\t\tvar element = $( this );\n\t\t\tif ( element.data( \"ui-tooltip-title\" ) ) {\n\t\t\t\telement.attr( \"title\", element.data( \"ui-tooltip-title\" ) );\n\t\t\t}\n\t\t});\n\t},\n\n\topen: function( event ) {\n\t\tvar that = this,\n\t\t\ttarget = $( event ? event.target : this.element )\n\t\t\t\t// we need closest here due to mouseover bubbling,\n\t\t\t\t// but always pointing at the same event target\n\t\t\t\t.closest( this.options.items );\n\n\t\t// No element to show a tooltip for or the tooltip is already open\n\t\tif ( !target.length || target.data( \"ui-tooltip-id\" ) ) {\n\t\t\treturn;\n\t\t}\n\n\t\tif ( target.attr( \"title\" ) ) {\n\t\t\ttarget.data( \"ui-tooltip-title\", target.attr( \"title\" ) );\n\t\t}\n\n\t\ttarget.data( \"ui-tooltip-open\", true );\n\n\t\t// kill parent tooltips, custom or native, for hover\n\t\tif ( event \u0026\u0026 event.type === \"mouseover\" ) {\n\t\t\ttarget.parents().each(function() {\n\t\t\t\tvar parent = $( this ),\n\t\t\t\t\tblurEvent;\n\t\t\t\tif ( parent.data( \"ui-tooltip-open\" ) ) {\n\t\t\t\t\tblurEvent = $.Event( \"blur\" );\n\t\t\t\t\tblurEvent.target = blurEvent.currentTarget = this;\n\t\t\t\t\tthat.close( blurEvent, true );\n\t\t\t\t}\n\t\t\t\tif ( parent.attr( \"title\" ) ) {\n\t\t\t\t\tparent.uniqueId();\n\t\t\t\t\tthat.parents[ this.id ] = {\n\t\t\t\t\t\telement: this,\n\t\t\t\t\t\ttitle: parent.attr( \"title\" )\n\t\t\t\t\t};\n\t\t\t\t\tparent.attr( \"title\", \"\" );\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\n\t\tthis._updateContent( target, event );\n\t},\n\n\t_updateContent: function( target, event ) {\n\t\tvar content,\n\t\t\tcontentOption = this.options.content,\n\t\t\tthat = this,\n\t\t\teventType = event ? event.type : null;\n\n\t\tif ( typeof contentOption === \"string\" ) {\n\t\t\treturn this._open( event, target, contentOption );\n\t\t}\n\n\t\tcontent = contentOption.call( target[0], function( response ) {\n\t\t\t// ignore async response if tooltip was closed already\n\t\t\tif ( !target.data( \"ui-tooltip-open\" ) ) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\t// IE may instantly serve a cached response for ajax requests\n\t\t\t// delay this call to _open so the other call to _open runs first\n\t\t\tthat._delay(function() {\n\t\t\t\t// jQuery creates a special event for focusin when it doesn\u0027t\n\t\t\t\t// exist natively. To improve performance, the native event\n\t\t\t\t// object is reused and the type is changed. Therefore, we can\u0027t\n\t\t\t\t// rely on the type being correct after the event finished\n\t\t\t\t// bubbling, so we set it back to the previous value. (#8740)\n\t\t\t\tif ( event ) {\n\t\t\t\t\tevent.type = eventType;\n\t\t\t\t}\n\t\t\t\tthis._open( event, target, response );\n\t\t\t});\n\t\t});\n\t\tif ( content ) {\n\t\t\tthis._open( event, target, content );\n\t\t}\n\t},\n\n\t_open: function( event, target, content ) {\n\t\tvar tooltip, events, delayedShow,\n\t\t\tpositionOption = $.extend( {}, this.options.position );\n\n\t\tif ( !content ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Content can be updated multiple times. If the tooltip already\n\t\t// exists, then just update the content and bail.\n\t\ttooltip = this._find( target );\n\t\tif ( tooltip.length ) {\n\t\t\ttooltip.find( \".ui-tooltip-content\" ).html( content );\n\t\t\treturn;\n\t\t}\n\n\t\t// if we have a title, clear it to prevent the native tooltip\n\t\t// we have to check first to avoid defining a title if none exists\n\t\t// (we don\u0027t want to cause an element to start matching [title])\n\t\t//\n\t\t// We use removeAttr only for key events, to allow IE to export the correct\n\t\t// accessible attributes. For mouse events, set to empty string to avoid\n\t\t// native tooltip showing up (happens only when removing inside mouseover).\n\t\tif ( target.is( \"[title]\" ) ) {\n\t\t\tif ( event \u0026\u0026 event.type === \"mouseover\" ) {\n\t\t\t\ttarget.attr( \"title\", \"\" );\n\t\t\t} else {\n\t\t\t\ttarget.removeAttr( \"title\" );\n\t\t\t}\n\t\t}\n\n\t\ttooltip = this._tooltip( target );\n\t\taddDescribedBy( target, tooltip.attr( \"id\" ) );\n\t\ttooltip.find( \".ui-tooltip-content\" ).html( content );\n\n\t\tfunction position( event ) {\n\t\t\tpositionOption.of = event;\n\t\t\tif ( tooltip.is( \":hidden\" ) ) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\ttooltip.position( positionOption );\n\t\t}\n\t\tif ( this.options.track \u0026\u0026 event \u0026\u0026 /^mouse/.test( event.type ) ) {\n\t\t\tthis._on( this.document, {\n\t\t\t\tmousemove: position\n\t\t\t});\n\t\t\t// trigger once to override element-relative positioning\n\t\t\tposition( event );\n\t\t} else {\n\t\t\ttooltip.position( $.extend({\n\t\t\t\tof: target\n\t\t\t}, this.options.position ) );\n\t\t}\n\n\t\ttooltip.hide();\n\n\t\tthis._show( tooltip, this.options.show );\n\t\t// Handle tracking tooltips that are shown with a delay (#8644). As soon\n\t\t// as the tooltip is visible, position the tooltip using the most recent\n\t\t// event.\n\t\tif ( this.options.show \u0026\u0026 this.options.show.delay ) {\n\t\t\tdelayedShow = this.delayedShow = setInterval(function() {\n\t\t\t\tif ( tooltip.is( \":visible\" ) ) {\n\t\t\t\t\tposition( positionOption.of );\n\t\t\t\t\tclearInterval( delayedShow );\n\t\t\t\t}\n\t\t\t}, $.fx.interval );\n\t\t}\n\n\t\tthis._trigger( \"open\", event, { tooltip: tooltip } );\n\n\t\tevents = {\n\t\t\tkeyup: function( event ) {\n\t\t\t\tif ( event.keyCode === $.ui.keyCode.ESCAPE ) {\n\t\t\t\t\tvar fakeEvent = $.Event(event);\n\t\t\t\t\tfakeEvent.currentTarget = target[0];\n\t\t\t\t\tthis.close( fakeEvent, true );\n\t\t\t\t}\n\t\t\t},\n\t\t\tremove: function() {\n\t\t\t\tthis._removeTooltip( tooltip );\n\t\t\t}\n\t\t};\n\t\tif ( !event || event.type === \"mouseover\" ) {\n\t\t\tevents.mouseleave = \"close\";\n\t\t}\n\t\tif ( !event || event.type === \"focusin\" ) {\n\t\t\tevents.focusout = \"close\";\n\t\t}\n\t\tthis._on( true, target, events );\n\t},\n\n\tclose: function( event ) {\n\t\tvar that = this,\n\t\t\ttarget = $( event ? event.currentTarget : this.element ),\n\t\t\ttooltip = this._find( target );\n\n\t\t// disabling closes the tooltip, so we need to track when we\u0027re closing\n\t\t// to avoid an infinite loop in case the tooltip becomes disabled on close\n\t\tif ( this.closing ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Clear the interval for delayed tracking tooltips\n\t\tclearInterval( this.delayedShow );\n\n\t\t// only set title if we had one before (see comment in _open())\n\t\tif ( target.data( \"ui-tooltip-title\" ) ) {\n\t\t\ttarget.attr( \"title\", target.data( \"ui-tooltip-title\" ) );\n\t\t}\n\n\t\tremoveDescribedBy( target );\n\n\t\ttooltip.stop( true );\n\t\tthis._hide( tooltip, this.options.hide, function() {\n\t\t\tthat._removeTooltip( $( this ) );\n\t\t});\n\n\t\ttarget.removeData( \"ui-tooltip-open\" );\n\t\tthis._off( target, \"mouseleave focusout keyup\" );\n\t\t// Remove \u0027remove\u0027 binding only on delegated targets\n\t\tif ( target[0] !== this.element[0] ) {\n\t\t\tthis._off( target, \"remove\" );\n\t\t}\n\t\tthis._off( this.document, \"mousemove\" );\n\n\t\tif ( event \u0026\u0026 event.type === \"mouseleave\" ) {\n\t\t\t$.each( this.parents, function( id, parent ) {\n\t\t\t\t$( parent.element ).attr( \"title\", parent.title );\n\t\t\t\tdelete that.parents[ id ];\n\t\t\t});\n\t\t}\n\n\t\tthis.closing = true;\n\t\tthis._trigger( \"close\", event, { tooltip: tooltip } );\n\t\tthis.closing = false;\n\t},\n\n\t_tooltip: function( element ) {\n\t\tvar id = \"ui-tooltip-\" + increments++,\n\t\t\ttooltip = $( \"\u003cdiv\u003e\" )\n\t\t\t\t.attr({\n\t\t\t\t\tid: id,\n\t\t\t\t\trole: \"tooltip\"\n\t\t\t\t})\n\t\t\t\t.addClass( \"ui-tooltip ui-widget ui-corner-all ui-widget-content \" +\n\t\t\t\t\t( this.options.tooltipClass || \"\" ) );\n\t\t$( \"\u003cdiv\u003e\" )\n\t\t\t.addClass( \"ui-tooltip-content\" )\n\t\t\t.appendTo( tooltip );\n\t\ttooltip.appendTo( this.document[0].body );\n\t\tthis.tooltips[ id ] = element;\n\t\treturn tooltip;\n\t},\n\n\t_find: function( target ) {\n\t\tvar id = target.data( \"ui-tooltip-id\" );\n\t\treturn id ? $( \"#\" + id ) : $();\n\t},\n\n\t_removeTooltip: function( tooltip ) {\n\t\ttooltip.remove();\n\t\tdelete this.tooltips[ tooltip.attr( \"id\" ) ];\n\t},\n\n\t_destroy: function() {\n\t\tvar that = this;\n\n\t\t// close open tooltips\n\t\t$.each( this.tooltips, function( id, element ) {\n\t\t\t// Delegate to close method to handle common cleanup\n\t\t\tvar event = $.Event( \"blur\" );\n\t\t\tevent.target = event.currentTarget = element[0];\n\t\t\tthat.close( event, true );\n\n\t\t\t// Remove immediately; destroying an open tooltip doesn\u0027t use the\n\t\t\t// hide animation\n\t\t\t$( \"#\" + id ).remove();\n\n\t\t\t// Restore the title\n\t\t\tif ( element.data( \"ui-tooltip-title\" ) ) {\n\t\t\t\telement.attr( \"title\", element.data( \"ui-tooltip-title\" ) );\n\t\t\t\telement.removeData( \"ui-tooltip-title\" );\n\t\t\t}\n\t\t});\n\t}\n});\n\n}( jQuery ) );\n\n/*!\n * jQuery UI Touch Punch 0.2.2\n *\n * Copyright 2011, Dave Furfero\n * Dual licensed under the MIT or GPL Version 2 licenses.\n *\n * Depends:\n * jquery.ui.widget.js\n * jquery.ui.mouse.js\n */\n(function ($) {\n\n // Detect touch support\n $.support.touch = \u0027ontouchend\u0027 in document;\n\n // Ignore browsers without touch support\n if (!$.support.touch) {\n return;\n }\n\n var mouseProto = $.ui.mouse.prototype,\n _mouseInit = mouseProto._mouseInit,\n touchHandled;\n\n /**\n * Simulate a mouse event based on a corresponding touch event\n * @param {Object} event A touch event\n * @param {String} simulatedType The corresponding mouse event\n */\n function simulateMouseEvent (event, simulatedType) {\n\n // Ignore multi-touch events\n if (event.originalEvent.touches.length \u003e 1) {\n return;\n }\n\n event.preventDefault();\n\n var touch = event.originalEvent.changedTouches[0],\n simulatedEvent = document.createEvent(\u0027MouseEvents\u0027);\n\n // Initialize the simulated mouse event using the touch event\u0027s coordinates\n simulatedEvent.initMouseEvent(\n simulatedType, // type\n true, // bubbles\n true, // cancelable\n window, // view\n 1, // detail\n touch.screenX, // screenX\n touch.screenY, // screenY\n touch.clientX, // clientX\n touch.clientY, // clientY\n false, // ctrlKey\n false, // altKey\n false, // shiftKey\n false, // metaKey\n 0, // button\n null // relatedTarget\n );\n\n // Dispatch the simulated event to the target element\n event.target.dispatchEvent(simulatedEvent);\n }\n\n /**\n * Handle the jQuery UI widget\u0027s touchstart events\n * @param {Object} event The widget element\u0027s touchstart event\n */\n mouseProto._touchStart = function (event) {\n\n var self = this;\n\n // Ignore the event if another widget is already being handled\n if (touchHandled || !self._mouseCapture(event.originalEvent.changedTouches[0])) {\n return;\n }\n\n // Set the flag to prevent other widgets from inheriting the touch event\n touchHandled = true;\n\n // Track movement to determine if interaction was a click\n self._touchMoved = false;\n\n // Simulate the mouseover event\n simulateMouseEvent(event, \u0027mouseover\u0027);\n\n // Simulate the mousemove event\n simulateMouseEvent(event, \u0027mousemove\u0027);\n\n // Simulate the mousedown event\n simulateMouseEvent(event, \u0027mousedown\u0027);\n };\n\n /**\n * Handle the jQuery UI widget\u0027s touchmove events\n * @param {Object} event The document\u0027s touchmove event\n */\n mouseProto._touchMove = function (event) {\n\n // Ignore event if not handled\n if (!touchHandled) {\n return;\n }\n\n // Interaction was not a click\n this._touchMoved = true;\n\n // Simulate the mousemove event\n simulateMouseEvent(event, \u0027mousemove\u0027);\n\n event.stopPropagation();\n };\n\n /**\n * Handle the jQuery UI widget\u0027s touchend events\n * @param {Object} event The document\u0027s touchend event\n */\n mouseProto._touchEnd = function (event) {\n\n // Ignore event if not handled\n if (!touchHandled) {\n return;\n }\n\n // Simulate the mouseup event\n simulateMouseEvent(event, \u0027mouseup\u0027);\n\n // Simulate the mouseout event\n simulateMouseEvent(event, \u0027mouseout\u0027);\n\n // If the touch interaction did not move, it should trigger a click\n if (!this._touchMoved) {\n\n // Simulate the click event\n simulateMouseEvent(event, \u0027click\u0027);\n }\n\n // Unset the flag to allow other widgets to inherit the touch event\n touchHandled = false;\n };\n\n /**\n * A duck punch of the $.ui.mouse _mouseInit method to support touch events.\n * This method extends the widget with bound touch event handlers that\n * translate touch events to mouse events and pass them to the widget\u0027s\n * original mouse event handling methods.\n */\n mouseProto._mouseInit = function () {\n\n var self = this;\n\n // Delegate the touch handlers to the widget\u0027s element\n self.element\n .bind(\u0027touchstart\u0027, $.proxy(self, \u0027_touchStart\u0027))\n .bind(\u0027touchmove\u0027, $.proxy(self, \u0027_touchMove\u0027))\n .bind(\u0027touchend\u0027, $.proxy(self, \u0027_touchEnd\u0027));\n\n // Call the original $.ui.mouse init method\n _mouseInit.call(self);\n };\n})(jQuery);\n\n(function ($) {\n // This is a hack to make stuff like ckeditor work inside modal dialogs. Since ckeditor dialogs are placed on body and not in the ui.dialog\u0027s DOM. See http://bugs.jqueryui.com/ticket/9087\n $.widget(\"ui.dialog\", $.ui.dialog, {\n _allowInteraction: function (event) {\n return true;\n }\n });\n\n $.ui.dialog.prototype._focusTabbable = function () {};\n})(jQuery);\n\njQuery = oldJQuery;\n"
,"scripts/flowplayer-3.2.12.min.js":"/*\n * flowplayer.js 3.2.12. The Flowplayer API\n *\n * Copyright 2009-2011 Flowplayer Oy\n *\n * This file is part of Flowplayer.\n *\n * Flowplayer is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * Flowplayer is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with Flowplayer. If not, see \u003chttp://www.gnu.org/licenses/\u003e.\n *\n * Date: ${date}\n * Revision: ${revision}\n */\n!function(){function h(p){console.log(\"$f.fireEvent\",[].slice.call(p))}function l(r){if(!r||typeof r!=\"object\"){return r}var p=new r.constructor();for(var q in r){if(r.hasOwnProperty(q)){p[q]=l(r[q])}}return p}function n(u,r){if(!u){return}var p,q=0,s=u.length;if(s===undefined){for(p in u){if(r.call(u[p],p,u[p])===false){break}}}else{for(var t=u[0];q\u003cs\u0026\u0026r.call(t,q,t)!==false;t=u[++q]){}}return u}function c(p){return document.getElementById(p)}function j(r,q,p){if(typeof q!=\"object\"){return r}if(r\u0026\u0026q){n(q,function(s,t){if(!p||typeof t!=\"function\"){r[s]=t}})}return r}function o(t){var r=t.indexOf(\".\");if(r!=-1){var q=t.slice(0,r)||\"*\";var p=t.slice(r+1,t.length);var s=[];n(document.getElementsByTagName(q),function(){if(this.className\u0026\u0026this.className.indexOf(p)!=-1){s.push(this)}});return s}}function g(p){p=p||window.event;if(p.preventDefault){p.stopPropagation();p.preventDefault()}else{p.returnValue=false;p.cancelBubble=true}return false}function k(r,p,q){r[p]=r[p]||[];r[p].push(q)}function e(p){return p.replace(/\u0026amp;/g,\"%26\").replace(/\u0026/g,\"%26\").replace(/=/g,\"%3D\")}function f(){return\"_\"+(\"\"+Math.random()).slice(2,10)}var i=function(u,s,t){var r=this,q={},v={};r.index=s;if(typeof u==\"string\"){u={url:u}}j(this,u,true);n((\"Begin*,Start,Pause*,Resume*,Seek*,Stop*,Finish*,LastSecond,Update,BufferFull,BufferEmpty,BufferStop\").split(\",\"),function(){var w=\"on\"+this;if(w.indexOf(\"*\")!=-1){w=w.slice(0,w.length-1);var x=\"onBefore\"+w.slice(2);r[x]=function(y){k(v,x,y);return r}}r[w]=function(y){k(v,w,y);return r};if(s==-1){if(r[x]){t[x]=r[x]}if(r[w]){t[w]=r[w]}}});j(this,{onCuepoint:function(y,x){if(arguments.length==1){q.embedded=[null,y];return r}if(typeof y==\"number\"){y=[y]}var w=f();q[w]=[y,x];if(t.isLoaded()){t._api().fp_addCuepoints(y,s,w)}return r},update:function(x){j(r,x);if(t.isLoaded()){t._api().fp_updateClip(x,s)}var w=t.getConfig();var y=(s==-1)?w.clip:w.playlist[s];j(y,x,true)},_fireEvent:function(w,z,x,B){if(w==\"onLoad\"){n(q,function(C,D){if(D[0]){t._api().fp_addCuepoints(D[0],s,C)}});return false}B=B||r;if(w==\"onCuepoint\"){var A=q[z];if(A){return A[1].call(t,B,x)}}if(z\u0026\u0026\"onBeforeBegin,onMetaData,onStart,onUpdate,onResume\".indexOf(w)!=-1){j(B,z);if(z.metaData){if(!B.duration){B.duration=z.metaData.duration}else{B.fullDuration=z.metaData.duration}}}var y=true;n(v[w],function(){y=this.call(t,B,z,x)});return y}});if(u.onCuepoint){var p=u.onCuepoint;r.onCuepoint.apply(r,typeof p==\"function\"?[p]:p);delete u.onCuepoint}n(u,function(w,x){if(typeof x==\"function\"){k(v,w,x);delete u[w]}});if(s==-1){t.onCuepoint=this.onCuepoint}};var m=function(q,s,r,u){var p=this,t={},v=false;if(u){j(t,u)}n(s,function(w,x){if(typeof x==\"function\"){t[w]=x;delete s[w]}});j(this,{animate:function(z,A,y){if(!z){return p}if(typeof A==\"function\"){y=A;A=500}if(typeof z==\"string\"){var x=z;z={};z[x]=A;A=500}if(y){var w=f();t[w]=y}if(A===undefined){A=500}s=r._api().fp_animate(q,z,A,w);return p},css:function(x,y){if(y!==undefined){var w={};w[x]=y;x=w}s=r._api().fp_css(q,x);j(p,s);return p},show:function(){this.display=\"block\";r._api().fp_showPlugin(q);return p},hide:function(){this.display=\"none\";r._api().fp_hidePlugin(q);return p},toggle:function(){this.display=r._api().fp_togglePlugin(q);return p},fadeTo:function(z,y,x){if(typeof y==\"function\"){x=y;y=500}if(x){var w=f();t[w]=x}this.display=r._api().fp_fadeTo(q,z,y,w);this.opacity=z;return p},fadeIn:function(x,w){return p.fadeTo(1,x,w)},fadeOut:function(x,w){return p.fadeTo(0,x,w)},getName:function(){return q},getPlayer:function(){return r},_fireEvent:function(x,w,y){if(x==\"onUpdate\"){var A=r._api().fp_getPlugin(q);if(!A){return}j(p,A);delete p.methods;if(!v){n(A.methods,function(){var C=\"\"+this;p[C]=function(){var D=[].slice.call(arguments);var E=r._api().fp_invoke(q,C,D);return E===\"undefined\"||E===undefined?p:E}});v=true}}var B=t[x];if(B){var z=B.apply(p,w);if(x.slice(0,1)==\"_\"){delete t[x]}return z}return p}})};function b(r,H,u){var x=this,w=null,E=false,v,t,G=[],z={},y={},F,s,q,D,p,B;j(x,{id:function(){return F},isLoaded:function(){return(w!==null\u0026\u0026w.fp_play!==undefined\u0026\u0026!E)},getParent:function(){return r},hide:function(I){if(I){r.style.height=\"0px\"}if(x.isLoaded()){w.style.height=\"0px\"}return x},show:function(){r.style.height=B+\"px\";if(x.isLoaded()){w.style.height=p+\"px\"}return x},isHidden:function(){return x.isLoaded()\u0026\u0026parseInt(w.style.height,10)===0},load:function(K){if(!x.isLoaded()\u0026\u0026x._fireEvent(\"onBeforeLoad\")!==false){var I=function(){if(v\u0026\u0026!flashembed.isSupported(H.version)){r.innerHTML=\"\"}if(K){K.cached=true;k(y,\"onLoad\",K)}flashembed(r,H,{config:u})};var J=0;n(a,function(){this.unload(function(L){if(++J==a.length){I()}})})}return x},unload:function(K){if(v.replace(/\\s/g,\"\")!==\"\"){if(x._fireEvent(\"onBeforeUnload\")===false){if(K){K(false)}return x}E=true;try{if(w){if(w.fp_isFullscreen()){w.fp_toggleFullscreen()}w.fp_close();x._fireEvent(\"onUnload\")}}catch(I){}var J=function(){w=null;r.innerHTML=v;E=false;if(K){K(true)}};if(/WebKit/i.test(navigator.userAgent)\u0026\u0026!/Chrome/i.test(navigator.userAgent)){setTimeout(J,0)}else{J()}}else{if(K){K(false)}}return x},getClip:function(I){if(I===undefined){I=D}return G[I]},getCommonClip:function(){return t},getPlaylist:function(){return G},getPlugin:function(I){var K=z[I];if(!K\u0026\u0026x.isLoaded()){var J=x._api().fp_getPlugin(I);if(J){K=new m(I,J,x);z[I]=K}}return K},getScreen:function(){return x.getPlugin(\"screen\")},getControls:function(){return x.getPlugin(\"controls\")._fireEvent(\"onUpdate\")},getLogo:function(){try{return x.getPlugin(\"logo\")._fireEvent(\"onUpdate\")}catch(I){}},getPlay:function(){return x.getPlugin(\"play\")._fireEvent(\"onUpdate\")},getConfig:function(I){return I?l(u):u},getFlashParams:function(){return H},loadPlugin:function(L,K,N,M){if(typeof N==\"function\"){M=N;N={}}var J=M?f():\"_\";x._api().fp_loadPlugin(L,K,N,J);var I={};I[J]=M;var O=new m(L,null,x,I);z[L]=O;return O},getState:function(){return x.isLoaded()?w.fp_getState():-1},play:function(J,I){var K=function(){if(J!==undefined){x._api().fp_play(J,I)}else{x._api().fp_play()}};if(x.isLoaded()){K()}else{if(E){setTimeout(function(){x.play(J,I)},50)}else{x.load(function(){K()})}}return x},getVersion:function(){var J=\"flowplayer.js 3.2.12\";if(x.isLoaded()){var I=w.fp_getVersion();I.push(J);return I}return J},_api:function(){if(!x.isLoaded()){throw\"Flowplayer \"+x.id()+\" not loaded when calling an API method\"}return w},setClip:function(I){n(I,function(J,K){if(typeof K==\"function\"){k(y,J,K);delete I[J]}else{if(J==\"onCuepoint\"){$f(r).getCommonClip().onCuepoint(I[J][0],I[J][1])}}});x.setPlaylist([I]);return x},getIndex:function(){return q},bufferAnimate:function(I){w.fp_bufferAnimate(I===undefined||I);return x},_swfHeight:function(){return w.clientHeight}});n((\"Click*,Load*,Unload*,Keypress*,Volume*,Mute*,Unmute*,PlaylistReplace,ClipAdd,Fullscreen*,FullscreenExit,Error,MouseOver,MouseOut\").split(\",\"),function(){var I=\"on\"+this;if(I.indexOf(\"*\")!=-1){I=I.slice(0,I.length-1);var J=\"onBefore\"+I.slice(2);x[J]=function(K){k(y,J,K);return x}}x[I]=function(K){k(y,I,K);return x}});n((\"pause,resume,mute,unmute,stop,toggle,seek,getStatus,getVolume,setVolume,getTime,isPaused,isPlaying,startBuffering,stopBuffering,isFullscreen,toggleFullscreen,reset,close,setPlaylist,addClip,playFeed,setKeyboardShortcutsEnabled,isKeyboardShortcutsEnabled\").split(\",\"),function(){var I=this;x[I]=function(K,J){if(!x.isLoaded()){return x}var L=null;if(K!==undefined\u0026\u0026J!==undefined){L=w[\"fp_\"+I](K,J)}else{L=(K===undefined)?w[\"fp_\"+I]():w[\"fp_\"+I](K)}return L===\"undefined\"||L===undefined?x:L}});x._fireEvent=function(R){if(typeof R==\"string\"){R=[R]}var S=R[0],P=R[1],N=R[2],M=R[3],L=0;if(u.debug){h(R)}if(!x.isLoaded()\u0026\u0026S==\"onLoad\"\u0026\u0026P==\"player\"){w=w||c(s);p=x._swfHeight();n(G,function(){this._fireEvent(\"onLoad\")});n(z,function(T,U){U._fireEvent(\"onUpdate\")});t._fireEvent(\"onLoad\")}if(S==\"onLoad\"\u0026\u0026P!=\"player\"){return}if(S==\"onError\"){if(typeof P==\"string\"||(typeof P==\"number\"\u0026\u0026typeof N==\"number\")){P=N;N=M}}if(S==\"onContextMenu\"){n(u.contextMenu[P],function(T,U){U.call(x)});return}if(S==\"onPluginEvent\"||S==\"onBeforePluginEvent\"){var I=P.name||P;var J=z[I];if(J){J._fireEvent(\"onUpdate\",P);return J._fireEvent(N,R.slice(3))}return}if(S==\"onPlaylistReplace\"){G=[];var O=0;n(P,function(){G.push(new i(this,O++,x))})}if(S==\"onClipAdd\"){if(P.isInStream){return}P=new i(P,N,x);G.splice(N,0,P);for(L=N+1;L\u003cG.length;L++){G[L].index++}}var Q=true;if(typeof P==\"number\"\u0026\u0026P\u003cG.length){D=P;var K=G[P];if(K){Q=K._fireEvent(S,N,M)}if(!K||Q!==false){Q=t._fireEvent(S,N,M,K)}}n(y[S],function(){Q=this.call(x,P,N);if(this.cached){y[S].splice(L,1)}if(Q===false){return false}L++});return Q};function C(){if($f(r)){$f(r).getParent().innerHTML=\"\";q=$f(r).getIndex();a[q]=x}else{a.push(x);q=a.length-1}B=parseInt(r.style.height,10)||r.clientHeight;F=r.id||\"fp\"+f();s=H.id||F+\"_api\";H.id=s;v=r.innerHTML;if(typeof u==\"string\"){u={clip:{url:u}}}u.playerId=F;u.clip=u.clip||{};if(r.getAttribute(\"href\",2)\u0026\u0026!u.clip.url){u.clip.url=r.getAttribute(\"href\",2)}if(u.clip.url){u.clip.url=e(u.clip.url)}t=new i(u.clip,-1,x);u.playlist=u.playlist||[u.clip];var J=0;n(u.playlist,function(){var M=this;if(typeof M==\"object\"\u0026\u0026M.length){M={url:\"\"+M}}if(M.url){M.url=e(M.url)}n(u.clip,function(N,O){if(O!==undefined\u0026\u0026M[N]===undefined\u0026\u0026typeof O!=\"function\"){M[N]=O}});u.playlist[J]=M;M=new i(M,J,x);G.push(M);J++});n(u,function(M,N){if(typeof N==\"function\"){if(t[M]){t[M](N)}else{k(y,M,N)}delete u[M]}});n(u.plugins,function(M,N){if(N){z[M]=new m(M,N,x)}});if(!u.plugins||u.plugins.controls===undefined){z.controls=new m(\"controls\",null,x)}z.canvas=new m(\"canvas\",null,x);v=r.innerHTML;function L(M){if(/iPad|iPhone|iPod/i.test(navigator.userAgent)\u0026\u0026!/.flv$/i.test(G[0].url)\u0026\u0026!K()){return true}if(!x.isLoaded()\u0026\u0026x._fireEvent(\"onBeforeClick\")!==false){x.load()}return g(M)}function K(){return x.hasiPadSupport\u0026\u0026x.hasiPadSupport()}function I(){if(v.replace(/\\s/g,\"\")!==\"\"){if(r.addEventListener){r.addEventListener(\"click\",L,false)}else{if(r.attachEvent){r.attachEvent(\"onclick\",L)}}}else{if(r.addEventListener\u0026\u0026!K()){r.addEventListener(\"click\",g,false)}x.load()}}setTimeout(I,0)}if(typeof r==\"string\"){var A=c(r);if(!A){throw\"Flowplayer cannot access element: \"+r}r=A;C()}else{C()}}var a=[];function d(p){this.length=p.length;this.each=function(r){n(p,r)};this.size=function(){return p.length};var q=this;for(name in b.prototype){q[name]=function(){var r=arguments;q.each(function(){this[name].apply(this,r)})}}}window.flowplayer=window.$f=function(){var q=null;var p=arguments[0];if(!arguments.length){n(a,function(){if(this.isLoaded()){q=this;return false}});return q||a[0]}if(arguments.length==1){if(typeof p==\"number\"){return a[p]}else{if(p==\"*\"){return new d(a)}n(a,function(){if(this.id()==p.id||this.id()==p||this.getParent()==p){q=this;return false}});return q}}if(arguments.length\u003e1){var u=arguments[1],r=(arguments.length==3)?arguments[2]:{};if(typeof u==\"string\"){u={src:u}}u=j({bgcolor:\"#000000\",version:[10,1],expressInstall:\"http://releases.flowplayer.org/swf/expressinstall.swf\",cachebusting:false},u);if(typeof p==\"string\"){if(p.indexOf(\".\")!=-1){var t=[];n(o(p),function(){t.push(new b(this,l(u),l(r)))});return new d(t)}else{var s=c(p);return new b(s!==null?s:l(p),l(u),l(r))}}else{if(p){return new b(p,l(u),l(r))}}}return null};j(window.$f,{fireEvent:function(){var q=[].slice.call(arguments);var r=$f(q[0]);return r?r._fireEvent(q.slice(1)):null},addPlugin:function(p,q){b.prototype[p]=q;return $f},each:n,extend:j});if(typeof jQuery==\"function\"){jQuery.fn.flowplayer=function(r,q){if(!arguments.length||typeof arguments[0]==\"number\"){var p=[];this.each(function(){var s=$f(this);if(s){p.push(s)}});return arguments.length?p[arguments[0]]:new d(p)}return this.each(function(){$f(this,l(r),q?l(q):{})})}}}();!function(){var h=document.all,j=\"http://get.adobe.com/flashplayer\",c=typeof jQuery==\"function\",e=/(\\d+)[^\\d]+(\\d+)[^\\d]*(\\d*)/,b={width:\"100%\",height:\"100%\",id:\"_\"+(\"\"+Math.random()).slice(9),allowfullscreen:true,allowscriptaccess:\"always\",quality:\"high\",version:[3,0],onFail:null,expressInstall:null,w3c:false,cachebusting:false};if(window.attachEvent){window.attachEvent(\"onbeforeunload\",function(){__flash_unloadHandler=function(){};__flash_savedUnloadHandler=function(){}})}function i(m,l){if(l){for(var f in l){if(l.hasOwnProperty(f)){m[f]=l[f]}}}return m}function a(f,n){var m=[];for(var l in f){if(f.hasOwnProperty(l)){m[l]=n(f[l])}}return m}window.flashembed=function(f,m,l){if(typeof f==\"string\"){f=document.getElementById(f.replace(\"#\",\"\"))}if(!f){return}if(typeof m==\"string\"){m={src:m}}return new d(f,i(i({},b),m),l)};var g=i(window.flashembed,{conf:b,getVersion:function(){var m,f;try{f=navigator.plugins[\"Shockwave Flash\"].description.slice(16)}catch(o){try{m=new ActiveXObject(\"ShockwaveFlash.ShockwaveFlash.7\");f=m\u0026\u0026m.GetVariable(\"$version\")}catch(n){try{m=new ActiveXObject(\"ShockwaveFlash.ShockwaveFlash.6\");f=m\u0026\u0026m.GetVariable(\"$version\")}catch(l){}}}f=e.exec(f);return f?[1*f[1],1*f[(f[1]*1\u003e9?2:3)]*1]:[0,0]},asString:function(l){if(l===null||l===undefined){return null}var f=typeof l;if(f==\"object\"\u0026\u0026l.push){f=\"array\"}switch(f){case\"string\":l=l.replace(new RegExp(\u0027([\"\\\\\\\\])\u0027,\"g\"),\"\\\\$1\");l=l.replace(/^\\s?(\\d+\\.?\\d*)%/,\"$1pct\");return\u0027\"\u0027+l+\u0027\"\u0027;case\"array\":return\"[\"+a(l,function(o){return g.asString(o)}).join(\",\")+\"]\";case\"function\":return\u0027\"function()\"\u0027;case\"object\":var m=[];for(var n in l){if(l.hasOwnProperty(n)){m.push(\u0027\"\u0027+n+\u0027\":\u0027+g.asString(l[n]))}}return\"{\"+m.join(\",\")+\"}\"}return String(l).replace(/\\s/g,\" \").replace(/\\\u0027/g,\u0027\"\u0027)},getHTML:function(o,l){o=i({},o);var n=\u0027\u003cobject width=\"\u0027+o.width+\u0027\" height=\"\u0027+o.height+\u0027\" id=\"\u0027+o.id+\u0027\" name=\"\u0027+o.id+\u0027\"\u0027;if(o.cachebusting){o.src+=((o.src.indexOf(\"?\")!=-1?\"\u0026\":\"?\")+Math.random())}if(o.w3c||!h){n+=\u0027 data=\"\u0027+o.src+\u0027\" type=\"application/x-shockwave-flash\"\u0027}else{n+=\u0027 classid=\"clsid:D27CDB6E-AE6D-11cf-96B8-444553540000\"\u0027}n+=\"\u003e\";if(o.w3c||h){n+=\u0027\u003cparam name=\"movie\" value=\"\u0027+o.src+\u0027\" /\u003e\u0027}o.width=o.height=o.id=o.w3c=o.src=null;o.onFail=o.version=o.expressInstall=null;for(var m in o){if(o[m]){n+=\u0027\u003cparam name=\"\u0027+m+\u0027\" value=\"\u0027+o[m]+\u0027\" /\u003e\u0027}}var p=\"\";if(l){for(var f in l){if(l[f]){var q=l[f];p+=f+\"=\"+(/function|object/.test(typeof q)?g.asString(q):q)+\"\u0026\"}}p=p.slice(0,-1);n+=\u0027\u003cparam name=\"flashvars\" value=\\\u0027\u0027+p+\"\u0027 /\u003e\"}n+=\"\u003c/object\u003e\";return n},isSupported:function(f){return k[0]\u003ef[0]||k[0]==f[0]\u0026\u0026k[1]\u003e=f[1]}});var k=g.getVersion();function d(f,n,m){if(g.isSupported(n.version)){f.innerHTML=g.getHTML(n,m)}else{if(n.expressInstall\u0026\u0026g.isSupported([6,65])){f.innerHTML=g.getHTML(i(n,{src:n.expressInstall}),{MMredirectURL:encodeURIComponent(location.href),MMplayerType:\"PlugIn\",MMdoctitle:document.title})}else{if(!f.innerHTML.replace(/\\s/g,\"\")){f.innerHTML=\"\u003ch2\u003eFlash version \"+n.version+\" or greater is required\u003c/h2\u003e\u003ch3\u003e\"+(k[0]\u003e0?\"Your version is \"+k:\"You have no flash plugin installed\")+\"\u003c/h3\u003e\"+(f.tagName==\"A\"?\"\u003cp\u003eClick here to download latest version\u003c/p\u003e\":\"\u003cp\u003eDownload latest version from \u003ca href=\u0027\"+j+\"\u0027\u003ehere\u003c/a\u003e\u003c/p\u003e\");if(f.tagName==\"A\"||f.tagName==\"DIV\"){f.onclick=function(){location.href=j}}}if(n.onFail){var l=n.onFail.call(this);if(typeof l==\"string\"){f.innerHTML=l}}}}if(h){window[n.id]=document.getElementById(n.id)}i(this,{getRoot:function(){return f},getOptions:function(){return n},getConf:function(){return m},getApi:function(){return f.firstChild}})}if(c){jQuery.tools=jQuery.tools||{version:\"3.2.12\"};jQuery.tools.flashembed={conf:b};jQuery.fn.flashembed=function(l,f){return this.each(function(){$(this).data(\"flashembed\",flashembed(this,l,f))})}}}();"
,"scripts/youtube.js":"/** @namespace H5P */\nH5P.VideoYouTube = (function ($) {\n\n /**\n * YouTube video player for H5P.\n *\n * @class\n * @param {Array} sources Video files to use\n * @param {Object} options Settings for the player\n * @param {Object} l10n Localization strings\n */\n function YouTube(sources, options, l10n) {\n var self = this;\n\n var player;\n var playbackRate = 1;\n var id = \u0027h5p-youtube-\u0027 + numInstances;\n numInstances++;\n\n var $wrapper = $(\u0027\u003cdiv/\u003e\u0027);\n var $placeholder = $(\u0027\u003cdiv/\u003e\u0027, {\n id: id,\n text: l10n.loading\n }).appendTo($wrapper);\n\n // Optional placeholder\n // var $placeholder = $(\u0027\u003ciframe id=\"\u0027 + id + \u0027\" type=\"text/html\" width=\"640\" height=\"360\" src=\"https://www.youtube.com/embed/\u0027 + getId(sources[0].path) + \u0027?enablejsapi=1\u0026origin=\u0027 + encodeURIComponent(ORIGIN) + \u0027\u0026autoplay=\u0027 + (options.autoplay ? 1 : 0) + \u0027\u0026controls=\u0027 + (options.controls ? 1 : 0) + \u0027\u0026disabledkb=\u0027 + (options.controls ? 0 : 1) + \u0027\u0026fs=0\u0026loop=\u0027 + (options.loop ? 1 : 0) + \u0027\u0026rel=0\u0026showinfo=0\u0026iv_load_policy=3\" frameborder=\"0\"\u003e\u003c/iframe\u003e\u0027).appendTo($wrapper);\n\n /**\n * Use the YouTube API to create a new player\n *\n * @private\n */\n var create = function () {\n if (!$placeholder.is(\u0027:visible\u0027) || player !== undefined) {\n return;\n }\n\n if (window.YT === undefined) {\n // Load API first\n loadAPI(create);\n return;\n }\n if (YT.Player === undefined) {\n return;\n }\n\n var width = $wrapper.width();\n if (width \u003c 200) {\n width = 200;\n }\n\n var loadCaptionsModule = true;\n\n var videoId = getId(sources[0].path);\n\n player = new YT.Player(id, {\n width: width,\n height: width * (9/16),\n videoId: videoId,\n playerVars: {\n origin: ORIGIN,\n autoplay: options.autoplay ? 1 : 0,\n controls: options.controls ? 1 : 0,\n disablekb: options.controls ? 0 : 1,\n fs: 0,\n playlist: options.loop ? videoId : undefined,\n rel: 0,\n showinfo: 0,\n iv_load_policy: 3,\n wmode: \"opaque\",\n start: options.startAt,\n playsinline: 1\n },\n events: {\n onReady: function () {\n self.trigger(\u0027ready\u0027);\n self.trigger(\u0027loaded\u0027);\n },\n onApiChange: function () {\n if (loadCaptionsModule) {\n loadCaptionsModule = false;\n\n // Always load captions\n player.loadModule(\u0027captions\u0027);\n }\n\n var trackList;\n try {\n // Grab tracklist from player\n trackList = player.getOption(\u0027captions\u0027, \u0027tracklist\u0027);\n }\n catch (err) {}\n if (trackList \u0026\u0026 trackList.length) {\n\n // Format track list into valid track options\n var trackOptions = [];\n for (var i = 0; i \u003c trackList.length; i++) {\n trackOptions.push(new H5P.Video.LabelValue(trackList[i].displayName, trackList[i].languageCode));\n }\n\n // Captions are ready for loading\n self.trigger(\u0027captions\u0027, trackOptions);\n }\n },\n onStateChange: function (state) {\n if (state.data \u003e -1 \u0026\u0026 state.data \u003c 4) {\n\n // Fix for keeping playback rate in IE11\n if (H5P.Video.IE11_PLAYBACK_RATE_FIX \u0026\u0026 state.data === H5P.Video.PLAYING \u0026\u0026 playbackRate !== 1) {\n // YT doesn\u0027t know that IE11 changed the rate so it must be reset before it\u0027s set to the correct value\n player.setPlaybackRate(1);\n player.setPlaybackRate(playbackRate);\n }\n // End IE11 fix\n\n self.trigger(\u0027stateChange\u0027, state.data);\n }\n },\n onPlaybackQualityChange: function (quality) {\n self.trigger(\u0027qualityChange\u0027, quality.data);\n },\n onPlaybackRateChange: function (playbackRate) {\n self.trigger(\u0027playbackRateChange\u0027, playbackRate.data);\n },\n onError: function (error) {\n var message;\n switch (error.data) {\n case 2:\n message = l10n.invalidYtId;\n break;\n\n case 100:\n message = l10n.unknownYtId;\n break;\n\n case 101:\n case 150:\n message = l10n.restrictedYt;\n break;\n\n default:\n message = l10n.unknownError + \u0027 \u0027 + error.data;\n break;\n }\n self.trigger(\u0027error\u0027, message);\n }\n }\n });\n };\n\n /**\n * Indicates if the video must be clicked for it to start playing.\n * For instance YouTube videos on iPad must be pressed to start playing.\n *\n * @public\n */\n self.pressToPlay = navigator.userAgent.match(/iPad/i) ? true : false;\n\n /**\n * Appends the video player to the DOM.\n *\n * @public\n * @param {jQuery} $container\n */\n self.appendTo = function ($container) {\n $container.addClass(\u0027h5p-youtube\u0027).append($wrapper);\n create();\n };\n\n /**\n * Get list of available qualities. Not available until after play.\n *\n * @public\n * @returns {Array}\n */\n self.getQualities = function () {\n if (!player || !player.getAvailableQualityLevels) {\n return;\n }\n\n var qualities = player.getAvailableQualityLevels();\n if (!qualities.length) {\n return; // No qualities\n }\n\n // Add labels\n for (var i = 0; i \u003c qualities.length; i++) {\n var quality = qualities[i];\n var label = (LABELS[quality] !== undefined ? LABELS[quality] : \u0027Unknown\u0027); // TODO: l10n\n qualities[i] = {\n name: quality,\n label: LABELS[quality]\n };\n }\n\n return qualities;\n };\n\n /**\n * Get current playback quality. Not available until after play.\n *\n * @public\n * @returns {String}\n */\n self.getQuality = function () {\n if (!player || !player.getPlaybackQuality) {\n return;\n }\n\n var quality = player.getPlaybackQuality();\n return quality === \u0027unknown\u0027 ? undefined : quality;\n };\n\n /**\n * Set current playback quality. Not available until after play.\n * Listen to event \"qualityChange\" to check if successful.\n *\n * @public\n * @params {String} [quality]\n */\n self.setQuality = function (quality) {\n if (!player || !player.setPlaybackQuality) {\n return;\n }\n\n player.setPlaybackQuality(quality);\n };\n\n /**\n * Start the video.\n *\n * @public\n */\n self.play = function () {\n if (!player || !player.playVideo) {\n self.on(\u0027ready\u0027, self.play);\n return;\n }\n\n player.playVideo();\n };\n\n /**\n * Pause the video.\n *\n * @public\n */\n self.pause = function () {\n self.off(\u0027ready\u0027, self.play);\n if (!player || !player.pauseVideo) {\n return;\n }\n player.pauseVideo();\n };\n\n /**\n * Seek video to given time.\n *\n * @public\n * @param {Number} time\n */\n self.seek = function (time) {\n if (!player || !player.seekTo) {\n return;\n }\n\n player.seekTo(time, true);\n };\n\n /**\n * Get elapsed time since video beginning.\n *\n * @public\n * @returns {Number}\n */\n self.getCurrentTime = function () {\n if (!player || !player.getCurrentTime) {\n return;\n }\n\n return player.getCurrentTime();\n };\n\n /**\n * Get total video duration time.\n *\n * @public\n * @returns {Number}\n */\n self.getDuration = function () {\n if (!player || !player.getDuration) {\n return;\n }\n\n return player.getDuration();\n };\n\n /**\n * Get percentage of video that is buffered.\n *\n * @public\n * @returns {Number} Between 0 and 100\n */\n self.getBuffered = function () {\n if (!player || !player.getVideoLoadedFraction) {\n return;\n }\n\n return player.getVideoLoadedFraction() * 100;\n };\n\n /**\n * Turn off video sound.\n *\n * @public\n */\n self.mute = function () {\n if (!player || !player.mute) {\n return;\n }\n\n player.mute();\n };\n\n /**\n * Turn on video sound.\n *\n * @public\n */\n self.unMute = function () {\n if (!player || !player.unMute) {\n return;\n }\n\n player.unMute();\n };\n\n /**\n * Check if video sound is turned on or off.\n *\n * @public\n * @returns {Boolean}\n */\n self.isMuted = function () {\n if (!player || !player.isMuted) {\n return;\n }\n\n return player.isMuted();\n };\n\n /**\n * Return the video sound level.\n *\n * @public\n * @returns {Number} Between 0 and 100.\n */\n self.getVolume = function () {\n if (!player || !player.getVolume) {\n return;\n }\n\n return player.getVolume();\n };\n\n /**\n * Set video sound level.\n *\n * @public\n * @param {Number} level Between 0 and 100.\n */\n self.setVolume = function (level) {\n if (!player || !player.setVolume) {\n return;\n }\n\n player.setVolume(level);\n };\n\n /**\n * Get list of available playback rates.\n *\n * @public\n * @returns {Array} available playback rates\n */\n self.getPlaybackRates = function () {\n if (!player || !player.getAvailablePlaybackRates) {\n return;\n }\n\n var playbackRates = player.getAvailablePlaybackRates();\n if (!playbackRates.length) {\n return; // No rates, but the array should contain at least 1\n }\n\n return playbackRates;\n };\n\n /**\n * Get current playback rate.\n *\n * @public\n * @returns {Number} such as 0.25, 0.5, 1, 1.25, 1.5 and 2\n */\n self.getPlaybackRate = function () {\n if (!player || !player.getPlaybackRate) {\n return;\n }\n\n var playbackRate = player.getPlaybackRate();\n\t return playbackRate;\n };\n\n /**\n * Set current playback rate.\n * Listen to event \"playbackRateChange\" to check if successful.\n *\n * @public\n * @params {Number} suggested rate that may be rounded to supported values\n */\n self.setPlaybackRate = function (newPlaybackRate) {\n if (!player || !player.setPlaybackRate) {\n return;\n }\n\n playbackRate = newPlaybackRate;\n player.setPlaybackRate(newPlaybackRate);\n };\n\n /**\n * Set current captions track.\n *\n * @param {H5P.Video.LabelValue} Captions track to show during playback\n */\n self.setCaptionsTrack = function (track) {\n player.setOption(\u0027captions\u0027, \u0027track\u0027, track ? {languageCode: track.value} : {});\n };\n\n /**\n * Figure out which captions track is currently used.\n *\n * @return {H5P.Video.LabelValue} Captions track\n */\n self.getCaptionsTrack = function () {\n var track = player.getOption(\u0027captions\u0027, \u0027track\u0027);\n return (track.languageCode ? new H5P.Video.LabelValue(track.displayName, track.languageCode) : null);\n };\n\n // Respond to resize events by setting the YT player size.\n self.on(\u0027resize\u0027, function () {\n if (!$wrapper.is(\u0027:visible\u0027)) {\n return;\n }\n\n if (!player) {\n // Player isn\u0027t created yet. Try again.\n create();\n return;\n }\n\n // Use as much space as possible\n $wrapper.css({\n width: \u0027100%\u0027,\n height: \u0027100%\u0027\n });\n\n var width = $wrapper[0].clientWidth;\n var height = options.fit ? $wrapper[0].clientHeight : (width * (9/16));\n\n // Set size\n $wrapper.css({\n width: width + \u0027px\u0027,\n height: height + \u0027px\u0027\n });\n\n player.setSize(width, height);\n });\n }\n\n /**\n * Check to see if we can play any of the given sources.\n *\n * @public\n * @static\n * @param {Array} sources\n * @returns {Boolean}\n */\n YouTube.canPlay = function (sources) {\n return getId(sources[0].path);\n };\n\n /**\n * Find id of YouTube video from given URL.\n *\n * @private\n * @param {String} url\n * @returns {String} YouTube video identifier\n */\n\n var getId = function (url) {\n // Has some false positives, but should cover all regular URLs that people can find\n var matches = url.match(/(?:(?:youtube.com\\/(?:attribution_link\\?(?:\\S+))?(?:v\\/|embed\\/|watch\\/|(?:user\\/(?:\\S+)\\/)?watch(?:\\S+)v\\=))|(?:youtu.be\\/|y2u.be\\/))([A-Za-z0-9_-]{11})/i);\n if (matches \u0026\u0026 matches[1]) {\n return matches[1];\n }\n };\n\n /**\n * Load the IFrame Player API asynchronously.\n */\n var loadAPI = function (loaded) {\n if (window.onYouTubeIframeAPIReady !== undefined) {\n // Someone else is loading, hook in\n var original = window.onYouTubeIframeAPIReady;\n window.onYouTubeIframeAPIReady = function (id) {\n loaded(id);\n original(id);\n };\n }\n else {\n // Load the API our self\n var tag = document.createElement(\u0027script\u0027);\n tag.src = \"https://www.youtube.com/iframe_api\";\n var firstScriptTag = document.getElementsByTagName(\u0027script\u0027)[0];\n firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);\n window.onYouTubeIframeAPIReady = loaded;\n }\n };\n\n /** @constant {Object} */\n var LABELS = {\n highres: \u00272160p\u0027,\n hd1440: \u00271440p\u0027,\n hd1080: \u00271080p\u0027,\n hd720: \u0027720p\u0027,\n large: \u0027480p\u0027,\n medium: \u0027360p\u0027,\n small: \u0027240p\u0027,\n tiny: \u0027144p\u0027,\n auto: \u0027Auto\u0027\n };\n\n /** @private */\n var numInstances = 0;\n\n // Extract the current origin (used for security)\n var ORIGIN = window.location.href.match(/http[s]?:\\/\\/[^\\/]+/)[0];\n\n return YouTube;\n})(H5P.jQuery);\n\n// Register video handler\nH5P.videoHandlers = H5P.videoHandlers || [];\nH5P.videoHandlers.push(H5P.VideoYouTube);\n"
,"scripts/html5.js":"/** @namespace H5P */\nH5P.VideoHtml5 = (function ($) {\n\n /**\n * HTML5 video player for H5P.\n *\n * @class\n * @param {Array} sources Video files to use\n * @param {Object} options Settings for the player\n * @param {Object} l10n Localization strings\n */\n function Html5(sources, options, l10n) {\n var self = this;\n\n /**\n * Displayed when the video is buffering\n * @private\n */\n var $throbber = $(\u0027\u003cdiv/\u003e\u0027, {\n \u0027class\u0027: \u0027h5p-video-loading\u0027\n });\n\n /**\n * Used to display error messages\n * @private\n */\n var $error = $(\u0027\u003cdiv/\u003e\u0027, {\n \u0027class\u0027: \u0027h5p-video-error\u0027\n });\n\n /**\n * Keep track of current state when changing quality.\n * @private\n */\n var stateBeforeChangingQuality;\n var currentTimeBeforeChangingQuality;\n\n /**\n * Avoids firing the same event twice.\n * @private\n */\n var lastState;\n\n /**\n * Keeps track whether or not the video has been loaded.\n * @private\n */\n var isLoaded = false;\n\n /**\n *\n * @private\n */\n var playbackRate = 1;\n var skipRateChange = false;\n\n // Create player\n var video = document.createElement(\u0027video\u0027);\n\n // Sort sources into qualities\n var qualities = getQualities(sources, video);\n\n // Select quality and source\n var currentQuality = getPreferredQuality();\n if (currentQuality === undefined || qualities[currentQuality] === undefined) {\n // No preferred quality, pick the first.\n for (currentQuality in qualities) {\n if (qualities.hasOwnProperty(currentQuality)) {\n break;\n }\n }\n }\n video.src = qualities[currentQuality].source.path;\n\n // Setting webkit-playsinline, which makes iOS 10 beeing able to play video\n // inside browser.\n video.setAttribute(\u0027webkit-playsinline\u0027, \u0027\u0027);\n video.setAttribute(\u0027playsinline\u0027, \u0027\u0027);\n video.setAttribute(\u0027preload\u0027, \u0027metadata\u0027);\n\n // Set options\n video.disableRemotePlayback = (options.disableRemotePlayback ? true : false);\n video.controls = (options.controls ? true : false);\n video.autoplay = (options.autoplay ? true : false);\n video.loop = (options.loop ? true : false);\n video.className = \u0027h5p-video\u0027;\n video.style.display = \u0027block\u0027;\n\n if (options.fit) {\n // Style is used since attributes with relative sizes aren\u0027t supported by IE9.\n video.style.width = \u0027100%\u0027;\n video.style.height = \u0027100%\u0027;\n }\n // Add poster if provided\n if (options.poster) {\n video.poster = options.poster;\n }\n\n /**\n * Register track to video\n *\n * @param {Object} trackData Track object\n * @param {string} trackData.kind Kind of track\n * @param {Object} trackData.track Source path\n * @param {string} [trackData.label] Label of track\n * @param {string} [trackData.srcLang] Language code\n */\n var addTrack = function (trackData) {\n // Skip invalid tracks\n if (!trackData.kind || !trackData.track.path) {\n return;\n }\n\n var track = document.createElement(\u0027track\u0027);\n track.kind = trackData.kind;\n track.src = trackData.track.path;\n if (trackData.label) {\n track.label = trackData.label;\n }\n\n if (trackData.srcLang) {\n track.srcLang = trackData.srcLang;\n }\n\n return track;\n };\n\n // Register tracks\n options.tracks.forEach(function (track, i) {\n var trackElement = addTrack(track);\n if (i === 0) {\n trackElement.default = true;\n }\n if (trackElement) {\n video.appendChild(trackElement);\n }\n });\n\n /**\n * Helps registering events.\n *\n * @private\n * @param {String} native Event name\n * @param {String} h5p Event name\n * @param {String} [arg] Optional argument\n */\n var mapEvent = function (native, h5p, arg) {\n video.addEventListener(native, function () {\n switch (h5p) {\n case \u0027stateChange\u0027:\n if (lastState === arg) {\n return; // Avoid firing event twice.\n }\n\n var validStartTime = options.startAt \u0026\u0026 options.startAt \u003e 0;\n if (arg === H5P.Video.PLAYING \u0026\u0026 validStartTime) {\n video.currentTime = options.startAt;\n delete options.startAt;\n }\n\n break;\n\n case \u0027loaded\u0027:\n isLoaded = true;\n\n if (stateBeforeChangingQuality !== undefined) {\n return; // Avoid loaded event when changing quality.\n }\n\n // Remove any errors\n if ($error.is(\u0027:visible\u0027)) {\n $error.remove();\n }\n\n if (OLD_ANDROID_FIX) {\n var andLoaded = function () {\n video.removeEventListener(\u0027durationchange\u0027, andLoaded, false);\n // On Android seeking isn\u0027t ready until after play.\n self.trigger(h5p);\n };\n video.addEventListener(\u0027durationchange\u0027, andLoaded, false);\n return;\n }\n break;\n\n case \u0027error\u0027:\n // Handle error and get message.\n arg = error(arguments[0], arguments[1]);\n break;\n\n case \u0027playbackRateChange\u0027:\n\n // Fix for keeping playback rate in IE11\n if (skipRateChange) {\n skipRateChange = false;\n return; // Avoid firing event when changing back\n }\n if (H5P.Video.IE11_PLAYBACK_RATE_FIX \u0026\u0026 playbackRate != video.playbackRate) { // Intentional\n // Prevent change in playback rate not triggered by the user\n video.playbackRate = playbackRate;\n skipRateChange = true;\n return;\n }\n // End IE11 fix\n\n arg = self.getPlaybackRate();\n break;\n }\n self.trigger(h5p, arg);\n }, false);\n };\n\n /**\n * Handle errors from the video player.\n *\n * @private\n * @param {Object} code Error\n * @param {String} [message]\n * @returns {String} Human readable error message.\n */\n var error = function (code, message) {\n if (code instanceof Event) {\n\n // No error code\n if (!code.target.error) {\n return \u0027\u0027;\n }\n\n switch (code.target.error.code) {\n case MediaError.MEDIA_ERR_ABORTED:\n message = l10n.aborted;\n break;\n case MediaError.MEDIA_ERR_NETWORK:\n message = l10n.networkFailure;\n break;\n case MediaError.MEDIA_ERR_DECODE:\n message = l10n.cannotDecode;\n break;\n case MediaError.MEDIA_ERR_SRC_NOT_SUPPORTED:\n message = l10n.formatNotSupported;\n break;\n case MediaError.MEDIA_ERR_ENCRYPTED:\n message = l10n.mediaEncrypted;\n break;\n }\n }\n if (!message) {\n message = l10n.unknownError;\n }\n\n // Hide throbber\n $throbber.remove();\n\n // Display error message to user\n $error.text(message).insertAfter(video);\n\n // Pass message to our error event\n return message;\n };\n\n /**\n * Appends the video player to the DOM.\n *\n * @public\n * @param {jQuery} $container\n */\n self.appendTo = function ($container) {\n $container.append(video);\n };\n\n /**\n * Get list of available qualities. Not available until after play.\n *\n * @public\n * @returns {Array}\n */\n self.getQualities = function () {\n // Create reverse list\n var options = [];\n for (var q in qualities) {\n if (qualities.hasOwnProperty(q)) {\n options.splice(0, 0, {\n name: q,\n label: qualities[q].label\n });\n }\n }\n\n if (options.length \u003c 2) {\n // Do not return if only one quality.\n return;\n }\n\n return options;\n };\n\n /**\n * Get current playback quality. Not available until after play.\n *\n * @public\n * @returns {String}\n */\n self.getQuality = function () {\n return currentQuality;\n };\n\n /**\n * Set current playback quality. Not available until after play.\n * Listen to event \"qualityChange\" to check if successful.\n *\n * @public\n * @params {String} [quality]\n */\n self.setQuality = function (quality) {\n if (qualities[quality] === undefined || quality === currentQuality) {\n return; // Invalid quality\n }\n\n // Keep track of last choice\n setPreferredQuality(quality);\n\n // Avoid multiple loaded events if changing quality multiple times.\n if (!stateBeforeChangingQuality) {\n // Keep track of last state\n stateBeforeChangingQuality = lastState;\n\n // Keep track of current time\n currentTimeBeforeChangingQuality = video.currentTime;\n\n // Seek and start video again after loading.\n var loaded = function () {\n video.removeEventListener(\u0027loadedmetadata\u0027, loaded, false);\n if (OLD_ANDROID_FIX) {\n var andLoaded = function () {\n video.removeEventListener(\u0027durationchange\u0027, andLoaded, false);\n // On Android seeking isn\u0027t ready until after play.\n self.seek(currentTimeBeforeChangingQuality);\n };\n video.addEventListener(\u0027durationchange\u0027, andLoaded, false);\n }\n else {\n // Seek to current time.\n self.seek(currentTimeBeforeChangingQuality);\n }\n\n // Always play to get image.\n video.play();\n\n if (stateBeforeChangingQuality !== H5P.Video.PLAYING) {\n // Do not resume playing\n video.pause();\n }\n\n // Done changing quality\n stateBeforeChangingQuality = undefined;\n\n // Remove any errors\n if ($error.is(\u0027:visible\u0027)) {\n $error.remove();\n }\n };\n video.addEventListener(\u0027loadedmetadata\u0027, loaded, false);\n }\n\n // Keep track of current quality\n currentQuality = quality;\n self.trigger(\u0027qualityChange\u0027, currentQuality);\n\n // Display throbber\n self.trigger(\u0027stateChange\u0027, H5P.Video.BUFFERING);\n\n // Change source\n video.src = qualities[quality].source.path; // (iPad does not support #t=).\n\n // Remove poster so it will not show during quality change\n video.removeAttribute(\u0027poster\u0027);\n };\n\n /**\n * Starts the video.\n *\n * @public\n * @return {Promise|undefined} May return a Promise that resolves when\n * play has been processed.\n */\n self.play = function () {\n if ($error.is(\u0027:visible\u0027)) {\n return;\n }\n\n if (!isLoaded) {\n // Make sure video is loaded before playing\n video.load();\n }\n\n return video.play();\n };\n\n /**\n * Pauses the video.\n *\n * @public\n */\n self.pause = function () {\n video.pause();\n };\n\n /**\n * Seek video to given time.\n *\n * @public\n * @param {Number} time\n */\n self.seek = function (time) {\n if (lastState === undefined) {\n // Make sure we always play before we seek to get an image.\n // If not iOS devices will reset currentTime when pressing play.\n video.play();\n video.pause();\n }\n\n video.currentTime = time;\n };\n\n /**\n * Get elapsed time since video beginning.\n *\n * @public\n * @returns {Number}\n */\n self.getCurrentTime = function () {\n return video.currentTime;\n };\n\n /**\n * Get total video duration time.\n *\n * @public\n * @returns {Number}\n */\n self.getDuration = function () {\n if (isNaN(video.duration)) {\n return;\n }\n\n return video.duration;\n };\n\n /**\n * Get percentage of video that is buffered.\n *\n * @public\n * @returns {Number} Between 0 and 100\n */\n self.getBuffered = function () {\n // Find buffer currently playing from\n var buffered = 0;\n for (var i = 0; i \u003c video.buffered.length; i++) {\n var from = video.buffered.start(i);\n var to = video.buffered.end(i);\n\n if (video.currentTime \u003e from \u0026\u0026 video.currentTime \u003c to) {\n buffered = to;\n break;\n }\n }\n\n // To percentage\n return buffered ? (buffered / video.duration) * 100 : 0;\n };\n\n /**\n * Turn off video sound.\n *\n * @public\n */\n self.mute = function () {\n video.muted = true;\n };\n\n /**\n * Turn on video sound.\n *\n * @public\n */\n self.unMute = function () {\n video.muted = false;\n };\n\n /**\n * Check if video sound is turned on or off.\n *\n * @public\n * @returns {Boolean}\n */\n self.isMuted = function () {\n return video.muted;\n };\n\n /**\n * Returns the video sound level.\n *\n * @public\n * @returns {Number} Between 0 and 100.\n */\n self.getVolume = function () {\n return video.volume * 100;\n };\n\n /**\n * Set video sound level.\n *\n * @public\n * @param {Number} level Between 0 and 100.\n */\n self.setVolume = function (level) {\n video.volume = level / 100;\n };\n\n /**\n * Get list of available playback rates.\n *\n * @public\n * @returns {Array} available playback rates\n */\n self.getPlaybackRates = function () {\n /*\n * not sure if there\u0027s a common rule about determining good speeds\n * using Google\u0027s standard options via a constant for setting\n */\n var playbackRates = PLAYBACK_RATES;\n\n return playbackRates;\n };\n\n /**\n * Get current playback rate.\n *\n * @public\n * @returns {Number} such as 0.25, 0.5, 1, 1.25, 1.5 and 2\n */\n self.getPlaybackRate = function () {\n return video.playbackRate;\n };\n\n /**\n * Set current playback rate.\n * Listen to event \"playbackRateChange\" to check if successful.\n *\n * @public\n * @params {Number} suggested rate that may be rounded to supported values\n */\n self.setPlaybackRate = function (newPlaybackRate) {\n playbackRate = newPlaybackRate;\n video.playbackRate = newPlaybackRate;\n };\n\n /**\n * Set current captions track.\n *\n * @param {H5P.Video.LabelValue} Captions track to show during playback\n */\n self.setCaptionsTrack = function (track) {\n for (var i = 0; i \u003c video.textTracks.length; i++) {\n video.textTracks[i].mode = (track \u0026\u0026 track.value === i ? \u0027showing\u0027 : \u0027disabled\u0027);\n }\n };\n\n /**\n * Figure out which captions track is currently used.\n *\n * @return {H5P.Video.LabelValue} Captions track\n */\n self.getCaptionsTrack = function () {\n for (var i = 0; i \u003c video.textTracks.length; i++) {\n if (video.textTracks[i].mode === \u0027showing\u0027) {\n return new H5P.Video.LabelValue(video.textTracks[i].label, i);\n }\n }\n\n return null;\n };\n\n // Register event listeners\n mapEvent(\u0027ended\u0027, \u0027stateChange\u0027, H5P.Video.ENDED);\n mapEvent(\u0027playing\u0027, \u0027stateChange\u0027, H5P.Video.PLAYING);\n mapEvent(\u0027pause\u0027, \u0027stateChange\u0027, H5P.Video.PAUSED);\n mapEvent(\u0027waiting\u0027, \u0027stateChange\u0027, H5P.Video.BUFFERING);\n mapEvent(\u0027loadedmetadata\u0027, \u0027loaded\u0027);\n mapEvent(\u0027error\u0027, \u0027error\u0027);\n mapEvent(\u0027ratechange\u0027, \u0027playbackRateChange\u0027);\n\n if (!video.controls) {\n // Disable context menu(right click) to prevent controls.\n video.addEventListener(\u0027contextmenu\u0027, function (event) {\n event.preventDefault();\n }, false);\n }\n\n // Display throbber when buffering/loading video.\n self.on(\u0027stateChange\u0027, function (event) {\n var state = event.data;\n lastState = state;\n if (state === H5P.Video.BUFFERING) {\n $throbber.insertAfter(video);\n }\n else {\n $throbber.remove();\n }\n });\n\n // Load captions after the video is loaded\n self.on(\u0027loaded\u0027, function () {\n nextTick(function () {\n var textTracks = [];\n for (var i = 0; i \u003c video.textTracks.length; i++) {\n textTracks.push(new H5P.Video.LabelValue(video.textTracks[i].label, i));\n }\n if (textTracks.length) {\n self.trigger(\u0027captions\u0027, textTracks);\n }\n });\n });\n\n // Video controls are ready\n nextTick(function () {\n self.trigger(\u0027ready\u0027);\n });\n }\n\n /**\n * Check to see if we can play any of the given sources.\n *\n * @public\n * @static\n * @param {Array} sources\n * @returns {Boolean}\n */\n Html5.canPlay = function (sources) {\n var video = document.createElement(\u0027video\u0027);\n if (video.canPlayType === undefined) {\n return false; // Not supported\n }\n\n // Cycle through sources\n for (var i = 0; i \u003c sources.length; i++) {\n var type = getType(sources[i]);\n if (type \u0026\u0026 video.canPlayType(type) !== \u0027\u0027) {\n // We should be able to play this\n return true;\n }\n }\n\n return false;\n };\n\n /**\n * Find source type.\n *\n * @private\n * @param {Object} source\n * @returns {String}\n */\n var getType = function (source) {\n var type = source.mime;\n if (!type) {\n // Try to get type from URL\n var matches = source.path.match(/\\.(\\w+)$/);\n if (matches \u0026\u0026 matches[1]) {\n type = \u0027video/\u0027 + matches[1];\n }\n }\n\n if (type \u0026\u0026 source.codecs) {\n // Add codecs\n type += \u0027; codecs=\"\u0027 + source.codecs + \u0027\"\u0027;\n }\n\n return type;\n };\n\n /**\n * Sort sources into qualities.\n *\n * @private\n * @static\n * @param {Array} sources\n * @param {Object} video\n * @returns {Object} Quality mapping\n */\n var getQualities = function (sources, video) {\n var qualities = {};\n var qualityIndex = 1;\n var lastQuality;\n\n // Cycle through sources\n for (var i = 0; i \u003c sources.length; i++) {\n var source = sources[i];\n\n // Find and update type.\n var type = source.type = getType(source);\n\n // Check if we support this type\n var isPlayable = type \u0026\u0026 (type === \u0027video/unknown\u0027 || video.canPlayType(type) !== \u0027\u0027);\n if (!isPlayable) {\n continue; // We cannot play this source\n }\n\n if (source.quality === undefined) {\n /**\n * No quality metadata. Create a quality tag to separate multiple sources of the same type,\n * e.g. if two mp4 files with different quality has been uploaded\n */\n\n if (lastQuality === undefined || qualities[lastQuality].source.type === type) {\n // Create a new quality tag\n source.quality = {\n name: \u0027q\u0027 + qualityIndex,\n label: (source.metadata \u0026\u0026 source.metadata.qualityName) ? source.metadata.qualityName : \u0027Quality \u0027 + qualityIndex // TODO: l10n\n };\n qualityIndex++;\n }\n else {\n /**\n * Assumes quality already exists in a different format.\n * Uses existing label for this quality.\n */\n source.quality = qualities[lastQuality].source.quality;\n }\n }\n\n // Log last quality\n lastQuality = source.quality.name;\n\n // Look to see if quality exists\n var quality = qualities[lastQuality];\n if (quality) {\n // We have a source with this quality. Check if we have a better format.\n if (source.mime.split(\u0027/\u0027)[1] === PREFERRED_FORMAT) {\n quality.source = source;\n }\n }\n else {\n // Add new source with quality.\n qualities[source.quality.name] = {\n label: source.quality.label,\n source: source\n };\n }\n }\n\n return qualities;\n };\n\n /**\n * Set preferred video quality.\n *\n * @private\n * @static\n * @param {String} quality Index of preferred quality\n */\n var setPreferredQuality = function (quality) {\n var settings = document.cookie.split(\u0027;\u0027);\n for (var i = 0; i \u003c settings.length; i++) {\n var setting = settings[i].split(\u0027=\u0027);\n if (setting[0] === \u0027H5PVideoQuality\u0027) {\n setting[1] = quality;\n settings[i] = setting.join(\u0027=\u0027);\n document.cookie = settings.join(\u0027;\u0027);\n return;\n }\n }\n\n document.cookie = \u0027H5PVideoQuality=\u0027 + quality + \u0027; \u0027 + document.cookie;\n };\n\n /**\n * Get preferred video quality.\n *\n * @private\n * @static\n * @returns {String} Index of preferred quality\n */\n var getPreferredQuality = function () {\n var quality, settings = document.cookie.split(\u0027;\u0027);\n for (var i = 0; i \u003c settings.length; i++) {\n var setting = settings[i].split(\u0027=\u0027);\n if (setting[0] === \u0027H5PVideoQuality\u0027) {\n quality = setting[1];\n break;\n }\n }\n\n return quality;\n };\n\n /**\n * Helps schedule a task for the next tick.\n * @param {function} task\n */\n var nextTick = function (task) {\n setTimeout(task, 0);\n };\n\n /** @constant {Boolean} */\n var OLD_ANDROID_FIX = false;\n\n /** @constant {Boolean} */\n var PREFERRED_FORMAT = \u0027mp4\u0027;\n\n /** @constant {Object} */\n var PLAYBACK_RATES = [0.25, 0.5, 1, 1.25, 1.5, 2];\n\n if (navigator.userAgent.indexOf(\u0027Android\u0027) !== -1) {\n // We have Android, check version.\n var version = navigator.userAgent.match(/AppleWebKit\\/(\\d+\\.?\\d*)/);\n if (version \u0026\u0026 version[1] \u0026\u0026 Number(version[1]) \u003c= 534.30) {\n // Include fix for devices running the native Android browser.\n // (We don\u0027t know when video was fixed, so the number is just the lastest\n // native android browser we found.)\n OLD_ANDROID_FIX = true;\n }\n }\n else {\n if (navigator.userAgent.indexOf(\u0027Chrome\u0027) !== -1) {\n // If we\u0027re using chrome on a device that isn\u0027t Android, prefer the webm\n // format. This is because Chrome has trouble with some mp4 codecs.\n PREFERRED_FORMAT = \u0027webm\u0027;\n }\n }\n\n return Html5;\n})(H5P.jQuery);\n\n// Register video handler\nH5P.videoHandlers = H5P.videoHandlers || [];\nH5P.videoHandlers.push(H5P.VideoHtml5);\n"
,"scripts/flash.js":"/** @namespace H5P */\nH5P.VideoFlash = (function ($) {\n\n /**\n * Flash video player for H5P.\n *\n * @class\n * @param {Array} sources Video files to use\n * @param {Object} options Settings for the player\n */\n function Flash(sources, options) {\n var self = this;\n\n // Player wrapper\n var $wrapper = $(\u0027\u003cdiv/\u003e\u0027, {\n \u0027class\u0027: \u0027h5p-video-flash\u0027,\n css: {\n width: \u0027100%\u0027,\n height: \u0027100%\u0027\n }\n });\n\n /**\n * Used to display error messages\n * @private\n */\n var $error = $(\u0027\u003cdiv/\u003e\u0027, {\n \u0027class\u0027: \u0027h5p-video-error\u0027\n });\n\n /**\n * Keep track of current state when changing quality.\n * @private\n */\n var stateBeforeChangingQuality;\n var currentTimeBeforeChangingQuality;\n\n // Sort sources into qualities\n //var qualities = getQualities(sources);\n var currentQuality;\n\n // Create player options\n var playerOptions = {\n buffering: true,\n clip: {\n url: sources[0].path, // getPreferredQuality(),\n autoPlay: options.autoplay,\n autoBuffering: true,\n scaling: \u0027fit\u0027,\n onSeek: function () {\n if (stateBeforeChangingQuality) {\n // ????\n }\n },\n onMetaData: function () {\n setTimeout(function () {\n if (stateBeforeChangingQuality !== undefined) {\n fp.seek(currentTimeBeforeChangingQuality);\n if (stateBeforeChangingQuality === H5P.Video.PLAYING) {\n // Resume play\n fp.play();\n }\n\n // Done changing quality\n stateBeforeChangingQuality = undefined;\n\n // Remove any errors\n if ($error.is(\u0027:visible\u0027)) {\n $error.remove();\n }\n }\n else {\n self.trigger(\u0027ready\u0027);\n self.trigger(\u0027loaded\u0027);\n }\n }, 0); // Run on next tick\n },\n onBegin: function () {\n self.trigger(\u0027stateChange\u0027, H5P.Video.PLAYING);\n },\n onResume: function () {\n self.trigger(\u0027stateChange\u0027, H5P.Video.PLAYING);\n },\n onPause: function () {\n self.trigger(\u0027stateChange\u0027, H5P.Video.PAUSED);\n },\n onFinish: function () {\n self.trigger(\u0027stateChange\u0027, H5P.Video.ENDED);\n },\n onError: function (code, message) {\n console.log(\u0027ERROR\u0027, code, message); // TODO\n self.trigger(\u0027error\u0027, message);\n }\n },\n plugins: {\n controls: null\n },\n play: null, // Disable overlay controls\n onPlaylistReplace: function () {\n that.playlistReplaced();\n }\n };\n\n if (options.controls) {\n playerOptions.plugins.controls = {};\n delete playerOptions.play;\n }\n\n var fp = flowplayer($wrapper[0], {\n src: \"http://releases.flowplayer.org/swf/flowplayer-3.2.16.swf\",\n wmode: \"opaque\"\n }, playerOptions);\n\n /**\n * Appends the video player to the DOM.\n *\n * @public\n * @param {jQuery} $container\n */\n self.appendTo = function ($container) {\n $wrapper.appendTo($container);\n };\n\n /**\n * Get list of available qualities. Not available until after play.\n *\n * @public\n * @returns {Array}\n */\n self.getQualities = function () {\n return;\n };\n\n /**\n * Get current playback quality. Not available until after play.\n *\n * @public\n * @returns {String}\n */\n self.getQuality = function () {\n return currentQuality;\n };\n\n /**\n * Set current playback quality. Not available until after play.\n * Listen to event \"qualityChange\" to check if successful.\n *\n * @public\n * @params {String} [quality]\n */\n self.setQuality = function (quality) {\n if (qualities[quality] === undefined || quality === currentQuality) {\n return; // Invalid quality\n }\n\n // Keep track of last choice\n setPreferredQuality(quality);\n\n // Avoid multiple loaded events if changing quality multiple times.\n if (!stateBeforeChangingQuality) {\n // Keep track of last state\n stateBeforeChangingQuality = lastState;\n\n // Keep track of current time\n currentTimeBeforeChangingQuality = video.currentTime;\n }\n\n // Keep track of current quality\n currentQuality = quality;\n self.trigger(\u0027qualityChange\u0027, currentQuality);\n\n // Display throbber\n self.trigger(\u0027stateChange\u0027, H5P.Video.BUFFERING);\n\n // Change source\n fp.setClip(qualities[quality].source.path);\n fp.startBuffering();\n };\n\n /**\n * Starts the video.\n *\n * @public\n */\n self.play = function () {\n if ($error.is(\u0027:visible\u0027)) {\n return;\n }\n\n fp.play();\n };\n\n /**\n * Pauses the video.\n *\n * @public\n */\n self.pause = function () {\n fp.pause();\n };\n\n /**\n * Seek video to given time.\n *\n * @public\n * @param {Number} time\n */\n self.seek = function (time) {\n fp.seek(time);\n };\n\n /**\n * Get elapsed time since video beginning.\n *\n * @public\n * @returns {Number}\n */\n self.getCurrentTime = function () {\n return fp.getTime();\n };\n\n /**\n * Get total video duration time.\n *\n * @public\n * @returns {Number}\n */\n self.getDuration = function () {\n return fp.getClip().metaData.duration;\n };\n\n /**\n * Get percentage of video that is buffered.\n *\n * @public\n * @returns {Number} Between 0 and 100\n */\n self.getBuffered = function () {\n return fp.getClip().buffer;\n };\n\n /**\n * Turn off video sound.\n *\n * @public\n */\n self.mute = function () {\n fp.mute();\n };\n\n /**\n * Turn on video sound.\n *\n * @public\n */\n self.unMute = function () {\n fp.unmute();\n };\n\n /**\n * Check if video sound is turned on or off.\n *\n * @public\n * @returns {Boolean}\n */\n self.isMuted = function () {\n return fp.muted;\n };\n\n /**\n * Returns the video sound level.\n *\n * @public\n * @returns {Number} Between 0 and 100.\n */\n self.getVolume = function () {\n return fp.volumeLevel * 100;\n };\n\n /**\n * Set video sound level.\n *\n * @public\n * @param {Number} volume Between 0 and 100.\n */\n self.setVolume = function (level) {\n fp.volume(level / 100);\n };\n\n // Handle resize events\n self.on(\u0027resize\u0027, function () {\n var $object = H5P.jQuery(fp.getParent()).children(\u0027object\u0027);\n var clip = fp.getClip();\n\n if (clip !== undefined) {\n $object.css(\u0027height\u0027, $object.width() * (clip.metaData.height / clip.metaData.width));\n }\n });\n }\n\n /**\n * Check to see if we can play any of the given sources.\n *\n * @public\n * @static\n * @param {Array} sources\n * @returns {Boolean}\n */\n Flash.canPlay = function (sources) {\n // Cycle through sources\n for (var i = 0; i \u003c sources.length; i++) {\n if (sources[i].mime === \u0027video/mp4\u0027 || /\\.mp4$/.test(sources[i].mime)) {\n return true; // We only play mp4\n }\n }\n };\n\n return Flash;\n})(H5P.jQuery);\n\n// Register video handler\nH5P.videoHandlers = H5P.videoHandlers || [];\nH5P.videoHandlers.push(H5P.VideoFlash);\n"
,"scripts/video.js":"/** @namespace H5P */\nH5P.Video = (function ($, ContentCopyrights, MediaCopyright, handlers) {\n\n /**\n * The ultimate H5P video player!\n *\n * @class\n * @param {Object} parameters Options for this library.\n * @param {Object} parameters.visuals Visual options\n * @param {Object} parameters.playback Playback options\n * @param {Object} parameters.a11y Accessibility options\n * @param {Boolean} [parameters.startAt] Start time of video\n * @param {Number} id Content identifier\n */\n function Video(parameters, id) {\n var self = this;\n\n // Ref youtube.js - ipad \u0026 youtube - issue\n self.pressToPlay = false;\n\n // Initialize event inheritance\n H5P.EventDispatcher.call(self);\n\n // Default language localization\n parameters = $.extend(true, parameters, {\n l10n: {\n name: \u0027Video\u0027,\n loading: \u0027Video player loading...\u0027,\n noPlayers: \u0027Found no video players that supports the given video format.\u0027,\n noSources: \u0027Video is missing sources.\u0027,\n aborted: \u0027Media playback has been aborted.\u0027,\n networkFailure: \u0027Network failure.\u0027,\n cannotDecode: \u0027Unable to decode media.\u0027,\n formatNotSupported: \u0027Video format not supported.\u0027,\n mediaEncrypted: \u0027Media encrypted.\u0027,\n unknownError: \u0027Unknown error.\u0027,\n invalidYtId: \u0027Invalid YouTube ID.\u0027,\n unknownYtId: \u0027Unable to find video with the given YouTube ID.\u0027,\n restrictedYt: \u0027The owner of this video does not allow it to be embedded.\u0027\n }\n });\n\n parameters.a11y = parameters.a11y || [];\n parameters.playback = parameters.playback || {};\n parameters.visuals = parameters.visuals || {};\n\n /** @private */\n var sources = [];\n if (parameters.sources) {\n for (var i = 0; i \u003c parameters.sources.length; i++) {\n // Clone to avoid changing of parameters.\n var source = $.extend(true, {}, parameters.sources[i]);\n\n // Create working URL without html entities.\n source.path = H5P.getPath($cleaner.html(source.path).text(), id);\n sources.push(source);\n }\n }\n\n /** @private */\n var tracks = [];\n parameters.a11y.forEach(function (track) {\n // Clone to avoid changing of parameters.\n var clone = $.extend(true, {}, track);\n\n // Create working URL without html entities\n if (clone.track \u0026\u0026 clone.track.path) {\n clone.track.path = H5P.getPath($cleaner.html(clone.track.path).text(), id);\n tracks.push(clone);\n }\n });\n\n /**\n * Attaches the video handler to the given container.\n * Inserts text if no handler is found.\n *\n * @public\n * @param {jQuery} $container\n */\n self.attach = function ($container) {\n $container.addClass(\u0027h5p-video\u0027).html(\u0027\u0027);\n\n if (self.appendTo !== undefined) {\n self.appendTo($container);\n }\n else {\n if (sources.length) {\n $container.text(parameters.l10n.noPlayers);\n }\n else {\n $container.text(parameters.l10n.noSources);\n }\n }\n };\n\n /**\n * Gather copyright information for the current video.\n *\n * @public\n * @returns {ContentCopyrights}\n */\n self.getCopyrights = function () {\n if (!sources[0] || !sources[0].copyright) {\n return;\n }\n\n // Use copyright information from H5P media field\n var info = new ContentCopyrights();\n info.addMedia(new MediaCopyright(sources[0].copyright));\n\n return info;\n };\n\n // Resize the video when we know its aspect ratio\n self.on(\u0027loaded\u0027, function () {\n self.trigger(\u0027resize\u0027);\n });\n\n // Find player for video sources\n if (sources.length) {\n var html5Handler;\n for (var i = 0; i \u003c handlers.length; i++) {\n var handler = handlers[i];\n if (handler.canPlay !== undefined \u0026\u0026 handler.canPlay(sources)) {\n handler.call(self, sources, {\n controls: parameters.visuals.controls,\n autoplay: parameters.playback.autoplay,\n loop: parameters.playback.loop,\n fit: parameters.visuals.fit,\n poster: parameters.visuals.poster === undefined ? undefined : H5P.getPath(parameters.visuals.poster.path, id),\n startAt: parameters.startAt || 0,\n tracks: tracks,\n disableRemotePlayback: (parameters.visuals.disableRemotePlayback || false)\n }, parameters.l10n);\n return;\n }\n\n if (handler === H5P.VideoHtml5) {\n html5Handler = handler;\n }\n }\n\n // Fallback to trying HTML5 player\n if (html5Handler) {\n html5Handler.call(self, sources, {\n controls: parameters.visuals.controls,\n autoplay: parameters.playback.autoplay,\n loop: parameters.playback.loop,\n fit: parameters.visuals.fit,\n poster: parameters.visuals.poster === undefined ? undefined : H5P.getPath(parameters.visuals.poster.path, id),\n startAt: parameters.startAt || 0,\n tracks: tracks,\n disableRemotePlayback: (parameters.visuals.disableRemotePlayback || false)\n }, parameters.l10n);\n }\n }\n }\n\n // Extends the event dispatcher\n Video.prototype = Object.create(H5P.EventDispatcher.prototype);\n Video.prototype.constructor = Video;\n\n // Player states\n /** @constant {Number} */\n Video.ENDED = 0;\n /** @constant {Number} */\n Video.PLAYING = 1;\n /** @constant {Number} */\n Video.PAUSED = 2;\n /** @constant {Number} */\n Video.BUFFERING = 3;\n /**\n * When video is queued to start\n * @constant {Number}\n */\n Video.VIDEO_CUED = 5;\n\n // Used to convert between html and text, since URLs have html entities.\n var $cleaner = H5P.jQuery(\u0027\u003cdiv/\u003e\u0027);\n\n /**\n * Help keep track of key value pairs used by the UI.\n *\n * @class\n * @param {string} label\n * @param {string} value\n */\n Video.LabelValue = function (label, value) {\n this.label = label;\n this.value = value;\n };\n\n /** @constant {Boolean} */\n Video.IE11_PLAYBACK_RATE_FIX = (navigator.userAgent.match(/Trident.*rv[ :]*11\\./) ? true : false);\n\n return Video;\n})(H5P.jQuery, H5P.ContentCopyrights, H5P.MediaCopyright, H5P.videoHandlers || []);\n"
,"dist/h5p-interactive-video.js":"!function(t){function e(n){if(o[n])return o[n].exports;var i=o[n]={i:n,l:!1,exports:{}};return t[n].call(i.exports,i,i.exports,e),i.l=!0,i.exports}var o={};e.m=t,e.c=o,e.d=function(t,o,n){e.o(t,o)||Object.defineProperty(t,o,{configurable:!1,enumerable:!0,get:n})},e.n=function(t){var o=t\u0026\u0026t.__esModule?function(){return t.default}:function(){return t};return e.d(o,\"a\",o),o},e.o=function(t,e){return Object.prototype.hasOwnProperty.call(t,e)},e.p=\"\",e(e.s=4)}([function(t,e,o){\"use strict\";function n(t){return t\u0026\u0026t.__esModule?t:{default:t}}function i(t,e,o){var n,r,a=this;H5P.EventDispatcher.call(a),a.contentId=e,a.instanceIndex=y(),a.bookmarksMenuId=\"interactive-video-\"+this.contentId+\"-bookmarks-chooser\",a.qualityMenuId=\"interactive-video-\"+this.contentId+\"-quality-chooser\",a.captionsMenuId=\"interactive-video-\"+this.contentId+\"-captions-chooser\",a.playbackRateMenuId=\"interactive-video-\"+this.contentId+\"-playback-rate-chooser\",a.isMinimal=!1,a.options=v.extend({video:{},assets:{}},t.interactiveVideo),a.options.video.startScreenOptions=a.options.video.startScreenOptions||{},a.options.video.startScreenOptions.title||(a.options.video.startScreenOptions.title=\"Interactive Video\"),a.startScreenOptions=v.extend({hideStartTitle:!1,shortStartDescription:\"\"},a.options.video.startScreenOptions),t.override\u0026\u0026(t.override.showSolutionButton||t.override.retryButton)\u0026\u0026(a.override={},t.override.showSolutionButton\u0026\u0026(a.override.enableSolutionsButton=\"on\"===t.override.showSolutionButton),t.override.retryButton\u0026\u0026(a.override.enableRetry=\"on\"===t.override.retryButton)),void 0!==t.override\u0026\u0026(a.showRewind10=void 0!==t.override.showRewind10\u0026\u0026t.override.showRewind10,a.showBookmarksmenuOnLoad=void 0!==t.override.showBookmarksmenuOnLoad\u0026\u0026t.override.showBookmarksmenuOnLoad,a.preventSkipping=t.override.preventSkipping||!1,a.deactivateSound=t.override.deactivateSound||!1),a.l10n=v.extend({interaction:\"Interaction\",play:\"Play\",pause:\"Pause\",mute:\"Mute\",unmute:\"Unmute\",quality:\"Video quality\",captions:\"Captions\",close:\"Close\",fullscreen:\"Fullscreen\",exitFullscreen:\"Exit fullscreen\",summary:\"Summary\",bookmarks:\"Bookmarks\",defaultAdaptivitySeekLabel:\"Continue\",continueWithVideo:\"Continue with video\",more:\"More\",playbackRate:\"Playback rate\",rewind10:\"Rewind 10 seconds\",navDisabled:\"Navigation is disabled\",sndDisabled:\"Sound is disabled\",requiresCompletionWarning:\"You need to answer all the questions correctly before continuing.\",back:\"Back\",hours:\"Hours\",minutes:\"Minutes\",seconds:\"Seconds\",currentTime:\"Current time:\",totalTime:\"Total time:\",navigationHotkeyInstructions:\"Use key \u0027k\u0027 for starting and stopping video at any time\",singleInteractionAnnouncement:\"Interaction appeared:\",multipleInteractionsAnnouncement:\"Multiple interactions appeared:\",videoPausedAnnouncement:\"Video was paused\",content:\"Content\"},t.l10n),o\u0026\u0026void 0!==o.previousState\u0026\u0026void 0!==o.previousState.progress\u0026\u0026void 0!==o.previousState.answers\u0026\u0026(a.previousState=o.previousState),a.lastState=H5P.Video.ENDED,a.on(\"resize\",function(){a.resize()}),a.justVideo=!1;var s=navigator.userAgent.match(/(iPhone|iPod) OS (\\d*)_/i);if(null!==s\u0026\u00263===s.length\u0026\u0026(a.justVideo=s[2]\u003c10),n=a.previousState\u0026\u0026a.previousState.progress?Math.floor(a.previousState.progress):0,0===n\u0026\u0026t.override\u0026\u0026t.override.startVideoAt\u0026\u0026(n=t.override.startVideoAt),r=t.override\u0026\u0026!!t.override.loop,this.autoplay=t.override\u0026\u0026!!t.override.autoplay,a.video=H5P.newRunnable({library:\"H5P.Video 1.3\",params:{sources:a.options.video.files,visuals:{poster:a.options.video.startScreenOptions.poster,controls:a.justVideo,fit:!1,disableRemotePlayback:!0},startAt:n,a11y:a.options.video.textTracks}},a.contentId,void 0,void 0,{parent:a}),a.justVideo)return void a.video.on(\"loaded\",function(){a.trigger(\"resize\")});var l=!1;a.video.on(\"loaded\",function(){l=!0,a.loaded()}),a.video.on(\"error\",function(){a.removeSplash()});var c=!0;if(a.video.on(\"stateChange\",function(e){!a.controls\u0026\u0026l\u0026\u0026(a.addControls(),a.trigger(\"resize\"));var o=e.data;if(a.currentState!==i.SEEKING)switch(o){case H5P.Video.ENDED:if(a.currentState=H5P.Video.ENDED,a.controls.$play.addClass(\"h5p-pause\").attr(\"aria-label\",a.l10n.play),a.timeUpdate(a.video.getCurrentTime()),a.updateCurrentTime(a.getDuration()),a.complete(),r){a.video.play();var n=t.override\u0026\u0026t.override.startVideoAt?t.override.startVideoAt:0;a.video.seek(n)}break;case H5P.Video.PLAYING:c\u0026\u0026(a.addQualityChooser(),a.addPlaybackRateChooser(),a.removeSplash(),a.startUpdatingBufferBar(),a.toggleBookmarksChooser(!1,c),c=!1),a.currentState=H5P.Video.PLAYING,a.controls.$play.removeClass(\"h5p-pause\").attr(\"aria-label\",a.l10n.pause),a.controls.$play.is(\":focus\")\u0026\u0026(a.controls.$play.blur(),a.controls.$play.focus()),a.timeUpdate(a.video.getCurrentTime());break;case H5P.Video.PAUSED:a.currentState=H5P.Video.PAUSED,a.controls.$play.addClass(\"h5p-pause\").attr(\"aria-label\",a.l10n.play),a.focusInteraction?(a.focusInteraction.getFirstTabbableElement().focus(),delete a.focusInteraction):a.controls.$play.is(\":focus\")\u0026\u0026(a.controls.$play.blur(),a.controls.$play.focus()),a.timeUpdate(a.video.getCurrentTime());break;case H5P.Video.BUFFERING:a.currentState=H5P.Video.BUFFERING,a.removeSplash(),a.startUpdatingBufferBar()}}),a.video.on(\"qualityChange\",function(t){var e=t.data;a.controls.$qualityChooser\u0026\u0026a.controls.$qualityChooser.find(\"li\").attr(\"aria-checked\",\"false\").filter(\u0027[data-quality=\"\u0027+e+\u0027\"]\u0027).attr(\"aria-checked\",\"true\")}),a.video.on(\"playbackRateChange\",function(t){var e=t.data;a.controls\u0026\u0026a.controls.$playbackRateChooser\u0026\u0026a.controls.$playbackRateChooser.find(\"li\").attr(\"aria-checked\",\"false\").filter(\u0027[playback-rate=\"\u0027+e+\u0027\"]\u0027).attr(\"aria-checked\",\"true\")}),a.on(\"enterFullScreen\",function(){a.hasFullScreen=!0,a.$container.parent(\".h5p-content\").css(\"height\",\"100%\"),a.controls.$fullscreen.addClass(\"h5p-exit\").attr(\"aria-label\",a.l10n.exitFullscreen),a.controls.$fullscreen.blur(),a.controls.$fullscreen.focus(),a.resizeInteractions()}),a.on(\"exitFullScreen\",function(){a.$container.hasClass(\"h5p-standalone\")\u0026\u0026a.$container.hasClass(\"h5p-minimal\")\u0026\u0026a.pause(),a.hasFullScreen=!1,a.$container.parent(\".h5p-content\").css(\"height\",\"\"),a.controls.$fullscreen.removeClass(\"h5p-exit\").attr(\"aria-label\",a.l10n.fullscreen),a.controls.$fullscreen.blur(),a.controls.$fullscreen.focus(),a.resizeInteractions(),a.dnb\u0026\u0026a.dnb.dialog\u0026\u0026!a.hasUncompletedRequiredInteractions()\u0026\u0026a.dnb.dialog.close()}),a.video.on(\"captions\",function(t){a.controls||(a.addControls(),a.trigger(\"resize\")),a.setCaptionTracks(t.data)}),a.interactions=[],a.options.assets.interactions)for(var u=0;u\u003ca.options.assets.interactions.length;u++)this.initInteraction(u);a.accessibility=new f.default(a.l10n)}Object.defineProperty(e,\"__esModule\",{value:!0}),e.KEY_CODE_START_PAUSE=void 0;var r=o(7),a=n(r),s=o(1),l=n(s),c=o(3),u=n(c),d=o(10),h=n(d),p=o(11),f=n(p),v=H5P.jQuery;i.prototype=Object.create(H5P.EventDispatcher.prototype),i.prototype.constructor=i,i.prototype.setCaptionTracks=function(t){var e=this;if(t.unshift(new H5P.Video.LabelValue(\"Off\",\"off\")),e.captionsTrackSelector)return void e.captionsTrackSelector.updateOptions(t);var o=e.video.getCaptionsTrack();o||(o=t[0]),e.captionsTrackSelector=new a.default(\"captions\",t,o,\"menuitemradio\",e.l10n,e.contentId),e.captionsTrackSelector.on(\"select\",function(t){e.video.setCaptionsTrack(\"off\"===t.data.value?null:t.data)}),e.captionsTrackSelector.on(\"close\",function(){\"true\"===e.controls.$more.attr(\"aria-expanded\")\u0026\u0026e.controls.$more.click()}),e.captionsTrackSelector.on(\"open\",function(){e.controls.$overlayButtons.addClass(\"h5p-hide\")}),v(e.captionsTrackSelector.control).insertAfter(e.controls.$volume),v(e.captionsTrackSelector.popup).css(e.controlsCss).insertAfter(v(e.captionsTrackSelector.control)),v(e.captionsTrackSelector.overlayControl).insertAfter(e.controls.$qualityButtonMinimal),e.controls.$overlayButtons=e.controls.$overlayButtons.add(e.captionsTrackSelector.overlayControl),e.minimalMenuKeyboardControls.insertElementAt(e.captionsTrackSelector.overlayControl,2)},i.prototype.getCurrentState=function(){var t=this;if(t.video.play){for(var e={progress:t.video.getCurrentTime(),answers:[]},o=0;o\u003ct.interactions.length;o++)e.answers[o]=t.interactions[o].getCurrentState();return e.progress?e:t.previousState\u0026\u0026t.previousState.progress?t.previousState:void 0}},i.prototype.removeSplash=function(){void 0!==this.$splash\u0026\u0026(this.$splash.remove(),delete this.$splash)},i.prototype.attach=function(t){var e=this,o=this;if(void 0!==this.isRoot\u0026\u0026this.isRoot()\u0026\u0026this.setActivityStarted(),this.$container=t,t.addClass(\"h5p-interactive-video\").html(\u0027\u003cdiv class=\"h5p-video-wrapper\"\u003e\u003c/div\u003e\u003cdiv role=\"toolbar\" class=\"h5p-controls\"\u003e\u003c/div\u003e\u0027),this.fontSize=16,this.width=640,this.interactions\u0026\u0026this.interactions.forEach(function(t){t.reCreate()}),this.$videoWrapper=t.children(\".h5p-video-wrapper\"),this.attachVideo(this.$videoWrapper),this.justVideo)return this.$videoWrapper.find(\"video\").css(\"minHeight\",\"200px\"),void t.children(\":not(.h5p-video-wrapper)\").remove();this.$read=v(\"\u003cdiv/\u003e\",{\"aria-live\":\"polite\",class:\"hidden-but-read\",appendTo:t}),this.readText=null,this.$controls=t.children(\".h5p-controls\").addClass(\"hidden\"),void 0===this.editor?(this.dnb=new H5P.DragNBar([],this.$videoWrapper,this.$container,{disableEditor:!0}),this.dnb.dialog.on(\"open\",function(){o.lastState=o.currentState,o.currentState!==H5P.Video.PAUSED\u0026\u0026o.currentState!==H5P.Video.ENDED\u0026\u0026o.video.pause()}),this.dnb.dialog.on(\"close\",function(){o.restoreTabIndexes(),o.lastState!==H5P.Video.PAUSED\u0026\u0026o.lastState!==H5P.Video.ENDED\u0026\u0026o.video.play()})):o.on(\"dnbEditorReady\",function(){o.dnb=o.editor.dnb,o.dnb.dialog.disableOverlay=!0}),this.video.pressToPlay||(this.currentState===i.LOADED?this.addControls():this.addSplash()),t.attr(\"tabindex\",\"-1\"),t.on(\"keyup\",function(t){var n=o.controls\u0026\u0026o.controls.$play,i=75===t.which;if(n\u0026\u0026i){if(\"INPUT\"===t.target.nodeName)return;if(e.hasUncompletedRequiredInteractions()){var r=v(document.activeElement);e.showWarningMask().find(\".h5p-button-back\").click(function(){return r.focus()})}else o.controls.$play.click()}}),this.$container.prepend(v(this.accessibility.getHotkeyInstructor())),this.$container.append(v(this.accessibility.getInteractionAnnouncer())),this.currentState=i.ATTACHED,this.autoplay\u0026\u0026o.video.play()},i.prototype.attachVideo=function(t){this.video.attach(t),this.justVideo||(this.$overlay=v(\u0027\u003cdiv class=\"h5p-overlay h5p-ie-transparent-background\"\u003e\u003c/div\u003e\u0027).appendTo(t))},i.prototype.addSplash=function(){var t=this;void 0!==this.editor||this.video.pressToPlay||!this.video.play||this.$splash||(this.$splash=v(\u0027\u003cdiv class=\"h5p-splash-wrapper\"\u003e\u003cdiv class=\"h5p-splash-outer\"\u003e\u003cdiv class=\"h5p-splash\" role=\"button\" tabindex=\"0\"\u003e\u003cdiv class=\"h5p-splash-main\"\u003e\u003cdiv class=\"h5p-splash-main-outer\"\u003e\u003cdiv class=\"h5p-splash-main-inner\"\u003e\u003cdiv class=\"h5p-splash-play-icon\" aria-label=\"\u0027+this.l10n.play+\u0027\"\u003e\u003c/div\u003e\u003cdiv class=\"h5p-splash-title\"\u003e\u0027+this.options.video.startScreenOptions.title+\u0027\u003c/div\u003e\u003c/div\u003e\u003c/div\u003e\u003c/div\u003e\u003cdiv class=\"h5p-splash-footer\"\u003e\u003cdiv class=\"h5p-splash-footer-holder\"\u003e\u003cdiv class=\"h5p-splash-description\"\u003e\u0027+t.startScreenOptions.shortStartDescription+\"\u003c/div\u003e\u003c/div\u003e\u003c/div\u003e\u003c/div\u003e\u003c/div\u003e\u003c/div\u003e\").click(function(){t.video.play()}).appendTo(this.$overlay).find(\".h5p-interaction-button\").click(function(){return!1}).end(),v(\".h5p-splash\",this.$splash).keydown(function(e){var o=e.which;32!==o\u0026\u002613!==o||(t.video.play(),e.preventDefault(),t.$controls.find(\".h5p-play\").focus())}),void 0!==this.startScreenOptions.shortStartDescription\u0026\u0026this.startScreenOptions.shortStartDescription.length||this.$splash.addClass(\"no-description\"),this.startScreenOptions.hideStartTitle\u0026\u0026this.$splash.addClass(\"no-title\"))},i.prototype.getDuration=function(){return void 0===this.duration\u0026\u0026(this.duration=this.video.getDuration()),this.duration},i.prototype.addControls=function(){var t=this,e=this;this.addSplash(),this.attachControls(this.$controls.removeClass(\"hidden\"));var o=this.getDuration(),n=i.humanizeTime(o),r=i.formatTimeForA11y(o,e.l10n);this.controls.$totalTime.find(\".human-time\").html(n),this.controls.$totalTime.find(\".hidden-but-read\").html(e.l10n.totalTime+\" \"+r),this.controls.$slider.slider(\"option\",\"max\",o),this.bookmarkMenuKeyboardControls=new l.default([new u.default]),this.bookmarkMenuKeyboardControls.on(\"close\",function(){return t.toggleBookmarksChooser(!1)}),this.addSliderInteractions(),this.addBookmarks(),this.trigger(\"controls\")},i.prototype.loaded=function(){var t=this.getDuration();if(this.oneSecondInPercentage=100/t,t=Math.floor(t),void 0!==this.editor){var e=b(\"interactions\",this.editor.field.fields),o=b(\"duration\",e.field.fields).fields;o[0].max=o[1].max=t,o[0].min=o[1].min=0;for(var n=b(\"adaptivity\",e.field.fields).fields,r=0;r\u003cn.length;r++)n[r].fields\u0026\u0026(b(\"seekTo\",n[r].fields).max=t)}if(this.hasMainSummary()){var a=t-this.options.summary.displayAt;a\u003c0\u0026\u0026(a=0),void 0===this.options.assets.interactions\u0026\u0026(this.options.assets.interactions=[]),this.options.assets.interactions.push({action:this.options.summary.task,x:80,y:80,duration:{from:a,to:t},displayType:\"button\",bigDialog:!0,className:\"h5p-summary-interaction h5p-end-summary\",label:\"\u003cp\u003e\"+this.l10n.summary+\"\u003c/p\u003e\",mainSummary:!0}),this.initInteraction(this.options.assets.interactions.length-1)}this.currentState===i.ATTACHED\u0026\u0026(this.video.pressToPlay||this.addControls(),this.trigger(\"resize\")),this.currentState=i.LOADED},i.prototype.initInteraction=function(t){var e=this,o=e.options.assets.interactions[t];if(e.override){var n={};o.adaptivity\u0026\u0026o.adaptivity.requireCompletion\u0026\u0026(n.enableRetry=!0),H5P.jQuery.extend(o.action.params.behaviour,e.override,n)}var i;void 0!==e.previousState\u0026\u0026void 0!==e.previousState.answers\u0026\u0026null!==e.previousState.answers[t]\u0026\u0026(i=e.previousState.answers[t]);var r=new h.default(o,e,i);return r.on(\"display\",function(t){var o=t.data;o.appendTo(e.$overlay),r.repositionToWrapper(e.$videoWrapper);var n=void 0!==e.video.pressToPlay;g(n?100:null,function(){(e.currentState===H5P.Video.PLAYING||e.currentState===H5P.Video.BUFFERING)\u0026\u0026r.pause()\u0026\u0026(e.focusInteraction||(e.focusInteraction=r),e.video.pause())}),e.seekingTo\u0026\u0026(e.seekingTo=void 0,o.focus()),setTimeout(function(){r.positionLabel(e.$videoWrapper.width())},0)}),r.on(\"hide\",function(t){t.data}),r.on(\"xAPI\",function(t){-1!==v.inArray(t.getVerb(),[\"completed\",\"answered\"])\u0026\u0026(t.setVerb(\"answered\"),r.isMainSummary()\u0026\u0026t.isFromChild()\u0026\u0026setTimeout(function(){e.complete()},0)),void 0===t.data.statement.context.extensions\u0026\u0026(t.data.statement.context.extensions={}),t.data.statement.context.extensions[\"http://id.tincanapi.com/extension/ending-point\"]=\"PT\"+Math.floor(e.video.getCurrentTime())+\"S\"}),e.interactions.push(r),r},i.prototype.hasMainSummary=function(){var t=this.options.summary;return!(void 0===t||void 0===t.displayAt||void 0===t.task||void 0===t.task.params||void 0===t.task.params.summaries||!t.task.params.summaries.length||void 0===t.task.params.summaries[0].summary||!t.task.params.summaries[0].summary.length)},i.prototype.addSliderInteractions=function(){var t=this;this.controls.$interactionsContainer.children().remove(),H5P.jQuery.extend([],this.interactions).sort(function(t,e){return t.getDuration().from-e.getDuration().from}).forEach(function(e){var o=e.addDot();void 0!==o\u0026\u0026(o.appendTo(t.controls.$interactionsContainer),t.preventSkipping||t.interactionKeyboardControls.addElement(o.get(0)))})},i.prototype.addBookmarks=function(){if(this.bookmarksMap={},void 0!==this.options.assets.bookmarks\u0026\u0026!this.preventSkipping)for(var t=0;t\u003cthis.options.assets.bookmarks.length;t++)this.addBookmark(t)},i.prototype.toggleBookmarksChooser=function(t){var e=arguments.length\u003e1\u0026\u0026void 0!==arguments[1]\u0026\u0026arguments[1];if(this.controls.$bookmarksButton){t=void 0===t?!this.controls.$bookmarksChooser.hasClass(\"h5p-show\"):t;var o=this.controls.$bookmarksChooser.hasClass(\"h5p-show\");t?(this.controls.$more.attr(\"aria-expanded\",\"true\"),this.controls.$minimalOverlay.addClass(\"h5p-show\"),this.controls.$minimalOverlay.find(\".h5p-minimal-button\").addClass(\"h5p-hide\"),this.controls.$bookmarksButton.attr(\"aria-expanded\",\"true\"),this.controls.$bookmarksChooser.css({maxHeight:t?this.controlsCss.maxHeight:\"32px\"}).addClass(\"h5p-show\"),this.controls.$bookmarksChooser.find(\u0027[tabindex=\"0\"]\u0027).first().focus()):(this.controls.$more.attr(\"aria-expanded\",\"false\"),this.controls.$minimalOverlay.removeClass(\"h5p-show\"),this.controls.$minimalOverlay.find(\".h5p-minimal-button\").removeClass(\"h5p-hide\"),this.controls.$bookmarksButton.attr(\"aria-expanded\",\"false\"),this.controls.$bookmarksChooser.css({maxHeight:t?this.controlsCss.maxHeight:\"32px\"}).removeClass(\"h5p-show\"),e||this.controls.$bookmarksButton.focus()),this.controls.$bookmarksChooser.toggleClass(\"h5p-transitioning\",t||o)}},i.prototype.showPreventSkippingMessage=function(t){var e=this;e.preventSkippingWarningTimeout||(e.$preventSkippingMessage||(e.$preventSkippingMessage=v(\"\u003cdiv\u003e\",{class:\"h5p-prevent-skipping-message\",appendTo:e.controls.$bookmarksContainer}),e.$preventSkippingMessageText=v(\"\u003cdiv\u003e\",{class:\"h5p-prevent-skipping-message-text\",html:e.l10n.navDisabled,appendTo:e.$preventSkippingMessage}),e.$preventSkippingMessageTextA11y=v(\"\u003cdiv\u003e\",{class:\"hidden-but-read\",html:e.l10n.navDisabled,appendTo:e.controls.$slider})),e.$preventSkippingMessage.css(\"left\",t),setTimeout(function(){e.$preventSkippingMessage.addClass(\"h5p-show\").attr(\"aria-hidden\",\"false\")},0),e.preventSkippingWarningTimeout=setTimeout(function(){e.$preventSkippingMessage.removeClass(\"h5p-show\").attr(\"aria-hidden\",\"true\"),setTimeout(function(){e.preventSkippingWarningTimeout=void 0},500)},2e3))},i.prototype.onBookmarkSelect=function(t,e){var o=this;o.currentState!==H5P.Video.PLAYING\u0026\u0026(t.mouseover().mouseout(),setTimeout(function(){o.timeUpdate(o.video.getCurrentTime())},0)),\"true\"===o.controls.$more.attr(\"aria-expanded\")\u0026\u0026o.$container.hasClass(\"h5p-minimal\")?o.controls.$more.click():o.toggleBookmarksChooser(!1),o.video.play(),o.video.seek(e.time);var n=i.formatTimeForA11y(e.time,o.l10n);setTimeout(function(){return o.read(o.l10n.currentTime+\" \"+n)},150)},i.prototype.addBookmark=function(t,e){var o=this,n=o.options.assets.bookmarks[t];void 0===e\u0026\u0026(e=Math.floor(10*n.time)/10);var i=o.bookmarksMap[e]=v(\u0027\u003cdiv class=\"h5p-bookmark\" style=\"left:\u0027+n.time*o.oneSecondInPercentage+\u0027%\"\u003e\u003cdiv class=\"h5p-bookmark-label\"\u003e\u003cdiv class=\"h5p-bookmark-text\"\u003e\u0027+n.label+\"\u003c/div\u003e\u003c/div\u003e\u003c/div\u003e\").appendTo(o.controls.$bookmarksContainer).data(\"id\",t).hover(function(){void 0!==o.bookmarkTimeout\u0026\u0026clearTimeout(o.bookmarkTimeout),o.controls.$bookmarksContainer.children(\".h5p-show\").removeClass(\"h5p-show\"),i.addClass(\"h5p-show\")},function(){o.bookmarkTimeout=setTimeout(function(){i.removeClass(\"h5p-show\")},2e3)});i.find(\".h5p-bookmark-label\").css(\"maxWidth\",parseInt(o.controls.$slider.parent().css(\"marginRight\"))-35),void 0===o.controls.$bookmarksList\u0026\u0026(o.controls.$bookmarksList=v(\u0027\u003cul role=\"menu\"\u003e\u003c/ul\u003e\u0027).insertAfter(o.controls.$bookmarksChooser.find(\"h3\")));var r=v(\u0027\u003cli role=\"menuitem\" aria-describedby=\"\u0027+o.bookmarksMenuId+\u0027\"\u003e\u0027+n.label+\"\u003c/li\u003e\").click(function(){return o.onBookmarkSelect(i,n)}).keydown(function(t){32!==t.which\u0026\u002613!==t.which||o.onBookmarkSelect(i,n),t.stopPropagation()});o.bookmarkMenuKeyboardControls.addElement(r.get(0));var a=o.controls.$bookmarksList.children(\":eq(\"+t+\")\");return 0!==a.length?r.insertBefore(a):r.appendTo(o.controls.$bookmarksList),o.on(\"bookmarksChanged\",function(n){var a=n.data.index,s=n.data.number;a===t\u0026\u0026s\u003c0?(r.remove(),delete o.bookmarksMap[e]):t\u003e=a\u0026\u0026(t+=s,i.data(\"id\",t))}),o.trigger(\"bookmarkAdded\",{bookmark:i}),i},i.prototype.attachControls=function(t){var e=this,o=v(\"\u003cdiv/\u003e\",{class:\"h5p-controls-left\",appendTo:t}),n=v(\"\u003cdiv/\u003e\",{class:\"h5p-control h5p-slider\",appendTo:t}),r=v(\"\u003cdiv/\u003e\",{class:\"h5p-controls-right\",appendTo:t});e.preventSkipping\u0026\u0026e.setDisabled(n),e.controls={},e.controls.$play=e.createButton(\"play\",\"h5p-control h5p-pause\",o,function(){var t=e.isDisabled(e.controls.$play);if(e.controls.$play.hasClass(\"h5p-pause\")\u0026\u0026!t){var o=!screen||Math.min(screen.width,screen.height)\u003c=e.width;!e.hasFullScreen\u0026\u0026o\u0026\u0026e.$container.hasClass(\"h5p-standalone\")\u0026\u0026e.$container.hasClass(\"h5p-minimal\")\u0026\u0026e.toggleFullScreen(),e.video.play()}else e.video.pause()}),e.showRewind10\u0026\u0026(e.controls.$rewind10=e.createButton(\"rewind10\",\"h5p-control\",o,function(){if(e.video.getCurrentTime()\u003e0){var t=Math.max(e.video.getCurrentTime()-10,0);e.video.seek(t),e.currentState===H5P.Video.PAUSED\u0026\u0026e.timeUpdate(t),e.currentState===H5P.Video.ENDED\u0026\u0026e.video.play()}}));var a=function(){var t=e.$container.hasClass(\"h5p-minimal\")\u0026\u0026\"true\"===e.controls.$more.attr(\"aria-expanded\");return t\u0026\u0026e.controls.$more.click(),t},s=function(t,o){return function(){var n=e.controls[t],i=e.controls[o],r=\"true\"===n.attr(\"aria-disabled\"),s=\"true\"===n.attr(\"aria-expanded\");r||(s?(n.attr(\"aria-expanded\",\"false\"),i.removeClass(\"h5p-show\"),n.focus(),a()):(n.attr(\"aria-expanded\",\"true\"),i.addClass(\"h5p-show\"),i.find(\u0027[tabindex=\"0\"]\u0027).focus()))}},c=e.options.assets.bookmarks\u0026\u0026e.options.assets.bookmarks.length,d=e.editor||c\u0026\u0026!e.preventSkipping;d\u0026\u0026(e.controls.$bookmarksChooser=H5P.jQuery(\"\u003cdiv/\u003e\",{class:\"h5p-chooser h5p-bookmarks\",role:\"dialog\",html:\u0027\u003ch3 id=\"\u0027+e.bookmarksMenuId+\u0027\"\u003e\u0027+e.l10n.bookmarks+\"\u003c/h3\u003e\"}),e.controls.$bookmarksChooser.append(v(\"\u003cspan\u003e\",{role:\"button\",class:\"h5p-chooser-close-button\",tabindex:\"0\",\"aria-label\":e.l10n.close,click:function(){return e.toggleBookmarksChooser()},keydown:function(t){13!==t.which\u0026\u002632!==t.which||(e.toggleBookmarksChooser(),t.preventDefault())}})),e.showRewind10\u0026\u0026e.controls.$bookmarksChooser.addClass(\"h5p-rewind-displacement\"),e.controls.$bookmarksButton=e.createButton(\"bookmarks\",\"h5p-control\",o,function(){e.toggleBookmarksChooser()}),e.controls.$bookmarksButton.attr(\"aria-haspopup\",\"true\"),e.controls.$bookmarksButton.attr(\"aria-expanded\",\"false\"),e.controls.$bookmarksChooser.insertAfter(e.controls.$bookmarksButton),e.controls.$bookmarksChooser.bind(\"transitionend\",function(){e.controls.$bookmarksChooser.removeClass(\"h5p-transitioning\")}));var h=\u0027\u003ctime class=\"h5p-current\"\u003e\\n \u003cspan class=\"hidden-but-read\"\u003e\u003c/span\u003e\\n \u003cspan class=\"human-time\" aria-hidden=\"true\"\u003e0:00\u003c/span\u003e\\n \u003c/time\u003e\u0027,p=v(\u0027\u003cdiv class=\"h5p-control h5p-simple-time\"\u003e\u0027+h+\"\u003c/div\u003e\").appendTo(o);e.controls.$currentTimeSimple=p.find(\".human-time\"),e.controls.$currentTimeA11ySimple=p.find(\".hidden-but-read\");var f=i.formatTimeForA11y(0,e.l10n),m=v(\u0027\u003cdiv class=\"h5p-control h5p-time\"\u003e\\n \u0027+h+\u0027\\n \u003cspan aria-hidden=\"true\"\u003e / \u003c/span\u003e\\n \u003ctime class=\"h5p-total\"\u003e\\n \u003cspan class=\"hidden-but-read\"\u003e\u0027+e.l10n.totalTime+\" \"+f+\u0027\u003c/span\u003e\\n \u003cspan class=\"human-time\" aria-hidden=\"true\"\u003e0:00\u003c/span\u003e\\n \u003c/time\u003e\\n \u003c/div\u003e\u0027).appendTo(r),b=m.find(\".h5p-current\");e.controls.$currentTime=b.find(\".human-time\"),e.controls.$currentTimeA11y=b.find(\".hidden-but-read\"),e.controls.$totalTime=m.find(\".h5p-total\"),e.updateCurrentTime(0);var g=function(){e.controls.$minimalOverlay.removeClass(\"h5p-show\"),e.controls.$more.attr(\"aria-expanded\",\"false\"),e.controls.$more.focus(),e.toggleBookmarksChooser(!1),e.controls.$qualityButton\u0026\u0026\"true\"===e.controls.$qualityButton.attr(\"aria-expanded\")\u0026\u0026e.controls.$qualityButton.click(),e.controls.$playbackRateButton\u0026\u0026\"true\"===e.controls.$playbackRateButton.attr(\"aria-expanded\")\u0026\u0026e.controls.$playbackRateButton.click(),setTimeout(function(){e.controls.$overlayButtons.removeClass(\"h5p-hide\")},150)};e.controls.$more=e.createButton(\"more\",\"h5p-control\",r,function(){\"true\"===e.controls.$more.attr(\"aria-expanded\")?g():(e.controls.$minimalOverlay.addClass(\"h5p-show\"),e.controls.$more.attr(\"aria-expanded\",\"true\"),e.removeSplash(),setTimeout(function(){e.controls.$minimalOverlay.find(\u0027[tabindex=\"0\"]\u0027).focus()},150)),d?e.controls.$bookmarksChooser.add(e.controls.$qualityChooser).removeClass(\"h5p-show\"):(e.controls.$qualityChooser.removeClass(\"h5p-show\"),e.controls.$playbackRateChooser.removeClass(\"h5p-show\"))}),e.controls.$playbackRateChooser=H5P.jQuery(\"\u003cdiv/\u003e\",{class:\"h5p-chooser h5p-playbackRate\",role:\"dialog\",html:\u0027\u003ch3 id=\"\u0027+e.playbackRateMenuId+\u0027\"\u003e\u0027+e.l10n.playbackRate+\"\u003c/h3\u003e\"}),e.controls.$playbackRateButton=e.createButton(\"playbackRate\",\"h5p-control\",r,s(\"$playbackRateButton\",\"$playbackRateChooser\")),e.setDisabled(e.controls.$playbackRateButton),e.controls.$playbackRateButton.attr(\"aria-haspopup\",\"true\"),e.controls.$playbackRateButton.attr(\"aria-expanded\",\"false\"),e.controls.$playbackRateChooser.insertAfter(e.controls.$playbackRateButton),function(){return-1!==navigator.userAgent.indexOf(\"Android\")}()||function(){return-1!==navigator.userAgent.indexOf(\"iPad\")}()||(e.controls.$volume=e.createButton(\"mute\",\"h5p-control\",r,function(){var t=e.controls.$volume;e.deactivateSound||(t.hasClass(\"h5p-muted\")?(t.removeClass(\"h5p-muted\").attr(\"aria-label\",e.l10n.mute),e.video.unMute()):(t.addClass(\"h5p-muted\").attr(\"aria-label\",e.l10n.unmute),e.video.mute()),t.blur(),t.focus())}),e.deactivateSound\u0026\u0026(e.controls.$volume.addClass(\"h5p-muted\").attr(\"aria-label\",e.l10n.sndDisabled),e.setDisabled(e.controls.$volume))),e.deactivateSound\u0026\u0026e.video.mute(),e.controls.$qualityChooser=H5P.jQuery(\"\u003cdiv/\u003e\",{class:\"h5p-chooser h5p-quality\",role:\"dialog\",html:\u0027\u003ch3 id=\"\u0027+e.qualityMenuId+\u0027\"\u003e\u0027+e.l10n.quality+\"\u003c/h3\u003e\"});var y=function(){e.isMinimal?e.controls.$more.click():e.controls.$qualityButton.click()};e.controls.$qualityChooser.append(v(\"\u003cspan\u003e\",{role:\"button\",class:\"h5p-chooser-close-button\",tabindex:\"0\",\"aria-label\":e.l10n.close,click:function(){return y()},keydown:function(t){32!==t.which\u0026\u002613!==t.which||(y(),t.preventDefault())}})),e.controls.$qualityButton=e.createButton(\"quality\",\"h5p-control\",r,s(\"$qualityButton\",\"$qualityChooser\")),e.setDisabled(e.controls.$qualityButton),e.controls.$qualityButton.attr(\"aria-haspopup\",\"true\"),e.controls.$qualityButton.attr(\"aria-expanded\",\"false\"),e.controls.$qualityChooser.insertAfter(e.controls.$qualityButton),e.editor||!1===H5P.fullscreenSupported||(e.controls.$fullscreen=e.createButton(\"fullscreen\",\"h5p-control\",r,function(){e.toggleFullScreen()})),e.controls.$minimalOverlay=H5P.jQuery(\"\u003cdiv/\u003e\",{class:\"h5p-minimal-overlay\",appendTo:e.$container});var k=H5P.jQuery(\"\u003cdiv/\u003e\",{role:\"menu\",class:\"h5p-minimal-wrap\",appendTo:e.controls.$minimalOverlay});e.minimalMenuKeyboardControls=new l.default([new u.default]),e.minimalMenuKeyboardControls.on(\"close\",function(){return g()}),e.controls.$overlayButtons=H5P.jQuery([]),d\u0026\u0026(e.controls.$bookmarkButtonMinimal=e.createButton(\"bookmarks\",\"h5p-minimal-button\",k,function(){e.controls.$overlayButtons.addClass(\"h5p-hide\"),e.toggleBookmarksChooser(!0)},!0),e.controls.$bookmarkButtonMinimal.attr(\"role\",\"menuitem\"),e.controls.$bookmarkButtonMinimal.attr(\"tabindex\",\"-1\"),e.controls.$overlayButtons=e.controls.$overlayButtons.add(e.controls.$bookmarkButtonMinimal),e.minimalMenuKeyboardControls.addElement(e.controls.$bookmarkButtonMinimal.get(0))),e.controls.$qualityButtonMinimal=e.createButton(\"quality\",\"h5p-minimal-button\",k,function(){e.isDisabled(e.controls.$qualityButton)||(e.controls.$overlayButtons.addClass(\"h5p-hide\"),e.controls.$qualityButton.click())},!0),e.setDisabled(e.controls.$qualityButtonMinimal),e.controls.$qualityButtonMinimal.attr(\"role\",\"menuitem\"),e.controls.$overlayButtons=e.controls.$overlayButtons.add(e.controls.$qualityButtonMinimal),e.minimalMenuKeyboardControls.addElement(e.controls.$qualityButtonMinimal.get(0)),e.controls.$playbackRateButtonMinimal=e.createButton(\"playbackRate\",\"h5p-minimal-button\",k,function(){e.isDisabled(e.controls.$playbackRateButton)||(e.controls.$overlayButtons.addClass(\"h5p-hide\"),e.controls.$playbackRateButton.click())},!0),e.controls.$playbackRateButtonMinimal.attr(\"role\",\"menuitem\"),e.setDisabled(e.controls.$playbackRateButtonMinimal),e.controls.$overlayButtons=e.controls.$overlayButtons.add(e.controls.$playbackRateButtonMinimal),e.minimalMenuKeyboardControls.addElement(e.controls.$playbackRateButtonMinimal.get(0)),e.addQualityChooser(),e.addPlaybackRateChooser(),e.interactionKeyboardControls=new l.default([new u.default]),e.controls.$interactionsContainer=v(\"\u003cdiv/\u003e\",{role:\"menu\",class:\"h5p-interactions-container\",\"aria-label\":e.l10n.interaction,appendTo:n}),e.controls.$bookmarksContainer=v(\"\u003cdiv/\u003e\",{class:\"h5p-bookmarks-container\",appendTo:n}),e.hasPlayPromise=!1,e.hasQueuedPause=!1,e.delayed=!1,e.controls.$slider=v(\"\u003cdiv/\u003e\",{appendTo:n}).slider({value:0,step:.01,orientation:\"horizontal\",range:\"min\",max:0,create:function(t){var o=v(t.target).find(\".ui-slider-handle\");o.attr(\"role\",\"slider\").attr(\"aria-valuemin\",\"0\").attr(\"aria-valuemax\",e.getDuration().toString()).attr(\"aria-valuetext\",i.formatTimeForA11y(0,e.l10n)).attr(\"aria-valuenow\",\"0\"),e.preventSkipping\u0026\u0026e.setDisabled(o).attr(\"aria-hidden\",\"true\")},start:function(){e.currentState!==i.SEEKING\u0026\u0026(e.delayedState||(e.currentState===H5P.Video.ENDED?e.lastState=H5P.Video.PLAYING:e.currentState===H5P.Video.BUFFERING\u0026\u0026e.lastState||(e.lastState=e.currentState)),e.delayedState=!0,clearTimeout(e.delayTimeout),e.delayTimeout=setTimeout(function(){e.delayedState=!1},200),e.hasPlayPromise?e.hasQueuedPause=!0:e.video.pause(),e.currentState=i.SEEKING,e.removeSplash(),e.$overlay.addClass(\"h5p-visible\"))},slide:function(t,o){var n=[\"Right\",\"Left\",\"ArrowRight\",\"ArrowLeft\"],i=-1!==n.indexOf(t.key),r=!i,a=o.value;if(i){var s=e.getDuration();a=-1!==t.key.indexOf(\"Right\")?Math.min(a+5,s):Math.max(a-5,0),e.timeUpdate(a,!0)}return e.video.seek(a),e.updateInteractions(a),e.updateCurrentTime(a),r},stop:function(t,o){e.currentState=e.lastState,e.video.seek(o.value),e.recreateCurrentInteractions();var n=e.lastState===H5P.Video.PLAYING||e.lastState===H5P.Video.VIDEO_CUED||e.hasQueuedPause;if(e.hasPlayPromise)e.hasQueuedPause=!1;else if(n){e.hasQueuedPause=!1;var i=e.video.play();e.hasQueuedPause=!1,i\u0026\u0026i.then?(e.hasPlayPromise=!0,i.then(function(){setTimeout(function(){(e.hasQueuedPause||e.hasActivePauseInteraction())\u0026\u0026e.video.pause(),e.hasPlayPromise=!1},0)})):e.hasActivePauseInteraction()\u0026\u0026(e.video.play(),setTimeout(function(){e.video.pause()},50))}else e.timeUpdate(o.value);e.$overlay.removeClass(\"h5p-visible\")}}),e.preventSkipping\u0026\u0026(e.controls.$slider.slider(\"disable\"),e.controls.$slider.click(function(t){return e.showPreventSkippingMessage(t.offsetX),!1})),e.showBookmarksmenuOnLoad\u0026\u0026!1===e.video.pressToPlay\u0026\u0026e.toggleBookmarksChooser(!0),e.controls.$buffered=v(\"\u003cdiv/\u003e\",{class:\"h5p-buffered\",prependTo:e.controls.$slider})},i.prototype.hasActivePauseInteraction=function(){var t=!1;return this.interactions.forEach(function(e){e.getElement()\u0026\u0026e.pause()\u0026\u0026(t=!0)}),t},i.prototype.createButton=function(t,e,o,n,i){var r=this,a={role:\"button\",tabindex:0,class:(void 0===e?\"\":e+\" \")+\"h5p-\"+t,on:{click:function(){n.call(this)},keydown:function(t){13!==t.which\u0026\u002632!==t.which||(n.call(this),t.preventDefault(),t.stopPropagation())}},appendTo:o};return a[i?\"text\":\"aria-label\"]=r.l10n[t],H5P.jQuery(\"\u003cdiv/\u003e\",a)},i.prototype.addQualityChooser=function(){var t=this;if(t.qualityMenuKeyboardControls=new l.default([new u.default]),t.qualityMenuKeyboardControls.on(\"close\",function(){return t.controls.$qualityButton.click()}),this.video.getQualities){var e=this.video.getQualities();if(e\u0026\u0026void 0!==this.controls.$qualityButton\u0026\u0026t.isDisabled(t.controls.$qualityButton)){for(var o=this.video.getQuality(),n=\"\",i=0;i\u003ce.length;i++){var r=e[i],a=r.name===o;n+=\u0027\u003cli role=\"menuitemradio\" data-quality=\"\u0027+r.name+\u0027\" aria-checked=\"\u0027+a+\u0027\" aria-describedby=\"\u0027+t.qualityMenuId+\u0027\"\u003e\u0027+r.label+\"\u003c/li\u003e\"}var s=v(\u0027\u003cul role=\"menu\"\u003e\u0027+n+\"\u003c/ul\u003e\").appendTo(this.controls.$qualityChooser);s.children().click(function(){var e=v(this).attr(\"data-quality\");t.updateQuality(e)}).keydown(function(e){if(32===e.which||13===e.which){var o=v(this).attr(\"data-quality\");t.updateQuality(o)}e.stopPropagation()});s.find(\"li\").get().forEach(function(e){t.qualityMenuKeyboardControls.addElement(e);var o=\"true\"===e.getAttribute(\"aria-checked\");m(e,o)}),t.removeDisabled(this.controls.$qualityButton.add(this.controls.$qualityButtonMinimal))}}},i.prototype.updateQuality=function(t){var e=this;e.video.setQuality(t),\"true\"===e.controls.$more.attr(\"aria-expanded\")?e.controls.$more.click():(e.controls.$qualityButton.click(),e.controls.$qualityButton.focus())},i.prototype.addPlaybackRateChooser=function(){var t=this,e=this;if(this.playbackRateMenuKeyboardControls=new l.default([new u.default]),this.playbackRateMenuKeyboardControls.on(\"close\",function(){return e.controls.$playbackRateButton.click()}),this.video.getPlaybackRates){var o=this.video.getPlaybackRates();if(!(o.length\u003c2)\u0026\u0026o\u0026\u0026void 0!==this.controls.$playbackRateButton\u0026\u0026e.isDisabled(this.controls.$playbackRateButton)){for(var n=this.video.getPlaybackRate(),i=\"\",r=0;r\u003co.length;r++){var a=o[r];i+=\u0027\u003cli role=\"menuitemradio\" playback-rate=\"\u0027+a+\u0027\" aria-checked=\"\u0027+(a===n)+\u0027\" aria-describedby=\"\u0027+e.playbackRateMenuId+\u0027\"\u003e\u0027+a+\"\u003c/li\u003e\"}var s=v(\u0027\u003cul role=\"menu\"\u003e\u0027+i+\"\u003c/ul\u003e\").appendTo(this.controls.$playbackRateChooser);s.children().click(function(){var t=v(this).attr(\"playback-rate\");e.updatePlaybackRate(t)}).keydown(function(t){if(32===t.which||13===t.which){var o=v(this).attr(\"playback-rate\");e.updatePlaybackRate(o)}t.stopPropagation()}),s.find(\"li\").get().forEach(function(e){t.playbackRateMenuKeyboardControls.addElement(e);var o=\"true\"===e.getAttribute(\"aria-checked\");m(e,o)}),e.removeDisabled(this.controls.$playbackRateButton.add(this.controls.$playbackRateButtonMinimal))}}},i.prototype.updatePlaybackRate=function(t){var e=this;e.video.setPlaybackRate(t),\"true\"===e.controls.$more.attr(\"aria-expanded\")?e.controls.$more.click():e.controls.$playbackRateButton.click()},i.prototype.startUpdatingBufferBar=function(){var t=this;if(!t.bufferLoop){!function e(){var o=t.video.getBuffered();o\u0026\u0026t.controls.$buffered\u0026\u0026t.controls.$buffered.css(\"width\",o+\"%\"),t.bufferLoop=setTimeout(e,500)}()}},i.prototype.resize=function(){if(this.$container){var t=this.$container.hasClass(\"h5p-fullscreen\")||this.$container.hasClass(\"h5p-semi-fullscreen\");this.$videoWrapper.css({marginTop:\"\",marginLeft:\"\",width:\"\",height:\"\"}),this.video.trigger(\"resize\");var e,o,n=this.justVideo?0:this.$controls.height(),i=this.$container.height();if(t){if((o=this.$videoWrapper.height())+n\u003c=i)this.$videoWrapper.css(\"marginTop\",(i-n-o)/2),e=this.$videoWrapper.width();else{var r=this.$videoWrapper.width()/o,a=i-n;e=a*r,this.$videoWrapper.css({marginLeft:(this.$container.width()-e)/2,width:e,height:a})}this.video.trigger(\"resize\")}else e=this.$container.width();this.scaledFontSize=e\u003ethis.width?this.fontSize*(e/this.width):this.fontSize,this.$container.css(\"fontSize\",this.scaledFontSize+\"px\"),this.editor||(e\u003cthis.width?this.$container.hasClass(\"h5p-minimal\")||this.$container.addClass(\"h5p-minimal\"):this.$container.hasClass(\"h5p-minimal\")\u0026\u0026this.$container.removeClass(\"h5p-minimal\")),this.isMinimal=this.$container.hasClass(\"h5p-minimal\");var s=this.$videoWrapper.height();if(this.controlsCss={bottom:\"\",maxHeight:s+\"px\"},t){var l=n;o+n\u003c=i\u0026\u0026(l=n+(i-n-o)/2),this.controlsCss.bottom=l+\"px\"}this.controls\u0026\u0026this.controls.$minimalOverlay\u0026\u0026this.controls.$minimalOverlay.css(this.controlsCss),this.$container.find(\".h5p-chooser\").css(this.controlsCss),this.editor?this.editor.dnb\u0026\u0026this.editor.dnb.dnr.setContainerEm(this.scaledFontSize):(this.resizeMobileView(),void 0!==this.$splash\u0026\u0026this.resizeStartScreen()),this.resizeInteractions()}},i.prototype.resizeMobileView=function(){if(!isNaN(this.currentState)){if(this.$container.width()/parseInt(this.$container.css(\"font-size\"),10)\u003c30){if(this.resizeInteractions(),!this.isMobileView){if(this.$container.addClass(\"mobile\"),this.isMobileView=!0,this.hasUncompletedRequiredInteractions()){var t=v(\".h5p-dialog\",this.$container);t.show()}else this.restoreTabIndexes(),this.dnb.dialog.closeOverlay();this.recreateCurrentInteractions()}}else if(this.isMobileView){if(this.dnb\u0026\u0026this.dnb.dialog\u0026\u0026!this.hasUncompletedRequiredInteractions()){this.dnb.dialog.close(!0);var e=this.$container.find(\".h5p-dialog .h5p-image img\");e.css({width:\"\",height:\"\"})}this.$container.removeClass(\"mobile\"),this.isMobileView=!1,this.recreateCurrentInteractions()}}},i.prototype.resizeInteractions=function(){if(!isNaN(this.currentState)){var t=this;this.interactions.forEach(function(e){e.resizeInteraction(),e.repositionToWrapper(t.$videoWrapper),e.positionLabel(t.$videoWrapper.width())})}},i.prototype.recreateCurrentInteractions=function(){this.dnb.blurAll(),this.interactions.forEach(function(t){t.reCreateInteraction()})},i.prototype.resizeStartScreen=function(){var t=50,e=!0,o=!0;void 0!==this.startScreenOptions.shortStartDescription\u0026\u0026this.startScreenOptions.shortStartDescription.length||(e=!1,this.startScreenOptions.hideStartTitle\u0026\u0026(o=!1,t=45));var n=v(\".h5p-splash-description\",this.$splash),i=v(\".h5p-splash-title\",this.$splash),r=n.clone().css(\"position\",\"absolute\").addClass(\"minimum-font-size\").appendTo(n.parent()),a=i.clone().css(\"position\",\"absolute\").addClass(\"minimum-font-size\").appendTo(i.parent()),s=parseInt(r.css(\"font-size\"),10),l=parseInt(a.css(\"font-size\"),10),c=this.$container.width(),u=parseInt(c/t,10);e||(o\u0026\u0026u\u003cs?u=s:u\u003c10\u0026\u0026(u=10)),c\u003c510?this.$splash.addClass(\"mobile\"):this.$splash.removeClass(\"mobile\"),.8*u\u003cs?n.addClass(\"minimum-font-size\"):n.removeClass(\"minimum-font-size\"),1.5*u\u003cl?i.addClass(\"minimum-font-size\"):i.removeClass(\"minimum-font-size\"),this.$splash.css(\"font-size\",u),r.remove(),a.remove()},i.prototype.toggleFullScreen=function(){var t=this;H5P.isFullscreen||this.$container.hasClass(\"h5p-fullscreen\")||this.$container.hasClass(\"h5p-semi-fullscreen\")?void 0!==H5P.exitFullScreen\u0026\u0026void 0!==H5P.fullScreenBrowserPrefix?H5P.exitFullScreen():(void 0===H5P.fullScreenBrowserPrefix?v(\".h5p-disable-fullscreen\").click():\"\"===H5P.fullScreenBrowserPrefix?window.top.document.exitFullScreen():\"ms\"===H5P.fullScreenBrowserPrefix?window.top.document.msExitFullscreen():window.top.document[H5P.fullScreenBrowserPrefix+\"CancelFullScreen\"](),t.trigger(\"exitFullScreen\")):(H5P.fullScreen(this.$container,this),void 0===H5P.exitFullScreen\u0026\u0026t.trigger(\"enterFullScreen\")),this.resizeInteractions()},i.prototype.timeUpdate=function(t,e){var o=this;if(t\u003e=0)try{var n=o.controls.$slider.find(\".ui-slider-handle\"),r=i.formatTimeForA11y(t,o.l10n);o.controls.$slider.slider(\"option\",\"value\",t),n.attr(\"aria-valuetext\",r),n.attr(\"aria-valuenow\",t.toString())}catch(t){return}o.updateInteractions(t),e||setTimeout(function(){(o.currentState===H5P.Video.PLAYING||o.currentState===H5P.Video.BUFFERING\u0026\u0026o.lastState===H5P.Video.PLAYING)\u0026\u0026o.timeUpdate(o.video.getCurrentTime())},40)},i.prototype.updateInteractions=function(t){var e=this,o=Math.floor(10*t)/10;o!==e.lastTenth\u0026\u0026void 0!==e.bookmarksMap\u0026\u0026void 0!==e.bookmarksMap[o]\u0026\u0026e.bookmarksMap[o].mouseover().mouseout(),e.lastTenth=o;var n=Math.floor(t);n!==e.lastSecond\u0026\u0026(e.toggleInteractions(n),e.currentState!==H5P.Video.PLAYING\u0026\u0026e.currentState!==H5P.Video.PAUSED||e.updateCurrentTime(n)),e.lastSecond=n},i.prototype.updateCurrentTime=function(t){var e=this;t=Math.max(t,0);var o=i.humanizeTime(t),n=i.formatTimeForA11y(t,e.l10n);e.controls.$currentTime.html(o),e.controls.$currentTimeA11y.html(e.l10n.currentTime+\" \"+n),e.controls.$currentTimeSimple.html(o),e.controls.$currentTimeA11ySimple.html(e.l10n.currentTime+\" \"+n)},i.prototype.complete=function(){this.editor||(this.completedSent||this.triggerXAPIScored(this.getUsersScore(),this.getUsersMaxScore(),\"completed\"),this.completedSent=!0)},i.prototype.getUsersScore=function(){for(var t=0,e=0;e\u003cthis.interactions.length;e++)this.interactions[e].score\u0026\u0026(t+=this.interactions[e].score);return t},i.prototype.getUsersMaxScore=function(){for(var t=0,e=0;e\u003cthis.interactions.length;e++)this.interactions[e].maxScore\u0026\u0026(t+=this.interactions[e].maxScore);return t},i.prototype.getScore=function(){return this.getUsersScore()},i.prototype.getMaxScore=function(){return this.getUsersMaxScore()},i.prototype.showOverlayMask=function(){var t=this;t.$videoWrapper.addClass(\"h5p-disable-opt-out\"),t.disableTabIndexes(),t.dnb.dialog.openOverlay(),t.restorePosterTabIndexes(),t.$container.find(\".h5p-dialog-wrapper\").click(function(){t.hasUncompletedRequiredInteractions()\u0026\u0026t.showWarningMask()}),t.toggleFocusTrap()},i.prototype.restorePosterTabIndexes=function(){var t=this;t.$overlay.find(\".h5p-interaction.h5p-poster\").each(function(){t.restoreTabIndexes(v(this))})},i.prototype.disableTabIndexes=function(){var t=this,e=t.$container.find(\".h5p-dialog-wrapper\");t.$tabbables=t.$container.find(\"a[href], area[href], input:not([disabled]), select:not([disabled]), textarea:not([disabled]), button:not([disabled]), iframe, object, embed, *[tabindex], *[contenteditable]\").filter(function(){var t=v(this),o=v.contains(e.get(0),t.get(0));if(t.data(\"tabindex\"))return!0;if(!o){var n=t.attr(\"tabindex\");return t.data(\"tabindex\",n),t.attr(\"tabindex\",\"-1\"),!0}return!1})},i.prototype.restoreTabIndexes=function(t){var e=this;e.$tabbables\u0026\u0026(e.$tabbables.each(function(){var e=v(this),o=e.data(\"tabindex\");if(t\u0026\u0026!v.contains(t.get(0),e.get(0)))return!0;e.hasClass(\"ui-slider-handle\")?(e.attr(\"tabindex\",0),e.removeData(\"tabindex\")):void 0!==o?(e.attr(\"tabindex\",o),e.removeData(\"tabindex\")):e.removeAttr(\"tabindex\")}),t||(e.$tabbables=void 0))},i.prototype.toggleFocusTrap=function(){var t=this,e=this.getVisibleInteractions().filter(function(t){return t.getRequiresCompletion()\u0026\u0026!t.hasFullScore()});e.length\u003e0?this.$container.off(\"focusin\").on(\"focusin\",function(o){return t.trapFocusInInteractions(e,v(o.target))}):this.$container.off(\"focusin\",\"**\")},i.prototype.trapFocusInInteractions=function(t,e){var o=t.some(function(t){var o=t.getElement();return $(o,e)}),n=!!this.$mask\u0026\u0026$(this.$mask,e);if(!o\u0026\u0026!n){var i=t[0].getElement();i\u0026\u0026i.focus()}},i.prototype.hideOverlayMask=function(){var t=this;return t.restoreTabIndexes(),t.dnb.dialog.closeOverlay(),t.$videoWrapper.removeClass(\"h5p-disable-opt-out\"),t.toggleFocusTrap(),t.$container.find(\".h5p-dialog-wrapper\")},i.prototype.showWarningMask=function(){var t=this,e=\"interactive-video-\"+t.contentId+\"-\"+t.instanceIndex+\"-completion-warning-text\";return t.$mask||(t.$mask=v(\u0027\u003cdiv class=\"h5p-warning-mask\" role=\"alertdialog\" aria-describedby=\"\u0027+e+\u0027\"\u003e\\n \u003cdiv class=\"h5p-warning-mask-wrapper\"\u003e\\n \u003cdiv id=\"\u0027+e+\u0027\" class=\"h5p-warning-mask-content\"\u003e\u0027+t.l10n.requiresCompletionWarning+\u0027\u003c/div\u003e\\n \u003cbutton type=\"button\" class=\"h5p-joubelui-button h5p-button-back\"\u003e\u0027+t.l10n.back+\"\u003c/button\u003e\\n \u003c/div\u003e\\n \u003c/div\u003e\").click(function(){t.$mask.hide()}).appendTo(t.$container)),t.$mask.show(),t.$mask.find(\".h5p-button-back\").focus(),t.$mask},i.prototype.setDisabled=function(t){return t.attr(\"aria-disabled\",\"true\").attr(\"tabindex\",\"-1\")},i.prototype.isDisabled=function(t){return\"true\"===t.attr(\"aria-disabled\")},i.prototype.removeDisabled=function(t){return t.removeAttr(\"aria-disabled\").attr(\"tabindex\",\"0\")},i.prototype.hasUncompletedRequiredInteractions=function(t){var e=this;return(void 0!==t?e.getVisibleInteractionsAt(t):e.getVisibleInteractions()).some(function(t){return t.getRequiresCompletion()\u0026\u0026!t.hasFullScore()})},i.prototype.getVisibleInteractions=function(){return this.interactions.filter(function(t){return t.isVisible()})},i.prototype.getVisibleInteractionsAt=function(t){return this.interactions.filter(function(e){return e.visibleAt(t)})},i.prototype.showSolutions=function(){},i.prototype.getTitle=function(){return H5P.createTitle(this.options.video.startScreenOptions.title)},i.prototype.toggleInteractions=function(t){for(var e=0;e\u003cthis.interactions.length;e++)this.interactions[e].toggle(t),this.interactions[e].repositionToWrapper(this.$videoWrapper);this.accessibility.announceInteractions(this.interactions)},i.prototype.play=function(){this.video.play()},i.prototype.seek=function(t){this.video.seek(t)},i.prototype.pause=function(){this.video\u0026\u0026this.video.pause\u0026\u0026this.video.pause()},i.prototype.resetTask=function(){if(void 0!==this.controls){this.seek(0),this.timeUpdate(-1),this.controls.$slider.slider(\"option\",\"value\",0);for(var t=0;t\u003cthis.interactions.length;t++)this.interactions[t].resetTask()}},i.prototype.read=function(t){var e=this;e.$read\u0026\u0026(e.readText?e.readText+=(\".\"===e.readText.substr(-1,1)?\" \":\". \")+t:e.readText=t,e.$read.html(e.readText),setTimeout(function(){e.readText=null,e.$read.html(\"\")},100))},i.prototype.getCopyrights=function(){var t=this,e=new H5P.ContentCopyrights;void 0!==t.options.video.files\u0026\u0026void 0!==t.options.video.files[0]\u0026\u0026e.addMedia(new H5P.MediaCopyright(t.options.video.files[0].copyright,t.l10n)),void 0!==t.options.video.startScreenOptions.copyright\u0026\u0026e.addMedia(t.options.video.startScreenOptions.copyright);var o=t.options.video.startScreenOptions.poster;if(o\u0026\u0026void 0!==o.copyright){var n=new H5P.MediaCopyright(o.copyright,t.l10n),i=H5P.getPath(o.path,t.contentId);n.setThumbnail(new H5P.Thumbnail(i,o.width,o.height)),e.addMedia(n)}for(var r=0;r\u003ct.interactions.length;r++){var a=t.interactions[r].getCopyrights();a\u0026\u0026e.addContent(a)}return e},i.SEEKING=4,i.LOADED=5,i.ATTACHED=6,i.humanizeTime=function(t){var e=i.secondsToMinutesAndHours(t),o=\"\";return 0!==e.hours\u0026\u0026(o+=e.hours+\":\",e.minutes\u003c10\u0026\u0026(o+=\"0\")),o+=e.minutes+\":\",e.seconds\u003c10\u0026\u0026(o+=\"0\"),o+=e.seconds},i.formatTimeForA11y=function(t,e){var o=i.secondsToMinutesAndHours(t);return(o.hours\u003e0?o.hours+\" \"+e.hours+\", \":\"\")+o.minutes+\" \"+e.minutes+\", \"+o.seconds+\" \"+e.seconds},i.secondsToMinutesAndHours=function(t){var e=Math.floor(t/60);return{seconds:Math.floor(t%60),minutes:e%60,hours:Math.floor(e/60)}};var m=function(t,e){e?t.setAttribute(\"tabindex\",\"0\"):t.removeAttribute(\"tabindex\")},b=function(t,e){for(var o=0;o\u003ce.length;o++)if(e[o].name===t)return e[o]},g=function(t,e){null===t?e():setTimeout(e,t)},y=function(){return void 0===window.interactiveVideoCounter\u0026\u0026(window.interactiveVideoCounter=0),window.interactiveVideoCounter++};i.prototype.getXAPIData=function(){var t=this,e=this.createXAPIEventTemplate(\"answered\");k(e),e.setScoredResult(t.getScore(),t.getMaxScore(),t,!0,t.getScore()===t.getMaxScore());var o=C(t.interactions);return{statement:e.data.statement,children:o}};var k=function(t){var e=t.getVerifiedStatementValue([\"object\",\"definition\"]);H5P.jQuery.extend(e,S())},S=function(){var t={};return t.interactionType=\"compound\",t.type=\"http://adlnet.gov/expapi/activities/cmi.interaction\",t.description={\"en-US\":\"\"},t},$=function(t,e){return void 0!==t\u0026\u0026void 0!==e\u0026\u0026(t.is(e)||v.contains(t.get(0),e.get(0)))},C=function(t){return t.map(function(t){return t.getXAPIData()}).filter(function(t){return!!t})};e.default=i;e.KEY_CODE_START_PAUSE=75},function(t,e,o){\"use strict\";function n(t,e){if(!(t instanceof e))throw new TypeError(\"Cannot call a class as a function\")}Object.defineProperty(e,\"__esModule\",{value:!0});var i=Object.assign||function(t){for(var e=1;e\u003carguments.length;e++){var o=arguments[e];for(var n in o)Object.prototype.hasOwnProperty.call(o,n)\u0026\u0026(t[n]=o[n])}return t},r=function(){function t(t,e){for(var o=0;o\u003ce.length;o++){var n=e[o];n.enumerable=n.enumerable||!1,n.configurable=!0,\"value\"in n\u0026\u0026(n.writable=!0),Object.defineProperty(t,n.key,n)}}return function(e,o,n){return o\u0026\u0026t(e.prototype,o),n\u0026\u0026t(e,n),e}}(),a=o(8),s=o(2),l=o(9),c=(0,a.removeAttribute)(\"tabindex\"),u=((0,s.forEach)(c),(0,a.setAttribute)(\"tabindex\",\"0\")),d=(0,a.setAttribute)(\"tabindex\",\"-1\"),h=(0,a.hasAttribute)(\"tabindex\"),p=function(){function t(e){n(this,t),i(this,(0,l.Eventful)()),this.plugins=e||[],this.elements=[],this.negativeTabIndexAllowed=!1,this.on(\"nextElement\",this.nextElement,this),this.on(\"previousElement\",this.previousElement,this),this.initPlugins()}return r(t,[{key:\"addElement\",value:function(t){this.elements.push(t),this.firesEvent(\"addElement\",t),1===this.elements.length\u0026\u0026this.setTabbable(t)}},{key:\"insertElementAt\",value:function(t,e){this.elements.splice(e,0,t),this.firesEvent(\"addElement\",t),1===this.elements.length\u0026\u0026this.setTabbable(t)}},{key:\"removeElement\",value:function(t){this.elements=(0,s.without)([t],this.elements),h(t)\u0026\u0026(this.setUntabbable(t),this.elements[0]\u0026\u0026this.setTabbable(this.elements[0])),this.firesEvent(\"removeElement\",t)}},{key:\"count\",value:function(){return this.elements.length}},{key:\"firesEvent\",value:function(t,e){var o=this.elements.indexOf(e);return this.fire(t,{element:e,index:o,elements:this.elements,oldElement:this.tabbableElement})}},{key:\"nextElement\",value:function(t){var e=t.index,o=e===this.elements.length-1,n=this.elements[o?0:e+1];this.setTabbable(n),n.focus()}},{key:\"setTabbable\",value:function(t){(0,s.forEach)(this.setUntabbable.bind(this),this.elements),u(t),this.tabbableElement=t}},{key:\"setUntabbable\",value:function(t){this.negativeTabIndexAllowed?d(t):c(t)}},{key:\"previousElement\",value:function(t){var e=t.index,o=0===e,n=this.elements[o?this.elements.length-1:e-1];this.setTabbable(n),n.focus()}},{key:\"useNegativeTabIndex\",value:function(){this.negativeTabIndexAllowed=!0,this.elements.forEach(function(t){t.hasAttribute(\"tabindex\")||d(t)})}},{key:\"initPlugins\",value:function(){this.plugins.forEach(function(t){void 0!==t.init\u0026\u0026t.init(this)},this)}}]),t}();e.default=p},function(t,e,o){\"use strict\";Object.defineProperty(e,\"__esModule\",{value:!0});var n=e.curry=function(t){var e=t.length;return function o(){var n=Array.prototype.slice.call(arguments,0);return n.length\u003e=e?t.apply(null,n):function(){var t=Array.prototype.slice.call(arguments,0);return o.apply(null,n.concat(t))}}},i=(e.compose=function(){for(var t=arguments.length,e=Array(t),o=0;o\u003ct;o++)e[o]=arguments[o];return e.reduce(function(t,e){return function(){return t(e.apply(void 0,arguments))}})},e.forEach=n(function(t,e){e.forEach(t)}),e.map=n(function(t,e){return e.map(t)}),e.filter=n(function(t,e){return e.filter(t)})),r=(e.some=n(function(t,e){return e.some(t)}),e.contains=n(function(t,e){return-1!=e.indexOf(t)}));e.without=n(function(t,e){return i(function(e){return!r(e,t)},e)}),e.inverseBooleanString=function(t){return(\"true\"!==t).toString()}},function(t,e,o){\"use strict\";function n(t,e){if(!(t instanceof e))throw new TypeError(\"Cannot call a class as a function\")}Object.defineProperty(e,\"__esModule\",{value:!0});var i=function(){function t(t,e){for(var o=0;o\u003ce.length;o++){var n=e[o];n.enumerable=n.enumerable||!1,n.configurable=!0,\"value\"in n\u0026\u0026(n.writable=!0),Object.defineProperty(t,n.key,n)}}return function(e,o,n){return o\u0026\u0026t(e.prototype,o),n\u0026\u0026t(e,n),e}}(),r=function(){function t(){n(this,t),this.selectability=!0}return i(t,[{key:\"init\",value:function(t){this.boundHandleKeyDown=this.handleKeyDown.bind(this),this.controls=t,this.controls.on(\"addElement\",this.listenForKeyDown,this),this.controls.on(\"removeElement\",this.removeKeyDownListener,this)}},{key:\"listenForKeyDown\",value:function(t){t.element.addEventListener(\"keydown\",this.boundHandleKeyDown)}},{key:\"removeKeyDownListener\",value:function(t){t.element.removeEventListener(\"keydown\",this.boundHandleKeyDown)}},{key:\"handleKeyDown\",value:function(t){switch(t.which){case 27:this.close(t.target),t.preventDefault(),t.stopPropagation();break;case 13:case 32:this.select(t.target),t.preventDefault(),t.stopPropagation();break;case 37:case 38:this.hasChromevoxModifiers(t)||(this.previousElement(t.target),t.preventDefault(),t.stopPropagation());break;case 39:case 40:this.hasChromevoxModifiers(t)||(this.nextElement(t.target),t.preventDefault(),t.stopPropagation())}}},{key:\"hasChromevoxModifiers\",value:function(t){return t.shiftKey||t.ctrlKey}},{key:\"previousElement\",value:function(t){this.controls.firesEvent(\"previousElement\",t)}},{key:\"nextElement\",value:function(t){this.controls.firesEvent(\"nextElement\",t)}},{key:\"select\",value:function(t){this.selectability\u0026\u0026!1!==this.controls.firesEvent(\"before-select\",t)\u0026\u0026(this.controls.firesEvent(\"select\",t),this.controls.firesEvent(\"after-select\",t))}},{key:\"disableSelectability\",value:function(){this.selectability=!1}},{key:\"enableSelectability\",value:function(){this.selectability=!0}},{key:\"close\",value:function(t){!1!==this.controls.firesEvent(\"before-close\",t)\u0026\u0026(this.controls.firesEvent(\"close\",t),this.controls.firesEvent(\"after-close\",t))}}]),t}();e.default=r},function(t,e,o){\"use strict\";o(5),o(6);var n=o(0),i=function(t){return t\u0026\u0026t.__esModule?t:{default:t}}(n);H5P=H5P||{},H5P.InteractiveVideo=i.default},function(t,e){},function(t,e){},function(t,e,o){\"use strict\";function n(t){return t\u0026\u0026t.__esModule?t:{default:t}}Object.defineProperty(e,\"__esModule\",{value:!0});var i=o(1),r=n(i),a=o(3),s=n(a),l={ICON:0,TEXT:1},c=function(t,e,o,n,i,a){var c=this,h=\"interactive-video-\"+a+\"-menu-\"+t,p=new r.default([new s.default]);p.on(\"close\",function(){return b()});var f=[];H5P.EventDispatcher.call(c);var v,m=function(){c.control.setAttribute(\"aria-expanded\",\"true\"),c.popup.classList.add(\"h5p-show\"),c.trigger(\"open\"),c.popup.querySelector(\u0027li[tabindex=\"0\"]\u0027).focus()},b=function(){c.control.setAttribute(\"aria-expanded\",\"false\"),c.control.focus(),c.popup.classList.remove(\"h5p-show\"),c.trigger(\"close\")},g=function(){\"true\"===c.control.getAttribute(\"aria-expanded\")?b():m()},y=function(t,e,o){for(var n=0;n\u003ct.length;n++)e.call(o,t[n],n)},k=function(t,e){o=e;var n=v.querySelectorAll(\u0027[aria-checked=\"true\"]\u0027);y(n,function(t){return t.setAttribute(\"aria-checked\",\"false\")},this),t.setAttribute(\"aria-checked\",\"true\"),b(),c.trigger(\"select\",e)},S=function(t){var e=t.value===o.value,i=d(null,l.TEXT,t.label,function(){k(this,t)},\"li\",n);return f.push({option:t,element:i}),i.setAttribute(\"aria-checked\",e.toString()),i.setAttribute(\"aria-describedby\",h),p.addElement(i),e?i.setAttribute(\"tabindex\",\"0\"):i.removeAttribute(\"tabindex\"),i};c.updateOptions=function(t){v\u0026\u0026v.parentNode.removeChild(v),v=u(null,null,\"ol\"),v.setAttribute(\"role\",\"menu\");for(var e=0;e\u003ct.length;e++)v.appendChild(S(t[e]));c.popup.appendChild(v)},c.popup=u(\"h5p-chooser h5p-\"+t,\u0027\u003ch3 id=\"\u0027+h+\u0027\"\u003e\u0027+i[t]+\"\u003c/h3\u003e\"),c.popup.setAttribute(\"role\",\"dialog\");var $=d(\"h5p-chooser-close-button\",l.ICON,i.close,g,\"div\",\"button\");c.popup.appendChild($),c.control=d(\"h5p-control h5p-\"+t,l.ICON,i[t],g,\"div\",\"button\"),c.control.setAttribute(\"aria-haspopup\",\"true\"),c.overlayControl=d(\"h5p-minimal-button h5p-\"+t,l.TEXT,i[t],g,\"div\",\"menuitem\"),c.overlayControl.tabIndex=\"-1\",c.overlayControl.classList.add(\"h5p-hide\"),c.updateOptions(e)};c.prototype=Object.create(H5P.EventDispatcher.prototype),c.prototype.constructor=c;var u=function(t,e,o){var n=document.createElement(o||\"div\");return t\u0026\u0026(n.className=t),e\u0026\u0026(n.innerHTML=e),n},d=function(t,e,o,n,i,r){var a=u(t,e===l.TEXT?o:\"\",i);return a.tabIndex=0,a.setAttribute(\"role\",r),e===l.ICON\u0026\u0026(a.title=o),a.addEventListener(\"click\",function(t){n.call(a,t)},!1),a.addEventListener(\"keydown\",function(t){32!==t.which\u0026\u002613!==t.which||(t.preventDefault(),n.call(a,t))},!1),a};e.default=c},function(t,e,o){\"use strict\";Object.defineProperty(e,\"__esModule\",{value:!0}),e.createElement=e.toggleClass=e.toggleVisibility=e.show=e.hide=e.removeClass=e.addClass=e.classListContains=e.removeChild=e.querySelectorAll=e.nodeListToArray=e.querySelector=e.appendChild=e.toggleAttribute=e.attributeEquals=e.hasAttribute=e.removeAttribute=e.setAttribute=e.getAttribute=void 0;var n=o(2),i=e.getAttribute=(0,n.curry)(function(t,e){return e.getAttribute(t)}),r=e.setAttribute=(0,n.curry)(function(t,e,o){return o.setAttribute(t,e)}),a=(e.removeAttribute=(0,n.curry)(function(t,e){return e.removeAttribute(t)}),e.hasAttribute=(0,n.curry)(function(t,e){return e.hasAttribute(t)}),e.attributeEquals=(0,n.curry)(function(t,e,o){return o.getAttribute(t)===e}),e.toggleAttribute=(0,n.curry)(function(t,e){var o=i(t,e);r(t,(0,n.inverseBooleanString)(o),e)}),e.appendChild=(0,n.curry)(function(t,e){return t.appendChild(e)}),e.querySelector=(0,n.curry)(function(t,e){return e.querySelector(t)}),e.nodeListToArray=function(t){return Array.prototype.slice.call(t)}),s=(e.querySelectorAll=(0,n.curry)(function(t,e){return a(e.querySelectorAll(t))}),e.removeChild=(0,n.curry)(function(t,e){return t.removeChild(e)}),e.classListContains=(0,n.curry)(function(t,e){return e.classList.contains(t)}),e.addClass=(0,n.curry)(function(t,e){return e.classList.add(t)})),l=e.removeClass=(0,n.curry)(function(t,e){return e.classList.remove(t)}),c=e.hide=s(\"hidden\"),u=e.show=l(\"hidden\");e.toggleVisibility=(0,n.curry)(function(t,e){return(t?u:c)(e)}),e.toggleClass=(0,n.curry)(function(t,e,o){o.classList[e?\"add\":\"remove\"](t)}),e.createElement=function(t){var e=t.tag,o=t.id,n=t.classes,i=t.attributes,r=document.createElement(e);return o\u0026\u0026(r.id=o),n\u0026\u0026n.forEach(function(t){r.classList.add(t)}),i\u0026\u0026Object.keys(i).forEach(function(t){r.setAttribute(t,i[t])}),r}},function(t,e,o){\"use strict\";Object.defineProperty(e,\"__esModule\",{value:!0});e.Eventful=function(){return{listeners:{},on:function(t,e,o){var n={listener:e,scope:o};return this.listeners[t]=this.listeners[t]||[],this.listeners[t].push(n),this},fire:function(t,e){return(this.listeners[t]||[]).every(function(t){return!1!==t.listener.call(t.scope||this,e)})},propagate:function(t,e){var o=this;t.forEach(function(t){return e.on(t,function(e){return o.fire(t,e)})})}}}},function(t,e,o){\"use strict\";function n(t,e,o){var n=this;H5P.EventDispatcher.call(n);var d,p,v,m,b=t.action;o\u0026\u0026(b.userDatas={state:o});var g,y,k,S=b.library.split(\" \")[0],$=e.l10n[h(S,t)?\"content\":\"interaction\"],C=\"H5P.Nil\"!==S\u0026\u0026\"button\"===t.displayType,w=[b.params.contentName,C?l(t.label):\"\",t.libraryTitle].filter(s)[0],T=!1,P=!1,x=!1;this.on(\"open-dialog\",function(){q()}),this.on(\"show-mask\",function(){N(this.getElement())});var I=function(){return a.extend({},{backgroundColor:\"rgb(255,255,255)\",boxShadow:!0},t.visuals)},E=function(o){d=a(\"\u003cdiv/\u003e\",{tabindex:0,role:\"button\",class:\"h5p-interaction \"+g+(o?\"\":\" h5p-hidden\"),\"aria-popup\":\"true\",\"aria-expanded\":\"false\",\"aria-label\":w,css:{left:t.x+\"%\",top:t.y+\"%\",width:\"\",height:\"\"},on:{click:function(){n.dialogDisabled||(q(),d.attr(\"aria-expanded\",\"true\"))},keydown:function(t){13!==t.which\u0026\u002632!==t.which||n.dialogDisabled||(q(),d.attr(\"aria-expanded\",\"true\"),t.preventDefault())}}}),d.on(\"keyup\",M),n.on(\"closeDialog\",function(){d\u0026\u0026(d.focus(),d.attr(\"aria-expanded\",\"false\"))}),n.getRequiresCompletion()\u0026\u0026void 0===e.editor\u0026\u0026e.currentState!==H5P.InteractiveVideo.SEEKING\u0026\u0026q(!0),a(\"\u003cdiv/\u003e\",{class:\"h5p-touch-area\"}).appendTo(d),a(\"\u003cdiv/\u003e\",{class:\"h5p-interaction-button\"}).appendTo(d),e.editor\u0026\u0026d.hover(function(){d.is(\".focused\")||d.is(\":focus\")||e.dnb\u0026\u0026(!e.dnb||e.dnb.newElement)?(e.editor.hideInteractionTitle(),T=!1):(e.editor.showInteractionTitle(w,d),T=!0)},function(){e.editor.hideInteractionTitle(),T=!1}).focus(function(){e.editor.hideInteractionTitle(),T=!1}).click(function(){e.editor.hideInteractionTitle()});var i=s(l(t.label));t.label\u0026\u0026i\u0026\u0026(p=A(t.label,\"h5p-interaction\").appendTo(d)),n.trigger(\"display\",d),setTimeout(function(){d\u0026\u0026d.removeClass(\"h5p-hidden\")},0)},A=function(t){var e=arguments.length\u003e1\u0026\u0026void 0!==arguments[1]?arguments[1]:\"\";return a(\"\u003cdiv/\u003e\",{class:\"h5p-interaction-label \"+e,html:\u0027\u003cdiv class=\"h5p-interaction-label-text\"\u003e\u0027+t+\"\u003c/div\u003e\"})},B=function(){return d=A(t.label,\"h5p-interaction h5p-interaction-label-standalone\"),d=d.css({left:t.x+\"%\",top:t.y+\"%\",width:\"\",height:\"initial\"}),n.trigger(\"display\",d),setTimeout(function(){d\u0026\u0026d.removeClass(\"h5p-hidden\")},0),d},M=function(t){t.which===r.KEY_CODE_START_PAUSE\u0026\u0026t.stopPropagation()},H=function(e){if(\"timecode\"===t.goto.type)e.click(function(e){1===e.which\u0026\u0026F({data:t.goto.time})}).keypress(function(e){32===e.which\u0026\u0026F({data:t.goto.time})}).attr(\"href\",\"#\").attr(\"tabindex\",\"0\");else{var o=t.goto.url;e.keypress(function(t){32===t.which\u0026\u0026this.click()}).attr({href:(\"other\"!==o.protocol?o.protocol:\"\")+o.url,target:\"_blank\"})}return e.addClass(\"goto-clickable\")},D=function(t){var o=!e.hasUncompletedRequiredInteractions(t);n.trigger(\"hide\",d),n.isButton()?o\u0026\u0026e.dnb.dialog.close():(e.isMobileView\u0026\u0026o\u0026\u0026e.dnb.dialog.close(),d.detach()),n.trigger(\"remove\",d),o\u0026\u0026U(d)},V=function(){var t=document.createElement(\"button\");return t.innerHTML=e.l10n.continueWithVideo,t.className=\"h5p-interaction-continue-button\",t.addEventListener(\"click\",function(){D(),e.play()}),t},O=function(t){if(\"H5P.Questionnaire\"===S){if(t.find(\".h5p-interaction-continue-button\").length)return;var o=V(),n=t.find(\".h5p-questionnaire-success-center\");n.length\u0026\u0026n.get(0).appendChild(o),y.on(\"noSuccessScreen\",function(){D(),e.play()})}},R=function(t,e){var o=function(t){return e.target===t.get(0)},n=9===e.which,i=t.first(),r=t.last();n\u0026\u0026e.shiftKey\u0026\u0026o(i)?(r.focus(),e.preventDefault()):n\u0026\u0026o(r)\u0026\u0026(i.focus(),e.preventDefault())},q=function(o){var i=e.$container.find(\".h5p-dialog-wrapper\");\"function\"==typeof y.setActivityStarted\u0026\u0026\"function\"==typeof y.getScore\u0026\u0026y.setActivityStarted();var r=n.isGotoClickable(),s=i.find(\"[tabindex]\"),l=a(r?\"\u003ca\u003e\":\"\u003cdiv\u003e\",{class:\"h5p-dialog-interaction h5p-frame\"});!r\u0026\u0026f(S)\u0026\u0026l.attr(\"tabindex\",\"0\"),l.on(\"keyup\",M),void 0!==e.editor?l.attr(\"tabindex\",-1):0===s.length\u0026\u0026l.attr(\"tabindex\",0),n.getRequiresCompletion()\u0026\u0026i.keydown(function(t){var e=i.find(\u0027[tabindex=\"0\"], button, input\u0027).filter(\":visible\");R(e,t)});var h=r?H(l):l;if(y.attach(h),O(h),G(y)\u0026\u0026(n.score=y.getScore(),n.maxScore=y.getMaxScore()),!n.hasFullScore()||!o){n.getRequiresCompletion()\u0026\u0026!n.hasFullScore()\u0026\u0026(e.dnb.dialog.hideCloseButton(),e.dnb.dialog.disableOverlay=!0,i.click(function(){if(!n.hasFullScore()){e.showWarningMask().find(\".h5p-button-back\").click(function(){return l.find(\"button\").last().focus()})}})),e.dnb.dialog.open(l),e.disableTabIndexes(),e.dnb.dialog.addLibraryClass(S),e.dnb.dialog.toggleClass(\"goto-clickable-visualize\",!(!r||!t.goto.visualize)),e.dnb.dialog.toggleClass(\"h5p-goto-timecode\",u(t,c.TIME_CODE)),e.dnb.dialog.disableOverlay\u0026\u0026e.restorePosterTabIndexes();var p=function t(){this.off(\"close\",t),e.dnb.$dialogContainer.one(\"transitionend\",function(){if(l.is(\".h5p-image\")){l.find(\"img\").css({width:\"\",height:\"\"})}});try{void 0!==y.pause\u0026\u0026(y.pause instanceof Function||\"function\"==typeof y.pause)\u0026\u0026y.pause()}catch(t){H5P.error(t)}};e.dnb.dialog.on(\"close\",p),e.dnb.dialog.on(\"close\",function(){return n.trigger(\"closeDialog\")});var v=function t(){n.dialogWidth=e.dnb.dialog.getDialogWidth(),e.dnb.dialog.off(\"close\",t)};if(e.dnb.dialog.on(\"close\",v),\"H5P.Image\"===S){var m=e.dnb.dialog.getMaxSize(d),g=l.find(\"img\");b.params.file.width\u0026\u0026b.params.file.height?L(g,m,{width:b.params.file.width,height:b.params.file.height},!e.isMobileView):(g.load(function(){g.is(\":visible\")\u0026\u0026L(g,m,{width:this.width,height:this.height},!e.isMobileView)}),e.dnb.dialog.position(d))}else e.isMobileView||e.dnb.dialog.position(d,{width:n.dialogWidth/16},!(\"H5P.Text\"===S||\"H5P.Table\"===S));if(\"H5P.Summary\"===S){var k=0;H5P.on(y,\"resize\",function(){var t=l.height();(k\u003et+10||k\u003ct-10)\u0026\u0026setTimeout(function(){e.dnb.dialog.scroll(t,300)},500),k=t})}setTimeout(function(){H5P.trigger(y,\"resize\")},0)}},L=function(t,o,n,i){n.width/=16,n.height/=16,n.height\u003eo.height\u0026\u0026(n.width=n.width*o.height/n.height,n.height=o.height),n.width\u003eo.width\u0026\u0026(n.height=n.height*o.width/n.width,n.width=o.width);var r=16/Number(t.css(\"fontSize\").replace(\"px\",\"\"));t.css({width:n.width*r+\"em\",height:n.height*r+\"em\"}),i\u0026\u0026e.dnb.dialog.position(d,n)},F=function(t){n.isButton()\u0026\u0026e.dnb.dialog.close(),e.currentState!==H5P.Video.PAUSED\u0026\u0026e.currentState!==H5P.Video.ENDED||e.play(),e.seek(t.data)},z=function(){var o=t.height||10,n=t.width||10,i=e.width/e.fontSize;return{height:o/(i/(e.$videoWrapper.width()/e.$videoWrapper.height()))*100+\"%\",width:n/i*100+\"%\"}},N=function(t){t.css(\"zIndex\",52),e.showOverlayMask()},U=function(t){t\u0026\u0026t.css(\"zIndex\",\"\"),e.hideOverlayMask()},j=function(){var o=n.isGotoClickable(),i=z(),r=I();if(d=a(\"\u003cdiv/\u003e\",{\"aria-label\":e.l10n.interaction,tabindex:\"-1\",class:\"h5p-interaction h5p-poster \"+g+(o\u0026\u0026t.goto.visualize?\" goto-clickable-visualize\":\"\"),css:{left:t.x+\"%\",top:t.y+\"%\",width:i.width,height:i.height}}),d.on(\"keyup\",M),\"H5P.IVHotspot\"!==S){d.css(\"background\",r.backgroundColor);var s=r.backgroundColor.split(\",\");if(s[3]){0===parseFloat(s[3].replace(\")\",\"\"))\u0026\u0026d.addClass(\"h5p-transparent-interaction\")}}!1===r.boxShadow\u0026\u0026d.addClass(\"h5p-box-shadow-disabled\"),\"H5P.Link\"===S\u0026\u0026(d.css(\"height\",\"auto\"),d.css(\"width\",\"auto\"),void 0===e.editor\u0026\u0026d.click(function(){return window.open(y.getUrl()),e.pause(),!1})),m=a(\"\u003cdiv\u003e\",{class:\"h5p-interaction-outer\"}).appendTo(d),v=a(o?\"\u003ca\u003e\":\"\u003cdiv\u003e\",{class:\"h5p-interaction-inner h5p-frame\"}).appendTo(m),!o\u0026\u0026f(S)\u0026\u0026v.attr(\"tabindex\",\"0\"),void 0!==e.editor\u0026\u0026y.disableAutoPlay\u0026\u0026y.disableAutoPlay();var l=o?H(v):v;y.attach(l),O(l),n.trigger(\"display\",d),n.getRequiresCompletion()\u0026\u0026e.currentState!==H5P.InteractiveVideo.SEEKING\u0026\u0026void 0===e.editor\u0026\u0026!n.hasFullScore()\u0026\u0026(N(d),d.focus()),setTimeout(function(){H5P.trigger(y,\"resize\")},0),\"function\"==typeof y.setActivityStarted\u0026\u0026\"function\"==typeof y.getScore\u0026\u0026y.setActivityStarted()},W=function(){var o,i,r=!0;if(t.adaptivity\u0026\u0026(i=n.hasFullScore(),r=!n.getRequiresCompletion()||i,i?o=t.adaptivity.correct:i||(o=t.adaptivity.wrong)),!o||void 0===o.seekTo)return void(void 0!==y.hasButton\u0026\u0026(y.hasButton(\"iv-continue\")||y.addButton(\"iv-continue\",e.l10n.defaultAdaptivitySeekLabel,function(){D(),_()}),y[r?\"showButton\":\"hideButton\"](\"iv-continue\")));e.pause(),!o.allowOptOut\u0026\u0026d\u0026\u0026(n.isButton()?(e.dnb.dialog.disableOverlay=!0,e.dnb.dialog.hideCloseButton()):N(d));var a=i?\"correct\":\"wrong\",s=o.seekLabel?o.seekLabel:e.l10n.defaultAdaptivitySeekLabel;y.hideButton(\"iv-continue\").addButton(\"iv-adaptivity-\"+a,s,function(){D(o.seekTo),!i\u0026\u0026y.resetTask\u0026\u0026(y.resetTask(),y.hideButton(\"iv-adaptivity-\"+a)),n.remove(),_(o.seekTo)}).showButton(\"iv-adaptivity-\"+a,1).hideButton(\"iv-adaptivity-\"+(i?\"wrong\":\"correct\"),1).hideButton(\"check-answer\",1).hideButton(\"show-solution\",1).hideButton(\"try-again\",1),void 0!==y.disableInput\u0026\u0026(y.disableInput instanceof Function||\"function\"==typeof y.disableInput)\u0026\u0026y.disableInput(),setTimeout(function(){var t=o.message.replace(\"\u003cp\u003e\",\"\").replace(\"\u003c/p\u003e\",\"\");y.updateFeedbackContent(t,!0),y.read(t)},0)},_=function(t){var o=K(),n=o.filter(function(t){return!t.isButton()});if(n.length?o=n:o.length\u0026\u0026e.$container.find(\".h5p-dialog-wrapper .h5p-dialog\").show(),o.length){var i=o[0];return i.isButton()?i.trigger(\"open-dialog\"):i.trigger(\"show-mask\"),void e.pause()}e.currentState!==H5P.Video.ENDED\u0026\u0026(void 0!==t\u0026\u0026(e.pause(),e.seek(t)),e.play(),e.controls.$play.focus())},K=function(){return e.getVisibleInteractions().filter(function(t){return t!==n}).filter(function(t){return t.getRequiresCompletion()\u0026\u0026!t.hasFullScore()})},Q=function(){var e=t.className;if(void 0===e){var o=b.library.split(\" \")[0].toLowerCase().split(\".\");e=o[0]+\"-\"+o[1]+\"-interaction\"}return t.goto\u0026\u0026\"timecode\"===t.goto.type\u0026\u0026(e+=\" h5p-goto-timecode\"),e};n.isGotoClickable=function(){return-1!==[\"H5P.Text\",\"H5P.Image\"].indexOf(S)\u0026\u0026t.goto\u0026\u0026-1!==[\"timecode\",\"url\"].indexOf(t.goto.type)},n.getCurrentState=function(){if(y\u0026\u0026(y.getCurrentState instanceof Function||\"function\"==typeof y.getCurrentState))return y.getCurrentState()},n.getDuration=function(){return{from:t.duration.from,to:t.duration.to}},n.getRequiresCompletion=function(){return!!t.adaptivity\u0026\u0026!!t.adaptivity.requireCompletion},n.pause=function(){return t.pause},n.isButton=function(){return\"button\"===t.displayType||!(!e.isMobileView||\"H5P.IVHotspot\"===S)\u0026\u0026(\"H5P.Image\"!==S||!1!==t.buttonOnMobile)},n.isStandaloneLabel=function(){return\"H5P.Nil\"===S},n.isMainSummary=function(){return!0===t.mainSummary},n.selectDot=function(){e.preventSkipping||(e.seekingTo=!0,Math.floor(10*e.video.getCurrentTime())!==Math.floor(10*t.duration.from)\u0026\u0026(e.currentState===H5P.Video.VIDEO_CUED?(e.play(),e.seek(t.duration.from)):e.currentState===H5P.Video.PLAYING?e.seek(t.duration.from):(e.play(),e.seek(t.duration.from),e.pause())))},n.addDot=function(){if(\"H5P.Nil\"!==S){var o=\"h5p-seekbar-interaction \"+g,i=a(\"\u003cdiv/\u003e\",{role:\"menuitem\",class:o,\"aria-label\":$+\". \"+w,title:w,css:{left:t.duration.from*e.oneSecondInPercentage+\"%\"},on:{click:n.selectDot,keydown:function(t){if(13===t.which||32===t.which)return n.selectDot(),!1}}});return e.preventSkipping\u0026\u0026i.attr(\"aria-disabled\",\"true\").attr(\"tabindex\",\"-1\"),i}},n.isVisible=function(){return x},n.visibleAt=function(e){return!(e\u003ct.duration.from||e\u003et.duration.to)},n.toggle=function(o,i){return o=Math.floor(o),n.visibleAt(o)?d?void 0:(x=!0,n.isStandaloneLabel()?B():n.isButton()?E(i):j(),void 0===e.editor?k=e.dnb.add(d,void 0,{dnbElement:k,disableContextMenu:!0}):(n.fit\u0026\u0026(e.editor.fit(d,t),n.fit=!1),d.focus(function(){e.pause()})),d):(x=!1,void(d\u0026\u0026(k\u0026\u0026(k.hideContextMenu(),k===e.dnb.focusedElement\u0026\u0026(k.blur(),delete e.dnb.focusedElement)),e.editor\u0026\u0026T\u0026\u0026(e.editor.hideInteractionTitle(),T=!1),n.remove())))},n.setTitle=function(t){d\u0026\u0026d.attr(\"aria-label\",t),w=t},n.reCreateInteraction=function(){\"H5P.IVHotspot\"!==S\u0026\u0026d\u0026\u0026(n.trigger(\"hide\",d),d.detach(),n.isStandaloneLabel()?B():n.isButton()?E(!0):j())},n.resizeInteraction=function(){n.isStandaloneLabel()||H5P.trigger(y,\"resize\")},n.positionLabel=function(t){d\u0026\u0026n.isButton()\u0026\u0026p\u0026\u0026!n.isStandaloneLabel()\u0026\u0026(p.removeClass(\"h5p-left-label\"),parseInt(d.css(\"left\"))+p.position().left+p.outerWidth()\u003et\u0026\u0026p.addClass(\"h5p-left-label\"))},n.setPosition=function(e,o){t.x=e,t.y=o,d.css({left:e+\"%\",top:o+\"%\"})},n.setSize=function(e,o){e\u0026\u0026(t.width=e),o\u0026\u0026(t.height=o),H5P.trigger(y,\"resize\")},n.remove=function(){d\u0026\u0026(n.trigger(\"domHidden\",{$dom:d,key:\"videoProgressedPast\"},{bubbles:!0,external:!0}),n.trigger(\"hide\",d),d.detach(),d=void 0)},n.reCreate=function(){g=Q(),n.isStandaloneLabel()||(b.params=b.params||{},y=H5P.newRunnable(b,e.contentId,void 0,void 0,{parent:e}),b.userDatas\u0026\u0026G(y)\u0026\u0026(n.score=y.getScore(),n.maxScore=y.getMaxScore()),y.on\u0026\u0026(y.on(\"xAPI\",function(t){var o=t.getVerifiedStatementValue([\"context\",\"contextActivities\",\"parent\"])||[],i=t.getContentXAPIId(e),r=\"completed\"===t.getVerb()||\"answered\"===t.getVerb();o.some(function(t){return t.id===i})\u0026\u0026r\u0026\u0026t.getMaxScore()\u0026\u0026null!==t.getScore()\u0026\u0026(n.score=t.getScore(),n.maxScore=t.getMaxScore(),W()),n.trigger(t)}),y.on(\"question-finished\",function(){W()}),y.on(\"resize\",function(){delete n.dialogWidth,e\u0026\u0026e.dnb\u0026\u0026e.dnb.dialog.removeStaticWidth()}),\"H5P.IVHotspot\"===S\u0026\u0026y.on(\"goto\",F),\"H5P.GoToQuestion\"===S\u0026\u0026y.on(\"chosen\",F)))};var G=function(t){return\"undefined\"!==(void 0===t?\"undefined\":i(t))\u0026\u0026\"function\"==typeof t.getScore\u0026\u0026\"function\"==typeof t.getMaxScore};n.setDnbElement=function(t){return k!==t\u0026\u0026(k=t,!0)},n.hasFullScore=function(){return n.score\u003e=n.maxScore},n.getLibraryName=function(){return S},n.getTitle=function(){return w},n.getClass=function(){return g},n.getCopyrights=function(){if(!n.isStandaloneLabel()){var o=H5P.newRunnable(b,e.contentId);if(void 0!==o){var i=new H5P.ContentCopyrights;return i.addContent(H5P.getCopyrights(o,t,e.contentId)),i.setLabel(w+\" \"+H5P.InteractiveVideo.humanizeTime(t.duration.from)+\" - \"+H5P.InteractiveVideo.humanizeTime(t.duration.to)),i}}},n.getXAPIData=function(){if(y\u0026\u0026(y.getXAPIData instanceof Function||\"function\"==typeof y.getXAPIData))return y.getXAPIData()},n.getSubcontentId=function(){return b.subContentId},n.getElement=function(){return d},n.getFirstTabbableElement=function(){var t=a(d.get(0)).find(\"[tabindex]\");return t\u0026\u0026t.length?t.get(0):d},n.focus=function(){d\u0026\u0026d.focus()},n.getClipboardData=function(){return H5P.DragNBar.clipboardify(H5PEditor.InteractiveVideo.clipboardKey,t,\"action\")},n.repositionToWrapper=function(e){if(d\u0026\u0026\"H5P.IVHotspot\"!==S){if(P\u0026\u0026(d.css({top:t.y+\"%\",left:t.x+\"%\"}),d.css(n.isButton()?{height:\"\",width:\"\"}:z()),P=!1),d.position().top+d.height()\u003ee.height()){var o=(e.height()-d.height())/e.height()*100;if(o\u003c0){o=0;var i=e.height()/parseFloat(d.css(\"font-size\"));d.css(\"height\",i+\"em\")}d.css(\"top\",o+\"%\"),P=!0}if(d.position().left+d.width()\u003ee.width()){var r=(e.width()-d.width())/e.width()*100;if(r\u003c0){r=0;var a=e.width()/parseFloat(d.css(\"font-size\"));d.css(\"width\",a+\"em\")}d.css(\"left\",r+\"%\"),P=!0}}},n.resetTask=function(){void 0!==b.userDatas\u0026\u0026void 0!==b.userDatas.state\u0026\u0026delete b.userDatas.state,delete n.score,delete n.maxScore,n.reCreate()},n.reCreate()}Object.defineProperty(e,\"__esModule\",{value:!0});var i=\"function\"==typeof Symbol\u0026\u0026\"symbol\"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t\u0026\u0026\"function\"==typeof Symbol\u0026\u0026t.constructor===Symbol\u0026\u0026t!==Symbol.prototype?\"symbol\":typeof t},r=o(0),a=H5P.jQuery,s=function(t){return void 0!==t\u0026\u0026\"string\"==typeof t\u0026\u0026t.length\u003e0},l=function(t){return s(t)?a(\"\u003cdiv\u003e\"+t+\"\u003c/div\u003e\").text():void 0},c={TIME_CODE:\"timecode\",URL:\"url\"},u=function(t,e){return void 0!==t.goto\u0026\u0026t.goto.type===e},d=[\"H5P.Image\",\"H5P.Nil\",\"H5P.Table\",\"H5P.Link\",\"H5P.GoToQuestion\",\"H5P.IVHotspot\",\"H5P.Text\"],h=function(t,e){return-1!==d.indexOf(t)||u(e,c.TIME_CODE)},p=[\"H5P.Text\",\"H5P.Table\"],f=function(t){return-1!==p.indexOf(t)};n.prototype=Object.create(H5P.EventDispatcher.prototype),n.prototype.constructor=n,e.default=n},function(t,e,o){\"use strict\";function n(t,e){if(!(t instanceof e))throw new TypeError(\"Cannot call a class as a function\")}Object.defineProperty(e,\"__esModule\",{value:!0});var i=function(){function t(t,e){for(var o=0;o\u003ce.length;o++){var n=e[o];n.enumerable=n.enumerable||!1,n.configurable=!0,\"value\"in n\u0026\u0026(n.writable=!0),Object.defineProperty(t,n.key,n)}}return function(e,o,n){return o\u0026\u0026t(e.prototype,o),n\u0026\u0026t(e,n),e}}(),r=function(t,e){return-1!==t.indexOf(e)},a=function(){function t(e){n(this,t),this.l10n=e;var o=document.createElement(\"div\");o.classList.add(\"h5p-iv-interactions-announcer\"),o.setAttribute(\"aria-live\",\"polite\"),o.setAttribute(\"aria-hidden\",\"true\"),this.interactionsAnnouncer=o;var i=document.createElement(\"div\");i.classList.add(\"h5p-iv-hotkey-instructions\"),i.textContent=e.navigationHotkeyInstructions,this.hotkeyInstructor=i,this.announcedInteractionIds=[]}return i(t,[{key:\"getHotkeyInstructor\",value:function(){return this.hotkeyInstructor}},{key:\"getInteractionAnnouncer\",value:function(){return this.interactionsAnnouncer}},{key:\"announceInteractions\",value:function(t){var e=this,o=t.filter(function(t){return t.isVisible()}),n=o.filter(function(t){return!r(e.announcedInteractionIds,t.getSubcontentId())});n.length\u003e0\u0026\u0026(this.interactionsAnnouncer.textContent=\"\",this.interactionsAnnouncer.textContent=\"\\n \"+this.getAnnouncementMessage(n.length)+\" \\n \"+this.getTitleAnnouncement(n.length,n[0])+\"\\n \"+this.getPauseAnnouncement(n)),this.announcedInteractionIds=o.map(function(t){return t.getSubcontentId()})}},{key:\"getAnnouncementMessage\",value:function(t){return 0===t?\"\":1===t?this.l10n.singleInteractionAnnouncement:this.l10n.multipleInteractionsAnnouncement}},{key:\"getTitleAnnouncement\",value:function(t,e){return 1===t?e.getTitle():\"\"}},{key:\"getPauseAnnouncement\",value:function(t){return t.some(function(t){return t.pause()})?\". \"+this.l10n.videoPausedAnnouncement:\"\"}}]),t}();e.default=a}]);"
,"summary-textual-editor.js":"/** @namespace H5PEditor */\nvar H5PEditor = H5PEditor || {};\n\nH5PEditor.SummaryTextualEditor = (function ($) {\n\n /**\n * Creates a text input widget for editing summaries.\n *\n * @class\n * @param {List}\n */\n function SummaryTextualEditor(list) {\n var self = this;\n var entity = list.getEntity();\n var recreation = false;\n var shouldWarn = false;\n\n /**\n * Instructions as to how this editor widget is used.\n * @public\n */\n self.helpText = t(\u0027helpText\u0027);\n\n // Create list html\n var $input = $(\u0027\u003ctextarea/\u003e\u0027, {\n rows: 20,\n css: {\n resize: \u0027none\u0027\n },\n placeholder: t(\u0027example\u0027),\n on: {\n change: function () {\n recreateList();\n }\n }\n });\n\n // Used to convert HTML to text and vice versa\n var $cleaner = $(\u0027\u003cdiv/\u003e\u0027);\n\n /**\n * Clears all items from the list, processes the text and add the items\n * from the text. This makes it possible to switch to another widget\n * without losing datas.\n *\n * @private\n */\n var recreateList = function () {\n // Get text input\n var textLines = $input.val().split(\"\\n\");\n textLines.push(\u0027\u0027); // Add separator\n\n // Reset list\n list.removeAllItems();\n recreation = true;\n // TODO: recreation can be dropped when group structure can be created without being appended.\n // Then the fields can be added back to the textarea like a validation.\n\n // Go through text lines and add statements to list\n var tip, statements = [];\n for (var i = 0; i \u003c textLines.length; i++) {\n var textLine = textLines[i].trim();\n if (textLine === \u0027\u0027) {\n // Task seperator\n if (statements.length || tip !== undefined) {\n // Add statements to list\n list.addItem({\n summary: statements,\n tip: tip\n });\n\n // Start new list of statements\n statements = [];\n tip = undefined;\n }\n continue;\n }\n\n // Convert text to html\n textLine = $cleaner.text(textLine).html();\n\n if (!statements.length \u0026\u0026 textLine.substr(0, 1) === \u0027:\u0027) {\n // If first line begins with \":\", it\u0027s a tip\n tip = textLine.substr(1, textLine.length);\n }\n else {\n // Add statement\n statements.push(textLine);\n }\n }\n\n recreation = false;\n };\n\n /**\n * Find the name of the given field.\n *\n * @private\n * @param {Object} field\n * @return {String}\n */\n var getName = function (field) {\n return (field.getName !== undefined ? field.getName() : field.field.name);\n };\n\n /**\n * Add items to the text input.\n *\n * @public\n * @param {Object} item instance\n */\n self.addItem = function (item) {\n if (recreation) {\n return;\n }\n if (!(item instanceof H5PEditor.Group)) {\n return;\n }\n\n var text = \u0027\u0027;\n item.forEachChild(function (child) {\n switch (getName(child)) {\n case \u0027summary\u0027:\n // Cycle through statements list\n child.forEachChild(function (grandChild) {\n // Grab HTML from text fields\n var html = grandChild.validate();\n if (html !== false) {\n // Strip all html tags and remove line breaks.\n html = html.replace(/(\u003c[^\u003e]*\u003e|\\r\\n|\\n|\\r)/gm, \u0027\u0027).trim();\n if (html !== \u0027\u0027) {\n text += html + \u0027\\n\u0027;\n }\n }\n });\n break;\n\n case \u0027tip\u0027:\n // Cycle through field in the tip group\n child.forEachChild(function (grandChild) {\n // Found text field containing tip\n var tip = grandChild.validate();\n if (tip !== false) {\n tip = tip.trim();\n if (tip !== \u0027\u0027) {\n // Add tip to the beginning\n text = \u0027:\u0027 + tip + \u0027\\n\u0027 + text;\n }\n }\n });\n break;\n }\n });\n\n if (text !== \u0027\u0027) {\n // Convert all escaped html to text\n $cleaner.html(text);\n text = $cleaner.text();\n\n // Append text\n var current = $input.val();\n if (current !== \u0027\u0027) {\n current += \u0027\\n\u0027;\n }\n $input.val(current + text);\n\n if (!warned \u0026\u0026 !shouldWarn) {\n shouldWarn = true;\n }\n }\n };\n\n /**\n * Puts this widget at the end of the given container.\n *\n * @public\n * @param {jQuery} $container\n */\n self.appendTo = function ($container) {\n $input.appendTo($container);\n if (shouldWarn \u0026\u0026 !warned) {\n alert(t(\u0027warning\u0027));\n warned = true;\n }\n };\n\n /**\n * Remove this widget from the editor DOM.\n *\n * @public\n */\n self.remove = function () {\n $input.remove();\n };\n }\n\n /**\n * Helps localize strings.\n *\n * @private\n * @param {String} identifier\n * @param {Object} [placeholders]\n * @returns {String}\n */\n var t = function (identifier, placeholders) {\n return H5PEditor.t(\u0027H5PEditor.SummaryTextualEditor\u0027, identifier, placeholders);\n };\n\n /**\n * Warn user the first time he uses the editor.\n */\n var warned = false;\n\n return SummaryTextualEditor;\n})(H5P.jQuery);\n\n\n// Add translations\nH5PEditor.language[\u0027H5PEditor.SummaryTextualEditor\u0027] = {\n \u0027libraryStrings\u0027: {\n \u0027helpText\u0027: \u0027Write each statement on a separate line.\\nUse an empty line to separate sets of statements.\\nFirst statement is always correct.\\nIf there is a tip - it is written on the first line with the prefix \" : \"\u0027,\n \u0027example\u0027: \u00272 + 2 = 4\\n0 * 4 = 4\\n\\n:Scandinavian city\\nOslo is the capital of Norway\\nOslo is the capital of Sweden\\nOslo is the capital of Island\u0027,\n \u0027warning\u0027: \u0027Warning! If you change the tasks in the textual editor all rich text formatting(incl. line breaks) will be removed.\u0027,\n }\n};\n"
,"js/stop-watch.js":"var H5P = H5P || {};\nH5P.Summary = H5P.Summary || {};\n\nH5P.Summary.StopWatch = (function () {\n /**\n * @class {H5P.Summary.StopWatch}\n * @constructor\n */\n function StopWatch() {\n /**\n * @property {number} duration in ms\n */\n this.duration = 0;\n }\n\n /**\n * Starts the stop watch\n *\n * @public\n * @return {H5P.Summary.StopWatch}\n */\n StopWatch.prototype.start = function(){\n /**\n * @property {number}\n */\n this.startTime = Date.now();\n return this;\n };\n\n /**\n * Stops the stopwatch, and returns the duration in seconds.\n *\n * @public\n * @return {number}\n */\n StopWatch.prototype.stop = function(){\n this.duration = this.duration + Date.now() - this.startTime;\n return this.passedTime();\n };\n\n /**\n * Sets the duration to 0\n *\n * @public\n */\n StopWatch.prototype.reset = function(){\n this.duration = 0;\n };\n\n /**\n * Returns the passed time in seconds\n *\n * @public\n * @return {number}\n */\n StopWatch.prototype.passedTime = function(){\n return Math.round(this.duration / 10) / 100;\n };\n\n return StopWatch;\n})();\n"
,"js/xapi-event-builder.js":"var H5P = H5P || {};\nH5P.Summary = H5P.Summary || {};\n\nH5P.Summary.XApiEventBuilder = (function ($, EventDispatcher) {\n /**\n * @typedef {object} LocalizedString\n * @property {string} en-US\n */\n\n /**\n * @class {H5P.Summary.XApiEventDefinitionBuilder}\n * @constructor\n */\n function XApiEventDefinitionBuilder(){\n EventDispatcher.call(this);\n /**\n * @property {object} attributes\n * @property {string} attributes.name\n * @property {string} attributes.description\n * @property {string} attributes.interactionType\n * @property {string} attributes.correctResponsesPattern\n * @property {object} attributes.optional\n */\n this.attributes = {};\n }\n\n XApiEventDefinitionBuilder.prototype = Object.create(EventDispatcher.prototype);\n XApiEventDefinitionBuilder.prototype.constructor = XApiEventDefinitionBuilder;\n\n\n /**\n * Sets name\n * @param {string} name\n * @return {XApiEventDefinitionBuilder}\n */\n XApiEventDefinitionBuilder.prototype.name = function (name) {\n this.attributes.name = name;\n return this;\n };\n\n /**\n * Question text and any additional information to generate the report.\n * @param {string} description\n * @return {XApiEventDefinitionBuilder}\n */\n XApiEventDefinitionBuilder.prototype.description = function (description) {\n this.attributes.description = description;\n return this;\n };\n\n /**\n * Type of the interaction.\n * @param {string} interactionType\n * @see {@link https://github.com/adlnet/xAPI-Spec/blob/master/xAPI-Data.md#interaction-types|xAPI Spec}\n * @return {XApiEventDefinitionBuilder}\n */\n XApiEventDefinitionBuilder.prototype.interactionType = function (interactionType) {\n this.attributes.interactionType = interactionType;\n return this;\n };\n\n /**\n * A pattern for determining the correct answers of the interaction\n * @param {string[]} correctResponsesPattern\n * @see {@link https://github.com/adlnet/xAPI-Spec/blob/master/xAPI-Data.md#response-patterns|xAPI Spec}\n * @return {XApiEventDefinitionBuilder}\n */\n XApiEventDefinitionBuilder.prototype.correctResponsesPattern = function (correctResponsesPattern) {\n this.attributes.correctResponsesPattern = correctResponsesPattern;\n return this;\n };\n\n /**\n * Sets optional attributes\n * @param {object} optional Can have one of the following configuration objects: choices, scale, source, target, steps\n * @return {XApiEventDefinitionBuilder}\n */\n XApiEventDefinitionBuilder.prototype.optional = function (optional) {\n this.attributes.optional = optional;\n return this;\n };\n\n /**\n * @return {object}\n */\n XApiEventDefinitionBuilder.prototype.build = function () {\n var definition = {};\n\n // sets attributes\n setAttribute(definition, \u0027name\u0027, localizeToEnUS(this.attributes.name));\n setAttribute(definition, \u0027description\u0027, localizeToEnUS(this.attributes.description));\n setAttribute(definition, \u0027interactionType\u0027, this.attributes.interactionType);\n setAttribute(definition, \u0027correctResponsesPattern\u0027, this.attributes.correctResponsesPattern);\n setAttribute(definition, \u0027type\u0027, \u0027http://adlnet.gov/expapi/activities/cmi.interaction\u0027);\n\n // adds the optional object to the definition\n if(this.attributes.optional){\n $.extend(definition, this.attributes.optional);\n }\n\n return definition;\n };\n\n // -----------------------------------------------------\n\n /**\n *\n * @constructor\n */\n function XApiEventResultBuilder(){\n EventDispatcher.call(this);\n /**\n * @property {object} attributes\n * @property {string} attributes.completion\n * @property {boolean} attributes.success\n * @property {boolean} attributes.response\n * @property {number} attributes.rawScore\n * @property {number} attributes.maxScore\n */\n this.attributes = {};\n }\n\n XApiEventResultBuilder.prototype = Object.create(EventDispatcher.prototype);\n XApiEventResultBuilder.prototype.constructor = XApiEventResultBuilder;\n\n /**\n * @param {boolean} completion\n * @return {XApiEventResultBuilder}\n */\n XApiEventResultBuilder.prototype.completion = function (completion) {\n this.attributes.completion = completion;\n return this;\n };\n\n /**\n * @param {boolean} success\n * @return {XApiEventResultBuilder}\n */\n XApiEventResultBuilder.prototype.success = function (success) {\n this.attributes.success = success;\n return this;\n };\n\n /**\n * @param {number} duration The duraction in seconds\n * @return {XApiEventResultBuilder}\n */\n XApiEventResultBuilder.prototype.duration = function (duration) {\n this.attributes.duration = duration;\n return this;\n };\n\n /**\n * Sets response\n * @param {string|string[]} response\n * @return {XApiEventResultBuilder}\n */\n XApiEventResultBuilder.prototype.response = function (response) {\n this.attributes.response = (typeof response === \u0027string\u0027) ? response : response.join(\u0027[,]\u0027);\n return this;\n };\n\n /**\n * Sets the score, and max score\n * @param {number} score\n * @param {number} maxScore\n * @return {XApiEventResultBuilder}\n */\n XApiEventResultBuilder.prototype.score = function (score, maxScore) {\n this.attributes.rawScore = score;\n this.attributes.maxScore = maxScore;\n return this;\n };\n\n /**\n * Builds the result object\n * @return {object}\n */\n XApiEventResultBuilder.prototype.build = function () {\n var result = {};\n\n setAttribute(result, \u0027response\u0027, this.attributes.response);\n setAttribute(result, \u0027completion\u0027, this.attributes.completion);\n setAttribute(result, \u0027success\u0027, this.attributes.success);\n\n if(isDefined(this.attributes.duration)){\n setAttribute(result, \u0027duration\u0027,\u0027PT\u0027 + this.attributes.duration + \u0027S\u0027);\n }\n\n // sets score\n if (isDefined(this.attributes.rawScore)) {\n result.score = {};\n setAttribute(result.score, \u0027raw\u0027, this.attributes.rawScore);\n\n if (isDefined(this.attributes.maxScore) \u0026\u0026 this.attributes.maxScore \u003e 0) {\n setAttribute(result.score, \u0027min\u0027, 0);\n setAttribute(result.score, \u0027max\u0027, this.attributes.maxScore);\n setAttribute(result.score, \u0027min\u0027, 0);\n setAttribute(result.score, \u0027scaled\u0027, Math.round(this.attributes.rawScore / this.attributes.maxScore * 10000) / 10000);\n }\n }\n\n return result;\n };\n\n // -----------------------------------------------------\n\n /**\n * @class {H5P.Summary.XApiEventBuilder}\n */\n function XApiEventBuilder() {\n EventDispatcher.call(this);\n /**\n * @property {object} attributes\n * @property {string} attributes.contentId\n * @property {string} attributes.subContentId\n */\n this.attributes = {};\n }\n\n XApiEventBuilder.prototype = Object.create(EventDispatcher.prototype);\n XApiEventBuilder.prototype.constructor = XApiEventBuilder;\n\n\n /**\n * @param {object} verb\n *\n * @public\n * @return {H5P.Summary.XApiEventBuilder}\n */\n XApiEventBuilder.prototype.verb = function (verb) {\n this.attributes.verb = verb;\n return this;\n };\n\n /**\n * @param {string} name\n * @param {string} mbox\n * @param {string} objectType\n *\n * @public\n * @return {H5P.Summary.XApiEventBuilder}\n */\n XApiEventBuilder.prototype.actor = function (name, mbox, objectType) {\n this.attributes.actor = {\n name: name,\n mbox: mbox,\n objectType: objectType\n };\n\n return this;\n };\n\n /**\n * Sets contentId\n * @param {string} contentId\n * @param {string} [subContentId]\n * @return {H5P.Summary.XApiEventBuilder}\n */\n XApiEventBuilder.prototype.contentId = function (contentId, subContentId) {\n this.attributes.contentId = contentId;\n this.attributes.subContentId = subContentId;\n return this;\n };\n\n /**\n * Sets parent in context\n * @param {string} parentContentId\n * @param {string} [parentSubContentId]\n * @return {H5P.Summary.XApiEventBuilder}\n */\n XApiEventBuilder.prototype.context = function (parentContentId, parentSubContentId) {\n this.attributes.parentContentId = parentContentId;\n this.attributes.parentSubContentId = parentSubContentId;\n return this;\n };\n\n /**\n * @param {object} result\n *\n * @public\n * @return {H5P.Summary.XApiEventBuilder}\n */\n XApiEventBuilder.prototype.result = function (result) {\n this.attributes.result = result;\n return this;\n };\n\n /**\n * @param {object} objectDefinition\n *\n * @public\n * @return {H5P.Summary.XApiEventBuilder}\n */\n XApiEventBuilder.prototype.objectDefinition = function (objectDefinition) {\n this.attributes.objectDefinition = objectDefinition;\n return this;\n };\n\n /**\n * Returns the buildt event\n * @public\n * @return {H5P.XAPIEvent}\n */\n XApiEventBuilder.prototype.build = function(){\n var event = new H5P.XAPIEvent();\n\n event.setActor();\n event.setVerb(this.attributes.verb);\n\n // sets context\n if(this.attributes.parentContentId || this.attributes.parentSubContentId){\n event.data.statement.context = {\n \u0027contextActivities\u0027: {\n \u0027parent\u0027: [\n {\n \u0027id\u0027: getContentXAPIId(this.attributes.parentContentId, this.attributes.parentSubContentId),\n \u0027objectType\u0027: \"Activity\"\n }\n ]\n }\n };\n }\n\n event.data.statement.object = {\n \u0027id\u0027: getContentXAPIId(this.attributes.contentId, this.attributes.subContentId),\n \u0027objectType\u0027: \u0027Activity\u0027\n };\n\n setAttribute(event.data, \u0027actor\u0027, this.attributes.actor);\n setAttribute(event.data.statement, \u0027result\u0027, this.attributes.result);\n setAttribute(event.data.statement.object, \u0027definition\u0027, this.attributes.objectDefinition);\n\n // sets h5p specific attributes\n if(event.data.statement.object.definition \u0026\u0026 (this.attributes.contentId || this.attributes.subContentId)) {\n var extensions = event.data.statement.object.definition.extensions = {};\n setAttribute(extensions, \u0027http://h5p.org/x-api/h5p-local-content-id\u0027, this.attributes.contentId);\n setAttribute(extensions, \u0027http://h5p.org/x-api/h5p-subContentId\u0027, this.attributes.subContentId);\n }\n\n return event;\n };\n\n /**\n * Creates a Localized String object for en-US\n *\n * @param str\n * @return {LocalizedString}\n */\n var localizeToEnUS = function(str){\n if(str != undefined){\n return {\n \u0027en-US\u0027: cleanString(str)\n };\n }\n };\n\n /**\n * Generates an id for the content\n * @param {string} contentId\n * @param {string} [subContentId]\n *\n * @see {@link https://github.com/h5p/h5p-php-library/blob/master/js/h5p-x-api-event.js#L240-L249}\n * @return {string}\n */\n var getContentXAPIId = function (contentId, subContentId) {\n if (contentId \u0026\u0026 H5PIntegration \u0026\u0026 H5PIntegration.contents) {\n var id = H5PIntegration.contents[\u0027cid-\u0027 + contentId].url;\n\n if (subContentId) {\n id += \u0027?subContentId=\u0027 + subContentId;\n }\n\n return id;\n }\n };\n\n /**\n * Removes html elements from string\n *\n * @param {string} str\n * @return {string}\n */\n var cleanString = function (str) {\n return $(\u0027\u003cdiv\u003e\u0027 + str + \u0027\u003c/div\u003e\u0027).text().trim();\n };\n\n var isDefined = function(val){\n return typeof val !== \u0027undefined\u0027;\n };\n\n function setAttribute(obj, key, value, required){\n if(isDefined(value)){\n obj[key] = value;\n } else if (required) {\n console.error(\"xApiEventBuilder: No value for [\" + key + \"] in\", obj);\n }\n }\n\n /**\n * Creates a new XApiEventBuilder\n *\n * @public\n * @static\n * @return {H5P.Summary.XApiEventBuilder}\n */\n XApiEventBuilder.create = function(){\n return new XApiEventBuilder();\n };\n\n /**\n * Creates a new XApiEventDefinitionBuilder\n *\n * @public\n * @static\n * @return {XApiEventDefinitionBuilder}\n */\n XApiEventBuilder.createDefinition = function(){\n return new XApiEventDefinitionBuilder();\n };\n\n /**\n * Creates a new XApiEventDefinitionBuilder\n *\n * @public\n * @static\n * @return {XApiEventResultBuilder}\n */\n XApiEventBuilder.createResult = function(){\n return new XApiEventResultBuilder();\n };\n\n /**\n * Returns choice to be used with \u0027cmi.interaction\u0027 for Activity of type \u0027choice\u0027\n *\n * @param {string} id\n * @param {string} description\n *\n * @public\n * @static\n * @see {@link https://github.com/adlnet/xAPI-Spec/blob/master/xAPI-Data.md#choice|xAPI-Spec}\n * @return {object}\n */\n XApiEventBuilder.createChoice = function(id, description){\n return {\n id: id,\n description: localizeToEnUS(description)\n };\n };\n\n /**\n * Takes an array of correct ids, and joins them to a \u0027correct response pattern\u0027\n *\n * @param {string[]} ids\n *\n * @public\n * @static\n * @see {@link https://github.com/adlnet/xAPI-Spec/blob/master/xAPI-Data.md#choice|xAPI-Spec}\n * @return {string}\n */\n XApiEventBuilder.createCorrectResponsePattern = function(ids){\n return ids.join(\u0027[,]\u0027);\n };\n\n /**\n * Interaction types\n *\n * @readonly\n * @enum {String}\n */\n XApiEventBuilder.interactionTypes = {\n CHOICE: \u0027choice\u0027,\n COMPOUND: \u0027compound\u0027,\n FILL_IN: \u0027fill-in\u0027,\n MATCHING: \u0027matching\u0027,\n TRUE_FALSE: \u0027true-false\u0027\n };\n\n /**\n * Verbs\n *\n * @readonly\n * @enum {String}\n */\n XApiEventBuilder.verbs = {\n ANSWERED: \u0027answered\u0027\n };\n\n return XApiEventBuilder;\n})(H5P.jQuery, H5P.EventDispatcher);\n"
,"js/summary.js":"H5P.Summary = (function ($, Question, XApiEventBuilder, StopWatch) {\n\n var summaryId = 0;\n\n function Summary(options, contentId, contentData) {\n if (!(this instanceof H5P.Summary)) {\n return new H5P.Summary(options, contentId);\n }\n\n this.id = this.contentId = contentId;\n this.summaryId = summaryId;\n Question.call(this, \u0027summary\u0027);\n this.offset = 0;\n this.score = 0;\n this.progress = 0;\n this.answers = [];\n this.answer = [];\n this.errorCounts = [];\n\n summaryId += 1;\n\n /**\n * The key is panel index, returns an array of the answer indexes the user tried.\n *\n * @property {number[][]}\n */\n this.userResponses = [];\n\n /**\n * The first key is panel index, and the second key is data-bit, value is index in panel\n *\n * @property {number[][]}\n */\n this.dataBitMap = [];\n\n // Remove empty summary to avoid JS-errors\n if (options.summaries) {\n options.summaries = options.summaries.filter(function (element) {\n return element.summary !== undefined;\n });\n }\n\n if (contentData \u0026\u0026 contentData.previousState !== undefined \u0026\u0026\n contentData.previousState.progress !== undefined \u0026\u0026\n contentData.previousState.answers) {\n this.progress = contentData.previousState.progress || this.progress;\n this.answers = contentData.previousState.answers || this.answers;\n\n var currentProgress = this.progress;\n\n // Do not count score screen as an error\n if (this.progress \u003e= options.summaries.length) {\n currentProgress = options.summaries.length - 1;\n }\n\n for (var i = 0; i \u003c= currentProgress; i++) {\n if (this.errorCounts[i] === undefined) {\n this.errorCounts[i] = 0;\n }\n if (this.answers[i]) {\n this.score += this.answers[i].length;\n this.errorCounts[i]++;\n }\n }\n }\n var that = this;\n\n /**\n * @property {StopWatch[]} Stop watches for tracking duration of slides\n */\n this.stopWatches = [];\n this.startStopWatch(this.progress);\n\n this.options = H5P.jQuery.extend({}, {\n overallFeedback: [],\n resultLabel: \"Your result:\",\n intro: \"Choose the correct statement.\",\n solvedLabel: \"Solved:\",\n scoreLabel: \"Wrong answers:\",\n labelCorrect: \"Correct.\",\n incorrectText: \"Incorrect! Please try again.\",\n labelCorrectAnswers: \"List of correct answers.\",\n postUserStatistics: (H5P.postUserStatistics === true),\n tipButtonLabel: \u0027Show tip\u0027,\n scoreBarLabel: \u0027You got :num out of :total points\u0027,\n progressText: \u0027Progress :num of :total\u0027\n }, options);\n\n this.summaries = that.options.summaries;\n\n // Prevent the score bar from interrupting the progress counter\n this.setBehaviour({disableReadSpeaker: true});\n\n // Required questiontype contract function\n this.showSolutions = function() {\n // intentionally left blank, no solution view exists\n };\n\n // Required questiontype contract function\n this.getMaxScore = function() {\n return this.summaries.length;\n };\n\n this.getScore = function() {\n var self = this;\n\n // count single correct answers\n return self.summaries.reduce(function(result, panel, index){\n var userResponse = self.userResponses[index] || [];\n\n return result + (self.correctOnFirstTry(userResponse) ? 1 : 0);\n }, 0);\n };\n\n this.getTitle = function() {\n return H5P.createTitle(this.options.intro);\n };\n\n this.getCurrentState = function () {\n return {\n progress: this.progress,\n answers: this.answers\n };\n };\n }\n\n Summary.prototype = Object.create(Question.prototype);\n Summary.prototype.constructor = Summary;\n\n /**\n * Registers DOM elements before they are attached.\n * Called from H5P.Question.\n */\n Summary.prototype.registerDomElements = function () {\n // Register task content area\n this.setContent(this.createQuestion());\n };\n\n // Function for attaching the multichoice to a DOM element.\n Summary.prototype.createQuestion = function() {\n var that = this;\n var id = 0; // element counter\n // variable to capture currently focused option.\n var currentFocusedOption;\n var elements = [];\n var $ = H5P.jQuery;\n this.$myDom = $(\u0027\u003cdiv\u003e\u0027, {\n \u0027class\u0027: \u0027summary-content\u0027\n });\n\n if (that.summaries === undefined || that.summaries.length === 0) {\n return;\n }\n\n // Create array objects\n for (var panelIndex = 0; panelIndex \u003c that.summaries.length; panelIndex++) {\n if (!(that.summaries[panelIndex].summary \u0026\u0026 that.summaries[panelIndex].summary.length)) {\n continue;\n }\n\n elements[panelIndex] = {\n tip: that.summaries[panelIndex].tip,\n summaries: []\n };\n\n for (var summaryIndex = 0; summaryIndex \u003c that.summaries[panelIndex].summary.length; summaryIndex++) {\n var isAnswer = (summaryIndex === 0);\n that.answer[id] = isAnswer; // First claim is correct\n\n // create mapping from data-bit to index in panel\n that.dataBitMap[panelIndex] = this.dataBitMap[panelIndex] || [];\n that.dataBitMap[panelIndex][id] = summaryIndex;\n\n // checks the answer and updates the user response array\n if(that.answers[panelIndex] \u0026\u0026 (that.answers[panelIndex].indexOf(id) !== -1)){\n this.storeUserResponse(panelIndex, summaryIndex);\n }\n\n // adds to elements\n elements[panelIndex].summaries[summaryIndex] = {\n id: id++,\n text: that.summaries[panelIndex].summary[summaryIndex]\n };\n }\n\n // if we have progressed passed this point, the success pattern must also be saved\n if(panelIndex \u003c that.progress){\n this.storeUserResponse(panelIndex, 0);\n }\n\n // Randomize elements\n for (var k = elements[panelIndex].summaries.length - 1; k \u003e 0; k--) {\n var j = Math.floor(Math.random() * (k + 1));\n var temp = elements[panelIndex].summaries[k];\n elements[panelIndex].summaries[k] = elements[panelIndex].summaries[j];\n elements[panelIndex].summaries[j] = temp;\n }\n }\n\n // Create content panels\n var $summary_container = $(\u0027\u003cdiv class=\"summary-container\"\u003e\u003c/div\u003e\u0027);\n var $summary_list = $(\u0027\u003cul role=\"list\" aria-labelledby=\"answerListHeading-\u0027+that.summaryId+\u0027\"\u003e\u003c/ul\u003e\u0027);\n var $evaluation = $(\u0027\u003cdiv class=\"summary-evaluation\"\u003e\u003c/div\u003e\u0027);\n var $evaluation_content = $(\u0027\u003cdiv id=\"questionDesc-\u0027+that.summaryId+\u0027\" class=\"summary-evaluation-content\"\u003e\u0027 + that.options.intro + \u0027\u003c/div\u003e\u0027);\n var $score = $(\u0027\u003cdiv class=\"summary-score\"\u003e\u003c/div\u003e\u0027);\n var $options = $(\u0027\u003cdiv class=\"summary-options\"\u003e\u003c/div\u003e\u0027);\n var $progress = $(\u0027\u003cdiv class=\"summary-progress\" aria-live=\"polite\"\u003e\u003c/div\u003e\u0027);\n var $progressNumeric = $(\u0027\u003cdiv class=\"summary-progress-numeric\" aria-hidden=\"true\"\u003e\u003c/div\u003e\u0027);\n var options_padding = parseInt($options.css(\u0027paddingLeft\u0027));\n // content div added for readspeaker that indicates list of correct answers.\n var $answersListHeading = $(\u0027\u003cdiv id=\"answerListHeading-\u0027+that.summaryId+\u0027\" class=\"h5p-hidden-read\"\u003e\u0027 + that.options.labelCorrectAnswers + \u0027\u003c/div\u003e\u0027);\n\n if (this.score) {\n $score.html(that.options.scoreLabel + \u0027 \u0027 + this.score).show();\n }\n\n // Insert content\n // aria-hidden = true added for readspeaker to avoid reading empty answers list.\n $summary_container.attr(\"aria-hidden\", \"true\");\n $summary_container.html($answersListHeading);\n $summary_container.append($summary_list);\n this.$myDom.append($summary_container);\n this.$myDom.append($evaluation);\n this.$myDom.append($options);\n $evaluation.append($evaluation_content);\n $evaluation.append($evaluation);\n $evaluation.append($progress);\n $evaluation.append($progressNumeric);\n $evaluation.append($score);\n\n /**\n * Handle selected alternative\n *\n * @param {jQuery} $el Selected element\n * @param {boolean} [setFocus] Set focus on first element of next panel.\n * Used when alt was selected with keyboard.\n */\n var selectedAlt = function ($el, setFocus) {\n var nodeId = Number($el.attr(\u0027data-bit\u0027));\n var panelId = Number($el.parent().data(\u0027panel\u0027));\n var isRadioClicked = $el.attr(\u0027aria-checked\u0027);\n if(isRadioClicked == \u0027true\u0027) return;\n\n if (that.errorCounts[panelId] === undefined) {\n that.errorCounts[panelId] = 0;\n }\n\n that.storeUserResponse(panelId, nodeId);\n\n // Correct answer?\n if (that.answer[nodeId]) {\n that.stopStopWatch(panelId);\n\n that.progress++;\n var position = $el.position();\n var summary = $summary_list.position();\n var $answer = $(\u0027\u003cli role=\"listitem\"\u003e\u0027 + $el.html() + \u0027\u003c/li\u003e\u0027);\n\n $progressNumeric.html(that.options.solvedLabel + \u0027 \u0027 + (panelId + 1) + \u0027/\u0027 + that.summaries.length);\n\n var interpolatedProgressText = that.options.progressText\n .replace(\u0027:num\u0027, panelId + 1)\n .replace(\u0027:total\u0027, that.summaries.length);\n $progress.html(interpolatedProgressText);\n\n $el.attr(\"aria-checked\", \"true\");\n\n // Insert correct claim into summary list\n $summary_list.append($answer);\n $summary_container.addClass(\u0027has-results\u0027);\n // change aria-hidden property as when correct answer is added inside list at top\n $summary_container.attr(\"aria-hidden\", \"false\");\n that.adjustTargetHeight($summary_container, $summary_list, $answer);\n\n\n // Move into position over clicked element\n $answer.css({display: \u0027block\u0027, width: $el.css(\u0027width\u0027), height: $el.css(\u0027height\u0027)});\n $answer.css({position: \u0027absolute\u0027, top: position.top, left: position.left});\n $answer.css({backgroundColor: \u0027#9dd8bb\u0027, border: \u0027\u0027});\n setTimeout(function () {\n $answer.css({backgroundColor: \u0027\u0027});\n }, 1);\n //$answer.animate({backgroundColor: \u0027#eee\u0027}, \u0027slow\u0027);\n\n var panel = parseInt($el.parent().attr(\u0027data-panel\u0027));\n var $curr_panel = $(\u0027.h5p-panel:eq(\u0027 + panel + \u0027)\u0027, that.$myDom);\n var $next_panel = $(\u0027.h5p-panel:eq(\u0027 + (panel + 1) + \u0027)\u0027, that.$myDom);\n var finished = ($next_panel.length === 0);\n // Disable panel while waiting for animation\n $curr_panel.addClass(\u0027panel-disabled\u0027);\n\n // Update tip:\n $evaluation_content.find(\u0027.joubel-tip-container\u0027).remove();\n if (elements[that.progress] !== undefined \u0026\u0026\n elements[that.progress].tip !== undefined \u0026\u0026\n elements[that.progress].tip.trim().length \u003e 0) {\n $evaluation_content.append(H5P.JoubelUI.createTip(elements[that.progress].tip, {\n tipLabel: that.options.tipButtonLabel\n }));\n }\n\n $answer.animate(\n {\n top: summary.top + that.offset,\n left: \u0027-=\u0027 + options_padding + \u0027px\u0027,\n width: \u0027+=\u0027 + (options_padding * 2) + \u0027px\u0027\n },\n {\n complete: function() {\n // Remove position (becomes inline);\n $(this).css(\u0027position\u0027, \u0027\u0027).css({\n width: \u0027\u0027,\n height: \u0027\u0027,\n top: \u0027\u0027,\n left: \u0027\u0027\n });\n $summary_container.css(\u0027height\u0027, \u0027\u0027);\n\n // Calculate offset for next summary item\n var tpadding = parseInt($answer.css(\u0027paddingTop\u0027)) * 2;\n var tmargin = parseInt($answer.css(\u0027marginBottom\u0027));\n var theight = parseInt($answer.css(\u0027height\u0027));\n that.offset += theight + tpadding + tmargin + 1;\n\n // Fade out current panel\n $curr_panel.fadeOut(\u0027fast\u0027, function () {\n $curr_panel.parent().css(\u0027height\u0027, \u0027auto\u0027);\n // Show next panel if present\n if (!finished) {\n // start next timer\n that.startStopWatch(that.progress);\n\n $next_panel.fadeIn(\u0027fast\u0027);\n\n // Focus first element of next panel\n if (setFocus) {\n $next_panel.children().get(0).focus();\n }\n } else {\n // Hide intermediate evaluation\n $evaluation_content.html(that.options.resultLabel);\n\n that.doFinalEvaluation();\n }\n that.trigger(\u0027resize\u0027);\n });\n }\n }\n );\n }\n else {\n // Remove event handler (prevent repeated clicks) and mouseover effect\n $el.off(\u0027click\u0027);\n $el.addClass(\u0027summary-failed\u0027);\n $el.removeClass(\u0027summary-claim-unclicked\u0027);\n $el.attr(\"aria-checked\", \"true\");\n $evaluation.children(\u0027.summary-score\u0027).css(\u0027display\u0027, \u0027block\u0027);\n $score.html(that.options.scoreLabel + \u0027 \u0027 + (++that.score));\n that.errorCounts[panelId]++;\n if (that.answers[panelId] === undefined) {\n that.answers[panelId] = [];\n }\n that.answers[panelId].push(nodeId);\n }\n\n that.trigger(\u0027resize\u0027);\n that.triggerXAPI(\u0027interacted\u0027);\n\n // Trigger answered xAPI event on first try for the current\n // statement group\n if (that.userResponses[panelId].length === 1) {\n that.trigger(that.createXApiAnsweredEvent(\n that.summaries[panelId],\n that.userResponses[panelId] || [],\n panelId,\n that.timePassedInStopWatch(panelId)));\n }\n\n // Trigger overall answered xAPI event when finished\n if (finished) {\n that.triggerXAPIScored(that.getScore(), that.getMaxScore(), \u0027answered\u0027);\n }\n };\n\n // Initialize the visible and invisible progress counters\n $progressNumeric.html(that.options.solvedLabel + \u0027 \u0027 + this.progress + \u0027/\u0027 + that.summaries.length);\n var interpolatedProgressText = that.options.progressText\n .replace(\u0027:num\u0027, that.progress)\n .replace(\u0027:total\u0027, that.summaries.length);\n $progress.html(interpolatedProgressText);\n\n // Add elements to content\n for (var i = 0; i \u003c elements.length; i++) {\n var element = elements[i];\n\n if (i \u003c that.progress) { // i is panelId\n for (var j = 0; j \u003c element.summaries.length; j++) {\n var sum = element.summaries[j];\n if (that.answer[sum.id]) {\n $summary_list.append(\u0027\u003cli style=\"display:block\"\u003e\u0027 + sum.text + \u0027\u003c/li\u003e\u0027);\n $summary_container.addClass(\u0027has-results\u0027);\n break;\n }\n }\n // Cannot use continue; due to id/animation system\n }\n\n // added aria-labelledby property for readspeaker to read, when first option receive focus\n var $page = $(\u0027\u003cul aria-labelledby=\"questionDesc-\u0027+that.summaryId+\u0027\" role=\"radiogroup\" class=\"h5p-panel\" data-panel=\"\u0027 + i + \u0027\"\u003e\u003c/ul\u003e\u0027);\n\n\n // Create initial tip for first summary-list if tip is available\n if (i==0 \u0026\u0026 element.tip !== undefined \u0026\u0026 element.tip.trim().length \u003e 0) {\n $evaluation_content.append(H5P.JoubelUI.createTip(element.tip, {\n tipLabel: that.options.tipButtonLabel\n }));\n }\n\n for (var j = 0; j \u003c element.summaries.length; j++) {\n var summaryLineClass = \u0027summary-claim-unclicked\u0027;\n\n // If progress is at current task\n if (that.progress === i \u0026\u0026 that.answers[that.progress]) {\n // Check if there are any previous wrong answers.\n for (var k = 0; k \u003c that.answers[that.progress].length; k++) {\n if (that.answers[that.progress][k] === element.summaries[j].id) {\n summaryLineClass = \u0027summary-failed\u0027;\n break;\n }\n }\n }\n\n var $node = $(\u0027\u0027 +\n \u0027\u003cli role=\"radio\" aria-checked=\"false\" data-name=\"\u0027+j+\u0027\" data-bit=\"\u0027 + element.summaries[j].id + \u0027\" class=\"\u0027 + summaryLineClass + \u0027\"\u003e\u0027 +\n element.summaries[j].text +\n \u0027\u003c/li\u003e\u0027);\n // added tabindex = 0 for the first option to avoid accessing rest of the options via TAB\n (j == 0) ? $node.attr(\"tabindex\", \"0\") : $node.attr(\"tabindex\", \"-1\");\n\n $node.on(\u0027focus\u0027, function() {\n var ind = $(this).attr(\u0027data-name\u0027);\n setFocusIndex(ind);\n });\n\n // function captures the index of currently focused option\n var setFocusIndex = function(idx) {\n currentFocusedOption = idx;\n };\n\n // Do not add click event for failed nodes\n if (summaryLineClass === \u0027summary-failed\u0027) {\n $page.append($node);\n continue;\n }\n\n $node.click(function() {\n selectedAlt($(this));\n }).keydown(function (e) {\n switch (e.which) {\n case 13: // Enter\n case 32: // Space\n selectedAlt($(this), true);\n e.preventDefault();\n break;\n\n case 37: // Left Arrow\n case 38: // Up Arrow\n // Go to previous Option\n that.gotoPreviousOption(that, currentFocusedOption);\n e.preventDefault();\n break;\n\n case 39: // Right Arrow\n case 40: // Down Arrow\n // Go to next Option\n that.gotoNextOption(that, currentFocusedOption);\n e.preventDefault();\n break;\n }\n });\n\n $page.append($node);\n }\n\n $options.append($page);\n }\n\n if (that.progress === elements.length) {\n $evaluation_content.html(that.options.resultLabel);\n that.doFinalEvaluation();\n }\n else {\n // Show first panel\n $(\u0027.h5p-panel:eq(\u0027 + (that.progress) + \u0027)\u0027, that.$myDom).css({display: \u0027block\u0027});\n if (that.progress) {\n that.offset = ($(\u0027.summary-claim-unclicked:visible:first\u0027, that.$myDom).outerHeight() * that.errorCounts.length);\n }\n }\n\n that.trigger(\u0027resize\u0027);\n\n return this.$myDom;\n };\n\n /**\n * Returns true if answers have been given\n *\n * @return {boolean}\n */\n Summary.prototype.getAnswerGiven = function () {\n return this.errorCounts.length \u003e 0;\n };\n\n /**\n * Handles moving the focus from the current option to the previous option and changes tabindex accorindgly\n *\n */\n Summary.prototype.gotoPreviousOption = function (that, currentFocusedOption) {\n this.currentFocusedOption = currentFocusedOption;\n var totOptions = that.summaries[that.progress].summary.length;\n var prevRadioEle = $(\"ul[data-panel=\"+that.progress+\"] li[role=\u0027radio\u0027]\", this.$myDom);\n\n //prevRadioEle.removeAttr(\"tabindex\");\n prevRadioEle.attr(\"tabindex\", \"-1\");\n this.currentFocusedOption--;\n\n if(this.currentFocusedOption \u003c 0) {\n var num = totOptions - 1;\n prevRadioEle.eq(num).attr(\"tabindex\", \"0\");\n prevRadioEle.eq(num).focus();\n }\n else {\n prevRadioEle.eq(this.currentFocusedOption).attr(\"tabindex\", \"0\");\n prevRadioEle.eq(this.currentFocusedOption).focus();\n }\n };\n\n /**\n * Handles moving the focus from the current option to the next option and changes tabindex accorindgly\n *\n */\n Summary.prototype.gotoNextOption = function (that, currentFocusedOption) {\n this.currentFocusedOption = currentFocusedOption;\n var totOptions = that.summaries[that.progress].summary.length;\n var nextRadioEle = $(\"ul[data-panel=\"+that.progress+\"] li[role=\u0027radio\u0027]\", this.$myDom);\n\n //nextRadioEle.removeAttr(\"tabindex\");\n nextRadioEle.attr(\"tabindex\", \"-1\");\n this.currentFocusedOption++;\n\n if(this.currentFocusedOption == totOptions) {\n nextRadioEle.eq(0).attr(\"tabindex\", \"0\");\n nextRadioEle.eq(0).focus();\n }\n else {\n nextRadioEle.eq(this.currentFocusedOption).attr(\"tabindex\", \"0\");\n nextRadioEle.eq(this.currentFocusedOption).focus();\n }\n };\n\n /**\n * Calculate final score and display feedback.\n *\n * @param container\n * @param options_panel\n * @param list\n * @param score\n */\n Summary.prototype.doFinalEvaluation = function () {\n var that = this;\n var errorCount = this.countErrors();\n var maxScore = that.summaries.length;\n var score = maxScore - errorCount;\n\n // Calculate percentage\n var percent = 100 - (errorCount / that.errorCounts.length * 100);\n\n // Show final evaluation\n var summary = H5P.Question.determineOverallFeedback(that.options.overallFeedback, percent / 100)\n .replace(\u0027@score\u0027, score)\n .replace(\u0027@total\u0027, maxScore)\n .replace(\u0027@percent\u0027, Math.round(percent));\n\n $(\".summary-evaluation-content\", this.$myDom).removeAttr(\"tabindex\");\n\n var scoreBarLabel = that.options.scoreBarLabel.replace(\u0027:num\u0027, score).replace(\u0027:total\u0027, maxScore);\n\n this.setFeedback(summary, score, maxScore, scoreBarLabel);\n\n // Only read out the score after the progress is read\n setTimeout(function() {\n that.setBehaviour({disableReadSpeaker: false});\n that.readFeedback();\n that.read(scoreBarLabel);\n }, 3000);\n\n that.trigger(\u0027resize\u0027);\n };\n\n /**\n * Resets the complete task back to its\u0027 initial state.\n * Used for contracts.\n */\n Summary.prototype.resetTask = function () {\n // Summary is not yet able to Reset itself\n };\n\n /**\n * Adjust height of container.\n *\n * @param container\n * @param elements\n * @param el\n */\n Summary.prototype.adjustTargetHeight = function (container, elements, el) {\n var new_height = parseInt(elements.outerHeight()) + parseInt(el.outerHeight()) + parseInt(el.css(\u0027marginBottom\u0027)) + parseInt(el.css(\u0027marginTop\u0027));\n if (new_height \u003e parseInt(container.css(\u0027height\u0027))) {\n container.animate({height: new_height});\n }\n };\n\n /**\n * Count amount of wrong answers\n *\n * @returns {number}\n */\n Summary.prototype.countErrors = function() {\n var error_count = 0;\n\n // Count boards without errors\n for (var i = 0; i \u003c this.summaries.length; i++) {\n if (this.errorCounts[i] === undefined) {\n error_count++;\n }\n else {\n error_count += this.errorCounts[i] ? 1 : 0;\n }\n }\n\n return error_count;\n };\n\n /**\n * Returns the choices array for xApi statements\n *\n * @param {String[]} answers\n *\n * @return {{ choices: []}}\n */\n Summary.prototype.getXApiChoices = function (answers) {\n var choices = answers.map(function(answer, index){\n return XApiEventBuilder.createChoice(index.toString(), answer);\n });\n\n return {\n choices: choices\n };\n };\n\n /**\n * Saves the user response\n *\n * @param {number} questionIndex\n * @param {number} answerIndex\n */\n Summary.prototype.storeUserResponse = function (questionIndex, answerIndex) {\n var self = this;\n if(self.userResponses[questionIndex] === undefined){\n self.userResponses[questionIndex] = [];\n }\n\n self.userResponses[questionIndex].push(this.dataBitMap[questionIndex][answerIndex]);\n };\n\n /**\n * Starts a stopwatch for indexed slide\n *\n * @param {number} index\n */\n Summary.prototype.startStopWatch = function (index) {\n this.stopWatches[index] = this.stopWatches[index] || new StopWatch();\n this.stopWatches[index].start();\n };\n\n /**\n * Stops a stopwatch for indexed slide\n *\n * @param {number} [index]\n */\n Summary.prototype.stopStopWatch = function (index) {\n if(this.stopWatches[index]){\n this.stopWatches[index].stop();\n }\n };\n\n /**\n * Returns the passed time in seconds of a stopwatch on an indexed slide,\n * or 0 if not existing\n *\n * @param {number} index\n * @return {number}\n */\n Summary.prototype.timePassedInStopWatch = function (index) {\n if(this.stopWatches[index] !== undefined){\n return this.stopWatches[index].passedTime();\n }\n else {\n // if not created, return no passed time,\n return 0;\n }\n };\n\n /**\n * Returns the time the user has spent on all questions so far\n *\n * @return {number}\n */\n Summary.prototype.getTotalPassedTime = function () {\n return this.stopWatches\n .filter(function(watch){\n return watch !== undefined;\n })\n .reduce(function(sum, watch){\n return sum + watch.passedTime();\n }, 0);\n };\n\n /**\n * Creates an xAPI answered event for a single statement list\n *\n * @param {object} panel\n * @param {number[]} userAnswer\n * @param {number} panelIndex\n * @param {number} duration\n *\n * @return {H5P.XAPIEvent}\n */\n Summary.prototype.createXApiAnsweredEvent = function (panel, userAnswer, panelIndex, duration) {\n var self = this;\n\n // creates the definition object\n var definition = XApiEventBuilder.createDefinition()\n .name(\u0027Summary statement\u0027)\n .description(self.options.intro)\n .interactionType(XApiEventBuilder.interactionTypes.CHOICE)\n .correctResponsesPattern([\u00270\u0027])\n .optional(self.getXApiChoices(panel.summary))\n .build();\n\n // create the result object\n var result = XApiEventBuilder.createResult()\n .response(userAnswer.join(\u0027[,]\u0027))\n .duration(duration)\n .score((self.correctOnFirstTry(userAnswer) ? 1 : 0), 1)\n .build();\n\n return XApiEventBuilder.create()\n .verb(XApiEventBuilder.verbs.ANSWERED)\n .objectDefinition(definition)\n .context(self.contentId, self.subContentId)\n .contentId(self.contentId, panel.subContentId)\n .result(result)\n .build();\n };\n\n Summary.prototype.correctOnFirstTry = function(userAnswer){\n return (userAnswer.length === 1) \u0026\u0026 userAnswer[0] === 0;\n };\n\n /**\n * Retrieves the xAPI data necessary for generating result reports.\n *\n * @return {object}\n */\n Summary.prototype.getXAPIData = function(){\n var self = this;\n\n // create array with userAnswer\n var children = self.summaries.map(function(panel, index) {\n var userResponse = self.userResponses[index] || [];\n var duration = self.timePassedInStopWatch(index);\n var event = self.createXApiAnsweredEvent(panel, userResponse, index, duration);\n\n return {\n statement: event.data.statement\n };\n });\n\n var result = XApiEventBuilder.createResult()\n .score(self.getScore(), self.getMaxScore())\n .duration(self.getTotalPassedTime())\n .build();\n\n // creates the definition object\n var definition = XApiEventBuilder.createDefinition()\n .interactionType(XApiEventBuilder.interactionTypes.COMPOUND)\n .name(self.getTitle())\n .description(self.options.intro)\n .build();\n\n var xAPIEvent = XApiEventBuilder.create()\n .verb(XApiEventBuilder.verbs.ANSWERED)\n .contentId(self.contentId, self.subContentId)\n .context(self.getParentAttribute(\u0027contentId\u0027), self.getParentAttribute(\u0027subContentId\u0027))\n .objectDefinition(definition)\n .result(result)\n .build();\n\n return {\n statement: xAPIEvent.data.statement,\n children: children\n };\n };\n\n /**\n * Returns an attribute from this.parent if it exists\n *\n * @param {string} attributeName\n * @return {*|undefined}\n */\n Summary.prototype.getParentAttribute = function (attributeName) {\n var self = this;\n\n if(self.parent !== undefined){\n return self.parent[attributeName];\n }\n };\n\n return Summary;\n\n})(H5P.jQuery, H5P.Question, H5P.Summary.XApiEventBuilder, H5P.Summary.StopWatch);\n"
,"scripts/duration.js":"var H5PEditor = H5PEditor || {};\n\n/**\n * Duration widget module\n *\n * @param {jQuery} $\n */\nH5PEditor.widgets.duration = H5PEditor.Duration = (function ($) {\n\n /**\n * Creates a time picker.\n *\n * @param {mixed} parent\n * @param {object} field\n * @param {mixed} params\n * @param {function} setValue\n * @returns {C}\n */\n function C(parent, field, params, setValue) {\n this.parent = parent;\n this.field = field;\n this.params = params;\n this.setValue = setValue;\n }\n\n /**\n * Append the field to the wrapper.\n *\n * @param {jQuery} $wrapper\n * @returns {undefined}\n */\n C.prototype.appendTo = function ($wrapper) {\n var that = this;\n\n this.$item = $(this.createHtml()).appendTo($wrapper);\n this.$inputs = this.$item.find(\u0027input\u0027);\n this.$errors = this.$item.children(\u0027.h5p-errors\u0027);\n\n this.$inputs.change(function () {\n // Validate\n var value = that.validate();\n\n if (value) {\n // Set param\n that.params = value;\n that.setValue(that.field, value);\n }\n }).click(function () {\n return false;\n });\n };\n\n /**\n * Creates HTML for the widget.\n */\n C.prototype.createHtml = function () {\n var input = H5PEditor.createText(this.params !== undefined ? C.humanizeTime(this.params.from) : undefined, 15, \u0027From\u0027) + \u0027 - \u0027 + H5PEditor.createText(this.params !== undefined ? C.humanizeTime(this.params.to) : undefined, 15, \u0027To\u0027);\n return H5PEditor.createFieldMarkup(this.field, input);\n };\n\n /**\n * Validate the current values.\n */\n C.prototype.validate = function () {\n var that = this;\n var duration = {};\n\n if (that.$errors.children().length) {\n // Field hasn\u0027t been fixed since last validate\n return false;\n }\n\n this.$inputs.each(function (i) {\n var $input = $(this);\n var value = H5P.trim($input.val());\n var field = that.field.fields[i];\n\n // Check that the input isn\u0027t blank\n if ((that.field.optional === undefined || !that.field.optional) \u0026\u0026 !value.length) {\n that.$errors.append(H5PEditor.createError(H5PEditor.t(\u0027core\u0027, \u0027requiredProperty\u0027, {\u0027:property\u0027: field.name})));\n return false;\n }\n\n // Split time format and check that we have between one and two colons.\n var values = value.split(\u0027:\u0027, 4);\n if (values.length !== 2 \u0026\u0026 values.length !== 3) {\n that.$errors.append(H5PEditor.createError(C.t(\u0027invalidTime\u0027, {\u0027:property\u0027: field.name})));\n return false;\n }\n\n // Validate seconds and add to value\n var allowedChars = new RegExp(\u0027^[0-9]+$\u0027);\n var j = values.length - 1;\n\n value = parseInt(values[j]);\n if (!values[j].match(allowedChars) || values[j].length !== 2 || value \u003e 59) {\n that.$errors.append(H5PEditor.createError(C.t(\u0027invalidTime\u0027, {\u0027:property\u0027: field.name})));\n return false;\n }\n\n // Validate minutes\n j = j - 1;\n var minutes = parseInt(values[j]);\n if (!values[j].match(allowedChars) || (values[j - 1] !== undefined \u0026\u0026 values[j].length !== 2) || (values[j - 1] === undefined \u0026\u0026 values[j].length !== (minutes + \u0027\u0027).length) || minutes \u003e 59) {\n that.$errors.append(H5PEditor.createError(C.t(\u0027invalidTime\u0027, {\u0027:property\u0027: field.name})));\n return false;\n }\n // Convert to seconds and add to value\n value += minutes * 60;\n\n // Validate hours\n j = j - 1;\n if (values[j] !== undefined) {\n var hours = parseInt(values[j]);\n if (!values[j].match(allowedChars) || values[j].length !== (hours + \u0027\u0027).length || hours \u003c 1) {\n that.$errors.append(H5PEditor.createError(C.t(\u0027invalidTime\u0027, {\u0027:property\u0027: field.name})));\n return false;\n }\n // Convert to seconds and add to value\n value += hours * 3600;\n }\n\n // Check that field doesn\u0027t exceed its min and max values.\n if (field.max !== undefined \u0026\u0026 value \u003e field.max) {\n that.$errors.append(H5PEditor.createError(H5PEditor.t(\u0027core\u0027, \u0027exceedsMax\u0027, {\u0027:property\u0027: field.name, \u0027:max\u0027: C.humanizeTime(field.max)})));\n return false;\n }\n else if (field.min !== undefined \u0026\u0026 value \u003c field.min) {\n that.$errors.append(H5PEditor.createError(C.t(\u0027exceedsMin\u0027, {\u0027:property\u0027: field.name, \u0027:min\u0027: C.humanizeTime(field.min)})));\n return false;\n }\n\n duration[field.name] = value;\n });\n\n // Check that \"To\" time always is after \"From\" time.\n if (duration.from \u003e duration.to) {\n this.$errors.append(H5PEditor.createError(C.t(\u0027fromBiggerThanTo\u0027)));\n }\n\n return H5PEditor.checkErrors(this.$errors, this.$inputs, duration);\n };\n\n /**\n * Remove this item.\n */\n C.prototype.remove = function () {\n this.$item.remove();\n };\n\n /**\n * Local translate function.\n *\n * @param {Atring} key\n * @param {Object} params\n * @returns {@exp;H5PEditor@call;t}\n */\n C.t = function (key, params) {\n return H5PEditor.t(\u0027H5PEditor.Duration\u0027, key, params);\n };\n\n /**\n * Formats time in H:MM:SS.\n *\n * @param {float} seconds\n * @returns {string}\n */\n C.humanizeTime = function (seconds) {\n var minutes = Math.floor(seconds / 60);\n var hours = Math.floor(minutes / 60);\n\n minutes = minutes % 60;\n seconds = Math.floor(seconds % 60);\n\n var time = \u0027\u0027;\n\n if (hours !== 0) {\n time += hours + \u0027:\u0027;\n\n if (minutes \u003c 10) {\n time += \u00270\u0027;\n }\n }\n\n time += minutes + \u0027:\u0027;\n\n if (seconds \u003c 10) {\n time += \u00270\u0027;\n }\n\n time += seconds;\n\n return time;\n };\n\n return C;\n})(H5P.jQuery);\n\n// Default english translations\nH5PEditor.language[\u0027H5PEditor.Duration\u0027] = {\n libraryStrings: {\n exceedsMin: \u0027\":property\" exceeds minimum value of :min.\u0027,\n fromBiggerThanTo: \u0027\"From\" must be earlier than \"To\".\u0027,\n invalidTime: \u0027\":property\" contains an invalid time format.\u0027\n }\n};\n"
,"timecode.js":"/**\n * @namespace H5PEditor\n */\nH5PEditor.widgets.timecode = H5PEditor.Timecode = (function ($, NumberField) {\n\n /**\n * Converts timecodes to seconds.\n *\n * @class\n * @param {*} parent\n * @param {Object} field\n * @param {Number} params\n * @param {Function} setValue\n */\n function Timecode(parent, field, params, setValue) {\n var self = this;\n\n // Global elements\n var $item, $input, $errors;\n\n self.field = field;\n\n /**\n * Initialize timecode fields.\n *\n * @private\n */\n var init = function () {\n if (params !== undefined) {\n // Create timecode\n params = toTimecode(params);\n }\n\n $item = $(createHtml());\n $input = $item.find(\u0027input\u0027);\n $errors = $item.children(\u0027.h5p-errors\u0027);\n\n // Validate on change\n $input.change(function () {\n // Validate\n var value = self.validate();\n\n if (value !== false) {\n // Set param\n setValue(field, value);\n }\n });\n };\n\n /**\n * Create the HTML for the field.\n *\n * @private\n */\n var createHtml = function () {\n return H5PEditor.createFieldMarkup(field, H5PEditor.createText(params, 15));\n };\n\n /**\n * Converts seconds to timecode.\n *\n * @private\n * @param {Number} seconds\n * @returns {String}\n */\n var toTimecode = function (seconds) {\n var time = \u0027\u0027;\n var minutes = Math.floor(seconds / 60);\n var hours = Math.floor(minutes / 60);\n\n minutes = minutes % 60;\n seconds = Math.floor(seconds % 60);\n\n if (hours !== 0) {\n time += hours + \u0027:\u0027;\n\n if (minutes \u003c 10) {\n // Leading zero\n time += \u00270\u0027;\n }\n }\n\n time += minutes + \u0027:\u0027;\n\n if (seconds \u003c 10) {\n // Leading zero\n time += \u00270\u0027;\n }\n\n time += seconds;\n\n return time;\n };\n\n\n /**\n * Converts seconds to timecode.\n *\n * @private\n * @param {Number} seconds\n * @returns {String}\n */\n var toSeconds = function (timecode) {\n // Split time format and check that we have between one and two colons.\n var values = timecode.split(\u0027:\u0027, 4);\n if (values.length !== 2 \u0026\u0026 values.length !== 3) {\n throw t(\u0027invalidTime\u0027, {\u0027:property\u0027: field.name});\n }\n\n // Validate seconds and add to value\n var allowedChars = new RegExp(\u0027^[0-9]+$\u0027);\n var j = values.length - 1;\n\n var seconds = parseInt(values[j]);\n if (!values[j].match(allowedChars) || values[j].length !== 2 || seconds \u003e 59) {\n throw t(\u0027invalidTime\u0027, {\u0027:property\u0027: field.name});\n }\n\n // Validate minutes\n j = j - 1;\n var minutes = parseInt(values[j]);\n if (!values[j].match(allowedChars) || (values[j - 1] !== undefined \u0026\u0026 values[j].length !== 2) || (values[j - 1] === undefined \u0026\u0026 values[j].length !== (minutes + \u0027\u0027).length) || minutes \u003e 59) {\n throw t(\u0027invalidTime\u0027, {\u0027:property\u0027: field.name});\n }\n // Convert to seconds and add to value\n seconds += minutes * 60;\n\n // Validate hours\n j = j - 1;\n if (values[j] !== undefined) {\n var hours = parseInt(values[j]);\n if (!values[j].match(allowedChars) || values[j].length !== (hours + \u0027\u0027).length || hours \u003c 1) {\n throw t(\u0027invalidTime\u0027, {\u0027:property\u0027: field.name});\n }\n // Convert to seconds and add to value\n seconds += hours * 3600;\n }\n\n return seconds;\n };\n\n /**\n * Append field to given wrapper.\n *\n * @public\n * @param {jquery} $wrapper\n */\n self.appendTo = function ($wrapper) {\n $item.appendTo($wrapper);\n };\n\n self.getDomElement = function () {\n return $item;\n };\n\n /**\n * Validate field.\n *\n * @return {*} valid value or false\n */\n self.validate = function () {\n // Retrieve timecode\n var value = H5P.trim($input.val());\n\n // Reset error messages\n $errors.html(\u0027\u0027);\n\n try {\n if (!value.length) {\n if (field.optional === true) {\n // Field is optional and does not have a value, nothing more to validate\n return;\n }\n\n // Field must have a value\n throw ct(\u0027requiredProperty\u0027, {\u0027:property\u0027: \u0027number field\u0027});\n }\n else {\n // Convert timecode to seconds\n value = toSeconds(value);\n\n // Check that field doesn\u0027t exceed its min and max values.\n if (field.max !== undefined \u0026\u0026 value \u003e field.max) {\n throw ct(\u0027exceedsMax\u0027, {\u0027:property\u0027: field.name, \u0027:max\u0027: toTimecode(field.max)});\n }\n else if (field.min !== undefined \u0026\u0026 value \u003c field.min) {\n throw ct(\u0027exceedsMin\u0027, {\u0027:property\u0027: field.name, \u0027:min\u0027: toTimecode(field.min)});\n }\n }\n }\n catch (error) {\n $errors.append(H5PEditor.createError(error));\n }\n\n return H5PEditor.checkErrors($errors, $input, value);\n };\n\n /**\n * Remove field.\n *\n * @public\n */\n self.remove = function () {\n $item.remove();\n };\n\n init();\n }\n\n /**\n * Retrieve local translation.\n *\n * @private\n * @param {String} key\n * @param {Object} [placeholders]\n * @returns {String}\n */\n var t = function (key, placeholders) {\n return H5PEditor.t(\u0027H5PEditor.Timecode\u0027, key, placeholders);\n };\n\n /**\n * Retrieve core translation.\n *\n * @private\n * @param {String} key\n * @param {Object} [placeholders]\n * @returns {String}\n */\n var ct = function (key, placeholders) {\n return H5PEditor.t(\u0027core\u0027, key, placeholders);\n };\n\n // Default english translations\n H5PEditor.language[\u0027H5PEditor.Timecode\u0027] = {\n libraryStrings: {\n invalidTime: \u0027\":property\" contains an invalid timecode.\u0027\n }\n };\n\n return Timecode;\n})(H5P.jQuery, H5PEditor.Number);\n"
,"select-toggle-fields.js":"H5PEditor.SelectToggleFields = (function ($) {\n\n if (Function.prototype.clone === undefined) {\n Function.prototype.clone = function() {\n var that = this;\n var temp = function temporary() {\n return that.apply(this, arguments);\n };\n for (var key in this) {\n temp[key] = this[key];\n }\n return temp;\n };\n }\n\n function SelectToggleFields(parent, field, params, setValue) {\n var self = this;\n\n // Set default value:\n params = params || \u0027\u0027;\n\n self.field = field;\n // Outsource readies\n self.passReadies = true;\n self.value = params;\n\n var fieldsToHide = [];\n var nameToFieldMap = {};\n\n parent.ready(function () {\n for (var i = 0; i \u003c field.options.length; i++) {\n var option = field.options[i];\n if (option.hideFields) {\n option.hideFields.forEach(function (path) {\n var f = H5PEditor.findField(path, parent);\n if (f.getDomElement !== undefined) {\n\n var $element = f.getDomElement();\n fieldsToHide.push($element);\n if (nameToFieldMap[option.value] === undefined) {\n nameToFieldMap[option.value] = [];\n }\n var originalValidate = f.validate.clone();\n nameToFieldMap[option.value].push($element);\n // Override validate function, so that we do not validate hidden\n // elements\n f.validate = function () {\n // if not hidden - let\u0027s validate\n return ($element.hasClass(\u0027h5peditor-select-toggle-field-hide\u0027) ? true : originalValidate());\n };\n }\n else {\n //throw\n console.error(\u0027Wrong usage - field need to implement getDomElement()\u0027);\n }\n });\n }\n }\n\n $selectWrapper.find(\u0027select\u0027).val(params);\n setValue(self.field, params);\n updateUI(params);\n });\n\n var $selectWrapper = $(\u0027\u003cdiv\u003e\u0027, {});\n\n var semantics = [\n {\n name: field.name,\n type: field.type,\n label: field.label,\n options: field.options,\n optional: field.optional,\n default: field.default\n }\n ];\n\n H5PEditor.processSemanticsChunk(semantics, params, $selectWrapper, self);\n\n var updateUI = function (value) {\n var fields = nameToFieldMap[value];\n\n if (fields) {\n // Unhide all fields:\n for (var i = 0; i \u003c fieldsToHide.length; i++) {\n fieldsToHide[i].removeClass(\u0027h5peditor-select-toggle-field-hide\u0027);\n }\n\n fields.forEach(function (f) {\n f.addClass(\u0027h5peditor-select-toggle-field-hide\u0027);\n });\n }\n else {\n // Hide all fields:\n for (var i = 0; i \u003c fieldsToHide.length; i++) {\n fieldsToHide[i].addClass(\u0027h5peditor-select-toggle-field-hide\u0027);\n }\n }\n };\n\n $selectWrapper.find(\u0027select\u0027).on(\u0027change\u0027, function () {\n self.value = $(this).val();\n setValue(self.field, self.value);\n updateUI(self.value);\n });\n\n /**\n *\n */\n self.appendTo = function ($wrapper) {\n $wrapper.append($selectWrapper);\n };\n\n /**\n * Always validate\n * @return {boolean}\n */\n self.validate = function () {\n return true;\n };\n\n self.remove = function () {};\n }\n\n return SelectToggleFields;\n})(H5PEditor.$);\n\n// Register widget\nH5PEditor.widgets.selectToggleFields = H5PEditor.SelectToggleFields;\n"
,"scripts/spectrum.js":"// Spectrum Colorpicker v1.8.0\n// https://github.com/bgrins/spectrum\n// Author: Brian Grinstead\n// License: MIT\n\n(function(jQuery) {\n\n(function (factory) {\n \"use strict\";\n\n if (typeof define === \u0027function\u0027 \u0026\u0026 define.amd) { // AMD\n define([\u0027jquery\u0027], factory);\n }\n else if (typeof exports == \"object\" \u0026\u0026 typeof module == \"object\") { // CommonJS\n module.exports = factory(require(\u0027jquery\u0027));\n }\n else { // Browser\n factory(jQuery);\n }\n})(function($, undefined) {\n \"use strict\";\n\n var defaultOpts = {\n\n // Callbacks\n beforeShow: noop,\n move: noop,\n change: noop,\n show: noop,\n hide: noop,\n\n // Options\n color: false,\n flat: false,\n showInput: false,\n allowEmpty: false,\n showButtons: true,\n clickoutFiresChange: true,\n showInitial: false,\n showPalette: false,\n showPaletteOnly: false,\n hideAfterPaletteSelect: false,\n togglePaletteOnly: false,\n showSelectionPalette: true,\n localStorageKey: false,\n appendTo: \"body .h5peditor-form\",\n maxSelectionSize: 7,\n cancelText: \"cancel\",\n chooseText: \"choose\",\n togglePaletteMoreText: \"more\",\n togglePaletteLessText: \"less\",\n clearText: \"Clear Color Selection\",\n noColorSelectedText: \"No Color Selected\",\n preferredFormat: false,\n className: \"\", // Deprecated - use containerClassName and replacerClassName instead.\n containerClassName: \"\",\n replacerClassName: \"\",\n showAlpha: false,\n theme: \"sp-light\",\n palette: [[\"#ffffff\", \"#000000\", \"#ff0000\", \"#ff8000\", \"#ffff00\", \"#008000\", \"#0000ff\", \"#4b0082\", \"#9400d3\"]],\n selectionPalette: [],\n disabled: false,\n offset: null\n },\n spectrums = [],\n IE = !!/msie/i.exec( window.navigator.userAgent ),\n rgbaSupport = (function() {\n function contains( str, substr ) {\n return !!~(\u0027\u0027 + str).indexOf(substr);\n }\n\n var elem = document.createElement(\u0027div\u0027);\n var style = elem.style;\n style.cssText = \u0027background-color:rgba(0,0,0,.5)\u0027;\n return contains(style.backgroundColor, \u0027rgba\u0027) || contains(style.backgroundColor, \u0027hsla\u0027);\n })(),\n replaceInput = [\n \"\u003cdiv class=\u0027sp-replacer\u0027\u003e\",\n \"\u003cdiv class=\u0027sp-preview\u0027\u003e\u003cdiv class=\u0027sp-preview-inner\u0027\u003e\u003c/div\u003e\u003c/div\u003e\",\n \"\u003cdiv class=\u0027sp-dd\u0027\u003e\u0026#9660;\u003c/div\u003e\",\n \"\u003c/div\u003e\"\n ].join(\u0027\u0027),\n markup = (function () {\n\n // IE does not support gradients with multiple stops, so we need to simulate\n // that for the rainbow slider with 8 divs that each have a single gradient\n var gradientFix = \"\";\n if (IE) {\n for (var i = 1; i \u003c= 6; i++) {\n gradientFix += \"\u003cdiv class=\u0027sp-\" + i + \"\u0027\u003e\u003c/div\u003e\";\n }\n }\n\n return [\n \"\u003cdiv class=\u0027sp-container sp-hidden\u0027\u003e\",\n \"\u003cdiv class=\u0027sp-palette-container\u0027\u003e\",\n \"\u003cdiv class=\u0027sp-palette sp-thumb sp-cf\u0027\u003e\u003c/div\u003e\",\n \"\u003cdiv class=\u0027sp-palette-button-container sp-cf\u0027\u003e\",\n \"\u003cbutton type=\u0027button\u0027 class=\u0027sp-palette-toggle\u0027\u003e\u003c/button\u003e\",\n \"\u003c/div\u003e\",\n \"\u003c/div\u003e\",\n \"\u003cdiv class=\u0027sp-picker-container\u0027\u003e\",\n \"\u003cdiv class=\u0027sp-top sp-cf\u0027\u003e\",\n \"\u003cdiv class=\u0027sp-fill\u0027\u003e\u003c/div\u003e\",\n \"\u003cdiv class=\u0027sp-top-inner\u0027\u003e\",\n \"\u003cdiv class=\u0027sp-color\u0027\u003e\",\n \"\u003cdiv class=\u0027sp-sat\u0027\u003e\",\n \"\u003cdiv class=\u0027sp-val\u0027\u003e\",\n \"\u003cdiv class=\u0027sp-dragger\u0027\u003e\u003c/div\u003e\",\n \"\u003c/div\u003e\",\n \"\u003c/div\u003e\",\n \"\u003c/div\u003e\",\n \"\u003cdiv class=\u0027sp-clear sp-clear-display\u0027\u003e\",\n \"\u003c/div\u003e\",\n \"\u003cdiv class=\u0027sp-hue\u0027\u003e\",\n \"\u003cdiv class=\u0027sp-slider\u0027\u003e\u003c/div\u003e\",\n gradientFix,\n \"\u003c/div\u003e\",\n \"\u003c/div\u003e\",\n \"\u003cdiv class=\u0027sp-alpha\u0027\u003e\u003cdiv class=\u0027sp-alpha-inner\u0027\u003e\u003cdiv class=\u0027sp-alpha-handle\u0027\u003e\u003c/div\u003e\u003c/div\u003e\u003c/div\u003e\",\n \"\u003c/div\u003e\",\n \"\u003cdiv class=\u0027sp-input-container sp-cf\u0027\u003e\",\n \"\u003cinput class=\u0027sp-input\u0027 type=\u0027text\u0027 spellcheck=\u0027false\u0027 /\u003e\",\n \"\u003c/div\u003e\",\n \"\u003cdiv class=\u0027sp-initial sp-thumb sp-cf\u0027\u003e\u003c/div\u003e\",\n \"\u003cdiv class=\u0027sp-button-container sp-cf\u0027\u003e\",\n \"\u003ca class=\u0027sp-cancel\u0027 href=\u0027#\u0027\u003e\u003c/a\u003e\",\n \"\u003cbutton type=\u0027button\u0027 class=\u0027sp-choose\u0027\u003e\u003c/button\u003e\",\n \"\u003c/div\u003e\",\n \"\u003c/div\u003e\",\n \"\u003c/div\u003e\"\n ].join(\"\");\n })();\n\n function paletteTemplate (p, color, className, opts) {\n var html = [];\n for (var i = 0; i \u003c p.length; i++) {\n var current = p[i];\n if(current) {\n var tiny = tinycolor(current);\n var c = tiny.toHsl().l \u003c 0.5 ? \"sp-thumb-el sp-thumb-dark\" : \"sp-thumb-el sp-thumb-light\";\n c += (tinycolor.equals(color, current)) ? \" sp-thumb-active\" : \"\";\n var formattedString = tiny.toString(opts.preferredFormat || \"rgb\");\n var swatchStyle = rgbaSupport ? (\"background-color:\" + tiny.toRgbString()) : \"filter:\" + tiny.toFilter();\n html.push(\u0027\u003cspan title=\"\u0027 + formattedString + \u0027\" data-color=\"\u0027 + tiny.toRgbString() + \u0027\" class=\"\u0027 + c + \u0027\"\u003e\u003cspan class=\"sp-thumb-inner\" style=\"\u0027 + swatchStyle + \u0027;\" /\u003e\u003c/span\u003e\u0027);\n } else {\n var cls = \u0027sp-clear-display\u0027;\n html.push($(\u0027\u003cdiv /\u003e\u0027)\n .append($(\u0027\u003cspan data-color=\"\" style=\"background-color:transparent;\" class=\"\u0027 + cls + \u0027\"\u003e\u003c/span\u003e\u0027)\n .attr(\u0027title\u0027, opts.noColorSelectedText)\n )\n .html()\n );\n }\n }\n return \"\u003cdiv class=\u0027sp-cf \" + className + \"\u0027\u003e\" + html.join(\u0027\u0027) + \"\u003c/div\u003e\";\n }\n\n function hideAll() {\n for (var i = 0; i \u003c spectrums.length; i++) {\n if (spectrums[i]) {\n spectrums[i].hide();\n }\n }\n }\n\n function instanceOptions(o, callbackContext) {\n var opts = $.extend({}, defaultOpts, o);\n opts.callbacks = {\n \u0027move\u0027: bind(opts.move, callbackContext),\n \u0027change\u0027: bind(opts.change, callbackContext),\n \u0027show\u0027: bind(opts.show, callbackContext),\n \u0027hide\u0027: bind(opts.hide, callbackContext),\n \u0027beforeShow\u0027: bind(opts.beforeShow, callbackContext)\n };\n\n return opts;\n }\n\n function spectrum(element, o) {\n\n var opts = instanceOptions(o, element),\n flat = opts.flat,\n showSelectionPalette = opts.showSelectionPalette,\n localStorageKey = opts.localStorageKey,\n theme = opts.theme,\n callbacks = opts.callbacks,\n resize = throttle(reflow, 10),\n visible = false,\n isDragging = false,\n dragWidth = 0,\n dragHeight = 0,\n dragHelperHeight = 0,\n slideHeight = 0,\n slideWidth = 0,\n alphaWidth = 0,\n alphaSlideHelperWidth = 0,\n slideHelperHeight = 0,\n currentHue = 0,\n currentSaturation = 0,\n currentValue = 0,\n currentAlpha = 1,\n palette = [],\n paletteArray = [],\n paletteLookup = {},\n selectionPalette = opts.selectionPalette.slice(0),\n maxSelectionSize = opts.maxSelectionSize,\n draggingClass = \"sp-dragging\",\n shiftMovementDirection = null;\n\n var doc = element.ownerDocument,\n body = doc.body,\n boundElement = $(element),\n disabled = false,\n container = $(markup, doc).addClass(theme),\n pickerContainer = container.find(\".sp-picker-container\"),\n dragger = container.find(\".sp-color\"),\n dragHelper = container.find(\".sp-dragger\"),\n slider = container.find(\".sp-hue\"),\n slideHelper = container.find(\".sp-slider\"),\n alphaSliderInner = container.find(\".sp-alpha-inner\"),\n alphaSlider = container.find(\".sp-alpha\"),\n alphaSlideHelper = container.find(\".sp-alpha-handle\"),\n textInput = container.find(\".sp-input\"),\n paletteContainer = container.find(\".sp-palette\"),\n initialColorContainer = container.find(\".sp-initial\"),\n cancelButton = container.find(\".sp-cancel\"),\n clearButton = container.find(\".sp-clear\"),\n chooseButton = container.find(\".sp-choose\"),\n toggleButton = container.find(\".sp-palette-toggle\"),\n isInput = boundElement.is(\"input\"),\n isInputTypeColor = isInput \u0026\u0026 boundElement.attr(\"type\") === \"color\" \u0026\u0026 inputTypeColorSupport(),\n shouldReplace = isInput \u0026\u0026 !flat,\n replacer = (shouldReplace) ? $(replaceInput).addClass(theme).addClass(opts.className).addClass(opts.replacerClassName) : $([]),\n offsetElement = (shouldReplace) ? replacer : boundElement,\n previewElement = replacer.find(\".sp-preview-inner\"),\n initialColor = opts.color || (isInput \u0026\u0026 boundElement.val()),\n colorOnShow = false,\n currentPreferredFormat = opts.preferredFormat,\n clickoutFiresChange = !opts.showButtons || opts.clickoutFiresChange,\n isEmpty = !initialColor,\n allowEmpty = opts.allowEmpty \u0026\u0026 !isInputTypeColor;\n\n function applyOptions() {\n\n if (opts.showPaletteOnly) {\n opts.showPalette = true;\n }\n\n toggleButton.text(opts.showPaletteOnly ? opts.togglePaletteMoreText : opts.togglePaletteLessText);\n\n if (opts.palette) {\n palette = opts.palette.slice(0);\n paletteArray = $.isArray(palette[0]) ? palette : [palette];\n paletteLookup = {};\n for (var i = 0; i \u003c paletteArray.length; i++) {\n for (var j = 0; j \u003c paletteArray[i].length; j++) {\n var rgb = tinycolor(paletteArray[i][j]).toRgbString();\n paletteLookup[rgb] = true;\n }\n }\n }\n\n container.toggleClass(\"sp-flat\", flat);\n container.toggleClass(\"sp-input-disabled\", !opts.showInput);\n container.toggleClass(\"sp-alpha-enabled\", opts.showAlpha);\n container.toggleClass(\"sp-clear-enabled\", allowEmpty);\n container.toggleClass(\"sp-buttons-disabled\", !opts.showButtons);\n container.toggleClass(\"sp-palette-buttons-disabled\", !opts.togglePaletteOnly);\n container.toggleClass(\"sp-palette-disabled\", !opts.showPalette);\n container.toggleClass(\"sp-palette-only\", opts.showPaletteOnly);\n container.toggleClass(\"sp-initial-disabled\", !opts.showInitial);\n container.addClass(opts.className).addClass(opts.containerClassName);\n\n reflow();\n }\n\n function initialize() {\n\n if (IE) {\n container.find(\"*:not(input)\").attr(\"unselectable\", \"on\");\n }\n\n applyOptions();\n\n if (shouldReplace) {\n boundElement.after(replacer).hide();\n }\n\n if (!allowEmpty) {\n clearButton.hide();\n }\n\n if (flat) {\n boundElement.after(container).hide();\n }\n else {\n\n var appendTo = opts.appendTo === \"parent\" ? boundElement.parent() : $(opts.appendTo);\n if (appendTo.length !== 1) {\n appendTo = $(\"body .h5peditor-form\");\n }\n\n appendTo.append(container);\n }\n\n updateSelectionPaletteFromStorage();\n\n offsetElement.bind(\"click.spectrum touchstart.spectrum\", function (e) {\n if (!disabled) {\n toggle();\n }\n\n e.stopPropagation();\n\n if (!$(e.target).is(\"input\")) {\n e.preventDefault();\n }\n });\n\n if(boundElement.is(\":disabled\") || (opts.disabled === true)) {\n disable();\n }\n\n // Prevent clicks from bubbling up to document. This would cause it to be hidden.\n container.click(stopPropagation);\n\n // Handle user typed input\n textInput.change(setFromTextInput);\n textInput.bind(\"paste\", function () {\n setTimeout(setFromTextInput, 1);\n });\n textInput.keydown(function (e) { if (e.keyCode == 13) { setFromTextInput(); } });\n\n cancelButton.text(opts.cancelText);\n cancelButton.bind(\"click.spectrum\", function (e) {\n e.stopPropagation();\n e.preventDefault();\n revert();\n hide();\n });\n\n clearButton.attr(\"title\", opts.clearText);\n clearButton.bind(\"click.spectrum\", function (e) {\n e.stopPropagation();\n e.preventDefault();\n isEmpty = true;\n move();\n\n if(flat) {\n //for the flat style, this is a change event\n updateOriginalInput(true);\n }\n });\n\n chooseButton.text(opts.chooseText);\n chooseButton.bind(\"click.spectrum\", function (e) {\n e.stopPropagation();\n e.preventDefault();\n\n if (IE \u0026\u0026 textInput.is(\":focus\")) {\n textInput.trigger(\u0027change\u0027);\n }\n\n if (isValid()) {\n updateOriginalInput(true);\n hide();\n }\n });\n\n toggleButton.text(opts.showPaletteOnly ? opts.togglePaletteMoreText : opts.togglePaletteLessText);\n toggleButton.bind(\"click.spectrum\", function (e) {\n e.stopPropagation();\n e.preventDefault();\n\n opts.showPaletteOnly = !opts.showPaletteOnly;\n\n // To make sure the Picker area is drawn on the right, next to the\n // Palette area (and not below the palette), first move the Palette\n // to the left to make space for the picker, plus 5px extra.\n // The \u0027applyOptions\u0027 function puts the whole container back into place\n // and takes care of the button-text and the sp-palette-only CSS class.\n if (!opts.showPaletteOnly \u0026\u0026 !flat) {\n container.css(\u0027left\u0027, \u0027-=\u0027 + (pickerContainer.outerWidth(true) + 5));\n }\n applyOptions();\n });\n\n draggable(alphaSlider, function (dragX, dragY, e) {\n currentAlpha = (dragX / alphaWidth);\n isEmpty = false;\n if (e.shiftKey) {\n currentAlpha = Math.round(currentAlpha * 10) / 10;\n }\n\n move();\n }, dragStart, dragStop);\n\n draggable(slider, function (dragX, dragY) {\n currentHue = parseFloat(dragY / slideHeight);\n isEmpty = false;\n if (!opts.showAlpha) {\n currentAlpha = 1;\n }\n move();\n }, dragStart, dragStop);\n\n draggable(dragger, function (dragX, dragY, e) {\n\n // shift+drag should snap the movement to either the x or y axis.\n if (!e.shiftKey) {\n shiftMovementDirection = null;\n }\n else if (!shiftMovementDirection) {\n var oldDragX = currentSaturation * dragWidth;\n var oldDragY = dragHeight - (currentValue * dragHeight);\n var furtherFromX = Math.abs(dragX - oldDragX) \u003e Math.abs(dragY - oldDragY);\n\n shiftMovementDirection = furtherFromX ? \"x\" : \"y\";\n }\n\n var setSaturation = !shiftMovementDirection || shiftMovementDirection === \"x\";\n var setValue = !shiftMovementDirection || shiftMovementDirection === \"y\";\n\n if (setSaturation) {\n currentSaturation = parseFloat(dragX / dragWidth);\n }\n if (setValue) {\n currentValue = parseFloat((dragHeight - dragY) / dragHeight);\n }\n\n isEmpty = false;\n if (!opts.showAlpha) {\n currentAlpha = 1;\n }\n\n move();\n\n }, dragStart, dragStop);\n\n if (!!initialColor) {\n set(initialColor);\n\n // In case color was black - update the preview UI and set the format\n // since the set function will not run (default color is black).\n updateUI();\n currentPreferredFormat = opts.preferredFormat || tinycolor(initialColor).format;\n\n addColorToSelectionPalette(initialColor);\n }\n else {\n updateUI();\n }\n\n if (flat) {\n show();\n }\n\n function paletteElementClick(e) {\n if (e.data \u0026\u0026 e.data.ignore) {\n set($(e.target).closest(\".sp-thumb-el\").data(\"color\"));\n move();\n }\n else {\n set($(e.target).closest(\".sp-thumb-el\").data(\"color\"));\n move();\n updateOriginalInput(true);\n if (opts.hideAfterPaletteSelect) {\n hide();\n }\n }\n\n return false;\n }\n\n var paletteEvent = IE ? \"mousedown.spectrum\" : \"click.spectrum touchstart.spectrum\";\n paletteContainer.delegate(\".sp-thumb-el\", paletteEvent, paletteElementClick);\n initialColorContainer.delegate(\".sp-thumb-el:nth-child(1)\", paletteEvent, { ignore: true }, paletteElementClick);\n }\n\n function updateSelectionPaletteFromStorage() {\n\n if (localStorageKey \u0026\u0026 window.localStorage) {\n\n // Migrate old palettes over to new format. May want to remove this eventually.\n try {\n var oldPalette = window.localStorage[localStorageKey].split(\",#\");\n if (oldPalette.length \u003e 1) {\n delete window.localStorage[localStorageKey];\n $.each(oldPalette, function(i, c) {\n addColorToSelectionPalette(c);\n });\n }\n }\n catch(e) { }\n\n try {\n selectionPalette = window.localStorage[localStorageKey].split(\";\");\n }\n catch (e) { }\n }\n }\n\n function addColorToSelectionPalette(color) {\n if (showSelectionPalette) {\n var rgb = tinycolor(color).toRgbString();\n if (!paletteLookup[rgb] \u0026\u0026 $.inArray(rgb, selectionPalette) === -1) {\n selectionPalette.push(rgb);\n while(selectionPalette.length \u003e maxSelectionSize) {\n selectionPalette.shift();\n }\n }\n\n if (localStorageKey \u0026\u0026 window.localStorage) {\n try {\n window.localStorage[localStorageKey] = selectionPalette.join(\";\");\n }\n catch(e) { }\n }\n }\n }\n\n function getUniqueSelectionPalette() {\n var unique = [];\n if (opts.showPalette) {\n for (var i = 0; i \u003c selectionPalette.length; i++) {\n var rgb = tinycolor(selectionPalette[i]).toRgbString();\n\n if (!paletteLookup[rgb]) {\n unique.push(selectionPalette[i]);\n }\n }\n }\n\n return unique.reverse().slice(0, opts.maxSelectionSize);\n }\n\n function drawPalette() {\n\n var currentColor = get();\n\n var html = $.map(paletteArray, function (palette, i) {\n return paletteTemplate(palette, currentColor, \"sp-palette-row sp-palette-row-\" + i, opts);\n });\n\n updateSelectionPaletteFromStorage();\n\n if (selectionPalette) {\n html.push(paletteTemplate(getUniqueSelectionPalette(), currentColor, \"sp-palette-row sp-palette-row-selection\", opts));\n }\n\n paletteContainer.html(html.join(\"\"));\n }\n\n function drawInitial() {\n if (opts.showInitial) {\n var initial = colorOnShow;\n var current = get();\n initialColorContainer.html(paletteTemplate([initial, current], current, \"sp-palette-row-initial\", opts));\n }\n }\n\n function dragStart() {\n if (dragHeight \u003c= 0 || dragWidth \u003c= 0 || slideHeight \u003c= 0) {\n reflow();\n }\n isDragging = true;\n container.addClass(draggingClass);\n shiftMovementDirection = null;\n boundElement.trigger(\u0027dragstart.spectrum\u0027, [ get() ]);\n }\n\n function dragStop() {\n isDragging = false;\n container.removeClass(draggingClass);\n boundElement.trigger(\u0027dragstop.spectrum\u0027, [ get() ]);\n }\n\n function setFromTextInput() {\n\n var value = textInput.val();\n\n if ((value === null || value === \"\") \u0026\u0026 allowEmpty) {\n set(null);\n updateOriginalInput(true);\n }\n else {\n var tiny = tinycolor(value);\n if (tiny.isValid()) {\n set(tiny);\n updateOriginalInput(true);\n }\n else {\n textInput.addClass(\"sp-validation-error\");\n }\n }\n }\n\n function toggle() {\n if (visible) {\n hide();\n }\n else {\n show();\n }\n }\n\n function show() {\n var event = $.Event(\u0027beforeShow.spectrum\u0027);\n\n if (visible) {\n reflow();\n return;\n }\n\n boundElement.trigger(event, [ get() ]);\n\n if (callbacks.beforeShow(get()) === false || event.isDefaultPrevented()) {\n return;\n }\n\n hideAll();\n visible = true;\n\n $(doc).bind(\"keydown.spectrum\", onkeydown);\n $(doc).bind(\"click.spectrum\", clickout);\n $(window).bind(\"resize.spectrum\", resize);\n replacer.addClass(\"sp-active\");\n container.removeClass(\"sp-hidden\");\n\n reflow();\n updateUI();\n\n colorOnShow = get();\n\n drawInitial();\n callbacks.show(colorOnShow);\n boundElement.trigger(\u0027show.spectrum\u0027, [ colorOnShow ]);\n }\n\n function onkeydown(e) {\n // Close on ESC\n if (e.keyCode === 27) {\n hide();\n }\n }\n\n function clickout(e) {\n // Return on right click.\n if (e.button == 2) { return; }\n\n // If a drag event was happening during the mouseup, don\u0027t hide\n // on click.\n if (isDragging) { return; }\n\n if (clickoutFiresChange) {\n updateOriginalInput(true);\n }\n else {\n revert();\n }\n hide();\n }\n\n function hide() {\n // Return if hiding is unnecessary\n if (!visible || flat) { return; }\n visible = false;\n\n $(doc).unbind(\"keydown.spectrum\", onkeydown);\n $(doc).unbind(\"click.spectrum\", clickout);\n $(window).unbind(\"resize.spectrum\", resize);\n\n replacer.removeClass(\"sp-active\");\n container.addClass(\"sp-hidden\");\n\n callbacks.hide(get());\n boundElement.trigger(\u0027hide.spectrum\u0027, [ get() ]);\n }\n\n function revert() {\n set(colorOnShow, true);\n }\n\n function set(color, ignoreFormatChange) {\n if (tinycolor.equals(color, get())) {\n // Update UI just in case a validation error needs\n // to be cleared.\n updateUI();\n return;\n }\n\n var newColor, newHsv;\n if (!color \u0026\u0026 allowEmpty) {\n isEmpty = true;\n } else {\n isEmpty = false;\n newColor = tinycolor(color);\n newHsv = newColor.toHsv();\n\n currentHue = (newHsv.h % 360) / 360;\n currentSaturation = newHsv.s;\n currentValue = newHsv.v;\n currentAlpha = newHsv.a;\n }\n updateUI();\n\n if (newColor \u0026\u0026 newColor.isValid() \u0026\u0026 !ignoreFormatChange) {\n currentPreferredFormat = opts.preferredFormat || newColor.getFormat();\n }\n }\n\n function get(opts) {\n opts = opts || { };\n\n if (allowEmpty \u0026\u0026 isEmpty) {\n return null;\n }\n\n return tinycolor.fromRatio({\n h: currentHue,\n s: currentSaturation,\n v: currentValue,\n a: Math.round(currentAlpha * 100) / 100\n }, { format: opts.format || currentPreferredFormat });\n }\n\n function isValid() {\n return !textInput.hasClass(\"sp-validation-error\");\n }\n\n function move() {\n updateUI();\n\n callbacks.move(get());\n boundElement.trigger(\u0027move.spectrum\u0027, [ get() ]);\n }\n\n function updateUI() {\n\n textInput.removeClass(\"sp-validation-error\");\n\n updateHelperLocations();\n\n // Update dragger background color (gradients take care of saturation and value).\n var flatColor = tinycolor.fromRatio({ h: currentHue, s: 1, v: 1 });\n dragger.css(\"background-color\", flatColor.toHexString());\n\n // Get a format that alpha will be included in (hex and names ignore alpha)\n var format = currentPreferredFormat;\n if (currentAlpha \u003c 1 \u0026\u0026 !(currentAlpha === 0 \u0026\u0026 format === \"name\")) {\n if (format === \"hex\" || format === \"hex3\" || format === \"hex6\" || format === \"name\") {\n format = \"rgb\";\n }\n }\n\n var realColor = get({ format: format }),\n displayColor = \u0027\u0027;\n\n //reset background info for preview element\n previewElement.removeClass(\"sp-clear-display\");\n previewElement.css(\u0027background-color\u0027, \u0027transparent\u0027);\n\n if (!realColor \u0026\u0026 allowEmpty) {\n // Update the replaced elements background with icon indicating no color selection\n previewElement.addClass(\"sp-clear-display\");\n }\n else {\n var realHex = realColor.toHexString(),\n realRgb = realColor.toRgbString();\n\n // Update the replaced elements background color (with actual selected color)\n if (rgbaSupport || realColor.alpha === 1) {\n previewElement.css(\"background-color\", realRgb);\n }\n else {\n previewElement.css(\"background-color\", \"transparent\");\n previewElement.css(\"filter\", realColor.toFilter());\n }\n\n if (opts.showAlpha) {\n var rgb = realColor.toRgb();\n rgb.a = 0;\n var realAlpha = tinycolor(rgb).toRgbString();\n var gradient = \"linear-gradient(left, \" + realAlpha + \", \" + realHex + \")\";\n\n if (IE) {\n alphaSliderInner.css(\"filter\", tinycolor(realAlpha).toFilter({ gradientType: 1 }, realHex));\n }\n else {\n alphaSliderInner.css(\"background\", \"-webkit-\" + gradient);\n alphaSliderInner.css(\"background\", \"-moz-\" + gradient);\n alphaSliderInner.css(\"background\", \"-ms-\" + gradient);\n // Use current syntax gradient on unprefixed property.\n alphaSliderInner.css(\"background\",\n \"linear-gradient(to right, \" + realAlpha + \", \" + realHex + \")\");\n }\n }\n\n displayColor = realColor.toString(format);\n }\n\n // Update the text entry input as it changes happen\n if (opts.showInput) {\n textInput.val(displayColor);\n }\n\n if (opts.showPalette) {\n drawPalette();\n }\n\n drawInitial();\n }\n\n function updateHelperLocations() {\n var s = currentSaturation;\n var v = currentValue;\n\n if(allowEmpty \u0026\u0026 isEmpty) {\n //if selected color is empty, hide the helpers\n alphaSlideHelper.hide();\n slideHelper.hide();\n dragHelper.hide();\n }\n else {\n //make sure helpers are visible\n alphaSlideHelper.show();\n slideHelper.show();\n dragHelper.show();\n\n // Where to show the little circle in that displays your current selected color\n var dragX = s * dragWidth;\n var dragY = dragHeight - (v * dragHeight);\n dragX = Math.max(\n -dragHelperHeight,\n Math.min(dragWidth - dragHelperHeight, dragX - dragHelperHeight)\n );\n dragY = Math.max(\n -dragHelperHeight,\n Math.min(dragHeight - dragHelperHeight, dragY - dragHelperHeight)\n );\n dragHelper.css({\n \"top\": dragY + \"px\",\n \"left\": dragX + \"px\"\n });\n\n var alphaX = currentAlpha * alphaWidth;\n alphaSlideHelper.css({\n \"left\": (alphaX - (alphaSlideHelperWidth / 2)) + \"px\"\n });\n\n // Where to show the bar that displays your current selected hue\n var slideY = (currentHue) * slideHeight;\n slideHelper.css({\n \"top\": (slideY - slideHelperHeight) + \"px\"\n });\n }\n }\n\n function updateOriginalInput(fireCallback) {\n var color = get(),\n displayColor = \u0027\u0027,\n hasChanged = !tinycolor.equals(color, colorOnShow);\n\n if (color) {\n displayColor = color.toString(currentPreferredFormat);\n // Update the selection palette with the current color\n addColorToSelectionPalette(color);\n }\n\n if (isInput) {\n boundElement.val(displayColor);\n }\n\n if (fireCallback \u0026\u0026 hasChanged) {\n callbacks.change(color);\n boundElement.trigger(\u0027change\u0027, [ color ]);\n }\n }\n\n function reflow() {\n if (!visible) {\n return; // Calculations would be useless and wouldn\u0027t be reliable anyways\n }\n dragWidth = dragger.width();\n dragHeight = dragger.height();\n dragHelperHeight = dragHelper.height();\n slideWidth = slider.width();\n slideHeight = slider.height();\n slideHelperHeight = slideHelper.height();\n alphaWidth = alphaSlider.width();\n alphaSlideHelperWidth = alphaSlideHelper.width();\n\n if (!flat) {\n container.css(\"position\", \"absolute\");\n if (opts.offset) {\n container.offset(opts.offset);\n } else {\n container.offset(getOffset(container, offsetElement));\n }\n }\n\n updateHelperLocations();\n\n if (opts.showPalette) {\n drawPalette();\n }\n\n boundElement.trigger(\u0027reflow.spectrum\u0027);\n }\n\n function destroy() {\n boundElement.show();\n offsetElement.unbind(\"click.spectrum touchstart.spectrum\");\n container.remove();\n replacer.remove();\n spectrums[spect.id] = null;\n }\n\n function option(optionName, optionValue) {\n if (optionName === undefined) {\n return $.extend({}, opts);\n }\n if (optionValue === undefined) {\n return opts[optionName];\n }\n\n opts[optionName] = optionValue;\n\n if (optionName === \"preferredFormat\") {\n currentPreferredFormat = opts.preferredFormat;\n }\n applyOptions();\n }\n\n function enable() {\n disabled = false;\n boundElement.attr(\"disabled\", false);\n offsetElement.removeClass(\"sp-disabled\");\n }\n\n function disable() {\n hide();\n disabled = true;\n boundElement.attr(\"disabled\", true);\n offsetElement.addClass(\"sp-disabled\");\n }\n\n function setOffset(coord) {\n opts.offset = coord;\n reflow();\n }\n\n initialize();\n\n var spect = {\n show: show,\n hide: hide,\n toggle: toggle,\n reflow: reflow,\n option: option,\n enable: enable,\n disable: disable,\n offset: setOffset,\n set: function (c) {\n set(c);\n updateOriginalInput();\n },\n get: get,\n destroy: destroy,\n container: container\n };\n\n spect.id = spectrums.push(spect) - 1;\n\n return spect;\n }\n\n /**\n * checkOffset - get the offset below/above and left/right element depending on screen position\n * Thanks https://github.com/jquery/jquery-ui/blob/master/ui/jquery.ui.datepicker.js\n */\n function getOffset(picker, input) {\n var extraY = 0;\n var dpWidth = picker.outerWidth();\n var dpHeight = picker.outerHeight();\n var inputHeight = input.outerHeight();\n var doc = picker[0].ownerDocument;\n var docElem = doc.documentElement;\n var viewWidth = docElem.clientWidth + $(doc).scrollLeft();\n var viewHeight = docElem.clientHeight + $(doc).scrollTop();\n var offset = input.offset();\n offset.top += inputHeight;\n\n offset.left -=\n Math.min(offset.left, (offset.left + dpWidth \u003e viewWidth \u0026\u0026 viewWidth \u003e dpWidth) ?\n Math.abs(offset.left + dpWidth - viewWidth) : 0);\n\n offset.top -=\n Math.min(offset.top, ((offset.top + dpHeight \u003e viewHeight \u0026\u0026 viewHeight \u003e dpHeight) ?\n Math.abs(dpHeight + inputHeight - extraY) : extraY));\n\n return offset;\n }\n\n /**\n * noop - do nothing\n */\n function noop() {\n\n }\n\n /**\n * stopPropagation - makes the code only doing this a little easier to read in line\n */\n function stopPropagation(e) {\n e.stopPropagation();\n }\n\n /**\n * Create a function bound to a given object\n * Thanks to underscore.js\n */\n function bind(func, obj) {\n var slice = Array.prototype.slice;\n var args = slice.call(arguments, 2);\n return function () {\n return func.apply(obj, args.concat(slice.call(arguments)));\n };\n }\n\n /**\n * Lightweight drag helper. Handles containment within the element, so that\n * when dragging, the x is within [0,element.width] and y is within [0,element.height]\n */\n function draggable(element, onmove, onstart, onstop) {\n onmove = onmove || function () { };\n onstart = onstart || function () { };\n onstop = onstop || function () { };\n var doc = document;\n var dragging = false;\n var offset = {};\n var maxHeight = 0;\n var maxWidth = 0;\n var hasTouch = (\u0027ontouchstart\u0027 in window);\n\n var duringDragEvents = {};\n duringDragEvents[\"selectstart\"] = prevent;\n duringDragEvents[\"dragstart\"] = prevent;\n duringDragEvents[\"touchmove mousemove\"] = move;\n duringDragEvents[\"touchend mouseup\"] = stop;\n\n function prevent(e) {\n if (e.stopPropagation) {\n e.stopPropagation();\n }\n if (e.preventDefault) {\n e.preventDefault();\n }\n e.returnValue = false;\n }\n\n function move(e) {\n if (dragging) {\n // Mouseup happened outside of window\n if (IE \u0026\u0026 doc.documentMode \u003c 9 \u0026\u0026 !e.button) {\n return stop();\n }\n\n var t0 = e.originalEvent \u0026\u0026 e.originalEvent.touches \u0026\u0026 e.originalEvent.touches[0];\n var pageX = t0 \u0026\u0026 t0.pageX || e.pageX;\n var pageY = t0 \u0026\u0026 t0.pageY || e.pageY;\n\n var dragX = Math.max(0, Math.min(pageX - offset.left, maxWidth));\n var dragY = Math.max(0, Math.min(pageY - offset.top, maxHeight));\n\n if (hasTouch) {\n // Stop scrolling in iOS\n prevent(e);\n }\n\n onmove.apply(element, [dragX, dragY, e]);\n }\n }\n\n function start(e) {\n var rightclick = (e.which) ? (e.which == 3) : (e.button == 2);\n\n if (!rightclick \u0026\u0026 !dragging) {\n if (onstart.apply(element, arguments) !== false) {\n dragging = true;\n maxHeight = $(element).height();\n maxWidth = $(element).width();\n offset = $(element).offset();\n\n $(doc).bind(duringDragEvents);\n $(doc.body).addClass(\"sp-dragging\");\n\n move(e);\n\n prevent(e);\n }\n }\n }\n\n function stop() {\n if (dragging) {\n $(doc).unbind(duringDragEvents);\n $(doc.body).removeClass(\"sp-dragging\");\n\n // Wait a tick before notifying observers to allow the click event\n // to fire in Chrome.\n setTimeout(function() {\n onstop.apply(element, arguments);\n }, 0);\n }\n dragging = false;\n }\n\n $(element).bind(\"touchstart mousedown\", start);\n }\n\n function throttle(func, wait, debounce) {\n var timeout;\n return function () {\n var context = this, args = arguments;\n var throttler = function () {\n timeout = null;\n func.apply(context, args);\n };\n if (debounce) clearTimeout(timeout);\n if (debounce || !timeout) timeout = setTimeout(throttler, wait);\n };\n }\n\n function inputTypeColorSupport() {\n return $.fn.spectrum.inputTypeColorSupport();\n }\n\n /**\n * Define a jQuery plugin\n */\n var dataID = \"spectrum.id\";\n $.fn.spectrum = function (opts, extra) {\n\n if (typeof opts == \"string\") {\n\n var returnValue = this;\n var args = Array.prototype.slice.call( arguments, 1 );\n\n this.each(function () {\n var spect = spectrums[$(this).data(dataID)];\n if (spect) {\n var method = spect[opts];\n if (!method) {\n throw new Error( \"Spectrum: no such method: \u0027\" + opts + \"\u0027\" );\n }\n\n if (opts == \"get\") {\n returnValue = spect.get();\n }\n else if (opts == \"container\") {\n returnValue = spect.container;\n }\n else if (opts == \"option\") {\n returnValue = spect.option.apply(spect, args);\n }\n else if (opts == \"destroy\") {\n spect.destroy();\n $(this).removeData(dataID);\n }\n else {\n method.apply(spect, args);\n }\n }\n });\n\n return returnValue;\n }\n\n // Initializing a new instance of spectrum\n return this.spectrum(\"destroy\").each(function () {\n var options = $.extend({}, opts, $(this).data());\n var spect = spectrum(this, options);\n $(this).data(dataID, spect.id);\n });\n };\n\n $.fn.spectrum.load = true;\n $.fn.spectrum.loadOpts = {};\n $.fn.spectrum.draggable = draggable;\n $.fn.spectrum.defaults = defaultOpts;\n $.fn.spectrum.inputTypeColorSupport = function inputTypeColorSupport() {\n if (typeof inputTypeColorSupport._cachedResult === \"undefined\") {\n var colorInput = $(\"\u003cinput type=\u0027color\u0027/\u003e\")[0]; // if color element is supported, value will default to not null\n inputTypeColorSupport._cachedResult = colorInput.type === \"color\" \u0026\u0026 colorInput.value !== \"\";\n }\n return inputTypeColorSupport._cachedResult;\n };\n\n $.spectrum = { };\n $.spectrum.localization = { };\n $.spectrum.palettes = { };\n\n $.fn.spectrum.processNativeColorInputs = function () {\n var colorInputs = $(\"input[type=color]\");\n if (colorInputs.length \u0026\u0026 !inputTypeColorSupport()) {\n colorInputs.spectrum({\n preferredFormat: \"hex6\"\n });\n }\n };\n\n // TinyColor v1.1.2\n // https://github.com/bgrins/TinyColor\n // Brian Grinstead, MIT License\n\n (function() {\n\n var trimLeft = /^[\\s,#]+/,\n trimRight = /\\s+$/,\n tinyCounter = 0,\n math = Math,\n mathRound = math.round,\n mathMin = math.min,\n mathMax = math.max,\n mathRandom = math.random;\n\n var tinycolor = function(color, opts) {\n\n color = (color) ? color : \u0027\u0027;\n opts = opts || { };\n\n // If input is already a tinycolor, return itself\n if (color instanceof tinycolor) {\n return color;\n }\n // If we are called as a function, call using new instead\n if (!(this instanceof tinycolor)) {\n return new tinycolor(color, opts);\n }\n\n var rgb = inputToRGB(color);\n this._originalInput = color,\n this._r = rgb.r,\n this._g = rgb.g,\n this._b = rgb.b,\n this._a = rgb.a,\n this._roundA = mathRound(100*this._a) / 100,\n this._format = opts.format || rgb.format;\n this._gradientType = opts.gradientType;\n\n // Don\u0027t let the range of [0,255] come back in [0,1].\n // Potentially lose a little bit of precision here, but will fix issues where\n // .5 gets interpreted as half of the total, instead of half of 1\n // If it was supposed to be 128, this was already taken care of by `inputToRgb`\n if (this._r \u003c 1) { this._r = mathRound(this._r); }\n if (this._g \u003c 1) { this._g = mathRound(this._g); }\n if (this._b \u003c 1) { this._b = mathRound(this._b); }\n\n this._ok = rgb.ok;\n this._tc_id = tinyCounter++;\n };\n\n tinycolor.prototype = {\n isDark: function() {\n return this.getBrightness() \u003c 128;\n },\n isLight: function() {\n return !this.isDark();\n },\n isValid: function() {\n return this._ok;\n },\n getOriginalInput: function() {\n return this._originalInput;\n },\n getFormat: function() {\n return this._format;\n },\n getAlpha: function() {\n return this._a;\n },\n getBrightness: function() {\n var rgb = this.toRgb();\n return (rgb.r * 299 + rgb.g * 587 + rgb.b * 114) / 1000;\n },\n setAlpha: function(value) {\n this._a = boundAlpha(value);\n this._roundA = mathRound(100*this._a) / 100;\n return this;\n },\n toHsv: function() {\n var hsv = rgbToHsv(this._r, this._g, this._b);\n return { h: hsv.h * 360, s: hsv.s, v: hsv.v, a: this._a };\n },\n toHsvString: function() {\n var hsv = rgbToHsv(this._r, this._g, this._b);\n var h = mathRound(hsv.h * 360), s = mathRound(hsv.s * 100), v = mathRound(hsv.v * 100);\n return (this._a == 1) ?\n \"hsv(\" + h + \", \" + s + \"%, \" + v + \"%)\" :\n \"hsva(\" + h + \", \" + s + \"%, \" + v + \"%, \"+ this._roundA + \")\";\n },\n toHsl: function() {\n var hsl = rgbToHsl(this._r, this._g, this._b);\n return { h: hsl.h * 360, s: hsl.s, l: hsl.l, a: this._a };\n },\n toHslString: function() {\n var hsl = rgbToHsl(this._r, this._g, this._b);\n var h = mathRound(hsl.h * 360), s = mathRound(hsl.s * 100), l = mathRound(hsl.l * 100);\n return (this._a == 1) ?\n \"hsl(\" + h + \", \" + s + \"%, \" + l + \"%)\" :\n \"hsla(\" + h + \", \" + s + \"%, \" + l + \"%, \"+ this._roundA + \")\";\n },\n toHex: function(allow3Char) {\n return rgbToHex(this._r, this._g, this._b, allow3Char);\n },\n toHexString: function(allow3Char) {\n return \u0027#\u0027 + this.toHex(allow3Char);\n },\n toHex8: function() {\n return rgbaToHex(this._r, this._g, this._b, this._a);\n },\n toHex8String: function() {\n return \u0027#\u0027 + this.toHex8();\n },\n toRgb: function() {\n return { r: mathRound(this._r), g: mathRound(this._g), b: mathRound(this._b), a: this._a };\n },\n toRgbString: function() {\n return (this._a == 1) ?\n \"rgb(\" + mathRound(this._r) + \", \" + mathRound(this._g) + \", \" + mathRound(this._b) + \")\" :\n \"rgba(\" + mathRound(this._r) + \", \" + mathRound(this._g) + \", \" + mathRound(this._b) + \", \" + this._roundA + \")\";\n },\n toPercentageRgb: function() {\n return { r: mathRound(bound01(this._r, 255) * 100) + \"%\", g: mathRound(bound01(this._g, 255) * 100) + \"%\", b: mathRound(bound01(this._b, 255) * 100) + \"%\", a: this._a };\n },\n toPercentageRgbString: function() {\n return (this._a == 1) ?\n \"rgb(\" + mathRound(bound01(this._r, 255) * 100) + \"%, \" + mathRound(bound01(this._g, 255) * 100) + \"%, \" + mathRound(bound01(this._b, 255) * 100) + \"%)\" :\n \"rgba(\" + mathRound(bound01(this._r, 255) * 100) + \"%, \" + mathRound(bound01(this._g, 255) * 100) + \"%, \" + mathRound(bound01(this._b, 255) * 100) + \"%, \" + this._roundA + \")\";\n },\n toName: function() {\n if (this._a === 0) {\n return \"transparent\";\n }\n\n if (this._a \u003c 1) {\n return false;\n }\n\n return hexNames[rgbToHex(this._r, this._g, this._b, true)] || false;\n },\n toFilter: function(secondColor) {\n var hex8String = \u0027#\u0027 + rgbaToHex(this._r, this._g, this._b, this._a);\n var secondHex8String = hex8String;\n var gradientType = this._gradientType ? \"GradientType = 1, \" : \"\";\n\n if (secondColor) {\n var s = tinycolor(secondColor);\n secondHex8String = s.toHex8String();\n }\n\n return \"progid:DXImageTransform.Microsoft.gradient(\"+gradientType+\"startColorstr=\"+hex8String+\",endColorstr=\"+secondHex8String+\")\";\n },\n toString: function(format) {\n var formatSet = !!format;\n format = format || this._format;\n\n var formattedString = false;\n var hasAlpha = this._a \u003c 1 \u0026\u0026 this._a \u003e= 0;\n var needsAlphaFormat = !formatSet \u0026\u0026 hasAlpha \u0026\u0026 (format === \"hex\" || format === \"hex6\" || format === \"hex3\" || format === \"name\");\n\n if (needsAlphaFormat) {\n // Special case for \"transparent\", all other non-alpha formats\n // will return rgba when there is transparency.\n if (format === \"name\" \u0026\u0026 this._a === 0) {\n return this.toName();\n }\n return this.toRgbString();\n }\n if (format === \"rgb\") {\n formattedString = this.toRgbString();\n }\n if (format === \"prgb\") {\n formattedString = this.toPercentageRgbString();\n }\n if (format === \"hex\" || format === \"hex6\") {\n formattedString = this.toHexString();\n }\n if (format === \"hex3\") {\n formattedString = this.toHexString(true);\n }\n if (format === \"hex8\") {\n formattedString = this.toHex8String();\n }\n if (format === \"name\") {\n formattedString = this.toName();\n }\n if (format === \"hsl\") {\n formattedString = this.toHslString();\n }\n if (format === \"hsv\") {\n formattedString = this.toHsvString();\n }\n\n return formattedString || this.toHexString();\n },\n\n _applyModification: function(fn, args) {\n var color = fn.apply(null, [this].concat([].slice.call(args)));\n this._r = color._r;\n this._g = color._g;\n this._b = color._b;\n this.setAlpha(color._a);\n return this;\n },\n lighten: function() {\n return this._applyModification(lighten, arguments);\n },\n brighten: function() {\n return this._applyModification(brighten, arguments);\n },\n darken: function() {\n return this._applyModification(darken, arguments);\n },\n desaturate: function() {\n return this._applyModification(desaturate, arguments);\n },\n saturate: function() {\n return this._applyModification(saturate, arguments);\n },\n greyscale: function() {\n return this._applyModification(greyscale, arguments);\n },\n spin: function() {\n return this._applyModification(spin, arguments);\n },\n\n _applyCombination: function(fn, args) {\n return fn.apply(null, [this].concat([].slice.call(args)));\n },\n analogous: function() {\n return this._applyCombination(analogous, arguments);\n },\n complement: function() {\n return this._applyCombination(complement, arguments);\n },\n monochromatic: function() {\n return this._applyCombination(monochromatic, arguments);\n },\n splitcomplement: function() {\n return this._applyCombination(splitcomplement, arguments);\n },\n triad: function() {\n return this._applyCombination(triad, arguments);\n },\n tetrad: function() {\n return this._applyCombination(tetrad, arguments);\n }\n };\n\n // If input is an object, force 1 into \"1.0\" to handle ratios properly\n // String input requires \"1.0\" as input, so 1 will be treated as 1\n tinycolor.fromRatio = function(color, opts) {\n if (typeof color == \"object\") {\n var newColor = {};\n for (var i in color) {\n if (color.hasOwnProperty(i)) {\n if (i === \"a\") {\n newColor[i] = color[i];\n }\n else {\n newColor[i] = convertToPercentage(color[i]);\n }\n }\n }\n color = newColor;\n }\n\n return tinycolor(color, opts);\n };\n\n // Given a string or object, convert that input to RGB\n // Possible string inputs:\n //\n // \"red\"\n // \"#f00\" or \"f00\"\n // \"#ff0000\" or \"ff0000\"\n // \"#ff000000\" or \"ff000000\"\n // \"rgb 255 0 0\" or \"rgb (255, 0, 0)\"\n // \"rgb 1.0 0 0\" or \"rgb (1, 0, 0)\"\n // \"rgba (255, 0, 0, 1)\" or \"rgba 255, 0, 0, 1\"\n // \"rgba (1.0, 0, 0, 1)\" or \"rgba 1.0, 0, 0, 1\"\n // \"hsl(0, 100%, 50%)\" or \"hsl 0 100% 50%\"\n // \"hsla(0, 100%, 50%, 1)\" or \"hsla 0 100% 50%, 1\"\n // \"hsv(0, 100%, 100%)\" or \"hsv 0 100% 100%\"\n //\n function inputToRGB(color) {\n\n var rgb = { r: 0, g: 0, b: 0 };\n var a = 1;\n var ok = false;\n var format = false;\n\n if (typeof color == \"string\") {\n color = stringInputToObject(color);\n }\n\n if (typeof color == \"object\") {\n if (color.hasOwnProperty(\"r\") \u0026\u0026 color.hasOwnProperty(\"g\") \u0026\u0026 color.hasOwnProperty(\"b\")) {\n rgb = rgbToRgb(color.r, color.g, color.b);\n ok = true;\n format = String(color.r).substr(-1) === \"%\" ? \"prgb\" : \"rgb\";\n }\n else if (color.hasOwnProperty(\"h\") \u0026\u0026 color.hasOwnProperty(\"s\") \u0026\u0026 color.hasOwnProperty(\"v\")) {\n color.s = convertToPercentage(color.s);\n color.v = convertToPercentage(color.v);\n rgb = hsvToRgb(color.h, color.s, color.v);\n ok = true;\n format = \"hsv\";\n }\n else if (color.hasOwnProperty(\"h\") \u0026\u0026 color.hasOwnProperty(\"s\") \u0026\u0026 color.hasOwnProperty(\"l\")) {\n color.s = convertToPercentage(color.s);\n color.l = convertToPercentage(color.l);\n rgb = hslToRgb(color.h, color.s, color.l);\n ok = true;\n format = \"hsl\";\n }\n\n if (color.hasOwnProperty(\"a\")) {\n a = color.a;\n }\n }\n\n a = boundAlpha(a);\n\n return {\n ok: ok,\n format: color.format || format,\n r: mathMin(255, mathMax(rgb.r, 0)),\n g: mathMin(255, mathMax(rgb.g, 0)),\n b: mathMin(255, mathMax(rgb.b, 0)),\n a: a\n };\n }\n\n\n // Conversion Functions\n // --------------------\n\n // `rgbToHsl`, `rgbToHsv`, `hslToRgb`, `hsvToRgb` modified from:\n // \u003chttp://mjijackson.com/2008/02/rgb-to-hsl-and-rgb-to-hsv-color-model-conversion-algorithms-in-javascript\u003e\n\n // `rgbToRgb`\n // Handle bounds / percentage checking to conform to CSS color spec\n // \u003chttp://www.w3.org/TR/css3-color/\u003e\n // *Assumes:* r, g, b in [0, 255] or [0, 1]\n // *Returns:* { r, g, b } in [0, 255]\n function rgbToRgb(r, g, b){\n return {\n r: bound01(r, 255) * 255,\n g: bound01(g, 255) * 255,\n b: bound01(b, 255) * 255\n };\n }\n\n // `rgbToHsl`\n // Converts an RGB color value to HSL.\n // *Assumes:* r, g, and b are contained in [0, 255] or [0, 1]\n // *Returns:* { h, s, l } in [0,1]\n function rgbToHsl(r, g, b) {\n\n r = bound01(r, 255);\n g = bound01(g, 255);\n b = bound01(b, 255);\n\n var max = mathMax(r, g, b), min = mathMin(r, g, b);\n var h, s, l = (max + min) / 2;\n\n if(max == min) {\n h = s = 0; // achromatic\n }\n else {\n var d = max - min;\n s = l \u003e 0.5 ? d / (2 - max - min) : d / (max + min);\n switch(max) {\n case r: h = (g - b) / d + (g \u003c b ? 6 : 0); break;\n case g: h = (b - r) / d + 2; break;\n case b: h = (r - g) / d + 4; break;\n }\n\n h /= 6;\n }\n\n return { h: h, s: s, l: l };\n }\n\n // `hslToRgb`\n // Converts an HSL color value to RGB.\n // *Assumes:* h is contained in [0, 1] or [0, 360] and s and l are contained [0, 1] or [0, 100]\n // *Returns:* { r, g, b } in the set [0, 255]\n function hslToRgb(h, s, l) {\n var r, g, b;\n\n h = bound01(h, 360);\n s = bound01(s, 100);\n l = bound01(l, 100);\n\n function hue2rgb(p, q, t) {\n if(t \u003c 0) t += 1;\n if(t \u003e 1) t -= 1;\n if(t \u003c 1/6) return p + (q - p) * 6 * t;\n if(t \u003c 1/2) return q;\n if(t \u003c 2/3) return p + (q - p) * (2/3 - t) * 6;\n return p;\n }\n\n if(s === 0) {\n r = g = b = l; // achromatic\n }\n else {\n var q = l \u003c 0.5 ? l * (1 + s) : l + s - l * s;\n var p = 2 * l - q;\n r = hue2rgb(p, q, h + 1/3);\n g = hue2rgb(p, q, h);\n b = hue2rgb(p, q, h - 1/3);\n }\n\n return { r: r * 255, g: g * 255, b: b * 255 };\n }\n\n // `rgbToHsv`\n // Converts an RGB color value to HSV\n // *Assumes:* r, g, and b are contained in the set [0, 255] or [0, 1]\n // *Returns:* { h, s, v } in [0,1]\n function rgbToHsv(r, g, b) {\n\n r = bound01(r, 255);\n g = bound01(g, 255);\n b = bound01(b, 255);\n\n var max = mathMax(r, g, b), min = mathMin(r, g, b);\n var h, s, v = max;\n\n var d = max - min;\n s = max === 0 ? 0 : d / max;\n\n if(max == min) {\n h = 0; // achromatic\n }\n else {\n switch(max) {\n case r: h = (g - b) / d + (g \u003c b ? 6 : 0); break;\n case g: h = (b - r) / d + 2; break;\n case b: h = (r - g) / d + 4; break;\n }\n h /= 6;\n }\n return { h: h, s: s, v: v };\n }\n\n // `hsvToRgb`\n // Converts an HSV color value to RGB.\n // *Assumes:* h is contained in [0, 1] or [0, 360] and s and v are contained in [0, 1] or [0, 100]\n // *Returns:* { r, g, b } in the set [0, 255]\n function hsvToRgb(h, s, v) {\n\n h = bound01(h, 360) * 6;\n s = bound01(s, 100);\n v = bound01(v, 100);\n\n var i = math.floor(h),\n f = h - i,\n p = v * (1 - s),\n q = v * (1 - f * s),\n t = v * (1 - (1 - f) * s),\n mod = i % 6,\n r = [v, q, p, p, t, v][mod],\n g = [t, v, v, q, p, p][mod],\n b = [p, p, t, v, v, q][mod];\n\n return { r: r * 255, g: g * 255, b: b * 255 };\n }\n\n // `rgbToHex`\n // Converts an RGB color to hex\n // Assumes r, g, and b are contained in the set [0, 255]\n // Returns a 3 or 6 character hex\n function rgbToHex(r, g, b, allow3Char) {\n\n var hex = [\n pad2(mathRound(r).toString(16)),\n pad2(mathRound(g).toString(16)),\n pad2(mathRound(b).toString(16))\n ];\n\n // Return a 3 character hex if possible\n if (allow3Char \u0026\u0026 hex[0].charAt(0) == hex[0].charAt(1) \u0026\u0026 hex[1].charAt(0) == hex[1].charAt(1) \u0026\u0026 hex[2].charAt(0) == hex[2].charAt(1)) {\n return hex[0].charAt(0) + hex[1].charAt(0) + hex[2].charAt(0);\n }\n\n return hex.join(\"\");\n }\n // `rgbaToHex`\n // Converts an RGBA color plus alpha transparency to hex\n // Assumes r, g, b and a are contained in the set [0, 255]\n // Returns an 8 character hex\n function rgbaToHex(r, g, b, a) {\n\n var hex = [\n pad2(convertDecimalToHex(a)),\n pad2(mathRound(r).toString(16)),\n pad2(mathRound(g).toString(16)),\n pad2(mathRound(b).toString(16))\n ];\n\n return hex.join(\"\");\n }\n\n // `equals`\n // Can be called with any tinycolor input\n tinycolor.equals = function (color1, color2) {\n if (!color1 || !color2) { return false; }\n return tinycolor(color1).toRgbString() == tinycolor(color2).toRgbString();\n };\n tinycolor.random = function() {\n return tinycolor.fromRatio({\n r: mathRandom(),\n g: mathRandom(),\n b: mathRandom()\n });\n };\n\n\n // Modification Functions\n // ----------------------\n // Thanks to less.js for some of the basics here\n // \u003chttps://github.com/cloudhead/less.js/blob/master/lib/less/functions.js\u003e\n\n function desaturate(color, amount) {\n amount = (amount === 0) ? 0 : (amount || 10);\n var hsl = tinycolor(color).toHsl();\n hsl.s -= amount / 100;\n hsl.s = clamp01(hsl.s);\n return tinycolor(hsl);\n }\n\n function saturate(color, amount) {\n amount = (amount === 0) ? 0 : (amount || 10);\n var hsl = tinycolor(color).toHsl();\n hsl.s += amount / 100;\n hsl.s = clamp01(hsl.s);\n return tinycolor(hsl);\n }\n\n function greyscale(color) {\n return tinycolor(color).desaturate(100);\n }\n\n function lighten (color, amount) {\n amount = (amount === 0) ? 0 : (amount || 10);\n var hsl = tinycolor(color).toHsl();\n hsl.l += amount / 100;\n hsl.l = clamp01(hsl.l);\n return tinycolor(hsl);\n }\n\n function brighten(color, amount) {\n amount = (amount === 0) ? 0 : (amount || 10);\n var rgb = tinycolor(color).toRgb();\n rgb.r = mathMax(0, mathMin(255, rgb.r - mathRound(255 * - (amount / 100))));\n rgb.g = mathMax(0, mathMin(255, rgb.g - mathRound(255 * - (amount / 100))));\n rgb.b = mathMax(0, mathMin(255, rgb.b - mathRound(255 * - (amount / 100))));\n return tinycolor(rgb);\n }\n\n function darken (color, amount) {\n amount = (amount === 0) ? 0 : (amount || 10);\n var hsl = tinycolor(color).toHsl();\n hsl.l -= amount / 100;\n hsl.l = clamp01(hsl.l);\n return tinycolor(hsl);\n }\n\n // Spin takes a positive or negative amount within [-360, 360] indicating the change of hue.\n // Values outside of this range will be wrapped into this range.\n function spin(color, amount) {\n var hsl = tinycolor(color).toHsl();\n var hue = (mathRound(hsl.h) + amount) % 360;\n hsl.h = hue \u003c 0 ? 360 + hue : hue;\n return tinycolor(hsl);\n }\n\n // Combination Functions\n // ---------------------\n // Thanks to jQuery xColor for some of the ideas behind these\n // \u003chttps://github.com/infusion/jQuery-xcolor/blob/master/jquery.xcolor.js\u003e\n\n function complement(color) {\n var hsl = tinycolor(color).toHsl();\n hsl.h = (hsl.h + 180) % 360;\n return tinycolor(hsl);\n }\n\n function triad(color) {\n var hsl = tinycolor(color).toHsl();\n var h = hsl.h;\n return [\n tinycolor(color),\n tinycolor({ h: (h + 120) % 360, s: hsl.s, l: hsl.l }),\n tinycolor({ h: (h + 240) % 360, s: hsl.s, l: hsl.l })\n ];\n }\n\n function tetrad(color) {\n var hsl = tinycolor(color).toHsl();\n var h = hsl.h;\n return [\n tinycolor(color),\n tinycolor({ h: (h + 90) % 360, s: hsl.s, l: hsl.l }),\n tinycolor({ h: (h + 180) % 360, s: hsl.s, l: hsl.l }),\n tinycolor({ h: (h + 270) % 360, s: hsl.s, l: hsl.l })\n ];\n }\n\n function splitcomplement(color) {\n var hsl = tinycolor(color).toHsl();\n var h = hsl.h;\n return [\n tinycolor(color),\n tinycolor({ h: (h + 72) % 360, s: hsl.s, l: hsl.l}),\n tinycolor({ h: (h + 216) % 360, s: hsl.s, l: hsl.l})\n ];\n }\n\n function analogous(color, results, slices) {\n results = results || 6;\n slices = slices || 30;\n\n var hsl = tinycolor(color).toHsl();\n var part = 360 / slices;\n var ret = [tinycolor(color)];\n\n for (hsl.h = ((hsl.h - (part * results \u003e\u003e 1)) + 720) % 360; --results; ) {\n hsl.h = (hsl.h + part) % 360;\n ret.push(tinycolor(hsl));\n }\n return ret;\n }\n\n function monochromatic(color, results) {\n results = results || 6;\n var hsv = tinycolor(color).toHsv();\n var h = hsv.h, s = hsv.s, v = hsv.v;\n var ret = [];\n var modification = 1 / results;\n\n while (results--) {\n ret.push(tinycolor({ h: h, s: s, v: v}));\n v = (v + modification) % 1;\n }\n\n return ret;\n }\n\n // Utility Functions\n // ---------------------\n\n tinycolor.mix = function(color1, color2, amount) {\n amount = (amount === 0) ? 0 : (amount || 50);\n\n var rgb1 = tinycolor(color1).toRgb();\n var rgb2 = tinycolor(color2).toRgb();\n\n var p = amount / 100;\n var w = p * 2 - 1;\n var a = rgb2.a - rgb1.a;\n\n var w1;\n\n if (w * a == -1) {\n w1 = w;\n } else {\n w1 = (w + a) / (1 + w * a);\n }\n\n w1 = (w1 + 1) / 2;\n\n var w2 = 1 - w1;\n\n var rgba = {\n r: rgb2.r * w1 + rgb1.r * w2,\n g: rgb2.g * w1 + rgb1.g * w2,\n b: rgb2.b * w1 + rgb1.b * w2,\n a: rgb2.a * p + rgb1.a * (1 - p)\n };\n\n return tinycolor(rgba);\n };\n\n\n // Readability Functions\n // ---------------------\n // \u003chttp://www.w3.org/TR/AERT#color-contrast\u003e\n\n // `readability`\n // Analyze the 2 colors and returns an object with the following properties:\n // `brightness`: difference in brightness between the two colors\n // `color`: difference in color/hue between the two colors\n tinycolor.readability = function(color1, color2) {\n var c1 = tinycolor(color1);\n var c2 = tinycolor(color2);\n var rgb1 = c1.toRgb();\n var rgb2 = c2.toRgb();\n var brightnessA = c1.getBrightness();\n var brightnessB = c2.getBrightness();\n var colorDiff = (\n Math.max(rgb1.r, rgb2.r) - Math.min(rgb1.r, rgb2.r) +\n Math.max(rgb1.g, rgb2.g) - Math.min(rgb1.g, rgb2.g) +\n Math.max(rgb1.b, rgb2.b) - Math.min(rgb1.b, rgb2.b)\n );\n\n return {\n brightness: Math.abs(brightnessA - brightnessB),\n color: colorDiff\n };\n };\n\n // `readable`\n // http://www.w3.org/TR/AERT#color-contrast\n // Ensure that foreground and background color combinations provide sufficient contrast.\n // *Example*\n // tinycolor.isReadable(\"#000\", \"#111\") =\u003e false\n tinycolor.isReadable = function(color1, color2) {\n var readability = tinycolor.readability(color1, color2);\n return readability.brightness \u003e 125 \u0026\u0026 readability.color \u003e 500;\n };\n\n // `mostReadable`\n // Given a base color and a list of possible foreground or background\n // colors for that base, returns the most readable color.\n // *Example*\n // tinycolor.mostReadable(\"#123\", [\"#fff\", \"#000\"]) =\u003e \"#000\"\n tinycolor.mostReadable = function(baseColor, colorList) {\n var bestColor = null;\n var bestScore = 0;\n var bestIsReadable = false;\n for (var i=0; i \u003c colorList.length; i++) {\n\n // We normalize both around the \"acceptable\" breaking point,\n // but rank brightness constrast higher than hue.\n\n var readability = tinycolor.readability(baseColor, colorList[i]);\n var readable = readability.brightness \u003e 125 \u0026\u0026 readability.color \u003e 500;\n var score = 3 * (readability.brightness / 125) + (readability.color / 500);\n\n if ((readable \u0026\u0026 ! bestIsReadable) ||\n (readable \u0026\u0026 bestIsReadable \u0026\u0026 score \u003e bestScore) ||\n ((! readable) \u0026\u0026 (! bestIsReadable) \u0026\u0026 score \u003e bestScore)) {\n bestIsReadable = readable;\n bestScore = score;\n bestColor = tinycolor(colorList[i]);\n }\n }\n return bestColor;\n };\n\n\n // Big List of Colors\n // ------------------\n // \u003chttp://www.w3.org/TR/css3-color/#svg-color\u003e\n var names = tinycolor.names = {\n aliceblue: \"f0f8ff\",\n antiquewhite: \"faebd7\",\n aqua: \"0ff\",\n aquamarine: \"7fffd4\",\n azure: \"f0ffff\",\n beige: \"f5f5dc\",\n bisque: \"ffe4c4\",\n black: \"000\",\n blanchedalmond: \"ffebcd\",\n blue: \"00f\",\n blueviolet: \"8a2be2\",\n brown: \"a52a2a\",\n burlywood: \"deb887\",\n burntsienna: \"ea7e5d\",\n cadetblue: \"5f9ea0\",\n chartreuse: \"7fff00\",\n chocolate: \"d2691e\",\n coral: \"ff7f50\",\n cornflowerblue: \"6495ed\",\n cornsilk: \"fff8dc\",\n crimson: \"dc143c\",\n cyan: \"0ff\",\n darkblue: \"00008b\",\n darkcyan: \"008b8b\",\n darkgoldenrod: \"b8860b\",\n darkgray: \"a9a9a9\",\n darkgreen: \"006400\",\n darkgrey: \"a9a9a9\",\n darkkhaki: \"bdb76b\",\n darkmagenta: \"8b008b\",\n darkolivegreen: \"556b2f\",\n darkorange: \"ff8c00\",\n darkorchid: \"9932cc\",\n darkred: \"8b0000\",\n darksalmon: \"e9967a\",\n darkseagreen: \"8fbc8f\",\n darkslateblue: \"483d8b\",\n darkslategray: \"2f4f4f\",\n darkslategrey: \"2f4f4f\",\n darkturquoise: \"00ced1\",\n darkviolet: \"9400d3\",\n deeppink: \"ff1493\",\n deepskyblue: \"00bfff\",\n dimgray: \"696969\",\n dimgrey: \"696969\",\n dodgerblue: \"1e90ff\",\n firebrick: \"b22222\",\n floralwhite: \"fffaf0\",\n forestgreen: \"228b22\",\n fuchsia: \"f0f\",\n gainsboro: \"dcdcdc\",\n ghostwhite: \"f8f8ff\",\n gold: \"ffd700\",\n goldenrod: \"daa520\",\n gray: \"808080\",\n green: \"008000\",\n greenyellow: \"adff2f\",\n grey: \"808080\",\n honeydew: \"f0fff0\",\n hotpink: \"ff69b4\",\n indianred: \"cd5c5c\",\n indigo: \"4b0082\",\n ivory: \"fffff0\",\n khaki: \"f0e68c\",\n lavender: \"e6e6fa\",\n lavenderblush: \"fff0f5\",\n lawngreen: \"7cfc00\",\n lemonchiffon: \"fffacd\",\n lightblue: \"add8e6\",\n lightcoral: \"f08080\",\n lightcyan: \"e0ffff\",\n lightgoldenrodyellow: \"fafad2\",\n lightgray: \"d3d3d3\",\n lightgreen: \"90ee90\",\n lightgrey: \"d3d3d3\",\n lightpink: \"ffb6c1\",\n lightsalmon: \"ffa07a\",\n lightseagreen: \"20b2aa\",\n lightskyblue: \"87cefa\",\n lightslategray: \"789\",\n lightslategrey: \"789\",\n lightsteelblue: \"b0c4de\",\n lightyellow: \"ffffe0\",\n lime: \"0f0\",\n limegreen: \"32cd32\",\n linen: \"faf0e6\",\n magenta: \"f0f\",\n maroon: \"800000\",\n mediumaquamarine: \"66cdaa\",\n mediumblue: \"0000cd\",\n mediumorchid: \"ba55d3\",\n mediumpurple: \"9370db\",\n mediumseagreen: \"3cb371\",\n mediumslateblue: \"7b68ee\",\n mediumspringgreen: \"00fa9a\",\n mediumturquoise: \"48d1cc\",\n mediumvioletred: \"c71585\",\n midnightblue: \"191970\",\n mintcream: \"f5fffa\",\n mistyrose: \"ffe4e1\",\n moccasin: \"ffe4b5\",\n navajowhite: \"ffdead\",\n navy: \"000080\",\n oldlace: \"fdf5e6\",\n olive: \"808000\",\n olivedrab: \"6b8e23\",\n orange: \"ffa500\",\n orangered: \"ff4500\",\n orchid: \"da70d6\",\n palegoldenrod: \"eee8aa\",\n palegreen: \"98fb98\",\n paleturquoise: \"afeeee\",\n palevioletred: \"db7093\",\n papayawhip: \"ffefd5\",\n peachpuff: \"ffdab9\",\n peru: \"cd853f\",\n pink: \"ffc0cb\",\n plum: \"dda0dd\",\n powderblue: \"b0e0e6\",\n purple: \"800080\",\n rebeccapurple: \"663399\",\n red: \"f00\",\n rosybrown: \"bc8f8f\",\n royalblue: \"4169e1\",\n saddlebrown: \"8b4513\",\n salmon: \"fa8072\",\n sandybrown: \"f4a460\",\n seagreen: \"2e8b57\",\n seashell: \"fff5ee\",\n sienna: \"a0522d\",\n silver: \"c0c0c0\",\n skyblue: \"87ceeb\",\n slateblue: \"6a5acd\",\n slategray: \"708090\",\n slategrey: \"708090\",\n snow: \"fffafa\",\n springgreen: \"00ff7f\",\n steelblue: \"4682b4\",\n tan: \"d2b48c\",\n teal: \"008080\",\n thistle: \"d8bfd8\",\n tomato: \"ff6347\",\n turquoise: \"40e0d0\",\n violet: \"ee82ee\",\n wheat: \"f5deb3\",\n white: \"fff\",\n whitesmoke: \"f5f5f5\",\n yellow: \"ff0\",\n yellowgreen: \"9acd32\"\n };\n\n // Make it easy to access colors via `hexNames[hex]`\n var hexNames = tinycolor.hexNames = flip(names);\n\n\n // Utilities\n // ---------\n\n // `{ \u0027name1\u0027: \u0027val1\u0027 }` becomes `{ \u0027val1\u0027: \u0027name1\u0027 }`\n function flip(o) {\n var flipped = { };\n for (var i in o) {\n if (o.hasOwnProperty(i)) {\n flipped[o[i]] = i;\n }\n }\n return flipped;\n }\n\n // Return a valid alpha value [0,1] with all invalid values being set to 1\n function boundAlpha(a) {\n a = parseFloat(a);\n\n if (isNaN(a) || a \u003c 0 || a \u003e 1) {\n a = 1;\n }\n\n return a;\n }\n\n // Take input from [0, n] and return it as [0, 1]\n function bound01(n, max) {\n if (isOnePointZero(n)) { n = \"100%\"; }\n\n var processPercent = isPercentage(n);\n n = mathMin(max, mathMax(0, parseFloat(n)));\n\n // Automatically convert percentage into number\n if (processPercent) {\n n = parseInt(n * max, 10) / 100;\n }\n\n // Handle floating point rounding errors\n if ((math.abs(n - max) \u003c 0.000001)) {\n return 1;\n }\n\n // Convert into [0, 1] range if it isn\u0027t already\n return (n % max) / parseFloat(max);\n }\n\n // Force a number between 0 and 1\n function clamp01(val) {\n return mathMin(1, mathMax(0, val));\n }\n\n // Parse a base-16 hex value into a base-10 integer\n function parseIntFromHex(val) {\n return parseInt(val, 16);\n }\n\n // Need to handle 1.0 as 100%, since once it is a number, there is no difference between it and 1\n // \u003chttp://stackoverflow.com/questions/7422072/javascript-how-to-detect-number-as-a-decimal-including-1-0\u003e\n function isOnePointZero(n) {\n return typeof n == \"string\" \u0026\u0026 n.indexOf(\u0027.\u0027) != -1 \u0026\u0026 parseFloat(n) === 1;\n }\n\n // Check to see if string passed in is a percentage\n function isPercentage(n) {\n return typeof n === \"string\" \u0026\u0026 n.indexOf(\u0027%\u0027) != -1;\n }\n\n // Force a hex value to have 2 characters\n function pad2(c) {\n return c.length == 1 ? \u00270\u0027 + c : \u0027\u0027 + c;\n }\n\n // Replace a decimal with it\u0027s percentage value\n function convertToPercentage(n) {\n if (n \u003c= 1) {\n n = (n * 100) + \"%\";\n }\n\n return n;\n }\n\n // Converts a decimal to a hex value\n function convertDecimalToHex(d) {\n return Math.round(parseFloat(d) * 255).toString(16);\n }\n // Converts a hex value to a decimal\n function convertHexToDecimal(h) {\n return (parseIntFromHex(h) / 255);\n }\n\n var matchers = (function() {\n\n // \u003chttp://www.w3.org/TR/css3-values/#integers\u003e\n var CSS_INTEGER = \"[-\\\\+]?\\\\d+%?\";\n\n // \u003chttp://www.w3.org/TR/css3-values/#number-value\u003e\n var CSS_NUMBER = \"[-\\\\+]?\\\\d*\\\\.\\\\d+%?\";\n\n // Allow positive/negative integer/number. Don\u0027t capture the either/or, just the entire outcome.\n var CSS_UNIT = \"(?:\" + CSS_NUMBER + \")|(?:\" + CSS_INTEGER + \")\";\n\n // Actual matching.\n // Parentheses and commas are optional, but not required.\n // Whitespace can take the place of commas or opening paren\n var PERMISSIVE_MATCH3 = \"[\\\\s|\\\\(]+(\" + CSS_UNIT + \")[,|\\\\s]+(\" + CSS_UNIT + \")[,|\\\\s]+(\" + CSS_UNIT + \")\\\\s*\\\\)?\";\n var PERMISSIVE_MATCH4 = \"[\\\\s|\\\\(]+(\" + CSS_UNIT + \")[,|\\\\s]+(\" + CSS_UNIT + \")[,|\\\\s]+(\" + CSS_UNIT + \")[,|\\\\s]+(\" + CSS_UNIT + \")\\\\s*\\\\)?\";\n\n return {\n rgb: new RegExp(\"rgb\" + PERMISSIVE_MATCH3),\n rgba: new RegExp(\"rgba\" + PERMISSIVE_MATCH4),\n hsl: new RegExp(\"hsl\" + PERMISSIVE_MATCH3),\n hsla: new RegExp(\"hsla\" + PERMISSIVE_MATCH4),\n hsv: new RegExp(\"hsv\" + PERMISSIVE_MATCH3),\n hsva: new RegExp(\"hsva\" + PERMISSIVE_MATCH4),\n hex3: /^([0-9a-fA-F]{1})([0-9a-fA-F]{1})([0-9a-fA-F]{1})$/,\n hex6: /^([0-9a-fA-F]{2})([0-9a-fA-F]{2})([0-9a-fA-F]{2})$/,\n hex8: /^([0-9a-fA-F]{2})([0-9a-fA-F]{2})([0-9a-fA-F]{2})([0-9a-fA-F]{2})$/\n };\n })();\n\n // `stringInputToObject`\n // Permissive string parsing. Take in a number of formats, and output an object\n // based on detected format. Returns `{ r, g, b }` or `{ h, s, l }` or `{ h, s, v}`\n function stringInputToObject(color) {\n\n color = color.replace(trimLeft,\u0027\u0027).replace(trimRight, \u0027\u0027).toLowerCase();\n var named = false;\n if (names[color]) {\n color = names[color];\n named = true;\n }\n else if (color == \u0027transparent\u0027) {\n return { r: 0, g: 0, b: 0, a: 0, format: \"name\" };\n }\n\n // Try to match string input using regular expressions.\n // Keep most of the number bounding out of this function - don\u0027t worry about [0,1] or [0,100] or [0,360]\n // Just return an object and let the conversion functions handle that.\n // This way the result will be the same whether the tinycolor is initialized with string or object.\n var match;\n if ((match = matchers.rgb.exec(color))) {\n return { r: match[1], g: match[2], b: match[3] };\n }\n if ((match = matchers.rgba.exec(color))) {\n return { r: match[1], g: match[2], b: match[3], a: match[4] };\n }\n if ((match = matchers.hsl.exec(color))) {\n return { h: match[1], s: match[2], l: match[3] };\n }\n if ((match = matchers.hsla.exec(color))) {\n return { h: match[1], s: match[2], l: match[3], a: match[4] };\n }\n if ((match = matchers.hsv.exec(color))) {\n return { h: match[1], s: match[2], v: match[3] };\n }\n if ((match = matchers.hsva.exec(color))) {\n return { h: match[1], s: match[2], v: match[3], a: match[4] };\n }\n if ((match = matchers.hex8.exec(color))) {\n return {\n a: convertHexToDecimal(match[1]),\n r: parseIntFromHex(match[2]),\n g: parseIntFromHex(match[3]),\n b: parseIntFromHex(match[4]),\n format: named ? \"name\" : \"hex8\"\n };\n }\n if ((match = matchers.hex6.exec(color))) {\n return {\n r: parseIntFromHex(match[1]),\n g: parseIntFromHex(match[2]),\n b: parseIntFromHex(match[3]),\n format: named ? \"name\" : \"hex\"\n };\n }\n if ((match = matchers.hex3.exec(color))) {\n return {\n r: parseIntFromHex(match[1] + \u0027\u0027 + match[1]),\n g: parseIntFromHex(match[2] + \u0027\u0027 + match[2]),\n b: parseIntFromHex(match[3] + \u0027\u0027 + match[3]),\n format: named ? \"name\" : \"hex\"\n };\n }\n\n return false;\n }\n\n window.tinycolor = tinycolor;\n })();\n\n $(function () {\n if ($.fn.spectrum.load) {\n $.fn.spectrum.processNativeColorInputs();\n }\n });\n\n});\n\n})(H5P.jQuery);\n"
,"scripts/color-selector.js":"/**\n * ColorSelector widget module\n *\n * @param {H5P.jQuery} $\n */\nH5PEditor.widgets.colorSelector = H5PEditor.ColorSelector = (function ($) {\n\n /**\n * Creates a color selector.\n *\n * @class H5PEditor.ColorSelector\n * @param {Object} parent\n * @param {Object} field\n * @param {Object} params\n * @param {function} setValue\n */\n function ColorSelector(parent, field, params, setValue) {\n this.parent = parent;\n this.field = field;\n this.params = params;\n this.setValue = setValue;\n }\n\n /**\n * Append the field to the wrapper.\n * @public\n * @param {H5P.jQuery} $wrapper\n */\n ColorSelector.prototype.appendTo = function ($wrapper) {\n var self = this;\n var html = H5PEditor.createFieldMarkup(this.field, \u0027\u003cinput type=\"text\" class=\"h5p-color-picker\"\u003e\u0027);\n self.$item = H5PEditor.$(html);\n self.$colorPicker = self.$item.find(\u0027.h5p-color-picker\u0027);\n\n self.config = {\n preferredFormat: \u0027hex\u0027,\n color: self.getColor(),\n change: function (color) {\n self.setColor(color);\n },\n hide: function (color) {\n // Need this to get color if cancel is clicked\n self.setColor(color);\n }\n };\n\n // Make it possible to set spectrum config\n if (self.field.spectrum !== undefined) {\n self.config = $.extend(self.config, self.field.spectrum);\n }\n\n // Create color picker widget\n self.$colorPicker.spectrum(self.config);\n\n self.$item.appendTo($wrapper);\n };\n\n /**\n * Return colorcode in \"css\" format\n *\n * @method colorToString\n * @param {Object} color\n * @return {String}\n */\n ColorSelector.prototype.colorToString = function (color) {\n switch (this.config.preferredFormat) {\n case \u0027rgb\u0027: return color.toRgbString();\n case \u0027hsv\u0027: return color.toHsvString();\n case \u0027hsl\u0027: return color.toHslString();\n default: return color.toHexString();\n }\n };\n\n /**\n * Hide color selector\n * @method hide\n */\n ColorSelector.prototype.hide = function () {\n this.$colorPicker.spectrum(\u0027hide\u0027);\n };\n /**\n * Save the color\n *\n * @param {Object} color The\n */\n ColorSelector.prototype.setColor = function (color) {\n // Save the value, allow null\n this.params = (color === null ? null : this.colorToString(color));\n this.setValue(this.field, this.params);\n };\n\n ColorSelector.prototype.getColor = function () {\n var isEmpty = (this.params === null || this.params === \"\");\n return isEmpty ? null : this.params;\n };\n\n /**\n * Validate the current values.\n */\n ColorSelector.prototype.validate = function () {\n this.hide();\n return (this.params.length !== 0);\n };\n\n ColorSelector.prototype.remove = function () {};\n\n return ColorSelector;\n})(H5P.jQuery);\n"
,"scripts/text-utilities.js":"var H5P = H5P || {};\n\n/**\n * H5P-Text Utilities\n *\n * Some functions that can be useful when dealing with texts in H5P.\n *\n * @param {H5P.jQuery} $\n */\nH5P.TextUtilities = function ($, EventDispatcher) {\n /**\n * Create Text Utilities.\n *\n * Might be needed later.\n *\n * @constructor\n */\n function TextUtilities() {\n }\n\n // Inheritance\n TextUtilities.prototype = Object.create(H5P.EventDispatcher.prototype);\n TextUtilities.prototype.constructor = TextUtilities;\n\n /** @constant {object} */\n TextUtilities.WORD_DELIMITER = /[\\s.?!,\\\u0027;]/g;\n\n /**\n * Check if a candidate string is considered isolated (in a larger string) by\n * checking the symbol before and after the candidate.\n *\n * @param {string} candidate - String to be looked for.\n * @param {string} text - (Larger) string that should contain candidate.\n * @param {object} params - Parameters.\n * @param {object} params.delimiter - Regular expression containing symbols used to isolate the candidate.\n * @return {boolean} True if string is isolated.\n */\n TextUtilities.isIsolated = function (candidate, text, params) {\n // Sanitization\n if (!candidate || !text) {\n return;\n }\n\n var delimiter = (!!params \u0026\u0026 !!params.delimiter) ? params.delimiter : TextUtilities.WORD_DELIMITER;\n\n var pos = text.indexOf(candidate);\n if (pos === -1) {\n return false;\n }\n\n var pred = (pos === 0 ? \u0027\u0027 : text[pos - 1].replace(delimiter, \u0027\u0027));\n var succ = (pos + candidate.length === text.length ? \u0027\u0027 : text[pos + candidate.length].replace(delimiter, \u0027\u0027));\n\n if (pred !== \u0027\u0027 || succ !== \u0027\u0027) {\n return false;\n }\n return true;\n };\n\n /**\n * Check whether two strings are considered to be similar.\n * The similarity is temporarily computed by word length and number of number of operations\n * required to change one word into the other (Damerau-Levenshtein). It\u0027s subject to\n * change, cmp. https://github.com/otacke/udacity-machine-learning-engineer/blob/master/submissions/capstone_proposals/h5p_fuzzy_blanks.md\n *\n * @param {String} string1 - String #1.\n * @param {String} string2 - String #2.\n * @param {object} params - Parameters.\n * @return {boolean} True, if strings are considered to be similar.\n */\n TextUtilities.areSimilar = function (string1, string2, params) {\n // Sanitization\n if (!string1 || typeof string1 !== \u0027string\u0027) {\n return;\n }\n if (!string2 || typeof string2 !== \u0027string\u0027) {\n return;\n }\n\n // Just temporariliy this unflexible. Will be configurable via params.\n var length = Math.min(string1.length, string2.length);\n var levenshtein = H5P.TextUtilities.computeLevenshteinDistance(string1, string2, true);\n if (levenshtein === 0) {\n return true;\n }\n if ((length \u003e 9) \u0026\u0026 (levenshtein \u003c= 2)) {\n return true;\n }\n if ((length \u003e 3) \u0026\u0026 (levenshtein \u003c= 1)) {\n return true;\n }\n return false;\n };\n\n\n\n /**\n * Compute the (Damerau-)Levenshtein distance for two strings.\n *\n * The (Damerau-)Levenshtein distance that is returned is equivalent to the\n * number of operations that are necessary to transform one string into the\n * other. Consequently, lower numbers indicate higher similarity between the\n * two strings.\n *\n * While the Levenshtein distance counts deletions, insertions and mismatches,\n * the Damerau-Levenshtein distance also counts swapping two characters as\n * only one operation (instead of two mismatches), because this seems to\n * happen quite often.\n *\n * See http://en.wikipedia.org/wiki/Damerau%E2%80%93Levenshtein_distance for details\n *\n * @public\n * @param {string} str1 - String no. 1.\n * @param {string} str2 - String no. 2.\n * @param {boolean} [countSwapping=false] - If true, swapping chars will count as operation.\n * @returns {number} Distance.\n */\n TextUtilities.computeLevenshteinDistance = function(str1, str2, countSwapping) {\n // sanity checks\n if (typeof str1 !== \u0027string\u0027 || typeof str2 !== \u0027string\u0027) {\n return undefined;\n }\n if (countSwapping \u0026\u0026 typeof countSwapping !== \u0027boolean\u0027) {\n countSwapping = false;\n }\n\n // degenerate cases\n if (str1 === str2) {\n return 0;\n }\n if (str1.length === 0) {\n return str2.length;\n }\n if (str2.length === 0) {\n return str1.length;\n }\n\n // counter variables\n var i, j;\n\n // indicates characters that don\u0027t match\n var cost;\n\n // matrix for storing distances\n var distance = [];\n\n // initialization\n for (i = 0; i \u003c= str1.length; i++) {\n distance[i] = [i];\n }\n for (j = 0; j \u003c= str2.length; j++) {\n distance[0][j] = j;\n }\n\n // computation\n for (i = 1; i \u003c= str1.length; i++) {\n for (j = 1; j \u003c= str2.length; j++) {\n cost = (str1[i-1] === str2[j-1]) ? 0 : 1;\n distance[i][j] = Math.min(\n distance[i-1][j] + 1, // deletion\n distance[i][j-1] + 1, // insertion\n distance[i-1][j-1] + cost // mismatch\n );\n // in Damerau-Levenshtein distance, transpositions are operations\n if (countSwapping) {\n if (i \u003e 1 \u0026\u0026 j \u003e 1 \u0026\u0026 str1[i-1] === str2[j-2] \u0026\u0026 str1[i-2] === str2[j-1]) {\n distance[i][j] = Math.min(distance[i][j], distance[i-2][j-2] + cost);\n }\n }\n }\n }\n return distance[str1.length][str2.length];\n };\n\n /**\n * Compute the Jaro(-Winkler) distance for two strings.\n *\n * The Jaro(-Winkler) distance will return a value between 0 and 1 indicating\n * the similarity of two strings. The higher the value, the more similar the\n * strings are.\n *\n * See https://en.wikipedia.org/wiki/Jaro%E2%80%93Winkler_distance for details\n *\n * It seems that a more generalized implementation of Winkler\u0027s modification\n * can improve the results. This might be implemented later.\n * http://disi.unitn.it/~p2p/RelatedWork/Matching/Hermans_bnaic-2012.pdf\n *\n * @public\n * @param {string} str1 - String no. 1.\n * @param {string} str2 - String no. 2.\n * @param {boolean} [favorSameStart=false] - If true, strings with same start get higher distance value.\n * @param {boolean} [longTolerance=false] - If true, Winkler\u0027s tolerance for long words will be used.\n * @returns {number} Distance.\n */\n TextUtilities.computeJaroDistance = function(str1, str2, favorSameStart, longTolerance) {\n // sanity checks\n if (typeof str1 !== \u0027string\u0027 || typeof str2 !== \u0027string\u0027) {\n return undefined;\n }\n if (favorSameStart \u0026\u0026 typeof favorSameStart !== \u0027boolean\u0027) {\n favorSameStart = false;\n }\n if (longTolerance \u0026\u0026 typeof longTolerance !== \u0027boolean\u0027) {\n longTolerance = false;\n }\n\n // degenerate cases\n if (str1.length === 0 || str2.length === 0) {\n return 0;\n }\n if (str1 === str2) {\n return 1;\n }\n\n // counter variables\n var i, j, k;\n\n // number of matches between both strings\n var matches = 0;\n\n // number of transpositions between both strings\n var transpositions = 0;\n\n // The Jaro-Winkler distance\n var distance = 0;\n\n // length of common prefix up to 4 chars\n var l = 0;\n\n // scaling factor, should not exceed 0.25 (Winkler default = 0.1)\n var p = 0.1;\n\n // will be used often\n var str1Len = str1.length;\n var str2Len = str2.length;\n\n // determines the distance that still counts as a match\n var matchWindow = Math.floor(Math.max(str1Len, str2Len) / 2)- 1;\n\n // will store matches\n var str1Flags = new Array(str1Len);\n var str2Flags = new Array(str2Len);\n\n // count matches\n for (i = 0; i \u003c str1Len; i++) {\n var start = (i \u003e= matchWindow) ? i - matchWindow : 0;\n var end = (i + matchWindow \u003c= (str2Len - 1)) ? (i + matchWindow) : (str2Len - 1);\n\n for (j = start; j \u003c= end; j++) {\n if (str1Flags[i] !== true \u0026\u0026 str2Flags[j] !== true \u0026\u0026 str1[i] === str2[j]) {\n str1Flags[i] = str2Flags[j] = true;\n matches += 1;\n break;\n }\n }\n }\n if (matches === 0) {\n return 0;\n }\n\n // count transpositions\n k = 0;\n for (i = 0; i \u003c str1Len; i++) {\n if (!str1Flags[i]) {\n continue;\n }\n while (!str2Flags[k]) {\n k += 1;\n }\n if (str1[i] !== str2[k]) {\n transpositions += 1;\n }\n k += 1;\n }\n transpositions = transpositions / 2;\n\n // compute Jaro distance\n distance = (matches/str1Len + matches/str2Len + (matches - transpositions) / matches) / 3;\n\n // modification used by Winkler\n if (favorSameStart) {\n if (distance \u003e 0.7 \u0026\u0026 str1Len \u003e 3 \u0026\u0026 str2Len \u003e 3) {\n while (str1[l] === str2[l] \u0026\u0026 l \u003c 4) {\n l += 1;\n }\n distance = distance + l * p * (1 - distance);\n\n // modification for long words\n if (longTolerance) {\n if (Math.max(str1Len, str2Len) \u003e 4 \u0026\u0026 matches \u003e l + 1 \u0026\u0026 2 * matches \u003e= Math.max(str1Len, str2Len) + l) {\n distance += ((1.0 - distance) * ((matches - l - 1) / (str1Len + str2Len - 2 * l + 2)));\n }\n }\n }\n }\n\n return distance;\n };\n\n\n /**\n * Check whether a text contains a string, but fuzzy.\n *\n * This function is naive. It moves a window of needle\u0027s length (+2)\n * over the haystack\u0027s text and each move compares for similarity using\n * a given string metric. This will be slow for long texts!!!\n *\n * TODO: You might want to look into the bitap algorithm or experiment\n * with regexps\n *\n * @param {String} needle - String to look for.\n * @param {String} haystack - Text to look in.\n * @param {object} params - Parameters.\n */\n TextUtilities.fuzzyContains = function (needle, haystack, params) {\n // Sanitization\n if (!needle || typeof needle !== \u0027string\u0027) {\n return false;\n }\n if (!haystack || typeof haystack !== \u0027string\u0027) {\n return false;\n }\n\n var found = false;\n for (var i = 0; i \u003c haystack.length - needle.length + 1; i++) {\n var h0 = haystack.substr(i, needle.length);\n var h1 = haystack.substr(i, needle.length + 1);\n var h2 = haystack.substr(i, needle.length + 2);\n\n // Checking isIsolated will e.g. prevent finding beginnings of words\n if (\n TextUtilities.isIsolated(h0, haystack) \u0026\u0026 TextUtilities.areSimilar(h0, needle) ||\n TextUtilities.isIsolated(h1, haystack) \u0026\u0026 TextUtilities.areSimilar(h1, needle) ||\n TextUtilities.isIsolated(h2, haystack) \u0026\u0026 TextUtilities.areSimilar(h2, needle)\n ) {\n found = true;\n break;\n }\n }\n return found;\n };\n\n return TextUtilities;\n}(H5P.jQuery, H5P.EventDispatcher);\n"
,"js/blanks.js":"/*global H5P*/\nH5P.Blanks = (function ($, Question) {\n /**\n * @constant\n * @default\n */\n var STATE_ONGOING = \u0027ongoing\u0027;\n var STATE_CHECKING = \u0027checking\u0027;\n var STATE_SHOWING_SOLUTION = \u0027showing-solution\u0027;\n var STATE_FINISHED = \u0027finished\u0027;\n\n /**\n * @typedef {Object} Params\n * Parameters/configuration object for Blanks\n *\n * @property {Object} Params.behaviour\n * @property {string} Params.behaviour.confirmRetryDialog\n * @property {string} Params.behaviour.confirmCheckDialog\n *\n * @property {Object} Params.confirmRetry\n * @property {string} Params.confirmRetry.header\n * @property {string} Params.confirmRetry.body\n * @property {string} Params.confirmRetry.cancelLabel\n * @property {string} Params.confirmRetry.confirmLabel\n *\n * @property {Object} Params.confirmCheck\n * @property {string} Params.confirmCheck.header\n * @property {string} Params.confirmCheck.body\n * @property {string} Params.confirmCheck.cancelLabel\n * @property {string} Params.confirmCheck.confirmLabel\n */\n\n /**\n * Initialize module.\n *\n * @class H5P.Blanks\n * @extends H5P.Question\n * @param {Params} params\n * @param {number} id Content identification\n * @param {Object} contentData Task specific content data\n */\n function Blanks(params, id, contentData) {\n var self = this;\n\n // Inheritance\n Question.call(self, \u0027blanks\u0027);\n\n // IDs\n this.contentId = id;\n\n this.params = $.extend(true, {}, {\n text: \"Fill in\",\n questions: [\n \"Oslo is the capital of *Norway*.\"\n ],\n overallFeedback: [],\n userAnswers: [], // TODO This isn\u0027t in semantics?\n showSolutions: \"Show solution\",\n tryAgain: \"Try again\",\n checkAnswer: \"Check\",\n changeAnswer: \"Change answer\",\n notFilledOut: \"Please fill in all blanks to view solution\",\n answerIsCorrect: \"\u0027:ans\u0027 is correct\",\n answerIsWrong: \"\u0027:ans\u0027 is wrong\",\n answeredCorrectly: \"Answered correctly\",\n answeredIncorrectly: \"Answered incorrectly\",\n solutionLabel: \"Correct answer:\",\n inputLabel: \"Blank input @num of @total\",\n inputHasTipLabel: \"Tip available\",\n tipLabel: \"Tip\",\n scoreBarLabel: \u0027You got :num out of :total points\u0027,\n behaviour: {\n enableRetry: true,\n enableSolutionsButton: true,\n caseSensitive: true,\n showSolutionsRequiresInput: true,\n autoCheck: false,\n separateLines: false,\n disableImageZooming: false\n }\n }, params);\n\n // Delete empty questions\n for (var i = this.params.questions.length - 1; i \u003e= 0; i--) {\n if (!this.params.questions[i]) {\n this.params.questions.splice(i, 1);\n }\n }\n\n // Previous state\n this.contentData = contentData;\n if (this.contentData !== undefined \u0026\u0026 this.contentData.previousState !== undefined) {\n this.previousState = this.contentData.previousState;\n }\n\n // Clozes\n this.clozes = [];\n\n // Keep track tabbing forward or backwards\n this.shiftPressed = false;\n\n H5P.$body.keydown(function (event) {\n if (event.keyCode === 16) {\n self.shiftPressed = true;\n }\n }).keyup(function (event) {\n if (event.keyCode === 16) {\n self.shiftPressed = false;\n }\n });\n }\n\n // Inheritance\n Blanks.prototype = Object.create(Question.prototype);\n Blanks.prototype.constructor = Blanks;\n\n /**\n * Registers this question type\u0027s DOM elements before they are attached.\n * Called from H5P.Question.\n */\n Blanks.prototype.registerDomElements = function () {\n var self = this;\n\n // Check for task media\n var media = self.params.media;\n if (media \u0026\u0026 media.library) {\n var type = media.library.split(\u0027 \u0027)[0];\n if (type === \u0027H5P.Image\u0027) {\n if (media.params.file) {\n // Register task image\n self.setImage(media.params.file.path, {\n disableImageZooming: self.params.behaviour.disableImageZooming,\n alt: media.params.alt\n });\n }\n }\n else if (type === \u0027H5P.Video\u0027) {\n if (media.params.sources) {\n // Register task video\n self.setVideo(media);\n }\n }\n }\n\n // Register task introduction text\n self.setIntroduction(self.params.text);\n\n // Register task content area\n self.setContent(self.createQuestions(), {\n \u0027class\u0027: self.params.behaviour.separateLines ? \u0027h5p-separate-lines\u0027 : \u0027\u0027\n });\n\n // ... and buttons\n self.registerButtons();\n\n // Restore previous state\n self.setH5PUserState();\n };\n\n /**\n * Create all the buttons for the task\n */\n Blanks.prototype.registerButtons = function () {\n var self = this;\n\n var $content = $(\u0027[data-content-id=\"\u0027 + self.contentId + \u0027\"].h5p-content\u0027);\n var $containerParents = $content.parents(\u0027.h5p-container\u0027);\n\n // select find container to attach dialogs to\n var $container;\n if($containerParents.length !== 0) {\n // use parent highest up if any\n $container = $containerParents.last();\n }\n else if($content.length !== 0){\n $container = $content;\n }\n else {\n $container = $(document.body);\n }\n\n if (!self.params.behaviour.autoCheck) {\n // Check answer button\n self.addButton(\u0027check-answer\u0027, self.params.checkAnswer, function () {\n self.toggleButtonVisibility(STATE_CHECKING);\n self.markResults();\n self.showEvaluation();\n self.triggerAnswered();\n }, true, {}, {\n confirmationDialog: {\n enable: self.params.behaviour.confirmCheckDialog,\n l10n: self.params.confirmCheck,\n instance: self,\n $parentElement: $container\n }\n });\n }\n\n // Show solution button\n self.addButton(\u0027show-solution\u0027, self.params.showSolutions, function () {\n self.showCorrectAnswers(false);\n }, self.params.behaviour.enableSolutionsButton);\n\n // Try again button\n if (self.params.behaviour.enableRetry === true) {\n self.addButton(\u0027try-again\u0027, self.params.tryAgain, function () {\n self.resetTask();\n self.$questions.filter(\u0027:first\u0027).find(\u0027input:first\u0027).focus();\n }, true, {}, {\n confirmationDialog: {\n enable: self.params.behaviour.confirmRetryDialog,\n l10n: self.params.confirmRetry,\n instance: self,\n $parentElement: $container\n }\n });\n }\n self.toggleButtonVisibility(STATE_ONGOING);\n };\n\n /**\n * Find blanks in a string and run a handler on those blanks\n *\n * @param {string} question\n * Question text containing blanks enclosed in asterisks.\n * @param {function} handler\n * Replaces the blanks text with an input field.\n * @returns {string}\n * The question with blanks replaced by the given handler.\n */\n Blanks.prototype.handleBlanks = function (question, handler) {\n // Go through the text and run handler on all asterisk\n var clozeEnd, clozeStart = question.indexOf(\u0027*\u0027);\n var self = this;\n while (clozeStart !== -1 \u0026\u0026 clozeEnd !== -1) {\n clozeStart++;\n clozeEnd = question.indexOf(\u0027*\u0027, clozeStart);\n if (clozeEnd === -1) {\n continue; // No end\n }\n var clozeContent = question.substring(clozeStart, clozeEnd);\n var replacer = \u0027\u0027;\n if (clozeContent.length) {\n replacer = handler(self.parseSolution(clozeContent));\n clozeEnd++;\n }\n else {\n clozeStart += 1;\n }\n question = question.slice(0, clozeStart - 1) + replacer + question.slice(clozeEnd);\n clozeEnd -= clozeEnd - clozeStart - replacer.length;\n\n // Find the next cloze\n clozeStart = question.indexOf(\u0027*\u0027, clozeEnd);\n }\n return question;\n };\n\n /**\n * Create questitons html for DOM\n */\n Blanks.prototype.createQuestions = function () {\n var self = this;\n\n var html = \u0027\u0027;\n var clozeNumber = 0;\n for (var i = 0; i \u003c self.params.questions.length; i++) {\n var question = self.params.questions[i];\n\n // Go through the question text and replace all the asterisks with input fields\n question = self.handleBlanks(question, function (solution) {\n // Create new cloze\n clozeNumber += 1;\n var defaultUserAnswer = (self.params.userAnswers.length \u003e self.clozes.length ? self.params.userAnswers[self.clozes.length] : null);\n var cloze = new Blanks.Cloze(solution, self.params.behaviour, defaultUserAnswer, {\n answeredCorrectly: self.params.answeredCorrectly,\n answeredIncorrectly: self.params.answeredIncorrectly,\n solutionLabel: self.params.solutionLabel,\n inputLabel: self.params.inputLabel,\n inputHasTipLabel: self.params.inputHasTipLabel,\n tipLabel: self.params.tipLabel\n });\n\n self.clozes.push(cloze);\n return cloze;\n });\n\n html += \u0027\u003cdiv\u003e\u0027 + question + \u0027\u003c/div\u003e\u0027;\n }\n\n self.hasClozes = clozeNumber \u003e 0;\n this.$questions = $(html);\n\n // Set input fields.\n this.$questions.find(\u0027input\u0027).each(function (i) {\n var afterCheck;\n if (self.params.behaviour.autoCheck) {\n afterCheck = function () {\n self.read((this.correct() ? self.params.answerIsCorrect : self.params.answerIsWrong).replace(\u0027:ans\u0027, this.getUserAnswer()));\n if (self.done || self.allBlanksFilledOut()) {\n // All answers has been given. Show solutions button.\n self.toggleButtonVisibility(STATE_CHECKING);\n self.showEvaluation();\n self.triggerAnswered();\n self.done = true;\n }\n };\n }\n self.clozes[i].setInput($(this), afterCheck, function () {\n self.toggleButtonVisibility(STATE_ONGOING);\n if (!self.params.behaviour.autoCheck) {\n self.hideEvaluation();\n }\n }, i, self.clozes.length);\n }).keydown(function (event) {\n var $this = $(this);\n\n // Adjust width of text input field to match value\n self.autoGrowTextField($this);\n\n var $inputs, isLastInput;\n var enterPressed = (event.keyCode === 13);\n var tabPressedAutoCheck = (event.keyCode === 9 \u0026\u0026 self.params.behaviour.autoCheck);\n\n if (enterPressed || tabPressedAutoCheck) {\n // Figure out which inputs are left to answer\n $inputs = self.$questions.find(\u0027.h5p-input-wrapper:not(.h5p-correct) .h5p-text-input\u0027);\n\n // Figure out if this is the last input\n isLastInput = $this.is($inputs[$inputs.length - 1]);\n }\n\n if ((tabPressedAutoCheck \u0026\u0026 isLastInput \u0026\u0026 !self.shiftPressed) ||\n (enterPressed \u0026\u0026 isLastInput)) {\n // Focus first button on next tick\n setTimeout(function () {\n self.focusButton();\n }, 10);\n }\n\n if (enterPressed) {\n if (isLastInput) {\n // Check answers\n $this.trigger(\u0027blur\u0027);\n }\n else {\n // Find next input to focus\n $inputs.eq($inputs.index($this) + 1).focus();\n }\n\n return false; // Prevent form submission on enter key\n }\n }).on(\u0027change\u0027, function () {\n self.answered = true;\n self.triggerXAPI(\u0027interacted\u0027);\n });\n\n self.on(\u0027resize\u0027, function () {\n self.resetGrowTextField();\n });\n\n return this.$questions;\n };\n\n /**\n *\n */\n Blanks.prototype.autoGrowTextField = function ($input) {\n // Do not set text field size when separate lines is enabled\n if (this.params.behaviour.separateLines) {\n return;\n }\n\n var self = this;\n var fontSize = parseInt($input.css(\u0027font-size\u0027), 10);\n var minEm = 3;\n var minPx = fontSize * minEm;\n var rightPadEm = 3.25;\n var rightPadPx = fontSize * rightPadEm;\n var static_min_pad = 0.5 * fontSize;\n\n setTimeout(function(){\n var tmp = $(\u0027\u003cdiv\u003e\u0027, {\n \u0027html\u0027: $input.val()\n });\n tmp.css({\n \u0027position\u0027: \u0027absolute\u0027,\n \u0027white-space\u0027: \u0027nowrap\u0027,\n \u0027font-size\u0027: $input.css(\u0027font-size\u0027),\n \u0027font-family\u0027: $input.css(\u0027font-family\u0027),\n \u0027padding\u0027: $input.css(\u0027padding\u0027),\n \u0027width\u0027: \u0027initial\u0027\n });\n $input.parent().append(tmp);\n var width = tmp.width();\n var parentWidth = self.$questions.width();\n tmp.remove();\n if (width \u003c= minPx) {\n // Apply min width\n $input.width(minPx + static_min_pad);\n }\n else if (width + rightPadPx \u003e= parentWidth) {\n // Apply max width of parent\n $input.width(parentWidth - rightPadPx);\n }\n else {\n // Apply width that wraps input\n $input.width(width + static_min_pad);\n }\n }, 1);\n };\n\n /**\n * Resize all text field growth to current size.\n */\n Blanks.prototype.resetGrowTextField = function () {\n var self = this;\n\n this.$questions.find(\u0027input\u0027).each(function () {\n self.autoGrowTextField($(this));\n });\n };\n\n /**\n * Toggle buttons dependent of state.\n *\n * Using CSS-rules to conditionally show/hide using the data-attribute [data-state]\n */\n Blanks.prototype.toggleButtonVisibility = function (state) {\n // The show solutions button is hidden if all answers are correct\n var allCorrect = (this.getScore() === this.getMaxScore());\n if (this.params.behaviour.autoCheck \u0026\u0026 allCorrect) {\n // We are viewing the solutions\n state = STATE_FINISHED;\n }\n\n if (this.params.behaviour.enableSolutionsButton) {\n if (state === STATE_CHECKING \u0026\u0026 !allCorrect) {\n this.showButton(\u0027show-solution\u0027);\n }\n else {\n this.hideButton(\u0027show-solution\u0027);\n }\n }\n\n if (this.params.behaviour.enableRetry) {\n if ((state === STATE_CHECKING \u0026\u0026 !allCorrect) || state === STATE_SHOWING_SOLUTION) {\n this.showButton(\u0027try-again\u0027);\n }\n else {\n this.hideButton(\u0027try-again\u0027);\n }\n }\n\n if (state === STATE_ONGOING) {\n this.showButton(\u0027check-answer\u0027);\n }\n else {\n this.hideButton(\u0027check-answer\u0027);\n }\n\n this.trigger(\u0027resize\u0027);\n };\n\n /**\n * Check if solution is allowed. Warn user if not\n */\n Blanks.prototype.allowSolution = function () {\n if (this.params.behaviour.showSolutionsRequiresInput === true) {\n if (!this.allBlanksFilledOut()) {\n this.updateFeedbackContent(this.params.notFilledOut);\n this.read(this.params.notFilledOut);\n return false;\n }\n }\n return true;\n };\n\n /**\n * Check if all blanks are filled out\n *\n * @method allBlanksFilledOut\n * @return {boolean} Returns true if all blanks are filled out.\n */\n Blanks.prototype.allBlanksFilledOut = function () {\n return !this.clozes.some(function (cloze) {\n return !cloze.filledOut();\n });\n };\n\n /**\n * Mark which answers are correct and which are wrong and disable fields if retry is off.\n */\n Blanks.prototype.markResults = function () {\n var self = this;\n for (var i = 0; i \u003c self.clozes.length; i++) {\n self.clozes[i].checkAnswer();\n if (!self.params.behaviour.enableRetry) {\n self.clozes[i].disableInput();\n }\n }\n this.trigger(\u0027resize\u0027);\n };\n\n /**\n * Removed marked results\n */\n Blanks.prototype.removeMarkedResults = function () {\n this.$questions.find(\u0027.h5p-input-wrapper\u0027).removeClass(\u0027h5p-correct h5p-wrong\u0027);\n this.$questions.find(\u0027.h5p-input-wrapper \u003e input\u0027).attr(\u0027disabled\u0027, false);\n this.trigger(\u0027resize\u0027);\n };\n\n\n /**\n * Displays the correct answers\n * @param {boolean} [alwaysShowSolution]\n * Will always show solution if true\n */\n Blanks.prototype.showCorrectAnswers = function (alwaysShowSolution) {\n if (!alwaysShowSolution \u0026\u0026 !this.allowSolution()) {\n return;\n }\n\n this.toggleButtonVisibility(STATE_SHOWING_SOLUTION);\n this.hideSolutions();\n\n for (var i = 0; i \u003c this.clozes.length; i++) {\n this.clozes[i].showSolution();\n }\n this.trigger(\u0027resize\u0027);\n };\n\n /**\n * Toggle input allowed for all input fields\n *\n * @method function\n * @param {boolean} enabled True if fields should allow input, otherwise false\n */\n Blanks.prototype.toggleAllInputs = function (enabled) {\n for (var i = 0; i \u003c this.clozes.length; i++) {\n this.clozes[i].toggleInput(enabled);\n }\n };\n\n /**\n * Display the correct solution for the input boxes.\n *\n * This is invoked from CP and QS - be carefull!\n */\n Blanks.prototype.showSolutions = function () {\n this.params.behaviour.enableSolutionsButton = true;\n this.toggleButtonVisibility(STATE_FINISHED);\n this.markResults();\n this.showEvaluation();\n this.showCorrectAnswers(true);\n this.toggleAllInputs(false);\n //Hides all buttons in \"show solution\" mode.\n this.hideButtons();\n };\n\n /**\n * Resets the complete task.\n * Used in contracts.\n * @public\n */\n Blanks.prototype.resetTask = function () {\n this.answered = false;\n this.hideEvaluation();\n this.hideSolutions();\n this.clearAnswers();\n this.removeMarkedResults();\n this.toggleButtonVisibility(STATE_ONGOING);\n this.resetGrowTextField();\n this.toggleAllInputs(true);\n this.done = false;\n };\n\n /**\n * Hides all buttons.\n * @public\n */\n Blanks.prototype.hideButtons = function () {\n this.toggleButtonVisibility(STATE_FINISHED);\n };\n\n /**\n * Trigger xAPI answered event\n */\n Blanks.prototype.triggerAnswered = function() {\n this.answered = true;\n var xAPIEvent = this.createXAPIEventTemplate(\u0027answered\u0027);\n this.addQuestionToXAPI(xAPIEvent);\n this.addResponseToXAPI(xAPIEvent);\n this.trigger(xAPIEvent);\n };\n\n /**\n * Get xAPI data.\n * Contract used by report rendering engine.\n *\n * @see contract at {@link https://h5p.org/documentation/developers/contracts#guides-header-6}\n */\n Blanks.prototype.getXAPIData = function () {\n var xAPIEvent = this.createXAPIEventTemplate(\u0027answered\u0027);\n this.addQuestionToXAPI(xAPIEvent);\n this.addResponseToXAPI(xAPIEvent);\n return {\n statement: xAPIEvent.data.statement\n };\n };\n\n /**\n * Generate xAPI object definition used in xAPI statements.\n * @return {Object}\n */\n Blanks.prototype.getxAPIDefinition = function () {\n var definition = {};\n definition.description = {\n \u0027en-US\u0027: this.params.text\n };\n definition.type = \u0027http://adlnet.gov/expapi/activities/cmi.interaction\u0027;\n definition.interactionType = \u0027fill-in\u0027;\n definition.correctResponsesPattern = [\u0027{case_matters=\u0027 + this.params.behaviour.caseSensitive + \u0027}\u0027];\n var firstCorrectResponse = true;\n // xAPI forces us to create solution patterns for all possible solution combinations\n for (var i = 0; i \u003c this.params.questions.length; i++) {\n var question = this.handleBlanks(this.params.questions[i], function(solution) {\n // Store new patterns for each extra alternative answer\n var newPatterns = [];\n for (var j = 0; j \u003c definition.correctResponsesPattern.length; j++) {\n if (!firstCorrectResponse) {\n definition.correctResponsesPattern[j] += \u0027[,]\u0027;\n }\n var prefix = definition.correctResponsesPattern[j];\n for (var k = 0; k \u003c solution.solutions.length; k++) {\n if (k === 0) {\n // This is the first possible answr, just add it to the pattern\n definition.correctResponsesPattern[j] += solution.solutions[k];\n }\n else {\n // This is an alternative possible answer, we need to create a new permutation\n newPatterns.push(prefix + solution.solutions[k]);\n }\n }\n }\n // Add any new permutations to the list of response patterns\n definition.correctResponsesPattern = definition.correctResponsesPattern.concat(newPatterns);\n\n firstCorrectResponse = false;\n\n // We replace the solutions in the question with a \"blank\"\n return \u0027__________\u0027;\n });\n definition.description[\u0027en-US\u0027] += question;\n }\n return definition;\n };\n\n /**\n * Add the question itselt to the definition part of an xAPIEvent\n */\n Blanks.prototype.addQuestionToXAPI = function(xAPIEvent) {\n var definition = xAPIEvent.getVerifiedStatementValue([\u0027object\u0027, \u0027definition\u0027]);\n $.extend(definition, this.getxAPIDefinition());\n };\n\n /**\n * Parse the solution text (text between the asterisks)\n *\n * @param {string} solutionText\n * @returns {object} with the following properties\n * - tip: the tip text for this solution, undefined if no tip\n * - solutions: array of solution words\n */\n Blanks.prototype.parseSolution = function (solutionText) {\n var tip, solution;\n\n var tipStart = solutionText.indexOf(\u0027:\u0027);\n if (tipStart !== -1) {\n // Found tip, now extract\n tip = solutionText.slice(tipStart + 1);\n solution = solutionText.slice(0, tipStart);\n }\n else {\n solution = solutionText;\n }\n\n // Split up alternatives\n var solutions = solution.split(\u0027/\u0027);\n\n // Trim solutions\n for (var i = 0; i \u003c solutions.length; i++) {\n solutions[i] = H5P.trim(solutions[i]);\n\n //decodes html entities\n var elem = document.createElement(\u0027textarea\u0027);\n elem.innerHTML = solutions[i];\n solutions[i] = elem.value;\n }\n\n return {\n tip: tip,\n solutions: solutions\n };\n };\n\n /**\n * Add the response part to an xAPI event\n *\n * @param {H5P.XAPIEvent} xAPIEvent\n * The xAPI event we will add a response to\n */\n Blanks.prototype.addResponseToXAPI = function (xAPIEvent) {\n xAPIEvent.setScoredResult(this.getScore(), this.getMaxScore(), this);\n xAPIEvent.data.statement.result.response = this.getxAPIResponse();\n };\n\n /**\n * Generate xAPI user response, used in xAPI statements.\n * @return {string} User answers separated by the \"[,]\" pattern\n */\n Blanks.prototype.getxAPIResponse = function () {\n var usersAnswers = this.getCurrentState();\n return usersAnswers.join(\u0027[,]\u0027);\n };\n\n /**\n * Show evaluation widget, i.e: \u0027You got x of y blanks correct\u0027\n */\n Blanks.prototype.showEvaluation = function () {\n var maxScore = this.getMaxScore();\n var score = this.getScore();\n var scoreText = H5P.Question.determineOverallFeedback(this.params.overallFeedback, score / maxScore).replace(\u0027@score\u0027, score).replace(\u0027@total\u0027, maxScore);\n\n this.setFeedback(scoreText, score, maxScore, this.params.scoreBarLabel);\n\n if (score === maxScore) {\n this.toggleButtonVisibility(STATE_FINISHED);\n }\n };\n\n /**\n * Hide the evaluation widget\n */\n Blanks.prototype.hideEvaluation = function () {\n // Clear evaluation section.\n this.removeFeedback();\n };\n\n /**\n * Hide solutions. (/try again)\n */\n Blanks.prototype.hideSolutions = function () {\n // Clean solution from quiz\n this.$questions.find(\u0027.h5p-correct-answer\u0027).remove();\n };\n\n /**\n * Get maximum number of correct answers.\n *\n * @returns {Number} Max points\n */\n Blanks.prototype.getMaxScore = function () {\n var self = this;\n return self.clozes.length;\n };\n\n /**\n * Count the number of correct answers.\n *\n * @returns {Number} Points\n */\n Blanks.prototype.getScore = function () {\n var self = this;\n var correct = 0;\n for (var i = 0; i \u003c self.clozes.length; i++) {\n if (self.clozes[i].correct()) {\n correct++;\n }\n self.params.userAnswers[i] = self.clozes[i].getUserAnswer();\n }\n\n return correct;\n };\n\n Blanks.prototype.getTitle = function() {\n return H5P.createTitle(this.params.text);\n };\n\n /**\n * Clear the user\u0027s answers\n */\n Blanks.prototype.clearAnswers = function () {\n this.clozes.forEach(function (cloze) {\n cloze.setUserInput(\u0027\u0027);\n cloze.resetAriaLabel();\n });\n };\n\n /**\n * Checks if all has been answered.\n *\n * @returns {Boolean}\n */\n Blanks.prototype.getAnswerGiven = function () {\n return this.answered || !this.hasClozes;\n };\n\n /**\n * Helps set focus the given input field.\n * @param {jQuery} $input\n */\n Blanks.setFocus = function ($input) {\n setTimeout(function () {\n $input.focus();\n }, 1);\n };\n\n /**\n * Returns an object containing content of each cloze\n *\n * @returns {object} object containing content for each cloze\n */\n Blanks.prototype.getCurrentState = function () {\n var clozesContent = [];\n\n // Get user input for every cloze\n this.clozes.forEach(function (cloze) {\n clozesContent.push(cloze.getUserInput());\n });\n return clozesContent;\n };\n\n /**\n * Sets answers to current user state\n */\n Blanks.prototype.setH5PUserState = function () {\n var self = this;\n var isValidState = (this.previousState !== undefined \u0026\u0026\n this.previousState.length \u0026\u0026\n this.previousState.length === this.clozes.length);\n\n // Check that stored user state is valid\n if (!isValidState) {\n return;\n }\n\n // Set input from user state\n var hasAllClozesFilled = true;\n this.previousState.forEach(function (clozeContent, ccIndex) {\n\n // Register that an answer has been given\n if (clozeContent.length) {\n self.answered = true;\n }\n\n var cloze = self.clozes[ccIndex];\n cloze.setUserInput(clozeContent);\n\n // Handle instant feedback\n if (self.params.behaviour.autoCheck) {\n if (cloze.filledOut()) {\n cloze.checkAnswer();\n } else {\n hasAllClozesFilled = false;\n }\n }\n });\n\n if (self.params.behaviour.autoCheck \u0026\u0026 hasAllClozesFilled) {\n self.showEvaluation();\n self.toggleButtonVisibility(STATE_CHECKING);\n }\n };\n\n /**\n * Disables any active input. Useful for freezing the task and dis-allowing\n * modification of wrong answers.\n */\n Blanks.prototype.disableInput = function () {\n this.$questions.find(\u0027input\u0027).attr(\u0027disabled\u0027, true);\n };\n\n return Blanks;\n})(H5P.jQuery, H5P.Question);\n"
,"js/cloze.js":"(function ($, Blanks) {\n\n /**\n * Simple private class for keeping track of clozes.\n *\n * @class H5P.Blanks.Cloze\n * @param {string} answer\n * @param {Object} behaviour Behavioral settings for the task from semantics\n * @param {boolean} behaviour.acceptSpellingErrors - If true, answers will also count correct if they contain small spelling errors.\n * @param {string} defaultUserAnswer\n * @param {Object} l10n Localized texts\n * @param {string} l10n.solutionLabel Assistive technology label for cloze solution\n * @param {string} l10n.inputLabel Assistive technology label for cloze input\n * @param {string} l10n.inputHasTipLabel Assistive technology label for input with tip\n * @param {string} l10n.tipLabel Label for tip icon\n */\n Blanks.Cloze = function (solution, behaviour, defaultUserAnswer, l10n) {\n var self = this;\n var $input, $wrapper;\n var answers = solution.solutions;\n var answer = answers.join(\u0027/\u0027);\n var tip = solution.tip;\n var checkedAnswer = null;\n var inputLabel = l10n.inputLabel;\n\n if (behaviour.caseSensitive !== true) {\n // Convert possible solutions into lowercase\n for (var i = 0; i \u003c answers.length; i++) {\n answers[i] = answers[i].toLowerCase();\n }\n }\n\n /**\n * Check if the answer is correct.\n *\n * @private\n * @param {string} answered\n */\n var correct = function (answered) {\n if (behaviour.caseSensitive !== true) {\n answered = answered.toLowerCase();\n }\n for (var i = 0; i \u003c answers.length; i++) {\n // Damerau-Levenshtein comparison\n if (behaviour.acceptSpellingErrors === true) {\n var levenshtein = H5P.TextUtilities.computeLevenshteinDistance(answered, answers[i], true);\n /*\n * The correctness is temporarily computed by word length and number of number of operations\n * required to change one word into the other (Damerau-Levenshtein). It\u0027s subject to\n * change, cmp. https://github.com/otacke/udacity-machine-learning-engineer/blob/master/submissions/capstone_proposals/h5p_fuzzy_blanks.md\n */\n if ((answers[i].length \u003e 9) \u0026\u0026 (levenshtein \u003c= 2)) {\n return true;\n } else if ((answers[i].length \u003e 3) \u0026\u0026 (levenshtein \u003c= 1)) {\n return true;\n }\n }\n // regular comparison\n if (answered === answers[i]) {\n return true;\n }\n }\n return false;\n };\n\n /**\n * Check if filled out.\n *\n * @param {boolean}\n */\n this.filledOut = function () {\n var answered = this.getUserAnswer();\n // Blank can be correct and is interpreted as filled out.\n return (answered !== \u0027\u0027 || correct(answered));\n };\n\n /**\n * Check the cloze and mark it as wrong or correct.\n */\n this.checkAnswer = function () {\n checkedAnswer = this.getUserAnswer();\n var isCorrect = correct(checkedAnswer);\n if (isCorrect) {\n $wrapper.addClass(\u0027h5p-correct\u0027);\n $input.attr(\u0027disabled\u0027, true)\n .attr(\u0027aria-label\u0027, inputLabel + \u0027. \u0027 + l10n.answeredCorrectly);\n }\n else {\n $wrapper.addClass(\u0027h5p-wrong\u0027);\n $input.attr(\u0027aria-label\u0027, inputLabel + \u0027. \u0027 + l10n.answeredIncorrectly);\n }\n };\n\n /**\n * Disables input.\n * @method disableInput\n */\n this.disableInput = function () {\n this.toggleInput(false);\n };\n\n /**\n * Enables input.\n * @method enableInput\n */\n this.enableInput = function () {\n this.toggleInput(true);\n };\n\n /**\n * Toggles input enable/disable\n * @method toggleInput\n * @param {boolean} enabled True if input should be enabled, otherwise false\n */\n this.toggleInput = function (enabled) {\n $input.attr(\u0027disabled\u0027, !enabled);\n };\n\n /**\n * Show the correct solution.\n */\n this.showSolution = function () {\n if (correct(this.getUserAnswer())) {\n return; // Only for the wrong ones\n }\n\n $(\u0027\u003cspan aria-hidden=\"true\" class=\"h5p-correct-answer\"\u003e \u0027 + answer + \u0027\u003c/span\u003e\u0027).insertAfter($wrapper);\n $input.attr(\u0027disabled\u0027, true);\n var ariaLabel = inputLabel + \u0027. \u0027 +\n l10n.solutionLabel + \u0027 \u0027 + answer + \u0027. \u0027 +\n l10n.answeredIncorrectly;\n\n $input.attr(\u0027aria-label\u0027, ariaLabel);\n };\n\n /**\n * @returns {boolean}\n */\n this.correct = function () {\n return correct(this.getUserAnswer());\n };\n\n /**\n * Set input element.\n *\n * @param {H5P.jQuery} $element\n * @param {function} afterCheck\n * @param {function} afterFocus\n * @param {number} clozeIndex Index of cloze\n * @param {number} totalCloze Total amount of clozes in blanks\n */\n this.setInput = function ($element, afterCheck, afterFocus, clozeIndex, totalCloze) {\n $input = $element;\n $wrapper = $element.parent();\n inputLabel = inputLabel.replace(\u0027@num\u0027, (clozeIndex + 1))\n .replace(\u0027@total\u0027, totalCloze);\n\n // Add tip if tip is set\n if(tip !== undefined \u0026\u0026 tip.trim().length \u003e 0) {\n $wrapper.addClass(\u0027has-tip\u0027)\n .append(H5P.JoubelUI.createTip(tip, {\n tipLabel: l10n.tipLabel\n }));\n inputLabel += \u0027. \u0027 + l10n.inputHasTipLabel;\n }\n\n $input.attr(\u0027aria-label\u0027, inputLabel);\n\n if (afterCheck !== undefined) {\n $input.blur(function () {\n if (self.filledOut()) {\n // Check answers\n if (!behaviour.enableRetry) {\n self.disableInput();\n }\n self.checkAnswer();\n afterCheck.apply(self);\n }\n });\n }\n $input.keyup(function () {\n if (checkedAnswer !== null \u0026\u0026 checkedAnswer !== self.getUserAnswer()) {\n // The Answer has changed since last check\n checkedAnswer = null;\n $wrapper.removeClass(\u0027h5p-wrong\u0027);\n $input.attr(\u0027aria-label\u0027, inputLabel);\n if (afterFocus !== undefined) {\n afterFocus();\n }\n }\n });\n };\n\n /**\n * @returns {string} Cloze html\n */\n this.toString = function () {\n var extra = defaultUserAnswer ? \u0027 value=\"\u0027 + defaultUserAnswer + \u0027\"\u0027 : \u0027\u0027;\n var result = \u0027\u003cspan class=\"h5p-input-wrapper\"\u003e\u003cinput type=\"text\" class=\"h5p-text-input\" autocomplete=\"off\" autocapitalize=\"off\"\u0027 + extra + \u0027\u003e\u003c/span\u003e\u0027;\n self.length = result.length;\n return result;\n };\n\n /**\n * @returns {string} Trimmed answer\n */\n this.getUserAnswer = function () {\n return H5P.trim($input.val());\n };\n\n /**\n * @returns {string} Answer\n */\n this.getUserInput = function () {\n return $input.val();\n };\n\n /**\n * @param {string} text New input text\n */\n this.setUserInput = function (text) {\n $input.val(text);\n };\n\n /**\n * Resets aria label of input field\n */\n this.resetAriaLabel = function () {\n $input.attr(\u0027aria-label\u0027, inputLabel);\n };\n };\n\n})(H5P.jQuery, H5P.Blanks);\n"
,"text.js":"H5P.AdvancedText = (function ($) {\n\n /**\n * A simple library for displaying text with advanced styling.\n *\n * @class H5P.AdvancedText\n * @param {Object} parameters\n * @param {Object} [parameters.text=\u0027New text\u0027]\n * @param {number} id\n */\n function AdvancedText(parameters, id) {\n var self = this;\n\n var html = (parameters.text === undefined ? \u0027\u003cem\u003eNew text\u003c/em\u003e\u0027 : parameters.text);\n\n /**\n * Wipe container and add text html.\n *\n * @alias H5P.AdvancedText#attach\n * @param {H5P.jQuery} $container\n */\n self.attach = function ($container) {\n $container.addClass(\u0027h5p-advanced-text\u0027).html(html);\n };\n }\n\n return AdvancedText;\n\n})(H5P.jQuery);\n"
,"H5PEditor.DragQuestion.js":"/*global H5P*/\nvar H5PEditor = H5PEditor || {};\n\n/**\n * Interactive Video editor widget module\n * TODO: Rewrite to use H5P.DragQuestion for previewing?\n\n * @param {jQuery} $\n */\nH5PEditor.widgets.dragQuestion = H5PEditor.DragQuestion = (function ($, DragNBar) {\n /**\n * Must be changed if the semantics for the elements changes.\n * @πvate\n * @type {string}\n */\n var clipboardKey = \u0027H5PEditor.DragQuestion\u0027;\n\n /**\n * Initialize interactive video editor.\n *\n * @param {Object} parent\n * @param {Object} field\n * @param {Object} params\n * @param {function} setValue\n */\n function C(parent, field, params, setValue) {\n var that = this;\n\n this.parent = parent;\n\n // Set params\n this.params = $.extend({\n elements: [],\n dropZones: []\n }, params);\n setValue(field, this.params);\n\n // Get updates for fields\n H5PEditor.followField(parent, \u0027settings/background\u0027, function (params) {\n that.setBackground(params);\n });\n H5PEditor.followField(parent, \u0027settings/size\u0027, function (params) {\n that.setSize(params);\n });\n\n // Need the override background opacity\n this.backgroundOpacity = parent.parent.params.backgroundOpacity;\n this.backgroundOpacity = (this.backgroundOpacity === undefined || this.backgroundOpacity.trim() === \u0027\u0027) ? undefined : this.backgroundOpacity;\n\n // Update opacity for all dropzones/draggables when global background opacity is changed\n parent.ready(function () {\n H5PEditor.findField(\u0027../behaviour/backgroundOpacity\u0027, parent).$item.find(\u0027input\u0027).on(\u0027change\u0027, function () {\n that.backgroundOpacity = $(this).val().trim();\n that.backgroundOpacity = (that.backgroundOpacity === \u0027\u0027) ? undefined : that.backgroundOpacity;\n that.updateAllElementsOpacity(that.elements, that.params.elements, \u0027element\u0027);\n });\n });\n\n // Get options from semantics, clone since we\u0027ll be changing values.\n this.elementFields = H5P.cloneObject(field.fields[0].field.fields, true);\n this.dropZoneFields = H5P.cloneObject(field.fields[1].field.fields, true);\n this.elementLibraryOptions = this.elementFields[0].options;\n this.elementDropZoneFieldWeight = 5;\n this.elementFields[this.elementDropZoneFieldWeight].options = [];\n this.dropZoneElementFieldWeight = 6;\n this.elementOptions = [];\n\n this.parent = parent;\n this.field = field;\n\n this.passReadies = true;\n parent.ready(function () {\n that.passReadies = false;\n });\n\n H5P.$window.on(\u0027resize\u0027, function () {\n if (that.size !== undefined \u0026\u0026 that.size.width !== undefined) {\n that.resize();\n }\n });\n }\n\n /**\n * Append field to wrapper.\n *\n * @param {jQuery} $wrapper\n * @returns {undefined}\n */\n C.prototype.appendTo = function ($wrapper) {\n var that = this;\n\n this.$item = $(this.createHtml()).appendTo($wrapper);\n this.$editor = this.$item.children(\u0027.h5peditor-dragquestion\u0027);\n this.$dnbWrapper = this.$item.children(\u0027.h5peditor-dragnbar\u0027);\n this.$dialog = this.$item.children(\u0027.h5peditor-fluid-dialog\u0027);\n this.$dialogInner = this.$dialog.children(\u0027.h5peditor-fd-inner\u0027);\n this.$errors = this.$item.children(\u0027.h5p-errors\u0027);\n\n // Handle click events for dialog buttons.\n this.$dialog.find(\u0027.h5peditor-done\u0027).click(function () {\n if (that.doneCallback() !== false) {\n that.hideDialog();\n }\n return false;\n }).end().find(\u0027.h5peditor-remove\u0027).click(function () {\n if (confirm(C.t(\u0027confirmRemoval\u0027))) {\n that.removeCallback();\n that.hideDialog();\n }\n return false;\n });\n };\n\n /**\n * Create HTML for the field.\n *\n * @returns {String}\n */\n C.prototype.createHtml = function () {\n var html = \u0027\u0027;\n if (this.field.label !== 0) {\n html += \u0027\u003cspan class=\"h5peditor-label\"\u003e\u0027 + this.field.label + \u0027\u003c/span\u003e\u0027;\n }\n\n html += \u0027\u003cdiv class=\"h5peditor-dragnbar\"\u003e\u003c/div\u003e\u0027 +\n \u0027\u003cdiv class=\"h5peditor-dragquestion\"\u003e\u0027 + C.t(\u0027noTaskSize\u0027) + \u0027\u003c/div\u003e\u0027 +\n \u0027\u003cdiv class=\"h5peditor-fluid-dialog\"\u003e\u0027 +\n \u0027 \u003cdiv class=\"h5peditor-fd-inner\"\u003e\u003c/div\u003e\u0027 +\n \u0027 \u003cdiv class=\"h5peditor-fd-buttons\"\u003e\u0027 +\n \u0027 \u003ca href=\"#\" class=\"h5peditor-fd-button h5peditor-done\"\u003e\u0027 + C.t(\u0027done\u0027) + \u0027\u003c/a\u003e\u0027 +\n \u0027 \u003ca href=\"#\" class=\"h5peditor-fd-button h5peditor-remove\"\u003e\u0027 + C.t(\u0027remove\u0027) + \u0027\u003c/a\u003e\u0027 +\n \u0027 \u003c/div\u003e\u0027 +\n \u0027\u003c/div\u003e\u0027;\n\n if (this.field.description !== undefined) {\n html += \u0027\u003cdiv class=\"h5peditor-field-description\"\u003e\u0027 + this.field.description + \u0027\u003c/div\u003e\u0027;\n }\n\n // removes the description field, so it\u0027s not re-rendered on top\n var field = this.removeAttribute(this.field, \u0027description\u0027);\n\n return H5PEditor.createFieldMarkup(field, html);\n };\n\n /**\n * Clones an object, and removes an attribute\n *\n * @param {object} obj\n * @param {string} attributeName\n *\n * @return {object}\n */\n C.prototype.removeAttribute = function (obj, attributeName) {\n var result = H5P.cloneObject(obj);\n result[attributeName] = undefined;\n return result;\n };\n\n /**\n * Set current background.\n *\n * @param {Object} params\n * @returns {undefined}\n */\n C.prototype.setBackground = function (params) {\n var path = params === undefined ? \u0027\u0027 : params.path;\n if (path !== \u0027\u0027) {\n // Add correct base path\n path = \u0027url(\"\u0027 + H5P.getPath(path, H5PEditor.contentId) + \u0027\")\u0027;\n }\n\n this.$editor.css({\n backgroundImage: path\n });\n };\n\n /**\n * Set current dimensions.\n *\n * @param {Object} params\n * @returns {undefined}\n */\n C.prototype.setSize = function (params) {\n this.size = params;\n };\n\n /**\n * Apply new size to task editor once visible.\n *\n * @returns {undefined}\n */\n C.prototype.setActive = function () {\n var that = this;\n if (this.size === undefined || this.size.width === undefined) {\n return;\n }\n\n if (this.dnb === undefined) {\n this.$editor.html(\u0027\u003cdiv class=\"h5p-throbber\"\u003e\u0027 + H5PEditor.t(\u0027core\u0027, \u0027loading\u0027) + \u0027\u003c/div\u003e\u0027)\n .addClass(\u0027h5p-ready\u0027);\n this.resize();\n H5PEditor.LibraryListCache.getLibraries(this.elementLibraryOptions, function (libraries) {\n // Prevents duplicate loading\n if (this.dnb === undefined) {\n that.activateEditor(libraries);\n }\n });\n }\n };\n\n /**\n * Adapt the editor when the window changes size.\n */\n C.prototype.resize = function () {\n if (!this.$editor.is(\u0027:visible\u0027)) {\n return;\n }\n if (this.fontSize === undefined) {\n // Get editor default font size.\n this.fontSize = parseInt(this.$editor.css(\u0027fontSize\u0027));\n }\n\n var maxWidth = this.$item.width();\n var editorCss;\n if (this.size.width \u003c maxWidth) {\n editorCss = {\n width: this.size.width,\n height: this.size.height,\n fontSize: this.fontSize\n };\n this.$dnbWrapper.css({\n width: this.size.width\n });\n }\n else {\n editorCss = {\n width: \u0027100%\u0027,\n height: maxWidth * (this.size.height / this.size.width),\n fontSize: this.fontSize * (maxWidth / this.size.width)\n };\n this.$dnbWrapper.css({\n width: \u0027100%\u0027\n });\n }\n\n this.$editor.css(editorCss);\n if (this.dnb !== undefined) {\n this.dnb.dnr.setContainerEm(editorCss.fontSize);\n }\n\n this.pToEm = (parseFloat(window.getComputedStyle(this.$editor[0]).width) / this.fontSize) / 100;\n };\n\n /**\n * Activate DragNBar and add elements.\n *\n * @returns {undefined}\n */\n C.prototype.activateEditor = function (libraries) {\n var that = this;\n this.$editor.html(\u0027\u0027).addClass(\u0027h5p-ready\u0027);\n\n // Create new bar\n this.dnb = new DragNBar(this.getButtons(libraries), this.$editor, this.$item);\n that.dnb.dnr.snap = 10;\n\n // Add event handling\n this.dnb.stopMovingCallback = function (x, y) {\n // Update params when the element is dropped.\n var id = that.dnb.dnd.$element.data(\u0027id\u0027);\n var params = that.dnb.dnd.$element.hasClass(\u0027h5p-dq-dz\u0027) ? that.params.dropZones[id] : that.params.elements[id];\n params.x = x;\n params.y = y;\n };\n this.dnb.dnd.releaseCallback = function () {\n // Edit element when it is dropped.\n if (that.dnb.newElement) {\n setTimeout(function () {\n that.dnb.dnd.$element.dblclick();\n that.dnb.blurAll();\n }, 1);\n }\n };\n this.dnb.attach(this.$dnbWrapper);\n\n this.dnb.on(\u0027paste\u0027, function (event) {\n var pasted = event.data;\n var $element;\n\n if (pasted.from === clipboardKey) {\n // Pasted content comes from the same version of DQ\n\n if (!pasted.generic) {\n // Non generic part, must be a drop zone\n that.center(pasted.specific);\n that.params.dropZones.push(pasted.specific);\n $element = that.insertDropZone(that.params.dropZones.length - 1);\n setTimeout(function () {\n that.dnb.focus($element);\n });\n }\n else if (that.elementLibraryOptions.indexOf(pasted.generic.library) !== -1) {\n // Has generic part and the generic libray is supported\n that.center(pasted.specific);\n that.params.elements.push(pasted.specific);\n $element = that.insertElement(that.params.elements.length - 1);\n setTimeout(function () {\n that.dnb.focus($element);\n });\n }\n else {\n alert(H5PEditor.t(\u0027H5P.DragNBar\u0027, \u0027unableToPaste\u0027));\n }\n }\n else if (pasted.generic) {\n if (that.elementLibraryOptions.indexOf(pasted.generic.library) !== -1) {\n // Supported library from another content type\n var id = C.getLibraryID(pasted.generic.library);\n var elementParams = C.getDefaultElementParams(id);\n elementParams.type = pasted.generic;\n elementParams.width = pasted.width * that.pToEm;\n elementParams.height = pasted.height * that.pToEm;\n\n that.center(elementParams);\n that.params.elements.push(elementParams);\n $element = that.insertElement(that.params.elements.length - 1);\n setTimeout(function () {\n that.dnb.focus($element);\n });\n }\n else {\n alert(H5PEditor.t(\u0027H5P.DragNBar\u0027, \u0027unableToPaste\u0027));\n }\n }\n });\n\n /**\n * Update params on end of resize\n * Dimensions contains a data object where each dimensions is optional.\n */\n this.dnb.dnr.on(\u0027stoppedResizing\u0027, function (dimensions) {\n var id = that.dnb.$element.data(\u0027id\u0027);\n var params = that.dnb.$element.hasClass(\u0027h5p-dq-dz\u0027) ? that.params.dropZones[id] : that.params.elements[id];\n var containerStyle = window.getComputedStyle(that.$editor[0]);\n\n // Set dimensions if they were passed in\n if (dimensions.data.left !== undefined) {\n params.x = dimensions.data.left / (parseFloat(containerStyle.width) / 100);\n }\n if (dimensions.data.top !== undefined) {\n params.y = dimensions.data.top / (parseFloat(containerStyle.height) / 100);\n }\n if (dimensions.data.width !== undefined) {\n params.width = dimensions.data.width;\n }\n if (dimensions.data.height !== undefined) {\n params.height = dimensions.data.height;\n }\n });\n\n // Add Elements\n this.elements = [];\n for (var i = 0; i \u003c this.params.elements.length; i++) {\n this.insertElement(i);\n }\n\n // Add Drop Zones\n this.dropZones = [];\n for (var j = 0; j \u003c this.params.dropZones.length; j++) {\n this.insertDropZone(j);\n }\n\n this.resize();\n };\n\n /**\n * Help center new elements\n * @param {object} params\n */\n C.prototype.center = function (params) {\n var size = window.getComputedStyle(this.dnb.$container[0]);\n var width = parseFloat(size.width);\n var height = parseFloat(size.height);\n var pos = {\n x: (width - (params.width * this.fontSize)) / 2,\n y: (height - (params.height * this.fontSize)) / 2\n };\n this.dnb.avoidOverlapping(pos, {\n width: params.width * this.fontSize,\n height: params.height * this.fontSize,\n });\n params.x = pos.x / (width / 100);\n params.y = pos.y / (height / 100);\n };\n\n /**\n * Generate sub forms that\u0027s ready to use in the dialog.\n *\n * @param {Object} semantics\n * @param {Object} params\n * @returns {Object} generatedForm\n */\n C.prototype.generateForm = function (semantics, params) {\n var $form = $(\u0027\u003cdiv\u003e\u003c/div\u003e\u0027);\n H5PEditor.processSemanticsChunk(semantics, params, $form, this);\n var $lib = $form.children(\u0027.library:first\u0027);\n if ($lib.length !== 0) {\n $lib.children(\u0027label, select, .h5peditor-field-description\u0027).hide().end().children(\u0027.libwrap\u0027).css(\u0027margin-top\u0027, \u00270\u0027);\n }\n\n return {\n $form: $form,\n children: this.children\n };\n };\n\n /**\n * Generate a list of buttons for DnB.\n *\n * @returns {Array} Buttons\n */\n C.prototype.getButtons = function (libraries) {\n var that = this;\n var id = \u0027dropzone\u0027;\n var buttons = [{\n id: id,\n title: C.t(\u0027insertElement\u0027, {\u0027:type\u0027: C.t(id)}),\n createElement: function () {\n that.params.dropZones.push({\n x: 0,\n y: 0,\n width: 5,\n height: 2.5,\n correctElements: []\n });\n\n return that.insertDropZone(that.params.dropZones.length - 1);\n }\n }];\n\n for (var i = 0; i \u003c libraries.length; i++) {\n if (libraries[i].restricted !== true) {\n buttons.push(this.getButton(libraries[i]));\n }\n }\n\n return buttons;\n };\n\n /**\n * Creates a fresh object with default element parameters.\n * @returns {object}\n */\n C.getDefaultElementParams = function (id) {\n return {\n x: 0,\n y: 0,\n width: 5,\n height: id === \u0027text\u0027 ? 1.25 : 5,\n dropZones: []\n };\n };\n\n /**\n * Find generic library identifier without version name.\n *\n * @param {string} library\n * @returns {string}\n */\n C.getLibraryID = function (library) {\n return library.split(\u0027 \u0027)[0].split(\u0027.\u0027)[1].toLowerCase();\n };\n\n /**\n * Generate a single element button for the DnB.\n *\n * @param {String} library Library name + version\n * @returns {Object} DnB button semantics\n */\n C.prototype.getButton = function (library) {\n var that = this;\n var id = C.getLibraryID(library.uberName);\n return {\n id: id,\n title: library.title,\n createElement: function () {\n var elementParams = C.getDefaultElementParams(id);\n elementParams.type = {\n library: library.uberName,\n params: {}\n };\n that.params.elements.push(elementParams);\n return that.insertElement(that.params.elements.length - 1);\n }\n };\n };\n\n /**\n * Insert element at given params index.\n *\n * @param {int} index\n * @returns {jQuery} The element\u0027s DOM\n */\n C.prototype.insertElement = function (index) {\n var that = this;\n var elementParams = this.params.elements[index];\n var element = this.generateForm(this.elementFields, elementParams);\n\n var library = this.children[0];\n\n // Get image aspect ratio\n var libraryChange = function () {\n if (library.children[0].field.type === \u0027image\u0027) {\n library.children[0].changes.push(function (params) {\n if (params === undefined) {\n return;\n }\n\n if (params.width !== undefined \u0026\u0026 params.height !== undefined) {\n var editorStyles = window.getComputedStyle(that.$editor[0]);\n var editorWidth = parseFloat(editorStyles.width);\n var editorHeight = parseFloat(editorStyles.height);\n\n var aspectRatio = params.height / params.width;\n if (editorHeight / editorWidth \u003e aspectRatio) {\n elementParams.height = elementParams.width * aspectRatio;\n }\n else {\n elementParams.width = elementParams.height / aspectRatio;\n }\n\n element.$element.css({\n width: elementParams.width + \u0027em\u0027,\n height: elementParams.height + \u0027em\u0027\n });\n }\n });\n }\n };\n\n if (library.children === undefined) {\n library.changes.push(libraryChange);\n }\n else {\n libraryChange();\n }\n\n element.$element = $(\u0027\u003cdiv class=\"h5p-dq-element\" style=\"width:\u0027 + elementParams.width + \u0027em;height:\u0027 + elementParams.height + \u0027em;top:\u0027 + elementParams.y + \u0027%;left:\u0027 + elementParams.x + \u0027%\"\u003e\u003c/div\u003e\u0027)\n .data(\u0027id\u0027, index)\n .appendTo(this.$editor)\n .dblclick(function () {\n that.editElement(element);\n }).hover(function () {\n C.setElementOpacity(element.$element, that.getElementOpacitySetting(elementParams));\n }, function () {\n // Need this timeout for firefox beeing able to get the css hover rule in place\n setTimeout(function () {\n C.setElementOpacity(element.$element, that.getElementOpacitySetting(elementParams));\n }, 1);\n });\n\n element.$innerElement = $(\u0027\u003cdiv\u003e\u0027, {\n \u0027class\u0027: \u0027h5p-dq-element-inner\u0027\n }).appendTo(element.$element);\n\n setTimeout(function () {\n var type = (elementParams.type ? elementParams.type.library.split(\u0027 \u0027)[0] : null);\n\n var dnbElement = that.dnb.add(element.$element, DragNBar.clipboardify(clipboardKey, elementParams, \u0027type\u0027), {\n cornerLock: (type === \u0027H5P.Image\u0027)\n });\n\n dnbElement.contextMenu.on(\u0027contextMenuEdit\u0027, function () {\n that.editElement(element);\n that.dnb.blurAll();\n });\n\n dnbElement.contextMenu.on(\u0027contextMenuRemove\u0027, that.elementRemove.bind(that, element));\n dnbElement.contextMenu.on(\u0027contextMenuBringToFront\u0027, that.elementBringToFront.bind(that, element));\n dnbElement.contextMenu.on(\u0027contextMenuSendToBack\u0027, that.elementSendToBack.bind(that, element));\n that.dnb.focus(element.$element);\n }, 0);\n\n // Update element\n that.updateElement(element, index);\n\n this.elements[index] = element;\n return element.$element;\n };\n\n /**\n * Removes an element\n *\n * @param {object} element\n */\n C.prototype.elementRemove = function (element) {\n var that = this;\n\n // confirm remove\n if (!confirm(C.t(\u0027confirmRemoval\u0027))) {\n return;\n }\n\n var id = element.$element.data(\u0027id\u0027);\n var value = id.toString();\n\n // Remove element form\n H5PEditor.removeChildren(element.children);\n\n // Remove element\n element.$element.remove();\n that.elements.splice(id, 1);\n that.params.elements.splice(id, 1);\n\n // Remove from options\n that.elementOptions.splice(id, 1);\n\n // Update drop zone params\n\n that.params.dropZones.forEach(function(dropZone){\n var elements = dropZone.correctElements;\n\n elements = that.arrayRemoveByValue(elements, value);\n elements = that.decrementIdsLargerThen(elements, id);\n\n // update correct elements\n dropZone.correctElements = elements;\n });\n\n that.updateInternalElementIDs(id);\n that.dnb.blurAll();\n };\n\n /**\n * Brings an element to the front\n *\n * @param {object} element\n */\n C.prototype.elementBringToFront = function (element) {\n var that = this;\n\n // Find element ID\n var id = element.$element.data(\u0027id\u0027);\n var oldId = id.toString();\n\n // Update visuals\n element.$element.appendTo(that.$editor);\n\n // Give new ID\n that.elements.push(that.elements.splice(id, 1)[0]);\n that.params.elements.push(that.params.elements.splice(id, 1)[0]);\n that.elementOptions.push(that.elementOptions.splice(id, 1)[0]);\n\n var newId = (that.elements.length - 1).toString();\n\n // Update drop zone params\n that.params.dropZones.forEach(function(dropZone) {\n // update correct elements\n dropZone.correctElements = dropZone.correctElements.map(function(entry){\n // Update ID in correct answers\n if (entry === oldId) {\n return newId;\n }\n // Adjust index for others\n else if (parseInt(entry) \u003e id) {\n return (parseInt(entry) - 1).toString();\n }\n // if not current, and not with larger id\n else {\n return entry;\n }\n });\n });\n\n that.updateInternalElementIDs(id);\n };\n\n /**\n * Sends an element to the back\n *\n * @param {object} element\n */\n C.prototype.elementSendToBack = function (element) {\n var that = this;\n\n // Find element ID\n var id = element.$element.data(\u0027id\u0027);\n var oldId = id.toString();\n\n // Update visuals\n element.$element.prependTo(that.$editor);\n\n // Give new ID\n that.elements.unshift(that.elements.splice(id, 1)[0]);\n that.params.elements.unshift(that.params.elements.splice(id, 1)[0]);\n that.elementOptions.unshift(that.elementOptions.splice(id, 1)[0]);\n\n var newId = (that.elements.length - 1).toString();\n\n // Update drop zone params\n that.params.dropZones.forEach(function(dropZone) {\n // update correct elements\n dropZone.correctElements = dropZone.correctElements.map(function(entry){\n // Update ID in correct answers\n if (entry === oldId) {\n return newId;\n }\n // Adjust index for others\n else if (parseInt(entry) \u003e id) {\n return (parseInt(entry) - 1).toString();\n }\n // if not current, and not with larger id\n else {\n return entry;\n }\n });\n });\n\n that.updateInternalElementIDs(id);\n };\n\n /**\n * Removes a value from an array\n *\n * @param {object[]} arr\n * @param {object} value\n *\n * @return {object[]}\n */\n C.prototype.arrayRemoveByValue = function (arr, value) {\n var ax;\n\n while ((ax = arr.indexOf(value)) !== -1) {\n arr.splice(ax, 1);\n }\n\n return arr;\n };\n\n /**\n * Takes an array of numbers (as strings), and decrements those larger\n * then a threshold\n *\n * @param {String[]} arr\n * @param {number} threshold\n *\n * @private\n * @return {string[]}\n */\n C.prototype.decrementIdsLargerThen = function (arr, threshold) {\n return arr.map(function(id){\n var value = parseInt(id);\n return (id \u003c threshold) ? id : (value - 1).toString();\n });\n };\n\n /**\n * Sync the internal ID of each element.\n * @param {number} start\n */\n C.prototype.updateInternalElementIDs = function (start) {\n for (var i = start; i \u003c this.elements.length; i++) {\n this.elements[i].$element.data(\u0027id\u0027, i);\n this.elementOptions[i].value = \u0027\u0027 + i;\n }\n };\n\n /**\n * Set callbacks and open dialog with the form for the given element.\n *\n * @param {Object} element\n * @returns {undefined}\n */\n C.prototype.editElement = function (element) {\n var that = this;\n var id = element.$element.data(\u0027id\u0027);\n\n this.doneCallback = function () {\n // Validate form\n var valid = true;\n for (var i = 0; i \u003c element.children.length; i++) {\n if (element.children[i].validate() === false) {\n valid = false;\n break;\n }\n }\n if (!valid) {\n return false;\n }\n\n\n // Must be removed before dnb changes focus!\n if (H5PEditor.Html) {\n H5PEditor.Html.removeWysiwyg();\n }\n\n // Update element\n that.updateElement(element, id);\n that.dnb.focus(element.$element);\n that.dnb.pressed = undefined;\n };\n\n this.removeCallback = function () {\n var i, j, ce;\n\n // Remove element form\n H5PEditor.removeChildren(element.children);\n\n // Remove element\n element.$element.remove();\n that.elements.splice(id, 1);\n that.params.elements.splice(id, 1);\n\n // Remove from options\n this.elementOptions.splice(id, 1);\n\n // Update drop zone params\n for (i = 0; i \u003c that.params.dropZones.length; i++) {\n ce = that.params.dropZones[i].correctElements;\n for (j = 0; j \u003c ce.length; j++) {\n if (ce[j] === \u0027\u0027 + id) {\n // Remove from correct answers\n ce.splice(j, 1);\n }\n else if (ce[j] \u003e id) {\n // Adjust index for others\n ce[j] = \u0027\u0027 + (ce[j] - 1);\n }\n }\n }\n\n // Change data index for \"all\" elements\n for (i = id; i \u003c that.elements.length; i++) {\n that.elements[i].$element.data(\u0027id\u0027, i);\n that.elementOptions[i].value = \u0027\u0027 + i;\n }\n };\n\n // Disable background opacity input if overriden globally\n var disableOpacityField = !!(that.params.elements[id].dropZones.length !== 0 \u0026\u0026 this.backgroundOpacity);\n H5PEditor.findField(\u0027backgroundOpacity\u0027, element).$item.find(\u0027input\u0027).prop({\n disabled: disableOpacityField,\n title: disableOpacityField ? C.t(\u0027backgroundOpacityOverridden\u0027) : \u0027\u0027\n });\n\n element.children[this.elementDropZoneFieldWeight].setActive();\n this.showDialog(element.$form);\n\n // Blur context menu when showing dialog.\n setTimeout(function () {\n that.dnb.blurAll();\n }, 10);\n };\n\n /**\n * Update the element with new data.\n *\n * @param {Object} element\n * @param {int} id\n * @returns {undefined}\n */\n C.prototype.updateElement = function (element, id) {\n var self = this;\n var params = this.params.elements[id];\n\n var type = (params.type.library.split(\u0027 \u0027)[0] === \u0027H5P.AdvancedText\u0027 ? \u0027text\u0027 : \u0027image\u0027);\n var hasCk = (element.children[0].children !== undefined \u0026\u0026 element.children[0].children[0].ckeditor !== undefined);\n if (type === \u0027text\u0027 \u0026\u0026 hasCk) {\n // Create new text instance. Replace asterisk with spans\n element.instance = H5P.newRunnable({\n library: params.type.library,\n params: {\n text: params.type.params.text.replace(/\\*([^*]+)\\*/g, \u0027\u003cspan class=\"h5p-dragquestion-placeholder\"\u003e$1\u003c/span\u003e\u0027)\n }\n }, H5PEditor.contentId, element.$innerElement);\n\n // Remove asterisk from params and input field\n params.type.params.text = params.type.params.text.replace(/\\*([^*]+)\\*/g, \u0027$1\u0027);\n element.children[0].children[0].ckeditor.setData(params.type.params.text);\n }\n else {\n // Create new instance\n element.instance = H5P.newRunnable(params.type, H5PEditor.contentId, element.$innerElement);\n }\n\n if (type === \u0027text\u0027) {\n element.$element.addClass(\u0027h5p-dq-text\u0027);\n }\n\n // Find label text without html\n var label = (type === \u0027text\u0027 ? $(\u0027\u003cdiv\u003e\u0027 + params.type.params.text + \u0027\u003c/div\u003e\u0027).text() : params.type.params.alt + \u0027\u0027);\n\n // Update correct element options\n this.elementOptions[id] = {\n value: \u0027\u0027 + id,\n label: C.t(type) + \u0027: \u0027 + C.getLabel(label)\n };\n\n // Retain size after toggling class\n var toggleDraggable = function (addClass, $element) {\n var toggleClass = addClass !== $element.hasClass(\u0027h5p-draggable\u0027);\n if (!toggleClass) {\n return;\n }\n\n if (addClass) {\n $element.addClass(\u0027h5p-draggable\u0027);\n }\n else {\n $element.removeClass(\u0027h5p-draggable\u0027);\n }\n };\n\n if (params.dropZones !== undefined \u0026\u0026 params.dropZones.length) {\n\n toggleDraggable(true, element.$element);\n }\n else {\n toggleDraggable(false, element.$element);\n\n if (type === \u0027text\u0027 \u0026\u0026 hasCk) {\n // When dialog closes, replace spans with drop zones\n this.hideDialogCallback = function () {\n var pWidth = self.$editor.width() / 100;\n var pHeight = self.$editor.height() / 100;\n element.$element.find(\u0027.h5p-dragquestion-placeholder\u0027).each(function () {\n var $span = $(this);\n var pos = $span.position();\n\n // Add new drop zone\n self.params.dropZones.push({\n x: params.x + ((pos.left - 3) / pWidth),\n y: params.y + ((pos.top - 2) / pHeight),\n width: ($span.width() / self.fontSize) + 0.5,\n height: ($span.height() / self.fontSize) + 0.3,\n backgroundOpacity: 0,\n correctElements: [],\n label: C.getLabel($span.text()),\n showLabel: false\n });\n self.insertDropZone(self.params.dropZones.length - 1);\n\n // Remove span\n $span.contents().unwrap();\n });\n delete self.hideDialogCallback;\n };\n }\n }\n\n C.setElementOpacity(element.$element, this.getElementOpacitySetting(params));\n };\n\n /**\n * Clips text at 32 chars\n *\n * @param {String} text\n * @returns {String}\n */\n C.getLabel = function (text) {\n return (text.length \u003e 32 ? text.substr(0, 32) + \u0027...\u0027 : text);\n };\n\n /**\n * Insert the drop zone at the given index.\n *\n * @param {int} index\n * @returns {H5P.jQuery}\n */\n C.prototype.insertDropZone = function (index) {\n var that = this,\n dropZoneParams = this.params.dropZones[index],\n dropZone = this.generateForm(this.dropZoneFields, dropZoneParams);\n\n dropZone.$dropZone = $(\u0027\u003cdiv class=\"h5p-dq-dz\" style=\"width:\u0027 + dropZoneParams.width + \u0027em;height:\u0027 + dropZoneParams.height + \u0027em;top:\u0027 + dropZoneParams.y + \u0027%;left:\u0027 + dropZoneParams.x + \u0027%\"\u003e\u003c/div\u003e\u0027)\n .appendTo(this.$editor)\n .data(\u0027id\u0027, index)\n .dblclick(function () {\n // Edit\n that.editDropZone(dropZone);\n that.dnb.blurAll();\n });\n\n // Add label\n this.updateDropZone(dropZone, index);\n\n // Add to dnb after element has been attached\n setTimeout(function () {\n\n var dropzoneDnBElement = that.dnb.add(dropZone.$dropZone, DragNBar.clipboardify(clipboardKey, dropZoneParams));\n\n // Register listeners for context menu buttons\n dropzoneDnBElement.contextMenu.on(\u0027contextMenuEdit\u0027, function () {\n that.editDropZone(dropZone);\n that.dnb.blurAll();\n });\n\n dropzoneDnBElement.contextMenu.on(\u0027contextMenuRemove\u0027, function () {\n if (!confirm(C.t(\u0027confirmRemoval\u0027))) {\n return;\n }\n\n // Remove element form\n H5PEditor.removeChildren(dropZone.children);\n var i;\n var j;\n var id = dropZone.$dropZone.data(\u0027id\u0027);\n\n // Remove element\n dropZone.$dropZone.remove();\n that.dropZones.splice(id, 1);\n that.params.dropZones.splice(id, 1);\n\n // Remove from elements\n that.elementFields[that.elementDropZoneFieldWeight].options.splice(id, 1);\n\n // Remove dropZone from element params properly\n for (i = 0; i \u003c that.params.elements.length; i++) {\n var dropZones = that.params.elements[i].dropZones;\n for (j = 0; j \u003c dropZones.length; j++) {\n if (parseInt(dropZones[j]) === id) {\n // Remove from element drop zones\n dropZones.splice(j, 1);\n if (!dropZones.length) {\n that.elements[i].$element.removeClass(\u0027h5p-draggable\u0027);\n }\n }\n else if (dropZones[j] \u003e id) {\n // Re index other drop zones\n dropZones[j] = \u0027\u0027 + (dropZones[j] - 1);\n }\n }\n }\n\n that.updateInternalDropZoneIDs(id);\n that.dnb.blurAll();\n });\n\n dropzoneDnBElement.contextMenu.on(\u0027contextMenuBringToFront\u0027, function () {\n var id = dropZone.$dropZone.data(\u0027id\u0027);\n\n // Update visuals\n dropZone.$dropZone.appendTo(that.$editor);\n\n // Get new ID\n that.dropZones.push(that.dropZones.splice(id, 1)[0]);\n that.params.dropZones.push(that.params.dropZones.splice(id, 1)[0]);\n var options = that.elementFields[that.elementDropZoneFieldWeight].options;\n options.push(options.splice(id, 1)[0]);\n var newID = (that.dropZones.length - 1);\n\n // Update dropZone IDs in element params\n for (i = 0; i \u003c that.params.elements.length; i++) {\n var dropZones = that.params.elements[i].dropZones;\n for (j = 0; j \u003c dropZones.length; j++) {\n if (parseInt(dropZones[j]) === id) {\n // Update ID\n dropZones[j] = newID;\n }\n else if (dropZones[j] \u003e id) {\n // Re-index other drop zones\n dropZones[j] = \u0027\u0027 + (dropZones[j] - 1);\n }\n }\n }\n\n that.updateInternalDropZoneIDs(id);\n });\n\n dropzoneDnBElement.contextMenu.on(\u0027contextMenuSendToBack\u0027, function () {\n var id = dropZone.$dropZone.data(\u0027id\u0027);\n\n // Update visuals\n dropZone.$dropZone.prependTo(that.$editor);\n\n // Get new ID\n that.dropZones.unshift(that.dropZones.splice(id, 1)[0]);\n that.params.dropZones.unshift(that.params.dropZones.splice(id, 1)[0]);\n var options = that.elementFields[that.elementDropZoneFieldWeight].options;\n options.unshift(options.splice(id, 1)[0]);\n var newID = (that.dropZones.length - 1);\n\n // Update dropZone IDs in element params\n for (i = 0; i \u003c that.params.elements.length; i++) {\n var dropZones = that.params.elements[i].dropZones;\n for (j = 0; j \u003c dropZones.length; j++) {\n if (parseInt(dropZones[j]) === id) {\n // Update ID\n dropZones[j] = newID;\n }\n else if (dropZones[j] \u003e id) {\n // Re-index other drop zones\n dropZones[j] = \u0027\u0027 + (dropZones[j] - 1);\n }\n }\n }\n\n that.updateInternalDropZoneIDs(id);\n });\n that.dnb.focus(dropZone.$dropZone);\n }, 0);\n\n this.dropZones[index] = dropZone;\n return dropZone.$dropZone;\n };\n\n /**\n * Sync the internal ID of each drop zone.\n * @param {number} start\n */\n C.prototype.updateInternalDropZoneIDs = function (start) {\n for (i = start; i \u003c this.dropZones.length; i++) {\n this.dropZones[i].$dropZone.data(\u0027id\u0027, i);\n this.elementFields[this.elementDropZoneFieldWeight].options[i].value = i + \u0027\u0027;\n }\n };\n\n /**\n * Set callbacks and open dialog with the form for the given drop zone.\n *\n * @param {Object} dropZone\n * @returns {undefined}\n */\n C.prototype.editDropZone = function (dropZone) {\n var that = this;\n var i, j, id = dropZone.$dropZone.data(\u0027id\u0027);\n\n this.doneCallback = function () {\n // Validate form\n var valid = true;\n for (var i = 0; i \u003c dropZone.children.length; i++) {\n if (dropZone.children[i].validate() === false) {\n valid = false;\n break;\n }\n }\n if (!valid) {\n return false;\n }\n\n // Must be removed before dnb changes focus!\n if (H5PEditor.Html) {\n H5PEditor.Html.removeWysiwyg();\n }\n\n that.updateDropZone(dropZone, id);\n that.dnb.focus(dropZone.$dropZone);\n that.dnb.pressed = undefined;\n };\n\n this.removeCallback = function () {\n // Remove element form\n H5PEditor.removeChildren(dropZone.children);\n\n // Remove element\n dropZone.$dropZone.remove();\n that.dropZones.splice(id, 1);\n that.params.dropZones.splice(id, 1);\n\n // Remove from elements\n this.elementFields[this.elementDropZoneFieldWeight].options.splice(id, 1);\n\n // Remove dropZone from element params properly\n for (i = 0; i \u003c that.params.elements.length; i++) {\n var dropZones = that.params.elements[i].dropZones;\n for (j = 0; j \u003c dropZones.length; j++) {\n if (parseInt(dropZones[j]) === id) {\n // Remove from element drop zones\n dropZones.splice(j, 1);\n if (!dropZones.length) {\n that.elements[i].$element.removeClass(\u0027h5p-draggable\u0027);\n }\n }\n else if (dropZones[j] \u003e id) {\n // Re index other drop zones\n dropZones[j] = \u0027\u0027 + (dropZones[j] - 1);\n }\n }\n }\n\n // Reindex all dropzones\n for (i = id; i \u003c that.dropZones.length; i++) {\n that.dropZones[i].$dropZone.data(\u0027id\u0027, i);\n this.elementFields[this.elementDropZoneFieldWeight].options[i].value = i + \u0027\u0027;\n }\n };\n\n // Add only available options\n var options = this.dropZoneFields[this.dropZoneElementFieldWeight].options = [];\n var dropZones;\n for (i = 0; i \u003c this.elementOptions.length; i++) {\n dropZones = this.params.elements[i].dropZones;\n for (j = 0; j \u003c dropZones.length; j++) {\n if (dropZones[j] === (id + \u0027\u0027)) {\n options.push(this.elementOptions[i]);\n break;\n }\n }\n }\n\n dropZone.children[this.dropZoneElementFieldWeight].setActive();\n this.showDialog(dropZone.$form);\n\n // Blur context menu when showing dialog\n setTimeout(function () {\n that.dnb.blurAll();\n }, 10);\n };\n\n /**\n * Remove old label and add new.\n *\n * @param {Object} dropZone\n * @param {int} id\n * @returns {undefined}\n */\n C.prototype.updateDropZone = function (dropZone, id) {\n var params = this.params.dropZones[id];\n\n // Remove old label and add new.\n dropZone.$dropZone.children(\u0027.h5p-dq-dz-label\u0027).remove();\n if (params.showLabel === true) {\n $(\u0027\u003cdiv class=\"h5p-dq-dz-label\"\u003e\u0027 + params.label + \u0027\u003c/div\u003e\u0027).appendTo(dropZone.$dropZone);\n dropZone.$dropZone.addClass(\u0027h5p-has-label\u0027);\n }\n else {\n dropZone.$dropZone.removeClass(\u0027h5p-has-label\u0027);\n }\n\n // Create/update Tip:\n dropZone.$dropZone.children(\u0027.joubel-tip-container\u0027).remove();\n if (params.tipsAndFeedback !== undefined \u0026\u0026 params.tipsAndFeedback.tip !== undefined \u0026\u0026 params.tipsAndFeedback.tip.trim().length !== 0) {\n dropZone.$dropZone.append(H5P.JoubelUI.createTip(params.tipsAndFeedback.tip, {showSpeechBubble: false}));\n }\n\n this.elementFields[this.elementDropZoneFieldWeight].options[id] = {\n value: \u0027\u0027 + id,\n label: params.label\n };\n\n C.setOpacity(dropZone.$dropZone.add(dropZone.$dropZone.children(\u0027.h5p-dq-dz-label\u0027)), \u0027background\u0027, params.backgroundOpacity);\n };\n\n /**\n * Attach form to dialog and show.\n *\n * @param {jQuery} $form\n * @returns {undefined}\n */\n C.prototype.showDialog = function ($form) {\n this.dnb.blurAll();\n this.$currentForm = $form;\n $form.appendTo(this.$dialogInner);\n this.$dialog.show();\n this.$editor.add(this.$dnbWrapper).hide();\n this.dnb.dnr.toggleModifiers(false);\n };\n\n /**\n * Hide dialog and detach form.\n *\n * @returns {undefined}\n */\n C.prototype.hideDialog = function () {\n // Attempt to find and close CKEditor instances before detaching.\n\n\n this.$currentForm.detach();\n this.$dialog.hide();\n this.$editor.add(this.$dnbWrapper).show();\n\n if (this.hideDialogCallback !== undefined) {\n this.hideDialogCallback();\n }\n this.dnb.dnr.toggleModifiers(true);\n };\n\n /**\n * Update transparency for background.\n *\n * @param {jQuery} $element\n * @param {Number} opacity\n */\n C.setElementOpacity = function ($element, opacity) {\n C.setOpacity($element, \u0027background\u0027, opacity);\n C.setOpacity($element, \u0027boxShadow\u0027, opacity);\n C.setOpacity($element, \u0027borderColor\u0027, opacity);\n };\n\n /**\n * Update all elements\u0027 opacity\n *\n * @param {Array} domElements\n * @param {Array} elements\n * @param {String} type\n */\n C.prototype.updateAllElementsOpacity = function (domElements, elements, type) {\n if (domElements === undefined) {\n return;\n }\n\n for (var i = 0; i \u003c domElements.length; i++) {\n C.setElementOpacity(domElements[i][\u0027$\u0027+type], this.getElementOpacitySetting(elements[i]));\n }\n };\n\n /**\n * Get the opacity setting for a given element\n *\n * @param {Object} element\n * @returns {String} opacity\n */\n C.prototype.getElementOpacitySetting = function (element) {\n if ((element.dropZones !== undefined \u0026\u0026 element.dropZones.length === 0) ||\n (this.backgroundOpacity === undefined)) {\n return element.backgroundOpacity;\n }\n\n return this.backgroundOpacity;\n };\n\n /**\n * Makes element background, border and shadow transparent.\n *\n * @param {jQuery} $element\n * @param {String} property\n * @param {Number} opacity\n */\n C.setOpacity = function ($element, property, opacity) {\n if (property === \u0027background\u0027) {\n // Set both color and gradient.\n C.setOpacity($element, \u0027backgroundColor\u0027, opacity);\n C.setOpacity($element, \u0027backgroundImage\u0027, opacity);\n return;\n }\n\n opacity = (opacity === undefined ? 1 : opacity / 100);\n\n // Private. Get css properties objects.\n function getProperties(property, value) {\n switch (property) {\n case \u0027borderColor\u0027:\n return {\n borderTopColor: value,\n borderRightColor: value,\n borderBottomColor: value,\n borderLeftColor: value\n };\n\n default:\n var properties = {};\n properties[property] = value;\n return properties;\n }\n }\n\n // Reset css to be sure we\u0027re using CSS and not inline values.\n var properties = getProperties(property, \u0027\u0027);\n $element.css(properties);\n\n for (var prop in properties) {\n break;\n }\n var style = $element.css(prop); // Assume all props are the same and use the first.\n style = C.setAlphas(style, \u0027rgba(\u0027, opacity); // Update rgba\n style = C.setAlphas(style, \u0027rgb(\u0027, opacity); // Convert rgb\n\n $element.css(getProperties(property, style));\n };\n\n /**\n * Updates alpha channel for colors in the given style.\n *\n * @param {String} style\n * @param {String} prefix\n * @param {Number} alpha\n */\n C.setAlphas = function (style, prefix, alpha) {\n // Style undefined\n if (!style) {\n return;\n }\n var colorStart = style.indexOf(prefix);\n\n while (colorStart !== -1) {\n var colorEnd = style.indexOf(\u0027)\u0027, colorStart);\n var channels = style.substring(colorStart + prefix.length, colorEnd).split(\u0027,\u0027);\n\n // Set alpha channel\n channels[3] = (channels[3] !== undefined ? parseFloat(channels[3]) * alpha : alpha);\n\n style = style.substring(0, colorStart) + \u0027rgba(\u0027 + channels.join(\u0027,\u0027) + style.substring(colorEnd, style.length);\n\n // Look for more colors\n colorStart = style.indexOf(prefix, colorEnd);\n }\n\n return style;\n };\n\n /**\n * Validate the current field.\n *\n * @returns {Boolean}\n */\n C.prototype.validate = function () {\n return true;\n };\n\n /**\n * Remove the field from DOM.\n *\n * @returns {undefined}\n */\n C.prototype.remove = function () {\n if (this.dnb !== undefined) {\n this.dnb.remove();\n }\n this.$item.remove();\n };\n\n /**\n * Collect functions to execute once the tree is complete.\n *\n * @param {function} ready\n * @returns {undefined}\n */\n C.prototype.ready = function (ready) {\n if (this.passReadies) {\n this.parent.ready(ready);\n }\n else {\n this.readies.push(ready);\n }\n };\n\n /**\n * Translate UI texts for this library.\n *\n * @param {String} key\n * @param {Object} vars\n * @returns {@exp;H5PEditor@call;t}\n */\n C.t = function (key, vars) {\n return H5PEditor.t(\u0027H5PEditor.DragQuestion\u0027, key, vars);\n };\n\n return C;\n})(H5P.jQuery, H5P.DragNBar);\n\n// Default english translations\nH5PEditor.language[\u0027H5PEditor.DragQuestion\u0027] = {\n libraryStrings: {\n insertElement: \u0027Insert :type\u0027,\n done: \u0027Done\u0027,\n remove: \u0027Remove\u0027,\n image: \u0027Image\u0027,\n text: \u0027Text\u0027,\n noTaskSize: \u0027Please specify task size first.\u0027,\n confirmRemoval: \u0027Are you sure you wish to remove this element?\u0027,\n backgroundOpacityOverridden: \u0027The background opacity is overridden\u0027,\n advancedtext: \u0027Advanced text\u0027,\n dropzone: \u0027Drop zone\u0027,\n selectAll: \u0027Select all\u0027,\n deselectAll: \u0027Deselect all\u0027\n }\n};\n"
,"H5PEditor.DynamicCheckboxes.js":"var H5PEditor = H5PEditor || {};\n\n/**\n * Editor widget module for dynamic value checkboxes.\n *\n * Displays a list of checkboxes, and the list is regenerated each time the\n * field is set as active unlike H5PEditor.select where the options are\n * generated when the field is initialized, and after that stays the same.\n *\n * Other fields may change the options in dynamicCheckboxes\n */\nH5PEditor.widgets.dynamicCheckboxes = H5PEditor.DynamicCheckboxes = (function ($) {\n /**\n * Initialize widget.\n *\n * @param {Object} parent\n * @param {Object} field\n * @param {Object} params\n * @param {function} setValue\n * @returns {_L8.C}\n */\n function C(parent, field, params, setValue) {\n this.parent = parent;\n this.field = field;\n this.setValue = setValue;\n\n if (params === undefined) {\n if (this.field.multiple) {\n this.params = [];\n }\n else {\n this.params = \u0027\u0027;\n }\n setValue(field, this.params);\n }\n else {\n this.params = params;\n }\n }\n\n /**\n * Append widget to form.\n *\n * @param {jQuery} $wrapper\n * @returns {undefined}\n */\n C.prototype.appendTo = function ($wrapper) {\n this.$item = $(H5PEditor.createFieldMarkup(this.field)).appendTo($wrapper);\n this.$errors = this.$item.children(\u0027.h5p-errors\u0027);\n };\n\n /**\n * The widget is set as active.\n * (re)Generate options.\n *\n * @returns {undefined}\n */\n C.prototype.setActive = function () {\n var that = this,\n html = \u0027\u0027,\n i, j, option, selected;\n\n for (i = 0; i \u003c this.field.options.length; i++) {\n option = this.field.options[i];\n selected = false;\n\n if (this.field.multiple) {\n // Check if selected\n for (j = 0; j \u003c this.params.length; j++) {\n if (this.params[j] === option.value) {\n selected = true;\n break;\n }\n }\n html += \u0027\u003cli\u003e\u003clabel class=\"h5p-editor-label\"\u003e\u003cinput type=\"checkbox\" value=\"\u0027 + option.value + \u0027\"\u0027 + (selected ? \u0027 checked=\"checked\"\u0027 : \u0027\u0027) + \u0027/\u003e\u003cdiv class=\"h5p-label-text\"\u003e\u0027 + option.label + \u0027\u003c/div\u003e\u003c/label\u003e\u003c/li\u003e\u0027;\n }\n else {\n // Check if selected\n if (this.params === option.value) {\n selected = true;\n }\n html += \u0027\u003cli\u003e\u003clabel class=\"h5p-editor-label\"\u003e\u003cinput type=\"radio\" name=\"dynboxradio1\" value=\"\u0027 + option.value + \u0027\"\u0027 + (selected ? \u0027 checked=\"checked\"\u0027 : \u0027\u0027) + \u0027/\u003e\u0027 + option.label + \u0027\u003c/label\u003e\u003c/li\u003e\u0027;\n }\n }\n\n this.$item.html(html ? \u0027\u003cdiv class=\"h5peditor-label\"\u003e\u0027 + this.field.label + \u0027\u003c/div\u003e\u0027 + (this.field.multiple ? \u0027\u003ca href=\"#\" class=\"h5p-selectall\"\u003e\u0027 + H5PEditor.t(\u0027H5PEditor.DragQuestion\u0027, \u0027selectAll\u0027) + \u0027\u003c/a\u003e\u0027 : \u0027\u0027) + \u0027\u003cul class=\"h5peditor-dynamiccheckboxes-select\"\u003e\u0027 + html + \u0027\u003c/ul\u003e\u0027 : \u0027\u0027);\n\n var updateSelectall, $a, $checkboxes = this.$item.find(\u0027input\u0027).change(function () {\n that.change($(this));\n\n // If all is checked change select all button.\n updateSelectAll();\n });\n\n $a = this.$item.find(\u0027.h5p-selectall\u0027).click(function () {\n if ($a.hasClass(\u0027h5p-deselectall\u0027)) {\n $checkboxes.each(function () {\n var $this = $(this);\n if ($this.is(\u0027:checked\u0027)) {\n $this.prop(\u0027checked\u0027, false).change();\n }\n });\n }\n else {\n $checkboxes.each(function () {\n var $this = $(this);\n if (!$this.is(\u0027:checked\u0027)) {\n $this.prop(\u0027checked\u0027, true).change();\n }\n });\n }\n\n return false;\n });\n\n updateSelectAll = function () {\n if ($checkboxes.length) {\n if ($checkboxes.length === $checkboxes.filter(\u0027:checked\u0027).length) {\n $a.addClass(\u0027h5p-deselectall\u0027).text(H5PEditor.t(\u0027H5PEditor.DragQuestion\u0027, \u0027deselectAll\u0027));\n }\n else {\n $a.removeClass(\u0027h5p-deselectall\u0027).text(H5PEditor.t(\u0027H5PEditor.DragQuestion\u0027, \u0027selectAll\u0027));\n }\n }\n };\n updateSelectAll();\n };\n\n /**\n * Update params with changes to checkbox.\n *\n * @param {jQuery} $input\n * @returns {undefined}\n */\n C.prototype.change = function ($input) {\n var i, value = $input.val();\n\n if (this.field.multiple) {\n if ($input.is(\u0027:checked\u0027)) {\n this.params.push(value);\n }\n else {\n for (i = 0; i \u003c this.params.length; i++) {\n if (this.params[i] === value) {\n this.params.splice(i, 1);\n }\n }\n }\n }\n else {\n if ($input.is(\u0027:checked\u0027)) {\n this.params = value;\n this.setValue(this.field, value);\n }\n }\n };\n\n /**\n * Validate the current field.\n *\n * @returns {Boolean}\n */\n C.prototype.validate = function () {\n return true;\n };\n\n /**\n *\n * @returns {undefined}\n */\n C.prototype.remove = function () {\n this.$item.remove();\n };\n\n return C;\n})(H5P.jQuery);\n\n// Get translations from H5PEditor.DragQuestion\n"
,"h5p-drag-question.js":"!function(e){function t(o){if(n[o])return n[o].exports;var i=n[o]={i:o,l:!1,exports:{}};return e[o].call(i.exports,i,i.exports,t),i.l=!0,i.exports}var n={};t.m=e,t.c=n,t.d=function(e,n,o){t.o(e,n)||Object.defineProperty(e,n,{configurable:!1,enumerable:!0,get:o})},t.n=function(e){var n=e\u0026\u0026e.__esModule?function(){return e.default}:function(){return e};return t.d(n,\"a\",n),n},t.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},t.p=\"\",t(t.s=3)}([function(e,t,n){\"use strict\";Object.defineProperty(t,\"__esModule\",{value:!0});var o=t.curry=function(e){var t=e.length;return function n(){var o=Array.prototype.slice.call(arguments,0);return o.length\u003e=t?e.apply(null,o):function(){var e=Array.prototype.slice.call(arguments,0);return n.apply(null,o.concat(e))}}},i=(t.compose=function(){for(var e=arguments.length,t=Array(e),n=0;n\u003ce;n++)t[n]=arguments[n];return t.reduce(function(e,t){return function(){return e(t.apply(void 0,arguments))}})},t.forEach=o(function(e,t){t.forEach(e)}),t.map=o(function(e,t){return t.map(e)}),t.filter=o(function(e,t){return t.filter(e)})),r=(t.some=o(function(e,t){return t.some(e)}),t.contains=o(function(e,t){return-1!=t.indexOf(e)}));t.without=o(function(e,t){return i(function(t){return!r(t,e)},t)}),t.inverseBooleanString=function(e){return(\"true\"!==e).toString()}},function(e,t,n){\"use strict\";Object.defineProperty(t,\"__esModule\",{value:!0}),t.createElement=t.toggleClass=t.toggleVisibility=t.show=t.hide=t.removeClass=t.addClass=t.classListContains=t.removeChild=t.querySelectorAll=t.nodeListToArray=t.querySelector=t.appendChild=t.toggleAttribute=t.attributeEquals=t.hasAttribute=t.removeAttribute=t.setAttribute=t.getAttribute=void 0;var o=n(0),i=t.getAttribute=(0,o.curry)(function(e,t){return t.getAttribute(e)}),r=t.setAttribute=(0,o.curry)(function(e,t,n){return n.setAttribute(e,t)}),a=(t.removeAttribute=(0,o.curry)(function(e,t){return t.removeAttribute(e)}),t.hasAttribute=(0,o.curry)(function(e,t){return t.hasAttribute(e)}),t.attributeEquals=(0,o.curry)(function(e,t,n){return n.getAttribute(e)===t}),t.toggleAttribute=(0,o.curry)(function(e,t){var n=i(e,t);r(e,(0,o.inverseBooleanString)(n),t)}),t.appendChild=(0,o.curry)(function(e,t){return e.appendChild(t)}),t.querySelector=(0,o.curry)(function(e,t){return t.querySelector(e)}),t.nodeListToArray=function(e){return Array.prototype.slice.call(e)}),s=(t.querySelectorAll=(0,o.curry)(function(e,t){return a(t.querySelectorAll(e))}),t.removeChild=(0,o.curry)(function(e,t){return e.removeChild(t)}),t.classListContains=(0,o.curry)(function(e,t){return t.classList.contains(e)}),t.addClass=(0,o.curry)(function(e,t){return t.classList.add(e)})),l=t.removeClass=(0,o.curry)(function(e,t){return t.classList.remove(e)}),u=t.hide=s(\"hidden\"),c=t.show=l(\"hidden\");t.toggleVisibility=(0,o.curry)(function(e,t){return(e?c:u)(t)}),t.toggleClass=(0,o.curry)(function(e,t,n){n.classList[t?\"add\":\"remove\"](e)}),t.createElement=function(e){var t=e.tag,n=e.id,o=e.classes,i=e.attributes,r=document.createElement(t);return n\u0026\u0026(r.id=n),o\u0026\u0026o.forEach(function(e){r.classList.add(e)}),i\u0026\u0026Object.keys(i).forEach(function(e){r.setAttribute(e,i[e])}),r}},function(e,t,n){\"use strict\";function o(e,t){if(!(e instanceof t))throw new TypeError(\"Cannot call a class as a function\")}Object.defineProperty(t,\"__esModule\",{value:!0});var i=function(){function e(e,t){for(var n=0;n\u003ct.length;n++){var o=t[n];o.enumerable=o.enumerable||!1,o.configurable=!0,\"value\"in o\u0026\u0026(o.writable=!0),Object.defineProperty(e,o.key,o)}}return function(t,n,o){return n\u0026\u0026e(t.prototype,n),o\u0026\u0026e(t,o),t}}(),r=function(){function e(){o(this,e)}return i(e,null,[{key:\"setElementOpacity\",value:function(t,n){e.setOpacity(t,\"borderColor\",n),e.setOpacity(t,\"boxShadow\",n),e.setOpacity(t,\"background\",n)}},{key:\"setOpacity\",value:function(t,n,o){function i(e,t){switch(e){case\"borderColor\":return{borderTopColor:t,borderRightColor:t,borderBottomColor:t,borderLeftColor:t};default:var n={};return n[e]=t,n}}if(\"background\"===n)return e.setOpacity(t,\"backgroundColor\",o),void e.setOpacity(t,\"backgroundImage\",o);o=void 0===o?1:o/100;var r=t.css(n),a=i(n,\"\");t.css(a);for(var s in a)break;var l=t.css(s);\"\"!==l\u0026\u0026\"none\"!==l||(l=r),l=e.setAlphas(l,\"rgba(\",o),l=e.setAlphas(l,\"rgb(\",o),t.css(i(n,l))}},{key:\"setAlphas\",value:function(e,t,n){if(e){for(var o=e.indexOf(t);-1!==o;){var i=e.indexOf(\")\",o),r=e.substring(o+t.length,i).split(\",\");r[3]=void 0!==r[3]?parseFloat(r[3])*n:n,e=e.substring(0,o)+\"rgba(\"+r.join(\",\")+e.substring(i,e.length),o=e.indexOf(t,i)}return e}}},{key:\"elementToDraggable\",value:function(e,t){for(var n=0;n\u003ce.length;n++)if(e[n]){var o=e[n].findElement(t);if(o)return o.draggable=e[n],o}}},{key:\"elementToDropZone\",value:function(e,t){for(var n=0;n\u003ce.length;n++)if(e[n].$dropZone.is(t))return e[n]}},{key:\"positionToPercentage\",value:function(e,t){return{top:100*parseInt(t.css(\"top\"))/e.innerHeight()+\"%\",left:100*parseInt(t.css(\"left\"))/e.innerWidth()+\"%\"}}},{key:\"addHover\",value:function(t,n){t.hover(function(){t.addClass(\"h5p-draggable-hover\"),t.parent().hasClass(\"h5p-dragging\")||e.setElementOpacity(t,n)},function(){t.parent().hasClass(\"h5p-dragging\")||setTimeout(function(){t.removeClass(\"h5p-draggable-hover\"),e.setElementOpacity(t,n)},1)}),e.setElementOpacity(t,n)}},{key:\"strip\",value:function(e){var t=document.createElement(\"div\");return t.innerHTML=e,t.textContent||t.innerText||\"\"}}]),e}();t.default=r},function(e,t,n){\"use strict\";function o(e){return e\u0026\u0026e.__esModule?e:{default:e}}function i(e,t,n){var o,i,r=this;w++,this.id=this.contentId=t,H5P.Question.call(r,\"dragquestion\"),this.options=y.extend(!0,{},{scoreShow:\"Check\",tryAgain:\"Retry\",grabbablePrefix:\"Grabbable {num} of {total}.\",grabbableSuffix:\"Placed in dropzone {num}.\",dropzonePrefix:\"Dropzone {num} of {total}.\",noDropzone:\"No dropzone\",tipLabel:\"Show tip.\",tipAvailable:\"Tip available\",correctAnswer:\"Correct answer\",wrongAnswer:\"Wrong answer\",feedbackHeader:\"Feedback\",scoreBarLabel:\"You got :num out of :total points\",scoreExplanationButtonLabel:\"Show score explanation\",question:{settings:{questionTitle:\"Drag and drop\",showTitle:!0,size:{width:620,height:310}},task:{elements:[],dropZones:[]}},overallFeedback:[],behaviour:{enableRetry:!0,preventResize:!1,singlePoint:!1,showSolutionsRequiresInput:!0,applyPenalties:!0,enableScoreExplanation:!0,dropZoneHighlighting:\"dragging\",autoAlignSpacing:2,showScorePoints:!0}},e),this.options.behaviour.singlePoint\u0026\u0026(this.options.behaviour.enableScoreExplanation=!1),this.draggables=[],this.dropZones=[],this.answered=n\u0026\u0026void 0!==n.previousState\u0026\u0026void 0!==n.previousState.answers\u0026\u0026n.previousState.answers.length,this.blankIsCorrect=!0,this.backgroundOpacity=void 0===this.options.behaviour.backgroundOpacity||\"\"===this.options.behaviour.backgroundOpacity.trim()?void 0:this.options.behaviour.backgroundOpacity,r.$noDropZone=y(\u0027\u003cdiv class=\"h5p-dq-no-dz\" role=\"button\" style=\"display:none;\"\u003e\u003cspan class=\"h5p-hidden-read\"\u003e\u0027+r.options.noDropzone+\"\u003c/span\u003e\u003c/div\u003e\");var a=k(r.draggables,r.dropZones,r.$noDropZone[0]),s=function(e){for(var t=0;t\u003ca.drop.elements.length;t++)a.drop.elements[t].setAttribute(\"aria-dropeffect\",e)},l=[],u=this.options.question.task;for(this.correctDZs=[],o=0;o\u003cu.dropZones.length;o++){l.push(!0);var c=u.dropZones[o].correctElements;for(i=0;i\u003cc.length;i++){var d=c[i];void 0===this.correctDZs[d]\u0026\u0026(this.correctDZs[d]=[]),this.correctDZs[d].push(o)}}this.weight=1;var h={prefix:r.options.grabbablePrefix.replace(\"{total}\",u.elements.length),suffix:r.options.grabbableSuffix,correctAnswer:r.options.correctAnswer,wrongAnswer:r.options.wrongAnswer};for(o=0;o\u003cu.elements.length;o++){var p=u.elements[o];if(void 0!==p.dropZones\u0026\u0026p.dropZones.length){void 0!==this.backgroundOpacity\u0026\u0026(p.backgroundOpacity=this.backgroundOpacity);var g=null;n\u0026\u0026void 0!==n.previousState\u0026\u0026void 0!==n.previousState.answers\u0026\u0026void 0!==n.previousState.answers[o]\u0026\u0026(g=n.previousState.answers[o]);var v=new m.default(p,o,g,h),x=\"dragging\"===r.options.behaviour.dropZoneHighlighting;for(v.on(\"elementadd\",function(e){a.drag.addElement(e.data)}),v.on(\"elementremove\",function(e){a.drag.removeElement(e.data),\"true\"===e.data.getAttribute(\"aria-grabbed\")\u0026\u0026(a.drag.firesEvent(\"select\",e.data),e.data.removeAttribute(\"aria-grabbed\"))}),v.on(\"focus\",function(e){a.drag.setTabbable(e.data),e.data.focus()}),v.on(\"dragstart\",function(e){x\u0026\u0026r.$container.addClass(\"h5p-dq-highlight-dz\"),s(e.data)}),v.on(\"dragend\",function(){x\u0026\u0026r.$container.removeClass(\"h5p-dq-highlight-dz\"),s(\"none\")}),v.on(\"interacted\",function(){r.answered=!0,r.triggerXAPIScored(r.getScore(),r.getMaxScore(),\"interacted\")}),v.on(\"leavingDropZone\",function(e){r.dropZones[e.data.dropZone].removeAlignable(e.data.$)}),this.draggables[o]=v,i=0;i\u003cp.dropZones.length;i++)l[p.dropZones[i]]=!1}}this.numDropZonesWithoutElements=0;var E={prefix:r.options.dropzonePrefix.replace(\"{total}\",u.dropZones.length),tipLabel:r.options.tipLabel,tipAvailable:r.options.tipAvailable};for(o=0;o\u003cu.dropZones.length;o++){var A=u.dropZones[o];!0===l[o]\u0026\u0026(this.numDropZonesWithoutElements+=1),this.blankIsCorrect\u0026\u0026A.correctElements.length\u0026\u0026(this.blankIsCorrect=!1),A.autoAlign={enabled:A.autoAlign,spacing:r.options.behaviour.autoAlignSpacing,size:r.options.question.settings.size},this.dropZones[o]=new b.default(A,o,E),this.dropZones[o].on(\"elementaligned\",function(e){for(var t=e.data,n=0;n\u003cr.draggables.length;n++){var o=r.draggables[n];if(o\u0026\u0026o.elements\u0026\u0026o.elements.length)for(var i=0;i\u003co.elements.length;i++){var a=o.elements[i];if(a\u0026\u0026a.$[0]===t[0])return void(a.position=f.default.positionToPercentage(r.$container,a.$))}}})}this.on(\"resize\",r.resize,r),this.on(\"domChanged\",function(e){r.contentId===e.data.contentId\u0026\u0026r.trigger(\"resize\")}),this.on(\"enterFullScreen\",function(){r.$container\u0026\u0026(r.$container.parents(\".h5p-content\").css(\"height\",\"100%\"),r.trigger(\"resize\"))}),this.on(\"exitFullScreen\",function(){r.$container\u0026\u0026(r.$container.parents(\".h5p-content\").css(\"height\",\"auto\"),r.trigger(\"resize\"))})}var r=n(4),a=o(r),s=n(6),l=o(s),u=n(7),c=o(u),d=n(8),h=o(d),p=n(2),f=o(p),g=n(9),b=o(g),v=n(10),m=o(v),y=H5P.jQuery,w=0;i.prototype=Object.create(H5P.Question.prototype),i.prototype.constructor=i,i.prototype.registerDomElements=function(){var e=this;e.options.question.settings.showTitle\u0026\u0026(e.$introduction=y(\u0027\u003cp class=\"h5p-dragquestion-introduction\" id=\"dq-intro-\u0027+w+\u0027\"\u003e\u0027+e.options.question.settings.questionTitle+\"\u003c/p\u003e\"),e.setIntroduction(e.$introduction));var t=\"\";if(void 0!==this.options.question.settings.background\u0026\u0026(t+=\"h5p-dragquestion-has-no-background\"),\"always\"===e.options.behaviour.dropZoneHighlighting\u0026\u0026(t\u0026\u0026(t+=\" \"),t+=\"h5p-dq-highlight-dz-always\"),e.setContent(e.createQuestionContent(),{class:t}),!1!==H5P.canHasFullScreen\u0026\u0026this.options.behaviour.enableFullScreen){var n=function(){H5P.isFullscreen?H5P.exitFullScreen(e.$container):H5P.fullScreen(e.$container.parent().parent(),e)},o=y(\"\u003cdiv/\u003e\",{class:\"h5p-my-fullscreen-button-enter\",title:this.options.localize.fullscreen,role:\"button\",tabindex:0,on:{click:n,keypress:function(e){13!==e.which\u0026\u002632!==e.which||(n(),e.preventDefault())}},prependTo:this.$container.parent()});this.on(\"enterFullScreen\",function(){o.attr(\"class\",\"h5p-my-fullscreen-button-exit\"),o.attr(\"title\",this.options.localize.exitFullscreen)}),this.on(\"exitFullScreen\",function(){o.attr(\"class\",\"h5p-my-fullscreen-button-enter\"),o.attr(\"title\",this.options.localize.fullscreen)})}e.registerButtons(),setTimeout(function(){e.trigger(\"resize\")},200)},i.prototype.getXAPIData=function(){var e=this.createXAPIEventTemplate(\"answered\");return this.addQuestionToXAPI(e),this.addResponseToXAPI(e),{statement:e.data.statement}},i.prototype.addQuestionToXAPI=function(e){var t=e.getVerifiedStatementValue([\"object\",\"definition\"]);y.extend(t,this.getXAPIDefinition())},i.prototype.getXAPIDefinition=function(){var e={};e.description={\"en-US\":y(\"\u003cdiv\u003e\"+this.options.question.settings.questionTitle+\"\u003c/div\u003e\").text()},e.type=\"http://adlnet.gov/expapi/activities/cmi.interaction\",e.interactionType=\"matching\",e.source=[];for(var t=0;t\u003cthis.options.question.task.elements.length;t++){var n=this.options.question.task.elements[t];if(n.dropZones\u0026\u0026n.dropZones.length){var o=n.type.params.alt?n.type.params.alt:n.type.params.text;e.source.push({id:\"\"+t,description:{\"en-US\":y(\"\u003cdiv\u003e\"+o+\"\u003c/div\u003e\").text()}})}}e.correctResponsesPattern=[\"\"],e.target=[];var i=!0;for(t=0;t\u003cthis.options.question.task.dropZones.length;t++)if(e.target.push({id:\"\"+t,description:{\"en-US\":y(\"\u003cdiv\u003e\"+this.options.question.task.dropZones[t].label+\"\u003c/div\u003e\").text()}}),this.options.question.task.dropZones[t].correctElements)for(var r=0;r\u003cthis.options.question.task.dropZones[t].correctElements.length;r++)i||(e.correctResponsesPattern[0]+=\"[,]\"),e.correctResponsesPattern[0]+=t+\"[.]\"+this.options.question.task.dropZones[t].correctElements[r],i=!1;return e},i.prototype.addResponseToXAPI=function(e){var t=this.getMaxScore(),n=this.getScore(),o=n==t;e.setScoredResult(n,t,this,!0,o),e.data.statement.result.response=this.getUserXAPIResponse()},i.prototype.getUserXAPIResponse=function(){var e=this.getUserAnswers();return e?e.filter(function(e){return e.elements.length}).map(function(e,t){return e.elements.filter(function(e){return void 0!==e.dropZone}).map(function(e){return e.dropZone+\"[.]\"+t}).join(\"[,]\")}).filter(function(e){return void 0!==e\u0026\u0026\"\"!==e}).join(\"[,]\"):\"\"},i.prototype.getUserAnswers=function(){return this.draggables.map(function(e,t){return{index:t,draggable:e}}).filter(function(e){return void 0!==e.draggable\u0026\u0026e.draggable.elements}).map(function(e){return{index:e.index,elements:e.draggable.elements}})},i.prototype.createQuestionContent=function(){var e;this.$container=y(\u0027\u003cdiv class=\"h5p-inner\" role=\"application\" aria-labelledby=\"dq-intro-\u0027+w+\u0027\"\u003e\u003c/div\u003e\u0027),void 0!==this.options.question.settings.background\u0026\u0026this.$container.css(\"backgroundImage\",\u0027url(\"\u0027+H5P.getPath(this.options.question.settings.background.path,this.id)+\u0027\")\u0027);var t=this.options.question.task;for(e=0;e\u003ct.elements.length;e++){var n=t.elements[e];if(void 0!==n.dropZones\u0026\u00260!==n.dropZones.length)this.draggables[e].appendTo(this.$container,this.id);else{var o=this.addElement(n,\"static\",e);H5P.newRunnable(n.type,this.id,o);!function(e,t){setTimeout(function(){f.default.setOpacity(e,\"background\",t.backgroundOpacity)},0)}(o,n)}}for(this.$noDropZone.appendTo(this.$container),e=0;e\u003cthis.dropZones.length;e++)this.dropZones[e].appendTo(this.$container,this.draggables);return this.$container},i.prototype.registerButtons=function(){this.addSolutionButton(),this.addRetryButton()},i.prototype.addSolutionButton=function(){var e=this;this.addButton(\"check-answer\",this.options.scoreShow,function(){e.answered=!0,e.showAllSolutions(),e.showScore(),e.addExplanation();var t=e.createXAPIEventTemplate(\"answered\");e.addQuestionToXAPI(t),e.addResponseToXAPI(t),e.trigger(t),(e.$introduction?e.$introduction:e.$container.children().first()).focus()})},i.prototype.addExplanation=function(){var e=this,t=this.options.question.task,n=[];t.dropZones.forEach(function(t,o){var i={correct:t.tipsAndFeedback.feedbackOnCorrect,incorrect:t.tipsAndFeedback.feedbackOnIncorrect};if(void 0!==i.correct||void 0!==i.incorrect){var r=t.correctElements,a={};e.draggables.forEach(function(e){e.elements.forEach(function(t){t.dropZone==o\u0026\u0026(a[e.id]={instance:e,correct:-1!==r.indexOf(\"\"+e.id)})})}),Object.keys(a).forEach(function(e){var r=a[e],s=f.default.strip(r.instance.type.params.alt||r.instance.type.params.text)||\"?\",l=f.default.strip(t.label);r.correct\u0026\u0026i.correct?(n.push({correct:l+\" + \"+s,text:i.correct}),r.instance.setFeedback(i.correct,o)):!r.correct\u0026\u0026i.incorrect\u0026\u0026(n.push({correct:l+\" + \",wrong:s,text:i.incorrect}),r.instance.setFeedback(i.incorrect,o))})}}),0!==n.length\u0026\u0026this.setExplanation(n,this.options.feedbackHeader)},i.prototype.addRetryButton=function(){var e=this;this.addButton(\"try-again\",this.options.tryAgain,function(){e.resetTask(),e.showButton(\"check-answer\"),e.hideButton(\"try-again\")},!1)},i.prototype.addElement=function(e,t,n){return y(\u0027\u003cdiv class=\"h5p-\u0027+t+\u0027\" style=\"left:\u0027+e.x+\"%;top:\"+e.y+\"%;width:\"+e.width+\"em;height:\"+e.height+\u0027em\"\u003e\u003c/div\u003e\u0027).appendTo(this.$container).data(\"id\",n)},i.prototype.resize=function(e){var t=this;if(void 0!==this.$container\u0026\u0026this.$container.is(\":visible\")){var n=e\u0026\u0026e.data\u0026\u0026e.data.decreaseSize;n||(this.$container.css(\"height\",\"99999px\"),t.$container.parents(\".h5p-standalone.h5p-dragquestion\").css(\"width\",\"\"));var o=this.options.question.settings.size,i=o.width/o.height,r=this.$container.parent(),a=r.width()-parseFloat(r.css(\"margin-left\"))-parseFloat(r.css(\"margin-right\")),s=t.$container.parents(\".h5p-standalone.h5p-dragquestion.h5p-semi-fullscreen\");if(s.length){s.css(\"width\",\"\"),n||(t.$container.css(\"width\",\"10px\"),s.css(\"width\",\"\"),setTimeout(function(){t.trigger(\"resize\",{decreaseSize:!0})},200));var l=y(window.frameElement);if(l){a=l.parent().width(),s.css(\"width\",a+\"px\")}}var u=a/i;a\u003c=0\u0026\u0026(a=o.width,u=o.height),this.$container.css({width:a+\"px\",height:u+\"px\",fontSize:a/o.width*16+\"px\"})}},i.prototype.disableDraggables=function(){this.draggables.forEach(function(e){e.disable()})},i.prototype.enableDraggables=function(){this.draggables.forEach(function(e){e.enable()})},i.prototype.getDropzoneWithoutAnswer=function(e,t){var n=[];return t.forEach(function(e){e.length\u0026\u0026e.forEach(function(e){n.indexOf(e)\u003c0\u0026\u0026n.push(e)})}),e-n.length-this.numDropZonesWithoutElements},i.prototype.showAllSolutions=function(e){this.points=0,this.rawPoints=0;var t=this.getDropzoneWithoutAnswer(this.dropZones.length,this.correctDZs);this.points+=t,this.rawPoints+=t;var n;!e\u0026\u0026this.options.behaviour.showScorePoints\u0026\u0026!this.options.behaviour.singlePoint\u0026\u0026this.options.behaviour.applyPenalties\u0026\u0026(n=new H5P.Question.ScorePoints);for(var o=0;o\u003cthis.draggables.length;o++){var i=this.draggables[o];void 0!==i\u0026\u0026(e||i.disable(),this.points+=i.results(e,this.correctDZs[o],n),this.rawPoints+=i.rawPoints)}this.points\u003c0\u0026\u0026(this.points=0),!this.answered\u0026\u0026this.blankIsCorrect\u0026\u0026(this.points=this.weight),this.options.behaviour.singlePoint\u0026\u0026(this.points=this.points===this.calculateMaxScore()?1:0),e||this.hideButton(\"check-answer\"),this.options.behaviour.enableRetry\u0026\u0026!e\u0026\u0026this.showButton(\"try-again\"),!this.hasButton(\"check-answer\")||!1!==this.options.behaviour.enableRetry\u0026\u0026this.points!==this.getMaxScore()||this.hideButton(\"try-again\")},i.prototype.showSolutions=function(){this.showAllSolutions(),this.showScore(),this.hideButton(\"check-answer\"),this.hideButton(\"try-again\"),this.disableDraggables()},i.prototype.resetTask=function(){this.points=0,this.rawPoints=0,this.answered=!1,this.enableDraggables(),this.draggables.forEach(function(e){e.resetPosition()}),this.showButton(\"check-answer\"),this.hideButton(\"try-again\"),this.removeFeedback(),this.setExplanation()},i.prototype.calculateMaxScore=function(){var e=0;if(this.blankIsCorrect)return this.getDropzoneWithoutAnswer(this.dropZones.length,this.correctDZs);e+=this.getDropzoneWithoutAnswer(this.dropZones.length,this.correctDZs);for(var t=this.options.question.task.elements,n=0;n\u003ct.length;n++){var o=this.correctDZs[n];void 0!==o\u0026\u0026o.length\u0026\u0026(t[n].multiple?e+=o.length:e++)}return e},i.prototype.getMaxScore=function(){return this.options.behaviour.singlePoint?this.weight:this.calculateMaxScore()},i.prototype.getScore=function(){this.showAllSolutions(!0);var e=this.options.behaviour.applyPenalties||this.options.behaviour.singlePoint?this.points:this.rawPoints;return delete this.points,delete this.rawPoints,e},i.prototype.getAnswerGiven=function(){return!this.options.behaviour.showSolutionsRequiresInput||this.answered||this.blankIsCorrect},i.prototype.showScore=function(){var e=this.calculateMaxScore();this.options.behaviour.singlePoint\u0026\u0026(e=1);var t=this.options.behaviour.applyPenalties||this.options.behaviour.singlePoint?this.points:this.rawPoints,n=H5P.Question.determineOverallFeedback(this.options.overallFeedback,t/e).replace(\"@score\",t).replace(\"@total\",e),o=!(!this.options.behaviour.enableScoreExplanation||!this.options.behaviour.applyPenalties)\u0026\u0026this.options.scoreExplanation;this.setFeedback(n,t,e,this.options.scoreBarLabel,o,void 0,this.options.scoreExplanationButtonLabel)},i.prototype.getCurrentState=function(){for(var e={answers:[]},t=0;t\u003cthis.draggables.length;t++){var n=this.draggables[t];if(void 0!==n){for(var o=[],i=0;i\u003cn.elements.length;i++){var r=n.elements[i];void 0!==r\u0026\u0026void 0!==r.dropZone\u0026\u0026o.push({x:Number(r.position.left.replace(\"%\",\"\")),y:Number(r.position.top.replace(\"%\",\"\")),dz:r.dropZone})}o.length\u0026\u0026(e.answers[t]=o)}}return e},i.prototype.getCopyrights=function(){var e=this,t=new H5P.ContentCopyrights,n=e.options.question.settings.background;if(void 0!==n\u0026\u0026void 0!==n.copyright){var o=new H5P.MediaCopyright(n.copyright);o.setThumbnail(new H5P.Thumbnail(H5P.getPath(n.path,e.id),n.width,n.height)),t.addMedia(o)}for(var i=0;i\u003ce.options.question.task.elements.length;i++){var r=e.options.question.task.elements[i],a=H5P.newRunnable(r.type,e.id);if(void 0!==a.getCopyrights){var s=a.getCopyrights();s.setLabel((r.dropZones.length?\"Draggable \":\"Static \")+(void 0!==r.type.params.contentName?r.type.params.contentName:\"element\")),t.addContent(s)}}return t},i.prototype.getTitle=function(){return H5P.createTitle(this.options.question.settings.questionTitle)};var k=function(e,t,n){var o={drag:new a.default([new h.default,new l.default]),drop:new a.default([new h.default,new c.default])};o.drag.useNegativeTabIndex(),o.drop.useNegativeTabIndex();var i,r=function(){i.draggable.trigger(\"dragend\"),i.element.$.removeClass(\"h5p-draggable-hover\"),f.default.setElementOpacity(i.element.$,i.draggable.backgroundOpacity),-1!==o.drop.elements.indexOf(n)\u0026\u0026(o.drop.removeElement(n),n.style.display=\"none\");for(var e=0;e\u003ct.length;e++){var r=t[e];r.dehighlight(),-1!==o.drop.elements.indexOf(r.$dropZone[0])\u0026\u0026o.drop.removeElement(r.$dropZone[0])}if(i.element.$.is(\":visible\"))i.element.$.focus();else{var a=i.draggable.elements[i.draggable.elements.length-1].$;o.drag.setTabbable(a[0]),a.focus()}i=void 0};return o.drag.on(\"select\",function(a){var s=f.default.elementToDraggable(e,a.element);if(i)return void r();i=s,i.element.$.addClass(\"h5p-draggable-hover\"),f.default.setElementOpacity(i.element.$,i.draggable.backgroundOpacity),i.draggable.trigger(\"dragstart\",i.draggable.mustCopyElement(i.element)?\"copy\":\"move\"),o.drop.addElement(n),n.style.display=\"block\",n.style.left=i.draggable.x+\"%\",n.style.top=i.draggable.y+\"%\",n.style.width=i.draggable.width+\"em\",n.style.height=i.draggable.height+\"em\";for(var l,u=0;u\u003ct.length;u++){var c=t[u];c.accepts(i.draggable,e)\u0026\u0026(c.highlight(),o.drop.addElement(c.$dropZone[0]),l\u0026\u0026i.element.dropZone!==c.id||(l=c.$dropZone))}l\u0026\u0026(o.drop.setTabbable(l[0]),l.focus())}),o.drop.on(\"select\",function(e){if(i){if(e.element===n)return void 0!==i.element.dropZone\u0026\u0026i.element.reset(),i.draggable.multiple||(i.element.$.css({left:i.draggable.x+\"%\",top:i.draggable.y+\"%\",width:i.draggable.width+\"em\",height:i.draggable.height+\"em\"}),i.draggable.updatePlacement(i.element)),i.element.$[0].setAttribute(\"aria-grabbed\",\"false\"),void r();var o=f.default.elementToDropZone(t,e.element);i.draggable.mustCopyElement(i.element)\u0026\u0026i.element.clone(),i.draggable.addToDropZone(i.index,i.element,o.id),i.element.$.css({left:o.x+\"%\",top:o.y+\"%\"}),-1===o.getIndexOf(i.element.$)\u0026\u0026o.alignables.push(i.element.$),o.autoAlign(),i.element.$[0].setAttribute(\"aria-grabbed\",\"false\"),r()}}),o};H5P.DragQuestion=i},function(e,t,n){\"use strict\";function o(e,t){if(!(e instanceof t))throw new TypeError(\"Cannot call a class as a function\")}Object.defineProperty(t,\"__esModule\",{value:!0});var i=Object.assign||function(e){for(var t=1;t\u003carguments.length;t++){var n=arguments[t];for(var o in n)Object.prototype.hasOwnProperty.call(n,o)\u0026\u0026(e[o]=n[o])}return e},r=function(){function e(e,t){for(var n=0;n\u003ct.length;n++){var o=t[n];o.enumerable=o.enumerable||!1,o.configurable=!0,\"value\"in o\u0026\u0026(o.writable=!0),Object.defineProperty(e,o.key,o)}}return function(t,n,o){return n\u0026\u0026e(t.prototype,n),o\u0026\u0026e(t,o),t}}(),a=n(1),s=n(0),l=n(5),u=(0,a.removeAttribute)(\"tabindex\"),c=((0,s.forEach)(u),(0,a.setAttribute)(\"tabindex\",\"0\")),d=(0,a.setAttribute)(\"tabindex\",\"-1\"),h=(0,a.hasAttribute)(\"tabindex\"),p=function(){function e(t){o(this,e),i(this,(0,l.Eventful)()),this.plugins=t||[],this.elements=[],this.negativeTabIndexAllowed=!1,this.on(\"nextElement\",this.nextElement,this),this.on(\"previousElement\",this.previousElement,this),this.initPlugins()}return r(e,[{key:\"addElement\",value:function(e){this.elements.push(e),this.firesEvent(\"addElement\",e),1===this.elements.length\u0026\u0026this.setTabbable(e)}},{key:\"removeElement\",value:function(e){this.elements=(0,s.without)([e],this.elements),h(e)\u0026\u0026(this.setUntabbable(e),this.elements[0]\u0026\u0026this.setTabbable(this.elements[0])),this.firesEvent(\"removeElement\",e)}},{key:\"firesEvent\",value:function(e,t){var n=this.elements.indexOf(t);return this.fire(e,{element:t,index:n,elements:this.elements,oldElement:this.tabbableElement})}},{key:\"nextElement\",value:function(e){var t=e.index,n=t===this.elements.length-1,o=this.elements[n?0:t+1];this.setTabbable(o),o.focus()}},{key:\"setTabbable\",value:function(e){(0,s.forEach)(this.setUntabbable.bind(this),this.elements),c(e),this.tabbableElement=e}},{key:\"setUntabbable\",value:function(e){this.negativeTabIndexAllowed?d(e):u(e)}},{key:\"previousElement\",value:function(e){var t=e.index,n=0===t,o=this.elements[n?this.elements.length-1:t-1];this.setTabbable(o),o.focus()}},{key:\"useNegativeTabIndex\",value:function(){this.negativeTabIndexAllowed=!0,this.elements.forEach(function(e){e.hasAttribute(\"tabindex\")||d(e)})}},{key:\"initPlugins\",value:function(){this.plugins.forEach(function(e){void 0!==e.init\u0026\u0026e.init(this)},this)}}]),e}();t.default=p},function(e,t,n){\"use strict\";Object.defineProperty(t,\"__esModule\",{value:!0});t.Eventful=function(){return{listeners:{},on:function(e,t,n){var o={listener:t,scope:n};return this.listeners[e]=this.listeners[e]||[],this.listeners[e].push(o),this},fire:function(e,t){return(this.listeners[e]||[]).every(function(e){return!1!==e.listener.call(e.scope||this,t)})},propagate:function(e,t){var n=this;e.forEach(function(e){return t.on(e,function(t){return n.fire(e,t)})})}}}},function(e,t,n){\"use strict\";function o(e,t){if(!(e instanceof t))throw new TypeError(\"Cannot call a class as a function\")}Object.defineProperty(t,\"__esModule\",{value:!0});var i=function(){function e(e,t){for(var n=0;n\u003ct.length;n++){var o=t[n];o.enumerable=o.enumerable||!1,o.configurable=!0,\"value\"in o\u0026\u0026(o.writable=!0),Object.defineProperty(e,o.key,o)}}return function(t,n,o){return n\u0026\u0026e(t.prototype,n),o\u0026\u0026e(t,o),t}}(),r=n(1),a=n(0),s=(0,r.setAttribute)(\"aria-grabbed\"),l=(0,r.attributeEquals)(\"aria-grabbed\",\"true\"),u=(0,a.filter)((0,r.hasAttribute)(\"aria-grabbed\")),c=(0,a.compose)((0,a.forEach)((0,r.setAttribute)(\"aria-grabbed\",\"false\")),u),d=(0,a.compose)((0,a.some)(l),u),h=function(){function e(){o(this,e)}return i(e,[{key:\"init\",value:function(e){this.controls=e,this.controls.on(\"select\",this.select,this)}},{key:\"addElement\",value:function(e){s(\"false\",e),this.controls.addElement(e)}},{key:\"setAllGrabbedToFalse\",value:function(){c(this.controls.elements)}},{key:\"hasAnyGrabbed\",value:function(){return d(this.controls.elements)}},{key:\"select\",value:function(e){var t=e.element,n=l(t);this.setAllGrabbedToFalse(),n||s(\"true\",t)}}]),e}();t.default=h},function(e,t,n){\"use strict\";function o(e,t){if(!(e instanceof t))throw new TypeError(\"Cannot call a class as a function\")}Object.defineProperty(t,\"__esModule\",{value:!0});var i=function(){function e(e,t){for(var n=0;n\u003ct.length;n++){var o=t[n];o.enumerable=o.enumerable||!1,o.configurable=!0,\"value\"in o\u0026\u0026(o.writable=!0),Object.defineProperty(e,o.key,o)}}return function(t,n,o){return n\u0026\u0026e(t.prototype,n),o\u0026\u0026e(t,o),t}}(),r=n(1),a=n(0),s=(0,r.setAttribute)(\"aria-dropeffect\",\"none\"),l=(0,r.setAttribute)(\"aria-dropeffect\",\"move\"),u=(0,a.filter)((0,r.hasAttribute)(\"aria-dropeffect\")),c=(0,a.compose)((0,a.forEach)(l),u),d=(0,a.compose)((0,a.forEach)(s),u),h=function(){function e(){o(this,e)}return i(e,[{key:\"init\",value:function(e){this.controls=e}},{key:\"setAllToMove\",value:function(){c(this.controls.elements)}},{key:\"setAllToNone\",value:function(){d(this.controls.elements)}}]),e}();t.default=h,h.DropEffect={COPY:\"copy\",MOVE:\"move\",EXECUTE:\"execute\",POPUP:\"popup\",NONE:\"none\"}},function(e,t,n){\"use strict\";function o(e,t){if(!(e instanceof t))throw new TypeError(\"Cannot call a class as a function\")}Object.defineProperty(t,\"__esModule\",{value:!0});var i=function(){function e(e,t){for(var n=0;n\u003ct.length;n++){var o=t[n];o.enumerable=o.enumerable||!1,o.configurable=!0,\"value\"in o\u0026\u0026(o.writable=!0),Object.defineProperty(e,o.key,o)}}return function(t,n,o){return n\u0026\u0026e(t.prototype,n),o\u0026\u0026e(t,o),t}}(),r=function(){function e(){o(this,e),this.selectability=!0}return i(e,[{key:\"init\",value:function(e){this.boundHandleKeyDown=this.handleKeyDown.bind(this),this.controls=e,this.controls.on(\"addElement\",this.listenForKeyDown,this),this.controls.on(\"removeElement\",this.removeKeyDownListener,this)}},{key:\"listenForKeyDown\",value:function(e){e.element.addEventListener(\"keydown\",this.boundHandleKeyDown)}},{key:\"removeKeyDownListener\",value:function(e){e.element.removeEventListener(\"keydown\",this.boundHandleKeyDown)}},{key:\"handleKeyDown\",value:function(e){switch(e.which){case 13:case 32:this.select(e.target),e.preventDefault();break;case 37:case 38:this.hasChromevoxModifiers(e)||(this.previousElement(e.target),e.preventDefault());break;case 39:case 40:this.hasChromevoxModifiers(e)||(this.nextElement(e.target),e.preventDefault())}}},{key:\"hasChromevoxModifiers\",value:function(e){return e.shiftKey||e.ctrlKey}},{key:\"previousElement\",value:function(e){this.controls.firesEvent(\"previousElement\",e)}},{key:\"nextElement\",value:function(e){this.controls.firesEvent(\"nextElement\",e)}},{key:\"select\",value:function(e){this.selectability\u0026\u0026!1!==this.controls.firesEvent(\"before-select\",e)\u0026\u0026(this.controls.firesEvent(\"select\",e),this.controls.firesEvent(\"after-select\",e))}},{key:\"disableSelectability\",value:function(){this.selectability=!1}},{key:\"enableSelectability\",value:function(){this.selectability=!0}}]),e}();t.default=r},function(e,t,n){\"use strict\";function o(e,t){if(!(e instanceof t))throw new TypeError(\"Cannot call a class as a function\")}Object.defineProperty(t,\"__esModule\",{value:!0});var i=function(){function e(e,t){for(var n=0;n\u003ct.length;n++){var o=t[n];o.enumerable=o.enumerable||!1,o.configurable=!0,\"value\"in o\u0026\u0026(o.writable=!0),Object.defineProperty(e,o.key,o)}}return function(t,n,o){return n\u0026\u0026e(t.prototype,n),o\u0026\u0026e(t,o),t}}(),r=n(2),a=function(e){return e\u0026\u0026e.__esModule?e:{default:e}}(r),s=H5P.jQuery,l=function(){function e(t,n,i){o(this,e);var r=this;H5P.EventDispatcher.call(r),r.id=n,r.showLabel=t.showLabel,r.label=t.label,r.x=t.x,r.y=t.y,r.width=t.width,r.height=t.height,r.backgroundOpacity=t.backgroundOpacity,r.tip=t.tipsAndFeedback.tip||\"\",r.single=t.single,r.autoAlignable=t.autoAlign,r.alignables=[],r.l10n=i}return i(e,[{key:\"appendTo\",value:function(e,t){var n=this,o=\u0027\u003cdiv class=\"h5p-inner\"\u003e\u003c/div\u003e\u0027,i=\"\";n.showLabel\u0026\u0026(o=\u0027\u003cdiv class=\"h5p-label\"\u003e\u0027+n.label+\u0027\u003cspan class=\"h5p-hidden-read\"\u003e\u003c/span\u003e\u003c/div\u003e\u0027+o,i=\" h5p-has-label\"),o=\u0027\u003cspan class=\"h5p-hidden-read\"\u003e\u0027+n.l10n.prefix.replace(\"{num}\",n.id+1)+\"\u003c/span\u003e\"+o,n.$dropZone=s(\"\u003cdiv/\u003e\",{class:\"h5p-dropzone\"+i,tabindex:\"-1\",role:\"button\",\"aria-disabled\":!0,css:{left:n.x+\"%\",top:n.y+\"%\",width:n.width+\"em\",height:n.height+\"em\"},html:o}).appendTo(e).children(\".h5p-inner\").droppable({activeClass:\"h5p-active\",tolerance:\"intersect\",accept:function(e){var o=a.default.elementToDraggable(t,e);return!!o\u0026\u0026n.accepts(o.draggable,t)},drop:function(e,t){var o=s(this);a.default.setOpacity(o.removeClass(\"h5p-over\"),\"background\",n.backgroundOpacity),t.draggable.data(\"addToZone\",n.id),-1===n.getIndexOf(t.draggable)\u0026\u0026n.alignables.push(t.draggable),n.autoAlignable.enabled\u0026\u0026n.autoAlign()},over:function(){a.default.setOpacity(s(this).addClass(\"h5p-over\"),\"background\",n.backgroundOpacity)},out:function(){a.default.setOpacity(s(this).removeClass(\"h5p-over\"),\"background\",n.backgroundOpacity)}}).end().focus(function(){r instanceof H5P.jQuery\u0026\u0026r.attr(\"tabindex\",\"0\")}).blur(function(){r instanceof H5P.jQuery\u0026\u0026r.attr(\"tabindex\",\"-1\")});var r=H5P.JoubelUI.createTip(n.tip,{tipLabel:n.l10n.tipLabel,tabcontrol:!0});r instanceof H5P.jQuery\u0026\u0026s(\"\u003cspan/\u003e\",{class:\"h5p-dq-tipwrap\",\"aria-label\":n.l10n.tipAvailable,append:r,appendTo:n.$dropZone}),t.forEach(function(e){var t=e.element.$;e.isInDropZone(n.id)\u0026\u0026-1===n.getIndexOf(t)\u0026\u0026n.alignables.push(t)}),n.autoAlignable.enabled\u0026\u0026n.autoAlign(),setTimeout(function(){a.default.setOpacity(n.$dropZone.children(\".h5p-label\"),\"background\",n.backgroundOpacity),a.default.setOpacity(n.$dropZone.children(\".h5p-inner\"),\"background\",n.backgroundOpacity)},0)}},{key:\"accepts\",value:function(e,t){var n=this;if(!e.hasDropZone(n.id))return!1;if(n.single)for(var o=0;o\u003ct.length;o++)if(t[o]\u0026\u0026t[o].isInDropZone(n.id))return!1;return!0}},{key:\"getIndexOf\",value:function(e){for(var t=this,n=0;n\u003ct.alignables.length;n++)if(t.alignables[n][0]===e[0])return n;return-1}},{key:\"removeAlignable\",value:function(e){var t=this,n=t.getIndexOf(e);-1!==n\u0026\u0026(t.alignables.splice(n,1),void 0===t.autoAlignTimer\u0026\u0026(t.autoAlignTimer=setTimeout(function(){delete t.autoAlignTimer,t.autoAlign()},1)))}},{key:\"autoAlign\",value:function(){for(var e,t,n=this,o=n.$dropZone.parent()[0].getBoundingClientRect(),i={x:n.autoAlignable.spacing/n.autoAlignable.size.width*100,y:n.autoAlignable.spacing/n.autoAlignable.size.height*100},r={x:n.x+i.x,y:n.y+i.y},a=n.$dropZone[0].getBoundingClientRect(),s={x:a.width-2*i.x,y:a.height-2*i.y},l={x:s.x,y:s.y},u=0,c=function(){e.css({left:r.x+\"%\",top:r.y+\"%\"}),n.trigger(\"elementaligned\",e);var i=t.width+n.autoAlignable.spacing;l.x-=i,r.x+=i/o.width*100;var a=t.height+n.autoAlignable.spacing;a\u003eu\u0026\u0026(u=a)},d=0;d\u003cn.alignables.length;d++)if(e=n.alignables[d],t=e[0].getBoundingClientRect(),l.x\u003e=t.width)c();else{if(l.x=s.x,r.x=n.x+i.x,u\u0026\u0026(l.y-=u,r.y+=u/o.height*100,u=0),l.y\u003c=0)return;c()}}},{key:\"highlight\",value:function(){this.$dropZone.attr(\"aria-disabled\",\"false\").children(\".h5p-inner\").addClass(\"h5p-active\")}},{key:\"dehighlight\",value:function(){this.$dropZone.attr(\"aria-disabled\",\"true\").children(\".h5p-inner\").removeClass(\"h5p-active\")}}]),e}();t.default=l},function(e,t,n){\"use strict\";function o(e,t){if(!(e instanceof t))throw new TypeError(\"Cannot call a class as a function\")}function i(e,t){if(!e)throw new ReferenceError(\"this hasn\u0027t been initialised - super() hasn\u0027t been called\");return!t||\"object\"!=typeof t\u0026\u0026\"function\"!=typeof t?e:t}function r(e,t){if(\"function\"!=typeof t\u0026\u0026null!==t)throw new TypeError(\"Super expression must either be null or a function, not \"+typeof t);e.prototype=Object.create(t\u0026\u0026t.prototype,{constructor:{value:e,enumerable:!1,writable:!0,configurable:!0}}),t\u0026\u0026(Object.setPrototypeOf?Object.setPrototypeOf(e,t):e.__proto__=t)}Object.defineProperty(t,\"__esModule\",{value:!0});var a=function(){function e(e,t){for(var n=0;n\u003ct.length;n++){var o=t[n];o.enumerable=o.enumerable||!1,o.configurable=!0,\"value\"in o\u0026\u0026(o.writable=!0),Object.defineProperty(e,o.key,o)}}return function(t,n,o){return n\u0026\u0026e(t.prototype,n),o\u0026\u0026e(t,o),t}}(),s=n(2),l=function(e){return e\u0026\u0026e.__esModule?e:{default:e}}(s),u=H5P.jQuery,c=function(e){function t(e,n,r,a){o(this,t);var s=i(this,(t.__proto__||Object.getPrototypeOf(t)).call(this)),l=s;if(l.$=u(l),l.id=n,l.elements=[],l.x=e.x,l.y=e.y,l.width=e.width,l.height=e.height,l.backgroundOpacity=e.backgroundOpacity,l.dropZones=e.dropZones,l.type=e.type,l.multiple=e.multiple,l.l10n=a,r){l.multiple\u0026\u0026l.elements.push({});for(var c=0;c\u003cr.length;c++)l.elements.push({dropZone:r[c].dz,position:{left:r[c].x+\"%\",top:r[c].y+\"%\"}})}return s}return r(t,e),a(t,[{key:\"appendTo\",value:function(e,t){var n=this;if(n.elements.length)for(var o=0;o\u003cn.elements.length;o++)n.attachElement(o,e,t);else n.attachElement(null,e,t)}},{key:\"attachElement\",value:function(e,t,n){var o,i=this;null===e?(o={},i.elements.push(o),e=i.elements.length-1):o=i.elements[e],u.extend(o,{clone:function(){i.attachElement(null,t,n)},reset:function(){void 0!==o.dropZone\u0026\u0026(i.trigger(\"leavingDropZone\",o),delete o.dropZone),i.multiple\u0026\u0026(o.$.remove(),delete i.elements[e],i.trigger(\"elementremove\",o.$[0])),delete o.position}}),o.$=u(\"\u003cdiv/\u003e\",{class:\"h5p-draggable\",tabindex:\"-1\",role:\"button\",css:{left:i.x+\"%\",top:i.y+\"%\",width:i.width+\"em\",height:i.height+\"em\"},appendTo:t}).on(\"click\",function(){i.trigger(\"focus\",this)}).draggable({revert:function(e){t.removeClass(\"h5p-dragging\");var n=u(this);return n.data(\"uiDraggable\").originalPosition={top:i.y+\"%\",left:i.x+\"%\"},i.updatePlacement(o),n[0].setAttribute(\"aria-grabbed\",\"false\"),i.trigger(\"dragend\"),!e},start:function(){var e=u(this),n=i.mustCopyElement(o);n\u0026\u0026o.clone(),e.removeClass(\"h5p-wrong\").detach().appendTo(t),t.addClass(\"h5p-dragging\"),l.default.setElementOpacity(e,i.backgroundOpacity),this.setAttribute(\"aria-grabbed\",\"true\"),i.trigger(\"focus\",this),i.trigger(\"dragstart\",{element:this,effect:n?\"copy\":\"move\"})},stop:function(){var n=u(this);o.position=l.default.positionToPercentage(t,n),n.css(o.position);var r=n.data(\"addToZone\");void 0!==r?(n.removeData(\"addToZone\"),i.addToDropZone(e,o,r)):o.reset()}}).css(\"position\",\"\"),i.element=o,o.position\u0026\u0026(o.$.css(o.position),i.updatePlacement(o)),l.default.addHover(o.$,i.backgroundOpacity),H5P.newRunnable(i.type,n,o.$),u(\u0027\u003cspan class=\"h5p-hidden-read\"\u003e\u0027+i.l10n.prefix.replace(\"{num}\",i.id+1)+\"\u003c/span\u003e\").prependTo(o.$),u(\u0027\u003cspan class=\"h5p-hidden-read\"\u003e\u003c/span\u003e\u0027).appendTo(o.$),setTimeout(function(){l.default.setElementOpacity(o.$,i.backgroundOpacity)},0),i.trigger(\"elementadd\",o.$[0])}},{key:\"setFeedback\",value:function(e,t){this.elements.forEach(function(n){n.dropZone===t\u0026\u0026(void 0===n.$feedback\u0026\u0026(n.$feedback=u(\"\u003cspan\u003e\",{class:\"h5p-hidden-read\",appendTo:n.$})),n.$feedback.html(e))})}},{key:\"mustCopyElement\",value:function(e){return this.multiple\u0026\u0026void 0===e.dropZone}},{key:\"hasDropZone\",value:function(e){for(var t=this,n=0;n\u003ct.dropZones.length;n++)if(parseInt(t.dropZones[n])===e)return!0;return!1}},{key:\"addToDropZone\",value:function(e,t,n){var o=this;if(o.multiple)for(var i=0;i\u003co.elements.length;i++)if(i!==e\u0026\u0026void 0!==o.elements[i]\u0026\u0026o.elements[i].dropZone===n)return void 0!==o.elements[e].dropZone\u0026\u0026o.elements[e].dropZone!==n\u0026\u0026o.trigger(\"leavingDropZone\",t),t.$.remove(),delete o.elements[e],void o.trigger(\"elementremove\",this.element.$[0]);void 0!==t.dropZone\u0026\u0026t.dropZone!==n\u0026\u0026o.trigger(\"leavingDropZone\",t),t.dropZone=n,o.updatePlacement(t),o.trigger(\"interacted\")}},{key:\"updatePlacement\",value:function(e){e.$suffix\u0026\u0026e.$suffix.remove(),void 0!==e.dropZone?(e.$.addClass(\"h5p-dropped\"),l.default.setElementOpacity(e.$,self.backgroundOpacity),e.$suffix=u(\u0027\u003cspan class=\"h5p-hidden-read\"\u003e\u0027+this.l10n.suffix.replace(\"{num}\",e.dropZone+1)+\". \u003c/span\u003e\").appendTo(e.$)):(e.$.removeClass(\"h5p-dropped\").removeClass(\"h5p-wrong\").removeClass(\"h5p-correct\").css({border:\"\",background:\"\"}),l.default.setElementOpacity(e.$,this.backgroundOpacity))}},{key:\"resetPosition\",value:function(){var e=this;this.elements.forEach(function(t){if(t.$feedback\u0026\u0026(t.$feedback.remove(),delete t.$feedback),void 0!==t.dropZone){var n=t.$;n.animate({left:e.x+\"%\",top:e.y+\"%\"},function(){e.multiple\u0026\u0026(void 0!==n.dropZone\u0026\u0026e.trigger(\"leavingDropZone\",n),n.remove(),e.elements.indexOf(t)\u003e=0\u0026\u0026delete e.elements[e.elements.indexOf(t)],e.trigger(\"elementremove\",n[0]))}),e.updatePlacement(t)}}),void 0!==e.element.dropZone\u0026\u0026(e.trigger(\"leavingDropZone\",e.element),delete e.element.dropZone),e.updatePlacement(e.element)}},{key:\"findElement\",value:function(e){for(var t=this,n=0;n\u003ct.elements.length;n++)if(void 0!==t.elements[n]\u0026\u0026t.elements[n].$.is(e))return{element:t.elements[n],index:n}}},{key:\"isInDropZone\",value:function(e){for(var t=this,n=0;n\u003ct.elements.length;n++)if(void 0!==t.elements[n]\u0026\u0026t.elements[n].dropZone===e)return!0;return!1}},{key:\"disable\",value:function(){for(var e=this,t=0;t\u003ce.elements.length;t++){var n=e.elements[t];n\u0026\u0026(n.$.draggable(\"disable\"),e.trigger(\"elementremove\",n.$[0]))}}},{key:\"enable\",value:function(){for(var e=this,t=0;t\u003ce.elements.length;t++){var n=e.elements[t];n\u0026\u0026(n.$.draggable(\"enable\"),e.trigger(\"elementadd\",n.$[0]))}}},{key:\"results\",value:function(e,t,n){var o,i,r,a,s=this,l=0;if(s.rawPoints=0,void 0===t){for(o=0;o\u003cs.elements.length;o++)void 0!==(r=s.elements[o])\u0026\u0026void 0!==r.dropZone\u0026\u0026(!0!==e\u0026\u0026s.markElement(r,\"wrong\",n),l--);return l}for(o=0;o\u003cs.elements.length;o++)if(void 0!==(r=s.elements[o])\u0026\u0026void 0!==r.dropZone){for(a=!1,i=0;i\u003ct.length;i++)if(r.dropZone===t[i]){!0!==e\u0026\u0026s.markElement(r,\"correct\",n),a=!0,s.rawPoints++,l++;break}a||(!0!==e\u0026\u0026s.markElement(r,\"wrong\",n),l--)}return l}},{key:\"markElement\",value:function(e,t,n){var o=u(\"\u003cspan/\u003e\",{class:\"h5p-hidden-read\",html:this.l10n[t+\"Answer\"]+\". \"});n\u0026\u0026(o=o.add(n.getElement(\"correct\"===t))),e.$suffix=e.$suffix.add(o),e.$.addClass(\"h5p-\"+t).append(o),l.default.setElementOpacity(e.$,this.backgroundOpacity)}}]),t}(H5P.EventDispatcher);t.default=c}]);"
,"scripts/keyboard-nav.js":"/**\n * @class\n * @classdesc Keyboard navigation for accessibility support\n * @extends H5P.EventDispatcher\n */\nH5P.KeyboardNav = (function (EventDispatcher) {\n /**\n * Construct a new KeyboardNav\n * @constructor\n */\n function KeyboardNav() {\n EventDispatcher.call(this);\n\n /** @member {boolean} */\n this.selectability = true;\n\n /** @member {HTMLElement[]|EventTarget[]} */\n this.elements = [];\n }\n\n KeyboardNav.prototype = Object.create(EventDispatcher.prototype);\n KeyboardNav.prototype.constructor = KeyboardNav;\n\n /**\n * Adds a new element to navigation\n *\n * @param {HTMLElement} el The element\n * @public\n */\n KeyboardNav.prototype.addElement = function(el){\n el.addEventListener(\u0027keydown\u0027, this.handleKeyDown.bind(this));\n el.addEventListener(\u0027click\u0027, this.onClick.bind(this));\n\n // add to array to navigate over\n this.elements.push(el);\n\n if(this.elements.length === 1){ // if first\n this.setTabbableAt(0);\n }\n };\n\n /**\n * Select the previous element in the list. Select the last element,\n * if the current element is the first element in the list.\n *\n * @param {Number} index The index of currently selected element\n * @public\n * @fires KeyboardNav#previousOption\n */\n KeyboardNav.prototype.previousOption = function (index) {\n var isFirstElement = index === 0;\n this.focusOnElementAt(isFirstElement ? (this.elements.length - 1) : (index - 1));\n\n /**\n * Previous option event\n *\n * @event KeyboardNav#previousOption\n * @type KeyboardNavigationEventData\n */\n this.trigger(\u0027previousOption\u0027, this.createEventPayload(index));\n };\n\n\n /**\n * Select the next element in the list. Select the first element,\n * if the current element is the first element in the list.\n *\n * @param {Number} index The index of the currently selected element\n * @public\n * @fires KeyboardNav#previousOption\n */\n KeyboardNav.prototype.nextOption = function (index) {\n var isLastElement = index === this.elements.length - 1;\n this.focusOnElementAt(isLastElement ? 0 : (index + 1));\n\n /**\n * Previous option event\n *\n * @event KeyboardNav#nextOption\n * @type KeyboardNavigationEventData\n */\n this.trigger(\u0027nextOption\u0027, this.createEventPayload(index));\n };\n\n /**\n * Focus on an element by index\n *\n * @param {Number} index The index of the element to focus on\n * @public\n */\n KeyboardNav.prototype.focusOnElementAt = function (index) {\n this.setTabbableAt(index);\n this.elements[index].focus();\n };\n\n /**\n * Disable possibility to select a word trough click and space or enter\n *\n * @public\n */\n KeyboardNav.prototype.disableSelectability = function () {\n this.selectability = false;\n };\n\n /**\n * Enable possibility to select a word trough click and space or enter\n *\n * @public\n */\n KeyboardNav.prototype.enableSelectability = function () {\n this.selectability = true;\n };\n\n /**\n * Sets tabbable on a single element in the list, by index\n * Also removes tabbable from all other elements in the list\n *\n * @param {Number} index The index of the element to set tabbale on\n * @public\n */\n KeyboardNav.prototype.setTabbableAt = function (index) {\n this.removeAllTabbable();\n this.elements[index].setAttribute(\u0027tabindex\u0027, \u00270\u0027);\n };\n\n /**\n * Remove tabbable from all entries\n *\n * @public\n */\n KeyboardNav.prototype.removeAllTabbable = function () {\n this.elements.forEach(function(el){\n el.removeAttribute(\u0027tabindex\u0027);\n });\n };\n\n /**\n * Toggles \u0027aria-selected\u0027 on an element, if selectability == true\n *\n * @param {EventTarget|HTMLElement} el The element to select/unselect\n * @private\n * @fires KeyboardNav#select\n */\n KeyboardNav.prototype.toggleSelect = function(el){\n if(this.selectability) {\n\n // toggle selection\n if (isElementSelected(el)) {\n el.removeAttribute(\u0027aria-selected\u0027);\n }\n else {\n el.setAttribute(\u0027aria-selected\u0027, \u0027true\u0027);\n }\n\n // focus current\n el.setAttribute(\u0027tabindex\u0027, \u00270\u0027);\n el.focus();\n\n var index = this.elements.indexOf(el);\n\n /**\n * Previous option event\n *\n * @event KeyboardNav#select\n * @type KeyboardNavigationEventData\n */\n this.trigger(\u0027select\u0027, this.createEventPayload(index));\n }\n };\n\n /**\n * Handles key down\n *\n * @param {KeyboardEvent} event Keyboard event\n * @private\n */\n KeyboardNav.prototype.handleKeyDown = function(event){\n var index;\n\n switch (event.which) {\n case 13: // Enter\n case 32: // Space\n // Select\n this.toggleSelect(event.target);\n event.preventDefault();\n break;\n\n case 37: // Left Arrow\n case 38: // Up Arrow\n // Go to previous Option\n index = this.elements.indexOf(event.currentTarget);\n this.previousOption(index);\n event.preventDefault();\n break;\n\n case 39: // Right Arrow\n case 40: // Down Arrow\n // Go to next Option\n index = this.elements.indexOf(event.currentTarget);\n this.nextOption(index);\n event.preventDefault();\n break;\n }\n };\n\n /**\n * Handles element click. Toggles \u0027aria-selected\u0027 on element\n *\n * @param {MouseEvent} event Mouse click event\n * @private\n */\n KeyboardNav.prototype.onClick = function(event){\n this.toggleSelect(event.currentTarget);\n };\n\n /**\n * Creates a paylod for event that is fired\n *\n * @param {Number} index\n * @return {KeyboardNavigationEventData}\n */\n KeyboardNav.prototype.createEventPayload = function(index){\n /**\n * Data that is passed along as the event parameter\n *\n * @typedef {Object} KeyboardNavigationEventData\n * @property {HTMLElement} element\n * @property {number} index\n * @property {boolean} selected\n */\n return {\n element: this.elements[index],\n index: index,\n selected: isElementSelected(this.elements[index])\n };\n };\n\n /**\n * Sets aria-selected=\"true\" on an element\n *\n * @param {HTMLElement} el The element to set selected\n * @return {boolean}\n */\n var isElementSelected = function(el){\n return el.getAttribute(\u0027aria-selected\u0027) === \u0027true\u0027;\n };\n\n return KeyboardNav;\n})(H5P.EventDispatcher);\n"
,"scripts/xAPI-generator.js":"H5P.MarkTheWords = H5P.MarkTheWords || {};\n\n/**\n * Mark the words XapiGenerator\n */\nH5P.MarkTheWords.XapiGenerator = (function ($) {\n\n /**\n * Xapi statements Generator\n * @param {H5P.MarkTheWords} markTheWords\n * @constructor\n */\n function XapiGenerator(markTheWords) {\n\n /**\n * Generate answered event\n * @return {H5P.XAPIEvent}\n */\n this.generateAnsweredEvent = function () {\n var xAPIEvent = markTheWords.createXAPIEventTemplate(\u0027answered\u0027);\n\n // Extend definition\n var objectDefinition = createDefinition(markTheWords);\n $.extend(true, xAPIEvent.getVerifiedStatementValue([\u0027object\u0027, \u0027definition\u0027]), objectDefinition);\n\n // Set score\n xAPIEvent.setScoredResult(markTheWords.getScore(),\n markTheWords.getMaxScore(),\n markTheWords,\n true,\n markTheWords.getScore() === markTheWords.getMaxScore()\n );\n\n // Extend user result\n var userResult = {\n response: getUserSelections(markTheWords)\n };\n\n $.extend(xAPIEvent.getVerifiedStatementValue([\u0027result\u0027]), userResult);\n\n return xAPIEvent;\n };\n }\n\n /**\n * Create object definition for question\n *\n * @param {H5P.MarkTheWords} markTheWords\n * @return {Object} Object definition\n */\n function createDefinition(markTheWords) {\n var definition = {};\n definition.description = {\n \u0027en-US\u0027: replaceLineBreaks(markTheWords.params.taskDescription)\n };\n definition.type = \u0027http://adlnet.gov/expapi/activities/cmi.interaction\u0027;\n definition.interactionType = \u0027choice\u0027;\n definition.correctResponsesPattern = [getCorrectResponsesPattern(markTheWords)];\n definition.choices = getChoices(markTheWords);\n definition.extensions = {\n \u0027https://h5p.org/x-api/line-breaks\u0027: markTheWords.getIndexesOfLineBreaks()\n };\n return definition;\n }\n\n /**\n * Replace line breaks\n *\n * @param {string} description\n * @return {string}\n */\n function replaceLineBreaks(description) {\n var sanitized = $(\u0027\u003cdiv\u003e\u0027 + description + \u0027\u003c/div\u003e\u0027).text();\n return sanitized.replace(/(\\n)+/g, \u0027\u003cbr/\u003e\u0027);\n }\n\n /**\n * Get all choices that it is possible to choose between\n *\n * @param {H5P.MarkTheWords} markTheWords\n * @return {Array}\n */\n function getChoices(markTheWords) {\n return markTheWords.selectableWords.map(function (word, index) {\n var text = word.getText();\n if (text.charAt(0) === \u0027*\u0027 \u0026\u0026 text.charAt(text.length - 1) === \u0027*\u0027) {\n text = text.substr(1, text.length - 2);\n }\n\n return {\n id: index.toString(),\n description: {\n \u0027en-US\u0027: $(\u0027\u003cdiv\u003e\u0027 + text + \u0027\u003c/div\u003e\u0027).text()\n }\n };\n });\n }\n\n /**\n * Get selected words as a user response pattern\n *\n * @param {H5P.MarkTheWords} markTheWords\n * @return {string}\n */\n function getUserSelections(markTheWords) {\n return markTheWords.selectableWords\n .reduce(function (prev, word, index) {\n if (word.isSelected()) {\n prev.push(index);\n }\n return prev;\n }, []).join(\u0027[,]\u0027);\n }\n\n /**\n * Get correct response pattern from correct words\n *\n * @param {H5P.MarkTheWords} markTheWords\n * @return {string}\n */\n function getCorrectResponsesPattern(markTheWords) {\n return markTheWords.selectableWords\n .reduce(function (prev, word, index) {\n if (word.isAnswer()) {\n prev.push(index);\n }\n return prev;\n }, []).join(\u0027[,]\u0027);\n }\n\n return XapiGenerator;\n})(H5P.jQuery);\n"
,"scripts/word.js":"H5P.MarkTheWords = H5P.MarkTheWords || {};\nH5P.MarkTheWords.Word = (function () {\n /**\n * @constant\n *\n * @type {string}\n */\n Word.ID_MARK_MISSED = \"h5p-description-missed\";\n /**\n * @constant\n *\n * @type {string}\n */\n Word.ID_MARK_CORRECT = \"h5p-description-correct\";\n /**\n * @constant\n *\n * @type {string}\n */\n Word.ID_MARK_INCORRECT = \"h5p-description-incorrect\";\n\n /**\n * Class for keeping track of selectable words.\n *\n * @class\n * @param {jQuery} $word\n */\n function Word($word) {\n var self = this;\n H5P.EventDispatcher.call(self);\n\n var input = $word.text();\n var handledInput = input;\n\n // Check if word is an answer\n var isAnswer = checkForAnswer();\n\n // Remove single asterisk and escape double asterisks.\n handleAsterisks();\n\n if (isAnswer) {\n $word.text(handledInput);\n }\n\n /**\n * Checks if the word is an answer by checking the first, second to last and last character of the word.\n *\n * @private\n * @return {Boolean} Returns true if the word is an answer.\n */\n function checkForAnswer() {\n // Check last and next to last character, in case of punctuations.\n var wordString = removeDoubleAsterisks(input);\n if (wordString.charAt(0) === (\u0027*\u0027) \u0026\u0026 wordString.length \u003e 2) {\n if (wordString.charAt(wordString.length - 1) === (\u0027*\u0027)) {\n handledInput = input.slice(1, input.length - 1);\n return true;\n }\n // If punctuation, add the punctuation to the end of the word.\n else if(wordString.charAt(wordString.length - 2) === (\u0027*\u0027)) {\n handledInput = input.slice(1, input.length - 2);\n return true;\n }\n return false;\n }\n return false;\n }\n\n /**\n * Removes double asterisks from string, used to handle input.\n *\n * @private\n * @param {String} wordString The string which will be handled.\n * @return {String} Returns a string without double asterisks.\n */\n function removeDoubleAsterisks(wordString) {\n var asteriskIndex = wordString.indexOf(\u0027*\u0027);\n var slicedWord = wordString;\n\n while (asteriskIndex !== -1) {\n if (wordString.indexOf(\u0027*\u0027, asteriskIndex + 1) === asteriskIndex + 1) {\n slicedWord = wordString.slice(0, asteriskIndex) + wordString.slice(asteriskIndex + 2, input.length);\n }\n asteriskIndex = wordString.indexOf(\u0027*\u0027, asteriskIndex + 1);\n }\n\n return slicedWord;\n }\n\n /**\n * Escape double asterisks ** = *, and remove single asterisk.\n *\n * @private\n */\n function handleAsterisks() {\n var asteriskIndex = handledInput.indexOf(\u0027*\u0027);\n\n while (asteriskIndex !== -1) {\n handledInput = handledInput.slice(0, asteriskIndex) + handledInput.slice(asteriskIndex + 1, handledInput.length);\n asteriskIndex = handledInput.indexOf(\u0027*\u0027, asteriskIndex + 1);\n }\n }\n\n /**\n * Removes any score points added to the marked word.\n */\n self.clearScorePoint = function () {\n for (var i = 0; $word[0].children.length; i++) {\n var scorePoint = $word[0].children[i];\n scorePoint.parentNode.removeChild(scorePoint);\n }\n };\n\n /**\n * Get Word as a string\n *\n * @return {string} Word as text\n */\n this.getText = function () {\n return input;\n };\n\n /**\n * Clears all marks from the word.\n *\n * @public\n */\n this.markClear = function () {\n $word\n .removeAttr(\u0027aria-selected\u0027)\n .removeAttr(\u0027aria-describedby\u0027);\n\n this.clearScorePoint();\n };\n\n /**\n * Check if the word is correctly marked and style it accordingly.\n * Reveal result\n *\n * @public\n * @param {H5P.Question.ScorePoints} scorePoints\n */\n this.markCheck = function (scorePoints) {\n if (this.isSelected()) {\n $word.attr(\u0027aria-describedby\u0027, isAnswer ? Word.ID_MARK_CORRECT : Word.ID_MARK_INCORRECT);\n\n if (scorePoints) {\n $word[0].appendChild(scorePoints.getElement(isAnswer));\n }\n }\n else if (isAnswer) {\n $word.attr(\u0027aria-describedby\u0027, Word.ID_MARK_MISSED);\n }\n };\n\n /**\n * Checks if the word is marked correctly.\n *\n * @public\n * @returns {Boolean} True if the marking is correct.\n */\n this.isCorrect = function () {\n return (isAnswer \u0026\u0026 this.isSelected());\n };\n\n /**\n * Checks if the word is marked wrong.\n *\n * @public\n * @returns {Boolean} True if the marking is wrong.\n */\n this.isWrong = function () {\n return (!isAnswer \u0026\u0026 this.isSelected());\n };\n\n /**\n * Checks if the word is correct, but has not been marked.\n *\n * @public\n * @returns {Boolean} True if the marking is missed.\n */\n this.isMissed = function () {\n return (isAnswer \u0026\u0026 !this.isSelected());\n };\n\n /**\n * Checks if the word is an answer.\n *\n * @public\n * @returns {Boolean} True if the word is an answer.\n */\n this.isAnswer = function () {\n return isAnswer;\n };\n\n /**\n * Checks if the word is selected.\n *\n * @public\n * @returns {Boolean} True if the word is selected.\n */\n this.isSelected = function () {\n return $word.attr(\u0027aria-selected\u0027) === \u0027true\u0027;\n };\n\n /**\n * Sets that the Word is selected\n *\n * @public\n */\n this.setSelected = function () {\n $word.attr(\u0027aria-selected\u0027, true);\n };\n }\n Word.prototype = Object.create(H5P.EventDispatcher.prototype);\n Word.prototype.constructor = Word;\n\n return Word;\n})();\n"
,"scripts/mark-the-words.js":"/*global H5P*/\n\n/**\n * Mark The Words module\n * @external {jQuery} $ H5P.jQuery\n */\nH5P.MarkTheWords = (function ($, Question, Word, KeyboardNav, XapiGenerator) {\n /**\n * Initialize module.\n *\n * @class H5P.MarkTheWords\n * @extends H5P.Question\n * @param {Object} params Behavior settings\n * @param {Number} contentId Content identification\n * @param {Object} contentData Object containing task specific content data\n *\n * @returns {Object} MarkTheWords Mark the words instance\n */\n function MarkTheWords(params, contentId, contentData) {\n var self = this;\n this.contentId = contentId;\n this.introductionId = \u0027mark-the-words-introduction-\u0027 + contentId;\n\n Question.call(this, \u0027mark-the-words\u0027);\n\n // Set default behavior.\n this.params = $.extend(true, {\n taskDescription: \"\",\n textField: \"This is a *nice*, *flexible* content type.\",\n overallFeedback: [],\n behaviour: {\n enableRetry: true,\n enableSolutionsButton: true,\n showScorePoints: true\n },\n checkAnswerButton: \"Check\",\n tryAgainButton: \"Retry\",\n showSolutionButton: \"Show solution\",\n correctAnswer: \"Correct!\",\n incorrectAnswer: \"Incorrect!\",\n missedAnswer: \"Missed!\",\n displaySolutionDescription: \"Task is updated to contain the solution.\",\n scoreBarLabel: \u0027You got :num out of :total points\u0027\n }, params);\n\n this.contentData = contentData;\n if (this.contentData !== undefined \u0026\u0026 this.contentData.previousState !== undefined) {\n this.previousState = this.contentData.previousState;\n }\n\n // Add keyboard navigation helper\n this.keyboardNav = new KeyboardNav();\n\n // on word clicked\n this.keyboardNav.on(\u0027select\u0027, function () {\n self.isAnswered = true;\n self.triggerXAPI(\u0027interacted\u0027);\n });\n\n this.initMarkTheWords();\n this.XapiGenerator = new XapiGenerator(this);\n }\n\n MarkTheWords.prototype = Object.create(H5P.EventDispatcher.prototype);\n MarkTheWords.prototype.constructor = MarkTheWords;\n\n /**\n * Initialize Mark The Words task\n */\n MarkTheWords.prototype.initMarkTheWords = function () {\n this.$inner = $(\u0027\u003cdiv class=\"h5p-word-inner\"\u003e\u003c/div\u003e\u0027);\n\n this.addTaskTo(this.$inner);\n\n // Set user state\n this.setH5PUserState();\n };\n\n /**\n * Recursive function that creates html for the words\n * @method createHtmlForWords\n * @param {Array} nodes Array of dom nodes\n * @return {string}\n */\n MarkTheWords.prototype.createHtmlForWords = function (nodes) {\n var self = this;\n var html = \u0027\u0027;\n for (var i = 0; i \u003c nodes.length; i++) {\n var node = nodes[i];\n\n if (node instanceof Text) {\n var text = $(node).text();\n var selectableStrings = text.replace(/(\u0026nbsp;|\\r\\n|\\n|\\r)/g, \u0027 \u0027)\n .match(/ \\*[^\\*]+\\* |[^\\s]+/g);\n\n if (selectableStrings) {\n selectableStrings.forEach(function (entry) {\n entry = entry.trim();\n\n // Words\n if (html) {\n // Add space before\n html += \u0027 \u0027;\n }\n\n // Remove prefix punctuations from word\n var prefix = entry.match(/^[\\[\\({⟨¿¡“\"«„]+/);\n var start = 0;\n if (prefix !== null) {\n start = prefix[0].length;\n html += prefix;\n }\n\n // Remove suffix punctuations from word\n var suffix = entry.match(/[\",….:;?!\\]\\)}⟩»”]+$/);\n var end = entry.length - start;\n if (suffix !== null) {\n end -= suffix[0].length;\n }\n\n // Word\n entry = entry.substr(start, end);\n if (entry.length) {\n html += \u0027\u003cspan role=\"option\"\u003e\u0027 + entry + \u0027\u003c/span\u003e\u0027;\n }\n\n if (suffix !== null) {\n html += suffix;\n }\n });\n }\n else if ((selectableStrings !== null) \u0026\u0026 text.length) {\n html += \u0027\u003cspan role=\"option\"\u003e\u0027 + text + \u0027\u003c/span\u003e\u0027;\n }\n }\n else {\n if (node.nodeName === \u0027BR\u0027) {\n html += \u0027\u003cbr/\u003e\u0027;\n }\n else {\n var attributes = \u0027 \u0027;\n for (var j = 0; j \u003c node.attributes.length; j++) {\n attributes +=node.attributes[j].name + \u0027=\"\u0027 + node.attributes[j].nodeValue + \u0027\" \u0027;\n }\n html += \u0027\u003c\u0027 + node.nodeName + attributes + \u0027\u003e\u0027;\n html += self.createHtmlForWords(node.childNodes);\n html += \u0027\u003c/\u0027 + node.nodeName + \u0027\u003e\u0027;\n }\n }\n }\n\n return html;\n };\n\n /**\n * Search for the last children in every paragraph and\n * return their indexes in an array\n *\n * @returns {Array}\n */\n MarkTheWords.prototype.getIndexesOfLineBreaks = function () {\n\n var indexes = [];\n var selectables = this.$wordContainer.find(\u0027span.h5p-word-selectable\u0027);\n\n selectables.each(function(index, selectable) {\n if ($(selectable).next().is(\u0027br\u0027)){\n indexes.push(index);\n }\n\n if ($(selectable).parent(\u0027p\u0027) \u0026\u0026 !$(selectable).parent().is(\u0027:last-child\u0027) \u0026\u0026 $(selectable).is(\u0027:last-child\u0027)){\n indexes.push(index);\n }\n });\n\n return indexes;\n };\n\n /**\n * Handle task and add it to container.\n * @param {jQuery} $container The object which our task will attach to.\n */\n MarkTheWords.prototype.addTaskTo = function ($container) {\n var self = this;\n self.selectableWords = [];\n self.answers = 0;\n\n // Wrapper\n var $wordContainer = $(\u0027\u003cdiv/\u003e\u0027, {\n \u0027class\u0027: \u0027h5p-word-selectable-words\u0027,\n \u0027aria-labelledby\u0027: self.introductionId,\n \u0027aria-multiselect\u0027: true,\n \u0027role\u0027: \u0027listbox\u0027,\n html: self.createHtmlForWords($.parseHTML(self.params.textField))\n });\n\n $wordContainer.find(\u0027[role=\"option\"]\u0027).each(function () {\n // Add keyboard navigation to this element\n self.keyboardNav.addElement(this);\n\n var selectableWord = new Word($(this));\n if (selectableWord.isAnswer()) {\n self.answers += 1;\n }\n self.selectableWords.push(selectableWord);\n });\n\n self.blankIsCorrect = (self.answers === 0);\n if (self.blankIsCorrect) {\n self.answers = 1;\n }\n\n $wordContainer.appendTo($container);\n self.$wordContainer = $wordContainer;\n };\n\n /**\n * Add check solution and retry buttons.\n */\n MarkTheWords.prototype.addButtons = function () {\n var self = this;\n self.$buttonContainer = $(\u0027\u003cdiv/\u003e\u0027, {\n \u0027class\u0027: \u0027h5p-button-bar\u0027\n });\n\n this.addButton(\u0027check-answer\u0027, this.params.checkAnswerButton, function () {\n self.isAnswered = true;\n self.keyboardNav.setTabbableAt(0);\n self.keyboardNav.disableSelectability();\n var answers = self.calculateScore();\n self.feedbackSelectedWords();\n self.hideButton(\u0027check-answer\u0027);\n\n\n if (!self.showEvaluation(answers)) {\n // Only show if a correct answer was not found.\n if (self.params.behaviour.enableSolutionsButton \u0026\u0026 (answers.correct \u003c self.answers)) {\n self.showButton(\u0027show-solution\u0027);\n }\n if (self.params.behaviour.enableRetry) {\n self.showButton(\u0027try-again\u0027);\n }\n }\n self.trigger(self.XapiGenerator.generateAnsweredEvent());\n });\n\n this.addButton(\u0027try-again\u0027, this.params.tryAgainButton, this.resetTask.bind(this), false);\n\n this.addButton(\u0027show-solution\u0027, this.params.showSolutionButton, function () {\n self.keyboardNav.setTabbableAt(0);\n self.keyboardNav.disableSelectability();\n self.setAllMarks();\n self.hideButton(\u0027check-answer\u0027);\n self.hideButton(\u0027show-solution\u0027);\n if (self.params.behaviour.enableRetry) {\n self.showButton(\u0027try-again\u0027);\n }\n\n self.read(self.params.displaySolutionDescription);\n }, false);\n };\n\n /**\n * Get Xapi Data.\n *\n * @see used in contracts {@link https://h5p.org/documentation/developers/contracts#guides-header-6}\n * @return {Object}\n */\n MarkTheWords.prototype.getXAPIData = function () {\n return {\n statement: this.XapiGenerator.generateAnsweredEvent().data.statement\n };\n };\n\n /**\n * Mark the words as correct, wrong or missed.\n *\n * @fires MarkTheWords#resize\n */\n MarkTheWords.prototype.setAllMarks = function () {\n this.selectableWords.forEach(function (entry) {\n entry.markCheck();\n entry.clearScorePoint();\n });\n\n /**\n * Resize event\n *\n * @event MarkTheWords#resize\n */\n this.trigger(\u0027resize\u0027);\n };\n\n /**\n * Mark the selected words as correct or wrong.\n *\n * @fires MarkTheWords#resize\n */\n MarkTheWords.prototype.feedbackSelectedWords = function () {\n var self = this;\n\n var scorePoints;\n if (self.params.behaviour.showScorePoints) {\n scorePoints = new H5P.Question.ScorePoints();\n }\n\n this.selectableWords.forEach(function (entry) {\n if (entry.isSelected()) {\n entry.markCheck(scorePoints);\n }\n });\n\n this.$wordContainer.addClass(\u0027h5p-disable-hover\u0027);\n this.trigger(\u0027resize\u0027);\n };\n\n /**\n * Evaluate task and display score text for word markings.\n *\n * @fires MarkTheWords#resize\n * @return {Boolean} Returns true if maxScore was achieved.\n */\n MarkTheWords.prototype.showEvaluation = function (answers) {\n this.hideEvaluation();\n var score = answers.score;\n\n //replace editor variables with values, uses regexp to replace all instances.\n var scoreText = H5P.Question.determineOverallFeedback(this.params.overallFeedback, score / this.answers).replace(/@score/g, score.toString())\n .replace(/@total/g, this.answers.toString())\n .replace(/@correct/g, answers.correct.toString())\n .replace(/@wrong/g, answers.wrong.toString())\n .replace(/@missed/g, answers.missed.toString());\n\n this.setFeedback(scoreText, score, this.answers, this.params.scoreBarLabel);\n\n this.trigger(\u0027resize\u0027);\n return score === this.answers;\n };\n\n /**\n * Clear the evaluation text.\n *\n * @fires MarkTheWords#resize\n */\n MarkTheWords.prototype.hideEvaluation = function () {\n this.removeFeedback();\n this.trigger(\u0027resize\u0027);\n };\n\n /**\n * Calculate the score.\n *\n * @return {Answers}\n */\n MarkTheWords.prototype.calculateScore = function () {\n var self = this;\n\n /**\n * @typedef {Object} Answers\n * @property {number} correct The number of correct answers\n * @property {number} wrong The number of wrong answers\n * @property {number} missed The number of answers the user missed\n * @property {number} score The calculated score\n */\n var initial = {\n correct: 0,\n wrong: 0,\n missed: 0,\n score: 0\n };\n\n // iterate over words, and calculate score\n var answers = self.selectableWords.reduce(function (result, word) {\n if (word.isCorrect()) {\n result.correct++;\n }\n else if (word.isWrong()) {\n result.wrong++;\n }\n else if (word.isMissed()) {\n result.missed++;\n }\n\n return result;\n }, initial);\n\n // if no wrong answers, and black is correct\n if (answers.wrong === 0 \u0026\u0026 self.blankIsCorrect) {\n answers.correct = 1;\n }\n\n // no negative score\n answers.score = Math.max(answers.correct - answers.wrong, 0);\n\n return answers;\n };\n\n /**\n * Clear styling on marked words.\n *\n * @fires MarkTheWords#resize\n */\n MarkTheWords.prototype.clearAllMarks = function () {\n this.selectableWords.forEach(function (entry) {\n entry.markClear();\n });\n\n this.$wordContainer.removeClass(\u0027h5p-disable-hover\u0027);\n this.trigger(\u0027resize\u0027);\n };\n\n /**\n * Returns true if task is checked or a word has been clicked\n *\n * @see {@link https://h5p.org/documentation/developers/contracts|Needed for contracts.}\n * @returns {Boolean} Always returns true.\n */\n MarkTheWords.prototype.getAnswerGiven = function () {\n return this.blankIsCorrect ? true : this.isAnswered;\n };\n\n /**\n * Counts the score, which is correct answers subtracted by wrong answers.\n *\n * @see {@link https://h5p.org/documentation/developers/contracts|Needed for contracts.}\n * @returns {Number} score The amount of points achieved.\n */\n MarkTheWords.prototype.getScore = function () {\n return this.calculateScore().score;\n };\n\n /**\n * Gets max score for this task.\n *\n * @see {@link https://h5p.org/documentation/developers/contracts|Needed for contracts.}\n * @returns {Number} maxScore The maximum amount of points achievable.\n */\n MarkTheWords.prototype.getMaxScore = function () {\n return this.answers;\n };\n\n /**\n * Get title\n * @returns {string}\n */\n MarkTheWords.prototype.getTitle = function () {\n return H5P.createTitle(this.params.taskDescription);\n };\n\n /**\n * Display the evaluation of the task, with proper markings.\n *\n * @fires MarkTheWords#resize\n * @see {@link https://h5p.org/documentation/developers/contracts|Needed for contracts.}\n */\n MarkTheWords.prototype.showSolutions = function () {\n var answers = this.calculateScore();\n this.showEvaluation(answers);\n this.setAllMarks();\n this.keyboardNav.setTabbableAt(0);\n this.keyboardNav.disableSelectability();\n this.read(this.params.displaySolutionDescription);\n this.hideButton(\u0027try-again\u0027);\n this.hideButton(\u0027show-solution\u0027);\n this.hideButton(\u0027check-answer\u0027);\n\n this.trigger(\u0027resize\u0027);\n };\n\n /**\n * Resets the task back to its\u0027 initial state.\n *\n * @fires MarkTheWords#resize\n * @see {@link https://h5p.org/documentation/developers/contracts|Needed for contracts.}\n */\n MarkTheWords.prototype.resetTask = function () {\n this.isAnswered = false;\n this.clearAllMarks();\n this.hideEvaluation();\n this.keyboardNav.setTabbableAt(0);\n this.keyboardNav.enableSelectability();\n this.hideButton(\u0027try-again\u0027);\n this.hideButton(\u0027show-solution\u0027);\n this.showButton(\u0027check-answer\u0027);\n this.trigger(\u0027resize\u0027);\n };\n\n /**\n * Returns an object containing the selected words\n *\n * @public\n * @returns {object} containing indexes of selected words\n */\n MarkTheWords.prototype.getCurrentState = function () {\n var selectedWordsIndexes = [];\n if (this.selectableWords === undefined) {\n return undefined;\n }\n\n this.selectableWords.forEach(function (selectableWord, swIndex) {\n if (selectableWord.isSelected()) {\n selectedWordsIndexes.push(swIndex);\n }\n });\n return selectedWordsIndexes;\n };\n\n /**\n * Sets answers to current user state\n */\n MarkTheWords.prototype.setH5PUserState = function () {\n var self = this;\n\n // Do nothing if user state is undefined\n if (this.previousState === undefined || this.previousState.length === undefined) {\n return;\n }\n\n // Select words from user state\n this.previousState.forEach(function (answeredWordIndex) {\n if (isNaN(answeredWordIndex) || answeredWordIndex \u003e= self.selectableWords.length || answeredWordIndex \u003c 0) {\n throw new Error(\u0027Stored user state is invalid\u0027);\n }\n self.selectableWords[answeredWordIndex].setSelected();\n });\n };\n\n /**\n * Register dom elements\n *\n * @see {@link https://github.com/h5p/h5p-question/blob/1558b6144333a431dd71e61c7021d0126b18e252/scripts/question.js#L1236|Called from H5P.Question}\n */\n MarkTheWords.prototype.registerDomElements = function () {\n // wrap introduction in div with id\n var introduction = \u0027\u003cdiv id=\"\u0027 + this.introductionId + \u0027\"\u003e\u0027 + this.params.taskDescription + \u0027\u003c/div\u003e\u0027;\n\n // Register description\n this.setIntroduction(introduction);\n\n // creates aria descriptions for correct/incorrect/missed\n this.createDescriptionsDom().appendTo(this.$inner);\n\n // Register content\n this.setContent(this.$inner, {\n \u0027class\u0027: \u0027h5p-word\u0027\n });\n\n // Register buttons\n this.addButtons();\n };\n\n /**\n * Creates dom with description to be used with aria-describedby\n * @return {jQuery}\n */\n MarkTheWords.prototype.createDescriptionsDom = function () {\n var self = this;\n var $el = $(\u0027\u003cdiv class=\"h5p-mark-the-words-descriptions\"\u003e\u003c/div\u003e\u0027);\n\n $(\u0027\u003cdiv id=\"\u0027 + Word.ID_MARK_CORRECT + \u0027\"\u003e\u0027 + self.params.correctAnswer + \u0027\u003c/div\u003e\u0027).appendTo($el);\n $(\u0027\u003cdiv id=\"\u0027 + Word.ID_MARK_INCORRECT + \u0027\"\u003e\u0027 + self.params.incorrectAnswer + \u0027\u003c/div\u003e\u0027).appendTo($el);\n $(\u0027\u003cdiv id=\"\u0027 + Word.ID_MARK_MISSED + \u0027\"\u003e\u0027 + self.params.missedAnswer + \u0027\u003c/div\u003e\u0027).appendTo($el);\n\n return $el;\n };\n\n return MarkTheWords;\n}(H5P.jQuery, H5P.Question, H5P.MarkTheWords.Word, H5P.KeyboardNav, H5P.MarkTheWords.XapiGenerator));\n"
,"dist/h5p-drag-text.js":"!function(e){function t(n){if(r[n])return r[n].exports;var o=r[n]={i:n,l:!1,exports:{}};return e[n].call(o.exports,o,o.exports,t),o.l=!0,o.exports}var r={};t.m=e,t.c=r,t.i=function(e){return e},t.d=function(e,r,n){t.o(e,r)||Object.defineProperty(e,r,{configurable:!1,enumerable:!0,get:n})},t.n=function(e){var r=e\u0026\u0026e.__esModule?function(){return e.default}:function(){return e};return t.d(r,\"a\",r),r},t.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},t.p=\"\",t(t.s=10)}([function(e,t,r){\"use strict\";Object.defineProperty(t,\"__esModule\",{value:!0});var n=t.curry=function(e){var t=e.length;return function r(){var n=Array.prototype.slice.call(arguments,0);return n.length\u003e=t?e.apply(null,n):function(){var e=Array.prototype.slice.call(arguments,0);return r.apply(null,n.concat(e))}}},o=(t.compose=function(){for(var e=arguments.length,t=Array(e),r=0;r\u003ce;r++)t[r]=arguments[r];return t.reduce(function(e,t){return function(){return e(t.apply(void 0,arguments))}})},t.forEach=n(function(e,t){t.forEach(e)}),t.map=n(function(e,t){return t.map(e)}),t.filter=n(function(e,t){return t.filter(e)})),a=(t.some=n(function(e,t){return t.some(e)}),t.contains=n(function(e,t){return-1!=t.indexOf(e)}));t.without=n(function(e,t){return o(function(t){return!a(t,e)},t)}),t.inverseBooleanString=function(e){return(\"true\"!==e).toString()}},function(e,t,r){\"use strict\";Object.defineProperty(t,\"__esModule\",{value:!0}),t.createElement=t.toggleClass=t.toggleVisibility=t.show=t.hide=t.removeClass=t.addClass=t.classListContains=t.removeChild=t.querySelectorAll=t.nodeListToArray=t.querySelector=t.appendChild=t.toggleAttribute=t.attributeEquals=t.hasAttribute=t.removeAttribute=t.setAttribute=t.getAttribute=void 0;var n=r(0),o=t.getAttribute=(0,n.curry)(function(e,t){return t.getAttribute(e)}),a=t.setAttribute=(0,n.curry)(function(e,t,r){return r.setAttribute(e,t)}),i=(t.removeAttribute=(0,n.curry)(function(e,t){return t.removeAttribute(e)}),t.hasAttribute=(0,n.curry)(function(e,t){return t.hasAttribute(e)}),t.attributeEquals=(0,n.curry)(function(e,t,r){return r.getAttribute(e)===t}),t.toggleAttribute=(0,n.curry)(function(e,t){var r=o(e,t);a(e,(0,n.inverseBooleanString)(r),t)}),t.appendChild=(0,n.curry)(function(e,t){return e.appendChild(t)}),t.querySelector=(0,n.curry)(function(e,t){return t.querySelector(e)}),t.nodeListToArray=function(e){return Array.prototype.slice.call(e)}),s=(t.querySelectorAll=(0,n.curry)(function(e,t){return i(t.querySelectorAll(e))}),t.removeChild=(0,n.curry)(function(e,t){return e.removeChild(t)}),t.classListContains=(0,n.curry)(function(e,t){return t.classList.contains(e)}),t.addClass=(0,n.curry)(function(e,t){return t.classList.add(e)})),l=t.removeClass=(0,n.curry)(function(e,t){return t.classList.remove(e)}),u=t.hide=s(\"hidden\"),c=t.show=l(\"hidden\");t.toggleVisibility=(0,n.curry)(function(e,t){return(e?c:u)(t)}),t.toggleClass=(0,n.curry)(function(e,t,r){r.classList[t?\"add\":\"remove\"](e)}),t.createElement=function(e){var t=e.tag,r=e.id,n=e.classes,o=e.attributes,a=document.createElement(t);return r\u0026\u0026(a.id=r),n\u0026\u0026n.forEach(function(e){a.classList.add(e)}),o\u0026\u0026Object.keys(o).forEach(function(e){a.setAttribute(e,o[e])}),a}},function(e,t,r){\"use strict\";Object.defineProperty(t,\"__esModule\",{value:!0});var n=function(e){var t=e.length;return function r(){var n=Array.prototype.slice.call(arguments,0);return n.length\u003e=t?e.apply(null,n):function(){var e=Array.prototype.slice.call(arguments,0);return r.apply(null,n.concat(e))}}},o=function(e,t){return t.substr(0,1)===e},a=function(e,t){return t.substr(-1)===e},i=n(function(e,t){return o(e,t)\u0026\u0026(t=t.slice(1)),a(e,t)\u0026\u0026(t=t.slice(0,-1)),t}),s=function(e){for(var t=e.length;t\u003e0;){var r=Math.floor(Math.random()*t);t--;var n=e[t];e[t]=e[r],e[r]=n}return e},l=function(e){var t=document.createElement(\"span\");return t.innerHTML=e,t};t.default={curry:n,cleanCharacter:i,startsWith:o,endsWith:a,shuffle:s,createElementWithTextPart:l}},function(e,t,r){\"use strict\";function n(e){return e\u0026\u0026e.__esModule?e:{default:e}}Object.defineProperty(t,\"__esModule\",{value:!0});var o=r(13),a=r(14),i=n(a),s=r(2),l=n(s),u=r(11),c=n(u),d=r(12),p=n(d),h=r(7),g=n(h),b=r(5),f=n(b),m=r(6),v=n(m),y=r(9),D=n(y);H5P.DragText=function(e,t,r){function n(r,n,o){var a=this;this.$=e(this),this.contentId=n,t.call(this,\"drag-text\"),this.params=e.extend(!0,{taskDescription:\"Set in adjectives in the following sentence\",textField:\"This is a *nice*, *flexible* content type, which allows you to highlight all the *wonderful* words in this *exciting* sentence.\\nThis is another line of *fantastic* text.\",overallFeedback:[],checkAnswer:\"Check\",tryAgain:\"Retry\",behaviour:{enableRetry:!0,enableSolutionsButton:!0,enableCheckButton:!0,instantFeedback:!1},showSolution:\"Show solution\",dropZoneIndex:\"Drop Zone @index.\",empty:\"Empty.\",contains:\"Drop Zone @index contains draggable @draggable.\",draggableIndex:\"Draggable. @index of @count.\",tipLabel:\"Show tip\",correctText:\"Correct!\",incorrectText:\"Incorrect!\",resetDropTitle:\"Reset drop\",resetDropDescription:\"Are you sure you want to reset this drop zone?\",grabbed:\"Draggable is grabbed.\",cancelledDragging:\"Cancelled dragging.\",correctAnswer:\"Correct answer:\",scoreBarLabel:\"You got :num out of :total points\"},r),this.contentData=o,void 0!==this.contentData\u0026\u0026void 0!==this.contentData.previousState\u0026\u0026void 0!==this.contentData.previousState.length\u0026\u0026(this.previousState=this.contentData.previousState),this.answered=!1,this.textFieldHtml=this.params.textField.replace(/(\\r\\n|\\n|\\r)/gm,\"\u003cbr/\u003e\"),this.introductionId=\"h5p-drag-text-\"+n+\"-introduction\",this.selectedElement=void 0,this.ariaDragControls=new f.default,this.ariaDropControls=new v.default,this.dragControls=new g.default([new D.default,this.ariaDragControls]),this.dragControls.useNegativeTabIndex(),this.dropControls=new g.default([new D.default,this.ariaDropControls]),this.dropControls.useNegativeTabIndex(),this.dragControls.on(\"before-select\",function(e){return!a.isElementDisabled(e.element)}),this.dragControls.on(\"select\",this.keyboardDraggableSelected,this),this.dropControls.on(\"select\",this.keyboardDroppableSelected,this),this.on(\"start\",this.addAllDroppablesToControls,this),this.on(\"revert\",this.removeControlsFromEmptyDropZones,this),this.on(\"stop\",function(e){e.data.target||a.removeControlsFromDropZonesIfAllEmpty()},this),this.on(\"drop\",this.removeControlsFromEmptyDropZones,this),this.on(\"start\",this.toggleDropEffect,this),this.on(\"stop\",this.toggleDropEffect,this),this.on(\"start\",function(e){var t=a.getDraggableByElement(e.data.element);a.setDraggableAriaLabel(t)}),this.on(\"stop\",function(e){var t=a.getDraggableByElement(e.data.element);a.setDraggableAriaLabel(t)}),this.on(\"start\",function(e){return e.data.element.setAttribute(\"aria-grabbed\",\"true\")}),this.on(\"stop\",function(e){return e.data.element.setAttribute(\"aria-grabbed\",\"false\")}),this.on(\"drop\",this.ariaDropControls.setAllToNone,this.ariaDropControls),this.on(\"drop\",function(e){this.dragControls.removeElement(e.data.element)},this),this.on(\"revert\",function(e){this.dragControls.insertElementAt(e.data.element,0)},this),this.on(\"drop\",this.updateDroppableElement,this),this.on(\"revert\",this.updateDroppableElement,this),this.initDragText(),this.stopWatch=new i.default,this.stopWatch.start(),this.on(\"resize\",this.resize,this),this.on(\"revert\",this.toggleDraggablesContainer,this),this.on(\"drop\",this.toggleDraggablesContainer,this),this.on(\"stop\",function(e){e.data.target||a.read(a.params.cancelledDragging)}),this.params.behaviour.instantFeedback\u0026\u0026this.on(\"revert\",function(){return a.instantFeedbackEvaluation()})}return n.prototype=Object.create(t.prototype),n.prototype.constructor=n,n.prototype.updateDroppableElement=function(e){var t=e.data.target,r=e.data.element,n=this.getDroppableByElement(t);t\u0026\u0026this.setDroppableLabel(t,r.textContent,n.getIndex())},n.prototype.removeControlsFromDropZonesIfAllEmpty=function(){this.anyDropZoneHasDraggable()||this.removeAllDroppablesFromControls()},n.prototype.removeControlsFromEmptyDropZones=function(){var e=this;this.droppables.filter(function(e){return!e.hasDraggable()}).map(function(e){return e.getElement()}).forEach(function(t){e.dropControls.removeElement(t)})},n.prototype.addAllDroppablesToControls=function(){var e=this;this.dropControls.count()\u003e0\u0026\u0026this.removeAllDroppablesFromControls(),this.droppables.map(function(e){return e.getElement()}).forEach(function(t){return e.dropControls.addElement(t)})},n.prototype.removeAllDroppablesFromControls=function(){var e=this;this.droppables.map(function(e){return e.getElement()}).forEach(function(t){return e.dropControls.removeElement(t)})},n.prototype.anyDropZoneHasDraggable=function(){return this.droppables.some(function(e){return e.hasDraggable()})},n.prototype.setDroppableLabel=function(e,t,r){var n=this.params.dropZoneIndex.replace(\"@index\",r.toString()),o=e.classList.contains(\"h5p-drag-correct-feedback\"),a=e.classList.contains(\"h5p-drag-wrong-feedback\"),i=o||a,s=e.childNodes.length\u003e0;if(e)if(i){var l=this.getDroppableByElement(e),u=\"\";u=o?l.correctFeedback?l.correctFeedback:this.params.correctText:l.incorrectFeedback?l.incorrectFeedback:this.params.incorrectText,e.setAttribute(\"aria-label\",n+\" \"+this.params.contains.replace(\"@index\",r.toString()).replace(\"@draggable\",t)+\" \"+u+\".\")}else s?e.setAttribute(\"aria-label\",n+\" \"+this.params.contains.replace(\"@index\",r.toString()).replace(\"@draggable\",t)):e.setAttribute(\"aria-label\",n+\" \"+this.params.empty.replace(\"@index\",r.toString()))},n.prototype.registerDomElements=function(){this.$introduction=e(\u0027\u003cp id=\"\u0027+this.introductionId+\u0027\"\u003e\u0027+this.params.taskDescription+\"\u003c/p\u003e\"),this.setIntroduction(this.$introduction),this.$introduction.parent().attr(\"tabindex\",\"-1\"),this.setContent(this.$inner),this.addButtons()},n.prototype.initDragText=function(){return this.$inner=e(\"\u003cdiv/\u003e\",{\"aria-describedby\":this.introductionId,class:\"h5p-drag-inner\"}),this.addTaskTo(this.$inner),this.setH5PUserState(),this.$inner},n.prototype.resize=function(){this.changeLayoutToFitWidth()},n.prototype.changeLayoutToFitWidth=function(){var e=this;e.addDropzoneWidth(),e.$inner.width()/parseFloat(e.$inner.css(\"font-size\"),10)\u003e43\u0026\u0026e.widestDraggable\u003c=e.$inner.width()/3?(e.$draggables.addClass(\"h5p-drag-wide-screen\"),e.$wordContainer.detach().appendTo(e.$taskContainer),e.draggables.forEach(function(e){e.getDraggableElement().addClass(\"h5p-drag-draggable-wide-screen\")}),e.$wordContainer.css({\"margin-right\":e.$draggables.width()})):(e.$wordContainer.css({\"margin-right\":0}),e.$draggables.removeClass(\"h5p-drag-wide-screen\"),e.$draggables.detach().appendTo(e.$taskContainer),e.draggables.forEach(function(e){e.getDraggableElement().removeClass(\"h5p-drag-draggable-wide-screen\")}))},n.prototype.addButtons=function(){var e=this;e.params.behaviour.enableCheckButton\u0026\u0026e.addButton(\"check-answer\",e.params.checkAnswer,function(){e.answered=!0,e.removeAllElementsFromDragControl(),e.showEvaluation()?(e.hideButton(\"show-solution\"),e.hideButton(\"try-again\"),e.hideButton(\"check-answer\")):(e.params.behaviour.enableRetry\u0026\u0026e.showButton(\"try-again\"),e.params.behaviour.enableSolutionsButton\u0026\u0026e.showButton(\"show-solution\"),e.hideButton(\"check-answer\"),e.disableDraggables()),e.$introduction.parent().focus()},!e.params.behaviour.instantFeedback),e.addButton(\"show-solution\",e.params.showSolution,function(){e.droppables.forEach(function(e){e.showSolution()}),e.draggables.forEach(function(t){return e.setDraggableAriaLabel(t)}),e.disableDraggables(),e.removeAllDroppablesFromControls(),e.hideButton(\"show-solution\")},e.initShowShowSolutionButton||!1),e.addButton(\"try-again\",e.params.tryAgain,function(){e.answered\u0026\u0026e.resetDraggables(),e.answered=!1,e.hideEvaluation(),e.hideExplanation(),e.hideButton(\"try-again\"),e.hideButton(\"show-solution\"),e.params.behaviour.instantFeedback?e.enableAllDropzonesAndDraggables():(e.showButton(\"check-answer\"),e.enableDraggables()),e.hideAllSolutions(),e.stopWatch.reset(),e.read(e.params.taskDescription)},e.initShowTryAgainButton||!1)},n.prototype.removeAllElementsFromDragControl=function(){var e=this;this.dragControls.elements.forEach(function(t){return e.dragControls.removeElement(t)})},n.prototype.keyboardDraggableSelected=function(e){var t=this.selectedElement,r=void 0!==this.selectedElement,n=this.selectedElement===e.element;r\u0026\u0026(this.selectedElement=void 0,this.trigger(\"stop\",{element:t})),r\u0026\u0026n||this.isElementDisabled(e.element)||(this.selectedElement=e.element,this.trigger(\"start\",{element:e.element}),this.focusOnFirstEmptyDropZone())},n.prototype.focusOnFirstEmptyDropZone=function(){var e=this.droppables.filter(function(e){return!e.hasDraggable()})[0],t=e.getElement();this.dropControls.setTabbable(t),t.focus()},n.prototype.isElementDisabled=function(e){return\"true\"===e.getAttribute(\"aria-disabled\")},n.prototype.keyboardDroppableSelected=function(e){var t=this,r=e.element,n=t.getDroppableByElement(r),o=t.getDraggableByElement(this.selectedElement),a=this.params.behaviour.instantFeedback\u0026\u0026n\u0026\u0026n.isCorrect(),i=!this.params.behaviour.instantFeedback\u0026\u0026n.hasFeedback();if(o\u0026\u0026n\u0026\u0026!a){var s=t.selectedElement;t.drop(o,n),t.selectedElement=void 0,this.trigger(\"stop\",{element:s,target:n.getElement()})}else if(n\u0026\u0026n.hasDraggable()\u0026\u0026!i\u0026\u0026!a){var l=r.querySelector(\"[aria-grabbed]\");this.createConfirmResetDialog(function(){t.revert(t.getDraggableByElement(l))}).show()}},n.prototype.toggleDraggablesContainer=function(){var e=0===this.$draggables.children().length;this.$draggables.toggleClass(\"hide\",e)},n.prototype.createConfirmResetDialog=function(e,t){var n=this,o=new r({headerText:n.params.resetDropTitle,dialogText:n.params.resetDropDescription});return o.appendTo(document.body),o.on(\"confirmed\",e,t||this),o},n.prototype.showDropzoneFeedback=function(){var e=this;this.droppables.forEach(function(t){t.addFeedback();var r=t.containedDraggable;t\u0026\u0026r\u0026\u0026(e.setDroppableLabel(t.getElement(),r.getElement().textContent,t.getIndex()),e.setDraggableAriaLabel(r))})},n.prototype.showExplanation=function(){var e=this,t=[];this.droppables.forEach(function(e){var r=e.containedDraggable;e\u0026\u0026r\u0026\u0026(e.isCorrect()\u0026\u0026e.correctFeedback\u0026\u0026t.push({correct:r.text,text:e.correctFeedback}),!e.isCorrect()\u0026\u0026e.incorrectFeedback\u0026\u0026t.push({correct:e.text,wrong:r.text,text:e.incorrectFeedback}))}),0!==t.length\u0026\u0026this.setExplanation(t,e.params.feedbackHeader)},n.prototype.showEvaluation=function(e){this.hideEvaluation(),this.showDropzoneFeedback(),this.showExplanation();var t=this.calculateScore(),r=this.droppables.length;if(!e){var n=this.createXAPIEventTemplate(\"answered\");this.addQuestionToXAPI(n),this.addResponseToXAPI(n),this.trigger(n)}var o=H5P.Question.determineOverallFeedback(this.params.overallFeedback,t/r).replace(/@score/g,t.toString()).replace(/@total/g,r.toString());return t===r\u0026\u0026(this.hideButton(\"check-answer\"),this.hideButton(\"show-solution\"),this.hideButton(\"try-again\"),this.disableDraggables()),this.trigger(\"resize\"),this.setFeedback(o,t,r,this.params.scoreBarLabel),t===r},n.prototype.calculateScore=function(){return this.droppables.reduce(function(e,t){return e+(t.isCorrect()?1:0)},0)},n.prototype.hideEvaluation=function(){this.removeFeedback(),this.trigger(\"resize\")},n.prototype.hideExplanation=function(){this.setExplanation(),this.trigger(\"resize\")},n.prototype.hideAllSolutions=function(){this.droppables.forEach(function(e){e.hideSolution()}),this.trigger(\"resize\")},n.prototype.addTaskTo=function(t){var r=this;r.widest=0,r.widestDraggable=0,r.droppables=[],r.draggables=[],r.$taskContainer=e(\"\u003cdiv/\u003e\",{class:\"h5p-drag-task\"}),r.$draggables=e(\"\u003cdiv/\u003e\",{class:\"h5p-drag-draggables-container\"}),r.$wordContainer=e(\"\u003cdiv/\u003e\",{class:\"h5p-drag-droppable-words\"}),(0,o.parseText)(r.textFieldHtml).forEach(function(e){if(r.isAnswerPart(e)){var t=(0,o.lex)(e),n=r.createDraggable(t.text),a=r.createDroppable(t.text,t.tip,t.correctFeedback,t.incorrectFeedback);r.params.behaviour.instantFeedback\u0026\u0026n.getDraggableElement().on(\"dragstop\",function(){a.addFeedback(),r.instantFeedbackEvaluation()})}else{var i=l.default.createElementWithTextPart(e);r.$wordContainer.append(i)}}),r.shuffleAndAddDraggables(r.$draggables),r.$draggables.appendTo(r.$taskContainer),r.$wordContainer.appendTo(r.$taskContainer),r.$taskContainer.appendTo(t),r.addDropzoneWidth()},n.prototype.isAnswerPart=function(e){return l.default.startsWith(\"*\",e)\u0026\u0026l.default.endsWith(\"*\",e)},n.prototype.addDropzoneWidth=function(){var e=this,t=0,r=0,n=parseInt(this.$inner.css(\"font-size\"),10),o=3*n,a=n;this.draggables.forEach(function(e){var n=e.getDraggableElement(),o=n.clone().css({position:\"absolute\",\"white-space\":\"nowrap\",width:\"auto\",padding:0,margin:0}).html(e.getAnswerText()).appendTo(n.parent()),i=o.outerWidth();r=i\u003er?i:r,o.text().length\u003e=20\u0026\u0026(o.html(e.getShortFormat()),i=o.width()),i+a\u003et\u0026\u0026(t=i+a),o.remove()}),t\u003co\u0026\u0026(t=o),this.widestDraggable=r,this.widest=t,this.droppables.forEach(function(t){t.getDropzone().width(e.widest)})},n.prototype.createDraggable=function(t){var r=this,n=e(\"\u003cdiv/\u003e\",{html:t,role:\"button\",\"aria-grabbed\":\"false\",tabindex:\"-1\"}).draggable({revert:function(e){return e||r.revert(o),!1},drag:r.propagateDragEvent(\"drag\",r),start:r.propagateDragEvent(\"start\",r),stop:function(e){r.trigger(\"stop\",{element:o.getElement(),target:e.target})},containment:r.$taskContainer}),o=new c.default(t,n,r.draggables.length);return o.on(\"addedToZone\",function(){r.triggerXAPI(\"interacted\")}),r.draggables.push(o),o},n.prototype.createDroppable=function(t,r,n,o){var a=this,i=this.draggables.length,s=e(\"\u003cdiv/\u003e\",{class:\"h5p-drag-dropzone-container\"}),l=e(\"\u003cdiv/\u003e\",{\"aria-dropeffect\":\"none\",\"aria-label\":this.params.dropZoneIndex.replace(\"@index\",i.toString())+\" \"+this.params.empty.replace(\"@index\",i.toString()),tabindex:\"-1\"}).appendTo(s).droppable({tolerance:\"pointer\",drop:function(e,t){var r=a.getDraggableByElement(t.draggable[0]),n=a.getDroppableByElement(e.target);r\u0026\u0026n\u0026\u0026a.drop(r,n)}}),u=new p.default(t,r,n,o,l,s,i,a.params);return u.appendDroppableTo(a.$wordContainer),a.droppables.push(u),u},n.prototype.propagateDragEvent=l.default.curry(function(e,t,r){t.trigger(e,{element:r.target})}),n.prototype.revert=function(e){var t=e.removeFromZone(),r=t?t.getElement():void 0;e.revertDraggableTo(this.$draggables),this.setDraggableAriaLabel(e),this.trigger(\"revert\",{element:e.getElement(),target:r}),this.trigger(\"resize\")},n.prototype.drop=function(e,t){var r=this;r.answered=!0,e.removeFromZone();var n=t.appendInsideDroppableTo(this.$draggables);n\u0026\u0026r.trigger(\"revert\",{element:n.getElement(),target:t.getElement()}),t.setDraggable(e),e.appendDraggableTo(t.getDropzone()),r.params.behaviour.instantFeedback\u0026\u0026(t.addFeedback(),r.instantFeedbackEvaluation(),r.params.behaviour.enableRetry\u0026\u0026!t.isCorrect()||t.disableDropzoneAndContainedDraggable()),this.trigger(\"drop\",{element:e.getElement(),target:t.getElement()}),this.trigger(\"resize\"),t.getElement().focus()},n.prototype.shuffleAndAddDraggables=function(e){var t=this;return l.default.shuffle(this.draggables).map(function(e,t){return e.setIndex(t)}).map(function(r){return t.addDraggableToContainer(e,r)}).map(function(e){return t.setDraggableAriaLabel(e)}).map(function(e){return t.addDraggableToControls(t.dragControls,e)})},n.prototype.setDraggableAriaLabel=function(e){e.text;if(e.isInsideDropZone()){e.getInsideDropzone().getDropzone().attr(\"aria-label\")}var t=this.draggables.length,r=this.params.draggableIndex.replace(\"@text\",e.text).replace(\"@index\",(e.getIndex()+1).toString()).replace(\"@count\",t.toString()),n=this.isGrabbed(e.getElement())?this.params.grabbed:\"\";return e.$draggable.attr(\"aria-label\",r+\" \"+n),e},n.prototype.isGrabbed=function(e){return\"true\"===e.getAttribute(\"aria-grabbed\")},n.prototype.addDraggableToContainer=function(e,t){return t.appendDraggableTo(e),t},n.prototype.addDraggableToControls=function(e,t){return e.addElement(t.getElement()),t},n.prototype.instantFeedbackEvaluation=function(){var e=this;e.isAllAnswersFilled()?(e.params.behaviour.enableSolutionsButton\u0026\u0026e.showButton(\"show-solution\"),e.params.behaviour.enableRetry\u0026\u0026e.showButton(\"try-again\"),e.showEvaluation()):(e.hideButton(\"try-again\"),e.hideButton(\"show-solution\"),e.hideEvaluation())},n.prototype.isAllAnswersFilled=function(){return this.draggables.every(function(e){return e.isInsideDropZone()})},n.prototype.enableAllDropzonesAndDraggables=function(){this.enableDraggables(),this.droppables.forEach(function(e){e.enableDropzone()})},n.prototype.disableDraggables=function(){this.draggables.forEach(function(e){e.disableDraggable()})},n.prototype.enableDraggables=function(){this.draggables.forEach(function(e){e.enableDraggable()})},n.prototype.getAnswerGiven=function(){return this.answered},n.prototype.getScore=function(){return this.calculateScore()},n.prototype.getMaxScore=function(){return this.droppables.length},n.prototype.getTitle=function(){return H5P.createTitle(this.params.taskDescription)},n.prototype.toggleDropEffect=function(){var e=void 0!==this.selectedElement;this.ariaDropControls[e?\"setAllToMove\":\"setAllToNone\"]()},n.prototype.getDraggableByElement=function(e){return this.draggables.filter(function(t){return t.$draggable.get(0)===e},this)[0]},n.prototype.getDroppableByElement=function(e){return this.droppables.filter(function(t){return t.$dropzone.get(0)===e},this)[0]},n.prototype.showSolutions=function(){this.showEvaluation(!0),this.droppables.forEach(function(e){e.addFeedback(),e.showSolution()}),this.removeAllDroppablesFromControls(),this.disableDraggables(),this.hideButton(\"try-again\"),this.hideButton(\"show-solution\"),this.hideButton(\"check-answer\"),this.trigger(\"resize\")},n.prototype.resetTask=function(){var e=this;e.answered=!1,e.resetDraggables(),e.hideEvaluation(),e.enableAllDropzonesAndDraggables(),e.hideButton(\"try-again\"),e.hideButton(\"show-solution\"),e.params.behaviour.instantFeedback||e.showButton(\"check-answer\"),e.hideAllSolutions(),this.trigger(\"resize\")},n.prototype.resetDraggables=function(){l.default.shuffle(this.draggables).forEach(this.revert,this)},n.prototype.getCurrentState=function(){var e=this;if(void 0!==this.draggables)return this.draggables.filter(function(e){return null!==e.getInsideDropzone()}).map(function(t){return{draggable:t.getInitialIndex(),droppable:e.droppables.indexOf(t.getInsideDropzone())}})},n.prototype.setH5PUserState=function(){var e=this,t=this;void 0!==this.previousState\u0026\u0026(this.previousState.forEach(function(r){if(!t.isValidIndex(r.draggable)||!t.isValidIndex(r.droppable))throw new Error(\"Stored user state is invalid\");var n=e.getDraggableByInitialIndex(r.draggable),o=t.droppables[r.droppable];t.drop(n,o),t.params.behaviour.instantFeedback\u0026\u0026(null!==o\u0026\u0026o.addFeedback(),o.isCorrect()\u0026\u0026o.disableDropzoneAndContainedDraggable())}),t.params.behaviour.instantFeedback\u0026\u0026t.isAllAnswersFilled()\u0026\u0026!t.showEvaluation()\u0026\u0026(t.params.behaviour.enableSolutionsButton\u0026\u0026(t.initShowShowSolutionButton=!0),t.params.behaviour.enableRetry\u0026\u0026(t.initShowTryAgainButton=!0)))},n.prototype.isValidIndex=function(e){return!isNaN(e)\u0026\u0026e\u003cthis.draggables.length\u0026\u0026e\u003e=0},n.prototype.getDraggableByInitialIndex=function(e){return this.draggables.filter(function(t){return t.hasInitialIndex(e)})[0]},n.prototype.getXAPIData=function(){var e=this.createXAPIEventTemplate(\"answered\");return this.addQuestionToXAPI(e),this.addResponseToXAPI(e),{statement:e.data.statement}},n.prototype.addQuestionToXAPI=function(t){var r=t.getVerifiedStatementValue([\"object\",\"definition\"]);e.extend(r,this.getxAPIDefinition())},n.prototype.getxAPIDefinition=function(){var e={};e.interactionType=\"fill-in\",e.type=\"http://adlnet.gov/expapi/activities/cmi.interaction\";var t=this.textFieldHtml,r=this.params.taskDescription+\"\u003cbr/\u003e\";return e.description={\"en-US\":r+this.replaceSolutionsWithBlanks(t)},e.correctResponsesPattern=[this.getSolutionsFromQuestion(t)],e},n.prototype.addResponseToXAPI=function(e){var t,r=this,n=r.getScore(),o=r.droppables.length;e.setScoredResult(n,o,r);var a={min:0,raw:n,max:o,scaled:Math.round(n/o*1e4)/1e4};r.stopWatch\u0026\u0026(t=\"PT\"+r.stopWatch.stop()+\"S\"),e.data.statement.result={response:r.getXAPIResponse(),score:a,duration:t,completion:!0}},n.prototype.getXAPIResponse=function(){return this.droppables.map(function(e){return e.hasDraggable()?e.containedDraggable.text:\"\"}).join(\"[,]\")},n.prototype.replaceSolutionsWithBlanks=function(e){var t=this;return(0,o.parseText)(e).map(function(e){return t.isAnswerPart(e)?\"__________\":e}).join(\"\")},n.prototype.getSolutionsFromQuestion=function(e){return(0,o.parseText)(e).filter(this.isAnswerPart).map(function(e){return(0,o.lex)(e)}).map(function(e){return e.text}).join(\"[,]\")},n}(H5P.jQuery,H5P.Question,H5P.ConfirmationDialog),t.default=H5P.DragText},function(e,t){},function(e,t,r){\"use strict\";function n(e,t){if(!(e instanceof t))throw new TypeError(\"Cannot call a class as a function\")}Object.defineProperty(t,\"__esModule\",{value:!0});var o=function(){function e(e,t){for(var r=0;r\u003ct.length;r++){var n=t[r];n.enumerable=n.enumerable||!1,n.configurable=!0,\"value\"in n\u0026\u0026(n.writable=!0),Object.defineProperty(e,n.key,n)}}return function(t,r,n){return r\u0026\u0026e(t.prototype,r),n\u0026\u0026e(t,n),t}}(),a=r(1),i=r(0),s=(0,a.setAttribute)(\"aria-grabbed\"),l=(0,a.attributeEquals)(\"aria-grabbed\",\"true\"),u=(0,i.filter)((0,a.hasAttribute)(\"aria-grabbed\")),c=(0,i.compose)((0,i.forEach)((0,a.setAttribute)(\"aria-grabbed\",\"false\")),u),d=(0,i.compose)((0,i.some)(l),u),p=function(){function e(){n(this,e)}return o(e,[{key:\"init\",value:function(e){this.controls=e,this.controls.on(\"select\",this.select,this)}},{key:\"addElement\",value:function(e){s(\"false\",e),this.controls.addElement(e)}},{key:\"setAllGrabbedToFalse\",value:function(){c(this.controls.elements)}},{key:\"hasAnyGrabbed\",value:function(){return d(this.controls.elements)}},{key:\"select\",value:function(e){var t=e.element,r=l(t);this.setAllGrabbedToFalse(),r||s(\"true\",t)}}]),e}();t.default=p},function(e,t,r){\"use strict\";function n(e,t){if(!(e instanceof t))throw new TypeError(\"Cannot call a class as a function\")}Object.defineProperty(t,\"__esModule\",{value:!0});var o=function(){function e(e,t){for(var r=0;r\u003ct.length;r++){var n=t[r];n.enumerable=n.enumerable||!1,n.configurable=!0,\"value\"in n\u0026\u0026(n.writable=!0),Object.defineProperty(e,n.key,n)}}return function(t,r,n){return r\u0026\u0026e(t.prototype,r),n\u0026\u0026e(t,n),t}}(),a=r(1),i=r(0),s=(0,a.setAttribute)(\"aria-dropeffect\",\"none\"),l=(0,a.setAttribute)(\"aria-dropeffect\",\"move\"),u=(0,i.filter)((0,a.hasAttribute)(\"aria-dropeffect\")),c=(0,i.compose)((0,i.forEach)(l),u),d=(0,i.compose)((0,i.forEach)(s),u),p=function(){function e(){n(this,e)}return o(e,[{key:\"init\",value:function(e){this.controls=e}},{key:\"setAllToMove\",value:function(){c(this.controls.elements)}},{key:\"setAllToNone\",value:function(){d(this.controls.elements)}}]),e}();t.default=p,p.DropEffect={COPY:\"copy\",MOVE:\"move\",EXECUTE:\"execute\",POPUP:\"popup\",NONE:\"none\"}},function(e,t,r){\"use strict\";function n(e,t){if(!(e instanceof t))throw new TypeError(\"Cannot call a class as a function\")}Object.defineProperty(t,\"__esModule\",{value:!0});var o=Object.assign||function(e){for(var t=1;t\u003carguments.length;t++){var r=arguments[t];for(var n in r)Object.prototype.hasOwnProperty.call(r,n)\u0026\u0026(e[n]=r[n])}return e},a=function(){function e(e,t){for(var r=0;r\u003ct.length;r++){var n=t[r];n.enumerable=n.enumerable||!1,n.configurable=!0,\"value\"in n\u0026\u0026(n.writable=!0),Object.defineProperty(e,n.key,n)}}return function(t,r,n){return r\u0026\u0026e(t.prototype,r),n\u0026\u0026e(t,n),t}}(),i=r(1),s=r(0),l=r(8),u=(0,i.removeAttribute)(\"tabindex\"),c=((0,s.forEach)(u),(0,i.setAttribute)(\"tabindex\",\"0\")),d=(0,i.setAttribute)(\"tabindex\",\"-1\"),p=(0,i.hasAttribute)(\"tabindex\"),h=function(){function e(t){n(this,e),o(this,(0,l.Eventful)()),this.plugins=t||[],this.elements=[],this.negativeTabIndexAllowed=!1,this.on(\"nextElement\",this.nextElement,this),this.on(\"previousElement\",this.previousElement,this),this.initPlugins()}return a(e,[{key:\"addElement\",value:function(e){this.elements.push(e),this.firesEvent(\"addElement\",e),1===this.elements.length\u0026\u0026this.setTabbable(e)}},{key:\"insertElementAt\",value:function(e,t){this.elements.splice(t,0,e),this.firesEvent(\"addElement\",e),1===this.elements.length\u0026\u0026this.setTabbable(e)}},{key:\"removeElement\",value:function(e){this.elements=(0,s.without)([e],this.elements),p(e)\u0026\u0026(this.setUntabbable(e),this.elements[0]\u0026\u0026this.setTabbable(this.elements[0])),this.firesEvent(\"removeElement\",e)}},{key:\"count\",value:function(){return this.elements.length}},{key:\"firesEvent\",value:function(e,t){var r=this.elements.indexOf(t);return this.fire(e,{element:t,index:r,elements:this.elements,oldElement:this.tabbableElement})}},{key:\"nextElement\",value:function(e){var t=e.index,r=t===this.elements.length-1,n=this.elements[r?0:t+1];this.setTabbable(n),n.focus()}},{key:\"setTabbable\",value:function(e){(0,s.forEach)(this.setUntabbable.bind(this),this.elements),c(e),this.tabbableElement=e}},{key:\"setUntabbable\",value:function(e){this.negativeTabIndexAllowed?d(e):u(e)}},{key:\"previousElement\",value:function(e){var t=e.index,r=0===t,n=this.elements[r?this.elements.length-1:t-1];this.setTabbable(n),n.focus()}},{key:\"useNegativeTabIndex\",value:function(){this.negativeTabIndexAllowed=!0,this.elements.forEach(function(e){e.hasAttribute(\"tabindex\")||d(e)})}},{key:\"initPlugins\",value:function(){this.plugins.forEach(function(e){void 0!==e.init\u0026\u0026e.init(this)},this)}}]),e}();t.default=h},function(e,t,r){\"use strict\";Object.defineProperty(t,\"__esModule\",{value:!0});t.Eventful=function(){return{listeners:{},on:function(e,t,r){var n={listener:t,scope:r};return this.listeners[e]=this.listeners[e]||[],this.listeners[e].push(n),this},fire:function(e,t){return(this.listeners[e]||[]).every(function(e){return!1!==e.listener.call(e.scope||this,t)})},propagate:function(e,t){var r=this;e.forEach(function(e){return t.on(e,function(t){return r.fire(e,t)})})}}}},function(e,t,r){\"use strict\";function n(e,t){if(!(e instanceof t))throw new TypeError(\"Cannot call a class as a function\")}Object.defineProperty(t,\"__esModule\",{value:!0});var o=function(){function e(e,t){for(var r=0;r\u003ct.length;r++){var n=t[r];n.enumerable=n.enumerable||!1,n.configurable=!0,\"value\"in n\u0026\u0026(n.writable=!0),Object.defineProperty(e,n.key,n)}}return function(t,r,n){return r\u0026\u0026e(t.prototype,r),n\u0026\u0026e(t,n),t}}(),a=function(){function e(){n(this,e),this.selectability=!0}return o(e,[{key:\"init\",value:function(e){this.boundHandleKeyDown=this.handleKeyDown.bind(this),this.controls=e,this.controls.on(\"addElement\",this.listenForKeyDown,this),this.controls.on(\"removeElement\",this.removeKeyDownListener,this)}},{key:\"listenForKeyDown\",value:function(e){e.element.addEventListener(\"keydown\",this.boundHandleKeyDown)}},{key:\"removeKeyDownListener\",value:function(e){e.element.removeEventListener(\"keydown\",this.boundHandleKeyDown)}},{key:\"handleKeyDown\",value:function(e){switch(e.which){case 13:case 32:this.select(e.target),e.preventDefault();break;case 37:case 38:this.hasChromevoxModifiers(e)||(this.previousElement(e.target),e.preventDefault());break;case 39:case 40:this.hasChromevoxModifiers(e)||(this.nextElement(e.target),e.preventDefault())}}},{key:\"hasChromevoxModifiers\",value:function(e){return e.shiftKey||e.ctrlKey}},{key:\"previousElement\",value:function(e){this.controls.firesEvent(\"previousElement\",e)}},{key:\"nextElement\",value:function(e){this.controls.firesEvent(\"nextElement\",e)}},{key:\"select\",value:function(e){this.selectability\u0026\u0026!1!==this.controls.firesEvent(\"before-select\",e)\u0026\u0026(this.controls.firesEvent(\"select\",e),this.controls.firesEvent(\"after-select\",e))}},{key:\"disableSelectability\",value:function(){this.selectability=!1}},{key:\"enableSelectability\",value:function(){this.selectability=!0}}]),e}();t.default=a},function(e,t,r){\"use strict\";r(4),H5P=H5P||{},H5P.DragText=r(3).default},function(e,t,r){\"use strict\";Object.defineProperty(t,\"__esModule\",{value:!0}),H5P.TextDraggable=function(e){function t(t,r,n){H5P.EventDispatcher.call(this);var o=this;o.text=t,o.insideDropzone=null,o.$draggable=e(r),o.index=n,o.initialIndex=n,o.shortFormat=o.text,o.shortFormat.length\u003e20\u0026\u0026(o.shortFormat=o.shortFormat.slice(0,17)+\"...\")}return t.prototype=Object.create(H5P.EventDispatcher.prototype),t.prototype.constructor=t,t.prototype.getIndex=function(){return this.index},t.prototype.setIndex=function(e){return this.index=e,this},t.prototype.getInitialIndex=function(){return this.initialIndex},t.prototype.hasInitialIndex=function(e){return this.initialIndex===e},t.prototype.appendDraggableTo=function(e){this.$draggable.detach().css({left:0,top:0}).appendTo(e)},t.prototype.revertDraggableTo=function(e){var t=this.$draggable.offset().left-e.offset().left,r=this.$draggable.offset().top-e.offset().top;this.$draggable.detach().prependTo(e).css({left:t,top:r}).animate({left:0,top:0})},t.prototype.toggleDroppedFeedback=function(e){e?this.$draggable.addClass(\"h5p-drag-dropped\"):this.$draggable.removeClass(\"h5p-drag-dropped\")},t.prototype.disableDraggable=function(){this.$draggable.draggable({disabled:!0})},t.prototype.enableDraggable=function(){this.$draggable.draggable({disabled:!1})},t.prototype.getDraggableElement=function(){return this.$draggable},t.prototype.getElement=function(){return this.$draggable.get(0)},t.prototype.removeFromZone=function(){var e=this.insideDropzone;return null!==this.insideDropzone\u0026\u0026(this.insideDropzone.removeFeedback(),this.insideDropzone.removeDraggable()),this.toggleDroppedFeedback(!1),this.removeShortFormat(),this.insideDropzone=null,e},t.prototype.addToZone=function(e){null!==this.insideDropzone\u0026\u0026this.insideDropzone.removeDraggable(),this.toggleDroppedFeedback(!0),this.insideDropzone=e,this.setShortFormat(),this.trigger(\"addedToZone\")},t.prototype.getAnswerText=function(){return this.text},t.prototype.setShortFormat=function(){this.$draggable.html(this.shortFormat)},t.prototype.getShortFormat=function(){return this.shortFormat},t.prototype.removeShortFormat=function(){this.$draggable.html(this.text)},t.prototype.getInsideDropzone=function(){return this.insideDropzone},t.prototype.isInsideDropZone=function(){return!!this.insideDropzone},t}(H5P.jQuery),t.default=H5P.TextDraggable},function(e,t,r){\"use strict\";Object.defineProperty(t,\"__esModule\",{value:!0}),H5P.TextDroppable=function(e){function t(t,n,o,a,i,s,l,u){var c=this;c.text=t,c.tip=n,c.correctFeedback=o,c.incorrectFeedback=a,c.index=l,c.params=u,c.containedDraggable=null,c.$dropzone=e(i),c.$dropzoneContainer=e(s),c.tip\u0026\u0026(c.$tip=H5P.JoubelUI.createTip(c.tip,{tipLabel:c.params.tipLabel}),c.$tip.attr(\"tabindex\",\"-1\"),c.$dropzoneContainer.append(c.$tip),c.$dropzone.focus(function(){return c.$tip.attr(\"tabindex\",\"0\")}),c.$dropzone.blur(function(){return c.removeTipTabIndexIfNoFocus()}),c.$tip.blur(function(){return c.removeTipTabIndexIfNoFocus()})),c.$incorrectText=e(\"\u003cdiv/\u003e\",{html:c.params.incorrectText+\" \"+c.params.correctAnswer,class:\"correct-answer\"}),c.$correctText=e(\"\u003cdiv/\u003e\",{html:c.params.correctText,class:\"correct-answer\"}),c.$showSolution=e(\"\u003cdiv/\u003e\",{class:r}).appendTo(c.$dropzoneContainer).hide()}var r=\"h5p-drag-show-solution-container\",n=\"h5p-drag-correct-feedback\",o=\"h5p-drag-wrong-feedback\";return t.prototype.removeTipTabIndexIfNoFocus=function(){var e=this;setTimeout(function(){e.$dropzone.is(\":focus\")||e.$tip.is(\":focus\")||e.$tip.attr(\"tabindex\",\"-1\")},0)},t.prototype.showSolution=function(){null===this.containedDraggable||this.containedDraggable.getAnswerText()!==this.text?(this.$showSolution.html(this.text),this.$showSolution.prepend(this.$incorrectText)):this.$showSolution.prepend(this.$correctText),this.$showSolution.show()},t.prototype.hideSolution=function(){this.$showSolution.html(\"\"),this.$showSolution.hide()},t.prototype.getElement=function(){return this.$dropzone.get(0)},t.prototype.appendDroppableTo=function(e){this.$dropzoneContainer.appendTo(e)},t.prototype.appendInsideDroppableTo=function(e){if(null!==this.containedDraggable)return this.containedDraggable.revertDraggableTo(e),this.containedDraggable},t.prototype.setDraggable=function(e){var t=this;t.containedDraggable!==e\u0026\u0026(null!==t.containedDraggable\u0026\u0026t.containedDraggable.removeFromZone(),t.containedDraggable=e,e.addToZone(t))},t.prototype.hasDraggable=function(){return!!this.containedDraggable},t.prototype.removeDraggable=function(){null!==this.containedDraggable\u0026\u0026(this.containedDraggable=null)},t.prototype.isCorrect=function(){return null!==this.containedDraggable\u0026\u0026this.containedDraggable.getAnswerText()===this.text},t.prototype.addFeedback=function(){this.isCorrect()?(this.$dropzone.removeClass(o).addClass(n),this.containedDraggable.getDraggableElement().removeClass(\"h5p-drag-draggable-wrong\").addClass(\"h5p-drag-draggable-correct\")):null===this.containedDraggable?this.$dropzone.removeClass(o).removeClass(n):(this.$dropzone.removeClass(n).addClass(o),null!==this.containedDraggable\u0026\u0026this.containedDraggable.getDraggableElement().addClass(\"h5p-drag-draggable-wrong\").removeClass(\"h5p-drag-draggable-correct\"))},t.prototype.removeFeedback=function(){this.$dropzone.removeClass(o).removeClass(n),null!==this.containedDraggable\u0026\u0026this.containedDraggable.getDraggableElement().removeClass(\"h5p-drag-draggable-wrong\").removeClass(\"h5p-drag-draggable-correct\")},t.prototype.hasFeedback=function(){return this.$dropzone.hasClass(o)||this.$dropzone.hasClass(n)},t.prototype.setShortFormat=function(){null!==this.containedDraggable\u0026\u0026this.containedDraggable.setShortFormat()},t.prototype.disableDropzoneAndContainedDraggable=function(){null!==this.containedDraggable\u0026\u0026this.containedDraggable.disableDraggable(),this.$dropzone.droppable({disabled:!0})},t.prototype.enableDropzone=function(){this.$dropzone.droppable({disabled:!1})},t.prototype.removeShortFormat=function(){null!==this.containedDraggable\u0026\u0026this.containedDraggable.removeShortFormat()},t.prototype.getDropzone=function(){return this.$dropzone},t.prototype.getIndex=function(){return this.index},t}(H5P.jQuery),t.default=H5P.TextDroppable},function(e,t,r){\"use strict\";Object.defineProperty(t,\"__esModule\",{value:!0}),t.lex=t.parseText=void 0;var n=r(2),o=function(e){return e\u0026\u0026e.__esModule?e:{default:e}}(n),a=function(e){return e.split(/(\\*.*?\\*)/).filter(function(e){return e.length\u003e0})},i=function(e){var t=e.match(/(:([^\\\\*]+))/g),r=e.match(/(\\\\\\+([^\\\\*:]+))/g),n=e.match(/(\\\\\\-([^\\\\*:]+))/g),a=o.default.cleanCharacter(\"*\",e).replace(t,\"\").replace(r,\"\").replace(n,\"\");return a=a.replace(/\\s+$/,\"\"),t\u0026\u0026(t=t[0].replace(\":\",\"\"),t=t.replace(/\\s+$/,\"\")),r\u0026\u0026(r=r[0].replace(\"\\\\+\",\"\"),r=r.replace(/\\s+$/,\"\")),n\u0026\u0026(n=n[0].replace(\"\\\\-\",\"\"),n=n.replace(/\\s+$/,\"\")),{tip:t,correctFeedback:r,incorrectFeedback:n,text:a}};t.parseText=a,t.lex=i},function(e,t,r){\"use strict\";Object.defineProperty(t,\"__esModule\",{value:!0});var n=n||{};n.DragText=n.DragText||{},n.DragText.StopWatch=function(){function e(){this.duration=0}return e.prototype.start=function(){return this.startTime=Date.now(),this},e.prototype.stop=function(){return this.duration=this.duration+Date.now()-this.startTime,this.passedTime()},e.prototype.reset=function(){this.duration=0,this.startTime=Date.now()},e.prototype.passedTime=function(){return Math.round(this.duration/10)/100},e}(),t.default=n.DragText.StopWatch}]);"
,"scripts/shepherd.js":"var oldShepherd = window.Shepherd;\r\n\r\n(function(root, Tether, factory ) {\r\n if (typeof define === \u0027function\u0027 \u0026\u0026 define.amd) {\r\n define([\"tether\"], factory);\r\n } else if (typeof exports === \u0027object\u0027) {\r\n module.exports = factory(require(\u0027tether\u0027));\r\n } else {\r\n root.Shepherd = factory(Tether);\r\n }\r\n}(this, H5P.Tether, function(Tether) {\r\n\r\n/* global Tether */\r\n\r\n\u0027use strict\u0027;\r\n\r\nvar _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i \u003c props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\u0027value\u0027 in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();\r\n\r\nvar _get = function get(_x4, _x5, _x6) { var _again = true; _function: while (_again) { var object = _x4, property = _x5, receiver = _x6; desc = parent = getter = undefined; _again = false; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { _x4 = parent; _x5 = property; _x6 = receiver; _again = true; continue _function; } } else if (\u0027value\u0027 in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } } };\r\n\r\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\u0027Cannot call a class as a function\u0027); } }\r\n\r\nfunction _inherits(subClass, superClass) { if (typeof superClass !== \u0027function\u0027 \u0026\u0026 superClass !== null) { throw new TypeError(\u0027Super expression must either be null or a function, not \u0027 + typeof superClass); } subClass.prototype = Object.create(superClass \u0026\u0026 superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) subClass.__proto__ = superClass; }\r\n\r\nvar _Tether$Utils = Tether.Utils;\r\nvar Evented = _Tether$Utils.Evented;\r\nvar addClass = _Tether$Utils.addClass;\r\nvar extend = _Tether$Utils.extend;\r\nvar hasClass = _Tether$Utils.hasClass;\r\nvar removeClass = _Tether$Utils.removeClass;\r\nvar uniqueId = _Tether$Utils.uniqueId;\r\n\r\nvar Shepherd = new Evented();\r\n\r\nvar ATTACHMENT = {\r\n \u0027top\u0027: \u0027bottom center\u0027,\r\n \u0027left\u0027: \u0027middle right\u0027,\r\n \u0027right\u0027: \u0027middle left\u0027,\r\n \u0027bottom\u0027: \u0027top center\u0027,\r\n \u0027center\u0027: \u0027middle center\u0027\r\n};\r\n\r\nfunction createFromHTML(html) {\r\n var el = document.createElement(\u0027div\u0027);\r\n el.innerHTML = html;\r\n return el.children[0];\r\n}\r\n\r\nfunction matchesSelector(el, sel) {\r\n var matches = undefined;\r\n if (typeof el.matches !== \u0027undefined\u0027) {\r\n matches = el.matches;\r\n } else if (typeof el.matchesSelector !== \u0027undefined\u0027) {\r\n matches = el.matchesSelector;\r\n } else if (typeof el.msMatchesSelector !== \u0027undefined\u0027) {\r\n matches = el.msMatchesSelector;\r\n } else if (typeof el.webkitMatchesSelector !== \u0027undefined\u0027) {\r\n matches = el.webkitMatchesSelector;\r\n } else if (typeof el.mozMatchesSelector !== \u0027undefined\u0027) {\r\n matches = el.mozMatchesSelector;\r\n } else if (typeof el.oMatchesSelector !== \u0027undefined\u0027) {\r\n matches = el.oMatchesSelector;\r\n }\r\n return matches.call(el, sel);\r\n}\r\n\r\nfunction parseShorthand(obj, props) {\r\n if (obj === null || typeof obj === \u0027undefined\u0027) {\r\n return obj;\r\n } else if (typeof obj === \u0027object\u0027) {\r\n return obj;\r\n }\r\n\r\n var vals = obj.split(\u0027 \u0027);\r\n var valsLen = vals.length;\r\n var propsLen = props.length;\r\n if (valsLen \u003e propsLen) {\r\n vals[0] = vals.slice(0, valsLen - propsLen + 1).join(\u0027 \u0027);\r\n vals.splice(1, (valsLen, propsLen));\r\n }\r\n\r\n var out = {};\r\n for (var i = 0; i \u003c propsLen; ++i) {\r\n var prop = props[i];\r\n out[prop] = vals[i];\r\n }\r\n\r\n return out;\r\n}\r\n\r\nvar Step = (function (_Evented) {\r\n function Step(tour, options) {\r\n _classCallCheck(this, Step);\r\n\r\n _get(Object.getPrototypeOf(Step.prototype), \u0027constructor\u0027, this).call(this, tour, options);\r\n this.tour = tour;\r\n this.bindMethods();\r\n this.setOptions(options);\r\n return this;\r\n }\r\n\r\n _inherits(Step, _Evented);\r\n\r\n _createClass(Step, [{\r\n key: \u0027bindMethods\u0027,\r\n value: function bindMethods() {\r\n var _this = this;\r\n\r\n var methods = [\u0027_show\u0027, \u0027show\u0027, \u0027hide\u0027, \u0027isOpen\u0027, \u0027cancel\u0027, \u0027complete\u0027, \u0027scrollTo\u0027, \u0027destroy\u0027];\r\n methods.map(function (method) {\r\n _this[method] = _this[method].bind(_this);\r\n });\r\n }\r\n }, {\r\n key: \u0027setOptions\u0027,\r\n value: function setOptions() {\r\n var options = arguments[0] === undefined ? {} : arguments[0];\r\n\r\n this.options = options;\r\n this.destroy();\r\n\r\n this.id = this.options.id || this.id || \u0027step-\u0027 + uniqueId();\r\n\r\n var when = this.options.when;\r\n if (when) {\r\n for (var _event in when) {\r\n if (({}).hasOwnProperty.call(when, _event)) {\r\n var handler = when[_event];\r\n this.on(_event, handler, this);\r\n }\r\n }\r\n }\r\n\r\n if (!this.options.buttons) {\r\n this.options.buttons = [{\r\n text: \u0027Next\u0027,\r\n action: this.tour.next\r\n }];\r\n }\r\n }\r\n }, {\r\n key: \u0027getTour\u0027,\r\n value: function getTour() {\r\n return this.tour;\r\n }\r\n }, {\r\n key: \u0027bindAdvance\u0027,\r\n value: function bindAdvance() {\r\n var _this2 = this;\r\n\r\n // An empty selector matches the step element\r\n\r\n var _parseShorthand = parseShorthand(this.options.advanceOn, [\u0027selector\u0027, \u0027event\u0027]);\r\n\r\n var event = _parseShorthand.event;\r\n var selector = _parseShorthand.selector;\r\n\r\n var handler = function handler(e) {\r\n if (!_this2.isOpen()) {\r\n return;\r\n }\r\n\r\n if (typeof selector !== \u0027undefined\u0027) {\r\n if (matchesSelector(e.target, selector)) {\r\n _this2.tour.next();\r\n }\r\n } else {\r\n if (_this2.el \u0026\u0026 e.target === _this2.el) {\r\n _this2.tour.next();\r\n }\r\n }\r\n };\r\n\r\n // TODO: this should also bind/unbind on show/hide\r\n document.body.addEventListener(event, handler);\r\n this.on(\u0027destroy\u0027, function () {\r\n return document.body.removeEventListener(event, handler);\r\n });\r\n }\r\n }, {\r\n key: \u0027getAttachTo\u0027,\r\n value: function getAttachTo() {\r\n var opts = parseShorthand(this.options.attachTo, [\u0027element\u0027, \u0027on\u0027]) || {};\r\n var selector = opts.element;\r\n\r\n if (typeof selector === \u0027string\u0027) {\r\n opts.element = document.querySelector(selector);\r\n\r\n if (!opts.element) {\r\n throw new Error(\u0027The element for this Shepherd step was not found \u0027 + selector);\r\n }\r\n }\r\n\r\n return opts;\r\n }\r\n }, {\r\n key: \u0027setupTether\u0027,\r\n value: function setupTether() {\r\n if (typeof Tether === \u0027undefined\u0027) {\r\n throw new Error(\u0027Using the attachment feature of Shepherd requires the Tether library\u0027);\r\n }\r\n\r\n var opts = this.getAttachTo();\r\n var attachment = ATTACHMENT[opts.on || \u0027right\u0027];\r\n if (typeof opts.element === \u0027undefined\u0027) {\r\n opts.element = \u0027viewport\u0027;\r\n attachment = \u0027middle center\u0027;\r\n }\r\n\r\n var tetherOpts = {\r\n classPrefix: \u0027shepherd\u0027,\r\n element: this.el,\r\n constraints: [{\r\n to: \u0027window\u0027,\r\n pin: true,\r\n attachment: \u0027together\u0027\r\n }],\r\n target: opts.element,\r\n offset: opts.offset || \u00270 0\u0027,\r\n attachment: attachment\r\n };\r\n\r\n if (this.tether) {\r\n this.tether.destroy();\r\n }\r\n\r\n this.tether = new Tether(extend(tetherOpts, this.options.tetherOptions));\r\n }\r\n }, {\r\n key: \u0027show\u0027,\r\n value: function show() {\r\n var _this3 = this;\r\n\r\n if (typeof this.options.beforeShowPromise !== \u0027undefined\u0027) {\r\n var beforeShowPromise = this.options.beforeShowPromise();\r\n if (typeof beforeShowPromise !== \u0027undefined\u0027) {\r\n return beforeShowPromise.then(function () {\r\n return _this3._show();\r\n });\r\n }\r\n }\r\n this._show();\r\n }\r\n }, {\r\n key: \u0027_show\u0027,\r\n value: function _show() {\r\n var _this4 = this;\r\n\r\n this.trigger(\u0027before-show\u0027);\r\n\r\n if (!this.el) {\r\n this.render();\r\n }\r\n\r\n addClass(this.el, \u0027shepherd-open\u0027);\r\n\r\n document.body.setAttribute(\u0027data-shepherd-step\u0027, this.id);\r\n\r\n this.setupTether();\r\n\r\n if (this.options.scrollTo) {\r\n setTimeout(function () {\r\n _this4.scrollTo();\r\n });\r\n }\r\n\r\n this.trigger(\u0027show\u0027);\r\n }\r\n }, {\r\n key: \u0027hide\u0027,\r\n value: function hide() {\r\n this.trigger(\u0027before-hide\u0027);\r\n\r\n removeClass(this.el, \u0027shepherd-open\u0027);\r\n\r\n document.body.removeAttribute(\u0027data-shepherd-step\u0027);\r\n\r\n if (this.tether) {\r\n this.tether.destroy();\r\n }\r\n this.tether = null;\r\n\r\n this.trigger(\u0027hide\u0027);\r\n }\r\n }, {\r\n key: \u0027isOpen\u0027,\r\n value: function isOpen() {\r\n return hasClass(this.el, \u0027shepherd-open\u0027);\r\n }\r\n }, {\r\n key: \u0027cancel\u0027,\r\n value: function cancel() {\r\n this.tour.cancel();\r\n this.trigger(\u0027cancel\u0027);\r\n }\r\n }, {\r\n key: \u0027complete\u0027,\r\n value: function complete() {\r\n this.tour.complete();\r\n this.trigger(\u0027complete\u0027);\r\n }\r\n }, {\r\n key: \u0027scrollTo\u0027,\r\n value: function scrollTo() {\r\n var _getAttachTo = this.getAttachTo();\r\n\r\n var element = _getAttachTo.element;\r\n\r\n if (typeof this.options.scrollToHandler !== \u0027undefined\u0027) {\r\n this.options.scrollToHandler(element);\r\n } else if (typeof element !== \u0027undefined\u0027) {\r\n element.scrollIntoView();\r\n }\r\n }\r\n }, {\r\n key: \u0027destroy\u0027,\r\n value: function destroy() {\r\n if (typeof this.el !== \u0027undefined\u0027) {\r\n document.body.removeChild(this.el);\r\n delete this.el;\r\n }\r\n\r\n if (this.tether) {\r\n this.tether.destroy();\r\n }\r\n this.tether = null;\r\n\r\n this.trigger(\u0027destroy\u0027);\r\n }\r\n }, {\r\n key: \u0027render\u0027,\r\n value: function render() {\r\n var _this5 = this;\r\n\r\n if (typeof this.el !== \u0027undefined\u0027) {\r\n this.destroy();\r\n }\r\n\r\n this.el = createFromHTML(\u0027\u003cdiv class=\\\u0027shepherd-step \u0027 + (this.options.classes || \u0027\u0027) + \u0027\\\u0027 data-id=\\\u0027\u0027 + this.id + \u0027\\\u0027 \u0027 + (this.options.idAttribute ? \u0027id=\"\u0027 + this.options.idAttribute + \u0027\"\u0027 : \u0027\u0027) + \u0027\u003e\u003c/div\u003e\u0027);\r\n\r\n var content = document.createElement(\u0027div\u0027);\r\n content.className = \u0027shepherd-content\u0027;\r\n this.el.appendChild(content);\r\n\r\n var header = document.createElement(\u0027header\u0027);\r\n content.appendChild(header);\r\n\r\n if (typeof this.options.title !== \u0027undefined\u0027) {\r\n header.innerHTML += \u0027\u003ch3 class=\\\u0027shepherd-title\\\u0027\u003e\u0027 + this.options.title + \u0027\u003c/h3\u003e\u0027;\r\n this.el.className += \u0027 shepherd-has-title\u0027;\r\n }\r\n\r\n if (this.options.showCancelLink) {\r\n var link = createFromHTML(\u0027\u003ca href class=\\\u0027shepherd-cancel-link\\\u0027\u003e✕\u003c/a\u003e\u0027);\r\n header.appendChild(link);\r\n\r\n this.el.className += \u0027 shepherd-has-cancel-link\u0027;\r\n\r\n this.bindCancelLink(link);\r\n }\r\n\r\n if (typeof this.options.text !== \u0027undefined\u0027) {\r\n (function () {\r\n var text = createFromHTML(\u0027\u003cdiv class=\\\u0027shepherd-text\\\u0027\u003e\u003c/div\u003e\u0027);\r\n var paragraphs = _this5.options.text;\r\n\r\n if (typeof paragraphs === \u0027function\u0027) {\r\n paragraphs = paragraphs.call(_this5, text);\r\n }\r\n\r\n if (paragraphs instanceof HTMLElement) {\r\n text.appendChild(paragraphs);\r\n } else {\r\n if (typeof paragraphs === \u0027string\u0027) {\r\n paragraphs = [paragraphs];\r\n }\r\n\r\n paragraphs.map(function (paragraph) {\r\n text.innerHTML += \u0027\u003cp\u003e\u0027 + paragraph + \u0027\u003c/p\u003e\u0027;\r\n });\r\n }\r\n\r\n content.appendChild(text);\r\n })();\r\n }\r\n\r\n var footer = document.createElement(\u0027footer\u0027);\r\n\r\n if (this.options.buttons) {\r\n (function () {\r\n var buttons = createFromHTML(\u0027\u003cul class=\\\u0027shepherd-buttons\\\u0027\u003e\u003c/ul\u003e\u0027);\r\n\r\n _this5.options.buttons.map(function (cfg) {\r\n var button = createFromHTML(\u0027\u003cli\u003e\u003ca class=\\\u0027shepherd-button \u0027 + (cfg.classes || \u0027\u0027) + \u0027\\\u0027\u003e\u0027 + cfg.text + \u0027\u003c/a\u003e\u0027);\r\n buttons.appendChild(button);\r\n _this5.bindButtonEvents(cfg, button.querySelector(\u0027a\u0027));\r\n });\r\n\r\n footer.appendChild(buttons);\r\n })();\r\n }\r\n\r\n content.appendChild(footer);\r\n\r\n document.body.appendChild(this.el);\r\n\r\n this.setupTether();\r\n\r\n if (this.options.advanceOn) {\r\n this.bindAdvance();\r\n }\r\n }\r\n }, {\r\n key: \u0027bindCancelLink\u0027,\r\n value: function bindCancelLink(link) {\r\n var _this6 = this;\r\n\r\n link.addEventListener(\u0027click\u0027, function (e) {\r\n e.preventDefault();\r\n _this6.cancel();\r\n });\r\n }\r\n }, {\r\n key: \u0027bindButtonEvents\u0027,\r\n value: function bindButtonEvents(cfg, el) {\r\n var _this7 = this;\r\n\r\n cfg.events = cfg.events || {};\r\n if (typeof cfg.action !== \u0027undefined\u0027) {\r\n // Including both a click event and an action is not supported\r\n cfg.events.click = cfg.action;\r\n }\r\n\r\n for (var _event2 in cfg.events) {\r\n if (({}).hasOwnProperty.call(cfg.events, _event2)) {\r\n var handler = cfg.events[_event2];\r\n if (typeof handler === \u0027string\u0027) {\r\n (function () {\r\n var page = handler;\r\n handler = function () {\r\n return _this7.tour.show(page);\r\n };\r\n })();\r\n }\r\n el.addEventListener(_event2, handler);\r\n }\r\n }\r\n\r\n this.on(\u0027destroy\u0027, function () {\r\n for (var _event3 in cfg.events) {\r\n if (({}).hasOwnProperty.call(cfg.events, _event3)) {\r\n var handler = cfg.events[_event3];\r\n el.removeEventListener(_event3, handler);\r\n }\r\n }\r\n });\r\n }\r\n }]);\r\n\r\n return Step;\r\n})(Evented);\r\n\r\nvar Tour = (function (_Evented2) {\r\n function Tour() {\r\n var _this8 = this;\r\n\r\n var options = arguments[0] === undefined ? {} : arguments[0];\r\n\r\n _classCallCheck(this, Tour);\r\n\r\n _get(Object.getPrototypeOf(Tour.prototype), \u0027constructor\u0027, this).call(this, options);\r\n this.bindMethods();\r\n this.options = options;\r\n this.steps = this.options.steps || [];\r\n\r\n // Pass these events onto the global Shepherd object\r\n var events = [\u0027complete\u0027, \u0027cancel\u0027, \u0027hide\u0027, \u0027start\u0027, \u0027show\u0027, \u0027active\u0027, \u0027inactive\u0027];\r\n events.map(function (event) {\r\n (function (e) {\r\n _this8.on(e, function (opts) {\r\n opts = opts || {};\r\n opts.tour = _this8;\r\n Shepherd.trigger(e, opts);\r\n });\r\n })(event);\r\n });\r\n\r\n return this;\r\n }\r\n\r\n _inherits(Tour, _Evented2);\r\n\r\n _createClass(Tour, [{\r\n key: \u0027bindMethods\u0027,\r\n value: function bindMethods() {\r\n var _this9 = this;\r\n\r\n var methods = [\u0027next\u0027, \u0027back\u0027, \u0027cancel\u0027, \u0027complete\u0027, \u0027hide\u0027];\r\n methods.map(function (method) {\r\n _this9[method] = _this9[method].bind(_this9);\r\n });\r\n }\r\n }, {\r\n key: \u0027addStep\u0027,\r\n value: function addStep(name, step) {\r\n if (typeof step === \u0027undefined\u0027) {\r\n step = name;\r\n }\r\n\r\n if (!(step instanceof Step)) {\r\n if (typeof name === \u0027string\u0027 || typeof name === \u0027number\u0027) {\r\n step.id = name.toString();\r\n }\r\n step = extend({}, this.options.defaults, step);\r\n step = new Step(this, step);\r\n } else {\r\n step.tour = this;\r\n }\r\n\r\n this.steps.push(step);\r\n return this;\r\n }\r\n }, {\r\n key: \u0027getById\u0027,\r\n value: function getById(id) {\r\n for (var i = 0; i \u003c this.steps.length; ++i) {\r\n var step = this.steps[i];\r\n if (step.id === id) {\r\n return step;\r\n }\r\n }\r\n }\r\n }, {\r\n key: \u0027getCurrentStep\u0027,\r\n value: function getCurrentStep() {\r\n return this.currentStep;\r\n }\r\n }, {\r\n key: \u0027next\u0027,\r\n value: function next() {\r\n var index = this.steps.indexOf(this.currentStep);\r\n\r\n if (index === this.steps.length - 1) {\r\n this.hide(index);\r\n this.trigger(\u0027complete\u0027);\r\n this.done();\r\n } else {\r\n this.show(index + 1);\r\n }\r\n }\r\n }, {\r\n key: \u0027back\u0027,\r\n value: function back() {\r\n var index = this.steps.indexOf(this.currentStep);\r\n this.show(index - 1);\r\n }\r\n }, {\r\n key: \u0027cancel\u0027,\r\n value: function cancel() {\r\n if (typeof this.currentStep !== \u0027undefined\u0027) {\r\n this.currentStep.hide();\r\n }\r\n this.trigger(\u0027cancel\u0027);\r\n this.done();\r\n }\r\n }, {\r\n key: \u0027complete\u0027,\r\n value: function complete() {\r\n if (typeof this.currentStep !== \u0027undefined\u0027) {\r\n this.currentStep.hide();\r\n }\r\n this.trigger(\u0027complete\u0027);\r\n this.done();\r\n }\r\n }, {\r\n key: \u0027hide\u0027,\r\n value: function hide() {\r\n if (typeof this.currentStep !== \u0027undefined\u0027) {\r\n this.currentStep.hide();\r\n }\r\n this.trigger(\u0027hide\u0027);\r\n this.done();\r\n }\r\n }, {\r\n key: \u0027done\u0027,\r\n value: function done() {\r\n Shepherd.activeTour = null;\r\n removeClass(document.body, \u0027shepherd-active\u0027);\r\n this.trigger(\u0027inactive\u0027, { tour: this });\r\n }\r\n }, {\r\n key: \u0027show\u0027,\r\n value: function show() {\r\n var key = arguments[0] === undefined ? 0 : arguments[0];\r\n\r\n if (this.currentStep) {\r\n this.currentStep.hide();\r\n } else {\r\n addClass(document.body, \u0027shepherd-active\u0027);\r\n this.trigger(\u0027active\u0027, { tour: this });\r\n }\r\n\r\n Shepherd.activeTour = this;\r\n\r\n var next = undefined;\r\n if (typeof key === \u0027string\u0027) {\r\n next = this.getById(key);\r\n } else {\r\n next = this.steps[key];\r\n }\r\n\r\n if (next) {\r\n this.trigger(\u0027show\u0027, {\r\n step: next,\r\n previous: this.currentStep\r\n });\r\n\r\n this.currentStep = next;\r\n next.show();\r\n }\r\n }\r\n }, {\r\n key: \u0027start\u0027,\r\n value: function start() {\r\n this.trigger(\u0027start\u0027);\r\n\r\n this.currentStep = null;\r\n this.next();\r\n }\r\n }]);\r\n\r\n return Tour;\r\n})(Evented);\r\n\r\nextend(Shepherd, { Tour: Tour, Step: Step, Evented: Evented });\r\nreturn Shepherd;\r\n\r\n}));\r\n\r\nH5P.Shepherd = Shepherd;\r\nwindow.Shepherd = oldShepherd\r\n"
,"scripts/h5p-guided-tour.js":"var H5P = H5P || {};\n\n/**\n * H5P Guided tour library.\n *\n * This is a utility library, which does not implement attach. I.e, it has to bee actively used by\n * other libraries\n *\n * @module\n */\nH5P.GuidedTour = (function ($) {\n\n /**\n * @type {Object}\n * @enum\n */\n var STEP_TYPES = {\n FIRST: 0,\n IN_BETWEEN: 1,\n LAST: 2,\n SINGLE: 3\n };\n\n /**\n * A class representing a step\n *\n * @class Step\n * @private\n * @param {Object} options\n * @param {number} stepType\n * @param {H5P.Sheperd.Tour} tour\n * @param {Object} highlight Object containing css-properties that will be\n * @param {Object} labels Labels for buttons\n * applied to current guided element (used if highlightElement === true)\n */\n function Step(options, stepType, tour, highlight, labels) {\n var self = this;\n options.classes = options.classes || \u0027\u0027;\n options.classes += \u0027 h5p shepherd-theme-arrows\u0027;\n\n // ************\n // First button\n // ************\n options.buttons = [];\n if (stepType === STEP_TYPES.FIRST) {\n // First step - exit button\n options.buttons.push({\n text: labels.exit,\n classes: \u0027shepherd-button-secondary\u0027,\n action: tour.cancel\n });\n\n options.classes += \u0027 first\u0027;\n }\n else if (stepType !== STEP_TYPES.SINGLE){\n // All others - back button\n options.buttons.push({\n text: labels.back,\n classes: \u0027shepherd-button-secondary\u0027,\n action: tour.back\n });\n }\n\n // *************\n // Second button\n // *************\n if (stepType === STEP_TYPES.LAST || stepType === STEP_TYPES.SINGLE) {\n // Last step - finish button\n options.buttons.push({\n text: labels.done,\n action: tour.complete,\n classes: \u0027shepherd-button-primary\u0027\n });\n\n options.classes += \u0027 last\u0027;\n }\n else {\n // All others - next button\n options.buttons.push({\n text: labels.next,\n action: tour.next,\n classes: \u0027shepherd-button-primary\u0027\n });\n }\n\n var $element;\n options.when = {\n show: function () {\n if (options.highlightElement) {\n $element = $element || $(options.attachTo.element);\n $element.css(highlight);\n }\n // Stop propagating click events, so that body don\u0027t get them\n var el = this.el;\n setTimeout(function() {\n $(el).on(\u0027click.guided-tour\u0027, function () {\n return false;\n });\n }, 0);\n },\n hide: function () {\n if (options.highlightElement) {\n $element = $element || $(options.attachTo.element);\n for(var property in highlight) {\n $element.css(property, \u0027\u0027);\n }\n }\n var el = this.el;\n setTimeout(function () {\n $(el).off(\u0027click.guided-tour\u0027);\n }, 0);\n }\n };\n\n if (options.noArrow) {\n options.classes += \u0027 h5p-guided-tour-step-no-arrow\u0027;\n }\n\n /**\n * Return options needed by Shepherd\n * @method getOptions\n * @return {Object}\n */\n self.getOptions = function () {\n return options;\n };\n }\n\n // Factory for creating storage instance\n var storage = (function () {\n var instance = {\n get: function (key, next) {\n var value;\n\n // Get value from browser storage\n if (window.localStorage !== undefined) {\n value = !!window.localStorage.getItem(key);\n }\n\n // Try to get a better value from user data storage\n try {\n H5P.getUserData(0, key, function (err, result) {\n if (!err) {\n value = result;\n }\n next(value);\n });\n }\n catch (err) {\n next(value);\n }\n },\n set: function (key, value) {\n\n // Store in browser\n if (window.localStorage !== undefined) {\n window.localStorage.setItem(key, value);\n }\n\n // Try to store in user data storage\n try {\n H5P.setUserData(0, key, value);\n }\n catch (err) { /* Suppress error messages */ }\n },\n };\n return instance;\n })();\n\n /**\n * Main class\n * @class H5P.GuidedTour\n * @param {Array} steps Array of step objects\n * @param {Object} options Options\n */\n function GuidedTour(steps, options) {\n var self = this;\n\n options = $.extend({}, {\n highlight: {\n background: \u0027#3288e6\u0027,\n color: \u0027#fff\u0027\n },\n labels: {\n exit: \u0027Exit\u0027,\n done: \u0027Done\u0027,\n back: \u0027Back\u0027,\n next: \u0027Next\u0027\n }\n }, options);\n\n var tour = new H5P.Shepherd.Tour({\n defaults: {\n showCancelLink: true\n }\n });\n\n for (var i = 0, numSteps = steps.length; i \u003c steps.length; i++ ) {\n var type = numSteps === 1 ? STEP_TYPES.SINGLE : (i === 0 ? STEP_TYPES.FIRST : (i+1 === numSteps ? STEP_TYPES.LAST : STEP_TYPES.IN_BETWEEN));\n tour.addStep((new Step(steps[i], type, tour, options.highlight, options.labels)).getOptions());\n }\n\n /**\n * Start the guided tour\n * @method start\n * @memberof H5P.GuidedTour\n * @return {boolean} Shown or not\n */\n self.start = function (force, started) {\n\n // Check if first element in tour exists:\n if(steps.length !== 0 \u0026\u0026 steps[0].attachTo \u0026\u0026 $(steps[0].attachTo.element).length === 0) {\n return;\n }\n\n var start = function () {\n // Remember the user has seen this guide\n self.setTourSeen();\n\n $(\u0027body\u0027).off(\u0027click.guided-tour\u0027);\n\n try {\n tour.start();\n }\n catch (err) { /* Suppress error messages / Missing tour elements */ }\n\n // Listen for click-events on body, so we can hide the guide:\n $(\u0027body\u0027).on(\u0027click.guided-tour\u0027, function () {\n tour.hide();\n });\n\n tour.on(\u0027complete\u0027, function () {\n $(\u0027body\u0027).off(\u0027click.guided-tour\u0027);\n });\n\n started();\n };\n\n if (force) {\n start();\n }\n else {\n self.ifTourHasNotBeenSeen(start);\n }\n };\n\n /**\n * Hides guide\n * @method hide\n * @memberof H5P.GuidedTour\n */\n self.hide = function () {\n tour.hide();\n };\n\n /**\n * Destroys tour, i.e removes DOM elements and event listeners\n */\n self.destroy = function () {\n self.hide();\n $(\u0027body\u0027).off(\u0027click.guided-tour\u0027);\n for (var i = 0; i \u003c tour.steps.length; i++) {\n var step = tour.steps[i];\n step \u0026\u0026 step.destroy();\n }\n };\n\n /**\n * Tells if tour is open or not\n * @method isOpen\n * @return {Boolean}\n * @memberof H5P.GuidedTour\n */\n self.isOpen = function () {\n var currentStep = tour.getCurrentStep();\n return currentStep !== undefined \u0026\u0026 currentStep.isOpen();\n };\n\n /**\n * Mark this tour as seen. This is persisted using localstorage. If not present, nothing is persisted.\n *\n * @method setTourSeen\n * @memberof H5P.GuidedTour\n */\n self.setTourSeen = function () {\n storage.set(options.id + \u0027-seen\u0027, true);\n };\n\n /**\n * Check if this tour has been seen by user. Reads value from localstorage\n *\n * @method hasTourBeenSeen\n * @memberof H5P.GuidedTour\n * @return {Boolean}\n */\n self.ifTourHasNotBeenSeen = function (action) {\n storage.get(options.id + \u0027-seen\u0027, function (value) {\n if (value !== true) {\n action();\n }\n });\n };\n }\n\n return GuidedTour;\n})(H5P.jQuery);\n"
,"scripts/go-to-question.js":"H5P.GoToQuestion = (function ($, EventDispatcher, UI) {\n var KEY_CODE_ENTER = 13;\n var KEY_CODE_SPACE = 32;\n var KEY_CODE_LEFT = 37;\n var KEY_CODE_UP = 38;\n var KEY_CODE_RIGHT = 39;\n var KEY_CODE_DOWN = 40;\n\n /**\n * Create a new Go To Question!\n *\n * @class H5P.GoToQuestion\n * @extends H5P.EventDispatcher\n * @param {Object} parameters\n */\n function GoToQuestion(parameters) {\n var self = this;\n\n // Initialize event inheritance\n EventDispatcher.call(self);\n\n // Clone parameters so that the parameters doesn\u0027t get the default values\n parameters = $.extend(true, {}, parameters);\n\n // Content defaults\n setDefaults(parameters, {\n text: \u0027Choose your side\u0027,\n choices: [\n {\n text: \"Dark side\",\n goTo: 1\n },\n {\n text: \"Light side\",\n goTo: 0\n }\n ],\n continueButtonLabel: \u0027Continue\u0027\n });\n\n // Private class variables\n var $wrapper;\n var $text;\n var $choices;\n var $chosenText;\n var $continueMsg;\n var $continueButton;\n\n /**\n * Creates the basic HTML elements that are needed to begin with.\n *\n * @private\n */\n var createHtml = function () {\n // Create question wrapper\n $wrapper = $(\u0027\u003cdiv/\u003e\u0027, {\n \u0027class\u0027: GoToQuestion.htmlClass + \u0027-wrapper\u0027\n });\n\n // Create and append question text\n var labelId = getNextId();\n $text = $(\u0027\u003cdiv/\u003e\u0027, {\n \u0027class\u0027: GoToQuestion.htmlClass + \u0027-text\u0027,\n id: labelId,\n html: parameters.text,\n appendTo: $wrapper\n });\n\n // Create and append choices wrapper\n $choices = $(\u0027\u003cul/\u003e\u0027, {\n \u0027class\u0027: GoToQuestion.htmlClass + \u0027-choices\u0027,\n role: \u0027group\u0027,\n \u0027aria-labelledby\u0027: labelId,\n appendTo: $wrapper\n });\n\n // Append choices to wrapper\n for (var i = 0; i \u003c parameters.choices.length; i++) {\n createChoice(parameters.choices[i], i === 0);\n }\n\n // Add chosen option text\n $chosenText = $(\u0027\u003cdiv/\u003e\u0027, {\n \u0027class\u0027: GoToQuestion.htmlClass + \u0027-chosentext\u0027\n });\n\n // Create continune message\n $continueMsg = $(\u0027\u003cdiv/\u003e\u0027, {\n \u0027class\u0027: GoToQuestion.htmlClass + \u0027-continuemsg\u0027,\n \u0027aria-live\u0027: \u0027polite\u0027,\n appendTo: $wrapper\n });\n\n // Create continue button\n $continueButton = UI.createButton({\n \u0027class\u0027: GoToQuestion.htmlClass + \u0027-continue\u0027,\n html: parameters.continueButtonLabel,\n title: parameters.continueButtonLabel\n });\n };\n\n /**\n * Create HTML for choice.\n *\n * @private\n * @param {object} choiceParams\n * @param {string} choiceParams.text\n * @param {int} choiceParams.goTo\n * @param {string} choiceParams.ifChosenText\n * @param {number} isFirst\n */\n var createChoice = function (choiceParams, isFirst) {\n // Wrapper and list element\n var $li = $(\u0027\u003cli/\u003e\u0027, {\n \u0027class\u0027: GoToQuestion.htmlClass + \u0027-choice\u0027,\n appendTo: $choices\n });\n\n // The button for choosing\n var $button = $(\u0027\u003cdiv/\u003e\u0027, {\n \u0027class\u0027: GoToQuestion.htmlClass + \u0027-button\u0027,\n role: \u0027button\u0027,\n \u0027aria-disabled\u0027: false,\n html: choiceParams.text,\n on: {\n click: function () {\n choose.call(this, choiceParams);\n },\n keypress: function (event) {\n if (event.which === KEY_CODE_ENTER || event.which === KEY_CODE_SPACE) {\n // Space bar pressed\n choose.call(this, choiceParams);\n event.preventDefault();\n }\n },\n keydown: function (event) {\n var direction;\n switch (event.which) {\n case KEY_CODE_LEFT:\n case KEY_CODE_UP:\n // Prev\n direction = \u0027previousElementSibling\u0027;\n break;\n\n case KEY_CODE_RIGHT:\n case KEY_CODE_DOWN:\n // Next\n direction = \u0027nextElementSibling\u0027;\n break;\n }\n\n if (direction \u0026\u0026 this.parentElement[direction]) {\n // Move focus to prev/next button\n var button = this.parentElement[direction].firstElementChild;\n button.setAttribute(\u0027tabindex\u0027, \u00270\u0027);\n button.focus();\n this.removeAttribute(\u0027tabindex\u0027);\n event.preventDefault();\n }\n }\n },\n appendTo: $li\n });\n if (isFirst) {\n $button.attr(\u0027tabindex\u0027, \u00270\u0027);\n }\n };\n\n /**\n * Choice chosen.\n *\n * @private\n * @param {object} choiceParams\n * @param {string} choiceParams.text\n * @param {int} choiceParams.goTo\n * @param {string} choiceParams.ifChosenText\n */\n var choose = function (choiceParams) {\n var $button = $(this);\n if ($button.attr(\u0027aria-disabled\u0027) === \u0027true\u0027) {\n return; // Prevent choosing another option while animation is running\n }\n\n // Disable all buttons\n var $buttons = $choices.find(\u0027.\u0027 + GoToQuestion.htmlClass + \u0027-button\u0027)\n .attr(\u0027aria-disabled\u0027, true);\n\n // Use parent LI as placeholder\n var $li = $button.parent();\n $li.css(\u0027height\u0027, $li[0].getBoundingClientRect().height);\n\n // Mark button as chosen and animate\n var buttonStyle = window.getComputedStyle($button[0]);\n var borderWidth = parseFloat(buttonStyle.borderTopWidth);\n $button.addClass(GoToQuestion.htmlClass + \u0027-chosen\u0027).css(\u0027top\u0027, $button[0].offsetTop + borderWidth);\n\n /**\n * Resets the choices UI\n * @private\n */\n var resetChoices = function () {\n $li.css(\u0027height\u0027, \u0027\u0027);\n $button.removeClass(GoToQuestion.htmlClass + \u0027-chosen\u0027).css(\u0027top\u0027, \u0027\u0027);\n $buttons.attr(\u0027aria-disabled\u0027, false);\n };\n\n // Animate the choice if we\u0027re going to have continue screen\n if (choiceParams.ifChosenText) {\n setTimeout(function () {\n // Start animation\n buttonStyle = window.getComputedStyle($button[0]);\n $button.css(\u0027top\u0027, $text[0].getBoundingClientRect().height - parseFloat(buttonStyle.paddingTop));\n }, 0);\n\n // Give some time for the animation to play before we continue\n setTimeout(function () {\n // Show message and continue button before proceeding\n continueScreen(choiceParams.text, choiceParams.ifChosenText, choiceParams.goTo);\n setTimeout(resetChoices, 0);\n }, 250);\n }\n else {\n // No animation, but let the choices stay for a while\n setTimeout(function () {\n // Done\n self.trigger(\u0027chosen\u0027, choiceParams.goTo);\n setTimeout(resetChoices, 0);\n }, 500);\n }\n };\n\n /**\n * Displays the continue message and button.\n *\n * @private\n * @param {string} chosenText Text from the chosen option\n * @param {string} continueMsg Message to display before continue\n * @param {number} goTo Where to continue\n */\n var continueScreen = function (chosenText, continueMsg, goTo) {\n\n // Remove choices\n $choices.detach();\n\n // Update elements\n $chosenText.html(chosenText).insertBefore($continueMsg);\n $continueMsg.html(continueMsg);\n $continueButton.appendTo($wrapper).on(\u0027click\u0027, createContinueHandler(goTo)).focus();\n\n // Makes it easy to re-style the task in this state\n $wrapper.addClass(GoToQuestion.htmlClass + \u0027-continuestate\u0027);\n };\n\n /**\n * Factory function for generating continue button handlers\n *\n * @private\n * @param {number} goTo\n */\n var createContinueHandler = function (goTo) {\n return function () {\n self.trigger(\u0027chosen\u0027, goTo);\n // Use timeout to avoid flickering\n setTimeout(function () {\n $continueButton.off(\u0027click\u0027).add($chosenText).detach();\n $continueMsg.html(\u0027\u0027);\n\n $choices.insertBefore($continueMsg);\n $wrapper.removeClass(GoToQuestion.htmlClass + \u0027-continuestate\u0027);\n }, 1);\n };\n };\n\n /**\n * Attach the question to the given container.\n *\n * @param {H5P.jQuery} $container\n */\n self.attach = function ($container) {\n if ($wrapper === undefined) {\n // Only create the HTML on the first attach\n createHtml();\n }\n\n // Add to DOM\n $container.addClass(GoToQuestion.htmlClass).html(\u0027\u0027).append($wrapper);\n };\n }\n\n // Extends the event dispatcher\n GoToQuestion.prototype = Object.create(EventDispatcher.prototype);\n GoToQuestion.prototype.constructor = GoToQuestion;\n\n // Set static html class base\n GoToQuestion.htmlClass = \u0027h5p-gotoquestion\u0027;\n\n // Counter for creating unique IDs\n var id = 0;\n\n /**\n * Generate unique page IDs\n */\n var getNextId = function () {\n return GoToQuestion.htmlClass + \u0027-\u0027 + (id++);\n };\n\n /**\n * Simple recusive function the helps set default values without\n * destroying object references.\n *\n * @param {object} params values\n * @param {object} values default values\n */\n var setDefaults = function (params, values) {\n for (var prop in values) {\n if (values.hasOwnProperty(prop)) {\n if (params[prop] === undefined) {\n // Not set, use default\n params[prop] = values[prop];\n }\n else if (params[prop] instanceof Object) {\n if (params[prop] instanceof Array) {\n // Check if array has valid objects\n if (!arrayHasObjects(params[prop], Object.keys(values[prop][0]))) {\n // Empty array, use default options\n params[prop] = values[prop];\n }\n }\n else {\n // Handle object\n setDefaults(params[prop], values[prop]);\n }\n }\n }\n }\n };\n\n /**\n * Check to see if the array has objects with the required properties.\n * Will strip away empty objects inserted by the editor.\n *\n * @param Array arr\n * @param Array objProps\n * @returns boolean\n */\n var arrayHasObjects = function (arr, objProps) {\n // Reverse traverse to make removal of objects easier\n var i = arr.length;\n while (i--) {\n if (arr[i] instanceof Object \u0026\u0026 !objectHasProps(arr[i], objProps)) {\n // Missing required object properties, remove from array\n arr.splice(i, 1);\n }\n }\n return !!arr.length;\n };\n\n /**\n * Checks to see if object has all the specified props.\n *\n * @param Object obj\n * @param Array props\n * @returns boolean\n */\n var objectHasProps = function (obj, props) {\n for (var i = 0; i \u003c props.length; i++) {\n if (obj[props[i]] === undefined) {\n return false;\n }\n }\n\n // Object had all props\n return true;\n };\n\n return GoToQuestion;\n})(H5P.jQuery, H5P.EventDispatcher, H5P.JoubelUI);\n"
,"scripts/iv-hotspot.js":"H5P.IVHotspot = (function ($, EventDispatcher) {\n\n /**\n * Create a new IV Hotspot!\n *\n * @class H5P.IVHotspot\n * @extends H5P.EventDispatcher\n * @param {Object} parameters\n */\n function IVHotspot(parameters) {\n var self = this;\n self.instanceIndex = getAndIncrementGlobalCounter();\n\n if (typeof parameters.texts === \u0027string\u0027) {\n parameters.texts = {};\n }\n\n parameters = $.extend(true, {\n destination: {\n type: \u0027timecode\u0027,\n time: \u00270\u0027\n },\n visuals: {\n shape: \u0027rectangular\u0027,\n backgroundColor: \u0027rgba(255, 255, 255, 0)\u0027\n },\n texts: {}\n }, parameters);\n\n EventDispatcher.call(self);\n\n /**\n * Attach the hotspot to the given container.\n *\n * @param {H5P.jQuery} $container\n */\n self.attach = function ($container) {\n $container.addClass(\u0027h5p-ivhotspot\u0027).css({\n backgroundColor: parameters.visuals.backgroundColor\n }).addClass(parameters.visuals.shape);\n\n var $a;\n if (parameters.destination.type === \u0027url\u0027) {\n var link = new H5P.Link({\n title: \u0027\u0027,\n linkWidget: parameters.destination.url\n });\n\n link.attach($container);\n $a = $container.find(\u0027a\u0027);\n $a.keypress(function (event) {\n if (event.which === 32) {\n this.click();\n }\n });\n }\n else {\n $a = $(\u0027\u003ca\u003e\u0027, {\n href: \u0027#\u0027,\n \u0027aria-labelledby\u0027: \u0027ivhotspot-\u0027 + self.instanceIndex + \u0027-description\u0027\n }).on(\u0027click\u0027, function (event) {\n self.trigger(\u0027goto\u0027, parameters.destination.time);\n event.preventDefault();\n }).keypress(function (event) {\n if (event.which === 32) {\n self.trigger(\u0027goto\u0027, parameters.destination.time);\n }\n });\n $container.html($a);\n }\n\n $a.css({cursor: parameters.visuals.pointerCursor ? \u0027pointer\u0027 : \u0027default\u0027});\n\n if (parameters.visuals.animation) {\n $container.append($(\u0027\u003cdiv\u003e\u0027, {\n \u0027class\u0027: \u0027blinking-hotspot\u0027\n }));\n }\n var alternativeTextContent = [parameters.texts.alternativeText, parameters.texts.label]\n .filter(function (text) {\n return text !== undefined;\n }).join(\u0027. \u0027);\n\n $(\u0027\u003cp\u003e\u0027, {\n id: \u0027ivhotspot-\u0027 + self.instanceIndex + \u0027-description\u0027,\n class: \u0027h5p-ivhotspot-invisible\u0027,\n text: alternativeTextContent\n }).appendTo($container);\n\n if (parameters.texts.label !== undefined) {\n var $label = $(\u0027\u003cp\u003e\u0027, {\n class: \u0027h5p-ivhotspot-interaction-title\u0027,\n text: parameters.texts.label\n }).appendTo($a);\n\n if (!parameters.texts.showLabel) {\n $label.addClass(\u0027h5p-ivhotspot-invisible\u0027);\n }\n\n else if (parameters.texts.labelColor) {\n $a.css(\u0027color\u0027, parameters.texts.labelColor);\n }\n }\n };\n }\n\n /**\n * Use a global counter to separate instances of iv-hotspots,\n * to maintain unique ids.\n *\n * Note that ids does not have to be unique across iframes.\n *\n * @return {number}\n */\n function getAndIncrementGlobalCounter() {\n if (window.interactiveVideoCounter === undefined) {\n window.interactiveVideoCounter = 0;\n }\n\n return window.interactiveVideoCounter++;\n }\n\n IVHotspot.prototype = Object.create(EventDispatcher.prototype);\n IVHotspot.prototype.constructor = IVHotspot;\n\n\n return IVHotspot;\n\n})(H5P.jQuery, H5P.EventDispatcher);\n"
,"dist/dist.js":"!function(e){function t(r){if(n[r])return n[r].exports;var o=n[r]={exports:{},id:r,loaded:!1};return e[r].call(o.exports,o,o.exports,t),o.loaded=!0,o.exports}var n={};return t.m=e,t.c=n,t.p=\"\",t(0)}([function(e,t,n){\"use strict\";H5P.OpenEndedQuestion=n(1).default},function(e,t,n){\"use strict\";function r(e){return e\u0026\u0026e.__esModule?e:{default:e}}function o(e,t){if(!(e instanceof t))throw new TypeError(\"Cannot call a class as a function\")}function i(e,t){if(!e)throw new ReferenceError(\"this hasn\u0027t been initialised - super() hasn\u0027t been called\");return!t||\"object\"!=typeof t\u0026\u0026\"function\"!=typeof t?e:t}function a(e,t){if(\"function\"!=typeof t\u0026\u0026null!==t)throw new TypeError(\"Super expression must either be null or a function, not \"+typeof t);e.prototype=Object.create(t\u0026\u0026t.prototype,{constructor:{value:e,enumerable:!1,writable:!0,configurable:!0}}),t\u0026\u0026(Object.setPrototypeOf?Object.setPrototypeOf(e,t):e.__proto__=t)}Object.defineProperty(t,\"__esModule\",{value:!0}),n(3);var u=n(2),c=r(u),s=function(e){function t(e){var n=(arguments.length\u003e1\u0026\u0026void 0!==arguments[1]?arguments[1]:null,arguments.length\u003e2\u0026\u0026void 0!==arguments[2]?arguments[2]:{});o(this,t);var r=i(this,(t.__proto__||Object.getPrototypeOf(t)).call(this)),a=e.question,u=void 0===a?\"Do you like cake?\":a,s=e.placeholderText,p=void 0===s?\"\":s,l=e.inputRows,d=void 0===l?1:l;return r.currentInput=\"\",r.xApiGenerator=new c.default(u),r.createQuestion=function(e){var t=document.createElement(\"div\");return t.className=\"h5p-open-ended-question-text\",t.innerHTML=e,t},r.createInput=function(e,t){var n=document.createElement(\"textarea\");return n.placeholder=t||\"\",n.textContent=this.currentInput,n.rows=e,n.style.resize=\"none\",n},r.attach=function(e){var t=this,n=document.createElement(\"div\");n.classList.add(\"h5p-open-ended-question\");var r=document.createElement(\"div\");r.classList.add(\"h5p-open-ended-question-question\"),r.classList.add(\"h5p-subcontent-question\");var o=this.createQuestion(u);r.appendChild(o);var i=document.createElement(\"div\");i.classList.add(\"h5p-open-ended-question-content\"),i.classList.add(\"h5p-subcontent-body\");var a=this.createInput(d,p);a.className=\"h5p-open-ended-question-input\",a.addEventListener(\"blur\",function(){var e=t.createXAPIEventTemplate(\"interacted\"),n=t.xApiGenerator.generateXApi(e,a.value);t.currentInput=a.value,t.trigger(n)}),i.appendChild(a),n.appendChild(r),n.appendChild(i),e.get(0).appendChild(n)},r.getCurrentState=function(){return this.currentInput},r.restorePreviousState=function(){n.previousState\u0026\u0026(this.currentInput=n.previousState)},r.restorePreviousState(),r}return a(t,e),t}(H5P.EventDispatcher);t.default=s},function(e,t){\"use strict\";function n(e,t){if(!(e instanceof t))throw new TypeError(\"Cannot call a class as a function\")}Object.defineProperty(t,\"__esModule\",{value:!0});var r=Object.assign||function(e){for(var t=1;t\u003carguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)\u0026\u0026(e[r]=n[r])}return e},o=function(){function e(e,t){for(var n=0;n\u003ct.length;n++){var r=t[n];r.enumerable=r.enumerable||!1,r.configurable=!0,\"value\"in r\u0026\u0026(r.writable=!0),Object.defineProperty(e,r.key,r)}}return function(t,n,r){return n\u0026\u0026e(t.prototype,n),r\u0026\u0026e(t,r),t}}(),i=function(){function e(t){n(this,e),this.event={description:{\"en-US\":t},type:\"http://adlnet.gov/expapi/activities/cmi.interaction\",interactionType:\"fill-in\"}}return o(e,[{key:\"generateXApi\",value:function(e,t){var n=e.data.statement;if(r(n,{result:{response:t}}),n.object){var o=n.object.definition;r(o,this.event)}return e}}]),e}();t.default=i},function(e,t){}]);"
,"dist/dist.js":"!function(e){function t(i){if(n[i])return n[i].exports;var a=n[i]={exports:{},id:i,loaded:!1};return e[i].call(a.exports,a,a.exports,t),a.loaded=!0,a.exports}var n={};return t.m=e,t.c=n,t.p=\"\",t(0)}([function(e,t,n){\"use strict\";H5P.SimpleMultiChoice=n(1).default},function(e,t,n){\"use strict\";function i(e){return e\u0026\u0026e.__esModule?e:{default:e}}function a(e,t){if(!(e instanceof t))throw new TypeError(\"Cannot call a class as a function\")}function r(e,t){if(!e)throw new ReferenceError(\"this hasn\u0027t been initialised - super() hasn\u0027t been called\");return!t||\"object\"!=typeof t\u0026\u0026\"function\"!=typeof t?e:t}function c(e,t){if(\"function\"!=typeof t\u0026\u0026null!==t)throw new TypeError(\"Super expression must either be null or a function, not \"+typeof t);e.prototype=Object.create(t\u0026\u0026t.prototype,{constructor:{value:e,enumerable:!1,writable:!0,configurable:!0}}),t\u0026\u0026(Object.setPrototypeOf?Object.setPrototypeOf(e,t):e.__proto__=t)}Object.defineProperty(t,\"__esModule\",{value:!0});var o=Object.assign||function(e){for(var t=1;t\u003carguments.length;t++){var n=arguments[t];for(var i in n)Object.prototype.hasOwnProperty.call(n,i)\u0026\u0026(e[i]=n[i])}return e},s=function(){function e(e,t){for(var n=0;n\u003ct.length;n++){var i=t[n];i.enumerable=i.enumerable||!1,i.configurable=!0,\"value\"in i\u0026\u0026(i.writable=!0),Object.defineProperty(e,i.key,i)}}return function(t,n,i){return n\u0026\u0026e(t.prototype,n),i\u0026\u0026e(t,i),t}}();n(3);var u=n(2),l=i(u),h=0,d=function(e){function t(e){var n=e.question,i=e.alternatives,c=void 0===i?[]:i,s=e.inputType,u=(arguments.length\u003e1\u0026\u0026void 0!==arguments[1]?arguments[1]:null,arguments.length\u003e2\u0026\u0026void 0!==arguments[2]?arguments[2]:{});a(this,t);var d=r(this,(t.__proto__||Object.getPrototypeOf(t)).call(this));return d.uniqueName=\"h5p-simple-multiple-choice-\"+h,h+=1,d.listItems=[],d.feedbackElements=[],d.state=c.map(function(e,t){return{id:t,text:e.text,checked:!1}}),d.hasFeedback=c.some(function(e){return e.feedback.chosenFeedback||e.feedback.notChosenFeedback}),d.feedbackShown=!1,d.xapiGenerator=new l.default({question:n,alternatives:c}),d.attach=function(e){var t=document.createElement(\"div\");t.className=\"h5p-simple-multiple-choice\";var n=document.createElement(\"div\");n.classList.add(\"h5p-simple-multiple-choice-question\"),n.classList.add(\"h5p-subcontent-question\");var i=this.createQuestion(this.uniqueName);n.appendChild(i),t.appendChild(n);var a=this.createAlternativesList(this.uniqueName);t.appendChild(a),e.get(0).appendChild(t)},d.createQuestion=function(e){var t=document.createElement(\"div\");return t.id=e,t.innerHTML=n,t},d.handleInputChange=function(e){this.feedbackShown\u0026\u0026(this.feedbackElements.forEach(function(e){e.parentNode.removeChild(e)}),this.feedbackElements=[],this.feedbackShown=!1,this.trigger(\"allow-finish-changed\")),this.state=this.state.map(function(t,n){var i=n===e;return\"radio\"!==s\u0026\u0026(i=n===e?!t.checked:t.checked),o({},t,{checked:i})});var t=this.createXAPIEventTemplate(\"interacted\"),n=this.xapiGenerator.generateXApi(t,this.state);this.trigger(n)},d.createAlternativesList=function(e){var t=this;if(!this.state.length){var n=document.createElement(\"div\");return n.className=\"h5p-simple-multiple-choice-alternatives-error\",n.textContent=\"ERROR: No alternatives chosen\",n}var i=document.createElement(\"ul\");return i.classList.add(\"h5p-simple-multiple-choice-alternatives\"),i.classList.add(\"h5p-subcontent-body\"),i.setAttribute(\"role\",\"listbox\"),i.setAttribute(\"aria-labelledby\",e),this.state.forEach(function(e){var n=e.id,a=e.text,r=e.checked,c=document.createElement(\"li\");c.className=\"h5p-simple-multiple-choice-alternative-li\";var o=document.createElement(\"label\"),u=document.createElement(\"input\");u.className=\"h5p-simple-multiple-choice-alternative-input\",u.type=s||\"checkbox\",u.name=t.uniqueName,r\u0026\u0026u.setAttribute(\"checked\",\"checked\"),o.addEventListener(\"change\",t.handleInputChange.bind(t,n)),o.appendChild(u),o.innerHTML+=a,c.appendChild(o),i.appendChild(c),t.listItems.push(c)}),i},d.getCurrentState=function(){return l.default.getResultPattern(this.state)},d.restorePreviousState=function(){var e=this;if(u.previousState){var t=u.previousState.split(\"[,]\");t.forEach(function(t){e.state[t].checked=!0})}},d.allowFinish=function(){return this.hasFeedback?this.hasFeedback\u0026\u0026this.feedbackShown?t.AllowFinish.ALLOW:t.AllowFinish.DENY:t.AllowFinish.ALWAYS},d.finish=function(){var e=this;return c.forEach(function(t,n){if(t.feedback){var i=void 0,a=e.state[n].checked;if(a\u0026\u0026t.feedback.chosenFeedback?i=t.feedback.chosenFeedback:!a\u0026\u0026t.feedback.notChosenFeedback\u0026\u0026(i=t.feedback.notChosenFeedback),i){var r=document.createElement(\"div\");r.className=\"h5p-simple-multiple-choice-alternative-feedback \"+(a?\"chosen\":\"not-chosen\"),r.innerHTML=i,e.feedbackElements.push(r),e.listItems[n].appendChild(r)}}}),this.feedbackShown=!0,0===this.feedbackElements.length},d.restorePreviousState(),d}return c(t,e),s(t,null,[{key:\"AllowFinish\",get:function(){return{ALWAYS:0,DENY:1,ALLOW:2}}}]),t}(H5P.EventDispatcher);t.default=d},function(e,t){\"use strict\";function n(e,t){if(!(e instanceof t))throw new TypeError(\"Cannot call a class as a function\")}Object.defineProperty(t,\"__esModule\",{value:!0});var i=Object.assign||function(e){for(var t=1;t\u003carguments.length;t++){var n=arguments[t];for(var i in n)Object.prototype.hasOwnProperty.call(n,i)\u0026\u0026(e[i]=n[i])}return e},a=function(){function e(e,t){for(var n=0;n\u003ct.length;n++){var i=t[n];i.enumerable=i.enumerable||!1,i.configurable=!0,\"value\"in i\u0026\u0026(i.writable=!0),Object.defineProperty(e,i.key,i)}}return function(t,n,i){return n\u0026\u0026e(t.prototype,n),i\u0026\u0026e(t,i),t}}(),r=function(){function e(t){var i=t.question,a=t.alternatives;n(this,e);var r=a.map(function(e,t){return{id:\"\"+t,description:{\"en-US\":e.text}}});this.event={description:{\"en-US\":i},type:\"http://adlnet.gov/expapi/activities/cmi.interaction\",interactionType:\"choice\",choices:r}}return a(e,[{key:\"generateXApi\",value:function(t,n){var a=e.getResultPattern(n),r=t.data.statement;if(i(r,{result:{response:a}}),r.object){var c=r.object.definition;i(c,this.event)}return t}}],[{key:\"getResultPattern\",value:function(e){return e.reduce(function(e,t,n){return t.checked\u0026\u0026(e+=(e.length?\"[,]\":\"\")+n),e},\"\")}}]),e}();t.default=r},function(e,t){}]);"
,"dist/dist.js":"!function(e){function t(r){if(n[r])return n[r].exports;var i=n[r]={exports:{},id:r,loaded:!1};return e[r].call(i.exports,i,i.exports,t),i.loaded=!0,i.exports}var n={};return t.m=e,t.c=n,t.p=\"\",t(0)}([function(e,t,n){\"use strict\";H5P.Questionnaire=n(6).default},function(e,t,n){\"use strict\";function r(e,t){if(!(e instanceof t))throw new TypeError(\"Cannot call a class as a function\")}Object.defineProperty(t,\"__esModule\",{value:!0});var i=function(){function e(e,t){for(var n=0;n\u003ct.length;n++){var r=t[n];r.enumerable=r.enumerable||!1,r.configurable=!0,\"value\"in r\u0026\u0026(r.writable=!0),Object.defineProperty(e,r.key,r)}}return function(t,n,r){return n\u0026\u0026e(t.prototype,n),r\u0026\u0026e(t,r),t}}();n(12);var s=function(){function e(){r(this,e)}return i(e,null,[{key:\"createButton\",value:function(t,n,r){var i=e.createElement(\"button\",{className:\"h5p-questionnaire-button \"+n,type:\"button\",textContent:t});return r\u0026\u0026i.addEventListener(\"click\",function(){r.trigger(n)}),i}},{key:\"createElement\",value:function(e,t){var n=document.createElement(e);return Object.keys(t).forEach(function(e){n[e]=t[e]}),n}},{key:\"createDiv\",value:function(t){return e.createElement(\"div\",t)}}]),e}();t.default=s},function(e,t,n){\"use strict\";function r(e){return e\u0026\u0026e.__esModule?e:{default:e}}function i(e,t){if(!(e instanceof t))throw new TypeError(\"Cannot call a class as a function\")}function s(e,t){if(!e)throw new ReferenceError(\"this hasn\u0027t been initialised - super() hasn\u0027t been called\");return!t||\"object\"!=typeof t\u0026\u0026\"function\"!=typeof t?e:t}function a(e,t){if(\"function\"!=typeof t\u0026\u0026null!==t)throw new TypeError(\"Super expression must either be null or a function, not \"+typeof t);e.prototype=Object.create(t\u0026\u0026t.prototype,{constructor:{value:e,enumerable:!1,writable:!0,configurable:!0}}),t\u0026\u0026(Object.setPrototypeOf?Object.setPrototypeOf(e,t):e.__proto__=t)}Object.defineProperty(t,\"__esModule\",{value:!0});var o=function(){function e(e,t){for(var n=0;n\u003ct.length;n++){var r=t[n];r.enumerable=r.enumerable||!1,r.configurable=!0,\"value\"in r\u0026\u0026(r.writable=!0),Object.defineProperty(e,r.key,r)}}return function(t,n,r){return n\u0026\u0026e(t.prototype,n),r\u0026\u0026e(t,r),t}}();n(14);var u=n(1),c=r(u),l=function(e){function t(e){i(this,t);var n=s(this,(t.__proto__||Object.getPrototypeOf(t)).call(this));return n.footerWrapper=document.createElement(\"div\"),n.footerWrapper.className=\"h5p-questionnaire-footer\",n.footerWrapper.appendChild(n.createButton(e.prevLabel,\"previous\")),n.footerWrapper.appendChild(n.createButton(e.nextLabel,\"next\")),n.footerWrapper.appendChild(n.createButton(e.continueLabel,\"next\",\"continue\")),n}return a(t,e),o(t,[{key:\"setForwardNavigationButton\",value:function(e){this.trigger(\"disable-next\"),this.trigger(\"disable-continue\"),this.trigger(\"enable-\"+e)}},{key:\"createButton\",value:function(e,t,n){var r=c.default.createButton(e,t,this);return this.on(\"enable-\"+(n||t),function(){r.classList.remove(\"disable\")}),this.on(\"disable-\"+(n||t),function(){r.classList.add(\"disable\")}),r}},{key:\"hide\",value:function(){var e=!(arguments.length\u003e0\u0026\u0026void 0!==arguments[0])||arguments[0];this.footerWrapper.classList[e?\"add\":\"remove\"](\"hide\")}},{key:\"attachTo\",value:function(e){e.appendChild(this.footerWrapper)}}]),t}(H5P.EventDispatcher);t.default=l},function(e,t,n){\"use strict\";function r(e,t){if(!(e instanceof t))throw new TypeError(\"Cannot call a class as a function\")}Object.defineProperty(t,\"__esModule\",{value:!0});var i=function(){function e(e,t){for(var n=0;n\u003ct.length;n++){var r=t[n];r.enumerable=r.enumerable||!1,r.configurable=!0,\"value\"in r\u0026\u0026(r.writable=!0),Object.defineProperty(e,r.key,r)}}return function(t,n,r){return n\u0026\u0026e(t.prototype,n),r\u0026\u0026e(t,r),t}}();n(10);var s=function(){function e(t,n){r(this,e),this.numberWidget=document.createElement(\"div\"),this.numberWidget.className=\"h5p-questionnaire-progress-bar-widget\",this.numberWidget.setAttribute(\"aria-hidden\",\"true\"),this.currentIndex=document.createElement(\"div\"),this.currentIndex.className=\"h5p-questionnaire-progress-bar-widget-current\",this.currentIndex.textContent=t;var i=document.createElement(\"div\");i.className=\"h5p-questionnaire-progress-bar-widget-separator\",i.textContent=\"/\";var s=document.createElement(\"div\");s.className=\"h5p-questionnaire-progress-bar-widget-max\",s.textContent=n,this.numberWidget.appendChild(this.currentIndex),this.numberWidget.appendChild(i),this.numberWidget.appendChild(s)}return i(e,[{key:\"setCurrentIndex\",value:function(e){this.currentIndex.textContent=e}},{key:\"attachTo\",value:function(e){e.appendChild(this.numberWidget)}}]),e}();t.default=s},function(e,t,n){\"use strict\";function r(e){return e\u0026\u0026e.__esModule?e:{default:e}}function i(e,t){if(!(e instanceof t))throw new TypeError(\"Cannot call a class as a function\")}Object.defineProperty(t,\"__esModule\",{value:!0});var s=function(){function e(e,t){for(var n=0;n\u003ct.length;n++){var r=t[n];r.enumerable=r.enumerable||!1,r.configurable=!0,\"value\"in r\u0026\u0026(r.writable=!0),Object.defineProperty(e,r.key,r)}}return function(t,n,r){return n\u0026\u0026e(t.prototype,n),r\u0026\u0026e(t,r),t}}();n(11);var a=n(3),o=r(a),u=function(){function e(t){var n=t.currentIndex,r=t.maxIndex,s=t.uiElements;i(this,e),this.maxIndex=r,this.uiElements=s,this.progressBar=document.createElement(\"div\"),this.progressBar.className=\"h5p-questionnaire-progress-bar\",this.progressBar.setAttribute(\"tabindex\",\"-1\"),this.progressBar.setAttribute(\"role\",\"progressbar\"),this.progressBar.setAttribute(\"aria-valuemin\",\"0\"),this.progressBar.setAttribute(\"aria-valuemax\",r),this.updateAriaValues(n),this.currentProgress=document.createElement(\"div\"),this.currentProgress.className=\"h5p-questionnaire-progress-bar-current\",this.numberWidget=new o.default(n,r),this.move(n),this.progressBar.appendChild(this.currentProgress)}return s(e,[{key:\"updateAriaValues\",value:function(e){this.progressBar.setAttribute(\"aria-valuenow\",e),this.progressBar.setAttribute(\"aria-valuetext\",this.uiElements.accessibility.progressBarText.replace(\"%current\",e).replace(\"%max\",this.maxIndex))}},{key:\"move\",value:function(e){this.numberWidget.setCurrentIndex(e),this.currentProgress.style.width=e/this.maxIndex*100+\"%\",this.updateAriaValues(e),this.progressBar.focus()}},{key:\"hide\",value:function(){var e=!(arguments.length\u003e0\u0026\u0026void 0!==arguments[0])||arguments[0];this.progressBar.classList[e?\"add\":\"remove\"](\"hide\")}},{key:\"attachNumberWidgetTo\",value:function(e){this.numberWidget.attachTo(e)}},{key:\"attachTo\",value:function(e){e.appendChild(this.progressBar)}}]),e}();t.default=u},function(e,t){\"use strict\";function n(e,t){if(!(e instanceof t))throw new TypeError(\"Cannot call a class as a function\")}function r(e,t){if(!e)throw new ReferenceError(\"this hasn\u0027t been initialised - super() hasn\u0027t been called\");return!t||\"object\"!=typeof t\u0026\u0026\"function\"!=typeof t?e:t}function i(e,t){if(\"function\"!=typeof t\u0026\u0026null!==t)throw new TypeError(\"Super expression must either be null or a function, not \"+typeof t);e.prototype=Object.create(t\u0026\u0026t.prototype,{constructor:{value:e,enumerable:!1,writable:!0,configurable:!0}}),t\u0026\u0026(Object.setPrototypeOf?Object.setPrototypeOf(e,t):e.__proto__=t)}Object.defineProperty(t,\"__esModule\",{value:!0});var s=function(){function e(e,t){for(var n=0;n\u003ct.length;n++){var r=t[n];r.enumerable=r.enumerable||!1,r.configurable=!0,\"value\"in r\u0026\u0026(r.writable=!0),Object.defineProperty(e,r.key,r)}}return function(t,n,r){return n\u0026\u0026e(t.prototype,n),r\u0026\u0026e(t,r),t}}(),a=function(e){function t(e){var i=e.progressBar,s=e.params,a=e.contentId,o=e.requiredField,u=(e.index,e.uiElements);n(this,t);var c=r(this,(t.__proto__||Object.getPrototypeOf(t)).call(this));return c.progressBar=i,c.questionnaireElement=document.createElement(\"div\"),c.questionnaireElement.className=\"h5p-questionnaire-element hide\",c.instance=H5P.newRunnable(s,a,H5P.jQuery(c.questionnaireElement),void 0,{parent:c}),c.requiredField=o,c.answered=s.userDatas\u0026\u0026s.userDatas.state\u0026\u0026s.userDatas.state.length,c.attachRequiredField(o,u),c.instance.on(\"xAPI\",c.handleInteraction.bind(c)),c.instance.on(\"allow-finish-changed\",c.trigger.bind(c)),c}return i(t,e),s(t,null,[{key:\"AllowFinish\",get:function(){return{ALWAYS:0,DENY:1,ALLOW:2}}}]),s(t,[{key:\"attachRequiredField\",value:function(e,t){if(e){var n=this.questionnaireElement.querySelector(\".h5p-subcontent-question\");this.questionnaireElement.classList.add(\"h5p-questionnaire-required\");var r=document.createElement(\"div\");r.textContent=\"* \"+t.requiredText,r.className=\"h5p-questionnaire-required-symbol\",n\u0026\u0026n.insertBefore(r,n.firstChild)}}},{key:\"handleInteraction\",value:function(e){if(\"http://adlnet.gov/expapi/verbs/interacted\"===e.data.statement.verb.id){var t=e.data.statement.result.response;t.trim\u0026\u0026(t=t.trim()),this.answered=!!t.length,this.trigger(\"handledInteraction\")}}},{key:\"allowFinish\",value:function(){return void 0!==this.instance.allowFinish?this.instance.allowFinish():t.AllowFinish.ALWAYS}},{key:\"finish\",value:function(){if(this.instance.finish)return this.instance.finish()}},{key:\"getCurrentState\",value:function(){return this.instance.getCurrentState?this.instance.getCurrentState():null}},{key:\"getElement\",value:function(){return this.questionnaireElement}},{key:\"isRequired\",value:function(){return this.requiredField}},{key:\"isAnswered\",value:function(){return this.answered}},{key:\"hide\",value:function(e){this.questionnaireElement.classList[e?\"add\":\"remove\"](\"hide\")}},{key:\"setActivityStarted\",value:function(){this.instance.setActivityStarted\u0026\u0026this.instance.setActivityStarted()}}]),t}(H5P.EventDispatcher);t.default=a},function(e,t,n){\"use strict\";function r(e){return e\u0026\u0026e.__esModule?e:{default:e}}function i(e,t){if(!(e instanceof t))throw new TypeError(\"Cannot call a class as a function\")}function s(e,t){if(!e)throw new ReferenceError(\"this hasn\u0027t been initialised - super() hasn\u0027t been called\");return!t||\"object\"!=typeof t\u0026\u0026\"function\"!=typeof t?e:t}function a(e,t){if(\"function\"!=typeof t\u0026\u0026null!==t)throw new TypeError(\"Super expression must either be null or a function, not \"+typeof t);e.prototype=Object.create(t\u0026\u0026t.prototype,{constructor:{value:e,enumerable:!1,writable:!0,configurable:!0}}),t\u0026\u0026(Object.setPrototypeOf?Object.setPrototypeOf(e,t):e.__proto__=t)}Object.defineProperty(t,\"__esModule\",{value:!0});var o=Object.assign||function(e){for(var t=1;t\u003carguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)\u0026\u0026(e[r]=n[r])}return e};n(13),n(15);var u=n(9),c=r(u),l=n(8),d=r(l),h=n(7),f=r(h),p=n(2),b=r(p),v=n(4),m=r(v),g=n(5),y=r(g),w=function(e){function t(e){var n=e.questionnaireElements,r=void 0===n?[]:n,a=e.successScreenOptions,u=void 0===a?{}:a,l=e.uiElements,h=void 0===l?{}:l,p=arguments.length\u003e1\u0026\u0026void 0!==arguments[1]?arguments[1]:null,v=arguments.length\u003e2\u0026\u0026void 0!==arguments[2]?arguments[2]:{};i(this,t);var g=s(this,(t.__proto__||Object.getPrototypeOf(t)).call(this));g.contentId=p,g.state={questionnaireElements:[],currentIndex:0},h=H5P.jQuery.extend(!0,{buttonLabels:{prevLabel:\"Back\",nextLabel:\"Next\",submitLabel:\"Submit\",continueLabel:\"Continue\"},accessibility:{requiredTextExitLabel:\"Close error message\",progressBarText:\"Question %current of %max\"},requiredMessage:\"This question requires an answer\",requiredText:\"required\",submitScreenTitle:\"You successfully answered all of the questions\",submitScreenSubtitle:\"Click below to submit your answers\"},h),g.createQuestionnaireBody=function(){var e=this,t=document.createElement(\"div\");return t.className=\"h5p-questionnaire-content\",r.forEach(function(n,r){var i=n.requiredField,s=n.library,a=e.createQuestionContent(i,s,r);t.appendChild(a.getElement()),e.state.questionnaireElements.push(a)}),this.createSubmitScreen().attachTo(t),u.enableSuccessScreen\u0026\u0026this.createSuccessScreen().attachTo(t),t},g.createQuestionContent=function(e,t,n){var r=this,i=new y.default({progressBar:this.progressBar,params:t,contentId:this.contentId,requiredField:e,index:n,uiElements:h});return i.on(\"handledInteraction\",function(){r.trigger(\"resize\"),r.requiredMessage.trigger(\"hideMessage\")}),i.on(\"allow-finish-changed\",function(){r.setForwardNavigationButton(r.state.currentIndex)}),i},g.createQuestionnaire=function(){var e=document.createElement(\"div\");if(e.className=\"h5p-questionnaire\",1===r.length\u0026\u0026!r[0].library)return e.classList.add(\"h5p-invalid-questionnaire\"),e.textContent=\"Invalid content\",e;this.createProgressBar(r).attachTo(e);var t=this.createQuestionnaireBody();e.appendChild(t),this.requiredMessage=new f.default(h),this.requiredMessage.attachTo(e);var n=this.createFooter();return n.attachTo(e),this.state.questionnaireElements.length\u0026\u0026this.state.questionnaireElements[0].setActivityStarted(),this.state.finished?u.enableSuccessScreen?this.showSuccessScreen():this.showSubmitScreen():this.move(this.state.currentIndex,this.state.currentIndex\u003e0),e},g.createSubmitScreen=function(){var e=this;return this.submitScreen=new d.default({title:h.submitScreenTitle,subtitle:h.submitScreenSubtitle,backLabel:h.buttonLabels.prevLabel,submitLabel:h.buttonLabels.submitLabel}),this.submitScreen.on(\"submit\",this.handleSubmit.bind(this)),this.submitScreen.on(\"previous\",function(){e.submitScreen.hide(),e.hideQuestion(!1),e.trigger(\"resize\")}),this.submitScreen},g.hideQuestion=function(e){this.state.questionnaireElements[this.state.questionnaireElements.length-1].hide(e),this.progressBar.hide(e),this.footer.hide(e)},g.createSuccessScreen=function(){var e=this;return this.successScreen=new c.default(u,this),this.successScreen.on(\"imageLoaded\",function(){e.trigger(\"resize\")}),this.successScreen},g.createProgressBar=function(e){return this.progressBar=new m.default({currentIndex:this.state.currentIndex+1,maxIndex:e.length,uiElements:h}),this.progressBar},g.showSubmitScreen=function(){this.hideQuestion(!0),this.submitScreen.show(),this.trigger(\"resize\")},g.showSuccessScreen=function(){this.hideQuestion(!0),this.submitScreen.hide(),this.successScreen.show(),this.trigger(\"resize\")},g.handleSubmit=function(){u.enableSuccessScreen?this.showSuccessScreen():this.trigger(\"noSuccessScreen\"),this.state.finished=!0,this.triggerXAPI(\"completed\")},g.createFooter=function(){var e=this,t=new b.default(h.buttonLabels);return t.on(\"next\",function(){e.move(e.state.currentIndex+1)\u0026\u0026e.showSubmitScreen()}),t.on(\"previous\",function(){e.move(e.state.currentIndex-1)}),t.trigger(\"disable-previous\"),this.footer=t,t},g.setForwardNavigationButton=function(e){if(!(e\u003ethis.state.questionnaireElements.length-1)){var t=this.state.questionnaireElements[e].allowFinish(),n=t===y.default.AllowFinish.ALLOW?\"next\":\"continue\";this.footer.setForwardNavigationButton(n)}},g.triggerRequiredQuestion=function(){this.requiredMessage.trigger(\"showMessage\"),this.trigger(\"resize\")},g.move=function(e){var t=arguments.length\u003e1\u0026\u0026void 0!==arguments[1]\u0026\u0026arguments[1],n=this.state,r=n.currentIndex,i=n.questionnaireElements,s=i[r];if(e\u003c0)return!1;if(!t\u0026\u0026e\u003er){if(!this.isValidAnswer(s))return this.triggerRequiredQuestion(),!1;if(s.allowFinish()===y.default.AllowFinish.DENY\u0026\u0026!s.finish())return this.setForwardNavigationButton(r),this.trigger(\"resize\"),!1}if(e\u003ei.length-1)return!0;this.footer.trigger(0===e?\"disable-previous\":\"enable-previous\"),this.setForwardNavigationButton(e),this.requiredMessage.trigger(\"hideMessage\"),i[r].hide(!0);var a=i[e];a.hide(!1);var u=a.getElement().querySelector(\".h5p-subcontent-question\");if(this.progressBar.attachNumberWidgetTo(u),this.trigger(\"resize\"),this.state=o(this.state,{currentIndex:e}),this.progressBar.move(e+1),0!==e\u0026\u00260!==r){var c=this.createXAPIEventTemplate(\"progressed\");c.data.statement.object\u0026\u0026(c.data.statement.object.definition.extensions[\"http://id.tincanapi.com/extension/ending-point\"]=e+1,this.trigger(c))}return i[e].setActivityStarted(),!1},g.isValidAnswer=function(e){return!e.isRequired()||e.isAnswered()},g.attach=function(e){e.get(0).classList.add(\"h5p-questionnaire-wrapper\"),e.get(0).appendChild(w)},g.getCurrentState=function(){var e=this.state.questionnaireElements.map(function(e){return e.getCurrentState()});return{questions:e,progress:this.state.currentIndex,finished:this.state.finished,version:1}},g.setPreviousState=function(){var e=v.previousState;if(e\u0026\u0026e.questions){if(this.state.finished=e.finished,e.progress){this.state.currentIndex=e.progress;var t=this.state.currentIndex\u003e=r.length;void 0===e.version\u0026\u0026t\u0026\u0026(this.state.currentIndex=r.length-1,this.state.finished=!0)}e.questions.forEach(function(e,t){r[t].library.userDatas=r[t].library.userDatas||{},r[t].library.userDatas.state=e})}},g.setPreviousState();var w=g.createQuestionnaire();return g}return a(t,e),t}(H5P.EventDispatcher);t.default=w},function(e,t,n){\"use strict\";function r(e,t){if(!(e instanceof t))throw new TypeError(\"Cannot call a class as a function\")}function i(e,t){if(!e)throw new ReferenceError(\"this hasn\u0027t been initialised - super() hasn\u0027t been called\");return!t||\"object\"!=typeof t\u0026\u0026\"function\"!=typeof t?e:t}function s(e,t){if(\"function\"!=typeof t\u0026\u0026null!==t)throw new TypeError(\"Super expression must either be null or a function, not \"+typeof t);e.prototype=Object.create(t\u0026\u0026t.prototype,{constructor:{value:e,enumerable:!1,writable:!0,configurable:!0}}),t\u0026\u0026(Object.setPrototypeOf?Object.setPrototypeOf(e,t):e.__proto__=t)}Object.defineProperty(t,\"__esModule\",{value:!0});var a=function(){function e(e,t){for(var n=0;n\u003ct.length;n++){var r=t[n];r.enumerable=r.enumerable||!1,r.configurable=!0,\"value\"in r\u0026\u0026(r.writable=!0),Object.defineProperty(e,r.key,r)}}return function(t,n,r){return n\u0026\u0026e(t.prototype,n),r\u0026\u0026e(t,r),t}}();n(16);var o=function(e){function t(e){r(this,t);var n=i(this,(t.__proto__||Object.getPrototypeOf(t)).call(this));n.requiredElement=document.createElement(\"div\"),n.requiredElement.classList.add(\"h5p-questionnaire-choice-required\"),n.requiredElement.classList.add(\"hide\"),n.requiredMessage=document.createElement(\"div\"),n.requiredMessage.textContent=e.requiredMessage,n.requiredMessage.className=\"h5p-questionnaire-choice-required-message\",n.requiredMessage.setAttribute(\"role\",\"alert\");var s=document.createElement(\"button\");return s.className=\"h5p-questionnaire-choice-required-exit\",s.setAttribute(\"aria-label\",e.accessibility.requiredTextExitLabel),s.addEventListener(\"click\",function(){n.hideMessage()}),n.on(\"hideMessage\",function(){n.hideMessage()}),n.on(\"showMessage\",function(){n.showMessage()}),n.requiredElement.appendChild(n.requiredMessage),n.requiredElement.appendChild(s),n}return s(t,e),a(t,[{key:\"showMessage\",value:function(){this.requiredElement.classList.remove(\"hide\")}},{key:\"hideMessage\",value:function(){this.requiredElement.classList.add(\"hide\")}},{key:\"attachTo\",value:function(e){e.appendChild(this.requiredElement)}}]),t}(H5P.EventDispatcher);t.default=o},function(e,t,n){\"use strict\";function r(e){return e\u0026\u0026e.__esModule?e:{default:e}}function i(e,t){if(!(e instanceof t))throw new TypeError(\"Cannot call a class as a function\")}function s(e,t){if(!e)throw new ReferenceError(\"this hasn\u0027t been initialised - super() hasn\u0027t been called\");return!t||\"object\"!=typeof t\u0026\u0026\"function\"!=typeof t?e:t}function a(e,t){if(\"function\"!=typeof t\u0026\u0026null!==t)throw new TypeError(\"Super expression must either be null or a function, not \"+typeof t);e.prototype=Object.create(t\u0026\u0026t.prototype,{constructor:{value:e,enumerable:!1,writable:!0,configurable:!0}}),t\u0026\u0026(Object.setPrototypeOf?Object.setPrototypeOf(e,t):e.__proto__=t)}Object.defineProperty(t,\"__esModule\",{value:!0});var o=function(){function e(e,t){for(var n=0;n\u003ct.length;n++){var r=t[n];r.enumerable=r.enumerable||!1,r.configurable=!0,\"value\"in r\u0026\u0026(r.writable=!0),Object.defineProperty(e,r.key,r)}}return function(t,n,r){return n\u0026\u0026e(t.prototype,n),r\u0026\u0026e(t,r),t}}();n(17);var u=n(1),c=r(u),l=function(e){function t(e){var n=e.title,r=e.subtitle,a=e.backLabel,o=e.submitLabel;i(this,t);var u=s(this,(t.__proto__||Object.getPrototypeOf(t)).call(this));return u.wrapper=c.default.createDiv({className:\"h5p-questionnaire-submit-screen hide\"}),u.wrapper.setAttribute(\"tabindex\",\"-1\"),u.wrapper.appendChild(c.default.createDiv({className:\"h5p-questionnaire-submit-screen-title\",textContent:n})),u.wrapper.appendChild(c.default.createDiv({className:\"h5p-questionnaire-submit-screen-subtitle\",textContent:r})),u.wrapper.appendChild(c.default.createButton(a,\"previous\",u)),u.wrapper.appendChild(c.default.createButton(o,\"submit\",u)),u.show=function(){this.wrapper.classList.remove(\"hide\"),this.wrapper.focus()},u.hide=function(){this.wrapper.classList.add(\"hide\")},u}return a(t,e),o(t,[{key:\"attachTo\",value:function(e){e.appendChild(this.wrapper)}}]),t}(H5P.EventDispatcher);t.default=l},function(e,t,n){\"use strict\";function r(e,t){if(!(e instanceof t))throw new TypeError(\"Cannot call a class as a function\")}function i(e,t){if(!e)throw new ReferenceError(\"this hasn\u0027t been initialised - super() hasn\u0027t been called\");return!t||\"object\"!=typeof t\u0026\u0026\"function\"!=typeof t?e:t}function s(e,t){if(\"function\"!=typeof t\u0026\u0026null!==t)throw new TypeError(\"Super expression must either be null or a function, not \"+typeof t);e.prototype=Object.create(t\u0026\u0026t.prototype,{constructor:{value:e,enumerable:!1,writable:!0,configurable:!0}}),t\u0026\u0026(Object.setPrototypeOf?Object.setPrototypeOf(e,t):e.__proto__=t)}Object.defineProperty(t,\"__esModule\",{value:!0});var a=function(){function e(e,t){for(var n=0;n\u003ct.length;n++){var r=t[n];r.enumerable=r.enumerable||!1,r.configurable=!0,\"value\"in r\u0026\u0026(r.writable=!0),Object.defineProperty(e,r.key,r)}}return function(t,n,r){return n\u0026\u0026e(t.prototype,n),r\u0026\u0026e(t,r),t}}();n(18);var o=function(e){function t(e,n){var s=e.successScreenImage,a=void 0===s?{}:s,o=e.successMessage,u=void 0===o?\"\":o;r(this,t);var c=i(this,(t.__proto__||Object.getPrototypeOf(t)).call(this));c.wrapper=document.createElement(\"div\"),c.wrapper.className=\"h5p-questionnaire-success\",c.wrapper.setAttribute(\"tabindex\",\"-1\"),c.wrapper.classList.add(\"hide\");var l=document.createElement(\"div\");l.className=\"h5p-questionnaire-success-center\",c.wrapper.appendChild(l);var d=document.createElement(\"div\");if(d.className=\"h5p-questionnaire-success-icon\",a.params\u0026\u0026a.params.file){d.classList.add(\"image\");var h=H5P.newRunnable(a,n.contentId,H5P.jQuery(d),void 0,{parent:n});h.on(\"loaded\",function(){c.trigger(\"imageLoaded\")})}else d.classList.add(\"standard-icon\");var f=document.createElement(\"div\");return f.className=\"h5p-questionnaire-success-message\",f.innerHTML=u,l.appendChild(d),l.appendChild(f),c.show=function(){this.wrapper.classList.remove(\"hide\"),this.wrapper.focus()},c}return s(t,e),a(t,[{key:\"attachTo\",value:function(e){e.appendChild(this.wrapper)}}]),t}(H5P.EventDispatcher);t.default=o},function(e,t){},function(e,t){},function(e,t){},function(e,t){},function(e,t){},function(e,t){},function(e,t){},function(e,t){},function(e,t){}]);"
,"Scripts/image-radio-button-group.js":"/**\n * ImageRadioButtonGroup widget module\n *\n * @param {H5P.jQuery} $\n */\nH5PEditor.widgets.imageRadioButtonGroup = (function ($) {\n\n var idCounter = 0;\n /**\n * Creates an image radio button group.\n *\n * @class H5PEditor.ImageRadioButtonGroup\n * @param {Object} parent\n * @param {Object} field\n * @param {Object} params\n * @param {function} setValue\n */\n function ImageRadioButtonGroup(parent, field, params, setValue) {\n this.parent = parent;\n this.field = field;\n this.params = params;\n this.setValue = setValue;\n }\n\n /**\n * Append the field to the wrapper.\n * @public\n * @param {H5P.jQuery} $wrapper\n */\n ImageRadioButtonGroup.prototype.appendTo = function ($wrapper) {\n var self = this;\n\n self.$container = $(\u0027\u003cdiv\u003e\u0027, {\n \u0027class\u0027: \u0027field text h5p-image-radio-button-group\u0027\n });\n\n // Add header:\n $(\u0027\u003cdiv\u003e\u0027, {\n \u0027class\u0027: \u0027h5peditor-label\u0027,\n html: self.field.label\n }).appendTo(self.$container);\n\n var $buttonGroup = $(\u0027\u003cdiv\u003e\u0027, {\n \u0027class\u0027: \u0027h5p-image-radio-button-container\u0027\n }).appendTo(self.$container);\n\n for (var i=0, numOptions = self.field.options.length; i \u003c numOptions; i++) {\n var option = self.field.options[i];\n var imgPath = H5P.getLibraryPath(self.field.library) + \u0027/\u0027 + option.image;\n var inputId = \u0027h5p-image-radio-button-\u0027 + (idCounter++);\n\n var $button = $(\u0027\u003cdiv\u003e\u0027, {\n \u0027class\u0027: \u0027h5p-image-radio-button \u0027 + option.value\n }).appendTo($buttonGroup);\n\n $(\u0027\u003cinput\u003e\u0027, {\n type: \u0027radio\u0027,\n name: self.field.name,\n value: option.value,\n id: inputId,\n checked: (self.params === option.value),\n change: function () {\n self.params = $(\u0027input[name=\u0027 + self.field.name + \u0027]:checked\u0027, $buttonGroup).val();\n self.setValue(self.field, self.params);\n }\n }).appendTo($button);\n\n $(\u0027\u003clabel\u003e\u0027, {\n \u0027for\u0027: inputId\n }).append($(\u0027\u003cdiv\u003e\u0027, {\n \u0027class\u0027: \u0027image-container\u0027,\n alt: option.label\n })).append($(\u0027\u003cspan\u003e\u0027, {\n html: option.label\n })).appendTo($button);\n\n if (option.description) {\n $(\u0027\u003cdiv\u003e\u0027, {\n \u0027class\u0027: \u0027h5p-option-description\u0027,\n html: option.description\n }).appendTo($button);\n }\n }\n\n // Add description:\n $(\u0027\u003cdiv\u003e\u0027, {\n \u0027class\u0027: \u0027h5peditor-field-description\u0027,\n html: self.field.description\n }).appendTo(self.$container);\n\n self.$container.appendTo($wrapper);\n };\n\n\n /**\n * Validate the current values.\n */\n ImageRadioButtonGroup.prototype.validate = function () {\n return true;\n };\n\n ImageRadioButtonGroup.prototype.remove = function () {};\n\n return ImageRadioButtonGroup;\n})(H5P.jQuery);\n"
,"Scripts/interactive-video-editor.js":"/*global H5PEditor, H5P*/\nH5PEditor.widgets.interactiveVideo = H5PEditor.InteractiveVideo = (function ($) {\n\n /**\n * Initialize interactive video editor.\n *\n * @class H5PEditor.InteractiveVideo\n * @param {Object} parent\n * @param {Object} field\n * @param {Object} params\n * @param {function} setValue\n */\n function InteractiveVideoEditor(parent, field, params, setValue) {\n var that = this;\n\n this.parent = parent;\n this.field = field;\n\n this.findField(this.field.video, function (field) {\n if (field.field.type !== \u0027video\u0027) {\n throw t(\u0027notVideoField\u0027, {\u0027:path\u0027: that.field.video});\n }\n\n if (field.params !== undefined) {\n that.setVideo(field.params);\n }\n\n field.changes.push(function (file) {\n that.setVideo(field.params);\n });\n });\n\n this.findField(this.field.poster, function (field) {\n if (field.field.type !== \u0027image\u0027) {\n throw t(\u0027notImageField\u0027, {\u0027:path\u0027: that.field.poster});\n }\n\n if (field.params !== undefined) {\n that.setPoster(field.params);\n }\n\n field.changes.push(function () {\n that.setPoster(field.params);\n });\n });\n\n this.params = $.extend({\n interactions: [],\n bookmarks: []\n }, params);\n setValue(field, this.params);\n\n this.children = [];\n\n this.passReadies = true;\n parent.ready(function () {\n that.passReadies = false;\n\n // Set active right away to generate common fields for interactions.\n that.setActive();\n });\n\n H5P.$window.on(\u0027resize\u0027, function () {\n if (that.IV) {\n that.IV.trigger(\u0027resize\u0027);\n }\n });\n\n // Tour de editor\n this.currentTabIndex = 0;\n\n // When wizard changes step\n parent.on(\u0027stepChanged\u0027, function (event) {\n that.currentTabIndex = event.data.id;\n that.startGuidedTour(H5PEditor.InteractiveVideo.GuidedTours.isOpen());\n });\n }\n\n /**\n * Must be changed if the semantics for the elements changes.\n * @private\n * @type {string}\n */\n InteractiveVideoEditor.clipboardKey = \u0027H5PEditor.InteractiveVideo\u0027;\n /**\n * Find a field, then run the callback.\n *\n * @param {function} callback\n */\n InteractiveVideoEditor.prototype.findField = function (path, callback) {\n var that = this;\n // Find field when tree is ready.\n this.parent.ready(function () {\n var field = H5PEditor.findField(path, that.parent);\n\n if (!field) {\n throw H5PEditor.t(\u0027core\u0027, \u0027unknownFieldPath\u0027, {\u0027:path\u0027: path});\n }\n\n callback(field);\n });\n };\n\n /**\n * Our tab has been set active. Create a new player if necessary.\n */\n InteractiveVideoEditor.prototype.setActive = function () {\n if (this.IV !== undefined) {\n // A video has been loaded, no need to recreate.\n // (but we can do some resizing :D)\n this.IV.trigger(\u0027resize\u0027);\n return;\n }\n\n // Reset css\n this.$editor.css({\n width: \u0027\u0027,\n height: \u0027\u0027,\n fontSize: \u0027\u0027\n });\n\n if (this.video === undefined) {\n this.$editor.html(this.noVideoSourceMessage(this.parent)).removeClass(\u0027h5p-interactive-video\u0027);\n return;\n }\n\n var that = this;\n\n // Create new player.\n this.IV = new H5P.InteractiveVideo({\n interactiveVideo: {\n video: {\n files: this.video,\n startScreenOptions: {\n poster: this.poster\n }\n },\n assets: this.params\n }\n }, H5PEditor.contentId);\n this.IV.editor = this;\n $(window).on(\u0027resize\u0027, function () {\n if (that.dnb) {\n that.dnb.resize();\n }\n });\n for (var i = 0; i \u003c this.IV.interactions.length; i++) {\n this.processInteraction(this.IV.interactions[i], this.params.interactions[i]);\n }\n this.IV.on(\u0027controls\u0027, function () {\n if (!that.IV) {\n return; // Video source or poster may have changed – abort!\n }\n\n // Add DragNBar.\n that.$bar = $(\u0027\u003cdiv class=\"h5p-interactive-video-dragnbar\"\u003e\u0027 + t(\u0027loading\u0027) + \u0027\u003c/div\u003e\u0027).prependTo(that.$editor);\n var interactions = findField(\u0027interactions\u0027, that.field.fields);\n var action = findField(\u0027action\u0027, interactions.field.fields);\n H5PEditor.LibraryListCache.getLibraries(\n action.options,\n function (libraries) {\n this.createDragNBar(libraries);\n this.setInteractionTitles();\n this.startGuidedTour();\n this.IV.trigger(\u0027dnbEditorReady\u0027);\n },\n that\n );\n\n // Add \"Add bookmark\" to bookmarks menu.\n $(\u0027\u003cdiv/\u003e\u0027, {\n \u0027class\u0027: \u0027h5p-add-bookmark\u0027,\n html: t(\u0027addBookmark\u0027),\n role: \u0027button\u0027,\n tabindex: 0,\n on: {\n click: function () {\n that.addBookmark();\n }\n },\n appendTo: that.IV.controls.$bookmarksChooser\n });\n });\n this.IV.on(\u0027bookmarkAdded\u0027, that.bookmarkAdded, that);\n this.IV.attach(this.$editor);\n\n // Create a focus handler\n this.$focusHandler = $(\u0027\u003cdiv\u003e\u0027, {\n \u0027class\u0027: \u0027h5peditor-iv-focus-handler\u0027\n }).click(function () {\n if (!that.dnb.focusedElement || !that.dnb.focusedElement.$element.is(\u0027:focus\u0027)) {\n\n // No focused element, remove overlay\n that.$focusHandler.removeClass(\u0027show\u0027);\n that.IV.$overlay.removeClass(\u0027h5p-visible\u0027);\n }\n }).appendTo(this.IV.$videoWrapper);\n\n this.pToEm = (this.IV.width / this.IV.fontSize) / 100;\n };\n\n /**\n * Set custom interaction titles when libraries are registered.\n */\n InteractiveVideoEditor.prototype.setInteractionTitles = function () {\n var self = this;\n\n this.IV.interactions.forEach(function (interaction) {\n // Try to figure out a title for the dialog\n var title = self.findLibraryTitle(interaction.getLibraryName());\n if (!title) {\n // Couldn\u0027t find anything, use default\n title = self.IV.l10n.interaction;\n }\n\n interaction.setTitle(title);\n });\n\n // Create title element\n this.$interactionTitle = $(\u0027\u003cdiv\u003e\u0027, {\n \u0027class\u0027: \u0027h5p-interaction-button-title\u0027\n }).appendTo(this.$editor);\n\n };\n\n InteractiveVideoEditor.prototype.showInteractionTitle = function (title, $interaction) {\n if (!this.$interactionTitle) {\n return;\n }\n\n // Set static margin\n var fontSize = parseInt(this.IV.$videoWrapper.css(\u0027font-size\u0027), 10);\n var staticMargin = 0.3 * fontSize;\n\n var videoOffsetX = $interaction.position().left;\n var videoOffsetY = $interaction.position().top;\n var dnbOffsetY = this.$bar.height();\n\n this.$interactionTitle.html(title);\n\n // center title\n var totalOffsetX = videoOffsetX - (this.$interactionTitle.outerWidth(true) / 2) + ($interaction.width() / 2);\n if (totalOffsetX \u003c 0) {\n totalOffsetX = 0;\n } else if(totalOffsetX + this.$interactionTitle.outerWidth(true) \u003e this.IV.$videoWrapper.width()) {\n totalOffsetX = this.IV.$videoWrapper.width() - this.$interactionTitle.outerWidth(true);\n }\n var totalOffsetY = videoOffsetY + dnbOffsetY - this.$interactionTitle.height() - 1;\n\n this.$interactionTitle.css({\n \u0027left\u0027: totalOffsetX,\n \u0027top\u0027: totalOffsetY - staticMargin\n }).addClass(\u0027show\u0027);\n };\n\n InteractiveVideoEditor.prototype.hideInteractionTitle = function () {\n if (!this.$interactionTitle) {\n return;\n }\n\n this.$interactionTitle.removeClass(\u0027show\u0027);\n };\n\n /**\n * Add bookmark\n */\n InteractiveVideoEditor.prototype.addBookmark = function () {\n var time = this.IV.video.getCurrentTime();\n\n // Find out where to place the bookmark\n for (var i = 0; i \u003c this.params.bookmarks.length; i++) {\n if (this.params.bookmarks[i].time \u003e time) {\n // Insert before this.\n break;\n }\n }\n\n var tenth = Math.floor(time * 10) / 10;\n if (this.IV.bookmarksMap[tenth] !== undefined) {\n // Create warning:\n this.displayMessage(t(\u0027bookmarkAlreadyExists\u0027));\n return; // Not space for another bookmark.\n }\n\n // Hide dialog\n if (this.IV.controls.$more.attr(\u0027aria-expanded\u0027) === \u0027true\u0027) {\n this.IV.controls.$more.click();\n }\n else {\n this.IV.controls.$bookmarks.click();\n }\n\n // Move other increament other ids.\n this.IV.trigger(\u0027bookmarksChanged\u0027, {\u0027index\u0027: i, \u0027number\u0027: 1});\n\n this.params.bookmarks.splice(i, 0, {\n time: time,\n label: t(\u0027newBookmark\u0027)\n });\n\n var $bookmark = this.IV.addBookmark(i, tenth);\n $bookmark.addClass(\u0027h5p-show\u0027);\n $bookmark.find(\u0027.h5p-bookmark-text\u0027).click();\n };\n\n /**\n * Display a popup containing a message.\n *\n * @param {string} message\n */\n InteractiveVideoEditor.prototype.displayMessage = function (message) {\n var timeout;\n var $warning = $(\u0027\u003cdiv/\u003e\u0027, {\n \u0027class\u0027: \u0027h5p-iv-message-popup\u0027,\n text: message,\n click: function () {\n clearTimeout(timeout);\n $warning.remove();\n }\n }).appendTo(this.$editor);\n\n timeout = setTimeout(function(){\n $warning.remove();\n }, 3000);\n };\n\n /**\n * Gets called whenever a bookmark is added to the UI.\n *\n * @param {H5P.Event} event\n */\n InteractiveVideoEditor.prototype.bookmarkAdded = function (event) {\n var self = this;\n var $bookmark = event.data.bookmark;\n\n $(\u0027\u003ca class=\"h5p-remove-bookmark\" href=\"#\"\u003e\u003c/a\u003e\u0027)\n .appendTo($bookmark.find(\u0027.h5p-bookmark-label\u0027))\n .click(function () {\n var id = $bookmark.data(\u0027id\u0027);\n self.params.bookmarks.splice(id, 1);\n self.IV.trigger(\u0027bookmarksChanged\u0027, {\u0027index\u0027: id, \u0027number\u0027: -1});\n $bookmark.remove();\n return false;\n });\n\n // Click to edit label.\n $bookmark.find(\u0027.h5p-bookmark-text\u0027).click(function () {\n if ($bookmark.hasClass(\u0027h5p-force-show\u0027)) {\n return; // Double click\n }\n $bookmark.addClass(\u0027h5p-force-show\u0027);\n var $text = $(this);\n\n // This is a IE-fix. Without this, text is not shown when editing\n $text.css({overflow: \u0027visible\u0027});\n\n var $input = $text.html(\u0027\u003cinput type=\"text\" class=\"h5p-bookmark-input\" style=\"width:\u0027 + ($text.width() - 19) + \u0027px\" maxlength=\"255\" value=\"\u0027 + $text.text() + \u0027\"/\u003e\u0027)\n .children()\n .blur(function () {\n var newText = $input.val();\n if (H5P.trim(newText) === \u0027\u0027) {\n newText = t(\u0027newBookmark\u0027);\n }\n $text.text(newText);\n $bookmark.removeClass(\u0027h5p-force-show\u0027).mouseover().mouseout();\n $text.css({overflow: \u0027hidden\u0027});\n\n var id = $bookmark.data(\u0027id\u0027);\n self.params.bookmarks[id].label = newText;\n self.IV.controls.$bookmarksChooser.find(\u0027li:eq(\u0027 + id + \u0027)\u0027).text(newText);\n })\n .keydown(function (event) {\n if (event.which === 13) {\n $input.blur();\n }\n })\n .focus();\n\n if ($input.val() === t(\u0027newBookmark\u0027)) {\n // Delete default value when editing\n $input.val(\u0027\u0027);\n }\n });\n };\n\n /**\n * Initialize the toolbar for creating interactivties.\n *\n * @param {Array} libraries\n */\n InteractiveVideoEditor.prototype.createDragNBar = function (libraries) {\n var that = this;\n\n this.libraries = libraries;\n this.dnb = new H5P.DragNBar(this.getButtons(libraries), this.IV.$videoWrapper, this.IV.$container);\n this.dnb.overflowThreshold = 16;\n\n /**\n * @private\n * @param {string} lib uber name\n * @returns {boolean}\n */\n var supported = function (lib) {\n for (var i = 0; i \u003c libraries.length; i++) {\n if (libraries[i].restricted !== true \u0026\u0026 libraries[i].uberName === lib) {\n return true; // Library is supported and allowed\n }\n }\n\n return false;\n };\n\n this.dnb.on(\u0027paste\u0027, function (event) {\n var pasted = event.data;\n var options = {\n width: pasted.width,\n height: pasted.height,\n pasted: true\n };\n\n if (pasted.from === InteractiveVideoEditor.clipboardKey) {\n // Pasted content comes from the same version of IV\n\n if (!pasted.generic) {\n // Non generic part, must be a something not created yet\n that.dnb.focus(that.addInteraction(pasted.specific, options));\n }\n else if (supported(pasted.generic.library)) {\n // Has generic part and the generic libray is supported\n that.dnb.focus(that.addInteraction(pasted.specific, options));\n }\n else {\n alert(H5PEditor.t(\u0027H5P.DragNBar\u0027, \u0027unableToPaste\u0027));\n }\n }\n else if (pasted.generic) {\n if (supported(pasted.generic.library)) {\n // Supported library from another content type\n\n if (pasted.specific.displayAsButton) {\n // Make sure buttons from CP still are buttons.\n options.displayType = \u0027button\u0027;\n }\n options.action = pasted.generic;\n that.dnb.focus(that.addInteraction(pasted.generic.library, options));\n }\n else {\n alert(H5PEditor.t(\u0027H5P.DragNBar\u0027, \u0027unableToPaste\u0027));\n }\n }\n });\n\n that.dnb.dnr.on(\u0027stoppedResizing\u0027, function (event) {\n // Set size in em\n that.interaction.setSize(event.data.width, event.data.height);\n\n if (event.data.left !== undefined \u0026\u0026 event.data.top !== undefined) {\n // Set pos in %\n var containerStyle = window.getComputedStyle(that.dnb.$container[0]);\n that.interaction.setPosition(event.data.left / (parseFloat(containerStyle.width) / 100), event.data.top / (parseFloat(containerStyle.height) / 100));\n }\n });\n\n // Make sure that dialog can\u0027t be closed without validation\n that.dnb.dialog.on(\u0027open\u0027, function () {\n that.dnb.dialog.disableOverlay = true;\n });\n\n this.dnb.dnd.startMovingCallback = function () {\n that.dnb.dnd.min = {x: 0, y: 0};\n that.dnb.dnd.max = {\n x: that.dnb.$container.width() - that.dnb.$element.outerWidth(),\n y: that.dnb.$container.height() - that.dnb.$element.outerHeight()\n };\n\n if (that.dnb.newElement) {\n that.dnb.dnd.adjust.x = 10;\n that.dnb.dnd.adjust.y = 10;\n that.dnb.dnd.min.y -= that.dnb.$list.height();\n }\n\n return true;\n };\n\n // Update params when the element is dropped.\n this.dnb.stopMovingCallback = function (x, y) {\n that.interaction.positionLabel(that.IV.$videoWrapper.width());\n that.interaction.setPosition(x, y);\n };\n\n this.dnb.dnd.releaseCallback = function () {\n // Edit element when it is dropped.\n if (that.dnb.newElement) {\n that.dnb.dnd.$element.dblclick();\n that.dnb.blurAll();\n }\n };\n that.IV.interactions.forEach(function (interaction) {\n // Add drag functionality if interaction has element\n if (interaction.getElement()) {\n var libraryName = interaction.getLibraryName();\n var options = {\n cornerLock: (libraryName === \u0027H5P.Image\u0027),\n disableResize: (libraryName === \u0027H5P.Link\u0027) || interaction.isButton()\n };\n that.addInteractionToDnb(interaction, interaction.getElement(), options);\n }\n });\n\n if (that.IV.scaledFontSize) {\n // Set the container em since the resizing is useless without it\n that.dnb.dnr.setContainerEm(that.IV.scaledFontSize);\n }\n\n this.dnb.attach(this.$bar);\n };\n\n /**\n * Create form for interaction.\n *\n * @param {H5P.InteractiveVideoInteraction} interaction\n * @param {Object} parameters\n */\n InteractiveVideoEditor.prototype.createInteractionForm = function (interaction, parameters) {\n var self = this;\n\n var $semanticFields = $(\u0027\u003cdiv\u003e\u0027, {\n \u0027class\u0027: \u0027h5p-dialog-inner-semantics\u0027\n });\n\n // Create form\n interaction.$form = $semanticFields;\n var interactions = findField(\u0027interactions\u0027, this.field.fields);\n\n // Clone semantics to avoid changing them for all interactions\n var interactionFields = H5PEditor.$.extend(true, [], interactions.field.fields);\n\n // Hide some fields for some interaction types\n var type = interaction.getLibraryName();\n\n if (InteractiveVideoEditor.XAPI_QUESTION_TYPES.indexOf(type) === -1) {\n hideFields(interactionFields, [\u0027adaptivity\u0027]);\n }\n if (type === \u0027H5P.Nil\u0027) {\n hideFields(interactionFields, [\u0027displayType\u0027]);\n }\n if (type !== \u0027H5P.Text\u0027 \u0026\u0026 type !== \u0027H5P.Image\u0027) {\n hideFields(interactionFields, [\u0027goto\u0027]);\n }\n if ([\u0027H5P.Text\u0027, \u0027H5P.Image\u0027, \u0027H5P.Link\u0027, \u0027H5P.Table\u0027].indexOf(type) === -1) {\n hideFields(interactionFields, [\u0027visuals\u0027]);\n }\n if (type === \u0027H5P.Summary\u0027) {\n var adaptivityFields = findField(\u0027adaptivity\u0027, interactionFields);\n hideFields(adaptivityFields.fields, [\u0027requireCompletion\u0027]);\n }\n\n if (parameters.visuals === undefined) {\n\n // Make Image background transparent by default\n if (type === \u0027H5P.Image\u0027) {\n parameters.visuals = {\n backgroundColor: \u0027rgba(0,0,0,0)\u0027,\n boxShadow: true\n };\n }\n // Set default link visuals\n else if (type === \u0027H5P.Link\u0027) {\n parameters.visuals = {\n backgroundColor: \u0027rgba(0,0,0,0.5)\u0027,\n boxShadow: true\n };\n }\n }\n\n // Always show link as poster\n if (type === \u0027H5P.Link\u0027 || type === \u0027H5P.GoToQuestion\u0027 || type === \u0027H5P.IVHotspot\u0027) {\n var field = findField(\u0027displayType\u0027, interactionFields);\n // Must set default to false and hide\n field.default = \u0027poster\u0027;\n field.widget = \u0027none\u0027;\n\n // Hide label field\n var labelField = findField(\u0027label\u0027, interactionFields);\n labelField.widget = \u0027none\u0027;\n\n if (type === \u0027H5P.GoToQuestion\u0027 \u0026\u0026 parameters.pause === undefined) {\n parameters.pause = true;\n }\n }\n\n // Set default displayType of images to poster\n if (type === \u0027H5P.Image\u0027) {\n var field = findField(\u0027displayType\u0027, interactionFields);\n field.default = \u0027poster\u0027;\n }\n\n H5PEditor.processSemanticsChunk(interactionFields, parameters, $semanticFields, self);\n\n self.setLibraryName(interaction.$form, type);\n };\n\n /**\n * Process interaction.\n *\n * @param {H5P.InteractiveVideoInteraction} interaction\n * @param {Object} parameters\n */\n InteractiveVideoEditor.prototype.processInteraction = function (interaction, parameters) {\n var self = this;\n var type = interaction.getLibraryName();\n this.createInteractionForm(interaction, parameters);\n\n // Keep track of form elements\n interaction.children = this.children;\n this.children = undefined;\n\n // Interaction fields object generated from interaction children\n var interactionFields = self.getInteractionFields(interaction);\n\n // Add classes to form elements if they exist\n if (interactionFields.duration.$item) {\n interactionFields.duration.$item.addClass(\u0027h5peditor-interaction-duration\u0027);\n }\n\n if (interactionFields.pause.$item) {\n interactionFields.pause.$item.addClass(\u0027h5peditor-interaction-pause\u0027);\n }\n\n if (interactionFields.label.$item) {\n interactionFields.label.$item.addClass(\u0027h5peditor-interaction-label\u0027);\n\n // Remove label when displayType is poster\n var $displayTypeRadios = $(\u0027.h5p-image-radio-button-group input:radio\u0027, interaction.$form);\n var $labelWrapper = interactionFields.label.$item;\n\n $displayTypeRadios.change(function () {\n $labelWrapper.toggleClass(\u0027hide\u0027, !interaction.isButton());\n if (!interaction.isButton() \u0026\u0026 interactionFields.pause.$item) {\n interactionFields.pause.$input[0].checked = true;\n interactionFields.pause.$input.trigger(\u0027change\u0027);\n }\n });\n\n $labelWrapper.toggleClass(\u0027hide\u0027, !interaction.isButton());\n }\n\n if (interactionFields.buttonOnMobile.$item) {\n var $buttonOnMobile = interactionFields.buttonOnMobile.$item;\n\n if (type == \u0027H5P.Image\u0027) {\n $displayTypeRadios.change(function () {\n $buttonOnMobile.toggleClass(\u0027hide\u0027, interaction.isButton());\n });\n\n $buttonOnMobile.addClass((interaction.isButton() ? \u0027hide\u0027 : \u0027\u0027));\n } else {\n $buttonOnMobile.remove();\n }\n }\n\n if (interactionFields.visuals.$group) {\n $(\u0027.h5p-image-radio-button-group input:radio\u0027, interaction.$form).change(function () {\n interactionFields.visuals.$group.toggleClass(\u0027hide\u0027, $(this).val() !== \u0027poster\u0027);\n });\n\n interactionFields.visuals.$group.toggleClass(\u0027hide\u0027, parameters.displayType !== \u0027poster\u0027);\n }\n\n // Create require completion instances for content types with scores.\n // Summary is filtered out because it can\u0027t be retried.\n var eligibleForRequireCompletion = InteractiveVideoEditor.XAPI_QUESTION_TYPES\n .filter(function (questionType) {\n return questionType !== \u0027H5P.Summary\u0027;\n }).indexOf(interaction.getLibraryName()) \u003e= 0;\n\n if (eligibleForRequireCompletion) {\n new H5PEditor.InteractiveVideo.RequireCompletion(self, interaction);\n }\n\n interaction.on(\u0027display\u0027, function (event) {\n var $interaction = event.data;\n // Customize rendering of interaction\n self.newInteraction(interaction, $interaction);\n });\n\n // Find library field instance\n var libraryFieldInstance;\n for (var i = 0; i \u003c interaction.children.length; i++) {\n if (interaction.children[i] instanceof H5PEditor.Library) {\n libraryFieldInstance = interaction.children[i];\n }\n }\n\n if (libraryFieldInstance) {\n /**\n * Callback for when library changes.\n *\n * @private\n */\n var libraryChange = function () {\n var lib = libraryFieldInstance.currentLibrary.split(\u0027 \u0027)[0];\n if (lib !== \u0027H5P.Image\u0027) {\n return;\n }\n\n /**\n * Callback for when image changes.\n *\n * @private\n * @param {Object} newParams\n */\n var imageChange = function (newParams) {\n if (newParams !== undefined \u0026\u0026 newParams.width !== undefined \u0026\u0026 newParams.height !== undefined) {\n self.setImageSize(parameters, newParams);\n }\n };\n\n // Add callback to the correct field\n libraryFieldInstance.forEachChild(function (child) {\n if (child.field.name === \u0027file\u0027) {\n child.changes.push(imageChange);\n return true;\n }\n });\n };\n\n // Add callback\n libraryFieldInstance.changes.push(libraryChange);\n if (libraryFieldInstance.children !== undefined) {\n // Trigger right away\n libraryChange();\n }\n }\n\n if (parameters.pasted) {\n if (type === \u0027H5P.Image\u0027 \u0026\u0026 parameters.action.params.file !== undefined) {\n self.setImageSize(parameters, parameters.action.params.file);\n }\n delete parameters.pasted;\n }\n };\n\n /**\n * Get interaction fields from interaction children\n * @param {Object} interaction\n * @return {Object} All interaction fields as object properties\n */\n InteractiveVideoEditor.prototype.getInteractionFields = function (interaction) {\n return interaction.children.reduce(function (prev, child) {\n if (child.field \u0026\u0026 child.field.name) {\n prev[child.field.name] = child;\n }\n return prev;\n }, {});\n };\n\n /**\n * Help set size for new images and keep aspect ratio.\n *\n * @param {object} parameters\n * @param {object} newParams\n */\n InteractiveVideoEditor.prototype.setImageSize = function (parameters, newParams) {\n if (newParams === undefined || newParams.width === undefined || newParams.height === undefined) {\n return;\n }\n var self = this;\n\n // Avoid to small images\n var fontSize = Number(self.IV.$videoWrapper.css(\u0027fontSize\u0027).replace(\u0027px\u0027, \u0027\u0027));\n if (newParams.width \u003c fontSize) {\n newParams.width = fontSize;\n }\n if (newParams.height \u003c fontSize) {\n newParams.height = fontSize;\n }\n\n // Reduce height for tiny images, stretched pixels looks horrible\n var suggestedHeight = newParams.height / fontSize;\n if (suggestedHeight \u003c parameters.height) {\n parameters.height = suggestedHeight;\n }\n\n // Calculate new width\n parameters.width = (parameters.height * (newParams.width / newParams.height));\n };\n\n /**\n * Add library name to library form.\n *\n * @param {H5P.jQuery} $form\n * Interaction view form\n * @param {string} libraryType\n * Library type, e.g. H5P.Blanks\n */\n InteractiveVideoEditor.prototype.setLibraryName = function ($form, libraryType) {\n var libraryName = libraryType.replace(\u0027.\u0027, \u0027-\u0027).toLowerCase() + \u0027-library\u0027;\n var $libraryForm = $form.children(\u0027.library\u0027);\n $libraryForm.addClass(libraryName);\n };\n\n /**\n *\n * @param interaction\n */\n InteractiveVideoEditor.prototype.openInteractionDialog = function (interaction) {\n var that = this;\n if (that.lastState !== H5P.Video.PAUSED \u0026\u0026 that.lastState !== H5P.Video.ENDED) {\n // Pause video\n that.IV.video.pause();\n }\n\n // Try to figure out a title for the dialog\n var title = interaction.getTitle();\n if (title === that.IV.l10n.interaction) {\n // Try to find something better than the default title\n title = that.findLibraryTitle(interaction.getLibraryName());\n if (!title) {\n // Couldn\u0027t find anything, use default\n title = that.IV.l10n.interaction;\n }\n }\n\n // Add dialog buttons\n var $doneButton = $(\u0027\u003ca href=\"#\" class=\"h5p-button h5p-done\"\u003e\u0027 + t(\u0027done\u0027) + \u0027\u003c/a\u003e\u0027)\n .click(function () {\n if (H5PEditor.Html) {\n // Need to do this before form is validated\n H5PEditor.Html.removeWysiwyg();\n }\n if (that.validDialog(interaction)) {\n that.dnb.dialog.close();\n interaction.focus();\n }\n that.IV.addSliderInteractions();\n return false;\n });\n\n var $removeButton = $(\u0027\u003ca href=\"#\" class=\"h5p-button h5p-remove\"\u003e\u0027 + t(\u0027remove\u0027) + \u0027\u003c/a\u003e\u0027)\n .click(function () {\n if (H5PEditor.Html) {\n // Need to do this before form is validated\n H5PEditor.Html.removeWysiwyg();\n }\n if (confirm(t(\u0027removeInteraction\u0027))) {\n that.removeInteraction(interaction);\n that.dnb.dialog.close();\n }\n that.IV.addSliderInteractions();\n that.dnb.blurAll();\n return false;\n });\n\n var $buttons = $(\u0027\u003cdiv class=\"h5p-dialog-buttons\"\u003e\u003c/div\u003e\u0027)\n .append($doneButton)\n .append($removeButton);\n\n interaction.setTitle(title);\n interaction.trigger(\u0027openEditDialog\u0027);\n that.dnb.dialog.open(interaction.$form, title, interaction.getClass() + \u0027-icon\u0027, $buttons);\n\n // Blur context menu when opening dialog\n setTimeout(function () {\n that.dnb.blurAll();\n }, 0);\n };\n\n /**\n * Add interaction to drag n bar and initialize listeners.\n * @param {H5P.InteractiveVideoInteraction} interaction Interaction\n * @param {H5P.jQuery} $interaction Interaction element\n * @param {Object} [options] Options for new dnb element\n */\n InteractiveVideoEditor.prototype.addInteractionToDnb = function (interaction, $interaction, options) {\n var that = this;\n var newDnbElement = that.dnb.add($interaction, interaction.getClipboardData(), options);\n var createdNewElement = interaction.setDnbElement(newDnbElement);\n\n if (!interaction.isButton()) {\n // For posters, we don\u0027t want the elements inside the interaction to be tabbable in the editor.\n $interaction.find(\u0027.h5p-interaction-inner\u0027).find(\u0027*\u0027).attr(\u0027tabindex\u0027, \u0027-1\u0027);\n }\n\n // New DragNBarElement was set, register listeners\n if (createdNewElement) {\n newDnbElement.contextMenu.on(\u0027contextMenuEdit\u0027, function () {\n that.openInteractionDialog(interaction);\n newDnbElement.hideContextMenu();\n });\n\n newDnbElement.contextMenu.on(\u0027contextMenuRemove\u0027, function () {\n if (confirm(t(\u0027removeInteraction\u0027))) {\n that.removeInteraction(interaction);\n that.dnb.dialog.close();\n }\n that.IV.addSliderInteractions();\n that.dnb.blurAll();\n });\n\n newDnbElement.contextMenu.on(\u0027contextMenuBringToFront\u0027, function () {\n // Find interaction index\n var oldZ;\n for (var i = 0; i \u003c that.IV.interactions.length; i++) {\n if (that.IV.interactions[i] === interaction) {\n oldZ = i;\n break;\n }\n }\n\n // Add to end of params\n that.params.interactions.push(that.params.interactions.splice(oldZ, 1)[0]);\n\n // Update internally for IV player\n that.IV.interactions.push(that.IV.interactions.splice(oldZ, 1)[0]);\n\n // Update visuals\n $interaction.appendTo(that.IV.$overlay);\n });\n\n newDnbElement.contextMenu.on(\u0027contextMenuSendToBack\u0027, function () {\n // Find interaction index\n var oldZ;\n for (var i = 0; i \u003c that.IV.interactions.length; i++) {\n if (that.IV.interactions[i] === interaction) {\n oldZ = i;\n break;\n }\n }\n\n // Add to end of params\n that.params.interactions.unshift(that.params.interactions.splice(oldZ, 1)[0]);\n\n // Update internally for IV player\n that.IV.interactions.unshift(that.IV.interactions.splice(oldZ, 1)[0]);\n\n // Update visuals\n $interaction.prependTo(that.IV.$overlay);\n });\n }\n };\n\n /**\n * Called when rendering a new interaction.\n *\n * @param {H5P.InteractiveVideoInteraction} interaction\n * @param {H5P.jQuery} $interaction\n */\n InteractiveVideoEditor.prototype.newInteraction = function (interaction, $interaction) {\n var that = this;\n var libraryName = interaction.getLibraryName();\n var options = {\n cornerLock: (libraryName === \u0027H5P.Image\u0027),\n disableResize: (libraryName === \u0027H5P.Link\u0027) || interaction.isButton()\n };\n\n if (!interaction.isButton()) {\n // Add overlay\n $(\u0027\u003cdiv/\u003e\u0027, {\n \u0027class\u0027: \u0027h5p-interaction-overlay\u0027\n }).appendTo($interaction);\n }\n\n if (that.dnb !== undefined) {\n // Add resizing, context menu etc.\n that.addInteractionToDnb(interaction, $interaction, options);\n }\n\n if (!interaction.isButton()) {\n // Pause video on resizing\n $interaction.children(\u0027.h5p-dragnresize-handle\u0027).mousedown(function (event) {\n that.interaction = interaction;\n that.IV.video.pause();\n });\n }\n\n // Disable the normal dialog\n interaction.dialogDisabled = true;\n\n $interaction.mousedown(function (event) {\n // Keep track of last state\n that.IV.lastState = that.IV.currentState;\n\n that.interaction = interaction;\n }).dblclick(function () {\n if (that.dnb !== undefined) {\n that.openInteractionDialog(interaction);\n }\n }).focus(function () {\n // On focus, show overlay\n that.$focusHandler.addClass(\u0027show\u0027);\n });\n };\n\n /**\n * Validate the current dialog to see if it can be closed.\n *\n * @param {H5P.InteractiveVideoInteraction} interaction\n * @returns {boolean}\n */\n InteractiveVideoEditor.prototype.validDialog = function (interaction) {\n var valid = true;\n var elementKids = interaction.children;\n for (var i = 0; i \u003c elementKids.length; i++) {\n if (elementKids[i].validate() === false) {\n valid = false;\n }\n }\n\n if (valid) {\n // Keep form\n interaction.$form.detach();\n\n // Remove interaction from display\n interaction.remove(true);\n\n // Recreate content instance\n interaction.reCreate();\n\n // Make sure the element is inside the container the next time it\u0027s displayed\n interaction.fit = true;\n\n // Check if we should show again\n interaction.toggle(this.IV.video.getCurrentTime(), true);\n\n if (this.dnb) {\n this.dnb.blurAll();\n }\n }\n\n return valid;\n };\n\n /**\n * Makes sure the given interaction doesn\u0027t stick out of the video container.\n *\n * @param {H5P.jQuery} $interaction\n * @param {Object} interactionParams\n */\n InteractiveVideoEditor.prototype.fit = function ($interaction, interactionParams) {\n var self = this;\n\n var sizeNPosition = self.dnb.getElementSizeNPosition($interaction);\n var updated = H5P.DragNBar.fitElementInside(sizeNPosition);\n\n // Set the updated properties\n var style = {};\n\n if (updated.width !== undefined) {\n interactionParams.width = updated.width / self.IV.scaledFontSize;\n style.width = interactionParams.width + \u0027em\u0027;\n }\n if (updated.left !== undefined) {\n interactionParams.x = updated.left / (sizeNPosition.containerWidth / 100);\n style.left = interactionParams.x + \u0027%\u0027;\n }\n if (updated.height !== undefined) {\n interactionParams.height = updated.height / self.IV.scaledFontSize;\n style.height = interactionParams.height + \u0027em\u0027;\n }\n if (updated.top !== undefined) {\n interactionParams.y = updated.top / (sizeNPosition.containerHeight / 100);\n style.top = interactionParams.y + \u0027%\u0027;\n }\n\n // Apply style\n $interaction.css(style);\n };\n\n /**\n * Revert our customization to the dialog.\n */\n InteractiveVideoEditor.prototype.hideDialog = function () {\n this.IV.hideDialog();\n this.IV.$dialog.children(\u0027.h5p-dialog-inner\u0027).css({\n height: \u0027\u0027,\n width: \u0027\u0027\n });\n this.IV.$dialog.children(\u0027.h5p-dialog-hide\u0027).show();\n this.IV.$dialog.children(\u0027.h5p-dialog-buttons\u0027).remove();\n };\n\n /**\n * Remove interaction from video.\n *\n * @param {number} id\n */\n InteractiveVideoEditor.prototype.removeInteraction = function (interaction) {\n for (var i = 0; i \u003c this.IV.interactions.length; i++) {\n if (this.IV.interactions[i] === interaction) {\n this.params.interactions.splice(i, 1);\n this.IV.interactions.splice(i, 1);\n break;\n }\n }\n H5PEditor.removeChildren(interaction.children);\n interaction.remove();\n };\n\n /**\n * Returns buttons for the DragNBar.\n *\n * @param {Array} libraries\n * @returns {Array}\n */\n InteractiveVideoEditor.prototype.getButtons = function (libraries) {\n var buttons = [];\n for (var i = 0; i \u003c libraries.length; i++) {\n if (libraries[i].restricted === undefined || !libraries[i].restricted) {\n buttons.push(this.getButton(libraries[i]));\n }\n }\n\n return buttons;\n };\n\n /**\n * Find the title for the given library.\n *\n * @param {string} libraryName\n * @returns {string}\n */\n InteractiveVideoEditor.prototype.findLibraryTitle = function (libraryName) {\n if (!this.libraries) {\n return;\n }\n\n for (var i = 0; i \u003c this.libraries.length; i++) {\n if (this.libraries[i].name === libraryName) {\n return this.getLibraryTitle(this.libraries[i]);\n }\n }\n };\n\n /**\n * Determines a human readable name for the library to use in the editor.\n *\n * @param {string} library\n * @returns {string}\n */\n InteractiveVideoEditor.prototype.getLibraryTitle = function (library) {\n // Determine title\n switch (library.name) {\n case \u0027H5P.Summary\u0027:\n return \u0027Statements\u0027;\n case \u0027H5P.Nil\u0027:\n return \u0027Label\u0027;\n default:\n return library.title;\n }\n };\n\n /**\n * Returns button data for the given library.\n *\n * @param {string} library\n * @returns {Object}\n */\n InteractiveVideoEditor.prototype.getButton = function (library) {\n var that = this;\n var id = library.name.split(\u0027.\u0027)[1].toLowerCase();\n\n return {\n id: id,\n title: that.getLibraryTitle(library),\n createElement: function () {\n return that.addInteraction(library.uberName);\n }\n };\n };\n\n /**\n * Add a new interaction to the interactive video.\n *\n * @param {string|object} library Content type or parameters\n * @param {object} [options] Override the default options\n * @returns {H5P.jQuery}\n */\n InteractiveVideoEditor.prototype.addInteraction = function (library, options) {\n this.IV.$overlay.addClass(\u0027h5p-visible\u0027);\n options = options || {};\n var self = this;\n self.IV.video.pause();\n\n var params;\n if (!(library instanceof String || typeof library === \u0027string\u0027)) {\n params = library;\n }\n\n var from = Math.floor(self.IV.video.getCurrentTime());\n if (!params) {\n var type = library.split(\u0027 \u0027)[0];\n\n params = {\n x: 47.813153766, // Center button\n y: 46.112273361,\n width: 10,\n height: 10,\n duration: {\n from: from,\n to: from + 10\n },\n libraryTitle: self.findLibraryTitle(type)\n };\n if (options.action) {\n params.action = options.action;\n params.displayType = options.displayType ? options.displayType : \u0027poster\u0027;\n }\n else {\n params.action = {\n library: library,\n params: {}\n };\n }\n if (options.width \u0026\u0026 options.height \u0026\u0026 !options.displayType) {\n params.width = options.width * this.pToEm;\n params.height = options.height * this.pToEm;\n }\n params.action.subContentId = H5P.createUUID();\n\n if (type === \u0027H5P.Nil\u0027) {\n params.label = \u0027Lorem ipsum dolor sit amet...\u0027;\n }\n else if (type === \u0027H5P.Link\u0027) {\n // Links are always posters\n params.displayType = \u0027poster\u0027;\n }\n if (options.pasted) {\n params.pasted = true;\n }\n }\n else {\n // Change starting time, but keep the same length\n params.duration.to = from + (params.duration.to - params.duration.from);\n params.duration.from = from;\n }\n\n var duration = Math.floor(self.IV.video.getDuration());\n if (params.duration.to \u003e duration) {\n // Keep interaction inside video play time\n params.duration.to = duration;\n }\n\n // Make sure we don\u0027t overlap another visible element\n var size = window.getComputedStyle(this.IV.$videoWrapper[0]);\n var widthToPx = parseFloat(size.width) / 100;\n var heightToPx = parseFloat(size.height) / 100;\n var pos = {\n x: params.x * widthToPx,\n y: params.y * heightToPx\n };\n this.dnb.avoidOverlapping(pos, {\n width: params.width * this.IV.scaledFontSize,\n height: params.height * this.IV.scaledFontSize,\n });\n params.x = pos.x / widthToPx;\n params.y = pos.y / heightToPx;\n\n self.params.interactions.push(params);\n var i = self.params.interactions.length - 1;\n self.interaction = self.IV.initInteraction(i);\n self.processInteraction(self.interaction, params);\n\n var $interaction = self.interaction.toggle(from);\n this.IV.addSliderInteractions();\n return $interaction;\n };\n\n /**\n * Set new video params and remove old player.\n *\n * @param {Object} files\n */\n InteractiveVideoEditor.prototype.setVideo = function (files) {\n this.video = files;\n\n if (this.IV !== undefined) {\n delete this.IV;\n }\n };\n\n /**\n * Set new poster and remove old player.\n *\n * @param {Object} poster\n */\n InteractiveVideoEditor.prototype.setPoster = function (poster) {\n this.poster = poster;\n\n if (this.IV !== undefined) {\n delete this.IV;\n }\n };\n\n /**\n * Disable guided tour\n *\n * @method disableGuidedTour\n */\n InteractiveVideoEditor.disableGuidedTour = function () {\n InteractiveVideoEditor.showGuidedTour = false;\n };\n InteractiveVideoEditor.showGuidedTour = true;\n /**\n * Start the guided tour if not disabled\n *\n * @method startGuidedTour\n * @param {Boolean} force If true, don\u0027t care if user already has seen it\n */\n InteractiveVideoEditor.prototype.startGuidedTour = function (force) {\n if (InteractiveVideoEditor.showGuidedTour) {\n H5PEditor.InteractiveVideo.GuidedTours.start(this.currentTabIndex, force || false, t);\n // Make sure the guided tour stays behind other important popups\n }\n };\n\n /**\n * Append field to wrapper.\n *\n * @param {H5P.jQuery} $wrapper\n */\n InteractiveVideoEditor.prototype.appendTo = function ($wrapper) {\n var self = this;\n // Added to support older versions of core. Needed when using IV in CP.\n var $libwrap = $wrapper.parent().parent();\n if ($libwrap.hasClass(\u0027libwrap\u0027)) {\n $libwrap.addClass(\u0027h5p-interactivevideo-editor\u0027);\n }\n\n this.$item = $(this.createHtml()).appendTo($wrapper);\n this.$editor = this.$item.children(\u0027.h5peditor-interactions\u0027);\n this.$errors = this.$item.children(\u0027.h5p-errors\u0027);\n this.$bar = this.$item.children(\u0027.h5peditor-dragnbar\u0027);\n\n $(\u0027\u003cspan\u003e\u0027, {\n \u0027class\u0027: \u0027h5peditor-guided-tour\u0027,\n html: t(\u0027tourButtonStart\u0027),\n click: function () {\n self.startGuidedTour(true);\n return false;\n }\n }).appendTo(\u0027.h5p-interactivevideo-editor .field-name-interactiveVideo \u003e .h5peditor-label-wrapper \u003e .h5peditor-label\u0027);\n self.startGuidedTour();\n };\n\n /**\n * Create HTML for the field.\n *\n * @returns {string}\n */\n InteractiveVideoEditor.prototype.createHtml = function () {\n return H5PEditor.createItem(this.field.widget, \u0027\u003cdiv class=\"h5peditor-interactions\"\u003e\u003c/div\u003e\u0027);\n };\n\n /**\n * Create HTML for the no video source message.\n *\n * @param {Object} parent\n * @returns {jQuery}\n */\n InteractiveVideoEditor.prototype.noVideoSourceMessage = function (parent) {\n var $html = $(\u0027\u003cdiv/\u003e\u0027);\n\n var $icon = $(\u0027\u003cdiv/\u003e\u0027, {\n \u0027class\u0027: \u0027h5p-no-video-icon\u0027,\n appendTo: $html\n });\n\n var $title = $(\u0027\u003cdiv/\u003e\u0027, {\n \u0027class\u0027: \u0027h5p-no-video-title\u0027,\n text: t(\u0027noVideoSource\u0027),\n appendTo: $html\n });\n\n var $text = $(\u0027\u003cdiv/\u003e\u0027, {\n \u0027class\u0027: \u0027h5p-no-video-text\u0027,\n text: t(\u0027selectVideo\u0027),\n appendTo: $html\n });\n\n var $button = $(\u0027\u003cbutton/\u003e\u0027, {\n \u0027class\u0027: \u0027h5p-no-video-button h5p-joubelui-button\u0027,\n type: \u0027button\u0027,\n text: t(\u0027tourButtonBack\u0027),\n click: function () {\n parent.$tabs[0].click()\n },\n appendTo: $html\n });\n\n return $html;\n };\n\n /**\n * Validate the current field.\n *\n * @returns {boolean}\n */\n InteractiveVideoEditor.prototype.validate = function () {\n // We must stops the playpack of any media!\n if (this.IV \u0026\u0026 this.IV.video) {\n this.IV.video.pause();\n }\n\n // Run validate on interactions to trigger the storing of values\n if (this.IV) {\n for (var i = 0; i \u003c this.IV.interactions.length; i++) {\n var interaction = this.IV.interactions[i];\n for (var j = 0; j \u003c interaction.children.length; j++) {\n interaction.children[j].validate();\n }\n }\n }\n\n return true; // An interactive video is always valid :-)\n };\n\n /**\n * Remove this item.\n */\n InteractiveVideoEditor.prototype.remove = function () {\n if (this.dnb !== undefined) {\n this.dnb.remove();\n }\n H5PEditor.InteractiveVideo.GuidedTours.remove();\n this.$item.remove();\n };\n\n /**\n * Collect functions to execute once the tree is complete.\n *\n * @param {function} ready\n */\n InteractiveVideoEditor.prototype.ready = function (ready) {\n if (this.passReadies) {\n this.parent.ready(ready);\n }\n else {\n this.readies.push(ready);\n }\n };\n\n /**\n * Translate UI texts for this library.\n *\n * @private\n * @param {string} key\n * @param {Object} [vars] Placeholders\n * @returns {string}\n */\n var t = InteractiveVideoEditor.t = function (key, vars) {\n return H5PEditor.t(\u0027H5PEditor.InteractiveVideo\u0027, key, vars);\n };\n\n /**\n * Look for field with the given name in the given collection.\n *\n * @private\n * @param {string} name of field\n * @param {Array} fields collection to look in\n * @returns {Object} field object\n */\n var findField = function (name, fields) {\n for (var i = 0; i \u003c fields.length; i++) {\n if (fields[i].name === name) {\n return fields[i];\n }\n }\n };\n\n /**\n * Hide the given fields from the given form.\n *\n * @private\n * @param {Array} interactionFields to be form\n * @param {Array} fields to hide\n */\n var hideFields = function (interactionFields, fields) {\n // Find and hide fields in list\n for (var i = 0; i \u003c fields.length; i++) {\n var field = findField(fields[i], interactionFields);\n if (field) {\n field.widget = \u0027none\u0027;\n }\n }\n };\n\n /**\n * A maintained list of strings with content types that has a score.\n * @type {string[]}\n */\n InteractiveVideoEditor.XAPI_QUESTION_TYPES = [\n \u0027H5P.MultiChoice\u0027,\n \u0027H5P.SingleChoiceSet\u0027,\n \u0027H5P.Blanks\u0027,\n \u0027H5P.DragQuestion\u0027,\n \u0027H5P.Summary\u0027,\n \u0027H5P.MarkTheWords\u0027,\n \u0027H5P.DragText\u0027,\n \u0027H5P.TrueFalse\u0027\n ];\n\n return InteractiveVideoEditor;\n})(H5P.jQuery);\n\n// Default english translations\nH5PEditor.language[\u0027H5PEditor.InteractiveVideo\u0027] = {\n libraryStrings: {\n selectVideo: \u0027You must select a video before adding interactions.\u0027,\n noVideoSource: \u0027No Video Source\u0027,\n notVideoField: \u0027\":path\" is not a video.\u0027,\n notImageField: \u0027\":path\" is not a image.\u0027,\n insertElement: \u0027Click and drag to place :type\u0027,\n popupTitle: \u0027Edit :type\u0027,\n done: \u0027Done\u0027,\n loading: \u0027Loading...\u0027,\n remove: \u0027Remove\u0027,\n removeInteraction: \u0027Are you sure you wish to remove this interaction?\u0027,\n addBookmark: \u0027Add bookmark\u0027,\n newBookmark: \u0027New bookmark\u0027,\n bookmarkAlreadyExists: \u0027Bookmark already exists here. Move playhead and add a bookmark at another time.\u0027,\n tourButtonStart: \u0027Tour\u0027,\n tourButtonExit: \u0027Exit\u0027,\n tourButtonDone: \u0027Done\u0027,\n tourButtonBack: \u0027Back\u0027,\n tourButtonNext: \u0027Next\u0027,\n tourStepUploadIntroText: \u0027\u003cp\u003eThis tour guides you through the most important features of the Interactive Video editor.\u003c/p\u003e\u003cp\u003eStart this tour at any time by pressing the Tour button in the top right corner.\u003c/p\u003e\u003cp\u003ePress EXIT to skip this tour or press NEXT to continue.\u003c/p\u003e\u0027,\n tourStepUploadFileTitle: \u0027Adding video\u0027,\n tourStepUploadFileText: \u0027\u003cp\u003eStart by adding a video file. You can upload a file from your computer or paste a URL to a YouTube video or a supported video file.\u003c/p\u003e\u003cp\u003eTo ensure compatibility across browsers, you can upload multiple file formats of the same video, such as mp4 and webm.\u003c/p\u003e\u0027,\n tourStepUploadAddInteractionsTitle: \u0027Adding interactions\u0027,\n tourStepUploadAddInteractionsText: \u0027\u003cp\u003eOnce you have added a video, you can start adding interactions.\u003c/p\u003e\u003cp\u003ePress the \u003cem\u003eAdd interactions\u003c/em\u003e tab to get started.\u003c/p\u003e\u0027,\n tourStepCanvasToolbarTitle: \u0027Adding interactions\u0027,\n tourStepCanvasToolbarText: \u0027To add an interaction, drag an element from the toolbar and drop it onto the video.\u0027,\n tourStepCanvasEditingTitle: \u0027Editing interactions\u0027,\n tourStepCanvasEditingText: \u0027\u003cp\u003eOnce an interaction has been added, you can drag to reposition it.\u003c/p\u003e\u003cp\u003eTo resize an interaction, press on the handles and drag.\u003c/p\u003e\u003cp\u003eWhen you select an interaction, a context menu will appear. To edit the content of the interaction, press the Edit button in the context menu. You can remove an interaction by pressing the Remove button on the context menu.\u003c/p\u003e\u0027,\n tourStepCanvasBookmarksTitle: \u0027Bookmarks\u0027,\n tourStepCanvasBookmarksText: \u0027You can add Bookmarks from the Bookmarks menu. Press the Bookmark button to open the menu.\u0027,\n tourStepCanvasPreviewTitle: \u0027Preview your interactive video\u0027,\n tourStepCanvasPreviewText: \u0027Press the Play button to preview your interactive video while editing.\u0027,\n tourStepCanvasSaveTitle: \u0027Save and view\u0027,\n tourStepCanvasSaveText: \"When you\u0027re done adding interactions to your video, press Save/Create to view the result.\",\n tourStepSummaryText: \u0027This optional Summary quiz will appear at the end of the video.\u0027,\n fullScoreRequiredPause: \u0027\"Full score required\" option requires that \"Pause\" is enabled.\u0027,\n fullScoreRequiredRetry: \u0027\"Full score required\" option requires that \"Retry\" is enabled\u0027,\n fullScoreRequiredTimeFrame: \u0027There already exists an interaction that requires full score at the same interval as this interaction.\u003cbr\u003e Only one of the interactions will be required to answer.\u0027\n }\n};\n"
,"Scripts/guided-tours.js":"H5PEditor.InteractiveVideo.GuidedTours = (function ($) {\n\n // Shorthand for translate function:\n var t = H5PEditor.InteractiveVideo.t;\n\n var currentTourId;\n\n /**\n * @class H5PEditor.InteractiveVideo.GuidedTours\n */\n function GuidedTours () {}\n\n /**\n * Defines the different tours in IV\n * @return {Array}\n */\n GuidedTours.setup = function () {\n\n if (GuidedTours.tours === undefined) {\n GuidedTours.tours = [\n // Upload video tab\n {\n steps: [\n {\n text: t(\u0027tourStepUploadIntroText\u0027),\n attachTo: {element: \u0027.field.wizard .h5peditor-label\u0027, on: \u0027bottom\u0027},\n noArrow: true\n },\n {\n title: t(\u0027tourStepUploadFileTitle\u0027),\n text: t(\u0027tourStepUploadFileText\u0027),\n attachTo: {element: \u0027.field.video .h5p-add-file\u0027, on: \u0027left\u0027},\n highlightElement: true\n },\n {\n title: t(\u0027tourStepUploadAddInteractionsTitle\u0027),\n text: t(\u0027tourStepUploadAddInteractionsText\u0027),\n attachTo: {element: \u0027.h5peditor-tab-assets\u0027, on: \u0027bottom\u0027},\n highlightElement: true\n }\n ],\n options: {\n id: \u0027h5p-editor-interactive-video-initial-v1\u0027\n }\n },\n // Interactions tab\n {\n steps: [\n {\n title: t(\u0027tourStepCanvasToolbarTitle\u0027),\n text: t(\u0027tourStepCanvasToolbarText\u0027),\n attachTo: {element: \u0027.h5peditor-dragnbar\u0027, on: \u0027bottom\u0027},\n highlightElement: true\n },\n {\n title: t(\u0027tourStepCanvasEditingTitle\u0027),\n text: t(\u0027tourStepCanvasEditingText\u0027),\n attachTo: {element: \u0027.h5p-video-wrapper\u0027, on: \u0027center\u0027},\n noArrow: true,\n scrollTo: true\n },\n {\n title: t(\u0027tourStepCanvasBookmarksTitle\u0027),\n text: t(\u0027tourStepCanvasBookmarksText\u0027),\n attachTo: {element: \u0027.h5p-control.h5p-bookmarks\u0027, on: \u0027right\u0027},\n highlightElement: true,\n scrollTo: true\n },\n {\n title: t(\u0027tourStepCanvasPreviewTitle\u0027),\n text: t(\u0027tourStepCanvasPreviewText\u0027),\n attachTo: {element: \u0027.h5p-control.h5p-play\u0027, on: \u0027right\u0027},\n highlightElement: true,\n scrollTo: true\n },\n {\n title: t(\u0027tourStepCanvasSaveTitle\u0027),\n text: t(\u0027tourStepCanvasSaveText\u0027),\n attachTo: {element: \u0027.h5p-video-wrapper\u0027, on: \u0027center\u0027},\n noArrow: true,\n scrollTo: true\n }\n ],\n options: {\n id: \u0027h5p-editor-interactive-video-interactions-v1\u0027\n }\n },\n // Summary tab\n {\n steps: [\n {\n text: t(\u0027tourStepSummaryText\u0027),\n attachTo: {element: \u0027.h5peditor-tabs\u0027, on: \u0027bottom\u0027},\n noArrow: true\n }\n ],\n options: {\n id: \u0027h5p-editor-interactive-video-summary-v1\u0027\n }\n }\n ];\n }\n\n return GuidedTours.tours;\n };\n\n /**\n * Starts a guided tour\n *\n * @method GuidedTours.start\n * @static\n * @param {number} tourId The index of the guide (as defined in the tours array)\n * @param {boolean} force Force displaying the guide (even if it has been displayed before)\n */\n GuidedTours.start = function (tourId, force, t) {\n force = force || false;\n\n var tours = GuidedTours.setup();\n\n if ((tourId \u003c 0 || (tourId+1) \u003e tours.length) ||\n (tourId === currentTourId \u0026\u0026 tours[currentTourId].instance.isOpen())) {\n return;\n }\n\n // Hide guide if another guide is allready present - only one guide at a time\n if (currentTourId !== undefined) {\n tours[currentTourId].instance.hide();\n }\n\n var tour = tours[tourId];\n\n // Add labels:\n tour.options.labels = {\n exit: t(\u0027tourButtonExit\u0027),\n done: t(\u0027tourButtonDone\u0027),\n back: t(\u0027tourButtonBack\u0027),\n next: t(\u0027tourButtonNext\u0027)\n };\n\n if (tour !== undefined) {\n if (tour.instance === undefined) {\n tour.instance = new H5P.GuidedTour(tour.steps, tour.options);\n }\n tour.instance.start(force, function () {\n currentTourId = tourId;\n });\n }\n };\n\n /**\n * Checks if any guided tour is open\n *\n * @method GuidedTours.isOpen\n * @static\n */\n GuidedTours.isOpen = function () {\n if (GuidedTours.tours) {\n for (var i = 0; i \u003c GuidedTours.tours.length; i++) {\n if (GuidedTours.tours[i].instance \u0026\u0026 GuidedTours.tours[i].instance.isOpen()) {\n return true;\n }\n }\n }\n return false;\n };\n\n /**\n * Removes all guided tours\n *\n * @method GuidedTours.remove\n * @static\n */\n GuidedTours.remove = function () {\n for (var i = 0; i \u003c GuidedTours.tours.length; i++) {\n var tour = GuidedTours.tours[i].instance;\n tour \u0026\u0026 tour.destroy();\n }\n };\n\n return GuidedTours;\n})(H5P.jQuery);\n"
,"Scripts/require-completion.js":"/**\n * @class H5PEditor.InteractiveVideo.RequireCompletion\n */\nH5PEditor.InteractiveVideo.RequireCompletion = (function () {\n\n /**\n * Handles the require completion option and the way it affects the interaction\n * and other interactions.\n *\n * @param {H5PEditor.InteractiveVideo} IVEditor\n * @param {Object} interaction\n * @constructor\n */\n function RequireCompletion (IVEditor, interaction) {\n\n // Shorthand for translating texts\n var t = H5PEditor.InteractiveVideo.t;\n\n // Determines if retry is enabled for this interaction\n var enableRetry;\n\n /**\n * Interaction fields gathers all fields of the interaction\n *\n * @type {Object} interactionFields\n * @param {Object} interactionFields.adaptivity\n */\n var interactionFields = IVEditor.getInteractionFields(interaction);\n\n /**\n * A group with adaptivity settings of the interaction\n *\n * @type {Object} adaptivityFields\n * @param {Object} adaptivityFields.requireCompletion\n */\n var adaptivityFields = IVEditor.getInteractionFields(interactionFields.adaptivity);\n\n // Message to show that triggering retry has been disabled\n var enableRetryDisabledMsg = document.createElement(\u0027div\u0027);\n enableRetryDisabledMsg.textContent = t(\u0027fullScoreRequiredRetry\u0027);\n enableRetryDisabledMsg.className = [\n \u0027h5peditor-field-description\u0027,\n \u0027h5peditor-enable-retry-disabled-msg\u0027,\n \u0027h5p-hide\u0027\n ].join(\u0027 \u0027);\n\n // Message to show that triggering pause option has been disabled\n var pauseDisabledMsg = document.createElement(\u0027div\u0027);\n pauseDisabledMsg.textContent = t(\u0027fullScoreRequiredPause\u0027);\n pauseDisabledMsg.className = [\n \u0027h5peditor-field-description\u0027,\n \u0027h5peditor-pause-disabled-msg\u0027,\n \u0027h5p-hide\u0027\n ].join(\u0027 \u0027);\n interactionFields.pause.$item.get(0).appendChild(pauseDisabledMsg);\n\n // Message showing that two interactions have a time conflict\n var conflictingTimeMsg = document.createElement(\u0027div\u0027);\n conflictingTimeMsg.innerHTML = t(\u0027fullScoreRequiredTimeFrame\u0027);\n conflictingTimeMsg.className = [\n \u0027h5peditor-field-description\u0027,\n \u0027h5peditor-conflicting-time-msg\u0027,\n \u0027h5p-hide\u0027\n ].join(\u0027 \u0027);\n\n interactionFields.pause.$item.get(0).parentNode\n .insertBefore(conflictingTimeMsg, interactionFields.pause.$item.get(0).nextSibling);\n\n // Handle behavioural changes of $form when require completion input is changed\n adaptivityFields.requireCompletion.$input.change(function () {\n handleRequireCompletionToggled();\n });\n\n // Check if conflict message should be shown when duration is changed\n interactionFields.duration.$inputs.change(function () {\n toggleDuration(adaptivityFields.requireCompletion.$input[0].checked);\n });\n\n // Check if conflicting message should be shown when dialog is opened\n interaction.on(\u0027openEditDialog\u0027, function () {\n pollForLoadedSemantics(interactionFields);\n });\n\n /**\n * Poll for when semantics of the interaction library has loaded\n */\n function pollForLoadedSemantics(fields) {\n var hasLoaded = fields.action.children;\n\n if (hasLoaded) {\n insertRetryButtonMessage(fields.action);\n handleRequireCompletionToggled();\n }\n else {\n setTimeout(function () {\n pollForLoadedSemantics(fields)\n }, 20);\n }\n }\n\n /**\n * Insert retry button message into the library specific semantics.\n *\n * @param {Object} library Library fields\n */\n function insertRetryButtonMessage(library) {\n var libraryFields = IVEditor.getInteractionFields(library);\n if (!libraryFields.behaviour) {\n return;\n }\n\n var behaviour = IVEditor.getInteractionFields(libraryFields.behaviour);\n enableRetry = behaviour.enableRetry;\n\n if (enableRetry \u0026\u0026 !enableRetryDisabledMsg.parentNode) {\n enableRetry.$item.get(0).parentNode\n .insertBefore(enableRetryDisabledMsg, enableRetry.$item.get(0).nextSibling);\n }\n }\n\n /**\n * If interaction has the require completion option enabled it will\n * search through all other interactions to determine if any of them\n * has a conflicting duration with this interaction, in which case a conflict\n * message will be displayed\n *\n * @param {Object} interaction Interaction that we are interested in checking\n * @param {Array} otherInteractions List of interactions that will be checked\n * for conflicting duration time with given interaction\n */\n function handleConflictingInteractions(interaction, otherInteractions) {\n if (!interaction.getRequiresCompletion()) {\n return;\n }\n\n var conflictingInteractions = getConflictingInteractions(interaction, otherInteractions);\n conflictingTimeMsg.classList.toggle(\u0027h5p-hide\u0027, !conflictingInteractions.length);\n }\n\n /**\n * Checks if an interaction is at a given time interval\n *\n * @param {Object} time Time we are comparing against\n * @param {number} time.from Showing from\n * @param {number} time.to End of the interval we are checking\n * @param {Object} interaction Interaction time interval\n *\n * @return {boolean} Returns true if the interaction starts or ends within\n * the given interval\n */\n function hasDurationWithin(time, interaction) {\n var duration = interaction.getDuration();\n return time.from \u003e= duration.from \u0026\u0026 time.from \u003c= duration.to\n || time.to \u003e= duration.from \u0026\u0026 time.to \u003c= duration.to;\n }\n\n /**\n * Checks if an interaction requires completion\n *\n * @param {Object} interaction Interaction that we are checking the settings of\n * @return {boolean} Returns true if the interaction requires completion\n */\n function hasRequireCompletion(interaction) {\n return interaction.getRequiresCompletion()\n }\n\n /**\n * Checks if an interaction has conflicting interval time with other interactions\n *\n * @param {Object} interaction Interaction we are checking\n * @param {Array} allInteractions Interactions that we are checking for conflicts\n * @return {Array} List of conflicting interactions\n */\n function getConflictingInteractions(interaction, allInteractions) {\n return allInteractions\n .filter(hasDurationWithin.bind(this, interaction.getDuration()))\n .filter(hasRequireCompletion)\n .filter(function (ia) {\n return ia !== interaction;\n });\n }\n\n /**\n * Checks the state of require completion checkbox and toggles messages\n * and disabled states of buttons accordingly\n */\n function handleRequireCompletionToggled() {\n var isChecked = adaptivityFields.requireCompletion.$input[0].checked;\n togglePause(isChecked);\n toggleRetry(isChecked);\n toggleDuration(isChecked);\n }\n\n /**\n * Toggles message for conflicting interval times of interactions\n *\n * @param {boolean} isChecked Require completion option checked state\n */\n function toggleDuration(isChecked) {\n if (!isChecked) {\n conflictingTimeMsg.classList.add(\u0027h5p-hide\u0027);\n return;\n }\n\n handleConflictingInteractions(interaction, IVEditor.IV.interactions);\n }\n\n /**\n * Toggles message and button state for pause option of interaction\n *\n * @param {boolean} isChecked Require completion option checked state\n */\n function togglePause(isChecked) {\n toggleBoolean(interactionFields.pause, isChecked);\n interactionFields.pause.$item.toggleClass(\u0027h5p-has-disabled-msg\u0027, isChecked);\n pauseDisabledMsg.classList.toggle(\u0027h5p-hide\u0027, !isChecked);\n }\n\n /**\n * Toggles message and button state for enable retry option of interaction\n *\n * @param {boolean} isChecked Require completion option checked state\n */\n function toggleRetry(isChecked) {\n if (enableRetry) {\n toggleBoolean(enableRetry, isChecked);\n enableRetryDisabledMsg.classList.toggle(\u0027h5p-hide\u0027, !isChecked);\n }\n }\n\n /**\n * Toggles a boolean semantics field and its disabled state\n *\n * @param {Object} boolean A boolean semantics field\n * @param {boolean} enable Require completion option checked state\n */\n function toggleBoolean(boolean, enable) {\n if (enable) {\n boolean.$input[0].checked = true;\n boolean.$input.trigger(\u0027change\u0027);\n }\n boolean.$input.attr(\u0027disabled\u0027, enable);\n }\n }\n\n return RequireCompletion;\n})();\n"
},"css": {"styles/h5p-font-icons.css":"@font-face {\n font-family: \u0027H5PFontIcons\u0027;\n src: url(\u0027../H5P/libraries/H5P.FontIcons-1.0/fonts/h5p.eot?w3m2qr\u0027);\n src: url(\u0027../H5P/libraries/H5P.FontIcons-1.0/fonts/h5p.eot?w3m2qr#iefix\u0027) format(\u0027embedded-opentype\u0027),\n url(\u0027../H5P/libraries/H5P.FontIcons-1.0/fonts/h5p.ttf?w3m2qr\u0027) format(\u0027truetype\u0027),\n url(\u0027../H5P/libraries/H5P.FontIcons-1.0/fonts/h5p.woff?w3m2qr\u0027) format(\u0027woff\u0027),\n url(\u0027../H5P/libraries/H5P.FontIcons-1.0/fonts/h5p.svg?w3m2qr#H5PFontIcons\u0027) format(\u0027svg\u0027);\n font-weight: normal;\n font-style: normal;\n}\n","Styles/Wizard.css":".field.wizard \u003e .h5peditor-label-wrapper {\n display: none;\n}\n.field.wizard \u003e .h5peditor-tabs {\n display: table;\n table-layout: fixed;\n width: 100%;\n margin: 0;\n padding: 0;\n}\nol.h5peditor-tabs {\n counter-reset: li;\n}\nol.h5peditor-tabs \u003e li.h5peditor-tab-li {\n list-style-type: none;\n position: relative;\n}\n.field.wizard .h5peditor-tab-li {\n padding: 0;\n position: relative;\n display: table-cell;\n line-height: initial;\n}\n.field.wizard .h5peditor-tab-a {\n display: block;\n position: relative;\n background: #e3e3e3;\n margin-right: 1px;\n padding: 11px 15px;\n color: #737373;\n}\n.field.wizard .h5peditor-tab-a span {\n display: block;\n padding-left: 45px;\n line-height: 1.5em;\n}\n.field.wizard .h5peditor-tab-a .field-step {\n font-size: 0.6em;\n font-style: italic;\n color: #757575;\n}\n\n/* Make the step field white on guided tour */\n.field.wizard .h5peditor-tab-a.shepherd-enabled .field-step {\n color: white;\n}\n\n.field.wizard .h5peditor-tab-a:before {\n font-family: \u0027H5PFontIcons\u0027;\n position: absolute;\n content: \"?\";\n font-size: 2em;\n}\n.field.wizard .h5peditor-tab-a:hover {\n background: #eaeaea;\n text-decoration: none;\n}\n.field.wizard .h5peditor-tab-a:focus {\n box-shadow: none;\n}\n.field.wizard .h5peditor-tab-a:hover:before,\n.field.wizard .h5peditor-tab-a:hover:after {\n border-top-color: #ddd;\n border-bottom-color: #ddd;\n}\n.field.wizard .h5peditor-tab-a:hover:after {\n border-top-color: transparent;\n border-bottom-color: transparent;\n border-left-color: #ddd;\n}\n.field.wizard .h5peditor-tab-a .field-name {\n font-weight: 600;\n font-size: 0.9em;\n width: 100%;\n}\n.field.wizard .h5peditor-tab-li:first-child \u003e .h5peditor-tab-a:before,\n.field.wizard .h5peditor-tab-li:last-child \u003e .h5peditor-tab-a:after {\n border: 0;\n}\n.field.wizard .h5peditor-tab-li:last-child \u003e .h5peditor-tab-a {\n margin-right: 0;\n}\n.field.wizard .h5peditor-tab-a.h5peditor-active {\n background: #ffffff;\n cursor: default;\n color: #444\n}\n.field.wizard .h5peditor-tab-a.h5peditor-active:before {\n border-top-color: #e8e8e8;\n border-bottom-color: #e8e8e8;\n color: #3aa2ec;\n}\n.field.wizard .h5peditor-tab-a.h5peditor-active:after {\n border-left-color: #e8e8e8;\n}\n.field.wizard .h5peditor-tab-a.h5peditor-active:hover:after {\n border-top-color: transparent;\n border-bottom-color: transparent;\n}\n.field.wizard \u003e .h5peditor-panes \u003e .group {\n background-color: transparent;\n box-shadow: none;\n border: 0px;\n display: block;\n}\n.field.wizard \u003e .h5peditor-panes \u003e .group \u003e .title {\n display: none;\n}\n.field.wizard \u003e .h5peditor-panes \u003e .group \u003e .content {\n display: block;\n}\n.field.wizard \u003e .h5peditor-panes \u003e .field {\n margin: 0;\n}\n.field.wizard .h5peditor-wizard-navigation-buttons {\n display: table;\n width: 100%;\n background-color: #e3e3e3;\n margin-bottom: 20px;\n font-size: 17px;\n line-height: initial;\n}\n.field.wizard .h5peditor-wizard-navigation-buttons:after {\n clear: both;\n content: \"\";\n display: block;\n}\n.field.wizard .h5peditor-wizard-navigation-buttons span {\n display: block;\n vertical-align: middle;\n}\n.field.wizard .h5peditor-wizard-navigation-buttons div div span:first-child {\n font-style: italic;\n color: #757575;\n}\n.field.wizard .h5peditor-wizard-navigation-buttons .nav-button-icon {\n display: table-cell;\n padding: 0.5em 0.75em;\n vertical-align: middle;\n font-size: 0.8em;\n font-weight: bold;\n}\n.field.wizard .h5peditor-wizard-navigation-buttons .nav-button-icon:before {\n font-family: \u0027H5PFontAwesome4\u0027;\n}\n.field.wizard .h5peditor-wizard-navigation-buttons .nav-button-prev .nav-button-icon:before {\n content: \"\\f104\";\n}\n.field.wizard .h5peditor-wizard-navigation-buttons .nav-button-next .nav-button-icon:before {\n content: \"\\f105\";\n}\n.field.wizard .h5peditor-wizard-navigation-buttons \u003e div {\n background: #fdfdfd;\n background: linear-gradient(#fdfdfd, #f3f3f3);\n border: 1px solid #d0d0d1;\n border-radius: 5px;\n margin: 0.5em;\n cursor: pointer;\n -webkit-user-select: none; /* Safari */\n -moz-user-select: none; /* Firefox */\n -ms-user-select: none; /* Internet Explorer/Edge */\n user-select: none;\n}\n.field.wizard .h5peditor-wizard-navigation-buttons \u003e div:hover {\n background: linear-gradient(to bottom, #fff 0, #d0d0d1 100%);\n border-color: #999;\n}\n.field.wizard .h5peditor-wizard-navigation-buttons \u003e div div {\n padding: 0.45em 0.7em;\n display: table-cell;\n}\n.field.wizard .h5peditor-wizard-navigation-buttons \u003e div div span:first-child {\n font-size: 0.625em;\n}\n.field.wizard .h5peditor-wizard-navigation-buttons \u003e div div .nav-button-label {\n font-size: 0.75em;\n}\n.field.wizard .h5peditor-wizard-navigation-buttons .nav-button-label:before {\n font-family: \u0027H5PFontIcons\u0027;\n content: \"?\";\n font-size: 1.3em;\n color: #737373;\n padding-right: 0.1em;\n top: 0.075em;\n left: -0.1em;\n position: relative;\n}\n.field.wizard .nav-button-prev {\n float: left;\n}\n.field.wizard .nav-button-next {\n float: right;\n}\n.field.wizard .nav-button-prev \u003e div {\n border-left: 1px solid #d0d0d1;\n}\n.field.wizard .nav-button-next \u003e div {\n border-right: 1px solid #d0d0d1;\n}\n","h5p-font-awesome.min.css":"/*!\n * Font Awesome 4.5.0 by @davegandy - http://fontawesome.io - @fontawesome\n * License - http://fontawesome.io/license (Font: SIL OFL 1.1, CSS: MIT License)\n */@font-face{font-family:\u0027H5PFontAwesome4\u0027;src:url(\u0027../H5P/libraries/FontAwesome-4.5/fontawesome-webfont.eot?v=4.5.0\u0027);src:url(\u0027../H5P/libraries/FontAwesome-4.5/fontawesome-webfont.eot?#iefix\u0026v=4.5.0\u0027) format(\u0027embedded-opentype\u0027),url(\u0027../H5P/libraries/FontAwesome-4.5/fontawesome-webfont.woff2?v=4.5.0\u0027) format(\u0027woff2\u0027),url(\u0027../H5P/libraries/FontAwesome-4.5/fontawesome-webfont.woff?v=4.5.0\u0027) format(\u0027woff\u0027),url(\u0027../H5P/libraries/FontAwesome-4.5/fontawesome-webfont.ttf?v=4.5.0\u0027) format(\u0027truetype\u0027),url(\u0027../H5P/libraries/FontAwesome-4.5/fontawesome-webfont.svg?v=4.5.0#fontawesomeregular\u0027) format(\u0027svg\u0027);font-weight:normal;font-style:normal}.fa{display:inline-block;font:normal normal normal 14px/1 H5PFontAwesome4;font-size:inherit;text-rendering:auto;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.fa-lg{font-size:1.33333333em;line-height:.75em;vertical-align:-15%}.fa-2x{font-size:2em}.fa-3x{font-size:3em}.fa-4x{font-size:4em}.fa-5x{font-size:5em}.fa-fw{width:1.28571429em;text-align:center}.fa-ul{padding-left:0;margin-left:2.14285714em;list-style-type:none}.fa-ul\u003eli{position:relative}.fa-li{position:absolute;left:-2.14285714em;width:2.14285714em;top:.14285714em;text-align:center}.fa-li.fa-lg{left:-1.85714286em}.fa-border{padding:.2em .25em .15em;border:solid .08em #eee;border-radius:.1em}.fa-pull-left{float:left}.fa-pull-right{float:right}.fa.fa-pull-left{margin-right:.3em}.fa.fa-pull-right{margin-left:.3em}.pull-right{float:right}.pull-left{float:left}.fa.pull-left{margin-right:.3em}.fa.pull-right{margin-left:.3em}.fa-spin{-webkit-animation:fa-spin 2s infinite linear;animation:fa-spin 2s infinite linear}.fa-pulse{-webkit-animation:fa-spin 1s infinite steps(8);animation:fa-spin 1s infinite steps(8)}@-webkit-keyframes fa-spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes fa-spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}.fa-rotate-90{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=1);-webkit-transform:rotate(90deg);-ms-transform:rotate(90deg);transform:rotate(90deg)}.fa-rotate-180{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=2);-webkit-transform:rotate(180deg);-ms-transform:rotate(180deg);transform:rotate(180deg)}.fa-rotate-270{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=3);-webkit-transform:rotate(270deg);-ms-transform:rotate(270deg);transform:rotate(270deg)}.fa-flip-horizontal{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=0, mirror=1);-webkit-transform:scale(-1, 1);-ms-transform:scale(-1, 1);transform:scale(-1, 1)}.fa-flip-vertical{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=2, mirror=1);-webkit-transform:scale(1, -1);-ms-transform:scale(1, -1);transform:scale(1, -1)}:root .fa-rotate-90,:root .fa-rotate-180,:root .fa-rotate-270,:root .fa-flip-horizontal,:root .fa-flip-vertical{filter:none}.fa-stack{position:relative;display:inline-block;width:2em;height:2em;line-height:2em;vertical-align:middle}.fa-stack-1x,.fa-stack-2x{position:absolute;left:0;width:100%;text-align:center}.fa-stack-1x{line-height:inherit}.fa-stack-2x{font-size:2em}.fa-inverse{color:#fff}.fa-glass:before{content:\"\\f000\"}.fa-music:before{content:\"\\f001\"}.fa-search:before{content:\"\\f002\"}.fa-envelope-o:before{content:\"\\f003\"}.fa-heart:before{content:\"\\f004\"}.fa-star:before{content:\"\\f005\"}.fa-star-o:before{content:\"\\f006\"}.fa-user:before{content:\"\\f007\"}.fa-film:before{content:\"\\f008\"}.fa-th-large:before{content:\"\\f009\"}.fa-th:before{content:\"\\f00a\"}.fa-th-list:before{content:\"\\f00b\"}.fa-check:before{content:\"\\f00c\"}.fa-remove:before,.fa-close:before,.fa-times:before{content:\"\\f00d\"}.fa-search-plus:before{content:\"\\f00e\"}.fa-search-minus:before{content:\"\\f010\"}.fa-power-off:before{content:\"\\f011\"}.fa-signal:before{content:\"\\f012\"}.fa-gear:before,.fa-cog:before{content:\"\\f013\"}.fa-trash-o:before{content:\"\\f014\"}.fa-home:before{content:\"\\f015\"}.fa-file-o:before{content:\"\\f016\"}.fa-clock-o:before{content:\"\\f017\"}.fa-road:before{content:\"\\f018\"}.fa-download:before{content:\"\\f019\"}.fa-arrow-circle-o-down:before{content:\"\\f01a\"}.fa-arrow-circle-o-up:before{content:\"\\f01b\"}.fa-inbox:before{content:\"\\f01c\"}.fa-play-circle-o:before{content:\"\\f01d\"}.fa-rotate-right:before,.fa-repeat:before{content:\"\\f01e\"}.fa-refresh:before{content:\"\\f021\"}.fa-list-alt:before{content:\"\\f022\"}.fa-lock:before{content:\"\\f023\"}.fa-flag:before{content:\"\\f024\"}.fa-headphones:before{content:\"\\f025\"}.fa-volume-off:before{content:\"\\f026\"}.fa-volume-down:before{content:\"\\f027\"}.fa-volume-up:before{content:\"\\f028\"}.fa-qrcode:before{content:\"\\f029\"}.fa-barcode:before{content:\"\\f02a\"}.fa-tag:before{content:\"\\f02b\"}.fa-tags:before{content:\"\\f02c\"}.fa-book:before{content:\"\\f02d\"}.fa-bookmark:before{content:\"\\f02e\"}.fa-print:before{content:\"\\f02f\"}.fa-camera:before{content:\"\\f030\"}.fa-font:before{content:\"\\f031\"}.fa-bold:before{content:\"\\f032\"}.fa-italic:before{content:\"\\f033\"}.fa-text-height:before{content:\"\\f034\"}.fa-text-width:before{content:\"\\f035\"}.fa-align-left:before{content:\"\\f036\"}.fa-align-center:before{content:\"\\f037\"}.fa-align-right:before{content:\"\\f038\"}.fa-align-justify:before{content:\"\\f039\"}.fa-list:before{content:\"\\f03a\"}.fa-dedent:before,.fa-outdent:before{content:\"\\f03b\"}.fa-indent:before{content:\"\\f03c\"}.fa-video-camera:before{content:\"\\f03d\"}.fa-photo:before,.fa-image:before,.fa-picture-o:before{content:\"\\f03e\"}.fa-pencil:before{content:\"\\f040\"}.fa-map-marker:before{content:\"\\f041\"}.fa-adjust:before{content:\"\\f042\"}.fa-tint:before{content:\"\\f043\"}.fa-edit:before,.fa-pencil-square-o:before{content:\"\\f044\"}.fa-share-square-o:before{content:\"\\f045\"}.fa-check-square-o:before{content:\"\\f046\"}.fa-arrows:before{content:\"\\f047\"}.fa-step-backward:before{content:\"\\f048\"}.fa-fast-backward:before{content:\"\\f049\"}.fa-backward:before{content:\"\\f04a\"}.fa-play:before{content:\"\\f04b\"}.fa-pause:before{content:\"\\f04c\"}.fa-stop:before{content:\"\\f04d\"}.fa-forward:before{content:\"\\f04e\"}.fa-fast-forward:before{content:\"\\f050\"}.fa-step-forward:before{content:\"\\f051\"}.fa-eject:before{content:\"\\f052\"}.fa-chevron-left:before{content:\"\\f053\"}.fa-chevron-right:before{content:\"\\f054\"}.fa-plus-circle:before{content:\"\\f055\"}.fa-minus-circle:before{content:\"\\f056\"}.fa-times-circle:before{content:\"\\f057\"}.fa-check-circle:before{content:\"\\f058\"}.fa-question-circle:before{content:\"\\f059\"}.fa-info-circle:before{content:\"\\f05a\"}.fa-crosshairs:before{content:\"\\f05b\"}.fa-times-circle-o:before{content:\"\\f05c\"}.fa-check-circle-o:before{content:\"\\f05d\"}.fa-ban:before{content:\"\\f05e\"}.fa-arrow-left:before{content:\"\\f060\"}.fa-arrow-right:before{content:\"\\f061\"}.fa-arrow-up:before{content:\"\\f062\"}.fa-arrow-down:before{content:\"\\f063\"}.fa-mail-forward:before,.fa-share:before{content:\"\\f064\"}.fa-expand:before{content:\"\\f065\"}.fa-compress:before{content:\"\\f066\"}.fa-plus:before{content:\"\\f067\"}.fa-minus:before{content:\"\\f068\"}.fa-asterisk:before{content:\"\\f069\"}.fa-exclamation-circle:before{content:\"\\f06a\"}.fa-gift:before{content:\"\\f06b\"}.fa-leaf:before{content:\"\\f06c\"}.fa-fire:before{content:\"\\f06d\"}.fa-eye:before{content:\"\\f06e\"}.fa-eye-slash:before{content:\"\\f070\"}.fa-warning:before,.fa-exclamation-triangle:before{content:\"\\f071\"}.fa-plane:before{content:\"\\f072\"}.fa-calendar:before{content:\"\\f073\"}.fa-random:before{content:\"\\f074\"}.fa-comment:before{content:\"\\f075\"}.fa-magnet:before{content:\"\\f076\"}.fa-chevron-up:before{content:\"\\f077\"}.fa-chevron-down:before{content:\"\\f078\"}.fa-retweet:before{content:\"\\f079\"}.fa-shopping-cart:before{content:\"\\f07a\"}.fa-folder:before{content:\"\\f07b\"}.fa-folder-open:before{content:\"\\f07c\"}.fa-arrows-v:before{content:\"\\f07d\"}.fa-arrows-h:before{content:\"\\f07e\"}.fa-bar-chart-o:before,.fa-bar-chart:before{content:\"\\f080\"}.fa-twitter-square:before{content:\"\\f081\"}.fa-facebook-square:before{content:\"\\f082\"}.fa-camera-retro:before{content:\"\\f083\"}.fa-key:before{content:\"\\f084\"}.fa-gears:before,.fa-cogs:before{content:\"\\f085\"}.fa-comments:before{content:\"\\f086\"}.fa-thumbs-o-up:before{content:\"\\f087\"}.fa-thumbs-o-down:before{content:\"\\f088\"}.fa-star-half:before{content:\"\\f089\"}.fa-heart-o:before{content:\"\\f08a\"}.fa-sign-out:before{content:\"\\f08b\"}.fa-linkedin-square:before{content:\"\\f08c\"}.fa-thumb-tack:before{content:\"\\f08d\"}.fa-external-link:before{content:\"\\f08e\"}.fa-sign-in:before{content:\"\\f090\"}.fa-trophy:before{content:\"\\f091\"}.fa-github-square:before{content:\"\\f092\"}.fa-upload:before{content:\"\\f093\"}.fa-lemon-o:before{content:\"\\f094\"}.fa-phone:before{content:\"\\f095\"}.fa-square-o:before{content:\"\\f096\"}.fa-bookmark-o:before{content:\"\\f097\"}.fa-phone-square:before{content:\"\\f098\"}.fa-twitter:before{content:\"\\f099\"}.fa-facebook-f:before,.fa-facebook:before{content:\"\\f09a\"}.fa-github:before{content:\"\\f09b\"}.fa-unlock:before{content:\"\\f09c\"}.fa-credit-card:before{content:\"\\f09d\"}.fa-feed:before,.fa-rss:before{content:\"\\f09e\"}.fa-hdd-o:before{content:\"\\f0a0\"}.fa-bullhorn:before{content:\"\\f0a1\"}.fa-bell:before{content:\"\\f0f3\"}.fa-certificate:before{content:\"\\f0a3\"}.fa-hand-o-right:before{content:\"\\f0a4\"}.fa-hand-o-left:before{content:\"\\f0a5\"}.fa-hand-o-up:before{content:\"\\f0a6\"}.fa-hand-o-down:before{content:\"\\f0a7\"}.fa-arrow-circle-left:before{content:\"\\f0a8\"}.fa-arrow-circle-right:before{content:\"\\f0a9\"}.fa-arrow-circle-up:before{content:\"\\f0aa\"}.fa-arrow-circle-down:before{content:\"\\f0ab\"}.fa-globe:before{content:\"\\f0ac\"}.fa-wrench:before{content:\"\\f0ad\"}.fa-tasks:before{content:\"\\f0ae\"}.fa-filter:before{content:\"\\f0b0\"}.fa-briefcase:before{content:\"\\f0b1\"}.fa-arrows-alt:before{content:\"\\f0b2\"}.fa-group:before,.fa-users:before{content:\"\\f0c0\"}.fa-chain:before,.fa-link:before{content:\"\\f0c1\"}.fa-cloud:before{content:\"\\f0c2\"}.fa-flask:before{content:\"\\f0c3\"}.fa-cut:before,.fa-scissors:before{content:\"\\f0c4\"}.fa-copy:before,.fa-files-o:before{content:\"\\f0c5\"}.fa-paperclip:before{content:\"\\f0c6\"}.fa-save:before,.fa-floppy-o:before{content:\"\\f0c7\"}.fa-square:before{content:\"\\f0c8\"}.fa-navicon:before,.fa-reorder:before,.fa-bars:before{content:\"\\f0c9\"}.fa-list-ul:before{content:\"\\f0ca\"}.fa-list-ol:before{content:\"\\f0cb\"}.fa-strikethrough:before{content:\"\\f0cc\"}.fa-underline:before{content:\"\\f0cd\"}.fa-table:before{content:\"\\f0ce\"}.fa-magic:before{content:\"\\f0d0\"}.fa-truck:before{content:\"\\f0d1\"}.fa-pinterest:before{content:\"\\f0d2\"}.fa-pinterest-square:before{content:\"\\f0d3\"}.fa-google-plus-square:before{content:\"\\f0d4\"}.fa-google-plus:before{content:\"\\f0d5\"}.fa-money:before{content:\"\\f0d6\"}.fa-caret-down:before{content:\"\\f0d7\"}.fa-caret-up:before{content:\"\\f0d8\"}.fa-caret-left:before{content:\"\\f0d9\"}.fa-caret-right:before{content:\"\\f0da\"}.fa-columns:before{content:\"\\f0db\"}.fa-unsorted:before,.fa-sort:before{content:\"\\f0dc\"}.fa-sort-down:before,.fa-sort-desc:before{content:\"\\f0dd\"}.fa-sort-up:before,.fa-sort-asc:before{content:\"\\f0de\"}.fa-envelope:before{content:\"\\f0e0\"}.fa-linkedin:before{content:\"\\f0e1\"}.fa-rotate-left:before,.fa-undo:before{content:\"\\f0e2\"}.fa-legal:before,.fa-gavel:before{content:\"\\f0e3\"}.fa-dashboard:before,.fa-tachometer:before{content:\"\\f0e4\"}.fa-comment-o:before{content:\"\\f0e5\"}.fa-comments-o:before{content:\"\\f0e6\"}.fa-flash:before,.fa-bolt:before{content:\"\\f0e7\"}.fa-sitemap:before{content:\"\\f0e8\"}.fa-umbrella:before{content:\"\\f0e9\"}.fa-paste:before,.fa-clipboard:before{content:\"\\f0ea\"}.fa-lightbulb-o:before{content:\"\\f0eb\"}.fa-exchange:before{content:\"\\f0ec\"}.fa-cloud-download:before{content:\"\\f0ed\"}.fa-cloud-upload:before{content:\"\\f0ee\"}.fa-user-md:before{content:\"\\f0f0\"}.fa-stethoscope:before{content:\"\\f0f1\"}.fa-suitcase:before{content:\"\\f0f2\"}.fa-bell-o:before{content:\"\\f0a2\"}.fa-coffee:before{content:\"\\f0f4\"}.fa-cutlery:before{content:\"\\f0f5\"}.fa-file-text-o:before{content:\"\\f0f6\"}.fa-building-o:before{content:\"\\f0f7\"}.fa-hospital-o:before{content:\"\\f0f8\"}.fa-ambulance:before{content:\"\\f0f9\"}.fa-medkit:before{content:\"\\f0fa\"}.fa-fighter-jet:before{content:\"\\f0fb\"}.fa-beer:before{content:\"\\f0fc\"}.fa-h-square:before{content:\"\\f0fd\"}.fa-plus-square:before{content:\"\\f0fe\"}.fa-angle-double-left:before{content:\"\\f100\"}.fa-angle-double-right:before{content:\"\\f101\"}.fa-angle-double-up:before{content:\"\\f102\"}.fa-angle-double-down:before{content:\"\\f103\"}.fa-angle-left:before{content:\"\\f104\"}.fa-angle-right:before{content:\"\\f105\"}.fa-angle-up:before{content:\"\\f106\"}.fa-angle-down:before{content:\"\\f107\"}.fa-desktop:before{content:\"\\f108\"}.fa-laptop:before{content:\"\\f109\"}.fa-tablet:before{content:\"\\f10a\"}.fa-mobile-phone:before,.fa-mobile:before{content:\"\\f10b\"}.fa-circle-o:before{content:\"\\f10c\"}.fa-quote-left:before{content:\"\\f10d\"}.fa-quote-right:before{content:\"\\f10e\"}.fa-spinner:before{content:\"\\f110\"}.fa-circle:before{content:\"\\f111\"}.fa-mail-reply:before,.fa-reply:before{content:\"\\f112\"}.fa-github-alt:before{content:\"\\f113\"}.fa-folder-o:before{content:\"\\f114\"}.fa-folder-open-o:before{content:\"\\f115\"}.fa-smile-o:before{content:\"\\f118\"}.fa-frown-o:before{content:\"\\f119\"}.fa-meh-o:before{content:\"\\f11a\"}.fa-gamepad:before{content:\"\\f11b\"}.fa-keyboard-o:before{content:\"\\f11c\"}.fa-flag-o:before{content:\"\\f11d\"}.fa-flag-checkered:before{content:\"\\f11e\"}.fa-terminal:before{content:\"\\f120\"}.fa-code:before{content:\"\\f121\"}.fa-mail-reply-all:before,.fa-reply-all:before{content:\"\\f122\"}.fa-star-half-empty:before,.fa-star-half-full:before,.fa-star-half-o:before{content:\"\\f123\"}.fa-location-arrow:before{content:\"\\f124\"}.fa-crop:before{content:\"\\f125\"}.fa-code-fork:before{content:\"\\f126\"}.fa-unlink:before,.fa-chain-broken:before{content:\"\\f127\"}.fa-question:before{content:\"\\f128\"}.fa-info:before{content:\"\\f129\"}.fa-exclamation:before{content:\"\\f12a\"}.fa-superscript:before{content:\"\\f12b\"}.fa-subscript:before{content:\"\\f12c\"}.fa-eraser:before{content:\"\\f12d\"}.fa-puzzle-piece:before{content:\"\\f12e\"}.fa-microphone:before{content:\"\\f130\"}.fa-microphone-slash:before{content:\"\\f131\"}.fa-shield:before{content:\"\\f132\"}.fa-calendar-o:before{content:\"\\f133\"}.fa-fire-extinguisher:before{content:\"\\f134\"}.fa-rocket:before{content:\"\\f135\"}.fa-maxcdn:before{content:\"\\f136\"}.fa-chevron-circle-left:before{content:\"\\f137\"}.fa-chevron-circle-right:before{content:\"\\f138\"}.fa-chevron-circle-up:before{content:\"\\f139\"}.fa-chevron-circle-down:before{content:\"\\f13a\"}.fa-html5:before{content:\"\\f13b\"}.fa-css3:before{content:\"\\f13c\"}.fa-anchor:before{content:\"\\f13d\"}.fa-unlock-alt:before{content:\"\\f13e\"}.fa-bullseye:before{content:\"\\f140\"}.fa-ellipsis-h:before{content:\"\\f141\"}.fa-ellipsis-v:before{content:\"\\f142\"}.fa-rss-square:before{content:\"\\f143\"}.fa-play-circle:before{content:\"\\f144\"}.fa-ticket:before{content:\"\\f145\"}.fa-minus-square:before{content:\"\\f146\"}.fa-minus-square-o:before{content:\"\\f147\"}.fa-level-up:before{content:\"\\f148\"}.fa-level-down:before{content:\"\\f149\"}.fa-check-square:before{content:\"\\f14a\"}.fa-pencil-square:before{content:\"\\f14b\"}.fa-external-link-square:before{content:\"\\f14c\"}.fa-share-square:before{content:\"\\f14d\"}.fa-compass:before{content:\"\\f14e\"}.fa-toggle-down:before,.fa-caret-square-o-down:before{content:\"\\f150\"}.fa-toggle-up:before,.fa-caret-square-o-up:before{content:\"\\f151\"}.fa-toggle-right:before,.fa-caret-square-o-right:before{content:\"\\f152\"}.fa-euro:before,.fa-eur:before{content:\"\\f153\"}.fa-gbp:before{content:\"\\f154\"}.fa-dollar:before,.fa-usd:before{content:\"\\f155\"}.fa-rupee:before,.fa-inr:before{content:\"\\f156\"}.fa-cny:before,.fa-rmb:before,.fa-yen:before,.fa-jpy:before{content:\"\\f157\"}.fa-ruble:before,.fa-rouble:before,.fa-rub:before{content:\"\\f158\"}.fa-won:before,.fa-krw:before{content:\"\\f159\"}.fa-bitcoin:before,.fa-btc:before{content:\"\\f15a\"}.fa-file:before{content:\"\\f15b\"}.fa-file-text:before{content:\"\\f15c\"}.fa-sort-alpha-asc:before{content:\"\\f15d\"}.fa-sort-alpha-desc:before{content:\"\\f15e\"}.fa-sort-amount-asc:before{content:\"\\f160\"}.fa-sort-amount-desc:before{content:\"\\f161\"}.fa-sort-numeric-asc:before{content:\"\\f162\"}.fa-sort-numeric-desc:before{content:\"\\f163\"}.fa-thumbs-up:before{content:\"\\f164\"}.fa-thumbs-down:before{content:\"\\f165\"}.fa-youtube-square:before{content:\"\\f166\"}.fa-youtube:before{content:\"\\f167\"}.fa-xing:before{content:\"\\f168\"}.fa-xing-square:before{content:\"\\f169\"}.fa-youtube-play:before{content:\"\\f16a\"}.fa-dropbox:before{content:\"\\f16b\"}.fa-stack-overflow:before{content:\"\\f16c\"}.fa-instagram:before{content:\"\\f16d\"}.fa-flickr:before{content:\"\\f16e\"}.fa-adn:before{content:\"\\f170\"}.fa-bitbucket:before{content:\"\\f171\"}.fa-bitbucket-square:before{content:\"\\f172\"}.fa-tumblr:before{content:\"\\f173\"}.fa-tumblr-square:before{content:\"\\f174\"}.fa-long-arrow-down:before{content:\"\\f175\"}.fa-long-arrow-up:before{content:\"\\f176\"}.fa-long-arrow-left:before{content:\"\\f177\"}.fa-long-arrow-right:before{content:\"\\f178\"}.fa-apple:before{content:\"\\f179\"}.fa-windows:before{content:\"\\f17a\"}.fa-android:before{content:\"\\f17b\"}.fa-linux:before{content:\"\\f17c\"}.fa-dribbble:before{content:\"\\f17d\"}.fa-skype:before{content:\"\\f17e\"}.fa-foursquare:before{content:\"\\f180\"}.fa-trello:before{content:\"\\f181\"}.fa-female:before{content:\"\\f182\"}.fa-male:before{content:\"\\f183\"}.fa-gittip:before,.fa-gratipay:before{content:\"\\f184\"}.fa-sun-o:before{content:\"\\f185\"}.fa-moon-o:before{content:\"\\f186\"}.fa-archive:before{content:\"\\f187\"}.fa-bug:before{content:\"\\f188\"}.fa-vk:before{content:\"\\f189\"}.fa-weibo:before{content:\"\\f18a\"}.fa-renren:before{content:\"\\f18b\"}.fa-pagelines:before{content:\"\\f18c\"}.fa-stack-exchange:before{content:\"\\f18d\"}.fa-arrow-circle-o-right:before{content:\"\\f18e\"}.fa-arrow-circle-o-left:before{content:\"\\f190\"}.fa-toggle-left:before,.fa-caret-square-o-left:before{content:\"\\f191\"}.fa-dot-circle-o:before{content:\"\\f192\"}.fa-wheelchair:before{content:\"\\f193\"}.fa-vimeo-square:before{content:\"\\f194\"}.fa-turkish-lira:before,.fa-try:before{content:\"\\f195\"}.fa-plus-square-o:before{content:\"\\f196\"}.fa-space-shuttle:before{content:\"\\f197\"}.fa-slack:before{content:\"\\f198\"}.fa-envelope-square:before{content:\"\\f199\"}.fa-wordpress:before{content:\"\\f19a\"}.fa-openid:before{content:\"\\f19b\"}.fa-institution:before,.fa-bank:before,.fa-university:before{content:\"\\f19c\"}.fa-mortar-board:before,.fa-graduation-cap:before{content:\"\\f19d\"}.fa-yahoo:before{content:\"\\f19e\"}.fa-google:before{content:\"\\f1a0\"}.fa-reddit:before{content:\"\\f1a1\"}.fa-reddit-square:before{content:\"\\f1a2\"}.fa-stumbleupon-circle:before{content:\"\\f1a3\"}.fa-stumbleupon:before{content:\"\\f1a4\"}.fa-delicious:before{content:\"\\f1a5\"}.fa-digg:before{content:\"\\f1a6\"}.fa-pied-piper:before{content:\"\\f1a7\"}.fa-pied-piper-alt:before{content:\"\\f1a8\"}.fa-drupal:before{content:\"\\f1a9\"}.fa-joomla:before{content:\"\\f1aa\"}.fa-language:before{content:\"\\f1ab\"}.fa-fax:before{content:\"\\f1ac\"}.fa-building:before{content:\"\\f1ad\"}.fa-child:before{content:\"\\f1ae\"}.fa-paw:before{content:\"\\f1b0\"}.fa-spoon:before{content:\"\\f1b1\"}.fa-cube:before{content:\"\\f1b2\"}.fa-cubes:before{content:\"\\f1b3\"}.fa-behance:before{content:\"\\f1b4\"}.fa-behance-square:before{content:\"\\f1b5\"}.fa-steam:before{content:\"\\f1b6\"}.fa-steam-square:before{content:\"\\f1b7\"}.fa-recycle:before{content:\"\\f1b8\"}.fa-automobile:before,.fa-car:before{content:\"\\f1b9\"}.fa-cab:before,.fa-taxi:before{content:\"\\f1ba\"}.fa-tree:before{content:\"\\f1bb\"}.fa-spotify:before{content:\"\\f1bc\"}.fa-deviantart:before{content:\"\\f1bd\"}.fa-soundcloud:before{content:\"\\f1be\"}.fa-database:before{content:\"\\f1c0\"}.fa-file-pdf-o:before{content:\"\\f1c1\"}.fa-file-word-o:before{content:\"\\f1c2\"}.fa-file-excel-o:before{content:\"\\f1c3\"}.fa-file-powerpoint-o:before{content:\"\\f1c4\"}.fa-file-photo-o:before,.fa-file-picture-o:before,.fa-file-image-o:before{content:\"\\f1c5\"}.fa-file-zip-o:before,.fa-file-archive-o:before{content:\"\\f1c6\"}.fa-file-sound-o:before,.fa-file-audio-o:before{content:\"\\f1c7\"}.fa-file-movie-o:before,.fa-file-video-o:before{content:\"\\f1c8\"}.fa-file-code-o:before{content:\"\\f1c9\"}.fa-vine:before{content:\"\\f1ca\"}.fa-codepen:before{content:\"\\f1cb\"}.fa-jsfiddle:before{content:\"\\f1cc\"}.fa-life-bouy:before,.fa-life-buoy:before,.fa-life-saver:before,.fa-support:before,.fa-life-ring:before{content:\"\\f1cd\"}.fa-circle-o-notch:before{content:\"\\f1ce\"}.fa-ra:before,.fa-rebel:before{content:\"\\f1d0\"}.fa-ge:before,.fa-empire:before{content:\"\\f1d1\"}.fa-git-square:before{content:\"\\f1d2\"}.fa-git:before{content:\"\\f1d3\"}.fa-y-combinator-square:before,.fa-yc-square:before,.fa-hacker-news:before{content:\"\\f1d4\"}.fa-tencent-weibo:before{content:\"\\f1d5\"}.fa-qq:before{content:\"\\f1d6\"}.fa-wechat:before,.fa-weixin:before{content:\"\\f1d7\"}.fa-send:before,.fa-paper-plane:before{content:\"\\f1d8\"}.fa-send-o:before,.fa-paper-plane-o:before{content:\"\\f1d9\"}.fa-history:before{content:\"\\f1da\"}.fa-circle-thin:before{content:\"\\f1db\"}.fa-header:before{content:\"\\f1dc\"}.fa-paragraph:before{content:\"\\f1dd\"}.fa-sliders:before{content:\"\\f1de\"}.fa-share-alt:before{content:\"\\f1e0\"}.fa-share-alt-square:before{content:\"\\f1e1\"}.fa-bomb:before{content:\"\\f1e2\"}.fa-soccer-ball-o:before,.fa-futbol-o:before{content:\"\\f1e3\"}.fa-tty:before{content:\"\\f1e4\"}.fa-binoculars:before{content:\"\\f1e5\"}.fa-plug:before{content:\"\\f1e6\"}.fa-slideshare:before{content:\"\\f1e7\"}.fa-twitch:before{content:\"\\f1e8\"}.fa-yelp:before{content:\"\\f1e9\"}.fa-newspaper-o:before{content:\"\\f1ea\"}.fa-wifi:before{content:\"\\f1eb\"}.fa-calculator:before{content:\"\\f1ec\"}.fa-paypal:before{content:\"\\f1ed\"}.fa-google-wallet:before{content:\"\\f1ee\"}.fa-cc-visa:before{content:\"\\f1f0\"}.fa-cc-mastercard:before{content:\"\\f1f1\"}.fa-cc-discover:before{content:\"\\f1f2\"}.fa-cc-amex:before{content:\"\\f1f3\"}.fa-cc-paypal:before{content:\"\\f1f4\"}.fa-cc-stripe:before{content:\"\\f1f5\"}.fa-bell-slash:before{content:\"\\f1f6\"}.fa-bell-slash-o:before{content:\"\\f1f7\"}.fa-trash:before{content:\"\\f1f8\"}.fa-copyright:before{content:\"\\f1f9\"}.fa-at:before{content:\"\\f1fa\"}.fa-eyedropper:before{content:\"\\f1fb\"}.fa-paint-brush:before{content:\"\\f1fc\"}.fa-birthday-cake:before{content:\"\\f1fd\"}.fa-area-chart:before{content:\"\\f1fe\"}.fa-pie-chart:before{content:\"\\f200\"}.fa-line-chart:before{content:\"\\f201\"}.fa-lastfm:before{content:\"\\f202\"}.fa-lastfm-square:before{content:\"\\f203\"}.fa-toggle-off:before{content:\"\\f204\"}.fa-toggle-on:before{content:\"\\f205\"}.fa-bicycle:before{content:\"\\f206\"}.fa-bus:before{content:\"\\f207\"}.fa-ioxhost:before{content:\"\\f208\"}.fa-angellist:before{content:\"\\f209\"}.fa-cc:before{content:\"\\f20a\"}.fa-shekel:before,.fa-sheqel:before,.fa-ils:before{content:\"\\f20b\"}.fa-meanpath:before{content:\"\\f20c\"}.fa-buysellads:before{content:\"\\f20d\"}.fa-connectdevelop:before{content:\"\\f20e\"}.fa-dashcube:before{content:\"\\f210\"}.fa-forumbee:before{content:\"\\f211\"}.fa-leanpub:before{content:\"\\f212\"}.fa-sellsy:before{content:\"\\f213\"}.fa-shirtsinbulk:before{content:\"\\f214\"}.fa-simplybuilt:before{content:\"\\f215\"}.fa-skyatlas:before{content:\"\\f216\"}.fa-cart-plus:before{content:\"\\f217\"}.fa-cart-arrow-down:before{content:\"\\f218\"}.fa-diamond:before{content:\"\\f219\"}.fa-ship:before{content:\"\\f21a\"}.fa-user-secret:before{content:\"\\f21b\"}.fa-motorcycle:before{content:\"\\f21c\"}.fa-street-view:before{content:\"\\f21d\"}.fa-heartbeat:before{content:\"\\f21e\"}.fa-venus:before{content:\"\\f221\"}.fa-mars:before{content:\"\\f222\"}.fa-mercury:before{content:\"\\f223\"}.fa-intersex:before,.fa-transgender:before{content:\"\\f224\"}.fa-transgender-alt:before{content:\"\\f225\"}.fa-venus-double:before{content:\"\\f226\"}.fa-mars-double:before{content:\"\\f227\"}.fa-venus-mars:before{content:\"\\f228\"}.fa-mars-stroke:before{content:\"\\f229\"}.fa-mars-stroke-v:before{content:\"\\f22a\"}.fa-mars-stroke-h:before{content:\"\\f22b\"}.fa-neuter:before{content:\"\\f22c\"}.fa-genderless:before{content:\"\\f22d\"}.fa-facebook-official:before{content:\"\\f230\"}.fa-pinterest-p:before{content:\"\\f231\"}.fa-whatsapp:before{content:\"\\f232\"}.fa-server:before{content:\"\\f233\"}.fa-user-plus:before{content:\"\\f234\"}.fa-user-times:before{content:\"\\f235\"}.fa-hotel:before,.fa-bed:before{content:\"\\f236\"}.fa-viacoin:before{content:\"\\f237\"}.fa-train:before{content:\"\\f238\"}.fa-subway:before{content:\"\\f239\"}.fa-medium:before{content:\"\\f23a\"}.fa-yc:before,.fa-y-combinator:before{content:\"\\f23b\"}.fa-optin-monster:before{content:\"\\f23c\"}.fa-opencart:before{content:\"\\f23d\"}.fa-expeditedssl:before{content:\"\\f23e\"}.fa-battery-4:before,.fa-battery-full:before{content:\"\\f240\"}.fa-battery-3:before,.fa-battery-three-quarters:before{content:\"\\f241\"}.fa-battery-2:before,.fa-battery-half:before{content:\"\\f242\"}.fa-battery-1:before,.fa-battery-quarter:before{content:\"\\f243\"}.fa-battery-0:before,.fa-battery-empty:before{content:\"\\f244\"}.fa-mouse-pointer:before{content:\"\\f245\"}.fa-i-cursor:before{content:\"\\f246\"}.fa-object-group:before{content:\"\\f247\"}.fa-object-ungroup:before{content:\"\\f248\"}.fa-sticky-note:before{content:\"\\f249\"}.fa-sticky-note-o:before{content:\"\\f24a\"}.fa-cc-jcb:before{content:\"\\f24b\"}.fa-cc-diners-club:before{content:\"\\f24c\"}.fa-clone:before{content:\"\\f24d\"}.fa-balance-scale:before{content:\"\\f24e\"}.fa-hourglass-o:before{content:\"\\f250\"}.fa-hourglass-1:before,.fa-hourglass-start:before{content:\"\\f251\"}.fa-hourglass-2:before,.fa-hourglass-half:before{content:\"\\f252\"}.fa-hourglass-3:before,.fa-hourglass-end:before{content:\"\\f253\"}.fa-hourglass:before{content:\"\\f254\"}.fa-hand-grab-o:before,.fa-hand-rock-o:before{content:\"\\f255\"}.fa-hand-stop-o:before,.fa-hand-paper-o:before{content:\"\\f256\"}.fa-hand-scissors-o:before{content:\"\\f257\"}.fa-hand-lizard-o:before{content:\"\\f258\"}.fa-hand-spock-o:before{content:\"\\f259\"}.fa-hand-pointer-o:before{content:\"\\f25a\"}.fa-hand-peace-o:before{content:\"\\f25b\"}.fa-trademark:before{content:\"\\f25c\"}.fa-registered:before{content:\"\\f25d\"}.fa-creative-commons:before{content:\"\\f25e\"}.fa-gg:before{content:\"\\f260\"}.fa-gg-circle:before{content:\"\\f261\"}.fa-tripadvisor:before{content:\"\\f262\"}.fa-odnoklassniki:before{content:\"\\f263\"}.fa-odnoklassniki-square:before{content:\"\\f264\"}.fa-get-pocket:before{content:\"\\f265\"}.fa-wikipedia-w:before{content:\"\\f266\"}.fa-safari:before{content:\"\\f267\"}.fa-chrome:before{content:\"\\f268\"}.fa-firefox:before{content:\"\\f269\"}.fa-opera:before{content:\"\\f26a\"}.fa-internet-explorer:before{content:\"\\f26b\"}.fa-tv:before,.fa-television:before{content:\"\\f26c\"}.fa-contao:before{content:\"\\f26d\"}.fa-500px:before{content:\"\\f26e\"}.fa-amazon:before{content:\"\\f270\"}.fa-calendar-plus-o:before{content:\"\\f271\"}.fa-calendar-minus-o:before{content:\"\\f272\"}.fa-calendar-times-o:before{content:\"\\f273\"}.fa-calendar-check-o:before{content:\"\\f274\"}.fa-industry:before{content:\"\\f275\"}.fa-map-pin:before{content:\"\\f276\"}.fa-map-signs:before{content:\"\\f277\"}.fa-map-o:before{content:\"\\f278\"}.fa-map:before{content:\"\\f279\"}.fa-commenting:before{content:\"\\f27a\"}.fa-commenting-o:before{content:\"\\f27b\"}.fa-houzz:before{content:\"\\f27c\"}.fa-vimeo:before{content:\"\\f27d\"}.fa-black-tie:before{content:\"\\f27e\"}.fa-fonticons:before{content:\"\\f280\"}.fa-reddit-alien:before{content:\"\\f281\"}.fa-edge:before{content:\"\\f282\"}.fa-credit-card-alt:before{content:\"\\f283\"}.fa-codiepie:before{content:\"\\f284\"}.fa-modx:before{content:\"\\f285\"}.fa-fort-awesome:before{content:\"\\f286\"}.fa-usb:before{content:\"\\f287\"}.fa-product-hunt:before{content:\"\\f288\"}.fa-mixcloud:before{content:\"\\f289\"}.fa-scribd:before{content:\"\\f28a\"}.fa-pause-circle:before{content:\"\\f28b\"}.fa-pause-circle-o:before{content:\"\\f28c\"}.fa-stop-circle:before{content:\"\\f28d\"}.fa-stop-circle-o:before{content:\"\\f28e\"}.fa-shopping-bag:before{content:\"\\f290\"}.fa-shopping-basket:before{content:\"\\f291\"}.fa-hashtag:before{content:\"\\f292\"}.fa-bluetooth:before{content:\"\\f293\"}.fa-bluetooth-b:before{content:\"\\f294\"}.fa-percent:before{content:\"\\f295\"}\n","H5P.DragNResize.css":".h5p-dragnbar-element.focused \u003e .h5p-dragnresize-handle {\n position: absolute;\n top: -4px;\n left: -4px;\n width: 7px;\n height: 7px;\n cursor: nwse-resize;\n border: 1px solid #0099ff;\n background-color: #fff;\n z-index: 1;\n}\n\n.h5p-dragnbar-element.focused \u003e .h5p-dragnresize-handle.ne {\n left: auto;\n right: -4px;\n cursor: nesw-resize;\n}\n\n.h5p-dragnbar-element.focused \u003e .h5p-dragnresize-handle.sw {\n top: auto;\n bottom: -4px;\n cursor: nesw-resize;\n}\n\n.h5p-dragnbar-element.focused \u003e .h5p-dragnresize-handle.se {\n top: auto;\n left: auto;\n bottom: -4px;\n right: -4px;\n}\n\n.h5p-dragnbar-element.focused \u003e .h5p-dragnresize-handle.n {\n left: calc(50% - 3px);\n cursor: ns-resize;\n}\n\n.h5p-dragnbar-element.focused \u003e .h5p-dragnresize-handle.w {\n top: calc(50% - 3px);\n cursor: ew-resize;\n}\n\n.h5p-dragnbar-element.focused \u003e .h5p-dragnresize-handle.e {\n top: calc(50% - 3px);\n left: auto;\n right: -4px;\n cursor: ew-resize;\n}\n\n.h5p-dragnbar-element.focused \u003e .h5p-dragnresize-handle.s {\n top: auto;\n left: auto;\n bottom: -4px;\n right: calc(50% - 3px);\n cursor: ns-resize;\n}\n","styles/drag-n-bar.css":".h5p-moving {\n cursor: move;\n opacity: 0.6;\n}\n\n.h5peditor .h5p-dragnbar-element.focused,\n.h5peditor .h5p-dragnbar-element:hover {\n outline: 1px solid #0099ff;\n}\n\n/* Display outline on label for h5p nil */\n.h5p-dragnbar-element.h5p-nil-interaction.focused,\n.h5p-dragnbar-element.h5p-nil-interaction:hover {\n outline: none;\n}\n\n.h5peditor .h5p-dragnbar-element.h5p-nil-interaction.focused \u003e .h5p-interaction-label,\n.h5peditor .h5p-dragnbar-element.h5p-nil-interaction:hover \u003e .h5p-interaction-label {\n outline: 1px solid #0099ff;\n}\n\n.h5peditor .hardware-accelerated {\n -webkit-transform: translateZ(0);\n -ms-transform: translateZ(0);\n transform: translateZ(0);\n}\n\n.h5peditor .h5peditor-dragnbar .h5p-dragnbar-li .h5p-dragnbar-tooltip {\n visibility: hidden;\n position: absolute;\n padding: 0 0.5em;\n top: 100%;\n left: 0;\n z-index: 2;\n border-radius: 4px;\n background-color: rgba(0, 0, 0, 0.9);\n color: #fff;\n font-family: \"Open Sans\", sans-serif;\n font-size: 0.6em;\n line-height: 2em;\n content: attr(data-label);\n white-space: pre;\n}\n\n.h5peditor .h5peditor-dragnbar .h5p-dragnbar-li:hover \u003e .h5p-dragnbar-tooltip {\n visibility: visible;\n}\n","styles/dialog.css":".h5p-dialog-title:before {\n content: \" \";\n font-family: \u0027H5PFontAwesome4\u0027;\n color: #313131;\n margin-right: 0.5em;\n margin-left: 0.1em;\n vertical-align: middle;\n}\n\n.h5p-dialog.h5p-big {\n padding: 0;\n}\n\n.h5p-dialog-title {\n color: #313131;\n float: left;\n}\n\n/* Remove h5p-nil library border */\n.h5peditor-interactions .h5p-dialog-inner .field.library.h5p-nil-library {\n display: none;\n}\n\n/* interaction semantics wrapper */\n.h5p-dialog-inner \u003e div \u003e .field:first-child {\n margin-top: 0;\n}\n.h5p-dialog-inner .h5peditor-interaction-label.hide,\n.h5p-dialog-inner \u003e div \u003e .field.library \u003e select,\n.h5p-dialog-inner \u003e div \u003e .field.library \u003e label {\n display: none;\n}\n.h5p-dialog-inner input[type=\"checkbox\"] {\n vertical-align: middle;\n}\n.h5p-dialog-inner div.ckeditor \u003e p {\n margin: 0.5em;\n}\n.h5p-dialog-inner div.ckeditor \u003e p:first-child {\n margin-top: 0;\n}\n.h5p-dialog-inner div.ckeditor \u003e p:last-child {\n margin-bottom: 0;\n}\n\n.h5p-dialog-wrapper {\n color: #313131;\n display: none;\n position: absolute;\n top: 0;\n left: 0;\n width: 100%;\n height: 100%;\n z-index: 51;\n background: rgba(44, 44, 44, 0.5);\n -webkit-transition: background-color 0.2s;\n -moz-transition: background-color 0.2s;\n transition: background-color 0.2s;\n filter:progid:DXImageTransform.Microsoft.gradient(startColorstr=#66000000,endColorstr=#66000000);\n}\n.h5p-dialog-wrapper.h5p-hidden {\n background: rgba(0,0,0,0);\n}\n.h5p-dialog-wrapper.h5p-hidden .h5p-dialog {\n -webkit-transform: translateY(100%);\n -moz-transform: translateY(100%);\n -ms-transform: translateY(100%);\n -o-transform: translateY(100%);\n transform: translateY(100%);\n}\n.h5p-dialog {\n position: absolute;\n width: 24.5em;\n max-height: 100%;\n margin: 1.25em;\n background: #fff;\n overflow: hidden;\n box-shadow: 0 0 2.5em 0 #191919;\n -webkit-transition: -webkit-transform 0.2s;\n -moz-transition: -moz-transform 0.2s;\n transition: transform 0.2s;\n}\n.h5p-dialog[data-lib=\"H5P.SingleChoiceSet\"] {\n overflow: hidden;\n padding: 0;\n}\n.h5p-dialog[data-lib=\"H5P.SingleChoiceSet\"] .h5p-dialog-inner {\n overflow: visible;\n width: 100%;\n}\n.h5p-dialog[data-lib=\"H5P.SingleChoiceSet\"] .h5p-sc-sound-control {\n right: 1.2em;\n}\n.h5p-dialog.h5p-big {\n width: auto;\n height: auto;\n max-height: none;\n left: 1.25em;\n right: 1.25em;\n top: 1.25em;\n bottom: 1.25em;\n margin: 0;\n box-sizing: border-box;\n -moz-box-sizing: border-box;\n}\n.h5p-dialog-inner {\n width: 22.9em;\n height: 100%;\n overflow: auto;\n}\n.h5p-big \u003e .h5p-dialog-inner {\n width: 96%;\n height: auto;\n}\n.h5p-dialog-inner::-webkit-scrollbar {\n width: 0.5em;\n background: #fff;\n}\n.h5p-dialog-inner::-webkit-scrollbar-thumb {\n background: #ddd;\n}\n.h5p-dialog-inner::-webkit-scrollbar-thumb:hover {\n background: #aaa;\n}\n.h5p-dialog-inner::-webkit-scrollbar-thumb:active,\n.h5p-dialog-inner::-webkit-scrollbar-thumb:focus {\n background: #888;\n}\n\n.h5p-interactive-video .h5p-dialog-hide {\n color: #191919;\n font-size: 1.3em;\n padding: 0.3em;\n line-height: 0.75em;\n position: absolute;\n right: 0.1em;\n top: 0.1em;\n height: 1em;\n z-index: 52;\n text-shadow: 0 0 0.5em #ffffff;\n font-family: \u0027H5PFontAwesome4\u0027;\n text-decoration: none;\n -webkit-transition: -webkit-transform 0.2s;\n -moz-transition: -moz-transform 0.2s;\n transition: transform 0.2s;\n}\n.h5p-interactive-video .h5p-dialog-hide:hover {\n text-decoration: none;\n -webkit-transform: scale(1.1,1.1);\n -moz-transform: scale(1.1,1.1);\n -ms-transform: scale(1.1,1.1);\n -o-transform: scale(1.1,1.1);\n transform: scale(1.1,1.1);\n}\n","styles/context-menu.css":"/* Custom H5P font to use for icons. */\n@font-face {\n font-family: \u0027H5PDragNBar\u0027;\n src:url(\u0027../H5P/libraries/H5P.DragNBar-1.4/fonts/H5PDragNBar.eot?5yxjqx\u0027);\n src:url(\u0027../H5P/libraries/H5P.DragNBar-1.4/fonts/H5PDragNBar.eot?#iefix5yxjqx\u0027) format(\u0027embedded-opentype\u0027),\n url(\u0027data:application/font-woff;base64,d09GRgABAAAAAAS0AAsAAAAABGgAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAABPUy8yAAABCAAAAGAAAABgDxICMmNtYXAAAAFoAAAAVAAAAFQaTsyXZ2FzcAAAAbwAAAAIAAAACAAAABBnbHlmAAABxAAAAHwAAAB8uhYcYGhlYWQAAAJAAAAANgAAADYGieuHaGhlYQAAAngAAAAkAAAAJAcAA8ZobXR4AAACnAAAABQAAAAUCgAAwmxvY2EAAAKwAAAADAAAAAwAKABSbWF4cAAAArwAAAAgAAAAIAAIABJuYW1lAAAC3AAAAbYAAAG2EB9/n3Bvc3QAAASUAAAAIAAAACAAAwAAAAMDAAGQAAUAAAKZAswAAACPApkCzAAAAesAMwEJAAAAAAAAAAAAAAAAAAAAARAAAAAAAAAAAAAAAAAAAAAAQAAA5ggDwP/AAEADwABAAAAAAQAAAAAAAAAAAAAAIAAAAAAAAwAAAAMAAAAcAAEAAwAAABwAAwABAAAAHAAEADgAAAAKAAgAAgACAAEAIOYI//3//wAAAAAAIOYI//3//wAB/+MZ/AADAAEAAAAAAAAAAAAAAAEAAf//AA8AAQAAAAAAAAAAAAIAADc5AQAAAAABAAAAAAAAAAAAAgAANzkBAAAAAAEAAAAAAAAAAAACAAA3OQEAAAAAAgDCAIIDPgL+AAgADwAAATUhETMVIREjEyE1IREzEQKW/ixnAhWoZv5uASxmApdn/iyoAhX+LWYBLP5uAAAAAAEAAAABAAAnj2iRXw889QALBAAAAAAA0hbTxgAAAADSFtPGAAAAAAM+Av4AAAAIAAIAAAAAAAAAAQAAA8D/wAAABAAAAAAAAz4AAQAAAAAAAAAAAAAAAAAAAAUEAAAAAAAAAAAAAAACAAAABAAAwgAAAAAACgAUAB4APgABAAAABQAQAAIAAAAAAAIAAAAAAAAAAAAAAAAAAAAAAAAADgCuAAEAAAAAAAEACwAAAAEAAAAAAAIABwCEAAEAAAAAAAMACwBCAAEAAAAAAAQACwCZAAEAAAAAAAUACwAhAAEAAAAAAAYACwBjAAEAAAAAAAoAGgC6AAMAAQQJAAEAFgALAAMAAQQJAAIADgCLAAMAAQQJAAMAFgBNAAMAAQQJAAQAFgCkAAMAAQQJAAUAFgAsAAMAAQQJAAYAFgBuAAMAAQQJAAoANADUSDVQRHJhZ05CYXIASAA1AFAARAByAGEAZwBOAEIAYQByVmVyc2lvbiAxLjAAVgBlAHIAcwBpAG8AbgAgADEALgAwSDVQRHJhZ05CYXIASAA1AFAARAByAGEAZwBOAEIAYQBySDVQRHJhZ05CYXIASAA1AFAARAByAGEAZwBOAEIAYQByUmVndWxhcgBSAGUAZwB1AGwAYQBySDVQRHJhZ05CYXIASAA1AFAARAByAGEAZwBOAEIAYQByRm9udCBnZW5lcmF0ZWQgYnkgSWNvTW9vbi4ARgBvAG4AdAAgAGcAZQBuAGUAcgBhAHQAZQBkACAAYgB5ACAASQBjAG8ATQBvAG8AbgAuAAAAAwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==\u0027) format(\u0027woff\u0027),\n url(\u0027../H5P/libraries/H5P.DragNBar-1.4/fonts/H5PDragNBar.ttf?5yxjqx\u0027) format(\u0027truetype\u0027),\n url(\u0027../H5P/libraries/H5P.DragNBar-1.4/fonts/H5PDragNBar.svg?5yxjqx#H5PDragNBar\u0027) format(\u0027svg\u0027);\n font-weight: normal;\n font-style: normal;\n}\n\n.h5p-dragnbar-context-menu {\n display: block;\n background-color: #c4e3f7;\n height: 36px;\n margin-top: -51px;\n position: absolute;\n border: 1px solid #0099ff;\n line-height: 36px;\n -webkit-filter: drop-shadow(0px 0px 0.25em rgba(44,44,44,0.75));\n filter: drop-shadow(0px 0px 0.25em rgba(44, 44, 44, 0.5));\n z-index: 100;\n font-size: 16px;\n}\n\n.h5p-dragnbar-context-menu.left-aligned:after {\n position: absolute;\n display: block;\n content: \"\";\n border-style: solid;\n border-width: 8px 7px 0 0;\n border-color: #c4e3f7 transparent transparent transparent;\n bottom: -7px;\n right: 0;\n left: initial;\n z-index: 1;\n transform: scaleX(-1);\n}\n\n.h5p-dragnbar-context-menu.left-aligned:before {\n position: absolute;\n display: block;\n content: \"\";\n border-style: solid;\n border-width: 10px 10px 0 0;\n border-color: #0099ff transparent transparent transparent;\n bottom: -10px;\n left: initial;\n right: -1px;\n transform: scaleX(-1);\n}\n\n.h5p-dragnbar-context-menu.left-aligned .h5p-context-menu-buttons {\n float: left;\n}\n\n.h5p-dragnbar-context-menu:before {\n position: absolute;\n display: block;\n content: \"\";\n border-style: solid;\n border-width: 9px 9px 0 0;\n border-color: #0099ff transparent transparent transparent;\n bottom: -9px;\n left: -1px;\n}\n\n.h5p-dragnbar-context-menu:after {\n position: absolute;\n display: block;\n content: \"\";\n border-style: solid;\n border-width: 8px 7px 0 0;\n border-color: #c4e3f7 transparent transparent transparent;\n bottom: -7px;\n left: 0;\n z-index: 1;\n}\n\n.h5p-dragnbar-context-menu .h5p-dragnbar-context-menu-button,\n.h5p-dragnbar-context-menu .h5p-context-menu-buttons,\n.h5p-dragnbar-context-menu .h5p-transform-panel,\n.h5p-dragnbar-context-menu .h5p-dragnbar-dimensions,\n.h5p-dragnbar-context-menu .h5p-dragnbar-coordinates {\n display: inline-block;\n position: relative;\n}\n\n.h5p-dragnbar-context-menu .h5p-dragnbar-coordinates {\n padding: 0 0.75em;\n background-color: #fff;\n color: #0061a2;\n border-right: 1px solid #0099ff;\n border-left: 1px solid #0099ff;\n line-height: 36px;\n}\n\n.h5p-dragnbar-context-menu.left-aligned .h5p-dragnbar-coordinates {\n border-left: none;\n border-right: none;\n}\n\n.h5p-dragnbar-context-menu.left-aligned .h5p-dragnbar-coordinates:last-child {\n border-right: 1px solid #0099ff;\n}\n\n.h5p-dragnbar-context-menu .h5p-dragnbar-coordinates:last-child {\n border-right: none;\n}\n\n.h5p-dragnbar-context-menu .h5p-dragnbar-context-menu-button {\n width: 32px;\n text-align: center;\n position: relative;\n cursor: pointer;\n\tline-height: 36px;\n\tvertical-align: middle;\n\toutline: none;\n}\n\n.h5p-dragnbar-context-menu .h5p-dragnbar-coordinates .h5p-dragnbar-x-container,\n.h5p-dragnbar-context-menu .h5p-dragnbar-coordinates .h5p-dragnbar-y-container {\n display: inline-block;\n position: relative;\n}\n\n/* Button stylings */\n.h5p-dragnbar-context-menu .h5p-dragnbar-coordinates .h5p-dragnbar-x-container:hover:before,\n.h5p-dragnbar-context-menu .h5p-dragnbar-coordinates .h5p-dragnbar-y-container:hover:before,\n.h5p-dragnbar-context-menu .h5p-dragnbar-context-menu-button:hover:before,\n.h5p-dragnbar-context-menu .h5p-dragnbar-input:hover:before {\n background-color: #000;\n color: #fff;\n opacity: 0.75;\n content: attr(aria-label);\n position: absolute;\n bottom: 42px;\n padding: 0 0.5em;\n transform: translateX(-50%);\n left: 50%;\n font-size: 14px;\n line-height: 2;\n border-radius: 4px;\n white-space: nowrap;\n}\n\n.h5p-dragnbar-context-menu .h5p-dragnbar-context-menu-button:after {\n font-family: \"H5PFontAwesome4\";\n content: \u0027\\f059\u0027;\n color: #0061a2;\n padding: 3px 5px;\n}\n\n.h5p-dragnbar-context-menu .h5p-dragnbar-context-menu-button:hover:after {\n border: 1px solid #61bfff;\n border-radius: 2px;\n color: #003c65;\n}\n\n.h5p-dragnbar-context-menu .h5p-dragnbar-context-menu-button.transform:after {\n content: \u0027\\f0b2\u0027;\n}\n\n.h5p-dragnbar-context-menu .h5p-dragnbar-context-menu-button.edit:after {\n content: \u0027\\f040\u0027;\n}\n\n.h5p-dragnbar-context-menu .h5p-dragnbar-context-menu-button.remove:after {\n content: \u0027\\f1f8\u0027;\n}\n\n.h5p-dragnbar-context-menu .h5p-dragnbar-context-menu-button.bringtofront:after {\n font-family: \"H5PDragNBar\";\n content: \"\\e608\";\n padding: 3px;\n font-size: 1.05em;\n vertical-align: bottom;\n}\n\n.h5p-dragnbar-context-menu .h5p-dragnbar-context-menu-button.sendtoback:after {\n font-family: \"H5PFontIcons\";\n content: \"\\e90f\";\n padding: 3px;\n font-size: 1.05em;\n vertical-align: bottom;\n}\n\n.ui-widget .h5p-dragnbar-coordinates \u003e div \u003e input,\n.h5p-dragnbar-coordinates input {\n font-size: 13px;\n background: none repeat scroll 0 0 transparent;\n border: medium none;\n width: 2em;\n text-align: left;\n color: #0061a2;\n vertical-align: bottom;\n margin-bottom: 3px;\n}\n\n.h5p-dragnbar-coordinates input.h5p-dragnbar-x {\n text-align: right;\n}\n\n.h5p-dragnbar-coordinates .h5p-dragnbar-coordinates-separater {\n margin: 0 0.25em;\n vertical-align: bottom;\n line-height: 24px;\n color: #555;\n}\n\n.h5p-dragnbar-coordinates input:focus {\n outline: none;\n}\n\n.left-aligned .h5p-dragnbar-dimensions {\n\tborder-left: 1px solid #0099ff;\n\tborder-right: 1px solid #0099ff;\n}\n.h5p-dragnbar-input {\n display: inline-block;\n position: relative;\n}\n.h5p-dragnbar-input \u003e input {\n\twidth: 3.25em;\n\theight: 36px;\n\tcolor: #0061a2;\n padding: 1em 0.5em 0;\n\tborder: 0;\n\toutline: none;\n box-sizing: border-box;\n vertical-align: top;\n font-size: 13px;\n}\n.h5p-dragnbar-input \u003e input:hover,\n.h5p-dragnbar-input \u003e input:focus {\n\tcolor: #044c7c;\n}\n.ui-widget .h5p-dragnbar-input \u003e input {\n font-size: 13px;\n font-family: inherit;\n}\n.h5p-dragnbar-width \u003e input {\n\ttext-align: right;\n\tpadding-right: 0.25em;\n}\n.h5p-dragnbar-height \u003e input {\n\tpadding-left: 0.25em;\n}\n.h5p-dragnbar-dimensions-separator {\n font-size: 14px;\n height: 29px;\n padding: 0.5em 0 0;\n\tbackground-color: #fff;\n\tdisplay: inline-block;\n\tvertical-align: top;\n\tcolor: #555;\n}\n\n.h5p-dragnbar-context-menu .h5p-transform-panel.hide,\n.h5p-dragnbar-context-menu .h5p-context-menu-buttons.hide,\n.h5p-dragnbar-context-menu .h5p-dragnbar-context-menu-button.transform.hide {\n display: none;\n}\n\n.h5p-dragnbar-context-menu.left-aligned .h5p-transform-panel {\n float: left;\n}\n\n.h5p-dragnbar-context-menu .h5p-transform-button-wrapper {\n margin-left: 4px;\n display: inline-block;\n}\n\n.h5p-dragnbar-context-menu.left-aligned .h5p-transform-button-wrapper {\n margin-left: 0;\n margin-right: 4px;\n}\n\n.h5p-dragnbar-context-menu .h5p-transform-button-wrapper.active {\n margin-right: 4px;\n margin-left: 4px;\n}\n\n.h5p-dragnbar-context-menu .h5p-transform-button-wrapper .transform {\n margin: 0;\n}\n\n.h5p-dragnbar-context-menu .h5p-context-menu-buttons {\n margin-right: 4px;\n}\n\n.h5p-dragnbar-context-menu.left-aligned .h5p-context-menu-buttons {\n margin-right: 0;\n margin-left: 4px;\n}\n\n.h5p-dragnbar-context-menu .h5p-transform-button-wrapper.active .transform:after {\n border: 1px solid #80c2ee;\n background: #b2d7ee;\n box-shadow: inset 0 1px 5px 0 rgba(2,94,156,0.65);\n}\n.h5p-dragnbar-context-menu .h5p-dragnbar-label {\n position: absolute;\n left: 0;\n font-size: 10px;\n color: #555;\n width: 100%;\n z-index: 1;\n text-align: center;\n padding: 1px 0 0;\n line-height: 18px;\n}\n","image.css":".h5p-image \u003e img {\n display: block;\n width: 100%;\n height: 100%;\n}\n.h5p-image \u003e .h5p-placeholder {\n background: url(\u0027../H5P/libraries/H5P.Image-1.0/placeholder.svg\u0027);\n background-size: cover;\n}\n","styles/text.css":".h5p-text ul,\n.h5p-text li {\n padding-left: 0;\n}\n.h5p-text ul li {\n list-style-type: circle;\n margin-left: 1.5em;\n padding-left: 0;\n}\n.h5p-text ol li {\n list-style-type: decimal;\n margin-left: 1.5em;\n padding-left: 0;\n}\n.h5p-text.h5p-frame {\n margin: 1em;\n}\n","styles/table.css":".h5p-table.h5p-frame {\n padding: 1em;\n}\n","link-widget.css":".h5peditor .h5p-link-widget .h5p-link-fields {\n display: flex;\n}\n\n.h5peditor .h5p-link-url,\n.h5peditor .h5p-link-protocol-selector {\n display: inline-block;\n margin: 0 1em 0 0;\n}\n\n.h5peditor .h5p-link-url {\n flex: 2;\n}\n","styles/tether.min.css":".tether-element,.tether-element *,.tether-element :after,.tether-element :before,.tether-element:after,.tether-element:before{box-sizing:border-box}.tether-element{position:absolute;display:none}.tether-element.tether-open{display:block}","css/drop-theme-arrows-bounce.min.css":".drop-element,.drop-element *,.drop-element :after,.drop-element :before,.drop-element:after,.drop-element:before{box-sizing:border-box}.drop-element{position:absolute;display:none}.drop-element.drop-open{display:block}.drop-element.drop-theme-arrows-bounce .drop-content{border-radius:5px;position:relative;font-family:inherit;background:#fff;color:#444;padding:1em;font-size:1.1em;line-height:1.5em;-webkit-transform:translateZ(0);transform:translateZ(0);-webkit-filter:drop-shadow(0 1px 4px rgba(0, 0, 0, .2));filter:drop-shadow(0 1px 4px rgba(0, 0, 0, .2))}.drop-element.drop-theme-arrows-bounce .drop-content:before{content:\"\";display:block;position:absolute;width:0;height:0;border-color:transparent;border-width:12px;border-style:solid}.drop-element.drop-theme-arrows-bounce.drop-element-attached-bottom.drop-element-attached-center .drop-content:before{top:100%;left:50%;margin-left:-12px;border-top-color:#fff}.drop-element.drop-theme-arrows-bounce.drop-element-attached-top.drop-element-attached-center .drop-content{margin-top:12px}.drop-element.drop-theme-arrows-bounce.drop-element-attached-top.drop-element-attached-center .drop-content:before{bottom:100%;left:50%;margin-left:-12px;border-bottom-color:#fff}.drop-element.drop-theme-arrows-bounce.drop-element-attached-right.drop-element-attached-middle .drop-content:before{left:100%;top:50%;margin-top:-12px;border-left-color:#fff}.drop-element.drop-theme-arrows-bounce.drop-element-attached-left.drop-element-attached-middle .drop-content:before{right:100%;top:50%;margin-top:-12px;border-right-color:#fff}.drop-element.drop-theme-arrows-bounce.drop-element-attached-top.drop-element-attached-left.drop-target-attached-bottom .drop-content:before{bottom:100%;left:12px;border-bottom-color:#fff}.drop-element.drop-theme-arrows-bounce.drop-element-attached-top.drop-element-attached-right.drop-target-attached-bottom .drop-content:before{bottom:100%;right:12px;border-bottom-color:#fff}.drop-element.drop-theme-arrows-bounce.drop-element-attached-bottom.drop-element-attached-left.drop-target-attached-top .drop-content:before{top:100%;left:12px;border-top-color:#fff}.drop-element.drop-theme-arrows-bounce.drop-element-attached-bottom.drop-element-attached-right.drop-target-attached-top .drop-content:before{top:100%;right:12px;border-top-color:#fff}.drop-element.drop-theme-arrows-bounce.drop-element-attached-top.drop-element-attached-right.drop-target-attached-left .drop-content:before{top:12px;left:100%;border-left-color:#fff}.drop-element.drop-theme-arrows-bounce.drop-element-attached-top.drop-element-attached-left.drop-target-attached-right .drop-content:before{top:12px;right:100%;border-right-color:#fff}.drop-element.drop-theme-arrows-bounce.drop-element-attached-bottom.drop-element-attached-right.drop-target-attached-left .drop-content:before{bottom:12px;left:100%;border-left-color:#fff}.drop-element.drop-theme-arrows-bounce.drop-element-attached-bottom.drop-element-attached-left.drop-target-attached-right .drop-content:before{bottom:12px;right:100%;border-right-color:#fff}.drop-element.drop-theme-arrows-bounce{max-width:100%;max-height:100%;-webkit-transform:translateZ(0);transform:translateZ(0);-webkit-transition:opacity .1s;transition:opacity .1s;opacity:0}.drop-element.drop-theme-arrows-bounce .drop-content{-webkit-transition:-webkit-transform .3s cubic-bezier(0,0,.265,1.55);transition:transform .3s cubic-bezier(0,0,.265,1.55);-webkit-transform:scale(0) translateZ(0);transform:scale(0) translateZ(0)}.drop-element.drop-theme-arrows-bounce.drop-open{display:none}.drop-element.drop-theme-arrows-bounce.drop-open-transitionend{display:block}.drop-element.drop-theme-arrows-bounce.drop-after-open{-webkit-transition:none;transition:none;opacity:1}.drop-element.drop-theme-arrows-bounce.drop-after-open .drop-content{-webkit-transform:scale(1) translateZ(0);transform:scale(1) translateZ(0)}.drop-element.drop-theme-arrows-bounce.drop-element-attached-bottom.drop-element-attached-center .drop-content{margin-bottom:12px;-webkit-transform-origin:50%,calc(100% + 12px);-ms-transform-origin:50%,calc(100% + 12px);transform-origin:50%,calc(100% + 12px)}.drop-element.drop-theme-arrows-bounce.drop-element-attached-top.drop-element-attached-center .drop-content{-webkit-transform-origin:50%,-12px;-ms-transform-origin:50%,-12px;transform-origin:50%,-12px}.drop-element.drop-theme-arrows-bounce.drop-element-attached-right.drop-element-attached-middle .drop-content{margin-right:12px;-webkit-transform-origin:calc(100% + 12px),50%;-ms-transform-origin:calc(100% + 12px),50%;transform-origin:calc(100% + 12px),50%}.drop-element.drop-theme-arrows-bounce.drop-element-attached-left.drop-element-attached-middle .drop-content{margin-left:12px;-webkit-transform-origin:-12px,50%;-ms-transform-origin:-12px,50%;transform-origin:-12px,50%}.drop-element.drop-theme-arrows-bounce.drop-element-attached-top.drop-element-attached-left.drop-target-attached-bottom .drop-content{margin-top:12px;-webkit-transform-origin:0,-12px;-ms-transform-origin:0,-12px;transform-origin:0,-12px}.drop-element.drop-theme-arrows-bounce.drop-element-attached-top.drop-element-attached-right.drop-target-attached-bottom .drop-content{margin-top:12px;-webkit-transform-origin:100%,-12px;-ms-transform-origin:100%,-12px;transform-origin:100%,-12px}.drop-element.drop-theme-arrows-bounce.drop-element-attached-bottom.drop-element-attached-left.drop-target-attached-top .drop-content{margin-bottom:12px;-webkit-transform-origin:0,calc(100% + 12px);-ms-transform-origin:0,calc(100% + 12px);transform-origin:0,calc(100% + 12px)}.drop-element.drop-theme-arrows-bounce.drop-element-attached-bottom.drop-element-attached-right.drop-target-attached-top .drop-content{margin-bottom:12px;-webkit-transform-origin:100%,calc(100% + 12px);-ms-transform-origin:100%,calc(100% + 12px);transform-origin:100%,calc(100% + 12px)}.drop-element.drop-theme-arrows-bounce.drop-element-attached-top.drop-element-attached-right.drop-target-attached-left .drop-content{margin-right:12px;-webkit-transform-origin:calc(100% + 12px),0;-ms-transform-origin:calc(100% + 12px),0;transform-origin:calc(100% + 12px),0}.drop-element.drop-theme-arrows-bounce.drop-element-attached-top.drop-element-attached-left.drop-target-attached-right .drop-content{margin-left:12px;-webkit-transform-origin:-12px,0;-ms-transform-origin:-12px,0;transform-origin:-12px,0}.drop-element.drop-theme-arrows-bounce.drop-element-attached-bottom.drop-element-attached-right.drop-target-attached-left .drop-content{margin-right:12px;-webkit-transform-origin:calc(100% + 12px),100%;-ms-transform-origin:calc(100% + 12px),100%;transform-origin:calc(100% + 12px),100%}.drop-element.drop-theme-arrows-bounce.drop-element-attached-bottom.drop-element-attached-left.drop-target-attached-right .drop-content{margin-left:12px;-webkit-transform-origin:-12px,100%;-ms-transform-origin:-12px,100%;transform-origin:-12px,100%}","css/joubel-help-dialog.css":"/* Main Container */\n.joubel-help-text-dialog-box {\n position: absolute;\n width: 100%;\n height: 100%;\n top: 0;\n left: 0;\n color: #555;\n z-index: 2;\n}\n\n/* Background for help dialog */\n.joubel-help-text-dialog-background {\n position: absolute;\n width: 100%;\n height: 100%;\n top: 0;\n left: 0;\n background: #555555;\n opacity: 0.75;\n}\n\n/* ------------------------------------ Main content container ------------------------ */\n.joubel-help-text-dialog-container {\n display: block;\n position: absolute;\n top: 3.5%;\n left: 20%;\n width: 60%;\n background: #fff;\n opacity: 1;\n max-height: 93%;\n overflow: auto;\n}\n\n/* Header */\n.joubel-help-text-header {\n font-size: 1.1em;\n border-bottom: 1px solid #E0E0E0;\n padding: 0.75em 3em 0.75em 1.5em;\n}\n\n/* Body */\n.joubel-help-text-body {\n padding: 0.5em 1.5em;\n margin: 1em 0 2em;\n}\n\n/* Close help dialog container */\n.joubel-help-text-remove {\n position: absolute;\n right: 1.5em;\n top: 0.8em;\n cursor: pointer;\n}\n\n.joubel-help-text-remove:hover {\n color: #333;\n}\n\n.joubel-help-text-remove:before {\n font-family: \u0027H5PFontAwesome4\u0027;\n content: \u0027\\f00d\u0027;\n font-size: 1.3em;\n right: 0em;\n top: 0em;\n}\n","css/joubel-message-dialog.css":"@CHARSET \"UTF-8\";\n\n.joubel-message-dialog {\n position: absolute;\n bottom: 0;\n left: 0;\n right: 0;\n width: 100%;\n padding: .3em;\n z-index: 11;\n box-sizing: border-box;\n -moz-box-sizing: border-box;\n border-top: 1px solid #ffcd0d;\n background-color: #fcffcc;\n text-align: center;\n font-size: 0.8em;\n}\n.joubel-message-dialog:before {\n font-family: \u0027H5PFontAwesome4\u0027;\n content: \u0027\\f05a\u0027;\n padding-right: .5em;\n font-size: 1.3em;\n position: relative;\n top: 0.1em;\n}","css/joubel-progress-circle.css":".joubel-progress-circle-wrapper{\n display: inline-block;\n padding: 0em 1em;\n}\n.joubel-progress-circle-percentage{\n position: relative;\n font-size: 1em;\n}\n\n.joubel-progress-circle-circle{\n -webkit-transform: rotate(0deg);\n -ms-transform: rotate(0deg);\n transform: rotate(0deg);\n\n display: -webkit-box; /* OLD - iOS 6-, Safari 3.1-6 */\n display: -ms-flexbox; /* TWEENER - IE 10 */\n display: -webkit-flex; /* NEW - Chrome */\n display: flex; /* NEW, Spec - Opera 12.1, Firefox 20+ */\n\n -webkit-align-items: center;\n -webkit-box-align: center;\n -ms-flex-align: center;\n align-items: center;\n\n -webkit-justify-content: center;\n -webkit-box-pack: center;\n -ms-flex-pack: center;\n justify-content: center;\n\n position: relative;\n\n top: 0.151em;\n left: 0.151em;\n text-align: center;\n width: 2.7em;\n height: 2.7em;\n\n -webkit-border-radius: 100%; /* Safari 3-4, iOS 1-3.2, Android 1.6- */\n -moz-border-radius: 100%; /* Firefox 1-3.6 */\n border-radius: 100%; /* Opera 10.5, IE 9, Safari 5, Chrome, Firefox 4, iOS 4, Android 2.1+ */\n\n background-color: #fff;\n}\n\n.joubel-progress-circle-active-border{\n position: relative;\n text-align: center;\n width: 3em;\n height: 3em;\n\n -webkit-border-radius: 100%; /* Safari 3-4, iOS 1-3.2, Android 1.6- */\n -moz-border-radius: 100%; /* Firefox 1-3.6 */\n border-radius: 100%; /* Opera 10.5, IE 9, Safari 5, Chrome, Firefox 4, iOS 4, Android 2.1+ */\n\n background-color: #1a73d9;\n}\n","css/joubel-simple-rounded-button.css":".joubel-simple-rounded-button {\n cursor: pointer;\n display: inline-block;\n margin: 0.25em 0;\n padding: 0.3em 1.2em;\n border-radius: 2em;\n background-color: #1a73d9;\n color: #FFFFFF;\n}\n\n.joubel-simple-rounded-button:hover,\n.joubel-simple-rounded-button:focus {\n background-color: #1356a3;\n}\n\n.joubel-simple-rounded-button:active {\n position: relative;\n background-color: #104888;\n\n -webkit-box-shadow: inset 0 4px 0px #0e407a;\n -moz-box-shadow: inset 0 4px 0px #0e407a;\n box-shadow: inset 0 4px 0px #0e407a;\n}\n\n.joubel-simple-rounded-button:active .joubel-simple-rounded-button-text {\n position: relative;\n top: 2px;\n}\n","css/joubel-speech-bubble.css":"@CHARSET \"UTF-8\";\n\n.joubel-speech-bubble {\n position: absolute;\n color: #333;\n z-index: 301;\n margin-top: 0.45em;\n min-width: 1em;\n opacity: 0;\n transition: opacity 0.5s ease;\n}\n.joubel-speech-bubble p {\n margin: 0.75em 0;\n}\n.joubel-speech-bubble p:first-child {\n margin-top: 0.25em;\n}\n.joubel-speech-bubble p:last-child {\n margin-bottom: 0.25em;\n}\n.joubel-speech-bubble.show {\n opacity: 1;\n}\n.joubel-speech-bubble-inner {\n background: #fbfbfb;\n box-shadow: 0 0 0.5em #2c2c2c;\n border-radius: 0.5em;\n padding: 0.2em 0.5em;\n text-align: left;\n position: relative;\n word-wrap: break-word; /* Long words have to break */\n z-index: 1;\n}\n.joubel-speech-bubble-inner-tail,\n.joubel-speech-bubble-tail {\n position: absolute;\n /* Setting these in pixels is intentional. We use it when calculating placement of bubble */\n width: 12px;\n height: 12px;\n background: #fbfbfb;\n -webkit-transform: rotate(45deg);\n -moz-transform: rotate(45deg);\n -ms-transform: rotate(45deg);\n -o-transform: rotate(45deg);\n transform: rotate(45deg);\n z-index: -1;\n}\n.joubel-speech-bubble-tail {\n box-shadow: 0 0 0.5em #2c2c2c;\n}\n","css/joubel-tip.css":".joubel-tip-container {\n display: inline-block;\n font-weight: normal;\n color: #777;\n cursor: pointer;\n}\n.joubel-tip-container:hover {\n color: #333;\n}\n.joubel-tip-container:focus {\n outline: 0;\n box-shadow: 0px 0px 5px 2px rgba(140,185,240,1);\n outline: rgba(140,185,240,1) solid 1px;\n}\n.joubel-tip-container.be-quiet:focus {\n outline: none;\n}\n.joubel-tip-container.be-quiet {\n pointer-events: none;\n}\n.joubel-tip-icon {\n text-align: center;\n font-size: 1.5em;\n line-height: 1.5em;\n width: 1.5em;\n height: 1.5em;\n pointer-events: none;\n}\n.joubel-tip-icon:before {\n font-family: Joubel;\n content: \"\\e888\";\n\n /* Better Font Rendering */\n -webkit-font-smoothing: antialiased;\n -moz-osx-font-smoothing: grayscale;\n}\n.joubel-tip-icon.help-icon:before {\n font-family: \u0027H5PFontAwesome4\u0027;\n content: \"\\f059\";\n}\n\n.joubel-tip-container * {\n pointer-events: none;\n}\n","css/joubel-slider.css":".h5p-joubel-ui-slider {\n -webkit-transition: -webkit-transform 0.3s ease-in-out;\n -moz-transition: -moz-transform 0.3s ease-in-out;\n -ms-transition: -ms-transform 0.3s ease-in-out;\n transition: transform 0.3s ease-in-out;\n\n /* Avoid flickering */\n -webkit-transform: translateX(0);\n -moz-transform: translateX(0);\n -ms-transform: translateX(0);\n transform: translateX(0);\n -webkit-backface-visibility: hidden;\n backface-visibility: hidden;\n\n height: 100%;\n}\n.h5p-joubel-ui-slide {\n position: absolute;\n width: 100%;\n height: 100%;\n\n top: 0;\n left: 0;\n\n display: none;\n}\n.h5p-joubel-ui-slide.current {\n display: block;\n}\n","css/joubel-score-bar.css":".h5p-joubelui-score-bar {\n display: inline-flex;\n display: -webkit-inline-flexbox;\n display: -ms-inline-flexbox;\n display: -webkit-inline-flex;\n width: 19.917em;\n max-width: 100%;\n background: #fff;\n border-radius: 1.5em;\n padding: 0.625em;\n border: 1px solid rgba(0, 0, 0, 0.08);\n box-sizing: border-box;\n position: relative;\n}\n.h5p-joubelui-score-bar-visuals {\n flex: 1;\n -webkit-box-flex: 1;\n -webkit-flex: 1;\n position: relative;\n overflow: visible;\n}\n.h5p-joubelui-score-bar-progress-wrapper {\n position: relative;\n margin-right: 1.7em;\n height: 0.917em;\n border-top-left-radius: 1.5em;\n border-bottom-left-radius: 1.5em;\n background: #ddd;\n}\n.h5p-joubelui-score-bar-progress {\n overflow: hidden;\n white-space: nowrap;\n color: transparent;\n position: absolute;\n left: 0;\n top: 0;\n height: 100%;\n width: 0;\n border-top-left-radius: .5em;\n border-bottom-left-radius: .5em;\n background: #48b57e; /* For browsers not supporting linear-gradient */\n background: linear-gradient(to right, #52ca8d, #48b57e);\n -webkit-transition: width 0.4s ease-in-out;\n -moz-transition: width 0.4s ease-in-out;\n -o-transition: width 0.4s ease-in-out;\n transition: width 0.4s ease-in-out;\n -webkit-backface-visibility: hidden;\n}\n/* The star */\n.h5p-joubelui-score-bar-star {\n height: 1.8em;\n width: 2.1em;\n position: absolute;\n right: 0;\n top: -0.4em;\n overflow: visible;\n}\n.h5p-joubelui-score-bar-full-score.h5p-joubelui-score-bar-animation-active .h5p-joubelui-score-bar-star {\n -webkit-animation: pound 0.8s 1;\n animation: pound 0.8s 1;\n}\n@keyframes pound {\n from {\n transform: scale(0);\n }\n 20% {\n transform: scale(1.4);\n }\n 60% {\n transform: scale(0.8);\n }\n 80% {\n transform: scale(1.2);\n }\n to {\n transform: scale(1);\n }\n}\n@-webkit-keyframes pound {\n from {\n -webkit-transform: scale(0);\n }\n 20% {\n -webkit-transform: scale(1.4);\n }\n 60% {\n -webkit-transform: scale(0.8);\n }\n 80% {\n -webkit-transform: scale(1.2);\n }\n to {\n -webkit-transform: scale(1);\n }\n}\n/* Styling the star */\n.h5p-joubelui-score-bar-star svg {\n overflow: visible;\n}\n.h5p-joubelui-score-bar-star-shadow {\n fill: #fff;\n}\n.h5p-joubelui-score-bar-star-border {\n fill: none;\n stroke: #ddd;\n stroke-miterlimit: 10;\n stroke-width: 3px;\n}\n.h5p-joubelui-score-bar-star-fill {\n fill: #ddd;\n}\n.h5p-joubelui-score-bar-full-score .h5p-joubelui-score-bar-star-border {\n stroke: #ab741a;\n stroke-width: 6;\n}\n.h5p-joubelui-score-bar-star-fill-full-score {\n visibility: hidden;\n fill: #ffc80b;\n}\n.h5p-joubelui-score-bar-full-score .h5p-joubelui-score-bar-star-fill {\n /* This will be a fallback for browsers not supporting the filter,\n i.e. Safari */\n fill: #ffc80b;\n}\n.h5p-joubelui-score-bar-full-score .h5p-joubelui-score-bar-star-fill-full-score {\n visibility: visible;\n}\n\n/* The numeric part on the end (score / maxScore) */\n.h5p-joubelui-score-numeric {\n margin: 0em 0.4em;\n font-size: 1.333em;\n line-height: 0.7;\n font-weight: bold;\n}\n.h5p-score-bar-has-help .h5p-joubelui-score-numeric {\n /* Need more space when icon is displayed */\n margin-right: 0.625em;\n}\n.h5p-joubelui-score-number {\n color: #333;\n}\n.h5p-joubelui-score-number-separator {\n color: #999;\n padding: 0 0.1em;\n}\n.h5p-joubelui-score-bar .joubel-tip-container {\n position: absolute;\n top: 0.1em;\n right: 0.3em;\n font-size: 1em;\n line-height: 1;\n color: #1a73d9;\n margin-right: 0.2em;\n}\n.h5p-joubelui-score-bar .joubel-tip-container \u003e .help-icon {\n font-size: 1em;\n line-height: 1;\n}\n","css/joubel-progressbar.css":".h5p-joubelui-progressbar {\n width: 100%;\n position: absolute;\n left: 0;\n bottom: 0;\n right: 0;\n height: .25em;\n background: #fff;\n -webkit-box-shadow: 0px -1px 3px 0px rgba(1,72,118,0.75);\n -moz-box-shadow: 0px -1px 3px 0px rgba(1,72,118,0.75);\n box-shadow: 0px -1px 3px 0px rgba(1,72,118,0.75);\n}\n\n.h5p-joubelui-progressbar-slide-status-text {\n font-size: 0;\n width: 0;\n height: 0;\n}\n\n.h5p-joubelui-progressbar-background {\n position: absolute;\n left: 0;\n top: 0;\n height: 100%;\n width: 0;\n background-color: #014876;\n -webkit-transition: width .3s ease-in-out;\n -moz-transition: width .3s ease-in-out;\n -o-transition: width .3s ease-in-out;\n transition: width .3s ease-in-out;\n}\n.h5p-joubelui-drop {\n z-index: 1;\n}\n.drop-element.h5p-joubelui-drop .drop-content {\n padding: .2em .8em;\n font-weight: bold;\n}\n","css/joubel-ui.css":"@CHARSET \"UTF-8\";\n\n/* Styling of button */\n.h5peditor .ui-dialog .h5p-joubelui-button,\n.h5peditor .h5p-joubelui-button,\n.h5p-joubelui-button {\n font-size: 1em;\n line-height: 1.2;\n margin: 0 0.5em 1em;\n padding: 0.5em 1.25em;\n border-radius: 2em;\n\n background: #1a73d9;\n color: #ffffff;\n\n cursor: pointer;\n border: none;\n box-shadow: none;\n -webkit-transform: translateZ(0);\n transform: translateZ(0);\n\n display: inline-block;\n text-align: center;\n text-shadow: none;\n text-decoration: none;\n vertical-align: baseline;\n}\n.h5p-joubelui-button:first-child {\n margin: 0 0.5em 1em 0;\n}\n\n.h5p-joubelui-button:last-child {\n margin: 0 0 1em 0.5em;\n}\n\n.h5p-joubelui-button:first-child:last-child {\n margin: 0 0 1em;\n}\n\n/* Truncated buttons */\n.h5p-joubelui-button.truncated {\n width: 2.235em;\n height: 2.235em;\n border-radius: 50%;\n padding: 0;\n text-align: center;\n}\n\n.h5p-joubelui-button.truncated:before {\n padding: 0;\n}\n\n.h5p-joubelui-button:hover,\n.h5p-joubelui-button:focus {\n background: #1356a3;\n color: #fff;\n text-decoration: none;\n -webkit-transition: initial;\n -moz-transition: initial;\n -o-transition: initial;\n transition: initial;\n}\n.h5p-joubelui-button:active {\n position: relative;\n background: #104888;\n\n -webkit-box-shadow: inset 0 4px 0 #0e407a;\n -moz-box-shadow: inset 0 4px 0 #0e407a;\n box-shadow: inset 0 4px 0 #0e407a;\n}\n.h5p-joubelui-button:active .h5p-joubelui-button-text {\n position: relative;\n top: 2px;\n}\n\n.h5p-joubelui-button:before {\n font-family: \u0027H5PFontAwesome4\u0027;\n padding-right: 0.5em;\n}\n\n.h5p-question-try-again:before {\n content: \"\\F01E\";\n}\n\n.h5p-question-show-solution:before {\n content: \"\\F06E\";\n}\n\n.h5p-question-check-answer:before {\n content: \"\\F058\";\n}\n","css/joubel-icon.css":"[class^=\"joubel-icon-\"], [class*=\" joubel-icon-\"] {\n /* use !important to prevent issues with browser extensions that change fonts */\n font-family: \u0027H5PFontIcons\u0027 !important;\n speak: none;\n font-size: 1.5em; \n line-height: 1.5em;\n font-style: normal;\n font-weight: normal;\n font-variant: normal;\n text-transform: none;\n word-wrap: normal;\n cursor: pointer;\n\n /* Better Font Rendering =========== */\n -webkit-font-smoothing: antialiased;\n -moz-osx-font-smoothing: grayscale;\n}\n\n/* Comment icon */\n.joubel-icon-comment-normal .h5p-icon-shadow:before {\n content: \"\\e90a\";\n color: rgb(221, 221, 221);\n}\n.joubel-icon-comment-normal .h5p-icon-speech-bubble:before {\n content: \"\\e908\";\n margin-left: -1em;\n color: rgb(206, 114, 193);\n}\n.joubel-icon-comment-normal .h5p-icon-question:before {\n content: \"\\e906\";\n margin-left: -1em;\n color: rgb(255, 255, 255);\n}\n.joubel-icon-comment-normal:hover .h5p-icon-speech-bubble:before {\n color: rgb(188, 92, 163);\n}\n.joubel-icon-comment-normal:active .h5p-icon-speech-bubble:before {\n color: rgb(206, 114, 193);\n position: relative;\n top: 0.05em;\n left: 0.05em;\n}\n.joubel-icon-comment-normal:active .h5p-icon-question:before {\n position: relative;\n top: 0.05em;\n left: 0.05em;\n}\n\n/* Tip icon */\n.joubel-icon-tip-normal .h5p-icon-shadow:before {\n content: \"\\e90a\";\n color: rgb(221, 221, 221);\n}\n.joubel-icon-tip-normal .h5p-icon-speech-bubble:before {\n content: \"\\e908\";\n margin-left: -1em;\n color: rgb(53, 128, 195);\n}\n.joubel-icon-tip-normal .h5p-icon-info:before {\n content: \"\\e905\";\n margin-left: -1em;\n color: rgb(255, 255, 255);\n}\n.joubel-icon-tip-normal:hover .h5p-icon-speech-bubble:before {\n color: rgb(72, 155, 213);\n}\n.joubel-icon-tip-normal:active .h5p-icon-speech-bubble:before {\n color: rgb(72, 155, 213);\n position: relative;\n top: 0.05em;\n left: 0.05em;\n}\n.joubel-icon-tip-normal:active .h5p-icon-info:before {\n position: relative;\n top: 0.05em;\n left: 0.05em;\n}\n\n/* Edit icon */\n.joubel-icon-edit .h5p-icon-circle:before {\n content: \"\\e90d\";\n color: #1d74c8;\n font-size: 1.5em;\n}\n.joubel-icon-edit .h5p-icon-pencil:before {\n content: \"\\e90c\";\n color: #1d74c8;\n font-size: 0.8em;\n text-align: center;\n position: absolute;\n margin-left: -1.42em;\n}\n.joubel-icon-edit:hover .h5p-icon-circle:before {\n content: \"\\e90e\";\n color: #1d74c8;\n}\n.joubel-icon-edit:hover .h5p-icon-pencil:before {\n color: #ffffff;\n}\n\n/* Approve icon */\n.joubel-icon-approve .h5p-icon-circle:before {\n content: \"\\e90d\";\n color: #3ea35f;\n font-size: 1.5em;\n}\n.joubel-icon-approve .h5p-icon-check:before {\n content: \"\\e601\";\n color: #3ea35f;\n font-size: 0.8em;\n text-align: center;\n position: absolute;\n margin-left: -1.42em;\n}\n.joubel-icon-approve:hover .h5p-icon-circle:before {\n content: \"\\e90e\";\n}\n.joubel-icon-approve:hover .h5p-icon-check:before {\n color: #ffffff;\n}\n\n/* Cancel icon */\n.joubel-icon-cancel .h5p-icon-circle:before {\n content: \"\\e90d\";\n color: #de3354;\n font-size: 1.5em;\n}\n.joubel-icon-cancel .h5p-icon-cross:before {\n content: \"\\e600\";\n color: #de3354;\n font-size: 0.8em;\n text-align: center;\n position: absolute;\n margin-left: -1.42em;\n}\n.joubel-icon-cancel:hover .h5p-icon-circle:before {\n content: \"\\e90e\";\n}\n.joubel-icon-cancel:hover .h5p-icon-cross:before {\n color: #ffffff;\n}\n\n/* Custom override CSS */\n.joubel-icon-tip-normal.help-icon:before {\n font-family: \u0027H5PFontAwesome4\u0027;\n content: \"\\f059\";\n}\n\n/* Hide icon layers if using font awesome */\n.joubel-icon-tip-normal.help-icon \u003e span {\n display: none;\n}\n","styles/question.css":".h5p-question {\n background: rgba(255, 255, 255, 0.9);\n position: relative;\n}\n.h5p-question-video {\n line-height: 0;\n}\n.h5p-question-video \u003e video {\n width: 100%;\n}\n.h5p-question-image {\n text-align: left;\n margin: 0 0 1em;\n line-height: 0.8125em;\n}\n.h5p-question-image img {\n display: block;\n width: 100%;\n height: auto;\n border: 0;\n outline: none;\n}\n\n.h5p-question-image-wrap {\n display: inline-block;\n position: relative;\n margin-bottom: 1em;\n -webkit-transform: translate(1em, 1em);\n transform: translate(1em, 1em);\n max-width: calc(100% - 2em);\n}\n\n.h5p-question-image.animatable .h5p-question-image-wrap.h5p-question-image-scalable {\n -webkit-transition: -webkit-transform 0.3s 0.3s, margin 0.3s 0.3s, width 0.3s 0s;\n transition: transform 0.3s 0.3s, margin 0.3s 0.3s, width 0.3s 0s;\n}\n\n.h5p-question-image.animatable.h5p-question-image-fill-width .h5p-question-image-wrap {\n -webkit-transition: -webkit-transform 0.3s 0s, margin 0.3s 0s, width 0.3s 0.3s;\n transition: transform 0.3s 0s, margin 0.3s 0s, width 0.3s 0.3s;\n}\n\n.h5p-question-image-overlay {\n display: none;\n position: absolute;\n left: 0;\n top: 0;\n width: 100%;\n height: 100%;\n}\n\n.h5p-question-image-overlay.show {\n display: block;\n}\n\n.h5p-question-image-fill-width .h5p-question-image-wrap,\n.h5p-no-frame \u003e .h5p-question .h5p-question-image-wrap,\n.h5p-transparent \u003e div \u003e .h5p-question .h5p-question-image-wrap {\n -webkit-transform: translate(0, 0);\n transform: translate(0, 0);\n margin: 0;\n max-width: 100%;\n}\n\n.h5p-question-image-scalable {\n cursor: pointer;\n width: 35%;\n}\n\n.h5p-question-image.h5p-question-image-fill-width .h5p-question-image-scalable{\n width: 100%;\n}\n\n.h5p-question-image-scalable:before {\n position: absolute;\n font-family: \u0027H5PFontAwesome4\u0027;\n content: \"\\f067\";\n right: 0.7em;\n top: 0.7em;\n color: #fff;\n font-size: 10px;\n -webkit-border-radius: 50%;\n -moz-border-radius: 50%;\n border-radius: 50%;\n background: rgba(0, 0, 0, 0.5);\n width: 1.8em;\n height: 1.8em;\n line-height: 1.8em;\n text-align: center;\n}\n\n.h5p-question-image-fill-width .h5p-question-image-scalable:before {\n content: \"\\f068\";\n}\n\n.h5p-question-introduction {\n margin: 1em;\n}\n\n.h5p-question-introduction {\n font-size: 1.125em;\n line-height: 1.125em;\n}\n\n.h5p-question-introduction \u003e p {\n font-size: inherit;\n line-height: inherit;\n margin: 0;\n}\n\n.h5p-question-content {\n margin: 1em;\n}\n\n.h5p-question-content.h5p-has-question-popup {\n position: relative;\n}\n\n.h5p-question-feedback {\n font-weight: bold;\n color: #1a73d9;\n margin: 0 1em;\n max-height: 0;\n opacity: 0;\n transition: max-height 0.15s ease, margin 0.15s ease, opacity 0.15s cubic-bezier(0,1,0,1);\n}\n\n.h5p-question-feedback.h5p-question-visible {\n opacity: 40%;\n margin: 1em;\n opacity: 1;\n transition: max-height 0.15s ease, margin 0.15s ease, opacity 0.15s ease-in;\n}\n.h5p-question-feedback-content {\n font-size: 1em;\n display: none;\n -webkit-backface-visibility: hidden;\n backface-visibility: hidden;\n}\n\n.h5p-question-feedback-content.has-content {\n display: block;\n margin-bottom: 0.8em;\n}\n\n.h5p-question-feedback-content-text {\n display: inline-block;\n}\n\n.h5p-question-buttons {\n margin: 0 1em;\n max-height: 0;\n opacity: 0;\n transition: max-height 0.15s ease, margin 0.15s ease, opacity 0.15s cubic-bezier(0,1,0,1);\n}\n.h5p-question-buttons.h5p-question-visible {\n max-height: none;\n opacity: 1;\n transition: max-height 0.15s ease, margin 0.15s ease, opacity 0.15s ease-in;\n}\n\n.h5p-question-feedback.h5p-question-popup .h5p-question-buttons {\n height: 3.14286em;\n max-height: 3.14286em;\n transition: none;\n}\n\n/* Remove margins when no frame or transparent */\n.h5p-no-frame \u003e .h5p-question \u003e *,\n.h5p-transparent \u003e div \u003e .h5p-question \u003e * {\n margin-left: 0;\n margin-right: 0;\n}\n\n.h5p-no-frame \u003e .h5p-question \u003e *:first-child,\n.h5p-transparent \u003e div \u003e .h5p-question \u003e *:first-child {\n margin-top: 0;\n}\n\n.h5p-no-frame \u003e .h5p-question \u003e *:last-child,\n.h5p-transparent \u003e div \u003e .h5p-question \u003e *:last-child {\n margin-bottom: 0;\n}\n\n/* CP specific styles */\n.h5p-course-presentation .h5p-question-introduction {\n font-size: 1.125em;\n line-height: 1.125em;\n}\n\n.h5p-course-presentation .h5p-question-introduction \u003e p {\n font-size: 1em;\n line-height: 1em;\n margin: 0;\n}\n.h5p-question .h5p-hidden-read {\n width: 1px;\n height: 1px;\n top: -1px;\n position: absolute;\n text-indent: 1px;\n overflow: hidden;\n}\n\n.h5p-question-popups {\n position: absolute;\n top: 0;\n left: 0;\n height: 100%;\n width: 100%;\n}\n\n.h5p-question-popups.hidden {\n display: none;\n}\n\n.h5p-question-feedback.h5p-question-popup {\n position: absolute;\n display: none;\n width: 22em;\n max-width: 100%;\n margin: 0;\n z-index: 3;\n background-color: white;\n box-shadow: 0px 0px 7px 0px rgba(0, 0, 0, 0.59);\n border-radius: 1em;\n padding: 1.5em;\n transition: none;\n}\n\n.h5p-question-feedback.h5p-question-popup.h5p-question-visible {\n display: block;\n box-sizing: border-box;\n max-height: 100%;\n}\n\n.h5p-question-feedback.h5p-question-popup .h5p-question-feedback-content {\n display: block;\n top: 0;\n}\n\n.h5p-question-feedback.h5p-question-popup.h5p-question-feedback-correct .h5p-question-feedback-content {\n margin-right: 1.5em;\n}\n\n.h5p-question-feedback.h5p-question-popup .h5p-question-retry-button {\n margin: 1em 0 0 0;\n}\n\n.h5p-question-feedback.h5p-question-popup .h5p-question-buttons {\n margin: 0;\n}\n\n.h5p-question-feedback.h5p-question-popup .h5p-question-feedback-close {\n position: absolute;\n right: 0;\n top: 0;\n margin: 1em;\n cursor: pointer;\n}\n\n.h5p-question-feedback.h5p-question-popup .h5p-question-feedback-close:before {\n font-family: \u0027h5pFontIcons\u0027;\n font-size: 2.5em;\n line-height: 0.9em;\n content: \u0027\\e600\u0027;\n color: #707070;\n}\n\n.h5p-question-feedback-tail {\n position: absolute;\n width: 1em;\n height: 1em;\n z-index: 3;\n background-color: white;\n box-shadow: -2px -2px 0px 0px rgba(0, 0, 0, 0.18);\n transform: rotate(225deg);\n}\n\n.h5p-question-plus-one,\n.h5p-question-minus-one {\n position: absolute;\n width: 1.923076923em;\n height: calc(1.923076923em * 0.638297872);\n background-size: 100% 100%;\n right: -1.615384615em;\n top: -0.846153846em;\n z-index: 1;\n opacity: 1;\n transition: opacity 150ms linear, transform 150ms linear;\n}\n.h5p-question-plus-one {\n background-image: url(../images/plus-one.svg);\n}\n.h5p-question-minus-one {\n background-image: url(../images/minus-one.svg);\n}\n.h5p-question-hidden-one {\n opacity: 0;\n transform: translateY(100%);\n}\n","styles/explainer.css":".h5p-question-explanation {\n /* Needed this to make it display in IE 11 */\n position: relative;\n}\n\n.h5p-question-explanation-container {\n margin: 0;\n padding: 1em;\n background: #FAFAFA;\n}\n\n.h5p-question-explanation-title {\n font-size: 1.125em;\n margin-bottom: 0.5em;\n}\n\n.h5p-question-explanation-list {\n background: #FFFFFF;\n border: 1px solid #e0e0e0;\n overflow: auto;\n overflow-x: hidden;\n\n list-style: none;\n padding: 0;\n margin: 0;\n}\n\n.h5p-question-explanation-item {\n padding: 0.5em;\n margin: 0;\n line-height: 1.2;\n display: flex;\n}\n\n.h5p-question-explanation-item:not(:last-child) {\n border-bottom: 1px solid #e0e0e0;\n}\n\n.h5p-question-explanation-status {\n display: flex;\n flex-shrink: 0;\n width: 8em;\n flex-wrap: wrap;\n}\n\n.h5p-question-explanation-correct,\n.h5p-question-explanation-wrong {\n display: inline-flex;\n font-weight: bold;\n margin-left: 0.5em;\n font-size: 0.9em;\n\n word-break: break-all;\n /* Non standard for WebKit */\n word-break: break-word;\n}\n\n.h5p-question-explanation-correct {\n color: #265c42;\n}\n\n.h5p-question-explanation-wrong {\n color: #b61c1e;\n text-decoration: line-through;\n}\n\n.h5p-question-explanation-text {\n display: inline-flex;\n padding-left: 1em;\n margin-left: 0.5em;\n border-left: 1px solid #ddd;\n}\n\n.h5p-question-explanation-list::-webkit-scrollbar {\n width: 0.4em;\n}\n\n.h5p-question-explanation-list::-webkit-scrollbar-thumb {\n background-color: #e0e0e0;\n}\n","styles/css/vertical-tabs.css":"/* line 3, ../scss/vertical-tabs.scss */\n.h5p-vtab-wrapper:after {\n visibility: hidden;\n display: block;\n font-size: 0;\n content: \u0027 \u0027;\n clear: both;\n height: 0;\n}\n\n/* line 12, ../scss/vertical-tabs.scss */\n.h5p-vtabs {\n float: left;\n width: 212px;\n position: relative;\n padding: 0;\n}\n\n/* line 18, ../scss/vertical-tabs.scss */\n.h5p-vtab-forms {\n border: 1px solid #d0d0d1;\n margin-left: 217px;\n}\n\n/* line 22, ../scss/vertical-tabs.scss */\n.h5p-vtab-form {\n position: relative;\n display: none;\n margin: 0;\n border: none;\n padding: 0;\n}\n\n/* line 29, ../scss/vertical-tabs.scss */\n.h5p-vtab-form.h5p-current {\n display: block;\n}\n\n/* line 32, ../scss/vertical-tabs.scss */\n.h5p-vtab-form \u003e .field {\n margin: 0;\n}\n\n/* line 35, ../scss/vertical-tabs.scss */\n.h5p-vtabs .h5p-vtab-li,\n.h5p-vtabs .h5p-placeholder {\n position: relative;\n padding: 0;\n margin: 0 0 3px 0;\n}\n\n/* line 42, ../scss/vertical-tabs.scss */\n.h5p-vtab-a {\n border: 1px solid #d0d0d1;\n background-color: #f5f5f5;\n height: 38px;\n font-size: 14px;\n font-weight: 600;\n line-height: 38px;\n -webkit-font-smoothing: antialiased;\n -moz-osx-font-smoothing: grayscale;\n padding: 0 30px;\n margin: 0 12px 0 0;\n cursor: pointer;\n overflow: hidden;\n white-space: nowrap;\n text-overflow: ellipsis;\n outline: none;\n}\n\n/* line 61, ../scss/vertical-tabs.scss */\n.h5p-vtabs .h5p-vtab-li.h5p-current .h5p-vtab-a {\n background: #747275;\n border: 1px solid #636164;\n border-right: 0;\n color: white;\n}\n/* line 68, ../scss/vertical-tabs.scss */\n.h5p-vtabs .h5p-vtab-li.h5p-current:after, .h5p-vtabs .h5p-vtab-li.h5p-current:before {\n position: absolute;\n left: 200px;\n content: \" \";\n width: 0;\n height: 0;\n}\n/* line 77, ../scss/vertical-tabs.scss */\n.h5p-vtabs .h5p-vtab-li.h5p-current:before {\n top: 0;\n border-top: 20px solid transparent;\n border-bottom: 20px solid transparent;\n border-left: 13px solid #636164;\n}\n/* line 84, ../scss/vertical-tabs.scss */\n.h5p-vtabs .h5p-vtab-li.h5p-current:after {\n top: 1px;\n border-top: 19px solid transparent;\n border-bottom: 19px solid transparent;\n border-left: 12px solid #747275;\n}\n/* line 92, ../scss/vertical-tabs.scss */\n.h5p-vtabs .h5p-vtab-li.h5p-current \u003e .vtab-order-wrapper \u003e .order-up,\n.h5p-vtabs .h5p-vtab-li.h5p-current \u003e .vtab-order-wrapper \u003e .order-down {\n background: #636164;\n}\n/* line 96, ../scss/vertical-tabs.scss */\n.h5p-vtabs .h5p-vtab-li.h5p-current \u003e .vtab-order-wrapper \u003e .order-up[aria-disabled=\"false\"]:hover,\n.h5p-vtabs .h5p-vtab-li.h5p-current \u003e .vtab-order-wrapper \u003e .order-down[aria-disabled=\"false\"]:hover {\n background: #49484a;\n}\n/* line 100, ../scss/vertical-tabs.scss */\n.h5p-vtabs .h5p-vtab-li.h5p-current \u003e .vtab-order-wrapper \u003e .order-up:after,\n.h5p-vtabs .h5p-vtab-li.h5p-current \u003e .vtab-order-wrapper \u003e .order-down:after {\n color: white;\n}\n\n/* line 107, ../scss/vertical-tabs.scss */\n.h5p-placeholder \u003e .h5p-vtab-a {\n background: #e8f2fa;\n border: dashed 2px #2782d1;\n height: 36px;\n}\n\n/* line 113, ../scss/vertical-tabs.scss */\n.h5p-vtabs \u003e button {\n float: right;\n margin: 8px 14px 8px 8px;\n}\n\n/* line 118, ../scss/vertical-tabs.scss */\n.h5p-vtabs .h5p-moving {\n position: absolute;\n z-index: 1;\n}\n/* line 122, ../scss/vertical-tabs.scss */\n.h5p-vtabs .h5p-moving \u003e .h5p-vtab-a {\n cursor: grabbing;\n cursor: -moz-grabbing;\n cursor: -webkit-grabbing;\n}\n\n/* line 129, ../scss/vertical-tabs.scss */\n.vtab-order-wrapper {\n position: absolute;\n top: 1px;\n left: 1px;\n}\n/* line 134, ../scss/vertical-tabs.scss */\n.vtab-order-wrapper \u003e .order-up,\n.vtab-order-wrapper \u003e .order-down {\n width: 19px;\n height: 19px;\n background: #d0d0d1;\n font-size: 14px;\n line-height: 19px;\n cursor: pointer;\n text-align: center;\n}\n/* line 144, ../scss/vertical-tabs.scss */\n.vtab-order-wrapper \u003e .order-up[aria-disabled=\"false\"]:hover,\n.vtab-order-wrapper \u003e .order-down[aria-disabled=\"false\"]:hover {\n background-color: #b6b6b8;\n}\n/* line 148, ../scss/vertical-tabs.scss */\n.vtab-order-wrapper \u003e .order-up:before,\n.vtab-order-wrapper \u003e .order-down:before {\n right: auto;\n left: -5px;\n}\n/* line 153, ../scss/vertical-tabs.scss */\n.vtab-order-wrapper \u003e .order-up[aria-disabled=\"true\"],\n.vtab-order-wrapper \u003e .order-down[aria-disabled=\"true\"] {\n cursor: default;\n}\n/* line 156, ../scss/vertical-tabs.scss */\n.vtab-order-wrapper \u003e .order-up[aria-disabled=\"true\"]:after,\n.vtab-order-wrapper \u003e .order-down[aria-disabled=\"true\"]:after {\n opacity: 0.25;\n}\n/* line 162, ../scss/vertical-tabs.scss */\n.vtab-order-wrapper \u003e .order-up:after {\n font-family: \"H5P\";\n content: \"\\e58e\";\n}\n/* line 167, ../scss/vertical-tabs.scss */\n.vtab-order-wrapper \u003e .order-down {\n top: auto;\n bottom: 1px;\n}\n/* line 171, ../scss/vertical-tabs.scss */\n.vtab-order-wrapper \u003e .order-down:after {\n font-family: \"H5P\";\n content: \"\\e58f\";\n}\n\n/* line 178, ../scss/vertical-tabs.scss */\n.vtab-remove-wrapper {\n position: absolute;\n top: 1px;\n right: 12px;\n}\n/* line 183, ../scss/vertical-tabs.scss */\n.vtab-remove-wrapper \u003e .remove {\n cursor: pointer;\n width: 1.25em;\n height: 38px;\n font-size: 1.75em;\n text-align: center;\n}\n/* line 190, ../scss/vertical-tabs.scss */\n.vtab-remove-wrapper \u003e .remove:after {\n font-family: \"H5P\";\n content: \"\\e890\";\n color: #454347;\n opacity: 0.7;\n display: inline-block;\n line-height: 38px;\n}\n/* line 198, ../scss/vertical-tabs.scss */\n.vtab-remove-wrapper \u003e .remove:after:hover {\n opacity: 1;\n}\n\n/* line 205, ../scss/vertical-tabs.scss */\n.h5p-current \u003e .vtab-remove-wrapper \u003e .remove:after {\n color: #fff;\n}\n\n/* line 209, ../scss/vertical-tabs.scss */\n.h5peditor-button.add-entity {\n width: 200px;\n height: 40px;\n background: #2579C6 linear-gradient(#3080c9 50%, transparent 50%, transparent);\n border: 1px solid #1f67a8;\n color: white;\n font-weight: 600;\n font-size: 14px;\n box-sizing: border-box;\n text-align: center;\n cursor: pointer;\n text-transform: uppercase;\n line-height: 28px;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n padding: 0 5px;\n border-radius: 3px;\n margin-top: 5px;\n}\n/* line 230, ../scss/vertical-tabs.scss */\n.h5peditor-button.add-entity:hover {\n background: #1f67a8 linear-gradient(#2a6fac 50%, transparent 50%, transparent);\n}\n/* line 234, ../scss/vertical-tabs.scss */\n.h5peditor-button.add-entity:before {\n font-family: \"H5P\";\n content: \"\\e902\";\n margin-right: -4px;\n font-weight: 400;\n font-size: 24px;\n transform: translate(-30%,15%);\n display: inline-block;\n}\n\n/* line 243, ../scss/vertical-tabs.scss */\n.h5p-vtab-form \u003e .library,\n.h5p-vtab-form \u003e .list,\n.h5p-vtab-form \u003e .group \u003e .content {\n padding: 10px;\n border: none;\n}\n","h5p-editor-table-list.css":".h5p-editor-table-list {\n width: 100%;\n table-layout: fixed;\n border-spacing: 0 5px;\n empty-cells: show;\n}\n.h5p-editor-table-list thead th,\n.h5p-editor-table-list tbody td {\n text-align: left;\n padding: 10px 5px;\n}\n.h5p-editor-table-list thead th:first-child,\n.h5p-editor-table-list tbody td:first-child {\n padding-left: 10px;\n}\n.h5p-editor-table-list thead th:last-child,\n.h5p-editor-table-list tbody td:last-child {\n padding-right: 10px;\n}\n.h5p-editor-table-list thead th.h5peditor-type-number {\n width: 75px;\n}\n.h5p-editor-table-list thead th.h5peditor-remove-header {\n width: 32px;\n}\n.h5p-editor-table-list tbody td {\n background: #f5f5f5;\n border-top: 1px solid #d0d0d1;\n border-bottom: 1px solid #d0d0d1;\n vertical-align: top;\n}\n.h5p-editor-table-list tbody td:first-child {\n border-left: 1px solid #d0d0d1;\n border-radius: .25em 0 0 .25em;\n}\n.h5p-editor-table-list tbody td:last-child {\n border-right: 1px solid #d0d0d1;\n border-radius: 0 .25em .25em 0;\n}\n.h5p-editor-table-list tfoot .h5peditor-button {\n margin-top: 0;\n}\n.h5p-editor-table-list td.h5peditor-remove-button {\n position: relative;\n}\n.h5p-editor-table-list td.h5peditor-remove-button .h5peditor-button {\n cursor: pointer;\n width: 32px;\n display: inline-block;\n height: 38px;\n font-size: 1.75em;\n}\n.h5p-editor-table-list td.h5peditor-remove-button .h5peditor-button:after {\n font-family: \"H5P\";\n content: \"\\e890\";\n opacity: 0.7;\n display: inline-block;\n line-height: 38px;\n}\n.h5p-editor-table-list td.h5peditor-remove-button .h5peditor-button:hover:after {\n opacity: 1;\n}\n.h5p-editor-table-list td.h5peditor-remove-button .h5peditor-button[aria-label]:before {\n top: 85%;\n right: 10%;\n}\n.h5p-editor-table-list td.h5peditor-remove-button .h5peditor-button[aria-disabled=\"true\"] {\n cursor: default;\n}\n.h5p-editor-table-list td.h5peditor-remove-button .h5peditor-button[aria-disabled=\"true\"]:after {\n opacity: 0.3;\n}\n.h5p-editor-table-list tbody .h5p-errors \u003e p {\n white-space: nowrap;\n margin: 6px 0 0 6px;\n font-size: 14px;\n}\n","h5p-editor-range-list.css":".h5p-editor-range-list thead th.h5peditor-type-number {\n white-space: nowrap;\n width: 65px;\n}\n.h5p-editor-range-list thead th.h5peditor-dash {\n width: 6px;\n}\n.h5p-editor-range-list tbody td.h5peditor-dash {\n line-height: 37px;\n}\n.h5p-editor-range-list .h5peditor-input-text {\n line-height: 38px;\n height: 38px;\n text-align: center;\n}\n.h5p-editor-range-list .number input {\n text-align: center;\n width: 65px;\n}\n.h5p-editor-range-list thead th.h5peditor-remove-header {\n position: relative;\n}\n.h5peditor-range-distribute {\n white-space: nowrap;\n font-weight: normal;\n font-size: 14px;\n padding: 0 20px;\n margin-left: 1em;\n height: 42px;\n line-height: 42px;\n\n color: #2579c6;\n font-weight: bold;\n background: #fff;\n border: 2px solid #2579c6;\n}\n.h5peditor-button-textual.h5peditor-range-distribute:hover {\n color: #1f67a8;\n border-color: #1f67a8;\n background: #fff;\n}\n.h5peditor-range-distribute[aria-disabled=\"true\"],\n.h5peditor-button-textual.h5peditor-range-distribute[aria-disabled=\"true\"]:hover {\n cursor: default;\n color: #8fb3d3;\n border-color: #8fb3d3;\n background: #fff;\n}\n.h5p-editor-table-list tbody .h5p-error-range-overlap td {\n border-color: #da0001;\n}\n.h5p-editor-range-list-message-area {\n display: none;\n background: #f4ecec;\n border-left: 2px solid #ad5b52;\n padding: 1em;\n margin-bottom: 0.5em;\n}\n.h5p-editor-range-list-message-area.problem-found {\n display: block;\n}\n","h5p-show-when.css":".h5p-editor-widget-show-when.hidden {\n display: none;\n}\n","styles/single-choice-set.css":".h5p-container.h5p-single-choice-set {\n overflow: hidden;\n}\n.h5p-container .h5p-sc-set ul {\n margin: 1em;\n padding: 0;\n}\n.h5p-sc-set-wrapper.initialized {\n overflow: hidden;\n -ms-scroll-limit: 0 0 0 0; /* IE11 bugfix for where this element can be out of line, when focusing on elements. */\n height: 100%;\n}\n\n.h5p-sc-set-wrapper.next-button-mode {\n margin-bottom: 2.5em;\n}\n\n.h5p-sc-set {\n height: 100%;\n padding: 0.5em;\n position: relative;\n box-sizing: border-box;\n}\n\n.h5p-single-choice-set .h5p-joubelui-progressbar {\n height: 5px; /* Setting height in px is intentional. We don\u0027t want it to ever get bigger */\n background-color: rgb(102, 102, 102);\n box-shadow: none;\n z-index: 1;\n}\n\n.h5p-single-choice-set .h5p-joubelui-progressbar-background {\n box-shadow: 0 0 0.25em 0 #fff;\n background-color: #0097fd;\n}\n\n.h5p-sc-set.h5p-sc-animate {\n transition: -webkit-transform 0.25s ease-in-out;\n transition: transform 0.25s ease-in-out;\n}\n.h5p-sc {\n box-sizing: border-box;\n width: 100%;\n height: auto;\n position: absolute;\n left: 0;\n top: 0;\n padding-bottom: .5em;\n}\n.initialized .h5p-sc-slide {\n display: none;\n}\n.initialized .h5p-sc-slide.h5p-sc-current-slide {\n display: block;\n}\n\n.h5p-ssc-next-button {\n display: none;\n position: absolute;\n right: 0.5em;\n bottom: 0;\n width: 2.1875em;\n padding: 0.5em 0;\n transition: transform 0.2s;\n font-family: H5PFontAwesome4;\n text-align: center;\n}\n.h5p-ssc-next-button:before {\n content: \"\\f054\";\n position: relative;\n left: 2px;\n padding: 0;\n}\n.h5p-ssc-next-button:active {\n /* Overriding JoubelUI, which sets it to relative positioning */\n position: absolute;\n}\n.navigatable .h5p-ssc-next-button {\n display: inline-block;\n}\n.h5p-ssc-next-button[aria-disabled=\"true\"] {\n transform: scale(0.01);\n visibility: hidden;\n}\n\nul.h5p-sc-alternatives {\n margin: 0;\n padding: 0;\n}\nul.h5p-sc-alternatives li.h5p-sc-alternative {\n position: relative;\n cursor: pointer;\n box-sizing: border-box;\n list-style: none;\n margin: .5em 0;\n padding: .4em 1.2em;\n background: #ddd;\n overflow: hidden;\n -webkit-border-radius: 0.25em;\n -moz-border-radius: 0.25em;\n border-radius: 0.25em;\n box-shadow: 0 0.1em 0 rgba(0,0,0, 0.3);\n\n transition: -webkit-transform 0.5s ease-in-out, width 0.5s ease-in-out;\n transition: transform 0.5s ease-in-out, width 0.5s ease-in-out;\n}\n\nul.h5p-sc-alternatives li.h5p-sc-alternative:hover,\nul.h5p-sc-alternatives li.h5p-sc-alternative:focus {\n background: #edd6e9;\n}\n\nul.h5p-sc-alternatives.h5p-sc-selected li.h5p-sc-alternative,\nul.h5p-sc-alternatives.h5p-sc-selected li.h5p-sc-alternative:hover,\nul.h5p-sc-alternatives.h5p-sc-selected li.h5p-sc-alternative:active,\nul.h5p-sc-alternatives.h5p-sc-selected li.h5p-sc-alternative:focus,\nul.h5p-sc-alternatives.h5p-sc-selected li.h5p-sc-alternative.h5p-sc-reveal-wrong:hover,\nul.h5p-sc-alternatives.h5p-sc-selected li.h5p-sc-alternative.h5p-sc-reveal-wrong:active,\nul.h5p-sc-alternatives.h5p-sc-selected li.h5p-sc-alternative.h5p-sc-reveal-wrong:focus {\n background: #ddd;\n -webkit-box-shadow: none;\n -moz-box-shadow: none;\n box-shadow: none;\n}\n\nul.h5p-sc-alternatives.h5p-sc-selected li.h5p-sc-alternative.h5p-sc-reveal-correct,\nul.h5p-sc-alternatives.h5p-sc-selected li.h5p-sc-alternative.h5p-sc-reveal-correct:hover,\nul.h5p-sc-alternatives.h5p-sc-selected li.h5p-sc-alternative.h5p-sc-reveal-correct:active,\nul.h5p-sc-alternatives.h5p-sc-selected li.h5p-sc-alternative.h5p-sc-reveal-correct:focus {\n background: #9dd8bb;\n color: #255c41;\n}\n\nul.h5p-sc-alternatives li.h5p-sc-alternative.h5p-sc-is-correct.h5p-sc-selected.h5p-sc-reveal-correct .h5p-sc-progressbar {\n background: #9dd8bb;\n color: #255c41;\n}\n\nul.h5p-sc-alternatives li.h5p-sc-alternative.h5p-sc-reveal-wrong {\n -webkit-transform: scale(.95);\n transform: scale(.95);\n}\n\nul.h5p-sc-alternatives.h5p-sc-selected li.h5p-sc-alternative.h5p-sc-reveal-wrong.h5p-sc-selected,\nul.h5p-sc-alternatives.h5p-sc-selected li.h5p-sc-alternative.h5p-sc-reveal-wrong.h5p-sc-selected:hover,\nul.h5p-sc-alternatives.h5p-sc-selected li.h5p-sc-alternative.h5p-sc-reveal-wrong.h5p-sc-selected:active,\nul.h5p-sc-alternatives.h5p-sc-selected li.h5p-sc-alternative.h5p-sc-reveal-wrong.h5p-sc-selected:focus,\nul.h5p-sc-alternatives.h5p-sc-selected li.h5p-sc-alternative.h5p-sc-is-wrong.h5p-sc-selected.h5p-sc-reveal-wrong .h5p-sc-progressbar {\n background: #f7d0d0;\n color: #b71c1c;\n}\n\nli.h5p-sc-alternative .h5p-sc-progressbar {\n position: absolute;\n top: 0;\n left: 0;\n height: 100%;\n width: 0%;\n background: #cee0f4;\n -webkit-border-radius: 0.25em;\n -moz-border-radius: 0.25em;\n border-radius: 0.25em;\n}\n.h5p-sc-drummed .h5p-sc-progressbar {\n background: transparent;\n transition: background 1s;\n}\n/* Using animation instead of transition on width made this much\n smoother on iPad */\nli.h5p-sc-alternative.h5p-sc-selected .h5p-sc-progressbar {\n -webkit-animation: progress 0.6s;\n -moz-animation: progress 0.6s;\n -o-animation: progress 0.6s;\n animation: progress 0.6s;\n\n -webkit-animation-fill-mode: forwards;\n -moz-animation-fill-mode: forwards;\n -o-animation-fill-mode: forwards;\n animation-fill-mode: forwards;\n}\n@-webkit-keyframes progress {\n from { } to { width: 100% }\n}\n@-moz-keyframes progress {\n from { } to { width: 100% }\n}\n@-ms-keyframes progress {\n from { } to { width: 100% }\n}\n@keyframes progress {\n from { } to { width: 100% }\n}\nli.h5p-sc-alternative .h5p-sc-label {\n position: relative;\n}\nli.h5p-sc-alternative .h5p-sc-label p {\n margin: 0.75em 0;\n}\nli.h5p-sc-alternative .h5p-sc-label p:first-child {\n margin-top: 0;\n}\nli.h5p-sc-alternative .h5p-sc-label p:last-child {\n margin-bottom: 0;\n}\nli.h5p-sc-alternative .h5p-sc-status {\n font-family: H5PFontAwesome4;\n font-size: 1.5em;\n width: 1.5em;\n height: 1.5em;\n line-height: 1.5;\n position: absolute;\n top: 0;\n right: 0;\n text-align: center;\n}\n.h5p-sc-alternative.h5p-sc-is-correct.h5p-sc-drummed .h5p-sc-status:after{\n content: \"\\f00c\";\n color: #255c41;\n}\n.h5p-sc-alternative.h5p-sc-is-wrong.h5p-sc-drummed .h5p-sc-status:after{\n content: \"\\f00d\";\n color: #b71c1c;\n}\n\n.h5p-sc-selected li.h5p-sc-alternative {\n cursor: auto;\n -webkit-box-shadow: none;\n -moz-box-shadow: none;\n box-shadow: none;\n}\n.h5p-sc-set-results {\n width: 100%;\n height: 100%;\n position: absolute;\n top: 0;\n text-align: center;\n box-sizing: border-box;\n}\n.h5p-sc-set-results \u003e .h5p-sc-feedback {\n display: block;\n font-size: 1.8em;\n margin-bottom: 1.3em;\n}\n\n.h5p-sc-sound-control {\n width: 1.3em;\n height: 1.5em;\n position: absolute;\n text-align: left;\n color: #757575;\n cursor: pointer;\n top: 1.25em;\n right: 0.75em;\n}\n\n.h5p-sc-sound-control:hover {\n color: #444;\n}\n.h5p-sc-sound-control:after {\n font-family: H5PFontAwesome4;\n font-size: 1.25em;\n content: \u0027\\f028\u0027;\n}\n[aria-pressed=\u0027true\u0027].h5p-sc-sound-control:after {\n content: \u0027\\f026\u0027;\n}\n.h5p-sc-solution-view {\n position: absolute;\n left: 100%;\n top: 0;\n width: 100%;\n height: 100%;\n\n outline: none;\n display:none;\n visibility: hidden;\n background: #fff;\n box-sizing: border-box;\n\n transition: left .3s ease-in-out, visibility .3s ease-in-out;\n}\n.h5p-sc-solution-view.visible {\n left: 0;\n visibility: visible;\n display: block;\n}\n.h5p-sc-solution-view-header {\n position: relative;\n text-align: center;\n height: 3.25em;\n background: #fff;\n border-bottom: 1px solid #ddd;\n box-shadow: 0 0 0.2em rgba(0,0,0,0.2);\n z-index: 1;\n}\n.h5p-sc-solution-view-title {\n display: inline-block;\n font-size: 1.2em;\n text-align: center;\n line-height: 2.75em;\n outline: none;\n}\n.h5p-single-choice-set .h5p-sc-solution-view .h5p-sc-close-solution-view {\n position: absolute;\n top: 50%;\n -webkit-transform: translateY(-50%);\n transform: translateY(-50%);\n left: 0;\n background: none;\n color: #1a73d9;\n}\n\n.h5p-single-choice-set .h5p-sc-solution-view .h5p-sc-close-solution-view:active {\n -webkit-box-shadow: none;\n -moz-box-shadow: none;\n box-shadow: none;\n color: #104888;\n}\n\n.h5p-single-choice-set .h5p-sc-solution-view .h5p-sc-close-solution-view:focus,\n.h5p-single-choice-set .h5p-sc-solution-view .h5p-sc-close-solution-view:hover {\n -webkit-box-shadow: none;\n -moz-box-shadow: none;\n box-shadow: none;\n color: #1356a3;\n}\n.h5p-single-choice-set .h5p-sc-solution-view .h5p-sc-close-solution-view:before {\n font-family: H5PFontAwesome4;\n content: \u0027\\f060\u0027;\n padding-right: 0.5em;\n}\n.h5p-sc-solution-choices {\n font-size: 1.1em;\n margin: 0 auto;\n -webkit-border-radius: 0.2em;\n -moz-border-radius: 0.2em;\n border-radius: 0.2em;\n padding: 0.5em;\n overflow: auto;\n box-sizing: border-box;\n position: absolute;\n bottom: 0;\n top: 2.95em;\n width: 100%;\n}\n.h5p-sc-solution-question {\n font-weight: bold;\n margin-bottom: 0.25em;\n padding-left: 0.5em;\n}\n.h5p-sc-solution-question p {\n margin: 1em 0;\n}\n.h5p-sc-solution-question p:first-child {\n margin-top: 0;\n}\n.h5p-sc-solution-answer {\n margin-bottom: 0.5em;\n padding-bottom: 0.5em;\n padding-left: 1.75em;\n border-bottom: 1px solid #ccc;\n position: relative;\n}\n.h5p-sc-solution-answer p {\n margin: 0.75em 0;\n}\n.h5p-sc-solution-answer p:first-child {\n margin-top: 0;\n}\n.h5p-sc-solution-answer p:last-child {\n margin-bottom: 0;\n}\n.h5p-sc-solution-answer:last-child {\n border-bottom: none;\n margin-bottom: 0;\n}\n.h5p-sc-solution-answer:before {\n font-size: 0.8em;\n font-family: H5PFontAwesome4;\n content: \"\\f00c\";\n color: #255c41;\n position: absolute;\n left: 0.75em;\n}\n\n/* Remove Question margin */\n.h5p-single-choice-set .h5p-question-content {\n margin: 0;\n height: 100%;\n}\n\n.h5p-single-choice-set .h5p-question-feedback-container {\n max-height: initial;\n margin: 0 0 1em;\n}\n\n.h5p-single-choice-set .h5p-sc-result-container {\n top: 50%;\n -webkit-transform: translateY(-50%);\n transform: translateY(-50%);\n position: absolute;\n width: 100%;\n}\n\n.h5p-single-choice-set .h5p-sc-feedback-container {\n outline: none;\n}\n\n/* Introduction */\n.h5p-sc-question {\n margin: 0.888888889em;\n padding-right: 1.777777778em;\n font-size: 1.125em;\n}\n\n.h5p-single-choice-set .h5p-sc-question p {\n font-size: 1em;\n margin: 0.75em 0;\n}\n.h5p-single-choice-set .h5p-sc-question p:first-child {\n margin-top: 0;\n}\n.h5p-single-choice-set .h5p-sc-question p:last-child {\n margin-bottom: 0;\n}\n\n/* Scrollbar style */\n.h5p-single-choice-set .h5p-sc-solution-choices::-webkit-scrollbar {\n width: 0.5em;\n background: #fff;\n}\n\n.h5p-single-choice-set .h5p-sc-solution-choices::-webkit-scrollbar-thumb {\n background: #ddd;\n}\n\n.h5p-single-choice-set .h5p-sc-solution-choices::-webkit-scrollbar-thumb:hover {\n background: #aaa;\n}\n\n.h5p-single-choice-set .h5p-sc-solution-choices::-webkit-scrollbar-thumb:active,\n.h5p-single-choice-set .h5p-sc-solution-choices::-webkit-scrollbar-thumb:focus {\n background: #888;\n}\n\n/* IV sepcific styles */\n.h5p-interactive-video .h5p-dialog[data-lib=\"H5P.SingleChoiceSet\"] {\n width: 24.5em;\n overflow: hidden;\n padding: 0;\n}\n\n.h5p-interactive-video .h5p-dialog[data-lib=\"H5P.SingleChoiceSet\"] .h5p-sc-sound-control {\n top: -2.075em;\n right: 2em;\n}\n.h5p-interactive-video .h5p-dialog[data-lib=\"H5P.SingleChoiceSet\"] .h5p-sc-sound-control:after {\n font-size: 1.075em;\n}\n\n.h5p-interactive-video .h5p-dialog[data-lib=\"H5P.SingleChoiceSet\"] .h5p-sc-question {\n margin-right: 0;\n}\n\n.h5p-interactive-video .h5p-dialog[data-lib=\"H5P.SingleChoiceSet\"] .h5p-sc-solution-view {\n top: 0;\n height: 100%;\n}\n\n.h5p-interactive-video.mobile .h5p-dialog[data-lib=\"H5P.SingleChoiceSet\"] .h5p-dialog-interaction.h5p-single-choice-set {\n height: 100%;\n}\n\n/* Standalone specific styles */\n.h5p-standalone.h5p-single-choice-set .h5p-joubelui-button {\n line-height: 1em;\n}\n\n.h5p-no-frame .h5p-standalone.h5p-single-choice-set .h5p-sc-alternatives,\n.h5p-no-frame .h5p-standalone.h5p-single-choice-set .h5p-sc-question {\n margin: 1em 0;\n}\n\n.h5p-no-frame .h5p-standalone.h5p-single-choice-set .h5p-sc-question {\n margin-top: 0;\n}\n\n.h5p-no-frame .h5p-standalone.h5p-single-choice-set .h5p-sc-sound-control {\n top: 0;\n}\n\n/* Transparent specific styles */\n.h5p-transparent \u003e div \u003e .h5p-single-choice-set .h5p-sc-alternatives,\n.h5p-transparent \u003e div \u003e .h5p-single-choice-set .h5p-sc-question {\n margin-left: 0;\n margin-right: 0;\n}\n\n.h5p-transparent \u003e div \u003e .h5p-single-choice-set .h5p-sc-question {\n margin-top: 0;\n}\n\n.h5p-transparent \u003e div \u003e .h5p-single-choice-set .h5p-sc-sound-control {\n top: 0;\n right: 0;\n}\n\n/* CP popup specific style */\n.h5p-course-presentation .h5p-popup-overlay.h5p-singlechoiceset .h5p-sc-sound-control {\n top: 0.6em;\n right: 3em;\n color: #000;\n}\n\n.h5p-course-presentation .h5p-popup-overlay.h5p-singlechoiceset .h5p-sc-sound-control:after {\n font-size: 1.8em;\n}\n\n.h5p-course-presentation .h5p-popup-overlay.h5p-singlechoiceset .h5p-sc-sound-control:hover {\n color: #555;\n}\n\n.h5p-course-presentation .h5p-popup-overlay.h5p-singlechoiceset .h5p-popup-container {\n min-height: initial;\n max-height: none;\n}\n","css/multichoice.css":"/* IcoMoon font licensed under the GNU General Public License: http://www.gnu.org/licenses/gpl.html */\n@font-face {\n font-family: \u0027icomoon-multichoice\u0027;\n src:url(\u0027../H5P/libraries/H5P.MultiChoice-1.10/fonts/icomoon.eot\u0027);\n src:url(\u0027../H5P/libraries/H5P.MultiChoice-1.10/fonts/icomoon.eot?#iefix\u0027) format(\u0027embedded-opentype\u0027),\n url(\u0027../H5P/libraries/H5P.MultiChoice-1.10/fonts/icomoon.woff\u0027) format(\u0027woff\u0027),\n url(\u0027../H5P/libraries/H5P.MultiChoice-1.10/fonts/icomoon.ttf\u0027) format(\u0027truetype\u0027),\n url(\u0027../H5P/libraries/H5P.MultiChoice-1.10/fonts/icomoon.svg#icomoon\u0027) format(\u0027svg\u0027);\n font-weight: normal;\n font-style: normal;\n}\n\n.h5p-multichoice .h5p-answers {\n list-style: none;\n padding: 0;\n overflow: visible;\n margin: 1em 0;\n}\n\n.h5p-multichoice .h5p-answer {\n list-style: none;\n margin: 0.5em 0;\n padding: 0;\n background: none;\n position: relative;\n cursor: pointer;\n}\n\n.h5p-multichoice .h5p-answer.h5p-has-tip .h5p-alternative-container,\n.h5p-multichoice .h5p-answer.h5p-should-not .h5p-alternative-container {\n padding-right: 2em;\n}\n\n.h5p-multichoice .h5p-answer.h5p-wrong .h5p-alternative-container,\n.h5p-multichoice .h5p-answer.h5p-correct .h5p-alternative-container {\n padding-right: 3em;\n}\n\n.h5p-multichoice .h5p-alternative-container {\n position: relative;\n text-align: left;\n display: block;\n padding: 0.25em 0.75em 0.25em 2.1em;\n border-radius: 0.3em;\n border: 0.1em solid #ddd;\n font-weight: normal;\n background: #ddd;\n -webkit-box-shadow: 0 0.1em 0 rgba(0, 0, 0, 0.3);\n -moz-box-shadow: 0 0.1em 0 rgba(0, 0, 0, 0.3);\n box-shadow: 0 0.1em 0 rgba(0, 0, 0, 0.3);\n line-height: 1.5em;\n text-indent: -2em;\n}\n.h5p-multichoice .h5p-answer .h5p-alternative-container:before {\n font-family: icomoon-multichoice;\n border: medium none;\n display: block;\n height: 1em;\n width: 1em;\n position: absolute;\n left: 2.5em;\n top: 0.25em;\n margin: auto;\n text-decoration: none;\n color: #494949;\n}\n.h5p-multichoice .h5p-answer[role=\"radio\"] .h5p-alternative-container:before {\n content: \"\\e600\";\n}\n.h5p-multichoice .h5p-answer[role=\"radio\"][aria-checked=\"true\"] .h5p-alternative-container:before {\n content: \"\\e603\";\n}\n.h5p-multichoice .h5p-answer[role=\"checkbox\"] .h5p-alternative-container:before {\n content: \"\\e602\";\n}\n.h5p-multichoice .h5p-answer[role=\"checkbox\"][aria-checked=\"true\"] .h5p-alternative-container:before {\n content: \"\\e601\";\n}\n.h5p-multichoice .h5p-answers .h5p-answer[aria-disabled=\"true\"] .h5p-alternative-container:before,\n.h5p-multichoice .h5p-answers .h5p-answer.h5p-correct .h5p-alternative-container:before,\n.h5p-multichoice .h5p-answers .h5p-answer.h5p-wrong .h5p-alternative-container:before {\n content: \u0027\u0027;\n}\n\n.h5p-multichoice .h5p-answer[aria-disabled=\"true\"] {\n cursor: default;\n}\n.h5p-multichoice .h5p-answer:hover .h5p-alternative-container,\n.h5p-multichoice .h5p-answer:focus .h5p-alternative-container {\n border: 0.1em solid #edd6e9;\n background: #edd6e9;\n}\n.h5p-multichoice .h5p-answer[aria-disabled=\"true\"]:hover .h5p-alternative-container,\n.h5p-multichoice .h5p-answer[aria-disabled=\"true\"]:focus .h5p-alternative-container {\n border: 0.1em solid #ddd;\n background: #ddd;\n}\n\n.h5p-multichoice .h5p-answer[aria-checked=\"true\"] .h5p-alternative-container,\n.h5p-multichoice .h5p-answer[aria-checked=\"true\"]:hover .h5p-alternative-container {\n border: 0.1em solid #cee0f4;\n color: #1a4473;\n background: #cee0f4;\n -webkit-box-shadow: none;\n -moz-box-shadow: none;\n box-shadow: none;\n}\n.h5p-multichoice .h5p-answer[aria-checked=\"true\"]:focus .h5p-alternative-container {\n border: 0.1em solid #e6eef8;\n background: #e6eef8;\n}\n.h5p-multichoice .h5p-answer[aria-checked=\"true\"][aria-disabled=\"true\"]:focus .h5p-alternative-container {\n border: 0.1em solid #cee0f4;\n background: #cee0f4;\n}\n.h5p-multichoice .h5p-answer.h5p-correct .h5p-alternative-container,\n.h5p-multichoice .h5p-answer.h5p-correct:hover .h5p-alternative-container {\n background: #b6e4ce;\n border-color: #b6e4ce;\n color: #255c41;\n}\n.h5p-multichoice .h5p-answer.h5p-wrong .h5p-alternative-container,\n.h5p-multichoice .h5p-answer.h5p-wrong:hover .h5p-alternative-container {\n background: #fbd7d8;\n border-color: #fbd7d8;\n color: #b71c1c;\n}\n\n.h5p-multichoice .h5p-answer:last-child {\n margin-bottom: 0;\n}\n\n.h5p-multichoice h2 {\n font-size: 1.5em;\n font-weight: normal;\n}\n\n.h5p-multichoice .h5p-answer-icon {\n font-family: \u0027H5PFontAwesome4\u0027;\n width: 1em;\n height: 1em;\n text-decoration: none;\n position: absolute;\n line-height: 1em;\n top: 0.54em;\n left: 0.75em;\n letter-spacing: 1em;\n overflow: hidden;\n}\n.h5p-multichoice .h5p-correct .h5p-answer-icon:before {\n content: \"\\f00c\";\n color: #255c41;\n}\n.h5p-multichoice .h5p-wrong .h5p-answer-icon:before {\n content: \"\\f00d\";\n color: #b71c1c;\n padding: 0 0.125em;\n}\n.h5p-multichoice .h5p-should .h5p-answer-icon,\n.h5p-multichoice .h5p-should-not .h5p-answer-icon {\n right: 2.125em;\n}\n\n.h5p-multichoice .h5p-solution-icon {\n font-family: icomoon-multichoice;\n position: absolute;\n right: 0.75em;\n line-height: 1em;\n top: 0.585em;\n width: 1em;\n height: 1em;\n overflow: hidden;\n}\n.h5p-multichoice .h5p-should[role=\"radio\"] .h5p-solution-icon:before {\n content: \"\\e603\";\n}\n.h5p-multichoice .h5p-should-not[role=\"radio\"] .h5p-solution-icon:before {\n content: \"\\e600\";\n}\n.h5p-multichoice .h5p-should[role=\"checkbox\"] .h5p-solution-icon:before {\n content: \"\\e601\";\n}\n.h5p-multichoice .h5p-should-not[role=\"checkbox\"] .h5p-solution-icon:before {\n content: \"\\e602\";\n}\n\n.h5p-multichoice .feedback-text {\n height: 2em;\n top: 0;\n margin: 0;\n padding: 0;\n font-weight: bold;\n font-size: 1.25em;\n line-height: 2em;\n color: #599413;\n}\n\n.h5p-multichoice .feedback-text.h5p-failed {\n color: #b71c1c;\n}\n.h5p-multichoice .feedback-text.h5p-almost {\n color: #666;\n}\n.h5p-multichoice .feedback-text.h5p-passed {\n color: #255c41;\n}\n\n.h5p-alternative-inner {\n margin: 0 0.75em 0 2em;\n}\n.h5p-alternative-inner div,\n.h5p-alternative-inner p {\n display: inline;\n}\n\n.h5p-clearfix {\n clear: both;\n}\n\n.h5p-multichoice .h5p-radio-or-checkbox {\n border: medium none;\n display: block;\n height: 1em;\n margin: auto;\n width: 1em;\n text-decoration: none;\n font-family: icomoon-multichoice;\n color: #494949;\n pointer-events: none;\n}\n\n.h5p-multichoice .h5p-selected .h5p-radio-or-checkbox {\n color: #235e7c;\n}\n\n.h5p-question p:last-child {\n margin-bottom: 0;\n}\n\n.h5p-question p:first-child {\n margin-top: 0;\n}\n\n.h5p-multichoice .h5p-feedback-button {\n position: absolute;\n cursor: pointer;\n right: 2.125em;\n top: 0.4375em;\n line-height: 1em;\n background: #fff;\n}\n.h5p-multichoice .h5p-selected.h5p-should.h5p-correct .h5p-feedback-button,\n.h5p-multichoice .h5p-selected.h5p-should-not.h5p-correct .h5p-feedback-button,\n.h5p-multichoice .h5p-selected.h5p-should.h5p-wrong .h5p-feedback-button,\n.h5p-multichoice .h5p-selected.h5p-should-not.h5p-wrong .h5p-feedback-button {\n right: 3.5em;\n}\n\n.h5p-multichoice .h5p-feedback-button:focus {\n outline: none;\n}\n.h5p-multichoice .h5p-feedback-button:before {\n font-family: \u0027H5PFontAwesome4\u0027;\n content: \"\\f075\";\n color: #fbfbfb;\n text-shadow: 0 0 0.25em #2c2c2c;\n}\n.h5p-multichoice .h5p-feedback-button:hover:before {\n color: #e1e1e1;\n}\n\n/* Feedback dialog*/\n.h5p-multichoice .h5p-feedback-dialog {\n position: relative;\n width: calc(100% - 0.5em);\n left: 0.25em;\n}\n.h5p-multichoice .h5p-answer .h5p-feedback-inner {\n background: #fbfbfb;\n border-bottom: 1px solid #ddd;\n border-left: 1px solid #ddd;\n border-right: 1px solid #ddd;\n padding: 0.5em 1.25em;\n text-align: left;\n position: relative;\n}\n\n.h5p-multichoice .h5p-answer.h5p-selected .h5p-feedback-inner {\n border-bottom: 1px solid #cee0f4;\n border-left: 1px solid #cee0f4;\n border-right: 1px solid #cee0f4;\n}\n\n.h5p-multichoice .h5p-feedback-inner:before {\n content: \"\";\n position: absolute;\n left: 0.625em;\n top: -0.3em;\n width: 0.5em;\n height: 0.5em;\n background: #fbfbfb;\n -webkit-transform: rotate(45deg);\n -moz-transform: rotate(45deg);\n -ms-transform: rotate(45deg);\n -o-transform: rotate(45deg);\n transform: rotate(45deg);\n box-shadow: inset 1px 1px 0px 0px #dcdcdc;\n}\n\n.h5p-multichoice .h5p-feedback-dialog.h5p-has-tip .h5p-feedback-inner:before {\n left: auto;\n right: 0.85em;\n}\n\n.h5p-multichoice .h5p-feedback-text {\n position: relative;\n z-index: 3;\n overflow: auto;\n overflow-x: hidden;\n overflow-y: auto;\n}\n\n.h5p-multichoice .h5p-feedback-text::-webkit-scrollbar {\n width: 0.4em;\n}\n.h5p-multichoice .h5p-feedback-text::-webkit-scrollbar-thumb {\n border-radius: 0.2em;\n background: #aaa;\n}\n\n/* Tip icon*/\n.h5p-multichoice .multichoice-tip {\n position: absolute;\n right: 0.246153846em;\n top: -0.123076923em;\n vertical-align: middle;\n text-align: center;\n font-size: 1.25em;\n line-height: 1.5;\n width: 2.15em;\n height: 100%;\n color: #777;\n cursor: pointer;\n font-weight: normal;\n}\n.h5p-multichoice .multichoice-tip:focus {\n outline: 0;\n box-shadow: 0px 0px 1px 3px rgba(140,185,240,1);\n}\n\n.h5p-multichoice .multichoice-tip .joubel-icon-tip-normal {\n line-height: initial;\n float: right;\n}\n\n.h5p-multichoice .multichoice-tip:hover {\n color: #333;\n}\n\n.h5p-multichoice .h5p-selected.h5p-should-not.h5p-correct .multichoice-tip,\n.h5p-multichoice .h5p-selected.h5p-should.h5p-correct .multichoice-tip,\n.h5p-multichoice .h5p-selected.h5p-should.h5p-wrong .multichoice-tip,\n.h5p-multichoice .h5p-selected.h5p-should-not.h5p-wrong .multichoice-tip {\n right: 3.125em;\n}\n\n/* Remove tip icon on check */\n.h5p-multichoice [aria-disabled=\"true\"] .h5p-multichoice-tipwrap {\n display: none;\n}\n\n.h5p-multichoice-tipwrap {\n display: inline;\n}\n\n.h5p-multichoice .h5p-question-plus-one,\n.h5p-multichoice .h5p-question-minus-one {\n display: inline-block;\n top: auto;\n right: auto;\n padding-top: 2px;\n}\n","radio-group.css":".h5p-editor-radio-group-container {\n margin-bottom: 1em;\n}\n.h5p-editor-radio-group-button {\n padding: .5em 0 0 0;\n margin-left: .3em;\n}\n.h5p-editor-radio-group-container.horizontal .h5p-editor-radio-group-button {\n display: inline-block;\n}\n","styles/h5p-true-false.css":".h5p-true-false-answers {\n margin: 1em 0 1em;\n}\n.h5p-true-false-answer {\n position: relative;\n display: inline-block;\n box-sizing: border-box;\n cursor: pointer;\n border-radius: 4px;\n border: 2px solid #ddd;\n margin: 0 1em 1em 0;\n padding: .5em 3.5em .5em .3em;\n box-shadow: 0 1px 0 0 #ccc;\n outline: none;\n background: #fff;\n}\n.aria-label {\n width: 0;\n height: 0;\n overflow: hidden;\n display: block;\n position: absolute;\n}\n.h5p-true-false-answer:hover {\n border-color: #8cb9f0;\n}\n.h5p-true-false-answer:focus {\n box-shadow: 0px 0px 5px 2px rgba(140,185,240,1);\n}\n.h5p-true-false-answer:before {\n margin: 0 .5em;\n font-family: \u0027H5PFontIcons\u0027;\n font-size: 0.8em;\n content: \u0027\\e60b\u0027;\n}\n.h5p-true-false-answer[aria-checked=true] {\n background: #d3ebfb;\n border-color: #6b9fde;\n color: #000;\n}\n.h5p-true-false-answer[aria-checked=true]::before {\n content: \u0027\\e60d\u0027;\n}\n.h5p-true-false-answer:after {\n font-family: \u0027H5PFontAwesome4\u0027;\n font-weight: normal;\n content: \u0027 \u0027;\n width: 2.5em;\n position: absolute;\n right: 0;\n top: 0;\n height: 100%;\n text-align: center;\n line-height: 2.5em;\n}\n.h5p-true-false-answer:active {\n border-color: #8cb9f0;\n transform: scale(0.95);\n}\n.h5p-true-false-answer.correct {\n background: #fff;\n border-color: #47b47d;\n box-shadow: none;\n}\n.h5p-true-false-answer.correct:after {\n background: #47b47d;\n content: \u0027\\f00c\u0027;\n color: #fff;\n}\n.h5p-true-false-answer.wrong {\n background: #fff;\n border-color: #dd2e2e;\n box-shadow: none;\n}\n.h5p-true-false-answer.wrong:after {\n background: #dd2e2e;\n content: \u0027\\f00d\u0027;\n color: #fff;\n}\n.h5p-true-false-answer[aria-disabled=true] {\n box-shadow: none;\n pointer-events: none;\n}\n/* When */\n.h5p-transparent \u003e div \u003e .h5p-question.h5p-true-false \u003e * {\n margin-left: 3px;\n}\n","h5p-jquery-ui.css":"/*! jQuery UI - v1.10.1 - 2013-02-15\n* http://jqueryui.com\n* Includes: jquery.ui.core.css, jquery.ui.accordion.css, jquery.ui.autocomplete.css, jquery.ui.button.css, jquery.ui.datepicker.css, jquery.ui.dialog.css, jquery.ui.menu.css, jquery.ui.progressbar.css, jquery.ui.resizable.css, jquery.ui.selectable.css, jquery.ui.slider.css, jquery.ui.spinner.css, jquery.ui.tabs.css, jquery.ui.tooltip.css\n* Copyright (c) 2013 jQuery Foundation and other contributors Licensed MIT */\n\n/* Layout helpers\n----------------------------------*/\n.ui-helper-hidden {\n\tdisplay: none;\n}\n.ui-helper-hidden-accessible {\n\tborder: 0;\n\tclip: rect(0 0 0 0);\n\theight: 1px;\n\tmargin: -1px;\n\toverflow: hidden;\n\tpadding: 0;\n\tposition: absolute;\n\twidth: 1px;\n}\n.ui-helper-reset {\n\tmargin: 0;\n\tpadding: 0;\n\tborder: 0;\n\toutline: 0;\n\tline-height: 1.3;\n\ttext-decoration: none;\n\tfont-size: 100%;\n\tlist-style: none;\n}\n.ui-helper-clearfix:before,\n.ui-helper-clearfix:after {\n\tcontent: \"\";\n\tdisplay: table;\n\tborder-collapse: collapse;\n}\n.ui-helper-clearfix:after {\n\tclear: both;\n}\n.ui-helper-clearfix {\n\tmin-height: 0; /* support: IE7 */\n}\n.ui-helper-zfix {\n\twidth: 100%;\n\theight: 100%;\n\ttop: 0;\n\tleft: 0;\n\tposition: absolute;\n\topacity: 0;\n\tfilter:Alpha(Opacity=0);\n}\n\n.ui-front {\n\tz-index: 100;\n}\n\n\n/* Interaction Cues\n----------------------------------*/\n.ui-state-disabled {\n\tcursor: default !important;\n}\n\n\n/* Icons\n----------------------------------*/\n\n/* states and images */\n.ui-icon {\n\tdisplay: block;\n\ttext-indent: -99999px;\n\toverflow: hidden;\n\tbackground-repeat: no-repeat;\n}\n\n\n/* Misc visuals\n----------------------------------*/\n\n/* Overlays */\n.ui-widget-overlay {\n\tposition: fixed;\n\ttop: 0;\n\tleft: 0;\n\twidth: 100%;\n\theight: 100%;\n}\n.ui-accordion .ui-accordion-header {\n\tdisplay: block;\n\tcursor: pointer;\n\tposition: relative;\n\tmargin-top: 2px;\n\tpadding: .5em .5em .5em .7em;\n\tmin-height: 0; /* support: IE7 */\n}\n.ui-accordion .ui-accordion-icons {\n\tpadding-left: 2.2em;\n}\n.ui-accordion .ui-accordion-noicons {\n\tpadding-left: .7em;\n}\n.ui-accordion .ui-accordion-icons .ui-accordion-icons {\n\tpadding-left: 2.2em;\n}\n.ui-accordion .ui-accordion-header .ui-accordion-header-icon {\n\tposition: absolute;\n\tleft: .5em;\n\ttop: 50%;\n\tmargin-top: -8px;\n}\n.ui-accordion .ui-accordion-content {\n\tpadding: 1em 2.2em;\n\tborder-top: 0;\n\toverflow: auto;\n}\n.ui-autocomplete {\n\tposition: absolute;\n\ttop: 0;\n\tleft: 0;\n\tcursor: default;\n}\n.ui-button {\n\tdisplay: inline-block;\n\tposition: relative;\n\tpadding: 0;\n\tline-height: normal;\n\tmargin-right: .1em;\n\tcursor: pointer;\n\tvertical-align: middle;\n\ttext-align: center;\n\toverflow: visible; /* removes extra width in IE */\n}\n.ui-button,\n.ui-button:link,\n.ui-button:visited,\n.ui-button:hover,\n.ui-button:active {\n\ttext-decoration: none;\n}\n/* to make room for the icon, a width needs to be set here */\n.ui-button-icon-only {\n\twidth: 2.2em;\n}\n/* button elements seem to need a little more width */\nbutton.ui-button-icon-only {\n\twidth: 2.4em;\n}\n.ui-button-icons-only {\n\twidth: 3.4em;\n}\nbutton.ui-button-icons-only {\n\twidth: 3.7em;\n}\n\n/* button text element */\n.ui-button .ui-button-text {\n\tdisplay: block;\n\tline-height: normal;\n}\n.ui-button-text-only .ui-button-text {\n\tpadding: .4em 1em;\n}\n.ui-button-icon-only .ui-button-text,\n.ui-button-icons-only .ui-button-text {\n\tpadding: .4em;\n\ttext-indent: -9999999px;\n}\n.ui-button-text-icon-primary .ui-button-text,\n.ui-button-text-icons .ui-button-text {\n\tpadding: .4em 1em .4em 2.1em;\n}\n.ui-button-text-icon-secondary .ui-button-text,\n.ui-button-text-icons .ui-button-text {\n\tpadding: .4em 2.1em .4em 1em;\n}\n.ui-button-text-icons .ui-button-text {\n\tpadding-left: 2.1em;\n\tpadding-right: 2.1em;\n}\n/* no icon support for input elements, provide padding by default */\ninput.ui-button {\n\tpadding: .4em 1em;\n}\n\n/* button icon element(s) */\n.ui-button-icon-only .ui-icon,\n.ui-button-text-icon-primary .ui-icon,\n.ui-button-text-icon-secondary .ui-icon,\n.ui-button-text-icons .ui-icon,\n.ui-button-icons-only .ui-icon {\n\tposition: absolute;\n\ttop: 50%;\n\tmargin-top: -8px;\n}\n.ui-button-icon-only .ui-icon {\n\tleft: 50%;\n\tmargin-left: -8px;\n}\n.ui-button-text-icon-primary .ui-button-icon-primary,\n.ui-button-text-icons .ui-button-icon-primary,\n.ui-button-icons-only .ui-button-icon-primary {\n\tleft: .5em;\n}\n.ui-button-text-icon-secondary .ui-button-icon-secondary,\n.ui-button-text-icons .ui-button-icon-secondary,\n.ui-button-icons-only .ui-button-icon-secondary {\n\tright: .5em;\n}\n\n/* button sets */\n.ui-buttonset {\n\tmargin-right: 7px;\n}\n.ui-buttonset .ui-button {\n\tmargin-left: 0;\n\tmargin-right: -.3em;\n}\n\n/* workarounds */\n/* reset extra padding in Firefox, see h5bp.com/l */\ninput.ui-button::-moz-focus-inner,\nbutton.ui-button::-moz-focus-inner {\n\tborder: 0;\n\tpadding: 0;\n}\n.ui-datepicker {\n\twidth: 17em;\n\tpadding: .2em .2em 0;\n\tdisplay: none;\n}\n.ui-datepicker .ui-datepicker-header {\n\tposition: relative;\n\tpadding: .2em 0;\n}\n.ui-datepicker .ui-datepicker-prev,\n.ui-datepicker .ui-datepicker-next {\n\tposition: absolute;\n\ttop: 2px;\n\twidth: 1.8em;\n\theight: 1.8em;\n}\n.ui-datepicker .ui-datepicker-prev-hover,\n.ui-datepicker .ui-datepicker-next-hover {\n\ttop: 1px;\n}\n.ui-datepicker .ui-datepicker-prev {\n\tleft: 2px;\n}\n.ui-datepicker .ui-datepicker-next {\n\tright: 2px;\n}\n.ui-datepicker .ui-datepicker-prev-hover {\n\tleft: 1px;\n}\n.ui-datepicker .ui-datepicker-next-hover {\n\tright: 1px;\n}\n.ui-datepicker .ui-datepicker-prev span,\n.ui-datepicker .ui-datepicker-next span {\n\tdisplay: block;\n\tposition: absolute;\n\tleft: 50%;\n\tmargin-left: -8px;\n\ttop: 50%;\n\tmargin-top: -8px;\n}\n.ui-datepicker .ui-datepicker-title {\n\tmargin: 0 2.3em;\n\tline-height: 1.8em;\n\ttext-align: center;\n}\n.ui-datepicker .ui-datepicker-title select {\n\tfont-size: 1em;\n\tmargin: 1px 0;\n}\n.ui-datepicker select.ui-datepicker-month-year {\n\twidth: 100%;\n}\n.ui-datepicker select.ui-datepicker-month,\n.ui-datepicker select.ui-datepicker-year {\n\twidth: 49%;\n}\n.ui-datepicker table {\n\twidth: 100%;\n\tfont-size: .9em;\n\tborder-collapse: collapse;\n\tmargin: 0 0 .4em;\n}\n.ui-datepicker th {\n\tpadding: .7em .3em;\n\ttext-align: center;\n\tfont-weight: bold;\n\tborder: 0;\n}\n.ui-datepicker td {\n\tborder: 0;\n\tpadding: 1px;\n}\n.ui-datepicker td span,\n.ui-datepicker td a {\n\tdisplay: block;\n\tpadding: .2em;\n\ttext-align: right;\n\ttext-decoration: none;\n}\n.ui-datepicker .ui-datepicker-buttonpane {\n\tbackground-image: none;\n\tmargin: .7em 0 0 0;\n\tpadding: 0 .2em;\n\tborder-left: 0;\n\tborder-right: 0;\n\tborder-bottom: 0;\n}\n.ui-datepicker .ui-datepicker-buttonpane button {\n\tfloat: right;\n\tmargin: .5em .2em .4em;\n\tcursor: pointer;\n\tpadding: .2em .6em .3em .6em;\n\twidth: auto;\n\toverflow: visible;\n}\n.ui-datepicker .ui-datepicker-buttonpane button.ui-datepicker-current {\n\tfloat: left;\n}\n\n/* with multiple calendars */\n.ui-datepicker.ui-datepicker-multi {\n\twidth: auto;\n}\n.ui-datepicker-multi .ui-datepicker-group {\n\tfloat: left;\n}\n.ui-datepicker-multi .ui-datepicker-group table {\n\twidth: 95%;\n\tmargin: 0 auto .4em;\n}\n.ui-datepicker-multi-2 .ui-datepicker-group {\n\twidth: 50%;\n}\n.ui-datepicker-multi-3 .ui-datepicker-group {\n\twidth: 33.3%;\n}\n.ui-datepicker-multi-4 .ui-datepicker-group {\n\twidth: 25%;\n}\n.ui-datepicker-multi .ui-datepicker-group-last .ui-datepicker-header,\n.ui-datepicker-multi .ui-datepicker-group-middle .ui-datepicker-header {\n\tborder-left-width: 0;\n}\n.ui-datepicker-multi .ui-datepicker-buttonpane {\n\tclear: left;\n}\n.ui-datepicker-row-break {\n\tclear: both;\n\twidth: 100%;\n\tfont-size: 0;\n}\n\n/* RTL support */\n.ui-datepicker-rtl {\n\tdirection: rtl;\n}\n.ui-datepicker-rtl .ui-datepicker-prev {\n\tright: 2px;\n\tleft: auto;\n}\n.ui-datepicker-rtl .ui-datepicker-next {\n\tleft: 2px;\n\tright: auto;\n}\n.ui-datepicker-rtl .ui-datepicker-prev:hover {\n\tright: 1px;\n\tleft: auto;\n}\n.ui-datepicker-rtl .ui-datepicker-next:hover {\n\tleft: 1px;\n\tright: auto;\n}\n.ui-datepicker-rtl .ui-datepicker-buttonpane {\n\tclear: right;\n}\n.ui-datepicker-rtl .ui-datepicker-buttonpane button {\n\tfloat: left;\n}\n.ui-datepicker-rtl .ui-datepicker-buttonpane button.ui-datepicker-current,\n.ui-datepicker-rtl .ui-datepicker-group {\n\tfloat: right;\n}\n.ui-datepicker-rtl .ui-datepicker-group-last .ui-datepicker-header,\n.ui-datepicker-rtl .ui-datepicker-group-middle .ui-datepicker-header {\n\tborder-right-width: 0;\n\tborder-left-width: 1px;\n}\n.ui-dialog {\n\tposition: absolute;\n\ttop: 0;\n\tleft: 0;\n\tpadding: .2em;\n\toutline: 0;\n}\n.ui-dialog .ui-dialog-titlebar {\n\tpadding: .4em 1em;\n\tposition: relative;\n}\n.ui-dialog .ui-dialog-title {\n\tfloat: left;\n\tmargin: .1em 0;\n\twhite-space: nowrap;\n\twidth: 90%;\n\toverflow: hidden;\n\ttext-overflow: ellipsis;\n}\n.ui-dialog .ui-dialog-titlebar-close {\n\tposition: absolute;\n\tright: .3em;\n\ttop: 50%;\n\twidth: 21px;\n\tmargin: -10px 0 0 0;\n\tpadding: 1px;\n\theight: 20px;\n}\n.ui-dialog .ui-dialog-content {\n\tposition: relative;\n\tborder: 0;\n\tpadding: .5em 1em;\n\tbackground: none;\n\toverflow: auto;\n}\n.ui-dialog .ui-dialog-buttonpane {\n\ttext-align: left;\n\tborder-width: 1px 0 0 0;\n\tbackground-image: none;\n\tmargin-top: .5em;\n\tpadding: .3em 1em .5em .4em;\n}\n.ui-dialog .ui-dialog-buttonpane .ui-dialog-buttonset {\n\tfloat: right;\n}\n.ui-dialog .ui-dialog-buttonpane button {\n\tmargin: .5em .4em .5em 0;\n\tcursor: pointer;\n}\n.ui-dialog .ui-resizable-se {\n\twidth: 12px;\n\theight: 12px;\n\tright: -5px;\n\tbottom: -5px;\n\tbackground-position: 16px 16px;\n}\n.ui-draggable .ui-dialog-titlebar {\n\tcursor: move;\n}\n.ui-menu {\n\tlist-style: none;\n\tpadding: 2px;\n\tmargin: 0;\n\tdisplay: block;\n\toutline: none;\n}\n.ui-menu .ui-menu {\n\tmargin-top: -3px;\n\tposition: absolute;\n}\n.ui-menu .ui-menu-item {\n\tmargin: 0;\n\tpadding: 0;\n\twidth: 100%;\n}\n.ui-menu .ui-menu-divider {\n\tmargin: 5px -2px 5px -2px;\n\theight: 0;\n\tfont-size: 0;\n\tline-height: 0;\n\tborder-width: 1px 0 0 0;\n}\n.ui-menu .ui-menu-item a {\n\ttext-decoration: none;\n\tdisplay: block;\n\tpadding: 2px .4em;\n\tline-height: 1.5;\n\tmin-height: 0; /* support: IE7 */\n\tfont-weight: normal;\n}\n.ui-menu .ui-menu-item a.ui-state-focus,\n.ui-menu .ui-menu-item a.ui-state-active {\n\tfont-weight: normal;\n\tmargin: -1px;\n}\n\n.ui-menu .ui-state-disabled {\n\tfont-weight: normal;\n\tmargin: .4em 0 .2em;\n\tline-height: 1.5;\n}\n.ui-menu .ui-state-disabled a {\n\tcursor: default;\n}\n\n/* icon support */\n.ui-menu-icons {\n\tposition: relative;\n}\n.ui-menu-icons .ui-menu-item a {\n\tposition: relative;\n\tpadding-left: 2em;\n}\n\n/* left-aligned */\n.ui-menu .ui-icon {\n\tposition: absolute;\n\ttop: .2em;\n\tleft: .2em;\n}\n\n/* right-aligned */\n.ui-menu .ui-menu-icon {\n\tposition: static;\n\tfloat: right;\n}\n.ui-progressbar {\n\theight: 2em;\n\ttext-align: left;\n\toverflow: hidden;\n}\n.ui-progressbar .ui-progressbar-value {\n\tmargin: -1px;\n\theight: 100%;\n}\n.ui-progressbar .ui-progressbar-overlay {\n\tbackground: url(\"images/animated-overlay.gif\");\n\theight: 100%;\n\tfilter: alpha(opacity=25);\n\topacity: 0.25;\n}\n.ui-progressbar-indeterminate .ui-progressbar-value {\n\tbackground-image: none;\n}\n.ui-resizable {\n\tposition: relative;\n}\n.ui-resizable-handle {\n\tposition: absolute;\n\tfont-size: 0.1px;\n\tdisplay: block;\n}\n.ui-resizable-disabled .ui-resizable-handle,\n.ui-resizable-autohide .ui-resizable-handle {\n\tdisplay: none;\n}\n.ui-resizable-n {\n\tcursor: n-resize;\n\theight: 7px;\n\twidth: 100%;\n\ttop: -5px;\n\tleft: 0;\n}\n.ui-resizable-s {\n\tcursor: s-resize;\n\theight: 7px;\n\twidth: 100%;\n\tbottom: -5px;\n\tleft: 0;\n}\n.ui-resizable-e {\n\tcursor: e-resize;\n\twidth: 7px;\n\tright: -5px;\n\ttop: 0;\n\theight: 100%;\n}\n.ui-resizable-w {\n\tcursor: w-resize;\n\twidth: 7px;\n\tleft: -5px;\n\ttop: 0;\n\theight: 100%;\n}\n.ui-resizable-se {\n\tcursor: se-resize;\n\twidth: 12px;\n\theight: 12px;\n\tright: 1px;\n\tbottom: 1px;\n}\n.ui-resizable-sw {\n\tcursor: sw-resize;\n\twidth: 9px;\n\theight: 9px;\n\tleft: -5px;\n\tbottom: -5px;\n}\n.ui-resizable-nw {\n\tcursor: nw-resize;\n\twidth: 9px;\n\theight: 9px;\n\tleft: -5px;\n\ttop: -5px;\n}\n.ui-resizable-ne {\n\tcursor: ne-resize;\n\twidth: 9px;\n\theight: 9px;\n\tright: -5px;\n\ttop: -5px;\n}\n.ui-selectable-helper {\n\tposition: absolute;\n\tz-index: 100;\n\tborder: 1px dotted black;\n}\n.ui-slider {\n\tposition: relative;\n\ttext-align: left;\n}\n.ui-slider .ui-slider-handle {\n\tposition: absolute;\n\tz-index: 2;\n\twidth: 1.2em;\n\theight: 1.2em;\n\tcursor: default;\n}\n.ui-slider .ui-slider-range {\n\tposition: absolute;\n\tz-index: 1;\n\tfont-size: .7em;\n\tdisplay: block;\n\tborder: 0;\n\tbackground-position: 0 0;\n}\n\n/* For IE8 - See #6727 */\n.ui-slider.ui-state-disabled .ui-slider-handle,\n.ui-slider.ui-state-disabled .ui-slider-range {\n\tfilter: inherit;\n}\n\n.ui-slider-horizontal {\n\theight: .8em;\n}\n.ui-slider-horizontal .ui-slider-handle {\n\ttop: -.3em;\n\tmargin-left: -.6em;\n}\n.ui-slider-horizontal .ui-slider-range {\n\ttop: 0;\n\theight: 100%;\n}\n.ui-slider-horizontal .ui-slider-range-min {\n\tleft: 0;\n}\n.ui-slider-horizontal .ui-slider-range-max {\n\tright: 0;\n}\n\n.ui-slider-vertical {\n\twidth: .8em;\n\theight: 100px;\n}\n.ui-slider-vertical .ui-slider-handle {\n\tleft: -.3em;\n\tmargin-left: 0;\n\tmargin-bottom: -.6em;\n}\n.ui-slider-vertical .ui-slider-range {\n\tleft: 0;\n\twidth: 100%;\n}\n.ui-slider-vertical .ui-slider-range-min {\n\tbottom: 0;\n}\n.ui-slider-vertical .ui-slider-range-max {\n\ttop: 0;\n}\n.ui-spinner {\n\tposition: relative;\n\tdisplay: inline-block;\n\toverflow: hidden;\n\tpadding: 0;\n\tvertical-align: middle;\n}\n.ui-spinner-input {\n\tborder: none;\n\tbackground: none;\n\tcolor: inherit;\n\tpadding: 0;\n\tmargin: .2em 0;\n\tvertical-align: middle;\n\tmargin-left: .4em;\n\tmargin-right: 22px;\n}\n.ui-spinner-button {\n\twidth: 16px;\n\theight: 50%;\n\tfont-size: .5em;\n\tpadding: 0;\n\tmargin: 0;\n\ttext-align: center;\n\tposition: absolute;\n\tcursor: default;\n\tdisplay: block;\n\toverflow: hidden;\n\tright: 0;\n}\n/* more specificity required here to overide default borders */\n.ui-spinner a.ui-spinner-button {\n\tborder-top: none;\n\tborder-bottom: none;\n\tborder-right: none;\n}\n/* vertical centre icon */\n.ui-spinner .ui-icon {\n\tposition: absolute;\n\tmargin-top: -8px;\n\ttop: 50%;\n\tleft: 0;\n}\n.ui-spinner-up {\n\ttop: 0;\n}\n.ui-spinner-down {\n\tbottom: 0;\n}\n\n/* TR overrides */\n.ui-spinner .ui-icon-triangle-1-s {\n\t/* need to fix icons sprite */\n\tbackground-position: -65px -16px;\n}\n.ui-tabs {\n\tposition: relative;/* position: relative prevents IE scroll bug (element with position: relative inside container with overflow: auto appear as \"fixed\") */\n\tpadding: .2em;\n}\n.ui-tabs .ui-tabs-nav {\n\tmargin: 0;\n\tpadding: .2em .2em 0;\n}\n.ui-tabs .ui-tabs-nav li {\n\tlist-style: none;\n\tfloat: left;\n\tposition: relative;\n\ttop: 0;\n\tmargin: 1px .2em 0 0;\n\tborder-bottom: 0;\n\tpadding: 0;\n\twhite-space: nowrap;\n}\n.ui-tabs .ui-tabs-nav li a {\n\tfloat: left;\n\tpadding: .5em 1em;\n\ttext-decoration: none;\n}\n.ui-tabs .ui-tabs-nav li.ui-tabs-active {\n\tmargin-bottom: -1px;\n\tpadding-bottom: 1px;\n}\n.ui-tabs .ui-tabs-nav li.ui-tabs-active a,\n.ui-tabs .ui-tabs-nav li.ui-state-disabled a,\n.ui-tabs .ui-tabs-nav li.ui-tabs-loading a {\n\tcursor: text;\n}\n.ui-tabs .ui-tabs-nav li a, /* first selector in group seems obsolete, but required to overcome bug in Opera applying cursor: text overall if defined elsewhere... */\n.ui-tabs-collapsible .ui-tabs-nav li.ui-tabs-active a {\n\tcursor: pointer;\n}\n.ui-tabs .ui-tabs-panel {\n\tdisplay: block;\n\tborder-width: 0;\n\tpadding: 1em 1.4em;\n\tbackground: none;\n}\n.ui-tooltip {\n\tpadding: 8px;\n\tposition: absolute;\n\tz-index: 9999;\n\tmax-width: 300px;\n\t-webkit-box-shadow: 0 0 5px #aaa;\n\tbox-shadow: 0 0 5px #aaa;\n}\nbody .ui-tooltip {\n\tborder-width: 2px;\n}\n\n/* Component containers\n----------------------------------*/\n.ui-widget {\n\tfont-family: Verdana,Arial,sans-serif/*{ffDefault}*/;\n\tfont-size: 1.1em/*{fsDefault}*/;\n}\n.ui-widget .ui-widget {\n\tfont-size: 1em;\n}\n.ui-widget input,\n.ui-widget select,\n.ui-widget textarea,\n.ui-widget button {\n\tfont-family: Verdana,Arial,sans-serif/*{ffDefault}*/;\n\tfont-size: 1em;\n}\n.ui-widget-content {\n\tborder: 1px solid #aaaaaa/*{borderColorContent}*/;\n\tbackground: #ffffff/*{bgColorContent}*/ url(images/ui-bg_flat_75_ffffff_40x100.png)/*{bgImgUrlContent}*/ 50%/*{bgContentXPos}*/ 50%/*{bgContentYPos}*/ repeat-x/*{bgContentRepeat}*/;\n\tcolor: #222222/*{fcContent}*/;\n}\n.ui-widget-content a {\n\tcolor: #222222/*{fcContent}*/;\n}\n.ui-widget-header {\n\tborder: 1px solid #aaaaaa/*{borderColorHeader}*/;\n\tbackground: #cccccc/*{bgColorHeader}*/ url(images/ui-bg_highlight-soft_75_cccccc_1x100.png)/*{bgImgUrlHeader}*/ 50%/*{bgHeaderXPos}*/ 50%/*{bgHeaderYPos}*/ repeat-x/*{bgHeaderRepeat}*/;\n\tcolor: #222222/*{fcHeader}*/;\n\tfont-weight: bold;\n}\n.ui-widget-header a {\n\tcolor: #222222/*{fcHeader}*/;\n}\n\n/* Interaction states\n----------------------------------*/\n.ui-state-default,\n.ui-widget-content .ui-state-default,\n.ui-widget-header .ui-state-default {\n\tborder: 1px solid #d3d3d3/*{borderColorDefault}*/;\n\tbackground: #e6e6e6/*{bgColorDefault}*/ url(images/ui-bg_glass_75_e6e6e6_1x400.png)/*{bgImgUrlDefault}*/ 50%/*{bgDefaultXPos}*/ 50%/*{bgDefaultYPos}*/ repeat-x/*{bgDefaultRepeat}*/;\n\tfont-weight: normal/*{fwDefault}*/;\n\tcolor: #555555/*{fcDefault}*/;\n}\n.ui-state-default a,\n.ui-state-default a:link,\n.ui-state-default a:visited {\n\tcolor: #555555/*{fcDefault}*/;\n\ttext-decoration: none;\n}\n.ui-state-hover,\n.ui-widget-content .ui-state-hover,\n.ui-widget-header .ui-state-hover,\n.ui-state-focus,\n.ui-widget-content .ui-state-focus,\n.ui-widget-header .ui-state-focus {\n\tborder: 1px solid #999999/*{borderColorHover}*/;\n\tbackground: #dadada/*{bgColorHover}*/ url(images/ui-bg_glass_75_dadada_1x400.png)/*{bgImgUrlHover}*/ 50%/*{bgHoverXPos}*/ 50%/*{bgHoverYPos}*/ repeat-x/*{bgHoverRepeat}*/;\n\tfont-weight: normal/*{fwDefault}*/;\n\tcolor: #212121/*{fcHover}*/;\n}\n.ui-state-hover a,\n.ui-state-hover a:hover,\n.ui-state-hover a:link,\n.ui-state-hover a:visited {\n\tcolor: #212121/*{fcHover}*/;\n\ttext-decoration: none;\n}\n.ui-state-active,\n.ui-widget-content .ui-state-active,\n.ui-widget-header .ui-state-active {\n\tborder: 1px solid #aaaaaa/*{borderColorActive}*/;\n\tbackground: #ffffff/*{bgColorActive}*/ url(images/ui-bg_glass_65_ffffff_1x400.png)/*{bgImgUrlActive}*/ 50%/*{bgActiveXPos}*/ 50%/*{bgActiveYPos}*/ repeat-x/*{bgActiveRepeat}*/;\n\tfont-weight: normal/*{fwDefault}*/;\n\tcolor: #212121/*{fcActive}*/;\n}\n.ui-state-active a,\n.ui-state-active a:link,\n.ui-state-active a:visited {\n\tcolor: #212121/*{fcActive}*/;\n\ttext-decoration: none;\n}\n\n/* Interaction Cues\n----------------------------------*/\n.ui-state-highlight,\n.ui-widget-content .ui-state-highlight,\n.ui-widget-header .ui-state-highlight {\n\tborder: 1px solid #fcefa1/*{borderColorHighlight}*/;\n\tbackground: #fbf9ee/*{bgColorHighlight}*/ url(images/ui-bg_glass_55_fbf9ee_1x400.png)/*{bgImgUrlHighlight}*/ 50%/*{bgHighlightXPos}*/ 50%/*{bgHighlightYPos}*/ repeat-x/*{bgHighlightRepeat}*/;\n\tcolor: #363636/*{fcHighlight}*/;\n}\n.ui-state-highlight a,\n.ui-widget-content .ui-state-highlight a,\n.ui-widget-header .ui-state-highlight a {\n\tcolor: #363636/*{fcHighlight}*/;\n}\n.ui-state-error,\n.ui-widget-content .ui-state-error,\n.ui-widget-header .ui-state-error {\n\tborder: 1px solid #cd0a0a/*{borderColorError}*/;\n\tbackground: #fef1ec/*{bgColorError}*/ url(images/ui-bg_glass_95_fef1ec_1x400.png)/*{bgImgUrlError}*/ 50%/*{bgErrorXPos}*/ 50%/*{bgErrorYPos}*/ repeat-x/*{bgErrorRepeat}*/;\n\tcolor: #cd0a0a/*{fcError}*/;\n}\n.ui-state-error a,\n.ui-widget-content .ui-state-error a,\n.ui-widget-header .ui-state-error a {\n\tcolor: #cd0a0a/*{fcError}*/;\n}\n.ui-state-error-text,\n.ui-widget-content .ui-state-error-text,\n.ui-widget-header .ui-state-error-text {\n\tcolor: #cd0a0a/*{fcError}*/;\n}\n.ui-priority-primary,\n.ui-widget-content .ui-priority-primary,\n.ui-widget-header .ui-priority-primary {\n\tfont-weight: bold;\n}\n.ui-priority-secondary,\n.ui-widget-content .ui-priority-secondary,\n.ui-widget-header .ui-priority-secondary {\n\topacity: .7;\n\tfilter:Alpha(Opacity=70);\n\tfont-weight: normal;\n}\n.ui-state-disabled,\n.ui-widget-content .ui-state-disabled,\n.ui-widget-header .ui-state-disabled {\n\topacity: .35;\n\tfilter:Alpha(Opacity=35);\n\tbackground-image: none;\n}\n.ui-state-disabled .ui-icon {\n\tfilter:Alpha(Opacity=35); /* For IE8 - See #6059 */\n}\n\n/* Icons\n----------------------------------*/\n\n/* states and images */\n.ui-icon {\n\twidth: 16px;\n\theight: 16px;\n\tbackground-position: 16px 16px;\n}\n.ui-icon,\n.ui-widget-content .ui-icon {\n\tbackground-image: url(images/ui-icons_222222_256x240.png)/*{iconsContent}*/;\n}\n.ui-widget-header .ui-icon {\n\tbackground-image: url(images/ui-icons_222222_256x240.png)/*{iconsHeader}*/;\n}\n.ui-state-default .ui-icon {\n\tbackground-image: url(images/ui-icons_888888_256x240.png)/*{iconsDefault}*/;\n}\n.ui-state-hover .ui-icon,\n.ui-state-focus .ui-icon {\n\tbackground-image: url(images/ui-icons_454545_256x240.png)/*{iconsHover}*/;\n}\n.ui-state-active .ui-icon {\n\tbackground-image: url(images/ui-icons_454545_256x240.png)/*{iconsActive}*/;\n}\n.ui-state-highlight .ui-icon {\n\tbackground-image: url(images/ui-icons_2e83ff_256x240.png)/*{iconsHighlight}*/;\n}\n.ui-state-error .ui-icon,\n.ui-state-error-text .ui-icon {\n\tbackground-image: url(images/ui-icons_cd0a0a_256x240.png)/*{iconsError}*/;\n}\n\n/* positioning */\n.ui-icon-carat-1-n { background-position: 0 0; }\n.ui-icon-carat-1-ne { background-position: -16px 0; }\n.ui-icon-carat-1-e { background-position: -32px 0; }\n.ui-icon-carat-1-se { background-position: -48px 0; }\n.ui-icon-carat-1-s { background-position: -64px 0; }\n.ui-icon-carat-1-sw { background-position: -80px 0; }\n.ui-icon-carat-1-w { background-position: -96px 0; }\n.ui-icon-carat-1-nw { background-position: -112px 0; }\n.ui-icon-carat-2-n-s { background-position: -128px 0; }\n.ui-icon-carat-2-e-w { background-position: -144px 0; }\n.ui-icon-triangle-1-n { background-position: 0 -16px; }\n.ui-icon-triangle-1-ne { background-position: -16px -16px; }\n.ui-icon-triangle-1-e { background-position: -32px -16px; }\n.ui-icon-triangle-1-se { background-position: -48px -16px; }\n.ui-icon-triangle-1-s { background-position: -64px -16px; }\n.ui-icon-triangle-1-sw { background-position: -80px -16px; }\n.ui-icon-triangle-1-w { background-position: -96px -16px; }\n.ui-icon-triangle-1-nw { background-position: -112px -16px; }\n.ui-icon-triangle-2-n-s { background-position: -128px -16px; }\n.ui-icon-triangle-2-e-w { background-position: -144px -16px; }\n.ui-icon-arrow-1-n { background-position: 0 -32px; }\n.ui-icon-arrow-1-ne { background-position: -16px -32px; }\n.ui-icon-arrow-1-e { background-position: -32px -32px; }\n.ui-icon-arrow-1-se { background-position: -48px -32px; }\n.ui-icon-arrow-1-s { background-position: -64px -32px; }\n.ui-icon-arrow-1-sw { background-position: -80px -32px; }\n.ui-icon-arrow-1-w { background-position: -96px -32px; }\n.ui-icon-arrow-1-nw { background-position: -112px -32px; }\n.ui-icon-arrow-2-n-s { background-position: -128px -32px; }\n.ui-icon-arrow-2-ne-sw { background-position: -144px -32px; }\n.ui-icon-arrow-2-e-w { background-position: -160px -32px; }\n.ui-icon-arrow-2-se-nw { background-position: -176px -32px; }\n.ui-icon-arrowstop-1-n { background-position: -192px -32px; }\n.ui-icon-arrowstop-1-e { background-position: -208px -32px; }\n.ui-icon-arrowstop-1-s { background-position: -224px -32px; }\n.ui-icon-arrowstop-1-w { background-position: -240px -32px; }\n.ui-icon-arrowthick-1-n { background-position: 0 -48px; }\n.ui-icon-arrowthick-1-ne { background-position: -16px -48px; }\n.ui-icon-arrowthick-1-e { background-position: -32px -48px; }\n.ui-icon-arrowthick-1-se { background-position: -48px -48px; }\n.ui-icon-arrowthick-1-s { background-position: -64px -48px; }\n.ui-icon-arrowthick-1-sw { background-position: -80px -48px; }\n.ui-icon-arrowthick-1-w { background-position: -96px -48px; }\n.ui-icon-arrowthick-1-nw { background-position: -112px -48px; }\n.ui-icon-arrowthick-2-n-s { background-position: -128px -48px; }\n.ui-icon-arrowthick-2-ne-sw { background-position: -144px -48px; }\n.ui-icon-arrowthick-2-e-w { background-position: -160px -48px; }\n.ui-icon-arrowthick-2-se-nw { background-position: -176px -48px; }\n.ui-icon-arrowthickstop-1-n { background-position: -192px -48px; }\n.ui-icon-arrowthickstop-1-e { background-position: -208px -48px; }\n.ui-icon-arrowthickstop-1-s { background-position: -224px -48px; }\n.ui-icon-arrowthickstop-1-w { background-position: -240px -48px; }\n.ui-icon-arrowreturnthick-1-w { background-position: 0 -64px; }\n.ui-icon-arrowreturnthick-1-n { background-position: -16px -64px; }\n.ui-icon-arrowreturnthick-1-e { background-position: -32px -64px; }\n.ui-icon-arrowreturnthick-1-s { background-position: -48px -64px; }\n.ui-icon-arrowreturn-1-w { background-position: -64px -64px; }\n.ui-icon-arrowreturn-1-n { background-position: -80px -64px; }\n.ui-icon-arrowreturn-1-e { background-position: -96px -64px; }\n.ui-icon-arrowreturn-1-s { background-position: -112px -64px; }\n.ui-icon-arrowrefresh-1-w { background-position: -128px -64px; }\n.ui-icon-arrowrefresh-1-n { background-position: -144px -64px; }\n.ui-icon-arrowrefresh-1-e { background-position: -160px -64px; }\n.ui-icon-arrowrefresh-1-s { background-position: -176px -64px; }\n.ui-icon-arrow-4 { background-position: 0 -80px; }\n.ui-icon-arrow-4-diag { background-position: -16px -80px; }\n.ui-icon-extlink { background-position: -32px -80px; }\n.ui-icon-newwin { background-position: -48px -80px; }\n.ui-icon-refresh { background-position: -64px -80px; }\n.ui-icon-shuffle { background-position: -80px -80px; }\n.ui-icon-transfer-e-w { background-position: -96px -80px; }\n.ui-icon-transferthick-e-w { background-position: -112px -80px; }\n.ui-icon-folder-collapsed { background-position: 0 -96px; }\n.ui-icon-folder-open { background-position: -16px -96px; }\n.ui-icon-document { background-position: -32px -96px; }\n.ui-icon-document-b { background-position: -48px -96px; }\n.ui-icon-note { background-position: -64px -96px; }\n.ui-icon-mail-closed { background-position: -80px -96px; }\n.ui-icon-mail-open { background-position: -96px -96px; }\n.ui-icon-suitcase { background-position: -112px -96px; }\n.ui-icon-comment { background-position: -128px -96px; }\n.ui-icon-person { background-position: -144px -96px; }\n.ui-icon-print { background-position: -160px -96px; }\n.ui-icon-trash { background-position: -176px -96px; }\n.ui-icon-locked { background-position: -192px -96px; }\n.ui-icon-unlocked { background-position: -208px -96px; }\n.ui-icon-bookmark { background-position: -224px -96px; }\n.ui-icon-tag { background-position: -240px -96px; }\n.ui-icon-home { background-position: 0 -112px; }\n.ui-icon-flag { background-position: -16px -112px; }\n.ui-icon-calendar { background-position: -32px -112px; }\n.ui-icon-cart { background-position: -48px -112px; }\n.ui-icon-pencil { background-position: -64px -112px; }\n.ui-icon-clock { background-position: -80px -112px; }\n.ui-icon-disk { background-position: -96px -112px; }\n.ui-icon-calculator { background-position: -112px -112px; }\n.ui-icon-zoomin { background-position: -128px -112px; }\n.ui-icon-zoomout { background-position: -144px -112px; }\n.ui-icon-search { background-position: -160px -112px; }\n.ui-icon-wrench { background-position: -176px -112px; }\n.ui-icon-gear { background-position: -192px -112px; }\n.ui-icon-heart { background-position: -208px -112px; }\n.ui-icon-star { background-position: -224px -112px; }\n.ui-icon-link { background-position: -240px -112px; }\n.ui-icon-cancel { background-position: 0 -128px; }\n.ui-icon-plus { background-position: -16px -128px; }\n.ui-icon-plusthick { background-position: -32px -128px; }\n.ui-icon-minus { background-position: -48px -128px; }\n.ui-icon-minusthick { background-position: -64px -128px; }\n.ui-icon-close { background-position: -80px -128px; }\n.ui-icon-closethick { background-position: -96px -128px; }\n.ui-icon-key { background-position: -112px -128px; }\n.ui-icon-lightbulb { background-position: -128px -128px; }\n.ui-icon-scissors { background-position: -144px -128px; }\n.ui-icon-clipboard { background-position: -160px -128px; }\n.ui-icon-copy { background-position: -176px -128px; }\n.ui-icon-contact { background-position: -192px -128px; }\n.ui-icon-image { background-position: -208px -128px; }\n.ui-icon-video { background-position: -224px -128px; }\n.ui-icon-script { background-position: -240px -128px; }\n.ui-icon-alert { background-position: 0 -144px; }\n.ui-icon-info { background-position: -16px -144px; }\n.ui-icon-notice { background-position: -32px -144px; }\n.ui-icon-help { background-position: -48px -144px; }\n.ui-icon-check { background-position: -64px -144px; }\n.ui-icon-bullet { background-position: -80px -144px; }\n.ui-icon-radio-on { background-position: -96px -144px; }\n.ui-icon-radio-off { background-position: -112px -144px; }\n.ui-icon-pin-w { background-position: -128px -144px; }\n.ui-icon-pin-s { background-position: -144px -144px; }\n.ui-icon-play { background-position: 0 -160px; }\n.ui-icon-pause { background-position: -16px -160px; }\n.ui-icon-seek-next { background-position: -32px -160px; }\n.ui-icon-seek-prev { background-position: -48px -160px; }\n.ui-icon-seek-end { background-position: -64px -160px; }\n.ui-icon-seek-start { background-position: -80px -160px; }\n/* ui-icon-seek-first is deprecated, use ui-icon-seek-start instead */\n.ui-icon-seek-first { background-position: -80px -160px; }\n.ui-icon-stop { background-position: -96px -160px; }\n.ui-icon-eject { background-position: -112px -160px; }\n.ui-icon-volume-off { background-position: -128px -160px; }\n.ui-icon-volume-on { background-position: -144px -160px; }\n.ui-icon-power { background-position: 0 -176px; }\n.ui-icon-signal-diag { background-position: -16px -176px; }\n.ui-icon-signal { background-position: -32px -176px; }\n.ui-icon-battery-0 { background-position: -48px -176px; }\n.ui-icon-battery-1 { background-position: -64px -176px; }\n.ui-icon-battery-2 { background-position: -80px -176px; }\n.ui-icon-battery-3 { background-position: -96px -176px; }\n.ui-icon-circle-plus { background-position: 0 -192px; }\n.ui-icon-circle-minus { background-position: -16px -192px; }\n.ui-icon-circle-close { background-position: -32px -192px; }\n.ui-icon-circle-triangle-e { background-position: -48px -192px; }\n.ui-icon-circle-triangle-s { background-position: -64px -192px; }\n.ui-icon-circle-triangle-w { background-position: -80px -192px; }\n.ui-icon-circle-triangle-n { background-position: -96px -192px; }\n.ui-icon-circle-arrow-e { background-position: -112px -192px; }\n.ui-icon-circle-arrow-s { background-position: -128px -192px; }\n.ui-icon-circle-arrow-w { background-position: -144px -192px; }\n.ui-icon-circle-arrow-n { background-position: -160px -192px; }\n.ui-icon-circle-zoomin { background-position: -176px -192px; }\n.ui-icon-circle-zoomout { background-position: -192px -192px; }\n.ui-icon-circle-check { background-position: -208px -192px; }\n.ui-icon-circlesmall-plus { background-position: 0 -208px; }\n.ui-icon-circlesmall-minus { background-position: -16px -208px; }\n.ui-icon-circlesmall-close { background-position: -32px -208px; }\n.ui-icon-squaresmall-plus { background-position: -48px -208px; }\n.ui-icon-squaresmall-minus { background-position: -64px -208px; }\n.ui-icon-squaresmall-close { background-position: -80px -208px; }\n.ui-icon-grip-dotted-vertical { background-position: 0 -224px; }\n.ui-icon-grip-dotted-horizontal { background-position: -16px -224px; }\n.ui-icon-grip-solid-vertical { background-position: -32px -224px; }\n.ui-icon-grip-solid-horizontal { background-position: -48px -224px; }\n.ui-icon-gripsmall-diagonal-se { background-position: -64px -224px; }\n.ui-icon-grip-diagonal-se { background-position: -80px -224px; }\n\n\n/* Misc visuals\n----------------------------------*/\n\n/* Corner radius */\n.ui-corner-all,\n.ui-corner-top,\n.ui-corner-left,\n.ui-corner-tl {\n\tborder-top-left-radius: 4px/*{cornerRadius}*/;\n}\n.ui-corner-all,\n.ui-corner-top,\n.ui-corner-right,\n.ui-corner-tr {\n\tborder-top-right-radius: 4px/*{cornerRadius}*/;\n}\n.ui-corner-all,\n.ui-corner-bottom,\n.ui-corner-left,\n.ui-corner-bl {\n\tborder-bottom-left-radius: 4px/*{cornerRadius}*/;\n}\n.ui-corner-all,\n.ui-corner-bottom,\n.ui-corner-right,\n.ui-corner-br {\n\tborder-bottom-right-radius: 4px/*{cornerRadius}*/;\n}\n\n/* Overlays */\n.ui-widget-overlay {\n\tbackground: #aaaaaa/*{bgColorOverlay}*/ url(images/ui-bg_flat_0_aaaaaa_40x100.png)/*{bgImgUrlOverlay}*/ 50%/*{bgOverlayXPos}*/ 50%/*{bgOverlayYPos}*/ repeat-x/*{bgOverlayRepeat}*/;\n\topacity: .3/*{opacityOverlay}*/;\n\tfilter: Alpha(Opacity=30)/*{opacityFilterOverlay}*/;\n}\n.ui-widget-shadow {\n\tmargin: -8px/*{offsetTopShadow}*/ 0 0 -8px/*{offsetLeftShadow}*/;\n\tpadding: 8px/*{thicknessShadow}*/;\n\tbackground: #aaaaaa/*{bgColorShadow}*/ url(images/ui-bg_flat_0_aaaaaa_40x100.png)/*{bgImgUrlShadow}*/ 50%/*{bgShadowXPos}*/ 50%/*{bgShadowYPos}*/ repeat-x/*{bgShadowRepeat}*/;\n\topacity: .3/*{opacityShadow}*/;\n\tfilter: Alpha(Opacity=30)/*{opacityFilterShadow}*/;\n\tborder-radius: 8px/*{cornerRadiusShadow}*/;\n}\n","styles/video.css":".h5p-video \u003e video {\n background: #000;\n}\n.h5p-video-flash {\n color: #fff;\n}\n.h5p-video-loading {\n display: none;\n position: absolute;\n top: 0;\n left: 0;\n width: 100%;\n height: 100%;\n background: #000 url(\u0027data:image/gif;base64,R0lGODlhIAAgAPUAAAAAAP///1RUVHp6ep6enrKyssDAwLa2tqioqI6OjnBwcF5eXpiYmMrKyszMzMbGxry8vIqKilhYWFBQUJSUlM7Ozk5OTtTU1KKiompqatjY2Nzc3HZ2dmZmZoCAgKysrISEhODg4N7e3uLi4mJiYujo6EREROzs7EpKSkBAQDAwMCwsLCYmJjY2Njo6OhwcHBISEhgYGA4ODggICAICAiIiIvr6+v////T09AAAAAAAAAAAAAAAAAAAAAAAAAAAACH+GkNyZWF0ZWQgd2l0aCBhamF4bG9hZC5pbmZvACH5BAAHAAAAIf8LTkVUU0NBUEUyLjADAQAAACwAAAAAIAAgAAAG/0CAcEicDBCOS8lBbDqfgAUidDqVSlaoliggbEbX8Amy3S4MoXQ6fC1DM5eNeh0+uJ0Lx0YuWj8IEQoKd0UQGhsaIooGGYRQFBcakocRjlALFReRGhcDllAMFZmalZ9OAg0VDqofpk8Dqw0ODo2uTQSzDQ12tk0FD8APCb1NBsYGDxzERMcGEB3LQ80QtdEHEAfZg9EACNnZHtwACd8FBOIKBwXqCAvcAgXxCAjD3BEF8xgE28sS8wj6CLi7Q2PLAAz6GDBIQMLNjIJaLDBIuBCEAhRQYMh4WEYCgY8JIoDwoGCBhRQqVrBg8SIGjBkcAUDEQ2GhyAEcMnSQYMFEC0QVLDXCpEFUiwAQIUEMGJCBhEkTLoC2hPFyhhsLGW4K6rBAAIoUP1m6hOEIK04FGRY8jaryBdlPJgQscLpgggmULMoEAQAh+QQABwABACwAAAAAIAAgAAAG/0CAcEicDDCPSqnUeCBAxKiUuEBoQqGltnQSTb9CAUMjEo2woZHWpgBPFxDNZoPGqpc3iTvaeWjkG2V2dyUbe1QPFxd/ciIGDBEKChEEB4dCEwcVFYqLBxmXYAkOm6QVEaFgCw+kDQ4NHKlgFA21rlCyUwIPvLwIuV8cBsMGDx3AUwzEBr/IUggHENKozlEH19dt1UQF2AfH20MF3QcF4OEACN0FCNroBAUfCAgD6EIR8ggYCfYAGfoICBBYYE+APgwCPfQDgZAAgwTntkkQyIBCggh60HFg8DACiAEZt1kAcTHCgAEKFqT4MoPGJQERYp5UkGGBBRcqWLyIAWNGy0JQEmSi7LBgggmcOmHI+BnKAgeUCogaRbqzJ9NLKEhIIioARYoWK2rwXNrSZSgTC7haOJpTrNIZzkygQMF2RdI9QQAAIfkEAAcAAgAsAAAAACAAIAAABv9AgHBInHAwj0ZI9HggBhOidDpcYC4b0SY0GpW+pxFiQaUKKJWLRpPlhrjf0ulEKBMXh7R6LRK933EnNyR2Qh0GFYkXexttJV5fNgiFAAsGDhUOmIsQFCAKChEEF5GUEwVJmpoHGWUKGgOUEQ8GBk0PIJS6CxC1vgq6ugm+tbnBhQIHEMoGdceFCgfS0h3PhQnTB87WZQQFBQcFHtx2CN8FCK3kVAgfCO9k61PvCBgYhPJSGPUYBOr5Qxj0I8AAGMAhIAgQZGDsIIAMCxNEEOAQwAQKCSR+qghAgcQIHgZIqDhB44ABCkxUDBVSQYYOKg9aOMlBQYcFEkyokInS5oJECSZcqKgRA8aMGTRoWLOQIQOJBRaCqmDxAoYMpORMLHgaVShVq1jJpbAgoevUqleVynNhQioLokaRqpWnYirctHPLBAEAIfkEAAcAAwAsAAAAACAAIAAABv9AgHBInCgIBsNmkyQMJsSodLggNC5YjWYZGoU0iMV0Kkg8Kg5HdisKuUelEkEwHko+jXS+ctFuRG1ucSUPYmMdBw8GDw15an1LbV6DJSIKUxIHSUmMDgcJIAoKIAwNI3BxODcPUhMIBhCbBggdYwoGgycEUyAHvrEHHnVDCSc3DpgFvsuXw0MeCGMRB8q+A87YAAIF3NwU2dgZH9wIYeDOIOXl3+fDDBgYCE7twwT29rX0Y/cMDBL6+/oxSPAPoJQECBNEMGSQCAiEEUDkazhEgUIQA5pRFLJAoYeMJjYKsQACI4cMDDdmGMBBQQYSIUVaaPlywYQWIgEsUNBhgQRHCyZUiDRBgoRNFClasIix0YRPoC5UsHgBQ8YMGjQAmpgAVSpVq1kNujBhIurUqlcpqnBh9mvajSxWnAWLNWeMGDBm6K2LLQgAIfkEAAcABAAsAAAAACAAIAAABv9AgHBInCgYB8jlAjEQOBOidDqUMAwNR2V70XhFF8SCShVEDIbHo5GtdL0bkWhDEJCrmCY63V5+RSEhIw9jZCQIB0l7aw4NfnGAISUlGhlUEoiJBwZNBQkeGRkgDA8agYGTGoVDEwQHBZoHGB1kGRAiIyOTJQ92QwMFsMIDd0MJIruTBFUICB/PCJbFv7qTNjYSQh4YGM0IHNNSCSUnNwas3NwEEeFTDhpSGQTz86vtQtlSAwwEDAzs96ZFYECBQQJpAe9ESMAwgr2EUxJEiAACRBSIZCSCGDDgIsYpFTlC+UiFA0cFCnyRJNKBg4IMHfKtrIKyAwkJLmYOMQHz5gRVEzqrkFggAIUJFUEBmFggwYIJFypqJEUxAUUKqCxiBHVhFOqKGjFgzNDZ4qkKFi9gyJhBg8ZMFS3Opl3rVieLu2FnsE0K4MXcvXzD0q3LF4BewAGDAAAh+QQABwAFACwAAAAAIAAgAAAG/0CAcEicKBKHg6ORZCgmxKh0KElADNiHo8K9XCqYxXQ6ARWSV2yj4XB4NZoLQTCmEg7nQ9rwYLsvcBsiBmJjCwgFiUkHWX1tbxoiIiEXGVMSBAgfikkIEQMZGR4JBoCCkyMXhUMTFAgYCJoFDB1jGQeSISEjJQZQQwOvsbEcdUMRG7ohJSUEdgTQBBi1xsAbI7vMhQPR0ArVUQm8zCUIABYJFAkMDB7gUhDkzBIkCfb2Eu9RGeQnJxEcEkSIAGKAPikPSti4YYPAABAgPIAgcTAKgg0E8gGIOKAjnYp1Og7goAAFyDokFYQycXKMAgUdOixg2VJKTBILJNCsSYTeAlYBFnbyFIJCAlATKVgMHeJCQtAULlQsHWICaVQWL6YCUGHiao0XMLSqULECKwwYM6ayUIE1BtoZNGgsZWFWBly5U1+4nQFXq5CzfPH6BRB4MBHBhpcGAQAh+QQABwAGACwAAAAAIAAgAAAG/0CAcEgEZBKIgsFQKFAUk6J0Kkl8DljI0vBwOB6ExXQ6GSSb2MO2W2lXKILxUEJBID6FtHr5aHgrFxcQYmMLDHZ2eGl8fV6BGhoOGVMCDAQEGIgIBCADHRkDCQeOkBsbF4RDFiCWl5gJqUUZBxcapqYGUUMKCQmWlgpyQxG1IiHHBEMTvcywwkQcGyIiIyMahAoR2todz0URxiHVCAAoIOceIMHeRQfHIyUjEgsD9fUW7LIlxyUlER0KOChQMClfkQf9+hUAmKFhHINECCQs0aCDRRILTEAk4mGiCBIYJUhwsXFXwhMlRE6wYKFFSSEKTpZYicJEChUvp5iw6cLFikWcUnq6UKGCBdAiKloUZVEjxtEhLIrWeBEDxlOoLF7AgCFjxlUAMah2nTGDxtetZGmoNXs1LduvANLCJaJ2rt27ePPKCQIAIfkEAAcABwAsAAAAACAAIAAABv9AgHBIBHRABMzhgEEkFJOidCoANT+F7PJg6DIW06llkGwiCtsDpGtoPBKC8HACYhCSiDx6ue42Kg4HYGESEQkJdndme2wPfxUVBh1iEYaHDHYJAwokHRwgBQaOjxcPg0Mon5WWIKdFHR8OshcXGhBRQyQDHgMDIBGTckIgf7UbGgxDJgoKvb1xwkMKFcbHgwvM2RLRRREaGscbGAApHeYdGa7cQgcbIiEiGxIoC/X1KetFGSLvIyEgFgQImCDAQj4pEEIoFIHAgkMTKFwcLMJAYYgRBkxodOFCxUQiHkooLLEhBccWKlh8lFZixIgSJVCqWMHixUohCmDqTMmixotJGDcBhNQpgkXNGDBgBCWgs8SDFy+SwpgR9AOOGzZOfEA6dcYMGkEBTGCgIQGArjTShi3iVe1atl/fTokrVwrYunjz6t3Lt+/bIAAh+QQABwAIACwAAAAAIAAgAAAG/0CAcEgEdDwMAqJAIEQyk6J0KhhQCBiEdlk4eCmS6dSiSFCuTe2n64UYIBGBeGgZJO6JpBKx9h7cBg8FC3MTAyAgEXcUSVkfH34GkoEGHVMoCgOHiYoRChkkHQogCAeTDw0OBoRFopkDHiADYVMdCIEPDhUVB1FDExkZCsMcrHMAHgYNFboVFEMuCyShohbHRAoPuxcXFawmEuELC9bXRBEV3NwEACooFvAC5eZEHxca+BoSLSb9/S30imTIt2GDBxUtXCh0EVCKAQ0iCiJQQZHiioZFGGwIEdEAi48fa2AkMiBEiBEhLrxYGeNFjJFDFJwcMUIEjJs4YQqRSbOmjFQZM2TIgKETWQmaJTQAXTqjKIESUEs8oEGValOdDqKWKEBjCI2rIxWcgHriBAgiVHVqKDF2LK2iQ0DguFEWAdwpCW7gMHa3SIK+gAMLHky4sOGAQQAAIfkEAAcACQAsAAAAACAAIAAABv9AgHBIBCw4kQQBQ2F4MsWoFGBRJBNNAgHBLXwSkmnURBqAIleGlosoHAoFkEAsNGU4AzMogdViEB8fbwcQCGFTJh0KiwMeZ3xqf4EHlBAQBx1SKQskGRkKeB4DGR0LCxkDGIKVBgYHh0QWEhKcnxkTUyQElq2tBbhDKRYWAgKmwHQDB70PDQlDKikmJiiyJnRECgYPzQ4PC0IqLS4u0y7YRR7cDhUODAA1Kyrz5OhRCOzsDQIvNSz/KljYK5KBXYUKFwbEWNhP4MAiBxBeuEAAhsWFMR4WYVBBg8cDM2bIsAhDI5EBGjakrBCypQyTQxRsELGhJo2bNELCFKJAhM9dmkNyztgJYECIoyIuEKFBFACDECNGhDDQtMiDo1ERVI1ZAmpUEFuFPCgRtYQIWE0TnCjB9oTWrSBKrGVbAtxWAjfmniAQVsiAvCcuzOkLAO+ITIT9KkjMuLFjmEEAACH5BAAHAAoALAAAAAAgACAAAAb/QIBwSARMOgNPIgECDTrFqBRgWmQUgwEosmQQviDJNOqyLDpXThLU/WIQCM9kLGyhBJIFKa3leglvHwUEYlMqJiYWFgJ6aR5sCV5wCAUFCCRSLC0uLoiLCwsSEhMCewmAcAcFBx+FRCsqsS4piC5TCwkIHwe8BxhzQy8sw7AtKnRCHJW9BhFDMDEv0sMsyEMZvBAG2wtCMN/fMTHWRAMH29sUQjIzMzLf5EUE6A8GAu347fFEHdsPDw4GzKBBkOC+Ih8AOqhAwKAQGgeJJGjgoOIBiBGlDKi48EHGKRkqVLhA8qMUBSQvaLhgMsoAlRo0OGhZhEHMDRoM0CRiYIPPVQ0IdgrJIKLoBhEehAI4EEJE0w2uWiYIQZVq0J0DRjgNMUJDN5oJSpQYwXUEAZoCNIhdW6KBgJ0XcLANAUWojRNiNShQutRG2698N2B4y1dI1MJjggAAIfkEAAcACwAsAAAAACAAIAAABv9AgHBIBJgkHQVnwFQsitAooHVcdDIKxcATSXgHAimURUVZJFbstpugEBiDiVhYU7VcJjM6uQR1GQQECBQSYi8sKyoqeCYCEiRZA34JgIIIBE9QMDEvNYiLJqGhKEgDlIEIqQiFRTCunCyKKlISIKgIHwUEckMzMzIymy8vc0IKGKkFBQcgvb6+wTDFQx24B8sFrDTbNM/TRArLB+MJQjRD3d9FDOMHEBBhRNvqRB3jEAYGA/TFCPn5DPjNifDPwAeBYjg8MPBgIUIpGRo+cNDgYZQMDRo4qFDRYpEBDkJWeOCxSAKRFQ6UJHLgwoUKFwisFJJBg4YLN/fNPKBhg81UC6xKRhAhoqcGmSsHbCAqwmcmjwlEhGAqAqlFBQZKhNi69UE8hAgclBjLdYQGEh4PnBhbYsTYCxlKMrDBduyDpx5trF2L4WtJvSE+4F2ZwYNfKEEAACH5BAAHAAwALAAAAAAgACAAAAb/QIBwSAS0TBPJIsPsSIrQKOC1crlMFmVGwRl4QAqBNBqrrVRXlGDRUSi8kURCYRkPYbEXa9W6ZklbAyBxCRQRYlIzMzJ4emhYWm+DchQMDAtSNDSLeCwqKn1+CwqTCQwEqE9RmzONL1ICA6aoBAgUE5mcdkIZp7UICAO5MrtDJBgYwMCqRZvFRArAHx8FEc/PCdMF24jXYyTUBwUHCt67BAfpBwnmdiDpEBAI7WMK8BAH9FIdBv39+lEy+PsHsAiHBwMLFknwoOGDDwqJFGjgoCKBiLwcVNDoQBjGAhorVGjQrWCECyhFMsA44IIGDSkxKUywoebLCxQUChQRIoRNQwMln7lJQKBCiZ49a1YgQe9BiadHQ4wY4fNCBn0lTkCVOjWEAZn0IGiFWmLEBgJBzZ1YyzYEArAADZy4UOHDAFxjggAAIfkEAAcADQAsAAAAACAAIAAABv9AgHBIBLxYKlcKZRFMLMWoVAiDHVdJk0WyyCgW0Gl0RobFjtltV8EZdMJiAG0+k1lZK5cJNVl02AMgAxNxQzRlMTUrLSkmAn4KAx4gEREShXKHVYlIehJ/kiAJCRECmIczUyYdoaMUEXBSc5gLlKMMBAOYuwu3BL+Xu4UdFL8ECB7CmCC/CAgYpspiCxgYzggK0nEU1x8R2mIDHx8FBQTgUwrkBwUf6FIdBQfsB+9RHfP59kUK+fP7RCIYgDAQAcAhCAwoNEDhIIAODxYa4OAQwYOIEaPtA+GgY4MGDQFyaNCxgoMHCwBGqHChgksHCfZlOKChZssKEDQWQkAgggJNBREYPBCxoaaGCxdQKntQomnTECFEiNBQVMODDNJuOB0BteuGohBSKltgY2uIEWiJamCgc5cGHCecPh2hAYFYbRI+uCxxosIDBIPiBAEAIfkEAAcADgAsAAAAACAAIAAABv9AgHBIBNBmM1isxlK1XMWotHhUvpouk8WSmnqHVdhVlZ1IFhLTV0qrxsZlSSfTQa2JbaSytnKlUBMLHQqEAndDSDJWTX9nGQocAwMTh18uAguPkhEDFpVfFpADIBEJCp9fE6OkCQmGqFMLrAkUHLBeHK0UDAyUt1ESCbwEBBm/UhHExCDHUQrKGBTNRR0I1ggE00Qk19baQ9UIBR8f30IKHwUFB+XmIAfrB9nmBAf2BwnmHRAH/Aen3zAYMACB36tpIAYqzKdNgYEHCg0s0BbhgUWIDyKsEXABYJQMBxxUcOCgwYMDB6fYwHGiAQFTCiIwMKDhwoWRIyWuUXCihM9DEiNGhBi6QUPNCkgNdLhz44RToEGFhiha8+aBiWs6OH0KVaiIDUVvMkj5ZcGHElyDTv16AQNWVKoQlAwxwiKCSV+CAAAh+QQABwAPACwAAAAAIAAgAAAG/0CAcEgk0mYzGOxVKzqfT9pR+WKprtCs8yhbWl2mlEurlSZjVRXYMkmRo8dzbaVKmSaLBer9nHVjXyYoAgsdHSZ8WixrEoUKGXuJWS6EHRkKAySSWiYkl5gDE5tZFgocAx4gCqNZHaggEQkWrE8WA7AJFJq0ThwRsQkcvE4ZCbkJIMNFJAkMzgzKRAsMBNUE0UML1hjX2AAdCBjh3dgDCOcI0N4MHx/nEd4kBfPzq9gEBwX5BQLlB///4D25lUgBBAgAC0h4AuJEiQRvPBiYeBBCMmI2cJQo8SADlA4FHkyk+KFfkQg2bGxcaYCBqgwgEhxw0OCByIkHFjyRsGFliU8QQEUI1aDhQoUKDWiKPNAhy4IGDkuMGBE0BNGiRyvQLKBTiwAMK6eO2CBiA1GjRx8kMPlmwYcNIahumHv2wgMCXTdNMGczxAaRBDiIyhIEACH5BAAHABAALAAAAAAgACAAAAb/QIBwSCwOabSZcclkImcwWKxJXT6lr1p1C3hCY7WVasV1JqGwF0vlcrXKzJlMWlu7TCgXnJm2p1AWE3tNLG0mFhILgoNLKngTiR0mjEsuApEKC5RLAgsdCqAom0UmGaADAxKjRR0cqAMKq0QLAx4gIAOyQxK3Eb66QhK+CcTAABLEycYkCRTOCcYKDATUEcYJ1NQeRhaMCwgYGAQYGUUXD4wJCOvrAkMVNycl0HADHwj3CNtCISfy8rm4ZDhQoGABDKqEYCghr0SJEfSoDDhAkeCBfUImXGg4IsQIA+WWdEAAoSJFDIuGdAjhMITLEBsMUACRIQOIBAceGDBgsoAmVSMKRDgc0VHEBg0aLjhY+kDnTggQCpBosuBBx44wjyatwHTnTgQJmwggICKE0Q1HL1TgWqFBUwMJ3HH5pgEm0gtquTowwCAsnAkDMOzEW5KBgpRLggAAIfkEAAcAEQAsAAAAACAAIAAABv9AgHBILBqPyGSSpmw2aTOntAiVwaZSGhQWi2GX2pk1Vnt9j+EZDPZisc5INbu2UqngxzlL5Urd8UVtfC4mJoBGfCkmFhMuh0QrihYCEoaPQ4sCCx0Sl5gSmx0dnkImJB0ZChmkACapChwcrCiwA7asErYeu0MeBxGAJCAeIBG2Gic2JQ2AAxHPCQoRJycl1gpwEgnb2yQS1uAGcCAMDBQUCRYAH9XgCV8KBPLyA0IL4CEjG/VSHRjz8joJIWAthMENwJpwQMAQAQYE/IQIcFBihMEQIg6sOtKBQYECDREwmFCExIURFkNs0HDhQAIPGTI4+3Cg5oECHxAQEFgkwwVPjCI2rLzgwEGDBw8MGLD5ESSJJAsMBF3JsuhRpQYg1CxwYGcTAQQ0iL1woYJRpFi3giApZQGGCmQryHWQVCmEBDyxTOBAoGbRmxQUsEUSBAAh+QQABwASACwAAAAAIAAgAAAG/0CAcEgsGo/IpHLJbDqf0CiNNosyp1UrckqdwbRHrBcWAxdnaBjsxTYTZepXjcVyE2Nylqq1sgtjLCt7Li1+QoMuJimGACqJJigojCqQFgISBg8PBgZmLgKXEgslJyclJRlgLgusHR0ip6cRYCiuGbcOsSUEYBIKvwoZBaanD2AZHAMDHB0RpiEhqFYTyh7KCxIjJSMjIRBWHCDi4hYACNzdIrNPHQkR7wkKQgsb3NAbHE4LFBQJ/gkThhCAdu/COiUKCChk4E/eEAEPNkjcoOHCgQ5ISCRAgEEhAQYRyhEhcUGihooOHBSIMMDVABAEEMjkuFDCkQwOTl64UMFBA0hNnA4ILfDhw0wCC5IsgLCzQs+fnAwIHWoUAQWbSgQwcOrUwSZOEIYWKIBgQMAmCwg8SPnVQNihCbBCmaCAQYEDnMgmyHAWSRAAIfkEAAcAEwAsAAAAACAAIAAABv9AgHBILBqPyKRyyWw6n9CodEpV0qrLK/ZIo822w2t39gUDut4ZDAAyDLDkmQxGL5xsp8t7OofFYi8OJYMlBFR+gCwsIoQle1IxNYorKo0lClQ1lCoqLoQjJRxULC0upiaMIyElIFQqKSkmsg8lqiEMVC4WKBa9CCG2BlQTEgISEhYgwCEiIhlSJgvSJCQoEhsizBsHUiQZHRnfJgAIGxrnGhFQEgrt7QtCCxob5hoVok0SHgP8HAooQxjMO1fBQaslHSKA8MDQAwkiAgxouHDBgcUPHZBIAJEgQYSPEQYAJEKiwYUKFRo0ePAAAYgBHTooGECBAAEGDDp6FHAkwwNNlA5WGhh64EABBEgR2CRAwaOEJAsOOEj5YCiEokaTYlgKgqcSAQkeCDVwFetRBBiUDrDgZAGDoQbMFijwAW1XKRMUJKhbVGmEDBOUBAEAIfkEAAcAFAAsAAAAACAAIAAABv9AgHBILBqPyKRyyWw6n9CodEqFUqrJRQkHwhoRp5PtNPAKJaVTaf0xA0DqdUnhpdEK8lKDagfYZw8lIyMlBFQzdjQzMxolISElHoeLizIig490UzIwnZ0hmCKaUjAxpi8vGqAiIpJTMTWoLCwGGyIhGwxULCu9vQgbwRoQVCotxy0qHsIaFxlSKiYuKdQqEhrYGhUFUiYWJijhKgAEF80VDl1PJgsSAhMTJkILFRfoDg+jSxYZJAv/ElwMoVChQoMGDwy4UiJBgYIMGTp0mEBEwAEH6BIaQNABiQAOHgYMcKiggzwiCww4QGig5QEMI/9lUAAiQQQQIQdwUIDiSAdQAxoNQDhwoAACBBgIEGCQwOZNEAMoIllQQCNRokaRKmXaNMIAC0sEJHCJtcAHrUqbJlAAtomEBFcLmEWalEACDgKkTMiQQKlRBgxAdGiLJAgAIfkEAAcAFQAsAAAAACAAIAAABv9AgHBILBqPyKRyyWw6n0yFBtpcbHBTanLiKJVsWa2R4PXeNuLiouwdKdJERGk08ibgQ8mmFAqVIHhDICEjfSVvgQAIhH0GiUIGIiEiIgyPABoblCIDjzQboKAZcDQ0AKUamamIWjMzpTQzFakaFx5prrkzELUaFRRpMMLDBBfGDgdpLzExMMwDFxUVDg4dWi8sLC8vNS8CDdIODQhaKior2doADA7TDwa3Ty0uLi3mK0ILDw7vBhCsS1xYMGEiRQoX+IQk6GfAwIFOS1BIkGDBAgoULogIKNAPwoEDBEggsUAiA4kFEwVYaKHmQEOPHz8wGJBhwQISHQYM4KAgQ4dYkxIyGungEuaBDwgwECDAIEEEEDp5ZjBpIokEBB8LaEWQlCmFCE897FTQoaoSASC0bu3KNIFbEFAXmGUiIcEHpFyXNnUbIYMFLRMygGDAAAEBpxwW/E0SBAAh+QQABwAWACwAAAAAIAAgAAAG/0CAcEgsGo9I4iLJZAowuKa0uHicTqXpNLPBnnATLXOxKZnNUfFx8jCPzgb1kfAOhcwJuZE8GtlDA3pGGCF+hXmCRBIbIiEiIgeJRR4iGo8iGZJECBudGnGaQwYangyhQw4aqheBpwAXsBcVma6yFQ4VCq4AD7cODq2nBxXEDYh6NEQ0BL8NDx+JNNIA0gMODQbZHXoz3dI0MwIGD9kGGHowMN3dQhTk2QfBUzEx6ekyQgvZEAf9tFIsWNR4Qa/ekAgG+vUroKuJihYqVgisEYOIgA8KDxRAkGDJERcmTLhwoSIiiz0FNGpEgIFAggwkBEyQIGHBAgEWQo5UcdIIiVcPBQp8QICAAAMKCUB4GKAgQ4cFEiygMJFCRRIJBDayJGA0QQQQA5jChDrBhFUmE0AQLdo16dKmThegcKFFAggMLRkk2AtWrIQUeix0GPB1b9gOAkwwCQIAIfkEAAcAFwAsAAAAACAAIAAABv9AgHBInAw8xKRymVx8Sqcbc8oUEErYU4nKHS4e2LCN0KVmLthR+HQoMxeX0SgUCjcQbuXEEJr3SwYZeUsMIiIhhyIJg0sLGhuGIhsDjEsEjxuQEZVKEhcajxptnEkDn6AagqREGBeuFxCrSQcVFQ4Oi7JDD7a3lLpCDbYNDarADQ4NDw8KwEIGy9C/wAUG1gabzgzXBnjOAwYQEAcHHc4C4+QHDJU0SwnqBQXNeTM07kkSBQfyHwjmZWTMsOfu3hAQ/AogQECAHpUYMAQSxCdkAoEC/hgSACGBCQsWNSDCGDhDyYKFCwkwoJCAwwIBJkykcJGihQoWL0SOXEKCAAZVDCoZRADhgUOGDhIsoHBhE2ROGFMEUABKgCWIAQMUdFiQ1IQLFTdDcrEwQGWCBEOzHn2JwquLFTXcCBhwNsFVox1ILJiwdEUlCwsUDOCQdasFE1yCAAA7AAAAAAAAAAAA\u0027) no-repeat center center;\n}\n.h5p-video-loading.h5p-show {\n display: block;\n}\n.h5p-video-error {\n position: absolute;\n text-align: center;\n top: 50%;\n left: 50%;\n color: #fff;\n padding: 1em;\n background: rgba(0,0,0,0.9);\n -webkit-transform: translate(-50%, -50%);\n -ms-transform: translate(-50%, -50%);\n transform: translate(-50%, -50%);\n}\n","dist/h5p-interactive-video.css":"@font-face{font-family:H5PInteractiveVideo;src:url(fonts/H5PInteractiveVideo.eot);src:url(fonts/H5PInteractiveVideo.eot?#iefix) format(\"embedded-opentype\"),url(fonts/H5PInteractiveVideo.woff) format(\"woff\"),url(fonts/H5PInteractiveVideo.ttf) format(\"truetype\"),url(fonts/H5PInteractiveVideo.svg#H5PInteractiveVideo) format(\"svg\");font-weight:400;font-style:normal}@font-face{font-family:H5Picons;src:url(fonts/h5p.eot);src:url(fonts/h5p.eot?#iefixv34b5s) format(\"embedded-opentype\"),url(fonts/h5p.ttf) format(\"truetype\"),url(fonts/h5p.woff) format(\"woff\"),url(fonts/h5p.svg#h5p) format(\"svg\");font-weight:400;font-style:normal}.h5p-interactive-video{position:relative;background:#000!important;overflow:hidden;line-height:1.25em;font-size:16px}.h5p-interactive-video\u003ediv{z-index:1}.h5p-interactive-video .h5p-video-wrapper.h5p-disable-opt-out{z-index:auto}.h5p-interactive-video .h5p-video-wrapper.h5p-disable-opt-out .h5p-interaction{z-index:1}.h5p-interactive-video .h5p-question{color:#000}.h5p-interactive-video .h5p-content-controls{visibility:hidden;position:absolute;top:0}.h5p-interactive-video .h5p-video-wrapper{position:relative;overflow:hidden}.h5p-interactive-video .h5p-video{display:block;width:100%;height:auto;color:#fff;clear:both}.h5p-interactive-video object{display:block}.h5p-interactive-video .h5p-overlay{color:#2c2c2c}.h5p-interactive-video .h5p-overlay.h5p-visible{position:absolute;top:0;left:0;width:100%;height:100%;overflow:hidden}.h5p-interactive-video .h5p-ie-transparent-background{background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAABmJLR0QA/wD/AP+gvaeTAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH3QUODw0yPG414gAAAA1JREFUCNdj+P//PwMACPwC/lyfz9oAAAAASUVORK5CYII=);filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(src=\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAABmJLR0QA/wD/AP+gvaeTAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH3QUODw0yPG414gAAAA1JREFUCNdj+P//PwMACPwC/lyfz9oAAAAASUVORK5CYII=\",sizingMethod=\"scale\")}.h5p-interactive-video .h5p-interaction{position:absolute;width:1.75em;height:1.75em;z-index:2;outline:none}.h5p-interactive-video .h5p-interaction .h5p-image:focus,.h5p-interactive-video .h5p-interaction.h5p-link-interaction a:focus{outline:2px solid #179fff}.h5p-interactive-video .h5p-interaction .h5p-image:focus{outline-offset:8px}.h5p-interactive-video .h5p-interaction .h5p-touch-area{width:2.5em;height:2.5em;position:absolute;top:50%;left:50%;transform:translate3d(-50%,-50%,0);cursor:pointer}.h5p-interactive-video .h5p-interaction-label{-webkit-transition:-webkit-transform .2s;-moz-transition:-moz-transform .2s;transition:transform .2s;position:absolute;top:0;left:.875em;height:100%;line-height:1.75em;padding:0 .875em 0 1.375em;background:rgba(0,0,0,.8);border-top-right-radius:1em;border-bottom-right-radius:1em;color:#fff;z-index:1;width:auto;white-space:nowrap;cursor:pointer;vertical-align:text-bottom;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr=#cc000000,endColorstr=#cc000000)}.h5p-interactive-video .h5p-interaction-label .h5p-interaction-label-text{display:block;color:#fff;font-size:.7em;margin:0}.h5p-interactive-video .h5p-interaction-label .h5p-interaction-label-text\u003ep{font-size:1em;margin:0;line-height:inherit}.h5p-interactive-video .h5p-interaction-label.h5p-left-label{left:auto;right:.875em;padding:0 1.375em 0 .875em;border-top-left-radius:1em;border-bottom-left-radius:1em;border-top-right-radius:0;border-bottom-right-radius:0}.h5p-interactive-video .h5p-interaction-label.h5p-interaction-label-standalone{left:0;padding:.2em .5em;line-height:1.5;height:auto;min-width:1.5em;border-radius:0;cursor:auto}.h5p-interactive-video .h5p-interaction-label.h5p-interaction-label-standalone:focus{outline:1px solid #09f;outline-offset:0}.h5p-interactive-video .h5p-interaction-button{cursor:pointer;position:relative;z-index:2;display:block;width:1.75em;height:1.75em;-moz-background-clip:padding-box;-webkit-background-clip:padding-box;background-clip:padding-box;border-radius:50%;line-height:1.75em;color:#fff;-webkit-box-shadow:0 .15em .25em 0 rgba(0,0,0,.5);-moz-box-shadow:0 .15em .25em 0 rgba(0,0,0,.5);box-shadow:0 .15em .25em 0 rgba(0,0,0,.5);text-align:center;border-color:transparent;-webkit-transition:-webkit-transform .2s,background .3s,box-shadow .3s,border-color .3s;-moz-transition:-moz-transform .2s,background .3s,box-shadow .3s,border-color .3s;-ms-transition:background .3s,box-shadow .3s,border-color .3s;-o-transition:background .3s,box-shadow .3s,border-color .3s;transition:transform .2s,background .3s,box-shadow .3s,border-color .3s}.h5p-interactive-video .h5p-interaction:hover .h5p-interaction-button{-webkit-box-shadow:0 .3em .25em 0 rgba(0,0,0,.5);-moz-box-shadow:0 .3em .25em 0 rgba(0,0,0,.5);box-shadow:0 .3em .25em 0 rgba(0,0,0,.5)}.h5p-interactive-video .h5p-hidden\u003e.h5p-interaction-button{-webkit-transform:rotate(90deg) scale(0);-moz-transform:rotate(90deg) scale(0);-ms-transform:rotate(90deg) scale(0);-o-transform:rotate(90deg) scale(0);transform:rotate(90deg) scale(0)}.h5p-interactive-video .h5p-hidden\u003e.h5p-interaction-label{-webkit-transform:scale(0) translateX(-100%);-moz-transform:scale(0) translateX(-100%);-ms-transform:scale(0) translateX(-100%);transform:scale(0) translateX(-100%)}.h5p-interactive-video div\u003e.h5p-interaction-button{background-color:#981d99}.h5p-interactive-video div:hover\u003e.h5p-interaction-button{background-color:#661366}.h5p-interactive-video div:focus\u003e.h5p-interaction-button{top:-.167em;left:-.167em;border:.167em solid #e489f3}.h5p-interactive-video div:active\u003e.h5p-interaction-button{background-color:#4c0e4c;box-shadow:0 .15em .25em 0 rgba(0,0,0,.5)}.h5p-interactive-video div\u003e.h5p-interaction-button:before{font-family:H5Picons;content:\"\\E609\"}.h5p-interactive-video .h5p-image-interaction\u003e.h5p-interaction-button,.h5p-interactive-video .h5p-link-interaction\u003e.h5p-interaction-button,.h5p-interactive-video .h5p-table-interaction\u003e.h5p-interaction-button,.h5p-interactive-video .h5p-text-interaction\u003e.h5p-interaction-button{background-color:#1d5cff}.h5p-interactive-video .h5p-image-interaction:hover\u003e.h5p-interaction-button,.h5p-interactive-video .h5p-link-interaction:hover\u003e.h5p-interaction-button,.h5p-interactive-video .h5p-table-interaction:hover\u003e.h5p-interaction-button,.h5p-interactive-video .h5p-text-interaction:hover\u003e.h5p-interaction-button{background-color:#003fdf}.h5p-interactive-video .h5p-image-interaction:focus\u003e.h5p-interaction-button,.h5p-interactive-video .h5p-link-interaction:focus\u003e.h5p-interaction-button,.h5p-interactive-video .h5p-table-interaction:focus\u003e.h5p-interaction-button,.h5p-interactive-video .h5p-text-interaction:focus\u003e.h5p-interaction-button{border-color:#70b0ff}.h5p-interactive-video .h5p-image-interaction:active\u003e.h5p-interaction-button,.h5p-interactive-video .h5p-link-interaction:active\u003e.h5p-interaction-button,.h5p-interactive-video .h5p-table-interaction:active\u003e.h5p-interaction-button,.h5p-interactive-video .h5p-text-interaction:active\u003e.h5p-interaction-button{background-color:#163c9b;box-shadow:0 .15em .25em 0 rgba(0,0,0,.5)}.h5p-interactive-video .h5p-image-interaction\u003e.h5p-interaction-button:before,.h5p-interactive-video .h5p-link-interaction\u003e.h5p-interaction-button:before,.h5p-interactive-video .h5p-table-interaction\u003e.h5p-interaction-button:before,.h5p-interactive-video .h5p-text-interaction\u003e.h5p-interaction-button:before{font-family:H5PFontAwesome4;content:\"\\F055\"}.h5p-interactive-video .h5p-goto-timecode\u003e.h5p-interaction-button{background-color:#018d82}.h5p-interactive-video .h5p-goto-timecode:hover\u003e.h5p-interaction-button{background-color:#007b71}.h5p-interactive-video .h5p-goto-timecode:focus\u003e.h5p-interaction-button{border-color:#53d5c9}.h5p-interactive-video .h5p-goto-timecode:active\u003e.h5p-interaction-button{background-color:#055e57}.h5p-interactive-video .h5p-dialog-interaction{font-size:.875em}.h5p-interactive-video .h5p-dialog-interaction.h5p-blanks .h5p-blanks-footer{min-height:5em}.h5p-interactive-video .h5p-link-interaction .h5p-link a{color:#fff;text-decoration:none}.h5p-interactive-video .h5p-interaction.h5p-poster.h5p-link-interaction{background-color:rgba(0,0,0,.5);box-shadow:0 0 10px 0 hsla(0,0%,100%,.2);border-radius:1em;height:auto;width:auto;cursor:pointer}.h5p-interactive-video .h5p-interaction.h5p-poster.h5p-link-interaction:focus,.h5p-interactive-video .h5p-interaction.h5p-poster.h5p-link-interaction:hover{background-color:rgba(0,0,0,.7);box-shadow:0 0 15px 0 hsla(0,0%,100%,.2)}.h5p-interactive-video .h5p-interaction.h5p-poster.h5p-link-interaction:active{background-color:rgba(0,0,0,.8);box-shadow:0 0 5px 0 hsla(0,0%,100%,.2)}.h5p-interactive-video .h5p-interaction .h5p-interaction-inner.h5p-link:after{font-family:H5PFontAwesome4;content:\"\\F08E\";color:#fff;margin-left:.7em;font-size:.75em}.h5p-interactive-video .h5p-interaction .h5p-interaction-inner.h5p-link.h5p-ivhotspot:after{content:none}.h5p-interactive-video .h5p-interaction.h5p-poster.h5p-link-interaction .h5p-interaction-inner.h5p-link{margin:0 .8em;width:auto;height:auto}.h5p-interactive-video .h5p-interaction.h5p-poster{z-index:1;background:#fff;box-shadow:0 0 .625em 0 rgba(0,0,0,.25);box-sizing:border-box}.h5p-interactive-video .h5p-interaction.h5p-poster.h5p-transparent-interaction.h5p-image-interaction:not(.goto-clickable-visualize):not(.h5p-box-shadow-disabled) .h5p-image img{filter:drop-shadow(0 0 .325em rgba(0,0,0,.25))}.h5p-interactive-video .h5p-interaction.h5p-poster.h5p-transparent-interaction.h5p-image-interaction:not(.goto-clickable-visualize){box-shadow:none;overflow:visible}.h5p-interactive-video .h5p-interaction.h5p-poster.h5p-box-shadow-disabled{box-shadow:none}.h5p-interactive-video .h5p-interaction.h5p-poster.h5p-transparent-interaction.h5p-box-shadow-disabled .h5p-image img{filter:none}.h5p-interactive-video .h5p-interaction.h5p-poster.h5p-ivhotspot-interaction{box-shadow:none;background:none;overflow:visible}.h5p-interactive-video .h5p-interaction.h5p-poster.h5p-ivhotspot-interaction .h5p-interaction-outer,.h5p-interactive-video .h5p-interaction.h5p-poster.h5p-transparent-interaction.h5p-image-interaction .h5p-interaction-outer{overflow:visible}.h5p-interactive-video .h5p-interaction.h5p-poster .h5p-interaction-outer{position:relative;top:0;left:0;height:100%;width:100%;overflow-y:auto}.h5p-interactive-video .h5p-interaction-inner,.h5p-interactive-video .h5p-interaction-inner.h5p-image{display:block;width:100%;height:auto;font-size:.875em;box-sizing:border-box;-moz-box-sizing:border-box}.h5p-interactive-video .h5p-interaction-inner.h5p-ivhotspot{height:100%}.h5p-interactive-video .h5p-interaction-inner.h5p-text{width:auto}.h5p-interactive-video .h5p-table:focus,.h5p-interactive-video .h5p-text:focus{outline:0}.h5p-interactive-video .h5p-interaction-inner.h5p-image,.h5p-interactive-video .h5p-interaction-inner.h5p-questionnaire-wrapper,.h5p-interactive-video .h5p-interaction-inner.h5p-single-choice-set{height:100%}.h5p-interactive-video .h5p-dialog .h5p-image img{margin:0 auto;position:relative;top:0}.h5p-interactive-video .h5p-interaction-overlay{position:absolute;left:0;top:0;width:100%;height:100%}.h5p-interactive-video .h5p-controls{font-size:16px;height:36px;background:#2c2c2c;display:flex;line-height:1.5em}.h5p-interactive-video .h5p-control{display:inline-block;height:36px;color:#fefefe;outline:0;width:36px;margin-right:6px;text-decoration:none;cursor:pointer;transition:box-shadow .1s ease-out .3s}.h5p-interactive-video .h5p-control:hover{text-decoration:none}.h5p-interactive-video .h5p-control:focus{outline:2px solid #179fff;outline-offset:-4px}.h5p-interactive-video .h5p-controls-left .h5p-control:first-child{margin:0 4px 0 8px}.h5p-interactive-video .h5p-controls-right .h5p-control:first-child{margin-right:6px}.h5p-interactive-video .h5p-control.h5p-time,.h5p-interactive-video [aria-disabled=true].h5p-control,.h5p-interactive-video [aria-disabled=true].h5p-control.h5p-slider,.h5p-interactive-video [aria-disabled=true].h5p-control.h5p-slider .ui-slider-handle{cursor:default}.h5p-interactive-video .h5p-control:before{position:absolute;font-family:H5PFontAwesome4;speak:none;font-style:normal;font-weight:400;font-variant:normal;font-size:22px;text-transform:none;line-height:37px;width:36px;color:#fbfbfb;text-align:center;-moz-box-sizing:border-box;box-sizing:border-box;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.h5p-interactive-video .h5p-minimal-overlay .h5p-minimal-button{display:inline-block;padding-top:4em;margin:0 1em;position:relative;vertical-align:bottom;outline:none;cursor:pointer;-webkit-transition:visibility 0s linear .1s}.h5p-interactive-video .h5p-minimal-overlay .h5p-minimal-button.h5p-hide{visibility:hidden;-webkit-transition-delay:0s}.h5p-interactive-video .h5p-minimal-overlay .h5p-minimal-button:before{font-size:4em;line-height:1em;position:absolute;font-family:H5PFontAwesome4;top:0;left:50%;transform:translateX(-50%)}.h5p-interactive-video .h5p-control:active:before,.h5p-interactive-video .h5p-control[aria-expanded=true]:before,.h5p-interactive-video .h5p-minimal-overlay .h5p-minimal-button:active{color:#bababa}.h5p-interactive-video .h5p-control:hover:before,.h5p-interactive-video .h5p-minimal-overlay .h5p-minimal-button:hover{color:#dbd7d1}.h5p-interactive-video .h5p-minimal-overlay .h5p-minimal-button:focus{outline:2px solid #179fff;outline-offset:5px}.h5p-interactive-video .h5p-minimal-overlay [aria-disabled=true].h5p-minimal-button,.h5p-interactive-video [aria-disabled=true].h5p-control:before{color:#606060}.h5p-interactive-video .h5p-minimal-overlay [aria-disabled=true].h5p-minimal-button{color:#747474}.h5p-interactive-video .h5p-play:before{content:\"\\F04C\"}.h5p-interactive-video .h5p-pause:before{content:\"\\F04B\"}.h5p-interactive-video .h5p-rewind10:before{content:\"\\F1DA\"}.h5p-interactive-video .h5p-control.h5p-bookmarks:before,.h5p-interactive-video .h5p-minimal-overlay .h5p-bookmarks:before{content:\"\\F02E\"}.h5p-interactive-video .h5p-control.h5p-quality:before,.h5p-interactive-video .h5p-minimal-overlay .h5p-quality:before{content:\"\\F013\"}.h5p-interactive-video .h5p-control.h5p-captions:before,.h5p-interactive-video .h5p-minimal-overlay .h5p-captions:before{content:\"\\F20A\"}.h5p-interactive-video .h5p-control.h5p-playbackRate:before,.h5p-interactive-video .h5p-minimal-overlay .h5p-playbackRate:before{content:\"\\F0E4\"}.h5p-interactive-video .h5p-fullscreen:before{content:\"\\F065\"}.h5p-interactive-video .h5p-exit:before{content:\"\\F066\"}.h5p-interactive-video .h5p-mute:before{content:\"\\F028\"}.h5p-interactive-video .h5p-muted:before{content:\"\\F026\"}.h5p-interactive-video .h5p-more:before{content:\"\\F142\"}.h5p-interactive-video.h5p-minimal .h5p-control.h5p-bookmarks,.h5p-interactive-video.h5p-minimal .h5p-control.h5p-captions,.h5p-interactive-video.h5p-minimal .h5p-control.h5p-playbackRate,.h5p-interactive-video.h5p-minimal .h5p-control.h5p-quality,.h5p-interactive-video.h5p-minimal .h5p-time,.h5p-interactive-video .h5p-more,.h5p-interactive-video .h5p-simple-time{display:none}.h5p-interactive-video.h5p-minimal .h5p-more,.h5p-interactive-video.h5p-minimal .h5p-simple-time{display:inline-block}.h5p-interactive-video .h5p-minimal-overlay{position:absolute;z-index:10;width:100%;height:100%;left:0;bottom:36px;border-bottom:1px solid #8e8e8e;text-align:center;color:#fefefe;background:rgba(0,0,0,.6);opacity:0;visibility:hidden;transition:visibility 0s linear .1s,opacity .1s linear}.h5p-interactive-video.h5p-minimal .h5p-minimal-overlay.h5p-show{opacity:1;visibility:visible;transition-delay:0s}.h5p-interactive-video .h5p-minimal-wrap{top:50%;position:absolute;width:100%;transform:translateY(-50%)}.h5p-interactive-video .h5p-chooser{font-size:17px;position:absolute;z-index:10;max-width:300px;line-height:21px;background:#2c2c2c;background:rgba(44,44,44,.8);color:#fbfbfb;opacity:0;visibility:hidden;bottom:72px;-webkit-transition:visibility 0s linear .1s,opacity .1s linear,bottom .1s linear;-moz-transition:visibility 0s linear .1s,opacity .1s linear,bottom .1s linear;transition:visibility 0s linear .1s,opacity .1s linear,bottom .1s linear;overflow-x:hidden;overflow-y:auto}.h5p-interactive-video.h5p-fullscreen .h5p-chooser,.h5p-interactive-video.h5p-semi-fullscreen .h5p-chooser{background:rgba(0,0,0,.6)}.h5p-interactive-video:not(.h5p-minimal) .h5p-chooser.h5p-bookmarks{z-index:1;width:200px;left:-34px;bottom:36px;overflow-y:hidden;opacity:0;transform:scaleX(.2) translateY(36px);-webkit-transition:transform .3s,opacity .3s,max-height .3s,left .3s;-moz-transition:transform .3s,opacity .3s,max-height .3s,left .3s;transition:transform .3s,opacity .3s,max-height .3s,left .3s}.h5p-interactive-video:not(.h5p-minimal) .h5p-chooser.h5p-bookmarks.h5p-rewind-displacement{left:8px}.h5p-interactive-video:not(.h5p-minimal) .h5p-chooser.h5p-bookmarks:not(.h5p-show){pointer-events:none}.h5p-interactive-video:not(.h5p-minimal) .h5p-chooser.h5p-bookmarks.h5p-show.h5p-transitioning{overflow:hidden}.h5p-interactive-video .h5p-chooser.h5p-bookmarks.h5p-transitioning{visibility:visible}.h5p-interactive-video .h5p-chooser.h5p-captions,.h5p-interactive-video .h5p-chooser.h5p-playbackRate,.h5p-interactive-video .h5p-chooser.h5p-quality{right:12px}.h5p-interactive-video .h5p-chooser.h5p-show{bottom:36px;opacity:1;visibility:visible;-webkit-transition-delay:0s;-moz-transition-delay:0s;transition-delay:0s}.h5p-interactive-video:not(.h5p-minimal) .h5p-chooser.h5p-bookmarks.h5p-show{width:200px;left:-10px;overflow-y:auto;opacity:1;transform:scaleX(1) translate(10px)}.h5p-interactive-video .h5p-chooser.h5p-bookmarks.h5p-show *{visibility:visible}.h5p-interactive-video .h5p-chooser\u003eh3{margin:0 0 8px;padding:8px 24px 8px 12px;font-size:19px;font-weight:400;border-bottom:1px solid #fbfbfb;color:#fbfbfb}.h5p-interactive-video .h5p-chooser\u003e[role=menu]{list-style:none;padding:0 2px 8px;margin:0}.h5p-interactive-video .h5p-chooser\u003e[role=menu]\u003e[role^=menuitem]{padding-left:32px;margin:2px 0;color:#fbfbfb}.h5p-interactive-video .h5p-chooser\u003e[role=menu]\u003e[role^=menuitem]:hover{cursor:pointer;color:#dbd7d1}.h5p-interactive-video .h5p-chooser\u003e[role=menu]\u003e[role^=menuitem]:focus{outline:2px solid #179fff}.h5p-interactive-video .h5p-chooser\u003e[role=menu]\u003e[role^=menuitem]:before{left:12px;position:absolute;font-family:H5PFontAwesome4;content:\"\\F10C\";-moz-box-sizing:border-box;box-sizing:border-box;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.h5p-interactive-video .h5p-chooser\u003e[role=menu]\u003eli[aria-checked=true]:before{content:\"\\F058\"}.h5p-interactive-video .h5p-chooser.h5p-bookmarks\u003e[role=menu]\u003eli:before{content:\"\\F02E\"}.h5p-interactive-video .h5p-chooser-close-button{cursor:pointer;position:absolute;top:.1em;right:.1em;width:1em;height:1em;text-align:center;line-height:1}.h5p-interactive-video.h5p-minimal .h5p-chooser-close-button{top:.3em;right:.3em;font-size:130%}.h5p-interactive-video .h5p-chooser-close-button:after{font-family:H5PFontAwesome4;content:\"\\F00D\"}.h5p-interactive-video .h5p-chooser-close-button:hover{color:#dbd7d1}.h5p-interactive-video .h5p-chooser-close-button:focus{outline:2px solid #179fff}.h5p-interactive-video.h5p-minimal .h5p-chooser{z-index:11;background-color:transparent;width:100%;height:100%;left:0;max-width:none}.h5p-interactive-video.h5p-minimal .h5p-chooser\u003eh3{border-bottom-color:#8e8e8e}.h5p-interactive-video .h5p-simple-time,.h5p-interactive-video .h5p-time{width:auto;height:auto;font-size:.875em;color:gray;padding:0 8px;line-height:36px}.h5p-interactive-video .h5p-time{float:left}.h5p-interactive-video .h5p-simple-time{float:right}.h5p-interactive-video .h5p-simple-time .h5p-current,.h5p-interactive-video .h5p-time .h5p-current{color:#fff;display:inline}.h5p-interactive-video .h5p-slider{width:auto;padding:14px 8px 12px;margin:0;height:10px;cursor:default;flex:1}.h5p-interactive-video .h5p-slider .ui-slider{background:#0b0d0c;border:0;height:8px;cursor:pointer;border-radius:0;-ms-touch-action:manipulation;touch-action:manipulation}.h5p-interactive-video [aria-disabled=true].h5p-slider .ui-slider{background:#000}.h5p-interactive-video .h5p-slider .ui-slider-range{color:#e2e2e2;height:9px;border-radius:0}.h5p-interactive-video [aria-disabled=true].h5p-slider .ui-slider-range{background:#7a7a7a}.h5p-interactive-video [aria-disabled=true].h5p-slider .ui-slider.ui-state-disabled{opacity:1;filter:none}.h5p-interactive-video .h5p-slider .ui-slider-handle{cursor:pointer;top:-4px;width:16px;height:16px;margin-left:-8px;text-shadow:0 0 2px #666;outline:none;text-decoration:none;border:0;background:#fbfbfb}.h5p-interactive-video .h5p-slider .ui-slider-handle:focus{outline:2px solid #179fff;outline-offset:4px}.h5p-interactive-video [aria-disabled=true].h5p-slider .ui-slider-handle{background:none}.h5p-interactive-video :not([aria-disabled=true]).h5p-slider .ui-slider-handle:before{font-family:H5PInteractiveVideo;content:\"\\E001\";font-size:26px;line-height:1;position:absolute;margin:-5px 0 0 -5px;speak:none;font-style:normal;font-weight:400;font-variant:normal;text-transform:none;color:#fbfbfb;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.h5p-interactive-video :not([aria-disabled=true]).h5p-slider .ui-slider-handle:hover:before{color:#dbd7d1}.h5p-interactive-video .h5p-buffered{position:absolute;top:0;left:0;height:8px;width:0;background:#4d4d4d}.h5p-interactive-video .h5p-bookmarks-container,.h5p-interactive-video .h5p-interactions-container{position:relative}.h5p-interactive-video .h5p-seekbar-interaction{position:absolute;top:-10px;width:7px;height:7px;border-radius:50%;transform:translateX(-50%);cursor:pointer;border:.083em solid #e36ee3;box-sizing:border-box}.h5p-interactive-video [aria-disabled=true].h5p-seekbar-interaction{border-color:#9e4d9e;cursor:default}.h5p-interactive-video :not([aria-disabled=true]).h5p-seekbar-interaction:hover{border-color:#e98be9}.h5p-interactive-video .h5p-seekbar-interaction.h5p-goto-timecode,.h5p-interactive-video .h5p-seekbar-interaction.h5p-gotoquestion-interaction,.h5p-interactive-video .h5p-seekbar-interaction.h5p-image-interaction,.h5p-interactive-video .h5p-seekbar-interaction.h5p-ivhotspot-interaction,.h5p-interactive-video .h5p-seekbar-interaction.h5p-link-interaction,.h5p-interactive-video .h5p-seekbar-interaction.h5p-table-interaction,.h5p-interactive-video .h5p-seekbar-interaction.h5p-text-interaction{border:none;background-color:#7ca1ff}.h5p-interactive-video [aria-disabled=true].h5p-seekbar-interaction.h5p-goto-timecode,.h5p-interactive-video [aria-disabled=true].h5p-seekbar-interaction.h5p-gotoquestion-interaction,.h5p-interactive-video [aria-disabled=true].h5p-seekbar-interaction.h5p-image-interaction,.h5p-interactive-video [aria-disabled=true].h5p-seekbar-interaction.h5p-ivhotspot-interaction,.h5p-interactive-video [aria-disabled=true].h5p-seekbar-interaction.h5p-link-interaction,.h5p-interactive-video [aria-disabled=true].h5p-seekbar-interaction.h5p-table-interaction,.h5p-interactive-video [aria-disabled=true].h5p-seekbar-interaction.h5p-text-interaction{background-color:#5770b2}.h5p-interactive-video :not([aria-disabled=true]).h5p-seekbar-interaction.h5p-goto-timecode:hover,.h5p-interactive-video :not([aria-disabled=true]).h5p-seekbar-interaction.h5p-gotoquestion-interaction:hover,.h5p-interactive-video :not([aria-disabled=true]).h5p-seekbar-interaction.h5p-image-interaction:hover,.h5p-interactive-video :not([aria-disabled=true]).h5p-seekbar-interaction.h5p-ivhotspot-interaction:hover,.h5p-interactive-video :not([aria-disabled=true]).h5p-seekbar-interaction.h5p-link-interaction:hover,.h5p-interactive-video :not([aria-disabled=true]).h5p-seekbar-interaction.h5p-table-interaction:hover,.h5p-interactive-video :not([aria-disabled=true]).h5p-seekbar-interaction.h5p-text-interaction:hover{background-color:#96b4ff}.h5p-interactive-video .h5p-seekbar-interaction:focus{outline:2px solid #179fff;outline-offset:2px}.h5p-interactive-video .h5p-bookmark{position:absolute;top:-13px;width:1px;height:36px;background:#a2a2a2;color:#fefefe;-webkit-transition:background-color .2s;-moz-transition:background-color .2s;transition:background-color .2s}.h5p-interactive-video .h5p-bookmark.h5p-show{background:#aeaeae}.h5p-interactive-video .h5p-bookmark-label,.h5p-interactive-video .h5p-prevent-skipping-message{position:absolute;bottom:46px;left:-16px;padding:0 10px;background:#2c2c2c;background:rgba(44,44,44,.8);opacity:0;visibility:hidden;max-width:300px;-webkit-transition:visibility 0s .2s,opacity .2s;-moz-transition:visibility 0s .2s,opacity .2s;transition:visibility 0s .2s,opacity .2s;z-index:1}.h5p-interactive-video .h5p-prevent-skipping-message{bottom:25px;transform:translateX(-1.1em)}.h5p-interactive-video .h5p-prevent-skipping-message-text{max-width:17.5em;line-height:30px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.h5p-interactive-video.h5p-minimal .h5p-prevent-skipping-message-text{max-width:9.5em}.h5p-interactive-video.h5p-fullscreen .h5p-bookmark-label,.h5p-interactive-video.h5p-fullscreen .h5p-prevent-skipping-message,.h5p-interactive-video.h5p-semi-fullscreen .h5p-bookmark-label,.h5p-interactive-video.h5p-semi-fullscreen .h5p-prevent-skipping-message{background:rgba(0,0,0,.6)}.h5p-interactive-video .h5p-prevent-skipping-message.h5p-show,.h5p-interactive-video .h5p-show .h5p-bookmark-label{opacity:1;visibility:visible;-webkit-transition:opacity .2s;-moz-transition:opacity .2s;transition:opacity .2s}.h5p-interactive-video .h5p-bookmark-label:after,.h5p-interactive-video .h5p-prevent-skipping-message:after{content:\"\";position:absolute;left:8px;border:9px solid transparent;border-top-width:10px;border-top-color:#2c2c2c;border-top-color:rgba(44,44,44,.8);border-bottom:0;top:100%}.h5p-interactive-video.h5p-fullscreen .h5p-bookmark-label:after,.h5p-interactive-video.h5p-fullscreen .h5p-prevent-skipping-message:after,.h5p-interactive-video.h5p-semi-fullscreen .h5p-bookmark-label:after,.h5p-interactive-video.h5p-semi-fullscreen .h5p-prevent-skipping-message:after{border-top-color:rgba(0,0,0,.6)}.h5p-interactive-video .h5p-bookmark-text{white-space:nowrap;text-overflow:ellipsis;overflow:hidden;line-height:30px}.h5p-interactive-video .h5p-bookmark-text:before{font-family:H5PFontAwesome4;content:\"\\F02E\";margin-right:8px}.h5p-interactive-video .h5p-dialog-wrapper,.h5p-interactive-video .h5p-warning-mask{display:none;position:absolute;top:0;left:0;width:100%;height:100%;z-index:51;background:rgba(44,44,44,.5);-webkit-transition:background-color .2s;-moz-transition:background-color .2s;transition:background-color .2s;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr=#66000000,endColorstr=#66000000)}.h5p-interactive-video .h5p-warning-mask{background:rgba(4,4,4,.77);z-index:53;-webkit-transform-style:preserve-3d;-moz-transform-style:preserve-3d;transform-style:preserve-3d}.h5p-interactive-video .h5p-warning-mask .h5p-warning-mask-wrapper{position:relative;top:50%;transform:perspective(1px) translateY(-50%)}.h5p-interactive-video .h5p-warning-mask-wrapper .h5p-warning-mask-content{max-width:17em;margin-left:auto;margin-right:auto;text-align:center;color:#fff;font-size:1.6em;line-height:1.2em}.h5p-interactive-video .h5p-warning-mask-wrapper .h5p-joubelui-button{margin-top:1.3em;display:block;margin-left:auto;margin-right:auto}.h5p-button-back:before{content:\"\\F060\"}.h5p-interactive-video .h5p-dialog-wrapper.h5p-hidden{background:transparent}.h5p-interactive-video .h5p-dialog-wrapper.h5p-hidden .h5p-dialog{-webkit-transform:translateY(100%);-moz-transform:translateY(100%);-ms-transform:translateY(100%);-o-transform:translateY(100%);transform:translateY(100%)}.h5p-interactive-video .h5p-dialog{position:absolute;width:auto;min-width:6.25em;min-height:4.6875em;margin:1.25em;background:#fff;overflow:hidden;box-shadow:0 0 .625em 0 rgba(0,0,0,.25);-webkit-transition:-webkit-transform .2s;-moz-transition:-moz-transform .2s;transition:transform .2s}.h5p-interactive-video .h5p-dialog:not(.h5p-big){max-width:calc(100% - 2.5em)}.h5p-interactive-video .h5p-dialog.h5p-medium{min-width:20em;top:0}.h5p-interactive-video .h5p-dialog-title{text-overflow:ellipsis;white-space:nowrap;overflow:hidden;width:calc(100% - 1em)}.h5p-interactive-video .h5p-dialog-titlebar{overflow:hidden;position:absolute;width:100%;top:0;padding:.5em 1em .5em .5em;box-sizing:border-box;border-bottom:1px solid #eee;font-size:.875em;color:#757575}.h5p-interactive-video .h5p-dialog.h5p-big{width:auto;height:auto;max-height:none;left:1.25em;right:1.25em;top:1.25em;bottom:1.25em;margin:0;box-sizing:border-box;-moz-box-sizing:border-box}.h5p-interactive-video .h5p-dialog-close{position:absolute;top:.25em;right:.5em;cursor:pointer;padding:.25em .5em}.h5p-interactive-video .h5p-dialog-close:focus{outline:2px solid #179fff}.h5p-interactive-video .h5p-dialog-close:before{font-family:H5PFontAwesome4;content:\"\\F057\";color:#757575}.h5p-interactive-video .h5p-dialog-close:focus:before,.h5p-interactive-video .h5p-dialog-close:hover:before{color:#555}.h5p-interactive-video .h5p-dialog-close:active:before{color:#454545}.h5p-interactive-video .h5p-dialog-inner{height:100%;overflow:hidden;overflow-y:auto}.h5p-interactive-video .h5p-big\u003e.h5p-dialog-inner{width:100%;height:auto}.h5p-interactive-video .h5p-dialog-inner::-webkit-scrollbar,.h5p-interactive-video .h5p-poster.h5p-interaction .h5p-interaction-outer::-webkit-scrollbar{width:.5em;background:#fff}.h5p-interactive-video .h5p-dialog-inner::-webkit-scrollbar-thumb,.h5p-interactive-video .h5p-poster.h5p-interaction .h5p-interaction-outer::-webkit-scrollbar-thumb{background:#ddd}.h5p-interactive-video .h5p-dialog-inner::-webkit-scrollbar-thumb:hover,.h5p-interactive-video .h5p-poster.h5p-interaction .h5p-interaction-outer::-webkit-scrollbar-thumb:hover{background:#aaa}.h5p-interactive-video .h5p-dialog-inner::-webkit-scrollbar-thumb:active,.h5p-interactive-video .h5p-dialog-inner::-webkit-scrollbar-thumb:focus,.h5p-interactive-video .h5p-poster.h5p-interaction .h5p-interaction-outer::-webkit-scrollbar-thumb:active,.h5p-interactive-video .h5p-poster.h5p-interaction .h5p-interaction-outer::-webkit-scrollbar-thumb:focus{background:#888}.h5p-interactive-video .h5p-dialog-hide{color:#191919;font-size:1.3em;padding:.3em;line-height:.75em;position:absolute;right:.1em;top:.1em;height:1em;z-index:52;text-shadow:0 0 .5em #fff;font-family:H5PFontAwesome4;text-decoration:none;-webkit-transition:-webkit-transform .2s;-moz-transition:-moz-transform .2s;transition:transform .2s}.h5p-interactive-video .h5p-dialog-hide:hover{text-decoration:none;-webkit-transform:scale(1.1);-moz-transform:scale(1.1);-ms-transform:scale(1.1);-o-transform:scale(1.1);transform:scale(1.1)}.h5p-interactive-video .h5p-question .h5p-joubelui-button{float:left}.h5p-interactive-video .h5p-question .h5p-joubelui-button:first-child{margin:0 .5em 1em 0}.h5p-interactive-video .h5p-question .h5p-joubelui-button:last-child{margin:0 0 1em .5em}.h5p-interactive-video .h5p-question .h5p-joubelui-button:first-child:last-child{margin:0 0 1em}.h5p-interactive-video .h5p-dialog-interaction.h5p-image{display:block;height:auto}.h5p-interactive-video .h5p-text p:first-child{margin-top:0}.h5p-interactive-video .h5p-text p:last-child{margin-bottom:0}.h5p-interactive-video .h5p-table{font-size:.875em;border-collapse:collapse}.h5p-interactive-video .h5p-table th{border-bottom:2px solid #191919}.h5p-interactive-video .h5p-table td{border-bottom:1px solid #595959}.h5p-interactive-video .h5p-table tr:last-child td{border-bottom:0}.h5p-interactive-video .h5p-nil-interaction\u003e.h5p-interaction-button{display:none}.h5p-interactive-video .h5p-nil-interaction\u003e.h5p-interaction-label{top:0;left:0;padding:.2em .5em;line-height:1.5;height:auto;min-width:1.5em;cursor:default;border-radius:0}.h5p-interactive-video .h5p-dragquestion .h5p-button{right:auto;left:1.225em}.h5p-interactive-video .h5p-splash{width:40%;margin:auto;text-align:center;background:#000;background:rgba(0,0,0,.75);color:#fff;cursor:pointer;-webkit-transition:background .2s ease-in;transition:background .2s ease-in}.h5p-interactive-video .h5p-splash-wrapper .h5p-splash-outer{display:table-cell;vertical-align:middle}.h5p-interactive-video .h5p-splash-wrapper .h5p-splash-play-icon{font-size:5em;padding:.5em 0;line-height:1em}.h5p-interactive-video .h5p-splash-wrapper.no-description .h5p-splash-play-icon,.h5p-interactive-video .h5p-splash-wrapper.no-description.no-title .h5p-splash-play-icon{padding:.5em 0;font-size:4em}.h5p-interactive-video .h5p-splash-wrapper.no-title .h5p-splash-play-icon{padding:.75em 0}.h5p-interactive-video .h5p-splash-wrapper .h5p-splash-play-icon:before{font-family:H5PFontAwesome4;content:\"\\F04B\";display:block}.h5p-interactive-video .h5p-splash-wrapper .h5p-splash .h5p-splash-title{font-family:Open Sans,sans-serif;font-size:1.5em;line-height:1.25em;padding:0 .5em 1.25em;margin-top:-1em}.h5p-interactive-video .h5p-splash-wrapper .h5p-splash .h5p-splash-description{font-family:Open Sans,sans-serif;border-top:1px solid hsla(0,0%,100%,.2);font-size:.75em;line-height:1.25;padding:1.25em}.h5p-interactive-video .h5p-splash\u003ep{margin:.5em 0 1em;color:#fff}.h5p-interactive-video .h5p-splash-wrapper{position:absolute;display:table;padding:1em 0;top:50%;width:100%;height:100%;-webkit-transform:translateY(-50%);-ms-transform:translateY(-50%);transform:translateY(-50%)}.h5p-interactive-video .h5p-splash:focus,.h5p-interactive-video .h5p-splash:hover{background:rgba(0,0,0,.85)}.h5p-interactive-video .h5p-splash:focus{outline:1px solid #87cefa}.h5p-interactive-video .h5p-splash-wrapper.no-description .h5p-splash .h5p-splash-description,.h5p-interactive-video .h5p-splash-wrapper.no-description.mobile .h5p-splash .h5p-splash-description{display:none}.h5p-interactive-video .h5p-splash-wrapper.no-description .h5p-splash{padding:1.5em 0}.h5p-interactive-video .h5p-splash-wrapper.no-description.no-title .h5p-splash{width:25%;padding:1em 0}.h5p-interactive-video .h5p-splash-wrapper.no-title .h5p-splash .h5p-splash-title,.h5p-interactive-video .h5p-splash-wrapper.no-title.mobile .h5p-splash .h5p-splash-title{display:none}.h5p-interactive-video .h5p-splash-wrapper .h5p-splash .h5p-splash-title.minimum-font-size{font-size:20px}.h5p-interactive-video .h5p-splash-wrapper .h5p-splash .h5p-splash-description.minimum-font-size{font-size:12px}.h5p-interactive-video .h5p-splash-wrapper.mobile .h5p-splash,.h5p-interactive-video .h5p-splash-wrapper.mobile.no-description .h5p-splash,.h5p-interactive-video .h5p-splash-wrapper.mobile.no-description.no-title .h5p-splash{width:100%;height:100%;margin:0;display:flex;top:0;left:0;position:absolute;flex-flow:column}.h5p-interactive-video .h5p-splash-wrapper.mobile{display:block;top:0;-webkit-transform:none;transform:none;width:100%;height:100%}.h5p-interactive-video .h5p-splash-wrapper.mobile .h5p-splash-outer{display:block;vertical-align:auto}.h5p-interactive-video .h5p-splash-wrapper.mobile .h5p-splash-main{flex:auto;position:relative}.h5p-interactive-video .h5p-splash-wrapper.mobile .h5p-splash-main-outer{position:absolute;height:100%;width:100%}.h5p-interactive-video .h5p-splash-wrapper.mobile .h5p-splash-main-inner{position:relative;top:50%;-webkit-transform:translateY(-50%);-ms-transform:translateY(-50%);transform:translateY(-50%)}.h5p-interactive-video .h5p-splash-wrapper.mobile .h5p-splash .h5p-splash-title{padding:.5em 2.5em}.h5p-interactive-video .h5p-splash-wrapper.mobile .h5p-splash .h5p-splash-description{padding:1em 1.5em}.h5p-interactive-video .h5p-splash-wrapper.mobile .h5p-splash-footer{flex:none}.h5p-interactive-video .h5p-video.h5p-youtube .h5p-splash-wrapper{display:none}.h5p-interactive-video .h5p-video.h5p-youtube .h5p-splash-wrapper .h5p-splash,.h5p-interactive-video .h5p-video.h5p-youtube .h5p-splash-wrapper:hover .h5p-splash{background:#000}.h5p-interactive-video .h5p-question .h5p-question-iv-adaptivity-correct,.h5p-interactive-video .h5p-question .h5p-question-iv-adaptivity-wrong{float:right}.h5p-interactive-video .h5p-question .h5p-question-iv-adaptivity-correct:before,.h5p-interactive-video .h5p-question .h5p-question-iv-adaptivity-wrong:before{content:\"\\F051\"}.h5p-interactive-video .h5p-question .h5p-question-iv-continue{float:right}.h5p-interactive-video .h5p-question-iv-continue:before{content:\"\\F04B\"}.h5p-interactive-video.mobile .h5p-dialog,.h5p-interactive-video.mobile .h5p-dialog.h5p-big{width:100%;height:100%;left:0;top:0}.h5p-no-frame .h5p-interactive-video.mobile .h5p-dialog,.h5p-no-frame .h5p-interactive-video.mobile .h5p-dialog.h5p-big{border:1px solid #eee}.h5p-interactive-video.mobile .h5p-dialog.h5p-big\u003e.h5p-dialog-inner,.h5p-interactive-video.mobile .h5p-dialog\u003e.h5p-dialog-inner{height:inherit;width:100%}.h5p-interactive-video .h5p-dialog.h5p-big[data-lib=\"H5P.Image\"] .h5p-dialog-inner{position:relative}.h5p-interactive-video .h5p-dialog.h5p-big[data-lib=\"H5P.Image\"] .h5p-image{position:absolute;left:50%;-webkit-transform:translateX(-50%);-moz-transform:translateX(-50%);-ms-transform:translateX(-50%);-o-transform:translateX(-50%);transform:translateX(-50%)}.h5p-interaction.h5p-poster.h5p-questionnaire-interaction .h5p-interaction-outer{overflow-y:hidden}.h5p-interactive-video .h5p-dialog.h5p-big[data-lib=\"H5P.Questionnaire\"] .h5p-questionnaire-wrapper{height:100%;width:100%}.h5p-interactive-video .h5p-dialog[data-lib=\"H5P.Questionnaire\"] .h5p-dialog-titlebar{background-color:#2269a9;border-bottom:1px solid #2269a9}.h5p-interactive-video .h5p-dialog[data-lib=\"H5P.Questionnaire\"] .h5p-dialog-close:before{color:#fff}.h5p-interactive-video .h5p-confirmation-dialog-background{z-index:101}.h5p-interactive-video .goto-clickable{cursor:pointer}.h5p-interactive-video .goto-clickable.h5p-text{cursor:pointer;display:block;margin:0;padding:1em;min-height:100%;text-decoration:none;color:#313131}.h5p-interactive-video .h5p-interaction.h5p-poster.goto-clickable-visualize .h5p-interaction-outer{position:static}.h5p-interactive-video .h5p-dialog.goto-clickable-visualize .h5p-dialog-inner,.h5p-interactive-video .h5p-poster.goto-clickable-visualize{border:2px solid #1d5cff;transition:border .3s,box-shadow .3s}.h5p-interactive-video .h5p-dialog.goto-clickable-visualize.h5p-goto-timecode .h5p-dialog-inner,.h5p-interactive-video .h5p-poster.goto-clickable-visualize.h5p-goto-timecode{border-color:#018d82}.h5p-interactive-video .h5p-dialog.goto-clickable-visualize .h5p-dialog-inner{box-sizing:border-box;min-height:calc(2.5em - 1px);height:auto}.h5p-interactive-video .h5p-dialog.goto-clickable-visualize .h5p-dialog-inner:hover{border-color:#003fdf}.h5p-interactive-video .h5p-poster.goto-clickable-visualize{box-shadow:2px 2px 2px rgba(0,0,0,.2)}.h5p-interactive-video .h5p-poster.goto-clickable-visualize.h5p-box-shadow-disabled{box-shadow:none}.h5p-interactive-video .h5p-poster.goto-clickable-visualize:hover{border-color:#003fdf;box-shadow:4px 4px 8px rgba(0,0,0,.4)}.h5p-interactive-video .h5p-dialog.goto-clickable-visualize.h5p-goto-timecode .h5p-dialog-inner:hover,.h5p-interactive-video .h5p-poster.goto-clickable-visualize.h5p-goto-timecode:hover{border-color:#00796f}.h5p-interactive-video .h5p-dialog.goto-clickable-visualize .h5p-dialog-inner,.h5p-interactive-video .h5p-poster.goto-clickable-visualize .h5p-dialog-inner{position:relative}.h5p-interactive-video .h5p-dialog.goto-clickable-visualize .h5p-dialog-inner:before,.h5p-interactive-video .h5p-poster.goto-clickable-visualize .goto-clickable:before{width:0;height:0;position:absolute;top:0;left:0;border-top:1.5em solid #1d5cff;border-right:1.5em solid transparent;opacity:.8;content:\"\";z-index:1;cursor:pointer;pointer-events:none;transition:border-top-color .3s}.h5p-interactive-video .h5p-dialog.goto-clickable-visualize.h5p-goto-timecode .h5p-dialog-inner:before,.h5p-interactive-video .h5p-poster.goto-clickable-visualize.h5p-goto-timecode .goto-clickable:before{border-top-color:#08a497}.h5p-interactive-video .h5p-dialog.goto-clickable-visualize .h5p-dialog-inner:hover:before,.h5p-interactive-video .h5p-poster.goto-clickable-visualize .goto-clickable:hover:before{border-top-color:#003fdf}.h5p-interactive-video .h5p-dialog.goto-clickable-visualize.h5p-goto-timecode .h5p-dialog-inner:hover:before,.h5p-interactive-video .h5p-poster.goto-clickable-visualize.h5p-goto-timecode .goto-clickable:hover:before{border-top-color:#027e74}.h5p-interactive-video .h5p-dialog.goto-clickable-visualize .h5p-dialog-inner:focus:before,.h5p-interactive-video .h5p-dialog.goto-clickable-visualize.h5p-goto-timecode .h5p-dialog-inner:focus:before,.h5p-interactive-video .h5p-poster.goto-clickable-visualize .goto-clickable:focus:before,.h5p-interactive-video .h5p-poster.goto-clickable-visualize.h5p-goto-timecode .goto-clickable:focus:before{border-top-color:transparent}.h5p-interactive-video .h5p-dialog.goto-clickable-visualize .h5p-dialog-inner:before{top:auto}.h5p-interactive-video .h5p-dialog.goto-clickable-visualize .h5p-dialog-inner:after,.h5p-interactive-video .h5p-poster.goto-clickable-visualize .goto-clickable:after{position:absolute;width:1em;height:1em;top:.25em;left:.25em;font-family:H5PFontAwesome4;font-size:.7em;content:\"\\F08E\";color:#fff;line-height:1;text-align:center;vertical-align:baseline;z-index:1;cursor:pointer;pointer-events:none;transition:color .3s}.h5p-interactive-video .h5p-dialog.goto-clickable-visualize.h5p-goto-timecode .h5p-dialog-inner:after,.h5p-interactive-video .h5p-poster.goto-clickable-visualize.h5p-goto-timecode .goto-clickable:after{content:\"\\F064\";transform:rotate(24deg) translateX(-2px)}.h5p-interactive-video .h5p-dialog.goto-clickable-visualize .h5p-dialog-inner:focus:after,.h5p-interactive-video .h5p-poster.goto-clickable-visualize .goto-clickable:focus:after{color:#1d5cff}.h5p-interactive-video .h5p-dialog.goto-clickable-visualize.h5p-goto-timecode .h5p-dialog-inner:focus:after,.h5p-interactive-video .h5p-poster.goto-clickable-visualize.h5p-goto-timecode .goto-clickable:focus:after{color:#018d82}.h5p-interactive-video .h5p-dialog.h5p-big.goto-clickable-visualize[data-lib=\"H5P.Image\"] .h5p-dialog-inner:after{top:.25em}.h5p-interactive-video .h5p-dialog.h5p-big[data-lib=\"H5P.Image\"] .h5p-image.goto-clickable{width:100%}.h5p-interactive-video .h5p-interaction-continue-button{cursor:pointer;text-transform:uppercase;color:#fff;background-color:#252525;border-radius:.5em;padding:.6em 2em;font-weight:600;font-size:.85em;width:auto;display:block;align-self:center;letter-spacing:3px;margin:1em auto}.h5p-interactive-video .h5p-interaction-continue-button:after{font-family:H5PFontAwesome4;content:\"\\F144\";margin-left:1.2em}.h5p-interactive-video .hidden{display:none}.h5p-interactive-video .hidden-but-read{left:-10000px;top:auto}.h5p-interactive-video .hidden-but-read,.h5p-iv-hotkey-instructions{position:absolute;width:1px;height:1px;overflow:hidden}.h5p-iv-interactions-announcer{position:absolute;top:0;width:1px;height:1px;overflow:hidden}","styles/H5PEditor.SummaryTextualEditor.css":".h5p-summary-editor textarea {\n padding: 20px;\n font-family: \"Open Sans\", sans-serif;\n line-height: 25px;\n}\n\n.h5p-summary-editor .h5p-help-text {\n white-space: pre-wrap;\n}\n","css/summary.css":".h5p-summary .summary-content .summary-container \u003e ul {\n margin: 0;\n padding: 0;\n display: block;\n}\n\n.h5p-summary .summary-container {\n margin: 1em 0;\n background-color: #fff;\n}\n\n.h5p-summary .summary-container.has-results {\n border: 1px solid #ddd;\n border-radius: 0.25em;\n}\n\n.h5p-summary .summary-options {\n height: auto;\n padding: 0;\n margin: 1em 0;\n}\n.h5p-summary .summary-options ul.h5p-panel {\n display: none;\n padding: 0;\n margin: 0;\n}\n\n.h5p-summary .summary-options ul.h5p-panel.panel-disabled {\n pointer-events: none;\n}\n\n.h5p-summary .summary-evaluation {\n overflow: hidden; /* Contain floated counters within the evaluation div */\n margin: 1em 0;\n}\n\n.h5p-summary .summary-evaluation-content {\n display: block;\n position: relative;\n font-size: 1.125em;\n float: left;\n padding: 0.1em 2em 0.1em 0;\n}\n\n.h5p-summary .summary-evaluation-content \u003e p {\n margin: 0;\n}\n\n.h5p-summary .summary-container li,\n.h5p-summary .summary-options li {\n list-style: none;\n background-color: #ddd;\n -moz-border-radius: 0.3em;\n -webkit-border-radius: 0.3em;\n border-radius: 0.3em;\n border: 0.1em solid #ddd;\n color: #000;\n font-size: 1em;\n padding: 0.375em 0.875em;\n text-decoration: none;\n margin: 0;\n margin-bottom: 0.3125em;\n -webkit-box-shadow: 0 0.1em 0 rgba(0, 0, 0, 0.2);\n -moz-box-shadow: 0 0.1em 0 rgba(0, 0, 0, 0.2);\n box-shadow: 0 0.1em 0 rgba(0, 0, 0, 0.2);\n}\n\n.h5p-summary .summary-content li \u003e p {\n margin: 0.4em 0 0 0;\n padding: 0;\n}\n.h5p-summary .summary-content li \u003e p:first-child {\n margin: 0;\n}\n.h5p-summary .summary-container li:not(:last-child) {\n border-bottom: 1px solid #ddd;\n border-radius: 0;\n}\n.h5p-summary .summary-container li {\n display: none;\n z-index: 5;\n margin: 0;\n border: 0;\n background: none;\n filter: none;\n -webkit-box-shadow: none;\n -moz-box-shadow: none;\n box-shadow: none;\n\n -webkit-transition: background-color 1000ms linear;\n -moz-transition: background-color 1000ms linear;\n -o-transition: background-color 1000ms linear;\n -ms-transition: background-color 1000ms linear;\n transition: background-color 1000ms linear;\n}\n.h5p-summary .summary-container li:before {\n text-decoration: none;\n content: \"\\f00c\";\n font-family: \u0027H5PFontAwesome4\u0027;\n color: #255c41;\n float: right;\n}\n.h5p-summary .h5p-panel:not(.panel-disabled) .summary-claim-unclicked:hover,\n.h5p-summary .h5p-panel:not(.panel-disabled) .summary-claim-unclicked:focus {\n cursor: pointer;\n filter: none;\n border: 0.1em solid #edd6e9;\n\n background: #edd6e9;\n}\n\n.h5p-summary li.summary-failed \u003e p,\n.h5p-summary li.summary-failed {\n color: #b71c1c;\n border: 0.1em solid #f7d0d0;\n background: #f7d0d0;\n text-decoration: line-through;\n font-weight: bold;\n -webkit-box-shadow: none;\n -moz-box-shadow: none;\n box-shadow: none;\n}\n\n.h5p-summary li.summary-failed:before {\n text-decoration: none;\n content: \"\\f00d\";\n font-family: \u0027H5PFontAwesome4\u0027;\n color: #b71c1c;\n float: right;\n line-height: 1.25;\n}\n\n.h5p-summary .summary-options div {\n font-size: 1em;\n padding:0;\n background-repeat: no-repeat;\n background-position: top right;\n}\n\n.h5p-summary .summary-score {\n display: none;\n float: right;\n background: #f7d0d0;\n -moz-border-radius: 0.3em;\n -webkit-border-radius: 0.3em;\n border-radius: 0.3em;\n padding: 0.1em 0.3em;\n font-weight: normal;\n}\n\n.h5p-summary .summary-score:before {\n text-decoration: none;\n content: \"\\f00d\";\n font-family: \u0027H5PFontAwesome4\u0027;\n color: #b71c1c;\n float: left;\n margin-right: 0.3em;\n top: 0.1em;\n}\n\n.h5p-summary .summary-progress {\n width: 0;\n height: 0;\n overflow: hidden;\n left: 0;\n position: absolute;\n}\n\n.h5p-summary .summary-progress-numeric {\n float: right;\n background: #9dd8bb;\n -moz-border-radius: 0.3em;\n -webkit-border-radius: 0.3em;\n border-radius: 0.3em;\n padding: 0.1em 0.3em;\n font-weight: normal;\n margin-left: 0.3em;\n}\n\n.h5p-summary .summary-progress-numeric:before {\n text-decoration: none;\n content: \"\\f00c\";\n font-family: \u0027H5PFontAwesome4\u0027;\n color: #255c41;\n float: left;\n margin-right: 0.3em;\n}\n\n.h5p-summary .summary-options h2 {\n font-size: 1.2em;\n font-weight: bold;\n padding-bottom: 0.5em;\n margin: 0;\n}\n\n.h5p-summary .summary-evaluation .joubel-tip-container {\n position: absolute;\n top: 0;\n right: 0;\n}\n.h5p-summary .summary-evaluation .joubel-tip-icon {\n line-height: 1;\n font-size: 1.3em;\n}\n\n.h5p-summary .summary-feedback {\n display: inline-block;\n float: right;\n}\n\n.summary-evaluation-content .joubel-icon-tip-normal {\n line-height: 0.75em;\n}\n\n.h5p-summary .h5p-hidden-read {\n width: 1px;\n height: 1px;\n top: -1px;\n position: absolute;\n text-indent: 1px;\n overflow: hidden;\n}\n","styles/duration.css":".field.duration input {\n width: 75px;\n}","timecode.css":".field.timecode input {\n width: 4.6875em;\n}\n","select-toggle-fields.css":".h5peditor-select-toggle-field-hide {\n display: none;\n}\n","styles/spectrum.css":"/***\nSpectrum Colorpicker v1.8.0\nhttps://github.com/bgrins/spectrum\nAuthor: Brian Grinstead\nLicense: MIT\n***/\n\n.sp-container {\n position:absolute;\n top:0;\n left:0;\n display:inline-block;\n *display: inline;\n *zoom: 1;\n /* https://github.com/bgrins/spectrum/issues/40 */\n z-index: 9999994;\n overflow: hidden;\n}\n.sp-container.sp-flat {\n position: relative;\n}\n\n/* Fix for * { box-sizing: border-box; } */\n.sp-container,\n.sp-container * {\n -webkit-box-sizing: content-box;\n -moz-box-sizing: content-box;\n box-sizing: content-box;\n}\n\n/* http://ansciath.tumblr.com/post/7347495869/css-aspect-ratio */\n.sp-top {\n position:relative;\n width: 100%;\n display:inline-block;\n}\n.sp-top-inner {\n position:absolute;\n top:0;\n left:0;\n bottom:0;\n right:0;\n}\n.sp-color {\n position: absolute;\n top:0;\n left:0;\n bottom:0;\n right:20%;\n}\n.sp-hue {\n position: absolute;\n top:0;\n right:0;\n bottom:0;\n left:84%;\n height: 100%;\n}\n\n.sp-clear-enabled .sp-hue {\n top:33px;\n height: 77.5%;\n}\n\n.sp-fill {\n padding-top: 80%;\n}\n.sp-sat, .sp-val {\n position: absolute;\n top:0;\n left:0;\n right:0;\n bottom:0;\n}\n\n.sp-alpha-enabled .sp-top {\n margin-bottom: 18px;\n}\n.sp-alpha-enabled .sp-alpha {\n display: block;\n}\n.sp-alpha-handle {\n position:absolute;\n top:-4px;\n bottom: -4px;\n width: 6px;\n left: 50%;\n cursor: pointer;\n border: 1px solid black;\n background: white;\n opacity: .8;\n}\n.sp-alpha {\n display: none;\n position: absolute;\n bottom: -14px;\n right: 0;\n left: 0;\n height: 8px;\n}\n.sp-alpha-inner {\n border: solid 1px #333;\n}\n\n.sp-clear {\n display: none;\n}\n\n.sp-clear.sp-clear-display {\n background-position: center;\n}\n\n.sp-clear-enabled .sp-clear {\n display: block;\n position:absolute;\n top:0px;\n right:0;\n bottom:0;\n left:84%;\n height: 28px;\n}\n\n/* Don\u0027t allow text selection */\n.sp-container, .sp-replacer, .sp-preview, .sp-dragger, .sp-slider, .sp-alpha, .sp-clear, .sp-alpha-handle, .sp-container.sp-dragging .sp-input, .sp-container button {\n -webkit-user-select:none;\n -moz-user-select: -moz-none;\n -o-user-select:none;\n user-select: none;\n}\n\n.sp-container.sp-input-disabled .sp-input-container {\n display: none;\n}\n.sp-container.sp-buttons-disabled .sp-button-container {\n display: none;\n}\n.sp-container.sp-palette-buttons-disabled .sp-palette-button-container {\n display: none;\n}\n.sp-palette-only .sp-picker-container {\n display: none;\n}\n.sp-palette-disabled .sp-palette-container {\n display: none;\n}\n\n.sp-initial-disabled .sp-initial {\n display: none;\n}\n\n\n/* Gradients for hue, saturation and value instead of images. Not pretty... but it works */\n.sp-sat {\n background-image: -webkit-gradient(linear, 0 0, 100% 0, from(#FFF), to(rgba(204, 154, 129, 0)));\n background-image: -webkit-linear-gradient(left, #FFF, rgba(204, 154, 129, 0));\n background-image: -moz-linear-gradient(left, #fff, rgba(204, 154, 129, 0));\n background-image: -o-linear-gradient(left, #fff, rgba(204, 154, 129, 0));\n background-image: -ms-linear-gradient(left, #fff, rgba(204, 154, 129, 0));\n background-image: linear-gradient(to right, #fff, rgba(204, 154, 129, 0));\n -ms-filter: \"progid:DXImageTransform.Microsoft.gradient(GradientType = 1, startColorstr=#FFFFFFFF, endColorstr=#00CC9A81)\";\n filter : progid:DXImageTransform.Microsoft.gradient(GradientType = 1, startColorstr=\u0027#FFFFFFFF\u0027, endColorstr=\u0027#00CC9A81\u0027);\n}\n.sp-val {\n background-image: -webkit-gradient(linear, 0 100%, 0 0, from(#000000), to(rgba(204, 154, 129, 0)));\n background-image: -webkit-linear-gradient(bottom, #000000, rgba(204, 154, 129, 0));\n background-image: -moz-linear-gradient(bottom, #000, rgba(204, 154, 129, 0));\n background-image: -o-linear-gradient(bottom, #000, rgba(204, 154, 129, 0));\n background-image: -ms-linear-gradient(bottom, #000, rgba(204, 154, 129, 0));\n background-image: linear-gradient(to top, #000, rgba(204, 154, 129, 0));\n -ms-filter: \"progid:DXImageTransform.Microsoft.gradient(startColorstr=#00CC9A81, endColorstr=#FF000000)\";\n filter : progid:DXImageTransform.Microsoft.gradient(startColorstr=\u0027#00CC9A81\u0027, endColorstr=\u0027#FF000000\u0027);\n}\n\n.sp-hue {\n background: -moz-linear-gradient(top, #ff0000 0%, #ffff00 17%, #00ff00 33%, #00ffff 50%, #0000ff 67%, #ff00ff 83%, #ff0000 100%);\n background: -ms-linear-gradient(top, #ff0000 0%, #ffff00 17%, #00ff00 33%, #00ffff 50%, #0000ff 67%, #ff00ff 83%, #ff0000 100%);\n background: -o-linear-gradient(top, #ff0000 0%, #ffff00 17%, #00ff00 33%, #00ffff 50%, #0000ff 67%, #ff00ff 83%, #ff0000 100%);\n background: -webkit-gradient(linear, left top, left bottom, from(#ff0000), color-stop(0.17, #ffff00), color-stop(0.33, #00ff00), color-stop(0.5, #00ffff), color-stop(0.67, #0000ff), color-stop(0.83, #ff00ff), to(#ff0000));\n background: -webkit-linear-gradient(top, #ff0000 0%, #ffff00 17%, #00ff00 33%, #00ffff 50%, #0000ff 67%, #ff00ff 83%, #ff0000 100%);\n background: linear-gradient(to bottom, #ff0000 0%, #ffff00 17%, #00ff00 33%, #00ffff 50%, #0000ff 67%, #ff00ff 83%, #ff0000 100%);\n}\n\n/* IE filters do not support multiple color stops.\n Generate 6 divs, line them up, and do two color gradients for each.\n Yes, really.\n */\n.sp-1 {\n height:17%;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr=\u0027#ff0000\u0027, endColorstr=\u0027#ffff00\u0027);\n}\n.sp-2 {\n height:16%;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr=\u0027#ffff00\u0027, endColorstr=\u0027#00ff00\u0027);\n}\n.sp-3 {\n height:17%;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr=\u0027#00ff00\u0027, endColorstr=\u0027#00ffff\u0027);\n}\n.sp-4 {\n height:17%;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr=\u0027#00ffff\u0027, endColorstr=\u0027#0000ff\u0027);\n}\n.sp-5 {\n height:16%;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr=\u0027#0000ff\u0027, endColorstr=\u0027#ff00ff\u0027);\n}\n.sp-6 {\n height:17%;\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr=\u0027#ff00ff\u0027, endColorstr=\u0027#ff0000\u0027);\n}\n\n.sp-hidden {\n display: none !important;\n}\n\n/* Clearfix hack */\n.sp-cf:before, .sp-cf:after { content: \"\"; display: table; }\n.sp-cf:after { clear: both; }\n.sp-cf { *zoom: 1; }\n\n/* Mobile devices, make hue slider bigger so it is easier to slide */\n@media (max-device-width: 480px) {\n .sp-color { right: 40%; }\n .sp-hue { left: 63%; }\n .sp-fill { padding-top: 60%; }\n}\n.sp-dragger {\n border-radius: 5px;\n height: 5px;\n width: 5px;\n border: 1px solid #fff;\n background: #000;\n cursor: pointer;\n position:absolute;\n top:0;\n left: 0;\n}\n.sp-slider {\n position: absolute;\n top:0;\n cursor:pointer;\n height: 3px;\n left: -1px;\n right: -1px;\n border: 1px solid #000;\n background: white;\n opacity: .8;\n}\n\n/*\nTheme authors:\nHere are the basic themeable display options (colors, fonts, global widths).\nSee http://bgrins.github.io/spectrum/themes/ for instructions.\n*/\n\n.sp-container {\n border-radius: 0;\n background-color: #ECECEC;\n border: solid 1px #f0c49B;\n padding: 0;\n}\n.sp-container, .sp-container button, .sp-container input, .sp-color, .sp-hue, .sp-clear {\n font: normal 12px \"Lucida Grande\", \"Lucida Sans Unicode\", \"Lucida Sans\", Geneva, Verdana, sans-serif;\n -webkit-box-sizing: border-box;\n -moz-box-sizing: border-box;\n -ms-box-sizing: border-box;\n box-sizing: border-box;\n}\n.sp-top {\n margin-bottom: 3px;\n}\n.sp-color, .sp-hue, .sp-clear {\n border: solid 1px #666;\n}\n\n/* Input */\n.sp-input-container {\n float:right;\n width: 100px;\n margin-bottom: 4px;\n}\n.sp-initial-disabled .sp-input-container {\n width: 100%;\n}\n.sp-input {\n font-size: 12px !important;\n border: 1px inset;\n padding: 4px 5px;\n margin: 0;\n width: 100%;\n background:transparent;\n border-radius: 3px;\n color: #222;\n}\n.sp-input:focus {\n border: 1px solid orange;\n}\n.sp-input.sp-validation-error {\n border: 1px solid red;\n background: #fdd;\n}\n.sp-picker-container , .sp-palette-container {\n float:left;\n position: relative;\n padding: 10px;\n padding-bottom: 300px;\n margin-bottom: -290px;\n}\n.sp-picker-container {\n width: 172px;\n border-left: solid 1px #fff;\n}\n\n/* Palettes */\n.sp-palette-container {\n border-right: solid 1px #ccc;\n}\n\n.sp-palette-only .sp-palette-container {\n border: 0;\n}\n\n.sp-palette .sp-thumb-el {\n display: block;\n position:relative;\n float:left;\n width: 24px;\n height: 15px;\n margin: 3px;\n cursor: pointer;\n border:solid 2px transparent;\n}\n.sp-palette .sp-thumb-el:hover, .sp-palette .sp-thumb-el.sp-thumb-active {\n border-color: orange;\n}\n.sp-thumb-el {\n position:relative;\n}\n\n/* Initial */\n.sp-initial {\n float: left;\n border: solid 1px #333;\n}\n.sp-initial span {\n width: 30px;\n height: 25px;\n border:none;\n display:block;\n float:left;\n margin:0;\n}\n\n.sp-initial .sp-clear-display {\n background-position: center;\n}\n\n/* Buttons */\n.sp-palette-button-container,\n.sp-button-container {\n float: right;\n}\n\n/* Replacer (the little preview div that shows up instead of the \u003cinput\u003e) */\n.sp-replacer {\n margin:0;\n overflow:hidden;\n cursor:pointer;\n padding: 4px;\n display:inline-block;\n *zoom: 1;\n *display: inline;\n border: solid 1px #91765d;\n background: #eee;\n color: #333;\n vertical-align: middle;\n}\n.sp-replacer:hover, .sp-replacer.sp-active {\n border-color: #F0C49B;\n color: #111;\n}\n.sp-replacer.sp-disabled {\n cursor:default;\n border-color: silver;\n color: silver;\n}\n.sp-dd {\n padding: 2px 0;\n height: 16px;\n line-height: 16px;\n float:left;\n font-size:10px;\n}\n.sp-preview {\n position:relative;\n width:25px;\n height: 20px;\n border: solid 1px #222;\n margin-right: 5px;\n float:left;\n z-index: 0;\n}\n\n.sp-palette {\n *width: 220px;\n max-width: 220px;\n}\n.sp-palette .sp-thumb-el {\n width:16px;\n height: 16px;\n margin:2px 1px;\n border: solid 1px #d0d0d0;\n}\n\n.sp-container {\n padding-bottom:0;\n}\n\n\n/* Buttons: http://hellohappy.org/css3-buttons/ */\n.sp-container button {\n background-color: #eeeeee;\n background-image: -webkit-linear-gradient(top, #eeeeee, #cccccc);\n background-image: -moz-linear-gradient(top, #eeeeee, #cccccc);\n background-image: -ms-linear-gradient(top, #eeeeee, #cccccc);\n background-image: -o-linear-gradient(top, #eeeeee, #cccccc);\n background-image: linear-gradient(to bottom, #eeeeee, #cccccc);\n border: 1px solid #ccc;\n border-bottom: 1px solid #bbb;\n border-radius: 3px;\n color: #333;\n font-size: 14px;\n line-height: 1;\n padding: 5px 4px;\n text-align: center;\n text-shadow: 0 1px 0 #eee;\n vertical-align: middle;\n}\n.sp-container button:hover {\n background-color: #dddddd;\n background-image: -webkit-linear-gradient(top, #dddddd, #bbbbbb);\n background-image: -moz-linear-gradient(top, #dddddd, #bbbbbb);\n background-image: -ms-linear-gradient(top, #dddddd, #bbbbbb);\n background-image: -o-linear-gradient(top, #dddddd, #bbbbbb);\n background-image: linear-gradient(to bottom, #dddddd, #bbbbbb);\n border: 1px solid #bbb;\n border-bottom: 1px solid #999;\n cursor: pointer;\n text-shadow: 0 1px 0 #ddd;\n}\n.sp-container button:active {\n border: 1px solid #aaa;\n border-bottom: 1px solid #888;\n -webkit-box-shadow: inset 0 0 5px 2px #aaaaaa, 0 1px 0 0 #eeeeee;\n -moz-box-shadow: inset 0 0 5px 2px #aaaaaa, 0 1px 0 0 #eeeeee;\n -ms-box-shadow: inset 0 0 5px 2px #aaaaaa, 0 1px 0 0 #eeeeee;\n -o-box-shadow: inset 0 0 5px 2px #aaaaaa, 0 1px 0 0 #eeeeee;\n box-shadow: inset 0 0 5px 2px #aaaaaa, 0 1px 0 0 #eeeeee;\n}\n.sp-cancel {\n font-size: 11px;\n color: #d93f3f !important;\n margin:0;\n padding:2px;\n margin-right: 5px;\n vertical-align: middle;\n text-decoration:none;\n\n}\n.sp-cancel:hover {\n color: #d93f3f !important;\n text-decoration: underline;\n}\n\n\n.sp-palette span:hover, .sp-palette span.sp-thumb-active {\n border-color: #000;\n}\n\n.sp-preview, .sp-alpha, .sp-thumb-el {\n position:relative;\n background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAwAAAAMCAIAAADZF8uwAAAAGUlEQVQYV2M4gwH+YwCGIasIUwhT25BVBADtzYNYrHvv4gAAAABJRU5ErkJggg==);\n}\n.sp-preview-inner, .sp-alpha-inner, .sp-thumb-inner {\n display:block;\n position:absolute;\n top:0;left:0;bottom:0;right:0;\n}\n\n.sp-palette .sp-thumb-inner {\n background-position: 50% 50%;\n background-repeat: no-repeat;\n}\n\n.sp-palette .sp-thumb-light.sp-thumb-active .sp-thumb-inner {\n background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABIAAAASCAYAAABWzo5XAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAIVJREFUeNpiYBhsgJFMffxAXABlN5JruT4Q3wfi/0DsT64h8UD8HmpIPCWG/KemIfOJCUB+Aoacx6EGBZyHBqI+WsDCwuQ9mhxeg2A210Ntfo8klk9sOMijaURm7yc1UP2RNCMbKE9ODK1HM6iegYLkfx8pligC9lCD7KmRof0ZhjQACDAAceovrtpVBRkAAAAASUVORK5CYII=);\n}\n\n.sp-palette .sp-thumb-dark.sp-thumb-active .sp-thumb-inner {\n background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABIAAAASCAYAAABWzo5XAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAadEVYdFNvZnR3YXJlAFBhaW50Lk5FVCB2My41LjEwMPRyoQAAAMdJREFUOE+tkgsNwzAMRMugEAahEAahEAZhEAqlEAZhEAohEAYh81X2dIm8fKpEspLGvudPOsUYpxE2BIJCroJmEW9qJ+MKaBFhEMNabSy9oIcIPwrB+afvAUFoK4H0tMaQ3XtlrggDhOVVMuT4E5MMG0FBbCEYzjYT7OxLEvIHQLY2zWwQ3D+9luyOQTfKDiFD3iUIfPk8VqrKjgAiSfGFPecrg6HN6m/iBcwiDAo7WiBeawa+Kwh7tZoSCGLMqwlSAzVDhoK+6vH4G0P5wdkAAAAASUVORK5CYII=);\n}\n\n.sp-clear-display {\n background-repeat:no-repeat;\n background-position: center;\n background-image: url(data:image/gif;base64,R0lGODlhFAAUAPcAAAAAAJmZmZ2dnZ6enqKioqOjo6SkpKWlpaampqenp6ioqKmpqaqqqqurq/Hx8fLy8vT09PX19ff39/j4+Pn5+fr6+vv7+wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAP8ALAAAAAAUABQAAAihAP9FoPCvoMGDBy08+EdhQAIJCCMybCDAAYUEARBAlFiQQoMABQhKUJBxY0SPICEYHBnggEmDKAuoPMjS5cGYMxHW3IiT478JJA8M/CjTZ0GgLRekNGpwAsYABHIypcAgQMsITDtWJYBR6NSqMico9cqR6tKfY7GeBCuVwlipDNmefAtTrkSzB1RaIAoXodsABiZAEFB06gIBWC1mLVgBa0AAOw==);\n}\n","styles/color-selector.css":".sp-container {\n background: #f5f5f5;\n border-color: #d0d0d1;\n box-shadow: 0 0 8px #ccc;\n}\n.sp-replacer:hover,\n.sp-replacer.sp-active {\n border-color: #9e9e9e;\n}\n.sp-container button,\n.sp-container button:hover {\n background: #747275;\n text-shadow: initial;\n color: #fff;\n padding: 5px 8px;\n text-transform: capitalize;\n}\n.sp-cancel {\n padding: 2px 6px;\n font-size: 12px;\n}\n","css/blanks.css":".h5p-blanks {\n position: relative;\n}\n.h5p-blanks .h5p-input-wrapper {\n display: inline-block;\n position: relative;\n}\n.h5p-blanks .h5p-text-input {\n font-family: H5PDroidSans, sans-serif;\n font-size: 1em;\n border-radius: 0.25em;\n border: 1px solid #a0a0a0;\n padding: 0.1875em 1em 0.1875em 0.5em;\n text-overflow: ellipsis;\n overflow: hidden;\n white-space: nowrap;\n width: 6em;\n}\n.h5p-blanks .h5p-text-input:focus {\n outline: none;\n box-shadow: 0 0 0.5em 0 #7fb8ff;\n border-color: #7fb8ff;\n}\n.h5p-blanks .h5p-text-input.h5p-not-filled-out {\n background: #fff0f0;\n}\n.h5p-blanks .h5p-separate-lines .h5p-input-wrapper {\n display: block;\n}\n.h5p-blanks .h5p-separate-lines .h5p-text-input {\n width: 100%;\n box-sizing: border-box;\n -moz-box-sizing: border-box;\n}\n\n/* Correctly answered input */\n.h5p-blanks .h5p-correct .h5p-text-input {\n background: #9dd8bb;\n border: 1px solid #9dd8bb;\n color: #255c41;\n}\n.h5p-blanks .h5p-correct-answer {\n color: #255c41;\n font-weight: bold;\n}\n.h5p-blanks .h5p-correct:after {\n position: absolute;\n right: 0.5em;\n top: 0;\n text-decoration: none;\n content: \"\\f00c\";\n font-family: \u0027H5PFontAwesome4\u0027;\n color: #255c41;\n}\n\n/* Wrongly answered input */\n.h5p-blanks .h5p-wrong .h5p-text-input {\n background-color: #f7d0d0;\n border: 1px solid #f7d0d0;\n color: #b71c1c;\n text-decoration: line-through;\n}\n.h5p-blanks .h5p-wrong:after {\n position: absolute;\n right: 0.5em;\n top: 0;\n font-family: \u0027H5PFontAwesome4\u0027;\n text-decoration: none;\n content: \"\\f00d\";\n color: #b71c1c;\n}\n\n/* Actual text paragraphs */\n.h5p-blanks .h5p-question-content p {\n line-height: 1.75em;\n margin: 0 0 1em;\n}\n\n/* Header and footer blocks (title + evaluation, buttons) */\n.h5p-blanks .joubel-tip-container {\n position: absolute;\n right: 0.4em;\n font-size: 1em;\n}\n.h5p-blanks .joubel-tip-container .joubel-icon-tip-normal {\n line-height: 1em;\n}\n.h5p-blanks .has-tip .h5p-text-input {\n padding-right: 2.25em;\n}\n.h5p-blanks .has-tip.h5p-correct:after,\n.h5p-blanks .has-tip.h5p-wrong:after {\n right: 2.25em;\n}\n.h5p-blanks .has-tip.h5p-correct .h5p-text-input,\n.h5p-blanks .has-tip.h5p-wrong .h5p-text-input {\n padding-right: 3.5em;\n}\n","text.css":".h5p-advanced-text ul,\n.h5p-advanced-text ol {\n padding: 0;\n margin: 1em 0;\n}\n.h5p-advanced-text ul li,\n.h5p-advanced-text ol li {\n margin: 0 0 1em 1.5em;\n padding: 0;\n}\n\n.h5p-advanced-text ul li:last-child,\n.h5p-advanced-text ol li:last-child {\n margin-bottom: 0;\n}\n.h5p-advanced-text ul li {\n list-style-type: circle;\n}\n.h5p-advanced-text ol li {\n list-style-type: decimal;\n}\n.h5p-advanced-text.h5p-frame {\n margin: 1em;\n}\n","H5PEditor.DragQuestion.css":".h5peditor-dragquestion-wrapper {\n position: relative;\n}\n\n.dragQuestion {\n position: relative;\n}\n\n.dragQuestion .h5peditor-dragnbar {\n font-size: 1em;\n background: #f5f5f5;\n border: 1px solid #ccc;\n border-bottom: none;\n}\n\n.dragQuestion .h5p-dragnbar-ul {\n float: none;\n padding: 0;\n margin: 0;\n list-style: none;\n}\n\n.dragQuestion .h5p-dragnbar-ul:after {\n visibility: hidden;\n display: block;\n content: \"\";\n clear: both;\n}\n\n.dragQuestion .h5p-dragnbar-li {\n float: left;\n margin: 0;\n padding: 0;\n background: none;\n border: none;\n position: relative;\n}\n\n.h5p-dragquestion-editor .h5peditor-dragnbar .h5p-dragnbar-li .h5p-dragnbar-tooltip {\n font-size: 0.9em;\n}\n\n.dragQuestion .h5p-dragnbar-li:hover {\n background: none;\n}\n\n.dragQuestion .h5p-dragnbar-li:before {\n top: 44px;\n font-size: 0.88em;\n}\n\n.dragQuestion .h5p-dragnbar-a {\n width: 1em;\n line-height: 1.5em;\n text-align: center;\n background: linear-gradient(to bottom,#fff 0,#f2f2f2 100%);\n border: 1px solid #ccc;\n border-radius: 0.25em;\n margin: 0.25em;\n display: block;\n padding: 0.25em 0.75em;\n color: #333;\n}\n\n.dragQuestion .h5p-dragnbar-a:hover {\n text-decoration: none;\n border-color: #999;\n}\n\n.dragQuestion .h5p-dragnbar-a:link, .dragQuestion .h5p-dragnbar-a:visited {\n color: #555;\n}\n.dragQuestion .h5p-dragnbar-a:before {\n font-family: \u0027H5PFontAwesome4\u0027;\n content: \"?\";\n}\n.dragQuestion .h5p-dragnbar-a:hover {\n text-decoration: none;\n}\n.dragQuestion .h5p-dragnbar-advancedtext-button:before {\n font-size: 1.125em;\n font-weight: bold;\n content: \"T\";\n}\n.dragQuestion .h5p-dragnbar-image-button:before {\n content: \"\\f03e\";\n}\n.dragQuestion .h5p-dragnbar-dropzone-button:before {\n content: \"\\f140\";\n}\n\n.h5peditor-dragquestion {\n padding: 0.5em 1em;\n}\n.h5peditor-dragquestion.h5p-ready {\n padding: 0;\n background-size: 100% 100%;\n background-color: #FFFFFF;\n position: relative;\n border: 1px solid #ccc;\n border-radius: 0;\n overflow: hidden;\n}\n\n.h5peditor-dragquestion .h5p-dragnbar-element.focused {\n outline-offset: -2px;\n}\n\n.h5peditor-dragquestion .h5p-dragnbar-element:not(.focused):focus {\n outline: none;\n}\n\n.h5p-dq-element {\n position: absolute;\n line-height: 1.25em;\n z-index: 1;\n background: #fff;\n cursor: pointer;\n}\n\n.h5p-dq-text {\n padding: 0.25em 0.5em;\n}\n.h5p-dq-element.h5p-draggable {\n border-radius: 0.5em;\n border: 0.1em solid #c6c6c6;\n cursor: pointer;\n position: absolute;\n text-align: center;\n background: #ddd;\n box-shadow: 0 0 0.3em rgba(0,0,0,0.2);\n z-index: 3;\n -webkit-user-select: none;\n -moz-user-select: none;\n -ms-user-select: none;\n padding: 0.3em 0.3em;\n line-height: 1.25em;\n\n display: flex;\n flex-direction: column;\n justify-content: center;\n}\n.h5p-dq-element.h5p-draggable .h5p-dq-element-inner {\n padding: 0;\n overflow: hidden;\n}\n.h5p-dq-element.h5p-draggable:hover {\n border: 0.1em solid rgb(212,190,216);\n color: #663366;\n background: #edd6e9;\n}\n\n.h5p-dq-element-inner.h5p-image {\n width: 100%;\n height: 100%;\n}\n.h5p-draggable \u003e ul {\n text-align: left;\n margin: 0.5em 0.5em 0.5em 2.25em;\n padding: 0;\n}\n\n.h5p-draggable \u003e ul \u003e li {\n background: transparent;\n list-style: disc outside none;\n padding: 0;\n margin: 0;\n}\n\n.h5p-dq-element p {\n margin: 0;\n padding: 0;\n}\n.h5p-dq-element span {\n line-height: 1em;\n}\n.h5p-dq-dz {\n cursor: pointer;\n position: absolute;\n border: 2px solid rgba(255,255,255,0.7);\n border-radius: 0.5em;\n z-index: 2;\n box-sizing: border-box;\n -moz-box-sizing: border-box;\n background: rgb(245, 245, 245);\n}\n.h5p-dq-dz:before {\n content: \" \";\n display: block;\n position: absolute;\n border: 2px dashed rgba(0, 0, 0, 0.7);\n width: 100%;\n height: 100%;\n top: -2px;\n left: -2px;\n}\n\n.h5p-dq-dz.h5p-has-label {\n border-radius: 0 0 0.5em 0.5em;\n}\n.h5p-dq-dz .joubel-tip-container {\n position: absolute;\n right: 0.5em;\n bottom: 0;\n font-size: 0.8em;\n}\n\n.h5peditor-dragquestion .h5p-moving {\n opacity: 0.75;\n}\n\n.h5p-dq-label {\n position: absolute;\n bottom: 100%;\n font-size: 0.75em;\n}\n\n.h5peditor-fluid-dialog {\n display: none;\n background: #fff;\n border: 1px solid #ccc;\n -webkit-box-shadow: 0 0 4px #a7a7a7;\n -moz-box-shadow: 0 0 4px #a7a7a7;\n box-shadow: 0 0 4px #a7a7a7;\n}\n.h5peditor-fd-inner {\n padding: 0.5em;\n}\n.h5peditor-fd-buttons {\n overflow: hidden;\n border-top: 1px solid #ccc;\n background: #f5f5f5;\n}\na.h5peditor-fd-button {\n font-size: 0.75em;\n float: right;\n padding: 0.625em 2em;\n margin: 0.5em;\n border-radius: 0.25em;\n border: 1px solid #ccc;\n color: #fff;\n background: #3673B5;\n background: -webkit-linear-gradient(top,#5A94D3 0,#3673B5 100%);\n background: -moz-linear-gradient(top,#5A94D3 0,#3673B5 100%);\n background: -ms-linear-gradient(top,#5A94D3 0,#3673B5 100%);\n background: -o-linear-gradient(top,#5A94D3 0,#3673B5 100%);\n border-color: #20588F;\n}\na.h5peditor-fd-button:hover {\n background: #3275bc;\n background: -webkit-linear-gradient(top,#3275bc 0,#285585 100%);\n background: -moz-linear-gradient(top,#3275bc 0,#285585 100%);\n background: -ms-linear-gradient(top,#3275bc 0,#285585 100%);\n background: -o-linear-gradient(top,#3275bc 0,#285585 100%);\n}\na.h5peditor-fd-button.h5peditor-remove {\n background: none;\n border: none;\n color: #a00;\n padding-right: 0;\n}\na.h5peditor-fd-button.h5peditor-remove:hover {\n color: #e40000;\n}\n.h5p-dq-dz-label {\n background: none repeat scroll 0 0 #ddd;\n margin-bottom: 0.1em;\n line-height: 1.25em;\n padding-left: 0.5em;\n position: absolute;\n bottom: 100%;\n left: -0.1em;\n right: -0.1em;\n white-space: nowrap;\n border-radius: 0.5em 0.5em 0 0;\n}\n\n.h5peditor-dynamiccheckboxes-select, .h5peditor-dynamiccheckboxes-select \u003e li {\n margin: 0;\n padding: 0;\n list-style: none;\n background: transparent;\n}\n.h5peditor-dynamiccheckboxes-select \u003e li {\n margin: 0.1em 1em;\n}\n.h5peditor-dynamiccheckboxes-select \u003e li \u003e .h5p-editor-label {\n font-weight: normal;\n}\n.h5peditor-dynamiccheckboxes-select \u003e li \u003e .h5p-editor-label \u003e input,\n.h5peditor-dynamiccheckboxes-select .h5p-label-text {\n vertical-align: middle;\n display: inline-block;\n}\n.field.dynamicCheckboxes .h5p-selectall {\n font-size: 0.75em;\n}\n\n.h5p-dragquestion-editor .h5peditor-panes \u003e .field.dragQuestion {\n background-color: #fff;\n padding: 20px;\n}\n\n.h5p-dragquestion-editor .h5peditor-form {\n border-radius: 0;\n padding: 0;\n background: #fff;\n}\n\n.h5p-dragquestion-editor .field.wizard \u003e .h5peditor-panes \u003e .group \u003e .content {\n border: 0;\n}\n\n.h5p-dragquestion-editor .field.wizard .h5peditor-tab-settings:before {\n content: \u0027\\e916\u0027;\n}\n.h5p-dragquestion-editor .field.wizard .h5peditor-tab-task:before {\n content: \u0027\\e991\u0027;\n}\n\n.h5p-dragquestion-editor .common {\n margin: 20px;\n background-color: #FAFBFC;\n}\n\n.h5p-dragquestion-editor .tree \u003e .field-name-backgroundOpacity,\n.h5p-dragquestion-editor .tree \u003e .field-name-behaviour,\n.h5p-dragquestion-editor .tree \u003e .field-name-overallFeedback {\n margin: 20px;\n}\n\n.field-name-backgroundOpacity .h5peditor-text {\n width: 75px;\n}\n","css/dragquestion.css":".h5p-dragquestion {\n display: block;\n background: #fff;\n}\n\nhtml.h5p-iframe .h5p-container.h5p-dragquestion.h5p-semi-fullscreen,\nhtml.h5p-iframe .h5p-container.h5p-dragquestion.h5p-fullscreen {\n overflow-y: auto;\n overflow-x: hidden;\n}\n\nhtml.h5p-iframe .h5p-container.h5p-dragquestion.h5p-semi-fullscreen {\n overflow-x: auto;\n}\n\n.h5p-question-content.h5p-dragquestion-has-no-background {\n border-bottom: 1px solid #eee;\n}\n.h5p-dragquestion \u003e .h5p-question-content \u003e .h5p-inner {\n position: relative;\n background-repeat: no-repeat;\n background-position: center top;\n background-size: 100% 100%;\n margin: 0 auto;\n overflow: hidden;\n}\n\n.h5p-dragquestion \u003e .h5p-question-content {\n margin-left: 0;\n margin-right: 0;\n}\n\n.h5p-dragquestion .h5p-static {\n background: #fff;\n position: absolute;\n z-index: 1;\n}\n\n.h5p-dragquestion .h5p-static.h5p-advanced-text {\n padding: 0.25em 0.5em;\n border-radius: 0.25em;\n}\n\n.h5p-dragquestion .h5p-static \u003e h2 {\n font-size: 1.5em;\n line-height: 1.25em;\n margin: 0;\n}\n.h5p-dragquestion .h5p-static \u003e p {\n margin: 0;\n padding: 0;\n font-size: 1em;\n line-height: 1.25em;\n}\n\n.h5p-dragquestion .h5p-draggable {\n border-radius: 0.25em;\n border: 0.1em solid #c6c6c6;\n cursor: pointer;\n position: absolute;\n text-align: center;\n padding: 0.3em 0.3em;\n line-height: 1.25em;\n\n -webkit-box-shadow: 0 0 0.2em rgba(0,0,0,0.2);\n -moz-box-shadow: 0 0 0.2em rgba(0,0,0,0.2);\n box-shadow: 0 0 0.2em rgba(0,0,0,0.2);\n\n background: rgb(221,221,221);\n\n z-index: 3;\n -webkit-user-select: none;\n -moz-user-select: none;\n -ms-user-select: none;\n\n display: flex;\n flex-direction: column;\n justify-content: center;\n}\n.h5p-dragquestion .h5p-draggable:not(.ui-state-disabled).h5p-draggable-hover {\n border: 0.1em solid rgb(212, 190, 216);\n background: #edd6e9;\n }\n.h5p-dragquestion .h5p-draggable.h5p-dropped {\n color: #1a4473;\n border: 0.1em solid #a9c3d0;\n background: #cee0f4;\n}\n.h5p-dragquestion .h5p-draggable \u003e img {\n pointer-events: none;\n}\n.h5p-dragquestion .h5p-draggable \u003e ul {\n text-align: left;\n margin: 0.5em 0.5em 0.5em 2.25em;\n padding: 0;\n}\n.h5p-dragquestion .h5p-draggable \u003e ul \u003e li {\n background: transparent;\n list-style: disc outside none;\n padding: 0;\n margin: 0;\n}\n.h5p-dragquestion .h5p-draggable.ui-draggable-dragging {\n opacity: 0.5;\n box-shadow: 0 0 0.3em rgba(0,0,0,0.2);\n}\n.h5p-dragquestion .h5p-draggable.ui-state-disabled {\n opacity: 1;\n cursor: default;\n -webkit-box-shadow: none;\n -moz-box-shadow: none;\n box-shadow: none;\n}\n.h5p-dragquestion .h5p-draggable p {\n margin: 0;\n padding: 0;\n}\n.h5p-dragquestion .h5p-draggable span {\n line-height: 1em;\n}\n\n.h5p-dragquestion .h5p-dropped.h5p-correct, .h5p-dragquestion .h5p-dropzone.h5p-correct-answer {\n color: #255c41;\n border: 0.1em solid #9dd8bb;\n box-shadow: none;\n background: #9dd8bb;\n}\n\n.h5p-dragquestion .h5p-dropped.h5p-wrong {\n border: 0.1em solid #f7d0d0;\n color: #b71c1c;\n background: #f7d0d0;\n}\n.h5p-dragquestion .h5p-dropped.h5p-wrong, .h5p-dragquestion .h5p-dropped.h5p-correct {\n text-align: left;\n}\n\n.h5p-dragquestion .h5p-draggable.h5p-correct:after,\n.h5p-dragquestion .h5p-draggable.h5p-wrong:after {\n font-family: \u0027H5PFontAwesome4\u0027;\n font-size: 0.75em;\n font-weight: normal;\n position: absolute;\n right: 0.1em;\n bottom: 0;\n background: inherit;\n -webkit-border-radius: 0.25em;\n -moz-border-radius: 0.25em;\n border-radius: 0.25em;\n line-height: 1;\n padding: 0.15em 0 0 0.2em;\n}\n\n.h5p-dragquestion .h5p-draggable.h5p-correct.h5p-advanced-text:after, .h5p-dragquestion .h5p-draggable.h5p-wrong.h5p-advanced-text:after {\n background: none;\n}\n.h5p-dragquestion .h5p-dropped.h5p-correct:after {\n content: \"\\f00c\";\n}\n\n.h5p-dragquestion .h5p-dropped.h5p-wrong:after {\n content: \"\\f00d\";\n}\n\n.h5p-dragquestion .h5p-dropzone {\n z-index: 2;\n position: absolute;\n}\n\n.h5p-dragquestion .h5p-dropzone \u003e .h5p-inner {\n height: 100%;\n position: relative;\n box-sizing: border-box;\n -moz-box-sizing: border-box;\n background: rgb(245, 245, 245);\n}\n\n.h5p-dragquestion .h5p-dropzone.h5p-has-label \u003e .h5p-inner {\n border-radius: 0 0em 0.25em 0.25em;\n}\n\n.h5p-dragquestion .h5p-dq-highlight-dz .h5p-dropzone \u003e .h5p-inner.h5p-active,\n.h5p-dragquestion .h5p-dq-highlight-dz-always .h5p-dropzone \u003e .h5p-inner {\n padding: 0;\n border: 2px dashed #666;\n}\n\n.h5p-dragquestion .h5p-dropzone \u003e .h5p-inner.h5p-over {\n background: #edd6e9;\n}\n\n.h5p-dragquestion .h5p-label {\n line-height: 1.25em;\n padding-left: 0.5em;\n right: 0;\n left: 0;\n bottom: 100%;\n white-space: nowrap;\n border-radius: 0.25em 0.25em 0 0;\n position: absolute;\n\n background: #ddd;\n}\n\n.h5p-dragquestion .h5p-dropzone-answer {\n position: absolute;\n top: 100%;\n margin-top: 0.125em;\n right: 0;\n padding: 0.25em 0.625em;\n font-size: 0.625em;\n line-height: 100%;\n\n border-radius: 0.25em;\n}\n\n.h5p-dragquestion .h5p-dropzone .joubel-tip-container {\n position: absolute;\n right: 0.5em;\n bottom: 0;\n font-size: 0.8em;\n}\n\n/* Make sure dragquestion has margins in fullscreen */\n.h5p-dragquestion.h5p-fullscreen \u003e .h5p-question-buttons,\n.h5p-dragquestion.h5p-fullscreen \u003e .h5p-question-feedback,\n.h5p-dragquestion.h5p-fullscreen \u003e .h5p-question-introduction {\n margin-left: 1em;\n margin-right: 1em;\n}\n\n/* Full screen button styling */\n.h5p-dragquestion .h5p-my-fullscreen-button-enter,\n.h5p-dragquestion .h5p-my-fullscreen-button-exit {\n cursor: pointer;\n font-size: 1.5em;\n color: #1a73d9;\n position: absolute;\n right: 10px;\n top: 10px;\n z-index: 1;\n}\n\n.h5p-dragquestion .h5p-my-fullscreen-button-enter {\n line-height: 1.5em;\n width: 1.5em;\n height: 1.5em;\n text-indent: 0.4em;\n}\n\n.h5p-dragquestion .h5p-my-fullscreen-button-exit {\n line-height: 2em;\n width: 2.2em;\n height: 2.2em;\n text-indent: 0.25em;\n}\n\n.h5p-dragquestion .h5p-my-fullscreen-button-enter:before {\n font-family: \u0027H5PFontAwesome4\u0027;\n content: \"\\f065\";\n}\n\n.h5p-dragquestion .h5p-my-fullscreen-button-exit:before {\n font-family: \u0027H5PFontAwesome4\u0027;\n content: \"\\f066\";\n font-size: 2em;\n}\n.h5p-dragquestion .h5p-dq-no-dz {\n position: absolute;\n}\n\n.h5p-dragquestion .h5p-dragquestion-introduction {\n outline: none;\n}\n\n.h5p-dragquestion .h5p-question-plus-one,\n.h5p-dragquestion .h5p-question-minus-one {\n width: 1.25em;\n height: calc(1.25em * 0.638297872);\n top: -0.15em;\n right: -0.15em;\n}\n","styles/mark-the-words.css":"/* The main containers for the module, specific to this module. */\n.h5p-mark-the-words {\n position: relative;\n background: rgba(255, 255, 255, 0.9);\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr=#e6FFFFFF,endColorstr=#e6FFFFFF);\n overflow: hidden;\n}\n\n.h5p-mark-the-words-descriptions {\n display: none;\n}\n\n/* Actual text paragraphs */\n.h5p-mark-the-words .h5p-word-inner p {\n font-size: 1em;\n font-weight: normal;\n padding: 0;\n margin: 0 0 1em;\n line-height: inherit;\n}\n\n.h5p-mark-the-words button.h5p-button:before {\n font-family: \u0027H5PFontAwesome4\u0027;\n content: \"\\f06e\";\n padding-right: 0.5em;\n}\n/* Selectable words container */\n.h5p-mark-the-words .h5p-word-selectable-words {\n line-height: 1.75em;\n outline: none;\n}\n/* Selectable words*/\n.h5p-mark-the-words [role=\"option\"] {\n white-space: nowrap;\n padding: 0.15em;\n border-radius: 0.25em;\n cursor: pointer;\n position: relative;\n}\n\n.h5p-mark-the-words .h5p-word-selectable-words:not(.h5p-disable-hover) [role=\"option\"]:hover {\n box-shadow: inset 0px 0px 0px 2px #cee0f4;\n}\n\n/* Colors and styling for word selections */\n.h5p-mark-the-words [aria-selected=\"true\"] {\n background: #cee0f4;\n}\n/* Missed word*/\n.h5p-mark-the-words [aria-describedby=\"h5p-description-missed\"] {\n border: 0.1em #77b395 dotted;\n background-color: #E4F4EC;\n}\n\n/* Correctly answered marking */\n.h5p-mark-the-words [aria-describedby=\"h5p-description-correct\"] {\n background: #9dd8bb;\n color: #255c41;\n display: inline-block;\n line-height: 1;\n}\n/* Wrongly answered marking */\n.h5p-mark-the-words [aria-describedby=\"h5p-description-incorrect\"] {\n background-color: #f7d0d0;\n color: #b71c1c;\n text-decoration: line-through;\n display: inline-block;\n line-height: 1;\n}\n/* Feedback icons */\n.h5p-mark-the-words [aria-describedby=\"h5p-description-correct\"]:after {\n position: relative;\n right: 0.1em;\n text-decoration: none;\n content: \"\\f00c\";\n font-family: \u0027H5PFontAwesome4\u0027;\n color: #255c41;\n padding-left: 0.75em;\n}\n.h5p-mark-the-words [aria-describedby=\"h5p-description-incorrect\"]:after {\n position: relative;\n right: 0.1em;\n display: inline-block;\n font-family: \u0027H5PFontAwesome4\u0027;\n text-decoration: none;\n content: \"\\f00d\";\n color: #b71c1c;\n padding-left: 0.75em;\n}\n/* SPECIFIC CSS CLASSES FOR MARK THE WORDS MODULE: */\n/* Start state for button: */\n.h5p-mark-the-words button.h5p-button.h5p-check-button:before {\n content: \"\\f058\";\n}\n.h5p-mark-the-words button.h5p-button.h5p-retry-button:before {\n content: \"\\f021\";\n}\n.h5p-mark-the-words button.h5p-button.h5p-check-button {\n display: inline-block;\n}\nbutton.h5p-retry-button.h5p-retry-button {\n display: none;\n}\n","dist/h5p-drag-text.css":".h5p-drag-text{position:relative;background:hsla(0,0%,100%,.9);overflow:hidden}.h5p-drag-text .hidden{display:none}.h5p-drag-text .h5p-drag-inner p{font-size:1em;font-weight:400;padding:0;margin:0 0 1em}.h5p-drag-text button.h5p-drag-button:before{font-family:H5PFontAwesome4;padding-right:.5em}.h5p-drag-text .h5p-drag-check-button:before{content:\"\\F058\"}.h5p-drag-text .h5p-drag-retry-button:before{content:\"\\F021\"}.h5p-drag-text .h5p-drag-show-solution-button:before{content:\"\\F06E\"}.h5p-drag-text .h5p-drag-check-button{display:inline-block}.h5p-drag-text .h5p-drag-retry-button,.h5p-drag-text .h5p-drag-show-solution-button{display:none}.h5p-drag-text .joubel-tip-container{top:-1.1em;right:-.6em;position:absolute;z-index:4;font-size:.9em}.h5p-drag-text .h5p-drag-correct-feedback:before{position:absolute;right:.5em;font-family:H5PFontAwesome4;content:\"\\F00C\";color:#255c41}.h5p-drag-text .h5p-drag-wrong-feedback:before{position:absolute;right:.5em;font-family:H5PFontAwesome4;content:\"\\F00D\";color:#b71c1c}.h5p-drag-text .h5p-drag-dropzone-container{position:relative;display:inline;padding-right:.1em}.h5p-drag-text [aria-dropeffect]{position:relative;top:-.1em;width:10em;height:1.25em;background-color:#cee0f4;border-radius:.25em;display:inline-block;vertical-align:middle;text-align:center;padding:.1em 1.65em .1em 0}.h5p-drag-text [aria-dropeffect].h5p-drag-correct-feedback{background:#9dd8bb}.h5p-drag-text [aria-dropeffect].h5p-drag-wrong-feedback{background:#f7d0d0}.h5p-drag-text [aria-dropeffect]:before{line-height:1.25}.h5p-drag-text .h5p-drag-draggables-container{position:relative;padding-top:.5em;display:inline-block}.h5p-drag-text .h5p-drag-draggables-container.hide{display:none}.h5p-drag-text [aria-grabbed]{line-height:1.25;cursor:pointer;border-radius:.25em;padding:.1em .6em;margin:.3em;vertical-align:top;text-align:center;display:inline-block;border:.1em solid #c6c6c6;overflow:hidden;background:#ddd;box-shadow:0 0 .3em rgba(0,0,0,.2);z-index:3;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none}.h5p-drag-text [aria-grabbed=true],.h5p-drag-text [aria-grabbed].h5p-drag-dropped:not(.ui-state-disabled):hover,.h5p-drag-text [aria-grabbed]:not(.ui-state-disabled):hover{border:.1em solid #d4bed8;color:#636;background:#edd6e9}.h5p-drag-text [aria-grabbed].h5p-drag-dropped{width:100%;margin:-.1em 0 0;padding:.1em .825em;white-space:nowrap;color:#1a4473;border:.1em solid #a9c3d0;background:#cee0f4}.h5p-drag-text [aria-grabbed=true]{opacity:.5;box-shadow:0 0 .8em rgba(0,0,0,.5)}.h5p-drag-text [aria-grabbed].ui-state-disabled{opacity:1}.h5p-drag-text .h5p-drag-dropped.h5p-drag-draggable-correct{padding:0;color:#255c41;border:none;box-shadow:none;line-height:1.5;background:none}.h5p-drag-text .h5p-drag-dropped.h5p-drag-draggable-wrong{padding:0;border:none;color:#b71c1c;box-shadow:none;line-height:1.5;background:none}.h5p-drag-text .h5p-drag-show-solution-container{position:relative;color:#255c41;font-weight:700;display:inline;padding-left:.5em}.h5p-drag-text .h5p-drag-droppable-words{line-height:1.75}.h5p-drag-text [aria-grabbed=true]{z-index:2}.h5p-drag-text .h5p-drag-task{width:100%;position:relative;display:inline-block}.h5p-drag-text .h5p-drag-wide-screen{float:right;padding-top:0}.h5p-drag-text .h5p-drag-draggable-wide-screen{display:block}.h5p-drag-text [aria-dropeffect].ui-droppable.ui-droppable-disabled.ui-state-disabled{opacity:1}.h5p-drag-text [aria-grabbed].h5p-drag-dropped.truncate{text-overflow:ellipsis}.h5p-drag-text .correct-answer{width:1px;height:1px;overflow:hidden;display:inline-block;color:transparent}.h5p-drag-text .h5p-question-introduction{outline:none}","styles/shepherd-theme-arrows.css":".shepherd-element, .shepherd-element:after, .shepherd-element:before, .shepherd-element *, .shepherd-element *:after, .shepherd-element *:before {\r\n box-sizing: border-box; }\r\n\r\n.shepherd-element {\r\n position: absolute;\r\n display: none; }\r\n .shepherd-element.shepherd-open {\r\n display: block; }\r\n\r\n.shepherd-element.shepherd-theme-arrows {\r\n max-width: 100%;\r\n max-height: 100%; }\r\n .shepherd-element.shepherd-theme-arrows .shepherd-content {\r\n border-radius: 5px;\r\n position: relative;\r\n font-family: inherit;\r\n background: #fff;\r\n color: #444;\r\n padding: 1em;\r\n font-size: 1.1em;\r\n line-height: 1.5em;\r\n -webkit-transform: translateZ(0);\r\n transform: translateZ(0);\r\n -webkit-filter: drop-shadow(0 1px 4px rgba(0, 0, 0, 0.2));\r\n filter: drop-shadow(0 1px 4px rgba(0, 0, 0, 0.2)); }\r\n .shepherd-element.shepherd-theme-arrows .shepherd-content:before {\r\n content: \"\";\r\n display: block;\r\n position: absolute;\r\n width: 0;\r\n height: 0;\r\n border-color: transparent;\r\n border-width: 16px;\r\n border-style: solid;\r\n pointer-events: none; }\r\n .shepherd-element.shepherd-theme-arrows.shepherd-element-attached-bottom.shepherd-element-attached-center .shepherd-content {\r\n margin-bottom: 16px; }\r\n .shepherd-element.shepherd-theme-arrows.shepherd-element-attached-bottom.shepherd-element-attached-center .shepherd-content:before {\r\n top: 100%;\r\n left: 50%;\r\n margin-left: -16px;\r\n border-top-color: #fff; }\r\n .shepherd-element.shepherd-theme-arrows.shepherd-element-attached-top.shepherd-element-attached-center .shepherd-content {\r\n margin-top: 16px; }\r\n .shepherd-element.shepherd-theme-arrows.shepherd-element-attached-top.shepherd-element-attached-center .shepherd-content:before {\r\n bottom: 100%;\r\n left: 50%;\r\n margin-left: -16px;\r\n border-bottom-color: #fff; }\r\n .shepherd-element.shepherd-theme-arrows.shepherd-element-attached-right.shepherd-element-attached-middle .shepherd-content {\r\n margin-right: 16px; }\r\n .shepherd-element.shepherd-theme-arrows.shepherd-element-attached-right.shepherd-element-attached-middle .shepherd-content:before {\r\n left: 100%;\r\n top: 50%;\r\n margin-top: -16px;\r\n border-left-color: #fff; }\r\n .shepherd-element.shepherd-theme-arrows.shepherd-element-attached-left.shepherd-element-attached-middle .shepherd-content {\r\n margin-left: 16px; }\r\n .shepherd-element.shepherd-theme-arrows.shepherd-element-attached-left.shepherd-element-attached-middle .shepherd-content:before {\r\n right: 100%;\r\n top: 50%;\r\n margin-top: -16px;\r\n border-right-color: #fff; }\r\n .shepherd-element.shepherd-theme-arrows.shepherd-element-attached-top.shepherd-element-attached-left.shepherd-target-attached-bottom .shepherd-content {\r\n margin-top: 16px; }\r\n .shepherd-element.shepherd-theme-arrows.shepherd-element-attached-top.shepherd-element-attached-left.shepherd-target-attached-bottom .shepherd-content:before {\r\n bottom: 100%;\r\n left: 16px;\r\n border-bottom-color: #fff; }\r\n .shepherd-element.shepherd-theme-arrows.shepherd-element-attached-top.shepherd-element-attached-right.shepherd-target-attached-bottom .shepherd-content {\r\n margin-top: 16px; }\r\n .shepherd-element.shepherd-theme-arrows.shepherd-element-attached-top.shepherd-element-attached-right.shepherd-target-attached-bottom .shepherd-content:before {\r\n bottom: 100%;\r\n right: 16px;\r\n border-bottom-color: #fff; }\r\n .shepherd-element.shepherd-theme-arrows.shepherd-element-attached-bottom.shepherd-element-attached-left.shepherd-target-attached-top .shepherd-content {\r\n margin-bottom: 16px; }\r\n .shepherd-element.shepherd-theme-arrows.shepherd-element-attached-bottom.shepherd-element-attached-left.shepherd-target-attached-top .shepherd-content:before {\r\n top: 100%;\r\n left: 16px;\r\n border-top-color: #fff; }\r\n .shepherd-element.shepherd-theme-arrows.shepherd-element-attached-bottom.shepherd-element-attached-right.shepherd-target-attached-top .shepherd-content {\r\n margin-bottom: 16px; }\r\n .shepherd-element.shepherd-theme-arrows.shepherd-element-attached-bottom.shepherd-element-attached-right.shepherd-target-attached-top .shepherd-content:before {\r\n top: 100%;\r\n right: 16px;\r\n border-top-color: #fff; }\r\n .shepherd-element.shepherd-theme-arrows.shepherd-element-attached-top.shepherd-element-attached-right.shepherd-target-attached-left .shepherd-content {\r\n margin-right: 16px; }\r\n .shepherd-element.shepherd-theme-arrows.shepherd-element-attached-top.shepherd-element-attached-right.shepherd-target-attached-left .shepherd-content:before {\r\n top: 16px;\r\n left: 100%;\r\n border-left-color: #fff; }\r\n .shepherd-element.shepherd-theme-arrows.shepherd-element-attached-top.shepherd-element-attached-left.shepherd-target-attached-right .shepherd-content {\r\n margin-left: 16px; }\r\n .shepherd-element.shepherd-theme-arrows.shepherd-element-attached-top.shepherd-element-attached-left.shepherd-target-attached-right .shepherd-content:before {\r\n top: 16px;\r\n right: 100%;\r\n border-right-color: #fff; }\r\n .shepherd-element.shepherd-theme-arrows.shepherd-element-attached-bottom.shepherd-element-attached-right.shepherd-target-attached-left .shepherd-content {\r\n margin-right: 16px; }\r\n .shepherd-element.shepherd-theme-arrows.shepherd-element-attached-bottom.shepherd-element-attached-right.shepherd-target-attached-left .shepherd-content:before {\r\n bottom: 16px;\r\n left: 100%;\r\n border-left-color: #fff; }\r\n .shepherd-element.shepherd-theme-arrows.shepherd-element-attached-bottom.shepherd-element-attached-left.shepherd-target-attached-right .shepherd-content {\r\n margin-left: 16px; }\r\n .shepherd-element.shepherd-theme-arrows.shepherd-element-attached-bottom.shepherd-element-attached-left.shepherd-target-attached-right .shepherd-content:before {\r\n bottom: 16px;\r\n right: 100%;\r\n border-right-color: #fff; }\r\n\r\n.shepherd-element.shepherd-theme-arrows.shepherd-element-attached-top.shepherd-element-attached-center.shepherd-has-title .shepherd-content:before, .shepherd-element.shepherd-theme-arrows.shepherd-element-attached-top.shepherd-element-attached-right.shepherd-target-attached-bottom.shepherd-has-title .shepherd-content:before, .shepherd-element.shepherd-theme-arrows.shepherd-element-attached-top.shepherd-element-attached-left.shepherd-target-attached-bottom.shepherd-has-title .shepherd-content:before {\r\n border-bottom-color: #eee; }\r\n\r\n.shepherd-element.shepherd-theme-arrows.shepherd-has-title .shepherd-content header {\r\n background: #eee;\r\n padding: 1em; }\r\n .shepherd-element.shepherd-theme-arrows.shepherd-has-title .shepherd-content header a.shepherd-cancel-link {\r\n padding: 0;\r\n margin-bottom: 0; }\r\n\r\n.shepherd-element.shepherd-theme-arrows.shepherd-has-cancel-link .shepherd-content header h3 {\r\n float: left; }\r\n\r\n.shepherd-element.shepherd-theme-arrows .shepherd-content {\r\n padding: 0; }\r\n .shepherd-element.shepherd-theme-arrows .shepherd-content * {\r\n font-size: inherit; }\r\n .shepherd-element.shepherd-theme-arrows .shepherd-content header {\r\n *zoom: 1;\r\n border-radius: 5px 5px 0 0; }\r\n .shepherd-element.shepherd-theme-arrows .shepherd-content header:after {\r\n content: \"\";\r\n display: table;\r\n clear: both; }\r\n .shepherd-element.shepherd-theme-arrows .shepherd-content header h3 {\r\n margin: 0;\r\n line-height: 1;\r\n font-weight: normal; }\r\n .shepherd-element.shepherd-theme-arrows .shepherd-content header a.shepherd-cancel-link {\r\n float: right;\r\n text-decoration: none;\r\n font-size: 1.25em;\r\n line-height: .8em;\r\n font-weight: normal;\r\n color: rgba(0, 0, 0, 0.5);\r\n opacity: 0.8;\r\n position: relative;\r\n top: .1em;\r\n padding: .8em;\r\n margin-bottom: -.8em; }\r\n .shepherd-element.shepherd-theme-arrows .shepherd-content header a.shepherd-cancel-link:hover {\r\n opacity: 1; }\r\n .shepherd-element.shepherd-theme-arrows .shepherd-content .shepherd-text {\r\n padding: 1em; }\r\n .shepherd-element.shepherd-theme-arrows .shepherd-content .shepherd-text p {\r\n margin: 0 0 0.5em 0;\r\n line-height: 1.3em; }\r\n .shepherd-element.shepherd-theme-arrows .shepherd-content .shepherd-text p:last-child {\r\n margin-bottom: 0; }\r\n .shepherd-element.shepherd-theme-arrows .shepherd-content footer {\r\n padding: 0 1em 1em; }\r\n .shepherd-element.shepherd-theme-arrows .shepherd-content footer .shepherd-buttons {\r\n text-align: right;\r\n list-style: none;\r\n padding: 0;\r\n margin: 0; }\r\n .shepherd-element.shepherd-theme-arrows .shepherd-content footer .shepherd-buttons li {\r\n display: inline;\r\n padding: 0;\r\n margin: 0; }\r\n .shepherd-element.shepherd-theme-arrows .shepherd-content footer .shepherd-buttons li .shepherd-button {\r\n display: inline-block;\r\n vertical-align: middle;\r\n *vertical-align: auto;\r\n *zoom: 1;\r\n *display: inline;\r\n border-radius: 3px;\r\n cursor: pointer;\r\n border: 0;\r\n margin: 0 0.5em 0 0;\r\n font-family: inherit;\r\n text-transform: uppercase;\r\n letter-spacing: .1em;\r\n font-size: .8em;\r\n line-height: 1em;\r\n padding: 0.75em 2em;\r\n background: #186ac2;\r\n color: #fff; }\r\n .shepherd-element.shepherd-theme-arrows .shepherd-content footer .shepherd-buttons li .shepherd-button.shepherd-button-secondary {\r\n background: #f3f3f3;\r\n color: #666; }\r\n .shepherd-element.shepherd-theme-arrows .shepherd-content footer .shepherd-buttons li:last-child .shepherd-button {\r\n margin-right: 0; }\r\n","styles/h5p-guided-tour.css":"/* Overriding max-width */\n.h5p.shepherd-element.shepherd-theme-arrows {\n max-width: 400px;\n font-size: 15px;\n z-index: 1;\n}\n\n/* Override main button background color */\n.shepherd-element.shepherd-theme-default .shepherd-content footer .shepherd-buttons li .shepherd-button-primary {\n background: #1a73d9;\n}\n\n.shepherd-element .shepherd-content footer .shepherd-buttons li .shepherd-button-primary:hover {\n background: #155ba7 !important;\n}\n.shepherd-element .shepherd-content footer .shepherd-buttons li .shepherd-button-secondary:hover {\n background: #eee !important;\n}\n\n/* Override header */\n.h5p.shepherd-element.shepherd-theme-arrows.shepherd-has-title .shepherd-content header {\n background: #eee;\n color: #333;\n}\n\n/* No arrow please */\n.shepherd-element.shepherd-theme-arrows.h5p-guided-tour-step-no-arrow .shepherd-content:before,\n.shepherd-element.shepherd-theme-arrows.h5p-guided-tour-step-no-arrow .shepherd-content:after {\n display: none;\n}\n\n/* More contrast, please */\n.h5p.shepherd-element.shepherd-theme-arrows .shepherd-content {\n border: 1px solid #ccc;\n -webkit-filter: drop-shadow(0 0 4px rgba(0, 0, 0, 0.4));\n filter: drop-shadow(0 0 4px rgba(0, 0, 0, 0.4));\n}\n\n/* A little less paddings */\n.h5p.shepherd-element.shepherd-theme-arrows .shepherd-content .shepherd-text {\n padding: .5em 1em;\n}\n\n.shepherd-element.shepherd-theme-arrows.shepherd-element-attached-left.shepherd-element-attached-middle .shepherd-content:before {\n border-right-color: #ccc;\n}\n.shepherd-element.shepherd-theme-arrows.shepherd-element-attached-top.shepherd-element-attached-center.shepherd-has-title .shepherd-content:before,\n.shepherd-element.shepherd-theme-arrows.shepherd-element-attached-top.shepherd-element-attached-right.shepherd-target-attached-bottom.shepherd-has-title .shepherd-content:before,\n.shepherd-element.shepherd-theme-arrows.shepherd-element-attached-top.shepherd-element-attached-left.shepherd-target-attached-bottom.shepherd-has-title .shepherd-content:before,\n.shepherd-element.shepherd-theme-arrows.shepherd-element-attached-top.shepherd-element-attached-center .shepherd-content:before {\n border-bottom-color: #ccc;\n}\n.shepherd-element.shepherd-theme-arrows .shepherd-content:after {\n content: \"\";\n display: block;\n position: absolute;\n width: 0;\n height: 0;\n border-color: transparent;\n border-width: 16px;\n border-style: solid;\n pointer-events: none;\n}\n.shepherd-element.shepherd-theme-arrows.shepherd-element-attached-left.shepherd-element-attached-middle .shepherd-content:after {\n right: 100%;\n top: 50%;\n margin-top: -16px;\n border-right-color: #fff;\n transform: translateX(1px);\n}\n.shepherd-element.shepherd-theme-arrows.shepherd-element-attached-top.shepherd-element-attached-center .shepherd-content:after {\n bottom: 100%;\n left: 50%;\n margin-left: -16px;\n border-bottom-color: #eee;\n transform: translateY(1px);\n}\n","styles/go-to-question.css":".h5p-content div.h5p-gotoquestion,\n.h5peditor div.h5p-gotoquestion {\n height: 100%;\n}\n.h5p-gotoquestion-wrapper {\n height: 100%;\n background: #f5f5f5;\n}\n.h5p-gotoquestion-wrapper.h5p-gotoquestion-continuestate {\n background: #fff;\n}\n.h5p-gotoquestion-text {\n background: #018d82;\n color: #fff;\n text-align: center;\n padding: 0.5em;\n}\n.h5p-gotoquestion-choices,\n.h5p-gotoquestion-choice {\n list-style: none;\n padding: 0;\n margin: 0;\n}\n.h5p-gotoquestion-choices {\n overflow: hidden;\n background: #f5f5f5;\n}\n.h5p-gotoquestion-choice {\n margin: 0.25em;\n text-align: center;\n}\n.h5p-gotoquestion-button {\n background: #fff;\n border-radius: 0.5em;\n border: 0.125em transparent solid;\n border-bottom-color: #d9d9d9;\n padding: 0.5em;\n cursor: pointer;\n outline: none;\n overflow: hidden;\n position: relative;\n transition: top 0.25s ease-in-out;\n}\n.h5p-gotoquestion-button:after {\n position: absolute;\n content: \" \";\n width: 100%;\n height: 100%;\n box-sizing: border-box;\n border: 0.125em transparent solid;\n left: 0;\n bottom: 0;\n}\n.h5p-gotoquestion-button[aria-disabled=false]:hover,\n.h5p-gotoquestion-button[aria-disabled=false]:focus {\n color: #018d82;\n}\n.h5p-gotoquestion-button[aria-disabled=false]:hover:after,\n.h5p-gotoquestion-button[aria-disabled=false]:focus:after {\n border-bottom-color: #018d82;\n}\n.h5p-gotoquestion-button[aria-disabled=false]:active,\n.h5p-gotoquestion-chosen,\n.h5p-gotoquestion-chosen:hover,\n.h5p-gotoquestion-chosen:focus {\n background: #018d82;\n color: #fff;\n border-bottom-color: transparent;\n}\n.h5p-gotoquestion-button[aria-disabled=true] {\n cursor: default;\n}\n.h5p-gotoquestion-chosen {\n position: absolute;\n width: 100%;\n left: 0;\n box-sizing: border-box;\n border-radius: 0;\n border: 0;\n}\n.h5p-gotoquestion-chosentext {\n background: #018d82;\n color: #fff;\n text-align: center;\n padding: 0 0 0.5em;\n}\n.h5p-gotoquestion-continuemsg {\n color: #007adf;\n text-align: center;\n padding: 0.5em;\n}\n.h5p-gotoquestion .h5p-gotoquestion-continue {\n margin: 0 auto 0.5em;\n display: block;\n}\n.h5p-gotoquestion-continue:before {\n content: \"\\f04b\";\n}\n","styles/iv-hotspot.css":".h5p-ivhotspot {\n overflow: hidden;\n cursor: pointer;\n box-sizing: border-box;\n width: 100%;\n height: 100%;\n}\n.h5p-ivhotspot \u003e a {\n position: absolute;\n left: 0;\n top: 0;\n z-index: 1;\n display: table;\n width: 100%;\n height: 100%;\n}\n.h5p-ivhotspot \u003e a {\n text-decoration: none;\n}\n.h5p-ivhotspot \u003e a \u003e p {\n display: table-cell;\n text-align: center;\n vertical-align: middle;\n}\n.h5p-ivhotspot \u003e a:focus {\n outline: 2px solid #179fff;\n outline-offset: 8px;\n}\n\n.h5p-ivhotspot.circular,\n.h5p-ivhotspot.circular \u003e a,\n.h5p-ivhotspot.circular .blinking-hotspot {\n border-radius: 50%;\n}\n.h5p-ivhotspot.rounded-rectangle,\n.h5p-ivhotspot.rounded-rectangle \u003e a,\n.h5p-ivhotspot.rounded-rectangle .blinking-hotspot {\n border-radius: 1em;\n}\n.h5p-ivhotspot-invisible {\n color: transparent;\n}\n.blinking-hotspot {\n position: absolute;\n left: -1px;\n top: -1px;\n width: 100%;\n height: 100%;\n border: solid 1px #ffffff;\n -webkit-animation: pulsing 1.5s ease-out;\n animation: pulsing 1.5s ease-out;\n -webkit-animation-iteration-count: infinite;\n animation-iteration-count: infinite;\n opacity: 0.1;\n -webkit-box-shadow: 0px 0px 0px 2px rgba(0, 0, 0, 0.4);\n -moz-box-shadow: 0px 0px 0px 2px rgba(0, 0, 0, 0.4);\n box-shadow: 0px 0px 0px 2px rgba(0, 0, 0, 0.4);\n}\n@-webkit-keyframes pulsing {\n 0% {\n -webkit-transform: scale(1, 1);\n opacity: 0.1;\n }\n 10%{\n opacity: 0.7;\n }\n 100% {\n -webkit-transform: scale(1.03, 1.03);\n opacity: 0.1;\n }\n}\n@keyframes pulsing {\n 0% {\n transform: scale(1, 1);\n opacity: 0.1;\n }\n 10%{\n opacity: 0.7;\n }\n 100% {\n transform: scale(1.03, 1.03);\n opacity: 0.1;\n }\n}\n","dist/styles.css":".h5p-open-ended-question-question{position:relative;background:#2880d0;font-size:1.2em;padding:.75em;color:#fff}.h5p-open-ended-question-content{position:relative;margin:0;padding:1em;background-color:#fff}.h5p-open-ended-question-question:before{width:.75em;height:.75em;content:\" \";position:absolute;bottom:-.4em;left:1em;background:#fff;-webkit-transform:rotate(45deg);transform:rotate(45deg)}.h5p-open-ended-question-input{padding:.5em;width:calc(100% - 1em);max-width:500px;box-sizing:border-box;font-family:inherit;font-size:inherit}","dist/styles.css":".h5p-simple-multiple-choice-question{background:#2880d0;font-size:1.2em;padding:.75em;color:#fff}.h5p-simple-multiple-choice-question:before{width:.75em;height:.75em;content:\" \";position:absolute;bottom:-.4em;left:1em;background:#fff;-webkit-transform:rotate(45deg);transform:rotate(45deg)}.h5p-simple-multiple-choice-alternatives,.h5p-simple-multiple-choice-alternatives-error{list-style-type:none;margin:0;padding:1em;position:relative;background-color:#fff}.h5p-simple-multiple-choice-alternatives-error{color:darkred}.h5p-simple-multiple-choice-alternatives label{cursor:pointer;position:relative;display:block}.h5p-simple-multiple-choice-alternative-li{margin:.25em 0}.h5p-simple-multiple-choice-alternative-input{vertical-align:middle;margin:0 3px 2px 5px}.h5p-simple-multiple-choice-alternative-feedback{position:relative;font-size:1em;padding:.7em 2.2em;margin-top:.5em;margin-left:-.4em;margin-right:-.4em}.h5p-simple-multiple-choice-alternative-feedback:before{content:\"\";position:absolute;left:.9em;top:-.25em;width:.5em;height:.5em;-webkit-transform:rotate(45deg);transform:rotate(45deg)}.h5p-simple-multiple-choice-alternative-feedback.chosen{border:1px solid #85b9e6;background:#e3f2ff}.h5p-simple-multiple-choice-alternative-feedback.chosen:before{background:#e3f2ff;border-top:1px solid #85b9e6;border-left:1px solid #85b9e6}.h5p-simple-multiple-choice-alternative-feedback.not-chosen{border:1px solid #f2b8d4;background:#faebf2}.h5p-simple-multiple-choice-alternative-feedback.not-chosen:before{background:#faebf2;border-top:1px solid #f2b8d4;border-left:1px solid #f2b8d4}","dist/styles.css":".h5p-questionnaire-element .h5p-subcontent-question{position:relative;padding:1.5em 5em 1.5em 1em;word-wrap:break-word}.h5p-questionnaire-element.h5p-questionnaire-required .h5p-subcontent-question{padding:.5em 5em 1em 1em}.h5p-questionnaire-required-symbol{background:#2880d0;padding-bottom:.5em;color:hsla(0,0%,100%,.6);font-size:.75em}.h5p-questionnaire-element .h5p-subcontent-body{font-size:.9em}.h5p-questionnaire{font-family:Open Sans,Calibri,Candara,Arial,sans-serif;position:relative;display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-orient:vertical;-webkit-box-direction:normal;-ms-flex-direction:column;flex-direction:column;height:100%;width:100%}.h5p-questionnaire-element.hide{display:none}.h5p-questionnaire-content{height:100%;width:100%;-webkit-flex:1;overflow:auto}.h5p-questionnaire-element{height:100%;width:100%}.h5p-invalid-questionnaire{color:red}.h5p-questionnaire .hide{display:none}.h5p-questionnaire-success{color:#fff;background:#2880d0;height:100%;display:-webkit-box;display:-ms-flexbox;display:flex;text-align:center;padding:5em 2em 4em;box-sizing:border-box}.h5p-questionnaire-success:focus{outline:none}.h5p-questionnaire-success-icon.image\u003eimg{width:auto!important;height:auto!important;max-width:500px;max-height:10em;margin:auto}.h5p-questionnaire-success-icon.standard-icon:before{font-family:H5PFontAwesome4;font-size:3em;content:\"\\F00C\"}.h5p-questionnaire-success-message{margin:1.5em 0 1em;font-size:1.485em;word-wrap:break-word}.h5p-questionnaire-success-center{margin:auto}.h5p-questionnaire-submit-screen{padding:5em 2em;text-align:center;color:#fff;background:#2880d0;height:100%;box-sizing:border-box}.h5p-questionnaire-submit-screen-title{font-size:1.485em}.h5p-questionnaire-submit-screen-subtitle{margin:.5em 0 2em;font-size:1em}.h5p-questionnaire-button.submit{background-color:#ff6b00;border-color:#ff6b00}.h5p-questionnaire-button.submit:after{font-family:H5PFontAwesome4;content:\"\\F058\";margin-left:.5em}.h5p-questionnaire-button.submit:hover{background-color:#ff7a1a}.h5p-questionnaire-button.submit:active{background-color:#e66507}.h5p-questionnaire-submit-screen .h5p-questionnaire-button:focus{outline-color:#0d263c}.h5p-questionnaire-submit-screen .h5p-questionnaire-button.previous{background:transparent;color:#fff;border-color:#fff;margin-right:.5em}.h5p-questionnaire-submit-screen .h5p-questionnaire-button.previous:hover{background-color:#3b8ace}.h5p-questionnaire-submit-screen .h5p-questionnaire-button.previous:active{background-color:#1879ce}.h5p-questionnaire-button,.h5peditor .h5p-questionnaire-button{padding:.6em 1em;color:#fff;background:#1f1f1f;border:1px solid #404040;cursor:pointer;text-transform:uppercase;font-weight:600;letter-spacing:2px;border-radius:.3em;font-size:.8em}.h5p-questionnaire-button:active{background-color:#1c1c1c}.h5p-questionnaire-button:hover{background-color:#363636}.h5p-questionnaire-button:focus{outline:1px solid #3b99fc}.h5p-questionnaire-button.disable{display:none}.h5p-questionnaire-button.previous:before{content:\"\\F137\"}.h5p-questionnaire-button.next:after{content:\"\\F138\"}.h5p-questionnaire-button.next:after,.h5p-questionnaire-button.previous:before{font-family:H5PFontAwesome4;margin-left:.5em}.h5p-questionnaire-button.previous:before{margin-left:0;margin-right:.5em}.h5p-questionnaire-choice-required{position:relative;background-color:#eb0000;color:#fff;padding:0 2em 0 1em}.h5p-questionnaire-choice-required.hide{display:none}.h5p-questionnaire-choice-required-message{font-size:.9em;display:inline-block}.h5p-questionnaire-choice-required-exit{display:inline-block;position:absolute;right:1em;top:.35em;border:none;background:none;cursor:pointer}.h5p-questionnaire-choice-required-exit:before{font-family:H5PFontAwesome4;content:\"\\F00D\";color:#fff;font-weight:800}.h5p-questionnaire-footer{background:#1f1f1f;padding:.7em 1.2em;display:inline-block;width:100%;box-sizing:border-box;border:1px solid #404040}.h5p-questionnaire-footer .h5p-questionnaire-button.next{float:right}.h5p-questionnaire-footer .h5p-questionnaire-button.previous{float:left}.h5p-questionnaire-progress-bar{background:#153552;height:.3em}.h5p-questionnaire-progress-bar-current{background:#ff6b00;height:100%;transition:width .25s ease-in-out}.h5p-questionnaire-progress-bar-widget{position:absolute;right:1em;top:calc(50% - .1em);-webkit-transform:translateY(-50%);transform:translateY(-50%);width:3.5em;height:3em;line-height:3em;background-color:#fff;text-align:center;border-radius:.2em}.h5p-questionnaire-progress-bar-widget:before{position:absolute;width:60%;height:0;content:\" \";bottom:-.55em;left:50%;-webkit-transform:translateX(-50%);transform:translateX(-50%);border:1px solid rgba(0,0,0,.1)}.h5p-questionnaire-progress-bar-widget-current,.h5p-questionnaire-progress-bar-widget-max,.h5p-questionnaire-progress-bar-widget-separator{display:inline-block;color:#8c8c8c;font-weight:600}.h5p-questionnaire-progress-bar-widget-separator{font-size:.85em;margin:0 .15em .2em .1em;vertical-align:middle}.h5p-questionnaire-progress-bar-widget-current{color:#ff6b00}","styles/image-radio-button-group.css":".h5p-image-radio-button {\n display: inline-block;\n position: relative;\n box-sizing: border-box;\n margin-right: .5em;\n padding: .5em;\n background-color: #fff;\n border: 1px solid #eee;\n height: 4.9em;\n}\n.h5p-image-radio-button:hover {\n border-color: #aaa;\n}\n.h5p-image-radio-button label {\n display: inline-block;\n cursor: pointer;\n}\n.h5p-image-radio-button label span {\n position: relative;\n top: -1.8em;\n font-size: 14px;\n line-height: 1;\n}\n.h5p-image-radio-button input {\n position: relative;\n top: -1.7em;\n cursor: pointer;\n}\n.h5p-image-radio-button .image-container {\n display: inline-block;\n cursor: pointer;\n margin: 0 .5em;\n}\n.h5p-image-radio-button .h5p-option-description {\n display: block;\n font-size: 10px;\n color: #888;\n max-width: 160px;\n line-height: 1.1;\n margin-top: 1em;\n border-top: 1px solid #eee;\n padding-top: .8em;\n}\n","styles/interactive-video-editor.css":"/* H5P specific icons generated by IcoMoon. */\n@font-face {\n font-family: \u0027H5PInteractiveVideoEditor\u0027;\n src: url(\u0027../H5P/libraries/H5PEditor.InteractiveVideo-1.17/fonts/h5p.eot?1\u0027);\n src: url(\u0027../H5P/libraries/H5PEditor.InteractiveVideo-1.17/fonts/h5p.eot#iefix1\u0027) format(\u0027embedded-opentype\u0027),\n url(\u0027../H5P/libraries/H5PEditor.InteractiveVideo-1.17/fonts/h5p.woff?1\u0027) format(\u0027woff\u0027),\n url(\u0027../H5P/libraries/H5PEditor.InteractiveVideo-1.17/fonts/h5p.ttf?1\u0027) format(\u0027truetype\u0027),\n url(\u0027../H5P/libraries/H5PEditor.InteractiveVideo-1.17/fonts/h5p.svg?1#icomoon\u0027) format(\u0027svg\u0027);\n font-weight: normal;\n font-style: normal;\n}\n\n.h5p-interactivevideo-editor .h5p-interactive-video {\n overflow: visible;\n}\n\n.h5p-interactivevideo-editor .h5p-interactive-video .h5p-overlay.h5p-visible {\n overflow: visible;\n}\n\n.h5p-interactive-video-dragnbar {\n font-size: 1em;\n padding: 0;\n background: #f5f5f5;\n float: left;\n width: 100%;\n}\n.h5p-interactive-video-dragnbar .h5p-dragnbar-ul {\n margin: 0 0 0 0.25em;\n list-style: none;\n padding: 0;\n float: left;\n height: 100%;\n}\n.h5p-interactive-video-dragnbar .h5p-dragnbar-li {\n position: relative;\n float: left;\n margin: 0;\n padding: 0;\n margin-right: 0.25em;\n background: none;\n border-left: none;\n border-right: none;\n}\n\n.h5p-interactive-video-dragnbar .h5p-dragnbar-li:hover {\n background: none;\n}\n\n.h5p-interactive-video-dragnbar .h5p-dragnbar-li:before {\n top: 100%;\n font-size: 0.585em;\n}\n\n.h5p-interactive-video-dragnbar .h5p-dragnbar-a {\n width: 1em;\n height: 1.1em;\n line-height: inherit;\n text-align: center;\n border: 1px solid #ccc;\n border-radius: 0.25em;\n margin: 0.25em 0 0.25em 0;\n display: block;\n padding: 0.2em 0.5em;\n color: #333;\n background: #f2f2f2;\n background: -webkit-linear-gradient(top,#fff 0,#f2f2f2 100%);\n background: -moz-linear-gradient(top,#fff 0,#f2f2f2 100%);\n background: -ms-linear-gradient(top,#fff 0,#f2f2f2 100%);\n background: -o-linear-gradient(top,#fff 0,#f2f2f2 100%);\n font-family: \u0027H5PFontAwesome4\u0027;\n}\n.h5p-dialog-title:before {\n content: \" \";\n font-family: \u0027H5PFontAwesome4\u0027;\n color: #313131;\n margin-right: 0.5em;\n vertical-align: bottom;\n}\n.h5p-interactive-video-dragnbar .h5p-dragnbar-a,\n.h5p-interactive-video-dragnbar .h5p-dragnbar-a:visited,\n.h5p-interactive-video-dragnbar .h5p-dragnbar-a:link {\n color: #333;\n}\n.h5p-interactive-video-dragnbar .h5p-dragnbar-a:hover {\n text-decoration: none;\n border-color: #999;\n}\n.h5p-interactive-video-dragnbar .h5p-dragnbar-a:before {\n font-size: 1em;\n}\n.h5p-interactive-video-dragnbar .h5p-dragnbar-nil-button:before,\n.h5p-nil-interaction-icon:before {\n content: \"\\f146\";\n}\n.h5p-interactive-video-dragnbar .h5p-dragnbar-text-button:before,\n.h5p-text-interaction-icon:before {\n content: \"T\";\n}\n.h5p-interactive-video-dragnbar .h5p-dragnbar-table-button:before,\n.h5p-table-interaction-icon:before {\n content: \"\\f0ce\";\n}\n.h5p-interactive-video-dragnbar .h5p-dragnbar-link-button:before,\n.h5p-link-interaction-icon:before {\n content: \"\\f0c1\";\n}\n.h5p-interactive-video-dragnbar .h5p-dragnbar-image-button:before,\n.h5p-image-interaction-icon:before {\n content: \"\\f03e\";\n}\n.h5p-interactive-video-dragnbar .h5p-dragnbar-gotoquestion-button:before,\n.h5p-gotoquestion-interaction-icon:before {\n content: \"\\f277\";\n}\n.h5p-interactive-video-dragnbar .h5p-dragnbar-truefalse-button:before,\n.h5p-truefalse-interaction-icon:before {\n font-family: \u0027H5PFontIcons\u0027;\n content: \"\\e902\";\n line-height: 1em;\n}\n.h5p-interactive-video-dragnbar .h5p-dragnbar-ivhotspot-button:before,\n.h5p-ivhotspot-interaction-icon:before {\n content: \"\\e900\";\n}\n.h5p-interactive-video-dragnbar .h5p-dragnbar-questionnaire-button:before,\n.h5p-questionnaire-interaction-icon:before {\n content: \"\\e901\";\n}\n\n/* H5P specific fonts: */\n.h5p-interactive-video-dragnbar .h5p-dragnbar-dragquestion-button:before,\n.h5p-interactive-video-dragnbar .h5p-dragnbar-multichoice-button:before,\n.h5p-interactive-video-dragnbar .h5p-dragnbar-blanks-button:before,\n.h5p-interactive-video-dragnbar .h5p-dragnbar-summary-button:before,\n.h5p-interactive-video-dragnbar .h5p-dragnbar-markthewords-button:before,\n.h5p-interactive-video-dragnbar .h5p-dragnbar-dragtext-button:before,\n.h5p-interactive-video-dragnbar .h5p-dragnbar-singlechoiceset-button:before,\n.h5p-interactive-video-dragnbar .h5p-dragnbar-questionnaire-button:before,\n.h5p-interactive-video-dragnbar .h5p-dragnbar-ivhotspot-button:before {\n font-family: \u0027H5PInteractiveVideoEditor\u0027;\n font-size: 1.2em;\n vertical-align: top;\n}\n.h5p-singlechoiceset-interaction-icon:before,\n.h5p-dragtext-interaction-icon:before,\n.h5p-markthewords-interaction-icon:before,\n.h5p-dragquestion-interaction-icon:before,\n.h5p-blanks-interaction-icon:before,\n.h5p-multichoice-interaction-icon:before,\n.h5p-summary-interaction-icon:before,\n.h5p-ivhotspot-interaction-icon:before,\n.h5p-questionnaire-interaction-icon:before {\n font-family: \u0027H5PInteractiveVideoEditor\u0027;\n}\n\n.h5p-interactive-video-dragnbar .h5p-dragnbar-summary-button:before,\n.h5p-summary-interaction-icon:before {\n content: \"\\e992\";\n}\n.h5p-interactive-video-dragnbar .h5p-dragnbar-multichoice-button:before,\n.h5p-multichoice-interaction-icon:before {\n content: \"\\e603\";\n}\n.h5p-interactive-video-dragnbar .h5p-dragnbar-blanks-button:before,\n.h5p-blanks-interaction-icon:before {\n content: \"\\e994\";\n}\n.h5p-interactive-video-dragnbar .h5p-dragnbar-dragquestion-button:before,\n.h5p-dragquestion-interaction-icon:before {\n content: \"\\e991\";\n}\n.h5p-interactive-video-dragnbar .h5p-dragnbar-markthewords-button:before,\n.h5p-markthewords-interaction-icon:before {\n content: \"\\e601\";\n}\n.h5p-interactive-video-dragnbar .h5p-dragnbar-dragtext-button:before,\n.h5p-dragtext-interaction-icon:before {\n content: \"\\e600\";\n}\n.h5p-interactive-video-dragnbar .h5p-dragnbar-singlechoiceset-button:before,\n.h5p-singlechoiceset-interaction-icon:before {\n content: \"\\e993\";\n}\n\n.h5p-interactivevideo-editor .h5p-dialog-buttons {\n position: absolute;\n top: 0;\n right: 0;\n padding: 0.5em;\n box-sizing: border-box;\n}\n\n.h5p-interactivevideo-editor .h5p-dialog-title {\n color: #313131;\n float: left;\n margin-top: 0.25em;\n}\n\n.h5p-interactivevideo-editor .h5p-button {\n display: block;\n margin: 0 0 0 0.625em;\n box-shadow: none;\n padding: 0.25em 2em;\n float: right;\n background: #f2f2f2;\n background: -webkit-linear-gradient(top,#fff 0,#f2f2f2 100%);\n background: -moz-linear-gradient(top,#fff 0,#f2f2f2 100%);\n background: -ms-linear-gradient(top,#fff 0,#f2f2f2 100%);\n background: -o-linear-gradient(top,#fff 0,#f2f2f2 100%);\n border: 1px solid #ccc;\n border-radius: 0.25em;\n font-size: 0.625em;\n color: #333;\n cursor: pointer;\n}\n\n.h5p-interactivevideo-editor .h5p-button:hover {\n text-decoration: none;\n text-decoration: none;\n border-color: #999;\n}\n\n.h5p-interactivevideo-editor .h5p-button.h5p-done {\n color: #fff;\n background: #3673B5;\n background: -webkit-linear-gradient(top,#5A94D3 0,#3673B5 100%);\n background: -moz-linear-gradient(top,#5A94D3 0,#3673B5 100%);\n background: -ms-linear-gradient(top,#5A94D3 0,#3673B5 100%);\n background: -o-linear-gradient(top,#5A94D3 0,#3673B5 100%);\n border-color: #20588F;\n}\n.h5p-interactivevideo-editor .h5p-button.h5p-done:hover {\n background: #3275bc;\n background: -webkit-linear-gradient(top,#3275bc 0,#285585 100%);\n background: -moz-linear-gradient(top,#3275bc 0,#285585 100%);\n background: -ms-linear-gradient(top,#3275bc 0,#285585 100%);\n background: -o-linear-gradient(top,#3275bc 0,#285585 100%);\n}\n\n.h5p-interactivevideo-editor .h5p-button.h5p-remove {\n background: none;\n border: none;\n color: #a00;\n}\n\n.h5p-interactivevideo-editor .h5p-button.h5p-remove:hover {\n background: none;\n border: none;\n color: #e40000;\n}\n.h5p-interactivevideo-editor .h5p-interactive-video a:focus {\n box-shadow: none;\n}\n.h5p-interactivevideo-editor .h5p-interactive-video .h5p-interaction-label:hover {\n cursor: pointer;\n}\n.h5p-interactivevideo-editor .field-name-interactiveVideo {\n margin-bottom: 0;\n}\n/* Wizard does hide the label by default - must override here */\n.h5p-interactivevideo-editor .field-name-interactiveVideo \u003e .h5peditor-label-wrapper {\n display: block;\n}\n.h5p-interactivevideo-editor .field-name-interactiveVideo \u003e .h5peditor-label-wrapper \u003e .h5peditor-label {\n display: block;\n position: relative;\n background: #e9e9e9;\n font-size: 1.5em;\n font-weight: normal;\n line-height: 1.5em;\n padding: 0.5em 0.75em;\n color: #444;\n margin: 0 0 1px 0;\n}\n.h5p-interactivevideo-editor .field-name-interactiveVideo \u003e .h5peditor-label-wrapper \u003e .h5peditor-label:before {\n font-family: \u0027H5PFontAwesome4\u0027;\n margin: 0 0.5em 0 0;\n content: \"\\f01d\";\n}\n.h5p-interactivevideo-editor .field-name-interactiveVideo \u003e .h5peditor-label-wrapper \u003e .h5peditor-label:after {\n content: \"\";\n}\n.h5p-interactivevideo-editor .h5peditor-form {\n border-radius: 0;\n padding: 0;\n background: #fff;\n}\n.h5p-interactivevideo-editor .group.field-name-override {\n margin: 0 20px;\n}\n.h5p-interactivevideo-editor .tree \u003e .field.group:last-child .content {\n background-color: #FAFBFC;\n}\n.h5p-interactivevideo-editor .tree \u003e .field.group:last-child .content .content{\n background-color: #FFF;\n}\n.h5p-interactivevideo-editor .tree \u003e .field.group:last-child .content .content .content{\n background-color: #FAFBFC;\n}\n.h5p-interactivevideo-editor .common {\n margin: 20px;\n background-color: #FAFBFC;\n}\n.h5p-interactivevideo-editor .common .fields {\n background-color: #FAFBFC;\n}\n.h5p-interactivevideo-editor .common .fields .content {\n background-color: #FFF;\n}\n.h5p-interactivevideo-editor .common .fields .content .content {\n background-color: #FAFBFC\n}\n.h5p-interactivevideo-editor .h5peditor-panes \u003e .field {\n border: 0;\n}\n.h5p-interactivevideo-editor .field.interactiveVideo {\n margin: 0;\n padding: 0;\n}\n.h5p-interactivevideo-editor textarea, .h5p-interactivevideo-editor input[type=\"text\"]:not(.h5p-dragnbar-x):not(.h5p-dragnbar-y), .h5p-interactivevideo-editor .ckeditor {\n border: 1px solid #dbdbdb;\n border-radius: 0;\n background: #fff;\n}\n.h5p-interactivevideo-editor textarea:focus, .h5p-interactivevideo-editor input[type=\"text\"]:not(.h5p-dragnbar-x):not(.h5p-dragnbar-y):focus {\n background: #fff;\n border-color: #dbdbdb;\n box-shadow: 0 0 0.25em #dbdbdb inset;\n}\n.h5p-interactivevideo-editor table.h5p-table, .h5p-interactivevideo-editor .h5p-table td, .h5p-interactivevideo-editor .h5p-table th {\n border: 1px dashed #999;\n}\n\n.h5p-interactivevideo-editor .library .wizard {\n border: 1px solid #dedede;\n margin: 1em 1em 1em 0;\n}\n.h5p-interactivevideo-editor .library div.field.wizard .h5peditor-tabs {\n border-top: 0;\n line-height: 100%;\n}\n.h5p-interactivevideo-editor .h5p-add-bookmark {\n padding: 0 12px 8px;\n color: #fefefe;\n font-style: italic;\n cursor: pointer;\n}\n.h5p-interactivevideo-editor .h5p-add-bookmark:hover {\n color: #dbd7d1;\n}\n.h5p-interactivevideo-editor .h5p-add-bookmark:before {\n font-family: H5PFontAwesome4;\n content: \"\\f055\";\n margin-right: 8px;\n font-style: normal;\n}\n.h5p-interactivevideo-editor .h5p-bookmark .h5p-bookmark-label {\n padding-right: 30px;\n}\n.h5p-interactivevideo-editor .h5p-remove-bookmark:before {\n font-family: H5PFontAwesome4;\n content: \"\\f057\";\n color: #fefefe;\n position: absolute;\n top: 0;\n right: 8px;\n}\n.h5p-interactivevideo-editor .h5p-remove-bookmark:hover:before {\n color: #dbd7d1;\n}\n.h5p-interactivevideo-editor .h5p-bookmark.h5p-force-show .h5p-bookmark-label {\n visibility: visible;\n opacity: 1;\n}\n\n.h5p-interactivevideo-editor .h5p-bookmark input[type=\"text\"].h5p-bookmark-input:focus,\n.h5p-interactivevideo-editor .h5p-bookmark input[type=\"text\"].h5p-bookmark-input {\n background: transparent;\n border: 0;\n color: #fefefe;\n outline: none;\n font-size: 1em;\n box-shadow: none;\n margin: 0;\n}\n.h5p-interactivevideo-editor .h5p-bookmark input[type=\"text\"].h5p-bookmark-input::-ms-clear {\n display: none;\n}\n.h5p-interactivevideo-editor .h5p-bookmark-text:before {\n font-family: H5PFontAwesome4;\n content: \"\\f02e\";\n margin-right: 8px;\n}\n.h5p-interactivevideo-editor .h5p-iv-message-popup {\n position: absolute;\n bottom: 36px;\n left: 0;\n right: 0;\n width: 100%;\n padding: .3em;\n z-index: 11;\n box-sizing: border-box;\n -moz-box-sizing: border-box;\n border-top: 1px solid #ffcd0d;\n background-color: #fcffcc;\n text-align: center;\n font-size: .6em;\n}\n.h5p-interactivevideo-editor .h5p-iv-message-popup:before {\n font-family: \"H5PFontAwesome4\";\n content: \u0027\\f05a\u0027;\n padding-right: .3em;\n font-size: 1.1em;\n}\n\n/* Label for interaction buttons */\n.h5p-interactivevideo-editor .h5peditor-interactions .h5p-interaction-button-title {\n display: none;\n background-color: #000;\n color: #fff;\n opacity: 0.75;\n position: absolute;\n padding: 0 0.5em;\n font-size: 0.6em;\n line-height: 2;\n border-radius: 0.35em;\n font-family: \u0027Open Sans\u0027, sans-serif;\n white-space: nowrap;\n z-index: 2;\n}\n\n.h5p-interactivevideo-editor .h5peditor-interactions .h5p-interaction-button-title.show {\n display: block;\n}\n\n/* Remove h5p-nil library border */\n.h5p-interactivevideo-editor .h5peditor-interactions .h5p-dialog-inner .field.library.h5p-nil-library {\n display: none;\n}\n\n.h5p-interactivevideo-editor .h5p-interactive-video .h5p-interaction[role=\"button\"] {\n outline: 0;\n}\n\n.h5p-interactivevideo-editor .h5p-interactive-video .h5p-interaction.h5p-poster {\n overflow: visible;\n overflow-y: visible;\n}\n\n.h5p-interactivevideo-editor .h5p-interactive-video .h5p-interaction.h5p-poster .h5p-interaction-inner {\n overflow: hidden;\n}\n\n/* Make sure box-shadow and drop-shadow is not cut off by poster boundaries */\n.h5p-interactivevideo-editor .h5p-interactive-video .h5p-interaction.h5p-poster.h5p-image-interaction.h5p-transparent-interaction .h5p-interaction-inner {\n overflow: visible;\n}\n\n/* interaction semantics wrapper */\n.h5p-interactivevideo-editor .h5p-dialog-inner .h5p-dialog-inner-semantics {\n padding: 0.5em;\n box-sizing: border-box;\n}\n\n.h5p-interactivevideo-editor .h5p-dialog-inner .h5peditor-interaction-duration {\n float: left;\n}\n\n.h5p-interactivevideo-editor .h5p-dragnbar-element.h5p-moving .h5p-interaction-button {\n cursor: move;\n}\n\n.h5p-interactivevideo-editor .h5p-dialog-inner .field {\n clear: both;\n}\n\n.h5p-interactivevideo-editor .h5p-dialog-inner .h5peditor-interaction-pause {\n margin-left: 1em;\n margin-top: 2.5em;\n float: left;\n clear: none;\n}\n\n.h5p-interactivevideo-editor .field.hide {\n display: none;\n}\n\n.h5p-interactivevideo-editor .h5peditor-iv-focus-handler {\n display: none;\n position: absolute;\n top: 0;\n left: 0;\n height: 100%;\n width: 100%;\n}\n\n.h5p-interactivevideo-editor .h5peditor-iv-focus-handler.show {\n display: block;\n}\n\n.h5p-interactivevideo-editor .h5p-image-radio-button.button .image-container {\n background: #fff url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAFUAAAA8CAYAAAAXDvbIAAAACXBIWXMAAAsTAAALEwEAmpwYAAA8BWlUWHRYTUw6Y29tLmFkb2JlLnhtcAAAAAAAPD94cGFja2V0IGJlZ2luPSLvu78iIGlkPSJXNU0wTXBDZWhpSHpyZVN6TlRjemtjOWQiPz4KPHg6eG1wbWV0YSB4bWxuczp4PSJhZG9iZTpuczptZXRhLyIgeDp4bXB0az0iQWRvYmUgWE1QIENvcmUgNS42LWMwMTQgNzkuMTU2Nzk3LCAyMDE0LzA4LzIwLTA5OjUzOjAyICAgICAgICAiPgogICA8cmRmOlJERiB4bWxuczpyZGY9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkvMDIvMjItcmRmLXN5bnRheC1ucyMiPgogICAgICA8cmRmOkRlc2NyaXB0aW9uIHJkZjphYm91dD0iIgogICAgICAgICAgICB4bWxuczp4bXA9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC8iCiAgICAgICAgICAgIHhtbG5zOnhtcE1NPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvbW0vIgogICAgICAgICAgICB4bWxuczpzdEV2dD0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL3NUeXBlL1Jlc291cmNlRXZlbnQjIgogICAgICAgICAgICB4bWxuczpwaG90b3Nob3A9Imh0dHA6Ly9ucy5hZG9iZS5jb20vcGhvdG9zaG9wLzEuMC8iCiAgICAgICAgICAgIHhtbG5zOmRjPSJodHRwOi8vcHVybC5vcmcvZGMvZWxlbWVudHMvMS4xLyIKICAgICAgICAgICAgeG1sbnM6dGlmZj0iaHR0cDovL25zLmFkb2JlLmNvbS90aWZmLzEuMC8iCiAgICAgICAgICAgIHhtbG5zOmV4aWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20vZXhpZi8xLjAvIj4KICAgICAgICAgPHhtcDpDcmVhdG9yVG9vbD5BZG9iZSBQaG90b3Nob3AgQ0MgMjAxNCAoV2luZG93cyk8L3htcDpDcmVhdG9yVG9vbD4KICAgICAgICAgPHhtcDpDcmVhdGVEYXRlPjIwMTUtMDYtMjJUMDk6NTU6NDkrMDI6MDA8L3htcDpDcmVhdGVEYXRlPgogICAgICAgICA8eG1wOk1ldGFkYXRhRGF0ZT4yMDE1LTA2LTIyVDA5OjU1OjQ5KzAyOjAwPC94bXA6TWV0YWRhdGFEYXRlPgogICAgICAgICA8eG1wOk1vZGlmeURhdGU+MjAxNS0wNi0yMlQwOTo1NTo0OSswMjowMDwveG1wOk1vZGlmeURhdGU+CiAgICAgICAgIDx4bXBNTTpJbnN0YW5jZUlEPnhtcC5paWQ6MDdhNWExMmEtMTBiMy1hZDQ5LWIyZGYtMjQ3YzQwY2FlNmE4PC94bXBNTTpJbnN0YW5jZUlEPgogICAgICAgICA8eG1wTU06RG9jdW1lbnRJRD5hZG9iZTpkb2NpZDpwaG90b3Nob3A6MTQ3Y2M2MTAtMThiNC0xMWU1LTlhODktY2VmOGMyNjhkNmE3PC94bXBNTTpEb2N1bWVudElEPgogICAgICAgICA8eG1wTU06T3JpZ2luYWxEb2N1bWVudElEPnhtcC5kaWQ6ZDkzMDk3ZGYtMGIxNy1iZTQ0LWJjYzktODJmNzBjMTVkNzI5PC94bXBNTTpPcmlnaW5hbERvY3VtZW50SUQ+CiAgICAgICAgIDx4bXBNTTpIaXN0b3J5PgogICAgICAgICAgICA8cmRmOlNlcT4KICAgICAgICAgICAgICAgPHJkZjpsaSByZGY6cGFyc2VUeXBlPSJSZXNvdXJjZSI+CiAgICAgICAgICAgICAgICAgIDxzdEV2dDphY3Rpb24+Y3JlYXRlZDwvc3RFdnQ6YWN0aW9uPgogICAgICAgICAgICAgICAgICA8c3RFdnQ6aW5zdGFuY2VJRD54bXAuaWlkOmQ5MzA5N2RmLTBiMTctYmU0NC1iY2M5LTgyZjcwYzE1ZDcyOTwvc3RFdnQ6aW5zdGFuY2VJRD4KICAgICAgICAgICAgICAgICAgPHN0RXZ0OndoZW4+MjAxNS0wNi0yMlQwOTo1NTo0OSswMjowMDwvc3RFdnQ6d2hlbj4KICAgICAgICAgICAgICAgICAgPHN0RXZ0OnNvZnR3YXJlQWdlbnQ+QWRvYmUgUGhvdG9zaG9wIENDIDIwMTQgKFdpbmRvd3MpPC9zdEV2dDpzb2Z0d2FyZUFnZW50PgogICAgICAgICAgICAgICA8L3JkZjpsaT4KICAgICAgICAgICAgICAgPHJkZjpsaSByZGY6cGFyc2VUeXBlPSJSZXNvdXJjZSI+CiAgICAgICAgICAgICAgICAgIDxzdEV2dDphY3Rpb24+c2F2ZWQ8L3N0RXZ0OmFjdGlvbj4KICAgICAgICAgICAgICAgICAgPHN0RXZ0Omluc3RhbmNlSUQ+eG1wLmlpZDowN2E1YTEyYS0xMGIzLWFkNDktYjJkZi0yNDdjNDBjYWU2YTg8L3N0RXZ0Omluc3RhbmNlSUQ+CiAgICAgICAgICAgICAgICAgIDxzdEV2dDp3aGVuPjIwMTUtMDYtMjJUMDk6NTU6NDkrMDI6MDA8L3N0RXZ0OndoZW4+CiAgICAgICAgICAgICAgICAgIDxzdEV2dDpzb2Z0d2FyZUFnZW50PkFkb2JlIFBob3Rvc2hvcCBDQyAyMDE0IChXaW5kb3dzKTwvc3RFdnQ6c29mdHdhcmVBZ2VudD4KICAgICAgICAgICAgICAgICAgPHN0RXZ0OmNoYW5nZWQ+Lzwvc3RFdnQ6Y2hhbmdlZD4KICAgICAgICAgICAgICAgPC9yZGY6bGk+CiAgICAgICAgICAgIDwvcmRmOlNlcT4KICAgICAgICAgPC94bXBNTTpIaXN0b3J5PgogICAgICAgICA8cGhvdG9zaG9wOkRvY3VtZW50QW5jZXN0b3JzPgogICAgICAgICAgICA8cmRmOkJhZz4KICAgICAgICAgICAgICAgPHJkZjpsaT5hZG9iZTpkb2NpZDpwaG90b3Nob3A6NDU1Mzc2NGQtZjMwZC0xMWU0LTg3NDYtYjE0ZDI0YWJlMWQ2PC9yZGY6bGk+CiAgICAgICAgICAgICAgIDxyZGY6bGk+YWRvYmU6ZG9jaWQ6cGhvdG9zaG9wOmM0NDQ1MWRjLTAwNmItMTFlNS1hNTM5LWI0Zjc2MzM3YzAxOTwvcmRmOmxpPgogICAgICAgICAgICAgICA8cmRmOmxpPnhtcC5kaWQ6YjIwZDYwOTgtYjY1Ny1jZjQ4LTg2NDMtMmE2MDk4YWJhZDIwPC9yZGY6bGk+CiAgICAgICAgICAgICAgIDxyZGY6bGk+eG1wLmRpZDpiYTkwODY0Ni1lOTg0LWRlNDQtYmJhZS0wNDczY2YzYmNmOTM8L3JkZjpsaT4KICAgICAgICAgICAgICAgPHJkZjpsaT54bXAuZGlkOmY3NDkwNjc1LTVkMzgtZTA0OC1iZDlhLTkxYTljYzlhOWJkODwvcmRmOmxpPgogICAgICAgICAgICA8L3JkZjpCYWc+CiAgICAgICAgIDwvcGhvdG9zaG9wOkRvY3VtZW50QW5jZXN0b3JzPgogICAgICAgICA8cGhvdG9zaG9wOkNvbG9yTW9kZT4zPC9waG90b3Nob3A6Q29sb3JNb2RlPgogICAgICAgICA8ZGM6Zm9ybWF0PmltYWdlL3BuZzwvZGM6Zm9ybWF0PgogICAgICAgICA8dGlmZjpPcmllbnRhdGlvbj4xPC90aWZmOk9yaWVudGF0aW9uPgogICAgICAgICA8dGlmZjpYUmVzb2x1dGlvbj43MjAwMDAvMTAwMDA8L3RpZmY6WFJlc29sdXRpb24+CiAgICAgICAgIDx0aWZmOllSZXNvbHV0aW9uPjcyMDAwMC8xMDAwMDwvdGlmZjpZUmVzb2x1dGlvbj4KICAgICAgICAgPHRpZmY6UmVzb2x1dGlvblVuaXQ+MjwvdGlmZjpSZXNvbHV0aW9uVW5pdD4KICAgICAgICAgPGV4aWY6Q29sb3JTcGFjZT42NTUzNTwvZXhpZjpDb2xvclNwYWNlPgogICAgICAgICA8ZXhpZjpQaXhlbFhEaW1lbnNpb24+ODU8L2V4aWY6UGl4ZWxYRGltZW5zaW9uPgogICAgICAgICA8ZXhpZjpQaXhlbFlEaW1lbnNpb24+NjA8L2V4aWY6UGl4ZWxZRGltZW5zaW9uPgogICAgICA8L3JkZjpEZXNjcmlwdGlvbj4KICAgPC9yZGY6UkRGPgo8L3g6eG1wbWV0YT4KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAKPD94cGFja2V0IGVuZD0idyI/Pqbfbr8AAAAgY0hSTQAAeiUAAICDAAD5/wAAgOkAAHUwAADqYAAAOpgAABdvkl/FRgAABxZJREFUeNrsnGtPE1sbhq/pCVpboS2tHFMUCogBCsYAiQbjgXiGokb97m944/8xfiMcIxGDYAxgE0VrQESRgyDUFNoKPQjSdt4P76YviBtFoLsb5k76ZWZlzawrs551P8+aqfD169cPoigagSiStiuZIAgehSiKJlEUUyUeOwdWBkQkDjuqiExisAuPqoRAgipBlaBKkqBKUCWokrYrRbwuJIoiTqeT4eFhJicnAcjNzaW4uBibzYYgCHsGquDz+eb/yv13FeiTJ0/o6ur66flz585x9uzZPQFWEARPXKa/0+n8W6AAXV1dOJ1OKaZuRcPDwzvSRoK6RqsxdLttJKiSpdpd5ebm7kgbCeoaFRcX/7JNZWXltq4RiUQIBAIsLi7Gft++fdu7PtVms+HxeDa1VPn5+QBEo1H8fj/BYBCVSoVOpyMpKWnT/gOBAA6Hg76+vnUgc3JyqKmp4dixY3G1a3Hxqb9r/peWlujv78fpdBIIBFAqlRw+fJhTp06RlZW1oU+v18vIyAhDQ0OMj48DYDKZ0Gg0zM/PEwwGUavV1NXVYbPZ4uZT4wb1V1peXqatrY2BgYEN5wwGA3a7HavVGjs2PT1Ne3s7U1NTsWPHjx/n9OnT6PV6xsbGePz4MTMzM2i1Wm7fvh2bDfsG6suXL2lsbEQmk1FRUYHFYsHv9/P8+XP8fj9Go5Fbt25hNpsZHBykp6cHr9eLSqXCarWSnZ1NdXU1ycnJsT7n5ua4f/8+brebzMxM7t69i0aj2XWoChJEq+a/uLiYuro6lEplLC62tLTg8Xhobm5Gq9UyMTFBOBxGoVBgt9spKipCrVZv6NNkMnHhwgUaGxuZnZ3F4XBw5syZ/eNTFxYWEAQBq9UaAwpgtVqpr69Hr9fjcrkYHR0lEolQUFDApUuXKC8v/ynQVRUVFVFaWgpAb28vPp9v/0BNSkpCFEXm5+c3nLNarVy7dg2tVgvA5cuXuXPnDlVVVb8e4F/hJDU1lVAohMPh2D9QCwoKABgYGODNmzeIorju/NGjR7l48SLV1dWxp1Mm+73bz8nJiS1yIyMj+P3+/QG1tLSUjIwMQqEQbW1tDA0NbWhTUVHB+fPn1y1Gv7l4UFZWRlJSEm63m1evXu0PqAaDgStXrnDw4EGCwSCtra28e/duAxyNRoNcLt9y/3l5eRQVFSGKIgMDA7jd7v1RUMnLy+PGjRvodDoCgQBNTU0bwG7D6lBTU4NarcbtdtPZ2UkwGNyVccjv3bv3H0CTKGCNRiNpaWmMjY0RCASYnJwkPT0do3H7Vlqn06HVapmZmWF6ehqfz0dmZuaOeldBEL4lZOlv1atqNBoWFhZoaWlhYmJiR/ouKytDp9MBMDg4uC4j25PTf61KSkqw2+0olUo8Hg9NTU18+vRpW32Gw2Ha29v58uULAOXl5THXsS+gBgIBPn78SDgcjqWcra2tzM3N/XFp8OHDh7x48YJwOMzJkyex2+0x7/uvK/1tVaFQiObm5ljqajQaSU9Px2q1xqbuVhSNRuno6MDhcCCKIhUVFdTW1qJSqXbl/hMOajQa5enTp7x9+xa5XE5lZSXV1dWYTKY/fkI7Ozvp7+9HFEUKCwt3FWhCQvV4PLx//x6Aqqoqrl69+sd9RSIRuru76e3tRRRF8vPzqa+vJzU1dVfHkHBQl5eXWVpaAn69xbKaykajUWQy2brqviiKPHv2jO7ubkRR5MiRIzQ0NKDX63d9DAkHValUxjKmqakpzGbzuljrcrnw+XwEg0EWFxcBWFlZQaFQkJaWRklJCTqdjr6+Prq6uhBFkZycHBoaGjAYDHEZQ8JB1ev1ZGVl4fV66enpwWAwIIoiHz58YGZmBpfLtWkmNDo6Snp6Or29vUQiETIyMmhoaCAtLS1uY0iYyv9aTUxM8ODBAwKBACkpKbHNwFVptVrUajUajYYDBw7E9rcmJyeJRP7/sc2hQ4e4efMm2dnZ8QOaSNspP8ZKp9PJo0ePYsVrk8mExWIhNzeXrKwskpOTkcvlKBSK2KI0PDxMR0cHS0tLmM1mrl+/jsViieu9J9R2yo/FD5vNhl6vZ2FhAaVSidlsJiUlZd2uwI86ceIEkUiE169fU1tbG3egCT39/82K26uU+00SVAnq1hc8r9f7j0CV71WogiDEzfCvkVwhCMIc//vWX/refwceUkEQPIrPnz+L4XA4AogSk+1HHIVCISpWVlbSI5HIQSCWc6/NSiRtOY4nrfsTBY1GQ0lJCZmZmRKdP1dEIQjCulgql8vJyMjAaDTicrl++hqOpE0Xx+jfWiqVSoXFYqGwsPCPtjAkn7qJ1Gq1BHWL2rSg4vV6mZ2dZXl5WSK1XaiBQIDp6WlCoZBEaLtQv3//zvj4eFxejN3TUEVRjMXV5eVlaapv36fK9nTu/w9J/t8BAHhD+KxwLA5vAAAAAElFTkSuQmCC) no-repeat center center;\n height: 60px;\n width: 85px;\n}\n.h5p-interactivevideo-editor .h5p-image-radio-button.poster .image-container {\n background: #fff url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAFUAAAA8CAYAAAAXDvbIAAAACXBIWXMAAAsTAAALEwEAmpwYAAA8BWlUWHRYTUw6Y29tLmFkb2JlLnhtcAAAAAAAPD94cGFja2V0IGJlZ2luPSLvu78iIGlkPSJXNU0wTXBDZWhpSHpyZVN6TlRjemtjOWQiPz4KPHg6eG1wbWV0YSB4bWxuczp4PSJhZG9iZTpuczptZXRhLyIgeDp4bXB0az0iQWRvYmUgWE1QIENvcmUgNS42LWMwMTQgNzkuMTU2Nzk3LCAyMDE0LzA4LzIwLTA5OjUzOjAyICAgICAgICAiPgogICA8cmRmOlJERiB4bWxuczpyZGY9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkvMDIvMjItcmRmLXN5bnRheC1ucyMiPgogICAgICA8cmRmOkRlc2NyaXB0aW9uIHJkZjphYm91dD0iIgogICAgICAgICAgICB4bWxuczp4bXA9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC8iCiAgICAgICAgICAgIHhtbG5zOnhtcE1NPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvbW0vIgogICAgICAgICAgICB4bWxuczpzdEV2dD0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL3NUeXBlL1Jlc291cmNlRXZlbnQjIgogICAgICAgICAgICB4bWxuczpwaG90b3Nob3A9Imh0dHA6Ly9ucy5hZG9iZS5jb20vcGhvdG9zaG9wLzEuMC8iCiAgICAgICAgICAgIHhtbG5zOmRjPSJodHRwOi8vcHVybC5vcmcvZGMvZWxlbWVudHMvMS4xLyIKICAgICAgICAgICAgeG1sbnM6dGlmZj0iaHR0cDovL25zLmFkb2JlLmNvbS90aWZmLzEuMC8iCiAgICAgICAgICAgIHhtbG5zOmV4aWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20vZXhpZi8xLjAvIj4KICAgICAgICAgPHhtcDpDcmVhdG9yVG9vbD5BZG9iZSBQaG90b3Nob3AgQ0MgMjAxNCAoV2luZG93cyk8L3htcDpDcmVhdG9yVG9vbD4KICAgICAgICAgPHhtcDpDcmVhdGVEYXRlPjIwMTUtMDYtMjJUMDk6NTU6MzkrMDI6MDA8L3htcDpDcmVhdGVEYXRlPgogICAgICAgICA8eG1wOk1ldGFkYXRhRGF0ZT4yMDE1LTA2LTIyVDA5OjU1OjM5KzAyOjAwPC94bXA6TWV0YWRhdGFEYXRlPgogICAgICAgICA8eG1wOk1vZGlmeURhdGU+MjAxNS0wNi0yMlQwOTo1NTozOSswMjowMDwveG1wOk1vZGlmeURhdGU+CiAgICAgICAgIDx4bXBNTTpJbnN0YW5jZUlEPnhtcC5paWQ6MDVlMDc2ZDItMTc1Ny1lYzQwLWI3MTMtMWUyZjcwYTY3MmRkPC94bXBNTTpJbnN0YW5jZUlEPgogICAgICAgICA8eG1wTU06RG9jdW1lbnRJRD5hZG9iZTpkb2NpZDpwaG90b3Nob3A6ZmUxMDA4MzQtMThiMy0xMWU1LTlhODktY2VmOGMyNjhkNmE3PC94bXBNTTpEb2N1bWVudElEPgogICAgICAgICA8eG1wTU06T3JpZ2luYWxEb2N1bWVudElEPnhtcC5kaWQ6MzEyZGI5NGItMDNkMC03YjRjLTlhNTAtMmIzMGFkMjMxOWU0PC94bXBNTTpPcmlnaW5hbERvY3VtZW50SUQ+CiAgICAgICAgIDx4bXBNTTpIaXN0b3J5PgogICAgICAgICAgICA8cmRmOlNlcT4KICAgICAgICAgICAgICAgPHJkZjpsaSByZGY6cGFyc2VUeXBlPSJSZXNvdXJjZSI+CiAgICAgICAgICAgICAgICAgIDxzdEV2dDphY3Rpb24+Y3JlYXRlZDwvc3RFdnQ6YWN0aW9uPgogICAgICAgICAgICAgICAgICA8c3RFdnQ6aW5zdGFuY2VJRD54bXAuaWlkOjMxMmRiOTRiLTAzZDAtN2I0Yy05YTUwLTJiMzBhZDIzMTllNDwvc3RFdnQ6aW5zdGFuY2VJRD4KICAgICAgICAgICAgICAgICAgPHN0RXZ0OndoZW4+MjAxNS0wNi0yMlQwOTo1NTozOSswMjowMDwvc3RFdnQ6d2hlbj4KICAgICAgICAgICAgICAgICAgPHN0RXZ0OnNvZnR3YXJlQWdlbnQ+QWRvYmUgUGhvdG9zaG9wIENDIDIwMTQgKFdpbmRvd3MpPC9zdEV2dDpzb2Z0d2FyZUFnZW50PgogICAgICAgICAgICAgICA8L3JkZjpsaT4KICAgICAgICAgICAgICAgPHJkZjpsaSByZGY6cGFyc2VUeXBlPSJSZXNvdXJjZSI+CiAgICAgICAgICAgICAgICAgIDxzdEV2dDphY3Rpb24+c2F2ZWQ8L3N0RXZ0OmFjdGlvbj4KICAgICAgICAgICAgICAgICAgPHN0RXZ0Omluc3RhbmNlSUQ+eG1wLmlpZDowNWUwNzZkMi0xNzU3LWVjNDAtYjcxMy0xZTJmNzBhNjcyZGQ8L3N0RXZ0Omluc3RhbmNlSUQ+CiAgICAgICAgICAgICAgICAgIDxzdEV2dDp3aGVuPjIwMTUtMDYtMjJUMDk6NTU6MzkrMDI6MDA8L3N0RXZ0OndoZW4+CiAgICAgICAgICAgICAgICAgIDxzdEV2dDpzb2Z0d2FyZUFnZW50PkFkb2JlIFBob3Rvc2hvcCBDQyAyMDE0IChXaW5kb3dzKTwvc3RFdnQ6c29mdHdhcmVBZ2VudD4KICAgICAgICAgICAgICAgICAgPHN0RXZ0OmNoYW5nZWQ+Lzwvc3RFdnQ6Y2hhbmdlZD4KICAgICAgICAgICAgICAgPC9yZGY6bGk+CiAgICAgICAgICAgIDwvcmRmOlNlcT4KICAgICAgICAgPC94bXBNTTpIaXN0b3J5PgogICAgICAgICA8cGhvdG9zaG9wOkRvY3VtZW50QW5jZXN0b3JzPgogICAgICAgICAgICA8cmRmOkJhZz4KICAgICAgICAgICAgICAgPHJkZjpsaT5hZG9iZTpkb2NpZDpwaG90b3Nob3A6NDU1Mzc2NGQtZjMwZC0xMWU0LTg3NDYtYjE0ZDI0YWJlMWQ2PC9yZGY6bGk+CiAgICAgICAgICAgICAgIDxyZGY6bGk+YWRvYmU6ZG9jaWQ6cGhvdG9zaG9wOmM0NDQ1MWRjLTAwNmItMTFlNS1hNTM5LWI0Zjc2MzM3YzAxOTwvcmRmOmxpPgogICAgICAgICAgICAgICA8cmRmOmxpPnhtcC5kaWQ6YjIwZDYwOTgtYjY1Ny1jZjQ4LTg2NDMtMmE2MDk4YWJhZDIwPC9yZGY6bGk+CiAgICAgICAgICAgICAgIDxyZGY6bGk+eG1wLmRpZDpiYTkwODY0Ni1lOTg0LWRlNDQtYmJhZS0wNDczY2YzYmNmOTM8L3JkZjpsaT4KICAgICAgICAgICAgICAgPHJkZjpsaT54bXAuZGlkOmY3NDkwNjc1LTVkMzgtZTA0OC1iZDlhLTkxYTljYzlhOWJkODwvcmRmOmxpPgogICAgICAgICAgICA8L3JkZjpCYWc+CiAgICAgICAgIDwvcGhvdG9zaG9wOkRvY3VtZW50QW5jZXN0b3JzPgogICAgICAgICA8cGhvdG9zaG9wOkNvbG9yTW9kZT4zPC9waG90b3Nob3A6Q29sb3JNb2RlPgogICAgICAgICA8ZGM6Zm9ybWF0PmltYWdlL3BuZzwvZGM6Zm9ybWF0PgogICAgICAgICA8dGlmZjpPcmllbnRhdGlvbj4xPC90aWZmOk9yaWVudGF0aW9uPgogICAgICAgICA8dGlmZjpYUmVzb2x1dGlvbj43MjAwMDAvMTAwMDA8L3RpZmY6WFJlc29sdXRpb24+CiAgICAgICAgIDx0aWZmOllSZXNvbHV0aW9uPjcyMDAwMC8xMDAwMDwvdGlmZjpZUmVzb2x1dGlvbj4KICAgICAgICAgPHRpZmY6UmVzb2x1dGlvblVuaXQ+MjwvdGlmZjpSZXNvbHV0aW9uVW5pdD4KICAgICAgICAgPGV4aWY6Q29sb3JTcGFjZT42NTUzNTwvZXhpZjpDb2xvclNwYWNlPgogICAgICAgICA8ZXhpZjpQaXhlbFhEaW1lbnNpb24+ODU8L2V4aWY6UGl4ZWxYRGltZW5zaW9uPgogICAgICAgICA8ZXhpZjpQaXhlbFlEaW1lbnNpb24+NjA8L2V4aWY6UGl4ZWxZRGltZW5zaW9uPgogICAgICA8L3JkZjpEZXNjcmlwdGlvbj4KICAgPC9yZGY6UkRGPgo8L3g6eG1wbWV0YT4KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAKPD94cGFja2V0IGVuZD0idyI/Pjz7hGoAAAAgY0hSTQAAeiUAAICDAAD5/wAAgOkAAHUwAADqYAAAOpgAABdvkl/FRgAABBNJREFUeNrsm89LMl0Ux78zzpiZwzNhOFiCuDEsjNy0aiESBNGifUSQgdOi1q1aRn9Ai0hq1x9Rq0gJapUpCC2EsHKRpPmr1LF5F+/79D6+9uOpGV/y6Xx3nus9HD/ee8+5d+4w+Xy+pqoqB0AFSasYhmEUTlVVTlVVBgBDTHQRxxID/UVQCSpBJagkgkpQCSqJoH7J6l9L59XV1T8WzMbGBo1Umv4ElURQCSpBJf0fJdVrcjqd8Pv9sNlsuL+/x/HxMRKJhC6+PR4P/H4/WFb7eIjH4zg6Ovr6UN1uN0KhECwWy7PN5/Nhb28P0WhUs3+v14vR0VFdYuV5vi1QdZ/+U1NTTUABgGVZTE9Po7e3V7P/er2uW6x6+mrrSLXZbC/aLRYLRFFELpfT5D8SiaBSqYDjOKjq559VsiyLZDLZGVDz+TysVmuL/eHhAcViscVuNpvB8zzu7+9/y382m8X+/v73yv4HBwdQFKXFfnh4iGw222QzmUxYXFzEysrKqyOcsj+As7MzbG9vIxAIQJIkFAoFRKNRRCKRpu8JgoCFhQUMDQ0BAGRZRjgcRiaTeXd5GR4e1iXWy8tLpFKpziipYrEYEokEenp68Pj4iFqt1tQuiiKCwSDcbvezbWBgAEtLSwiHw0in06/6Hh8fx+TkpC5xxuNxbG5udk7x32g0UCgUWoBarVaEQqEmoD8lSRJkWYbL5XqzDNLtx7NsZ0z/nzIajZiYmMDp6enzWipJEoLBIJxO56v9+vr6IMsydnZ2cHFx0dJ+fn4OURTx9PSkKT6DwYBYLNY5UHmex9zcHMbGxjAyMoKtrS2YTCbIsgy73f5uf1EUMT8/j/X1dZTL5aa2ZDLZtlLoy0IVBAGzs7Pw+XwAAJfLheXlZfA8D0mSftuP2WyG0Whsgfots38wGITH42myORyOT63JLxX3XV1dcDgc4Hn+uV0QBBgMhufPDMOgUqmgWq2CZVnUajWk0+m27aDaDvWtJKOHAoEAZmZmPtxvd3cXJycnnVn8a00gvyaSl/Tjx49P+fvveURHjdRisQhVVTXtyxmGQalUevEPur6+Rrlc/lA5pCgKbm9vOxfq2tpaWwOORCItu7M/fu9PIqgElaASVBJB/eJicrnc0z/vUZH0AMowKo1Umv4ElaCSCCpB/W7iGIZR8PdpFb3vr0tFxSjc1dWVqigKAdVHKsdxKlev1/lGo8EA/562NxoNwvNZqqrKN62pZrMZXq8X/f39REfjmtpkMBgMsNvtsFqtyGQyLZfKSO8uqq9nf6PRCKfTicHBQQiCQLT0LKm6u7sJ6ken/1uNd3d3uLm5QbVaJVJaoZZKJaTTaVQqFSKkFWqtVkMqldJ8L//bQ/310kO1WqWprr1Opb1/O/TXACjzX+BRnHH2AAAAAElFTkSuQmCC) no-repeat center center;\n height: 60px;\n width: 85px;\n}\n.h5p-interactivevideo-editor .h5p-dialog-inner \u003e div \u003e .field.library {\n border: 0;\n padding: 0;\n margin: 0;\n}\n.h5p-interactivevideo-editor .h5p-interaction.h5p-poster \u003e div {\n z-index: 1;\n}\n.h5p-interactivevideo-editor .h5p-ivhotspot \u003e a {\n box-sizing: border-box;\n border: 2px solid rgba(255,255,255,0.7);\n}\n.h5p-interactivevideo-editor .h5p-ivhotspot \u003e a:before {\n content: \" \";\n display: block;\n position: absolute;\n border: 2px dashed rgba(0, 0, 0, 0.7);\n width: 100%;\n height: 100%;\n top: -2px;\n left: -2px;\n}\n.h5p-interactivevideo-editor .h5p-ivhotspot.circular \u003e a:before {\n border-radius: 50%;\n}\n.h5p-interactivevideo-editor .field.wizard \u003e .h5peditor-panes \u003e .group \u003e .content {\n border: 0;\n}\n/* Avoid double padding between start screen options and behavioural settings */\n.h5p-interactivevideo-editor .group.field-video \u003e .content {\n padding-bottom: 0;\n}\n.h5peditor-interactions:not(.h5p-interactive-video) {\n margin: 1.6em;\n padding: 1em;\n color: white;\n background-color: black;\n text-align: center;\n}\n\n.h5peditor-interactions .h5p-no-video-icon {\n width: 8em;\n height: 8em;\n margin: 0 auto;\n background-image: url(\u0027../H5P/libraries/H5PEditor.InteractiveVideo-1.17/images/no-video-source.svg\u0027);\n background-repeat: no-repeat;\n}\n\n.h5peditor-interactions .h5p-no-video-title {\n font-size: 1.7em;\n}\n\n.h5peditor-interactions .h5p-no-video-button {\n margin: 1em 0 1.5em 0;\n padding: 0.8em 1.8em;\n font-weight: 100;\n font-size: 1em;\n line-height: 1em;\n}\n\n.h5peditor-interactions .h5p-no-video-button:before {\n font-family: \u0027H5PFontAwesome4\u0027;\n content: \"\\f060\";\n}\n\n.h5peditor-interactions.h5p-interactive-video {\n font-weight: inherit;\n padding: 0;\n margin-bottom: 10px;\n color: inherit;\n}\n\n/* Make sure there are not a double padding before the summary tabs fields */\n.h5p-interactivevideo-editor .field-name-summary \u003e .content {\n padding-top: 0;\n}\n\n/* Tour button placed in Wizard\u0027s header */\n.h5p-interactivevideo-editor .h5peditor-guided-tour {\n position: absolute;\n right: .5em;\n color: #666;\n background: transparent;\n border-radius: 4px;\n font-size: 0.7em;\n cursor: pointer;\n padding: 0 1em;\n}\n.h5p-interactivevideo-editor .h5peditor-guided-tour:before {\n font-family: \u0027H5PFontAwesome4\u0027;\n content: \u0027\\f14e\u0027;\n margin-right: .5em;\n}\n.h5p-interactivevideo-editor .h5peditor-guided-tour:hover,\n.h5p-interactivevideo-editor .h5peditor-guided-tour:focus {\n color: #333;\n background: #ddd;\n}\n.h5p-interactivevideo-editor .h5peditor-guided-tour:active {\n color: #555;\n background: #ccc;\n}\n.h5p-poster.h5p-ivhotspot-interaction {\n overflow: visible;\n}\n.h5p-interactivevideo-editor .field.wizard .h5peditor-tab-video:before {\n content: \u0027\\e911\u0027;\n}\n.h5p-interactivevideo-editor .field.wizard .h5peditor-tab-assets:before {\n content: \u0027\\e917\u0027;\n}\n.h5p-interactivevideo-editor .field.wizard .h5peditor-tab-summary:before {\n content: \u0027\\e912\u0027;\n}\n.h5p-interactivevideo-editor .field.wizard .field.interactiveVideo {\n margin-top: 5px;\n}\n\n.h5p-interactivevideo-editor .h5p-interactive-video .h5p-video-wrapper.h5p-youtube {\n overflow: hidden !important;\n}\n\n/* Remove option for full enable full screen in Drag Question */\n.h5p-interactivevideo-editor .h5p-dragquestion-editor .field-name-enableFullScreen {\n display: none;\n}\n","styles/require-completion.css":".h5p-interactive-video .h5peditor-interaction-pause.h5p-has-disabled-msg {\n margin-top: 1em;\n}\n\n.h5p-interactive-video .h5peditor-interaction-pause.h5p-has-disabled-msg .h5p-errors {\n margin: 0;\n}\n\n.h5p-interactive-video .h5peditor-pause-disabled-msg {\n margin-left: 1.4em;\n}\n\n.h5p-interactive-video .h5peditor-pause-disabled-msg.h5p-hide {\n display: none;\n}\n\n.h5p-interactive-video .h5peditor-enable-retry-disabled-msg.h5p-hide {\n display: none;\n}\n\n.h5p-interactive-video .h5peditor-conflicting-time-msg {\n color: red;\n clear: both;\n}\n\n.h5p-interactive-video .h5peditor-conflicting-time-msg.h5p-hide {\n display: none;\n}\n\n.h5p-interactive-video .field.group.h5p-hide {\n display: none;\n}\n"}}