MediaWiki:Common.js : Différence entre versions
(7 révisions intermédiaires par le même utilisateur non affichées) | |||
Ligne 1 : | Ligne 1 : | ||
+ | /* | ||
+ | Copyright (C) Federico Zivolo 2019 | ||
+ | Distributed under the MIT License (license terms are at http://opensource.org/licenses/MIT). | ||
+ | */ | ||
+ | (function(e,t){'object'==typeof exports&&'undefined'!=typeof module?module.exports=t():'function'==typeof define&&define.amd?define(t):e.Popper=t()})(this,function(){'use strict';function e(e){return e&&'[object Function]'==={}.toString.call(e)}function t(e,t){if(1!==e.nodeType)return[];var o=e.ownerDocument.defaultView,n=o.getComputedStyle(e,null);return t?n[t]:n}function o(e){return'HTML'===e.nodeName?e:e.parentNode||e.host}function n(e){if(!e)return document.body;switch(e.nodeName){case'HTML':case'BODY':return e.ownerDocument.body;case'#document':return e.body;}var i=t(e),r=i.overflow,p=i.overflowX,s=i.overflowY;return /(auto|scroll|overlay)/.test(r+s+p)?e:n(o(e))}function i(e){return e&&e.referenceNode?e.referenceNode:e}function r(e){return 11===e?re:10===e?pe:re||pe}function p(e){if(!e)return document.documentElement;for(var o=r(10)?document.body:null,n=e.offsetParent||null;n===o&&e.nextElementSibling;)n=(e=e.nextElementSibling).offsetParent;var i=n&&n.nodeName;return i&&'BODY'!==i&&'HTML'!==i?-1!==['TH','TD','TABLE'].indexOf(n.nodeName)&&'static'===t(n,'position')?p(n):n:e?e.ownerDocument.documentElement:document.documentElement}function s(e){var t=e.nodeName;return'BODY'!==t&&('HTML'===t||p(e.firstElementChild)===e)}function d(e){return null===e.parentNode?e:d(e.parentNode)}function a(e,t){if(!e||!e.nodeType||!t||!t.nodeType)return document.documentElement;var o=e.compareDocumentPosition(t)&Node.DOCUMENT_POSITION_FOLLOWING,n=o?e:t,i=o?t:e,r=document.createRange();r.setStart(n,0),r.setEnd(i,0);var l=r.commonAncestorContainer;if(e!==l&&t!==l||n.contains(i))return s(l)?l:p(l);var f=d(e);return f.host?a(f.host,t):a(e,d(t).host)}function l(e){var t=1<arguments.length&&void 0!==arguments[1]?arguments[1]:'top',o='top'===t?'scrollTop':'scrollLeft',n=e.nodeName;if('BODY'===n||'HTML'===n){var i=e.ownerDocument.documentElement,r=e.ownerDocument.scrollingElement||i;return r[o]}return e[o]}function f(e,t){var o=2<arguments.length&&void 0!==arguments[2]&&arguments[2],n=l(t,'top'),i=l(t,'left'),r=o?-1:1;return e.top+=n*r,e.bottom+=n*r,e.left+=i*r,e.right+=i*r,e}function m(e,t){var o='x'===t?'Left':'Top',n='Left'==o?'Right':'Bottom';return parseFloat(e['border'+o+'Width'],10)+parseFloat(e['border'+n+'Width'],10)}function h(e,t,o,n){return ee(t['offset'+e],t['scroll'+e],o['client'+e],o['offset'+e],o['scroll'+e],r(10)?parseInt(o['offset'+e])+parseInt(n['margin'+('Height'===e?'Top':'Left')])+parseInt(n['margin'+('Height'===e?'Bottom':'Right')]):0)}function c(e){var t=e.body,o=e.documentElement,n=r(10)&&getComputedStyle(o);return{height:h('Height',t,o,n),width:h('Width',t,o,n)}}function g(e){return le({},e,{right:e.left+e.width,bottom:e.top+e.height})}function u(e){var o={};try{if(r(10)){o=e.getBoundingClientRect();var n=l(e,'top'),i=l(e,'left');o.top+=n,o.left+=i,o.bottom+=n,o.right+=i}else o=e.getBoundingClientRect()}catch(t){}var p={left:o.left,top:o.top,width:o.right-o.left,height:o.bottom-o.top},s='HTML'===e.nodeName?c(e.ownerDocument):{},d=s.width||e.clientWidth||p.width,a=s.height||e.clientHeight||p.height,f=e.offsetWidth-d,h=e.offsetHeight-a;if(f||h){var u=t(e);f-=m(u,'x'),h-=m(u,'y'),p.width-=f,p.height-=h}return g(p)}function b(e,o){var i=2<arguments.length&&void 0!==arguments[2]&&arguments[2],p=r(10),s='HTML'===o.nodeName,d=u(e),a=u(o),l=n(e),m=t(o),h=parseFloat(m.borderTopWidth,10),c=parseFloat(m.borderLeftWidth,10);i&&s&&(a.top=ee(a.top,0),a.left=ee(a.left,0));var b=g({top:d.top-a.top-h,left:d.left-a.left-c,width:d.width,height:d.height});if(b.marginTop=0,b.marginLeft=0,!p&&s){var w=parseFloat(m.marginTop,10),y=parseFloat(m.marginLeft,10);b.top-=h-w,b.bottom-=h-w,b.left-=c-y,b.right-=c-y,b.marginTop=w,b.marginLeft=y}return(p&&!i?o.contains(l):o===l&&'BODY'!==l.nodeName)&&(b=f(b,o)),b}function w(e){var t=1<arguments.length&&void 0!==arguments[1]&&arguments[1],o=e.ownerDocument.documentElement,n=b(e,o),i=ee(o.clientWidth,window.innerWidth||0),r=ee(o.clientHeight,window.innerHeight||0),p=t?0:l(o),s=t?0:l(o,'left'),d={top:p-n.top+n.marginTop,left:s-n.left+n.marginLeft,width:i,height:r};return g(d)}function y(e){var n=e.nodeName;if('BODY'===n||'HTML'===n)return!1;if('fixed'===t(e,'position'))return!0;var i=o(e);return!!i&&y(i)}function E(e){if(!e||!e.parentElement||r())return document.documentElement;for(var o=e.parentElement;o&&'none'===t(o,'transform');)o=o.parentElement;return o||document.documentElement}function v(e,t,r,p){var s=4<arguments.length&&void 0!==arguments[4]&&arguments[4],d={top:0,left:0},l=s?E(e):a(e,i(t));if('viewport'===p)d=w(l,s);else{var f;'scrollParent'===p?(f=n(o(t)),'BODY'===f.nodeName&&(f=e.ownerDocument.documentElement)):'window'===p?f=e.ownerDocument.documentElement:f=p;var m=b(f,l,s);if('HTML'===f.nodeName&&!y(l)){var h=c(e.ownerDocument),g=h.height,u=h.width;d.top+=m.top-m.marginTop,d.bottom=g+m.top,d.left+=m.left-m.marginLeft,d.right=u+m.left}else d=m}r=r||0;var v='number'==typeof r;return d.left+=v?r:r.left||0,d.top+=v?r:r.top||0,d.right-=v?r:r.right||0,d.bottom-=v?r:r.bottom||0,d}function x(e){var t=e.width,o=e.height;return t*o}function O(e,t,o,n,i){var r=5<arguments.length&&void 0!==arguments[5]?arguments[5]:0;if(-1===e.indexOf('auto'))return e;var p=v(o,n,r,i),s={top:{width:p.width,height:t.top-p.top},right:{width:p.right-t.right,height:p.height},bottom:{width:p.width,height:p.bottom-t.bottom},left:{width:t.left-p.left,height:p.height}},d=Object.keys(s).map(function(e){return le({key:e},s[e],{area:x(s[e])})}).sort(function(e,t){return t.area-e.area}),a=d.filter(function(e){var t=e.width,n=e.height;return t>=o.clientWidth&&n>=o.clientHeight}),l=0<a.length?a[0].key:d[0].key,f=e.split('-')[1];return l+(f?'-'+f:'')}function L(e,t,o){var n=3<arguments.length&&void 0!==arguments[3]?arguments[3]:null,r=n?E(t):a(t,i(o));return b(o,r,n)}function S(e){var t=e.ownerDocument.defaultView,o=t.getComputedStyle(e),n=parseFloat(o.marginTop||0)+parseFloat(o.marginBottom||0),i=parseFloat(o.marginLeft||0)+parseFloat(o.marginRight||0),r={width:e.offsetWidth+i,height:e.offsetHeight+n};return r}function T(e){var t={left:'right',right:'left',bottom:'top',top:'bottom'};return e.replace(/left|right|bottom|top/g,function(e){return t[e]})}function C(e,t,o){o=o.split('-')[0];var n=S(e),i={width:n.width,height:n.height},r=-1!==['right','left'].indexOf(o),p=r?'top':'left',s=r?'left':'top',d=r?'height':'width',a=r?'width':'height';return i[p]=t[p]+t[d]/2-n[d]/2,i[s]=o===s?t[s]-n[a]:t[T(s)],i}function D(e,t){return Array.prototype.find?e.find(t):e.filter(t)[0]}function N(e,t,o){if(Array.prototype.findIndex)return e.findIndex(function(e){return e[t]===o});var n=D(e,function(e){return e[t]===o});return e.indexOf(n)}function P(t,o,n){var i=void 0===n?t:t.slice(0,N(t,'name',n));return i.forEach(function(t){t['function']&&console.warn('`modifier.function` is deprecated, use `modifier.fn`!');var n=t['function']||t.fn;t.enabled&&e(n)&&(o.offsets.popper=g(o.offsets.popper),o.offsets.reference=g(o.offsets.reference),o=n(o,t))}),o}function k(){if(!this.state.isDestroyed){var e={instance:this,styles:{},arrowStyles:{},attributes:{},flipped:!1,offsets:{}};e.offsets.reference=L(this.state,this.popper,this.reference,this.options.positionFixed),e.placement=O(this.options.placement,e.offsets.reference,this.popper,this.reference,this.options.modifiers.flip.boundariesElement,this.options.modifiers.flip.padding),e.originalPlacement=e.placement,e.positionFixed=this.options.positionFixed,e.offsets.popper=C(this.popper,e.offsets.reference,e.placement),e.offsets.popper.position=this.options.positionFixed?'fixed':'absolute',e=P(this.modifiers,e),this.state.isCreated?this.options.onUpdate(e):(this.state.isCreated=!0,this.options.onCreate(e))}}function W(e,t){return e.some(function(e){var o=e.name,n=e.enabled;return n&&o===t})}function B(e){for(var t=[!1,'ms','Webkit','Moz','O'],o=e.charAt(0).toUpperCase()+e.slice(1),n=0;n<t.length;n++){var i=t[n],r=i?''+i+o:e;if('undefined'!=typeof document.body.style[r])return r}return null}function H(){return this.state.isDestroyed=!0,W(this.modifiers,'applyStyle')&&(this.popper.removeAttribute('x-placement'),this.popper.style.position='',this.popper.style.top='',this.popper.style.left='',this.popper.style.right='',this.popper.style.bottom='',this.popper.style.willChange='',this.popper.style[B('transform')]=''),this.disableEventListeners(),this.options.removeOnDestroy&&this.popper.parentNode.removeChild(this.popper),this}function A(e){var t=e.ownerDocument;return t?t.defaultView:window}function M(e,t,o,i){var r='BODY'===e.nodeName,p=r?e.ownerDocument.defaultView:e;p.addEventListener(t,o,{passive:!0}),r||M(n(p.parentNode),t,o,i),i.push(p)}function F(e,t,o,i){o.updateBound=i,A(e).addEventListener('resize',o.updateBound,{passive:!0});var r=n(e);return M(r,'scroll',o.updateBound,o.scrollParents),o.scrollElement=r,o.eventsEnabled=!0,o}function I(){this.state.eventsEnabled||(this.state=F(this.reference,this.options,this.state,this.scheduleUpdate))}function R(e,t){return A(e).removeEventListener('resize',t.updateBound),t.scrollParents.forEach(function(e){e.removeEventListener('scroll',t.updateBound)}),t.updateBound=null,t.scrollParents=[],t.scrollElement=null,t.eventsEnabled=!1,t}function U(){this.state.eventsEnabled&&(cancelAnimationFrame(this.scheduleUpdate),this.state=R(this.reference,this.state))}function Y(e){return''!==e&&!isNaN(parseFloat(e))&&isFinite(e)}function V(e,t){Object.keys(t).forEach(function(o){var n='';-1!==['width','height','top','right','bottom','left'].indexOf(o)&&Y(t[o])&&(n='px'),e.style[o]=t[o]+n})}function j(e,t){Object.keys(t).forEach(function(o){var n=t[o];!1===n?e.removeAttribute(o):e.setAttribute(o,t[o])})}function q(e,t){var o=e.offsets,n=o.popper,i=o.reference,r=$,p=function(e){return e},s=r(i.width),d=r(n.width),a=-1!==['left','right'].indexOf(e.placement),l=-1!==e.placement.indexOf('-'),f=t?a||l||s%2==d%2?r:Z:p,m=t?r:p;return{left:f(1==s%2&&1==d%2&&!l&&t?n.left-1:n.left),top:m(n.top),bottom:m(n.bottom),right:f(n.right)}}function K(e,t,o){var n=D(e,function(e){var o=e.name;return o===t}),i=!!n&&e.some(function(e){return e.name===o&&e.enabled&&e.order<n.order});if(!i){var r='`'+t+'`';console.warn('`'+o+'`'+' modifier is required by '+r+' modifier in order to work, be sure to include it before '+r+'!')}return i}function z(e){return'end'===e?'start':'start'===e?'end':e}function G(e){var t=1<arguments.length&&void 0!==arguments[1]&&arguments[1],o=he.indexOf(e),n=he.slice(o+1).concat(he.slice(0,o));return t?n.reverse():n}function _(e,t,o,n){var i=e.match(/((?:\-|\+)?\d*\.?\d*)(.*)/),r=+i[1],p=i[2];if(!r)return e;if(0===p.indexOf('%')){var s;switch(p){case'%p':s=o;break;case'%':case'%r':default:s=n;}var d=g(s);return d[t]/100*r}if('vh'===p||'vw'===p){var a;return a='vh'===p?ee(document.documentElement.clientHeight,window.innerHeight||0):ee(document.documentElement.clientWidth,window.innerWidth||0),a/100*r}return r}function X(e,t,o,n){var i=[0,0],r=-1!==['right','left'].indexOf(n),p=e.split(/(\+|\-)/).map(function(e){return e.trim()}),s=p.indexOf(D(p,function(e){return-1!==e.search(/,|\s/)}));p[s]&&-1===p[s].indexOf(',')&&console.warn('Offsets separated by white space(s) are deprecated, use a comma (,) instead.');var d=/\s*,\s*|\s+/,a=-1===s?[p]:[p.slice(0,s).concat([p[s].split(d)[0]]),[p[s].split(d)[1]].concat(p.slice(s+1))];return a=a.map(function(e,n){var i=(1===n?!r:r)?'height':'width',p=!1;return e.reduce(function(e,t){return''===e[e.length-1]&&-1!==['+','-'].indexOf(t)?(e[e.length-1]=t,p=!0,e):p?(e[e.length-1]+=t,p=!1,e):e.concat(t)},[]).map(function(e){return _(e,i,t,o)})}),a.forEach(function(e,t){e.forEach(function(o,n){Y(o)&&(i[t]+=o*('-'===e[n-1]?-1:1))})}),i}function J(e,t){var o,n=t.offset,i=e.placement,r=e.offsets,p=r.popper,s=r.reference,d=i.split('-')[0];return o=Y(+n)?[+n,0]:X(n,p,s,d),'left'===d?(p.top+=o[0],p.left-=o[1]):'right'===d?(p.top+=o[0],p.left+=o[1]):'top'===d?(p.left+=o[0],p.top-=o[1]):'bottom'===d&&(p.left+=o[0],p.top+=o[1]),e.popper=p,e}var Q=Math.min,Z=Math.floor,$=Math.round,ee=Math.max,te='undefined'!=typeof window&&'undefined'!=typeof document&&'undefined'!=typeof navigator,oe=function(){for(var e=['Edge','Trident','Firefox'],t=0;t<e.length;t+=1)if(te&&0<=navigator.userAgent.indexOf(e[t]))return 1;return 0}(),ne=te&&window.Promise,ie=ne?function(e){var t=!1;return function(){t||(t=!0,window.Promise.resolve().then(function(){t=!1,e()}))}}:function(e){var t=!1;return function(){t||(t=!0,setTimeout(function(){t=!1,e()},oe))}},re=te&&!!(window.MSInputMethodContext&&document.documentMode),pe=te&&/MSIE 10/.test(navigator.userAgent),se=function(e,t){if(!(e instanceof t))throw new TypeError('Cannot call a class as a function')},de=function(){function e(e,t){for(var o,n=0;n<t.length;n++)o=t[n],o.enumerable=o.enumerable||!1,o.configurable=!0,'value'in o&&(o.writable=!0),Object.defineProperty(e,o.key,o)}return function(t,o,n){return o&&e(t.prototype,o),n&&e(t,n),t}}(),ae=function(e,t,o){return t in e?Object.defineProperty(e,t,{value:o,enumerable:!0,configurable:!0,writable:!0}):e[t]=o,e},le=Object.assign||function(e){for(var t,o=1;o<arguments.length;o++)for(var n in t=arguments[o],t)Object.prototype.hasOwnProperty.call(t,n)&&(e[n]=t[n]);return e},fe=te&&/Firefox/i.test(navigator.userAgent),me=['auto-start','auto','auto-end','top-start','top','top-end','right-start','right','right-end','bottom-end','bottom','bottom-start','left-end','left','left-start'],he=me.slice(3),ce={FLIP:'flip',CLOCKWISE:'clockwise',COUNTERCLOCKWISE:'counterclockwise'},ge=function(){function t(o,n){var i=this,r=2<arguments.length&&void 0!==arguments[2]?arguments[2]:{};se(this,t),this.scheduleUpdate=function(){return requestAnimationFrame(i.update)},this.update=ie(this.update.bind(this)),this.options=le({},t.Defaults,r),this.state={isDestroyed:!1,isCreated:!1,scrollParents:[]},this.reference=o&&o.jquery?o[0]:o,this.popper=n&&n.jquery?n[0]:n,this.options.modifiers={},Object.keys(le({},t.Defaults.modifiers,r.modifiers)).forEach(function(e){i.options.modifiers[e]=le({},t.Defaults.modifiers[e]||{},r.modifiers?r.modifiers[e]:{})}),this.modifiers=Object.keys(this.options.modifiers).map(function(e){return le({name:e},i.options.modifiers[e])}).sort(function(e,t){return e.order-t.order}),this.modifiers.forEach(function(t){t.enabled&&e(t.onLoad)&&t.onLoad(i.reference,i.popper,i.options,t,i.state)}),this.update();var p=this.options.eventsEnabled;p&&this.enableEventListeners(),this.state.eventsEnabled=p}return de(t,[{key:'update',value:function(){return k.call(this)}},{key:'destroy',value:function(){return H.call(this)}},{key:'enableEventListeners',value:function(){return I.call(this)}},{key:'disableEventListeners',value:function(){return U.call(this)}}]),t}();return ge.Utils=('undefined'==typeof window?global:window).PopperUtils,ge.placements=me,ge.Defaults={placement:'bottom',positionFixed:!1,eventsEnabled:!0,removeOnDestroy:!1,onCreate:function(){},onUpdate:function(){},modifiers:{shift:{order:100,enabled:!0,fn:function(e){var t=e.placement,o=t.split('-')[0],n=t.split('-')[1];if(n){var i=e.offsets,r=i.reference,p=i.popper,s=-1!==['bottom','top'].indexOf(o),d=s?'left':'top',a=s?'width':'height',l={start:ae({},d,r[d]),end:ae({},d,r[d]+r[a]-p[a])};e.offsets.popper=le({},p,l[n])}return e}},offset:{order:200,enabled:!0,fn:J,offset:0},preventOverflow:{order:300,enabled:!0,fn:function(e,t){var o=t.boundariesElement||p(e.instance.popper);e.instance.reference===o&&(o=p(o));var n=B('transform'),i=e.instance.popper.style,r=i.top,s=i.left,d=i[n];i.top='',i.left='',i[n]='';var a=v(e.instance.popper,e.instance.reference,t.padding,o,e.positionFixed);i.top=r,i.left=s,i[n]=d,t.boundaries=a;var l=t.priority,f=e.offsets.popper,m={primary:function(e){var o=f[e];return f[e]<a[e]&&!t.escapeWithReference&&(o=ee(f[e],a[e])),ae({},e,o)},secondary:function(e){var o='right'===e?'left':'top',n=f[o];return f[e]>a[e]&&!t.escapeWithReference&&(n=Q(f[o],a[e]-('right'===e?f.width:f.height))),ae({},o,n)}};return l.forEach(function(e){var t=-1===['left','top'].indexOf(e)?'secondary':'primary';f=le({},f,m[t](e))}),e.offsets.popper=f,e},priority:['left','right','top','bottom'],padding:5,boundariesElement:'scrollParent'},keepTogether:{order:400,enabled:!0,fn:function(e){var t=e.offsets,o=t.popper,n=t.reference,i=e.placement.split('-')[0],r=Z,p=-1!==['top','bottom'].indexOf(i),s=p?'right':'bottom',d=p?'left':'top',a=p?'width':'height';return o[s]<r(n[d])&&(e.offsets.popper[d]=r(n[d])-o[a]),o[d]>r(n[s])&&(e.offsets.popper[d]=r(n[s])),e}},arrow:{order:500,enabled:!0,fn:function(e,o){var n;if(!K(e.instance.modifiers,'arrow','keepTogether'))return e;var i=o.element;if('string'==typeof i){if(i=e.instance.popper.querySelector(i),!i)return e;}else if(!e.instance.popper.contains(i))return console.warn('WARNING: `arrow.element` must be child of its popper element!'),e;var r=e.placement.split('-')[0],p=e.offsets,s=p.popper,d=p.reference,a=-1!==['left','right'].indexOf(r),l=a?'height':'width',f=a?'Top':'Left',m=f.toLowerCase(),h=a?'left':'top',c=a?'bottom':'right',u=S(i)[l];d[c]-u<s[m]&&(e.offsets.popper[m]-=s[m]-(d[c]-u)),d[m]+u>s[c]&&(e.offsets.popper[m]+=d[m]+u-s[c]),e.offsets.popper=g(e.offsets.popper);var b=d[m]+d[l]/2-u/2,w=t(e.instance.popper),y=parseFloat(w['margin'+f],10),E=parseFloat(w['border'+f+'Width'],10),v=b-e.offsets.popper[m]-y-E;return v=ee(Q(s[l]-u,v),0),e.arrowElement=i,e.offsets.arrow=(n={},ae(n,m,$(v)),ae(n,h,''),n),e},element:'[x-arrow]'},flip:{order:600,enabled:!0,fn:function(e,t){if(W(e.instance.modifiers,'inner'))return e;if(e.flipped&&e.placement===e.originalPlacement)return e;var o=v(e.instance.popper,e.instance.reference,t.padding,t.boundariesElement,e.positionFixed),n=e.placement.split('-')[0],i=T(n),r=e.placement.split('-')[1]||'',p=[];switch(t.behavior){case ce.FLIP:p=[n,i];break;case ce.CLOCKWISE:p=G(n);break;case ce.COUNTERCLOCKWISE:p=G(n,!0);break;default:p=t.behavior;}return p.forEach(function(s,d){if(n!==s||p.length===d+1)return e;n=e.placement.split('-')[0],i=T(n);var a=e.offsets.popper,l=e.offsets.reference,f=Z,m='left'===n&&f(a.right)>f(l.left)||'right'===n&&f(a.left)<f(l.right)||'top'===n&&f(a.bottom)>f(l.top)||'bottom'===n&&f(a.top)<f(l.bottom),h=f(a.left)<f(o.left),c=f(a.right)>f(o.right),g=f(a.top)<f(o.top),u=f(a.bottom)>f(o.bottom),b='left'===n&&h||'right'===n&&c||'top'===n&&g||'bottom'===n&&u,w=-1!==['top','bottom'].indexOf(n),y=!!t.flipVariations&&(w&&'start'===r&&h||w&&'end'===r&&c||!w&&'start'===r&&g||!w&&'end'===r&&u),E=!!t.flipVariationsByContent&&(w&&'start'===r&&c||w&&'end'===r&&h||!w&&'start'===r&&u||!w&&'end'===r&&g),v=y||E;(m||b||v)&&(e.flipped=!0,(m||b)&&(n=p[d+1]),v&&(r=z(r)),e.placement=n+(r?'-'+r:''),e.offsets.popper=le({},e.offsets.popper,C(e.instance.popper,e.offsets.reference,e.placement)),e=P(e.instance.modifiers,e,'flip'))}),e},behavior:'flip',padding:5,boundariesElement:'viewport',flipVariations:!1,flipVariationsByContent:!1},inner:{order:700,enabled:!1,fn:function(e){var t=e.placement,o=t.split('-')[0],n=e.offsets,i=n.popper,r=n.reference,p=-1!==['left','right'].indexOf(o),s=-1===['top','left'].indexOf(o);return i[p?'left':'top']=r[o]-(s?i[p?'width':'height']:0),e.placement=T(t),e.offsets.popper=g(i),e}},hide:{order:800,enabled:!0,fn:function(e){if(!K(e.instance.modifiers,'hide','preventOverflow'))return e;var t=e.offsets.reference,o=D(e.instance.modifiers,function(e){return'preventOverflow'===e.name}).boundaries;if(t.bottom<o.top||t.left>o.right||t.top>o.bottom||t.right<o.left){if(!0===e.hide)return e;e.hide=!0,e.attributes['x-out-of-boundaries']=''}else{if(!1===e.hide)return e;e.hide=!1,e.attributes['x-out-of-boundaries']=!1}return e}},computeStyle:{order:850,enabled:!0,fn:function(e,t){var o=t.x,n=t.y,i=e.offsets.popper,r=D(e.instance.modifiers,function(e){return'applyStyle'===e.name}).gpuAcceleration;void 0!==r&&console.warn('WARNING: `gpuAcceleration` option moved to `computeStyle` modifier and will not be supported in future versions of Popper.js!');var s,d,a=void 0===r?t.gpuAcceleration:r,l=p(e.instance.popper),f=u(l),m={position:i.position},h=q(e,2>window.devicePixelRatio||!fe),c='bottom'===o?'top':'bottom',g='right'===n?'left':'right',b=B('transform');if(d='bottom'==c?'HTML'===l.nodeName?-l.clientHeight+h.bottom:-f.height+h.bottom:h.top,s='right'==g?'HTML'===l.nodeName?-l.clientWidth+h.right:-f.width+h.right:h.left,a&&b)m[b]='translate3d('+s+'px, '+d+'px, 0)',m[c]=0,m[g]=0,m.willChange='transform';else{var w='bottom'==c?-1:1,y='right'==g?-1:1;m[c]=d*w,m[g]=s*y,m.willChange=c+', '+g}var E={"x-placement":e.placement};return e.attributes=le({},E,e.attributes),e.styles=le({},m,e.styles),e.arrowStyles=le({},e.offsets.arrow,e.arrowStyles),e},gpuAcceleration:!0,x:'bottom',y:'right'},applyStyle:{order:900,enabled:!0,fn:function(e){return V(e.instance.popper,e.styles),j(e.instance.popper,e.attributes),e.arrowElement&&Object.keys(e.arrowStyles).length&&V(e.arrowElement,e.arrowStyles),e},onLoad:function(e,t,o,n,i){var r=L(i,t,e,o.positionFixed),p=O(o.placement,r,t,e,o.modifiers.flip.boundariesElement,o.modifiers.flip.padding);return t.setAttribute('x-placement',p),V(t,{position:o.positionFixed?'fixed':'absolute'}),o},gpuAcceleration:void 0}}},ge}); | ||
+ | |||
+ | /*! | ||
+ | * Bootstrap util.js v4.5.0 (https://getbootstrap.com/) | ||
+ | * Copyright 2011-2020 The Bootstrap Authors (https://github.com/twbs/bootstrap/graphs/contributors) | ||
+ | * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) | ||
+ | */ | ||
+ | (function (global, factory) { | ||
+ | typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory(require('jquery')) : | ||
+ | typeof define === 'function' && define.amd ? define(['jquery'], factory) : | ||
+ | (global = global || self, global.Util = factory(global.jQuery)); | ||
+ | }(this, (function ($) { 'use strict'; | ||
+ | |||
+ | $ = $ && Object.prototype.hasOwnProperty.call($, 'default') ? $['default'] : $; | ||
+ | |||
+ | /** | ||
+ | * -------------------------------------------------------------------------- | ||
+ | * Bootstrap (v4.5.0): util.js | ||
+ | * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) | ||
+ | * -------------------------------------------------------------------------- | ||
+ | */ | ||
+ | /** | ||
+ | * ------------------------------------------------------------------------ | ||
+ | * Private TransitionEnd Helpers | ||
+ | * ------------------------------------------------------------------------ | ||
+ | */ | ||
+ | |||
+ | var TRANSITION_END = 'transitionend'; | ||
+ | var MAX_UID = 1000000; | ||
+ | var MILLISECONDS_MULTIPLIER = 1000; // Shoutout AngusCroll (https://goo.gl/pxwQGp) | ||
+ | |||
+ | function toType(obj) { | ||
+ | if (obj === null || typeof obj === 'undefined') { | ||
+ | return "" + obj; | ||
+ | } | ||
+ | |||
+ | return {}.toString.call(obj).match(/\s([a-z]+)/i)[1].toLowerCase(); | ||
+ | } | ||
+ | |||
+ | function getSpecialTransitionEndEvent() { | ||
+ | return { | ||
+ | bindType: TRANSITION_END, | ||
+ | delegateType: TRANSITION_END, | ||
+ | handle: function handle(event) { | ||
+ | if ($(event.target).is(this)) { | ||
+ | return event.handleObj.handler.apply(this, arguments); // eslint-disable-line prefer-rest-params | ||
+ | } | ||
+ | |||
+ | return undefined; | ||
+ | } | ||
+ | }; | ||
+ | } | ||
+ | |||
+ | function transitionEndEmulator(duration) { | ||
+ | var _this = this; | ||
+ | |||
+ | var called = false; | ||
+ | $(this).one(Util.TRANSITION_END, function () { | ||
+ | called = true; | ||
+ | }); | ||
+ | setTimeout(function () { | ||
+ | if (!called) { | ||
+ | Util.triggerTransitionEnd(_this); | ||
+ | } | ||
+ | }, duration); | ||
+ | return this; | ||
+ | } | ||
+ | |||
+ | function setTransitionEndSupport() { | ||
+ | $.fn.emulateTransitionEnd = transitionEndEmulator; | ||
+ | $.event.special[Util.TRANSITION_END] = getSpecialTransitionEndEvent(); | ||
+ | } | ||
+ | /** | ||
+ | * -------------------------------------------------------------------------- | ||
+ | * Public Util Api | ||
+ | * -------------------------------------------------------------------------- | ||
+ | */ | ||
+ | |||
+ | |||
+ | var Util = { | ||
+ | TRANSITION_END: 'bsTransitionEnd', | ||
+ | getUID: function getUID(prefix) { | ||
+ | do { | ||
+ | // eslint-disable-next-line no-bitwise | ||
+ | prefix += ~~(Math.random() * MAX_UID); // "~~" acts like a faster Math.floor() here | ||
+ | } while (document.getElementById(prefix)); | ||
+ | |||
+ | return prefix; | ||
+ | }, | ||
+ | getSelectorFromElement: function getSelectorFromElement(element) { | ||
+ | var selector = element.getAttribute('data-target'); | ||
+ | |||
+ | if (!selector || selector === '#') { | ||
+ | var hrefAttr = element.getAttribute('href'); | ||
+ | selector = hrefAttr && hrefAttr !== '#' ? hrefAttr.trim() : ''; | ||
+ | } | ||
+ | |||
+ | try { | ||
+ | return document.querySelector(selector) ? selector : null; | ||
+ | } catch (err) { | ||
+ | return null; | ||
+ | } | ||
+ | }, | ||
+ | getTransitionDurationFromElement: function getTransitionDurationFromElement(element) { | ||
+ | if (!element) { | ||
+ | return 0; | ||
+ | } // Get transition-duration of the element | ||
+ | |||
+ | |||
+ | var transitionDuration = $(element).css('transition-duration'); | ||
+ | var transitionDelay = $(element).css('transition-delay'); | ||
+ | var floatTransitionDuration = parseFloat(transitionDuration); | ||
+ | var floatTransitionDelay = parseFloat(transitionDelay); // Return 0 if element or transition duration is not found | ||
+ | |||
+ | if (!floatTransitionDuration && !floatTransitionDelay) { | ||
+ | return 0; | ||
+ | } // If multiple durations are defined, take the first | ||
+ | |||
+ | |||
+ | transitionDuration = transitionDuration.split(',')[0]; | ||
+ | transitionDelay = transitionDelay.split(',')[0]; | ||
+ | return (parseFloat(transitionDuration) + parseFloat(transitionDelay)) * MILLISECONDS_MULTIPLIER; | ||
+ | }, | ||
+ | reflow: function reflow(element) { | ||
+ | return element.offsetHeight; | ||
+ | }, | ||
+ | triggerTransitionEnd: function triggerTransitionEnd(element) { | ||
+ | $(element).trigger(TRANSITION_END); | ||
+ | }, | ||
+ | // TODO: Remove in v5 | ||
+ | supportsTransitionEnd: function supportsTransitionEnd() { | ||
+ | return Boolean(TRANSITION_END); | ||
+ | }, | ||
+ | isElement: function isElement(obj) { | ||
+ | return (obj[0] || obj).nodeType; | ||
+ | }, | ||
+ | typeCheckConfig: function typeCheckConfig(componentName, config, configTypes) { | ||
+ | for (var property in configTypes) { | ||
+ | if (Object.prototype.hasOwnProperty.call(configTypes, property)) { | ||
+ | var expectedTypes = configTypes[property]; | ||
+ | var value = config[property]; | ||
+ | var valueType = value && Util.isElement(value) ? 'element' : toType(value); | ||
+ | |||
+ | if (!new RegExp(expectedTypes).test(valueType)) { | ||
+ | throw new Error(componentName.toUpperCase() + ": " + ("Option \"" + property + "\" provided type \"" + valueType + "\" ") + ("but expected type \"" + expectedTypes + "\".")); | ||
+ | } | ||
+ | } | ||
+ | } | ||
+ | }, | ||
+ | findShadowRoot: function findShadowRoot(element) { | ||
+ | if (!document.documentElement.attachShadow) { | ||
+ | return null; | ||
+ | } // Can find the shadow root otherwise it'll return the document | ||
+ | |||
+ | |||
+ | if (typeof element.getRootNode === 'function') { | ||
+ | var root = element.getRootNode(); | ||
+ | return root instanceof ShadowRoot ? root : null; | ||
+ | } | ||
+ | |||
+ | if (element instanceof ShadowRoot) { | ||
+ | return element; | ||
+ | } // when we don't find a shadow root | ||
+ | |||
+ | |||
+ | if (!element.parentNode) { | ||
+ | return null; | ||
+ | } | ||
+ | |||
+ | return Util.findShadowRoot(element.parentNode); | ||
+ | }, | ||
+ | jQueryDetection: function jQueryDetection() { | ||
+ | if (typeof $ === 'undefined') { | ||
+ | throw new TypeError('Bootstrap\'s JavaScript requires jQuery. jQuery must be included before Bootstrap\'s JavaScript.'); | ||
+ | } | ||
+ | |||
+ | var version = $.fn.jquery.split(' ')[0].split('.'); | ||
+ | var minMajor = 1; | ||
+ | var ltMajor = 2; | ||
+ | var minMinor = 9; | ||
+ | var minPatch = 1; | ||
+ | var maxMajor = 4; | ||
+ | |||
+ | if (version[0] < ltMajor && version[1] < minMinor || version[0] === minMajor && version[1] === minMinor && version[2] < minPatch || version[0] >= maxMajor) { | ||
+ | throw new Error('Bootstrap\'s JavaScript requires at least jQuery v1.9.1 but less than v4.0.0'); | ||
+ | } | ||
+ | } | ||
+ | }; | ||
+ | Util.jQueryDetection(); | ||
+ | setTransitionEndSupport(); | ||
+ | |||
+ | return Util; | ||
+ | |||
+ | }))); | ||
+ | //# sourceMappingURL=util.js.map | ||
+ | |||
/*! | /*! | ||
− | + | * Bootstrap dropdown.js v4.5.0 (https://getbootstrap.com/) | |
− | + | * Copyright 2011-2020 The Bootstrap Authors (https://github.com/twbs/bootstrap/graphs/contributors) | |
− | + | * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) | |
− | */ | + | */ |
+ | (function (global, factory) { | ||
+ | typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory(require('jquery'), require('popper.js'), require('./util.js')) : | ||
+ | typeof define === 'function' && define.amd ? define(['jquery', 'popper.js', './util.js'], factory) : | ||
+ | (global = global || self, global.Dropdown = factory(global.jQuery, global.Popper, global.Util)); | ||
+ | }(this, (function ($, Popper, Util) { 'use strict'; | ||
+ | |||
+ | $ = $ && Object.prototype.hasOwnProperty.call($, 'default') ? $['default'] : $; | ||
+ | Popper = Popper && Object.prototype.hasOwnProperty.call(Popper, 'default') ? Popper['default'] : Popper; | ||
+ | Util = Util && Object.prototype.hasOwnProperty.call(Util, 'default') ? Util['default'] : Util; | ||
+ | |||
+ | function _defineProperties(target, props) { | ||
+ | for (var i = 0; i < props.length; i++) { | ||
+ | var descriptor = props[i]; | ||
+ | descriptor.enumerable = descriptor.enumerable || false; | ||
+ | descriptor.configurable = true; | ||
+ | if ("value" in descriptor) descriptor.writable = true; | ||
+ | Object.defineProperty(target, descriptor.key, descriptor); | ||
+ | } | ||
+ | } | ||
+ | |||
+ | function _createClass(Constructor, protoProps, staticProps) { | ||
+ | if (protoProps) _defineProperties(Constructor.prototype, protoProps); | ||
+ | if (staticProps) _defineProperties(Constructor, staticProps); | ||
+ | return Constructor; | ||
+ | } | ||
+ | |||
+ | function _defineProperty(obj, key, value) { | ||
+ | if (key in obj) { | ||
+ | Object.defineProperty(obj, key, { | ||
+ | value: value, | ||
+ | enumerable: true, | ||
+ | configurable: true, | ||
+ | writable: true | ||
+ | }); | ||
+ | } else { | ||
+ | obj[key] = value; | ||
+ | } | ||
+ | |||
+ | return obj; | ||
+ | } | ||
+ | |||
+ | function ownKeys(object, enumerableOnly) { | ||
+ | var keys = Object.keys(object); | ||
+ | |||
+ | if (Object.getOwnPropertySymbols) { | ||
+ | var symbols = Object.getOwnPropertySymbols(object); | ||
+ | if (enumerableOnly) symbols = symbols.filter(function (sym) { | ||
+ | return Object.getOwnPropertyDescriptor(object, sym).enumerable; | ||
+ | }); | ||
+ | keys.push.apply(keys, symbols); | ||
+ | } | ||
+ | |||
+ | return keys; | ||
+ | } | ||
+ | |||
+ | function _objectSpread2(target) { | ||
+ | for (var i = 1; i < arguments.length; i++) { | ||
+ | var source = arguments[i] != null ? arguments[i] : {}; | ||
+ | |||
+ | if (i % 2) { | ||
+ | ownKeys(Object(source), true).forEach(function (key) { | ||
+ | _defineProperty(target, key, source[key]); | ||
+ | }); | ||
+ | } else if (Object.getOwnPropertyDescriptors) { | ||
+ | Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); | ||
+ | } else { | ||
+ | ownKeys(Object(source)).forEach(function (key) { | ||
+ | Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); | ||
+ | }); | ||
+ | } | ||
+ | } | ||
+ | |||
+ | return target; | ||
+ | } | ||
+ | |||
+ | /** | ||
+ | * ------------------------------------------------------------------------ | ||
+ | * Constants | ||
+ | * ------------------------------------------------------------------------ | ||
+ | */ | ||
+ | |||
+ | var NAME = 'dropdown'; | ||
+ | var VERSION = '4.5.0'; | ||
+ | var DATA_KEY = 'bs.dropdown'; | ||
+ | var EVENT_KEY = "." + DATA_KEY; | ||
+ | var DATA_API_KEY = '.data-api'; | ||
+ | var JQUERY_NO_CONFLICT = $.fn[NAME]; | ||
+ | var ESCAPE_KEYCODE = 27; // KeyboardEvent.which value for Escape (Esc) key | ||
+ | |||
+ | var SPACE_KEYCODE = 32; // KeyboardEvent.which value for space key | ||
+ | |||
+ | var TAB_KEYCODE = 9; // KeyboardEvent.which value for tab key | ||
+ | |||
+ | var ARROW_UP_KEYCODE = 38; // KeyboardEvent.which value for up arrow key | ||
+ | |||
+ | var ARROW_DOWN_KEYCODE = 40; // KeyboardEvent.which value for down arrow key | ||
+ | |||
+ | var RIGHT_MOUSE_BUTTON_WHICH = 3; // MouseEvent.which value for the right button (assuming a right-handed mouse) | ||
+ | |||
+ | var REGEXP_KEYDOWN = new RegExp(ARROW_UP_KEYCODE + "|" + ARROW_DOWN_KEYCODE + "|" + ESCAPE_KEYCODE); | ||
+ | var EVENT_HIDE = "hide" + EVENT_KEY; | ||
+ | var EVENT_HIDDEN = "hidden" + EVENT_KEY; | ||
+ | var EVENT_SHOW = "show" + EVENT_KEY; | ||
+ | var EVENT_SHOWN = "shown" + EVENT_KEY; | ||
+ | var EVENT_CLICK = "click" + EVENT_KEY; | ||
+ | var EVENT_CLICK_DATA_API = "click" + EVENT_KEY + DATA_API_KEY; | ||
+ | var EVENT_KEYDOWN_DATA_API = "keydown" + EVENT_KEY + DATA_API_KEY; | ||
+ | var EVENT_KEYUP_DATA_API = "keyup" + EVENT_KEY + DATA_API_KEY; | ||
+ | var CLASS_NAME_DISABLED = 'disabled'; | ||
+ | var CLASS_NAME_SHOW = 'show'; | ||
+ | var CLASS_NAME_DROPUP = 'dropup'; | ||
+ | var CLASS_NAME_DROPRIGHT = 'dropright'; | ||
+ | var CLASS_NAME_DROPLEFT = 'dropleft'; | ||
+ | var CLASS_NAME_MENURIGHT = 'dropdown-menu-right'; | ||
+ | var CLASS_NAME_POSITION_STATIC = 'position-static'; | ||
+ | var SELECTOR_DATA_TOGGLE = '[data-toggle="dropdown"]'; | ||
+ | var SELECTOR_FORM_CHILD = '.dropdown form'; | ||
+ | var SELECTOR_MENU = '.dropdown-menu'; | ||
+ | var SELECTOR_NAVBAR_NAV = '.navbar-nav'; | ||
+ | var SELECTOR_VISIBLE_ITEMS = '.dropdown-menu .dropdown-item:not(.disabled):not(:disabled)'; | ||
+ | var PLACEMENT_TOP = 'top-start'; | ||
+ | var PLACEMENT_TOPEND = 'top-end'; | ||
+ | var PLACEMENT_BOTTOM = 'bottom-start'; | ||
+ | var PLACEMENT_BOTTOMEND = 'bottom-end'; | ||
+ | var PLACEMENT_RIGHT = 'right-start'; | ||
+ | var PLACEMENT_LEFT = 'left-start'; | ||
+ | var Default = { | ||
+ | offset: 0, | ||
+ | flip: true, | ||
+ | boundary: 'scrollParent', | ||
+ | reference: 'toggle', | ||
+ | display: 'dynamic', | ||
+ | popperConfig: null | ||
+ | }; | ||
+ | var DefaultType = { | ||
+ | offset: '(number|string|function)', | ||
+ | flip: 'boolean', | ||
+ | boundary: '(string|element)', | ||
+ | reference: '(string|element)', | ||
+ | display: 'string', | ||
+ | popperConfig: '(null|object)' | ||
+ | }; | ||
+ | /** | ||
+ | * ------------------------------------------------------------------------ | ||
+ | * Class Definition | ||
+ | * ------------------------------------------------------------------------ | ||
+ | */ | ||
+ | |||
+ | var Dropdown = /*#__PURE__*/function () { | ||
+ | function Dropdown(element, config) { | ||
+ | this._element = element; | ||
+ | this._popper = null; | ||
+ | this._config = this._getConfig(config); | ||
+ | this._menu = this._getMenuElement(); | ||
+ | this._inNavbar = this._detectNavbar(); | ||
+ | |||
+ | this._addEventListeners(); | ||
+ | } // Getters | ||
+ | |||
+ | |||
+ | var _proto = Dropdown.prototype; | ||
+ | |||
+ | // Public | ||
+ | _proto.toggle = function toggle() { | ||
+ | if (this._element.disabled || $(this._element).hasClass(CLASS_NAME_DISABLED)) { | ||
+ | return; | ||
+ | } | ||
+ | |||
+ | var isActive = $(this._menu).hasClass(CLASS_NAME_SHOW); | ||
+ | |||
+ | Dropdown._clearMenus(); | ||
+ | |||
+ | if (isActive) { | ||
+ | return; | ||
+ | } | ||
+ | |||
+ | this.show(true); | ||
+ | }; | ||
+ | |||
+ | _proto.show = function show(usePopper) { | ||
+ | if (usePopper === void 0) { | ||
+ | usePopper = false; | ||
+ | } | ||
+ | |||
+ | if (this._element.disabled || $(this._element).hasClass(CLASS_NAME_DISABLED) || $(this._menu).hasClass(CLASS_NAME_SHOW)) { | ||
+ | return; | ||
+ | } | ||
+ | |||
+ | var relatedTarget = { | ||
+ | relatedTarget: this._element | ||
+ | }; | ||
+ | var showEvent = $.Event(EVENT_SHOW, relatedTarget); | ||
+ | |||
+ | var parent = Dropdown._getParentFromElement(this._element); | ||
+ | |||
+ | $(parent).trigger(showEvent); | ||
+ | |||
+ | if (showEvent.isDefaultPrevented()) { | ||
+ | return; | ||
+ | } // Disable totally Popper.js for Dropdown in Navbar | ||
+ | |||
+ | |||
+ | if (!this._inNavbar && usePopper) { | ||
+ | /** | ||
+ | * Check for Popper dependency | ||
+ | * Popper - https://popper.js.org | ||
+ | */ | ||
+ | if (typeof Popper === 'undefined') { | ||
+ | throw new TypeError('Bootstrap\'s dropdowns require Popper.js (https://popper.js.org/)'); | ||
+ | } | ||
+ | |||
+ | var referenceElement = this._element; | ||
+ | |||
+ | if (this._config.reference === 'parent') { | ||
+ | referenceElement = parent; | ||
+ | } else if (Util.isElement(this._config.reference)) { | ||
+ | referenceElement = this._config.reference; // Check if it's jQuery element | ||
+ | |||
+ | if (typeof this._config.reference.jquery !== 'undefined') { | ||
+ | referenceElement = this._config.reference[0]; | ||
+ | } | ||
+ | } // If boundary is not `scrollParent`, then set position to `static` | ||
+ | // to allow the menu to "escape" the scroll parent's boundaries | ||
+ | // https://github.com/twbs/bootstrap/issues/24251 | ||
+ | |||
+ | |||
+ | if (this._config.boundary !== 'scrollParent') { | ||
+ | $(parent).addClass(CLASS_NAME_POSITION_STATIC); | ||
+ | } | ||
+ | |||
+ | this._popper = new Popper(referenceElement, this._menu, this._getPopperConfig()); | ||
+ | } // If this is a touch-enabled device we add extra | ||
+ | // empty mouseover listeners to the body's immediate children; | ||
+ | // only needed because of broken event delegation on iOS | ||
+ | // https://www.quirksmode.org/blog/archives/2014/02/mouse_event_bub.html | ||
+ | |||
+ | |||
+ | if ('ontouchstart' in document.documentElement && $(parent).closest(SELECTOR_NAVBAR_NAV).length === 0) { | ||
+ | $(document.body).children().on('mouseover', null, $.noop); | ||
+ | } | ||
+ | |||
+ | this._element.focus(); | ||
+ | |||
+ | this._element.setAttribute('aria-expanded', true); | ||
+ | |||
+ | $(this._menu).toggleClass(CLASS_NAME_SHOW); | ||
+ | $(parent).toggleClass(CLASS_NAME_SHOW).trigger($.Event(EVENT_SHOWN, relatedTarget)); | ||
+ | }; | ||
+ | |||
+ | _proto.hide = function hide() { | ||
+ | if (this._element.disabled || $(this._element).hasClass(CLASS_NAME_DISABLED) || !$(this._menu).hasClass(CLASS_NAME_SHOW)) { | ||
+ | return; | ||
+ | } | ||
+ | |||
+ | var relatedTarget = { | ||
+ | relatedTarget: this._element | ||
+ | }; | ||
+ | var hideEvent = $.Event(EVENT_HIDE, relatedTarget); | ||
+ | |||
+ | var parent = Dropdown._getParentFromElement(this._element); | ||
+ | |||
+ | $(parent).trigger(hideEvent); | ||
+ | |||
+ | if (hideEvent.isDefaultPrevented()) { | ||
+ | return; | ||
+ | } | ||
+ | |||
+ | if (this._popper) { | ||
+ | this._popper.destroy(); | ||
+ | } | ||
+ | |||
+ | $(this._menu).toggleClass(CLASS_NAME_SHOW); | ||
+ | $(parent).toggleClass(CLASS_NAME_SHOW).trigger($.Event(EVENT_HIDDEN, relatedTarget)); | ||
+ | }; | ||
+ | |||
+ | _proto.dispose = function dispose() { | ||
+ | $.removeData(this._element, DATA_KEY); | ||
+ | $(this._element).off(EVENT_KEY); | ||
+ | this._element = null; | ||
+ | this._menu = null; | ||
+ | |||
+ | if (this._popper !== null) { | ||
+ | this._popper.destroy(); | ||
+ | |||
+ | this._popper = null; | ||
+ | } | ||
+ | }; | ||
+ | |||
+ | _proto.update = function update() { | ||
+ | this._inNavbar = this._detectNavbar(); | ||
+ | |||
+ | if (this._popper !== null) { | ||
+ | this._popper.scheduleUpdate(); | ||
+ | } | ||
+ | } // Private | ||
+ | ; | ||
+ | |||
+ | _proto._addEventListeners = function _addEventListeners() { | ||
+ | var _this = this; | ||
+ | |||
+ | $(this._element).on(EVENT_CLICK, function (event) { | ||
+ | event.preventDefault(); | ||
+ | event.stopPropagation(); | ||
+ | |||
+ | _this.toggle(); | ||
+ | }); | ||
+ | }; | ||
+ | |||
+ | _proto._getConfig = function _getConfig(config) { | ||
+ | config = _objectSpread2(_objectSpread2(_objectSpread2({}, this.constructor.Default), $(this._element).data()), config); | ||
+ | Util.typeCheckConfig(NAME, config, this.constructor.DefaultType); | ||
+ | return config; | ||
+ | }; | ||
+ | |||
+ | _proto._getMenuElement = function _getMenuElement() { | ||
+ | if (!this._menu) { | ||
+ | var parent = Dropdown._getParentFromElement(this._element); | ||
+ | |||
+ | if (parent) { | ||
+ | this._menu = parent.querySelector(SELECTOR_MENU); | ||
+ | } | ||
+ | } | ||
+ | |||
+ | return this._menu; | ||
+ | }; | ||
+ | |||
+ | _proto._getPlacement = function _getPlacement() { | ||
+ | var $parentDropdown = $(this._element.parentNode); | ||
+ | var placement = PLACEMENT_BOTTOM; // Handle dropup | ||
+ | |||
+ | if ($parentDropdown.hasClass(CLASS_NAME_DROPUP)) { | ||
+ | placement = $(this._menu).hasClass(CLASS_NAME_MENURIGHT) ? PLACEMENT_TOPEND : PLACEMENT_TOP; | ||
+ | } else if ($parentDropdown.hasClass(CLASS_NAME_DROPRIGHT)) { | ||
+ | placement = PLACEMENT_RIGHT; | ||
+ | } else if ($parentDropdown.hasClass(CLASS_NAME_DROPLEFT)) { | ||
+ | placement = PLACEMENT_LEFT; | ||
+ | } else if ($(this._menu).hasClass(CLASS_NAME_MENURIGHT)) { | ||
+ | placement = PLACEMENT_BOTTOMEND; | ||
+ | } | ||
+ | |||
+ | return placement; | ||
+ | }; | ||
+ | |||
+ | _proto._detectNavbar = function _detectNavbar() { | ||
+ | return $(this._element).closest('.navbar').length > 0; | ||
+ | }; | ||
+ | |||
+ | _proto._getOffset = function _getOffset() { | ||
+ | var _this2 = this; | ||
+ | |||
+ | var offset = {}; | ||
+ | |||
+ | if (typeof this._config.offset === 'function') { | ||
+ | offset.fn = function (data) { | ||
+ | data.offsets = _objectSpread2(_objectSpread2({}, data.offsets), _this2._config.offset(data.offsets, _this2._element) || {}); | ||
+ | return data; | ||
+ | }; | ||
+ | } else { | ||
+ | offset.offset = this._config.offset; | ||
+ | } | ||
+ | |||
+ | return offset; | ||
+ | }; | ||
+ | |||
+ | _proto._getPopperConfig = function _getPopperConfig() { | ||
+ | var popperConfig = { | ||
+ | placement: this._getPlacement(), | ||
+ | modifiers: { | ||
+ | offset: this._getOffset(), | ||
+ | flip: { | ||
+ | enabled: this._config.flip | ||
+ | }, | ||
+ | preventOverflow: { | ||
+ | boundariesElement: this._config.boundary | ||
+ | } | ||
+ | } | ||
+ | }; // Disable Popper.js if we have a static display | ||
+ | |||
+ | if (this._config.display === 'static') { | ||
+ | popperConfig.modifiers.applyStyle = { | ||
+ | enabled: false | ||
+ | }; | ||
+ | } | ||
+ | |||
+ | return _objectSpread2(_objectSpread2({}, popperConfig), this._config.popperConfig); | ||
+ | } // Static | ||
+ | ; | ||
+ | |||
+ | Dropdown._jQueryInterface = function _jQueryInterface(config) { | ||
+ | return this.each(function () { | ||
+ | var data = $(this).data(DATA_KEY); | ||
+ | |||
+ | var _config = typeof config === 'object' ? config : null; | ||
+ | |||
+ | if (!data) { | ||
+ | data = new Dropdown(this, _config); | ||
+ | $(this).data(DATA_KEY, data); | ||
+ | } | ||
+ | |||
+ | if (typeof config === 'string') { | ||
+ | if (typeof data[config] === 'undefined') { | ||
+ | throw new TypeError("No method named \"" + config + "\""); | ||
+ | } | ||
+ | |||
+ | data[config](); | ||
+ | } | ||
+ | }); | ||
+ | }; | ||
+ | |||
+ | Dropdown._clearMenus = function _clearMenus(event) { | ||
+ | if (event && (event.which === RIGHT_MOUSE_BUTTON_WHICH || event.type === 'keyup' && event.which !== TAB_KEYCODE)) { | ||
+ | return; | ||
+ | } | ||
+ | |||
+ | var toggles = [].slice.call(document.querySelectorAll(SELECTOR_DATA_TOGGLE)); | ||
+ | |||
+ | for (var i = 0, len = toggles.length; i < len; i++) { | ||
+ | var parent = Dropdown._getParentFromElement(toggles[i]); | ||
+ | |||
+ | var context = $(toggles[i]).data(DATA_KEY); | ||
+ | var relatedTarget = { | ||
+ | relatedTarget: toggles[i] | ||
+ | }; | ||
+ | |||
+ | if (event && event.type === 'click') { | ||
+ | relatedTarget.clickEvent = event; | ||
+ | } | ||
+ | |||
+ | if (!context) { | ||
+ | continue; | ||
+ | } | ||
+ | |||
+ | var dropdownMenu = context._menu; | ||
+ | |||
+ | if (!$(parent).hasClass(CLASS_NAME_SHOW)) { | ||
+ | continue; | ||
+ | } | ||
+ | |||
+ | if (event && (event.type === 'click' && /input|textarea/i.test(event.target.tagName) || event.type === 'keyup' && event.which === TAB_KEYCODE) && $.contains(parent, event.target)) { | ||
+ | continue; | ||
+ | } | ||
+ | |||
+ | var hideEvent = $.Event(EVENT_HIDE, relatedTarget); | ||
+ | $(parent).trigger(hideEvent); | ||
+ | |||
+ | if (hideEvent.isDefaultPrevented()) { | ||
+ | continue; | ||
+ | } // If this is a touch-enabled device we remove the extra | ||
+ | // empty mouseover listeners we added for iOS support | ||
+ | |||
+ | |||
+ | if ('ontouchstart' in document.documentElement) { | ||
+ | $(document.body).children().off('mouseover', null, $.noop); | ||
+ | } | ||
+ | |||
+ | toggles[i].setAttribute('aria-expanded', 'false'); | ||
+ | |||
+ | if (context._popper) { | ||
+ | context._popper.destroy(); | ||
+ | } | ||
+ | |||
+ | $(dropdownMenu).removeClass(CLASS_NAME_SHOW); | ||
+ | $(parent).removeClass(CLASS_NAME_SHOW).trigger($.Event(EVENT_HIDDEN, relatedTarget)); | ||
+ | } | ||
+ | }; | ||
+ | |||
+ | Dropdown._getParentFromElement = function _getParentFromElement(element) { | ||
+ | var parent; | ||
+ | var selector = Util.getSelectorFromElement(element); | ||
+ | |||
+ | if (selector) { | ||
+ | parent = document.querySelector(selector); | ||
+ | } | ||
+ | |||
+ | return parent || element.parentNode; | ||
+ | } // eslint-disable-next-line complexity | ||
+ | ; | ||
+ | |||
+ | Dropdown._dataApiKeydownHandler = function _dataApiKeydownHandler(event) { | ||
+ | // If not input/textarea: | ||
+ | // - And not a key in REGEXP_KEYDOWN => not a dropdown command | ||
+ | // If input/textarea: | ||
+ | // - If space key => not a dropdown command | ||
+ | // - If key is other than escape | ||
+ | // - If key is not up or down => not a dropdown command | ||
+ | // - If trigger inside the menu => not a dropdown command | ||
+ | if (/input|textarea/i.test(event.target.tagName) ? event.which === SPACE_KEYCODE || event.which !== ESCAPE_KEYCODE && (event.which !== ARROW_DOWN_KEYCODE && event.which !== ARROW_UP_KEYCODE || $(event.target).closest(SELECTOR_MENU).length) : !REGEXP_KEYDOWN.test(event.which)) { | ||
+ | return; | ||
+ | } | ||
+ | |||
+ | if (this.disabled || $(this).hasClass(CLASS_NAME_DISABLED)) { | ||
+ | return; | ||
+ | } | ||
+ | |||
+ | var parent = Dropdown._getParentFromElement(this); | ||
+ | |||
+ | var isActive = $(parent).hasClass(CLASS_NAME_SHOW); | ||
+ | |||
+ | if (!isActive && event.which === ESCAPE_KEYCODE) { | ||
+ | return; | ||
+ | } | ||
+ | |||
+ | event.preventDefault(); | ||
+ | event.stopPropagation(); | ||
+ | |||
+ | if (!isActive || isActive && (event.which === ESCAPE_KEYCODE || event.which === SPACE_KEYCODE)) { | ||
+ | if (event.which === ESCAPE_KEYCODE) { | ||
+ | $(parent.querySelector(SELECTOR_DATA_TOGGLE)).trigger('focus'); | ||
+ | } | ||
+ | |||
+ | $(this).trigger('click'); | ||
+ | return; | ||
+ | } | ||
+ | |||
+ | var items = [].slice.call(parent.querySelectorAll(SELECTOR_VISIBLE_ITEMS)).filter(function (item) { | ||
+ | return $(item).is(':visible'); | ||
+ | }); | ||
+ | |||
+ | if (items.length === 0) { | ||
+ | return; | ||
+ | } | ||
+ | |||
+ | var index = items.indexOf(event.target); | ||
+ | |||
+ | if (event.which === ARROW_UP_KEYCODE && index > 0) { | ||
+ | // Up | ||
+ | index--; | ||
+ | } | ||
+ | |||
+ | if (event.which === ARROW_DOWN_KEYCODE && index < items.length - 1) { | ||
+ | // Down | ||
+ | index++; | ||
+ | } | ||
+ | |||
+ | if (index < 0) { | ||
+ | index = 0; | ||
+ | } | ||
+ | |||
+ | items[index].focus(); | ||
+ | }; | ||
+ | |||
+ | _createClass(Dropdown, null, [{ | ||
+ | key: "VERSION", | ||
+ | get: function get() { | ||
+ | return VERSION; | ||
+ | } | ||
+ | }, { | ||
+ | key: "Default", | ||
+ | get: function get() { | ||
+ | return Default; | ||
+ | } | ||
+ | }, { | ||
+ | key: "DefaultType", | ||
+ | get: function get() { | ||
+ | return DefaultType; | ||
+ | } | ||
+ | }]); | ||
+ | |||
+ | return Dropdown; | ||
+ | }(); | ||
+ | /** | ||
+ | * ------------------------------------------------------------------------ | ||
+ | * Data Api implementation | ||
+ | * ------------------------------------------------------------------------ | ||
+ | */ | ||
+ | |||
+ | |||
+ | $(document).on(EVENT_KEYDOWN_DATA_API, SELECTOR_DATA_TOGGLE, Dropdown._dataApiKeydownHandler).on(EVENT_KEYDOWN_DATA_API, SELECTOR_MENU, Dropdown._dataApiKeydownHandler).on(EVENT_CLICK_DATA_API + " " + EVENT_KEYUP_DATA_API, Dropdown._clearMenus).on(EVENT_CLICK_DATA_API, SELECTOR_DATA_TOGGLE, function (event) { | ||
+ | event.preventDefault(); | ||
+ | event.stopPropagation(); | ||
+ | |||
+ | Dropdown._jQueryInterface.call($(this), 'toggle'); | ||
+ | }).on(EVENT_CLICK_DATA_API, SELECTOR_FORM_CHILD, function (e) { | ||
+ | e.stopPropagation(); | ||
+ | }); | ||
+ | /** | ||
+ | * ------------------------------------------------------------------------ | ||
+ | * jQuery | ||
+ | * ------------------------------------------------------------------------ | ||
+ | */ | ||
+ | |||
+ | $.fn[NAME] = Dropdown._jQueryInterface; | ||
+ | $.fn[NAME].Constructor = Dropdown; | ||
+ | |||
+ | $.fn[NAME].noConflict = function () { | ||
+ | $.fn[NAME] = JQUERY_NO_CONFLICT; | ||
+ | return Dropdown._jQueryInterface; | ||
+ | }; | ||
+ | |||
+ | return Dropdown; | ||
+ | |||
+ | }))); | ||
/*! | /*! | ||
− | + | * Bootstrap tooltip.js v4.5.0 (https://getbootstrap.com/) | |
− | + | * Copyright 2011-2020 The Bootstrap Authors (https://github.com/twbs/bootstrap/graphs/contributors) | |
− | + | * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) | |
+ | */ | ||
+ | (function (global, factory) { | ||
+ | typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory(require('jquery'), require('popper.js'), require('./util.js')) : | ||
+ | typeof define === 'function' && define.amd ? define(['jquery', 'popper.js', './util.js'], factory) : | ||
+ | (global = global || self, global.Tooltip = factory(global.jQuery, global.Popper, global.Util)); | ||
+ | }(this, (function ($, Popper, Util) { 'use strict'; | ||
+ | |||
+ | $ = $ && Object.prototype.hasOwnProperty.call($, 'default') ? $['default'] : $; | ||
+ | Popper = Popper && Object.prototype.hasOwnProperty.call(Popper, 'default') ? Popper['default'] : Popper; | ||
+ | Util = Util && Object.prototype.hasOwnProperty.call(Util, 'default') ? Util['default'] : Util; | ||
+ | |||
+ | function _defineProperties(target, props) { | ||
+ | for (var i = 0; i < props.length; i++) { | ||
+ | var descriptor = props[i]; | ||
+ | descriptor.enumerable = descriptor.enumerable || false; | ||
+ | descriptor.configurable = true; | ||
+ | if ("value" in descriptor) descriptor.writable = true; | ||
+ | Object.defineProperty(target, descriptor.key, descriptor); | ||
+ | } | ||
+ | } | ||
+ | |||
+ | function _createClass(Constructor, protoProps, staticProps) { | ||
+ | if (protoProps) _defineProperties(Constructor.prototype, protoProps); | ||
+ | if (staticProps) _defineProperties(Constructor, staticProps); | ||
+ | return Constructor; | ||
+ | } | ||
+ | |||
+ | function _defineProperty(obj, key, value) { | ||
+ | if (key in obj) { | ||
+ | Object.defineProperty(obj, key, { | ||
+ | value: value, | ||
+ | enumerable: true, | ||
+ | configurable: true, | ||
+ | writable: true | ||
+ | }); | ||
+ | } else { | ||
+ | obj[key] = value; | ||
+ | } | ||
+ | |||
+ | return obj; | ||
+ | } | ||
+ | |||
+ | function ownKeys(object, enumerableOnly) { | ||
+ | var keys = Object.keys(object); | ||
+ | |||
+ | if (Object.getOwnPropertySymbols) { | ||
+ | var symbols = Object.getOwnPropertySymbols(object); | ||
+ | if (enumerableOnly) symbols = symbols.filter(function (sym) { | ||
+ | return Object.getOwnPropertyDescriptor(object, sym).enumerable; | ||
+ | }); | ||
+ | keys.push.apply(keys, symbols); | ||
+ | } | ||
+ | |||
+ | return keys; | ||
+ | } | ||
+ | |||
+ | function _objectSpread2(target) { | ||
+ | for (var i = 1; i < arguments.length; i++) { | ||
+ | var source = arguments[i] != null ? arguments[i] : {}; | ||
+ | |||
+ | if (i % 2) { | ||
+ | ownKeys(Object(source), true).forEach(function (key) { | ||
+ | _defineProperty(target, key, source[key]); | ||
+ | }); | ||
+ | } else if (Object.getOwnPropertyDescriptors) { | ||
+ | Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); | ||
+ | } else { | ||
+ | ownKeys(Object(source)).forEach(function (key) { | ||
+ | Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); | ||
+ | }); | ||
+ | } | ||
+ | } | ||
+ | |||
+ | return target; | ||
+ | } | ||
+ | |||
+ | /** | ||
+ | * -------------------------------------------------------------------------- | ||
+ | * Bootstrap (v4.5.0): tools/sanitizer.js | ||
+ | * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) | ||
+ | * -------------------------------------------------------------------------- | ||
+ | */ | ||
+ | var uriAttrs = ['background', 'cite', 'href', 'itemtype', 'longdesc', 'poster', 'src', 'xlink:href']; | ||
+ | var ARIA_ATTRIBUTE_PATTERN = /^aria-[\w-]*$/i; | ||
+ | var DefaultWhitelist = { | ||
+ | // Global attributes allowed on any supplied element below. | ||
+ | '*': ['class', 'dir', 'id', 'lang', 'role', ARIA_ATTRIBUTE_PATTERN], | ||
+ | a: ['target', 'href', 'title', 'rel'], | ||
+ | area: [], | ||
+ | b: [], | ||
+ | br: [], | ||
+ | col: [], | ||
+ | code: [], | ||
+ | div: [], | ||
+ | em: [], | ||
+ | hr: [], | ||
+ | h1: [], | ||
+ | h2: [], | ||
+ | h3: [], | ||
+ | h4: [], | ||
+ | h5: [], | ||
+ | h6: [], | ||
+ | i: [], | ||
+ | img: ['src', 'srcset', 'alt', 'title', 'width', 'height'], | ||
+ | li: [], | ||
+ | ol: [], | ||
+ | p: [], | ||
+ | pre: [], | ||
+ | s: [], | ||
+ | small: [], | ||
+ | span: [], | ||
+ | sub: [], | ||
+ | sup: [], | ||
+ | strong: [], | ||
+ | u: [], | ||
+ | ul: [] | ||
+ | }; | ||
+ | /** | ||
+ | * A pattern that recognizes a commonly useful subset of URLs that are safe. | ||
+ | * | ||
+ | * Shoutout to Angular 7 https://github.com/angular/angular/blob/7.2.4/packages/core/src/sanitization/url_sanitizer.ts | ||
+ | */ | ||
+ | |||
+ | var SAFE_URL_PATTERN = /^(?:(?:https?|mailto|ftp|tel|file):|[^#&/:?]*(?:[#/?]|$))/gi; | ||
+ | /** | ||
+ | * A pattern that matches safe data URLs. Only matches image, video and audio types. | ||
+ | * | ||
+ | * Shoutout to Angular 7 https://github.com/angular/angular/blob/7.2.4/packages/core/src/sanitization/url_sanitizer.ts | ||
+ | */ | ||
+ | |||
+ | var DATA_URL_PATTERN = /^data:(?:image\/(?:bmp|gif|jpeg|jpg|png|tiff|webp)|video\/(?:mpeg|mp4|ogg|webm)|audio\/(?:mp3|oga|ogg|opus));base64,[\d+/a-z]+=*$/i; | ||
+ | |||
+ | function allowedAttribute(attr, allowedAttributeList) { | ||
+ | var attrName = attr.nodeName.toLowerCase(); | ||
+ | |||
+ | if (allowedAttributeList.indexOf(attrName) !== -1) { | ||
+ | if (uriAttrs.indexOf(attrName) !== -1) { | ||
+ | return Boolean(attr.nodeValue.match(SAFE_URL_PATTERN) || attr.nodeValue.match(DATA_URL_PATTERN)); | ||
+ | } | ||
+ | |||
+ | return true; | ||
+ | } | ||
+ | |||
+ | var regExp = allowedAttributeList.filter(function (attrRegex) { | ||
+ | return attrRegex instanceof RegExp; | ||
+ | }); // Check if a regular expression validates the attribute. | ||
+ | |||
+ | for (var i = 0, len = regExp.length; i < len; i++) { | ||
+ | if (attrName.match(regExp[i])) { | ||
+ | return true; | ||
+ | } | ||
+ | } | ||
+ | |||
+ | return false; | ||
+ | } | ||
+ | |||
+ | function sanitizeHtml(unsafeHtml, whiteList, sanitizeFn) { | ||
+ | if (unsafeHtml.length === 0) { | ||
+ | return unsafeHtml; | ||
+ | } | ||
+ | |||
+ | if (sanitizeFn && typeof sanitizeFn === 'function') { | ||
+ | return sanitizeFn(unsafeHtml); | ||
+ | } | ||
+ | |||
+ | var domParser = new window.DOMParser(); | ||
+ | var createdDocument = domParser.parseFromString(unsafeHtml, 'text/html'); | ||
+ | var whitelistKeys = Object.keys(whiteList); | ||
+ | var elements = [].slice.call(createdDocument.body.querySelectorAll('*')); | ||
+ | |||
+ | var _loop = function _loop(i, len) { | ||
+ | var el = elements[i]; | ||
+ | var elName = el.nodeName.toLowerCase(); | ||
+ | |||
+ | if (whitelistKeys.indexOf(el.nodeName.toLowerCase()) === -1) { | ||
+ | el.parentNode.removeChild(el); | ||
+ | return "continue"; | ||
+ | } | ||
+ | |||
+ | var attributeList = [].slice.call(el.attributes); | ||
+ | var whitelistedAttributes = [].concat(whiteList['*'] || [], whiteList[elName] || []); | ||
+ | attributeList.forEach(function (attr) { | ||
+ | if (!allowedAttribute(attr, whitelistedAttributes)) { | ||
+ | el.removeAttribute(attr.nodeName); | ||
+ | } | ||
+ | }); | ||
+ | }; | ||
+ | |||
+ | for (var i = 0, len = elements.length; i < len; i++) { | ||
+ | var _ret = _loop(i); | ||
+ | |||
+ | if (_ret === "continue") continue; | ||
+ | } | ||
+ | |||
+ | return createdDocument.body.innerHTML; | ||
+ | } | ||
+ | |||
+ | /** | ||
+ | * ------------------------------------------------------------------------ | ||
+ | * Constants | ||
+ | * ------------------------------------------------------------------------ | ||
+ | */ | ||
+ | |||
+ | var NAME = 'tooltip'; | ||
+ | var VERSION = '4.5.0'; | ||
+ | var DATA_KEY = 'bs.tooltip'; | ||
+ | var EVENT_KEY = "." + DATA_KEY; | ||
+ | var JQUERY_NO_CONFLICT = $.fn[NAME]; | ||
+ | var CLASS_PREFIX = 'bs-tooltip'; | ||
+ | var BSCLS_PREFIX_REGEX = new RegExp("(^|\\s)" + CLASS_PREFIX + "\\S+", 'g'); | ||
+ | var DISALLOWED_ATTRIBUTES = ['sanitize', 'whiteList', 'sanitizeFn']; | ||
+ | var DefaultType = { | ||
+ | animation: 'boolean', | ||
+ | template: 'string', | ||
+ | title: '(string|element|function)', | ||
+ | trigger: 'string', | ||
+ | delay: '(number|object)', | ||
+ | html: 'boolean', | ||
+ | selector: '(string|boolean)', | ||
+ | placement: '(string|function)', | ||
+ | offset: '(number|string|function)', | ||
+ | container: '(string|element|boolean)', | ||
+ | fallbackPlacement: '(string|array)', | ||
+ | boundary: '(string|element)', | ||
+ | sanitize: 'boolean', | ||
+ | sanitizeFn: '(null|function)', | ||
+ | whiteList: 'object', | ||
+ | popperConfig: '(null|object)' | ||
+ | }; | ||
+ | var AttachmentMap = { | ||
+ | AUTO: 'auto', | ||
+ | TOP: 'top', | ||
+ | RIGHT: 'right', | ||
+ | BOTTOM: 'bottom', | ||
+ | LEFT: 'left' | ||
+ | }; | ||
+ | var Default = { | ||
+ | animation: true, | ||
+ | template: '<div class="tooltip" role="tooltip">' + '<div class="arrow"></div>' + '<div class="tooltip-inner"></div></div>', | ||
+ | trigger: 'hover focus', | ||
+ | title: '', | ||
+ | delay: 0, | ||
+ | html: false, | ||
+ | selector: false, | ||
+ | placement: 'top', | ||
+ | offset: 0, | ||
+ | container: false, | ||
+ | fallbackPlacement: 'flip', | ||
+ | boundary: 'scrollParent', | ||
+ | sanitize: true, | ||
+ | sanitizeFn: null, | ||
+ | whiteList: DefaultWhitelist, | ||
+ | popperConfig: null | ||
+ | }; | ||
+ | var HOVER_STATE_SHOW = 'show'; | ||
+ | var HOVER_STATE_OUT = 'out'; | ||
+ | var Event = { | ||
+ | HIDE: "hide" + EVENT_KEY, | ||
+ | HIDDEN: "hidden" + EVENT_KEY, | ||
+ | SHOW: "show" + EVENT_KEY, | ||
+ | SHOWN: "shown" + EVENT_KEY, | ||
+ | INSERTED: "inserted" + EVENT_KEY, | ||
+ | CLICK: "click" + EVENT_KEY, | ||
+ | FOCUSIN: "focusin" + EVENT_KEY, | ||
+ | FOCUSOUT: "focusout" + EVENT_KEY, | ||
+ | MOUSEENTER: "mouseenter" + EVENT_KEY, | ||
+ | MOUSELEAVE: "mouseleave" + EVENT_KEY | ||
+ | }; | ||
+ | var CLASS_NAME_FADE = 'fade'; | ||
+ | var CLASS_NAME_SHOW = 'show'; | ||
+ | var SELECTOR_TOOLTIP_INNER = '.tooltip-inner'; | ||
+ | var SELECTOR_ARROW = '.arrow'; | ||
+ | var TRIGGER_HOVER = 'hover'; | ||
+ | var TRIGGER_FOCUS = 'focus'; | ||
+ | var TRIGGER_CLICK = 'click'; | ||
+ | var TRIGGER_MANUAL = 'manual'; | ||
+ | /** | ||
+ | * ------------------------------------------------------------------------ | ||
+ | * Class Definition | ||
+ | * ------------------------------------------------------------------------ | ||
+ | */ | ||
+ | |||
+ | var Tooltip = /*#__PURE__*/function () { | ||
+ | function Tooltip(element, config) { | ||
+ | if (typeof Popper === 'undefined') { | ||
+ | throw new TypeError('Bootstrap\'s tooltips require Popper.js (https://popper.js.org/)'); | ||
+ | } // private | ||
+ | |||
+ | |||
+ | this._isEnabled = true; | ||
+ | this._timeout = 0; | ||
+ | this._hoverState = ''; | ||
+ | this._activeTrigger = {}; | ||
+ | this._popper = null; // Protected | ||
+ | |||
+ | this.element = element; | ||
+ | this.config = this._getConfig(config); | ||
+ | this.tip = null; | ||
+ | |||
+ | this._setListeners(); | ||
+ | } // Getters | ||
+ | |||
+ | |||
+ | var _proto = Tooltip.prototype; | ||
+ | |||
+ | // Public | ||
+ | _proto.enable = function enable() { | ||
+ | this._isEnabled = true; | ||
+ | }; | ||
+ | |||
+ | _proto.disable = function disable() { | ||
+ | this._isEnabled = false; | ||
+ | }; | ||
+ | |||
+ | _proto.toggleEnabled = function toggleEnabled() { | ||
+ | this._isEnabled = !this._isEnabled; | ||
+ | }; | ||
+ | |||
+ | _proto.toggle = function toggle(event) { | ||
+ | if (!this._isEnabled) { | ||
+ | return; | ||
+ | } | ||
+ | |||
+ | if (event) { | ||
+ | var dataKey = this.constructor.DATA_KEY; | ||
+ | var context = $(event.currentTarget).data(dataKey); | ||
+ | |||
+ | if (!context) { | ||
+ | context = new this.constructor(event.currentTarget, this._getDelegateConfig()); | ||
+ | $(event.currentTarget).data(dataKey, context); | ||
+ | } | ||
+ | |||
+ | context._activeTrigger.click = !context._activeTrigger.click; | ||
+ | |||
+ | if (context._isWithActiveTrigger()) { | ||
+ | context._enter(null, context); | ||
+ | } else { | ||
+ | context._leave(null, context); | ||
+ | } | ||
+ | } else { | ||
+ | if ($(this.getTipElement()).hasClass(CLASS_NAME_SHOW)) { | ||
+ | this._leave(null, this); | ||
+ | |||
+ | return; | ||
+ | } | ||
+ | |||
+ | this._enter(null, this); | ||
+ | } | ||
+ | }; | ||
+ | |||
+ | _proto.dispose = function dispose() { | ||
+ | clearTimeout(this._timeout); | ||
+ | $.removeData(this.element, this.constructor.DATA_KEY); | ||
+ | $(this.element).off(this.constructor.EVENT_KEY); | ||
+ | $(this.element).closest('.modal').off('hide.bs.modal', this._hideModalHandler); | ||
+ | |||
+ | if (this.tip) { | ||
+ | $(this.tip).remove(); | ||
+ | } | ||
+ | |||
+ | this._isEnabled = null; | ||
+ | this._timeout = null; | ||
+ | this._hoverState = null; | ||
+ | this._activeTrigger = null; | ||
+ | |||
+ | if (this._popper) { | ||
+ | this._popper.destroy(); | ||
+ | } | ||
+ | |||
+ | this._popper = null; | ||
+ | this.element = null; | ||
+ | this.config = null; | ||
+ | this.tip = null; | ||
+ | }; | ||
+ | |||
+ | _proto.show = function show() { | ||
+ | var _this = this; | ||
+ | |||
+ | if ($(this.element).css('display') === 'none') { | ||
+ | throw new Error('Please use show on visible elements'); | ||
+ | } | ||
+ | |||
+ | var showEvent = $.Event(this.constructor.Event.SHOW); | ||
+ | |||
+ | if (this.isWithContent() && this._isEnabled) { | ||
+ | $(this.element).trigger(showEvent); | ||
+ | var shadowRoot = Util.findShadowRoot(this.element); | ||
+ | var isInTheDom = $.contains(shadowRoot !== null ? shadowRoot : this.element.ownerDocument.documentElement, this.element); | ||
+ | |||
+ | if (showEvent.isDefaultPrevented() || !isInTheDom) { | ||
+ | return; | ||
+ | } | ||
+ | |||
+ | var tip = this.getTipElement(); | ||
+ | var tipId = Util.getUID(this.constructor.NAME); | ||
+ | tip.setAttribute('id', tipId); | ||
+ | this.element.setAttribute('aria-describedby', tipId); | ||
+ | this.setContent(); | ||
+ | |||
+ | if (this.config.animation) { | ||
+ | $(tip).addClass(CLASS_NAME_FADE); | ||
+ | } | ||
+ | |||
+ | var placement = typeof this.config.placement === 'function' ? this.config.placement.call(this, tip, this.element) : this.config.placement; | ||
+ | |||
+ | var attachment = this._getAttachment(placement); | ||
+ | |||
+ | this.addAttachmentClass(attachment); | ||
+ | |||
+ | var container = this._getContainer(); | ||
+ | |||
+ | $(tip).data(this.constructor.DATA_KEY, this); | ||
+ | |||
+ | if (!$.contains(this.element.ownerDocument.documentElement, this.tip)) { | ||
+ | $(tip).appendTo(container); | ||
+ | } | ||
+ | |||
+ | $(this.element).trigger(this.constructor.Event.INSERTED); | ||
+ | this._popper = new Popper(this.element, tip, this._getPopperConfig(attachment)); | ||
+ | $(tip).addClass(CLASS_NAME_SHOW); // If this is a touch-enabled device we add extra | ||
+ | // empty mouseover listeners to the body's immediate children; | ||
+ | // only needed because of broken event delegation on iOS | ||
+ | // https://www.quirksmode.org/blog/archives/2014/02/mouse_event_bub.html | ||
+ | |||
+ | if ('ontouchstart' in document.documentElement) { | ||
+ | $(document.body).children().on('mouseover', null, $.noop); | ||
+ | } | ||
+ | |||
+ | var complete = function complete() { | ||
+ | if (_this.config.animation) { | ||
+ | _this._fixTransition(); | ||
+ | } | ||
+ | |||
+ | var prevHoverState = _this._hoverState; | ||
+ | _this._hoverState = null; | ||
+ | $(_this.element).trigger(_this.constructor.Event.SHOWN); | ||
+ | |||
+ | if (prevHoverState === HOVER_STATE_OUT) { | ||
+ | _this._leave(null, _this); | ||
+ | } | ||
+ | }; | ||
+ | |||
+ | if ($(this.tip).hasClass(CLASS_NAME_FADE)) { | ||
+ | var transitionDuration = Util.getTransitionDurationFromElement(this.tip); | ||
+ | $(this.tip).one(Util.TRANSITION_END, complete).emulateTransitionEnd(transitionDuration); | ||
+ | } else { | ||
+ | complete(); | ||
+ | } | ||
+ | } | ||
+ | }; | ||
+ | |||
+ | _proto.hide = function hide(callback) { | ||
+ | var _this2 = this; | ||
+ | |||
+ | var tip = this.getTipElement(); | ||
+ | var hideEvent = $.Event(this.constructor.Event.HIDE); | ||
+ | |||
+ | var complete = function complete() { | ||
+ | if (_this2._hoverState !== HOVER_STATE_SHOW && tip.parentNode) { | ||
+ | tip.parentNode.removeChild(tip); | ||
+ | } | ||
+ | |||
+ | _this2._cleanTipClass(); | ||
+ | |||
+ | _this2.element.removeAttribute('aria-describedby'); | ||
+ | |||
+ | $(_this2.element).trigger(_this2.constructor.Event.HIDDEN); | ||
+ | |||
+ | if (_this2._popper !== null) { | ||
+ | _this2._popper.destroy(); | ||
+ | } | ||
+ | |||
+ | if (callback) { | ||
+ | callback(); | ||
+ | } | ||
+ | }; | ||
+ | |||
+ | $(this.element).trigger(hideEvent); | ||
+ | |||
+ | if (hideEvent.isDefaultPrevented()) { | ||
+ | return; | ||
+ | } | ||
+ | |||
+ | $(tip).removeClass(CLASS_NAME_SHOW); // If this is a touch-enabled device we remove the extra | ||
+ | // empty mouseover listeners we added for iOS support | ||
+ | |||
+ | if ('ontouchstart' in document.documentElement) { | ||
+ | $(document.body).children().off('mouseover', null, $.noop); | ||
+ | } | ||
+ | |||
+ | this._activeTrigger[TRIGGER_CLICK] = false; | ||
+ | this._activeTrigger[TRIGGER_FOCUS] = false; | ||
+ | this._activeTrigger[TRIGGER_HOVER] = false; | ||
+ | |||
+ | if ($(this.tip).hasClass(CLASS_NAME_FADE)) { | ||
+ | var transitionDuration = Util.getTransitionDurationFromElement(tip); | ||
+ | $(tip).one(Util.TRANSITION_END, complete).emulateTransitionEnd(transitionDuration); | ||
+ | } else { | ||
+ | complete(); | ||
+ | } | ||
+ | |||
+ | this._hoverState = ''; | ||
+ | }; | ||
+ | |||
+ | _proto.update = function update() { | ||
+ | if (this._popper !== null) { | ||
+ | this._popper.scheduleUpdate(); | ||
+ | } | ||
+ | } // Protected | ||
+ | ; | ||
+ | |||
+ | _proto.isWithContent = function isWithContent() { | ||
+ | return Boolean(this.getTitle()); | ||
+ | }; | ||
+ | |||
+ | _proto.addAttachmentClass = function addAttachmentClass(attachment) { | ||
+ | $(this.getTipElement()).addClass(CLASS_PREFIX + "-" + attachment); | ||
+ | }; | ||
+ | |||
+ | _proto.getTipElement = function getTipElement() { | ||
+ | this.tip = this.tip || $(this.config.template)[0]; | ||
+ | return this.tip; | ||
+ | }; | ||
+ | |||
+ | _proto.setContent = function setContent() { | ||
+ | var tip = this.getTipElement(); | ||
+ | this.setElementContent($(tip.querySelectorAll(SELECTOR_TOOLTIP_INNER)), this.getTitle()); | ||
+ | $(tip).removeClass(CLASS_NAME_FADE + " " + CLASS_NAME_SHOW); | ||
+ | }; | ||
+ | |||
+ | _proto.setElementContent = function setElementContent($element, content) { | ||
+ | if (typeof content === 'object' && (content.nodeType || content.jquery)) { | ||
+ | // Content is a DOM node or a jQuery | ||
+ | if (this.config.html) { | ||
+ | if (!$(content).parent().is($element)) { | ||
+ | $element.empty().append(content); | ||
+ | } | ||
+ | } else { | ||
+ | $element.text($(content).text()); | ||
+ | } | ||
+ | |||
+ | return; | ||
+ | } | ||
+ | |||
+ | if (this.config.html) { | ||
+ | if (this.config.sanitize) { | ||
+ | content = sanitizeHtml(content, this.config.whiteList, this.config.sanitizeFn); | ||
+ | } | ||
+ | |||
+ | $element.html(content); | ||
+ | } else { | ||
+ | $element.text(content); | ||
+ | } | ||
+ | }; | ||
+ | |||
+ | _proto.getTitle = function getTitle() { | ||
+ | var title = this.element.getAttribute('data-original-title'); | ||
+ | |||
+ | if (!title) { | ||
+ | title = typeof this.config.title === 'function' ? this.config.title.call(this.element) : this.config.title; | ||
+ | } | ||
+ | |||
+ | return title; | ||
+ | } // Private | ||
+ | ; | ||
+ | |||
+ | _proto._getPopperConfig = function _getPopperConfig(attachment) { | ||
+ | var _this3 = this; | ||
+ | |||
+ | var defaultBsConfig = { | ||
+ | placement: attachment, | ||
+ | modifiers: { | ||
+ | offset: this._getOffset(), | ||
+ | flip: { | ||
+ | behavior: this.config.fallbackPlacement | ||
+ | }, | ||
+ | arrow: { | ||
+ | element: SELECTOR_ARROW | ||
+ | }, | ||
+ | preventOverflow: { | ||
+ | boundariesElement: this.config.boundary | ||
+ | } | ||
+ | }, | ||
+ | onCreate: function onCreate(data) { | ||
+ | if (data.originalPlacement !== data.placement) { | ||
+ | _this3._handlePopperPlacementChange(data); | ||
+ | } | ||
+ | }, | ||
+ | onUpdate: function onUpdate(data) { | ||
+ | return _this3._handlePopperPlacementChange(data); | ||
+ | } | ||
+ | }; | ||
+ | return _objectSpread2(_objectSpread2({}, defaultBsConfig), this.config.popperConfig); | ||
+ | }; | ||
+ | |||
+ | _proto._getOffset = function _getOffset() { | ||
+ | var _this4 = this; | ||
+ | |||
+ | var offset = {}; | ||
+ | |||
+ | if (typeof this.config.offset === 'function') { | ||
+ | offset.fn = function (data) { | ||
+ | data.offsets = _objectSpread2(_objectSpread2({}, data.offsets), _this4.config.offset(data.offsets, _this4.element) || {}); | ||
+ | return data; | ||
+ | }; | ||
+ | } else { | ||
+ | offset.offset = this.config.offset; | ||
+ | } | ||
+ | |||
+ | return offset; | ||
+ | }; | ||
+ | |||
+ | _proto._getContainer = function _getContainer() { | ||
+ | if (this.config.container === false) { | ||
+ | return document.body; | ||
+ | } | ||
+ | |||
+ | if (Util.isElement(this.config.container)) { | ||
+ | return $(this.config.container); | ||
+ | } | ||
+ | |||
+ | return $(document).find(this.config.container); | ||
+ | }; | ||
+ | |||
+ | _proto._getAttachment = function _getAttachment(placement) { | ||
+ | return AttachmentMap[placement.toUpperCase()]; | ||
+ | }; | ||
+ | |||
+ | _proto._setListeners = function _setListeners() { | ||
+ | var _this5 = this; | ||
+ | |||
+ | var triggers = this.config.trigger.split(' '); | ||
+ | triggers.forEach(function (trigger) { | ||
+ | if (trigger === 'click') { | ||
+ | $(_this5.element).on(_this5.constructor.Event.CLICK, _this5.config.selector, function (event) { | ||
+ | return _this5.toggle(event); | ||
+ | }); | ||
+ | } else if (trigger !== TRIGGER_MANUAL) { | ||
+ | var eventIn = trigger === TRIGGER_HOVER ? _this5.constructor.Event.MOUSEENTER : _this5.constructor.Event.FOCUSIN; | ||
+ | var eventOut = trigger === TRIGGER_HOVER ? _this5.constructor.Event.MOUSELEAVE : _this5.constructor.Event.FOCUSOUT; | ||
+ | $(_this5.element).on(eventIn, _this5.config.selector, function (event) { | ||
+ | return _this5._enter(event); | ||
+ | }).on(eventOut, _this5.config.selector, function (event) { | ||
+ | return _this5._leave(event); | ||
+ | }); | ||
+ | } | ||
+ | }); | ||
+ | |||
+ | this._hideModalHandler = function () { | ||
+ | if (_this5.element) { | ||
+ | _this5.hide(); | ||
+ | } | ||
+ | }; | ||
+ | |||
+ | $(this.element).closest('.modal').on('hide.bs.modal', this._hideModalHandler); | ||
+ | |||
+ | if (this.config.selector) { | ||
+ | this.config = _objectSpread2(_objectSpread2({}, this.config), {}, { | ||
+ | trigger: 'manual', | ||
+ | selector: '' | ||
+ | }); | ||
+ | } else { | ||
+ | this._fixTitle(); | ||
+ | } | ||
+ | }; | ||
+ | |||
+ | _proto._fixTitle = function _fixTitle() { | ||
+ | var titleType = typeof this.element.getAttribute('data-original-title'); | ||
+ | |||
+ | if (this.element.getAttribute('title') || titleType !== 'string') { | ||
+ | this.element.setAttribute('data-original-title', this.element.getAttribute('title') || ''); | ||
+ | this.element.setAttribute('title', ''); | ||
+ | } | ||
+ | }; | ||
+ | |||
+ | _proto._enter = function _enter(event, context) { | ||
+ | var dataKey = this.constructor.DATA_KEY; | ||
+ | context = context || $(event.currentTarget).data(dataKey); | ||
+ | |||
+ | if (!context) { | ||
+ | context = new this.constructor(event.currentTarget, this._getDelegateConfig()); | ||
+ | $(event.currentTarget).data(dataKey, context); | ||
+ | } | ||
+ | |||
+ | if (event) { | ||
+ | context._activeTrigger[event.type === 'focusin' ? TRIGGER_FOCUS : TRIGGER_HOVER] = true; | ||
+ | } | ||
+ | |||
+ | if ($(context.getTipElement()).hasClass(CLASS_NAME_SHOW) || context._hoverState === HOVER_STATE_SHOW) { | ||
+ | context._hoverState = HOVER_STATE_SHOW; | ||
+ | return; | ||
+ | } | ||
+ | |||
+ | clearTimeout(context._timeout); | ||
+ | context._hoverState = HOVER_STATE_SHOW; | ||
+ | |||
+ | if (!context.config.delay || !context.config.delay.show) { | ||
+ | context.show(); | ||
+ | return; | ||
+ | } | ||
+ | |||
+ | context._timeout = setTimeout(function () { | ||
+ | if (context._hoverState === HOVER_STATE_SHOW) { | ||
+ | context.show(); | ||
+ | } | ||
+ | }, context.config.delay.show); | ||
+ | }; | ||
+ | |||
+ | _proto._leave = function _leave(event, context) { | ||
+ | var dataKey = this.constructor.DATA_KEY; | ||
+ | context = context || $(event.currentTarget).data(dataKey); | ||
+ | |||
+ | if (!context) { | ||
+ | context = new this.constructor(event.currentTarget, this._getDelegateConfig()); | ||
+ | $(event.currentTarget).data(dataKey, context); | ||
+ | } | ||
+ | |||
+ | if (event) { | ||
+ | context._activeTrigger[event.type === 'focusout' ? TRIGGER_FOCUS : TRIGGER_HOVER] = false; | ||
+ | } | ||
+ | |||
+ | if (context._isWithActiveTrigger()) { | ||
+ | return; | ||
+ | } | ||
+ | |||
+ | clearTimeout(context._timeout); | ||
+ | context._hoverState = HOVER_STATE_OUT; | ||
+ | |||
+ | if (!context.config.delay || !context.config.delay.hide) { | ||
+ | context.hide(); | ||
+ | return; | ||
+ | } | ||
+ | |||
+ | context._timeout = setTimeout(function () { | ||
+ | if (context._hoverState === HOVER_STATE_OUT) { | ||
+ | context.hide(); | ||
+ | } | ||
+ | }, context.config.delay.hide); | ||
+ | }; | ||
+ | |||
+ | _proto._isWithActiveTrigger = function _isWithActiveTrigger() { | ||
+ | for (var trigger in this._activeTrigger) { | ||
+ | if (this._activeTrigger[trigger]) { | ||
+ | return true; | ||
+ | } | ||
+ | } | ||
+ | |||
+ | return false; | ||
+ | }; | ||
+ | |||
+ | _proto._getConfig = function _getConfig(config) { | ||
+ | var dataAttributes = $(this.element).data(); | ||
+ | Object.keys(dataAttributes).forEach(function (dataAttr) { | ||
+ | if (DISALLOWED_ATTRIBUTES.indexOf(dataAttr) !== -1) { | ||
+ | delete dataAttributes[dataAttr]; | ||
+ | } | ||
+ | }); | ||
+ | config = _objectSpread2(_objectSpread2(_objectSpread2({}, this.constructor.Default), dataAttributes), typeof config === 'object' && config ? config : {}); | ||
+ | |||
+ | if (typeof config.delay === 'number') { | ||
+ | config.delay = { | ||
+ | show: config.delay, | ||
+ | hide: config.delay | ||
+ | }; | ||
+ | } | ||
+ | |||
+ | if (typeof config.title === 'number') { | ||
+ | config.title = config.title.toString(); | ||
+ | } | ||
+ | |||
+ | if (typeof config.content === 'number') { | ||
+ | config.content = config.content.toString(); | ||
+ | } | ||
+ | |||
+ | Util.typeCheckConfig(NAME, config, this.constructor.DefaultType); | ||
+ | |||
+ | if (config.sanitize) { | ||
+ | config.template = sanitizeHtml(config.template, config.whiteList, config.sanitizeFn); | ||
+ | } | ||
+ | |||
+ | return config; | ||
+ | }; | ||
+ | |||
+ | _proto._getDelegateConfig = function _getDelegateConfig() { | ||
+ | var config = {}; | ||
+ | |||
+ | if (this.config) { | ||
+ | for (var key in this.config) { | ||
+ | if (this.constructor.Default[key] !== this.config[key]) { | ||
+ | config[key] = this.config[key]; | ||
+ | } | ||
+ | } | ||
+ | } | ||
+ | |||
+ | return config; | ||
+ | }; | ||
+ | |||
+ | _proto._cleanTipClass = function _cleanTipClass() { | ||
+ | var $tip = $(this.getTipElement()); | ||
+ | var tabClass = $tip.attr('class').match(BSCLS_PREFIX_REGEX); | ||
+ | |||
+ | if (tabClass !== null && tabClass.length) { | ||
+ | $tip.removeClass(tabClass.join('')); | ||
+ | } | ||
+ | }; | ||
+ | |||
+ | _proto._handlePopperPlacementChange = function _handlePopperPlacementChange(popperData) { | ||
+ | this.tip = popperData.instance.popper; | ||
+ | |||
+ | this._cleanTipClass(); | ||
+ | |||
+ | this.addAttachmentClass(this._getAttachment(popperData.placement)); | ||
+ | }; | ||
+ | |||
+ | _proto._fixTransition = function _fixTransition() { | ||
+ | var tip = this.getTipElement(); | ||
+ | var initConfigAnimation = this.config.animation; | ||
+ | |||
+ | if (tip.getAttribute('x-placement') !== null) { | ||
+ | return; | ||
+ | } | ||
+ | |||
+ | $(tip).removeClass(CLASS_NAME_FADE); | ||
+ | this.config.animation = false; | ||
+ | this.hide(); | ||
+ | this.show(); | ||
+ | this.config.animation = initConfigAnimation; | ||
+ | } // Static | ||
+ | ; | ||
+ | |||
+ | Tooltip._jQueryInterface = function _jQueryInterface(config) { | ||
+ | return this.each(function () { | ||
+ | var data = $(this).data(DATA_KEY); | ||
+ | |||
+ | var _config = typeof config === 'object' && config; | ||
+ | |||
+ | if (!data && /dispose|hide/.test(config)) { | ||
+ | return; | ||
+ | } | ||
+ | |||
+ | if (!data) { | ||
+ | data = new Tooltip(this, _config); | ||
+ | $(this).data(DATA_KEY, data); | ||
+ | } | ||
+ | |||
+ | if (typeof config === 'string') { | ||
+ | if (typeof data[config] === 'undefined') { | ||
+ | throw new TypeError("No method named \"" + config + "\""); | ||
+ | } | ||
+ | |||
+ | data[config](); | ||
+ | } | ||
+ | }); | ||
+ | }; | ||
+ | |||
+ | _createClass(Tooltip, null, [{ | ||
+ | key: "VERSION", | ||
+ | get: function get() { | ||
+ | return VERSION; | ||
+ | } | ||
+ | }, { | ||
+ | key: "Default", | ||
+ | get: function get() { | ||
+ | return Default; | ||
+ | } | ||
+ | }, { | ||
+ | key: "NAME", | ||
+ | get: function get() { | ||
+ | return NAME; | ||
+ | } | ||
+ | }, { | ||
+ | key: "DATA_KEY", | ||
+ | get: function get() { | ||
+ | return DATA_KEY; | ||
+ | } | ||
+ | }, { | ||
+ | key: "Event", | ||
+ | get: function get() { | ||
+ | return Event; | ||
+ | } | ||
+ | }, { | ||
+ | key: "EVENT_KEY", | ||
+ | get: function get() { | ||
+ | return EVENT_KEY; | ||
+ | } | ||
+ | }, { | ||
+ | key: "DefaultType", | ||
+ | get: function get() { | ||
+ | return DefaultType; | ||
+ | } | ||
+ | }]); | ||
+ | |||
+ | return Tooltip; | ||
+ | }(); | ||
+ | /** | ||
+ | * ------------------------------------------------------------------------ | ||
+ | * jQuery | ||
+ | * ------------------------------------------------------------------------ | ||
+ | */ | ||
+ | |||
+ | |||
+ | $.fn[NAME] = Tooltip._jQueryInterface; | ||
+ | $.fn[NAME].Constructor = Tooltip; | ||
+ | |||
+ | $.fn[NAME].noConflict = function () { | ||
+ | $.fn[NAME] = JQUERY_NO_CONFLICT; | ||
+ | return Tooltip._jQueryInterface; | ||
+ | }; | ||
+ | |||
+ | return Tooltip; | ||
+ | |||
+ | }))); | ||
+ | |||
+ | /** | ||
+ | * CatRename | ||
+ | * | ||
+ | * Ajoute un onglet permettant de renommer une catégorie, en déplaçant les pages | ||
+ | * incluses dans celle-ci. Permet de faire faire l'action à un bot en un clic. | ||
+ | * | ||
+ | * {{Projet:JavaScript/Script|CatRename}} | ||
+ | */ | ||
+ | /* <nowiki> */ | ||
+ | |||
+ | /* globals mw, OO, $ */ | ||
+ | |||
+ | if ( mw.config.get( 'wgNamespaceNumber' ) === 14 ) { | ||
+ | mw.loader.using( 'mediawiki.util', function () { | ||
+ | 'use strict'; | ||
+ | |||
+ | // Site-related parameters | ||
+ | const TAG = 'RenommageCategorie'; | ||
+ | const DAILY_LIMIT = 250; | ||
+ | const RBOT_PAGE = 'Wikipédia:Bot/Requêtes/Catégories'; | ||
+ | const DR_TEMPLATE = '{{Suppression Immédiate|raison=Catégorie récemment renommée en [[:Catégorie:$2]] ($3)|utilisateur=$4}}\n\n'; | ||
+ | const RBOT_TEMPLATE = '\n{{Déplacement catégorie|ancienne=$1|nouvelle=$2|raison=$3|demandeur=$4}}'; | ||
+ | |||
+ | // Literal non-breaking space, for situations where HTML entities can't be used | ||
+ | const NBSP = String.fromCharCode( 0xA0 ); | ||
+ | |||
+ | // Messages | ||
+ | const messages = { | ||
+ | 'fr': { | ||
+ | 'catrename-title': 'Renommer une catégorie', | ||
+ | 'catrename-portlet-title': 'CatRename', | ||
+ | |||
+ | 'catrename-action-rename': 'Renommer', | ||
+ | 'catrename-action-cancel': 'Annuler', | ||
+ | 'catrename-action-rbot': '… ou faire faire la tâche par un bot', | ||
+ | |||
+ | 'catrename-checkbox-movetalk': 'Renommer aussi la page de discussion associée', | ||
+ | 'catrename-checkbox-leave-redirect': 'Laisser une redirection vers le nouveau titre', | ||
+ | 'catrename-checkbox-post-dr': 'Déposer une demande de suppression de l\'ancienne catégorie', | ||
+ | 'catrename-checkbox-watch': 'Suivre les catégories originale et nouvelle', | ||
+ | 'catrename-checkbox-watch-members': 'Suivre les pages modifiées', | ||
+ | |||
+ | 'catrename-field-title': 'Nouveau titre' + NBSP + ':', | ||
+ | 'catrename-field-reason': 'Motif' + NBSP + ':', | ||
+ | |||
+ | 'catrename-summary': 'Remplacement de la catégorie [[Catégorie:$1]] par [[Catégorie:$2]] : $3', | ||
+ | 'catrename-dr-summary': 'Demande de suppression après renommage', | ||
+ | 'catrename-rbot-summary': 'RBOT : Demande de renommage de catégorie', | ||
+ | |||
+ | 'catrename-status-checkcategory': 'Vérification de la catégorie cible', | ||
+ | 'catrename-status-getmembers': 'Récupération des pages membres de la catégorie', | ||
+ | 'catrename-status-waitinglock': 'En attente de la fin de renommage dans d\'autres onglets', | ||
+ | 'catrename-status-checklimits': 'Vérification de la limite journalière', | ||
+ | 'catrename-status-editmembers': 'Modification de la page $1 sur $2', | ||
+ | 'catrename-status-renamecategory': 'Renommage de la catégorie', | ||
+ | 'catrename-status-postdr': 'Dépôt de la demande de suppression', | ||
+ | 'catrename-status-postrbot': 'Dépôt de la requête aux bots', | ||
+ | |||
+ | 'catrename-error-canceled': 'Le processus de renommage a été annulé.', | ||
+ | 'catrename-error-same': 'Le nouveau titre est identique au titre actuel.', | ||
+ | 'catrename-error-invalidtitle': 'Le titre de la catégorie demandée est non valide, vide, ou mal formé.', | ||
+ | 'catrename-error-noreason': 'Veuillez indiquer un motif pour ce renommage.', | ||
+ | 'catrename-error-protected': 'Cette catégorie est protégée, vous n\'êtes pas autorisé à la renommer.', | ||
+ | 'catrename-error-categoryexist': 'Il existe déjà une catégorie avec ce nom…', | ||
+ | 'catrename-error-limitreached': 'Le renommage de cette catégorie vous ferait faire plus de $1 modifications avec ce script en moins de 24h. Vous pouvez cependant faire une requête aux bots via le bouton en bas à gauche.', | ||
+ | 'catrename-error-categorypresent': 'La page contient déjà la nouvelle catégorie.', | ||
+ | 'catrename-error-notfound': 'La catégorie n\'a pas été trouvée dans le code de la page, peut-être est-elle incluse via un modèle' + NBSP + '?', | ||
+ | 'catrename-error-pageprotected': 'La page est protégée en écriture.', | ||
+ | 'catrename-error-articleexists': 'Impossible de déplacer la catégorie, la page de destination «' + NBSP + '$1' + NBSP + '» existe déjà.', | ||
+ | } | ||
+ | }; | ||
+ | mw.messages.set( messages.fr ); | ||
+ | var lang = mw.config.get( 'wgUserLanguage' ); | ||
+ | if ( lang !== 'fr' && lang in messages ) { | ||
+ | mw.messages.set( messages[ lang ] ); | ||
+ | } | ||
+ | |||
+ | |||
+ | var isBootstrapped = false; | ||
+ | var instanceWindowManager; | ||
+ | var instanceCatRename; | ||
+ | |||
+ | $( function ( $ ) { | ||
+ | var portlet = mw.util.addPortletLink( 'p-cactions', '#', mw.msg( 'catrename-portlet-title' ) ); | ||
+ | $( portlet ).on( 'click', function ( e ) { | ||
+ | e.preventDefault(); | ||
+ | mw.loader.using( [ 'oojs-ui', 'mediawiki.storage', 'mediawiki.api' ], function () { | ||
+ | bootstrapOnce(); | ||
+ | instanceCatRename.open(); | ||
+ | } ); | ||
+ | } ); | ||
+ | } ); | ||
+ | |||
+ | |||
+ | /* Instanciate CatRename and add it to MediaWiki's UI. */ | ||
+ | |||
+ | function bootstrapOnce() { | ||
+ | if (isBootstrapped) { | ||
+ | return; | ||
+ | } | ||
+ | |||
+ | isBootstrapped = true; | ||
+ | |||
+ | /** | ||
+ | * Main class of the gadget CatRename, which is displayed as a ProcessDialog | ||
+ | * | ||
+ | * @class | ||
+ | * @extends OO.ui.ProcessDialog | ||
+ | * | ||
+ | * @constructor | ||
+ | */ | ||
+ | var CatRename = function () { | ||
+ | // Initialize config | ||
+ | var config = { size: 'medium' }; | ||
+ | |||
+ | // Parent constructor | ||
+ | CatRename.parent.call( this, config ); | ||
+ | |||
+ | // Properties | ||
+ | this.api = new mw.Api( { timeout: 7000 } ); | ||
+ | this.oldTitle; | ||
+ | this.newTitle; | ||
+ | this.oldPageName; | ||
+ | this.newPageName; | ||
+ | this.reason; | ||
+ | this.deferred; | ||
+ | this.members; | ||
+ | this.lockID; | ||
+ | this.nextTab; | ||
+ | this.noSpammingDelay; | ||
+ | |||
+ | // Graphical properties | ||
+ | this.configContent = new OO.ui.PanelLayout( { padded: true, expanded: false } ); | ||
+ | this.statusContent = new OO.ui.PanelLayout( { padded: true, expanded: false } ); | ||
+ | this.newNameInput; | ||
+ | this.reasonInput; | ||
+ | this.optionCheckboxes; | ||
+ | this.layout; | ||
+ | this.$body; | ||
+ | this.statusIndicator; | ||
+ | this.pagesInError; | ||
+ | }; | ||
+ | |||
+ | |||
+ | |||
+ | /* Setup */ | ||
+ | |||
+ | OO.inheritClass( CatRename, OO.ui.ProcessDialog ); | ||
+ | |||
+ | |||
+ | |||
+ | /* Static Properties */ | ||
+ | |||
+ | CatRename.static.name = 'catrename'; | ||
+ | CatRename.static.title = mw.msg( 'catrename-title' ); | ||
+ | CatRename.static.actions = [ | ||
+ | { action: 'rename', label: mw.msg( 'catrename-action-rename' ), flags: [ 'primary', 'progressive' ] }, | ||
+ | { action: 'cancel', label: mw.msg( 'catrename-action-cancel' ), flags: [ 'safe', 'back' ] }, | ||
+ | { action: 'rbot', label: mw.msg( 'catrename-action-rbot' ), flags: 'other' } | ||
+ | ]; | ||
+ | |||
+ | |||
+ | |||
+ | /* ProcessDialog-related Methods */ | ||
+ | |||
+ | /** | ||
+ | * Build the interface displayed inside the ProcessDialog box. | ||
+ | */ | ||
+ | CatRename.prototype.initialize = function () { | ||
+ | CatRename.parent.prototype.initialize.apply( this, arguments ); | ||
+ | |||
+ | this.newNameInput = new OO.ui.TextInputWidget( { value: mw.config.get( 'wgTitle' ) } ); | ||
+ | this.reasonInput = new OO.ui.TextInputWidget( { | ||
+ | maxLength: 500, | ||
+ | name: 'wpSummary' | ||
+ | } ); | ||
+ | |||
+ | this.optionCheckboxes = new OO.ui.CheckboxMultiselectInputWidget( { | ||
+ | value: [ 'movetalk', 'post-dr' ], | ||
+ | options: [ | ||
+ | { data: 'movetalk', label: mw.msg( 'catrename-checkbox-movetalk' ) }, | ||
+ | ( this.userInGroup( 'sysop' ) || this.userInGroup( 'bot' ) ? | ||
+ | { data: 'leave-redirect', label: mw.msg( 'catrename-checkbox-leave-redirect' ) } : | ||
+ | { data: 'post-dr', label: mw.msg( 'catrename-checkbox-post-dr' ) } | ||
+ | ), | ||
+ | { data: 'watch', label: mw.msg( 'catrename-checkbox-watch' ) }, | ||
+ | { data: 'watch-members', label: mw.msg( 'catrename-checkbox-watch-members' ) } | ||
+ | ] | ||
+ | } ); | ||
+ | |||
+ | this.layout = new OO.ui.Widget( { | ||
+ | content: [ | ||
+ | new OO.ui.FieldLayout( | ||
+ | this.newNameInput, { | ||
+ | align: 'top', | ||
+ | label: mw.msg( 'catrename-field-title' ), | ||
+ | } | ||
+ | ), | ||
+ | new OO.ui.FieldLayout( | ||
+ | this.reasonInput, { | ||
+ | align: 'top', | ||
+ | label: mw.msg( 'catrename-field-reason' ), | ||
+ | } | ||
+ | ), | ||
+ | new OO.ui.FieldLayout( | ||
+ | this.optionCheckboxes, {} | ||
+ | ) | ||
+ | ], | ||
+ | } ); | ||
+ | |||
+ | this.configContent.$element.append( this.layout.$element ); | ||
+ | |||
+ | this.$body.append( this.configContent.$element ); | ||
+ | |||
+ | this.statusIndicator = $( '<h3>' ) | ||
+ | .css( 'text-align', 'center' ) | ||
+ | .css( 'margin-top', '1em' ) | ||
+ | .css( 'margin-bottom', '2em' ); | ||
+ | this.pagesInError = $( '<ul>' ); | ||
+ | this.statusContent.$element.append( this.statusIndicator ).append( this.pagesInError ); | ||
+ | |||
+ | this.setSize( this.size ); | ||
+ | this.updateSize(); | ||
+ | }; | ||
+ | |||
+ | /** | ||
+ | * Get a process for taking action. | ||
+ | * | ||
+ | * This method is called within the ProcessDialog when the user clicks | ||
+ | * on an action button (the one defined in CatRename.static.actions). | ||
+ | * Here is defined in which order each method of the category moving | ||
+ | * process is called. | ||
+ | * @param {string} action Name of the action button clicked. | ||
+ | * @return {OO.ui.Process} Action process. | ||
+ | */ | ||
+ | CatRename.prototype.getActionProcess = function ( action ) { | ||
+ | var process = new OO.ui.Process(), | ||
+ | options = this.optionCheckboxes.getValue(); | ||
+ | |||
+ | if ( action === 'cancel' || action === '' ) { // empty string when closing with Escape key | ||
+ | return process.next( this.unlockMultitabs, this ) | ||
+ | .next( this.closeDialog, this ); | ||
+ | } | ||
+ | else if ( action === 'rename' ) { | ||
+ | process.next( this.prepare, this ) | ||
+ | .next( this.checkCategory, this ) | ||
+ | .next( this.getMembers, this ) | ||
+ | .next( this.lockMultitabs, this ) | ||
+ | .next( this.checkLimits, this ) | ||
+ | .next( this.editMembers, this ) | ||
+ | .next( this.renameCategory, this ); | ||
+ | } | ||
+ | else if ( action === 'rbot' ) { | ||
+ | process.next( this.prepare, this ) | ||
+ | .next( this.checkCategory, this ) | ||
+ | .next( this.getMembers, this ) | ||
+ | .next( this.postRBot, this ) | ||
+ | .next( this.renameCategory, this ); | ||
+ | } | ||
+ | |||
+ | if ( options.indexOf( 'post-dr' ) > -1 ) { | ||
+ | process.next( this.postDR, this ); | ||
+ | } | ||
+ | process.next( this.unlockMultitabs, this ) | ||
+ | .next( this.success, this ) | ||
+ | .next( this.closeDialog, this ); | ||
+ | |||
+ | return process; | ||
+ | }; | ||
+ | |||
+ | /** | ||
+ | * Close the window. | ||
+ | * | ||
+ | * @return {jQuery.Promise} Promise resolved when window is closed | ||
+ | */ | ||
+ | CatRename.prototype.closeDialog = function () { | ||
+ | var dialog = this; | ||
+ | |||
+ | var lifecycle = dialog.close(); | ||
+ | |||
+ | return lifecycle.closed; | ||
+ | }; | ||
+ | |||
+ | /** | ||
+ | * Get the height of the window body. | ||
+ | * Used by the ProcessDialog to set an accurate height to the dialog. | ||
+ | * | ||
+ | * @return {number} Height in px the dialog should be. | ||
+ | */ | ||
+ | CatRename.prototype.getBodyHeight = function () { | ||
+ | return this.configContent.$element.outerHeight( true ); | ||
+ | }; | ||
+ | |||
+ | |||
+ | |||
+ | /* Process step methods */ | ||
+ | |||
+ | /** | ||
+ | * Fetch and validate user's input to make it easily accessible later. | ||
+ | * | ||
+ | * @return {undefined|OO.ui.Error} Error message for the ProcessDialog | ||
+ | * to display, if any. | ||
+ | */ | ||
+ | CatRename.prototype.prepare = function () { | ||
+ | var dialog = this; | ||
+ | |||
+ | this.oldTitle = mw.config.get( 'wgTitle' ); | ||
+ | this.newTitle = this.newNameInput.getValue().trim().replace(/^([Cc]atégorie|[Cc]ategory):/, ''); | ||
+ | this.reason = this.reasonInput.getValue().trim(); | ||
+ | |||
+ | if ( mw.config.get( 'wgCaseSensitiveNamespaces' ).indexOf( 14 ) === -1 ) { | ||
+ | this.newTitle = this.newTitle.charAt( 0 ).toUpperCase() + this.newTitle.slice( 1 ); | ||
+ | } | ||
+ | if ( this.newTitle === this.oldTitle ) { | ||
+ | return new OO.ui.Error( mw.msg( 'catrename-error-same' ) ); | ||
+ | } | ||
+ | if ( mw.Title.makeTitle( 14, this.newTitle ) === null ) { | ||
+ | return new OO.ui.Error( mw.msg( 'catrename-error-invalidtitle' ) ); | ||
+ | } | ||
+ | if ( this.reason === '' ) { | ||
+ | return new OO.ui.Error( mw.msg( 'catrename-error-noreason' ) ); | ||
+ | } | ||
+ | |||
+ | this.oldPageName = mw.config.get('wgFormattedNamespaces')[ 14 ] + ':' + this.oldTitle; | ||
+ | this.newPageName = mw.config.get('wgFormattedNamespaces')[ 14 ] + ':' + this.newTitle; | ||
+ | |||
+ | // Disable actions button when a process is runing | ||
+ | this.getActions().get( { actions: 'rename' } )[ 0 ].setDisabled( true ); | ||
+ | this.getActions().get( { actions: 'rbot' } )[ 0 ].setDisabled( true ); | ||
+ | // Except for the cancel button, which behaviour change to cancel the ongoing process | ||
+ | this.getActions().get( { actions: 'cancel' } )[ 0 ].on( 'click', function () { | ||
+ | dialog.errorHandler( mw.msg( 'catrename-error-canceled' ) ); | ||
+ | } ); | ||
+ | |||
+ | return; | ||
+ | }; | ||
+ | |||
+ | /** | ||
+ | * Check if it is technically possible to move the category. | ||
+ | * | ||
+ | * Two main checks are performed: | ||
+ | * * Has the user the right to move the category according to the | ||
+ | * protection level? | ||
+ | * * Is the target title free? | ||
+ | * @return {JQuery.Deferred} Promise telling to continue the process if | ||
+ | * successful or stopping the process if rejected. | ||
+ | */ | ||
+ | CatRename.prototype.checkCategory = function () { | ||
+ | var dialog = this; | ||
+ | this.deferred = $.Deferred(); | ||
+ | |||
+ | this.showStatus( mw.msg( 'catrename-status-checkcategory' ) ); | ||
+ | |||
+ | var restrictionMove = mw.config.get( 'wgRestrictionMove' ); | ||
+ | for ( var i = 0; i < restrictionMove.length; i++ ) { | ||
+ | if ( ! this.userInGroup( restrictionMove[ i ] ) ) { | ||
+ | this.errorHandler( mw.msg( 'catrename-error-protected' ) ); | ||
+ | return this.deferred; | ||
+ | } | ||
+ | } | ||
+ | |||
+ | this.api.get( { | ||
+ | 'action': 'query', | ||
+ | 'format': 'json', | ||
+ | 'formatversion': 2, | ||
+ | 'prop': 'categoryinfo', | ||
+ | 'titles': this.newPageName | ||
+ | } ).then( function ( data ) { | ||
+ | if ( data.query.pages[ 0 ].missing !== true ) { | ||
+ | //TODO: Allow user to move pages without renaming the cat | ||
+ | dialog.errorHandler( mw.msg( 'catrename-error-categoryexist' ) ); | ||
+ | return; | ||
+ | } | ||
+ | |||
+ | dialog.deferred.resolve(); | ||
+ | } ).fail( function ( error ) { | ||
+ | dialog.errorHandler( error ); | ||
+ | } ); | ||
+ | |||
+ | return this.deferred; | ||
+ | }; | ||
+ | |||
+ | /** | ||
+ | * Get all pages, files and sub-categories in the source category. | ||
+ | * | ||
+ | * This method populates the attribute 'members'. | ||
+ | * @return {JQuery.Deferred} Promise telling to continue the process if | ||
+ | * successful or stopping the process if rejected. | ||
+ | */ | ||
+ | CatRename.prototype.getMembers = function () { | ||
+ | var dialog = this; | ||
+ | this.deferred = $.Deferred(); | ||
+ | this.members = []; | ||
+ | |||
+ | this.showStatus( mw.msg( 'catrename-status-getmembers' ) ); | ||
+ | |||
+ | function doGetMembers( paramsContinue ) { | ||
+ | var params = { | ||
+ | 'action': 'query', | ||
+ | 'format': 'json', | ||
+ | 'list': 'categorymembers', | ||
+ | 'formatversion': '2', | ||
+ | 'cmtitle': mw.config.get( 'wgPageName' ), | ||
+ | 'cmprop': 'title', | ||
+ | 'cmlimit': 'max', | ||
+ | }; | ||
+ | if ( paramsContinue ) { | ||
+ | $.extend( params, paramsContinue ); | ||
+ | } | ||
+ | |||
+ | dialog.api.get( params ).then( function ( data ) { | ||
+ | |||
+ | var categoryMembers = data.query.categorymembers; | ||
+ | for ( var i = 0; i < categoryMembers.length; i++ ) { | ||
+ | dialog.members.push( categoryMembers[ i ].title ); | ||
+ | } | ||
+ | |||
+ | if ( data[ 'continue' ] ) { | ||
+ | doGetMembers( data[ 'continue' ] ); | ||
+ | } | ||
+ | else { | ||
+ | dialog.deferred.resolve(); | ||
+ | } | ||
+ | } ).fail( function ( error ) { | ||
+ | dialog.errorHandler( error ); | ||
+ | } ); | ||
+ | |||
+ | } | ||
+ | doGetMembers(); | ||
+ | |||
+ | return this.deferred; | ||
+ | }; | ||
+ | |||
+ | /** | ||
+ | * Lock the process while other instances of CatRename are running. | ||
+ | * | ||
+ | * This method acts a bit like the POSIX sem_wait. | ||
+ | * @return {JQuery.Deferred} Promise telling to continue the process | ||
+ | * when it is its turn to execute. | ||
+ | */ | ||
+ | CatRename.prototype.lockMultitabs = function () { | ||
+ | var dialog = this; | ||
+ | this.deferred = $.Deferred(); | ||
+ | |||
+ | if ( this.userInGroup( 'bot' ) ) { | ||
+ | return; | ||
+ | } | ||
+ | |||
+ | this.lockID = 'catrename-' + this.randomString( 16 ); | ||
+ | this.nextTab = null; | ||
+ | |||
+ | this.showStatus( mw.msg( 'catrename-status-waitinglock' ) ); | ||
+ | |||
+ | //TODO: check lock timestamp | ||
+ | if ( mw.storage.get( 'catrename-lock' ) === null ) { | ||
+ | mw.storage.set( 'catrename-lock', this.lockID ); | ||
+ | this.deferred.resolve(); | ||
+ | } | ||
+ | else { | ||
+ | $( window ).on( 'storage.catrename.catrename-waiting', function ( event ) { | ||
+ | if ( event.originalEvent.key === 'catrename-lock' && event.originalEvent.newValue === dialog.lockID ) { | ||
+ | $( window ).off( 'storage.catrename-waiting' ); | ||
+ | dialog.deferred.resolve(); | ||
+ | } | ||
+ | } ); | ||
+ | mw.storage.set( 'catrename-addtab', this.lockID ); | ||
+ | } | ||
+ | |||
+ | |||
+ | $( window ).on( 'storage.catrename', function ( event ) { | ||
+ | // if this tab has no successor and a new one appears, add it as our successor | ||
+ | if ( dialog.nextTab === null && event.originalEvent.key === 'catrename-addtab' && event.originalEvent.newValue !== null ) { | ||
+ | dialog.nextTab = event.originalEvent.newValue; | ||
+ | mw.storage.set( dialog.lockID, dialog.nextTab ); | ||
+ | } | ||
+ | // if our successor decides to leave, remove it and take its successor | ||
+ | else if ( dialog.nextTab !== null && event.originalEvent.key === 'catrename-removetab' && event.originalEvent.newValue === dialog.nextTab ) { | ||
+ | dialog.nextTab = mw.storage.get( dialog.nextTab ); | ||
+ | if ( dialog.nextTab !== null ) { | ||
+ | mw.storage.set( dialog.lockID, dialog.nextTab ); | ||
+ | } | ||
+ | else { | ||
+ | mw.storage.remove( dialog.lockID ); | ||
+ | } | ||
+ | } | ||
+ | } ); | ||
+ | |||
+ | window.addEventListener( 'unload', function (e) { | ||
+ | dialog.unlockMultitabs(); | ||
+ | } ); | ||
+ | |||
+ | return this.deferred; | ||
+ | }; | ||
+ | |||
+ | /** | ||
+ | * Check if the daily limit of edits using this script would be reached | ||
+ | * if the move is performed. | ||
+ | * | ||
+ | * In fact, we are not looking realy on a daily basis, but a 24h rolling | ||
+ | * period. | ||
+ | * @return {JQuery.Deferred} Promise telling to continue the process | ||
+ | * when it is its turn to execute. | ||
+ | */ | ||
+ | CatRename.prototype.checkLimits = function () { | ||
+ | var dialog = this; | ||
+ | this.deferred = $.Deferred(); | ||
+ | var yesterday = new Date(); | ||
+ | yesterday.setDate( yesterday.getDate() - 1 ); | ||
+ | |||
+ | if ( this.userInGroup( 'bot' ) ) { | ||
+ | this.noSpammingDelay = 0; | ||
+ | return; | ||
+ | } | ||
+ | |||
+ | this.noSpammingDelay = 5000; | ||
+ | if ( this.members.length > 50 ) { | ||
+ | this.noSpammingDelay = 20000; | ||
+ | } | ||
+ | else if ( this.members.length > 10 ) { | ||
+ | this.noSpammingDelay = 10000; | ||
+ | } | ||
+ | |||
+ | this.showStatus( mw.msg( 'catrename-status-checklimits' ) ); | ||
+ | |||
+ | this.api.get( { | ||
+ | 'action': 'query', | ||
+ | 'format': 'json', | ||
+ | 'list': 'usercontribs', | ||
+ | 'formatversion': '2', | ||
+ | 'uclimit': 'max', // only query DAILY_LIMIT results ? | ||
+ | 'ucend': yesterday.toISOString(), | ||
+ | 'ucuser': mw.config.get( 'wgUserName' ), | ||
+ | 'ucprop': 'timestamp', | ||
+ | 'uctag': TAG | ||
+ | } ).then( function ( data ) { | ||
+ | |||
+ | if ( data.query.usercontribs.length + dialog.members.length >= DAILY_LIMIT ) { | ||
+ | dialog.errorHandler( mw.msg( 'catrename-error-limitreached', DAILY_LIMIT ), false ); | ||
+ | } | ||
+ | else { | ||
+ | dialog.deferred.resolve(); | ||
+ | } | ||
+ | } ).fail( function ( error ) { | ||
+ | dialog.errorHandler( error ); | ||
+ | } ); | ||
+ | |||
+ | return this.deferred; | ||
+ | }; | ||
+ | |||
+ | /** | ||
+ | * Try to move all the pages inside the 'members' attribute from the old | ||
+ | * to the new category name by fetching and editing their wikicode. | ||
+ | * | ||
+ | * @return {JQuery.Deferred} Promise telling to continue the process | ||
+ | * when it is its turn to execute. | ||
+ | */ | ||
+ | CatRename.prototype.editMembers = function () { | ||
+ | var dialog = this, | ||
+ | totalPages = this.members.length, | ||
+ | oldCatRegex = this.buildRegex( this.oldTitle ), | ||
+ | newCatRegex = this.buildRegex( this.newTitle ), | ||
+ | summary = mw.msg( 'catrename-summary', this.oldTitle, this.newTitle, this.reason ), | ||
+ | commonPayload = { | ||
+ | summary: summary, | ||
+ | minor: true, | ||
+ | tags: TAG | ||
+ | }; | ||
+ | this.deferred = $.Deferred(); | ||
+ | |||
+ | if ( this.userInGroup( 'bot' ) ) { | ||
+ | commonPayload[ 'bot' ] = 1; | ||
+ | } | ||
+ | if ( this.optionCheckboxes.getValue().indexOf( 'watch-members' ) > -1 ) { | ||
+ | commonPayload[ 'watchlist' ] = 'watch'; | ||
+ | } | ||
+ | |||
+ | function doEdit() { | ||
+ | var member = dialog.members.pop(); | ||
+ | if ( dialog.deferred.state() !== 'pending' ) { | ||
+ | return; | ||
+ | } | ||
+ | if ( member === undefined ) { | ||
+ | dialog.deferred.resolve(); | ||
+ | return; | ||
+ | } | ||
+ | |||
+ | //TODO: a progress-bar ? | ||
+ | dialog.showStatus( mw.msg( 'catrename-status-editmembers', totalPages - dialog.members.length, totalPages ) ); | ||
+ | |||
+ | dialog.api.edit( member, function ( revision ) { | ||
+ | var content = revision.content, | ||
+ | newCatInPageList = content.match( newCatRegex ); | ||
+ | |||
+ | if ( newCatInPageList !== null ) { | ||
+ | dialog.logFailedPages( member, mw.msg( 'catrename-error-categorypresent' ) ); | ||
+ | } | ||
+ | else { | ||
+ | content = content.replace( | ||
+ | oldCatRegex, | ||
+ | '$1[[' + dialog.newPageName + '$6]]' | ||
+ | ); | ||
+ | } | ||
+ | |||
+ | return $.extend( { text: content }, commonPayload ); | ||
+ | } ) | ||
+ | .then( function ( result ) { | ||
+ | if ( result.nochange === true ) { | ||
+ | dialog.logFailedPages( member, mw.msg( 'catrename-error-notfound' ) ); | ||
+ | } | ||
+ | |||
+ | setTimeout( doEdit, dialog.noSpammingDelay ); | ||
+ | } ) | ||
+ | .fail( function ( code, data ) { | ||
+ | if ( code === 'protectedpage' ) { | ||
+ | dialog.logFailedPages( member, mw.msg( 'catrename-error-pageprotected' ) ); | ||
+ | doEdit(); | ||
+ | } | ||
+ | else { | ||
+ | dialog.errorHandler( code ); | ||
+ | } | ||
+ | } ); | ||
+ | } | ||
+ | doEdit(); | ||
+ | |||
+ | return this.deferred; | ||
+ | }; | ||
+ | |||
+ | /** | ||
+ | * Move the category itself. | ||
+ | * | ||
+ | * @return {JQuery.Deferred} Promise telling to continue the process | ||
+ | * when it is its turn to execute. | ||
+ | */ | ||
+ | CatRename.prototype.renameCategory = function () { | ||
+ | var dialog = this; | ||
+ | this.deferred = $.Deferred(); | ||
+ | |||
+ | this.showStatus( mw.msg( 'catrename-status-renamecategory' ) ); | ||
+ | |||
+ | var payload = { | ||
+ | 'action': 'move', | ||
+ | 'format': 'json', | ||
+ | 'from': mw.config.get( 'wgPageName' ), | ||
+ | 'to': this.newPageName, | ||
+ | 'reason': this.reason, | ||
+ | 'tags': TAG, | ||
+ | 'formatversion': '2' | ||
+ | }; | ||
+ | |||
+ | var options = this.optionCheckboxes.getValue(); | ||
+ | if ( options.indexOf( 'movetalk' ) > -1 ) { | ||
+ | payload[ 'movetalk' ] = 1; | ||
+ | } | ||
+ | if ( options.indexOf( 'watch' ) > -1 ) { | ||
+ | payload[ 'watchlist' ] = 'watch'; | ||
+ | } | ||
+ | if ( this.userInGroup( 'sysop' ) || this.userInGroup( 'bot' ) ) { | ||
+ | if ( options.indexOf( 'leave-redirect' ) === -1 ) { | ||
+ | payload[ 'noredirect' ] = 1; | ||
+ | } | ||
+ | } | ||
+ | |||
+ | this.api.postWithToken( 'csrf', payload ).then( function ( data ) { | ||
+ | dialog.deferred.resolve(); | ||
+ | } ).fail( function ( error ) { | ||
+ | if ( error === 'articleexists' ) { | ||
+ | dialog.errorHandler( mw.msg( 'catrename-error-articleexists', dialog.newPageName ) ); | ||
+ | } | ||
+ | else { | ||
+ | dialog.errorHandler( error ); | ||
+ | } | ||
+ | } ); | ||
+ | |||
+ | return this.deferred; | ||
+ | }; | ||
+ | |||
+ | /** | ||
+ | * Post a deletion request. | ||
+ | * | ||
+ | * @return {JQuery.Deferred} Promise telling to continue the process | ||
+ | * when it is its turn to execute. | ||
+ | */ | ||
+ | CatRename.prototype.postDR = function () { | ||
+ | var dialog = this; | ||
+ | this.deferred = $.Deferred(); | ||
+ | |||
+ | this.showStatus( mw.msg( 'catrename-status-postdr' ) ); | ||
+ | |||
+ | var content = DR_TEMPLATE | ||
+ | .replace( /\$1/g, this.oldTitle ) | ||
+ | .replace( /\$2/g, this.newTitle ) | ||
+ | .replace( /\$3/g, this.reason ) | ||
+ | .replace( /\$4/g, mw.config.get( 'wgUserName' ) ); | ||
+ | |||
+ | this.api.postWithToken( 'csrf', { | ||
+ | 'action': 'edit', | ||
+ | 'format': 'json', | ||
+ | 'title': this.oldPageName, | ||
+ | 'summary': mw.msg( 'catrename-dr-summary' ), | ||
+ | 'tags': TAG, | ||
+ | 'nocreate': 1, | ||
+ | 'prependtext': content, | ||
+ | 'formatversion': '2' | ||
+ | } ).then( function ( data ) { | ||
+ | dialog.deferred.resolve(); | ||
+ | } ).fail( function ( error ) { | ||
+ | dialog.errorHandler( error ); | ||
+ | } ); | ||
+ | |||
+ | return this.deferred; | ||
+ | }; | ||
+ | |||
+ | /** | ||
+ | * Post a move request for the bots. | ||
+ | * | ||
+ | * @return {JQuery.Deferred} Promise telling to continue the process | ||
+ | * when it is its turn to execute. | ||
+ | */ | ||
+ | CatRename.prototype.postRBot = function () { | ||
+ | var dialog = this; | ||
+ | this.deferred = $.Deferred(); | ||
+ | |||
+ | this.showStatus( mw.msg( 'catrename-status-postrbot' ) ); | ||
+ | |||
+ | var content = RBOT_TEMPLATE | ||
+ | .replace( /\$1/g, this.oldTitle ) | ||
+ | .replace( /\$2/g, this.newTitle ) | ||
+ | .replace( /\$3/g, this.reason ) | ||
+ | .replace( /\$4/g, mw.config.get( 'wgUserName' ) ); | ||
+ | |||
+ | this.api.postWithToken( 'csrf', { | ||
+ | 'action': 'edit', | ||
+ | 'format': 'json', | ||
+ | 'title': RBOT_PAGE, | ||
+ | 'summary': mw.msg( 'catrename-rbot-summary' ), | ||
+ | 'tags': TAG, | ||
+ | 'nocreate': 1, | ||
+ | 'appendtext': content, | ||
+ | 'formatversion': '2' | ||
+ | } ).then( function ( data ) { | ||
+ | dialog.deferred.resolve(); | ||
+ | } ).fail( function ( error ) { | ||
+ | dialog.errorHandler( error ); | ||
+ | } ); | ||
+ | |||
+ | return this.deferred; | ||
+ | }; | ||
+ | |||
+ | /** | ||
+ | * Release the lock to allow other instances of CatRename to execute. | ||
+ | * | ||
+ | * This method acts a bit like the POSIX sem_post. | ||
+ | */ | ||
+ | CatRename.prototype.unlockMultitabs = function () { | ||
+ | if ( this.lockID !== undefined ) { | ||
+ | $( window ).off( 'storage.catrename' ); | ||
+ | |||
+ | mw.storage.set( 'catrename-removetab', this.lockID ); //Inform other tabs that we're closing | ||
+ | mw.storage.remove( this.lockID ); //Clean up our mess from the localStorage | ||
+ | |||
+ | // wake up the next tab, or reset if there is none | ||
+ | if ( mw.storage.get( 'catrename-lock' ) === this.lockID ) { | ||
+ | if ( this.nextTab !== null ) { | ||
+ | mw.storage.set( 'catrename-lock', this.nextTab ); | ||
+ | } | ||
+ | else { | ||
+ | mw.storage.remove( 'catrename-lock' ); | ||
+ | } | ||
+ | } | ||
+ | |||
+ | delete this.lockID; | ||
+ | } | ||
+ | }; | ||
+ | |||
+ | /** | ||
+ | * Method called when all has gone well (yeah !). | ||
+ | */ | ||
+ | CatRename.prototype.success = function () { | ||
+ | var dialog = this; | ||
+ | |||
+ | setTimeout( function () { | ||
+ | window.location = mw.util.getUrl( dialog.newPageName ); | ||
+ | }, 1000 ); | ||
+ | }; | ||
+ | |||
+ | |||
+ | |||
+ | /* Helper Methods */ | ||
+ | |||
+ | /** | ||
+ | * Get information about the current user's groups. | ||
+ | * | ||
+ | * @param {string} groupName Name of the group to check. | ||
+ | * @return {boolean} Whether the current user is in the given group. | ||
+ | */ | ||
+ | CatRename.prototype.userInGroup = function ( groupName ) { | ||
+ | return ( mw.config.get( 'wgUserGroups' ).indexOf( groupName ) > -1 ); | ||
+ | }; | ||
+ | |||
+ | /** | ||
+ | * Display a status message inside the main content of the dialog. | ||
+ | * | ||
+ | * @return {string} Status message to display. | ||
+ | */ | ||
+ | CatRename.prototype.showStatus = function ( status ) { | ||
+ | this.statusIndicator.text( status ); | ||
+ | this.$body.children().detach(); | ||
+ | this.$body.append( this.statusContent.$element ); | ||
+ | }; | ||
+ | |||
+ | /** | ||
+ | * Raise an error using OO.ui.Error, and reset all what should be. | ||
+ | * | ||
+ | * @param {string} error Error message to display to the user. | ||
+ | * @param {boolean} recoverable Is the error recoverable (default to true). | ||
+ | * @param {boolean} warning Should we raise a warning instead an error (default to false). | ||
+ | */ | ||
+ | CatRename.prototype.errorHandler = function ( error, recoverable, warning ) { | ||
+ | var errorMessage = new OO.ui.Error( error, { recoverable: recoverable || true, warning: warning || false } ); | ||
+ | |||
+ | this.unlockMultitabs(); | ||
+ | this.$body.children().detach(); | ||
+ | this.$body.append( this.configContent.$element ); | ||
+ | |||
+ | this.getActions().get( { actions: 'rename' } )[ 0 ].setDisabled( false ); | ||
+ | this.getActions().get( { actions: 'rbot' } )[ 0 ].setDisabled( false ); | ||
+ | |||
+ | this.deferred.reject( errorMessage ); | ||
+ | }; | ||
+ | |||
+ | /** | ||
+ | * Add a page to the error log. | ||
+ | * | ||
+ | * @param {string} pageName Name (including namespace) of the page. | ||
+ | * @param {string} reason Explaination of the error. | ||
+ | */ | ||
+ | CatRename.prototype.logFailedPages = function ( pageName, reason ) { | ||
+ | var li = $( '<li>' ).text( ' - ' + reason ), | ||
+ | a = $( '<a>' ).attr( 'href', mw.util.getUrl( pageName ) ).text( pageName ); | ||
+ | this.pagesInError.append( li.prepend( a ) ); | ||
+ | }; | ||
+ | |||
+ | /** | ||
+ | * Build a regex to extract the link to a given category from wikicode. | ||
+ | * | ||
+ | * @param {string} category Name (without namespace) of the category. | ||
+ | * @return {RegExp} Regex object to extract the given category. | ||
+ | */ | ||
+ | CatRename.prototype.buildRegex = function ( category ) { | ||
+ | var formattedNamespace = mw.config.get( 'wgFormattedNamespaces' )[ 14 ], | ||
+ | isFirstLetterCaseSensitive = ( mw.config.get( 'wgCaseSensitiveNamespaces' ).indexOf( 14 ) > -1 ), | ||
+ | namespace = '(?:[' + formattedNamespace.charAt( 0 ) + formattedNamespace.charAt( 0 ).toLowerCase() + ']' + formattedNamespace.slice( 1 ) + '|[Cc]ategory)'; | ||
+ | |||
+ | category = category.replace( /([\\\^\$\*\+\?\.\|\{\}\[\]\(\)])/g, '\\$1' ); | ||
+ | |||
+ | if ( ! isFirstLetterCaseSensitive ) { | ||
+ | var firstLetter = category.charAt(0); | ||
+ | if ( firstLetter.toUpperCase() !== firstLetter.toLowerCase() ) { | ||
+ | category = '[' + firstLetter.toUpperCase() + firstLetter.toLowerCase() + ']' | ||
+ | + category.slice(1); | ||
+ | } | ||
+ | } | ||
− | + | return new RegExp('(\\s*)\\[\\[( |_)*' + namespace + '( |_)*:( |_)*' + category + '( |_)*(\\|[^\\]]*)?\\]\\]', 'g'); | |
+ | }; | ||
− | + | /** | |
− | + | * Generate a random string. | |
− | + | * | |
− | + | * @param {number} length Length of the string to generate. | |
− | + | * @return {string} The generated string. | |
− | + | */ | |
− | + | CatRename.prototype.randomString = function ( length ) { | |
+ | var result = ''; | ||
+ | var chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'; | ||
+ | for ( var i = 0; i < length; ++i ) { | ||
+ | result += chars.charAt( Math.floor( Math.random() * chars.length ) ); | ||
+ | } | ||
+ | return result; | ||
+ | }; | ||
− | + | instanceWindowManager = new OO.ui.WindowManager(); | |
− | + | $( 'body' ).append( instanceWindowManager.$element ); | |
− | + | instanceCatRename = new CatRename(); | |
− | + | instanceWindowManager.addWindows( [ instanceCatRename ] ); | |
− | |||
− | |||
− | |||
− | |||
} | } | ||
− | + | } ); | |
− | }); | + | } |
+ | |||
+ | /* </nowiki> */ | ||
+ | |||
+ | var navHeight = $('#esp-navbar ul').height(); | ||
+ | var $nav = $('#esp-navbar'); | ||
+ | $('#navbar-toggler').click(function(e) { | ||
+ | if (!$nav.hasClass('open')) { | ||
+ | $nav.css('height', navHeight + 'px'); | ||
+ | } else { | ||
+ | $nav.css('height', ''); | ||
+ | } | ||
+ | $nav.toggleClass('open'); | ||
}); | }); | ||
+ | |||
+ | $('.timeline-wrapper').on('mousedown touchstart', function (me) { | ||
+ | if ($(me.target).hasClass('timeline-desc')) return; | ||
+ | var move = $(this).find('ul'); | ||
+ | var lastOffset = move.data('lastTransform'); | ||
+ | var lastOffsetX = lastOffset ? lastOffset.dx : 0; | ||
+ | var pageX = me.originalEvent.touches ? me.originalEvent.touches[0].pageX : me.pageX; | ||
+ | var startX = pageX - lastOffsetX; | ||
+ | $(document).on('mousemove touchmove', function (e) { | ||
+ | var newX = e.originalEvent.touches ? e.originalEvent.touches[0].pageX : e.pageX; | ||
+ | var max = $(move).attr('data-maxtranslate'); | ||
+ | if (max > 0) max = 0; | ||
+ | var newDx = Math.max(Math.min(0, newX - startX), max); | ||
+ | move.css('transform', 'translate(' + newDx + 'px)'); | ||
+ | move.data('lastTransform', { | ||
+ | dx: newDx | ||
+ | }); | ||
+ | }); | ||
+ | }); | ||
+ | $(document).on('mouseup touchend', function () { | ||
+ | $(this).off('mousemove touchmove'); | ||
+ | }); | ||
+ | $('.timeline-wrapper').each(function () { | ||
+ | var maxTranslate = ($(this).find('li').length * 200 - $(this).width()) * - 1; | ||
+ | $(this).find('ul').attr('data-maxTranslate', maxTranslate); | ||
+ | var desc = $('<div>', { | ||
+ | 'class': 'timeline-desc' | ||
+ | }); | ||
+ | $(this).append(desc); | ||
+ | $(this).find('.event').on('click touch', function () { | ||
+ | $('.event.active').removeClass('active'); | ||
+ | $(this).addClass('active'); | ||
+ | desc.html($(this).find('.description').html()); | ||
+ | }); | ||
+ | $(this).find('li:first-of-type .event').click(); | ||
+ | }); |
Version actuelle datée du 27 février 2025 à 12:53
/* Copyright (C) Federico Zivolo 2019 Distributed under the MIT License (license terms are at http://opensource.org/licenses/MIT). */ (function(e,t){'object'==typeof exports&&'undefined'!=typeof module?module.exports=t():'function'==typeof define&&define.amd?define(t):e.Popper=t()})(this,function(){'use strict';function e(e){return e&&'[object Function]'==={}.toString.call(e)}function t(e,t){if(1!==e.nodeType)return[];var o=e.ownerDocument.defaultView,n=o.getComputedStyle(e,null);return t?n[t]:n}function o(e){return'HTML'===e.nodeName?e:e.parentNode||e.host}function n(e){if(!e)return document.body;switch(e.nodeName){case'HTML':case'BODY':return e.ownerDocument.body;case'#document':return e.body;}var i=t(e),r=i.overflow,p=i.overflowX,s=i.overflowY;return /(auto|scroll|overlay)/.test(r+s+p)?e:n(o(e))}function i(e){return e&&e.referenceNode?e.referenceNode:e}function r(e){return 11===e?re:10===e?pe:re||pe}function p(e){if(!e)return document.documentElement;for(var o=r(10)?document.body:null,n=e.offsetParent||null;n===o&&e.nextElementSibling;)n=(e=e.nextElementSibling).offsetParent;var i=n&&n.nodeName;return i&&'BODY'!==i&&'HTML'!==i?-1!==['TH','TD','TABLE'].indexOf(n.nodeName)&&'static'===t(n,'position')?p(n):n:e?e.ownerDocument.documentElement:document.documentElement}function s(e){var t=e.nodeName;return'BODY'!==t&&('HTML'===t||p(e.firstElementChild)===e)}function d(e){return null===e.parentNode?e:d(e.parentNode)}function a(e,t){if(!e||!e.nodeType||!t||!t.nodeType)return document.documentElement;var o=e.compareDocumentPosition(t)&Node.DOCUMENT_POSITION_FOLLOWING,n=o?e:t,i=o?t:e,r=document.createRange();r.setStart(n,0),r.setEnd(i,0);var l=r.commonAncestorContainer;if(e!==l&&t!==l||n.contains(i))return s(l)?l:p(l);var f=d(e);return f.host?a(f.host,t):a(e,d(t).host)}function l(e){var t=1<arguments.length&&void 0!==arguments[1]?arguments[1]:'top',o='top'===t?'scrollTop':'scrollLeft',n=e.nodeName;if('BODY'===n||'HTML'===n){var i=e.ownerDocument.documentElement,r=e.ownerDocument.scrollingElement||i;return r[o]}return e[o]}function f(e,t){var o=2<arguments.length&&void 0!==arguments[2]&&arguments[2],n=l(t,'top'),i=l(t,'left'),r=o?-1:1;return e.top+=n*r,e.bottom+=n*r,e.left+=i*r,e.right+=i*r,e}function m(e,t){var o='x'===t?'Left':'Top',n='Left'==o?'Right':'Bottom';return parseFloat(e['border'+o+'Width'],10)+parseFloat(e['border'+n+'Width'],10)}function h(e,t,o,n){return ee(t['offset'+e],t['scroll'+e],o['client'+e],o['offset'+e],o['scroll'+e],r(10)?parseInt(o['offset'+e])+parseInt(n['margin'+('Height'===e?'Top':'Left')])+parseInt(n['margin'+('Height'===e?'Bottom':'Right')]):0)}function c(e){var t=e.body,o=e.documentElement,n=r(10)&&getComputedStyle(o);return{height:h('Height',t,o,n),width:h('Width',t,o,n)}}function g(e){return le({},e,{right:e.left+e.width,bottom:e.top+e.height})}function u(e){var o={};try{if(r(10)){o=e.getBoundingClientRect();var n=l(e,'top'),i=l(e,'left');o.top+=n,o.left+=i,o.bottom+=n,o.right+=i}else o=e.getBoundingClientRect()}catch(t){}var p={left:o.left,top:o.top,width:o.right-o.left,height:o.bottom-o.top},s='HTML'===e.nodeName?c(e.ownerDocument):{},d=s.width||e.clientWidth||p.width,a=s.height||e.clientHeight||p.height,f=e.offsetWidth-d,h=e.offsetHeight-a;if(f||h){var u=t(e);f-=m(u,'x'),h-=m(u,'y'),p.width-=f,p.height-=h}return g(p)}function b(e,o){var i=2<arguments.length&&void 0!==arguments[2]&&arguments[2],p=r(10),s='HTML'===o.nodeName,d=u(e),a=u(o),l=n(e),m=t(o),h=parseFloat(m.borderTopWidth,10),c=parseFloat(m.borderLeftWidth,10);i&&s&&(a.top=ee(a.top,0),a.left=ee(a.left,0));var b=g({top:d.top-a.top-h,left:d.left-a.left-c,width:d.width,height:d.height});if(b.marginTop=0,b.marginLeft=0,!p&&s){var w=parseFloat(m.marginTop,10),y=parseFloat(m.marginLeft,10);b.top-=h-w,b.bottom-=h-w,b.left-=c-y,b.right-=c-y,b.marginTop=w,b.marginLeft=y}return(p&&!i?o.contains(l):o===l&&'BODY'!==l.nodeName)&&(b=f(b,o)),b}function w(e){var t=1<arguments.length&&void 0!==arguments[1]&&arguments[1],o=e.ownerDocument.documentElement,n=b(e,o),i=ee(o.clientWidth,window.innerWidth||0),r=ee(o.clientHeight,window.innerHeight||0),p=t?0:l(o),s=t?0:l(o,'left'),d={top:p-n.top+n.marginTop,left:s-n.left+n.marginLeft,width:i,height:r};return g(d)}function y(e){var n=e.nodeName;if('BODY'===n||'HTML'===n)return!1;if('fixed'===t(e,'position'))return!0;var i=o(e);return!!i&&y(i)}function E(e){if(!e||!e.parentElement||r())return document.documentElement;for(var o=e.parentElement;o&&'none'===t(o,'transform');)o=o.parentElement;return o||document.documentElement}function v(e,t,r,p){var s=4<arguments.length&&void 0!==arguments[4]&&arguments[4],d={top:0,left:0},l=s?E(e):a(e,i(t));if('viewport'===p)d=w(l,s);else{var f;'scrollParent'===p?(f=n(o(t)),'BODY'===f.nodeName&&(f=e.ownerDocument.documentElement)):'window'===p?f=e.ownerDocument.documentElement:f=p;var m=b(f,l,s);if('HTML'===f.nodeName&&!y(l)){var h=c(e.ownerDocument),g=h.height,u=h.width;d.top+=m.top-m.marginTop,d.bottom=g+m.top,d.left+=m.left-m.marginLeft,d.right=u+m.left}else d=m}r=r||0;var v='number'==typeof r;return d.left+=v?r:r.left||0,d.top+=v?r:r.top||0,d.right-=v?r:r.right||0,d.bottom-=v?r:r.bottom||0,d}function x(e){var t=e.width,o=e.height;return t*o}function O(e,t,o,n,i){var r=5<arguments.length&&void 0!==arguments[5]?arguments[5]:0;if(-1===e.indexOf('auto'))return e;var p=v(o,n,r,i),s={top:{width:p.width,height:t.top-p.top},right:{width:p.right-t.right,height:p.height},bottom:{width:p.width,height:p.bottom-t.bottom},left:{width:t.left-p.left,height:p.height}},d=Object.keys(s).map(function(e){return le({key:e},s[e],{area:x(s[e])})}).sort(function(e,t){return t.area-e.area}),a=d.filter(function(e){var t=e.width,n=e.height;return t>=o.clientWidth&&n>=o.clientHeight}),l=0<a.length?a[0].key:d[0].key,f=e.split('-')[1];return l+(f?'-'+f:'')}function L(e,t,o){var n=3<arguments.length&&void 0!==arguments[3]?arguments[3]:null,r=n?E(t):a(t,i(o));return b(o,r,n)}function S(e){var t=e.ownerDocument.defaultView,o=t.getComputedStyle(e),n=parseFloat(o.marginTop||0)+parseFloat(o.marginBottom||0),i=parseFloat(o.marginLeft||0)+parseFloat(o.marginRight||0),r={width:e.offsetWidth+i,height:e.offsetHeight+n};return r}function T(e){var t={left:'right',right:'left',bottom:'top',top:'bottom'};return e.replace(/left|right|bottom|top/g,function(e){return t[e]})}function C(e,t,o){o=o.split('-')[0];var n=S(e),i={width:n.width,height:n.height},r=-1!==['right','left'].indexOf(o),p=r?'top':'left',s=r?'left':'top',d=r?'height':'width',a=r?'width':'height';return i[p]=t[p]+t[d]/2-n[d]/2,i[s]=o===s?t[s]-n[a]:t[T(s)],i}function D(e,t){return Array.prototype.find?e.find(t):e.filter(t)[0]}function N(e,t,o){if(Array.prototype.findIndex)return e.findIndex(function(e){return e[t]===o});var n=D(e,function(e){return e[t]===o});return e.indexOf(n)}function P(t,o,n){var i=void 0===n?t:t.slice(0,N(t,'name',n));return i.forEach(function(t){t['function']&&console.warn('`modifier.function` is deprecated, use `modifier.fn`!');var n=t['function']||t.fn;t.enabled&&e(n)&&(o.offsets.popper=g(o.offsets.popper),o.offsets.reference=g(o.offsets.reference),o=n(o,t))}),o}function k(){if(!this.state.isDestroyed){var e={instance:this,styles:{},arrowStyles:{},attributes:{},flipped:!1,offsets:{}};e.offsets.reference=L(this.state,this.popper,this.reference,this.options.positionFixed),e.placement=O(this.options.placement,e.offsets.reference,this.popper,this.reference,this.options.modifiers.flip.boundariesElement,this.options.modifiers.flip.padding),e.originalPlacement=e.placement,e.positionFixed=this.options.positionFixed,e.offsets.popper=C(this.popper,e.offsets.reference,e.placement),e.offsets.popper.position=this.options.positionFixed?'fixed':'absolute',e=P(this.modifiers,e),this.state.isCreated?this.options.onUpdate(e):(this.state.isCreated=!0,this.options.onCreate(e))}}function W(e,t){return e.some(function(e){var o=e.name,n=e.enabled;return n&&o===t})}function B(e){for(var t=[!1,'ms','Webkit','Moz','O'],o=e.charAt(0).toUpperCase()+e.slice(1),n=0;n<t.length;n++){var i=t[n],r=i?''+i+o:e;if('undefined'!=typeof document.body.style[r])return r}return null}function H(){return this.state.isDestroyed=!0,W(this.modifiers,'applyStyle')&&(this.popper.removeAttribute('x-placement'),this.popper.style.position='',this.popper.style.top='',this.popper.style.left='',this.popper.style.right='',this.popper.style.bottom='',this.popper.style.willChange='',this.popper.style[B('transform')]=''),this.disableEventListeners(),this.options.removeOnDestroy&&this.popper.parentNode.removeChild(this.popper),this}function A(e){var t=e.ownerDocument;return t?t.defaultView:window}function M(e,t,o,i){var r='BODY'===e.nodeName,p=r?e.ownerDocument.defaultView:e;p.addEventListener(t,o,{passive:!0}),r||M(n(p.parentNode),t,o,i),i.push(p)}function F(e,t,o,i){o.updateBound=i,A(e).addEventListener('resize',o.updateBound,{passive:!0});var r=n(e);return M(r,'scroll',o.updateBound,o.scrollParents),o.scrollElement=r,o.eventsEnabled=!0,o}function I(){this.state.eventsEnabled||(this.state=F(this.reference,this.options,this.state,this.scheduleUpdate))}function R(e,t){return A(e).removeEventListener('resize',t.updateBound),t.scrollParents.forEach(function(e){e.removeEventListener('scroll',t.updateBound)}),t.updateBound=null,t.scrollParents=[],t.scrollElement=null,t.eventsEnabled=!1,t}function U(){this.state.eventsEnabled&&(cancelAnimationFrame(this.scheduleUpdate),this.state=R(this.reference,this.state))}function Y(e){return''!==e&&!isNaN(parseFloat(e))&&isFinite(e)}function V(e,t){Object.keys(t).forEach(function(o){var n='';-1!==['width','height','top','right','bottom','left'].indexOf(o)&&Y(t[o])&&(n='px'),e.style[o]=t[o]+n})}function j(e,t){Object.keys(t).forEach(function(o){var n=t[o];!1===n?e.removeAttribute(o):e.setAttribute(o,t[o])})}function q(e,t){var o=e.offsets,n=o.popper,i=o.reference,r=$,p=function(e){return e},s=r(i.width),d=r(n.width),a=-1!==['left','right'].indexOf(e.placement),l=-1!==e.placement.indexOf('-'),f=t?a||l||s%2==d%2?r:Z:p,m=t?r:p;return{left:f(1==s%2&&1==d%2&&!l&&t?n.left-1:n.left),top:m(n.top),bottom:m(n.bottom),right:f(n.right)}}function K(e,t,o){var n=D(e,function(e){var o=e.name;return o===t}),i=!!n&&e.some(function(e){return e.name===o&&e.enabled&&e.order<n.order});if(!i){var r='`'+t+'`';console.warn('`'+o+'`'+' modifier is required by '+r+' modifier in order to work, be sure to include it before '+r+'!')}return i}function z(e){return'end'===e?'start':'start'===e?'end':e}function G(e){var t=1<arguments.length&&void 0!==arguments[1]&&arguments[1],o=he.indexOf(e),n=he.slice(o+1).concat(he.slice(0,o));return t?n.reverse():n}function _(e,t,o,n){var i=e.match(/((?:\-|\+)?\d*\.?\d*)(.*)/),r=+i[1],p=i[2];if(!r)return e;if(0===p.indexOf('%')){var s;switch(p){case'%p':s=o;break;case'%':case'%r':default:s=n;}var d=g(s);return d[t]/100*r}if('vh'===p||'vw'===p){var a;return a='vh'===p?ee(document.documentElement.clientHeight,window.innerHeight||0):ee(document.documentElement.clientWidth,window.innerWidth||0),a/100*r}return r}function X(e,t,o,n){var i=[0,0],r=-1!==['right','left'].indexOf(n),p=e.split(/(\+|\-)/).map(function(e){return e.trim()}),s=p.indexOf(D(p,function(e){return-1!==e.search(/,|\s/)}));p[s]&&-1===p[s].indexOf(',')&&console.warn('Offsets separated by white space(s) are deprecated, use a comma (,) instead.');var d=/\s*,\s*|\s+/,a=-1===s?[p]:[p.slice(0,s).concat([p[s].split(d)[0]]),[p[s].split(d)[1]].concat(p.slice(s+1))];return a=a.map(function(e,n){var i=(1===n?!r:r)?'height':'width',p=!1;return e.reduce(function(e,t){return''===e[e.length-1]&&-1!==['+','-'].indexOf(t)?(e[e.length-1]=t,p=!0,e):p?(e[e.length-1]+=t,p=!1,e):e.concat(t)},[]).map(function(e){return _(e,i,t,o)})}),a.forEach(function(e,t){e.forEach(function(o,n){Y(o)&&(i[t]+=o*('-'===e[n-1]?-1:1))})}),i}function J(e,t){var o,n=t.offset,i=e.placement,r=e.offsets,p=r.popper,s=r.reference,d=i.split('-')[0];return o=Y(+n)?[+n,0]:X(n,p,s,d),'left'===d?(p.top+=o[0],p.left-=o[1]):'right'===d?(p.top+=o[0],p.left+=o[1]):'top'===d?(p.left+=o[0],p.top-=o[1]):'bottom'===d&&(p.left+=o[0],p.top+=o[1]),e.popper=p,e}var Q=Math.min,Z=Math.floor,$=Math.round,ee=Math.max,te='undefined'!=typeof window&&'undefined'!=typeof document&&'undefined'!=typeof navigator,oe=function(){for(var e=['Edge','Trident','Firefox'],t=0;t<e.length;t+=1)if(te&&0<=navigator.userAgent.indexOf(e[t]))return 1;return 0}(),ne=te&&window.Promise,ie=ne?function(e){var t=!1;return function(){t||(t=!0,window.Promise.resolve().then(function(){t=!1,e()}))}}:function(e){var t=!1;return function(){t||(t=!0,setTimeout(function(){t=!1,e()},oe))}},re=te&&!!(window.MSInputMethodContext&&document.documentMode),pe=te&&/MSIE 10/.test(navigator.userAgent),se=function(e,t){if(!(e instanceof t))throw new TypeError('Cannot call a class as a function')},de=function(){function e(e,t){for(var o,n=0;n<t.length;n++)o=t[n],o.enumerable=o.enumerable||!1,o.configurable=!0,'value'in o&&(o.writable=!0),Object.defineProperty(e,o.key,o)}return function(t,o,n){return o&&e(t.prototype,o),n&&e(t,n),t}}(),ae=function(e,t,o){return t in e?Object.defineProperty(e,t,{value:o,enumerable:!0,configurable:!0,writable:!0}):e[t]=o,e},le=Object.assign||function(e){for(var t,o=1;o<arguments.length;o++)for(var n in t=arguments[o],t)Object.prototype.hasOwnProperty.call(t,n)&&(e[n]=t[n]);return e},fe=te&&/Firefox/i.test(navigator.userAgent),me=['auto-start','auto','auto-end','top-start','top','top-end','right-start','right','right-end','bottom-end','bottom','bottom-start','left-end','left','left-start'],he=me.slice(3),ce={FLIP:'flip',CLOCKWISE:'clockwise',COUNTERCLOCKWISE:'counterclockwise'},ge=function(){function t(o,n){var i=this,r=2<arguments.length&&void 0!==arguments[2]?arguments[2]:{};se(this,t),this.scheduleUpdate=function(){return requestAnimationFrame(i.update)},this.update=ie(this.update.bind(this)),this.options=le({},t.Defaults,r),this.state={isDestroyed:!1,isCreated:!1,scrollParents:[]},this.reference=o&&o.jquery?o[0]:o,this.popper=n&&n.jquery?n[0]:n,this.options.modifiers={},Object.keys(le({},t.Defaults.modifiers,r.modifiers)).forEach(function(e){i.options.modifiers[e]=le({},t.Defaults.modifiers[e]||{},r.modifiers?r.modifiers[e]:{})}),this.modifiers=Object.keys(this.options.modifiers).map(function(e){return le({name:e},i.options.modifiers[e])}).sort(function(e,t){return e.order-t.order}),this.modifiers.forEach(function(t){t.enabled&&e(t.onLoad)&&t.onLoad(i.reference,i.popper,i.options,t,i.state)}),this.update();var p=this.options.eventsEnabled;p&&this.enableEventListeners(),this.state.eventsEnabled=p}return de(t,[{key:'update',value:function(){return k.call(this)}},{key:'destroy',value:function(){return H.call(this)}},{key:'enableEventListeners',value:function(){return I.call(this)}},{key:'disableEventListeners',value:function(){return U.call(this)}}]),t}();return ge.Utils=('undefined'==typeof window?global:window).PopperUtils,ge.placements=me,ge.Defaults={placement:'bottom',positionFixed:!1,eventsEnabled:!0,removeOnDestroy:!1,onCreate:function(){},onUpdate:function(){},modifiers:{shift:{order:100,enabled:!0,fn:function(e){var t=e.placement,o=t.split('-')[0],n=t.split('-')[1];if(n){var i=e.offsets,r=i.reference,p=i.popper,s=-1!==['bottom','top'].indexOf(o),d=s?'left':'top',a=s?'width':'height',l={start:ae({},d,r[d]),end:ae({},d,r[d]+r[a]-p[a])};e.offsets.popper=le({},p,l[n])}return e}},offset:{order:200,enabled:!0,fn:J,offset:0},preventOverflow:{order:300,enabled:!0,fn:function(e,t){var o=t.boundariesElement||p(e.instance.popper);e.instance.reference===o&&(o=p(o));var n=B('transform'),i=e.instance.popper.style,r=i.top,s=i.left,d=i[n];i.top='',i.left='',i[n]='';var a=v(e.instance.popper,e.instance.reference,t.padding,o,e.positionFixed);i.top=r,i.left=s,i[n]=d,t.boundaries=a;var l=t.priority,f=e.offsets.popper,m={primary:function(e){var o=f[e];return f[e]<a[e]&&!t.escapeWithReference&&(o=ee(f[e],a[e])),ae({},e,o)},secondary:function(e){var o='right'===e?'left':'top',n=f[o];return f[e]>a[e]&&!t.escapeWithReference&&(n=Q(f[o],a[e]-('right'===e?f.width:f.height))),ae({},o,n)}};return l.forEach(function(e){var t=-1===['left','top'].indexOf(e)?'secondary':'primary';f=le({},f,m[t](e))}),e.offsets.popper=f,e},priority:['left','right','top','bottom'],padding:5,boundariesElement:'scrollParent'},keepTogether:{order:400,enabled:!0,fn:function(e){var t=e.offsets,o=t.popper,n=t.reference,i=e.placement.split('-')[0],r=Z,p=-1!==['top','bottom'].indexOf(i),s=p?'right':'bottom',d=p?'left':'top',a=p?'width':'height';return o[s]<r(n[d])&&(e.offsets.popper[d]=r(n[d])-o[a]),o[d]>r(n[s])&&(e.offsets.popper[d]=r(n[s])),e}},arrow:{order:500,enabled:!0,fn:function(e,o){var n;if(!K(e.instance.modifiers,'arrow','keepTogether'))return e;var i=o.element;if('string'==typeof i){if(i=e.instance.popper.querySelector(i),!i)return e;}else if(!e.instance.popper.contains(i))return console.warn('WARNING: `arrow.element` must be child of its popper element!'),e;var r=e.placement.split('-')[0],p=e.offsets,s=p.popper,d=p.reference,a=-1!==['left','right'].indexOf(r),l=a?'height':'width',f=a?'Top':'Left',m=f.toLowerCase(),h=a?'left':'top',c=a?'bottom':'right',u=S(i)[l];d[c]-u<s[m]&&(e.offsets.popper[m]-=s[m]-(d[c]-u)),d[m]+u>s[c]&&(e.offsets.popper[m]+=d[m]+u-s[c]),e.offsets.popper=g(e.offsets.popper);var b=d[m]+d[l]/2-u/2,w=t(e.instance.popper),y=parseFloat(w['margin'+f],10),E=parseFloat(w['border'+f+'Width'],10),v=b-e.offsets.popper[m]-y-E;return v=ee(Q(s[l]-u,v),0),e.arrowElement=i,e.offsets.arrow=(n={},ae(n,m,$(v)),ae(n,h,''),n),e},element:'[x-arrow]'},flip:{order:600,enabled:!0,fn:function(e,t){if(W(e.instance.modifiers,'inner'))return e;if(e.flipped&&e.placement===e.originalPlacement)return e;var o=v(e.instance.popper,e.instance.reference,t.padding,t.boundariesElement,e.positionFixed),n=e.placement.split('-')[0],i=T(n),r=e.placement.split('-')[1]||'',p=[];switch(t.behavior){case ce.FLIP:p=[n,i];break;case ce.CLOCKWISE:p=G(n);break;case ce.COUNTERCLOCKWISE:p=G(n,!0);break;default:p=t.behavior;}return p.forEach(function(s,d){if(n!==s||p.length===d+1)return e;n=e.placement.split('-')[0],i=T(n);var a=e.offsets.popper,l=e.offsets.reference,f=Z,m='left'===n&&f(a.right)>f(l.left)||'right'===n&&f(a.left)<f(l.right)||'top'===n&&f(a.bottom)>f(l.top)||'bottom'===n&&f(a.top)<f(l.bottom),h=f(a.left)<f(o.left),c=f(a.right)>f(o.right),g=f(a.top)<f(o.top),u=f(a.bottom)>f(o.bottom),b='left'===n&&h||'right'===n&&c||'top'===n&&g||'bottom'===n&&u,w=-1!==['top','bottom'].indexOf(n),y=!!t.flipVariations&&(w&&'start'===r&&h||w&&'end'===r&&c||!w&&'start'===r&&g||!w&&'end'===r&&u),E=!!t.flipVariationsByContent&&(w&&'start'===r&&c||w&&'end'===r&&h||!w&&'start'===r&&u||!w&&'end'===r&&g),v=y||E;(m||b||v)&&(e.flipped=!0,(m||b)&&(n=p[d+1]),v&&(r=z(r)),e.placement=n+(r?'-'+r:''),e.offsets.popper=le({},e.offsets.popper,C(e.instance.popper,e.offsets.reference,e.placement)),e=P(e.instance.modifiers,e,'flip'))}),e},behavior:'flip',padding:5,boundariesElement:'viewport',flipVariations:!1,flipVariationsByContent:!1},inner:{order:700,enabled:!1,fn:function(e){var t=e.placement,o=t.split('-')[0],n=e.offsets,i=n.popper,r=n.reference,p=-1!==['left','right'].indexOf(o),s=-1===['top','left'].indexOf(o);return i[p?'left':'top']=r[o]-(s?i[p?'width':'height']:0),e.placement=T(t),e.offsets.popper=g(i),e}},hide:{order:800,enabled:!0,fn:function(e){if(!K(e.instance.modifiers,'hide','preventOverflow'))return e;var t=e.offsets.reference,o=D(e.instance.modifiers,function(e){return'preventOverflow'===e.name}).boundaries;if(t.bottom<o.top||t.left>o.right||t.top>o.bottom||t.right<o.left){if(!0===e.hide)return e;e.hide=!0,e.attributes['x-out-of-boundaries']=''}else{if(!1===e.hide)return e;e.hide=!1,e.attributes['x-out-of-boundaries']=!1}return e}},computeStyle:{order:850,enabled:!0,fn:function(e,t){var o=t.x,n=t.y,i=e.offsets.popper,r=D(e.instance.modifiers,function(e){return'applyStyle'===e.name}).gpuAcceleration;void 0!==r&&console.warn('WARNING: `gpuAcceleration` option moved to `computeStyle` modifier and will not be supported in future versions of Popper.js!');var s,d,a=void 0===r?t.gpuAcceleration:r,l=p(e.instance.popper),f=u(l),m={position:i.position},h=q(e,2>window.devicePixelRatio||!fe),c='bottom'===o?'top':'bottom',g='right'===n?'left':'right',b=B('transform');if(d='bottom'==c?'HTML'===l.nodeName?-l.clientHeight+h.bottom:-f.height+h.bottom:h.top,s='right'==g?'HTML'===l.nodeName?-l.clientWidth+h.right:-f.width+h.right:h.left,a&&b)m[b]='translate3d('+s+'px, '+d+'px, 0)',m[c]=0,m[g]=0,m.willChange='transform';else{var w='bottom'==c?-1:1,y='right'==g?-1:1;m[c]=d*w,m[g]=s*y,m.willChange=c+', '+g}var E={"x-placement":e.placement};return e.attributes=le({},E,e.attributes),e.styles=le({},m,e.styles),e.arrowStyles=le({},e.offsets.arrow,e.arrowStyles),e},gpuAcceleration:!0,x:'bottom',y:'right'},applyStyle:{order:900,enabled:!0,fn:function(e){return V(e.instance.popper,e.styles),j(e.instance.popper,e.attributes),e.arrowElement&&Object.keys(e.arrowStyles).length&&V(e.arrowElement,e.arrowStyles),e},onLoad:function(e,t,o,n,i){var r=L(i,t,e,o.positionFixed),p=O(o.placement,r,t,e,o.modifiers.flip.boundariesElement,o.modifiers.flip.padding);return t.setAttribute('x-placement',p),V(t,{position:o.positionFixed?'fixed':'absolute'}),o},gpuAcceleration:void 0}}},ge}); /*! * Bootstrap util.js v4.5.0 (https://getbootstrap.com/) * Copyright 2011-2020 The Bootstrap Authors (https://github.com/twbs/bootstrap/graphs/contributors) * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) */ (function (global, factory) { typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory(require('jquery')) : typeof define === 'function' && define.amd ? define(['jquery'], factory) : (global = global || self, global.Util = factory(global.jQuery)); }(this, (function ($) { 'use strict'; $ = $ && Object.prototype.hasOwnProperty.call($, 'default') ? $['default'] : $; /** * -------------------------------------------------------------------------- * Bootstrap (v4.5.0): util.js * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) * -------------------------------------------------------------------------- */ /** * ------------------------------------------------------------------------ * Private TransitionEnd Helpers * ------------------------------------------------------------------------ */ var TRANSITION_END = 'transitionend'; var MAX_UID = 1000000; var MILLISECONDS_MULTIPLIER = 1000; // Shoutout AngusCroll (https://goo.gl/pxwQGp) function toType(obj) { if (obj === null || typeof obj === 'undefined') { return "" + obj; } return {}.toString.call(obj).match(/\s([a-z]+)/i)[1].toLowerCase(); } function getSpecialTransitionEndEvent() { return { bindType: TRANSITION_END, delegateType: TRANSITION_END, handle: function handle(event) { if ($(event.target).is(this)) { return event.handleObj.handler.apply(this, arguments); // eslint-disable-line prefer-rest-params } return undefined; } }; } function transitionEndEmulator(duration) { var _this = this; var called = false; $(this).one(Util.TRANSITION_END, function () { called = true; }); setTimeout(function () { if (!called) { Util.triggerTransitionEnd(_this); } }, duration); return this; } function setTransitionEndSupport() { $.fn.emulateTransitionEnd = transitionEndEmulator; $.event.special[Util.TRANSITION_END] = getSpecialTransitionEndEvent(); } /** * -------------------------------------------------------------------------- * Public Util Api * -------------------------------------------------------------------------- */ var Util = { TRANSITION_END: 'bsTransitionEnd', getUID: function getUID(prefix) { do { // eslint-disable-next-line no-bitwise prefix += ~~(Math.random() * MAX_UID); // "~~" acts like a faster Math.floor() here } while (document.getElementById(prefix)); return prefix; }, getSelectorFromElement: function getSelectorFromElement(element) { var selector = element.getAttribute('data-target'); if (!selector || selector === '#') { var hrefAttr = element.getAttribute('href'); selector = hrefAttr && hrefAttr !== '#' ? hrefAttr.trim() : ''; } try { return document.querySelector(selector) ? selector : null; } catch (err) { return null; } }, getTransitionDurationFromElement: function getTransitionDurationFromElement(element) { if (!element) { return 0; } // Get transition-duration of the element var transitionDuration = $(element).css('transition-duration'); var transitionDelay = $(element).css('transition-delay'); var floatTransitionDuration = parseFloat(transitionDuration); var floatTransitionDelay = parseFloat(transitionDelay); // Return 0 if element or transition duration is not found if (!floatTransitionDuration && !floatTransitionDelay) { return 0; } // If multiple durations are defined, take the first transitionDuration = transitionDuration.split(',')[0]; transitionDelay = transitionDelay.split(',')[0]; return (parseFloat(transitionDuration) + parseFloat(transitionDelay)) * MILLISECONDS_MULTIPLIER; }, reflow: function reflow(element) { return element.offsetHeight; }, triggerTransitionEnd: function triggerTransitionEnd(element) { $(element).trigger(TRANSITION_END); }, // TODO: Remove in v5 supportsTransitionEnd: function supportsTransitionEnd() { return Boolean(TRANSITION_END); }, isElement: function isElement(obj) { return (obj[0] || obj).nodeType; }, typeCheckConfig: function typeCheckConfig(componentName, config, configTypes) { for (var property in configTypes) { if (Object.prototype.hasOwnProperty.call(configTypes, property)) { var expectedTypes = configTypes[property]; var value = config[property]; var valueType = value && Util.isElement(value) ? 'element' : toType(value); if (!new RegExp(expectedTypes).test(valueType)) { throw new Error(componentName.toUpperCase() + ": " + ("Option \"" + property + "\" provided type \"" + valueType + "\" ") + ("but expected type \"" + expectedTypes + "\".")); } } } }, findShadowRoot: function findShadowRoot(element) { if (!document.documentElement.attachShadow) { return null; } // Can find the shadow root otherwise it'll return the document if (typeof element.getRootNode === 'function') { var root = element.getRootNode(); return root instanceof ShadowRoot ? root : null; } if (element instanceof ShadowRoot) { return element; } // when we don't find a shadow root if (!element.parentNode) { return null; } return Util.findShadowRoot(element.parentNode); }, jQueryDetection: function jQueryDetection() { if (typeof $ === 'undefined') { throw new TypeError('Bootstrap\'s JavaScript requires jQuery. jQuery must be included before Bootstrap\'s JavaScript.'); } var version = $.fn.jquery.split(' ')[0].split('.'); var minMajor = 1; var ltMajor = 2; var minMinor = 9; var minPatch = 1; var maxMajor = 4; if (version[0] < ltMajor && version[1] < minMinor || version[0] === minMajor && version[1] === minMinor && version[2] < minPatch || version[0] >= maxMajor) { throw new Error('Bootstrap\'s JavaScript requires at least jQuery v1.9.1 but less than v4.0.0'); } } }; Util.jQueryDetection(); setTransitionEndSupport(); return Util; }))); //# sourceMappingURL=util.js.map /*! * Bootstrap dropdown.js v4.5.0 (https://getbootstrap.com/) * Copyright 2011-2020 The Bootstrap Authors (https://github.com/twbs/bootstrap/graphs/contributors) * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) */ (function (global, factory) { typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory(require('jquery'), require('popper.js'), require('./util.js')) : typeof define === 'function' && define.amd ? define(['jquery', 'popper.js', './util.js'], factory) : (global = global || self, global.Dropdown = factory(global.jQuery, global.Popper, global.Util)); }(this, (function ($, Popper, Util) { 'use strict'; $ = $ && Object.prototype.hasOwnProperty.call($, 'default') ? $['default'] : $; Popper = Popper && Object.prototype.hasOwnProperty.call(Popper, 'default') ? Popper['default'] : Popper; Util = Util && Object.prototype.hasOwnProperty.call(Util, 'default') ? Util['default'] : Util; function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; } function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; } function _objectSpread2(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; } /** * ------------------------------------------------------------------------ * Constants * ------------------------------------------------------------------------ */ var NAME = 'dropdown'; var VERSION = '4.5.0'; var DATA_KEY = 'bs.dropdown'; var EVENT_KEY = "." + DATA_KEY; var DATA_API_KEY = '.data-api'; var JQUERY_NO_CONFLICT = $.fn[NAME]; var ESCAPE_KEYCODE = 27; // KeyboardEvent.which value for Escape (Esc) key var SPACE_KEYCODE = 32; // KeyboardEvent.which value for space key var TAB_KEYCODE = 9; // KeyboardEvent.which value for tab key var ARROW_UP_KEYCODE = 38; // KeyboardEvent.which value for up arrow key var ARROW_DOWN_KEYCODE = 40; // KeyboardEvent.which value for down arrow key var RIGHT_MOUSE_BUTTON_WHICH = 3; // MouseEvent.which value for the right button (assuming a right-handed mouse) var REGEXP_KEYDOWN = new RegExp(ARROW_UP_KEYCODE + "|" + ARROW_DOWN_KEYCODE + "|" + ESCAPE_KEYCODE); var EVENT_HIDE = "hide" + EVENT_KEY; var EVENT_HIDDEN = "hidden" + EVENT_KEY; var EVENT_SHOW = "show" + EVENT_KEY; var EVENT_SHOWN = "shown" + EVENT_KEY; var EVENT_CLICK = "click" + EVENT_KEY; var EVENT_CLICK_DATA_API = "click" + EVENT_KEY + DATA_API_KEY; var EVENT_KEYDOWN_DATA_API = "keydown" + EVENT_KEY + DATA_API_KEY; var EVENT_KEYUP_DATA_API = "keyup" + EVENT_KEY + DATA_API_KEY; var CLASS_NAME_DISABLED = 'disabled'; var CLASS_NAME_SHOW = 'show'; var CLASS_NAME_DROPUP = 'dropup'; var CLASS_NAME_DROPRIGHT = 'dropright'; var CLASS_NAME_DROPLEFT = 'dropleft'; var CLASS_NAME_MENURIGHT = 'dropdown-menu-right'; var CLASS_NAME_POSITION_STATIC = 'position-static'; var SELECTOR_DATA_TOGGLE = '[data-toggle="dropdown"]'; var SELECTOR_FORM_CHILD = '.dropdown form'; var SELECTOR_MENU = '.dropdown-menu'; var SELECTOR_NAVBAR_NAV = '.navbar-nav'; var SELECTOR_VISIBLE_ITEMS = '.dropdown-menu .dropdown-item:not(.disabled):not(:disabled)'; var PLACEMENT_TOP = 'top-start'; var PLACEMENT_TOPEND = 'top-end'; var PLACEMENT_BOTTOM = 'bottom-start'; var PLACEMENT_BOTTOMEND = 'bottom-end'; var PLACEMENT_RIGHT = 'right-start'; var PLACEMENT_LEFT = 'left-start'; var Default = { offset: 0, flip: true, boundary: 'scrollParent', reference: 'toggle', display: 'dynamic', popperConfig: null }; var DefaultType = { offset: '(number|string|function)', flip: 'boolean', boundary: '(string|element)', reference: '(string|element)', display: 'string', popperConfig: '(null|object)' }; /** * ------------------------------------------------------------------------ * Class Definition * ------------------------------------------------------------------------ */ var Dropdown = /*#__PURE__*/function () { function Dropdown(element, config) { this._element = element; this._popper = null; this._config = this._getConfig(config); this._menu = this._getMenuElement(); this._inNavbar = this._detectNavbar(); this._addEventListeners(); } // Getters var _proto = Dropdown.prototype; // Public _proto.toggle = function toggle() { if (this._element.disabled || $(this._element).hasClass(CLASS_NAME_DISABLED)) { return; } var isActive = $(this._menu).hasClass(CLASS_NAME_SHOW); Dropdown._clearMenus(); if (isActive) { return; } this.show(true); }; _proto.show = function show(usePopper) { if (usePopper === void 0) { usePopper = false; } if (this._element.disabled || $(this._element).hasClass(CLASS_NAME_DISABLED) || $(this._menu).hasClass(CLASS_NAME_SHOW)) { return; } var relatedTarget = { relatedTarget: this._element }; var showEvent = $.Event(EVENT_SHOW, relatedTarget); var parent = Dropdown._getParentFromElement(this._element); $(parent).trigger(showEvent); if (showEvent.isDefaultPrevented()) { return; } // Disable totally Popper.js for Dropdown in Navbar if (!this._inNavbar && usePopper) { /** * Check for Popper dependency * Popper - https://popper.js.org */ if (typeof Popper === 'undefined') { throw new TypeError('Bootstrap\'s dropdowns require Popper.js (https://popper.js.org/)'); } var referenceElement = this._element; if (this._config.reference === 'parent') { referenceElement = parent; } else if (Util.isElement(this._config.reference)) { referenceElement = this._config.reference; // Check if it's jQuery element if (typeof this._config.reference.jquery !== 'undefined') { referenceElement = this._config.reference[0]; } } // If boundary is not `scrollParent`, then set position to `static` // to allow the menu to "escape" the scroll parent's boundaries // https://github.com/twbs/bootstrap/issues/24251 if (this._config.boundary !== 'scrollParent') { $(parent).addClass(CLASS_NAME_POSITION_STATIC); } this._popper = new Popper(referenceElement, this._menu, this._getPopperConfig()); } // If this is a touch-enabled device we add extra // empty mouseover listeners to the body's immediate children; // only needed because of broken event delegation on iOS // https://www.quirksmode.org/blog/archives/2014/02/mouse_event_bub.html if ('ontouchstart' in document.documentElement && $(parent).closest(SELECTOR_NAVBAR_NAV).length === 0) { $(document.body).children().on('mouseover', null, $.noop); } this._element.focus(); this._element.setAttribute('aria-expanded', true); $(this._menu).toggleClass(CLASS_NAME_SHOW); $(parent).toggleClass(CLASS_NAME_SHOW).trigger($.Event(EVENT_SHOWN, relatedTarget)); }; _proto.hide = function hide() { if (this._element.disabled || $(this._element).hasClass(CLASS_NAME_DISABLED) || !$(this._menu).hasClass(CLASS_NAME_SHOW)) { return; } var relatedTarget = { relatedTarget: this._element }; var hideEvent = $.Event(EVENT_HIDE, relatedTarget); var parent = Dropdown._getParentFromElement(this._element); $(parent).trigger(hideEvent); if (hideEvent.isDefaultPrevented()) { return; } if (this._popper) { this._popper.destroy(); } $(this._menu).toggleClass(CLASS_NAME_SHOW); $(parent).toggleClass(CLASS_NAME_SHOW).trigger($.Event(EVENT_HIDDEN, relatedTarget)); }; _proto.dispose = function dispose() { $.removeData(this._element, DATA_KEY); $(this._element).off(EVENT_KEY); this._element = null; this._menu = null; if (this._popper !== null) { this._popper.destroy(); this._popper = null; } }; _proto.update = function update() { this._inNavbar = this._detectNavbar(); if (this._popper !== null) { this._popper.scheduleUpdate(); } } // Private ; _proto._addEventListeners = function _addEventListeners() { var _this = this; $(this._element).on(EVENT_CLICK, function (event) { event.preventDefault(); event.stopPropagation(); _this.toggle(); }); }; _proto._getConfig = function _getConfig(config) { config = _objectSpread2(_objectSpread2(_objectSpread2({}, this.constructor.Default), $(this._element).data()), config); Util.typeCheckConfig(NAME, config, this.constructor.DefaultType); return config; }; _proto._getMenuElement = function _getMenuElement() { if (!this._menu) { var parent = Dropdown._getParentFromElement(this._element); if (parent) { this._menu = parent.querySelector(SELECTOR_MENU); } } return this._menu; }; _proto._getPlacement = function _getPlacement() { var $parentDropdown = $(this._element.parentNode); var placement = PLACEMENT_BOTTOM; // Handle dropup if ($parentDropdown.hasClass(CLASS_NAME_DROPUP)) { placement = $(this._menu).hasClass(CLASS_NAME_MENURIGHT) ? PLACEMENT_TOPEND : PLACEMENT_TOP; } else if ($parentDropdown.hasClass(CLASS_NAME_DROPRIGHT)) { placement = PLACEMENT_RIGHT; } else if ($parentDropdown.hasClass(CLASS_NAME_DROPLEFT)) { placement = PLACEMENT_LEFT; } else if ($(this._menu).hasClass(CLASS_NAME_MENURIGHT)) { placement = PLACEMENT_BOTTOMEND; } return placement; }; _proto._detectNavbar = function _detectNavbar() { return $(this._element).closest('.navbar').length > 0; }; _proto._getOffset = function _getOffset() { var _this2 = this; var offset = {}; if (typeof this._config.offset === 'function') { offset.fn = function (data) { data.offsets = _objectSpread2(_objectSpread2({}, data.offsets), _this2._config.offset(data.offsets, _this2._element) || {}); return data; }; } else { offset.offset = this._config.offset; } return offset; }; _proto._getPopperConfig = function _getPopperConfig() { var popperConfig = { placement: this._getPlacement(), modifiers: { offset: this._getOffset(), flip: { enabled: this._config.flip }, preventOverflow: { boundariesElement: this._config.boundary } } }; // Disable Popper.js if we have a static display if (this._config.display === 'static') { popperConfig.modifiers.applyStyle = { enabled: false }; } return _objectSpread2(_objectSpread2({}, popperConfig), this._config.popperConfig); } // Static ; Dropdown._jQueryInterface = function _jQueryInterface(config) { return this.each(function () { var data = $(this).data(DATA_KEY); var _config = typeof config === 'object' ? config : null; if (!data) { data = new Dropdown(this, _config); $(this).data(DATA_KEY, data); } if (typeof config === 'string') { if (typeof data[config] === 'undefined') { throw new TypeError("No method named \"" + config + "\""); } data[config](); } }); }; Dropdown._clearMenus = function _clearMenus(event) { if (event && (event.which === RIGHT_MOUSE_BUTTON_WHICH || event.type === 'keyup' && event.which !== TAB_KEYCODE)) { return; } var toggles = [].slice.call(document.querySelectorAll(SELECTOR_DATA_TOGGLE)); for (var i = 0, len = toggles.length; i < len; i++) { var parent = Dropdown._getParentFromElement(toggles[i]); var context = $(toggles[i]).data(DATA_KEY); var relatedTarget = { relatedTarget: toggles[i] }; if (event && event.type === 'click') { relatedTarget.clickEvent = event; } if (!context) { continue; } var dropdownMenu = context._menu; if (!$(parent).hasClass(CLASS_NAME_SHOW)) { continue; } if (event && (event.type === 'click' && /input|textarea/i.test(event.target.tagName) || event.type === 'keyup' && event.which === TAB_KEYCODE) && $.contains(parent, event.target)) { continue; } var hideEvent = $.Event(EVENT_HIDE, relatedTarget); $(parent).trigger(hideEvent); if (hideEvent.isDefaultPrevented()) { continue; } // If this is a touch-enabled device we remove the extra // empty mouseover listeners we added for iOS support if ('ontouchstart' in document.documentElement) { $(document.body).children().off('mouseover', null, $.noop); } toggles[i].setAttribute('aria-expanded', 'false'); if (context._popper) { context._popper.destroy(); } $(dropdownMenu).removeClass(CLASS_NAME_SHOW); $(parent).removeClass(CLASS_NAME_SHOW).trigger($.Event(EVENT_HIDDEN, relatedTarget)); } }; Dropdown._getParentFromElement = function _getParentFromElement(element) { var parent; var selector = Util.getSelectorFromElement(element); if (selector) { parent = document.querySelector(selector); } return parent || element.parentNode; } // eslint-disable-next-line complexity ; Dropdown._dataApiKeydownHandler = function _dataApiKeydownHandler(event) { // If not input/textarea: // - And not a key in REGEXP_KEYDOWN => not a dropdown command // If input/textarea: // - If space key => not a dropdown command // - If key is other than escape // - If key is not up or down => not a dropdown command // - If trigger inside the menu => not a dropdown command if (/input|textarea/i.test(event.target.tagName) ? event.which === SPACE_KEYCODE || event.which !== ESCAPE_KEYCODE && (event.which !== ARROW_DOWN_KEYCODE && event.which !== ARROW_UP_KEYCODE || $(event.target).closest(SELECTOR_MENU).length) : !REGEXP_KEYDOWN.test(event.which)) { return; } if (this.disabled || $(this).hasClass(CLASS_NAME_DISABLED)) { return; } var parent = Dropdown._getParentFromElement(this); var isActive = $(parent).hasClass(CLASS_NAME_SHOW); if (!isActive && event.which === ESCAPE_KEYCODE) { return; } event.preventDefault(); event.stopPropagation(); if (!isActive || isActive && (event.which === ESCAPE_KEYCODE || event.which === SPACE_KEYCODE)) { if (event.which === ESCAPE_KEYCODE) { $(parent.querySelector(SELECTOR_DATA_TOGGLE)).trigger('focus'); } $(this).trigger('click'); return; } var items = [].slice.call(parent.querySelectorAll(SELECTOR_VISIBLE_ITEMS)).filter(function (item) { return $(item).is(':visible'); }); if (items.length === 0) { return; } var index = items.indexOf(event.target); if (event.which === ARROW_UP_KEYCODE && index > 0) { // Up index--; } if (event.which === ARROW_DOWN_KEYCODE && index < items.length - 1) { // Down index++; } if (index < 0) { index = 0; } items[index].focus(); }; _createClass(Dropdown, null, [{ key: "VERSION", get: function get() { return VERSION; } }, { key: "Default", get: function get() { return Default; } }, { key: "DefaultType", get: function get() { return DefaultType; } }]); return Dropdown; }(); /** * ------------------------------------------------------------------------ * Data Api implementation * ------------------------------------------------------------------------ */ $(document).on(EVENT_KEYDOWN_DATA_API, SELECTOR_DATA_TOGGLE, Dropdown._dataApiKeydownHandler).on(EVENT_KEYDOWN_DATA_API, SELECTOR_MENU, Dropdown._dataApiKeydownHandler).on(EVENT_CLICK_DATA_API + " " + EVENT_KEYUP_DATA_API, Dropdown._clearMenus).on(EVENT_CLICK_DATA_API, SELECTOR_DATA_TOGGLE, function (event) { event.preventDefault(); event.stopPropagation(); Dropdown._jQueryInterface.call($(this), 'toggle'); }).on(EVENT_CLICK_DATA_API, SELECTOR_FORM_CHILD, function (e) { e.stopPropagation(); }); /** * ------------------------------------------------------------------------ * jQuery * ------------------------------------------------------------------------ */ $.fn[NAME] = Dropdown._jQueryInterface; $.fn[NAME].Constructor = Dropdown; $.fn[NAME].noConflict = function () { $.fn[NAME] = JQUERY_NO_CONFLICT; return Dropdown._jQueryInterface; }; return Dropdown; }))); /*! * Bootstrap tooltip.js v4.5.0 (https://getbootstrap.com/) * Copyright 2011-2020 The Bootstrap Authors (https://github.com/twbs/bootstrap/graphs/contributors) * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) */ (function (global, factory) { typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory(require('jquery'), require('popper.js'), require('./util.js')) : typeof define === 'function' && define.amd ? define(['jquery', 'popper.js', './util.js'], factory) : (global = global || self, global.Tooltip = factory(global.jQuery, global.Popper, global.Util)); }(this, (function ($, Popper, Util) { 'use strict'; $ = $ && Object.prototype.hasOwnProperty.call($, 'default') ? $['default'] : $; Popper = Popper && Object.prototype.hasOwnProperty.call(Popper, 'default') ? Popper['default'] : Popper; Util = Util && Object.prototype.hasOwnProperty.call(Util, 'default') ? Util['default'] : Util; function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; } function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; } function _objectSpread2(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; } /** * -------------------------------------------------------------------------- * Bootstrap (v4.5.0): tools/sanitizer.js * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) * -------------------------------------------------------------------------- */ var uriAttrs = ['background', 'cite', 'href', 'itemtype', 'longdesc', 'poster', 'src', 'xlink:href']; var ARIA_ATTRIBUTE_PATTERN = /^aria-[\w-]*$/i; var DefaultWhitelist = { // Global attributes allowed on any supplied element below. '*': ['class', 'dir', 'id', 'lang', 'role', ARIA_ATTRIBUTE_PATTERN], a: ['target', 'href', 'title', 'rel'], area: [], b: [], br: [], col: [], code: [], div: [], em: [], hr: [], h1: [], h2: [], h3: [], h4: [], h5: [], h6: [], i: [], img: ['src', 'srcset', 'alt', 'title', 'width', 'height'], li: [], ol: [], p: [], pre: [], s: [], small: [], span: [], sub: [], sup: [], strong: [], u: [], ul: [] }; /** * A pattern that recognizes a commonly useful subset of URLs that are safe. * * Shoutout to Angular 7 https://github.com/angular/angular/blob/7.2.4/packages/core/src/sanitization/url_sanitizer.ts */ var SAFE_URL_PATTERN = /^(?:(?:https?|mailto|ftp|tel|file):|[^#&/:?]*(?:[#/?]|$))/gi; /** * A pattern that matches safe data URLs. Only matches image, video and audio types. * * Shoutout to Angular 7 https://github.com/angular/angular/blob/7.2.4/packages/core/src/sanitization/url_sanitizer.ts */ var DATA_URL_PATTERN = /^data:(?:image\/(?:bmp|gif|jpeg|jpg|png|tiff|webp)|video\/(?:mpeg|mp4|ogg|webm)|audio\/(?:mp3|oga|ogg|opus));base64,[\d+/a-z]+=*$/i; function allowedAttribute(attr, allowedAttributeList) { var attrName = attr.nodeName.toLowerCase(); if (allowedAttributeList.indexOf(attrName) !== -1) { if (uriAttrs.indexOf(attrName) !== -1) { return Boolean(attr.nodeValue.match(SAFE_URL_PATTERN) || attr.nodeValue.match(DATA_URL_PATTERN)); } return true; } var regExp = allowedAttributeList.filter(function (attrRegex) { return attrRegex instanceof RegExp; }); // Check if a regular expression validates the attribute. for (var i = 0, len = regExp.length; i < len; i++) { if (attrName.match(regExp[i])) { return true; } } return false; } function sanitizeHtml(unsafeHtml, whiteList, sanitizeFn) { if (unsafeHtml.length === 0) { return unsafeHtml; } if (sanitizeFn && typeof sanitizeFn === 'function') { return sanitizeFn(unsafeHtml); } var domParser = new window.DOMParser(); var createdDocument = domParser.parseFromString(unsafeHtml, 'text/html'); var whitelistKeys = Object.keys(whiteList); var elements = [].slice.call(createdDocument.body.querySelectorAll('*')); var _loop = function _loop(i, len) { var el = elements[i]; var elName = el.nodeName.toLowerCase(); if (whitelistKeys.indexOf(el.nodeName.toLowerCase()) === -1) { el.parentNode.removeChild(el); return "continue"; } var attributeList = [].slice.call(el.attributes); var whitelistedAttributes = [].concat(whiteList['*'] || [], whiteList[elName] || []); attributeList.forEach(function (attr) { if (!allowedAttribute(attr, whitelistedAttributes)) { el.removeAttribute(attr.nodeName); } }); }; for (var i = 0, len = elements.length; i < len; i++) { var _ret = _loop(i); if (_ret === "continue") continue; } return createdDocument.body.innerHTML; } /** * ------------------------------------------------------------------------ * Constants * ------------------------------------------------------------------------ */ var NAME = 'tooltip'; var VERSION = '4.5.0'; var DATA_KEY = 'bs.tooltip'; var EVENT_KEY = "." + DATA_KEY; var JQUERY_NO_CONFLICT = $.fn[NAME]; var CLASS_PREFIX = 'bs-tooltip'; var BSCLS_PREFIX_REGEX = new RegExp("(^|\\s)" + CLASS_PREFIX + "\\S+", 'g'); var DISALLOWED_ATTRIBUTES = ['sanitize', 'whiteList', 'sanitizeFn']; var DefaultType = { animation: 'boolean', template: 'string', title: '(string|element|function)', trigger: 'string', delay: '(number|object)', html: 'boolean', selector: '(string|boolean)', placement: '(string|function)', offset: '(number|string|function)', container: '(string|element|boolean)', fallbackPlacement: '(string|array)', boundary: '(string|element)', sanitize: 'boolean', sanitizeFn: '(null|function)', whiteList: 'object', popperConfig: '(null|object)' }; var AttachmentMap = { AUTO: 'auto', TOP: 'top', RIGHT: 'right', BOTTOM: 'bottom', LEFT: 'left' }; var Default = { animation: true, template: '<div class="tooltip" role="tooltip">' + '<div class="arrow"></div>' + '<div class="tooltip-inner"></div></div>', trigger: 'hover focus', title: '', delay: 0, html: false, selector: false, placement: 'top', offset: 0, container: false, fallbackPlacement: 'flip', boundary: 'scrollParent', sanitize: true, sanitizeFn: null, whiteList: DefaultWhitelist, popperConfig: null }; var HOVER_STATE_SHOW = 'show'; var HOVER_STATE_OUT = 'out'; var Event = { HIDE: "hide" + EVENT_KEY, HIDDEN: "hidden" + EVENT_KEY, SHOW: "show" + EVENT_KEY, SHOWN: "shown" + EVENT_KEY, INSERTED: "inserted" + EVENT_KEY, CLICK: "click" + EVENT_KEY, FOCUSIN: "focusin" + EVENT_KEY, FOCUSOUT: "focusout" + EVENT_KEY, MOUSEENTER: "mouseenter" + EVENT_KEY, MOUSELEAVE: "mouseleave" + EVENT_KEY }; var CLASS_NAME_FADE = 'fade'; var CLASS_NAME_SHOW = 'show'; var SELECTOR_TOOLTIP_INNER = '.tooltip-inner'; var SELECTOR_ARROW = '.arrow'; var TRIGGER_HOVER = 'hover'; var TRIGGER_FOCUS = 'focus'; var TRIGGER_CLICK = 'click'; var TRIGGER_MANUAL = 'manual'; /** * ------------------------------------------------------------------------ * Class Definition * ------------------------------------------------------------------------ */ var Tooltip = /*#__PURE__*/function () { function Tooltip(element, config) { if (typeof Popper === 'undefined') { throw new TypeError('Bootstrap\'s tooltips require Popper.js (https://popper.js.org/)'); } // private this._isEnabled = true; this._timeout = 0; this._hoverState = ''; this._activeTrigger = {}; this._popper = null; // Protected this.element = element; this.config = this._getConfig(config); this.tip = null; this._setListeners(); } // Getters var _proto = Tooltip.prototype; // Public _proto.enable = function enable() { this._isEnabled = true; }; _proto.disable = function disable() { this._isEnabled = false; }; _proto.toggleEnabled = function toggleEnabled() { this._isEnabled = !this._isEnabled; }; _proto.toggle = function toggle(event) { if (!this._isEnabled) { return; } if (event) { var dataKey = this.constructor.DATA_KEY; var context = $(event.currentTarget).data(dataKey); if (!context) { context = new this.constructor(event.currentTarget, this._getDelegateConfig()); $(event.currentTarget).data(dataKey, context); } context._activeTrigger.click = !context._activeTrigger.click; if (context._isWithActiveTrigger()) { context._enter(null, context); } else { context._leave(null, context); } } else { if ($(this.getTipElement()).hasClass(CLASS_NAME_SHOW)) { this._leave(null, this); return; } this._enter(null, this); } }; _proto.dispose = function dispose() { clearTimeout(this._timeout); $.removeData(this.element, this.constructor.DATA_KEY); $(this.element).off(this.constructor.EVENT_KEY); $(this.element).closest('.modal').off('hide.bs.modal', this._hideModalHandler); if (this.tip) { $(this.tip).remove(); } this._isEnabled = null; this._timeout = null; this._hoverState = null; this._activeTrigger = null; if (this._popper) { this._popper.destroy(); } this._popper = null; this.element = null; this.config = null; this.tip = null; }; _proto.show = function show() { var _this = this; if ($(this.element).css('display') === 'none') { throw new Error('Please use show on visible elements'); } var showEvent = $.Event(this.constructor.Event.SHOW); if (this.isWithContent() && this._isEnabled) { $(this.element).trigger(showEvent); var shadowRoot = Util.findShadowRoot(this.element); var isInTheDom = $.contains(shadowRoot !== null ? shadowRoot : this.element.ownerDocument.documentElement, this.element); if (showEvent.isDefaultPrevented() || !isInTheDom) { return; } var tip = this.getTipElement(); var tipId = Util.getUID(this.constructor.NAME); tip.setAttribute('id', tipId); this.element.setAttribute('aria-describedby', tipId); this.setContent(); if (this.config.animation) { $(tip).addClass(CLASS_NAME_FADE); } var placement = typeof this.config.placement === 'function' ? this.config.placement.call(this, tip, this.element) : this.config.placement; var attachment = this._getAttachment(placement); this.addAttachmentClass(attachment); var container = this._getContainer(); $(tip).data(this.constructor.DATA_KEY, this); if (!$.contains(this.element.ownerDocument.documentElement, this.tip)) { $(tip).appendTo(container); } $(this.element).trigger(this.constructor.Event.INSERTED); this._popper = new Popper(this.element, tip, this._getPopperConfig(attachment)); $(tip).addClass(CLASS_NAME_SHOW); // If this is a touch-enabled device we add extra // empty mouseover listeners to the body's immediate children; // only needed because of broken event delegation on iOS // https://www.quirksmode.org/blog/archives/2014/02/mouse_event_bub.html if ('ontouchstart' in document.documentElement) { $(document.body).children().on('mouseover', null, $.noop); } var complete = function complete() { if (_this.config.animation) { _this._fixTransition(); } var prevHoverState = _this._hoverState; _this._hoverState = null; $(_this.element).trigger(_this.constructor.Event.SHOWN); if (prevHoverState === HOVER_STATE_OUT) { _this._leave(null, _this); } }; if ($(this.tip).hasClass(CLASS_NAME_FADE)) { var transitionDuration = Util.getTransitionDurationFromElement(this.tip); $(this.tip).one(Util.TRANSITION_END, complete).emulateTransitionEnd(transitionDuration); } else { complete(); } } }; _proto.hide = function hide(callback) { var _this2 = this; var tip = this.getTipElement(); var hideEvent = $.Event(this.constructor.Event.HIDE); var complete = function complete() { if (_this2._hoverState !== HOVER_STATE_SHOW && tip.parentNode) { tip.parentNode.removeChild(tip); } _this2._cleanTipClass(); _this2.element.removeAttribute('aria-describedby'); $(_this2.element).trigger(_this2.constructor.Event.HIDDEN); if (_this2._popper !== null) { _this2._popper.destroy(); } if (callback) { callback(); } }; $(this.element).trigger(hideEvent); if (hideEvent.isDefaultPrevented()) { return; } $(tip).removeClass(CLASS_NAME_SHOW); // If this is a touch-enabled device we remove the extra // empty mouseover listeners we added for iOS support if ('ontouchstart' in document.documentElement) { $(document.body).children().off('mouseover', null, $.noop); } this._activeTrigger[TRIGGER_CLICK] = false; this._activeTrigger[TRIGGER_FOCUS] = false; this._activeTrigger[TRIGGER_HOVER] = false; if ($(this.tip).hasClass(CLASS_NAME_FADE)) { var transitionDuration = Util.getTransitionDurationFromElement(tip); $(tip).one(Util.TRANSITION_END, complete).emulateTransitionEnd(transitionDuration); } else { complete(); } this._hoverState = ''; }; _proto.update = function update() { if (this._popper !== null) { this._popper.scheduleUpdate(); } } // Protected ; _proto.isWithContent = function isWithContent() { return Boolean(this.getTitle()); }; _proto.addAttachmentClass = function addAttachmentClass(attachment) { $(this.getTipElement()).addClass(CLASS_PREFIX + "-" + attachment); }; _proto.getTipElement = function getTipElement() { this.tip = this.tip || $(this.config.template)[0]; return this.tip; }; _proto.setContent = function setContent() { var tip = this.getTipElement(); this.setElementContent($(tip.querySelectorAll(SELECTOR_TOOLTIP_INNER)), this.getTitle()); $(tip).removeClass(CLASS_NAME_FADE + " " + CLASS_NAME_SHOW); }; _proto.setElementContent = function setElementContent($element, content) { if (typeof content === 'object' && (content.nodeType || content.jquery)) { // Content is a DOM node or a jQuery if (this.config.html) { if (!$(content).parent().is($element)) { $element.empty().append(content); } } else { $element.text($(content).text()); } return; } if (this.config.html) { if (this.config.sanitize) { content = sanitizeHtml(content, this.config.whiteList, this.config.sanitizeFn); } $element.html(content); } else { $element.text(content); } }; _proto.getTitle = function getTitle() { var title = this.element.getAttribute('data-original-title'); if (!title) { title = typeof this.config.title === 'function' ? this.config.title.call(this.element) : this.config.title; } return title; } // Private ; _proto._getPopperConfig = function _getPopperConfig(attachment) { var _this3 = this; var defaultBsConfig = { placement: attachment, modifiers: { offset: this._getOffset(), flip: { behavior: this.config.fallbackPlacement }, arrow: { element: SELECTOR_ARROW }, preventOverflow: { boundariesElement: this.config.boundary } }, onCreate: function onCreate(data) { if (data.originalPlacement !== data.placement) { _this3._handlePopperPlacementChange(data); } }, onUpdate: function onUpdate(data) { return _this3._handlePopperPlacementChange(data); } }; return _objectSpread2(_objectSpread2({}, defaultBsConfig), this.config.popperConfig); }; _proto._getOffset = function _getOffset() { var _this4 = this; var offset = {}; if (typeof this.config.offset === 'function') { offset.fn = function (data) { data.offsets = _objectSpread2(_objectSpread2({}, data.offsets), _this4.config.offset(data.offsets, _this4.element) || {}); return data; }; } else { offset.offset = this.config.offset; } return offset; }; _proto._getContainer = function _getContainer() { if (this.config.container === false) { return document.body; } if (Util.isElement(this.config.container)) { return $(this.config.container); } return $(document).find(this.config.container); }; _proto._getAttachment = function _getAttachment(placement) { return AttachmentMap[placement.toUpperCase()]; }; _proto._setListeners = function _setListeners() { var _this5 = this; var triggers = this.config.trigger.split(' '); triggers.forEach(function (trigger) { if (trigger === 'click') { $(_this5.element).on(_this5.constructor.Event.CLICK, _this5.config.selector, function (event) { return _this5.toggle(event); }); } else if (trigger !== TRIGGER_MANUAL) { var eventIn = trigger === TRIGGER_HOVER ? _this5.constructor.Event.MOUSEENTER : _this5.constructor.Event.FOCUSIN; var eventOut = trigger === TRIGGER_HOVER ? _this5.constructor.Event.MOUSELEAVE : _this5.constructor.Event.FOCUSOUT; $(_this5.element).on(eventIn, _this5.config.selector, function (event) { return _this5._enter(event); }).on(eventOut, _this5.config.selector, function (event) { return _this5._leave(event); }); } }); this._hideModalHandler = function () { if (_this5.element) { _this5.hide(); } }; $(this.element).closest('.modal').on('hide.bs.modal', this._hideModalHandler); if (this.config.selector) { this.config = _objectSpread2(_objectSpread2({}, this.config), {}, { trigger: 'manual', selector: '' }); } else { this._fixTitle(); } }; _proto._fixTitle = function _fixTitle() { var titleType = typeof this.element.getAttribute('data-original-title'); if (this.element.getAttribute('title') || titleType !== 'string') { this.element.setAttribute('data-original-title', this.element.getAttribute('title') || ''); this.element.setAttribute('title', ''); } }; _proto._enter = function _enter(event, context) { var dataKey = this.constructor.DATA_KEY; context = context || $(event.currentTarget).data(dataKey); if (!context) { context = new this.constructor(event.currentTarget, this._getDelegateConfig()); $(event.currentTarget).data(dataKey, context); } if (event) { context._activeTrigger[event.type === 'focusin' ? TRIGGER_FOCUS : TRIGGER_HOVER] = true; } if ($(context.getTipElement()).hasClass(CLASS_NAME_SHOW) || context._hoverState === HOVER_STATE_SHOW) { context._hoverState = HOVER_STATE_SHOW; return; } clearTimeout(context._timeout); context._hoverState = HOVER_STATE_SHOW; if (!context.config.delay || !context.config.delay.show) { context.show(); return; } context._timeout = setTimeout(function () { if (context._hoverState === HOVER_STATE_SHOW) { context.show(); } }, context.config.delay.show); }; _proto._leave = function _leave(event, context) { var dataKey = this.constructor.DATA_KEY; context = context || $(event.currentTarget).data(dataKey); if (!context) { context = new this.constructor(event.currentTarget, this._getDelegateConfig()); $(event.currentTarget).data(dataKey, context); } if (event) { context._activeTrigger[event.type === 'focusout' ? TRIGGER_FOCUS : TRIGGER_HOVER] = false; } if (context._isWithActiveTrigger()) { return; } clearTimeout(context._timeout); context._hoverState = HOVER_STATE_OUT; if (!context.config.delay || !context.config.delay.hide) { context.hide(); return; } context._timeout = setTimeout(function () { if (context._hoverState === HOVER_STATE_OUT) { context.hide(); } }, context.config.delay.hide); }; _proto._isWithActiveTrigger = function _isWithActiveTrigger() { for (var trigger in this._activeTrigger) { if (this._activeTrigger[trigger]) { return true; } } return false; }; _proto._getConfig = function _getConfig(config) { var dataAttributes = $(this.element).data(); Object.keys(dataAttributes).forEach(function (dataAttr) { if (DISALLOWED_ATTRIBUTES.indexOf(dataAttr) !== -1) { delete dataAttributes[dataAttr]; } }); config = _objectSpread2(_objectSpread2(_objectSpread2({}, this.constructor.Default), dataAttributes), typeof config === 'object' && config ? config : {}); if (typeof config.delay === 'number') { config.delay = { show: config.delay, hide: config.delay }; } if (typeof config.title === 'number') { config.title = config.title.toString(); } if (typeof config.content === 'number') { config.content = config.content.toString(); } Util.typeCheckConfig(NAME, config, this.constructor.DefaultType); if (config.sanitize) { config.template = sanitizeHtml(config.template, config.whiteList, config.sanitizeFn); } return config; }; _proto._getDelegateConfig = function _getDelegateConfig() { var config = {}; if (this.config) { for (var key in this.config) { if (this.constructor.Default[key] !== this.config[key]) { config[key] = this.config[key]; } } } return config; }; _proto._cleanTipClass = function _cleanTipClass() { var $tip = $(this.getTipElement()); var tabClass = $tip.attr('class').match(BSCLS_PREFIX_REGEX); if (tabClass !== null && tabClass.length) { $tip.removeClass(tabClass.join('')); } }; _proto._handlePopperPlacementChange = function _handlePopperPlacementChange(popperData) { this.tip = popperData.instance.popper; this._cleanTipClass(); this.addAttachmentClass(this._getAttachment(popperData.placement)); }; _proto._fixTransition = function _fixTransition() { var tip = this.getTipElement(); var initConfigAnimation = this.config.animation; if (tip.getAttribute('x-placement') !== null) { return; } $(tip).removeClass(CLASS_NAME_FADE); this.config.animation = false; this.hide(); this.show(); this.config.animation = initConfigAnimation; } // Static ; Tooltip._jQueryInterface = function _jQueryInterface(config) { return this.each(function () { var data = $(this).data(DATA_KEY); var _config = typeof config === 'object' && config; if (!data && /dispose|hide/.test(config)) { return; } if (!data) { data = new Tooltip(this, _config); $(this).data(DATA_KEY, data); } if (typeof config === 'string') { if (typeof data[config] === 'undefined') { throw new TypeError("No method named \"" + config + "\""); } data[config](); } }); }; _createClass(Tooltip, null, [{ key: "VERSION", get: function get() { return VERSION; } }, { key: "Default", get: function get() { return Default; } }, { key: "NAME", get: function get() { return NAME; } }, { key: "DATA_KEY", get: function get() { return DATA_KEY; } }, { key: "Event", get: function get() { return Event; } }, { key: "EVENT_KEY", get: function get() { return EVENT_KEY; } }, { key: "DefaultType", get: function get() { return DefaultType; } }]); return Tooltip; }(); /** * ------------------------------------------------------------------------ * jQuery * ------------------------------------------------------------------------ */ $.fn[NAME] = Tooltip._jQueryInterface; $.fn[NAME].Constructor = Tooltip; $.fn[NAME].noConflict = function () { $.fn[NAME] = JQUERY_NO_CONFLICT; return Tooltip._jQueryInterface; }; return Tooltip; }))); /** * CatRename * * Ajoute un onglet permettant de renommer une catégorie, en déplaçant les pages * incluses dans celle-ci. Permet de faire faire l'action à un bot en un clic. * * {{Projet:JavaScript/Script|CatRename}} */ /* <nowiki> */ /* globals mw, OO, $ */ if ( mw.config.get( 'wgNamespaceNumber' ) === 14 ) { mw.loader.using( 'mediawiki.util', function () { 'use strict'; // Site-related parameters const TAG = 'RenommageCategorie'; const DAILY_LIMIT = 250; const RBOT_PAGE = 'Wikipédia:Bot/Requêtes/Catégories'; const DR_TEMPLATE = '{{Suppression Immédiate|raison=Catégorie récemment renommée en [[:Catégorie:$2]] ($3)|utilisateur=$4}}\n\n'; const RBOT_TEMPLATE = '\n{{Déplacement catégorie|ancienne=$1|nouvelle=$2|raison=$3|demandeur=$4}}'; // Literal non-breaking space, for situations where HTML entities can't be used const NBSP = String.fromCharCode( 0xA0 ); // Messages const messages = { 'fr': { 'catrename-title': 'Renommer une catégorie', 'catrename-portlet-title': 'CatRename', 'catrename-action-rename': 'Renommer', 'catrename-action-cancel': 'Annuler', 'catrename-action-rbot': '… ou faire faire la tâche par un bot', 'catrename-checkbox-movetalk': 'Renommer aussi la page de discussion associée', 'catrename-checkbox-leave-redirect': 'Laisser une redirection vers le nouveau titre', 'catrename-checkbox-post-dr': 'Déposer une demande de suppression de l\'ancienne catégorie', 'catrename-checkbox-watch': 'Suivre les catégories originale et nouvelle', 'catrename-checkbox-watch-members': 'Suivre les pages modifiées', 'catrename-field-title': 'Nouveau titre' + NBSP + ':', 'catrename-field-reason': 'Motif' + NBSP + ':', 'catrename-summary': 'Remplacement de la catégorie [[Catégorie:$1]] par [[Catégorie:$2]] : $3', 'catrename-dr-summary': 'Demande de suppression après renommage', 'catrename-rbot-summary': 'RBOT : Demande de renommage de catégorie', 'catrename-status-checkcategory': 'Vérification de la catégorie cible', 'catrename-status-getmembers': 'Récupération des pages membres de la catégorie', 'catrename-status-waitinglock': 'En attente de la fin de renommage dans d\'autres onglets', 'catrename-status-checklimits': 'Vérification de la limite journalière', 'catrename-status-editmembers': 'Modification de la page $1 sur $2', 'catrename-status-renamecategory': 'Renommage de la catégorie', 'catrename-status-postdr': 'Dépôt de la demande de suppression', 'catrename-status-postrbot': 'Dépôt de la requête aux bots', 'catrename-error-canceled': 'Le processus de renommage a été annulé.', 'catrename-error-same': 'Le nouveau titre est identique au titre actuel.', 'catrename-error-invalidtitle': 'Le titre de la catégorie demandée est non valide, vide, ou mal formé.', 'catrename-error-noreason': 'Veuillez indiquer un motif pour ce renommage.', 'catrename-error-protected': 'Cette catégorie est protégée, vous n\'êtes pas autorisé à la renommer.', 'catrename-error-categoryexist': 'Il existe déjà une catégorie avec ce nom…', 'catrename-error-limitreached': 'Le renommage de cette catégorie vous ferait faire plus de $1 modifications avec ce script en moins de 24h. Vous pouvez cependant faire une requête aux bots via le bouton en bas à gauche.', 'catrename-error-categorypresent': 'La page contient déjà la nouvelle catégorie.', 'catrename-error-notfound': 'La catégorie n\'a pas été trouvée dans le code de la page, peut-être est-elle incluse via un modèle' + NBSP + '?', 'catrename-error-pageprotected': 'La page est protégée en écriture.', 'catrename-error-articleexists': 'Impossible de déplacer la catégorie, la page de destination «' + NBSP + '$1' + NBSP + '» existe déjà.', } }; mw.messages.set( messages.fr ); var lang = mw.config.get( 'wgUserLanguage' ); if ( lang !== 'fr' && lang in messages ) { mw.messages.set( messages[ lang ] ); } var isBootstrapped = false; var instanceWindowManager; var instanceCatRename; $( function ( $ ) { var portlet = mw.util.addPortletLink( 'p-cactions', '#', mw.msg( 'catrename-portlet-title' ) ); $( portlet ).on( 'click', function ( e ) { e.preventDefault(); mw.loader.using( [ 'oojs-ui', 'mediawiki.storage', 'mediawiki.api' ], function () { bootstrapOnce(); instanceCatRename.open(); } ); } ); } ); /* Instanciate CatRename and add it to MediaWiki's UI. */ function bootstrapOnce() { if (isBootstrapped) { return; } isBootstrapped = true; /** * Main class of the gadget CatRename, which is displayed as a ProcessDialog * * @class * @extends OO.ui.ProcessDialog * * @constructor */ var CatRename = function () { // Initialize config var config = { size: 'medium' }; // Parent constructor CatRename.parent.call( this, config ); // Properties this.api = new mw.Api( { timeout: 7000 } ); this.oldTitle; this.newTitle; this.oldPageName; this.newPageName; this.reason; this.deferred; this.members; this.lockID; this.nextTab; this.noSpammingDelay; // Graphical properties this.configContent = new OO.ui.PanelLayout( { padded: true, expanded: false } ); this.statusContent = new OO.ui.PanelLayout( { padded: true, expanded: false } ); this.newNameInput; this.reasonInput; this.optionCheckboxes; this.layout; this.$body; this.statusIndicator; this.pagesInError; }; /* Setup */ OO.inheritClass( CatRename, OO.ui.ProcessDialog ); /* Static Properties */ CatRename.static.name = 'catrename'; CatRename.static.title = mw.msg( 'catrename-title' ); CatRename.static.actions = [ { action: 'rename', label: mw.msg( 'catrename-action-rename' ), flags: [ 'primary', 'progressive' ] }, { action: 'cancel', label: mw.msg( 'catrename-action-cancel' ), flags: [ 'safe', 'back' ] }, { action: 'rbot', label: mw.msg( 'catrename-action-rbot' ), flags: 'other' } ]; /* ProcessDialog-related Methods */ /** * Build the interface displayed inside the ProcessDialog box. */ CatRename.prototype.initialize = function () { CatRename.parent.prototype.initialize.apply( this, arguments ); this.newNameInput = new OO.ui.TextInputWidget( { value: mw.config.get( 'wgTitle' ) } ); this.reasonInput = new OO.ui.TextInputWidget( { maxLength: 500, name: 'wpSummary' } ); this.optionCheckboxes = new OO.ui.CheckboxMultiselectInputWidget( { value: [ 'movetalk', 'post-dr' ], options: [ { data: 'movetalk', label: mw.msg( 'catrename-checkbox-movetalk' ) }, ( this.userInGroup( 'sysop' ) || this.userInGroup( 'bot' ) ? { data: 'leave-redirect', label: mw.msg( 'catrename-checkbox-leave-redirect' ) } : { data: 'post-dr', label: mw.msg( 'catrename-checkbox-post-dr' ) } ), { data: 'watch', label: mw.msg( 'catrename-checkbox-watch' ) }, { data: 'watch-members', label: mw.msg( 'catrename-checkbox-watch-members' ) } ] } ); this.layout = new OO.ui.Widget( { content: [ new OO.ui.FieldLayout( this.newNameInput, { align: 'top', label: mw.msg( 'catrename-field-title' ), } ), new OO.ui.FieldLayout( this.reasonInput, { align: 'top', label: mw.msg( 'catrename-field-reason' ), } ), new OO.ui.FieldLayout( this.optionCheckboxes, {} ) ], } ); this.configContent.$element.append( this.layout.$element ); this.$body.append( this.configContent.$element ); this.statusIndicator = $( '<h3>' ) .css( 'text-align', 'center' ) .css( 'margin-top', '1em' ) .css( 'margin-bottom', '2em' ); this.pagesInError = $( '<ul>' ); this.statusContent.$element.append( this.statusIndicator ).append( this.pagesInError ); this.setSize( this.size ); this.updateSize(); }; /** * Get a process for taking action. * * This method is called within the ProcessDialog when the user clicks * on an action button (the one defined in CatRename.static.actions). * Here is defined in which order each method of the category moving * process is called. * @param {string} action Name of the action button clicked. * @return {OO.ui.Process} Action process. */ CatRename.prototype.getActionProcess = function ( action ) { var process = new OO.ui.Process(), options = this.optionCheckboxes.getValue(); if ( action === 'cancel' || action === '' ) { // empty string when closing with Escape key return process.next( this.unlockMultitabs, this ) .next( this.closeDialog, this ); } else if ( action === 'rename' ) { process.next( this.prepare, this ) .next( this.checkCategory, this ) .next( this.getMembers, this ) .next( this.lockMultitabs, this ) .next( this.checkLimits, this ) .next( this.editMembers, this ) .next( this.renameCategory, this ); } else if ( action === 'rbot' ) { process.next( this.prepare, this ) .next( this.checkCategory, this ) .next( this.getMembers, this ) .next( this.postRBot, this ) .next( this.renameCategory, this ); } if ( options.indexOf( 'post-dr' ) > -1 ) { process.next( this.postDR, this ); } process.next( this.unlockMultitabs, this ) .next( this.success, this ) .next( this.closeDialog, this ); return process; }; /** * Close the window. * * @return {jQuery.Promise} Promise resolved when window is closed */ CatRename.prototype.closeDialog = function () { var dialog = this; var lifecycle = dialog.close(); return lifecycle.closed; }; /** * Get the height of the window body. * Used by the ProcessDialog to set an accurate height to the dialog. * * @return {number} Height in px the dialog should be. */ CatRename.prototype.getBodyHeight = function () { return this.configContent.$element.outerHeight( true ); }; /* Process step methods */ /** * Fetch and validate user's input to make it easily accessible later. * * @return {undefined|OO.ui.Error} Error message for the ProcessDialog * to display, if any. */ CatRename.prototype.prepare = function () { var dialog = this; this.oldTitle = mw.config.get( 'wgTitle' ); this.newTitle = this.newNameInput.getValue().trim().replace(/^([Cc]atégorie|[Cc]ategory):/, ''); this.reason = this.reasonInput.getValue().trim(); if ( mw.config.get( 'wgCaseSensitiveNamespaces' ).indexOf( 14 ) === -1 ) { this.newTitle = this.newTitle.charAt( 0 ).toUpperCase() + this.newTitle.slice( 1 ); } if ( this.newTitle === this.oldTitle ) { return new OO.ui.Error( mw.msg( 'catrename-error-same' ) ); } if ( mw.Title.makeTitle( 14, this.newTitle ) === null ) { return new OO.ui.Error( mw.msg( 'catrename-error-invalidtitle' ) ); } if ( this.reason === '' ) { return new OO.ui.Error( mw.msg( 'catrename-error-noreason' ) ); } this.oldPageName = mw.config.get('wgFormattedNamespaces')[ 14 ] + ':' + this.oldTitle; this.newPageName = mw.config.get('wgFormattedNamespaces')[ 14 ] + ':' + this.newTitle; // Disable actions button when a process is runing this.getActions().get( { actions: 'rename' } )[ 0 ].setDisabled( true ); this.getActions().get( { actions: 'rbot' } )[ 0 ].setDisabled( true ); // Except for the cancel button, which behaviour change to cancel the ongoing process this.getActions().get( { actions: 'cancel' } )[ 0 ].on( 'click', function () { dialog.errorHandler( mw.msg( 'catrename-error-canceled' ) ); } ); return; }; /** * Check if it is technically possible to move the category. * * Two main checks are performed: * * Has the user the right to move the category according to the * protection level? * * Is the target title free? * @return {JQuery.Deferred} Promise telling to continue the process if * successful or stopping the process if rejected. */ CatRename.prototype.checkCategory = function () { var dialog = this; this.deferred = $.Deferred(); this.showStatus( mw.msg( 'catrename-status-checkcategory' ) ); var restrictionMove = mw.config.get( 'wgRestrictionMove' ); for ( var i = 0; i < restrictionMove.length; i++ ) { if ( ! this.userInGroup( restrictionMove[ i ] ) ) { this.errorHandler( mw.msg( 'catrename-error-protected' ) ); return this.deferred; } } this.api.get( { 'action': 'query', 'format': 'json', 'formatversion': 2, 'prop': 'categoryinfo', 'titles': this.newPageName } ).then( function ( data ) { if ( data.query.pages[ 0 ].missing !== true ) { //TODO: Allow user to move pages without renaming the cat dialog.errorHandler( mw.msg( 'catrename-error-categoryexist' ) ); return; } dialog.deferred.resolve(); } ).fail( function ( error ) { dialog.errorHandler( error ); } ); return this.deferred; }; /** * Get all pages, files and sub-categories in the source category. * * This method populates the attribute 'members'. * @return {JQuery.Deferred} Promise telling to continue the process if * successful or stopping the process if rejected. */ CatRename.prototype.getMembers = function () { var dialog = this; this.deferred = $.Deferred(); this.members = []; this.showStatus( mw.msg( 'catrename-status-getmembers' ) ); function doGetMembers( paramsContinue ) { var params = { 'action': 'query', 'format': 'json', 'list': 'categorymembers', 'formatversion': '2', 'cmtitle': mw.config.get( 'wgPageName' ), 'cmprop': 'title', 'cmlimit': 'max', }; if ( paramsContinue ) { $.extend( params, paramsContinue ); } dialog.api.get( params ).then( function ( data ) { var categoryMembers = data.query.categorymembers; for ( var i = 0; i < categoryMembers.length; i++ ) { dialog.members.push( categoryMembers[ i ].title ); } if ( data[ 'continue' ] ) { doGetMembers( data[ 'continue' ] ); } else { dialog.deferred.resolve(); } } ).fail( function ( error ) { dialog.errorHandler( error ); } ); } doGetMembers(); return this.deferred; }; /** * Lock the process while other instances of CatRename are running. * * This method acts a bit like the POSIX sem_wait. * @return {JQuery.Deferred} Promise telling to continue the process * when it is its turn to execute. */ CatRename.prototype.lockMultitabs = function () { var dialog = this; this.deferred = $.Deferred(); if ( this.userInGroup( 'bot' ) ) { return; } this.lockID = 'catrename-' + this.randomString( 16 ); this.nextTab = null; this.showStatus( mw.msg( 'catrename-status-waitinglock' ) ); //TODO: check lock timestamp if ( mw.storage.get( 'catrename-lock' ) === null ) { mw.storage.set( 'catrename-lock', this.lockID ); this.deferred.resolve(); } else { $( window ).on( 'storage.catrename.catrename-waiting', function ( event ) { if ( event.originalEvent.key === 'catrename-lock' && event.originalEvent.newValue === dialog.lockID ) { $( window ).off( 'storage.catrename-waiting' ); dialog.deferred.resolve(); } } ); mw.storage.set( 'catrename-addtab', this.lockID ); } $( window ).on( 'storage.catrename', function ( event ) { // if this tab has no successor and a new one appears, add it as our successor if ( dialog.nextTab === null && event.originalEvent.key === 'catrename-addtab' && event.originalEvent.newValue !== null ) { dialog.nextTab = event.originalEvent.newValue; mw.storage.set( dialog.lockID, dialog.nextTab ); } // if our successor decides to leave, remove it and take its successor else if ( dialog.nextTab !== null && event.originalEvent.key === 'catrename-removetab' && event.originalEvent.newValue === dialog.nextTab ) { dialog.nextTab = mw.storage.get( dialog.nextTab ); if ( dialog.nextTab !== null ) { mw.storage.set( dialog.lockID, dialog.nextTab ); } else { mw.storage.remove( dialog.lockID ); } } } ); window.addEventListener( 'unload', function (e) { dialog.unlockMultitabs(); } ); return this.deferred; }; /** * Check if the daily limit of edits using this script would be reached * if the move is performed. * * In fact, we are not looking realy on a daily basis, but a 24h rolling * period. * @return {JQuery.Deferred} Promise telling to continue the process * when it is its turn to execute. */ CatRename.prototype.checkLimits = function () { var dialog = this; this.deferred = $.Deferred(); var yesterday = new Date(); yesterday.setDate( yesterday.getDate() - 1 ); if ( this.userInGroup( 'bot' ) ) { this.noSpammingDelay = 0; return; } this.noSpammingDelay = 5000; if ( this.members.length > 50 ) { this.noSpammingDelay = 20000; } else if ( this.members.length > 10 ) { this.noSpammingDelay = 10000; } this.showStatus( mw.msg( 'catrename-status-checklimits' ) ); this.api.get( { 'action': 'query', 'format': 'json', 'list': 'usercontribs', 'formatversion': '2', 'uclimit': 'max', // only query DAILY_LIMIT results ? 'ucend': yesterday.toISOString(), 'ucuser': mw.config.get( 'wgUserName' ), 'ucprop': 'timestamp', 'uctag': TAG } ).then( function ( data ) { if ( data.query.usercontribs.length + dialog.members.length >= DAILY_LIMIT ) { dialog.errorHandler( mw.msg( 'catrename-error-limitreached', DAILY_LIMIT ), false ); } else { dialog.deferred.resolve(); } } ).fail( function ( error ) { dialog.errorHandler( error ); } ); return this.deferred; }; /** * Try to move all the pages inside the 'members' attribute from the old * to the new category name by fetching and editing their wikicode. * * @return {JQuery.Deferred} Promise telling to continue the process * when it is its turn to execute. */ CatRename.prototype.editMembers = function () { var dialog = this, totalPages = this.members.length, oldCatRegex = this.buildRegex( this.oldTitle ), newCatRegex = this.buildRegex( this.newTitle ), summary = mw.msg( 'catrename-summary', this.oldTitle, this.newTitle, this.reason ), commonPayload = { summary: summary, minor: true, tags: TAG }; this.deferred = $.Deferred(); if ( this.userInGroup( 'bot' ) ) { commonPayload[ 'bot' ] = 1; } if ( this.optionCheckboxes.getValue().indexOf( 'watch-members' ) > -1 ) { commonPayload[ 'watchlist' ] = 'watch'; } function doEdit() { var member = dialog.members.pop(); if ( dialog.deferred.state() !== 'pending' ) { return; } if ( member === undefined ) { dialog.deferred.resolve(); return; } //TODO: a progress-bar ? dialog.showStatus( mw.msg( 'catrename-status-editmembers', totalPages - dialog.members.length, totalPages ) ); dialog.api.edit( member, function ( revision ) { var content = revision.content, newCatInPageList = content.match( newCatRegex ); if ( newCatInPageList !== null ) { dialog.logFailedPages( member, mw.msg( 'catrename-error-categorypresent' ) ); } else { content = content.replace( oldCatRegex, '$1[[' + dialog.newPageName + '$6]]' ); } return $.extend( { text: content }, commonPayload ); } ) .then( function ( result ) { if ( result.nochange === true ) { dialog.logFailedPages( member, mw.msg( 'catrename-error-notfound' ) ); } setTimeout( doEdit, dialog.noSpammingDelay ); } ) .fail( function ( code, data ) { if ( code === 'protectedpage' ) { dialog.logFailedPages( member, mw.msg( 'catrename-error-pageprotected' ) ); doEdit(); } else { dialog.errorHandler( code ); } } ); } doEdit(); return this.deferred; }; /** * Move the category itself. * * @return {JQuery.Deferred} Promise telling to continue the process * when it is its turn to execute. */ CatRename.prototype.renameCategory = function () { var dialog = this; this.deferred = $.Deferred(); this.showStatus( mw.msg( 'catrename-status-renamecategory' ) ); var payload = { 'action': 'move', 'format': 'json', 'from': mw.config.get( 'wgPageName' ), 'to': this.newPageName, 'reason': this.reason, 'tags': TAG, 'formatversion': '2' }; var options = this.optionCheckboxes.getValue(); if ( options.indexOf( 'movetalk' ) > -1 ) { payload[ 'movetalk' ] = 1; } if ( options.indexOf( 'watch' ) > -1 ) { payload[ 'watchlist' ] = 'watch'; } if ( this.userInGroup( 'sysop' ) || this.userInGroup( 'bot' ) ) { if ( options.indexOf( 'leave-redirect' ) === -1 ) { payload[ 'noredirect' ] = 1; } } this.api.postWithToken( 'csrf', payload ).then( function ( data ) { dialog.deferred.resolve(); } ).fail( function ( error ) { if ( error === 'articleexists' ) { dialog.errorHandler( mw.msg( 'catrename-error-articleexists', dialog.newPageName ) ); } else { dialog.errorHandler( error ); } } ); return this.deferred; }; /** * Post a deletion request. * * @return {JQuery.Deferred} Promise telling to continue the process * when it is its turn to execute. */ CatRename.prototype.postDR = function () { var dialog = this; this.deferred = $.Deferred(); this.showStatus( mw.msg( 'catrename-status-postdr' ) ); var content = DR_TEMPLATE .replace( /\$1/g, this.oldTitle ) .replace( /\$2/g, this.newTitle ) .replace( /\$3/g, this.reason ) .replace( /\$4/g, mw.config.get( 'wgUserName' ) ); this.api.postWithToken( 'csrf', { 'action': 'edit', 'format': 'json', 'title': this.oldPageName, 'summary': mw.msg( 'catrename-dr-summary' ), 'tags': TAG, 'nocreate': 1, 'prependtext': content, 'formatversion': '2' } ).then( function ( data ) { dialog.deferred.resolve(); } ).fail( function ( error ) { dialog.errorHandler( error ); } ); return this.deferred; }; /** * Post a move request for the bots. * * @return {JQuery.Deferred} Promise telling to continue the process * when it is its turn to execute. */ CatRename.prototype.postRBot = function () { var dialog = this; this.deferred = $.Deferred(); this.showStatus( mw.msg( 'catrename-status-postrbot' ) ); var content = RBOT_TEMPLATE .replace( /\$1/g, this.oldTitle ) .replace( /\$2/g, this.newTitle ) .replace( /\$3/g, this.reason ) .replace( /\$4/g, mw.config.get( 'wgUserName' ) ); this.api.postWithToken( 'csrf', { 'action': 'edit', 'format': 'json', 'title': RBOT_PAGE, 'summary': mw.msg( 'catrename-rbot-summary' ), 'tags': TAG, 'nocreate': 1, 'appendtext': content, 'formatversion': '2' } ).then( function ( data ) { dialog.deferred.resolve(); } ).fail( function ( error ) { dialog.errorHandler( error ); } ); return this.deferred; }; /** * Release the lock to allow other instances of CatRename to execute. * * This method acts a bit like the POSIX sem_post. */ CatRename.prototype.unlockMultitabs = function () { if ( this.lockID !== undefined ) { $( window ).off( 'storage.catrename' ); mw.storage.set( 'catrename-removetab', this.lockID ); //Inform other tabs that we're closing mw.storage.remove( this.lockID ); //Clean up our mess from the localStorage // wake up the next tab, or reset if there is none if ( mw.storage.get( 'catrename-lock' ) === this.lockID ) { if ( this.nextTab !== null ) { mw.storage.set( 'catrename-lock', this.nextTab ); } else { mw.storage.remove( 'catrename-lock' ); } } delete this.lockID; } }; /** * Method called when all has gone well (yeah !). */ CatRename.prototype.success = function () { var dialog = this; setTimeout( function () { window.location = mw.util.getUrl( dialog.newPageName ); }, 1000 ); }; /* Helper Methods */ /** * Get information about the current user's groups. * * @param {string} groupName Name of the group to check. * @return {boolean} Whether the current user is in the given group. */ CatRename.prototype.userInGroup = function ( groupName ) { return ( mw.config.get( 'wgUserGroups' ).indexOf( groupName ) > -1 ); }; /** * Display a status message inside the main content of the dialog. * * @return {string} Status message to display. */ CatRename.prototype.showStatus = function ( status ) { this.statusIndicator.text( status ); this.$body.children().detach(); this.$body.append( this.statusContent.$element ); }; /** * Raise an error using OO.ui.Error, and reset all what should be. * * @param {string} error Error message to display to the user. * @param {boolean} recoverable Is the error recoverable (default to true). * @param {boolean} warning Should we raise a warning instead an error (default to false). */ CatRename.prototype.errorHandler = function ( error, recoverable, warning ) { var errorMessage = new OO.ui.Error( error, { recoverable: recoverable || true, warning: warning || false } ); this.unlockMultitabs(); this.$body.children().detach(); this.$body.append( this.configContent.$element ); this.getActions().get( { actions: 'rename' } )[ 0 ].setDisabled( false ); this.getActions().get( { actions: 'rbot' } )[ 0 ].setDisabled( false ); this.deferred.reject( errorMessage ); }; /** * Add a page to the error log. * * @param {string} pageName Name (including namespace) of the page. * @param {string} reason Explaination of the error. */ CatRename.prototype.logFailedPages = function ( pageName, reason ) { var li = $( '<li>' ).text( ' - ' + reason ), a = $( '<a>' ).attr( 'href', mw.util.getUrl( pageName ) ).text( pageName ); this.pagesInError.append( li.prepend( a ) ); }; /** * Build a regex to extract the link to a given category from wikicode. * * @param {string} category Name (without namespace) of the category. * @return {RegExp} Regex object to extract the given category. */ CatRename.prototype.buildRegex = function ( category ) { var formattedNamespace = mw.config.get( 'wgFormattedNamespaces' )[ 14 ], isFirstLetterCaseSensitive = ( mw.config.get( 'wgCaseSensitiveNamespaces' ).indexOf( 14 ) > -1 ), namespace = '(?:[' + formattedNamespace.charAt( 0 ) + formattedNamespace.charAt( 0 ).toLowerCase() + ']' + formattedNamespace.slice( 1 ) + '|[Cc]ategory)'; category = category.replace( /([\\\^\$\*\+\?\.\|\{\}\[\]\(\)])/g, '\\$1' ); if ( ! isFirstLetterCaseSensitive ) { var firstLetter = category.charAt(0); if ( firstLetter.toUpperCase() !== firstLetter.toLowerCase() ) { category = '[' + firstLetter.toUpperCase() + firstLetter.toLowerCase() + ']' + category.slice(1); } } return new RegExp('(\\s*)\\[\\[( |_)*' + namespace + '( |_)*:( |_)*' + category + '( |_)*(\\|[^\\]]*)?\\]\\]', 'g'); }; /** * Generate a random string. * * @param {number} length Length of the string to generate. * @return {string} The generated string. */ CatRename.prototype.randomString = function ( length ) { var result = ''; var chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'; for ( var i = 0; i < length; ++i ) { result += chars.charAt( Math.floor( Math.random() * chars.length ) ); } return result; }; instanceWindowManager = new OO.ui.WindowManager(); $( 'body' ).append( instanceWindowManager.$element ); instanceCatRename = new CatRename(); instanceWindowManager.addWindows( [ instanceCatRename ] ); } } ); } /* </nowiki> */ var navHeight = $('#esp-navbar ul').height(); var $nav = $('#esp-navbar'); $('#navbar-toggler').click(function(e) { if (!$nav.hasClass('open')) { $nav.css('height', navHeight + 'px'); } else { $nav.css('height', ''); } $nav.toggleClass('open'); }); $('.timeline-wrapper').on('mousedown touchstart', function (me) { if ($(me.target).hasClass('timeline-desc')) return; var move = $(this).find('ul'); var lastOffset = move.data('lastTransform'); var lastOffsetX = lastOffset ? lastOffset.dx : 0; var pageX = me.originalEvent.touches ? me.originalEvent.touches[0].pageX : me.pageX; var startX = pageX - lastOffsetX; $(document).on('mousemove touchmove', function (e) { var newX = e.originalEvent.touches ? e.originalEvent.touches[0].pageX : e.pageX; var max = $(move).attr('data-maxtranslate'); if (max > 0) max = 0; var newDx = Math.max(Math.min(0, newX - startX), max); move.css('transform', 'translate(' + newDx + 'px)'); move.data('lastTransform', { dx: newDx }); }); }); $(document).on('mouseup touchend', function () { $(this).off('mousemove touchmove'); }); $('.timeline-wrapper').each(function () { var maxTranslate = ($(this).find('li').length * 200 - $(this).width()) * - 1; $(this).find('ul').attr('data-maxTranslate', maxTranslate); var desc = $('<div>', { 'class': 'timeline-desc' }); $(this).append(desc); $(this).find('.event').on('click touch', function () { $('.event.active').removeClass('active'); $(this).addClass('active'); desc.html($(this).find('.description').html()); }); $(this).find('li:first-of-type .event').click(); });