diff --git a/Build/Gruntfile.js b/Build/Gruntfile.js index cc1463f..dd0da96 100644 --- a/Build/Gruntfile.js +++ b/Build/Gruntfile.js @@ -23,10 +23,12 @@ module.exports = function(grunt) { }, files: { "Resources/Public/JavaScript/ddbKitodoZeitungsportal.js" : [ - 'Resources/Public/Javascript/OpenLayers/glif.min.js', - 'Resources/Public/Javascript/OpenLayers/ol3-dlf.js', + '../dlf/Resources/Public/Javascript/jQueryUI/jquery-ui-mouse-slider-resizable-autocomplete.js', + '../dlf/Resources/Public/Javascript/OpenLayers/glif.min.js', + '../dlf/Resources/Public/Javascript/OpenLayers/ol3-dlf.js', // Viewer - '../dlf/Resources/Public/Javascript/PageView/Utility.js', + // highlight exact word in search results + 'Resources/Private/JavaScript/Kitodo/PageView/Utility.js', '../dlf/Resources/Public/Javascript/PageView/OL3.js', '../dlf/Resources/Public/Javascript/PageView/OL3Styles.js', '../dlf/Resources/Public/Javascript/PageView/OL3Sources.js', @@ -35,9 +37,14 @@ module.exports = function(grunt) { '../dlf/Resources/Public/Javascript/PageView/AnnotationControl.js', '../dlf/Resources/Public/Javascript/PageView/ImageManipulationControl.js', '../dlf/Resources/Public/Javascript/PageView/FulltextDownloadControl.js', + // custom scrolling 'Resources/Private/JavaScript/Kitodo/PageView/FulltextControl.js', '../dlf/Resources/Public/Javascript/PageView/FullTextUtility.js', - '../dlf/Resources/Public/Javascript/PageView/PageView.js' + '../dlf/Resources/Public/Javascript/PageView/PageView.js', + // Search + // use standard input instead of submit button + // TODO: add template + 'Resources/Private/JavaScript/Kitodo/Search/SearchInDocument.js' ], } } diff --git a/Resources/Private/JavaScript/Kitodo/PageView/FulltextControl.js b/Resources/Private/JavaScript/Kitodo/PageView/FulltextControl.js index 555600f..44d9205 100644 --- a/Resources/Private/JavaScript/Kitodo/PageView/FulltextControl.js +++ b/Resources/Private/JavaScript/Kitodo/PageView/FulltextControl.js @@ -57,7 +57,13 @@ var dlfViewerFullTextControl = function(map, image, fulltextUrl) { */ this.dic = $('#tx-dlf-tools-fulltext').length > 0 && $('#tx-dlf-tools-fulltext').attr('data-dic') ? dlfUtils.parseDataDic($('#tx-dlf-tools-fulltext')) : - {'fulltext':'Fulltext', 'fulltext-on':'Activate Fulltext','fulltext-off':'Deactivate Fulltext', 'activate-full-text-initially':'0', 'full-text-scroll-element':'html, body'}; + { + 'fulltext':'Fulltext', + 'fulltext-on':'Activate Fulltext', + 'fulltext-off':'Deactivate Fulltext', + 'activate-full-text-initially':'0', + 'full-text-scroll-element':'html, body', + 'search-hl-parameters':'tx_dlf[highlight_word]'}; /** * @type {number} @@ -71,6 +77,12 @@ var dlfViewerFullTextControl = function(map, image, fulltextUrl) { */ this.fullTextScrollElement = this.dic['full-text-scroll-element']; + /** + * @type {string} + * @private + */ + this.searchHlParameters = this.dic['search-hl-parameters']; + /** * @type {ol.Feature|undefined} * @private diff --git a/Resources/Private/JavaScript/Kitodo/PageView/Utility.js b/Resources/Private/JavaScript/Kitodo/PageView/Utility.js new file mode 100644 index 0000000..e34f2ab --- /dev/null +++ b/Resources/Private/JavaScript/Kitodo/PageView/Utility.js @@ -0,0 +1,913 @@ +'use strict'; + +/** + * (c) Kitodo. Key to digital objects e.V. + * + * This file is part of the Kitodo and TYPO3 projects. + * + * @license GNU General Public License version 3 or later. + * For the full copyright and license information, please read the + * LICENSE.txt file that was distributed with this source code. + */ + +// Internet Explorer does not support String.prototype.endsWith +if (String.prototype.endsWith === undefined) { + String.prototype.endsWith = function(searchString, length) { + if (searchString === null || searchString === '' || length !== null && searchString.length > length || searchString.length > this.length) { + return false; + } + length = length === null || length > this.length || length <= 0 ? this.length : length; + var substr = this.substr(0, length); + return substr.lastIndexOf(searchString) === length - searchString.length; + }; +} + +/** + * Base namespace for utility functions used by the dlf module. + * + * @const + */ +var dlfUtils; +dlfUtils = dlfUtils || {}; + +/** + * @type {{ZOOMIFY: string}} + */ +dlfUtils.CUSTOM_MIMETYPE = { + IIIF: 'application/vnd.kitodo.iiif', + IIP: 'application/vnd.netfpx', + ZOOMIFY: 'application/vnd.kitodo.zoomify' +}; + +/** + * @type {number} + */ +dlfUtils.RUNNING_INDEX = 99999999; + +/** + * @param imageSourceObjs + * @param {string} opt_origin + * @return {Array.} + */ +dlfUtils.createOl3Layers = function (imageSourceObjs, opt_origin) { + + var origin = opt_origin !== undefined ? opt_origin : null, + widthSum = 0, + offsetWidth = 0, + layers = []; + + imageSourceObjs.forEach(function (imageSourceObj) { + var tileSize = void 0; + if (widthSum > 0) { + // set offset width in case of multiple images + offsetWidth = widthSum; + } + + // + // Create layer + // + var extent = [offsetWidth, -imageSourceObj.height, imageSourceObj.width + offsetWidth, 0], + layer = void 0; + + if (imageSourceObj.mimetype === dlfUtils.CUSTOM_MIMETYPE.ZOOMIFY) { + // create zoomify layer + layer = new ol.layer.Tile({ + source: new ol.source.Zoomify({ + url: imageSourceObj.src, + size: [imageSourceObj.width, imageSourceObj.height], + crossOrigin: origin, + offset: [offsetWidth, 0] + }), + zDirection: -1 + }); + } else if (imageSourceObj.mimetype === dlfUtils.CUSTOM_MIMETYPE.IIIF) { + + var quality = imageSourceObj.qualities !== undefined && imageSourceObj.qualities.length > 0 + ? $.inArray('color', imageSourceObj.qualities) >= 0 + ? 'color' + : $.inArray('native', imageSourceObj.qualities) >= 0 + ? 'native' + : 'default' + : 'default'; + + layer = new ol.layer.Tile({ + source: new dlfViewerSource.IIIF({ + url: imageSourceObj.src, + version: imageSourceObj.version, + size: [imageSourceObj.width, imageSourceObj.height], + crossOrigin: origin, + resolutions: imageSourceObj.resolutions, + tileSize: imageSourceObj.tilesize, + sizes: imageSourceObj.sizes, + format: 'jpg', + quality, + supports: imageSourceObj.supports, + offset: [offsetWidth, 0], + projection: new ol.proj.Projection({ + code: 'kitodo-image', + units: 'pixels', + extent: extent + }) + }), + zDirection: -1 + }); + } else if (imageSourceObj.mimetype === dlfUtils.CUSTOM_MIMETYPE.IIP) { + tileSize = imageSourceObj.tilesize !== undefined && imageSourceObj.tilesize.length > 0 + ? imageSourceObj.tilesize[0] + : 256; + + layer = new ol.layer.Tile({ + source: new dlfViewerSource.IIP({ + url: imageSourceObj.src, + size: [imageSourceObj.width, imageSourceObj.height], + crossOrigin: origin, + tileSize, + offset: [offsetWidth, 0] + }), + zDirection: -1 + }); + } else { + + // create static image source + layer = new ol.layer.Image({ + source: new ol.source.ImageStatic({ + url: imageSourceObj.src, + projection: new ol.proj.Projection({ + code: 'kitodo-image', + units: 'pixels', + extent: extent + }), + imageExtent: extent, + crossOrigin: origin + }) + }); + } + layers.push(layer); + + // add to cumulative width + widthSum += imageSourceObj.width; + }); + + return layers; +}; + +/** + * @param {Array.<{src: *, width: *, height: *}>} images + * @return {ol.View} + */ +dlfUtils.createOl3View = function (images) { + + // + // Calculate map extent + // + var maxLonX = images.reduce(function (prev, curr) { + return prev + curr.width; + }, 0), + maxLatY = images.reduce(function (prev, curr) { + return Math.max(prev, curr.height); + }, 0), + extent = [0, -maxLatY, maxLonX, 0]; + + // globally define max zoom + window.OL3_MAX_ZOOM = 8; + + // define map projection + var proj = new ol.proj.Projection({ + code: 'kitodo-image', + units: 'pixels', + extent: extent + }); + + // define view + var viewParams = { + projection: proj, + center: ol.extent.getCenter(extent), + zoom: 1, + maxZoom: window.OL3_MAX_ZOOM, + extent + }; + + return new ol.View(viewParams); +}; + +/** + * Returns true if the specified value is not undefined + * @param {?} val + * @return {boolean} + */ +dlfUtils.exists = function (val) { + return val !== undefined; +}; + +/** + * Fetch image data for given image sources. + * + * @param {Array.<{url: *, mimetype: *}>} imageSourceObjs + * @return {JQueryStatic.Deferred} + */ +dlfUtils.fetchImageData = function (imageSourceObjs) { + + // use deferred for async behavior + var deferredResponse = new $.Deferred(); + + /** + * This holds information about the loading state of the images + * @type {Array.} + */ + var imageSourceData = [], + loadCount = 0, + finishLoading = function finishLoading() { + loadCount += 1; + + if (loadCount === imageSourceObjs.length) { + deferredResponse.resolve(imageSourceData); + } + }; + + imageSourceObjs.forEach(function (imageSourceObj, index) { + if (imageSourceObj.mimetype === dlfUtils.CUSTOM_MIMETYPE.ZOOMIFY) { + dlfUtils.fetchZoomifyData(imageSourceObj) + .done(function (imageSourceDataObj) { + imageSourceData[index] = imageSourceDataObj; + finishLoading(); + }); + } else if (imageSourceObj.mimetype === dlfUtils.CUSTOM_MIMETYPE.IIIF) { + dlfUtils.getIIIFResource(imageSourceObj) + .done(function (imageSourceDataObj) { + imageSourceData[index] = imageSourceDataObj; + finishLoading(); + }); + } else if (imageSourceObj.mimetype === dlfUtils.CUSTOM_MIMETYPE.IIP) { + dlfUtils.fetchIIPData(imageSourceObj) + .done(function (imageSourceDataObj) { + imageSourceData[index] = imageSourceDataObj; + finishLoading(); + }); + } else { + // In the worse case expect static image file + dlfUtils.fetchStaticImageData(imageSourceObj) + .done(function (imageSourceDataObj) { + imageSourceData[index] = imageSourceDataObj; + finishLoading(); + }); + } + }); + + return deferredResponse; +}; + + +/** + * Fetches the image data for static images source. + * + * @param {{url: *, mimetype: *}} imageSourceObj + * @return {JQueryStatic.Deferred} + */ +dlfUtils.fetchStaticImageData = function (imageSourceObj) { + + // use deferred for async behavior + var deferredResponse = new $.Deferred(); + + // Create new Image object. + var image = new Image(); + + // Register onload handler. + image.onload = function () { + + var imageDataObj = { + src: this.src, + mimetype: imageSourceObj.mimetype, + width: this.width, + height: this.height + }; + + deferredResponse.resolve(imageDataObj); + }; + + // Initialize image loading. + image.src = imageSourceObj.url; + + return deferredResponse; +}; + +/** + * @param imageSourceObj + * @returns {JQueryStatic.Deferred} + */ +dlfUtils.getIIIFResource = function getIIIFResource(imageSourceObj) { + + var deferredResponse = new $.Deferred(); + var type = 'GET'; + $.ajax({ + url: dlfViewerSource.IIIF.getMetdadataURL(imageSourceObj.url), + type, + dataType: 'json' + }).done(cb); + + function cb(data) { + var mimetype = imageSourceObj.mimetype, + uri, + imageResource; + if (dlfUtils.supportsIIIF(data)) { + if (data['@context'] && data['@context'] === 'http://iiif.io/api/image/2/context.json') { + uri = decodeURI(data['@id']); + uri = dlfUtils.removeInfoJson(uri); + imageResource = dlfUtils.buildImageV2(mimetype, uri, data); + deferredResponse.resolve(imageResource); + } else if (data['@context'] && + (data['@context'] === 'http://iiif.io/api/image/3/context.json' || + Array.isArray(data['@context']) && data['@context'].includes('http://iiif.io/api/image/3/context.json'))) { + uri = decodeURI(data['id']); + uri = dlfUtils.removeInfoJson(uri); + imageResource = dlfUtils.buildImageV3(mimetype, uri, data); + deferredResponse.resolve(imageResource); + } else { + uri = imageSourceObj.url; + uri = dlfUtils.removeInfoJson(uri); + imageResource = dlfUtils.buildImageV1(mimetype, uri, data); + deferredResponse.resolve(imageResource); + } + } + } + + return deferredResponse; +}; + +/** + * @param uri + * @returns {*} + */ +dlfUtils.removeInfoJson = function removeInfoJson(uri) { + if (uri.endsWith('/info.json')) { + uri = uri.substr(0, uri.lastIndexOf('/')); + } + return uri; +}; + +/** + * + * @param data + * @param data.protocol + * @param data.identifier + * @param data.width + * @param data.height + * @param data.profile + * @param data.documentElement + * @returns {boolean} + */ +dlfUtils.supportsIIIF = function supportsIIIF(data) { + // Version 2.0 and forwards + if (data.protocol && data.protocol === 'http://iiif.io/api/image' || + data['@context'] && data['@context'] === "http://iiif.io/api/image/2/context.json") { + return true; + // Version 1.1 + } else if (data['@context'] && ( + data['@context'] === "http://library.stanford.edu/iiif/image-api/1.1/context.json" || + data['@context'] === "http://iiif.io/api/image/1/context.json")) { + return true; + // Version 1.0 + } else if (data.profile && + data.profile.indexOf("http://library.stanford.edu/iiif/image-api/compliance.html") === 0) { + return true; + } else if (data.identifier && data.width && data.height) { + return true; + } else return data.documentElement && "info" === data.documentElement.tagName && + "http://library.stanford.edu/iiif/image-api/ns/" === data.documentElement.namespaceURI; +}; + +dlfUtils.iiifProfiles = { + version1: { + level0: { + supports: [], + formats: [], + qualities: ['native'] + }, + level1: { + supports: ['regionByPx', 'sizeByW', 'sizeByH', 'sizeByPct'], + formats: ['jpg'], + qualities: ['native'] + }, + level2: { + supports: ['regionByPx', 'regionByPct', 'sizeByW', 'sizeByH', 'sizeByPct', + 'sizeByConfinedWh', 'sizeByWh'], + formats: ['jpg', 'png'], + qualities: ['native', 'color', 'grey', 'bitonal'] + } + }, + version2: { + level0: { + supports: [], + formats: ['jpg'], + qualities: ['default'] + }, + level1: { + supports: ['regionByPx', 'sizeByW', 'sizeByH', 'sizeByPct'], + formats: ['jpg'], + qualities: ['default'] + }, + level2: { + supports: ['regionByPx', 'regionByPct', 'sizeByW', 'sizeByH', 'sizeByPct', + 'sizeByConfinedWh', 'sizeByDistortedWh', 'sizeByWh'], + formats: ['jpg', 'png'], + qualities: ['default', 'bitonal'] + } + }, + version3: { + level0: { + supports: [], + formats: ['jpg'], + qualities: ['default'] + }, + level1: { + supports: ['regionByPx', 'regionSquare', 'sizeByW', 'sizeByH'], + formats: ['jpg'], + qualities: ['default'] + }, + level2: { + supports: ['regionByPx', 'regionSquare', 'regionByPct', + 'sizeByW', 'sizeByH', 'sizeByPct', 'sizeByConfinedWh', 'sizeByWh'], + formats: ['jpg'], + qualities: ['default', 'bitonal'] + } + }, + none: { + none: { + supports: [], + formats: [], + qualities: [] + } + } +}; + +/** + * + * @param mimetype + * @param uri + * @param jsonld + * @param jsonld.width + * @param jsonld.height + * @param jsonld.tiles + * @param jsonld.extraFormats + * @param jsonld.extraQualities + * @param jsonld.extraFeatures + * @param jsonld.profile + * @returns {{src: *, width, height, tilesize: [*,*], qualities: *, formats: *, resolutions: *, mimetype: *}} + */ +dlfUtils.buildImageV3 = function buildImageV2(mimetype, uri, jsonld) { + var levelProfile = this.getIiifComplianceLevelProfile(jsonld, 'version3'); + return { + src: uri, + version: 'version3', + width: jsonld.width, + height: jsonld.height, + tilesize: jsonld.tiles !== undefined ? [jsonld.tiles.map(function(a) { + return a.width; + })[0], jsonld.tiles.map(function (a) { + return a.height === undefined ? a.width : a.height; + })[0]] : undefined, + sizes: jsonld.sizes === undefined ? undefined : jsonld.sizes.map(function(size) { + return [size.width, size.height]; + }), + qualities: ['default'].concat(levelProfile.qualities).concat(jsonld.extraQualities === undefined ? [] : jsonld.extraQualities), + formats: ['jpg'].concat(levelProfile.formats).concat(jsonld.extraFormats === undefined ? [] : jsonld.extraFormats), + supports: levelProfile.supports.concat(jsonld.extraFeatures === undefined ? [] : jsonld.extraFeatures), + resolutions: jsonld.tiles !== undefined ? jsonld.tiles.map(function (a) { + return a.scaleFactors; + })[0] : [], + mimetype: mimetype + }; +}; + +/** + * + * @param mimetype + * @param uri + * @param jsonld + * @param jsonld.tiles + * @param jsonld.width + * @param jsonld.height + * @param jsonld.profile + * @param jsonld.scaleFactors + * @returns {{src: *, width, height, tilesize: [*,*], qualities: *, formats: *, resolutions: *, mimetype: *}} + */ +dlfUtils.buildImageV2 = function buildImageV2(mimetype, uri, jsonld) { + if (typeof jsonld.profile === "string") { + jsonld.profile = [jsonld.profile, {}]; + } + if (jsonld.profile !== undefined && jsonld.profile.length < 2) { + jsonld.profile.push({}); + } + var levelProfile = this.getIiifComplianceLevelProfile(jsonld, 'version2'); + return { + src: uri, + version: 'version2', + width: jsonld.width, + height: jsonld.height, + tilesize: jsonld.tiles !== undefined ? [jsonld.tiles.map(function(a) { + return a.width; + })[0], jsonld.tiles.map(function (a) { + return a.height === undefined ? a.width : a.height; + })[0]] : undefined, + sizes: jsonld.sizes === undefined ? undefined : jsonld.sizes.map(function(size) { + return [size.width, size.height]; + }), + qualities: ['default'].concat(levelProfile.qualities).concat(jsonld.profile[1].qualities === undefined ? [] : jsonld.profile[1].qualities), + formats: ['jpg'].concat(levelProfile.formats).concat(jsonld.profile[1].formats === undefined ? [] : jsonld.profile[1].formats), + supports: levelProfile.supports.concat(jsonld.profile[1].supports === undefined ? [] : jsonld.profile[1].supports), + resolutions: jsonld.tiles !== undefined ? jsonld.tiles.map(function (a) { + return a.scaleFactors; + })[0] : [], + mimetype: mimetype + }; +}; + +/** + * + * @param mimetype + * @param uri + * @param jsonld + * @param jsonld.width + * @param jsonld.height + * @param jsonld.scale_factors + * @param jsonld.tile_width + * @param jsonld.tile_height + * @param jsonld.qualities + * @param jsonld.formats + * @returns {{src: *, version, width, height, tilesize: [*,*], qualities: *, formats: *, resolutions: *, mimetype: *}} + */ +dlfUtils.buildImageV1 = function buildImageV1(mimetype, uri, jsonld) { + var levelProfile = this.getIiifComplianceLevelProfile(jsonld, 'version1'); + return { + src: uri, + version: 'version1', + width: jsonld.width, + height: jsonld.height, + tilesize: jsonld.tile_width === undefined ? jsonld.tile_height === undefined ? undefined : jsonld.tile_height : + jsonld.tile_height === undefined ? jsonld.tile_width : [jsonld.tile_width, jsonld.tile_height], + qualities: ['native'].concat(levelProfile.qualities).concat(jsonld.qualities === undefined ? [] : jsonld.qualities), + formats: ['jpg'].concat(levelProfile.formats).concat(jsonld.formats === undefined ? [] : jsonld.formats), + supports:levelProfile.supports, + resolutions: jsonld.scale_factors, + mimetype + }; +}; + +/** + * + * @param jsonld + * @param jsonld.profile + * @param version + * @returns string + */ +dlfUtils.getIiifComplianceLevelProfile = function(jsonld, version) { + var regexVersion1 = new RegExp('^https?\\:\\/\\/library\\.stanford\\.edu\\/iiif\\/image-api\\/(1\\.1\\/)?compliance\\.html#level[0-2]$'), + regexVersion2 = new RegExp('^https?\\:\\/\\/iiif\\.io\\/api\\/image\\/2\\/level[0-2](\\.json)?$'), + regexVersion3 = new RegExp('(^https?\\:\\/\\/iiif\\.io\\/api\\/image\\/3\\/level[0-2](\\.json)?$)|(^level[0-2]$)'), + level; + if (jsonld.profile === undefined) { + return dlfUtils.iiifProfiles.none.none; + } + switch (version) { + case 'version1': + if (regexVersion1.test(jsonld.profile)) { + level = jsonld.profile; + } + break; + case 'version2': + if (typeof jsonld.profile === 'string' && regexVersion2.test(jsonld.profile)) { + level = jsonld.profile; + } + if (Array.isArray(jsonld.profile) && jsonld.profile.length >= 1 && typeof jsonld.profile[0] === 'string' && regexVersion2.test(jsonld.profile[0])) { + level = jsonld.profile[0]; + } + break; + case 'version3': + if (regexVersion3.test(jsonld.profile)) { + level = jsonld.profile; + } + break; + default: + } + if (level !== undefined) { + level = level.match(/level[0-2](\.json)?$/); + level = Array.isArray(level) ? level[0].replace('.json', '') : undefined; + if (level !== undefined) { + return dlfUtils.iiifProfiles[version][level]; + } + } + return dlfUtils.iiifProfiles.none.none; +}; + +/** + * Fetches the image data for iip images source. + * + * @param {{url: *, mimetype: *}} imageSourceObj + * @return {JQueryStatic.Deferred} + */ +dlfUtils.fetchIIPData = function (imageSourceObj) { + + // use deferred for async behavior + var deferredResponse = new $.Deferred(); + + $.ajax({ + url: dlfViewerSource.IIP.getMetdadataURL(imageSourceObj.url) //'http://localhost:8000/fcgi-bin/iipsrv.fcgi?FIF=F4713/HD7.tif&obj=IIP,1.0&obj=Max-size&obj=Tile-size&obj=Resolution-number', + }).done(cb); + function cb(response, type) { + if (type !== 'success') throw new Error('Problems while fetching ImageProperties.xml'); + + var imageDataObj = $.extend({ + src: imageSourceObj.url, + mimetype: imageSourceObj.mimetype + }, dlfViewerSource.IIP.parseMetadata(response)); + + deferredResponse.resolve(imageDataObj); + } + + return deferredResponse; +}; + +/** + * Fetch image data for zoomify source. + * + * @param {{url: *, mimetype: *}} imageSourceObj + * @return {JQueryStatic.Deferred} + */ +dlfUtils.fetchZoomifyData = function (imageSourceObj) { + + // use deferred for async behavior + var deferredResponse = new $.Deferred(); + + $.ajax({ + url: imageSourceObj.url + }).done(cb); + function cb(response, type) { + if (type !== 'success') { + throw new Error('Problems while fetching ImageProperties.xml'); + } + + var properties = $(response).find('IMAGE_PROPERTIES'); + + var imageDataObj = { + src: imageSourceObj.url.substring(0, imageSourceObj.url.lastIndexOf("/") + 1), + width: parseInt(properties.attr('WIDTH')), + height: parseInt(properties.attr('HEIGHT')), + tilesize: parseInt(properties.attr('TILESIZE')), + mimetype: imageSourceObj.mimetype + }; + + deferredResponse.resolve(imageDataObj); + } + + return deferredResponse; +}; + +/** + * @param {string} name Name of the cookie + * @return {string|null} Value of the cookie + * @TODO replace unescape function + */ +dlfUtils.getCookie = function (name) { + + var results = document.cookie.match("(^|;) ?" + name + "=([^;]*)(;|$)"); + + if (results) { + + return decodeURI(results[2]); + } else { + + return null; + } +}; + +/** + * Returns url parameters + * @returns {Object|undefined} + */ +dlfUtils.getUrlParams = function () { + if (Object.prototype.hasOwnProperty.call(location, 'search')) { + var search = decodeURIComponent(location.search).slice(1).split('&'), + params = {}; + + search.forEach(function (item) { + var s = item.split('='); + params[s[0]] = s[1]; + }); + + return params; + } + return undefined; +}; + +/** + * Returns true if the specified value is null. + * @param {?} val + * @return {boolean} + */ +dlfUtils.isNull = function (val) { + return val === null; +}; + +/** + * Returns true if the specified value is null, empty or undefined. + * @param {?} val + * @return {boolean} + */ +dlfUtils.isNullEmptyUndefinedOrNoNumber = function (val) { + return val === null || val === undefined || val === '' || isNaN(val); +}; + +/** + * @param {Array.<{url: *, mimetype: *}>} imageObjs + * @return {boolean} + */ +dlfUtils.isCorsEnabled = function (imageObjs) { + // fix for proper working with ie + if (!window.location.origin) { + window.location.origin = window.location.protocol + '//' + window.location.hostname + + (window.location.port ? ':' + window.location.port : ''); + } + + // fetch data from server + // with access control allowed + var response = true; + + imageObjs.forEach(function (imageObj) { + var url = imageObj.mimetype === dlfUtils.CUSTOM_MIMETYPE.ZOOMIFY + ? imageObj.url.replace('ImageProperties.xml', 'TileGroup0/0-0-0.jpg') + : + imageObj.mimetype === dlfUtils.CUSTOM_MIMETYPE.IIIF + ? dlfViewerSource.IIIF.getMetdadataURL(imageObj.url) + : imageObj.mimetype === dlfUtils.CUSTOM_MIMETYPE.IIP + ? dlfViewerSource.IIP.getMetdadataURL(imageObj.url) + : imageObj.url; + + url = window.location.origin + window.location.pathname + '?eID=tx_dlf_pageview_proxy&url=' + encodeURIComponent(url) + '&header=2'; + + $.ajax({ + url: url, + async: false + }).done(function (data, type) { + response = type === 'success' && data.indexOf('Access-Control-Allow-Origin') !== -1; + }).fail(function (data, type) { + response = false; + }); + }); + return response; +}; + +/** + * Functions checks if WebGL is enabled in the browser + * @return {boolean} + */ +dlfUtils.isWebGLEnabled = function () { + if (!!window.WebGLRenderingContext) { + var canvas = document.createElement("canvas"), + rendererNames = ["webgl", "experimental-webgl", "moz-webgl", "webkit-3d"], + context = false; + + for (var i = 0; i < rendererNames.length; i++) { + try { + context = canvas.getContext(rendererNames[i]); + if (context && typeof context.getParameter === "function") { + // WebGL is enabled; + return true; + } + } catch (e) {} + } + // WebGL not supported + return false; + } + + // WebGL not supported + return false; +}; + +/** + * @param {Element} element + * @return {Object} + */ +dlfUtils.parseDataDic = function (element) { + var dataDicString = $(element).attr('data-dic'), + dataDicRecords = dataDicString.split(';'), + dataDic = {}; + + for (var i = 0, ii = dataDicRecords.length; i < ii; i++) { + var key = dataDicRecords[i].split(':')[0], + value = dataDicRecords[i].split(':')[1]; + dataDic[key] = value; + } + + return dataDic; +}; + +/** + * Set a cookie value + * + * @param {string} name The key of the value + * @param {?} value The value to save + */ +dlfUtils.setCookie = function (name, value) { + + document.cookie = name + "=" + decodeURI(value) + "; path=/"; +}; + +/** + * Scales down the given features geometries. as a further improvement this function + * adds a unique id to every feature + * @param {Array.} features + * @param {Object} imageObj + * @param {number} width + * @param {number} height + * @param {number=} opt_offset + * @deprecated + * @return {Array.} + */ +dlfUtils.scaleToImageSize = function (features, imageObj, width, height, opt_offset) { + + // update size / scale settings of imageObj + var image = void 0; + if (width && height) { + + image = { + 'width': width, + 'height': height, + 'scale': imageObj.width / width + }; + } + + if (image === undefined) return []; + + var scale = image.scale, + offset = opt_offset !== undefined ? opt_offset : 0; + + // do rescaling and set a id + for (var i in features) { + + var oldCoordinates = features[i].getGeometry().getCoordinates()[0], + newCoordinates = []; + + for (var j = 0; j < oldCoordinates.length; j++) { + newCoordinates.push( + [offset + scale * oldCoordinates[j][0], 0 - scale * oldCoordinates[j][1]]); + } + + features[i].setGeometry(new ol.geom.Polygon([newCoordinates])); + + // set index + dlfUtils.RUNNING_INDEX += 1; + features[i].setId('' + dlfUtils.RUNNING_INDEX); + } + + return features; +}; + +/** + * Trim text in the feature to avoid comparison against for e.g. ',' or '.'. + * @param {string} string + * @param {string} character + * @return {string} + */ +function trimByChar(string, character) { + const arr = Array.from(string); + const first = arr.findIndex((char) => char !== character); + const last = arr.reverse().findIndex((char) => char !== character); + return (first === -1 && last === -1) ? '' : string.substring(first, string.length - last); +} + +/** + * Trim text in the feature to avoid comparison against given list of chars. + * @param {string} string + * @param {Array} characters + * @return {string} + */ +function trimByChars(string, characters) { + var trimmed = string; + + for (const character of characters) { + trimmed = trimByChar(trimmed, character); + } + + return trimmed; +} + +/** + * Search a feature collection for a feature with the given text + * @param {Array.} featureCollection + * @param {string} text + * @return {Array.|undefined} + */ +dlfUtils.searchFeatureCollectionForText = function (featureCollection, text) { + var features = []; + featureCollection.forEach(function (ft) { + if (ft.get('fulltext') !== undefined) { + var trimmedFt = trimByChars( + ft.get('fulltext'), + [',', '.', ';', ':', '-', '\'', '"', '!', '?', '(', ')', '[', ']'] + ); + if (trimmedFt.toLowerCase() === text.toLowerCase()) { + features.push(ft); + } + } + }); + return features.length > 0 ? features : undefined; +}; diff --git a/Resources/Private/JavaScript/Kitodo/Search/SearchInDocument.js b/Resources/Private/JavaScript/Kitodo/Search/SearchInDocument.js new file mode 100644 index 0000000..190f113 --- /dev/null +++ b/Resources/Private/JavaScript/Kitodo/Search/SearchInDocument.js @@ -0,0 +1,285 @@ +/** + * (c) Kitodo. Key to digital objects e.V. + * + * This file is part of the Kitodo and TYPO3 projects. + * + * @license GNU General Public License version 3 or later. + * For the full copyright and license information, please read the + * LICENSE.txt file that was distributed with this source code. + */ + +/** + * This function increases the start parameter of the search form and submits + * the form. + * + * @returns void + */ +function nextResultPage() { + var currentStart = $("#tx-dlf-search-in-document-form input[id='tx-dlf-search-in-document-start']").val(); + var newStart = parseInt(currentStart) + 20; + $("#tx-dlf-search-in-document-form input[id='tx-dlf-search-in-document-start']").val(newStart); + $('#tx-dlf-search-in-document-form').submit(); +}; + +/** + * This function decreases the start parameter of the search form and submits + * the form. + * + * @returns void + */ +function previousResultPage() { + var currentStart = $("#tx-dlf-search-in-document-form input[id='tx-dlf-search-in-document-start']").val(); + var newStart = (parseInt(currentStart) > 20) ? (parseInt(currentStart) - 20) : 0; + $("#tx-dlf-search-in-document-form input[id='tx-dlf-search-in-document-start']").val(newStart); + $('#tx-dlf-search-in-document-form').submit(); +}; + +/** + * This function resets the start parameter on new queries. + * + * @returns void + */ +function resetStart() { + $("#tx-dlf-search-in-document-form input[id='tx-dlf-search-in-document-start']").val(0); +} + +/** + * Add highlight effect for found search phrase. + * @param {array} highlightIds + * + * @returns void + */ +function addHighlightEffect(highlightIds) { + // TODO: highlight found phrase in full text - verify page? + if (highlightIds.length > 0) { + highlightIds.forEach(function (highlightId) { + var targetElement = $('#' + highlightId); + + if (targetElement.length > 0 && !targetElement.hasClass('highlight')) { + targetElement.addClass('highlight'); + } + }); + } +} + +/** + * Get base URL for snippet links. + * + * @param {string} id + * + * @returns {string} + */ +function getBaseUrl(id) { + // Take the workview baseUrl from the form action. + // The URL may be in the following form + // - http://example.com/index.php?id=14 + // - http://example.com/workview (using slug on page with uid=14) + var baseUrl = $("form#tx-dlf-search-in-document-form").attr('action'); + + // check if action URL contains id, if not, get URL from window + if(baseUrl.split('?')[0].indexOf(id) === -1) { + baseUrl = $(location).attr('href'); + } + + return baseUrl; +} + +/** + * Get current URL query parameters. + * It returns array of params in form 'param=value' if there are any params supplied in the given url. If there are none it returns empty array + * + * @param {string} baseUrl + * + * @returns {array} array with params or empty + */ +function getCurrentQueryParams(baseUrl) { + if(baseUrl.indexOf('?') > 0) { + return baseUrl.slice(baseUrl.indexOf('?') + 1).split('&'); + } + + return []; +} + +/** + * Get all URL query parameters for snippet links. + * All means that it includes together params which were already supplied in the page url and params which are returned as search results. + * + * @param {string} baseUrl + * @param {array} queryParams + * + * @returns {array} array with params in form 'param' => 'value' + */ +function getAllQueryParams(baseUrl, queryParams) { + var params = getCurrentQueryParams(baseUrl); + + var queryParam; + for(var i = 0; i < params.length; i++) { + queryParam = params[i].split('='); + if(queryParams.indexOf(queryParam[0]) === -1) { + queryParams.push(queryParam[0]); + queryParams[queryParam[0]] = queryParam[1]; + } + } + return queryParams; +} + +/** + * Get needed URL query parameters. + * It returns array of params as objects 'param' => 'value'. It contains exactly 3 params which are taken out of search result. + * + * @param {array} element + * + * @returns {array} array with params in form 'param' => 'value' + */ +function getNeededQueryParams(element) { + var searchWord = element['snippet']; + searchWord = searchWord.substring(searchWord.indexOf('') + 4, searchWord.indexOf('')); + + var id = $("input[id='tx-dlf-search-in-document-id']").attr('name'); + var highlightWord = $("input[id='tx-dlf-search-in-document-highlight-word']").attr('name'); + var page = $("input[id='tx-dlf-search-in-document-page']").attr('name'); + + var queryParams = []; + + if(getBaseUrl(element['uid']).split('?')[0].indexOf(element['uid']) === -1) { + queryParams.push(id); + queryParams[id] = element['uid']; + } + queryParams.push(highlightWord); + queryParams[highlightWord] = encodeURIComponent(searchWord); + queryParams.push(page); + queryParams[page] = element['page']; + + return queryParams; +} + +/** + * Get snippet link. + * + * @param {array} element + * + * @returns {string} + */ +function getLink(element) { + var baseUrl = getBaseUrl(element['uid']); + + var queryParams = getNeededQueryParams(element); + + if (baseUrl.indexOf('?') > 0) { + queryParams = getAllQueryParams(baseUrl, queryParams); + baseUrl = baseUrl.split('?')[0]; + } + + var link = baseUrl + '?'; + + // add query params to result link + for(var i = 0; i < queryParams.length; i++) { + link += queryParams[i] + '=' + queryParams[queryParams[i]] + '&'; + } + link = link.slice(0, -1); + return link; +} + +function getNavigationButtons(start, numFound) { + var buttons = ""; + + if (start > 0) { + buttons += ''; + } + + if (numFound > (start + 20)) { + buttons += ''; + } + return buttons; +} + +function search() { + resetStart(); + + $('#tx-dlf-search-in-document-loading').show(); + $('#tx-dlf-search-in-document-clearing').hide(); + $('#tx-dlf-search-in-document-button-next').hide(); + $('#tx-dlf-search-in-document-button-previous').hide(); + // Send the data using post + $.post( + "https://sdvtypo3ddbzeitungsportaldev.slub-dresden.de/", + { + eID: "tx_dlf_search_in_document", + q: $("input[id='tx-dlf-search-in-document-query']").val(), + uid: $("input[id='tx-dlf-search-in-document-id']").val(), + start: $("input[id='tx-dlf-search-in-document-start']").val(), + encrypted: $("input[id='tx-dlf-search-in-document-encrypted']").val(), + }, + function (data) { + var resultItems = []; + var resultList = '
    '; + var start = -1; + if (data['numFound'] > 0) { + data['documents'].forEach(function (element, i) { + if (start < 0) { + start = i; + } + + if (element['snippet'].length > 0) { + resultItems[element['page']] = '' + + $('#tx-dlf-search-in-document-label-page').text() + ' ' + element['page'] + + '
    ' + + '' + + '' + element['snippet'] + '' + + ''; + } + + addHighlightEffect(element['highlight']); + }); + // Sort result by page. + resultItems.sort(function (a, b) { + return a - b; + }); + resultItems.forEach(function (item, index) { + resultList += '
  • ' + item + '
  • '; + }); + } else { + resultList += '
  • ' + $('#tx-dlf-search-in-document-label-noresult').text() + '
  • '; + } + resultList += '
'; + resultList += getNavigationButtons(start, data['numFound']); + $('#tx-dlf-search-in-document-results').html(resultList); + }, + "json" + ) + .done(function (data) { + $('#tx-dfgviewer-sru-results-loading').hide(); + $('#tx-dfgviewer-sru-results-clearing').show(); + }); +} + +function clearSearch() { + $('#tx-dlf-search-in-document-results ul').remove(); + $('.results-active-indicator').remove(); + $('#tx-dlf-search-in-document-query').val(''); +} + +function triggerSearchAfterHitLoad() { + var queryParams = getCurrentQueryParams(getBaseUrl(" ")); + + for(var i = 0; i < queryParams.length; i++) { + var queryParam = queryParams[i].split('='); + + if(queryParam[0].indexOf($("input[id='tx-dlf-search-in-document-highlight-word']").attr('name')) != -1) { + $("input[id='tx-dlf-search-in-document-query']").val(queryParam[1]); + search(); + break; + } + } +} + +$(document).ready(function() { + document.getElementById('tx-dlf-search-in-document-query').addEventListener("keydown", function (e) { + if (e.key === 'Enter') { + e.preventDefault(); + search(); + } + }); + + triggerSearchAfterHitLoad() +}); diff --git a/Resources/Public/JavaScript/ddbKitodoZeitungsportal.js b/Resources/Public/JavaScript/ddbKitodoZeitungsportal.js index 9534f0c..f02f9fa 100644 --- a/Resources/Public/JavaScript/ddbKitodoZeitungsportal.js +++ b/Resources/Public/JavaScript/ddbKitodoZeitungsportal.js @@ -1,4 +1,17 @@ -"use strict"; +/*! jQuery UI - v1.12.1 - 2017-11-09 +* http://jqueryui.com +* Includes: widget.js, position.js, disable-selection.js, keycode.js, unique-id.js, widgets/resizable.js, widgets/autocomplete.js, widgets/menu.js, widgets/mouse.js, widgets/slider.js +* Copyright jQuery Foundation and other contributors; Licensed MIT */ +(function(t){"function"==typeof define&&define.amd?define(["jquery"],t):t(jQuery)})((function(t){t.ui=t.ui||{},t.ui.version="1.12.1";var e=0,i=Array.prototype.slice;t.cleanData=function(e){return function(i){var n,s,o;for(o=0;null!=(s=i[o]);o++)try{n=t._data(s,"events"),n&&n.remove&&t(s).triggerHandler("remove")}catch(t){}e(i)}}(t.cleanData),t.widget=function(e,i,n){var s,o,r,a={},h=e.split(".")[0];e=e.split(".")[1];var l=h+"-"+e;return n||(n=i,i=t.Widget),t.isArray(n)&&(n=t.extend.apply(null,[{}].concat(n))),t.expr[":"][l.toLowerCase()]=function(e){return!!t.data(e,l)},t[h]=t[h]||{},s=t[h][e],o=t[h][e]=function(t,e){return this._createWidget?(arguments.length&&this._createWidget(t,e),void 0):new o(t,e)},t.extend(o,s,{version:n.version,_proto:t.extend({},n),_childConstructors:[]}),r=new i,r.options=t.widget.extend({},r.options),t.each(n,(function(e,n){return t.isFunction(n)?(a[e]=function(){function t(){return i.prototype[e].apply(this,arguments)}function s(t){return i.prototype[e].apply(this,t)}return function(){var e,i=this._super,o=this._superApply;return this._super=t,this._superApply=s,e=n.apply(this,arguments),this._super=i,this._superApply=o,e}}(),void 0):(a[e]=n,void 0)})),o.prototype=t.widget.extend(r,{widgetEventPrefix:s?r.widgetEventPrefix||e:e},a,{constructor:o,namespace:h,widgetName:e,widgetFullName:l}),s?(t.each(s._childConstructors,(function(e,i){var n=i.prototype;t.widget(n.namespace+"."+n.widgetName,o,i._proto)})),delete s._childConstructors):i._childConstructors.push(o),t.widget.bridge(e,o),o},t.widget.extend=function(e){for(var n,s,o=i.call(arguments,1),r=0,a=o.length;a>r;r++)for(n in o[r])s=o[r][n],o[r].hasOwnProperty(n)&&void 0!==s&&(e[n]=t.isPlainObject(s)?t.isPlainObject(e[n])?t.widget.extend({},e[n],s):t.widget.extend({},s):s);return e},t.widget.bridge=function(e,n){var s=n.prototype.widgetFullName||e;t.fn[e]=function(o){var r="string"==typeof o,a=i.call(arguments,1),h=this;return r?this.length||"instance"!==o?this.each((function(){var i,n=t.data(this,s);return"instance"===o?(h=n,!1):n?t.isFunction(n[o])&&"_"!==o.charAt(0)?(i=n[o].apply(n,a),i!==n&&void 0!==i?(h=i&&i.jquery?h.pushStack(i.get()):i,!1):void 0):t.error("no such method '"+o+"' for "+e+" widget instance"):t.error("cannot call methods on "+e+" prior to initialization; "+"attempted to call method '"+o+"'")})):h=void 0:(a.length&&(o=t.widget.extend.apply(null,[o].concat(a))),this.each((function(){var e=t.data(this,s);e?(e.option(o||{}),e._init&&e._init()):t.data(this,s,new n(o,this))}))),h}},t.Widget=function(){},t.Widget._childConstructors=[],t.Widget.prototype={widgetName:"widget",widgetEventPrefix:"",defaultElement:"
",options:{classes:{},disabled:!1,create:null},_createWidget:function(i,n){n=t(n||this.defaultElement||this)[0],this.element=t(n),this.uuid=e++,this.eventNamespace="."+this.widgetName+this.uuid,this.bindings=t(),this.hoverable=t(),this.focusable=t(),this.classesElementLookup={},n!==this&&(t.data(n,this.widgetFullName,this),this._on(!0,this.element,{remove:function(t){t.target===n&&this.destroy()}}),this.document=t(n.style?n.ownerDocument:n.document||n),this.window=t(this.document[0].defaultView||this.document[0].parentWindow)),this.options=t.widget.extend({},this.options,this._getCreateOptions(),i),this._create(),this.options.disabled&&this._setOptionDisabled(this.options.disabled),this._trigger("create",null,this._getCreateEventData()),this._init()},_getCreateOptions:function(){return{}},_getCreateEventData:t.noop,_create:t.noop,_init:t.noop,destroy:function(){var e=this;this._destroy(),t.each(this.classesElementLookup,(function(t,i){e._removeClass(i,t)})),this.element.off(this.eventNamespace).removeData(this.widgetFullName),this.widget().off(this.eventNamespace).removeAttr("aria-disabled"),this.bindings.off(this.eventNamespace)},_destroy:t.noop,widget:function(){return this.element},option:function(e,i){var n,s,o,r=e;if(0===arguments.length)return t.widget.extend({},this.options);if("string"==typeof e)if(r={},n=e.split("."),e=n.shift(),n.length){for(s=r[e]=t.widget.extend({},this.options[e]),o=0;n.length-1>o;o++)s[n[o]]=s[n[o]]||{},s=s[n[o]];if(e=n.pop(),1===arguments.length)return void 0===s[e]?null:s[e];s[e]=i}else{if(1===arguments.length)return void 0===this.options[e]?null:this.options[e];r[e]=i}return this._setOptions(r),this},_setOptions:function(t){var e;for(e in t)this._setOption(e,t[e]);return this},_setOption:function(t,e){return"classes"===t&&this._setOptionClasses(e),this.options[t]=e,"disabled"===t&&this._setOptionDisabled(e),this},_setOptionClasses:function(e){var i,n,s;for(i in e)s=this.classesElementLookup[i],e[i]!==this.options.classes[i]&&s&&s.length&&(n=t(s.get()),this._removeClass(s,i),n.addClass(this._classes({element:n,keys:i,classes:e,add:!0})))},_setOptionDisabled:function(t){this._toggleClass(this.widget(),this.widgetFullName+"-disabled",null,!!t),t&&(this._removeClass(this.hoverable,null,"ui-state-hover"),this._removeClass(this.focusable,null,"ui-state-focus"))},enable:function(){return this._setOptions({disabled:!1})},disable:function(){return this._setOptions({disabled:!0})},_classes:function(e){function i(i,o){var r,a;for(a=0;i.length>a;a++)r=s.classesElementLookup[i[a]]||t(),r=e.add?t(t.unique(r.get().concat(e.element.get()))):t(r.not(e.element).get()),s.classesElementLookup[i[a]]=r,n.push(i[a]),o&&e.classes[i[a]]&&n.push(e.classes[i[a]])}var n=[],s=this;return e=t.extend({element:this.element,classes:this.options.classes||{}},e),this._on(e.element,{remove:"_untrackClassesElement"}),e.keys&&i(e.keys.match(/\S+/g)||[],!0),e.extra&&i(e.extra.match(/\S+/g)||[]),n.join(" ")},_untrackClassesElement:function(e){var i=this;t.each(i.classesElementLookup,(function(n,s){-1!==t.inArray(e.target,s)&&(i.classesElementLookup[n]=t(s.not(e.target).get()))}))},_removeClass:function(t,e,i){return this._toggleClass(t,e,i,!1)},_addClass:function(t,e,i){return this._toggleClass(t,e,i,!0)},_toggleClass:function(t,e,i,n){n="boolean"==typeof n?n:i;var s="string"==typeof t||null===t,o={extra:s?e:i,keys:s?t:e,element:s?this.element:t,add:n};return o.element.toggleClass(this._classes(o),n),this},_on:function(e,i,n){var s,o=this;"boolean"!=typeof e&&(n=i,i=e,e=!1),n?(i=s=t(i),this.bindings=this.bindings.add(i)):(n=i,i=this.element,s=this.widget()),t.each(n,(function(n,r){function a(){return e||o.options.disabled!==!0&&!t(this).hasClass("ui-state-disabled")?("string"==typeof r?o[r]:r).apply(o,arguments):void 0}"string"!=typeof r&&(a.guid=r.guid=r.guid||a.guid||t.guid++);var h=n.match(/^([\w:-]*)\s*(.*)$/),l=h[1]+o.eventNamespace,u=h[2];u?s.on(l,u,a):i.on(l,a)}))},_off:function(e,i){i=(i||"").split(" ").join(this.eventNamespace+" ")+this.eventNamespace,e.off(i).off(i),this.bindings=t(this.bindings.not(e).get()),this.focusable=t(this.focusable.not(e).get()),this.hoverable=t(this.hoverable.not(e).get())},_delay:function(t,e){function i(){return("string"==typeof t?n[t]:t).apply(n,arguments)}var n=this;return setTimeout(i,e||0)},_hoverable:function(e){this.hoverable=this.hoverable.add(e),this._on(e,{mouseenter:function(e){this._addClass(t(e.currentTarget),null,"ui-state-hover")},mouseleave:function(e){this._removeClass(t(e.currentTarget),null,"ui-state-hover")}})},_focusable:function(e){this.focusable=this.focusable.add(e),this._on(e,{focusin:function(e){this._addClass(t(e.currentTarget),null,"ui-state-focus")},focusout:function(e){this._removeClass(t(e.currentTarget),null,"ui-state-focus")}})},_trigger:function(e,i,n){var s,o,r=this.options[e];if(n=n||{},i=t.Event(i),i.type=(e===this.widgetEventPrefix?e:this.widgetEventPrefix+e).toLowerCase(),i.target=this.element[0],o=i.originalEvent)for(s in o)s in i||(i[s]=o[s]);return this.element.trigger(i,n),!(t.isFunction(r)&&r.apply(this.element[0],[i].concat(n))===!1||i.isDefaultPrevented())}},t.each({show:"fadeIn",hide:"fadeOut"},(function(e,i){t.Widget.prototype["_"+e]=function(n,s,o){"string"==typeof s&&(s={effect:s});var r,a=s?s===!0||"number"==typeof s?i:s.effect||i:e;s=s||{},"number"==typeof s&&(s={duration:s}),r=!t.isEmptyObject(s),s.complete=o,s.delay&&n.delay(s.delay),r&&t.effects&&t.effects.effect[a]?n[e](s):a!==e&&n[a]?n[a](s.duration,s.easing,o):n.queue((function(i){t(this)[e](),o&&o.call(n[0]),i()}))}})),t.widget,function(){function e(t,e,i){return[parseFloat(t[0])*(c.test(t[0])?e/100:1),parseFloat(t[1])*(c.test(t[1])?i/100:1)]}function i(e,i){return parseInt(t.css(e,i),10)||0}function n(e){var i=e[0];return 9===i.nodeType?{width:e.width(),height:e.height(),offset:{top:0,left:0}}:t.isWindow(i)?{width:e.width(),height:e.height(),offset:{top:e.scrollTop(),left:e.scrollLeft()}}:i.preventDefault?{width:0,height:0,offset:{top:i.pageY,left:i.pageX}}:{width:e.outerWidth(),height:e.outerHeight(),offset:e.offset()}}var s,o=Math.max,r=Math.abs,a=/left|center|right/,h=/top|center|bottom/,l=/[\+\-]\d+(\.[\d]+)?%?/,u=/^\w+/,c=/%$/,f=t.fn.position;t.position={scrollbarWidth:function(){if(void 0!==s)return s;var e,i,n=t("
"),o=n.children()[0];return t("body").append(n),e=o.offsetWidth,n.css("overflow","scroll"),i=o.offsetWidth,e===i&&(i=n[0].clientWidth),n.remove(),s=e-i},getScrollInfo:function(e){var i=e.isWindow||e.isDocument?"":e.element.css("overflow-x"),n=e.isWindow||e.isDocument?"":e.element.css("overflow-y"),s="scroll"===i||"auto"===i&&e.widthi?"left":e>0?"right":"center",vertical:0>a?"top":n>0?"bottom":"middle"};l>d&&d>r(e+i)&&(c.horizontal="center"),u>p&&p>r(n+a)&&(c.vertical="middle"),c.important=o(r(e),r(i))>o(r(n),r(a))?"horizontal":"vertical",s.using.call(this,t,c)}),h.offset(t.extend(S,{using:a}))}))},t.ui.position={fit:{left:function(t,e){var i,n=e.within,s=n.isWindow?n.scrollLeft:n.offset.left,r=n.width,a=t.left-e.collisionPosition.marginLeft,h=s-a,l=a+e.collisionWidth-r-s;e.collisionWidth>r?h>0&&0>=l?(i=t.left+h+e.collisionWidth-r-s,t.left+=h-i):t.left=l>0&&0>=h?s:h>l?s+r-e.collisionWidth:s:h>0?t.left+=h:l>0?t.left-=l:t.left=o(t.left-a,t.left)},top:function(t,e){var i,n=e.within,s=n.isWindow?n.scrollTop:n.offset.top,r=e.within.height,a=t.top-e.collisionPosition.marginTop,h=s-a,l=a+e.collisionHeight-r-s;e.collisionHeight>r?h>0&&0>=l?(i=t.top+h+e.collisionHeight-r-s,t.top+=h-i):t.top=l>0&&0>=h?s:h>l?s+r-e.collisionHeight:s:h>0?t.top+=h:l>0?t.top-=l:t.top=o(t.top-a,t.top)}},flip:{left:function(t,e){var i,n,s=e.within,o=s.offset.left+s.scrollLeft,a=s.width,h=s.isWindow?s.scrollLeft:s.offset.left,l=t.left-e.collisionPosition.marginLeft,u=l-h,c=l+e.collisionWidth-a-h,f="left"===e.my[0]?-e.elemWidth:"right"===e.my[0]?e.elemWidth:0,d="left"===e.at[0]?e.targetWidth:"right"===e.at[0]?-e.targetWidth:0,p=-2*e.offset[0];0>u?(i=t.left+f+d+p+e.collisionWidth-a-o,(0>i||r(u)>i)&&(t.left+=f+d+p)):c>0&&(n=t.left-e.collisionPosition.marginLeft+f+d+p-h,(n>0||c>r(n))&&(t.left+=f+d+p))},top:function(t,e){var i,n,s=e.within,o=s.offset.top+s.scrollTop,a=s.height,h=s.isWindow?s.scrollTop:s.offset.top,l=t.top-e.collisionPosition.marginTop,u=l-h,c=l+e.collisionHeight-a-h,f="top"===e.my[1],d=f?-e.elemHeight:"bottom"===e.my[1]?e.elemHeight:0,p="top"===e.at[1]?e.targetHeight:"bottom"===e.at[1]?-e.targetHeight:0,g=-2*e.offset[1];0>u?(n=t.top+d+p+g+e.collisionHeight-a-o,(0>n||r(u)>n)&&(t.top+=d+p+g)):c>0&&(i=t.top-e.collisionPosition.marginTop+d+p+g-h,(i>0||c>r(i))&&(t.top+=d+p+g))}},flipfit:{left:function(){t.ui.position.flip.left.apply(this,arguments),t.ui.position.fit.left.apply(this,arguments)},top:function(){t.ui.position.flip.top.apply(this,arguments),t.ui.position.fit.top.apply(this,arguments)}}}}(),t.ui.position,t.fn.extend({disableSelection:function(){var t="onselectstart"in document.createElement("div")?"selectstart":"mousedown";return function(){return this.on(t+".ui-disableSelection",(function(t){t.preventDefault()}))}}(),enableSelection:function(){return this.off(".ui-disableSelection")}}),t.ui.keyCode={BACKSPACE:8,COMMA:188,DELETE:46,DOWN:40,END:35,ENTER:13,ESCAPE:27,HOME:36,LEFT:37,PAGE_DOWN:34,PAGE_UP:33,PERIOD:190,RIGHT:39,SPACE:32,TAB:9,UP:38},t.fn.extend({uniqueId:function(){var t=0;return function(){return this.each((function(){this.id||(this.id="ui-id-"+ ++t)}))}}(),removeUniqueId:function(){return this.each((function(){/^ui-id-\d+$/.test(this.id)&&t(this).removeAttr("id")}))}}),t.ui.ie=!!/msie [\w.]+/.exec(navigator.userAgent.toLowerCase());var n=!1;t(document).on("mouseup",(function(){n=!1})),t.widget("ui.mouse",{version:"1.12.1",options:{cancel:"input, textarea, button, select, option",distance:1,delay:0},_mouseInit:function(){var e=this;this.element.on("mousedown."+this.widgetName,(function(t){return e._mouseDown(t)})).on("click."+this.widgetName,(function(i){return!0===t.data(i.target,e.widgetName+".preventClickEvent")?(t.removeData(i.target,e.widgetName+".preventClickEvent"),i.stopImmediatePropagation(),!1):void 0})),this.started=!1},_mouseDestroy:function(){this.element.off("."+this.widgetName),this._mouseMoveDelegate&&this.document.off("mousemove."+this.widgetName,this._mouseMoveDelegate).off("mouseup."+this.widgetName,this._mouseUpDelegate)},_mouseDown:function(e){if(!n){this._mouseMoved=!1,this._mouseStarted&&this._mouseUp(e),this._mouseDownEvent=e;var i=this,s=1===e.which,o="string"==typeof this.options.cancel&&e.target.nodeName?t(e.target).closest(this.options.cancel).length:!1;return s&&!o&&this._mouseCapture(e)?(this.mouseDelayMet=!this.options.delay,this.mouseDelayMet||(this._mouseDelayTimer=setTimeout((function(){i.mouseDelayMet=!0}),this.options.delay)),this._mouseDistanceMet(e)&&this._mouseDelayMet(e)&&(this._mouseStarted=this._mouseStart(e)!==!1,!this._mouseStarted)?(e.preventDefault(),!0):(!0===t.data(e.target,this.widgetName+".preventClickEvent")&&t.removeData(e.target,this.widgetName+".preventClickEvent"),this._mouseMoveDelegate=function(t){return i._mouseMove(t)},this._mouseUpDelegate=function(t){return i._mouseUp(t)},this.document.on("mousemove."+this.widgetName,this._mouseMoveDelegate).on("mouseup."+this.widgetName,this._mouseUpDelegate),e.preventDefault(),n=!0,!0)):!0}},_mouseMove:function(e){if(this._mouseMoved){if(t.ui.ie&&(!document.documentMode||9>document.documentMode)&&!e.button)return this._mouseUp(e);if(!e.which)if(e.originalEvent.altKey||e.originalEvent.ctrlKey||e.originalEvent.metaKey||e.originalEvent.shiftKey)this.ignoreMissingWhich=!0;else if(!this.ignoreMissingWhich)return this._mouseUp(e)}return(e.which||e.button)&&(this._mouseMoved=!0),this._mouseStarted?(this._mouseDrag(e),e.preventDefault()):(this._mouseDistanceMet(e)&&this._mouseDelayMet(e)&&(this._mouseStarted=this._mouseStart(this._mouseDownEvent,e)!==!1,this._mouseStarted?this._mouseDrag(e):this._mouseUp(e)),!this._mouseStarted)},_mouseUp:function(e){this.document.off("mousemove."+this.widgetName,this._mouseMoveDelegate).off("mouseup."+this.widgetName,this._mouseUpDelegate),this._mouseStarted&&(this._mouseStarted=!1,e.target===this._mouseDownEvent.target&&t.data(e.target,this.widgetName+".preventClickEvent",!0),this._mouseStop(e)),this._mouseDelayTimer&&(clearTimeout(this._mouseDelayTimer),delete this._mouseDelayTimer),this.ignoreMissingWhich=!1,n=!1,e.preventDefault()},_mouseDistanceMet:function(t){return Math.max(Math.abs(this._mouseDownEvent.pageX-t.pageX),Math.abs(this._mouseDownEvent.pageY-t.pageY))>=this.options.distance},_mouseDelayMet:function(){return this.mouseDelayMet},_mouseStart:function(){},_mouseDrag:function(){},_mouseStop:function(){},_mouseCapture:function(){return!0}}),t.ui.plugin={add:function(e,i,n){var s,o=t.ui[e].prototype;for(s in n)o.plugins[s]=o.plugins[s]||[],o.plugins[s].push([i,n[s]])},call:function(t,e,i,n){var s,o=t.plugins[e];if(o&&(n||t.element[0].parentNode&&11!==t.element[0].parentNode.nodeType))for(s=0;o.length>s;s++)t.options[o[s][0]]&&o[s][1].apply(t.element,i)}},t.widget("ui.resizable",t.ui.mouse,{version:"1.12.1",widgetEventPrefix:"resize",options:{alsoResize:!1,animate:!1,animateDuration:"slow",animateEasing:"swing",aspectRatio:!1,autoHide:!1,classes:{"ui-resizable-se":"ui-icon ui-icon-gripsmall-diagonal-se"},containment:!1,ghost:!1,grid:!1,handles:"e,s,se",helper:!1,maxHeight:null,maxWidth:null,minHeight:10,minWidth:10,zIndex:90,resize:null,start:null,stop:null},_num:function(t){return parseFloat(t)||0},_isNumber:function(t){return!isNaN(parseFloat(t))},_hasScroll:function(e,i){if("hidden"===t(e).css("overflow"))return!1;var n=i&&"left"===i?"scrollLeft":"scrollTop",s=!1;return e[n]>0?!0:(e[n]=1,s=e[n]>0,e[n]=0,s)},_create:function(){var e,i=this.options,n=this;this._addClass("ui-resizable"),t.extend(this,{_aspectRatio:!!i.aspectRatio,aspectRatio:i.aspectRatio,originalElement:this.element,_proportionallyResizeElements:[],_helper:i.helper||i.ghost||i.animate?i.helper||"ui-resizable-helper":null}),this.element[0].nodeName.match(/^(canvas|textarea|input|select|button|img)$/i)&&(this.element.wrap(t("
").css({position:this.element.css("position"),width:this.element.outerWidth(),height:this.element.outerHeight(),top:this.element.css("top"),left:this.element.css("left")})),this.element=this.element.parent().data("ui-resizable",this.element.resizable("instance")),this.elementIsWrapper=!0,e={marginTop:this.originalElement.css("marginTop"),marginRight:this.originalElement.css("marginRight"),marginBottom:this.originalElement.css("marginBottom"),marginLeft:this.originalElement.css("marginLeft")},this.element.css(e),this.originalElement.css("margin",0),this.originalResizeStyle=this.originalElement.css("resize"),this.originalElement.css("resize","none"),this._proportionallyResizeElements.push(this.originalElement.css({position:"static",zoom:1,display:"block"})),this.originalElement.css(e),this._proportionallyResize()),this._setupHandles(),i.autoHide&&t(this.element).on("mouseenter",(function(){i.disabled||(n._removeClass("ui-resizable-autohide"),n._handles.show())})).on("mouseleave",(function(){i.disabled||n.resizing||(n._addClass("ui-resizable-autohide"),n._handles.hide())})),this._mouseInit()},_destroy:function(){this._mouseDestroy();var e,i=function(e){t(e).removeData("resizable").removeData("ui-resizable").off(".resizable").find(".ui-resizable-handle").remove()};return this.elementIsWrapper&&(i(this.element),e=this.element,this.originalElement.css({position:e.css("position"),width:e.outerWidth(),height:e.outerHeight(),top:e.css("top"),left:e.css("left")}).insertAfter(e),e.remove()),this.originalElement.css("resize",this.originalResizeStyle),i(this.originalElement),this},_setOption:function(t,e){switch(this._super(t,e),t){case"handles":this._removeHandles(),this._setupHandles();break;default:}},_setupHandles:function(){var e,i,n,s,o,r=this.options,a=this;if(this.handles=r.handles||(t(".ui-resizable-handle",this.element).length?{n:".ui-resizable-n",e:".ui-resizable-e",s:".ui-resizable-s",w:".ui-resizable-w",se:".ui-resizable-se",sw:".ui-resizable-sw",ne:".ui-resizable-ne",nw:".ui-resizable-nw"}:"e,s,se"),this._handles=t(),this.handles.constructor===String)for("all"===this.handles&&(this.handles="n,e,s,w,se,sw,ne,nw"),n=this.handles.split(","),this.handles={},i=0;n.length>i;i++)e=t.trim(n[i]),s="ui-resizable-"+e,o=t("
"),this._addClass(o,"ui-resizable-handle "+s),o.css({zIndex:r.zIndex}),this.handles[e]=".ui-resizable-"+e,this.element.append(o);this._renderAxis=function(e){var i,n,s,o;e=e||this.element;for(i in this.handles)this.handles[i].constructor===String?this.handles[i]=this.element.children(this.handles[i]).first().show():(this.handles[i].jquery||this.handles[i].nodeType)&&(this.handles[i]=t(this.handles[i]),this._on(this.handles[i],{mousedown:a._mouseDown})),this.elementIsWrapper&&this.originalElement[0].nodeName.match(/^(textarea|input|select|button)$/i)&&(n=t(this.handles[i],this.element),o=/sw|ne|nw|se|n|s/.test(i)?n.outerHeight():n.outerWidth(),s=["padding",/ne|nw|n/.test(i)?"Top":/se|sw|s/.test(i)?"Bottom":/^e$/.test(i)?"Right":"Left"].join(""),e.css(s,o),this._proportionallyResize()),this._handles=this._handles.add(this.handles[i])},this._renderAxis(this.element),this._handles=this._handles.add(this.element.find(".ui-resizable-handle")),this._handles.disableSelection(),this._handles.on("mouseover",(function(){a.resizing||(this.className&&(o=this.className.match(/ui-resizable-(se|sw|ne|nw|n|e|s|w)/i)),a.axis=o&&o[1]?o[1]:"se")})),r.autoHide&&(this._handles.hide(),this._addClass("ui-resizable-autohide"))},_removeHandles:function(){this._handles.remove()},_mouseCapture:function(e){var i,n,s=!1;for(i in this.handles)n=t(this.handles[i])[0],(n===e.target||t.contains(n,e.target))&&(s=!0);return!this.options.disabled&&s},_mouseStart:function(e){var i,n,s,o=this.options,r=this.element;return this.resizing=!0,this._renderProxy(),i=this._num(this.helper.css("left")),n=this._num(this.helper.css("top")),o.containment&&(i+=t(o.containment).scrollLeft()||0,n+=t(o.containment).scrollTop()||0),this.offset=this.helper.offset(),this.position={left:i,top:n},this.size=this._helper?{width:this.helper.width(),height:this.helper.height()}:{width:r.width(),height:r.height()},this.originalSize=this._helper?{width:r.outerWidth(),height:r.outerHeight()}:{width:r.width(),height:r.height()},this.sizeDiff={width:r.outerWidth()-r.width(),height:r.outerHeight()-r.height()},this.originalPosition={left:i,top:n},this.originalMousePosition={left:e.pageX,top:e.pageY},this.aspectRatio="number"==typeof o.aspectRatio?o.aspectRatio:this.originalSize.width/this.originalSize.height||1,s=t(".ui-resizable-"+this.axis).css("cursor"),t("body").css("cursor","auto"===s?this.axis+"-resize":s),this._addClass("ui-resizable-resizing"),this._propagate("start",e),!0},_mouseDrag:function(e){var i,n,s=this.originalMousePosition,o=this.axis,r=e.pageX-s.left||0,a=e.pageY-s.top||0,h=this._change[o];return this._updatePrevProperties(),h?(i=h.apply(this,[e,r,a]),this._updateVirtualBoundaries(e.shiftKey),(this._aspectRatio||e.shiftKey)&&(i=this._updateRatio(i,e)),i=this._respectSize(i,e),this._updateCache(i),this._propagate("resize",e),n=this._applyChanges(),!this._helper&&this._proportionallyResizeElements.length&&this._proportionallyResize(),t.isEmptyObject(n)||(this._updatePrevProperties(),this._trigger("resize",e,this.ui()),this._applyChanges()),!1):!1},_mouseStop:function(e){this.resizing=!1;var i,n,s,o,r,a,h,l=this.options,u=this;return this._helper&&(i=this._proportionallyResizeElements,n=i.length&&/textarea/i.test(i[0].nodeName),s=n&&this._hasScroll(i[0],"left")?0:u.sizeDiff.height,o=n?0:u.sizeDiff.width,r={width:u.helper.width()-o,height:u.helper.height()-s},a=parseFloat(u.element.css("left"))+(u.position.left-u.originalPosition.left)||null,h=parseFloat(u.element.css("top"))+(u.position.top-u.originalPosition.top)||null,l.animate||this.element.css(t.extend(r,{top:h,left:a})),u.helper.height(u.size.height),u.helper.width(u.size.width),this._helper&&!l.animate&&this._proportionallyResize()),t("body").css("cursor","auto"),this._removeClass("ui-resizable-resizing"),this._propagate("stop",e),this._helper&&this.helper.remove(),!1},_updatePrevProperties:function(){this.prevPosition={top:this.position.top,left:this.position.left},this.prevSize={width:this.size.width,height:this.size.height}},_applyChanges:function(){var t={};return this.position.top!==this.prevPosition.top&&(t.top=this.position.top+"px"),this.position.left!==this.prevPosition.left&&(t.left=this.position.left+"px"),this.size.width!==this.prevSize.width&&(t.width=this.size.width+"px"),this.size.height!==this.prevSize.height&&(t.height=this.size.height+"px"),this.helper.css(t),t},_updateVirtualBoundaries:function(t){var e,i,n,s,o,r=this.options;o={minWidth:this._isNumber(r.minWidth)?r.minWidth:0,maxWidth:this._isNumber(r.maxWidth)?r.maxWidth:1/0,minHeight:this._isNumber(r.minHeight)?r.minHeight:0,maxHeight:this._isNumber(r.maxHeight)?r.maxHeight:1/0},(this._aspectRatio||t)&&(e=o.minHeight*this.aspectRatio,n=o.minWidth/this.aspectRatio,i=o.maxHeight*this.aspectRatio,s=o.maxWidth/this.aspectRatio,e>o.minWidth&&(o.minWidth=e),n>o.minHeight&&(o.minHeight=n),o.maxWidth>i&&(o.maxWidth=i),o.maxHeight>s&&(o.maxHeight=s)),this._vBoundaries=o},_updateCache:function(t){this.offset=this.helper.offset(),this._isNumber(t.left)&&(this.position.left=t.left),this._isNumber(t.top)&&(this.position.top=t.top),this._isNumber(t.height)&&(this.size.height=t.height),this._isNumber(t.width)&&(this.size.width=t.width)},_updateRatio:function(t){var e=this.position,i=this.size,n=this.axis;return this._isNumber(t.height)?t.width=t.height*this.aspectRatio:this._isNumber(t.width)&&(t.height=t.width/this.aspectRatio),"sw"===n&&(t.left=e.left+(i.width-t.width),t.top=null),"nw"===n&&(t.top=e.top+(i.height-t.height),t.left=e.left+(i.width-t.width)),t},_respectSize:function(t){var e=this._vBoundaries,i=this.axis,n=this._isNumber(t.width)&&e.maxWidth&&e.maxWidtht.width,r=this._isNumber(t.height)&&e.minHeight&&e.minHeight>t.height,a=this.originalPosition.left+this.originalSize.width,h=this.originalPosition.top+this.originalSize.height,l=/sw|nw|w/.test(i),u=/nw|ne|n/.test(i);return o&&(t.width=e.minWidth),r&&(t.height=e.minHeight),n&&(t.width=e.maxWidth),s&&(t.height=e.maxHeight),o&&l&&(t.left=a-e.minWidth),n&&l&&(t.left=a-e.maxWidth),r&&u&&(t.top=h-e.minHeight),s&&u&&(t.top=h-e.maxHeight),t.width||t.height||t.left||!t.top?t.width||t.height||t.top||!t.left||(t.left=null):t.top=null,t},_getPaddingPlusBorderDimensions:function(t){for(var e=0,i=[],n=[t.css("borderTopWidth"),t.css("borderRightWidth"),t.css("borderBottomWidth"),t.css("borderLeftWidth")],s=[t.css("paddingTop"),t.css("paddingRight"),t.css("paddingBottom"),t.css("paddingLeft")];4>e;e++)i[e]=parseFloat(n[e])||0,i[e]+=parseFloat(s[e])||0;return{height:i[0]+i[2],width:i[1]+i[3]}},_proportionallyResize:function(){if(this._proportionallyResizeElements.length)for(var t,e=0,i=this.helper||this.element;this._proportionallyResizeElements.length>e;e++)t=this._proportionallyResizeElements[e],this.outerDimensions||(this.outerDimensions=this._getPaddingPlusBorderDimensions(t)),t.css({height:i.height()-this.outerDimensions.height||0,width:i.width()-this.outerDimensions.width||0})},_renderProxy:function(){var e=this.element,i=this.options;this.elementOffset=e.offset(),this._helper?(this.helper=this.helper||t("
"),this._addClass(this.helper,this._helper),this.helper.css({width:this.element.outerWidth(),height:this.element.outerHeight(),position:"absolute",left:this.elementOffset.left+"px",top:this.elementOffset.top+"px",zIndex:++i.zIndex}),this.helper.appendTo("body").disableSelection()):this.helper=this.element},_change:{e:function(t,e){return{width:this.originalSize.width+e}},w:function(t,e){var i=this.originalSize,n=this.originalPosition;return{left:n.left+e,width:i.width-e}},n:function(t,e,i){var n=this.originalSize,s=this.originalPosition;return{top:s.top+i,height:n.height-i}},s:function(t,e,i){return{height:this.originalSize.height+i}},se:function(e,i,n){return t.extend(this._change.s.apply(this,arguments),this._change.e.apply(this,[e,i,n]))},sw:function(e,i,n){return t.extend(this._change.s.apply(this,arguments),this._change.w.apply(this,[e,i,n]))},ne:function(e,i,n){return t.extend(this._change.n.apply(this,arguments),this._change.e.apply(this,[e,i,n]))},nw:function(e,i,n){return t.extend(this._change.n.apply(this,arguments),this._change.w.apply(this,[e,i,n]))}},_propagate:function(e,i){t.ui.plugin.call(this,e,[i,this.ui()]),"resize"!==e&&this._trigger(e,i,this.ui())},plugins:{},ui:function(){return{originalElement:this.originalElement,element:this.element,helper:this.helper,position:this.position,size:this.size,originalSize:this.originalSize,originalPosition:this.originalPosition}}}),t.ui.plugin.add("resizable","animate",{stop:function(e){var i=t(this).resizable("instance"),n=i.options,s=i._proportionallyResizeElements,o=s.length&&/textarea/i.test(s[0].nodeName),r=o&&i._hasScroll(s[0],"left")?0:i.sizeDiff.height,a=o?0:i.sizeDiff.width,h={width:i.size.width-a,height:i.size.height-r},l=parseFloat(i.element.css("left"))+(i.position.left-i.originalPosition.left)||null,u=parseFloat(i.element.css("top"))+(i.position.top-i.originalPosition.top)||null;i.element.animate(t.extend(h,u&&l?{top:u,left:l}:{}),{duration:n.animateDuration,easing:n.animateEasing,step:function(){var n={width:parseFloat(i.element.css("width")),height:parseFloat(i.element.css("height")),top:parseFloat(i.element.css("top")),left:parseFloat(i.element.css("left"))};s&&s.length&&t(s[0]).css({width:n.width,height:n.height}),i._updateCache(n),i._propagate("resize",e)}})}}),t.ui.plugin.add("resizable","containment",{start:function(){var e,i,n,s,o,r,a,h=t(this).resizable("instance"),l=h.options,u=h.element,c=l.containment,f=c instanceof t?c.get(0):/parent/.test(c)?u.parent().get(0):c;f&&(h.containerElement=t(f),/document/.test(c)||c===document?(h.containerOffset={left:0,top:0},h.containerPosition={left:0,top:0},h.parentData={element:t(document),left:0,top:0,width:t(document).width(),height:t(document).height()||document.body.parentNode.scrollHeight}):(e=t(f),i=[],t(["Top","Right","Left","Bottom"]).each((function(t,n){i[t]=h._num(e.css("padding"+n))})),h.containerOffset=e.offset(),h.containerPosition=e.position(),h.containerSize={height:e.innerHeight()-i[3],width:e.innerWidth()-i[1]},n=h.containerOffset,s=h.containerSize.height,o=h.containerSize.width,r=h._hasScroll(f,"left")?f.scrollWidth:o,a=h._hasScroll(f)?f.scrollHeight:s,h.parentData={element:f,left:n.left,top:n.top,width:r,height:a}))},resize:function(e){var i,n,s,o,r=t(this).resizable("instance"),a=r.options,h=r.containerOffset,l=r.position,u=r._aspectRatio||e.shiftKey,c={top:0,left:0},f=r.containerElement,d=!0;f[0]!==document&&/static/.test(f.css("position"))&&(c=h),l.left<(r._helper?h.left:0)&&(r.size.width=r.size.width+(r._helper?r.position.left-h.left:r.position.left-c.left),u&&(r.size.height=r.size.width/r.aspectRatio,d=!1),r.position.left=a.helper?h.left:0),l.top<(r._helper?h.top:0)&&(r.size.height=r.size.height+(r._helper?r.position.top-h.top:r.position.top),u&&(r.size.width=r.size.height*r.aspectRatio,d=!1),r.position.top=r._helper?h.top:0),s=r.containerElement.get(0)===r.element.parent().get(0),o=/relative|absolute/.test(r.containerElement.css("position")),s&&o?(r.offset.left=r.parentData.left+r.position.left,r.offset.top=r.parentData.top+r.position.top):(r.offset.left=r.element.offset().left,r.offset.top=r.element.offset().top),i=Math.abs(r.sizeDiff.width+(r._helper?r.offset.left-c.left:r.offset.left-h.left)),n=Math.abs(r.sizeDiff.height+(r._helper?r.offset.top-c.top:r.offset.top-h.top)),i+r.size.width>=r.parentData.width&&(r.size.width=r.parentData.width-i,u&&(r.size.height=r.size.width/r.aspectRatio,d=!1)),n+r.size.height>=r.parentData.height&&(r.size.height=r.parentData.height-n,u&&(r.size.width=r.size.height*r.aspectRatio,d=!1)),d||(r.position.left=r.prevPosition.left,r.position.top=r.prevPosition.top,r.size.width=r.prevSize.width,r.size.height=r.prevSize.height)},stop:function(){var e=t(this).resizable("instance"),i=e.options,n=e.containerOffset,s=e.containerPosition,o=e.containerElement,r=t(e.helper),a=r.offset(),h=r.outerWidth()-e.sizeDiff.width,l=r.outerHeight()-e.sizeDiff.height;e._helper&&!i.animate&&/relative/.test(o.css("position"))&&t(this).css({left:a.left-s.left-n.left,width:h,height:l}),e._helper&&!i.animate&&/static/.test(o.css("position"))&&t(this).css({left:a.left-s.left-n.left,width:h,height:l})}}),t.ui.plugin.add("resizable","alsoResize",{start:function(){var e=t(this).resizable("instance"),i=e.options;t(i.alsoResize).each((function(){var e=t(this);e.data("ui-resizable-alsoresize",{width:parseFloat(e.width()),height:parseFloat(e.height()),left:parseFloat(e.css("left")),top:parseFloat(e.css("top"))})}))},resize:function(e,i){var n=t(this).resizable("instance"),s=n.options,o=n.originalSize,r=n.originalPosition,a={height:n.size.height-o.height||0,width:n.size.width-o.width||0,top:n.position.top-r.top||0,left:n.position.left-r.left||0};t(s.alsoResize).each((function(){var e=t(this),n=t(this).data("ui-resizable-alsoresize"),s={},o=e.parents(i.originalElement[0]).length?["width","height"]:["width","height","top","left"];t.each(o,(function(t,e){var i=(n[e]||0)+(a[e]||0);i&&i>=0&&(s[e]=i||null)})),e.css(s)}))},stop:function(){t(this).removeData("ui-resizable-alsoresize")}}),t.ui.plugin.add("resizable","ghost",{start:function(){var e=t(this).resizable("instance"),i=e.size;e.ghost=e.originalElement.clone(),e.ghost.css({opacity:.25,display:"block",position:"relative",height:i.height,width:i.width,margin:0,left:0,top:0}),e._addClass(e.ghost,"ui-resizable-ghost"),t.uiBackCompat!==!1&&"string"==typeof e.options.ghost&&e.ghost.addClass(this.options.ghost),e.ghost.appendTo(e.helper)},resize:function(){var e=t(this).resizable("instance");e.ghost&&e.ghost.css({position:"relative",height:e.size.height,width:e.size.width})},stop:function(){var e=t(this).resizable("instance");e.ghost&&e.helper&&e.helper.get(0).removeChild(e.ghost.get(0))}}),t.ui.plugin.add("resizable","grid",{resize:function(){var e,i=t(this).resizable("instance"),n=i.options,s=i.size,o=i.originalSize,r=i.originalPosition,a=i.axis,h="number"==typeof n.grid?[n.grid,n.grid]:n.grid,l=h[0]||1,u=h[1]||1,c=Math.round((s.width-o.width)/l)*l,f=Math.round((s.height-o.height)/u)*u,d=o.width+c,p=o.height+f,g=n.maxWidth&&d>n.maxWidth,v=n.maxHeight&&p>n.maxHeight,m=n.minWidth&&n.minWidth>d,b=n.minHeight&&n.minHeight>p;n.grid=h,m&&(d+=l),b&&(p+=u),g&&(d-=l),v&&(p-=u),/^(se|s|e)$/.test(a)?(i.size.width=d,i.size.height=p):/^(ne)$/.test(a)?(i.size.width=d,i.size.height=p,i.position.top=r.top-f):/^(sw)$/.test(a)?(i.size.width=d,i.size.height=p,i.position.left=r.left-c):((0>=p-u||0>=d-l)&&(e=i._getPaddingPlusBorderDimensions(this)),p-u>0?(i.size.height=p,i.position.top=r.top-f):(p=u-e.height,i.size.height=p,i.position.top=r.top+o.height-p),d-l>0?(i.size.width=d,i.position.left=r.left-c):(d=l-e.width,i.size.width=d,i.position.left=r.left+o.width-d))}}),t.ui.resizable,t.ui.safeActiveElement=function(t){var e;try{e=t.activeElement}catch(i){e=t.body}return e||(e=t.body),e.nodeName||(e=t.body),e},t.widget("ui.menu",{version:"1.12.1",defaultElement:"