mirror of
https://gerrit.wikimedia.org/r/mediawiki/extensions/Popups
synced 2024-11-24 23:46:21 +00:00
938a4b85d4
The "checkin" part of the Popups schema was superseded by the ReadingDepth schema, the implementation of which is tracked by T155639. As well as removing all checkin-related code, update the Popups schema to the latest version - the version that doesn't have the checkin property. Bug: T155639 Depends-On: I762ec3fc91decf3cffa869dbd783faf62f01329a Change-Id: If764917b6e121e1f9db980a4efa30c0f7a166197
1 line
151 KiB
Plaintext
1 line
151 KiB
Plaintext
{"version":3,"sources":["/w/extensions/Popups/webpack/bootstrap 94af4e96e5ae8032d502","/w/extensions/Popups/./src/index.js","/w/extensions/Popups/./~/redux/lib/index.js","/w/extensions/Popups/./~/process/browser.js","/w/extensions/Popups/./~/redux/lib/createStore.js","/w/extensions/Popups/./~/redux/~/lodash/isPlainObject.js","/w/extensions/Popups/./~/redux/~/lodash/_baseGetTag.js","/w/extensions/Popups/./~/redux/~/lodash/_Symbol.js","/w/extensions/Popups/./~/redux/~/lodash/_root.js","/w/extensions/Popups/./~/redux/~/lodash/_freeGlobal.js","/w/extensions/Popups/./~/redux/~/lodash/_getRawTag.js","/w/extensions/Popups/./~/redux/~/lodash/_objectToString.js","/w/extensions/Popups/./~/redux/~/lodash/_getPrototype.js","/w/extensions/Popups/./~/redux/~/lodash/_overArg.js","/w/extensions/Popups/./~/redux/~/lodash/isObjectLike.js","/w/extensions/Popups/./~/symbol-observable/index.js","/w/extensions/Popups/./~/symbol-observable/lib/index.js","/w/extensions/Popups/(webpack)/buildin/module.js","/w/extensions/Popups/./~/symbol-observable/lib/ponyfill.js","/w/extensions/Popups/./~/redux/lib/combineReducers.js","/w/extensions/Popups/./~/redux/lib/utils/warning.js","/w/extensions/Popups/./~/redux/lib/bindActionCreators.js","/w/extensions/Popups/./~/redux/lib/applyMiddleware.js","/w/extensions/Popups/./~/redux/lib/compose.js","/w/extensions/Popups/./~/redux-thunk/lib/index.js","/w/extensions/Popups/./src/constants.js","/w/extensions/Popups/./src/gateway/rest.js","/w/extensions/Popups/./src/preview/model.js","/w/extensions/Popups/./src/gateway/mediawiki.js","/w/extensions/Popups/./src/userSettings.js","/w/extensions/Popups/./src/previewBehavior.js","/w/extensions/Popups/./src/schema.js","/w/extensions/Popups/./src/settingsDialog.js","/w/extensions/Popups/./src/changeListener.js","/w/extensions/Popups/./src/isEnabled.js","/w/extensions/Popups/./src/processLinks.js","/w/extensions/Popups/./src/renderer.js","/w/extensions/Popups/./src/wait.js","/w/extensions/Popups/./src/changeListeners/index.js","/w/extensions/Popups/./src/changeListeners/footerLink.js","/w/extensions/Popups/./src/changeListeners/eventLogging.js","/w/extensions/Popups/./src/changeListeners/linkTitle.js","/w/extensions/Popups/./src/changeListeners/render.js","/w/extensions/Popups/./src/changeListeners/settings.js","/w/extensions/Popups/./src/changeListeners/syncUserSettings.js","/w/extensions/Popups/./src/actions.js","/w/extensions/Popups/./src/actionTypes.js","/w/extensions/Popups/./src/reducers/index.js","/w/extensions/Popups/./src/reducers/eventLogging.js","/w/extensions/Popups/./src/reducers/nextState.js","/w/extensions/Popups/./src/counts.js","/w/extensions/Popups/./src/reducers/preview.js","/w/extensions/Popups/./src/reducers/settings.js","/w/extensions/Popups/./src/popups.js","/w/extensions/Popups/./src/gateway/index.js","/w/extensions/Popups/./src/preview/index.js"],"names":[],"mappings":";AAAA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA,uBAAe;AACf;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;;AAGA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;;;;;;;ACtCA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,YAAW,OAAO;AAClB,aAAY;AACZ;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,YAAW,YAAY;AACvB,YAAW,OAAO;AAClB,YAAW,mBAAmB;AAC9B,YAAW,wBAAwB;AACnC,YAAW,SAAS;AACpB,YAAW,2BAA2B;AACtC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,YAAW,YAAY;AACvB,aAAY;AACZ;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,aAAY;AACZ;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA,KAAI;AACJ;AACA;AACA,KAAI;AACJ;AACA;AACA,KAAI;;AAEJ,GAAE;AACF,EAAC;;AAED;AACA;AACA;AACA;;;;;;;ACvKA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,uCAAsC,uCAAuC,kBAAkB;;AAE/F;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,wC;;;;;;;AC7CA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA,MAAK;AACL;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA,MAAK;AACL;AACA;AACA,EAAC;AACD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;AACL;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;;;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;AACL;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;AACA;;;;AAIA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;AACL;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,wBAAuB,sBAAsB;AAC7C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,sBAAqB;AACrB;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA,4BAA2B;AAC3B;AACA;AACA;AACA,6BAA4B,UAAU;;;;;;;ACnLtC;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,uCAAsC,uCAAuC,kBAAkB;;AAE/F;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW,SAAS;AACpB;AACA;AACA,YAAW,IAAI;AACf;AACA;AACA;AACA;AACA;AACA,YAAW,SAAS;AACpB;AACA;AACA;AACA;AACA,cAAa,MAAM;AACnB;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,gBAAe,IAAI;AACnB;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAa,SAAS;AACtB,gBAAe,SAAS;AACxB;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAa,OAAO;AACpB;AACA;AACA;AACA;AACA;AACA,gBAAe,OAAO;AACtB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA,MAAK;AACL;AACA;;AAEA;AACA,oBAAmB,sBAAsB;AACzC;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAa,SAAS;AACtB,gBAAe;AACf;AACA;AACA;AACA;AACA;;AAEA;AACA,eAAc,yBAAyB;AACvC;;AAEA;AACA;AACA,gBAAe,WAAW;AAC1B;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,kBAAiB,OAAO;AACxB;AACA,oBAAmB,aAAa;AAChC;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,iBAAgB;AAChB;AACA,MAAK;AACL;AACA,MAAK;AACL;;AAEA;AACA;AACA;AACA,aAAY,yBAAyB;;AAErC;AACA;AACA;AACA;AACA;AACA,IAAG;AACH,E;;;;;;ACpQA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW,EAAE;AACb,cAAa,QAAQ;AACrB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,qBAAoB,iBAAiB;AACrC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;;;;;;AC7DA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA,YAAW,EAAE;AACb,cAAa,OAAO;AACpB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;;;;;;AC3BA;;AAEA;AACA;;AAEA;;;;;;;ACLA;;AAEA;AACA;;AAEA;AACA;;AAEA;;;;;;;ACRA;AACA;;AAEA;;;;;;;;ACHA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA,YAAW,EAAE;AACb,cAAa,OAAO;AACpB;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,IAAG;;AAEH;AACA;AACA;AACA;AACA,MAAK;AACL;AACA;AACA;AACA;AACA;;AAEA;;;;;;;AC7CA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,YAAW,EAAE;AACb,cAAa,OAAO;AACpB;AACA;AACA;AACA;;AAEA;;;;;;;ACrBA;;AAEA;AACA;;AAEA;;;;;;;ACLA;AACA;AACA;AACA;AACA,YAAW,SAAS;AACpB,YAAW,SAAS;AACpB,cAAa,SAAS;AACtB;AACA;AACA;AACA;AACA;AACA;;AAEA;;;;;;;ACdA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW,EAAE;AACb,cAAa,QAAQ;AACrB;AACA;AACA,qBAAoB;AACpB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;;;;;;AC5BA;;;;;;;ACAA;;AAEA;AACA;AACA,EAAC;;AAED;;AAEA;;AAEA,uCAAsC,uCAAuC,kBAAkB;;AAE/F,UAAS;;;AAGT;AACA;AACA,EAAC;AACD;AACA,EAAC;AACD;AACA,EAAC;AACD;AACA,EAAC;AACD;AACA;;AAEA;AACA,6B;;;;;;;AC5BA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;ACTA;;AAEA;AACA;AACA,EAAC;AACD;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA,GAAE;AACF;AACA;;AAEA;AACA,G;;;;;;ACtBA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA,uCAAsC,uCAAuC,kBAAkB;;AAE/F;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA,oEAAmE;AACnE;;AAEA;AACA;AACA,IAAG;;AAEH;AACA;AACA,IAAG;;AAEH;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,4CAA2C,sCAAsC;;AAEjF;AACA;AACA;;AAEA;AACA,oCAAmC,aAAa;AAChD;AACA;AACA,IAAG;AACH;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW,OAAO;AAClB;AACA;AACA;AACA;AACA;AACA;AACA,cAAa,SAAS;AACtB;AACA;AACA;AACA;AACA;AACA,kBAAiB,wBAAwB;AACzC;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA,IAAG;AACH;AACA;;AAEA;AACA,yEAAwE;AACxE;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,oBAAmB,6BAA6B;AAChD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,E;;;;;;;AC7IA;;AAEA;AACA;AACA;AACA;AACA;AACA,YAAW,OAAO;AAClB,cAAa;AACb;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAG;AACH;AACA,E;;;;;;ACxBA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW,gBAAgB;AAC3B;AACA;AACA;AACA,YAAW,SAAS;AACpB;AACA;AACA,cAAa,gBAAgB;AAC7B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA,kBAAiB,iBAAiB;AAClC;AACA;AACA;AACA;AACA;AACA;AACA;AACA,E;;;;;;AClDA;;AAEA;;AAEA,oDAAmD,gBAAgB,sBAAsB,OAAO,2BAA2B,0BAA0B,yDAAyD,2BAA2B,EAAE,EAAE,EAAE,eAAe;;AAE9P;;AAEA;;AAEA;;AAEA,uCAAsC,uCAAuC,kBAAkB;;AAE/F;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW,YAAY;AACvB,cAAa,SAAS;AACtB;AACA;AACA,yEAAwE,aAAa;AACrF;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAO;AACP;;AAEA,yBAAwB;AACxB;AACA,QAAO;AACP;AACA;AACA,E;;;;;;ACzDA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW,YAAY;AACvB,cAAa,SAAS;AACtB;AACA;AACA;;AAEA;AACA,mEAAkE,aAAa;AAC/E;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,MAAK;AACL;AACA,E;;;;;;ACrCA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA,4B;;;;;;ACtBA;AACA;AACA;;;;;;;ACFA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,YAAW,SAAS;AACpB,YAAW,qBAAqB;AAChC,cAAa;AACb;AACA;;AAEA;AACA;AACA;AACA,aAAY,OAAO;AACnB,cAAa;AACb;AACA;AACA;AACA;AACA;AACA,+BAA8B;AAC9B;AACA;AACA,IAAG;AACH;;AAEA;AACA;AACA;AACA,aAAY,OAAO;AACnB,eAAc;AACd;AACA;AACA;AACA;AACA;AACA,KAAI;AACJ;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,YAAW,OAAO;AAClB,YAAW,IAAI;AACf,cAAa;AACb;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA,qBAAoB;AACpB;AACA,GAAE;AACF;;AAEA;AACA;AACA;AACA,YAAW,OAAO;AAClB,YAAW,IAAI;AACf,cAAa;AACb;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;;;;;;ACzFA;AACA;;AAEA;AACA,cAAa,OAAO;AACpB,eAAc,OAAO;AACrB,eAAc,OAAO;AACrB,eAAc,OAAO;AACrB,eAAc,OAAO;AACrB,eAAc,iBAAiB;AAC/B;AACA;AACA,eAAc,OAAO;AACrB,eAAc,iBAAiB;AAC/B;;AAEA;AACA;AACA;AACA,YAAW,OAAO;AAClB,YAAW,OAAO;AAClB,YAAW,OAAO;AAClB,YAAW,OAAO;AAClB,YAAW,OAAO;AAClB,YAAW,iBAAiB;AAC5B,aAAY;AACZ;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA,YAAW,iBAAiB;AAC5B,aAAY;AACZ;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW,OAAO;AAClB,aAAY;AACZ;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW,OAAO;AAClB,aAAY;AACZ;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA,UAAS,oBAAoB;AAC7B;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA,eAAc;AACd;AACA;AACA;AACA,eAAc;AACd;AACA;AACA;AACA;;;;;;;ACzIA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,YAAW,OAAO;AAClB,YAAW,iBAAiB;AAC5B,cAAa;AACb;AACA;;AAEA;AACA;AACA;AACA,aAAY,OAAO;AACnB,cAAa;AACb;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA,IAAG;AACH;;AAEA;AACA;AACA;AACA,aAAY,OAAO;AACnB,eAAc;AACd;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,YAAW,OAAO;AAClB,aAAY,MAAM;AAClB;AACA,cAAa;AACb;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA,YAAW,OAAO;AAClB,cAAa;AACb;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;;;;;;ACzGA;AACA,cAAa,OAAO;AACpB;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA,YAAW,WAAW;AACtB;AACA,aAAY;AACZ;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAc;AACd;AACA;AACA;AACA,IAAG;;AAEH;AACA;AACA;AACA,cAAa,QAAQ;AACrB;AACA;AACA;AACA,IAAG;;AAEH;AACA;AACA;AACA;AACA,eAAc;AACd;AACA;AACA;AACA,IAAG;;AAEH;AACA;AACA;AACA;AACA;AACA,eAAc;AACd;AACA;AACA;;AAEA;AACA;AACA,KAAI;AACJ;AACA;;AAEA;AACA,IAAG;;AAEH;AACA;AACA;AACA,cAAa,OAAO;AACpB;AACA;AACA;AACA;AACA;AACA;;;;;;;AC9EA;AACA;;AAEA;AACA,cAAa,OAAO;AACpB,eAAc,OAAO;AACrB,eAAc,SAAS;AACvB,eAAc,SAAS;AACvB,eAAc,SAAS;AACvB;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW,OAAO;AAClB,YAAW,QAAQ;AACnB,YAAW,OAAO;AAClB,aAAY;AACZ;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA,GAAE;AACF;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;ACrDA;AACA;;AAEA;AACA;AACA;AACA;AACA,YAAW,OAAO;AAClB,YAAW,OAAO;AAClB,aAAY;AACZ;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;;;;;;ACvBA;AACA;;AAEA;AACA;AACA;AACA,cAAa,SAAS;AACtB;AACA;;AAEA;AACA;AACA;AACA,YAAW;AACX;AACA;AACA;AACA;AACA;AACA,aAAY;AACZ;AACA;;AAEA;AACA;AACA,aAAY,OAAO;AACnB,eAAc,OAAO;AACrB;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA,KAAI;AACJ;AACA;;AAEA;AACA;AACA;AACA,eAAc,YAAY;AAC1B;AACA;AACA;AACA;AACA,KAAI;;AAEJ;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA,KAAI;;AAEJ;AACA;AACA;AACA;AACA;AACA;AACA,KAAI;;AAEJ;AACA;AACA,eAAc,QAAQ;AACtB;AACA;AACA;AACA,KAAI;;AAEJ;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAc,QAAQ;AACtB;AACA;AACA;AACA;AACA;AACA,MAAK;AACL;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,aAAY,OAAO;AACnB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAI;AACJ;AACA;AACA;AACA;AACA;AACA,KAAI;AACJ;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,GAAE;;AAEF;AACA;;AAEA;AACA;AACA;AACA,YAAW,cAAc;AACzB,aAAY,OAAO;AACnB;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,YAAW,cAAc;AACzB,YAAW,QAAQ;AACnB;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,GAAE;AACF;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,cAAa,QAAQ;AACrB;AACA;AACA;AACA;AACA;;;;;;;ACzMA;AACA,cAAa,SAAS;AACtB,YAAW,OAAO;AAClB,YAAW,OAAO;AAClB;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW,YAAY;AACvB,YAAW,0BAA0B;AACrC;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;AACA,GAAE;AACF;;;;;;;ACrCA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW,QAAQ;AACnB,YAAW,OAAO;AAClB;AACA,YAAW,OAAO;AAClB;AACA,aAAY;AACZ;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;;;;;;AC9BA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,YAAW,OAAO;AAClB,YAAW,OAAO;AAClB,aAAY;AACZ;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,GAAE;AACF;AACA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA,GAAE;AACF;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW,OAAO;AAClB,YAAW,SAAS;AACpB;AACA,YAAW,OAAO;AAClB;AACA,aAAY;AACZ;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,IAAG;AACH;;;;;;;ACvFA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA,GAAE;AACF;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,cAAa,OAAO;AACpB,eAAc,OAAO;AACrB,eAAc,QAAQ;AACtB,eAAc,OAAO;AACrB,eAAc,QAAQ;AACtB;AACA;;AAEA;AACA,2CAA0C,iCAAiC;AAC3E;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW,wBAAwB;AACnC,aAAY;AACZ;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAa,MAAM;AACnB,cAAa,OAAO;AACpB;AACA;AACA,eAAc;AACd;AACA;AACA;AACA,IAAG;;AAEH;AACA;AACA;AACA;AACA;AACA,eAAc;AACd;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,YAAW,wBAAwB;AACnC,aAAY;AACZ;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA,6BAA4B;AAC5B;AACA,GAAE;;AAEF;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW,wBAAwB;AACnC,aAAY;AACZ;AACA;AACA;AACA;;AAEA,6BAA4B;AAC5B;AACA;AACA,GAAE;;AAEF;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW,OAAO;AAClB,YAAW,OAAO;AAClB,aAAY;AACZ;AACA;AACA;AACA;AACA;AACA;;AAEA,8CAA6C;AAC7C,2CAA0C;AAC1C;;AAEA;AACA,0CAAyC;;AAEzC;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,IAAG;AACH;AACA;AACA,GAAE;;AAEF;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW,mBAAmB;AAC9B,YAAW,MAAM;AACjB,YAAW,2BAA2B;AACtC,aAAY,eAAe;AAC3B;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA,YAAW,mBAAmB;AAC9B,aAAY,eAAe;AAC3B;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA,GAAE;AACF;;AAEA;AACA,cAAa,OAAO;AACpB,eAAc,QAAQ;AACtB,eAAc,QAAQ;AACtB;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW,OAAO;AAClB,aAAY;AACZ;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,GAAE;AACF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW,OAAO;AAClB,YAAW,OAAO;AAClB,YAAW,OAAO;AAClB,YAAW,OAAO;AAClB,YAAW,OAAO;AAClB,YAAW,OAAO;AAClB,YAAW,OAAO;AAClB,YAAW,OAAO;AAClB,YAAW,OAAO;AAClB,aAAY;AACZ;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAG;;AAEH;AACA;AACA;AACA;AACA;AACA;AACA,GAAE;AACF;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAG;AACH;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,cAAa,OAAO;AACpB,eAAc,OAAO;AACrB,eAAc,QAAQ;AACtB,eAAc,QAAQ;AACtB;;AAEA;AACA;AACA;AACA,YAAW,mBAAmB;AAC9B,YAAW,OAAO;AAClB,aAAY;AACZ;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,YAAW,mBAAmB;AAC9B,YAAW,yBAAyB;AACpC,aAAY;AACZ;AACA;AACA;;AAEA;AACA;AACA,GAAE;AACF;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA,GAAE;AACF;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW,mBAAmB;AAC9B,YAAW,yBAAyB;AACpC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA,GAAE;;AAEF;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW,OAAO;AAClB;AACA,YAAW,eAAe;AAC1B,YAAW,QAAQ;AACnB;AACA,aAAY;AACZ;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,GAAE;;AAEF;AACA;;AAEA;AACA;AACA;AACA;;;;;;;AC/qBA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW,OAAO;AAClB,aAAY;AACZ;AACA;AACA;;AAEA;AACA;AACA,GAAE;;AAEF;AACA;;;;;;;ACvBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;ACPA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAY,OAAO;AACnB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,8DAA6D;AAC7D;AACA;AACA;AACA;AACA,YAAW,OAAO;AAClB,aAAY;AACZ;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,KAAI;AACJ;;AAEA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA;;;;;;;ACxEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW,OAAO;AAClB,YAAW,mBAAmB;AAC9B,aAAY;AACZ;AACA;AACA;AACA;AACA;;AAEA;AACA,kCAAiC;;AAEjC;AACA;AACA;AACA;;;;;;;ACzBA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAY;AACZ;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,aAAY,QAAQ;AACpB;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA,aAAY,QAAQ;AACpB;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;;;;;;AC9DA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW,2BAA2B;AACtC,aAAY;AACZ;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA;AACA;;;;;;;ACxBA;AACA;AACA;AACA,YAAW,OAAO;AAClB,YAAW,OAAO;AAClB,aAAY;AACZ;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA,IAAG;AACH;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;;;;;;AC3CA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW,wBAAwB;AACnC,aAAY;AACZ;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA,YAAW,OAAO;AAClB,YAAW,OAAO;AAClB,YAAW,OAAO;AAClB,aAAY;AACZ;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,YAAW,OAAO;AAClB,YAAW,OAAO;AAClB,YAAW,OAAO;AAClB,YAAW,OAAO;AAClB,YAAW,SAAS;AACpB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;AC3DA;AACA;AACA,cAAa;AACb;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA,0BAAyB;;AAEzB;AACA;AACA;AACA;AACA;AACA,YAAW,OAAO;AAClB,aAAY;AACZ;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW,QAAQ;AACnB,YAAW,QAAQ;AACnB,YAAW,wBAAwB;AACnC,YAAW,SAAS;AACpB,YAAW,OAAO;AAClB;AACA,cAAa;AACb;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,YAAW,mBAAmB;AAC9B,YAAW,QAAQ;AACnB,YAAW,KAAK;AAChB,aAAY;AACZ;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,IAAG;;AAEH;AACA;AACA;AACA;AACA;AACA,MAAK;AACL,KAAI;AACJ;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAO;AACP,OAAM;AACN,KAAI;AACJ;AACA;;AAEA;AACA;AACA;AACA;AACA,YAAW,QAAQ;AACnB,YAAW,MAAM;AACjB,YAAW,mBAAmB;AAC9B,YAAW,SAAS;AACpB,aAAY;AACZ;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,IAAG;;AAEH;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,KAAI;AACJ;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,aAAY;AACZ;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,IAAG;;AAEH;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;AACL,KAAI;AACJ;AACA;;AAEA;AACA;AACA;AACA;AACA,YAAW,QAAQ;AACnB,aAAY;AACZ;AACA;AACA;AACA;AACA;AACA,GAAE;AACF;;AAEA;AACA;AACA;AACA,aAAY;AACZ;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,aAAY;AACZ;AACA;AACA;AACA;AACA,GAAE;AACF;;AAEA;AACA;AACA;AACA;AACA,aAAY;AACZ;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,aAAY;AACZ;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW,QAAQ;AACnB,aAAY;AACZ;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAG;AACH;AACA;;AAEA;AACA;AACA;AACA;AACA,aAAY;AACZ;AACA;AACA;AACA;AACA;AACA;;AAEA;;;;;;;ACpTA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;AChBA;AACA;AACA;AACA;AACA;;;;;;;ACJA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,YAAW,OAAO;AAClB,aAAY;AACZ;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW,OAAO;AAClB,YAAW,OAAO;AAClB,aAAY,OAAO;AACnB;AACA;AACA;;AAEA;AACA;AACA;AACA,gBAAe;AACf;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAI;;AAEJ;AACA;AACA;AACA,KAAI;;AAEJ;AACA;AACA;AACA;AACA,MAAK;AACL,KAAI;;AAEJ;AACA;;AAEA;AACA;AACA;AACA;AACA,MAAK;AACL;AACA;AACA,MAAK;AACL,KAAI;;AAEJ;AACA;AACA;AACA;AACA;AACA;AACA,KAAI;;AAEJ;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAI;;AAEJ;AACA;AACA;AACA;AACA,MAAK;AACL,KAAI;;AAEJ;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,KAAI;AACJ;AACA;;AAEA;AACA;AACA,KAAI;;AAEJ;AACA;AACA;AACA;;;;;;;ACrJA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW,OAAO;AAClB,YAAW,OAAO;AAClB,aAAY;AACZ;AACA;AACA,iBAAgB;AAChB;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;;;;;;;ACrCA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW,OAAO;AAClB,aAAY;AACZ;AACA;AACA;;AAEA;AACA;AACA,GAAE;AACF;AACA,GAAE;AACF;AACA,GAAE;AACF;AACA,GAAE;AACF;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW,OAAO;AAClB,aAAY;AACZ;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA,GAAE;AACF;AACA,GAAE;AACF;AACA,GAAE;AACF;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;;;;;;;AClEA;AACA;;AAEA;AACA;AACA;AACA,YAAW,OAAO;AAClB,YAAW,OAAO;AAClB;AACA,aAAY,OAAO;AACnB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,KAAI;AACJ;AACA;AACA;AACA,KAAI;AACJ;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA,MAAK;AACL,KAAI;AACJ;AACA;AACA;AACA,MAAK;AACL;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;AACL;AACA;;AAEA;AACA;AACA;AACA,KAAI;;AAEJ;AACA;AACA;AACA,KAAI;;AAEJ;AACA;AACA;AACA,KAAI;AACJ;AACA;AACA;AACA;AACA;AACA,MAAK;AACL;;AAEA;AACA;AACA;AACA;AACA;;;;;;;AC9FA;AACA;;AAEA;AACA;AACA;AACA,YAAW,OAAO;AAClB,YAAW,OAAO;AAClB,aAAY,OAAO;AACnB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,KAAI;AACJ;AACA;AACA;AACA;AACA,KAAI;AACJ;AACA;AACA;AACA;AACA;AACA,MAAK;AACL;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,MAAK;;AAEL;AACA;AACA;AACA,KAAI;AACJ;AACA;AACA;AACA;;;;;;;ACvDA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;ACjBA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,YAAW,OAAO;AAClB,cAAa,eAAe,qBAAqB;AACjD,+DAA8D;AAC9D;AACA;AACA;AACA;AACA;AACA;;;;;;;AClBA;AACA;AACA;;AAEA;AACA,cAAa,OAAO;AACpB,eAAc,OAAO;AACrB,eAAc,OAAO;AACrB,eAAc,OAAO;AACrB,eAAc,OAAO;AACrB,eAAc,iBAAiB;AAC/B;AACA;AACA,eAAc,OAAO;AACrB,eAAc,iBAAiB;AAC/B;;AAEA;AACA;AACA;AACA,YAAW,OAAO;AAClB,YAAW,OAAO;AAClB,YAAW,OAAO;AAClB,YAAW,OAAO;AAClB,YAAW,OAAO;AAClB,YAAW,iBAAiB;AAC5B,aAAY;AACZ;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA,YAAW,iBAAiB;AAC5B,aAAY;AACZ;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW,OAAO;AAClB,aAAY;AACZ;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAW,OAAO;AAClB,aAAY;AACZ;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA,UAAS,oBAAoB;AAC7B;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,IAAG;AACH;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA,eAAc;AACd;AACA;AACA;AACA,eAAc;AACd;AACA;AACA;AACA","file":"/index.js","sourcesContent":[" \t// The module cache\n \tvar installedModules = {};\n\n \t// The require function\n \tfunction __webpack_require__(moduleId) {\n\n \t\t// Check if module is in cache\n \t\tif(installedModules[moduleId])\n \t\t\treturn installedModules[moduleId].exports;\n\n \t\t// Create a new module (and put it into the cache)\n \t\tvar module = installedModules[moduleId] = {\n \t\t\texports: {},\n \t\t\tid: moduleId,\n \t\t\tloaded: false\n \t\t};\n\n \t\t// Execute the module function\n \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\n \t\t// Flag the module as loaded\n \t\tmodule.loaded = true;\n\n \t\t// Return the exports of the module\n \t\treturn module.exports;\n \t}\n\n\n \t// expose the modules object (__webpack_modules__)\n \t__webpack_require__.m = modules;\n\n \t// expose the module cache\n \t__webpack_require__.c = installedModules;\n\n \t// __webpack_public_path__\n \t__webpack_require__.p = \"\";\n\n \t// Load entry module and return exports\n \treturn __webpack_require__(0);\n\n\n\n// WEBPACK FOOTER //\n// webpack/bootstrap 94af4e96e5ae8032d502","var mw = mediaWiki,\n\t$ = jQuery,\n\tRedux = require( 'redux' ),\n\tReduxThunk = require( 'redux-thunk' ),\n\tconstants = require( './constants' ),\n\n\tcreateRESTBaseGateway = require( './gateway/rest' ),\n\tcreateMediaWikiApiGateway = require( './gateway/mediawiki' ),\n\tcreateUserSettings = require( './userSettings' ),\n\tcreatePreviewBehavior = require( './previewBehavior' ),\n\tcreateSchema = require( './schema' ),\n\tcreateSettingsDialogRenderer = require( './settingsDialog' ),\n\tregisterChangeListener = require( './changeListener' ),\n\tcreateIsEnabled = require( './isEnabled' ),\n\tprocessLinks = require( './processLinks' ),\n\trenderer = require( './renderer' ),\n\n\tchangeListeners = require( './changeListeners' ),\n\tactions = require( './actions' ),\n\treducers = require( './reducers' ),\n\n\tBLACKLISTED_LINKS = [\n\t\t'.extiw',\n\t\t'.image',\n\t\t'.new',\n\t\t'.internal',\n\t\t'.external',\n\t\t'.oo-ui-buttonedElement-button',\n\t\t'.cancelLink a'\n\t];\n\n/**\n * Creates a gateway with sensible values for the dependencies.\n *\n * @param {mw.Map} config\n * @return {ext.popups.Gateway}\n */\nfunction createGateway( config ) {\n\tif ( config.get( 'wgPopupsAPIUseRESTBase' ) ) {\n\t\treturn createRESTBaseGateway( $.ajax, constants );\n\t}\n\treturn createMediaWikiApiGateway( new mw.Api(), constants );\n}\n\n/**\n * Subscribes the registered change listeners to the\n * [store](http://redux.js.org/docs/api/Store.html#store).\n *\n * @param {Redux.Store} store\n * @param {Object} actions\n * @param {mw.eventLog.Schema} schema\n * @param {ext.popups.UserSettings} userSettings\n * @param {Function} settingsDialog\n * @param {ext.popups.PreviewBehavior} previewBehavior\n */\nfunction registerChangeListeners( store, actions, schema, userSettings, settingsDialog, previewBehavior ) {\n\tregisterChangeListener( store, changeListeners.footerLink( actions ) );\n\tregisterChangeListener( store, changeListeners.linkTitle() );\n\tregisterChangeListener( store, changeListeners.render( previewBehavior ) );\n\tregisterChangeListener( store, changeListeners.eventLogging( actions, schema ) );\n\tregisterChangeListener( store, changeListeners.syncUserSettings( userSettings ) );\n\tregisterChangeListener( store, changeListeners.settings( actions, settingsDialog ) );\n}\n\n/**\n * Binds the actions (or \"action creators\") to the\n * [store](http://redux.js.org/docs/api/Store.html#store).\n *\n * @param {Redux.Store} store\n * @return {Object}\n */\nfunction createBoundActions( store ) {\n\treturn Redux.bindActionCreators( actions, store.dispatch );\n}\n\n/**\n * Creates the reducer for all actions.\n *\n * @return {Redux.Reducer}\n */\nfunction createRootReducer() {\n\treturn Redux.combineReducers( reducers );\n}\n\n/*\n * Initialize the application by:\n * 1. Creating the state store\n * 2. Binding the actions to such store\n * 3. Trigger the boot action to bootstrap the system\n * 4. When the page content is ready:\n * - Process the eligible links for page previews\n * - Initialize the renderer\n * - Bind hover and click events to the eligible links to trigger actions\n */\nmw.requestIdleCallback( function () {\n\tvar compose = Redux.compose,\n\t\tstore,\n\t\tactions,\n\n\t\t// So-called \"services\".\n\t\tgenerateToken = mw.user.generateRandomSessionId,\n\t\tgateway = createGateway( mw.config ),\n\t\tuserSettings,\n\t\tsettingsDialog,\n\t\tisEnabled,\n\t\tschema,\n\t\tpreviewBehavior;\n\n\tuserSettings = createUserSettings( mw.storage );\n\tsettingsDialog = createSettingsDialogRenderer();\n\tschema = createSchema( mw.config, window );\n\n\tisEnabled = createIsEnabled( mw.user, userSettings, mw.config );\n\n\t// If debug mode is enabled, then enable Redux DevTools.\n\tif ( mw.config.get( 'debug' ) === true ) {\n\t\t// eslint-disable-next-line no-underscore-dangle\n\t\tcompose = window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || compose;\n\t}\n\n\tstore = Redux.createStore(\n\t\tcreateRootReducer(),\n\t\tcompose( Redux.applyMiddleware(\n\t\t\tReduxThunk.default\n\t\t) )\n\t);\n\tactions = createBoundActions( store );\n\n\tpreviewBehavior = createPreviewBehavior( mw.config, mw.user, actions );\n\n\tregisterChangeListeners( store, actions, schema, userSettings, settingsDialog, previewBehavior );\n\n\tactions.boot(\n\t\tisEnabled,\n\t\tmw.user,\n\t\tuserSettings,\n\t\tgenerateToken,\n\t\tmw.config\n\t);\n\n\tmw.hook( 'wikipage.content' ).add( function ( $container ) {\n\t\tvar previewLinks =\n\t\t\tprocessLinks(\n\t\t\t\t$container,\n\t\t\t\tBLACKLISTED_LINKS,\n\t\t\t\tmw.config\n\t\t\t);\n\n\t\trenderer.init();\n\n\t\tpreviewLinks\n\t\t\t.on( 'mouseover focus', function ( event ) {\n\t\t\t\tactions.linkDwell( this, event, gateway, generateToken );\n\t\t\t} )\n\t\t\t.on( 'mouseout blur', function () {\n\t\t\t\tactions.abandon( this );\n\t\t\t} )\n\t\t\t.on( 'click', function () {\n\t\t\t\tactions.linkClick( this );\n\t\t\t} );\n\n\t} );\n} );\n\n// FIXME: Currently needs to be exposed for testing purposes\nmw.popups = require( './popups' );\nwindow.Redux = Redux;\nwindow.ReduxThunk = ReduxThunk;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./src/index.js\n// module id = 0\n// module chunks = 0","'use strict';\n\nexports.__esModule = true;\nexports.compose = exports.applyMiddleware = exports.bindActionCreators = exports.combineReducers = exports.createStore = undefined;\n\nvar _createStore = require('./createStore');\n\nvar _createStore2 = _interopRequireDefault(_createStore);\n\nvar _combineReducers = require('./combineReducers');\n\nvar _combineReducers2 = _interopRequireDefault(_combineReducers);\n\nvar _bindActionCreators = require('./bindActionCreators');\n\nvar _bindActionCreators2 = _interopRequireDefault(_bindActionCreators);\n\nvar _applyMiddleware = require('./applyMiddleware');\n\nvar _applyMiddleware2 = _interopRequireDefault(_applyMiddleware);\n\nvar _compose = require('./compose');\n\nvar _compose2 = _interopRequireDefault(_compose);\n\nvar _warning = require('./utils/warning');\n\nvar _warning2 = _interopRequireDefault(_warning);\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }\n\n/*\n* This is a dummy function to check if the function name has been altered by minification.\n* If the function has been minified and NODE_ENV !== 'production', warn the user.\n*/\nfunction isCrushed() {}\n\nif (process.env.NODE_ENV !== 'production' && typeof isCrushed.name === 'string' && isCrushed.name !== 'isCrushed') {\n (0, _warning2['default'])('You are currently using minified code outside of NODE_ENV === \\'production\\'. ' + 'This means that you are running a slower development build of Redux. ' + 'You can use loose-envify (https://github.com/zertosh/loose-envify) for browserify ' + 'or DefinePlugin for webpack (http://stackoverflow.com/questions/30030031) ' + 'to ensure you have the correct code for your production build.');\n}\n\nexports.createStore = _createStore2['default'];\nexports.combineReducers = _combineReducers2['default'];\nexports.bindActionCreators = _bindActionCreators2['default'];\nexports.applyMiddleware = _applyMiddleware2['default'];\nexports.compose = _compose2['default'];\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/redux/lib/index.js\n// module id = 1\n// module chunks = 0","// shim for using process in browser\nvar process = module.exports = {};\n\n// cached from whatever global is present so that test runners that stub it\n// don't break things. But we need to wrap it in a try catch in case it is\n// wrapped in strict mode code which doesn't define any globals. It's inside a\n// function because try/catches deoptimize in certain engines.\n\nvar cachedSetTimeout;\nvar cachedClearTimeout;\n\nfunction defaultSetTimout() {\n throw new Error('setTimeout has not been defined');\n}\nfunction defaultClearTimeout () {\n throw new Error('clearTimeout has not been defined');\n}\n(function () {\n try {\n if (typeof setTimeout === 'function') {\n cachedSetTimeout = setTimeout;\n } else {\n cachedSetTimeout = defaultSetTimout;\n }\n } catch (e) {\n cachedSetTimeout = defaultSetTimout;\n }\n try {\n if (typeof clearTimeout === 'function') {\n cachedClearTimeout = clearTimeout;\n } else {\n cachedClearTimeout = defaultClearTimeout;\n }\n } catch (e) {\n cachedClearTimeout = defaultClearTimeout;\n }\n} ())\nfunction runTimeout(fun) {\n if (cachedSetTimeout === setTimeout) {\n //normal enviroments in sane situations\n return setTimeout(fun, 0);\n }\n // if setTimeout wasn't available but was latter defined\n if ((cachedSetTimeout === defaultSetTimout || !cachedSetTimeout) && setTimeout) {\n cachedSetTimeout = setTimeout;\n return setTimeout(fun, 0);\n }\n try {\n // when when somebody has screwed with setTimeout but no I.E. maddness\n return cachedSetTimeout(fun, 0);\n } catch(e){\n try {\n // When we are in I.E. but the script has been evaled so I.E. doesn't trust the global object when called normally\n return cachedSetTimeout.call(null, fun, 0);\n } catch(e){\n // same as above but when it's a version of I.E. that must have the global object for 'this', hopfully our context correct otherwise it will throw a global error\n return cachedSetTimeout.call(this, fun, 0);\n }\n }\n\n\n}\nfunction runClearTimeout(marker) {\n if (cachedClearTimeout === clearTimeout) {\n //normal enviroments in sane situations\n return clearTimeout(marker);\n }\n // if clearTimeout wasn't available but was latter defined\n if ((cachedClearTimeout === defaultClearTimeout || !cachedClearTimeout) && clearTimeout) {\n cachedClearTimeout = clearTimeout;\n return clearTimeout(marker);\n }\n try {\n // when when somebody has screwed with setTimeout but no I.E. maddness\n return cachedClearTimeout(marker);\n } catch (e){\n try {\n // When we are in I.E. but the script has been evaled so I.E. doesn't trust the global object when called normally\n return cachedClearTimeout.call(null, marker);\n } catch (e){\n // same as above but when it's a version of I.E. that must have the global object for 'this', hopfully our context correct otherwise it will throw a global error.\n // Some versions of I.E. have different rules for clearTimeout vs setTimeout\n return cachedClearTimeout.call(this, marker);\n }\n }\n\n\n\n}\nvar queue = [];\nvar draining = false;\nvar currentQueue;\nvar queueIndex = -1;\n\nfunction cleanUpNextTick() {\n if (!draining || !currentQueue) {\n return;\n }\n draining = false;\n if (currentQueue.length) {\n queue = currentQueue.concat(queue);\n } else {\n queueIndex = -1;\n }\n if (queue.length) {\n drainQueue();\n }\n}\n\nfunction drainQueue() {\n if (draining) {\n return;\n }\n var timeout = runTimeout(cleanUpNextTick);\n draining = true;\n\n var len = queue.length;\n while(len) {\n currentQueue = queue;\n queue = [];\n while (++queueIndex < len) {\n if (currentQueue) {\n currentQueue[queueIndex].run();\n }\n }\n queueIndex = -1;\n len = queue.length;\n }\n currentQueue = null;\n draining = false;\n runClearTimeout(timeout);\n}\n\nprocess.nextTick = function (fun) {\n var args = new Array(arguments.length - 1);\n if (arguments.length > 1) {\n for (var i = 1; i < arguments.length; i++) {\n args[i - 1] = arguments[i];\n }\n }\n queue.push(new Item(fun, args));\n if (queue.length === 1 && !draining) {\n runTimeout(drainQueue);\n }\n};\n\n// v8 likes predictible objects\nfunction Item(fun, array) {\n this.fun = fun;\n this.array = array;\n}\nItem.prototype.run = function () {\n this.fun.apply(null, this.array);\n};\nprocess.title = 'browser';\nprocess.browser = true;\nprocess.env = {};\nprocess.argv = [];\nprocess.version = ''; // empty string to avoid regexp issues\nprocess.versions = {};\n\nfunction noop() {}\n\nprocess.on = noop;\nprocess.addListener = noop;\nprocess.once = noop;\nprocess.off = noop;\nprocess.removeListener = noop;\nprocess.removeAllListeners = noop;\nprocess.emit = noop;\n\nprocess.binding = function (name) {\n throw new Error('process.binding is not supported');\n};\n\nprocess.cwd = function () { return '/' };\nprocess.chdir = function (dir) {\n throw new Error('process.chdir is not supported');\n};\nprocess.umask = function() { return 0; };\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/process/browser.js\n// module id = 2\n// module chunks = 0","'use strict';\n\nexports.__esModule = true;\nexports.ActionTypes = undefined;\nexports['default'] = createStore;\n\nvar _isPlainObject = require('lodash/isPlainObject');\n\nvar _isPlainObject2 = _interopRequireDefault(_isPlainObject);\n\nvar _symbolObservable = require('symbol-observable');\n\nvar _symbolObservable2 = _interopRequireDefault(_symbolObservable);\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }\n\n/**\n * These are private action types reserved by Redux.\n * For any unknown actions, you must return the current state.\n * If the current state is undefined, you must return the initial state.\n * Do not reference these action types directly in your code.\n */\nvar ActionTypes = exports.ActionTypes = {\n INIT: '@@redux/INIT'\n};\n\n/**\n * Creates a Redux store that holds the state tree.\n * The only way to change the data in the store is to call `dispatch()` on it.\n *\n * There should only be a single store in your app. To specify how different\n * parts of the state tree respond to actions, you may combine several reducers\n * into a single reducer function by using `combineReducers`.\n *\n * @param {Function} reducer A function that returns the next state tree, given\n * the current state tree and the action to handle.\n *\n * @param {any} [preloadedState] The initial state. You may optionally specify it\n * to hydrate the state from the server in universal apps, or to restore a\n * previously serialized user session.\n * If you use `combineReducers` to produce the root reducer function, this must be\n * an object with the same shape as `combineReducers` keys.\n *\n * @param {Function} enhancer The store enhancer. You may optionally specify it\n * to enhance the store with third-party capabilities such as middleware,\n * time travel, persistence, etc. The only store enhancer that ships with Redux\n * is `applyMiddleware()`.\n *\n * @returns {Store} A Redux store that lets you read the state, dispatch actions\n * and subscribe to changes.\n */\nfunction createStore(reducer, preloadedState, enhancer) {\n var _ref2;\n\n if (typeof preloadedState === 'function' && typeof enhancer === 'undefined') {\n enhancer = preloadedState;\n preloadedState = undefined;\n }\n\n if (typeof enhancer !== 'undefined') {\n if (typeof enhancer !== 'function') {\n throw new Error('Expected the enhancer to be a function.');\n }\n\n return enhancer(createStore)(reducer, preloadedState);\n }\n\n if (typeof reducer !== 'function') {\n throw new Error('Expected the reducer to be a function.');\n }\n\n var currentReducer = reducer;\n var currentState = preloadedState;\n var currentListeners = [];\n var nextListeners = currentListeners;\n var isDispatching = false;\n\n function ensureCanMutateNextListeners() {\n if (nextListeners === currentListeners) {\n nextListeners = currentListeners.slice();\n }\n }\n\n /**\n * Reads the state tree managed by the store.\n *\n * @returns {any} The current state tree of your application.\n */\n function getState() {\n return currentState;\n }\n\n /**\n * Adds a change listener. It will be called any time an action is dispatched,\n * and some part of the state tree may potentially have changed. You may then\n * call `getState()` to read the current state tree inside the callback.\n *\n * You may call `dispatch()` from a change listener, with the following\n * caveats:\n *\n * 1. The subscriptions are snapshotted just before every `dispatch()` call.\n * If you subscribe or unsubscribe while the listeners are being invoked, this\n * will not have any effect on the `dispatch()` that is currently in progress.\n * However, the next `dispatch()` call, whether nested or not, will use a more\n * recent snapshot of the subscription list.\n *\n * 2. The listener should not expect to see all state changes, as the state\n * might have been updated multiple times during a nested `dispatch()` before\n * the listener is called. It is, however, guaranteed that all subscribers\n * registered before the `dispatch()` started will be called with the latest\n * state by the time it exits.\n *\n * @param {Function} listener A callback to be invoked on every dispatch.\n * @returns {Function} A function to remove this change listener.\n */\n function subscribe(listener) {\n if (typeof listener !== 'function') {\n throw new Error('Expected listener to be a function.');\n }\n\n var isSubscribed = true;\n\n ensureCanMutateNextListeners();\n nextListeners.push(listener);\n\n return function unsubscribe() {\n if (!isSubscribed) {\n return;\n }\n\n isSubscribed = false;\n\n ensureCanMutateNextListeners();\n var index = nextListeners.indexOf(listener);\n nextListeners.splice(index, 1);\n };\n }\n\n /**\n * Dispatches an action. It is the only way to trigger a state change.\n *\n * The `reducer` function, used to create the store, will be called with the\n * current state tree and the given `action`. Its return value will\n * be considered the **next** state of the tree, and the change listeners\n * will be notified.\n *\n * The base implementation only supports plain object actions. If you want to\n * dispatch a Promise, an Observable, a thunk, or something else, you need to\n * wrap your store creating function into the corresponding middleware. For\n * example, see the documentation for the `redux-thunk` package. Even the\n * middleware will eventually dispatch plain object actions using this method.\n *\n * @param {Object} action A plain object representing “what changed”. It is\n * a good idea to keep actions serializable so you can record and replay user\n * sessions, or use the time travelling `redux-devtools`. An action must have\n * a `type` property which may not be `undefined`. It is a good idea to use\n * string constants for action types.\n *\n * @returns {Object} For convenience, the same action object you dispatched.\n *\n * Note that, if you use a custom middleware, it may wrap `dispatch()` to\n * return something else (for example, a Promise you can await).\n */\n function dispatch(action) {\n if (!(0, _isPlainObject2['default'])(action)) {\n throw new Error('Actions must be plain objects. ' + 'Use custom middleware for async actions.');\n }\n\n if (typeof action.type === 'undefined') {\n throw new Error('Actions may not have an undefined \"type\" property. ' + 'Have you misspelled a constant?');\n }\n\n if (isDispatching) {\n throw new Error('Reducers may not dispatch actions.');\n }\n\n try {\n isDispatching = true;\n currentState = currentReducer(currentState, action);\n } finally {\n isDispatching = false;\n }\n\n var listeners = currentListeners = nextListeners;\n for (var i = 0; i < listeners.length; i++) {\n listeners[i]();\n }\n\n return action;\n }\n\n /**\n * Replaces the reducer currently used by the store to calculate the state.\n *\n * You might need this if your app implements code splitting and you want to\n * load some of the reducers dynamically. You might also need this if you\n * implement a hot reloading mechanism for Redux.\n *\n * @param {Function} nextReducer The reducer for the store to use instead.\n * @returns {void}\n */\n function replaceReducer(nextReducer) {\n if (typeof nextReducer !== 'function') {\n throw new Error('Expected the nextReducer to be a function.');\n }\n\n currentReducer = nextReducer;\n dispatch({ type: ActionTypes.INIT });\n }\n\n /**\n * Interoperability point for observable/reactive libraries.\n * @returns {observable} A minimal observable of state changes.\n * For more information, see the observable proposal:\n * https://github.com/zenparsing/es-observable\n */\n function observable() {\n var _ref;\n\n var outerSubscribe = subscribe;\n return _ref = {\n /**\n * The minimal observable subscription method.\n * @param {Object} observer Any object that can be used as an observer.\n * The observer object should have a `next` method.\n * @returns {subscription} An object with an `unsubscribe` method that can\n * be used to unsubscribe the observable from the store, and prevent further\n * emission of values from the observable.\n */\n subscribe: function subscribe(observer) {\n if (typeof observer !== 'object') {\n throw new TypeError('Expected the observer to be an object.');\n }\n\n function observeState() {\n if (observer.next) {\n observer.next(getState());\n }\n }\n\n observeState();\n var unsubscribe = outerSubscribe(observeState);\n return { unsubscribe: unsubscribe };\n }\n }, _ref[_symbolObservable2['default']] = function () {\n return this;\n }, _ref;\n }\n\n // When a store is created, an \"INIT\" action is dispatched so that every\n // reducer returns their initial state. This effectively populates\n // the initial state tree.\n dispatch({ type: ActionTypes.INIT });\n\n return _ref2 = {\n dispatch: dispatch,\n subscribe: subscribe,\n getState: getState,\n replaceReducer: replaceReducer\n }, _ref2[_symbolObservable2['default']] = observable, _ref2;\n}\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/redux/lib/createStore.js\n// module id = 3\n// module chunks = 0","var baseGetTag = require('./_baseGetTag'),\n getPrototype = require('./_getPrototype'),\n isObjectLike = require('./isObjectLike');\n\n/** `Object#toString` result references. */\nvar objectTag = '[object Object]';\n\n/** Used for built-in method references. */\nvar funcProto = Function.prototype,\n objectProto = Object.prototype;\n\n/** Used to resolve the decompiled source of functions. */\nvar funcToString = funcProto.toString;\n\n/** Used to check objects for own properties. */\nvar hasOwnProperty = objectProto.hasOwnProperty;\n\n/** Used to infer the `Object` constructor. */\nvar objectCtorString = funcToString.call(Object);\n\n/**\n * Checks if `value` is a plain object, that is, an object created by the\n * `Object` constructor or one with a `[[Prototype]]` of `null`.\n *\n * @static\n * @memberOf _\n * @since 0.8.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is a plain object, else `false`.\n * @example\n *\n * function Foo() {\n * this.a = 1;\n * }\n *\n * _.isPlainObject(new Foo);\n * // => false\n *\n * _.isPlainObject([1, 2, 3]);\n * // => false\n *\n * _.isPlainObject({ 'x': 0, 'y': 0 });\n * // => true\n *\n * _.isPlainObject(Object.create(null));\n * // => true\n */\nfunction isPlainObject(value) {\n if (!isObjectLike(value) || baseGetTag(value) != objectTag) {\n return false;\n }\n var proto = getPrototype(value);\n if (proto === null) {\n return true;\n }\n var Ctor = hasOwnProperty.call(proto, 'constructor') && proto.constructor;\n return typeof Ctor == 'function' && Ctor instanceof Ctor &&\n funcToString.call(Ctor) == objectCtorString;\n}\n\nmodule.exports = isPlainObject;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/redux/~/lodash/isPlainObject.js\n// module id = 4\n// module chunks = 0","var Symbol = require('./_Symbol'),\n getRawTag = require('./_getRawTag'),\n objectToString = require('./_objectToString');\n\n/** `Object#toString` result references. */\nvar nullTag = '[object Null]',\n undefinedTag = '[object Undefined]';\n\n/** Built-in value references. */\nvar symToStringTag = Symbol ? Symbol.toStringTag : undefined;\n\n/**\n * The base implementation of `getTag` without fallbacks for buggy environments.\n *\n * @private\n * @param {*} value The value to query.\n * @returns {string} Returns the `toStringTag`.\n */\nfunction baseGetTag(value) {\n if (value == null) {\n return value === undefined ? undefinedTag : nullTag;\n }\n return (symToStringTag && symToStringTag in Object(value))\n ? getRawTag(value)\n : objectToString(value);\n}\n\nmodule.exports = baseGetTag;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/redux/~/lodash/_baseGetTag.js\n// module id = 5\n// module chunks = 0","var root = require('./_root');\n\n/** Built-in value references. */\nvar Symbol = root.Symbol;\n\nmodule.exports = Symbol;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/redux/~/lodash/_Symbol.js\n// module id = 6\n// module chunks = 0","var freeGlobal = require('./_freeGlobal');\n\n/** Detect free variable `self`. */\nvar freeSelf = typeof self == 'object' && self && self.Object === Object && self;\n\n/** Used as a reference to the global object. */\nvar root = freeGlobal || freeSelf || Function('return this')();\n\nmodule.exports = root;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/redux/~/lodash/_root.js\n// module id = 7\n// module chunks = 0","/** Detect free variable `global` from Node.js. */\nvar freeGlobal = typeof global == 'object' && global && global.Object === Object && global;\n\nmodule.exports = freeGlobal;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/redux/~/lodash/_freeGlobal.js\n// module id = 8\n// module chunks = 0","var Symbol = require('./_Symbol');\n\n/** Used for built-in method references. */\nvar objectProto = Object.prototype;\n\n/** Used to check objects for own properties. */\nvar hasOwnProperty = objectProto.hasOwnProperty;\n\n/**\n * Used to resolve the\n * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring)\n * of values.\n */\nvar nativeObjectToString = objectProto.toString;\n\n/** Built-in value references. */\nvar symToStringTag = Symbol ? Symbol.toStringTag : undefined;\n\n/**\n * A specialized version of `baseGetTag` which ignores `Symbol.toStringTag` values.\n *\n * @private\n * @param {*} value The value to query.\n * @returns {string} Returns the raw `toStringTag`.\n */\nfunction getRawTag(value) {\n var isOwn = hasOwnProperty.call(value, symToStringTag),\n tag = value[symToStringTag];\n\n try {\n value[symToStringTag] = undefined;\n var unmasked = true;\n } catch (e) {}\n\n var result = nativeObjectToString.call(value);\n if (unmasked) {\n if (isOwn) {\n value[symToStringTag] = tag;\n } else {\n delete value[symToStringTag];\n }\n }\n return result;\n}\n\nmodule.exports = getRawTag;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/redux/~/lodash/_getRawTag.js\n// module id = 9\n// module chunks = 0","/** Used for built-in method references. */\nvar objectProto = Object.prototype;\n\n/**\n * Used to resolve the\n * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring)\n * of values.\n */\nvar nativeObjectToString = objectProto.toString;\n\n/**\n * Converts `value` to a string using `Object.prototype.toString`.\n *\n * @private\n * @param {*} value The value to convert.\n * @returns {string} Returns the converted string.\n */\nfunction objectToString(value) {\n return nativeObjectToString.call(value);\n}\n\nmodule.exports = objectToString;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/redux/~/lodash/_objectToString.js\n// module id = 10\n// module chunks = 0","var overArg = require('./_overArg');\n\n/** Built-in value references. */\nvar getPrototype = overArg(Object.getPrototypeOf, Object);\n\nmodule.exports = getPrototype;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/redux/~/lodash/_getPrototype.js\n// module id = 11\n// module chunks = 0","/**\n * Creates a unary function that invokes `func` with its argument transformed.\n *\n * @private\n * @param {Function} func The function to wrap.\n * @param {Function} transform The argument transform.\n * @returns {Function} Returns the new function.\n */\nfunction overArg(func, transform) {\n return function(arg) {\n return func(transform(arg));\n };\n}\n\nmodule.exports = overArg;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/redux/~/lodash/_overArg.js\n// module id = 12\n// module chunks = 0","/**\n * Checks if `value` is object-like. A value is object-like if it's not `null`\n * and has a `typeof` result of \"object\".\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is object-like, else `false`.\n * @example\n *\n * _.isObjectLike({});\n * // => true\n *\n * _.isObjectLike([1, 2, 3]);\n * // => true\n *\n * _.isObjectLike(_.noop);\n * // => false\n *\n * _.isObjectLike(null);\n * // => false\n */\nfunction isObjectLike(value) {\n return value != null && typeof value == 'object';\n}\n\nmodule.exports = isObjectLike;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/redux/~/lodash/isObjectLike.js\n// module id = 13\n// module chunks = 0","module.exports = require('./lib/index');\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/symbol-observable/index.js\n// module id = 14\n// module chunks = 0","'use strict';\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\n\nvar _ponyfill = require('./ponyfill');\n\nvar _ponyfill2 = _interopRequireDefault(_ponyfill);\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }\n\nvar root; /* global window */\n\n\nif (typeof self !== 'undefined') {\n root = self;\n} else if (typeof window !== 'undefined') {\n root = window;\n} else if (typeof global !== 'undefined') {\n root = global;\n} else if (typeof module !== 'undefined') {\n root = module;\n} else {\n root = Function('return this')();\n}\n\nvar result = (0, _ponyfill2['default'])(root);\nexports['default'] = result;\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/symbol-observable/lib/index.js\n// module id = 15\n// module chunks = 0","module.exports = function(module) {\r\n\tif(!module.webpackPolyfill) {\r\n\t\tmodule.deprecate = function() {};\r\n\t\tmodule.paths = [];\r\n\t\t// module.parent = undefined by default\r\n\t\tmodule.children = [];\r\n\t\tmodule.webpackPolyfill = 1;\r\n\t}\r\n\treturn module;\r\n}\r\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// (webpack)/buildin/module.js\n// module id = 16\n// module chunks = 0","'use strict';\n\nObject.defineProperty(exports, \"__esModule\", {\n\tvalue: true\n});\nexports['default'] = symbolObservablePonyfill;\nfunction symbolObservablePonyfill(root) {\n\tvar result;\n\tvar _Symbol = root.Symbol;\n\n\tif (typeof _Symbol === 'function') {\n\t\tif (_Symbol.observable) {\n\t\t\tresult = _Symbol.observable;\n\t\t} else {\n\t\t\tresult = _Symbol('observable');\n\t\t\t_Symbol.observable = result;\n\t\t}\n\t} else {\n\t\tresult = '@@observable';\n\t}\n\n\treturn result;\n};\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/symbol-observable/lib/ponyfill.js\n// module id = 17\n// module chunks = 0","'use strict';\n\nexports.__esModule = true;\nexports['default'] = combineReducers;\n\nvar _createStore = require('./createStore');\n\nvar _isPlainObject = require('lodash/isPlainObject');\n\nvar _isPlainObject2 = _interopRequireDefault(_isPlainObject);\n\nvar _warning = require('./utils/warning');\n\nvar _warning2 = _interopRequireDefault(_warning);\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }\n\nfunction getUndefinedStateErrorMessage(key, action) {\n var actionType = action && action.type;\n var actionName = actionType && '\"' + actionType.toString() + '\"' || 'an action';\n\n return 'Given action ' + actionName + ', reducer \"' + key + '\" returned undefined. ' + 'To ignore an action, you must explicitly return the previous state.';\n}\n\nfunction getUnexpectedStateShapeWarningMessage(inputState, reducers, action, unexpectedKeyCache) {\n var reducerKeys = Object.keys(reducers);\n var argumentName = action && action.type === _createStore.ActionTypes.INIT ? 'preloadedState argument passed to createStore' : 'previous state received by the reducer';\n\n if (reducerKeys.length === 0) {\n return 'Store does not have a valid reducer. Make sure the argument passed ' + 'to combineReducers is an object whose values are reducers.';\n }\n\n if (!(0, _isPlainObject2['default'])(inputState)) {\n return 'The ' + argumentName + ' has unexpected type of \"' + {}.toString.call(inputState).match(/\\s([a-z|A-Z]+)/)[1] + '\". Expected argument to be an object with the following ' + ('keys: \"' + reducerKeys.join('\", \"') + '\"');\n }\n\n var unexpectedKeys = Object.keys(inputState).filter(function (key) {\n return !reducers.hasOwnProperty(key) && !unexpectedKeyCache[key];\n });\n\n unexpectedKeys.forEach(function (key) {\n unexpectedKeyCache[key] = true;\n });\n\n if (unexpectedKeys.length > 0) {\n return 'Unexpected ' + (unexpectedKeys.length > 1 ? 'keys' : 'key') + ' ' + ('\"' + unexpectedKeys.join('\", \"') + '\" found in ' + argumentName + '. ') + 'Expected to find one of the known reducer keys instead: ' + ('\"' + reducerKeys.join('\", \"') + '\". Unexpected keys will be ignored.');\n }\n}\n\nfunction assertReducerSanity(reducers) {\n Object.keys(reducers).forEach(function (key) {\n var reducer = reducers[key];\n var initialState = reducer(undefined, { type: _createStore.ActionTypes.INIT });\n\n if (typeof initialState === 'undefined') {\n throw new Error('Reducer \"' + key + '\" returned undefined during initialization. ' + 'If the state passed to the reducer is undefined, you must ' + 'explicitly return the initial state. The initial state may ' + 'not be undefined.');\n }\n\n var type = '@@redux/PROBE_UNKNOWN_ACTION_' + Math.random().toString(36).substring(7).split('').join('.');\n if (typeof reducer(undefined, { type: type }) === 'undefined') {\n throw new Error('Reducer \"' + key + '\" returned undefined when probed with a random type. ' + ('Don\\'t try to handle ' + _createStore.ActionTypes.INIT + ' or other actions in \"redux/*\" ') + 'namespace. They are considered private. Instead, you must return the ' + 'current state for any unknown actions, unless it is undefined, ' + 'in which case you must return the initial state, regardless of the ' + 'action type. The initial state may not be undefined.');\n }\n });\n}\n\n/**\n * Turns an object whose values are different reducer functions, into a single\n * reducer function. It will call every child reducer, and gather their results\n * into a single state object, whose keys correspond to the keys of the passed\n * reducer functions.\n *\n * @param {Object} reducers An object whose values correspond to different\n * reducer functions that need to be combined into one. One handy way to obtain\n * it is to use ES6 `import * as reducers` syntax. The reducers may never return\n * undefined for any action. Instead, they should return their initial state\n * if the state passed to them was undefined, and the current state for any\n * unrecognized action.\n *\n * @returns {Function} A reducer function that invokes every reducer inside the\n * passed object, and builds a state object with the same shape.\n */\nfunction combineReducers(reducers) {\n var reducerKeys = Object.keys(reducers);\n var finalReducers = {};\n for (var i = 0; i < reducerKeys.length; i++) {\n var key = reducerKeys[i];\n\n if (process.env.NODE_ENV !== 'production') {\n if (typeof reducers[key] === 'undefined') {\n (0, _warning2['default'])('No reducer provided for key \"' + key + '\"');\n }\n }\n\n if (typeof reducers[key] === 'function') {\n finalReducers[key] = reducers[key];\n }\n }\n var finalReducerKeys = Object.keys(finalReducers);\n\n if (process.env.NODE_ENV !== 'production') {\n var unexpectedKeyCache = {};\n }\n\n var sanityError;\n try {\n assertReducerSanity(finalReducers);\n } catch (e) {\n sanityError = e;\n }\n\n return function combination() {\n var state = arguments.length <= 0 || arguments[0] === undefined ? {} : arguments[0];\n var action = arguments[1];\n\n if (sanityError) {\n throw sanityError;\n }\n\n if (process.env.NODE_ENV !== 'production') {\n var warningMessage = getUnexpectedStateShapeWarningMessage(state, finalReducers, action, unexpectedKeyCache);\n if (warningMessage) {\n (0, _warning2['default'])(warningMessage);\n }\n }\n\n var hasChanged = false;\n var nextState = {};\n for (var i = 0; i < finalReducerKeys.length; i++) {\n var key = finalReducerKeys[i];\n var reducer = finalReducers[key];\n var previousStateForKey = state[key];\n var nextStateForKey = reducer(previousStateForKey, action);\n if (typeof nextStateForKey === 'undefined') {\n var errorMessage = getUndefinedStateErrorMessage(key, action);\n throw new Error(errorMessage);\n }\n nextState[key] = nextStateForKey;\n hasChanged = hasChanged || nextStateForKey !== previousStateForKey;\n }\n return hasChanged ? nextState : state;\n };\n}\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/redux/lib/combineReducers.js\n// module id = 18\n// module chunks = 0","'use strict';\n\nexports.__esModule = true;\nexports['default'] = warning;\n/**\n * Prints a warning in the console if it exists.\n *\n * @param {String} message The warning message.\n * @returns {void}\n */\nfunction warning(message) {\n /* eslint-disable no-console */\n if (typeof console !== 'undefined' && typeof console.error === 'function') {\n console.error(message);\n }\n /* eslint-enable no-console */\n try {\n // This error was thrown as a convenience so that if you enable\n // \"break on all exceptions\" in your console,\n // it would pause the execution at this line.\n throw new Error(message);\n /* eslint-disable no-empty */\n } catch (e) {}\n /* eslint-enable no-empty */\n}\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/redux/lib/utils/warning.js\n// module id = 19\n// module chunks = 0","'use strict';\n\nexports.__esModule = true;\nexports['default'] = bindActionCreators;\nfunction bindActionCreator(actionCreator, dispatch) {\n return function () {\n return dispatch(actionCreator.apply(undefined, arguments));\n };\n}\n\n/**\n * Turns an object whose values are action creators, into an object with the\n * same keys, but with every function wrapped into a `dispatch` call so they\n * may be invoked directly. This is just a convenience method, as you can call\n * `store.dispatch(MyActionCreators.doSomething())` yourself just fine.\n *\n * For convenience, you can also pass a single function as the first argument,\n * and get a function in return.\n *\n * @param {Function|Object} actionCreators An object whose values are action\n * creator functions. One handy way to obtain it is to use ES6 `import * as`\n * syntax. You may also pass a single function.\n *\n * @param {Function} dispatch The `dispatch` function available on your Redux\n * store.\n *\n * @returns {Function|Object} The object mimicking the original object, but with\n * every action creator wrapped into the `dispatch` call. If you passed a\n * function as `actionCreators`, the return value will also be a single\n * function.\n */\nfunction bindActionCreators(actionCreators, dispatch) {\n if (typeof actionCreators === 'function') {\n return bindActionCreator(actionCreators, dispatch);\n }\n\n if (typeof actionCreators !== 'object' || actionCreators === null) {\n throw new Error('bindActionCreators expected an object or a function, instead received ' + (actionCreators === null ? 'null' : typeof actionCreators) + '. ' + 'Did you write \"import ActionCreators from\" instead of \"import * as ActionCreators from\"?');\n }\n\n var keys = Object.keys(actionCreators);\n var boundActionCreators = {};\n for (var i = 0; i < keys.length; i++) {\n var key = keys[i];\n var actionCreator = actionCreators[key];\n if (typeof actionCreator === 'function') {\n boundActionCreators[key] = bindActionCreator(actionCreator, dispatch);\n }\n }\n return boundActionCreators;\n}\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/redux/lib/bindActionCreators.js\n// module id = 20\n// module chunks = 0","'use strict';\n\nexports.__esModule = true;\n\nvar _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; };\n\nexports['default'] = applyMiddleware;\n\nvar _compose = require('./compose');\n\nvar _compose2 = _interopRequireDefault(_compose);\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }\n\n/**\n * Creates a store enhancer that applies middleware to the dispatch method\n * of the Redux store. This is handy for a variety of tasks, such as expressing\n * asynchronous actions in a concise manner, or logging every action payload.\n *\n * See `redux-thunk` package as an example of the Redux middleware.\n *\n * Because middleware is potentially asynchronous, this should be the first\n * store enhancer in the composition chain.\n *\n * Note that each middleware will be given the `dispatch` and `getState` functions\n * as named arguments.\n *\n * @param {...Function} middlewares The middleware chain to be applied.\n * @returns {Function} A store enhancer applying the middleware.\n */\nfunction applyMiddleware() {\n for (var _len = arguments.length, middlewares = Array(_len), _key = 0; _key < _len; _key++) {\n middlewares[_key] = arguments[_key];\n }\n\n return function (createStore) {\n return function (reducer, preloadedState, enhancer) {\n var store = createStore(reducer, preloadedState, enhancer);\n var _dispatch = store.dispatch;\n var chain = [];\n\n var middlewareAPI = {\n getState: store.getState,\n dispatch: function dispatch(action) {\n return _dispatch(action);\n }\n };\n chain = middlewares.map(function (middleware) {\n return middleware(middlewareAPI);\n });\n _dispatch = _compose2['default'].apply(undefined, chain)(store.dispatch);\n\n return _extends({}, store, {\n dispatch: _dispatch\n });\n };\n };\n}\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/redux/lib/applyMiddleware.js\n// module id = 21\n// module chunks = 0","\"use strict\";\n\nexports.__esModule = true;\nexports[\"default\"] = compose;\n/**\n * Composes single-argument functions from right to left. The rightmost\n * function can take multiple arguments as it provides the signature for\n * the resulting composite function.\n *\n * @param {...Function} funcs The functions to compose.\n * @returns {Function} A function obtained by composing the argument functions\n * from right to left. For example, compose(f, g, h) is identical to doing\n * (...args) => f(g(h(...args))).\n */\n\nfunction compose() {\n for (var _len = arguments.length, funcs = Array(_len), _key = 0; _key < _len; _key++) {\n funcs[_key] = arguments[_key];\n }\n\n if (funcs.length === 0) {\n return function (arg) {\n return arg;\n };\n }\n\n if (funcs.length === 1) {\n return funcs[0];\n }\n\n var last = funcs[funcs.length - 1];\n var rest = funcs.slice(0, -1);\n return function () {\n return rest.reduceRight(function (composed, f) {\n return f(composed);\n }, last.apply(undefined, arguments));\n };\n}\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/redux/lib/compose.js\n// module id = 22\n// module chunks = 0","'use strict';\n\nexports.__esModule = true;\nfunction createThunkMiddleware(extraArgument) {\n return function (_ref) {\n var dispatch = _ref.dispatch,\n getState = _ref.getState;\n return function (next) {\n return function (action) {\n if (typeof action === 'function') {\n return action(dispatch, getState, extraArgument);\n }\n\n return next(action);\n };\n };\n };\n}\n\nvar thunk = createThunkMiddleware();\nthunk.withExtraArgument = createThunkMiddleware;\n\nexports['default'] = thunk;\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/redux-thunk/lib/index.js\n// module id = 23\n// module chunks = 0","module.exports = {\n\tTHUMBNAIL_SIZE: 300 * $.bracketedDevicePixelRatio()\n};\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./src/constants.js\n// module id = 24\n// module chunks = 0","var RESTBASE_ENDPOINT = '/api/rest_v1/page/summary/',\n\tRESTBASE_PROFILE = 'https://www.mediawiki.org/wiki/Specs/Summary/1.0.0',\n\tcreateModel = require( '../preview/model' ).createModel,\n\t$ = window.jQuery,\n\tmw = window.mediaWiki;\n\n/**\n * RESTBase gateway factory\n *\n * @param {Function} ajax function from jQuery for example\n * @param {ext.popups.constants} config set of configuration values\n * @returns {ext.popups.Gateway}\n */\nfunction createRESTBaseGateway( ajax, config ) {\n\n\t/**\n\t * Fetch page data from the API\n\t *\n\t * @param {String} title\n\t * @return {jQuery.Promise}\n\t */\n\tfunction fetch( title ) {\n\t\treturn ajax( {\n\t\t\turl: RESTBASE_ENDPOINT + encodeURIComponent( title ),\n\t\t\theaders: {\n\t\t\t\tAccept: 'application/json; charset=utf-8' +\n\t\t\t\t\t'profile=\"' + RESTBASE_PROFILE + '\"'\n\t\t\t}\n\t\t} );\n\t}\n\n\t/**\n\t * Get the page summary from the api and transform the data\n\t *\n\t * @param {String} title\n\t * @returns {jQuery.Promise<ext.popups.PreviewModel>}\n\t */\n\tfunction getPageSummary( title ) {\n\t\treturn fetch( title )\n\t\t\t.then( function( page ) {\n\t\t\t\treturn convertPageToModel( page, config.THUMBNAIL_SIZE );\n\t\t\t} );\n\t}\n\n\treturn {\n\t\tfetch: fetch,\n\t\tconvertPageToModel: convertPageToModel,\n\t\tgetPageSummary: getPageSummary\n\t};\n}\n\n/**\n * Takes the original thumbnail and ensure it fits within limits of THUMBNAIL_SIZE\n *\n * @param {Object} original image\n * @param {int} thumbSize expected thumbnail size\n * @returns {Object}\n */\nfunction generateThumbnailData( original, thumbSize ) {\n\tvar parts = original.source.split( '/' ),\n\t\tfilename = parts[ parts.length - 1 ];\n\n\tif ( thumbSize > original.width && filename.indexOf( '.svg' ) === -1 ) {\n\t\tthumbSize = original.width;\n\t}\n\n\treturn $.extend( {}, original, {\n\t\tsource: parts.join( '/' ) + '/' + thumbSize + 'px-' + filename\n\t} );\n}\n\n/**\n * Transform the rest API response to a preview model\n *\n * @param {Object} page\n * @param {int} thumbSize\n * @returns {ext.popups.PreviewModel}\n */\nfunction convertPageToModel( page, thumbSize ) {\n\treturn createModel(\n\t\tpage.title,\n\t\tnew mw.Title( page.title ).getUrl(),\n\t\tpage.lang,\n\t\tpage.dir,\n\t\tpage.extract,\n\t\tpage.originalimage ? generateThumbnailData( page.originalimage, thumbSize ) : undefined\n\t);\n}\n\nmodule.exports = createRESTBaseGateway;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./src/gateway/rest.js\n// module id = 25\n// module chunks = 0","var TYPE_GENERIC = 'generic',\n\tTYPE_PAGE = 'page';\n\n/**\n * @typedef {Object} ext.popups.PreviewModel\n * @property {String} title\n * @property {String} url The canonical URL of the page being previewed\n * @property {String} languageCode\n * @property {String} languageDirection Either \"ltr\" or \"rtl\"\n * @property {String|undefined} extract `undefined` if the extract isn't\n * viable, e.g. if it's empty after having ellipsis and parentheticals\n * removed\n * @property {String} type Either \"EXTRACT\" or \"GENERIC\"\n * @property {Object|undefined} thumbnail\n */\n\n/**\n * Creates a preview model.\n *\n * @param {String} title\n * @param {String} url The canonical URL of the page being previewed\n * @param {String} languageCode\n * @param {String} languageDirection Either \"ltr\" or \"rtl\"\n * @param {String} extract\n * @param {Object|undefined} thumbnail\n * @return {ext.popups.PreviewModel}\n */\nfunction createModel(\n\ttitle,\n\turl,\n\tlanguageCode,\n\tlanguageDirection,\n\textract,\n\tthumbnail\n) {\n\tvar processedExtract = processExtract( extract ),\n\t\tresult = {\n\t\t\ttitle: title,\n\t\t\turl: url,\n\t\t\tlanguageCode: languageCode,\n\t\t\tlanguageDirection: languageDirection,\n\t\t\textract: processedExtract,\n\t\t\ttype: processedExtract === undefined ? TYPE_GENERIC : TYPE_PAGE,\n\t\t\tthumbnail: thumbnail\n\t\t};\n\n\treturn result;\n}\n\n/**\n * Processes the extract returned by the TextExtracts MediaWiki API query\n * module.\n *\n * @param {String|undefined} extract\n * @return {String|undefined}\n */\nfunction processExtract( extract ) {\n\tvar result;\n\n\tif ( extract === undefined || extract === '' ) {\n\t\treturn undefined;\n\t}\n\n\tresult = extract;\n\tresult = removeParentheticals( result );\n\tresult = removeEllipsis( result );\n\n\treturn result.length > 0 ? result : undefined;\n}\n\n/**\n * Removes the trailing ellipsis from the extract, if it's there.\n *\n * This function was extracted from\n * `mw.popups.renderer.article#removeEllipsis`.\n *\n * @param {String} extract\n * @return {String}\n */\nfunction removeEllipsis( extract ) {\n\treturn extract.replace( /\\.\\.\\.$/, '' );\n}\n\n/**\n * Removes parentheticals from the extract.\n *\n * If the parenthesis are unbalanced or out of order, then the extract is\n * returned without further processing.\n *\n * This function was extracted from\n * `mw.popups.renderer.article#removeParensFromText`.\n *\n * @param {String} extract\n * @return {String}\n */\nfunction removeParentheticals( extract ) {\n\tvar\n\t\tch,\n\t\tresult = '',\n\t\tlevel = 0,\n\t\ti = 0;\n\n\tfor ( i; i < extract.length; i++ ) {\n\t\tch = extract.charAt( i );\n\n\t\tif ( ch === ')' && level === 0 ) {\n\t\t\treturn extract;\n\t\t}\n\t\tif ( ch === '(' ) {\n\t\t\tlevel++;\n\t\t\tcontinue;\n\t\t} else if ( ch === ')' ) {\n\t\t\tlevel--;\n\t\t\tcontinue;\n\t\t}\n\t\tif ( level === 0 ) {\n\t\t\t// Remove leading spaces before brackets\n\t\t\tif ( ch === ' ' && extract.charAt( i + 1 ) === '(' ) {\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tresult += ch;\n\t\t}\n\t}\n\n\treturn ( level === 0 ) ? result : extract;\n}\n\nmodule.exports = {\n\t/**\n\t* @constant {String}\n\t*/\n\tTYPE_GENERIC: TYPE_GENERIC,\n\t/**\n\t* @constant {String}\n\t*/\n\tTYPE_PAGE: TYPE_PAGE,\n\tcreateModel: createModel\n};\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./src/preview/model.js\n// module id = 26\n// module chunks = 0","var EXTRACT_LENGTH = 525,\n\t// Public and private cache lifetime (5 minutes)\n\tCACHE_LIFETIME = 300,\n\tcreateModel = require( '../preview/model' ).createModel;\n\n/**\n * MediaWiki API gateway factory\n *\n * @param {mw.Api} api\n * @param {mw.ext.constants} config\n * @returns {ext.popups.Gateway}\n */\nfunction createMediaWikiApiGateway( api, config ) {\n\n\t/**\n\t * Fetch page data from the API\n\t *\n\t * @param {String} title\n\t * @return {jQuery.Promise}\n\t */\n\tfunction fetch( title ) {\n\t\treturn api.get( {\n\t\t\taction: 'query',\n\t\t\tprop: 'info|extracts|pageimages|revisions|info',\n\t\t\tformatversion: 2,\n\t\t\tredirects: true,\n\t\t\texintro: true,\n\t\t\texchars: EXTRACT_LENGTH,\n\n\t\t\t// There is an added geometric limit on .mwe-popups-extract\n\t\t\t// so that text does not overflow from the card.\n\t\t\texplaintext: true,\n\n\t\t\tpiprop: 'thumbnail',\n\t\t\tpithumbsize: config.THUMBNAIL_SIZE,\n\t\t\trvprop: 'timestamp',\n\t\t\tinprop: 'url',\n\t\t\ttitles: title,\n\t\t\tsmaxage: CACHE_LIFETIME,\n\t\t\tmaxage: CACHE_LIFETIME,\n\t\t\tuselang: 'content'\n\t\t}, {\n\t\t\theaders: {\n\t\t\t\t'X-Analytics': 'preview=1'\n\t\t\t}\n\t\t} );\n\t}\n\n\t/**\n\t * Get the page summary from the api and transform the data\n\t *\n\t * @param {String} title\n\t * @returns {jQuery.Promise<ext.popups.PreviewModel>}\n\t */\n\tfunction getPageSummary( title ) {\n\t\treturn fetch( title )\n\t\t\t.then( extractPageFromResponse )\n\t\t\t.then( convertPageToModel );\n\t}\n\n\treturn {\n\t\tfetch: fetch,\n\t\textractPageFromResponse: extractPageFromResponse,\n\t\tconvertPageToModel: convertPageToModel,\n\t\tgetPageSummary: getPageSummary\n\t};\n}\n\n/**\n * Extract page data from the MediaWiki API response\n *\n * @param {Object} data API response data\n * @throws {Error} Throw an error if page data cannot be extracted,\n * i.e. if the response is empty,\n * @returns {Object}\n */\nfunction extractPageFromResponse( data ) {\n\tif (\n\t\tdata.query &&\n\t\tdata.query.pages &&\n\t\tdata.query.pages.length\n\t) {\n\t\treturn data.query.pages[ 0 ];\n\t}\n\n\tthrow new Error( 'API response `query.pages` is empty.' );\n}\n\n/**\n * Transform the MediaWiki API response to a preview model\n *\n * @param {Object} page\n * @returns {ext.popups.PreviewModel}\n */\nfunction convertPageToModel( page ) {\n\treturn createModel(\n\t\tpage.title,\n\t\tpage.canonicalurl,\n\t\tpage.pagelanguagehtmlcode,\n\t\tpage.pagelanguagedir,\n\t\tpage.extract,\n\t\tpage.thumbnail\n\t);\n}\n\nmodule.exports = createMediaWikiApiGateway;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./src/gateway/mediawiki.js\n// module id = 27\n// module chunks = 0","/**\n * @typedef {Object} ext.popups.UserSettings\n */\n\nvar IS_ENABLED_KEY = 'mwe-popups-enabled',\n\tPREVIEW_COUNT_KEY = 'ext.popups.core.previewCount';\n\n/**\n * Given the global state of the application, creates an object whose methods\n * encapsulate all interactions with the given User Agent's storage.\n *\n * @param {mw.storage} storage The `mw.storage` singleton instance\n *\n * @return {ext.popups.UserSettings}\n */\nmodule.exports = function ( storage ) {\n\treturn {\n\n\t\t/**\n\t\t * Gets whether or not the user has previously enabled Page Previews.\n\t\t *\n\t\t * N.B. that if the user hasn't previously enabled or disabled Page\n\t\t * Previews, i.e. mw.popups.userSettings.setIsEnabled(true), then they\n\t\t * are treated as if they have enabled them.\n\t\t *\n\t\t * @return {Boolean}\n\t\t */\n\t\tgetIsEnabled: function () {\n\t\t\treturn storage.get( IS_ENABLED_KEY ) !== '0';\n\t\t},\n\n\t\t/**\n\t\t * Sets whether or not the user has enabled Page Previews.\n\t\t *\n\t\t * @param {Boolean} isEnabled\n\t\t */\n\t\tsetIsEnabled: function ( isEnabled ) {\n\t\t\tstorage.set( IS_ENABLED_KEY, isEnabled ? '1' : '0' );\n\t\t},\n\n\t\t/**\n\t\t * Gets whether or not the user has previously enabled **or disabled**\n\t\t * Page Previews.\n\t\t *\n\t\t * @return {Boolean}\n\t\t */\n\t\thasIsEnabled: function () {\n\t\t\treturn storage.get( IS_ENABLED_KEY, undefined ) !== undefined;\n\t\t},\n\n\t\t/**\n\t\t * Gets the number of Page Previews that the user has seen.\n\t\t *\n\t\t * If the storage isn't available, then -1 is returned.\n\t\t *\n\t\t * @return {Number}\n\t\t */\n\t\tgetPreviewCount: function () {\n\t\t\tvar result = storage.get( PREVIEW_COUNT_KEY );\n\n\t\t\tif ( result === false ) {\n\t\t\t\treturn -1;\n\t\t\t} else if ( result === null ) {\n\t\t\t\treturn 0;\n\t\t\t}\n\n\t\t\treturn parseInt( result, 10 );\n\t\t},\n\n\t\t/**\n\t\t * Sets the number of Page Previews that the user has seen.\n\t\t *\n\t\t * @param {Number} count\n\t\t */\n\t\tsetPreviewCount: function ( count ) {\n\t\t\tstorage.set( PREVIEW_COUNT_KEY, count.toString() );\n\t\t}\n\t};\n};\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./src/userSettings.js\n// module id = 28\n// module chunks = 0","var mw = window.mediaWiki,\n\t$ = jQuery;\n\n/**\n * @typedef {Object} ext.popups.PreviewBehavior\n * @property {String} settingsUrl\n * @property {Function} showSettings\n * @property {Function} previewDwell\n * @property {Function} previewAbandon\n */\n\n/**\n * Creates an instance of `ext.popups.PreviewBehavior`.\n *\n * If the user is logged out, then clicking the cog should show the settings\n * modal.\n *\n * If the user is logged in, then clicking the cog should send them to the\n * Special:Preferences page with the \"Beta features\" tab open if Page Previews\n * is enabled as a beta feature, or the \"Appearance\" tab otherwise.\n *\n * @param {mw.Map} config\n * @param {mw.User} user\n * @param {Object} actions The action creators bound to the Redux store\n * @return {ext.popups.PreviewBehavior}\n */\nmodule.exports = function ( config, user, actions ) {\n\tvar isBetaFeature = config.get( 'wgPopupsBetaFeature' ),\n\t\trawTitle,\n\t\tsettingsUrl,\n\t\tshowSettings = $.noop;\n\n\tif ( user.isAnon() ) {\n\t\tshowSettings = function ( event ) {\n\t\t\tevent.preventDefault();\n\n\t\t\tactions.showSettings();\n\t\t};\n\t} else {\n\t\trawTitle = 'Special:Preferences#mw-prefsection-';\n\t\trawTitle += isBetaFeature ? 'betafeatures' : 'rendering';\n\n\t\tsettingsUrl = mw.Title.newFromText( rawTitle )\n\t\t\t.getUrl();\n\t}\n\n\treturn {\n\t\tsettingsUrl: settingsUrl,\n\t\tshowSettings: showSettings,\n\t\tpreviewDwell: actions.previewDwell,\n\t\tpreviewAbandon: actions.abandon,\n\t\tpreviewShow: actions.previewShow\n\t};\n};\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./src/previewBehavior.js\n// module id = 29\n// module chunks = 0","var mw = window.mediaWiki,\n\t$ = jQuery;\n\n/**\n * Creates an instance of an EventLogging schema that can be used to log\n * Popups events.\n *\n * @param {mw.Map} config\n * @param {Window} window\n * @return {mw.eventLog.Schema}\n */\nmodule.exports = function ( config, window ) {\n\tvar samplingRate = config.get( 'wgPopupsSchemaSamplingRate', 0 );\n\n\tif (\n\t\t!window.navigator ||\n\t\t!$.isFunction( window.navigator.sendBeacon ) ||\n\t\twindow.QUnit\n\t) {\n\t\tsamplingRate = 0;\n\t}\n\n\treturn new mw.eventLog.Schema( 'Popups', samplingRate );\n};\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./src/schema.js\n// module id = 30\n// module chunks = 0","var mw = window.mediaWiki,\n\t$ = jQuery;\n\n/**\n * Creates a render function that will create the settings dialog and return\n * a set of methods to operate on it\n * @returns {Function} render function\n */\nmodule.exports = function () {\n\n\t/**\n\t * Cached settings dialog\n\t *\n\t * @type {jQuery}\n\t */\n\tvar $dialog,\n\t\t/**\n\t\t * Cached settings overlay\n\t\t *\n\t\t * @type {jQuery}\n\t\t */\n\t\t$overlay;\n\n\t/**\n\t * Renders the relevant form and labels in the settings dialog\n\t * @param {Object} boundActions\n\t * @returns {Object} object with methods to affect the rendered UI\n\t */\n\treturn function ( boundActions ) {\n\n\t\tif ( !$dialog ) {\n\t\t\t$dialog = createSettingsDialog();\n\t\t\t$overlay = $( '<div>' ).addClass( 'mwe-popups-overlay' );\n\n\t\t\t// Setup event bindings\n\n\t\t\t$dialog.find( '.save' ).click( function () {\n\t\t\t\t// Find the selected value (simple|advanced|off)\n\t\t\t\tvar selected = getSelectedSetting( $dialog ),\n\t\t\t\t\t// Only simple means enabled, advanced is disabled in favor of\n\t\t\t\t\t// NavPops and off means disabled.\n\t\t\t\t\tenabled = selected === 'simple';\n\n\t\t\t\tboundActions.saveSettings( enabled );\n\t\t\t} );\n\t\t\t$dialog.find( '.close, .okay' ).click( boundActions.hideSettings );\n\t\t}\n\n\t\treturn {\n\t\t\t/**\n\t\t\t * Append the dialog and overlay to a DOM element\n\t\t\t * @param {HTMLElement} el\n\t\t\t */\n\t\t\tappendTo: function ( el ) {\n\t\t\t\t$overlay.appendTo( el );\n\t\t\t\t$dialog.appendTo( el );\n\t\t\t},\n\n\t\t\t/**\n\t\t\t * Show the settings element and position it correctly\n\t\t\t */\n\t\t\tshow: function () {\n\t\t\t\tvar h = $( window ).height(),\n\t\t\t\t\tw = $( window ).width();\n\n\t\t\t\t$overlay.show();\n\n\t\t\t\t// FIXME: Should recalc on browser resize\n\t\t\t\t$dialog\n\t\t\t\t\t.show()\n\t\t\t\t\t.css( 'left', ( w - $dialog.outerWidth( true ) ) / 2 )\n\t\t\t\t\t.css( 'top', ( h - $dialog.outerHeight( true ) ) / 2 );\n\t\t\t},\n\n\t\t\t/**\n\t\t\t * Hide the settings dialog.\n\t\t\t */\n\t\t\thide: function () {\n\t\t\t\t$overlay.hide();\n\t\t\t\t$dialog.hide();\n\t\t\t},\n\n\t\t\t/**\n\t\t\t * Toggle the help dialog on or off\n\t\t\t * @param {Boolean} visible if you want to show or hide the help dialog\n\t\t\t */\n\t\t\ttoggleHelp: function ( visible ) {\n\t\t\t\ttoggleHelp( $dialog, visible );\n\t\t\t},\n\n\t\t\t/**\n\t\t\t * Update the form depending on the enabled flag\n\t\t\t *\n\t\t\t * If false and no navpops, then checks 'off'\n\t\t\t * If true, then checks 'on'\n\t\t\t * If false, and there are navpops, then checks 'advanced'\n\t\t\t *\n\t\t\t * @param {Boolean} enabled if page previews are enabled\n\t\t\t */\n\t\t\tsetEnabled: function ( enabled ) {\n\t\t\t\tvar name = 'off';\n\t\t\t\tif ( enabled ) {\n\t\t\t\t\tname = 'simple';\n\t\t\t\t} else if ( isNavPopupsEnabled() ) {\n\t\t\t\t\tname = 'advanced';\n\t\t\t\t}\n\n\t\t\t\t// Check the appropiate radio button\n\t\t\t\t$dialog.find( '#mwe-popups-settings-' + name )\n\t\t\t\t\t.prop( 'checked', true );\n\t\t\t}\n\t\t};\n\t};\n};\n\n/**\n * Create the settings dialog\n *\n * @return {jQuery} settings dialog\n */\nfunction createSettingsDialog() {\n\tvar $el,\n\t\tpath = mw.config.get( 'wgExtensionAssetsPath' ) + '/Popups/resources/ext.popups/images/',\n\t\tchoices = [\n\t\t\t{\n\t\t\t\tid: 'simple',\n\t\t\t\tname: mw.msg( 'popups-settings-option-simple' ),\n\t\t\t\tdescription: mw.msg( 'popups-settings-option-simple-description' ),\n\t\t\t\timage: path + 'hovercard.svg',\n\t\t\t\tisChecked: true\n\t\t\t},\n\t\t\t{\n\t\t\t\tid: 'advanced',\n\t\t\t\tname: mw.msg( 'popups-settings-option-advanced' ),\n\t\t\t\tdescription: mw.msg( 'popups-settings-option-advanced-description' ),\n\t\t\t\timage: path + 'navpop.svg'\n\t\t\t},\n\t\t\t{\n\t\t\t\tid: 'off',\n\t\t\t\tname: mw.msg( 'popups-settings-option-off' )\n\t\t\t}\n\t\t];\n\n\tif ( !isNavPopupsEnabled() ) {\n\t\t// remove the advanced option\n\t\tchoices.splice( 1, 1 );\n\t}\n\n\t// render the template\n\t$el = mw.template.get( 'ext.popups', 'settings.mustache' ).render( {\n\t\theading: mw.msg( 'popups-settings-title' ),\n\t\tcloseLabel: mw.msg( 'popups-settings-cancel' ),\n\t\tsaveLabel: mw.msg( 'popups-settings-save' ),\n\t\thelpText: mw.msg( 'popups-settings-help' ),\n\t\tokLabel: mw.msg( 'popups-settings-help-ok' ),\n\t\tdescriptionText: mw.msg( 'popups-settings-description' ),\n\t\tchoices: choices\n\t} );\n\n\treturn $el;\n}\n\n/**\n * Get the selected value on the radio button\n *\n * @param {jQuery.Object} $el the element to extract the setting from\n * @return {String} Which should be (simple|advanced|off)\n */\nfunction getSelectedSetting( $el ) {\n\treturn $el.find(\n\t\t'input[name=mwe-popups-setting]:checked, #mwe-popups-settings'\n\t).val();\n}\n\n/**\n * Toggles the visibility between a form and the help\n * @param {jQuery.Object} $el element that contains form and help\n * @param {Boolean} visible if the help should be visible, or the form\n */\nfunction toggleHelp( $el, visible ) {\n\tvar $dialog = $( '#mwe-popups-settings' ),\n\t\tformSelectors = 'main, .save, .close',\n\t\thelpSelectors = '.mwe-popups-settings-help, .okay';\n\n\tif ( visible ) {\n\t\t$dialog.find( formSelectors ).hide();\n\t\t$dialog.find( helpSelectors ).show();\n\t} else {\n\t\t$dialog.find( formSelectors ).show();\n\t\t$dialog.find( helpSelectors ).hide();\n\t}\n}\n\n/**\n * Checks if the NavigationPopups gadget is enabled by looking at the global\n * variables\n * @returns {Boolean} if navpops was found to be enabled\n */\nfunction isNavPopupsEnabled() {\n\t/* global pg: false*/\n\treturn typeof pg !== 'undefined' && pg.fn.disablePopups !== undefined;\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./src/settingsDialog.js\n// module id = 31\n// module chunks = 0","/**\n * @typedef {Function} ext.popups.ChangeListener\n * @param {Object} prevState The previous state\n * @param {Object} state The current state\n */\n\n/**\n * Registers a change listener, which is bound to the\n * [store](http://redux.js.org/docs/api/Store.html).\n *\n * A change listener is a function that is only invoked when the state in the\n * [store](http://redux.js.org/docs/api/Store.html) changes. N.B. that there\n * may not be a 1:1 correspondence with actions being dispatched to the store\n * and the state in the store changing.\n *\n * See [Store#subscribe](http://redux.js.org/docs/api/Store.html#subscribe)\n * for more information about what change listeners may and may not do.\n *\n * @param {Redux.Store} store\n * @param {ext.popups.ChangeListener} callback\n */\nmodule.exports = function ( store, callback ) {\n\t// This function is based on the example in [the documentation for\n\t// Store#subscribe](http://redux.js.org/docs/api/Store.html#subscribe),\n\t// which was written by Dan Abramov.\n\n\tvar state;\n\n\tstore.subscribe( function () {\n\t\tvar prevState = state;\n\n\t\tstate = store.getState();\n\n\t\tif ( prevState !== state ) {\n\t\t\tcallback( prevState, state );\n\t\t}\n\t} );\n};\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./src/changeListener.js\n// module id = 32\n// module chunks = 0","/**\n * Given the global state of the application, creates a function that gets\n * whether or not the user should have Page Previews enabled.\n *\n * If Page Previews is configured as a beta feature (see\n * `$wgPopupsBetaFeature`), the user must be logged in and have enabled the\n * beta feature in order to see previews.\n *\n * If Page Previews is configured as a preference, then the user must either\n * be logged in and have enabled the preference or be logged out and have not\n * disabled previews via the settings modal.\n *\n * @param {mw.user} user The `mw.user` singleton instance\n * @param {Object} userSettings An object returned by\n * `mw.popups.createUserSettings`\n * @param {mw.Map} config\n *\n * @return {Boolean}\n */\nmodule.exports = function ( user, userSettings, config ) {\n\tif ( !user.isAnon() ) {\n\t\treturn config.get( 'wgPopupsShouldSendModuleToUser' );\n\t}\n\n\tif ( config.get( 'wgPopupsBetaFeature' ) ) {\n\t\treturn false;\n\t}\n\n\treturn !userSettings.hasIsEnabled() ||\n\t\t( userSettings.hasIsEnabled() && userSettings.getIsEnabled() );\n};\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./src/isEnabled.js\n// module id = 33\n// module chunks = 0","var mw = window.mediaWiki,\n\t$ = jQuery;\n\n/**\n * @private\n *\n * Gets the title of a local page from an href given some configuration.\n *\n * @param {String} href\n * @param {mw.Map} config\n * @return {String|undefined}\n */\nfunction getTitle( href, config ) {\n\tvar linkHref,\n\t\tmatches,\n\t\tqueryLength,\n\t\ttitleRegex = new RegExp( mw.RegExp.escape( config.get( 'wgArticlePath' ) )\n\t\t\t.replace( '\\\\$1', '(.+)' ) );\n\n\t// Skip every URI that mw.Uri cannot parse\n\ttry {\n\t\tlinkHref = new mw.Uri( href );\n\t} catch ( e ) {\n\t\treturn undefined;\n\t}\n\n\t// External links\n\tif ( linkHref.host !== location.hostname ) {\n\t\treturn undefined;\n\t}\n\n\tqueryLength = Object.keys( linkHref.query ).length;\n\n\t// No query params (pretty URL)\n\tif ( !queryLength ) {\n\t\tmatches = titleRegex.exec( linkHref.path );\n\t\treturn matches ? decodeURIComponent( matches[ 1 ] ) : undefined;\n\t} else if ( queryLength === 1 && linkHref.query.hasOwnProperty( 'title' ) ) {\n\t\t// URL is not pretty, but only has a `title` parameter\n\t\treturn linkHref.query.title;\n\t}\n\n\treturn undefined;\n}\n\n/**\n * Processes and returns link elements (or \"`<a>`s\") that are eligible for\n * previews in a given container.\n *\n * An `<a>` is eligible for a preview if:\n *\n * * It has an href and a title, i.e. `<a href=\"/wiki/Foo\" title=\"Foo\" />`.\n * * It doesn't have any blacklisted CSS classes.\n * * Its href is a valid URI of a page on the local wiki.\n *\n * If an `<a>` is eligible, then the title of the page on the local wiki is\n * stored in the `data-previews-page-title` attribute for later reuse.\n *\n * @param {jQuery} $container\n * @param {String[]} blacklist If an `<a>` has one or more of these CSS\n * classes, then it will be ignored.\n * @param {mw.Map} config\n *\n * @return {jQuery}\n */\nmodule.exports = function ( $container, blacklist, config ) {\n\tvar contentNamespaces;\n\n\tcontentNamespaces = config.get( 'wgContentNamespaces' );\n\n\treturn $container\n\t\t.find( 'a[href][title]:not(' + blacklist.join( ', ' ) + ')' )\n\t\t.filter( function () {\n\t\t\tvar title,\n\t\t\t\ttitleText = getTitle( this.href, config );\n\n\t\t\tif ( !titleText ) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\t// Is titleText in a content namespace?\n\t\t\ttitle = mw.Title.newFromText( titleText );\n\t\t\tif ( title && ( $.inArray( title.namespace, contentNamespaces ) >= 0 ) ) {\n\t\t\t\t$( this ).data( 'page-previews-title', titleText );\n\n\t\t\t\treturn true;\n\t\t\t}\n\t\t} );\n};\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./src/processLinks.js\n// module id = 34\n// module chunks = 0","var mw = window.mediaWiki,\n\t$ = jQuery,\n\tisSafari = navigator.userAgent.match( /Safari/ ) !== null,\n\twait = require( './wait' ),\n\tSIZES = {\n\t\tportraitImage: {\n\t\t\th: 250, // Exact height\n\t\t\tw: 203 // Max width\n\t\t},\n\t\tlandscapeImage: {\n\t\t\th: 200, // Max height\n\t\t\tw: 300 // Exact Width\n\t\t},\n\t\tlandscapePopupWidth: 450,\n\t\tportraitPopupWidth: 300,\n\t\tpokeySize: 8 // Height of the pokey.\n\t},\n\t$window = $( window );\n\n/**\n * Extracted from `mw.popups.createSVGMasks`.\n */\nfunction createPokeyMasks() {\n\t$( '<div>' )\n\t\t.attr( 'id', 'mwe-popups-svg' )\n\t\t.html(\n\t\t\t'<svg width=\"0\" height=\"0\">' +\n\t\t\t\t'<defs>' +\n\t\t\t\t\t'<clippath id=\"mwe-popups-mask\">' +\n\t\t\t\t\t\t'<polygon points=\"0 8, 10 8, 18 0, 26 8, 1000 8, 1000 1000, 0 1000\"/>' +\n\t\t\t\t\t'</clippath>' +\n\t\t\t\t\t'<clippath id=\"mwe-popups-mask-flip\">' +\n\t\t\t\t\t\t'<polygon points=\"0 8, 274 8, 282 0, 290 8, 1000 8, 1000 1000, 0 1000\"/>' +\n\t\t\t\t\t'</clippath>' +\n\t\t\t\t\t'<clippath id=\"mwe-popups-landscape-mask\">' +\n\t\t\t\t\t\t'<polygon points=\"0 8, 174 8, 182 0, 190 8, 1000 8, 1000 1000, 0 1000\"/>' +\n\t\t\t\t\t'</clippath>' +\n\t\t\t\t\t'<clippath id=\"mwe-popups-landscape-mask-flip\">' +\n\t\t\t\t\t\t'<polygon points=\"0 0, 1000 0, 1000 243, 190 243, 182 250, 174 243, 0 243\"/>' +\n\t\t\t\t\t'</clippath>' +\n\t\t\t\t'</defs>' +\n\t\t\t'</svg>'\n\t\t)\n\t\t.appendTo( document.body );\n}\n\n/**\n * Initializes the renderer.\n */\nfunction init() {\n\tcreatePokeyMasks();\n}\n\n/**\n * The model of how a view is rendered, which is constructed from a response\n * from the gateway.\n *\n * TODO: Rename `isTall` to `isPortrait`.\n *\n * @typedef {Object} ext.popups.Preview\n * @property {jQuery} el\n * @property {Boolean} hasThumbnail\n * @property {Object} thumbnail\n * @property {Boolean} isTall Sugar around\n * `preview.hasThumbnail && thumbnail.isTall`\n */\n\n/**\n * Renders a preview given data from the {@link gateway ext.popups.Gateway}.\n * The preview is rendered and added to the DOM but will remain hidden until\n * the `show` method is called.\n *\n * Previews are rendered at:\n *\n * # The position of the mouse when the user dwells on the link with their\n * mouse.\n * # The centermost point of the link when the user dwells on the link with\n * their keboard or other assistive device.\n *\n * Since the content of the preview doesn't change but its position might, we\n * distinguish between \"rendering\" - generating HTML from a MediaWiki API\n * response - and \"showing/hiding\" - positioning the layout and changing its\n * orientation, if necessary.\n *\n * @param {ext.popups.PreviewModel} model\n * @return {ext.popups.Preview}\n */\nfunction render( model ) {\n\tvar preview = model.extract === undefined ? createEmptyPreview( model ) : createPreview( model );\n\n\treturn {\n\n\t\t/**\n\t\t * Shows the preview given an event representing the user's interaction\n\t\t * with the active link, e.g. an instance of\n\t\t * [MouseEvent](https://developer.mozilla.org/en/docs/Web/API/MouseEvent).\n\t\t *\n\t\t * See `show` for more detail.\n\t\t *\n\t\t * @param {Event} event\n\t\t * @param {Object} boundActions The\n\t\t * [bound action creators](http://redux.js.org/docs/api/bindActionCreators.html)\n\t\t * that were (likely) created in [boot.js](./boot.js).\n\t\t * @return {jQuery.Promise}\n\t\t */\n\t\tshow: function ( event, boundActions ) {\n\t\t\treturn show( preview, event, boundActions );\n\t\t},\n\n\t\t/**\n\t\t * Hides the preview.\n\t\t *\n\t\t * See `hide` for more detail.\n\t\t *\n\t\t * @return {jQuery.Promise}\n\t\t */\n\t\thide: function () {\n\t\t\treturn hide( preview );\n\t\t}\n\t};\n}\n\n/**\n * Creates an instance of the DTO backing a preview.\n *\n * @param {ext.popups.PreviewModel} model\n * @return {ext.popups.Preview}\n */\nfunction createPreview( model ) {\n\tvar templateData,\n\t\tthumbnail = createThumbnail( model.thumbnail ),\n\t\thasThumbnail = thumbnail !== null,\n\n\t\t// FIXME: This should probably be moved into the gateway as we'll soon be\n\t\t// fetching HTML from the API. See\n\t\t// https://phabricator.wikimedia.org/T141651 for more detail.\n\t\textract = renderExtract( model.extract, model.title ),\n\n\t\t$el;\n\n\ttemplateData = $.extend( {}, model, {\n\t\thasThumbnail: hasThumbnail\n\t} );\n\n\t$el = mw.template.get( 'ext.popups', 'preview.mustache' )\n\t\t.render( templateData );\n\n\tif ( hasThumbnail ) {\n\t\t$el.find( '.mwe-popups-discreet' ).append( thumbnail.el );\n\t}\n\n\tif ( extract.length ) {\n\t\t$el.find( '.mwe-popups-extract' ).append( extract );\n\t}\n\n\treturn {\n\t\tel: $el,\n\t\thasThumbnail: hasThumbnail,\n\t\tthumbnail: thumbnail,\n\t\tisTall: hasThumbnail && thumbnail.isTall\n\t};\n}\n\n/**\n * Creates an instance of the DTO backing a preview. In this case the DTO\n * represents a generic preview, which covers the following scenarios:\n *\n * * The page doesn't exist, i.e. the user hovered over a redlink or a\n * redirect to a page that doesn't exist.\n * * The page doesn't have a viable extract.\n *\n * @param {ext.popups.PreviewModel} model\n * @return {ext.popups.Preview}\n */\nfunction createEmptyPreview( model ) {\n\tvar templateData,\n\t\t$el;\n\n\ttemplateData = $.extend( {}, model, {\n\t\textractMsg: mw.msg( 'popups-preview-no-preview' ),\n\t\treadMsg: mw.msg( 'popups-preview-footer-read' )\n\t} );\n\n\t$el = mw.template.get( 'ext.popups', 'preview-empty.mustache' )\n\t\t.render( templateData );\n\n\treturn {\n\t\tel: $el,\n\t\thasThumbnail: false,\n\t\tisTall: false\n\t};\n}\n\n/**\n * Converts the extract into a list of elements, which correspond to fragments\n * of the extract. Fragements that match the title verbatim are wrapped in a\n * `<b>` element.\n *\n * Using the bolded elements of the extract of the page directly is covered by\n * [T141651](https://phabricator.wikimedia.org/T141651).\n *\n * Extracted from `mw.popups.renderer.article.getProcessedElements`.\n *\n * @param {String} extract\n * @param {String} title\n * @return {Array}\n */\nfunction renderExtract( extract, title ) {\n\tvar regExp, escapedTitle,\n\t\telements = [],\n\t\tboldIdentifier = '<bi-' + Math.random() + '>',\n\t\tsnip = '<snip-' + Math.random() + '>';\n\n\ttitle = title.replace( /\\s+/g, ' ' ).trim(); // Remove extra white spaces\n\tescapedTitle = mw.RegExp.escape( title ); // Escape RegExp elements\n\tregExp = new RegExp( '(^|\\\\s)(' + escapedTitle + ')(|$)', 'i' );\n\n\t// Remove text in parentheses along with the parentheses\n\textract = extract.replace( /\\s+/, ' ' ); // Remove extra white spaces\n\n\t// Make title bold in the extract text\n\t// As the extract is html escaped there can be no such string in it\n\t// Also, the title is escaped of RegExp elements thus can't have \"*\"\n\textract = extract.replace( regExp, '$1' + snip + boldIdentifier + '$2' + snip + '$3' );\n\textract = extract.split( snip );\n\n\t$.each( extract, function ( index, part ) {\n\t\tif ( part.indexOf( boldIdentifier ) === 0 ) {\n\t\t\telements.push( $( '<b>' ).text( part.substring( boldIdentifier.length ) ) );\n\t\t} else {\n\t\t\telements.push( document.createTextNode( part ) );\n\t\t}\n\t} );\n\n\treturn elements;\n}\n\n/**\n * Shows the preview.\n *\n * Extracted from `mw.popups.render.openPopup`.\n *\n * TODO: From the perspective of the client, there's no need to distinguish\n * between renderering and showing a preview. Merge #render and Preview#show.\n *\n * @param {ext.popups.Preview} preview\n * @param {Event} event\n * @param {ext.popups.PreviewBehavior} behavior\n * @return {jQuery.Promise} A promise that resolves when the promise has faded\n * in\n */\nfunction show( preview, event, behavior ) {\n\tvar layout = createLayout( preview, event );\n\n\tpreview.el.appendTo( document.body );\n\n\t// Hack to \"refresh\" the SVG so that it's displayed.\n\t//\n\t// Elements get added to the DOM and not to the screen because of different\n\t// namespaces of HTML and SVG.\n\t//\n\t// See http://stackoverflow.com/a/13654655/366138 for more detail.\n\t//\n\t// TODO: Find out how early on in the render that this could be done, e.g.\n\t// createThumbnail?\n\tpreview.el.html( preview.el.html() );\n\n\tlayoutPreview( preview, layout );\n\n\tpreview.el.hover( behavior.previewDwell, behavior.previewAbandon );\n\n\tpreview.el.find( '.mwe-popups-settings-icon' )\n\t\t.attr( 'href', behavior.settingsUrl )\n\t\t.click( behavior.showSettings );\n\n\tpreview.el.show();\n\n\treturn wait( 200 )\n\t\t.then( behavior.previewShow );\n}\n\n/**\n * Extracted from `mw.popups.render.closePopup`.\n *\n * @param {ext.popups.Preview} preview\n * @return {jQuery.Promise} A promise that resolves when the preview has faded\n * out\n */\nfunction hide( preview ) {\n\tvar fadeInClass,\n\t\tfadeOutClass;\n\n\t// FIXME: This method clearly needs access to the layout of the preview.\n\tfadeInClass = ( preview.el.hasClass( 'mwe-popups-fade-in-up' ) ) ?\n\t\t'mwe-popups-fade-in-up' :\n\t\t'mwe-popups-fade-in-down';\n\n\tfadeOutClass = ( fadeInClass === 'mwe-popups-fade-in-up' ) ?\n\t\t'mwe-popups-fade-out-down' :\n\t\t'mwe-popups-fade-out-up';\n\n\tpreview.el\n\t\t.removeClass( fadeInClass )\n\t\t.addClass( fadeOutClass );\n\n\treturn wait( 150 ).then( function () {\n\t\tpreview.el.remove();\n\t} );\n}\n\n/**\n * @typedef {Object} ext.popups.Thumbnail\n * @property {Element} el\n * @property {Boolean} isTall Whether or not the thumbnail is portrait\n */\n\n/**\n * Creates a thumbnail from the representation of a thumbnail returned by the\n * PageImages MediaWiki API query module.\n *\n * If there's no thumbnail, the thumbnail is too small, or the thumbnail's URL\n * contains characters that could be used to perform an\n * [XSS attack via CSS](https://www.owasp.org/index.php/Testing_for_CSS_Injection_(OTG-CLIENT-005)),\n * then `null` is returned.\n *\n * Extracted from `mw.popups.renderer.article.createThumbnail`.\n *\n * @param {Object} rawThumbnail\n * @return {ext.popups.Thumbnail|null}\n */\nfunction createThumbnail( rawThumbnail ) {\n\tvar tall, thumbWidth, thumbHeight,\n\t\tx, y, width, height, clipPath,\n\t\tdevicePixelRatio = $.bracketedDevicePixelRatio();\n\n\tif ( !rawThumbnail ) {\n\t\treturn null;\n\t}\n\n\ttall = rawThumbnail.width < rawThumbnail.height;\n\tthumbWidth = rawThumbnail.width / devicePixelRatio;\n\tthumbHeight = rawThumbnail.height / devicePixelRatio;\n\n\tif (\n\t\t// Image too small for landscape display\n\t\t( !tall && thumbWidth < SIZES.landscapeImage.w ) ||\n\t\t// Image too small for portrait display\n\t\t( tall && thumbHeight < SIZES.portraitImage.h ) ||\n\t\t// These characters in URL that could inject CSS and thus JS\n\t\t(\n\t\t\trawThumbnail.source.indexOf( '\\\\' ) > -1 ||\n\t\t\trawThumbnail.source.indexOf( '\\'' ) > -1 ||\n\t\t\trawThumbnail.source.indexOf( '\\\"' ) > -1\n\t\t)\n\t) {\n\t\treturn null;\n\t}\n\n\tif ( tall ) {\n\t\tx = ( thumbWidth > SIZES.portraitImage.w ) ?\n\t\t\t( ( thumbWidth - SIZES.portraitImage.w ) / -2 ) :\n\t\t\t( SIZES.portraitImage.w - thumbWidth );\n\t\ty = ( thumbHeight > SIZES.portraitImage.h ) ?\n\t\t\t( ( thumbHeight - SIZES.portraitImage.h ) / -2 ) : 0;\n\t\twidth = SIZES.portraitImage.w;\n\t\theight = SIZES.portraitImage.h;\n\t} else {\n\t\tx = 0;\n\t\ty = ( thumbHeight > SIZES.landscapeImage.h ) ?\n\t\t\t( ( thumbHeight - SIZES.landscapeImage.h ) / -2 ) : 0;\n\t\twidth = SIZES.landscapeImage.w + 3;\n\t\theight = ( thumbHeight > SIZES.landscapeImage.h ) ?\n\t\t\tSIZES.landscapeImage.h : thumbHeight;\n\t\tclipPath = 'mwe-popups-mask';\n\t}\n\n\treturn {\n\t\tel: createThumbnailElement(\n\t\t\ttall ? 'mwe-popups-is-tall' : 'mwe-popups-is-not-tall',\n\t\t\trawThumbnail.source,\n\t\t\tx,\n\t\t\ty,\n\t\t\tthumbWidth,\n\t\t\tthumbHeight,\n\t\t\twidth,\n\t\t\theight,\n\t\t\tclipPath\n\t\t),\n\t\tisTall: tall,\n\t\twidth: thumbWidth,\n\t\theight: thumbHeight\n\t};\n}\n\n/**\n * Creates the SVG image element that represents the thumbnail.\n *\n * This function is distinct from `createThumbnail` as it abstracts away some\n * browser issues that are uncovered when manipulating elements across\n * namespaces.\n *\n * @param {String} className\n * @param {String} url\n * @param {Number} x\n * @param {Number} y\n * @param {Number} thumbnailWidth\n * @param {Number} thumbnailHeight\n * @param {Number} width\n * @param {Number} height\n * @param {String} clipPath\n * @return {jQuery}\n */\nfunction createThumbnailElement( className, url, x, y, thumbnailWidth, thumbnailHeight, width, height, clipPath ) {\n\tvar $thumbnailSVGImage, $thumbnail,\n\t\tns = 'http://www.w3.org/2000/svg',\n\n\t\t// Use createElementNS to create the svg:image tag as jQuery uses\n\t\t// createElement instead. Some browsers mistakenly map the image tag to\n\t\t// img tag.\n\t\tsvgElement = document.createElementNS( 'http://www.w3.org/2000/svg', 'image' );\n\n\t$thumbnailSVGImage = $( svgElement );\n\t$thumbnailSVGImage\n\t\t.addClass( className )\n\t\t.attr( {\n\t\t\tx: x,\n\t\t\ty: y,\n\t\t\twidth: thumbnailWidth,\n\t\t\theight: thumbnailHeight,\n\t\t\t'clip-path': 'url(#' + clipPath + ')'\n\t\t} );\n\n\t// Certain browsers, e.g. IE9, will not correctly set attributes from\n\t// foreign namespaces using Element#setAttribute (see T134979). Apart from\n\t// Safari, all supported browsers can set them using Element#setAttributeNS\n\t// (see T134979).\n\tif ( isSafari ) {\n\t\tsvgElement.setAttribute( 'xlink:href', url );\n\t} else {\n\t\tsvgElement.setAttributeNS( ns, 'xlink:href', url );\n\t}\n\t$thumbnail = $( '<svg>' )\n\t\t.attr( {\n\t\t\txmlns: ns,\n\t\t\twidth: width,\n\t\t\theight: height\n\t\t} )\n\t\t.append( $thumbnailSVGImage );\n\n\treturn $thumbnail;\n}\n\n/**\n * Represents the layout of a preview, which consists of a position (`offset`)\n * and whether or not the preview should be flipped horizontally or\n * vertically (`flippedX` and `flippedY` respectively).\n *\n * @typedef {Object} ext.popups.PreviewLayout\n * @property {Object} offset\n * @property {Boolean} flippedX\n * @property {Boolean} flippedY\n */\n\n/**\n * Extracted from `mw.popups.renderer.article.getOffset`.\n *\n * @param {ext.popups.Preview} preview\n * @param {Object} event\n * @return {ext.popups.PreviewLayout}\n */\nfunction createLayout( preview, event ) {\n\tvar flippedX = false,\n\t\tflippedY = false,\n\t\tlink = $( event.target ),\n\t\toffsetTop = ( event.pageY ) ? // If it was a mouse event\n\t\t\t// Position according to mouse\n\t\t\t// Since client rectangles are relative to the viewport,\n\t\t\t// take scroll position into account.\n\t\t\tgetClosestYPosition(\n\t\t\t\tevent.pageY - $window.scrollTop(),\n\t\t\t\tlink.get( 0 ).getClientRects(),\n\t\t\t\tfalse\n\t\t\t) + $window.scrollTop() + SIZES.pokeySize :\n\t\t\t// Position according to link position or size\n\t\t\tlink.offset().top + link.height() + SIZES.pokeySize,\n\t\tclientTop = ( event.clientY ) ?\n\t\t\tevent.clientY :\n\t\t\toffsetTop,\n\t\toffsetLeft = ( event.pageX ) ?\n\t\t\tevent.pageX :\n\t\t\tlink.offset().left;\n\n\t// X Flip\n\tif ( offsetLeft > ( $window.width() / 2 ) ) {\n\t\toffsetLeft += ( !event.pageX ) ? link.width() : 0;\n\t\toffsetLeft -= !preview.isTall ?\n\t\t\tSIZES.portraitPopupWidth :\n\t\t\tSIZES.landscapePopupWidth;\n\t\tflippedX = true;\n\t}\n\n\tif ( event.pageX ) {\n\t\toffsetLeft += ( flippedX ) ? 20 : -20;\n\t}\n\n\t// Y Flip\n\tif ( clientTop > ( $window.height() / 2 ) ) {\n\t\tflippedY = true;\n\n\t\t// Mirror the positioning of the preview when there's no \"Y flip\": rest\n\t\t// the pokey on the edge of the link's bounding rectangle. In this case\n\t\t// the edge is the top-most.\n\t\toffsetTop = link.offset().top - SIZES.pokeySize;\n\n\t\t// Change the Y position to the top of the link\n\t\tif ( event.pageY ) {\n\t\t\t// Since client rectangles are relative to the viewport,\n\t\t\t// take scroll position into account.\n\t\t\toffsetTop = getClosestYPosition(\n\t\t\t\tevent.pageY - $window.scrollTop(),\n\t\t\t\tlink.get( 0 ).getClientRects(),\n\t\t\t\ttrue\n\t\t\t) + $window.scrollTop();\n\t\t}\n\t}\n\n\treturn {\n\t\toffset: {\n\t\t\ttop: offsetTop,\n\t\t\tleft: offsetLeft\n\t\t},\n\t\tflippedX: flippedX,\n\t\tflippedY: flippedY\n\t};\n}\n\n/**\n * Generates a list of declarative CSS classes that represent the layout of\n * the preview.\n *\n * @param {ext.popups.Preview} preview\n * @param {ext.popups.PreviewLayout} layout\n * @return {String[]}\n */\nfunction getClasses( preview, layout ) {\n\tvar classes = [];\n\n\tif ( layout.flippedY ) {\n\t\tclasses.push( 'mwe-popups-fade-in-down' );\n\t} else {\n\t\tclasses.push( 'mwe-popups-fade-in-up' );\n\t}\n\n\tif ( layout.flippedY && layout.flippedX ) {\n\t\tclasses.push( 'flipped_x_y' );\n\t}\n\n\tif ( layout.flippedY && !layout.flippedX ) {\n\t\tclasses.push( 'flipped_y' );\n\t}\n\n\tif ( layout.flippedX && !layout.flippedY ) {\n\t\tclasses.push( 'flipped_x' );\n\t}\n\n\tif ( ( !preview.hasThumbnail || preview.isTall ) && !layout.flippedY ) {\n\t\tclasses.push( 'mwe-popups-no-image-tri' );\n\t}\n\n\tif ( ( preview.hasThumbnail && !preview.isTall ) && !layout.flippedY ) {\n\t\tclasses.push( 'mwe-popups-image-tri' );\n\t}\n\n\tif ( preview.isTall ) {\n\t\tclasses.push( 'mwe-popups-is-tall' );\n\t} else {\n\t\tclasses.push( 'mwe-popups-is-not-tall' );\n\t}\n\n\treturn classes;\n}\n\n/**\n * Lays out the preview given the layout.\n *\n * If the preview should be oriented differently, then the pokey is updated,\n * e.g. if the preview should be flipped vertically, then the pokey is\n * removed.\n *\n * If the thumbnail is landscape and isn't the full height of the thumbnail\n * container, then pull the extract up to keep whitespace consistent across\n * previews.\n *\n * @param {ext.popups.Preview} preview\n * @param {ext.popups.PreviewLayout} layout\n */\nfunction layoutPreview( preview, layout ) {\n\tvar popup = preview.el,\n\t\tisTall = preview.isTall,\n\t\thasThumbnail = preview.hasThumbnail,\n\t\tthumbnail = preview.thumbnail,\n\t\tflippedY = layout.flippedY,\n\t\tflippedX = layout.flippedX,\n\t\toffsetTop = layout.offset.top;\n\n\tif ( !flippedY && !isTall && hasThumbnail && thumbnail.height < SIZES.landscapeImage.h ) {\n\t\t$( '.mwe-popups-extract' ).css(\n\t\t\t'margin-top',\n\t\t\tthumbnail.height - SIZES.pokeySize\n\t\t);\n\t}\n\n\tpopup.addClass( getClasses( preview, layout ).join( ' ' ) );\n\n\tif ( flippedY ) {\n\t\toffsetTop -= popup.outerHeight();\n\t}\n\n\tpopup.css( {\n\t\ttop: offsetTop,\n\t\tleft: layout.offset.left + 'px'\n\t} );\n\n\tif ( flippedY && hasThumbnail ) {\n\t\tpopup.find( 'image' )[ 0 ]\n\t\t\t.setAttribute( 'clip-path', '' );\n\t}\n\n\tif ( flippedY && flippedX && hasThumbnail && isTall ) {\n\t\tpopup.find( 'image' )[ 0 ]\n\t\t\t.setAttribute( 'clip-path', 'url(#mwe-popups-landscape-mask-flip)' );\n\t}\n\n\tif ( flippedX && !flippedY && hasThumbnail && !isTall ) {\n\t\tpopup.find( 'image' )[ 0 ]\n\t\t\t.setAttribute( 'clip-path', 'url(#mwe-popups-mask-flip)' );\n\t}\n\n\tif ( flippedX && !flippedY && hasThumbnail && isTall ) {\n\t\tpopup.removeClass( 'mwe-popups-no-image-tri' )\n\t\t\t.find( 'image' )[ 0 ]\n\t\t\t.setAttribute( 'clip-path', 'url(#mwe-popups-landscape-mask)' );\n\t}\n}\n\n/**\n * Given the rectangular box(es) find the 'y' boundary of the closest\n * rectangle to the point 'y'. The point 'y' is the location of the mouse\n * on the 'y' axis and the rectangular box(es) are the borders of the\n * element over which the mouse is located. There will be more than one\n * rectangle in case the element spans multiple lines.\n *\n * In the majority of cases the mouse pointer will be inside a rectangle.\n * However, some browsers (i.e. Chrome) trigger a hover action even when\n * the mouse pointer is just outside a bounding rectangle. That's why\n * we need to look at all rectangles and not just the rectangle that\n * encloses the point.\n *\n * @param {Number} y the point for which the closest location is being\n * looked for\n * @param {ClientRectList} rects list of rectangles defined by four edges\n * @param {Boolean} [isTop] should the resulting rectangle's top 'y'\n * boundary be returned. By default the bottom 'y' value is returned.\n * @return {Number}\n */\nfunction getClosestYPosition( y, rects, isTop ) {\n\tvar result,\n\t\tdeltaY,\n\t\tminY = null;\n\n\t$.each( rects, function ( i, rect ) {\n\t\tdeltaY = Math.abs( y - rect.top + y - rect.bottom );\n\n\t\tif ( minY === null || minY > deltaY ) {\n\t\t\tminY = deltaY;\n\t\t\t// Make sure the resulting point is at or outside the rectangle\n\t\t\t// boundaries.\n\t\t\tresult = ( isTop ) ? Math.floor( rect.top ) : Math.ceil( rect.bottom );\n\t\t}\n\t} );\n\n\treturn result;\n}\n\nmodule.exports = {\n\trender: render,\n\tinit: init\n};\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./src/renderer.js\n// module id = 35\n// module chunks = 0","var $ = jQuery;\n\n/**\n * Sugar around `window.setTimeout`.\n *\n * @example\n * function continueProcessing() {\n * // ...\n * }\n *\n * wait( 150 ).then( continueProcessing );\n *\n * @param {Number} delay The number of milliseconds to wait\n * @return {jQuery.Promise}\n */\nmodule.exports = function ( delay ) {\n\tvar result = $.Deferred();\n\n\tsetTimeout( function () {\n\t\tresult.resolve();\n\t}, delay );\n\n\treturn result.promise();\n};\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./src/wait.js\n// module id = 36\n// module chunks = 0","module.exports = {\n\tfooterLink: require( './footerLink' ),\n\teventLogging: require( './eventLogging' ),\n\tlinkTitle: require( './linkTitle' ),\n\trender: require( './render' ),\n\tsettings: require( './settings' ),\n\tsyncUserSettings: require( './syncUserSettings' )\n};\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./src/changeListeners/index.js\n// module id = 37\n// module chunks = 0","var mw = window.mediaWiki,\n\t$ = jQuery;\n\n/**\n * Creates the link element and appends it to the footer element.\n *\n * The following elements are considered to be the footer element (highest\n * priority to lowest):\n *\n * # `#footer-places`\n * # `#f-list`\n * # The parent element of `#footer li`, which is either an `ol` or `ul`.\n *\n * @return {jQuery} The link element\n */\nfunction createFooterLink() {\n\tvar $link = $( '<li>' ).append(\n\t\t\t$( '<a>' )\n\t\t\t\t.attr( 'href', '#' )\n\t\t\t\t.text( mw.message( 'popups-settings-enable' ).text() )\n\t\t),\n\t\t$footer;\n\n\t// As yet, we don't know whether the link should be visible.\n\t$link.hide();\n\n\t// From https://en.wikipedia.org/wiki/MediaWiki:Gadget-ReferenceTooltips.js,\n\t// which was written by Yair rand <https://en.wikipedia.org/wiki/User:Yair_rand>.\n\t$footer = $( '#footer-places, #f-list' );\n\n\tif ( $footer.length === 0 ) {\n\t\t$footer = $( '#footer li' ).parent();\n\t}\n\n\t$footer.append( $link );\n\n\treturn $link;\n}\n\n/**\n * Creates an instance of the footer link change listener.\n *\n * The change listener covers the following behaviour:\n *\n * * The \"Enable previews\" link (the \"link\") is appended to the footer menu\n * (see `createFooterLink` above).\n * * When Page Previews are disabled, then the link is shown; otherwise, the\n * link is hidden.\n * * When the user clicks the link, then the `showSettings` bound action\n * creator is called.\n *\n * @param {Object} boundActions\n * @return {ext.popups.ChangeListener}\n */\nmodule.exports = function ( boundActions ) {\n\tvar $footerLink;\n\n\treturn function ( prevState, state ) {\n\t\tif ( $footerLink === undefined ) {\n\t\t\t$footerLink = createFooterLink();\n\t\t\t$footerLink.click( function ( e ) {\n\t\t\t\te.preventDefault();\n\t\t\t\tboundActions.showSettings();\n\t\t\t} );\n\t\t}\n\n\t\tif ( state.settings.shouldShowFooterLink ) {\n\t\t\t$footerLink.show();\n\t\t} else {\n\t\t\t$footerLink.hide();\n\t\t}\n\t};\n};\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./src/changeListeners/footerLink.js\n// module id = 38\n// module chunks = 0","var $ = jQuery;\n\n/**\n * Creates an instance of the event logging change listener.\n *\n * When an event is enqueued to be logged it'll be logged using the schema.\n * Since it's the responsibility of EventLogging (and the UA) to deliver\n * logged events, the `EVENT_LOGGED` is immediately dispatched rather than\n * waiting for some indicator of completion.\n *\n * @param {Object} boundActions\n * @param {mw.eventLog.Schema} schema\n * @return {ext.popups.ChangeListener}\n */\nmodule.exports = function ( boundActions, schema ) {\n\treturn function ( _, state ) {\n\t\tvar eventLogging = state.eventLogging,\n\t\t\tevent = eventLogging.event;\n\n\t\tif ( event ) {\n\t\t\tschema.log( $.extend( true, {}, eventLogging.baseData, event ) );\n\n\t\t\tboundActions.eventLogged();\n\t\t}\n\t};\n};\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./src/changeListeners/eventLogging.js\n// module id = 39\n// module chunks = 0","var $ = jQuery;\n\n/**\n * Creates an instance of the link title change listener.\n *\n * While the user dwells on a link, then it becomes the active link. The\n * change listener will remove a link's `title` attribute while it's the\n * active link.\n *\n * @return {ext.popups.ChangeListener}\n */\nmodule.exports = function () {\n\tvar title;\n\n\t/**\n\t * Destroys the title attribute of the element, storing its value in local\n\t * state so that it can be restored later (see `restoreTitleAttr`).\n\t *\n\t * @param {Element} el\n\t */\n\tfunction destroyTitleAttr( el ) {\n\t\tvar $el = $( el );\n\n\t\t// Has the user dwelled on a link? If we've already removed its title\n\t\t// attribute, then NOOP.\n\t\tif ( title ) {\n\t\t\treturn;\n\t\t}\n\n\t\ttitle = $el.attr( 'title' );\n\n\t\t$el.attr( 'title', '' );\n\t}\n\n\t/**\n\t * Restores the title attribute of the element.\n\t *\n\t * @param {Element} el\n\t */\n\tfunction restoreTitleAttr( el ) {\n\t\t$( el ).attr( 'title', title );\n\n\t\ttitle = undefined;\n\t}\n\n\treturn function ( prevState, state ) {\n\t\tvar hasPrevActiveLink = prevState && prevState.preview.activeLink;\n\n\t\tif ( hasPrevActiveLink ) {\n\n\t\t\t// Has the user dwelled on a link immediately after abandoning another\n\t\t\t// (remembering that the ABANDON_END action is delayed by\n\t\t\t// ~10e2 ms).\n\t\t\tif ( prevState.preview.activeLink !== state.preview.activeLink ) {\n\t\t\t\trestoreTitleAttr( prevState.preview.activeLink );\n\t\t\t}\n\t\t}\n\n\t\tif ( state.preview.activeLink ) {\n\t\t\tdestroyTitleAttr( state.preview.activeLink );\n\t\t}\n\t};\n};\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./src/changeListeners/linkTitle.js\n// module id = 40\n// module chunks = 0","var renderer = require( '../renderer' );\n\n/**\n * Creates an instance of the render change listener.\n *\n * FIXME: Remove hard coupling with renderer, inject it as a parameter\n * * Wire it up in index.js\n * * Fix tests to remove require mocking\n *\n * @param {ext.popups.PreviewBehavior} previewBehavior\n * @return {ext.popups.ChangeListener}\n */\nmodule.exports = function ( previewBehavior ) {\n\tvar preview;\n\n\treturn function ( prevState, state ) {\n\t\tif ( state.preview.shouldShow && !preview ) {\n\t\t\tpreview = renderer.render( state.preview.fetchResponse );\n\t\t\tpreview.show( state.preview.activeEvent, previewBehavior );\n\t\t} else if ( !state.preview.shouldShow && preview ) {\n\t\t\tpreview.hide();\n\t\t\tpreview = undefined;\n\t\t}\n\t};\n};\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./src/changeListeners/render.js\n// module id = 41\n// module chunks = 0","/**\n * Creates an instance of the settings change listener.\n *\n * @param {Object} boundActions\n * @param {Object} render function that renders a jQuery el with the settings\n * @return {ext.popups.ChangeListener}\n */\nmodule.exports = function ( boundActions, render ) {\n\tvar settings;\n\n\treturn function ( prevState, state ) {\n\t\tif ( !prevState ) {\n\t\t\t// Nothing to do on initialization\n\t\t\treturn;\n\t\t}\n\n\t\t// Update global modal visibility\n\t\tif (\n\t\t\tprevState.settings.shouldShow === false &&\n\t\t\tstate.settings.shouldShow === true\n\t\t) {\n\t\t\t// Lazily instantiate the settings UI\n\t\t\tif ( !settings ) {\n\t\t\t\tsettings = render( boundActions );\n\t\t\t\tsettings.appendTo( document.body );\n\t\t\t}\n\n\t\t\t// Update the UI settings with the current settings\n\t\t\tsettings.setEnabled( state.preview.enabled );\n\n\t\t\tsettings.show();\n\t\t} else if (\n\t\t\tprevState.settings.shouldShow === true &&\n\t\t\tstate.settings.shouldShow === false\n\t\t) {\n\t\t\tsettings.hide();\n\t\t}\n\n\t\t// Update help visibility\n\t\tif ( prevState.settings.showHelp !== state.settings.showHelp ) {\n\t\t\tsettings.toggleHelp( state.settings.showHelp );\n\t\t}\n\t};\n};\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./src/changeListeners/settings.js\n// module id = 42\n// module chunks = 0","/**\n * Creates an instance of the user settings sync change listener.\n *\n * This change listener syncs certain parts of the state tree to user\n * settings when they change.\n *\n * Used for:\n *\n * * Enabled state: If the previews are enabled or disabled.\n * * Preview count: When the user dwells on a link for long enough that\n * a preview is shown, then their preview count will be incremented (see\n * `mw.popups.reducers.eventLogging`, and is persisted to local storage.\n *\n * @param {ext.popups.UserSettings} userSettings\n * @return {ext.popups.ChangeListener}\n */\nmodule.exports = function ( userSettings ) {\n\n\treturn function ( prevState, state ) {\n\n\t\tsyncIfChanged(\n\t\t\tprevState, state, 'eventLogging', 'previewCount',\n\t\t\tuserSettings.setPreviewCount\n\t\t);\n\t\tsyncIfChanged(\n\t\t\tprevState, state, 'preview', 'enabled',\n\t\t\tuserSettings.setIsEnabled\n\t\t);\n\n\t};\n};\n\n/**\n * Given a state tree, reducer and property, safely return the value of the\n * property if the reducer and property exist\n * @param {Object} state tree\n * @param {String} reducer key to access on the state tree\n * @param {String} prop key to access on the reducer key of the state tree\n * @return {*}\n */\nfunction get( state, reducer, prop ) {\n\treturn state[ reducer ] && state[ reducer ][ prop ];\n}\n\n/**\n * Calls a sync function if the property prop on the property reducer on\n * the state trees has changed value.\n * @param {Object} prevState\n * @param {Object} state\n * @param {String} reducer key to access on the state tree\n * @param {String} prop key to access on the reducer key of the state tree\n * @param {Function} sync function to be called with the newest value if\n * changed\n */\nfunction syncIfChanged( prevState, state, reducer, prop, sync ) {\n\tvar current = get( state, reducer, prop );\n\tif ( prevState && ( get( prevState, reducer, prop ) !== current ) ) {\n\t\tsync( current );\n\t}\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./src/changeListeners/syncUserSettings.js\n// module id = 43\n// module chunks = 0","var $ = jQuery,\n\tmw = window.mediaWiki,\n\tactions = {},\n\ttypes = require( './actionTypes' ),\n\tFETCH_START_DELAY = 50, // ms.\n\n\t// The delay after which a FETCH_END action should be dispatched.\n\t//\n\t// If the API endpoint responds faster than 500 ms (or, say, the API\n\t// response is served from the UA's cache), then we introduce a delay of\n\t// 300 - t to make the preview delay consistent to the user.\n\tFETCH_END_TARGET_DELAY = 500, // ms.\n\n\tABANDON_END_DELAY = 300; // ms.\n\n/**\n * Mixes in timing information to an action.\n *\n * Warning: the `baseAction` parameter is modified and returned.\n *\n * @param {Object} baseAction\n * @return {Object}\n */\nfunction timedAction( baseAction ) {\n\tbaseAction.timestamp = mw.now();\n\n\treturn baseAction;\n}\n\n/**\n * Represents Page Previews booting.\n *\n * When a Redux store is created, the `@@INIT` action is immediately\n * dispatched to it. To avoid overriding the term, we refer to booting rather\n * than initializing.\n *\n * Page Previews persists critical pieces of information to local storage.\n * Since reading from and writing to local storage are synchronous, Page\n * Previews is booted when the browser is idle (using\n * [`mw.requestIdleCallback`](https://developer.mozilla.org/en-US/docs/Web/API/Window/requestIdleCallback))\n * so as not to impact latency-critical events.\n *\n * @param {Boolean} isEnabled See `mw.popups.isEnabled`\n * @param {mw.user} user\n * @param {ext.popups.UserSettings} userSettings\n * @param {Function} generateToken\n * @param {mw.Map} config The config of the MediaWiki client-side application,\n * i.e. `mw.config`\n * @returns {Object}\n */\nactions.boot = function (\n\tisEnabled,\n\tuser,\n\tuserSettings,\n\tgenerateToken,\n\tconfig\n) {\n\tvar editCount = config.get( 'wgUserEditCount' ),\n\t\tpreviewCount = userSettings.getPreviewCount();\n\n\treturn {\n\t\ttype: types.BOOT,\n\t\tisEnabled: isEnabled,\n\t\tisNavPopupsEnabled: config.get( 'wgPopupsConflictsWithNavPopupGadget' ),\n\t\tsessionToken: user.sessionId(),\n\t\tpageToken: generateToken(),\n\t\tpage: {\n\t\t\ttitle: config.get( 'wgTitle' ),\n\t\t\tnamespaceID: config.get( 'wgNamespaceNumber' ),\n\t\t\tid: config.get( 'wgArticleId' )\n\t\t},\n\t\tuser: {\n\t\t\tisAnon: user.isAnon(),\n\t\t\teditCount: editCount,\n\t\t\tpreviewCount: previewCount\n\t\t}\n\t};\n};\n\n/**\n * Represents Page Previews fetching data via the gateway.\n *\n * @param {ext.popups.Gateway} gateway\n * @param {Element} el\n * @param {Date} started The time at which the interaction started.\n * @return {Redux.Thunk}\n */\nactions.fetch = function ( gateway, el, started ) {\n\tvar title = $( el ).data( 'page-previews-title' );\n\n\treturn function ( dispatch ) {\n\t\tdispatch( {\n\t\t\ttype: types.FETCH_START,\n\t\t\tel: el,\n\t\t\ttitle: title\n\t\t} );\n\n\t\tgateway.getPageSummary( title )\n\t\t\t.fail( function () {\n\t\t\t\tdispatch( {\n\t\t\t\t\ttype: types.FETCH_FAILED,\n\t\t\t\t\tel: el\n\t\t\t\t} );\n\t\t\t} )\n\t\t\t.done( function ( result ) {\n\t\t\t\tvar now = mw.now(),\n\t\t\t\t\tdelay;\n\n\t\t\t\t// If the API request has taken longer than the target delay, then\n\t\t\t\t// don't delay any further.\n\t\t\t\tdelay = Math.max(\n\t\t\t\t\tFETCH_END_TARGET_DELAY - Math.round( now - started ),\n\t\t\t\t\t0\n\t\t\t\t);\n\n\t\t\t\t// FIXME: This needs to reference a global because the tests are\n\t\t\t\t// stubbing a global, so can't be required at the top at the moment.\n\t\t\t\t// When the tests are moved to common.js we should find a different way\n\t\t\t\t// of stubbing this wait\n\t\t\t\tmw.popups.wait( delay )\n\t\t\t\t\t.then( function () {\n\t\t\t\t\t\tdispatch( {\n\t\t\t\t\t\t\ttype: types.FETCH_END,\n\t\t\t\t\t\t\tel: el,\n\t\t\t\t\t\t\tresult: result\n\t\t\t\t\t\t} );\n\t\t\t\t\t} );\n\t\t\t} );\n\t};\n};\n\n/**\n * Represents the user dwelling on a link, either by hovering over it with\n * their mouse or by focussing it using their keyboard or an assistive device.\n *\n * @param {Element} el\n * @param {Event} event\n * @param {ext.popups.Gateway} gateway\n * @param {Function} generateToken\n * @return {Redux.Thunk}\n */\nactions.linkDwell = function ( el, event, gateway, generateToken ) {\n\tvar token = generateToken();\n\n\treturn function ( dispatch, getState ) {\n\t\tvar action = timedAction( {\n\t\t\ttype: types.LINK_DWELL,\n\t\t\tel: el,\n\t\t\tevent: event,\n\t\t\ttoken: token\n\t\t} );\n\n\t\t// Has the new generated token been accepted?\n\t\tfunction isNewInteraction() {\n\t\t\treturn getState().preview.activeToken === token;\n\t\t}\n\n\t\tdispatch( action );\n\n\t\tif ( !isNewInteraction() ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// FIXME: This needs to reference a global because the tests are stubbing\n\t\t// a global, so can't be required at the top at the moment. When the tests\n\t\t// are moved to common.js we should find a different way of stubbing this\n\t\t// wait\n\t\tmw.popups.wait( FETCH_START_DELAY )\n\t\t\t.then( function () {\n\t\t\t\tvar previewState = getState().preview;\n\n\t\t\t\tif ( previewState.enabled && isNewInteraction() ) {\n\t\t\t\t\tdispatch( actions.fetch( gateway, el, action.timestamp ) );\n\t\t\t\t}\n\t\t\t} );\n\t};\n};\n\n/**\n * Represents the user abandoning a link, either by moving their mouse away\n * from it or by shifting focus to another UI element using their keyboard or\n * an assistive device, or abandoning a preview by moving their mouse away\n * from it.\n *\n * @return {Redux.Thunk}\n */\nactions.abandon = function () {\n\treturn function ( dispatch, getState ) {\n\t\tvar token = getState().preview.activeToken;\n\n\t\tdispatch( timedAction( {\n\t\t\ttype: types.ABANDON_START,\n\t\t\ttoken: token\n\t\t} ) );\n\n\t\t// FIXME: This needs to reference a global because the tests are stubbing\n\t\t// a global, so can't be required at the top at the moment. When the tests\n\t\t// are moved to common.js we should find a different way of stubbing this\n\t\t// wait\n\t\tmw.popups.wait( ABANDON_END_DELAY )\n\t\t\t.then( function () {\n\t\t\t\tdispatch( {\n\t\t\t\t\ttype: types.ABANDON_END,\n\t\t\t\t\ttoken: token\n\t\t\t\t} );\n\t\t\t} );\n\t};\n};\n\n/**\n * Represents the user clicking on a link with their mouse, keyboard, or an\n * assistive device.\n *\n * @param {Element} el\n * @return {Object}\n */\nactions.linkClick = function ( el ) {\n\treturn timedAction( {\n\t\ttype: types.LINK_CLICK,\n\t\tel: el\n\t} );\n};\n\n/**\n * Represents the user dwelling on a preview with their mouse.\n *\n * @return {Object}\n */\nactions.previewDwell = function () {\n\treturn {\n\t\ttype: types.PREVIEW_DWELL\n\t};\n};\n\n/**\n * Represents a preview being shown to the user.\n *\n * This action is dispatched by the `mw.popups.changeListeners.render` change\n * listener.\n *\n * @return {Object}\n */\nactions.previewShow = function () {\n\treturn timedAction( {\n\t\ttype: types.PREVIEW_SHOW\n\t} );\n};\n\n/**\n * Represents the user clicking either the \"Enable previews\" footer menu link,\n * or the \"cog\" icon that's present on each preview.\n *\n * @return {Object}\n */\nactions.showSettings = function () {\n\treturn {\n\t\ttype: types.SETTINGS_SHOW\n\t};\n};\n\n/**\n * Represents the user closing the settings dialog and saving their settings.\n *\n * @return {Object}\n */\nactions.hideSettings = function () {\n\treturn {\n\t\ttype: types.SETTINGS_HIDE\n\t};\n};\n\n/**\n * Represents the user saving their settings.\n *\n * N.B. This action returns a Redux.Thunk not because it needs to perform\n * asynchronous work, but because it needs to query the global state for the\n * current enabled state. In order to keep the enabled state in a single\n * place (the preview reducer), we query it and dispatch it as `wasEnabled`\n * so that other reducers (like settings) can act on it without having to\n * duplicate the `enabled` state locally.\n * See doc/adr/0003-keep-enabled-state-only-in-preview-reducer.md for more\n * details.\n *\n * @param {Boolean} enabled if previews are enabled or not\n * @return {Redux.Thunk}\n */\nactions.saveSettings = function ( enabled ) {\n\treturn function ( dispatch, getState ) {\n\t\tdispatch( {\n\t\t\ttype: types.SETTINGS_CHANGE,\n\t\t\twasEnabled: getState().preview.enabled,\n\t\t\tenabled: enabled\n\t\t} );\n\t};\n};\n\n/**\n * Represents the queued event being logged\n * `mw.popups.changeListeners.eventLogging` change listener.\n *\n * @return {Object}\n */\nactions.eventLogged = function () {\n\treturn {\n\t\ttype: types.EVENT_LOGGED\n\t};\n};\n\nmodule.exports = actions;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./src/actions.js\n// module id = 44\n// module chunks = 0","module.exports = {\n\tBOOT: 'BOOT',\n\tLINK_DWELL: 'LINK_DWELL',\n\tABANDON_START: 'ABANDON_START',\n\tABANDON_END: 'ABANDON_END',\n\tLINK_CLICK: 'LINK_CLICK',\n\tFETCH_START: 'FETCH_START',\n\tFETCH_END: 'FETCH_END',\n\tFETCH_FAILED: 'FETCH_FAILED',\n\tPREVIEW_DWELL: 'PREVIEW_DWELL',\n\tPREVIEW_SHOW: 'PREVIEW_SHOW',\n\tPREVIEW_CLICK: 'PREVIEW_CLICK',\n\tSETTINGS_SHOW: 'SETTINGS_SHOW',\n\tSETTINGS_HIDE: 'SETTINGS_HIDE',\n\tSETTINGS_CHANGE: 'SETTINGS_CHANGE',\n\tEVENT_LOGGED: 'EVENT_LOGGED'\n};\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./src/actionTypes.js\n// module id = 45\n// module chunks = 0","module.exports = {\n\teventLogging: require( './eventLogging' ),\n\tpreview: require( './preview' ),\n\tsettings: require( './settings' )\n};\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./src/reducers/index.js\n// module id = 46\n// module chunks = 0","var actionTypes = require( './../actionTypes' ),\n\tnextState = require( './nextState' ),\n\tcounts = require( './../counts' );\n\n/**\n * Initialize the data that's shared between all events logged with [the Popups\n * schema](https://meta.wikimedia.org/wiki/Schema:Popups).\n *\n * @param {Object} bootAction\n * @return {Object}\n */\nfunction getBaseData( bootAction ) {\n\tvar result = {\n\t\tpageTitleSource: bootAction.page.title,\n\t\tnamespaceIdSource: bootAction.page.namespaceID,\n\t\tpageIdSource: bootAction.page.id,\n\t\tisAnon: bootAction.user.isAnon,\n\t\tpopupEnabled: bootAction.isEnabled,\n\t\tpageToken: bootAction.pageToken,\n\t\tsessionToken: bootAction.sessionToken,\n\t\tpreviewCountBucket: counts.getPreviewCountBucket( bootAction.user.previewCount ),\n\t\thovercardsSuppressedByGadget: bootAction.isNavPopupsEnabled\n\t};\n\n\tif ( !bootAction.user.isAnon ) {\n\t\tresult.editCountBucket = counts.getEditCountBucket( bootAction.user.editCount );\n\t}\n\n\treturn result;\n}\n\n/**\n * Reducer for actions that may result in an event being logged with the\n * Popups schema via Event Logging.\n *\n * TODO: For obvious reasons, this reducer and the associated change listener\n * are tightly bound to the Popups schema. This reducer must be\n * renamed/moved if we introduce additional instrumentation.\n *\n * The base data represents data that's shared between all events. Very nearly\n * all of it is initialized during the BOOT action (see `getBaseData`) and\n * doesn't change between link interactions, e.g. the user being an anon or\n * the number of edits they've made.\n *\n * The user's number of previews, however, does change between link\n * interactions and the associated bucket (a computed property) is what is\n * logged. This is reflected in the state tree: the `previewCount` property is\n * used to store the user's number of previews and the\n * `baseData.previewCountBucket` property is used to store the associated\n * bucket.\n *\n * @param {Object} state\n * @param {Object} action\n * @return {Object} The state as a result of processing the action\n */\nmodule.exports = function ( state, action ) {\n\tvar nextCount, abandonEvent;\n\n\tif ( state === undefined ) {\n\t\tstate = {\n\t\t\tpreviewCount: undefined,\n\t\t\tbaseData: {},\n\t\t\tinteraction: undefined,\n\t\t\tevent: undefined\n\t\t};\n\t}\n\n\tswitch ( action.type ) {\n\t\tcase actionTypes.BOOT:\n\t\t\treturn nextState( state, {\n\t\t\t\tpreviewCount: action.user.previewCount,\n\t\t\t\tbaseData: getBaseData( action ),\n\t\t\t\tevent: {\n\t\t\t\t\taction: 'pageLoaded'\n\t\t\t\t}\n\t\t\t} );\n\n\t\tcase actionTypes.EVENT_LOGGED:\n\t\t\treturn nextState( state, {\n\t\t\t\tevent: undefined\n\t\t\t} );\n\n\t\tcase actionTypes.FETCH_END:\n\t\t\treturn nextState( state, {\n\t\t\t\tinteraction: nextState( state.interaction, {\n\t\t\t\t\tpreviewType: action.result.type\n\t\t\t\t} )\n\t\t\t} );\n\n\t\tcase actionTypes.PREVIEW_SHOW:\n\t\t\tnextCount = state.previewCount + 1;\n\n\t\t\treturn nextState( state, {\n\t\t\t\tpreviewCount: nextCount,\n\t\t\t\tbaseData: nextState( state.baseData, {\n\t\t\t\t\tpreviewCountBucket: counts.getPreviewCountBucket( nextCount )\n\t\t\t\t} ),\n\t\t\t\tinteraction: nextState( state.interaction, {\n\t\t\t\t\ttimeToPreviewShow: action.timestamp - state.interaction.started\n\t\t\t\t} )\n\t\t\t} );\n\n\t\tcase actionTypes.LINK_DWELL:\n\t\t\treturn nextState( state, {\n\t\t\t\tinteraction: {\n\t\t\t\t\ttoken: action.token,\n\t\t\t\t\tstarted: action.timestamp\n\t\t\t\t}\n\t\t\t} );\n\n\t\tcase actionTypes.LINK_CLICK:\n\t\t\treturn nextState( state, {\n\t\t\t\tevent: {\n\t\t\t\t\taction: 'opened',\n\t\t\t\t\tlinkInteractionToken: state.interaction.token,\n\t\t\t\t\ttotalInteractionTime: Math.round( action.timestamp - state.interaction.started )\n\t\t\t\t}\n\t\t\t} );\n\n\t\tcase actionTypes.ABANDON_START:\n\t\t\treturn nextState( state, {\n\t\t\t\tinteraction: nextState( state.interaction, {\n\t\t\t\t\tfinished: action.timestamp\n\t\t\t\t} )\n\t\t\t} );\n\n\t\tcase actionTypes.ABANDON_END:\n\t\t\tabandonEvent = {\n\t\t\t\tlinkInteractionToken: state.interaction.token,\n\t\t\t\ttotalInteractionTime: Math.round( state.interaction.finished - state.interaction.started )\n\t\t\t};\n\n\t\t\t// Has the preview been shown? If so, then, in the context of the\n\t\t\t// instrumentation, then the preview has been dismissed by the user\n\t\t\t// rather than the user has abandoned the link.\n\t\t\tif ( state.interaction.timeToPreviewShow !== undefined ) {\n\t\t\t\tabandonEvent.action = 'dismissed';\n\t\t\t\tabandonEvent.previewType = state.interaction.previewType;\n\t\t\t} else {\n\t\t\t\tabandonEvent.action = 'dwelledButAbandoned';\n\t\t\t}\n\n\t\t\treturn nextState( state, {\n\t\t\t\tevent: abandonEvent\n\t\t\t} );\n\n\t\tdefault:\n\t\t\treturn state;\n\t}\n};\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./src/reducers/eventLogging.js\n// module id = 47\n// module chunks = 0","/**\n * Creates the next state tree from the current state tree and some updates.\n *\n * N.B. OO.copy doesn't copy Element instances, whereas $.extend does.\n * However, OO.copy does copy properties whose values are undefined or null,\n * whereas $.extend doesn't. Since the state tree contains an Element instance\n * - the preview.activeLink property - and we want to copy undefined/null into\n * the state we need to manually iterate over updates and check with\n * hasOwnProperty to copy over to the new state.\n *\n * In [change listeners](/doc/change_listeners.md), for example, we talk about\n * the previous state and the current state (the `prevState` and `state`\n * parameters, respectively). Since\n * [reducers](http://redux.js.org/docs/basics/Reducers.html) take the current\n * state and an action and make updates, \"next state\" seems appropriate.\n *\n * @param {Object} state\n * @param {Object} updates\n * @return {Object}\n */\nmodule.exports = function ( state, updates ) {\n\tvar result = {},\n\t\tkey;\n\n\tfor ( key in state ) {\n\t\tif ( state.hasOwnProperty( key ) && !updates.hasOwnProperty( key ) ) {\n\t\t\tresult[ key ] = state[ key ];\n\t\t}\n\t}\n\n\tfor ( key in updates ) {\n\t\tif ( updates.hasOwnProperty( key ) ) {\n\t\t\tresult[ key ] = updates[ key ];\n\t\t}\n\t}\n\n\treturn result;\n};\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./src/reducers/nextState.js\n// module id = 48\n// module chunks = 0","/**\n * Return count bucket for the number of edits a user has made.\n *\n * The buckets are defined as part of\n * [the Popups schema](https://meta.wikimedia.org/wiki/Schema:Popups).\n *\n * Extracted from `mw.popups.schemaPopups.getEditCountBucket`.\n *\n * @param {Number} count\n * @return {String}\n */\nfunction getEditCountBucket( count ) {\n\tvar bucket;\n\n\tif ( count === 0 ) {\n\t\tbucket = '0';\n\t} else if ( count >= 1 && count <= 4 ) {\n\t\tbucket = '1-4';\n\t} else if ( count >= 5 && count <= 99 ) {\n\t\tbucket = '5-99';\n\t} else if ( count >= 100 && count <= 999 ) {\n\t\tbucket = '100-999';\n\t} else if ( count >= 1000 ) {\n\t\tbucket = '1000+';\n\t}\n\n\treturn bucket + ' edits';\n}\n\n/**\n * Return count bucket for the number of previews a user has seen.\n *\n * If local storage isn't available - because the user has disabled it\n * or the browser doesn't support it - then then \"unknown\" is returned.\n *\n * The buckets are defined as part of\n * [the Popups schema](https://meta.wikimedia.org/wiki/Schema:Popups).\n *\n * Extracted from `mw.popups.getPreviewCountBucket`.\n *\n * @param {Number} count\n * @return {String}\n */\nfunction getPreviewCountBucket( count ) {\n\tvar bucket;\n\n\tif ( count === -1 ) {\n\t\treturn 'unknown';\n\t}\n\n\tif ( count === 0 ) {\n\t\tbucket = '0';\n\t} else if ( count >= 1 && count <= 4 ) {\n\t\tbucket = '1-4';\n\t} else if ( count >= 5 && count <= 20 ) {\n\t\tbucket = '5-20';\n\t} else if ( count >= 21 ) {\n\t\tbucket = '21+';\n\t}\n\n\treturn bucket + ' previews';\n}\n\nmodule.exports = {\n\tgetPreviewCountBucket: getPreviewCountBucket,\n\tgetEditCountBucket: getEditCountBucket\n};\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./src/counts.js\n// module id = 49\n// module chunks = 0","var actionTypes = require( './../actionTypes' ),\n\tnextState = require( './nextState' );\n\n/**\n * Reducer for actions that modify the state of the preview model\n *\n * @param {Object} state before action\n * @param {Object} action Redux action that modified state.\n * Must have `type` property.\n * @return {Object} state after action\n */\nmodule.exports = function ( state, action ) {\n\tif ( state === undefined ) {\n\t\tstate = {\n\t\t\tenabled: undefined,\n\t\t\tactiveLink: undefined,\n\t\t\tactiveEvent: undefined,\n\t\t\tactiveToken: '',\n\t\t\tshouldShow: false,\n\t\t\tisUserDwelling: false\n\t\t};\n\t}\n\n\tswitch ( action.type ) {\n\t\tcase actionTypes.BOOT:\n\t\t\treturn nextState( state, {\n\t\t\t\tenabled: action.isEnabled\n\t\t\t} );\n\t\tcase actionTypes.SETTINGS_CHANGE:\n\t\t\treturn nextState( state, {\n\t\t\t\tenabled: action.enabled\n\t\t\t} );\n\t\tcase actionTypes.LINK_DWELL:\n\t\t\t// New interaction\n\t\t\tif ( action.el !== state.activeLink ) {\n\t\t\t\treturn nextState( state, {\n\t\t\t\t\tactiveLink: action.el,\n\t\t\t\t\tactiveEvent: action.event,\n\t\t\t\t\tactiveToken: action.token,\n\n\t\t\t\t\t// When the user dwells on a link with their keyboard, a preview is\n\t\t\t\t\t// renderered, and then dwells on another link, the ABANDON_END\n\t\t\t\t\t// action will be ignored.\n\t\t\t\t\t//\n\t\t\t\t\t// Ensure that all the preview is hidden.\n\t\t\t\t\tshouldShow: false,\n\n\t\t\t\t\tisUserDwelling: true\n\t\t\t\t} );\n\t\t\t} else {\n\t\t\t\t// Dwelling back into the same link\n\t\t\t\treturn nextState( state, {\n\t\t\t\t\tisUserDwelling: true\n\t\t\t\t} );\n\t\t\t}\n\n\t\tcase actionTypes.ABANDON_END:\n\t\t\tif ( action.token === state.activeToken && !state.isUserDwelling ) {\n\t\t\t\treturn nextState( state, {\n\t\t\t\t\tactiveLink: undefined,\n\t\t\t\t\tactiveToken: undefined,\n\t\t\t\t\tactiveEvent: undefined,\n\t\t\t\t\tfetchResponse: undefined,\n\t\t\t\t\tshouldShow: false\n\t\t\t\t} );\n\t\t\t}\n\t\t\treturn state;\n\n\t\tcase actionTypes.PREVIEW_DWELL:\n\t\t\treturn nextState( state, {\n\t\t\t\tisUserDwelling: true\n\t\t\t} );\n\n\t\tcase actionTypes.ABANDON_START:\n\t\t\treturn nextState( state, {\n\t\t\t\tisUserDwelling: false\n\t\t\t} );\n\n\t\tcase actionTypes.FETCH_START:\n\t\t\treturn nextState( state, {\n\t\t\t\tfetchResponse: undefined\n\t\t\t} );\n\t\tcase actionTypes.FETCH_END:\n\t\t\tif ( action.el === state.activeLink ) {\n\t\t\t\treturn nextState( state, {\n\t\t\t\t\tfetchResponse: action.result,\n\t\t\t\t\tshouldShow: true\n\t\t\t\t} );\n\t\t\t}\n\n\t\t\t/* falls through */\n\t\tdefault:\n\t\t\treturn state;\n\t}\n};\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./src/reducers/preview.js\n// module id = 50\n// module chunks = 0","var actionTypes = require( './../actionTypes' ),\n\tnextState = require( './nextState' );\n\n/**\n * Reducer for actions that modify the state of the settings\n *\n * @param {Object} state\n * @param {Object} action\n * @return {Object} state after action\n */\nmodule.exports = function ( state, action ) {\n\tif ( state === undefined ) {\n\t\tstate = {\n\t\t\tshouldShow: false,\n\t\t\tshowHelp: false,\n\t\t\tshouldShowFooterLink: false\n\t\t};\n\t}\n\n\tswitch ( action.type ) {\n\t\tcase actionTypes.SETTINGS_SHOW:\n\t\t\treturn nextState( state, {\n\t\t\t\tshouldShow: true,\n\t\t\t\tshowHelp: false\n\t\t\t} );\n\t\tcase actionTypes.SETTINGS_HIDE:\n\t\t\treturn nextState( state, {\n\t\t\t\tshouldShow: false,\n\t\t\t\tshowHelp: false\n\t\t\t} );\n\t\tcase actionTypes.SETTINGS_CHANGE:\n\t\t\treturn action.wasEnabled === action.enabled ?\n\t\t\t\t// If the setting is the same, just hide the dialogs\n\t\t\t\tnextState( state, {\n\t\t\t\t\tshouldShow: false\n\t\t\t\t} ) :\n\t\t\t\t// If the settings have changed...\n\t\t\t\tnextState( state, {\n\t\t\t\t\t// If we enabled, we just hide directly, no help\n\t\t\t\t\t// If we disabled, keep it showing and let the ui show the help.\n\t\t\t\t\tshouldShow: !action.enabled,\n\t\t\t\t\tshowHelp: !action.enabled,\n\n\t\t\t\t\t// Since the footer link is only ever shown to anonymous users (see\n\t\t\t\t\t// the BOOT case below), state.userIsAnon is always truthy here.\n\t\t\t\t\tshouldShowFooterLink: !action.enabled\n\t\t\t\t} );\n\n\t\tcase actionTypes.BOOT:\n\t\t\treturn nextState( state, {\n\t\t\t\tshouldShowFooterLink: action.user.isAnon && !action.isEnabled\n\t\t\t} );\n\t\tdefault:\n\t\t\treturn state;\n\t}\n};\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./src/reducers/settings.js\n// module id = 51\n// module chunks = 0","module.exports = {\n\tactions: require( './actions' ),\n\tactionTypes: require( './actionTypes' ),\n\tchangeListeners: require( './changeListeners' ),\n\tcounts: require( './counts' ),\n\tcreatePreviewBehavior: require( './previewBehavior' ),\n\tcreateUserSettings: require( './userSettings' ),\n\tcreateSchema: require( './schema' ),\n\tcreateSettingsDialogRenderer: require( './settingsDialog' ),\n\tgateway: require( './gateway' ),\n\tisEnabled: require( './isEnabled' ),\n\trenderer: require( './renderer' ),\n\tpreview: require( './preview' ),\n\tprocessLinks: require( './processLinks' ),\n\tregisterChangeListener: require( './changeListener' ),\n\treducers: require( './reducers' ),\n\twait: require( './wait' )\n};\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./src/popups.js\n// module id = 52\n// module chunks = 0","/**\n * Interface for API gateway that fetches page summary\n *\n * @interface ext.popups.Gateway\n */\n\n/**\n * Returns a preview model fetched from the api\n * @function\n * @name ext.popups.Gateway#getPageSummary\n * @param {String} title Page title we're querying\n * @returns {jQuery.Promise} that resolves with {ext.popups.PreviewModel}\n * if the request is successful and the response is not empty; otherwise\n * it rejects.\n */\nmodule.exports = {\n\tcreateMediaWikiApiGateway: require( './mediawiki' ),\n\tcreateRESTBaseGateway: require( './rest' )\n};\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./src/gateway/index.js\n// module id = 53\n// module chunks = 0","var createModel,\n\tTYPE_GENERIC = 'generic',\n\tTYPE_PAGE = 'page';\n\n/**\n * @typedef {Object} ext.popups.PreviewModel\n * @property {String} title\n * @property {String} url The canonical URL of the page being previewed\n * @property {String} languageCode\n * @property {String} languageDirection Either \"ltr\" or \"rtl\"\n * @property {String|undefined} extract `undefined` if the extract isn't\n * viable, e.g. if it's empty after having ellipsis and parentheticals\n * removed\n * @property {String} type Either \"EXTRACT\" or \"GENERIC\"\n * @property {Object|undefined} thumbnail\n */\n\n/**\n * Creates a preview model.\n *\n * @param {String} title\n * @param {String} url The canonical URL of the page being previewed\n * @param {String} languageCode\n * @param {String} languageDirection Either \"ltr\" or \"rtl\"\n * @param {String} extract\n * @param {Object|undefined} thumbnail\n * @return {ext.popups.PreviewModel}\n */\ncreateModel = function (\n\ttitle,\n\turl,\n\tlanguageCode,\n\tlanguageDirection,\n\textract,\n\tthumbnail\n) {\n\tvar processedExtract = processExtract( extract ),\n\t\tresult = {\n\t\t\ttitle: title,\n\t\t\turl: url,\n\t\t\tlanguageCode: languageCode,\n\t\t\tlanguageDirection: languageDirection,\n\t\t\textract: processedExtract,\n\t\t\ttype: processedExtract === undefined ? TYPE_GENERIC : TYPE_PAGE,\n\t\t\tthumbnail: thumbnail\n\t\t};\n\n\treturn result;\n};\n\n/**\n * Processes the extract returned by the TextExtracts MediaWiki API query\n * module.\n *\n * @param {String|undefined} extract\n * @return {String|undefined}\n */\nfunction processExtract( extract ) {\n\tvar result;\n\n\tif ( extract === undefined || extract === '' ) {\n\t\treturn undefined;\n\t}\n\n\tresult = extract;\n\tresult = removeParentheticals( result );\n\tresult = removeEllipsis( result );\n\n\treturn result.length > 0 ? result : undefined;\n}\n\n/**\n * Removes the trailing ellipsis from the extract, if it's there.\n *\n * This function was extracted from\n * `mw.popups.renderer.article#removeEllipsis`.\n *\n * @param {String} extract\n * @return {String}\n */\nfunction removeEllipsis( extract ) {\n\treturn extract.replace( /\\.\\.\\.$/, '' );\n}\n\n/**\n * Removes parentheticals from the extract.\n *\n * If the parenthesis are unbalanced or out of order, then the extract is\n * returned without further processing.\n *\n * This function was extracted from\n * `mw.popups.renderer.article#removeParensFromText`.\n *\n * @param {String} extract\n * @return {String}\n */\nfunction removeParentheticals( extract ) {\n\tvar\n\t\tch,\n\t\tresult = '',\n\t\tlevel = 0,\n\t\ti = 0;\n\n\tfor ( i; i < extract.length; i++ ) {\n\t\tch = extract.charAt( i );\n\n\t\tif ( ch === ')' && level === 0 ) {\n\t\t\treturn extract;\n\t\t}\n\t\tif ( ch === '(' ) {\n\t\t\tlevel++;\n\t\t\tcontinue;\n\t\t} else if ( ch === ')' ) {\n\t\t\tlevel--;\n\t\t\tcontinue;\n\t\t}\n\t\tif ( level === 0 ) {\n\t\t\t// Remove leading spaces before brackets\n\t\t\tif ( ch === ' ' && extract.charAt( i + 1 ) === '(' ) {\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tresult += ch;\n\t\t}\n\t}\n\n\treturn ( level === 0 ) ? result : extract;\n}\n\nmodule.exports = {\n\t/**\n\t* @constant {String}\n\t*/\n\tTYPE_GENERIC: TYPE_GENERIC,\n\t/**\n\t* @constant {String}\n\t*/\n\tTYPE_PAGE: TYPE_PAGE,\n\tcreateModel: createModel\n};\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./src/preview/index.js\n// module id = 54\n// module chunks = 0"],"sourceRoot":""} |